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