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