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