Move *.jst from / to /_lib to keep things tidy, implement /_lib/Problem.jst and ...
[ndcode_site.git] / api / sign_up / create_account.json.jst
1 let XDate = require('xdate')
2
3 return async env => {
4   let post_request = await _require('/_lib/post_request.jst')
5   let session_cookie = await _require('/_lib/session_cookie.jst')
6   let Problem = await _require('/_lib/Problem.jst')
7
8   post_request(
9     // env
10     env,
11     // api
12     '/api/sign_up/create_account',
13     // func
14     async (verification_code, details) => {
15       // coerce and/or validate
16       verification_code = verification_code.slice(0, 6).toLowerCase()
17       details = {
18         email: details.email.slice(0, 256).toLowerCase(),
19         given_names: details.given_names.slice(0, 256),
20         family_name: details.family_name.slice(0, 256),
21         password: details.password.slice(0, 256),
22         contact_me: details.contact_me ? true : false
23       }
24
25       let transaction = await env.site.database.Transaction()
26       try {
27         // initialize env.session_key, set cookie in env.response
28         let session = await session_cookie(env, transaction)
29
30         let captcha = await session.get('captcha')
31         if (captcha === undefined || XDate.now() >= captcha.get('expires'))
32           throw new Problem(
33             'No verification image in session',
34             `Please call the "/api/verification_image.png" endpoint to create a verification image, in same session as the "/api/sign_up.json" call and less than one hour prior.`,
35             418
36           )
37         
38         let captcha_text = await captcha.get('text')
39         if (verification_code !== captcha_text) {
40           console.log(`verification code mismatch, \"${verification_code}\" should be \"${captcha_text}\"`)
41
42           throw new Problem(
43             'Verification code mismatch',
44             `The provided verification code "${verification_code}" did not match the verification image.`,
45             419
46           )
47         }
48
49         let accounts = await (
50           await transaction.get({})
51         ).get('accounts', {})
52
53         if (accounts.has(details.email))
54           throw new Problem(
55             'Account already exists',
56             `The email "${details.email}" already has an account registered.`,
57             420
58           )
59         accounts.set(details.email, transaction.json_to_logjson(details))
60
61         await transaction.commit()
62       }
63       catch (error) {
64         transaction.rollback()
65         throw error
66       }
67     }
68   )
69 }