4c3fe7b47263b82120ea0d04813dc6f26f077597
[ndcode_site.git] / my_account / verify_password / index.html.jst
1 return async env => {
2   let breadcrumbs = await _require('/_lib/breadcrumbs.jst')
3   let icon_cross = await env.site.get_min_svg('/_svg/icon_cross.svg')
4   let icon_tick = await env.site.get_min_svg('/_svg/icon_tick.svg')
5   let navbar = await _require('/_lib/navbar.jst')
6   let session_cookie = await _require('/_lib/session_cookie.jst')
7
8   // preload draft details if any
9   let details = {}
10   if (Object.prototype.hasOwnProperty.call(env.parsed_url.query, 'email'))
11     details.email = decodeURIComponent(env.parsed_url.query.email)
12   if (
13      Object.prototype.hasOwnProperty.call(
14       env.parsed_url.query,
15       'link_code'
16     )
17   )
18     details.link_code =
19       decodeURIComponent(env.parsed_url.query.link_code)
20   console.log('details', JSON.stringify(details))
21
22   await navbar(
23     env,
24     // head
25     async _out => {},
26     // body
27     async _out => {
28       await breadcrumbs(env, _out)
29
30       p {'You will need to verify your new password via an emailed link before you can use it to sign in to your account.'}
31
32       div.accordion#accordion.mb-5(role="tablist" aria-multiselectable="true") {
33         div.card#step-1 {
34           div.card-header#step-1-heading(role="tab") {
35             span#step-1-tick(style="display: none;") {
36               span.icon-color.pr-3 {_out.push(icon_tick)}
37             }
38             span#step-1-cross(style="display: none;") {
39               span.icon-color.pr-3 {_out.push(icon_cross)}
40             }
41             //span#step-1-spinner(style="display: none;") {
42             //  span.icon-color.pr-3 {
43             //    div.spinner-border(role="status") {
44             //      span.sr-only {'Loading...'}
45             //    }
46             //  }
47             //}
48             a.h5(data-toggle="collapse" data-parent="#accordion" href="#step-1-collapse" aria-expanded="true" aria-controls="step-1-collapse") {
49               'Link details'
50             }
51           }
52           div#step-1-collapse.collapse.show(role="tabpanel" aria-labelledby="step-1-heading" data-parent="#accordion") {
53             div.card-body {
54               div.row {
55                 div.col-md-6 {
56                   div.form-group {
57                    label.form-label(for="email") {'Email *'}
58                     input.form-control#email(type="email" value=details.email || '' placeholder="Account email address" required="required" maxlength=256) {}
59                   }
60                 }
61                 div.col-md-6 {
62                   div.form-group {
63                     label.form-label(for="link-code") {'Link code *'}
64                     input.form-control#link-code(type="text" value=details.link_code || '' placeholder="Type the code from the email link" required="required" minlength=32 maxlength=32) {}
65                   }
66                 }
67               }
68
69               button.btn.btn-success#step-1-continue(type="button") {'Continue'}
70               p.'mt-3'.mb-0 {'* These fields are required.'}
71             }
72           }
73         }
74         div.card#step-2 {
75           div.card-header#step-2-heading(role="tab") {
76             span#step-2-tick(style="display: none;") {
77               span.icon-color.pr-3 {_out.push(icon_tick)}
78             }
79             span#step-2-cross(style="display: none;") {
80               span.icon-color.pr-3 {_out.push(icon_cross)}
81             }
82             span#step-2-spinner(style="display: none;") {
83               span.icon-color.pr-3 {
84                 div.spinner-border(role="status") {
85                   span.sr-only {'Loading...'}
86                 }
87               }
88             }
89             a.h5.collapsed(data-toggle="collapse" data-parent="#accordion" href="#step-2-collapse" aria-expanded="false" aria-controls="step-2-collapse") {
90               'Verify password'
91             }
92           }
93           div#step-2-collapse.collapse(role="tabpanel" aria-labelledby="step-2-heading" data-parent="#accordion") {
94             div.card-body {
95               p#step-2-message {'Please enter link details first.'}
96
97               button.btn.btn-outline-secondary#step-2-back(type="button") {'Back'}
98               button.btn.btn-outline-secondary.ml-2#step-2-sign-in(type="button") {'Sign in'}
99             }
100           }
101         }
102       }
103     },
104     // scripts
105     async _out => {
106       //script(src="/js/api_call.js") {}
107
108       script {
109         let api_account_verify_password = async (...args) => api_call(
110           '/api/account/verify_password.json',
111           ...args
112         )
113
114         let step_1 = async () => {
115           if (
116             !document.getElementById('email').reportValidity() ||
117               !document.getElementById('link-code').reportValidity()
118           ) {
119             $('#step-1-tick').hide()
120             $('#step-1-cross').show()
121             //$('#step-1-spinner').hide()
122             return false
123           }
124           $('#step-1-tick').show()
125           $('#step-1-cross').hide()
126           //$('#step-1-spinner').hide()
127           return true
128         }
129
130         let step_2 = async () => {
131           $('#step-2-tick').hide()
132           $('#step-2-cross').hide()
133           $('#step-2-spinner').show()
134           document.getElementById('step-1').scrollIntoView()
135
136           let email
137           try {
138             email = document.getElementById('email').value.slice(0, 256).toLowerCase()
139             await api_account_verify_password(
140               // email
141               email,
142               // link_code
143               document.getElementById('link-code').value.slice(0, 32).toLowerCase()
144             )
145           }
146           catch (error) {
147             let problem =
148               error instanceof Problem ?
149                 error :
150                 new Problem(
151                   // title
152                   'Bad request',
153                   // details
154                   (error.stack || error.message).toString()
155                   // status
156                   400
157                 )
158
159             $('#step-2-tick').hide()
160             $('#step-2-cross').show()
161             $('#step-2-spinner').hide()
162
163             document.getElementById('step-2-message').textContent = problem.detail
164             $('#step-2-collapse').collapse('show')
165             return false
166           }
167           $('#step-2-tick').show()
168           $('#step-2-cross').hide()
169           $('#step-2-spinner').hide()
170
171           document.getElementById('step-2-message').textContent = `New password for "${email}" has been verified. You can now sign in.`
172           return true
173         }
174
175         document.addEventListener(
176           'DOMContentLoaded',
177           () => {
178             document.getElementById('step-1-continue').addEventListener(
179               'click',
180               async () => {
181                 if (await step_1() && await step_2())
182                   $('#step-2-collapse').collapse('show')
183               }
184             )
185
186             document.getElementById('step-2-back').addEventListener(
187               'click',
188               () => {$('#step-1-collapse').collapse('show')}
189             )
190
191             document.getElementById('step-2-sign-in').addEventListener(
192               'click',
193               () => {document.getElementById('sign-in').click()}
194             )
195           }
196         )
197       }
198     }
199   )
200 }