diff options
Diffstat (limited to 'src/internal-server/app/Controllers/Http/UserController.js')
-rw-r--r-- | src/internal-server/app/Controllers/Http/UserController.js | 178 |
1 files changed, 97 insertions, 81 deletions
diff --git a/src/internal-server/app/Controllers/Http/UserController.js b/src/internal-server/app/Controllers/Http/UserController.js index a3ad736fa..e387e39c4 100644 --- a/src/internal-server/app/Controllers/Http/UserController.js +++ b/src/internal-server/app/Controllers/Http/UserController.js | |||
@@ -1,41 +1,38 @@ | |||
1 | const User = use('App/Models/User'); | 1 | const User = use('App/Models/User'); |
2 | const Service = use('App/Models/Service'); | 2 | const Service = use('App/Models/Service'); |
3 | const Workspace = use('App/Models/Workspace'); | 3 | const Workspace = use('App/Models/Workspace'); |
4 | const { | 4 | const { validateAll } = use('Validator'); |
5 | validateAll, | ||
6 | } = use('Validator'); | ||
7 | 5 | ||
8 | const btoa = require('btoa'); | 6 | const btoa = require('btoa'); |
9 | const fetch = require('node-fetch'); | 7 | const fetch = require('node-fetch'); |
10 | const uuid = require('uuid/v4'); | 8 | const { v4: uuid } = require('uuid'); |
11 | const crypto = require('crypto'); | 9 | const crypto = require('crypto'); |
12 | const { DEFAULT_APP_SETTINGS } = require('../../../../environment'); | 10 | const { DEFAULT_APP_SETTINGS } = require('../../../../environment'); |
13 | 11 | ||
14 | const apiRequest = (url, route, method, auth) => new Promise((resolve, reject) => { | 12 | const apiRequest = (url, route, method, auth) => |
15 | const base = `${url}/v1/`; | 13 | new Promise((resolve, reject) => { |
16 | const user = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Ferdi/5.3.0-beta.1 Chrome/69.0.3497.128 Electron/4.2.4 Safari/537.36'; | 14 | const base = `${url}/v1/`; |
15 | const user = | ||
16 | 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Ferdi/5.3.0-beta.1 Chrome/69.0.3497.128 Electron/4.2.4 Safari/537.36'; | ||
17 | 17 | ||
18 | try { | 18 | try { |
19 | fetch(base + route, { | 19 | fetch(base + route, { |
20 | method, | 20 | method, |
21 | headers: { | 21 | headers: { |
22 | Authorization: `Bearer ${auth}`, | 22 | Authorization: `Bearer ${auth}`, |
23 | 'User-Agent': user, | 23 | 'User-Agent': user, |
24 | }, | 24 | }, |
25 | }) | 25 | }) |
26 | .then(data => data.json()) | 26 | .then(data => data.json()) |
27 | .then(json => resolve(json)); | 27 | .then(json => resolve(json)); |
28 | } catch (e) { | 28 | } catch (e) { |
29 | reject(); | 29 | reject(); |
30 | } | 30 | } |
31 | }); | 31 | }); |
32 | 32 | ||
33 | class UserController { | 33 | class UserController { |
34 | // Register a new user | 34 | // Register a new user |
35 | async signup({ | 35 | async signup({ request, response }) { |
36 | request, | ||
37 | response, | ||
38 | }) { | ||
39 | // Validate user input | 36 | // Validate user input |
40 | const validation = await validateAll(request.all(), { | 37 | const validation = await validateAll(request.all(), { |
41 | firstname: 'required', | 38 | firstname: 'required', |
@@ -52,15 +49,13 @@ class UserController { | |||
52 | 49 | ||
53 | return response.send({ | 50 | return response.send({ |
54 | message: 'Successfully created account', | 51 | message: 'Successfully created account', |
55 | token: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJGZXJkaSBJbnRlcm5hbCBTZXJ2ZXIiLCJpYXQiOjE1NzEwNDAyMTUsImV4cCI6MjUzMzk1NDE3ODQ0LCJhdWQiOiJnZXRmZXJkaS5jb20iLCJzdWIiOiJmZXJkaUBsb2NhbGhvc3QiLCJ1c2VySWQiOiIxIn0.9_TWFGp6HROv8Yg82Rt6i1-95jqWym40a-HmgrdMC6M', | 52 | token: |
53 | 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJGZXJkaSBJbnRlcm5hbCBTZXJ2ZXIiLCJpYXQiOjE1NzEwNDAyMTUsImV4cCI6MjUzMzk1NDE3ODQ0LCJhdWQiOiJnZXRmZXJkaS5jb20iLCJzdWIiOiJmZXJkaUBsb2NhbGhvc3QiLCJ1c2VySWQiOiIxIn0.9_TWFGp6HROv8Yg82Rt6i1-95jqWym40a-HmgrdMC6M', | ||
56 | }); | 54 | }); |
57 | } | 55 | } |
58 | 56 | ||
59 | // Login using an existing user | 57 | // Login using an existing user |
60 | async login({ | 58 | async login({ request, response }) { |
61 | request, | ||
62 | response, | ||
63 | }) { | ||
64 | if (!request.header('Authorization')) { | 59 | if (!request.header('Authorization')) { |
65 | return response.status(401).send({ | 60 | return response.status(401).send({ |
66 | message: 'Please provide authorization', | 61 | message: 'Please provide authorization', |
@@ -70,17 +65,19 @@ class UserController { | |||
70 | 65 | ||
71 | return response.send({ | 66 | return response.send({ |
72 | message: 'Successfully logged in', | 67 | message: 'Successfully logged in', |
73 | token: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJGZXJkaSBJbnRlcm5hbCBTZXJ2ZXIiLCJpYXQiOjE1NzEwNDAyMTUsImV4cCI6MjUzMzk1NDE3ODQ0LCJhdWQiOiJnZXRmZXJkaS5jb20iLCJzdWIiOiJmZXJkaUBsb2NhbGhvc3QiLCJ1c2VySWQiOiIxIn0.9_TWFGp6HROv8Yg82Rt6i1-95jqWym40a-HmgrdMC6M', | 68 | token: |
69 | 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJGZXJkaSBJbnRlcm5hbCBTZXJ2ZXIiLCJpYXQiOjE1NzEwNDAyMTUsImV4cCI6MjUzMzk1NDE3ODQ0LCJhdWQiOiJnZXRmZXJkaS5jb20iLCJzdWIiOiJmZXJkaUBsb2NhbGhvc3QiLCJ1c2VySWQiOiIxIn0.9_TWFGp6HROv8Yg82Rt6i1-95jqWym40a-HmgrdMC6M', | ||
74 | }); | 70 | }); |
75 | } | 71 | } |
76 | 72 | ||
77 | // Return information about the current user | 73 | // Return information about the current user |
78 | async me({ | 74 | async me({ response }) { |
79 | response, | ||
80 | }) { | ||
81 | const user = await User.find(1); | 75 | const user = await User.find(1); |
82 | 76 | ||
83 | const settings = typeof user.settings === 'string' ? JSON.parse(user.settings) : user.settings; | 77 | const settings = |
78 | typeof user.settings === 'string' | ||
79 | ? JSON.parse(user.settings) | ||
80 | : user.settings; | ||
84 | 81 | ||
85 | return response.send({ | 82 | return response.send({ |
86 | accountType: 'individual', | 83 | accountType: 'individual', |
@@ -94,14 +91,11 @@ class UserController { | |||
94 | isSubscriptionOwner: true, | 91 | isSubscriptionOwner: true, |
95 | lastname: 'Application', | 92 | lastname: 'Application', |
96 | locale: DEFAULT_APP_SETTINGS.fallbackLocale, | 93 | locale: DEFAULT_APP_SETTINGS.fallbackLocale, |
97 | ...settings || {}, | 94 | ...(settings || {}), |
98 | }); | 95 | }); |
99 | } | 96 | } |
100 | 97 | ||
101 | async updateMe({ | 98 | async updateMe({ request, response }) { |
102 | request, | ||
103 | response, | ||
104 | }) { | ||
105 | const user = await User.find(1); | 99 | const user = await User.find(1); |
106 | 100 | ||
107 | let settings = user.settings || {}; | 101 | let settings = user.settings || {}; |
@@ -132,16 +126,11 @@ class UserController { | |||
132 | locale: DEFAULT_APP_SETTINGS.fallbackLocale, | 126 | locale: DEFAULT_APP_SETTINGS.fallbackLocale, |
133 | ...newSettings, | 127 | ...newSettings, |
134 | }, | 128 | }, |
135 | status: [ | 129 | status: ['data-updated'], |
136 | 'data-updated', | ||
137 | ], | ||
138 | }); | 130 | }); |
139 | } | 131 | } |
140 | 132 | ||
141 | async import({ | 133 | async import({ request, response }) { |
142 | request, | ||
143 | response, | ||
144 | }) { | ||
145 | // Validate user input | 134 | // Validate user input |
146 | const validation = await validateAll(request.all(), { | 135 | const validation = await validateAll(request.all(), { |
147 | email: 'required|email', | 136 | email: 'required|email', |
@@ -149,7 +138,8 @@ class UserController { | |||
149 | server: 'required', | 138 | server: 'required', |
150 | }); | 139 | }); |
151 | if (validation.fails()) { | 140 | if (validation.fails()) { |
152 | let errorMessage = 'There was an error while trying to import your account:\n'; | 141 | let errorMessage = |
142 | 'There was an error while trying to import your account:\n'; | ||
153 | for (const message of validation.messages()) { | 143 | for (const message of validation.messages()) { |
154 | if (message.validation === 'required') { | 144 | if (message.validation === 'required') { |
155 | errorMessage += `- Please make sure to supply your ${message.field}\n`; | 145 | errorMessage += `- Please make sure to supply your ${message.field}\n`; |
@@ -162,16 +152,16 @@ class UserController { | |||
162 | return response.status(401).send(errorMessage); | 152 | return response.status(401).send(errorMessage); |
163 | } | 153 | } |
164 | 154 | ||
165 | const { | 155 | const { email, password, server } = request.all(); |
166 | email, | ||
167 | password, | ||
168 | server, | ||
169 | } = request.all(); | ||
170 | 156 | ||
171 | const hashedPassword = crypto.createHash('sha256').update(password).digest('base64'); | 157 | const hashedPassword = crypto |
158 | .createHash('sha256') | ||
159 | .update(password) | ||
160 | .digest('base64'); | ||
172 | 161 | ||
173 | const base = `${server}/v1/`; | 162 | const base = `${server}/v1/`; |
174 | const userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Ferdi/5.3.0-beta.1 Chrome/69.0.3497.128 Electron/4.2.4 Safari/537.36'; | 163 | const userAgent = |
164 | 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Ferdi/5.3.0-beta.1 Chrome/69.0.3497.128 Electron/4.2.4 Safari/537.36'; | ||
175 | 165 | ||
176 | // Try to get an authentication token | 166 | // Try to get an authentication token |
177 | let token; | 167 | let token; |
@@ -188,7 +178,8 @@ class UserController { | |||
188 | const content = await rawResponse.json(); | 178 | const content = await rawResponse.json(); |
189 | 179 | ||
190 | if (!content.message || content.message !== 'Successfully logged in') { | 180 | if (!content.message || content.message !== 'Successfully logged in') { |
191 | const errorMessage = 'Could not login into Franz with your supplied credentials. Please check and try again'; | 181 | const errorMessage = |
182 | 'Could not login into Franz with your supplied credentials. Please check and try again'; | ||
192 | return response.status(401).send(errorMessage); | 183 | return response.status(401).send(errorMessage); |
193 | } | 184 | } |
194 | 185 | ||
@@ -210,7 +201,8 @@ class UserController { | |||
210 | return response.status(401).send(errorMessage); | 201 | return response.status(401).send(errorMessage); |
211 | } | 202 | } |
212 | if (!userInf) { | 203 | if (!userInf) { |
213 | const errorMessage = 'Could not get your user info from Franz. Please check your credentials or try again later'; | 204 | const errorMessage = |
205 | 'Could not get your user info from Franz. Please check your credentials or try again later'; | ||
214 | return response.status(401).send(errorMessage); | 206 | return response.status(401).send(errorMessage); |
215 | } | 207 | } |
216 | 208 | ||
@@ -225,9 +217,14 @@ class UserController { | |||
225 | let serviceId; | 217 | let serviceId; |
226 | do { | 218 | do { |
227 | serviceId = uuid(); | 219 | serviceId = uuid(); |
228 | } while ((await Service.query().where('serviceId', serviceId).fetch()).rows.length > 0); // eslint-disable-line no-await-in-loop | 220 | } while ( |
229 | 221 | // eslint-disable-next-line no-await-in-loop | |
230 | await Service.create({ // eslint-disable-line no-await-in-loop | 222 | (await Service.query().where('serviceId', serviceId).fetch()).rows |
223 | .length > 0 | ||
224 | ); | ||
225 | |||
226 | // eslint-disable-next-line no-await-in-loop | ||
227 | await Service.create({ | ||
231 | serviceId, | 228 | serviceId, |
232 | name: service.name, | 229 | name: service.name, |
233 | recipeId: service.recipeId, | 230 | recipeId: service.recipeId, |
@@ -249,11 +246,18 @@ class UserController { | |||
249 | let workspaceId; | 246 | let workspaceId; |
250 | do { | 247 | do { |
251 | workspaceId = uuid(); | 248 | workspaceId = uuid(); |
252 | } while ((await Workspace.query().where('workspaceId', workspaceId).fetch()).rows.length > 0); // eslint-disable-line no-await-in-loop | 249 | } while ( |
253 | 250 | // eslint-disable-next-line no-await-in-loop | |
254 | const services = workspace.services.map(service => serviceIdTranslation[service]); | 251 | (await Workspace.query().where('workspaceId', workspaceId).fetch()) |
255 | 252 | .rows.length > 0 | |
256 | await Workspace.create({ // eslint-disable-line no-await-in-loop | 253 | ); |
254 | |||
255 | const services = workspace.services.map( | ||
256 | service => serviceIdTranslation[service], | ||
257 | ); | ||
258 | |||
259 | // eslint-disable-next-line no-await-in-loop | ||
260 | await Workspace.create({ | ||
257 | workspaceId, | 261 | workspaceId, |
258 | name: workspace.name, | 262 | name: workspace.name, |
259 | order: workspace.order, | 263 | order: workspace.order, |
@@ -266,7 +270,9 @@ class UserController { | |||
266 | return response.status(401).send(errorMessage); | 270 | return response.status(401).send(errorMessage); |
267 | } | 271 | } |
268 | 272 | ||
269 | return response.send('Your account has been imported. You can now use your Franz account in Ferdi.'); | 273 | return response.send( |
274 | 'Your account has been imported. You can now use your Franz account in Ferdi.', | ||
275 | ); | ||
270 | } | 276 | } |
271 | 277 | ||
272 | // Account import/export | 278 | // Account import/export |
@@ -291,10 +297,7 @@ class UserController { | |||
291 | .send(exportData); | 297 | .send(exportData); |
292 | } | 298 | } |
293 | 299 | ||
294 | async importFerdi({ | 300 | async importFerdi({ request, response }) { |
295 | request, | ||
296 | response, | ||
297 | }) { | ||
298 | const validation = await validateAll(request.all(), { | 301 | const validation = await validateAll(request.all(), { |
299 | file: 'required', | 302 | file: 'required', |
300 | }); | 303 | }); |
@@ -306,7 +309,9 @@ class UserController { | |||
306 | try { | 309 | try { |
307 | file = JSON.parse(request.input('file')); | 310 | file = JSON.parse(request.input('file')); |
308 | } catch (e) { | 311 | } catch (e) { |
309 | return response.send('Could not import: Invalid file, could not read file'); | 312 | return response.send( |
313 | 'Could not import: Invalid file, could not read file', | ||
314 | ); | ||
310 | } | 315 | } |
311 | 316 | ||
312 | if (!file || !file.services || !file.workspaces) { | 317 | if (!file || !file.services || !file.workspaces) { |
@@ -322,9 +327,14 @@ class UserController { | |||
322 | let serviceId; | 327 | let serviceId; |
323 | do { | 328 | do { |
324 | serviceId = uuid(); | 329 | serviceId = uuid(); |
325 | } while ((await Service.query().where('serviceId', serviceId).fetch()).rows.length > 0); // eslint-disable-line no-await-in-loop | 330 | } while ( |
326 | 331 | // eslint-disable-next-line no-await-in-loop | |
327 | await Service.create({ // eslint-disable-line no-await-in-loop | 332 | (await Service.query().where('serviceId', serviceId).fetch()).rows |
333 | .length > 0 | ||
334 | ); | ||
335 | |||
336 | // eslint-disable-next-line no-await-in-loop | ||
337 | await Service.create({ | ||
328 | serviceId, | 338 | serviceId, |
329 | name: service.name, | 339 | name: service.name, |
330 | recipeId: service.recipeId, | 340 | recipeId: service.recipeId, |
@@ -344,13 +354,19 @@ class UserController { | |||
344 | let workspaceId; | 354 | let workspaceId; |
345 | do { | 355 | do { |
346 | workspaceId = uuid(); | 356 | workspaceId = uuid(); |
347 | } while ((await Workspace.query().where('workspaceId', workspaceId).fetch()).rows.length > 0); // eslint-disable-line no-await-in-loop | 357 | } while ( |
348 | 358 | // eslint-disable-next-line no-await-in-loop | |
349 | const services = (workspace.services && typeof (workspace.services) === 'object') ? | 359 | (await Workspace.query().where('workspaceId', workspaceId).fetch()) |
350 | workspace.services.map((service) => serviceIdTranslation[service]) : | 360 | .rows.length > 0 |
351 | []; | 361 | ); |
352 | 362 | ||
353 | await Workspace.create({ // eslint-disable-line no-await-in-loop | 363 | const services = |
364 | workspace.services && typeof workspace.services === 'object' | ||
365 | ? workspace.services.map(service => serviceIdTranslation[service]) | ||
366 | : []; | ||
367 | |||
368 | // eslint-disable-next-line no-await-in-loop | ||
369 | await Workspace.create({ | ||
354 | workspaceId, | 370 | workspaceId, |
355 | name: workspace.name, | 371 | name: workspace.name, |
356 | order: workspace.order, | 372 | order: workspace.order, |