aboutsummaryrefslogtreecommitdiffstats
path: root/app/Controllers/Http/UserController.js
diff options
context:
space:
mode:
authorLibravatar vantezzen <properly@protonmail.com>2019-09-05 11:22:49 +0200
committerLibravatar vantezzen <properly@protonmail.com>2019-09-05 11:22:49 +0200
commit29b8334b060dc0c05a509d523ead4b3a30229fef (patch)
tree4dbfcfb90a3eff31acd219b27557bbdc594f589f /app/Controllers/Http/UserController.js
parentAdd cookie notice to login page (diff)
downloadferdium-server-29b8334b060dc0c05a509d523ead4b3a30229fef.tar.gz
ferdium-server-29b8334b060dc0c05a509d523ead4b3a30229fef.tar.zst
ferdium-server-29b8334b060dc0c05a509d523ead4b3a30229fef.zip
Add eslint
Diffstat (limited to 'app/Controllers/Http/UserController.js')
-rw-r--r--app/Controllers/Http/UserController.js213
1 files changed, 101 insertions, 112 deletions
diff --git a/app/Controllers/Http/UserController.js b/app/Controllers/Http/UserController.js
index ced27bb..1e67092 100644
--- a/app/Controllers/Http/UserController.js
+++ b/app/Controllers/Http/UserController.js
@@ -1,12 +1,10 @@
1'use strict'
2
3const User = use('App/Models/User'); 1const User = use('App/Models/User');
4const Service = use('App/Models/Service'); 2const Service = use('App/Models/Service');
5const Workspace = use('App/Models/Workspace'); 3const Workspace = use('App/Models/Workspace');
6const { 4const {
7 validateAll 5 validateAll,
8} = use('Validator'); 6} = use('Validator');
9const Env = use('Env') 7const Env = use('Env');
10 8
11const atob = require('atob'); 9const atob = require('atob');
12const btoa = require('btoa'); 10const btoa = require('btoa');
@@ -14,49 +12,44 @@ const fetch = require('node-fetch');
14const uuid = require('uuid/v4'); 12const uuid = require('uuid/v4');
15const crypto = require('crypto'); 13const crypto = require('crypto');
16 14
17const franzRequest = async (route, method, auth) => { 15const franzRequest = (route, method, auth) => new Promise((resolve, reject) => {
18 return new Promise(async (resolve, reject) => { 16 const base = 'https://api.franzinfra.com/v1/';
19 const base = 'https://api.franzinfra.com/v1/'; 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';
20 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'; 18
21 19 try {
22 try { 20 fetch(base + route, {
23 const rawResponse = await fetch(base + route, { 21 method,
24 method, 22 headers: {
25 headers: { 23 Authorization: `Bearer ${auth}`,
26 'Authorization': 'Bearer ' + auth, 24 'User-Agent': user,
27 'User-Agent': user 25 },
28 }, 26 })
29 }); 27 .then((data) => data.json())
30 const content = await rawResponse.json(); 28 .then((json) => resolve(json));
31 29 } catch (e) {
32 resolve(content); 30 reject();
33 } catch (e) { 31 }
34 reject(); 32});
35 }
36 })
37}
38 33
39class UserController { 34class UserController {
40
41 // Register a new user 35 // Register a new user
42 async signup({ 36 async signup({
43 request, 37 request,
44 response, 38 response,
45 auth, 39 auth,
46 session
47 }) { 40 }) {
48 // Validate user input 41 // Validate user input
49 const validation = await validateAll(request.all(), { 42 const validation = await validateAll(request.all(), {
50 firstname: 'required', 43 firstname: 'required',
51 email: 'required|email|unique:users,email', 44 email: 'required|email|unique:users,email',
52 password: 'required' 45 password: 'required',
53 }); 46 });
54 if (validation.fails()) { 47 if (validation.fails()) {
55 return response.status(401).send({ 48 return response.status(401).send({
56 "message": "Invalid POST arguments", 49 message: 'Invalid POST arguments',
57 "messages": validation.messages(), 50 messages: validation.messages(),
58 "status": 401 51 status: 401,
59 }) 52 });
60 } 53 }
61 54
62 const data = request.only(['firstname', 'email', 'password']); 55 const data = request.only(['firstname', 'email', 'password']);
@@ -67,21 +60,21 @@ class UserController {
67 user = await User.create({ 60 user = await User.create({
68 email: data.email, 61 email: data.email,
69 password: data.password, 62 password: data.password,
70 username: data.firstname 63 username: data.firstname,
71 }); 64 });
72 } catch (e) { 65 } catch (e) {
73 return response.status(401).send({ 66 return response.status(401).send({
74 "message": "E-Mail Address already in use", 67 message: 'E-Mail Address already in use',
75 "status": 401 68 status: 401,
76 }) 69 });
77 } 70 }
78 71
79 // Generate new auth token 72 // Generate new auth token
80 const token = await auth.generate(user) 73 const token = await auth.generate(user);
81 74
82 return response.send({ 75 return response.send({
83 "message": "Successfully created account", 76 message: 'Successfully created account',
84 "token": token.token 77 token: token.token,
85 }); 78 });
86 } 79 }
87 80
@@ -89,115 +82,112 @@ class UserController {
89 async login({ 82 async login({
90 request, 83 request,
91 response, 84 response,
92 auth 85 auth,
93 }) { 86 }) {
94 if (!request.header('Authorization')) { 87 if (!request.header('Authorization')) {
95 return response.status(401).send({ 88 return response.status(401).send({
96 "message": "Please provide authorization", 89 message: 'Please provide authorization',
97 "status": 401 90 status: 401,
98 }) 91 });
99 } 92 }
100 93
101 // Get auth data from auth token 94 // Get auth data from auth token
102 const authHeader = atob(request.header('Authorization').replace('Basic ', '')).split(':'); 95 const authHeader = atob(request.header('Authorization').replace('Basic ', '')).split(':');
103 96
104 // Check if user with email exists 97 // Check if user with email exists
105 let user = (await User.query().where('email', authHeader[0]).first()); 98 const user = (await User.query().where('email', authHeader[0]).first());
106 if (!user || !user.email) { 99 if (!user || !user.email) {
107 return response.status(401).send({ 100 return response.status(401).send({
108 "message": "User credentials not valid (Invalid mail)", 101 message: 'User credentials not valid (Invalid mail)',
109 "code": "invalid-credentials", 102 code: 'invalid-credentials',
110 "status": 401 103 status: 401,
111 }); 104 });
112 } 105 }
113 106
114 // Try to login 107 // Try to login
115 let token; 108 let token;
116 try { 109 try {
117 token = await auth.attempt(user.email, authHeader[1]) 110 token = await auth.attempt(user.email, authHeader[1]);
118 } catch (e) { 111 } catch (e) {
119 return response.status(401).send({ 112 return response.status(401).send({
120 "message": "User credentials not valid", 113 message: 'User credentials not valid',
121 "code": "invalid-credentials", 114 code: 'invalid-credentials',
122 "status": 401 115 status: 401,
123 }); 116 });
124 } 117 }
125 118
126 return response.send({ 119 return response.send({
127 "message": "Successfully logged in", 120 message: 'Successfully logged in',
128 "token": token.token 121 token: token.token,
129 }); 122 });
130 } 123 }
131 124
132 // Return information about the current user 125 // Return information about the current user
133 async me({ 126 async me({
134 request,
135 response, 127 response,
136 auth, 128 auth,
137 session
138 }) { 129 }) {
139 try { 130 try {
140 await auth.getUser() 131 await auth.getUser();
141 } catch (error) { 132 } catch (error) {
142 response.send('Missing or invalid api token') 133 response.send('Missing or invalid api token');
143 } 134 }
144 135
145 return response.send({ 136 return response.send({
146 accountType: "individual", 137 accountType: 'individual',
147 beta: false, 138 beta: false,
148 donor: {}, 139 donor: {},
149 email: auth.user.email, 140 email: auth.user.email,
150 emailValidated: true, 141 emailValidated: true,
151 features: {}, 142 features: {},
152 firstname: "Franz", 143 firstname: 'Franz',
153 id: "82c1cf9d-ab58-4da2-b55e-aaa41d2142d8", 144 id: '82c1cf9d-ab58-4da2-b55e-aaa41d2142d8',
154 isPremium: true, 145 isPremium: true,
155 isSubscriptionOwner: true, 146 isSubscriptionOwner: true,
156 lastname: "Franz", 147 lastname: 'Franz',
157 locale: "en-US" 148 locale: 'en-US',
158 }); 149 });
159 } 150 }
160 151
161 152
162
163 async import({ 153 async import({
164 request, 154 request,
165 response 155 response,
166 }) { 156 }) {
167 // Validate user input 157 // Validate user input
168 const validation = await validateAll(request.all(), { 158 const validation = await validateAll(request.all(), {
169 email: 'required|email|unique:users,email', 159 email: 'required|email|unique:users,email',
170 password: 'required' 160 password: 'required',
171 }); 161 });
172 if (validation.fails()) { 162 if (validation.fails()) {
173 let errorMessage = "There was an error while trying to import your account:\n"; 163 let errorMessage = 'There was an error while trying to import your account:\n';
174 for (const message of validation.messages()) { 164 for (const message of validation.messages()) {
175 if (message.validation == 'required') { 165 if (message.validation === 'required') {
176 errorMessage += '- Please make sure to supply your ' + message.field + '\n' 166 errorMessage += `- Please make sure to supply your ${message.field}\n`;
177 } else if (message.validation == 'unique') { 167 } else if (message.validation === 'unique') {
178 errorMessage += '- There is already a user with this email.\n' 168 errorMessage += '- There is already a user with this email.\n';
179 } else { 169 } else {
180 errorMessage += message.message + '\n'; 170 errorMessage += `${message.message}\n`;
181 } 171 }
182 } 172 }
183 return response.status(401).send(errorMessage) 173 return response.status(401).send(errorMessage);
184 } 174 }
185 175
186 const { 176 const {
187 email, 177 email,
188 password 178 password,
189 } = request.all() 179 } = request.all();
190 180
191 const hashedPassword = crypto.createHash('sha256').update(password).digest('base64'); 181 const hashedPassword = crypto.createHash('sha256').update(password).digest('base64');
192 182
193 if(Env.get('CONNECT_WITH_FRANZ') == 'false') { 183 if (Env.get('CONNECT_WITH_FRANZ') == 'false') { // eslint-disable-line eqeqeq
194 await User.create({ 184 await User.create({
195 email, 185 email,
196 password: hashedPassword, 186 password: hashedPassword,
197 username: 'Franz' 187 username: 'Franz',
198 }); 188 });
199 189
200 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.') 190 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.');
201 } 191 }
202 192
203 const base = 'https://api.franzinfra.com/v1/'; 193 const base = 'https://api.franzinfra.com/v1/';
@@ -206,42 +196,41 @@ class UserController {
206 // Try to get an authentication token 196 // Try to get an authentication token
207 let token; 197 let token;
208 try { 198 try {
209 const basicToken = btoa(email + ':' + hashedPassword) 199 const basicToken = btoa(`${email}:${hashedPassword}`);
210 200
211 const rawResponse = await fetch(base + 'auth/login', { 201 const rawResponse = await fetch(`${base}auth/login`, {
212 method: 'POST', 202 method: 'POST',
213 headers: { 203 headers: {
214 'Authorization': 'Basic ' + basicToken, 204 Authorization: `Basic ${basicToken}`,
215 'User-Agent': userAgent 205 'User-Agent': userAgent,
216 }, 206 },
217 }); 207 });
218 const content = await rawResponse.json(); 208 const content = await rawResponse.json();
219 209
220 if (!content.message || content.message !== 'Successfully logged in') { 210 if (!content.message || content.message !== 'Successfully logged in') {
221 const errorMessage = 'Could not login into Franz with your supplied credentials. Please check and try again'; 211 const errorMessage = 'Could not login into Franz with your supplied credentials. Please check and try again';
222 return response.status(401).send(errorMessage) 212 return response.status(401).send(errorMessage);
223 } 213 }
224 214
225 token = content.token; 215 token = content.token;
226 } catch (e) { 216 } catch (e) {
227 return response.status(401).send({ 217 return response.status(401).send({
228 "message": "Cannot login to Franz", 218 message: 'Cannot login to Franz',
229 "error": e 219 error: e,
230 }) 220 });
231 } 221 }
232 222
233 // Get user information 223 // Get user information
234 let userInf = false; 224 let userInf = false;
235 try { 225 try {
236 userInf = await franzRequest('me', 'GET', token) 226 userInf = await franzRequest('me', 'GET', token);
237 console.log('A', userInf)
238 } catch (e) { 227 } catch (e) {
239 const errorMessage = 'Could not get your user info from Franz. Please check your credentials or try again later.\nError: ' + e; 228 const errorMessage = `Could not get your user info from Franz. Please check your credentials or try again later.\nError: ${e}`;
240 return response.status(401).send(errorMessage) 229 return response.status(401).send(errorMessage);
241 } 230 }
242 if (!userInf) { 231 if (!userInf) {
243 const errorMessage = 'Could not get your user info from Franz. Please check your credentials or try again later.\nError: ' + e; 232 const errorMessage = 'Could not get your user info from Franz. Please check your credentials or try again later';
244 return response.status(401).send(errorMessage) 233 return response.status(401).send(errorMessage);
245 } 234 }
246 235
247 // Create user in DB 236 // Create user in DB
@@ -250,69 +239,69 @@ class UserController {
250 user = await User.create({ 239 user = await User.create({
251 email: userInf.email, 240 email: userInf.email,
252 password: hashedPassword, 241 password: hashedPassword,
253 username: userInf.firstname 242 username: userInf.firstname,
254 }); 243 });
255 } catch (e) { 244 } catch (e) {
256 const errorMessage = 'Could not create your user in our system.\nError: ' + e; 245 const errorMessage = `Could not create your user in our system.\nError: ${e}`;
257 return response.status(401).send(errorMessage) 246 return response.status(401).send(errorMessage);
258 } 247 }
259 248
260 let serviceIdTranslation = {}; 249 const serviceIdTranslation = {};
261 250
262 // Import services 251 // Import services
263 try { 252 try {
264 const services = await franzRequest('me/services', 'GET', token) 253 const services = await franzRequest('me/services', 'GET', token);
265 254
266 for (const service of services) { 255 for (const service of services) {
267 // Get new, unused uuid 256 // Get new, unused uuid
268 let serviceId; 257 let serviceId;
269 do { 258 do {
270 serviceId = uuid(); 259 serviceId = uuid();
271 } while ((await Service.query().where('serviceId', serviceId).fetch()).rows.length > 0) 260 } while ((await Service.query().where('serviceId', serviceId).fetch()).rows.length > 0); // eslint-disable-line no-await-in-loop
272 261
273 await Service.create({ 262 await Service.create({ // eslint-disable-line no-await-in-loop
274 userId: user.id, 263 userId: user.id,
275 serviceId, 264 serviceId,
276 name: service.name, 265 name: service.name,
277 recipeId: service.recipeId, 266 recipeId: service.recipeId,
278 settings: JSON.stringify(service) 267 settings: JSON.stringify(service),
279 }); 268 });
280 269
281 serviceIdTranslation[service.id] = serviceId; 270 serviceIdTranslation[service.id] = serviceId;
282 } 271 }
283 } catch (e) { 272 } catch (e) {
284 const errorMessage = 'Could not import your services into our system.\nError: ' + e; 273 const errorMessage = `Could not import your services into our system.\nError: ${e}`;
285 return response.status(401).send(errorMessage) 274 return response.status(401).send(errorMessage);
286 } 275 }
287 276
288 // Import workspaces 277 // Import workspaces
289 try { 278 try {
290 const workspaces = await franzRequest('workspace', 'GET', token) 279 const workspaces = await franzRequest('workspace', 'GET', token);
291 280
292 for (const workspace of workspaces) { 281 for (const workspace of workspaces) {
293 let workspaceId; 282 let workspaceId;
294 do { 283 do {
295 workspaceId = uuid(); 284 workspaceId = uuid();
296 } while ((await Workspace.query().where('workspaceId', workspaceId).fetch()).rows.length > 0) 285 } while ((await Workspace.query().where('workspaceId', workspaceId).fetch()).rows.length > 0); // eslint-disable-line no-await-in-loop
297 286
298 const services = workspace.services.map(service => serviceIdTranslation[service]) 287 const services = workspace.services.map((service) => serviceIdTranslation[service]);
299 288
300 await Workspace.create({ 289 await Workspace.create({ // eslint-disable-line no-await-in-loop
301 userId: auth.user.id, 290 userId: user.id,
302 workspaceId, 291 workspaceId,
303 name: workspace.name, 292 name: workspace.name,
304 order: workspace.order, 293 order: workspace.order,
305 services: JSON.stringify(services), 294 services: JSON.stringify(services),
306 data: JSON.stringify({}) 295 data: JSON.stringify({}),
307 }); 296 });
308 } 297 }
309 } catch (e) { 298 } catch (e) {
310 const errorMessage = 'Could not import your workspaces into our system.\nError: ' + e; 299 const errorMessage = `Could not import your workspaces into our system.\nError: ${e}`;
311 return response.status(401).send(errorMessage) 300 return response.status(401).send(errorMessage);
312 } 301 }
313 302
314 return response.send('Your account has been imported. You can now use your Franz account in Ferdi.') 303 return response.send('Your account has been imported. You can now use your Franz account in Ferdi.');
315 } 304 }
316} 305}
317 306
318module.exports = UserController 307module.exports = UserController;