Use (Transaction|LazyValue).get_json() instead of logjson.logjson_to_json() and ...
[ndcode_site.git] / api / account / sign_up / send_email_verification_link.json.jst
1 let crypto = require('crypto')
2 let XDate = require('xdate')
3
4 return async env => {
5   let globals = await env.site.get_json('/_config/globals.json')
6   let nodemailer_noreply = await env.site.get_nodemailer(
7     '/_config/nodemailer_noreply.json'
8   )
9   let post_request = await _require('/_lib/post_request.jst')
10   let session_cookie = await _require('/_lib/session_cookie.jst')
11   let Problem = await _require('/_lib/Problem.jst')
12
13   await post_request(
14     // env
15     env,
16     // handler
17     async email => {
18       // coerce and/or validate
19       email = email.slice(0, 256).toLowerCase()
20       if (email.length === 0)
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 send an email verification link.`
41             421
42           )
43
44         if (await account.get_json('email_verified'))
45           throw new Problem(
46             'Email already verified',
47             `Your email "${email}" is already verified. You can now sign in.`
48             422
49           )
50
51         let link_code = crypto.randomBytes(16).toString('hex')
52         let expires = new XDate()
53         expires.addDays(1)
54         account.set_json(
55           'verify_email',
56           {link_code, expires: expires.getTime()}
57         )
58
59         let given_names = await account.get_json('given_names', '')
60         let family_name = await account.get_json('family_name', '')
61         let name =
62           family_name.length ? `${given_names} ${family_name}` : given_names
63
64         await nodemailer_noreply.sendMail(
65           {
66             from: globals.noreply_from,
67             to: `${name} <${email}>`,
68             subject: 'Email address verification',
69             text: `Dear ${given_names},
70
71 We have received a request to sign up using your email address.
72
73 If this request is valid, please verify your email address by visiting the below link:
74 ${globals.site_url}/my_account/verify_email/index.html?email=${encodeURIComponent(email)}&link_code=${encodeURIComponent(link_code)}
75
76 The link is valid for 24 hours.
77
78 Thanks,
79 ${globals.noreply_signature}
80 `
81           }
82         )
83
84         await transaction.commit()
85       }
86       catch (error) {
87         transaction.rollback()
88         throw error
89       }
90     }
91   )
92 }