Move account-related APIs down one level into /api/account and the former /api/sign_u...
[ndcode_site.git] / api / account / sign_up / verify_email.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 email verification link.`
39             421
40           )
41
42         if (
43           await logjson.logjson_to_json(
44             await account.get('email_verified')
45           )
46         )
47           throw new Problem(
48             'Email already verified',
49             `Your email "${email}" is already verified. You can now sign in.`
50             422
51           )
52
53         let verify_email = await account.get('verify_email')
54         if (
55           verify_email === undefined ||
56             XDate.now() >= await logjson.logjson_to_json(
57               await verify_email.get('expires')
58             )
59         )
60           throw new Problem(
61             'Link code missing',
62             `Email verification link code for account "${email}" does not exist or has expired.`,
63             423
64           )
65         if (
66           link_code !== await logjson.logjson_to_json(
67             await verify_email.get('link_code')
68           )
69         )
70           throw new Problem(
71             'Link code mismatch',
72             `Provided email verification link code "${link_code}" does not match expected value.`,
73             423
74           )
75
76         await account.delete('verify_email')
77         await account.set('email_verified', true)
78
79         await transaction.commit()
80       }
81       catch (error) {
82         transaction.rollback()
83         throw error
84       }
85     }
86   )
87 }