7ef9d16813908ee80ab41ab5582fad9c0298f474
[ndcode_site.git] / api / sign_up / send_verification_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 nodemailer_noreply = await env.site.get_nodemailer(
7     '/_config/nodemailer_noreply.json'
8   )
9   let globals = await env.site.get_json('/_config/globals.json')
10   let post_request = await _require('/_lib/post_request.jst')
11   let session_cookie = await _require('/_lib/session_cookie.jst')
12   let Problem = await _require('/_lib/Problem.jst')
13
14   post_request(
15     // env
16     env,
17     // endpoint
18     '/api/sign_up/send_verification_email',
19     // func
20     async email => {
21       // coerce and/or validate
22       email = email.slice(0, 256).toLowerCase()
23       if (email.length === 0)
24         throw new Problem(
25           'Bad request',
26           'Minimum length check failed',
27           400
28         )
29
30       let transaction = await env.site.database.Transaction()
31       try {
32         // initialize env.session_key, set cookie in env.response
33         await session_cookie(env, transaction)
34
35         let account = await (
36           await (
37             await transaction.get({})
38           ).get('accounts', {})
39         ).get(email)
40         if (account === undefined)
41           throw new Problem(
42             'Account does not exist',
43             `Please create the account for "${email}" before attempting to send a verification email.`
44             421
45           )
46
47         let link_code = crypto.randomBytes(16).toString('hex')
48         let expires = new XDate()
49         expires.addDays(1)
50         account.set(
51           'verify_email',
52           transaction.json_to_logjson({link_code, expires: expires.getTime()})
53         )
54
55         let given_names = await logjson.logjson_to_json(
56           await account.get('given_names', '')
57         )
58         let family_name = await logjson.logjson_to_json(
59           await account.get('family_name', '')
60         )
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 }