c682c2cfc135cc9a02c7d08666f1ed0f8b66d1a2
[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 nodemailer_noreply = await env.site.get_nodemailer(
6     '/_config/nodemailer_noreply.json'
7   )
8   let post_request = await _require('/_lib/post_request.jst')
9   let session_cookie = await _require('/_lib/session_cookie.jst')
10   let Problem = await _require('/_lib/Problem.jst')
11
12   await post_request(
13     // env
14     env,
15     // handler
16     async email => {
17       // coerce and/or validate
18       email = email.slice(0, 256).toLowerCase()
19       if (email.length === 0)
20         throw new Problem(
21           'Bad request',
22           'Minimum length check failed',
23           400
24         )
25
26       let transaction = await env.site.database.Transaction()
27       try {
28         // initialize env.session_key, set cookie in env.response
29         await session_cookie(env, transaction)
30
31         let account = await (
32           await (
33             await transaction.get({})
34           ).get('accounts', {})
35         ).get(email)
36         if (account === undefined)
37           throw new Problem(
38             'Account does not exist',
39             `Please create the account for "${email}" before attempting to send an email verification link.`
40             421
41           )
42
43         if (await account.get_json('email_verified'))
44           throw new Problem(
45             'Email already verified',
46             `Your email "${email}" is already verified. You can now sign in.`
47             422
48           )
49
50         let link_code = crypto.randomBytes(16).toString('hex')
51         let expires = new XDate()
52         expires.addDays(1)
53         account.set_json(
54           'verify_email',
55           {link_code, expires: expires.getTime()}
56         )
57
58         let globals = await (await transaction.get({})).get('globals')
59         let site_url = await globals.get_json('site_url')
60         let noreply_from = await globals.get_json('noreply_from')
61         let noreply_signature = await globals.get_json('noreply_signature')
62
63         let given_names = await account.get_json('given_names', '')
64         let family_name = await account.get_json('family_name', '')
65         let name =
66           family_name.length ? `${given_names} ${family_name}` : given_names
67
68         await nodemailer_noreply.sendMail(
69           {
70             from: noreply_from,
71             to: `${name} <${email}>`,
72             subject: 'Email address verification',
73             text: `Dear ${given_names},
74
75 We have received a request to sign up using your email address.
76
77 If this request is valid, please verify your email address by visiting the below link:
78 ${site_url}/my_account/verify_email/index.html?email=${encodeURIComponent(email)}&link_code=${encodeURIComponent(link_code)}
79
80 The link is valid for 24 hours.
81
82 Thanks,
83 ${noreply_signature}
84 `
85           }
86         )
87
88         await transaction.commit()
89       }
90       catch (error) {
91         transaction.rollback()
92         throw error
93       }
94     }
95   )
96 }