b82e3284910d8c1c9b073b265be5d2c23e99ed7c
[ndcode_site.git] / api / 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   post_request(
11     // env
12     env,
13     // endpoint
14     '/api/sign_up/verify_email',
15     // func
16     async (email, link_code) => {
17       // coerce and/or validate
18       email = email.slice(0, 256).toLowerCase()
19       link_code = link_code.slice(0, 256).toLowerCase()
20       if (email.length === 0 || link_code.length < 32)
21         throw new Problem(
22           'Bad request',
23           'Minimum length check failed',
24           400
25         )
26
27       let transaction = await env.site.database.Transaction()
28       try {
29         // initialize env.session_key, set cookie in env.response
30         await session_cookie(env, transaction)
31
32         let account = await (
33           await (
34             await transaction.get({})
35           ).get('accounts', {})
36         ).get(email)
37         if (account === undefined)
38           throw new Problem(
39             'Account does not exist',
40             `Please create the account for "${email}" before attempting to verify the email link.`
41             421
42           )
43
44         if (
45           await logjson.logjson_to_json(
46             await account.get('email_verified')
47           )
48         )
49           throw new Problem(
50             'Email already verified',
51             `Your email "${email}" is already verified. You can now sign in.`
52             422
53           )
54
55         let verify_email = await account.get('verify_email')
56         if (
57           verify_email === undefined ||
58             XDate.now() >= await logjson.logjson_to_json(
59               await verify_email.get('expires')
60             )
61         )
62           throw new Problem(
63             'Link code missing',
64             `Link code for email "${email}" does not exist or has expired.`,
65             423
66           )
67         if (
68           link_code !== await logjson.logjson_to_json(
69             await verify_email.get('link_code')
70           )
71         )
72           throw new Problem(
73             'Link code mismatch',
74             `Provided link code "${link_code}" does not match expected value.`,
75             423
76           )
77
78         await account.delete('verify_email')
79         await account.set('email_verified', true)
80
81         await transaction.commit()
82       }
83       catch (error) {
84         transaction.rollback()
85         throw error
86       }
87     }
88   )
89 }