aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar Markus Hatvan <markus_hatvan@aon.at>2021-08-16 18:10:23 +0200
committerLibravatar GitHub <noreply@github.com>2021-08-16 21:40:23 +0530
commit26a9dba22236bc22a7612107630282cfe02d20e0 (patch)
tree25af338b5a4b080a3bd2c60c500a34cafdff3581 /src
parentchore: replace moment.js with day.js (#1804) (diff)
downloadferdium-app-26a9dba22236bc22a7612107630282cfe02d20e0.tar.gz
ferdium-app-26a9dba22236bc22a7612107630282cfe02d20e0.tar.zst
ferdium-app-26a9dba22236bc22a7612107630282cfe02d20e0.zip
chore: update outdated node_modules (#1807)
- upgrade 'uuid', '@types/uuid', 'macos-version', 'normalize-url' and 'os-name' dependencies to latest - updated 'macos-version' imports to named imports
Diffstat (limited to 'src')
-rw-r--r--src/electron/macOSPermissions.js9
-rw-r--r--src/helpers/userAgent-helpers.ts11
-rw-r--r--src/internal-server/app/Controllers/Http/ServiceController.js6
-rw-r--r--src/internal-server/app/Controllers/Http/UserController.js178
-rw-r--r--src/internal-server/app/Controllers/Http/WorkspaceController.js57
-rw-r--r--src/lib/Tray.js55
-rw-r--r--src/webview/notifications.js19
7 files changed, 190 insertions, 145 deletions
diff --git a/src/electron/macOSPermissions.js b/src/electron/macOSPermissions.js
index 887af2903..fc2f9b72d 100644
--- a/src/electron/macOSPermissions.js
+++ b/src/electron/macOSPermissions.js
@@ -1,14 +1,17 @@
1import { systemPreferences, dialog } from 'electron'; 1import { systemPreferences, dialog } from 'electron';
2import { pathExistsSync, mkdirSync, writeFileSync } from 'fs-extra'; 2import { pathExistsSync, mkdirSync, writeFileSync } from 'fs-extra';
3import macosVersion from 'macos-version'; 3import { isMacOSVersionGreaterThanOrEqualTo } from 'macos-version';
4import { dirname } from 'path'; 4import { dirname } from 'path';
5import { askForScreenCaptureAccess } from 'node-mac-permissions'; 5import { askForScreenCaptureAccess } from 'node-mac-permissions';
6import { userDataPath } from '../environment'; 6import { userDataPath } from '../environment';
7 7
8const debug = require('debug')('Ferdi:macOSPermissions'); 8const debug = require('debug')('Ferdi:macOSPermissions');
9 9
10const isExplicitScreenCapturePermissionReqd = macosVersion.isGreaterThanOrEqualTo('10.15'); 10const isExplicitScreenCapturePermissionReqd =
11debug(`Should check explicitly for screen-capture permissions: ${isExplicitScreenCapturePermissionReqd}`); 11 isMacOSVersionGreaterThanOrEqualTo('10.15');
12debug(
13 `Should check explicitly for screen-capture permissions: ${isExplicitScreenCapturePermissionReqd}`,
14);
12 15
13const filePath = userDataPath('.has-app-requested-screen-capture-permissions'); 16const filePath = userDataPath('.has-app-requested-screen-capture-permissions');
14 17
diff --git a/src/helpers/userAgent-helpers.ts b/src/helpers/userAgent-helpers.ts
index 73c8bfd03..dea49ad7e 100644
--- a/src/helpers/userAgent-helpers.ts
+++ b/src/helpers/userAgent-helpers.ts
@@ -1,12 +1,17 @@
1import os from 'os'; 1import os from 'os';
2import macosVersion from 'macos-version'; 2import { macOSVersion } from 'macos-version';
3import { chrome } from 'useragent-generator'; 3import { chrome } from 'useragent-generator';
4import { 4import {
5 chromeVersion, isMac, isWindows, is64Bit, osArch, osRelease, 5 chromeVersion,
6 isMac,
7 isWindows,
8 is64Bit,
9 osArch,
10 osRelease,
6} from '../environment'; 11} from '../environment';
7 12
8function macOS() { 13function macOS() {
9 const version = macosVersion() || ''; 14 const version = macOSVersion() || '';
10 let cpuName = os.cpus()[0].model.split(' ')[0]; 15 let cpuName = os.cpus()[0].model.split(' ')[0];
11 if (cpuName && cpuName.match(/\(/)) { 16 if (cpuName && cpuName.match(/\(/)) {
12 cpuName = cpuName.split('(')[0]; 17 cpuName = cpuName.split('(')[0];
diff --git a/src/internal-server/app/Controllers/Http/ServiceController.js b/src/internal-server/app/Controllers/Http/ServiceController.js
index c76a287f7..dea5a888e 100644
--- a/src/internal-server/app/Controllers/Http/ServiceController.js
+++ b/src/internal-server/app/Controllers/Http/ServiceController.js
@@ -2,7 +2,7 @@ const Service = use('App/Models/Service');
2const { validateAll } = use('Validator'); 2const { validateAll } = use('Validator');
3const Env = use('Env'); 3const Env = use('Env');
4 4
5const uuid = require('uuid/v4'); 5const { v4: uuid } = require('uuid');
6const path = require('path'); 6const path = require('path');
7const fs = require('fs-extra'); 7const fs = require('fs-extra');
8const { LOCAL_HOSTNAME } = require('../../../../config'); 8const { LOCAL_HOSTNAME } = require('../../../../config');
@@ -156,9 +156,7 @@ class ServiceController {
156 id, 156 id,
157 name: service.name, 157 name: service.name,
158 ...newSettings, 158 ...newSettings,
159 iconUrl: `http://${hostname}:${port}/v1/icon/${ 159 iconUrl: `http://${hostname}:${port}/v1/icon/${newSettings.iconId}`,
160 newSettings.iconId
161 }`,
162 userId: 1, 160 userId: 1,
163 }, 161 },
164 status: ['updated'], 162 status: ['updated'],
diff --git a/src/internal-server/app/Controllers/Http/UserController.js b/src/internal-server/app/Controllers/Http/UserController.js
index a3ad736fa..e387e39c4 100644
--- a/src/internal-server/app/Controllers/Http/UserController.js
+++ b/src/internal-server/app/Controllers/Http/UserController.js
@@ -1,41 +1,38 @@
1const User = use('App/Models/User'); 1const User = use('App/Models/User');
2const Service = use('App/Models/Service'); 2const Service = use('App/Models/Service');
3const Workspace = use('App/Models/Workspace'); 3const Workspace = use('App/Models/Workspace');
4const { 4const { validateAll } = use('Validator');
5 validateAll,
6} = use('Validator');
7 5
8const btoa = require('btoa'); 6const btoa = require('btoa');
9const fetch = require('node-fetch'); 7const fetch = require('node-fetch');
10const uuid = require('uuid/v4'); 8const { v4: uuid } = require('uuid');
11const crypto = require('crypto'); 9const crypto = require('crypto');
12const { DEFAULT_APP_SETTINGS } = require('../../../../environment'); 10const { DEFAULT_APP_SETTINGS } = require('../../../../environment');
13 11
14const apiRequest = (url, route, method, auth) => new Promise((resolve, reject) => { 12const apiRequest = (url, route, method, auth) =>
15 const base = `${url}/v1/`; 13 new Promise((resolve, reject) => {
16 const user = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Ferdi/5.3.0-beta.1 Chrome/69.0.3497.128 Electron/4.2.4 Safari/537.36'; 14 const base = `${url}/v1/`;
15 const user =
16 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Ferdi/5.3.0-beta.1 Chrome/69.0.3497.128 Electron/4.2.4 Safari/537.36';
17 17
18 try { 18 try {
19 fetch(base + route, { 19 fetch(base + route, {
20 method, 20 method,
21 headers: { 21 headers: {
22 Authorization: `Bearer ${auth}`, 22 Authorization: `Bearer ${auth}`,
23 'User-Agent': user, 23 'User-Agent': user,
24 }, 24 },
25 }) 25 })
26 .then(data => data.json()) 26 .then(data => data.json())
27 .then(json => resolve(json)); 27 .then(json => resolve(json));
28 } catch (e) { 28 } catch (e) {
29 reject(); 29 reject();
30 } 30 }
31}); 31 });
32 32
33class UserController { 33class UserController {
34 // Register a new user 34 // Register a new user
35 async signup({ 35 async signup({ request, response }) {
36 request,
37 response,
38 }) {
39 // Validate user input 36 // Validate user input
40 const validation = await validateAll(request.all(), { 37 const validation = await validateAll(request.all(), {
41 firstname: 'required', 38 firstname: 'required',
@@ -52,15 +49,13 @@ class UserController {
52 49
53 return response.send({ 50 return response.send({
54 message: 'Successfully created account', 51 message: 'Successfully created account',
55 token: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJGZXJkaSBJbnRlcm5hbCBTZXJ2ZXIiLCJpYXQiOjE1NzEwNDAyMTUsImV4cCI6MjUzMzk1NDE3ODQ0LCJhdWQiOiJnZXRmZXJkaS5jb20iLCJzdWIiOiJmZXJkaUBsb2NhbGhvc3QiLCJ1c2VySWQiOiIxIn0.9_TWFGp6HROv8Yg82Rt6i1-95jqWym40a-HmgrdMC6M', 52 token:
53 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJGZXJkaSBJbnRlcm5hbCBTZXJ2ZXIiLCJpYXQiOjE1NzEwNDAyMTUsImV4cCI6MjUzMzk1NDE3ODQ0LCJhdWQiOiJnZXRmZXJkaS5jb20iLCJzdWIiOiJmZXJkaUBsb2NhbGhvc3QiLCJ1c2VySWQiOiIxIn0.9_TWFGp6HROv8Yg82Rt6i1-95jqWym40a-HmgrdMC6M',
56 }); 54 });
57 } 55 }
58 56
59 // Login using an existing user 57 // Login using an existing user
60 async login({ 58 async login({ request, response }) {
61 request,
62 response,
63 }) {
64 if (!request.header('Authorization')) { 59 if (!request.header('Authorization')) {
65 return response.status(401).send({ 60 return response.status(401).send({
66 message: 'Please provide authorization', 61 message: 'Please provide authorization',
@@ -70,17 +65,19 @@ class UserController {
70 65
71 return response.send({ 66 return response.send({
72 message: 'Successfully logged in', 67 message: 'Successfully logged in',
73 token: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJGZXJkaSBJbnRlcm5hbCBTZXJ2ZXIiLCJpYXQiOjE1NzEwNDAyMTUsImV4cCI6MjUzMzk1NDE3ODQ0LCJhdWQiOiJnZXRmZXJkaS5jb20iLCJzdWIiOiJmZXJkaUBsb2NhbGhvc3QiLCJ1c2VySWQiOiIxIn0.9_TWFGp6HROv8Yg82Rt6i1-95jqWym40a-HmgrdMC6M', 68 token:
69 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJGZXJkaSBJbnRlcm5hbCBTZXJ2ZXIiLCJpYXQiOjE1NzEwNDAyMTUsImV4cCI6MjUzMzk1NDE3ODQ0LCJhdWQiOiJnZXRmZXJkaS5jb20iLCJzdWIiOiJmZXJkaUBsb2NhbGhvc3QiLCJ1c2VySWQiOiIxIn0.9_TWFGp6HROv8Yg82Rt6i1-95jqWym40a-HmgrdMC6M',
74 }); 70 });
75 } 71 }
76 72
77 // Return information about the current user 73 // Return information about the current user
78 async me({ 74 async me({ response }) {
79 response,
80 }) {
81 const user = await User.find(1); 75 const user = await User.find(1);
82 76
83 const settings = typeof user.settings === 'string' ? JSON.parse(user.settings) : user.settings; 77 const settings =
78 typeof user.settings === 'string'
79 ? JSON.parse(user.settings)
80 : user.settings;
84 81
85 return response.send({ 82 return response.send({
86 accountType: 'individual', 83 accountType: 'individual',
@@ -94,14 +91,11 @@ class UserController {
94 isSubscriptionOwner: true, 91 isSubscriptionOwner: true,
95 lastname: 'Application', 92 lastname: 'Application',
96 locale: DEFAULT_APP_SETTINGS.fallbackLocale, 93 locale: DEFAULT_APP_SETTINGS.fallbackLocale,
97 ...settings || {}, 94 ...(settings || {}),
98 }); 95 });
99 } 96 }
100 97
101 async updateMe({ 98 async updateMe({ request, response }) {
102 request,
103 response,
104 }) {
105 const user = await User.find(1); 99 const user = await User.find(1);
106 100
107 let settings = user.settings || {}; 101 let settings = user.settings || {};
@@ -132,16 +126,11 @@ class UserController {
132 locale: DEFAULT_APP_SETTINGS.fallbackLocale, 126 locale: DEFAULT_APP_SETTINGS.fallbackLocale,
133 ...newSettings, 127 ...newSettings,
134 }, 128 },
135 status: [ 129 status: ['data-updated'],
136 'data-updated',
137 ],
138 }); 130 });
139 } 131 }
140 132
141 async import({ 133 async import({ request, response }) {
142 request,
143 response,
144 }) {
145 // Validate user input 134 // Validate user input
146 const validation = await validateAll(request.all(), { 135 const validation = await validateAll(request.all(), {
147 email: 'required|email', 136 email: 'required|email',
@@ -149,7 +138,8 @@ class UserController {
149 server: 'required', 138 server: 'required',
150 }); 139 });
151 if (validation.fails()) { 140 if (validation.fails()) {
152 let errorMessage = 'There was an error while trying to import your account:\n'; 141 let errorMessage =
142 'There was an error while trying to import your account:\n';
153 for (const message of validation.messages()) { 143 for (const message of validation.messages()) {
154 if (message.validation === 'required') { 144 if (message.validation === 'required') {
155 errorMessage += `- Please make sure to supply your ${message.field}\n`; 145 errorMessage += `- Please make sure to supply your ${message.field}\n`;
@@ -162,16 +152,16 @@ class UserController {
162 return response.status(401).send(errorMessage); 152 return response.status(401).send(errorMessage);
163 } 153 }
164 154
165 const { 155 const { email, password, server } = request.all();
166 email,
167 password,
168 server,
169 } = request.all();
170 156
171 const hashedPassword = crypto.createHash('sha256').update(password).digest('base64'); 157 const hashedPassword = crypto
158 .createHash('sha256')
159 .update(password)
160 .digest('base64');
172 161
173 const base = `${server}/v1/`; 162 const base = `${server}/v1/`;
174 const userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Ferdi/5.3.0-beta.1 Chrome/69.0.3497.128 Electron/4.2.4 Safari/537.36'; 163 const userAgent =
164 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Ferdi/5.3.0-beta.1 Chrome/69.0.3497.128 Electron/4.2.4 Safari/537.36';
175 165
176 // Try to get an authentication token 166 // Try to get an authentication token
177 let token; 167 let token;
@@ -188,7 +178,8 @@ class UserController {
188 const content = await rawResponse.json(); 178 const content = await rawResponse.json();
189 179
190 if (!content.message || content.message !== 'Successfully logged in') { 180 if (!content.message || content.message !== 'Successfully logged in') {
191 const errorMessage = 'Could not login into Franz with your supplied credentials. Please check and try again'; 181 const errorMessage =
182 'Could not login into Franz with your supplied credentials. Please check and try again';
192 return response.status(401).send(errorMessage); 183 return response.status(401).send(errorMessage);
193 } 184 }
194 185
@@ -210,7 +201,8 @@ class UserController {
210 return response.status(401).send(errorMessage); 201 return response.status(401).send(errorMessage);
211 } 202 }
212 if (!userInf) { 203 if (!userInf) {
213 const errorMessage = 'Could not get your user info from Franz. Please check your credentials or try again later'; 204 const errorMessage =
205 'Could not get your user info from Franz. Please check your credentials or try again later';
214 return response.status(401).send(errorMessage); 206 return response.status(401).send(errorMessage);
215 } 207 }
216 208
@@ -225,9 +217,14 @@ class UserController {
225 let serviceId; 217 let serviceId;
226 do { 218 do {
227 serviceId = uuid(); 219 serviceId = uuid();
228 } while ((await Service.query().where('serviceId', serviceId).fetch()).rows.length > 0); // eslint-disable-line no-await-in-loop 220 } while (
229 221 // eslint-disable-next-line no-await-in-loop
230 await Service.create({ // eslint-disable-line no-await-in-loop 222 (await Service.query().where('serviceId', serviceId).fetch()).rows
223 .length > 0
224 );
225
226 // eslint-disable-next-line no-await-in-loop
227 await Service.create({
231 serviceId, 228 serviceId,
232 name: service.name, 229 name: service.name,
233 recipeId: service.recipeId, 230 recipeId: service.recipeId,
@@ -249,11 +246,18 @@ class UserController {
249 let workspaceId; 246 let workspaceId;
250 do { 247 do {
251 workspaceId = uuid(); 248 workspaceId = uuid();
252 } while ((await Workspace.query().where('workspaceId', workspaceId).fetch()).rows.length > 0); // eslint-disable-line no-await-in-loop 249 } while (
253 250 // eslint-disable-next-line no-await-in-loop
254 const services = workspace.services.map(service => serviceIdTranslation[service]); 251 (await Workspace.query().where('workspaceId', workspaceId).fetch())
255 252 .rows.length > 0
256 await Workspace.create({ // eslint-disable-line no-await-in-loop 253 );
254
255 const services = workspace.services.map(
256 service => serviceIdTranslation[service],
257 );
258
259 // eslint-disable-next-line no-await-in-loop
260 await Workspace.create({
257 workspaceId, 261 workspaceId,
258 name: workspace.name, 262 name: workspace.name,
259 order: workspace.order, 263 order: workspace.order,
@@ -266,7 +270,9 @@ class UserController {
266 return response.status(401).send(errorMessage); 270 return response.status(401).send(errorMessage);
267 } 271 }
268 272
269 return response.send('Your account has been imported. You can now use your Franz account in Ferdi.'); 273 return response.send(
274 'Your account has been imported. You can now use your Franz account in Ferdi.',
275 );
270 } 276 }
271 277
272 // Account import/export 278 // Account import/export
@@ -291,10 +297,7 @@ class UserController {
291 .send(exportData); 297 .send(exportData);
292 } 298 }
293 299
294 async importFerdi({ 300 async importFerdi({ request, response }) {
295 request,
296 response,
297 }) {
298 const validation = await validateAll(request.all(), { 301 const validation = await validateAll(request.all(), {
299 file: 'required', 302 file: 'required',
300 }); 303 });
@@ -306,7 +309,9 @@ class UserController {
306 try { 309 try {
307 file = JSON.parse(request.input('file')); 310 file = JSON.parse(request.input('file'));
308 } catch (e) { 311 } catch (e) {
309 return response.send('Could not import: Invalid file, could not read file'); 312 return response.send(
313 'Could not import: Invalid file, could not read file',
314 );
310 } 315 }
311 316
312 if (!file || !file.services || !file.workspaces) { 317 if (!file || !file.services || !file.workspaces) {
@@ -322,9 +327,14 @@ class UserController {
322 let serviceId; 327 let serviceId;
323 do { 328 do {
324 serviceId = uuid(); 329 serviceId = uuid();
325 } while ((await Service.query().where('serviceId', serviceId).fetch()).rows.length > 0); // eslint-disable-line no-await-in-loop 330 } while (
326 331 // eslint-disable-next-line no-await-in-loop
327 await Service.create({ // eslint-disable-line no-await-in-loop 332 (await Service.query().where('serviceId', serviceId).fetch()).rows
333 .length > 0
334 );
335
336 // eslint-disable-next-line no-await-in-loop
337 await Service.create({
328 serviceId, 338 serviceId,
329 name: service.name, 339 name: service.name,
330 recipeId: service.recipeId, 340 recipeId: service.recipeId,
@@ -344,13 +354,19 @@ class UserController {
344 let workspaceId; 354 let workspaceId;
345 do { 355 do {
346 workspaceId = uuid(); 356 workspaceId = uuid();
347 } while ((await Workspace.query().where('workspaceId', workspaceId).fetch()).rows.length > 0); // eslint-disable-line no-await-in-loop 357 } while (
348 358 // eslint-disable-next-line no-await-in-loop
349 const services = (workspace.services && typeof (workspace.services) === 'object') ? 359 (await Workspace.query().where('workspaceId', workspaceId).fetch())
350 workspace.services.map((service) => serviceIdTranslation[service]) : 360 .rows.length > 0
351 []; 361 );
352 362
353 await Workspace.create({ // eslint-disable-line no-await-in-loop 363 const services =
364 workspace.services && typeof workspace.services === 'object'
365 ? workspace.services.map(service => serviceIdTranslation[service])
366 : [];
367
368 // eslint-disable-next-line no-await-in-loop
369 await Workspace.create({
354 workspaceId, 370 workspaceId,
355 name: workspace.name, 371 name: workspace.name,
356 order: workspace.order, 372 order: workspace.order,
diff --git a/src/internal-server/app/Controllers/Http/WorkspaceController.js b/src/internal-server/app/Controllers/Http/WorkspaceController.js
index 4189fbcdd..f1a5ddf2b 100644
--- a/src/internal-server/app/Controllers/Http/WorkspaceController.js
+++ b/src/internal-server/app/Controllers/Http/WorkspaceController.js
@@ -1,16 +1,11 @@
1const Workspace = use('App/Models/Workspace'); 1const Workspace = use('App/Models/Workspace');
2const { 2const { validateAll } = use('Validator');
3 validateAll,
4} = use('Validator');
5 3
6const uuid = require('uuid/v4'); 4const { v4: uuid } = require('uuid');
7 5
8class WorkspaceController { 6class WorkspaceController {
9 // Create a new workspace for user 7 // Create a new workspace for user
10 async create({ 8 async create({ request, response }) {
11 request,
12 response,
13 }) {
14 // Validate user input 9 // Validate user input
15 const validation = await validateAll(request.all(), { 10 const validation = await validateAll(request.all(), {
16 name: 'required', 11 name: 'required',
@@ -29,7 +24,10 @@ class WorkspaceController {
29 let workspaceId; 24 let workspaceId;
30 do { 25 do {
31 workspaceId = uuid(); 26 workspaceId = uuid();
32 } while ((await Workspace.query().where('workspaceId', workspaceId).fetch()).rows.length > 0); // eslint-disable-line no-await-in-loop 27 } while (
28 (await Workspace.query().where('workspaceId', workspaceId).fetch()).rows
29 .length > 0
30 ); // eslint-disable-line no-await-in-loop
33 31
34 const order = (await Workspace.all()).rows.length; 32 const order = (await Workspace.all()).rows.length;
35 33
@@ -50,11 +48,7 @@ class WorkspaceController {
50 }); 48 });
51 } 49 }
52 50
53 async edit({ 51 async edit({ request, response, params }) {
54 request,
55 response,
56 params,
57 }) {
58 // Validate user input 52 // Validate user input
59 const validation = await validateAll(request.all(), { 53 const validation = await validateAll(request.all(), {
60 name: 'required', 54 name: 'required',
@@ -69,20 +63,19 @@ class WorkspaceController {
69 } 63 }
70 64
71 const data = request.all(); 65 const data = request.all();
72 const { 66 const { id } = params;
73 id,
74 } = params;
75 67
76 // Update data in database 68 // Update data in database
77 await (Workspace.query() 69 await Workspace.query()
78 .where('workspaceId', id)).update({ 70 .where('workspaceId', id)
79 name: data.name, 71 .update({
80 services: JSON.stringify(data.services), 72 name: data.name,
81 }); 73 services: JSON.stringify(data.services),
74 });
82 75
83 // Get updated row 76 // Get updated row
84 const workspace = (await Workspace.query() 77 const workspace = (await Workspace.query().where('workspaceId', id).fetch())
85 .where('workspaceId', id).fetch()).rows[0]; 78 .rows[0];
86 79
87 return response.send({ 80 return response.send({
88 id: workspace.workspaceId, 81 id: workspace.workspaceId,
@@ -111,13 +104,10 @@ class WorkspaceController {
111 }); 104 });
112 } 105 }
113 106
114 const { 107 const { id } = params;
115 id,
116 } = params;
117 108
118 // Update data in database 109 // Update data in database
119 await (Workspace.query() 110 await Workspace.query().where('workspaceId', id).delete();
120 .where('workspaceId', id)).delete();
121 111
122 return response.send({ 112 return response.send({
123 message: 'Successfully deleted workspace', 113 message: 'Successfully deleted workspace',
@@ -125,9 +115,7 @@ class WorkspaceController {
125 } 115 }
126 116
127 // List all workspaces a user has created 117 // List all workspaces a user has created
128 async list({ 118 async list({ response }) {
129 response,
130 }) {
131 const workspaces = (await Workspace.all()).rows; 119 const workspaces = (await Workspace.all()).rows;
132 // Convert to array with all data Franz wants 120 // Convert to array with all data Franz wants
133 let workspacesArray = []; 121 let workspacesArray = [];
@@ -136,7 +124,10 @@ class WorkspaceController {
136 id: workspace.workspaceId, 124 id: workspace.workspaceId,
137 name: workspace.name, 125 name: workspace.name,
138 order: workspace.order, 126 order: workspace.order,
139 services: typeof workspace.services === 'string' ? JSON.parse(workspace.services) : workspace.services, 127 services:
128 typeof workspace.services === 'string'
129 ? JSON.parse(workspace.services)
130 : workspace.services,
140 userId: 1, 131 userId: 1,
141 })); 132 }));
142 } 133 }
diff --git a/src/lib/Tray.js b/src/lib/Tray.js
index f5970f7e7..c629e212d 100644
--- a/src/lib/Tray.js
+++ b/src/lib/Tray.js
@@ -1,8 +1,14 @@
1import { 1import {
2 app, Menu, nativeImage, nativeTheme, systemPreferences, Tray, ipcMain, 2 app,
3 Menu,
4 nativeImage,
5 nativeTheme,
6 systemPreferences,
7 Tray,
8 ipcMain,
3} from 'electron'; 9} from 'electron';
4import { join } from 'path'; 10import { join } from 'path';
5import macosVersion from 'macos-version'; 11import { isMacOSVersionGreaterThanOrEqualTo } from 'macos-version';
6import { isMac, isWindows, isLinux } from '../environment'; 12import { isMac, isWindows, isLinux } from '../environment';
7 13
8const FILE_EXTENSION = isWindows ? 'ico' : 'png'; 14const FILE_EXTENSION = isWindows ? 'ico' : 'png';
@@ -64,7 +70,9 @@ export default class TrayIcon {
64 70
65 if (appSettings.type === 'app') { 71 if (appSettings.type === 'app') {
66 const { isAppMuted } = appSettings.data; 72 const { isAppMuted } = appSettings.data;
67 this.trayMenuTemplate[1].label = isAppMuted ? 'Enable Notifications && Audio' : 'Disable Notifications && Audio'; 73 this.trayMenuTemplate[1].label = isAppMuted
74 ? 'Enable Notifications && Audio'
75 : 'Disable Notifications && Audio';
68 this.trayMenu = Menu.buildFromTemplate(this.trayMenuTemplate); 76 this.trayMenu = Menu.buildFromTemplate(this.trayMenuTemplate);
69 if (isLinux) { 77 if (isLinux) {
70 this.trayIcon.setContextMenu(this.trayMenu); 78 this.trayIcon.setContextMenu(this.trayMenu);
@@ -107,9 +115,12 @@ export default class TrayIcon {
107 } 115 }
108 116
109 if (isMac) { 117 if (isMac) {
110 this.themeChangeSubscriberId = systemPreferences.subscribeNotification('AppleInterfaceThemeChangedNotification', () => { 118 this.themeChangeSubscriberId = systemPreferences.subscribeNotification(
111 this._refreshIcon(); 119 'AppleInterfaceThemeChangedNotification',
112 }); 120 () => {
121 this._refreshIcon();
122 },
123 );
113 } 124 }
114 } 125 }
115 126
@@ -149,7 +160,8 @@ export default class TrayIcon {
149 _getAssetFromIndicator(indicator) { 160 _getAssetFromIndicator(indicator) {
150 if (indicator === '•') { 161 if (indicator === '•') {
151 return INDICATOR_TRAY_INDIRECT; 162 return INDICATOR_TRAY_INDIRECT;
152 } if (indicator !== 0) { 163 }
164 if (indicator !== 0) {
153 return INDICATOR_TRAY_UNREAD; 165 return INDICATOR_TRAY_UNREAD;
154 } 166 }
155 return INDICATOR_TRAY_PLAIN; 167 return INDICATOR_TRAY_PLAIN;
@@ -158,11 +170,16 @@ export default class TrayIcon {
158 _refreshIcon() { 170 _refreshIcon() {
159 if (!this.trayIcon) return; 171 if (!this.trayIcon) return;
160 172
161 this.trayIcon.setImage(this._getAsset('tray', this._getAssetFromIndicator(this.indicator))); 173 this.trayIcon.setImage(
174 this._getAsset('tray', this._getAssetFromIndicator(this.indicator)),
175 );
162 176
163 if (isMac) { 177 if (isMac) {
164 this.trayIcon.setPressedImage( 178 this.trayIcon.setPressedImage(
165 this._getAsset('tray', `${this._getAssetFromIndicator(this.indicator)}-active`), 179 this._getAsset(
180 'tray',
181 `${this._getAssetFromIndicator(this.indicator)}-active`,
182 ),
166 ); 183 );
167 } 184 }
168 } 185 }
@@ -170,12 +187,24 @@ export default class TrayIcon {
170 _getAsset(type, asset) { 187 _getAsset(type, asset) {
171 let { platform } = process; 188 let { platform } = process;
172 189
173 if (isMac && (nativeTheme.shouldUseDarkColors || macosVersion.isGreaterThanOrEqualTo('11'))) { 190 if (
191 isMac &&
192 (nativeTheme.shouldUseDarkColors ||
193 isMacOSVersionGreaterThanOrEqualTo('11'))
194 ) {
174 platform = `${platform}-dark`; 195 platform = `${platform}-dark`;
175 } 196 }
176 197
177 return nativeImage.createFromPath(join( 198 return nativeImage.createFromPath(
178 __dirname, '..', 'assets', 'images', type, platform, `${asset}.${FILE_EXTENSION}`, 199 join(
179 )); 200 __dirname,
201 '..',
202 'assets',
203 'images',
204 type,
205 platform,
206 `${asset}.${FILE_EXTENSION}`,
207 ),
208 );
180 } 209 }
181} 210}
diff --git a/src/webview/notifications.js b/src/webview/notifications.js
index 205a3220c..73cdb89d4 100644
--- a/src/webview/notifications.js
+++ b/src/webview/notifications.js
@@ -1,22 +1,25 @@
1import { ipcRenderer } from 'electron'; 1import { ipcRenderer } from 'electron';
2import uuidV1 from 'uuid/v1'; 2import { v1 as uuidV1 } from 'uuid';
3 3
4const debug = require('debug')('Ferdi:Notifications'); 4const debug = require('debug')('Ferdi:Notifications');
5 5
6export class NotificationsHandler { 6export class NotificationsHandler {
7 onNotify = (data) => data; 7 onNotify = data => data;
8 8
9 displayNotification(title, options) { 9 displayNotification(title, options) {
10 return new Promise((resolve) => { 10 return new Promise(resolve => {
11 debug('New notification', title, options); 11 debug('New notification', title, options);
12 12
13 const notificationId = uuidV1(); 13 const notificationId = uuidV1();
14 14
15 ipcRenderer.sendToHost('notification', this.onNotify({ 15 ipcRenderer.sendToHost(
16 title, 16 'notification',
17 options, 17 this.onNotify({
18 notificationId, 18 title,
19 })); 19 options,
20 notificationId,
21 }),
22 );
20 23
21 ipcRenderer.once(`notification-onclick:${notificationId}`, () => { 24 ipcRenderer.once(`notification-onclick:${notificationId}`, () => {
22 resolve(); 25 resolve();