Add /_lib/get_nodemailer.jst
[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 get_globals = await _require('/_lib/get_globals.jst')
6   let get_nodemailer = await _require('/_lib/get_nodemailer.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, 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 = await get_nodemailer(env, transaction, 'noreply')
61         let globals = await get_globals(env, transaction)
62         site_url = await globals.get_json('site_url')
63         noreply_from = await globals.get_json('noreply_from')
64         noreply_signature = await globals.get_json('noreply_signature')
65
66         given_names = await account.get_json('given_names', '')
67         family_name = await account.get_json('family_name', '')
68
69         await transaction.commit()
70       }
71       catch (error) {
72         transaction.rollback()
73         throw error
74       }
75
76       let name =
77         family_name.length ? `${given_names} ${family_name}` : given_names
78       await nodemailer.sendMail(
79         {
80           from: noreply_from,
81           to: `${name} <${email}>`,
82           subject: 'Email address verification',
83           text: `Dear ${given_names},
84
85 We have received a request to sign up using your email address.
86
87 If this request is valid, please verify your email address by visiting the below link:
88 ${site_url}/my_account/verify_email/index.html?email=${encodeURIComponent(email)}&link_code=${encodeURIComponent(link_code)}
89
90 The link is valid for 24 hours.
91
92 Thanks,
93 ${noreply_signature}
94 `
95         }
96       )
97     }
98   )
99 }