Finish changing XDate.now() to env.now, new XDate() to new XDate(env.now)
[ndcode_site.git] / api / account / verify_password.json.jst
1 let crypto = require('crypto')
2 let jst_server = (await import('@ndcode/jst_server')).default
3
4 return async env => {
5   let post_request = await _require('/_lib/post_request.jst')
6
7   await post_request(
8     // env
9     env,
10     // handler
11     async (email, link_code) => {
12       // coerce and/or validate
13       email = email.slice(0, 256).toLowerCase()
14       link_code = link_code.slice(0, 256).toLowerCase()
15       if (email.length === 0 || link_code.length < 32)
16         throw new jst_server.Problem(
17           'Bad request',
18           'Minimum length check failed',
19           400
20         )
21
22       let transaction = await env.site.database.Transaction()
23       try {
24         let root = await transaction.get({})
25         let accounts = await root.get('accounts', {})
26         let account = await accounts.get(email)
27         if (account === undefined)
28           throw new jst_server.Problem(
29             'Account does not exist',
30             `Please create the account for "${email}" before attempting to verify the password reset link.`
31             421
32           )
33
34         let verify_password = await account.get('verify_password')
35         if (
36           verify_password === undefined ||
37             env.now >= await verify_password.get_json('expires')
38         )
39           throw new jst_server.Problem(
40             'Link code missing',
41             `Password reset link code for account "${email}" does not exist or has expired.`,
42             423
43           )
44         if (link_code !== await verify_password.get_json('link_code'))
45           throw new jst_server.Problem(
46             'Link code mismatch',
47             `Provided password reset link code "${link_code}" does not match expected value.`,
48             423
49           )
50
51         await account.delete('verify_password')
52         await account.set('password', await verify_password.get('password'))
53
54         await transaction.commit()
55       }
56       catch (error) {
57         transaction.rollback()
58         throw error
59       }
60     }
61   )
62 }