Add expiry on sign up draft (to prevent leakage of personal information)
[ndcode_site.git] / api / account / sign_up / create_account.json.jst
1 let logjson = (await import('@ndcode/logjson')).default
2 let XDate = require('xdate')
3
4 return async env => {
5   let post_request = await _require('/_lib/post_request.jst')
6   let session_cookie = await _require('/_lib/session_cookie.jst')
7   let Problem = await _require('/_lib/Problem.jst')
8
9   await post_request(
10     // env
11     env,
12     // handler
13     async (verification_code, details) => {
14       // coerce and/or validate
15       verification_code = verification_code.slice(0, 6).toLowerCase()
16       details = {
17         email: details.email.slice(0, 256).toLowerCase(),
18         given_names: details.given_names.slice(0, 256),
19         family_name: details.family_name.slice(0, 256),
20         password: details.password.slice(0, 256),
21         contact_me: details.contact_me ? true : false
22       }
23       if (
24         verification_code.length < 6 ||
25           details.given_names.length === 0 ||
26           details.password.length < 8
27       )
28         throw new Problem(
29           'Bad request',
30           'Minimum length check failed',
31           400
32         )
33
34       let transaction = await env.site.database.Transaction()
35       try {
36         // initialize env.session_key, set cookie in env.response
37         let session = await session_cookie(env, transaction)
38
39         let captcha = await session.get('captcha')
40         if (
41           captcha === undefined ||
42             XDate.now() >= await logjson.logjson_to_json(
43               await captcha.get('expires')
44             )
45         )
46           throw new Problem(
47             'No verification image in session',
48             `Please call the "/api/verification_image.png" endpoint to create a verification image, in same session as the "/api/account/sign_up/create_account.json" call and less than one hour prior.`,
49             418
50           )
51         
52         let captcha_text = await logjson.logjson_to_json(
53           await captcha.get('text')
54         )
55         if (verification_code !== captcha_text) {
56           console.log(`verification code mismatch, \"${verification_code}\" should be \"${captcha_text}\"`)
57
58           throw new Problem(
59             'Verification code mismatch',
60             `The provided verification code "${verification_code}" did not match the verification image.`,
61             419
62           )
63         }
64
65         let accounts = await (
66           await transaction.get({})
67         ).get('accounts', {})
68
69         if (accounts.has(details.email))
70           throw new Problem(
71             'Account already exists',
72             `The email "${details.email}" already has an account registered.`,
73             420
74           )
75         accounts.set(details.email, transaction.json_to_logjson(details))
76
77         await transaction.commit()
78       }
79       catch (error) {
80         transaction.rollback()
81         throw error
82       }
83     }
84   )
85 }