aboutsummaryrefslogtreecommitdiffstats
path: root/app/Controllers/Http/Dashboard
diff options
context:
space:
mode:
Diffstat (limited to 'app/Controllers/Http/Dashboard')
-rw-r--r--app/Controllers/Http/Dashboard/AccountController.ts30
-rw-r--r--app/Controllers/Http/Dashboard/DataController.ts10
-rw-r--r--app/Controllers/Http/Dashboard/DeleteController.ts10
-rw-r--r--app/Controllers/Http/Dashboard/ExportController.ts27
-rw-r--r--app/Controllers/Http/Dashboard/ForgotPasswordController.ts18
-rw-r--r--app/Controllers/Http/Dashboard/LogOutController.ts6
-rw-r--r--app/Controllers/Http/Dashboard/LoginController.ts49
-rw-r--r--app/Controllers/Http/Dashboard/ResetPasswordController.ts49
-rw-r--r--app/Controllers/Http/Dashboard/TransferController.ts67
9 files changed, 142 insertions, 124 deletions
diff --git a/app/Controllers/Http/Dashboard/AccountController.ts b/app/Controllers/Http/Dashboard/AccountController.ts
index 5870f19..a748c75 100644
--- a/app/Controllers/Http/Dashboard/AccountController.ts
+++ b/app/Controllers/Http/Dashboard/AccountController.ts
@@ -1,6 +1,6 @@
1import type { HttpContext } from '@adonisjs/core/http' 1import type { HttpContext } from '@adonisjs/core/http';
2import { schema, rules, validator } from '@adonisjs/validator' 2import { schema, rules, validator } from '@adonisjs/validator';
3import crypto from 'node:crypto' 3import crypto from 'node:crypto';
4 4
5export default class AccountController { 5export default class AccountController {
6 /** 6 /**
@@ -11,7 +11,7 @@ export default class AccountController {
11 username: auth.user?.username, 11 username: auth.user?.username,
12 email: auth.user?.email, 12 email: auth.user?.email,
13 lastname: auth.user?.lastname, 13 lastname: auth.user?.lastname,
14 }) 14 });
15 } 15 }
16 16
17 /** 17 /**
@@ -42,26 +42,26 @@ export default class AccountController {
42 lastname: schema.string([rules.required()]), 42 lastname: schema.string([rules.required()]),
43 }), 43 }),
44 data: request.only(['username', 'email', 'lastname']), 44 data: request.only(['username', 'email', 'lastname']),
45 }) 45 });
46 } catch (error) { 46 } catch (error) {
47 session.flash(error.messages) 47 session.flash(error.messages);
48 return response.redirect('/user/account') 48 return response.redirect('/user/account');
49 } 49 }
50 50
51 // Update user account 51 // Update user account
52 const { user } = auth 52 const { user } = auth;
53 if (user) { 53 if (user) {
54 user.username = request.input('username') 54 user.username = request.input('username');
55 user.lastname = request.input('lastname') 55 user.lastname = request.input('lastname');
56 user.email = request.input('email') 56 user.email = request.input('email');
57 if (request.input('password')) { 57 if (request.input('password')) {
58 const hashedPassword = crypto 58 const hashedPassword = crypto
59 .createHash('sha256') 59 .createHash('sha256')
60 .update(request.input('password')) 60 .update(request.input('password'))
61 .digest('base64') 61 .digest('base64');
62 user.password = hashedPassword 62 user.password = hashedPassword;
63 } 63 }
64 await user.save() 64 await user.save();
65 } 65 }
66 66
67 return view.render('dashboard/account', { 67 return view.render('dashboard/account', {
@@ -69,6 +69,6 @@ export default class AccountController {
69 lastname: user?.lastname, 69 lastname: user?.lastname,
70 email: user?.email, 70 email: user?.email,
71 success: user !== undefined, 71 success: user !== undefined,
72 }) 72 });
73 } 73 }
74} 74}
diff --git a/app/Controllers/Http/Dashboard/DataController.ts b/app/Controllers/Http/Dashboard/DataController.ts
index 8a77329..5f22979 100644
--- a/app/Controllers/Http/Dashboard/DataController.ts
+++ b/app/Controllers/Http/Dashboard/DataController.ts
@@ -1,14 +1,14 @@
1import type { HttpContext } from '@adonisjs/core/http' 1import type { HttpContext } from '@adonisjs/core/http';
2 2
3export default class DataController { 3export default class DataController {
4 /** 4 /**
5 * Display the data page 5 * Display the data page
6 */ 6 */
7 public async show({ view, auth }: HttpContext) { 7 public async show({ view, auth }: HttpContext) {
8 const { user } = auth 8 const { user } = auth;
9 9
10 const services = await user?.related('services').query() 10 const services = await user?.related('services').query();
11 const workspaces = await user?.related('workspaces').query() 11 const workspaces = await user?.related('workspaces').query();
12 12
13 return view.render('dashboard/data', { 13 return view.render('dashboard/data', {
14 username: user?.username, 14 username: user?.username,
@@ -19,6 +19,6 @@ export default class DataController {
19 stringify: JSON.stringify, 19 stringify: JSON.stringify,
20 services, 20 services,
21 workspaces, 21 workspaces,
22 }) 22 });
23 } 23 }
24} 24}
diff --git a/app/Controllers/Http/Dashboard/DeleteController.ts b/app/Controllers/Http/Dashboard/DeleteController.ts
index bd824b0..76e41ca 100644
--- a/app/Controllers/Http/Dashboard/DeleteController.ts
+++ b/app/Controllers/Http/Dashboard/DeleteController.ts
@@ -1,20 +1,20 @@
1import type { HttpContext } from '@adonisjs/core/http' 1import type { HttpContext } from '@adonisjs/core/http';
2 2
3export default class DeleteController { 3export default class DeleteController {
4 /** 4 /**
5 * Display the delete page 5 * Display the delete page
6 */ 6 */
7 public async show({ view }: HttpContext) { 7 public async show({ view }: HttpContext) {
8 return view.render('dashboard/delete') 8 return view.render('dashboard/delete');
9 } 9 }
10 10
11 /** 11 /**
12 * Delete user and session 12 * Delete user and session
13 */ 13 */
14 public async delete({ auth, response }: HttpContext) { 14 public async delete({ auth, response }: HttpContext) {
15 auth.user?.delete() 15 auth.user?.delete();
16 auth.use('web').logout() 16 auth.use('web').logout();
17 17
18 return response.redirect('/user/login') 18 return response.redirect('/user/login');
19 } 19 }
20} 20}
diff --git a/app/Controllers/Http/Dashboard/ExportController.ts b/app/Controllers/Http/Dashboard/ExportController.ts
index 5b6df70..6b20a82 100644
--- a/app/Controllers/Http/Dashboard/ExportController.ts
+++ b/app/Controllers/Http/Dashboard/ExportController.ts
@@ -1,30 +1,33 @@
1import type { HttpContext } from '@adonisjs/core/http' 1import type { HttpContext } from '@adonisjs/core/http';
2 2
3// eslint-disable-next-line @typescript-eslint/no-explicit-any 3// eslint-disable-next-line @typescript-eslint/no-explicit-any
4function deepParseToJSON(obj: any): Record<string, unknown> { 4function deepParseToJSON(obj: any): Record<string, unknown> {
5 if (typeof obj !== 'object' || obj === null) { 5 if (typeof obj !== 'object' || obj === null) {
6 try { 6 try {
7 // Try to parse the object as JSON 7 // Try to parse the object as JSON
8 return JSON.parse(obj) as Record<string, unknown> 8 return JSON.parse(obj) as Record<string, unknown>;
9 } catch { 9 } catch {
10 // If parsing fails, return the original value 10 // If parsing fails, return the original value
11 return obj 11 return obj;
12 } 12 }
13 } 13 }
14 14
15 // If obj is an object, recursively parse its keys 15 // If obj is an object, recursively parse its keys
16 if (Array.isArray(obj)) { 16 if (Array.isArray(obj)) {
17 // If obj is an array, recursively parse each element 17 // If obj is an array, recursively parse each element
18 return obj.map((item) => deepParseToJSON(item)) as unknown as Record<string, unknown> 18 return obj.map(item => deepParseToJSON(item)) as unknown as Record<
19 string,
20 unknown
21 >;
19 } else { 22 } else {
20 // If obj is an object, recursively parse its keys 23 // If obj is an object, recursively parse its keys
21 const parsedObj: Record<string, unknown> = {} 24 const parsedObj: Record<string, unknown> = {};
22 for (const key in obj) { 25 for (const key in obj) {
23 if (obj.hasOwnProperty(key)) { 26 if (obj.hasOwnProperty(key)) {
24 parsedObj[key] = deepParseToJSON(obj[key]) 27 parsedObj[key] = deepParseToJSON(obj[key]);
25 } 28 }
26 } 29 }
27 return parsedObj 30 return parsedObj;
28 } 31 }
29} 32}
30 33
@@ -33,9 +36,9 @@ export default class ExportController {
33 * Display the export page 36 * Display the export page
34 */ 37 */
35 public async show({ auth, response }: HttpContext) { 38 public async show({ auth, response }: HttpContext) {
36 const user = auth.user! 39 const user = auth.user!;
37 const services = await user.related('services').query() 40 const services = await user.related('services').query();
38 const workspaces = await user.related('workspaces').query() 41 const workspaces = await user.related('workspaces').query();
39 42
40 const exportData = { 43 const exportData = {
41 username: user.username, 44 username: user.username,
@@ -43,11 +46,11 @@ export default class ExportController {
43 mail: user.email, 46 mail: user.email,
44 services: deepParseToJSON(JSON.parse(JSON.stringify(services))), 47 services: deepParseToJSON(JSON.parse(JSON.stringify(services))),
45 workspaces: deepParseToJSON(JSON.parse(JSON.stringify(workspaces))), 48 workspaces: deepParseToJSON(JSON.parse(JSON.stringify(workspaces))),
46 } 49 };
47 50
48 return response 51 return response
49 .header('Content-Type', 'application/force-download') 52 .header('Content-Type', 'application/force-download')
50 .header('Content-disposition', 'attachment; filename=export.ferdium-data') 53 .header('Content-disposition', 'attachment; filename=export.ferdium-data')
51 .send(exportData) 54 .send(exportData);
52 } 55 }
53} 56}
diff --git a/app/Controllers/Http/Dashboard/ForgotPasswordController.ts b/app/Controllers/Http/Dashboard/ForgotPasswordController.ts
index f7b1d0e..1878c4d 100644
--- a/app/Controllers/Http/Dashboard/ForgotPasswordController.ts
+++ b/app/Controllers/Http/Dashboard/ForgotPasswordController.ts
@@ -1,13 +1,13 @@
1import type { HttpContext } from '@adonisjs/core/http' 1import type { HttpContext } from '@adonisjs/core/http';
2import { schema, rules, validator } from '@adonisjs/validator' 2import { schema, rules, validator } from '@adonisjs/validator';
3import User from '#app/Models/User' 3import User from '#app/Models/User';
4 4
5export default class ForgotPasswordController { 5export default class ForgotPasswordController {
6 /** 6 /**
7 * Display the forgot password form 7 * Display the forgot password form
8 */ 8 */
9 public async show({ view }: HttpContext) { 9 public async show({ view }: HttpContext) {
10 return view.render('dashboard/forgotPassword') 10 return view.render('dashboard/forgotPassword');
11 } 11 }
12 12
13 /** 13 /**
@@ -20,22 +20,22 @@ export default class ForgotPasswordController {
20 mail: schema.string([rules.email(), rules.required()]), 20 mail: schema.string([rules.email(), rules.required()]),
21 }), 21 }),
22 data: request.only(['mail']), 22 data: request.only(['mail']),
23 }) 23 });
24 } catch { 24 } catch {
25 return view.render('others/message', { 25 return view.render('others/message', {
26 heading: 'Cannot reset your password', 26 heading: 'Cannot reset your password',
27 text: 'Please enter a valid email address', 27 text: 'Please enter a valid email address',
28 }) 28 });
29 } 29 }
30 30
31 try { 31 try {
32 const user = await User.findByOrFail('email', request.input('mail')) 32 const user = await User.findByOrFail('email', request.input('mail'));
33 await user.forgotPassword() 33 await user.forgotPassword();
34 } catch {} 34 } catch {}
35 35
36 return view.render('others/message', { 36 return view.render('others/message', {
37 heading: 'Reset password', 37 heading: 'Reset password',
38 text: 'If your provided E-Mail address is linked to an account, we have just sent an E-Mail to that address.', 38 text: 'If your provided E-Mail address is linked to an account, we have just sent an E-Mail to that address.',
39 }) 39 });
40 } 40 }
41} 41}
diff --git a/app/Controllers/Http/Dashboard/LogOutController.ts b/app/Controllers/Http/Dashboard/LogOutController.ts
index 5d250c4..f085d00 100644
--- a/app/Controllers/Http/Dashboard/LogOutController.ts
+++ b/app/Controllers/Http/Dashboard/LogOutController.ts
@@ -1,12 +1,12 @@
1import type { HttpContext } from '@adonisjs/core/http' 1import type { HttpContext } from '@adonisjs/core/http';
2 2
3export default class LogOutController { 3export default class LogOutController {
4 /** 4 /**
5 * Login a user 5 * Login a user
6 */ 6 */
7 public async logout({ auth, response }: HttpContext) { 7 public async logout({ auth, response }: HttpContext) {
8 auth.logout() 8 auth.logout();
9 9
10 return response.redirect('/user/login') 10 return response.redirect('/user/login');
11 } 11 }
12} 12}
diff --git a/app/Controllers/Http/Dashboard/LoginController.ts b/app/Controllers/Http/Dashboard/LoginController.ts
index 5a54448..3367a2f 100644
--- a/app/Controllers/Http/Dashboard/LoginController.ts
+++ b/app/Controllers/Http/Dashboard/LoginController.ts
@@ -1,15 +1,15 @@
1import type { HttpContext } from '@adonisjs/core/http' 1import type { HttpContext } from '@adonisjs/core/http';
2import { schema, rules, validator } from '@adonisjs/validator' 2import { schema, rules, validator } from '@adonisjs/validator';
3import User from '#app/Models/User' 3import User from '#app/Models/User';
4import crypto from 'node:crypto' 4import crypto from 'node:crypto';
5import { handleVerifyAndReHash } from '../../../../helpers/PasswordHash.js' 5import { handleVerifyAndReHash } from '../../../../helpers/PasswordHash.js';
6 6
7export default class LoginController { 7export default class LoginController {
8 /** 8 /**
9 * Display the login form 9 * Display the login form
10 */ 10 */
11 public async show({ view }: HttpContext) { 11 public async show({ view }: HttpContext) {
12 return view.render('dashboard/login') 12 return view.render('dashboard/login');
13 } 13 }
14 14
15 /** 15 /**
@@ -23,51 +23,54 @@ export default class LoginController {
23 password: schema.string([rules.required()]), 23 password: schema.string([rules.required()]),
24 }), 24 }),
25 data: request.only(['mail', 'password']), 25 data: request.only(['mail', 'password']),
26 }) 26 });
27 } catch { 27 } catch {
28 session.flash({ 28 session.flash({
29 type: 'danger', 29 type: 'danger',
30 message: 'Invalid mail or password', 30 message: 'Invalid mail or password',
31 }) 31 });
32 session.flashExcept(['password']) 32 session.flashExcept(['password']);
33 33
34 return response.redirect('/user/login') 34 return response.redirect('/user/login');
35 } 35 }
36 36
37 try { 37 try {
38 const { mail, password } = request.all() 38 const { mail, password } = request.all();
39 39
40 // Check if user with email exists 40 // Check if user with email exists
41 const user = await User.query().where('email', mail).first() 41 const user = await User.query().where('email', mail).first();
42 if (!user?.email) { 42 if (!user?.email) {
43 throw new Error('User credentials not valid (Invalid email)') 43 throw new Error('User credentials not valid (Invalid email)');
44 } 44 }
45 45
46 const hashedPassword = crypto.createHash('sha256').update(password).digest('base64') 46 const hashedPassword = crypto
47 .createHash('sha256')
48 .update(password)
49 .digest('base64');
47 50
48 // Verify password 51 // Verify password
49 let isMatchedPassword = false 52 let isMatchedPassword = false;
50 try { 53 try {
51 isMatchedPassword = await handleVerifyAndReHash(user, hashedPassword) 54 isMatchedPassword = await handleVerifyAndReHash(user, hashedPassword);
52 } catch (error) { 55 } catch (error) {
53 return response.internalServerError({ message: error.message }) 56 return response.internalServerError({ message: error.message });
54 } 57 }
55 58
56 if (!isMatchedPassword) { 59 if (!isMatchedPassword) {
57 throw new Error('User credentials not valid (Invalid password)') 60 throw new Error('User credentials not valid (Invalid password)');
58 } 61 }
59 62
60 await auth.use('web').login(user) 63 await auth.use('web').login(user);
61 64
62 return response.redirect('/user/account') 65 return response.redirect('/user/account');
63 } catch { 66 } catch {
64 session.flash({ 67 session.flash({
65 type: 'danger', 68 type: 'danger',
66 message: 'Invalid mail or password', 69 message: 'Invalid mail or password',
67 }) 70 });
68 session.flashExcept(['password']) 71 session.flashExcept(['password']);
69 72
70 return response.redirect('/user/login') 73 return response.redirect('/user/login');
71 } 74 }
72 } 75 }
73} 76}
diff --git a/app/Controllers/Http/Dashboard/ResetPasswordController.ts b/app/Controllers/Http/Dashboard/ResetPasswordController.ts
index b62b5d2..261d773 100644
--- a/app/Controllers/Http/Dashboard/ResetPasswordController.ts
+++ b/app/Controllers/Http/Dashboard/ResetPasswordController.ts
@@ -1,30 +1,35 @@
1import type { HttpContext } from '@adonisjs/core/http' 1import type { HttpContext } from '@adonisjs/core/http';
2import { schema, rules, validator } from '@adonisjs/validator' 2import { schema, rules, validator } from '@adonisjs/validator';
3import Token from '#app/Models/Token' 3import Token from '#app/Models/Token';
4import moment from 'moment' 4import moment from 'moment';
5import crypto from 'node:crypto' 5import crypto from 'node:crypto';
6 6
7export default class ResetPasswordController { 7export default class ResetPasswordController {
8 /** 8 /**
9 * Display the reset password form 9 * Display the reset password form
10 */ 10 */
11 public async show({ view, request }: HttpContext) { 11 public async show({ view, request }: HttpContext) {
12 const { token } = request.qs() 12 const { token } = request.qs();
13 13
14 if (token) { 14 if (token) {
15 return view.render('dashboard/resetPassword', { token }) 15 return view.render('dashboard/resetPassword', { token });
16 } 16 }
17 17
18 return view.render('others/message', { 18 return view.render('others/message', {
19 heading: 'Invalid token', 19 heading: 'Invalid token',
20 text: 'Please make sure you are using a valid and recent link to reset your password.', 20 text: 'Please make sure you are using a valid and recent link to reset your password.',
21 }) 21 });
22 } 22 }
23 23
24 /** 24 /**
25 * Resets user password 25 * Resets user password
26 */ 26 */
27 public async resetPassword({ response, request, session, view }: HttpContext) { 27 public async resetPassword({
28 response,
29 request,
30 session,
31 view,
32 }: HttpContext) {
28 try { 33 try {
29 await validator.validate({ 34 await validator.validate({
30 schema: schema.create({ 35 schema: schema.create({
@@ -32,14 +37,14 @@ export default class ResetPasswordController {
32 token: schema.string([rules.required()]), 37 token: schema.string([rules.required()]),
33 }), 38 }),
34 data: request.only(['password', 'password_confirmation', 'token']), 39 data: request.only(['password', 'password_confirmation', 'token']),
35 }) 40 });
36 } catch { 41 } catch {
37 session.flash({ 42 session.flash({
38 type: 'danger', 43 type: 'danger',
39 message: 'Passwords do not match', 44 message: 'Passwords do not match',
40 }) 45 });
41 46
42 return response.redirect(`/user/reset?token=${request.input('token')}`) 47 return response.redirect(`/user/reset?token=${request.input('token')}`);
43 } 48 }
44 49
45 const tokenRow = await Token.query() 50 const tokenRow = await Token.query()
@@ -47,30 +52,34 @@ export default class ResetPasswordController {
47 .where('token', request.input('token')) 52 .where('token', request.input('token'))
48 .where('type', 'forgot_password') 53 .where('type', 'forgot_password')
49 .where('is_revoked', false) 54 .where('is_revoked', false)
50 .where('updated_at', '>=', moment().subtract(24, 'hours').format('YYYY-MM-DD HH:mm:ss')) 55 .where(
51 .first() 56 'updated_at',
57 '>=',
58 moment().subtract(24, 'hours').format('YYYY-MM-DD HH:mm:ss'),
59 )
60 .first();
52 61
53 if (!tokenRow) { 62 if (!tokenRow) {
54 return view.render('others/message', { 63 return view.render('others/message', {
55 heading: 'Cannot reset your password', 64 heading: 'Cannot reset your password',
56 text: 'Please make sure you are using a valid and recent link to reset your password and that your passwords entered match.', 65 text: 'Please make sure you are using a valid and recent link to reset your password and that your passwords entered match.',
57 }) 66 });
58 } 67 }
59 68
60 // Update user password 69 // Update user password
61 const hashedPassword = crypto 70 const hashedPassword = crypto
62 .createHash('sha256') 71 .createHash('sha256')
63 .update(request.input('password')) 72 .update(request.input('password'))
64 .digest('base64') 73 .digest('base64');
65 tokenRow.user.password = hashedPassword 74 tokenRow.user.password = hashedPassword;
66 await tokenRow.user.save() 75 await tokenRow.user.save();
67 76
68 // Delete token to prevent it from being used again 77 // Delete token to prevent it from being used again
69 await tokenRow.delete() 78 await tokenRow.delete();
70 79
71 return view.render('others/message', { 80 return view.render('others/message', {
72 heading: 'Reset password', 81 heading: 'Reset password',
73 text: 'Successfully reset your password. You can now login to your account using your new password.', 82 text: 'Successfully reset your password. You can now login to your account using your new password.',
74 }) 83 });
75 } 84 }
76} 85}
diff --git a/app/Controllers/Http/Dashboard/TransferController.ts b/app/Controllers/Http/Dashboard/TransferController.ts
index 0296973..ab50bcf 100644
--- a/app/Controllers/Http/Dashboard/TransferController.ts
+++ b/app/Controllers/Http/Dashboard/TransferController.ts
@@ -1,8 +1,8 @@
1import type { HttpContext } from '@adonisjs/core/http' 1import type { HttpContext } from '@adonisjs/core/http';
2import { schema, validator } from '@adonisjs/validator' 2import { schema, validator } from '@adonisjs/validator';
3import Service from '#app/Models/Service' 3import Service from '#app/Models/Service';
4import Workspace from '#app/Models/Workspace' 4import Workspace from '#app/Models/Workspace';
5import { v4 as uuidv4 } from 'uuid' 5import { v4 as uuidv4 } from 'uuid';
6 6
7const importSchema = schema.create({ 7const importSchema = schema.create({
8 username: schema.string(), 8 username: schema.string(),
@@ -10,52 +10,52 @@ const importSchema = schema.create({
10 mail: schema.string(), 10 mail: schema.string(),
11 services: schema.array().anyMembers(), 11 services: schema.array().anyMembers(),
12 workspaces: schema.array().anyMembers(), 12 workspaces: schema.array().anyMembers(),
13}) 13});
14 14
15export default class TransferController { 15export default class TransferController {
16 /** 16 /**
17 * Display the transfer page 17 * Display the transfer page
18 */ 18 */
19 public async show({ view }: HttpContext) { 19 public async show({ view }: HttpContext) {
20 return view.render('dashboard/transfer') 20 return view.render('dashboard/transfer');
21 } 21 }
22 22
23 public async import({ auth, request, response, session, view }: HttpContext) { 23 public async import({ auth, request, response, session, view }: HttpContext) {
24 let file 24 let file;
25 try { 25 try {
26 file = await validator.validate({ 26 file = await validator.validate({
27 schema: importSchema, 27 schema: importSchema,
28 data: JSON.parse(request.body().file), 28 data: JSON.parse(request.body().file),
29 }) 29 });
30 } catch { 30 } catch {
31 session.flash({ 31 session.flash({
32 message: 'Invalid Ferdium account file', 32 message: 'Invalid Ferdium account file',
33 }) 33 });
34 34
35 return response.redirect('/user/transfer') 35 return response.redirect('/user/transfer');
36 } 36 }
37 37
38 if (!file?.services || !file.workspaces) { 38 if (!file?.services || !file.workspaces) {
39 session.flash({ 39 session.flash({
40 type: 'danger', 40 type: 'danger',
41 message: 'Invalid Ferdium account file (2)', 41 message: 'Invalid Ferdium account file (2)',
42 }) 42 });
43 return response.redirect('/user/transfer') 43 return response.redirect('/user/transfer');
44 } 44 }
45 45
46 const serviceIdTranslation = {} 46 const serviceIdTranslation = {};
47 47
48 // Import services 48 // Import services
49 try { 49 try {
50 for (const service of file.services) { 50 for (const service of file.services) {
51 // Get new, unused uuid 51 // Get new, unused uuid
52 let serviceId 52 let serviceId;
53 do { 53 do {
54 serviceId = uuidv4() 54 serviceId = uuidv4();
55 } while ( 55 } while (
56 // eslint-disable-next-line no-await-in-loop, unicorn/no-await-expression-member 56 // eslint-disable-next-line no-await-in-loop, unicorn/no-await-expression-member
57 (await Service.query().where('serviceId', serviceId)).length > 0 57 (await Service.query().where('serviceId', serviceId)).length > 0
58 ) 58 );
59 59
60 // eslint-disable-next-line no-await-in-loop 60 // eslint-disable-next-line no-await-in-loop
61 await Service.create({ 61 await Service.create({
@@ -67,37 +67,38 @@ export default class TransferController {
67 typeof service.settings === 'string' 67 typeof service.settings === 'string'
68 ? service.settings 68 ? service.settings
69 : JSON.stringify(service.settings), 69 : JSON.stringify(service.settings),
70 }) 70 });
71 71
72 // @ts-expect-error Element implicitly has an 'any' type because expression of type 'any' can't be used to index type '{}' 72 // @ts-expect-error Element implicitly has an 'any' type because expression of type 'any' can't be used to index type '{}'
73 serviceIdTranslation[service.service_id || service.serviceId] = serviceId 73 serviceIdTranslation[service.service_id || service.serviceId] =
74 serviceId;
74 } 75 }
75 } catch (error) { 76 } catch (error) {
76 // eslint-disable-next-line no-console 77 // eslint-disable-next-line no-console
77 console.log(error) 78 console.log(error);
78 const errorMessage = `Could not import your services into our system.\nError: ${error}` 79 const errorMessage = `Could not import your services into our system.\nError: ${error}`;
79 return view.render('others/message', { 80 return view.render('others/message', {
80 heading: 'Error while importing', 81 heading: 'Error while importing',
81 text: errorMessage, 82 text: errorMessage,
82 }) 83 });
83 } 84 }
84 85
85 // Import workspaces 86 // Import workspaces
86 try { 87 try {
87 for (const workspace of file.workspaces) { 88 for (const workspace of file.workspaces) {
88 let workspaceId 89 let workspaceId;
89 90
90 do { 91 do {
91 workspaceId = uuidv4() 92 workspaceId = uuidv4();
92 } while ( 93 } while (
93 // eslint-disable-next-line no-await-in-loop, unicorn/no-await-expression-member 94 // eslint-disable-next-line no-await-in-loop, unicorn/no-await-expression-member
94 (await Workspace.query().where('workspaceId', workspaceId)).length > 0 95 (await Workspace.query().where('workspaceId', workspaceId)).length > 0
95 ) 96 );
96 97
97 const services = workspace.services.map( 98 const services = workspace.services.map(
98 // @ts-expect-error Parameter 'service' implicitly has an 'any' type. 99 // @ts-expect-error Parameter 'service' implicitly has an 'any' type.
99 (service) => serviceIdTranslation[service] 100 service => serviceIdTranslation[service],
100 ) 101 );
101 102
102 // eslint-disable-next-line no-await-in-loop 103 // eslint-disable-next-line no-await-in-loop
103 await Workspace.create({ 104 await Workspace.create({
@@ -107,20 +108,22 @@ export default class TransferController {
107 order: workspace.order, 108 order: workspace.order,
108 services: JSON.stringify(services), 109 services: JSON.stringify(services),
109 data: 110 data:
110 typeof workspace.data === 'string' ? workspace.data : JSON.stringify(workspace.data), 111 typeof workspace.data === 'string'
111 }) 112 ? workspace.data
113 : JSON.stringify(workspace.data),
114 });
112 } 115 }
113 } catch (error) { 116 } catch (error) {
114 const errorMessage = `Could not import your workspaces into our system.\nError: ${error}` 117 const errorMessage = `Could not import your workspaces into our system.\nError: ${error}`;
115 return view.render('others/message', { 118 return view.render('others/message', {
116 heading: 'Error while importing', 119 heading: 'Error while importing',
117 text: errorMessage, 120 text: errorMessage,
118 }) 121 });
119 } 122 }
120 123
121 return view.render('others/message', { 124 return view.render('others/message', {
122 heading: 'Successfully imported', 125 heading: 'Successfully imported',
123 text: 'Your account has been imported, you can now login as usual!', 126 text: 'Your account has been imported, you can now login as usual!',
124 }) 127 });
125 } 128 }
126} 129}