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