Add /_lib/get_nodemailer.jst
[ndcode_site.git] / api / account / password_reset.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, password) => {
16       // coerce and/or validate
17       email = email.slice(0, 256).toLowerCase()
18       password = password.slice(0, 256)
19       if (email.length === 0 || password.length < 8)
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       let link_code
28       let nodemailer, noreply_from, noreply_signature
29       let given_names, family_name
30       try {
31         // initialize env.session_key, set cookie in env.response
32         await get_session(env, transaction)
33
34         let account = await (
35           await (
36             await transaction.get({})
37           ).get('accounts', {})
38         ).get(email)
39         if (account === undefined)
40           throw new Problem(
41             'Account does not exist',
42             `Please create the account for "${email}" before attempting to reset its password.`
43             421
44           )
45
46         link_code = crypto.randomBytes(16).toString('hex')
47         let expires = new XDate()
48         expires.addDays(1)
49         account.set_json(
50           'verify_password',
51           {password, link_code, expires: expires.getTime()}
52         )
53
54         nodemailer = await get_nodemailer(env, transaction, 'noreply')
55         let globals = await get_globals(env, transaction)
56         site_url = await globals.get_json('site_url')
57         noreply_from = await globals.get_json('noreply_from')
58         noreply_signature = await globals.get_json('noreply_signature')
59
60         given_names = await account.get_json('given_names', '')
61         family_name = await account.get_json('family_name', '')
62
63         await transaction.commit()
64       }
65       catch (error) {
66         transaction.rollback()
67         throw error
68       }
69
70       let name =
71         family_name.length ? `${given_names} ${family_name}` : given_names
72       await nodemailer.sendMail(
73         {
74           from: noreply_from,
75           to: `${name} <${email}>`,
76           subject: 'Password reset',
77           text: `Dear ${given_names},
78
79 We have received a request to reset the account password for your email address.
80
81 If this request is valid, please verify the new password by visiting the below link:
82 ${site_url}/my_account/verify_password/index.html?email=${encodeURIComponent(email)}&link_code=${encodeURIComponent(link_code)}
83
84 The link is valid for 24 hours.
85
86 Thanks,
87 ${noreply_signature}
88 `
89         }
90       )
91     }
92   )
93 }