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