aboutsummaryrefslogtreecommitdiffstats
path: root/app/Controllers/Http/UserController.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/Controllers/Http/UserController.js')
-rw-r--r--app/Controllers/Http/UserController.js150
1 files changed, 77 insertions, 73 deletions
diff --git a/app/Controllers/Http/UserController.js b/app/Controllers/Http/UserController.js
index 0d768a9..99336cb 100644
--- a/app/Controllers/Http/UserController.js
+++ b/app/Controllers/Http/UserController.js
@@ -1,44 +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 { 4const { validateAll } = use('Validator');
5 validateAll,
6} = use('Validator');
7const Env = use('Env'); 5const Env = use('Env');
8 6
9const atob = require('atob'); 7const atob = require('atob');
10const btoa = require('btoa'); 8const btoa = require('btoa');
11const fetch = require('node-fetch'); 9const fetch = require('node-fetch');
12const uuid = require('uuid/v4'); 10const { v4: uuid } = require('uuid');
13const crypto = require('crypto'); 11const crypto = require('crypto');
14 12
15const franzRequest = (route, method, auth) => new Promise((resolve, reject) => { 13const franzRequest = (route, method, auth) =>
16 const base = 'https://api.franzinfra.com/v1/'; 14 new Promise((resolve, reject) => {
17 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 base = 'https://api.franzinfra.com/v1/';
16 const user =
17 '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';
18 18
19 try { 19 try {
20 fetch(base + route, { 20 fetch(base + route, {
21 method, 21 method,
22 headers: { 22 headers: {
23 Authorization: `Bearer ${auth}`, 23 Authorization: `Bearer ${auth}`,
24 'User-Agent': user, 24 'User-Agent': user,
25 }, 25 },
26 }) 26 })
27 .then((data) => data.json()) 27 .then(data => data.json())
28 .then((json) => resolve(json)); 28 .then(json => resolve(json));
29 } catch (e) { 29 } catch (e) {
30 reject(); 30 reject();
31 } 31 }
32}); 32 });
33 33
34class UserController { 34class UserController {
35 // Register a new user 35 // Register a new user
36 async signup({ 36 async signup({ request, response, auth }) {
37 request, 37 if (Env.get('IS_REGISTRATION_ENABLED') == 'false') {
38 response, 38 // eslint-disable-line eqeqeq
39 auth,
40 }) {
41 if (Env.get('IS_REGISTRATION_ENABLED') == 'false') { // eslint-disable-line eqeqeq
42 return response.status(401).send({ 39 return response.status(401).send({
43 message: 'Registration is disabled on this server', 40 message: 'Registration is disabled on this server',
44 status: 401, 41 status: 401,
@@ -89,11 +86,7 @@ class UserController {
89 } 86 }
90 87
91 // Login using an existing user 88 // Login using an existing user
92 async login({ 89 async login({ request, response, auth }) {
93 request,
94 response,
95 auth,
96 }) {
97 if (!request.header('Authorization')) { 90 if (!request.header('Authorization')) {
98 return response.status(401).send({ 91 return response.status(401).send({
99 message: 'Please provide authorization', 92 message: 'Please provide authorization',
@@ -102,10 +95,12 @@ class UserController {
102 } 95 }
103 96
104 // Get auth data from auth token 97 // Get auth data from auth token
105 const authHeader = atob(request.header('Authorization').replace('Basic ', '')).split(':'); 98 const authHeader = atob(
99 request.header('Authorization').replace('Basic ', ''),
100 ).split(':');
106 101
107 // Check if user with email exists 102 // Check if user with email exists
108 const user = (await User.query().where('email', authHeader[0]).first()); 103 const user = await User.query().where('email', authHeader[0]).first();
109 if (!user || !user.email) { 104 if (!user || !user.email) {
110 return response.status(401).send({ 105 return response.status(401).send({
111 message: 'User credentials not valid (Invalid mail)', 106 message: 'User credentials not valid (Invalid mail)',
@@ -133,17 +128,17 @@ class UserController {
133 } 128 }
134 129
135 // Return information about the current user 130 // Return information about the current user
136 async me({ 131 async me({ response, auth }) {
137 response,
138 auth,
139 }) {
140 try { 132 try {
141 await auth.getUser(); 133 await auth.getUser();
142 } catch (error) { 134 } catch (error) {
143 response.send('Missing or invalid api token'); 135 response.send('Missing or invalid api token');
144 } 136 }
145 137
146 const settings = typeof auth.user.settings === 'string' ? JSON.parse(auth.user.settings) : auth.user.settings; 138 const settings =
139 typeof auth.user.settings === 'string'
140 ? JSON.parse(auth.user.settings)
141 : auth.user.settings;
147 142
148 return response.send({ 143 return response.send({
149 accountType: 'individual', 144 accountType: 'individual',
@@ -158,15 +153,11 @@ class UserController {
158 isSubscriptionOwner: true, 153 isSubscriptionOwner: true,
159 lastname: auth.user.lastname, 154 lastname: auth.user.lastname,
160 locale: 'en-US', 155 locale: 'en-US',
161 ...settings || {}, 156 ...(settings || {}),
162 }); 157 });
163 } 158 }
164 159
165 async updateMe({ 160 async updateMe({ request, response, auth }) {
166 request,
167 response,
168 auth,
169 }) {
170 let settings = auth.user.settings || {}; 161 let settings = auth.user.settings || {};
171 if (typeof settings === 'string') { 162 if (typeof settings === 'string') {
172 settings = JSON.parse(settings); 163 settings = JSON.parse(settings);
@@ -195,21 +186,15 @@ class UserController {
195 isSubscriptionOwner: true, 186 isSubscriptionOwner: true,
196 lastname: auth.user.lastname, 187 lastname: auth.user.lastname,
197 locale: 'en-US', 188 locale: 'en-US',
198 ...newSettings || {}, 189 ...(newSettings || {}),
199 }, 190 },
200 status: [ 191 status: ['data-updated'],
201 'data-updated',
202 ],
203 }); 192 });
204 } 193 }
205 194
206 195 async import({ request, response, view }) {
207 async import({ 196 if (Env.get('IS_REGISTRATION_ENABLED') == 'false') {
208 request, 197 // eslint-disable-line eqeqeq
209 response,
210 view,
211 }) {
212 if (Env.get('IS_REGISTRATION_ENABLED') == 'false') { // eslint-disable-line eqeqeq
213 return response.status(401).send({ 198 return response.status(401).send({
214 message: 'Registration is disabled on this server', 199 message: 'Registration is disabled on this server',
215 status: 401, 200 status: 401,
@@ -222,7 +207,8 @@ class UserController {
222 password: 'required', 207 password: 'required',
223 }); 208 });
224 if (validation.fails()) { 209 if (validation.fails()) {
225 let errorMessage = 'There was an error while trying to import your account:\n'; 210 let errorMessage =
211 'There was an error while trying to import your account:\n';
226 for (const message of validation.messages()) { 212 for (const message of validation.messages()) {
227 if (message.validation === 'required') { 213 if (message.validation === 'required') {
228 errorMessage += `- Please make sure to supply your ${message.field}\n`; 214 errorMessage += `- Please make sure to supply your ${message.field}\n`;
@@ -238,14 +224,15 @@ class UserController {
238 }); 224 });
239 } 225 }
240 226
241 const { 227 const { email, password } = request.all();
242 email,
243 password,
244 } = request.all();
245 228
246 const hashedPassword = crypto.createHash('sha256').update(password).digest('base64'); 229 const hashedPassword = crypto
230 .createHash('sha256')
231 .update(password)
232 .digest('base64');
247 233
248 if (Env.get('CONNECT_WITH_FRANZ') == 'false') { // eslint-disable-line eqeqeq 234 if (Env.get('CONNECT_WITH_FRANZ') == 'false') {
235 // eslint-disable-line eqeqeq
249 await User.create({ 236 await User.create({
250 email, 237 email,
251 password: hashedPassword, 238 password: hashedPassword,
@@ -253,11 +240,14 @@ class UserController {
253 lastname: 'Franz', 240 lastname: 'Franz',
254 }); 241 });
255 242
256 return response.send('Your account has been created but due to this server\'s configuration, we could not import your Franz account data.\n\nIf you are the server owner, please set CONNECT_WITH_FRANZ to true to enable account imports.'); 243 return response.send(
244 "Your account has been created but due to this server's configuration, we could not import your Franz account data.\n\nIf you are the server owner, please set CONNECT_WITH_FRANZ to true to enable account imports.",
245 );
257 } 246 }
258 247
259 const base = 'https://api.franzinfra.com/v1/'; 248 const base = 'https://api.franzinfra.com/v1/';
260 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'; 249 const userAgent =
250 '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';
261 251
262 // Try to get an authentication token 252 // Try to get an authentication token
263 let token; 253 let token;
@@ -281,7 +271,8 @@ class UserController {
281 const content = await rawResponse.json(); 271 const content = await rawResponse.json();
282 272
283 if (!content.message || content.message !== 'Successfully logged in') { 273 if (!content.message || content.message !== 'Successfully logged in') {
284 const errorMessage = 'Could not login into Franz with your supplied credentials. Please check and try again'; 274 const errorMessage =
275 'Could not login into Franz with your supplied credentials. Please check and try again';
285 return response.status(401).send(errorMessage); 276 return response.status(401).send(errorMessage);
286 } 277 }
287 278
@@ -302,7 +293,8 @@ class UserController {
302 return response.status(401).send(errorMessage); 293 return response.status(401).send(errorMessage);
303 } 294 }
304 if (!userInf) { 295 if (!userInf) {
305 const errorMessage = 'Could not get your user info from Franz. Please check your credentials or try again later'; 296 const errorMessage =
297 'Could not get your user info from Franz. Please check your credentials or try again later';
306 return response.status(401).send(errorMessage); 298 return response.status(401).send(errorMessage);
307 } 299 }
308 300
@@ -331,9 +323,13 @@ class UserController {
331 let serviceId; 323 let serviceId;
332 do { 324 do {
333 serviceId = uuid(); 325 serviceId = uuid();
334 } while ((await Service.query().where('serviceId', serviceId).fetch()).rows.length > 0); // eslint-disable-line no-await-in-loop 326 } while (
327 (await Service.query().where('serviceId', serviceId).fetch()).rows
328 .length > 0
329 ); // eslint-disable-line no-await-in-loop
335 330
336 await Service.create({ // eslint-disable-line no-await-in-loop 331 await Service.create({
332 // eslint-disable-line no-await-in-loop
337 userId: user.id, 333 userId: user.id,
338 serviceId, 334 serviceId,
339 name: service.name, 335 name: service.name,
@@ -356,11 +352,17 @@ class UserController {
356 let workspaceId; 352 let workspaceId;
357 do { 353 do {
358 workspaceId = uuid(); 354 workspaceId = uuid();
359 } while ((await Workspace.query().where('workspaceId', workspaceId).fetch()).rows.length > 0); // eslint-disable-line no-await-in-loop 355 } while (
356 (await Workspace.query().where('workspaceId', workspaceId).fetch())
357 .rows.length > 0
358 ); // eslint-disable-line no-await-in-loop
360 359
361 const services = workspace.services.map((service) => serviceIdTranslation[service]); 360 const services = workspace.services.map(
361 service => serviceIdTranslation[service],
362 );
362 363
363 await Workspace.create({ // eslint-disable-line no-await-in-loop 364 await Workspace.create({
365 // eslint-disable-line no-await-in-loop
364 userId: user.id, 366 userId: user.id,
365 workspaceId, 367 workspaceId,
366 name: workspace.name, 368 name: workspace.name,
@@ -374,7 +376,9 @@ class UserController {
374 return response.status(401).send(errorMessage); 376 return response.status(401).send(errorMessage);
375 } 377 }
376 378
377 return response.send('Your account has been imported. You can now use your Franz account in Ferdi.'); 379 return response.send(
380 'Your account has been imported. You can now use your Franz account in Ferdi.',
381 );
378 } 382 }
379} 383}
380 384