aboutsummaryrefslogtreecommitdiffstats
path: root/src/server/app/Controllers/Http/UserController.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/app/Controllers/Http/UserController.js')
-rw-r--r--src/server/app/Controllers/Http/UserController.js228
1 files changed, 0 insertions, 228 deletions
diff --git a/src/server/app/Controllers/Http/UserController.js b/src/server/app/Controllers/Http/UserController.js
deleted file mode 100644
index 07e118afd..000000000
--- a/src/server/app/Controllers/Http/UserController.js
+++ /dev/null
@@ -1,228 +0,0 @@
1const Service = use('App/Models/Service');
2const Workspace = use('App/Models/Workspace');
3const {
4 validateAll,
5} = use('Validator');
6
7const btoa = require('btoa');
8const fetch = require('node-fetch');
9const uuid = require('uuid/v4');
10const crypto = require('crypto');
11
12const apiRequest = (url, route, method, auth) => new Promise((resolve, reject) => {
13 const base = `${url}/v1/`;
14 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
16 try {
17 fetch(base + route, {
18 method,
19 headers: {
20 Authorization: `Bearer ${auth}`,
21 'User-Agent': user,
22 },
23 })
24 .then(data => data.json())
25 .then(json => resolve(json));
26 } catch (e) {
27 reject();
28 }
29});
30
31class UserController {
32 // Register a new user
33 async signup({
34 request,
35 response,
36 }) {
37 // Validate user input
38 const validation = await validateAll(request.all(), {
39 firstname: 'required',
40 email: 'required|email',
41 password: 'required',
42 });
43 if (validation.fails()) {
44 return response.status(401).send({
45 message: 'Invalid POST arguments',
46 messages: validation.messages(),
47 status: 401,
48 });
49 }
50
51 return response.send({
52 message: 'Successfully created account',
53 token: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJGZXJkaSBJbnRlcm5hbCBTZXJ2ZXIiLCJpYXQiOjE1NzEwNDAyMTUsImV4cCI6MjUzMzk1NDE3ODQ0LCJhdWQiOiJnZXRmZXJkaS5jb20iLCJzdWIiOiJmZXJkaUBsb2NhbGhvc3QiLCJ1c2VySWQiOiIxIn0.9_TWFGp6HROv8Yg82Rt6i1-95jqWym40a-HmgrdMC6M',
54 });
55 }
56
57 // Login using an existing user
58 async login({
59 request,
60 response,
61 }) {
62 if (!request.header('Authorization')) {
63 return response.status(401).send({
64 message: 'Please provide authorization',
65 status: 401,
66 });
67 }
68
69 return response.send({
70 message: 'Successfully logged in',
71 token: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJGZXJkaSBJbnRlcm5hbCBTZXJ2ZXIiLCJpYXQiOjE1NzEwNDAyMTUsImV4cCI6MjUzMzk1NDE3ODQ0LCJhdWQiOiJnZXRmZXJkaS5jb20iLCJzdWIiOiJmZXJkaUBsb2NhbGhvc3QiLCJ1c2VySWQiOiIxIn0.9_TWFGp6HROv8Yg82Rt6i1-95jqWym40a-HmgrdMC6M',
72 });
73 }
74
75 // Return information about the current user
76 async me({
77 response,
78 }) {
79 return response.send({
80 accountType: 'individual',
81 beta: false,
82 donor: {},
83 email: '',
84 emailValidated: true,
85 features: {},
86 firstname: 'Ferdi',
87 id: '82c1cf9d-ab58-4da2-b55e-aaa41d2142d8',
88 isPremium: true,
89 isSubscriptionOwner: true,
90 lastname: 'Application',
91 locale: 'en-US',
92 });
93 }
94
95
96 async import({
97 request,
98 response,
99 }) {
100 // Validate user input
101 const validation = await validateAll(request.all(), {
102 email: 'required|email',
103 password: 'required',
104 server: 'required',
105 });
106 if (validation.fails()) {
107 let errorMessage = 'There was an error while trying to import your account:\n';
108 for (const message of validation.messages()) {
109 if (message.validation === 'required') {
110 errorMessage += `- Please make sure to supply your ${message.field}\n`;
111 } else if (message.validation === 'unique') {
112 errorMessage += '- There is already a user with this email.\n';
113 } else {
114 errorMessage += `${message.message}\n`;
115 }
116 }
117 return response.status(401).send(errorMessage);
118 }
119
120 const {
121 email,
122 password,
123 server,
124 } = request.all();
125
126 const hashedPassword = crypto.createHash('sha256').update(password).digest('base64');
127
128 const base = `${server}/v1/`;
129 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';
130
131 // Try to get an authentication token
132 let token;
133 try {
134 const basicToken = btoa(`${email}:${hashedPassword}`);
135
136 const rawResponse = await fetch(`${base}auth/login`, {
137 method: 'POST',
138 headers: {
139 Authorization: `Basic ${basicToken}`,
140 'User-Agent': userAgent,
141 },
142 });
143 const content = await rawResponse.json();
144
145 if (!content.message || content.message !== 'Successfully logged in') {
146 const errorMessage = 'Could not login into Franz with your supplied credentials. Please check and try again';
147 return response.status(401).send(errorMessage);
148 }
149
150 // eslint-disable-next-line prefer-destructuring
151 token = content.token;
152 } catch (e) {
153 return response.status(401).send({
154 message: 'Cannot login to Franz',
155 error: e,
156 });
157 }
158
159 // Get user information
160 let userInf = false;
161 try {
162 userInf = await apiRequest(server, 'me', 'GET', token);
163 } catch (e) {
164 const errorMessage = `Could not get your user info from Franz. Please check your credentials or try again later.\nError: ${e}`;
165 return response.status(401).send(errorMessage);
166 }
167 if (!userInf) {
168 const errorMessage = 'Could not get your user info from Franz. Please check your credentials or try again later';
169 return response.status(401).send(errorMessage);
170 }
171
172 const serviceIdTranslation = {};
173
174 // Import services
175 try {
176 const services = await apiRequest(server, 'me/services', 'GET', token);
177
178 for (const service of services) {
179 // Get new, unused uuid
180 let serviceId;
181 do {
182 serviceId = uuid();
183 } while ((await Service.query().where('serviceId', serviceId).fetch()).rows.length > 0); // eslint-disable-line no-await-in-loop
184
185 await Service.create({ // eslint-disable-line no-await-in-loop
186 serviceId,
187 name: service.name,
188 recipeId: service.recipeId,
189 settings: JSON.stringify(service),
190 });
191
192 serviceIdTranslation[service.id] = serviceId;
193 }
194 } catch (e) {
195 const errorMessage = `Could not import your services into our system.\nError: ${e}`;
196 return response.status(401).send(errorMessage);
197 }
198
199 // Import workspaces
200 try {
201 const workspaces = await apiRequest(server, 'workspace', 'GET', token);
202
203 for (const workspace of workspaces) {
204 let workspaceId;
205 do {
206 workspaceId = uuid();
207 } while ((await Workspace.query().where('workspaceId', workspaceId).fetch()).rows.length > 0); // eslint-disable-line no-await-in-loop
208
209 const services = workspace.services.map(service => serviceIdTranslation[service]);
210
211 await Workspace.create({ // eslint-disable-line no-await-in-loop
212 workspaceId,
213 name: workspace.name,
214 order: workspace.order,
215 services: JSON.stringify(services),
216 data: JSON.stringify({}),
217 });
218 }
219 } catch (e) {
220 const errorMessage = `Could not import your workspaces into our system.\nError: ${e}`;
221 return response.status(401).send(errorMessage);
222 }
223
224 return response.send('Your account has been imported. You can now use your Franz account in Ferdi.');
225 }
226}
227
228module.exports = UserController;