aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorLibravatar vantezzen <hello@vantezzen.io>2019-10-23 10:41:34 +0200
committerLibravatar vantezzen <hello@vantezzen.io>2019-10-23 10:41:34 +0200
commit26bff86fee36e2bedeee19c750634860e59ed3ec (patch)
tree95425ae73b61ac04b9274298c240f8becd4e7bdc /app
parentFix #8 (diff)
downloadferdium-server-26bff86fee36e2bedeee19c750634860e59ed3ec.tar.gz
ferdium-server-26bff86fee36e2bedeee19c750634860e59ed3ec.tar.zst
ferdium-server-26bff86fee36e2bedeee19c750634860e59ed3ec.zip
#9 Implement custom service icons
Diffstat (limited to 'app')
-rw-r--r--app/Controllers/Http/ServiceController.js245
1 files changed, 168 insertions, 77 deletions
diff --git a/app/Controllers/Http/ServiceController.js b/app/Controllers/Http/ServiceController.js
index 7162268..e4e69fe 100644
--- a/app/Controllers/Http/ServiceController.js
+++ b/app/Controllers/Http/ServiceController.js
@@ -2,8 +2,12 @@ const Service = use('App/Models/Service');
2const { 2const {
3 validateAll, 3 validateAll,
4} = use('Validator'); 4} = use('Validator');
5const Env = use('Env');
6const Helpers = use('Helpers');
5 7
6const uuid = require('uuid/v4'); 8const uuid = require('uuid/v4');
9const path = require('path');
10const fs = require('fs-extra');
7 11
8class ServiceController { 12class ServiceController {
9 // Create a new service for user 13 // Create a new service for user
@@ -81,24 +85,28 @@ class ServiceController {
81 85
82 const services = (await auth.user.services().fetch()).rows; 86 const services = (await auth.user.services().fetch()).rows;
83 // Convert to array with all data Franz wants 87 // Convert to array with all data Franz wants
84 const servicesArray = services.map((service) => ({ 88 const servicesArray = services.map((service) => {
85 customRecipe: false, 89 const settings = typeof service.settings === "string" ? JSON.parse(service.settings) : service.settings;
86 hasCustomIcon: false, 90
87 isBadgeEnabled: true, 91 return {
88 isDarkModeEnabled: '', 92 customRecipe: false,
89 isEnabled: true, 93 hasCustomIcon: false,
90 isMuted: false, 94 isBadgeEnabled: true,
91 isNotificationEnabled: true, 95 isDarkModeEnabled: '',
92 order: 1, 96 isEnabled: true,
93 spellcheckerLanguage: '', 97 isMuted: false,
94 workspaces: [], 98 isNotificationEnabled: true,
95 iconUrl: null, 99 order: 1,
96 ...typeof service.settings === "string" ? JSON.parse(service.settings) : service.settings, 100 spellcheckerLanguage: '',
97 id: service.serviceId, 101 workspaces: [],
98 name: service.name, 102 ...settings,
99 recipeId: service.recipeId, 103 iconUrl: settings.iconId ? `${Env.get('APP_URL')}/v1/icon/${settings.iconId}` : null,
100 userId: auth.user.id, 104 id: service.serviceId,
101 })); 105 name: service.name,
106 recipeId: service.recipeId,
107 userId: auth.user.id,
108 }
109 });
102 110
103 return response.send(servicesArray); 111 return response.send(servicesArray);
104 } 112 }
@@ -115,52 +123,131 @@ class ServiceController {
115 return response.send('Missing or invalid api token'); 123 return response.send('Missing or invalid api token');
116 } 124 }
117 125
118 // Validate user input 126 if (request.file('icon')) {
119 const validation = await validateAll(request.all(), { 127 // Upload custom service icon
120 name: 'required', 128 const icon = request.file('icon', {
121 }); 129 types: ['image'],
122 if (validation.fails()) { 130 size: '2mb'
123 return response.status(401).send({ 131 });
124 message: 'Invalid POST arguments', 132 const {
125 messages: validation.messages(), 133 id,
126 status: 401, 134 } = params;
135 const service = (await Service.query()
136 .where('serviceId', id)
137 .where('userId', auth.user.id).fetch()).rows[0];
138 const settings = typeof service.settings === "string" ? JSON.parse(service.settings) : service.settings;
139
140 let iconId;
141 do {
142 iconId = uuid() + uuid();
143 } while(await fs.exists(path.join(Helpers.tmpPath('uploads'), iconId)));
144
145 await icon.move(Helpers.tmpPath('uploads'), {
146 name: iconId,
147 overwrite: true
148 })
149
150 if (!icon.moved()) {
151 return response.status(500).send(icon.error());
152 }
153
154 const newSettings = {
155 ...settings,
156 ...{
157 iconId,
158 customIconVersion: settings && settings.customIconVersion ? settings.customIconVersion + 1 : 1,
159 },
160 };
161
162 // Update data in database
163 await (Service.query()
164 .where('serviceId', id)
165 .where('userId', auth.user.id)).update({
166 name: service.name,
167 settings: JSON.stringify(newSettings),
168 });
169
170 return response.send({
171 data: {
172 id,
173 name: service.name,
174 ...newSettings,
175 iconUrl: `${Env.get('APP_URL')}/v1/icon/${newSettings.iconId}`,
176 userId: auth.user.id,
177 },
178 status: ["updated"]
179 });
180 } else {
181 // Update service info
182 const validation = await validateAll(request.all(), {
183 name: 'required',
184 });
185 if (validation.fails()) {
186 return response.status(401).send({
187 message: 'Invalid POST arguments',
188 messages: validation.messages(),
189 status: 401,
190 });
191 }
192
193 const data = request.all();
194 const {
195 id,
196 } = params;
197
198 // Get current settings from db
199 const serviceData = (await Service.query()
200 .where('serviceId', id)
201 .where('userId', auth.user.id).fetch()).rows[0];
202
203 const settings = {
204 ...typeof serviceData.settings === "string" ? JSON.parse(serviceData.settings) : serviceData.settings,
205 ...data,
206 };
207
208 // Update data in database
209 await (Service.query()
210 .where('serviceId', id)
211 .where('userId', auth.user.id)).update({
212 name: data.name,
213 settings: JSON.stringify(settings),
214 });
215
216 // Get updated row
217 const service = (await Service.query()
218 .where('serviceId', id)
219 .where('userId', auth.user.id).fetch()).rows[0];
220
221 return response.send({
222 data: {
223 id,
224 name: service.name,
225 ...settings,
226 iconUrl: `${Env.get('APP_URL')}/v1/icon/${settings.iconId}`,
227 userId: auth.user.id,
228 },
229 status: ["updated"]
127 }); 230 });
128 } 231 }
232 }
129 233
130 const data = request.all(); 234 async icon({
235 params,
236 response,
237 auth
238 }) {
131 const { 239 const {
132 id, 240 id,
133 } = params; 241 } = params;
134 242
135 // Get current settings from db 243 const iconPath = path.join(Helpers.tmpPath('uploads'), id);
136 const serviceData = (await Service.query() 244 if (!await fs.exists(iconPath)) {
137 .where('serviceId', id) 245 return response.status(404).send({
138 .where('userId', auth.user.id).fetch()).rows[0]; 246 status: 'Icon doesn\'t exist'
139 247 });
140 const settings = { 248 }
141 ...typeof serviceData.settings === "string" ? JSON.parse(serviceData.settings) : serviceData.settings,
142 ...data,
143 };
144
145 // Update data in database
146 await (Service.query()
147 .where('serviceId', id)
148 .where('userId', auth.user.id)).update({
149 name: data.name,
150 settings: JSON.stringify(settings),
151 });
152
153 // Get updated row
154 const service = (await Service.query()
155 .where('serviceId', id)
156 .where('userId', auth.user.id).fetch()).rows[0];
157 249
158 return response.send({ 250 return response.download(iconPath);
159 id: service.serviceId,
160 name: data.name,
161 ...settings,
162 userId: auth.user.id,
163 });
164 } 251 }
165 252
166 async reorder({ 253 async reorder({
@@ -185,32 +272,36 @@ class ServiceController {
185 await (Service.query() // eslint-disable-line no-await-in-loop 272 await (Service.query() // eslint-disable-line no-await-in-loop
186 .where('serviceId', service) 273 .where('serviceId', service)
187 .where('userId', auth.user.id)) 274 .where('userId', auth.user.id))
188 .update({ 275 .update({
189 settings: JSON.stringify(settings), 276 settings: JSON.stringify(settings),
190 }); 277 });
191 } 278 }
192 279
193 // Get new services 280 // Get new services
194 const services = (await auth.user.services().fetch()).rows; 281 const services = (await auth.user.services().fetch()).rows;
195 // Convert to array with all data Franz wants 282 // Convert to array with all data Franz wants
196 const servicesArray = services.map((service) => ({ 283 const servicesArray = services.map((service) => {
197 customRecipe: false, 284 const settings = typeof service.settings === "string" ? JSON.parse(service.settings) : service.settings;
198 hasCustomIcon: false, 285
199 isBadgeEnabled: true, 286 return {
200 isDarkModeEnabled: '', 287 customRecipe: false,
201 isEnabled: true, 288 hasCustomIcon: false,
202 isMuted: false, 289 isBadgeEnabled: true,
203 isNotificationEnabled: true, 290 isDarkModeEnabled: '',
204 order: 1, 291 isEnabled: true,
205 spellcheckerLanguage: '', 292 isMuted: false,
206 workspaces: [], 293 isNotificationEnabled: true,
207 iconUrl: null, 294 order: 1,
208 ...typeof service.settings === "string" ? JSON.parse(service.settings) : service.settings, 295 spellcheckerLanguage: '',
209 id: service.serviceId, 296 workspaces: [],
210 name: service.name, 297 ...settings,
211 recipeId: service.recipeId, 298 iconUrl: settings.iconId ? `${Env.get('APP_URL')}/v1/icon/${settings.iconId}` : null,
212 userId: auth.user.id, 299 id: service.serviceId,
213 })); 300 name: service.name,
301 recipeId: service.recipeId,
302 userId: auth.user.id,
303 }
304 });
214 305
215 return response.send(servicesArray); 306 return response.send(servicesArray);
216 } 307 }