diff options
author | Vijay A <avijayr@protonmail.com> | 2021-08-13 00:45:01 +0530 |
---|---|---|
committer | Vijay A <avijayr@protonmail.com> | 2021-08-13 00:45:01 +0530 |
commit | 2d27d5e66649d4f5baf127a53ee5ae524eae3a59 (patch) | |
tree | c592ea219ac8cd987fc367f57b54034c450ab2ab /src/internal-server/app/Controllers/Http/ServiceController.js | |
parent | Ferdi v5.6.0 (diff) | |
parent | 5.6.1-nightly.24 [skip ci] (diff) | |
download | ferdium-app-2d27d5e66649d4f5baf127a53ee5ae524eae3a59.tar.gz ferdium-app-2d27d5e66649d4f5baf127a53ee5ae524eae3a59.tar.zst ferdium-app-2d27d5e66649d4f5baf127a53ee5ae524eae3a59.zip |
chore: merge from nightly branch into release branch in prep for next beta
Diffstat (limited to 'src/internal-server/app/Controllers/Http/ServiceController.js')
-rw-r--r-- | src/internal-server/app/Controllers/Http/ServiceController.js | 292 |
1 files changed, 292 insertions, 0 deletions
diff --git a/src/internal-server/app/Controllers/Http/ServiceController.js b/src/internal-server/app/Controllers/Http/ServiceController.js new file mode 100644 index 000000000..c76a287f7 --- /dev/null +++ b/src/internal-server/app/Controllers/Http/ServiceController.js | |||
@@ -0,0 +1,292 @@ | |||
1 | const Service = use('App/Models/Service'); | ||
2 | const { validateAll } = use('Validator'); | ||
3 | const Env = use('Env'); | ||
4 | |||
5 | const uuid = require('uuid/v4'); | ||
6 | const path = require('path'); | ||
7 | const fs = require('fs-extra'); | ||
8 | const { LOCAL_HOSTNAME } = require('../../../../config'); | ||
9 | |||
10 | const hostname = LOCAL_HOSTNAME; | ||
11 | const port = Env.get('PORT'); | ||
12 | |||
13 | class ServiceController { | ||
14 | // Create a new service for user | ||
15 | async create({ request, response }) { | ||
16 | // Validate user input | ||
17 | const validation = await validateAll(request.all(), { | ||
18 | name: 'required|string', | ||
19 | recipeId: 'required', | ||
20 | }); | ||
21 | if (validation.fails()) { | ||
22 | return response.status(401).send({ | ||
23 | message: 'Invalid POST arguments', | ||
24 | messages: validation.messages(), | ||
25 | status: 401, | ||
26 | }); | ||
27 | } | ||
28 | |||
29 | const data = request.all(); | ||
30 | |||
31 | // Get new, unused uuid | ||
32 | let serviceId; | ||
33 | do { | ||
34 | serviceId = uuid(); | ||
35 | } while ( | ||
36 | (await Service.query().where('serviceId', serviceId).fetch()).rows | ||
37 | .length > 0 | ||
38 | ); // eslint-disable-line no-await-in-loop | ||
39 | |||
40 | await Service.create({ | ||
41 | serviceId, | ||
42 | name: data.name, | ||
43 | recipeId: data.recipeId, | ||
44 | settings: JSON.stringify(data), | ||
45 | }); | ||
46 | |||
47 | return response.send({ | ||
48 | data: { | ||
49 | userId: 1, | ||
50 | id: serviceId, | ||
51 | isEnabled: true, | ||
52 | isNotificationEnabled: true, | ||
53 | isBadgeEnabled: true, | ||
54 | isMuted: false, | ||
55 | isDarkModeEnabled: '', // TODO: This should ideally be a boolean (false). But, changing it caused the sidebar toggle to not work. | ||
56 | spellcheckerLanguage: '', | ||
57 | order: 1, | ||
58 | customRecipe: false, | ||
59 | hasCustomIcon: false, | ||
60 | workspaces: [], | ||
61 | iconUrl: null, | ||
62 | ...data, | ||
63 | }, | ||
64 | status: ['created'], | ||
65 | }); | ||
66 | } | ||
67 | |||
68 | // List all services a user has created | ||
69 | async list({ response }) { | ||
70 | const services = (await Service.all()).rows; | ||
71 | // Convert to array with all data Franz wants | ||
72 | const servicesArray = services.map(service => { | ||
73 | const settings = | ||
74 | typeof service.settings === 'string' | ||
75 | ? JSON.parse(service.settings) | ||
76 | : service.settings; | ||
77 | |||
78 | return { | ||
79 | customRecipe: false, | ||
80 | hasCustomIcon: false, | ||
81 | isBadgeEnabled: true, | ||
82 | isDarkModeEnabled: '', // TODO: This should ideally be a boolean (false). But, changing it caused the sidebar toggle to not work. | ||
83 | isEnabled: true, | ||
84 | isMuted: false, | ||
85 | isNotificationEnabled: true, | ||
86 | order: 1, | ||
87 | spellcheckerLanguage: '', | ||
88 | workspaces: [], | ||
89 | ...JSON.parse(service.settings), | ||
90 | iconUrl: settings.iconId | ||
91 | ? `http://${hostname}:${port}/v1/icon/${settings.iconId}` | ||
92 | : null, | ||
93 | id: service.serviceId, | ||
94 | name: service.name, | ||
95 | recipeId: service.recipeId, | ||
96 | userId: 1, | ||
97 | }; | ||
98 | }); | ||
99 | |||
100 | return response.send(servicesArray); | ||
101 | } | ||
102 | |||
103 | async edit({ request, response, params }) { | ||
104 | if (request.file('icon')) { | ||
105 | // Upload custom service icon | ||
106 | await fs.ensureDir(path.join(Env.get('USER_PATH'), 'icons')); | ||
107 | |||
108 | const icon = request.file('icon', { | ||
109 | types: ['image'], | ||
110 | size: '2mb', | ||
111 | }); | ||
112 | const { id } = params; | ||
113 | const service = (await Service.query().where('serviceId', id).fetch()) | ||
114 | .rows[0]; | ||
115 | const settings = | ||
116 | typeof service.settings === 'string' | ||
117 | ? JSON.parse(service.settings) | ||
118 | : service.settings; | ||
119 | |||
120 | // Generate new icon ID | ||
121 | let iconId; | ||
122 | do { | ||
123 | iconId = uuid() + uuid(); | ||
124 | } while (fs.existsSync(path.join(Env.get('USER_PATH'), 'icons', iconId))); | ||
125 | |||
126 | await icon.move(path.join(Env.get('USER_PATH'), 'icons'), { | ||
127 | name: iconId, | ||
128 | overwrite: true, | ||
129 | }); | ||
130 | |||
131 | if (!icon.moved()) { | ||
132 | return response.status(500).send(icon.error()); | ||
133 | } | ||
134 | |||
135 | const newSettings = { | ||
136 | ...settings, | ||
137 | ...{ | ||
138 | iconId, | ||
139 | customIconVersion: | ||
140 | settings && settings.customIconVersion | ||
141 | ? settings.customIconVersion + 1 | ||
142 | : 1, | ||
143 | }, | ||
144 | }; | ||
145 | |||
146 | // Update data in database | ||
147 | await Service.query() | ||
148 | .where('serviceId', id) | ||
149 | .update({ | ||
150 | name: service.name, | ||
151 | settings: JSON.stringify(newSettings), | ||
152 | }); | ||
153 | |||
154 | return response.send({ | ||
155 | data: { | ||
156 | id, | ||
157 | name: service.name, | ||
158 | ...newSettings, | ||
159 | iconUrl: `http://${hostname}:${port}/v1/icon/${ | ||
160 | newSettings.iconId | ||
161 | }`, | ||
162 | userId: 1, | ||
163 | }, | ||
164 | status: ['updated'], | ||
165 | }); | ||
166 | } | ||
167 | // Update service info | ||
168 | const data = request.all(); | ||
169 | const { id } = params; | ||
170 | |||
171 | // Get current settings from db | ||
172 | const serviceData = (await Service.query().where('serviceId', id).fetch()) | ||
173 | .rows[0]; | ||
174 | |||
175 | const settings = { | ||
176 | ...(typeof serviceData.settings === 'string' | ||
177 | ? JSON.parse(serviceData.settings) | ||
178 | : serviceData.settings), | ||
179 | ...data, | ||
180 | }; | ||
181 | |||
182 | // Update data in database | ||
183 | await Service.query() | ||
184 | .where('serviceId', id) | ||
185 | .update({ | ||
186 | name: data.name, | ||
187 | settings: JSON.stringify(settings), | ||
188 | }); | ||
189 | |||
190 | // Get updated row | ||
191 | const service = (await Service.query().where('serviceId', id).fetch()) | ||
192 | .rows[0]; | ||
193 | |||
194 | return response.send({ | ||
195 | data: { | ||
196 | id, | ||
197 | name: service.name, | ||
198 | ...settings, | ||
199 | iconUrl: `${Env.get('APP_URL')}/v1/icon/${settings.iconId}`, | ||
200 | userId: 1, | ||
201 | }, | ||
202 | status: ['updated'], | ||
203 | }); | ||
204 | } | ||
205 | |||
206 | async icon({ params, response }) { | ||
207 | const { id } = params; | ||
208 | |||
209 | const iconPath = path.join(Env.get('USER_PATH'), 'icons', id); | ||
210 | if (!fs.existsSync(iconPath)) { | ||
211 | return response.status(404).send({ | ||
212 | status: "Icon doesn't exist", | ||
213 | }); | ||
214 | } | ||
215 | |||
216 | return response.download(iconPath); | ||
217 | } | ||
218 | |||
219 | async reorder({ request, response }) { | ||
220 | const data = request.all(); | ||
221 | |||
222 | for (const service of Object.keys(data)) { | ||
223 | // Get current settings from db | ||
224 | const serviceData = ( | ||
225 | await Service.query() // eslint-disable-line no-await-in-loop | ||
226 | .where('serviceId', service) | ||
227 | .fetch() | ||
228 | ).rows[0]; | ||
229 | |||
230 | const settings = { | ||
231 | ...JSON.parse(serviceData.settings), | ||
232 | order: data[service], | ||
233 | }; | ||
234 | |||
235 | // Update data in database | ||
236 | await Service.query() // eslint-disable-line no-await-in-loop | ||
237 | .where('serviceId', service) | ||
238 | .update({ | ||
239 | settings: JSON.stringify(settings), | ||
240 | }); | ||
241 | } | ||
242 | |||
243 | // Get new services | ||
244 | const services = (await Service.all()).rows; | ||
245 | // Convert to array with all data Franz wants | ||
246 | const servicesArray = services.map(service => { | ||
247 | const settings = | ||
248 | typeof service.settings === 'string' | ||
249 | ? JSON.parse(service.settings) | ||
250 | : service.settings; | ||
251 | |||
252 | return { | ||
253 | customRecipe: false, | ||
254 | hasCustomIcon: false, | ||
255 | isBadgeEnabled: true, | ||
256 | isDarkModeEnabled: '', // TODO: This should ideally be a boolean (false). But, changing it caused the sidebar toggle to not work. | ||
257 | isEnabled: true, | ||
258 | isMuted: false, | ||
259 | isNotificationEnabled: true, | ||
260 | order: 1, | ||
261 | spellcheckerLanguage: '', | ||
262 | workspaces: [], | ||
263 | ...JSON.parse(service.settings), | ||
264 | iconUrl: settings.iconId | ||
265 | ? `http://${hostname}:${port}/v1/icon/${settings.iconId}` | ||
266 | : null, | ||
267 | id: service.serviceId, | ||
268 | name: service.name, | ||
269 | recipeId: service.recipeId, | ||
270 | userId: 1, | ||
271 | }; | ||
272 | }); | ||
273 | |||
274 | return response.send(servicesArray); | ||
275 | } | ||
276 | |||
277 | update({ response }) { | ||
278 | return response.send([]); | ||
279 | } | ||
280 | |||
281 | async delete({ params, response }) { | ||
282 | // Update data in database | ||
283 | await Service.query().where('serviceId', params.id).delete(); | ||
284 | |||
285 | return response.send({ | ||
286 | message: 'Sucessfully deleted service', | ||
287 | status: 200, | ||
288 | }); | ||
289 | } | ||
290 | } | ||
291 | |||
292 | module.exports = ServiceController; | ||