aboutsummaryrefslogtreecommitdiffstats
path: root/app/Controllers/Http/Dashboard/TransferController.ts
blob: 0296973223ce26b76dc9fefcd3255d9101be76f2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import type { HttpContext } from '@adonisjs/core/http'
import { schema, validator } from '@adonisjs/validator'
import Service from '#app/Models/Service'
import Workspace from '#app/Models/Workspace'
import { v4 as uuidv4 } from 'uuid'

const importSchema = schema.create({
  username: schema.string(),
  lastname: schema.string(),
  mail: schema.string(),
  services: schema.array().anyMembers(),
  workspaces: schema.array().anyMembers(),
})

export default class TransferController {
  /**
   * Display the transfer page
   */
  public async show({ view }: HttpContext) {
    return view.render('dashboard/transfer')
  }

  public async import({ auth, request, response, session, view }: HttpContext) {
    let file
    try {
      file = await validator.validate({
        schema: importSchema,
        data: JSON.parse(request.body().file),
      })
    } catch {
      session.flash({
        message: 'Invalid Ferdium account file',
      })

      return response.redirect('/user/transfer')
    }

    if (!file?.services || !file.workspaces) {
      session.flash({
        type: 'danger',
        message: 'Invalid Ferdium account file (2)',
      })
      return response.redirect('/user/transfer')
    }

    const serviceIdTranslation = {}

    // Import services
    try {
      for (const service of file.services) {
        // Get new, unused uuid
        let serviceId
        do {
          serviceId = uuidv4()
        } while (
          // eslint-disable-next-line no-await-in-loop, unicorn/no-await-expression-member
          (await Service.query().where('serviceId', serviceId)).length > 0
        )

        // eslint-disable-next-line no-await-in-loop
        await Service.create({
          userId: auth.user?.id,
          serviceId,
          name: service.name,
          recipeId: service.recipe_id || service.recipeId,
          settings:
            typeof service.settings === 'string'
              ? service.settings
              : JSON.stringify(service.settings),
        })

        // @ts-expect-error Element implicitly has an 'any' type because expression of type 'any' can't be used to index type '{}'
        serviceIdTranslation[service.service_id || service.serviceId] = serviceId
      }
    } catch (error) {
      // eslint-disable-next-line no-console
      console.log(error)
      const errorMessage = `Could not import your services into our system.\nError: ${error}`
      return view.render('others/message', {
        heading: 'Error while importing',
        text: errorMessage,
      })
    }

    // Import workspaces
    try {
      for (const workspace of file.workspaces) {
        let workspaceId

        do {
          workspaceId = uuidv4()
        } while (
          // eslint-disable-next-line no-await-in-loop, unicorn/no-await-expression-member
          (await Workspace.query().where('workspaceId', workspaceId)).length > 0
        )

        const services = workspace.services.map(
          // @ts-expect-error Parameter 'service' implicitly has an 'any' type.
          (service) => serviceIdTranslation[service]
        )

        // eslint-disable-next-line no-await-in-loop
        await Workspace.create({
          userId: auth.user?.id,
          workspaceId,
          name: workspace.name,
          order: workspace.order,
          services: JSON.stringify(services),
          data:
            typeof workspace.data === 'string' ? workspace.data : JSON.stringify(workspace.data),
        })
      }
    } catch (error) {
      const errorMessage = `Could not import your workspaces into our system.\nError: ${error}`
      return view.render('others/message', {
        heading: 'Error while importing',
        text: errorMessage,
      })
    }

    return view.render('others/message', {
      heading: 'Successfully imported',
      text: 'Your account has been imported, you can now login as usual!',
    })
  }
}