Add ticks, crosses and spinners in sign up form
[ndcode_site.git] / api / sign_up.json.jst
1 let stream_buffers = require('stream-buffers')
2 let XDate = require('xdate')
3
4 return async env => {
5   let session_cookie = await _require('/session_cookie.jst')
6
7   if (env.request.method !== 'POST') {
8     env.response.setHeader('Allow', 'POST')
9     env.mime_type = 'application/problem+json; charset=utf-8'
10     env.site.serve(
11       env,
12       405,
13       Buffer.from(
14         JSON.stringify(
15           {
16             title: 'Method not allowed',
17             detail: `The endpoint "${env.parsed_url.path}" requires a POST request.`,
18             status: 405
19           },
20           null,
21           2
22         ) + '\n',
23         'utf-8'
24       ),
25       'sign_up.json.jst'
26     )
27     return
28   }
29
30   let write_stream = new stream_buffers.WritableStreamBuffer()
31   let data = new Promise(
32     (resolve, reject) => {
33       write_stream.
34       on('finish', () => {resolve(write_stream.getContents())}).
35       on('error', () => {reject()})
36     }
37   )
38   env.request.pipe(write_stream)
39   let query = JSON.parse((await data).toString())
40   let email = query.email.toLowerCase()
41   console.log('sign up', email)
42
43   // initialize env.session_key, set cookie in env.response
44   let transaction = await env.site.database.Transaction()
45   let session = await session_cookie(env, transaction)
46
47   let captcha = await session.get('captcha')
48   if (captcha === undefined || XDate.now() >= captcha.get('expires')) {
49     transaction.rollback()
50
51     env.mime_type = 'application/problem+json; charset=utf-8'
52     env.site.serve(
53       env,
54       418,
55       Buffer.from(
56         JSON.stringify(
57           {
58             title: 'No verification image in session',
59             detail: `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.`,
60             status: 418
61           },
62           null,
63           2
64         ) + '\n',
65         'utf-8'
66       ),
67       'sign_up.json.jst'
68     )
69     return
70   }
71
72   
73   let verification_code = query.verification_code.toLowerCase()
74   let captcha_text = await captcha.get('text')
75   if (verification_code !== captcha_text) {
76     console.log(`verification code mismatch, \"${verification_code}\" should be \"${captcha_text}\"`)
77     transaction.rollback()
78
79     env.mime_type = 'application/problem+json; charset=utf-8'
80     env.site.serve(
81       env,
82       419,
83       Buffer.from(
84         JSON.stringify(
85           {
86             title: 'Verification code mismatch',
87             detail: `The provided verification code "${verification_code}" did not match the verification image.`,
88             status: 419
89           },
90           null,
91           2
92         ) + '\n',
93         'utf-8'
94       ),
95       'sign_up.json.jst'
96     )
97     return
98   }
99
100   let accounts = await (
101     await transaction.get({})
102   ).get('accounts', {})
103
104   if (accounts.has(email)) {
105     transaction.rollback()
106
107     env.mime_type = 'application/problem+json; charset=utf-8'
108     env.site.serve(
109       env,
110       420,
111       Buffer.from(
112         JSON.stringify(
113           {
114             title: 'Account already exists',
115             detail: `The email "${email}" already has an account registered.`,
116             status: 420
117           },
118           null,
119           2
120         ) + '\n',
121         'utf-8'
122       ),
123       'sign_up.json.jst'
124     )
125     return
126   }
127   accounts.set(
128     email,
129     transaction.json_to_logjson(
130       {
131         given_names: query.given_names || '',
132         family_name: query.family_name || '',
133         password: query.password || '',
134         contact_me: query.contact_me || false,
135         email_verified: false
136       }
137     )
138   )
139
140   await transaction.commit()
141
142   env.site.serve(
143     env,
144     200,
145     Buffer.from(
146       JSON.stringify(
147         null,
148         null,
149         2
150       ) + '\n',
151       'utf-8'
152     ),
153     'sign_up.json.jst'
154   )
155 }