aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md6
-rw-r--r--package-lock.json5
-rw-r--r--package.json2
-rw-r--r--src/stores/AppStore.js62
-rw-r--r--src/stores/UserStore.js66
5 files changed, 61 insertions, 80 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 68a7df1c5..13c69db18 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
1# [v5.6.1-nightly.33](https://github.com/getferdi/ferdi/compare/v5.6.1-nightly.32...v5.6.1-nightly.33) (2021-08-19)
2
3### Bug Fixes
4
5- Reverted back to `moment.js` from `day.js` due to bug #1811 💖 @vraravam
6
1# [v5.6.1-nightly.32](https://github.com/getferdi/ferdi/compare/v5.6.1-nightly.30...v5.6.1-nightly.32) (2021-08-18) 7# [v5.6.1-nightly.32](https://github.com/getferdi/ferdi/compare/v5.6.1-nightly.30...v5.6.1-nightly.32) (2021-08-18)
2 8
3- Sorted the recipes according to their service name in the 'Add new Service' screen 💖 @vraravam 9- Sorted the recipes according to their service name in the 'Add new Service' screen 💖 @vraravam
diff --git a/package-lock.json b/package-lock.json
index 68f9b25d8..b8ce3c4f5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11614,11 +11614,6 @@
11614 "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", 11614 "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==",
11615 "dev": true 11615 "dev": true
11616 }, 11616 },
11617 "dayjs": {
11618 "version": "1.10.6",
11619 "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.6.tgz",
11620 "integrity": "sha512-AztC/IOW4L1Q41A86phW5Thhcrco3xuAA+YX/BLpLWWjRcTj5TOt/QImBLmCKlrF7u7k47arTnOyL6GnbG8Hvw=="
11621 },
11622 "dbus-next": { 11617 "dbus-next": {
11623 "version": "0.9.2", 11618 "version": "0.9.2",
11624 "resolved": "https://registry.npmjs.org/dbus-next/-/dbus-next-0.9.2.tgz", 11619 "resolved": "https://registry.npmjs.org/dbus-next/-/dbus-next-0.9.2.tgz",
diff --git a/package.json b/package.json
index 15534b1a7..1ad918693 100644
--- a/package.json
+++ b/package.json
@@ -75,7 +75,6 @@
75 "css": "2.2.4", 75 "css": "2.2.4",
76 "csstype": "3.0.8", 76 "csstype": "3.0.8",
77 "darkreader": "4.9.34", 77 "darkreader": "4.9.34",
78 "dayjs": "1.10.6",
79 "dbus-next": "0.9.2", 78 "dbus-next": "0.9.2",
80 "debug": "4.3.2", 79 "debug": "4.3.2",
81 "du": "1.0.0", 80 "du": "1.0.0",
@@ -100,6 +99,7 @@
100 "mobx-react": "5.4.2", 99 "mobx-react": "5.4.2",
101 "mobx-react-form": "1.35.1", 100 "mobx-react-form": "1.35.1",
102 "mobx-react-router": "3.1.2", 101 "mobx-react-router": "3.1.2",
102 "moment": "2.29.1",
103 "ms": "2.1.3", 103 "ms": "2.1.3",
104 "node-fetch": "2.6.1", 104 "node-fetch": "2.6.1",
105 "node-mac-permissions": "2.2.0", 105 "node-mac-permissions": "2.2.0",
diff --git a/src/stores/AppStore.js b/src/stores/AppStore.js
index 71213774d..9c8cce679 100644
--- a/src/stores/AppStore.js
+++ b/src/stores/AppStore.js
@@ -8,7 +8,7 @@ import {
8 process as remoteProcess, 8 process as remoteProcess,
9} from '@electron/remote'; 9} from '@electron/remote';
10import { action, computed, observable } from 'mobx'; 10import { action, computed, observable } from 'mobx';
11import dayjs from 'dayjs'; 11import moment from 'moment';
12import AutoLaunch from 'auto-launch'; 12import AutoLaunch from 'auto-launch';
13import ms from 'ms'; 13import ms from 'ms';
14import { URL } from 'url'; 14import { URL } from 'url';
@@ -48,8 +48,7 @@ const autoLauncher = new AutoLaunch({
48 path: executablePath, 48 path: executablePath,
49}); 49});
50 50
51const CATALINA_NOTIFICATION_HACK_KEY = 51const CATALINA_NOTIFICATION_HACK_KEY = '_temp_askedForCatalinaNotificationPermissions';
52 '_temp_askedForCatalinaNotificationPermissions';
53 52
54export default class AppStore extends Store { 53export default class AppStore extends Store {
55 updateStatusTypes = { 54 updateStatusTypes = {
@@ -75,7 +74,7 @@ export default class AppStore extends Store {
75 74
76 @observable authRequestFailed = false; 75 @observable authRequestFailed = false;
77 76
78 @observable timeSuspensionStart = dayjs(); 77 @observable timeSuspensionStart = moment();
79 78
80 @observable timeOfflineStart; 79 @observable timeOfflineStart;
81 80
@@ -229,7 +228,7 @@ export default class AppStore extends Store {
229 powerMonitor.on('suspend', () => { 228 powerMonitor.on('suspend', () => {
230 debug('System suspended starting timer'); 229 debug('System suspended starting timer');
231 230
232 this.timeSuspensionStart = dayjs(); 231 this.timeSuspensionStart = moment();
233 }); 232 });
234 233
235 powerMonitor.on('resume', () => { 234 powerMonitor.on('resume', () => {
@@ -237,8 +236,8 @@ export default class AppStore extends Store {
237 this.actions.service.resetLastPollTimer(); 236 this.actions.service.resetLastPollTimer();
238 237
239 if ( 238 if (
240 this.timeSuspensionStart.add(10, 'm').isBefore(dayjs()) && 239 this.timeSuspensionStart.add(10, 'm').isBefore(moment())
241 this.stores.settings.app.get('reloadAfterResume') 240 && this.stores.settings.app.get('reloadAfterResume')
242 ) { 241 ) {
243 debug('Reloading services, user info and features'); 242 debug('Reloading services, user info and features');
244 243
@@ -284,15 +283,15 @@ export default class AppStore extends Store {
284 ferdi: { 283 ferdi: {
285 version: ferdiVersion, 284 version: ferdiVersion,
286 electron: electronVersion, 285 electron: electronVersion,
287 installedRecipes: this.stores.recipes.all.map(recipe => ({ 286 installedRecipes: this.stores.recipes.all.map((recipe) => ({
288 id: recipe.id, 287 id: recipe.id,
289 version: recipe.version, 288 version: recipe.version,
290 })), 289 })),
291 devRecipes: this.stores.recipePreviews.dev.map(recipe => ({ 290 devRecipes: this.stores.recipePreviews.dev.map((recipe) => ({
292 id: recipe.id, 291 id: recipe.id,
293 version: recipe.version, 292 version: recipe.version,
294 })), 293 })),
295 services: this.stores.services.all.map(service => ({ 294 services: this.stores.services.all.map((service) => ({
296 id: service.id, 295 id: service.id,
297 recipe: service.recipe.id, 296 recipe: service.recipe.id,
298 isAttached: service.isAttached, 297 isAttached: service.isAttached,
@@ -303,7 +302,7 @@ export default class AppStore extends Store {
303 isDarkModeEnabled: service.isDarkModeEnabled, 302 isDarkModeEnabled: service.isDarkModeEnabled,
304 })), 303 })),
305 messages: this.stores.globalError.messages, 304 messages: this.stores.globalError.messages,
306 workspaces: this.stores.workspaces.workspaces.map(workspace => ({ 305 workspaces: this.stores.workspaces.workspaces.map((workspace) => ({
307 id: workspace.id, 306 id: workspace.id,
308 services: workspace.services, 307 services: workspace.services,
309 })), 308 })),
@@ -316,7 +315,9 @@ export default class AppStore extends Store {
316 } 315 }
317 316
318 // Actions 317 // Actions
319 @action _notify({ title, options, notificationId, serviceId = null }) { 318 @action _notify({
319 title, options, notificationId, serviceId = null,
320 }) {
320 if (this.stores.settings.all.app.isAppMuted) return; 321 if (this.stores.settings.all.app.isAppMuted) return;
321 322
322 // TODO: is there a simple way to use blobs for notifications without storing them on disk? 323 // TODO: is there a simple way to use blobs for notifications without storing them on disk?
@@ -358,8 +359,8 @@ export default class AppStore extends Store {
358 if (indicator === 0 && unreadIndirectMessageCount !== 0) { 359 if (indicator === 0 && unreadIndirectMessageCount !== 0) {
359 indicator = '•'; 360 indicator = '•';
360 } else if ( 361 } else if (
361 unreadDirectMessageCount === 0 && 362 unreadDirectMessageCount === 0
362 unreadIndirectMessageCount === 0 363 && unreadIndirectMessageCount === 0
363 ) { 364 ) {
364 indicator = 0; 365 indicator = 0;
365 } else { 366 } else {
@@ -440,25 +441,22 @@ export default class AppStore extends Store {
440 const clearAppCache = this.clearAppCacheRequest.execute(); 441 const clearAppCache = this.clearAppCacheRequest.execute();
441 const allServiceIds = await getServiceIdsFromPartitions(); 442 const allServiceIds = await getServiceIdsFromPartitions();
442 const allOrphanedServiceIds = allServiceIds.filter( 443 const allOrphanedServiceIds = allServiceIds.filter(
443 id => 444 (id) => !this.stores.services.all.find(
444 !this.stores.services.all.find( 445 (s) => id.replace('service-', '') === s.id,
445 s => id.replace('service-', '') === s.id, 446 ),
446 ),
447 ); 447 );
448 448
449 try { 449 try {
450 await Promise.all( 450 await Promise.all(
451 allOrphanedServiceIds.map(id => removeServicePartitionDirectory(id)), 451 allOrphanedServiceIds.map((id) => removeServicePartitionDirectory(id)),
452 ); 452 );
453 } catch (ex) { 453 } catch (ex) {
454 console.log('Error while deleting service partition directory - ', ex); 454 console.log('Error while deleting service partition directory - ', ex);
455 } 455 }
456 await Promise.all( 456 await Promise.all(
457 this.stores.services.all.map(s => 457 this.stores.services.all.map((s) => this.actions.service.clearCache({
458 this.actions.service.clearCache({ 458 serviceId: s.id,
459 serviceId: s.id, 459 })),
460 }),
461 ),
462 ); 460 );
463 461
464 await clearAppCache._promise; 462 await clearAppCache._promise;
@@ -473,9 +471,9 @@ export default class AppStore extends Store {
473 // Reactions 471 // Reactions
474 _offlineCheck() { 472 _offlineCheck() {
475 if (!this.isOnline) { 473 if (!this.isOnline) {
476 this.timeOfflineStart = dayjs(); 474 this.timeOfflineStart = moment();
477 } else { 475 } else {
478 const deltaTime = dayjs().diff(this.timeOfflineStart); 476 const deltaTime = moment().diff(this.timeOfflineStart);
479 477
480 if (deltaTime > ms('30m')) { 478 if (deltaTime > ms('30m')) {
481 this.actions.service.reloadAll(); 479 this.actions.service.reloadAll();
@@ -490,16 +488,16 @@ export default class AppStore extends Store {
490 } 488 }
491 489
492 if ( 490 if (
493 locale && 491 locale
494 Object.prototype.hasOwnProperty.call(locales, locale) && 492 && Object.prototype.hasOwnProperty.call(locales, locale)
495 locale !== this.locale 493 && locale !== this.locale
496 ) { 494 ) {
497 this.locale = locale; 495 this.locale = locale;
498 } else if (!locale) { 496 } else if (!locale) {
499 this.locale = this._getDefaultLocale(); 497 this.locale = this._getDefaultLocale();
500 } 498 }
501 499
502 dayjs.locale(this.locale); 500 moment.locale(this.locale);
503 501
504 debug(`Set locale to "${this.locale}"`); 502 debug(`Set locale to "${this.locale}"`);
505 } 503 }
@@ -571,8 +569,8 @@ export default class AppStore extends Store {
571 debug('Do not disturb mode is', dnd); 569 debug('Do not disturb mode is', dnd);
572 // ipcRenderer.on('autoUpdate', (event, data) => { 570 // ipcRenderer.on('autoUpdate', (event, data) => {
573 if ( 571 if (
574 dnd !== this.stores.settings.all.app.isAppMuted && 572 dnd !== this.stores.settings.all.app.isAppMuted
575 !this.isSystemMuteOverridden 573 && !this.isSystemMuteOverridden
576 ) { 574 ) {
577 this.actions.app.muteApp({ 575 this.actions.app.muteApp({
578 isMuted: dnd, 576 isMuted: dnd,
diff --git a/src/stores/UserStore.js b/src/stores/UserStore.js
index 066638613..2e009893a 100644
--- a/src/stores/UserStore.js
+++ b/src/stores/UserStore.js
@@ -1,5 +1,5 @@
1import { observable, computed, action } from 'mobx'; 1import { observable, computed, action } from 'mobx';
2import dayjs from 'dayjs'; 2import moment from 'moment';
3import jwt from 'jsonwebtoken'; 3import jwt from 'jsonwebtoken';
4import localStorage from 'mobx-localstorage'; 4import localStorage from 'mobx-localstorage';
5import { session } from '@electron/remote'; 5import { session } from '@electron/remote';
@@ -46,10 +46,7 @@ export default class UserStore extends Store {
46 46
47 @observable updateUserInfoRequest = new Request(this.api.user, 'updateInfo'); 47 @observable updateUserInfoRequest = new Request(this.api.user, 'updateInfo');
48 48
49 @observable getLegacyServicesRequest = new CachedRequest( 49 @observable getLegacyServicesRequest = new CachedRequest(this.api.user, 'getLegacyServices');
50 this.api.user,
51 'getLegacyServices',
52 );
53 50
54 @observable deleteAccountRequest = new CachedRequest(this.api.user, 'delete'); 51 @observable deleteAccountRequest = new CachedRequest(this.api.user, 'delete');
55 52
@@ -84,17 +81,13 @@ export default class UserStore extends Store {
84 81
85 // Register action handlers 82 // Register action handlers
86 this.actions.user.login.listen(this._login.bind(this)); 83 this.actions.user.login.listen(this._login.bind(this));
87 this.actions.user.retrievePassword.listen( 84 this.actions.user.retrievePassword.listen(this._retrievePassword.bind(this));
88 this._retrievePassword.bind(this),
89 );
90 this.actions.user.logout.listen(this._logout.bind(this)); 85 this.actions.user.logout.listen(this._logout.bind(this));
91 this.actions.user.signup.listen(this._signup.bind(this)); 86 this.actions.user.signup.listen(this._signup.bind(this));
92 this.actions.user.invite.listen(this._invite.bind(this)); 87 this.actions.user.invite.listen(this._invite.bind(this));
93 this.actions.user.update.listen(this._update.bind(this)); 88 this.actions.user.update.listen(this._update.bind(this));
94 this.actions.user.resetStatus.listen(this._resetStatus.bind(this)); 89 this.actions.user.resetStatus.listen(this._resetStatus.bind(this));
95 this.actions.user.importLegacyServices.listen( 90 this.actions.user.importLegacyServices.listen(this._importLegacyServices.bind(this));
96 this._importLegacyServices.bind(this),
97 );
98 this.actions.user.delete.listen(this._delete.bind(this)); 91 this.actions.user.delete.listen(this._delete.bind(this));
99 92
100 // Reactions 93 // Reactions
@@ -151,7 +144,7 @@ export default class UserStore extends Store {
151 if (!this.authToken) return false; 144 if (!this.authToken) return false;
152 145
153 const { tokenExpiry } = this._parseToken(this.authToken); 146 const { tokenExpiry } = this._parseToken(this.authToken);
154 return this.authToken !== null && dayjs(tokenExpiry).isBefore(dayjs()); 147 return this.authToken !== null && moment(tokenExpiry).isBefore(moment());
155 } 148 }
156 149
157 @computed get data() { 150 @computed get data() {
@@ -183,14 +176,7 @@ export default class UserStore extends Store {
183 } 176 }
184 177
185 @action async _signup({ 178 @action async _signup({
186 firstname, 179 firstname, lastname, email, password, accountType, company, plan, currency,
187 lastname,
188 email,
189 password,
190 accountType,
191 company,
192 plan,
193 currency,
194 }) { 180 }) {
195 const authToken = await this.signupRequest.execute({ 181 const authToken = await this.signupRequest.execute({
196 firstname, 182 firstname,
@@ -219,7 +205,7 @@ export default class UserStore extends Store {
219 } 205 }
220 206
221 @action async _invite({ invites }) { 207 @action async _invite({ invites }) {
222 const data = invites.filter(invite => invite.email !== ''); 208 const data = invites.filter((invite) => invite.email !== '');
223 209
224 const response = await this.inviteRequest.execute(data)._promise; 210 const response = await this.inviteRequest.execute(data)._promise;
225 211
@@ -234,8 +220,7 @@ export default class UserStore extends Store {
234 @action async _update({ userData }) { 220 @action async _update({ userData }) {
235 if (!this.isLoggedIn) return; 221 if (!this.isLoggedIn) return;
236 222
237 const response = await this.updateUserInfoRequest.execute(userData) 223 const response = await this.updateUserInfoRequest.execute(userData)._promise;
238 ._promise;
239 224
240 this.getUserInfoRequest.patch(() => response.data); 225 this.getUserInfoRequest.patch(() => response.data);
241 this.actionStatus = response.status || []; 226 this.actionStatus = response.status || [];
@@ -265,20 +250,15 @@ export default class UserStore extends Store {
265 this.isImportLegacyServicesExecuting = true; 250 this.isImportLegacyServicesExecuting = true;
266 251
267 // Reduces recipe duplicates 252 // Reduces recipe duplicates
268 const recipes = services 253 const recipes = services.filter((obj, pos, arr) => arr.map((mapObj) => mapObj.recipe.id).indexOf(obj.recipe.id) === pos).map((s) => s.recipe.id);
269 .filter(
270 (obj, pos, arr) =>
271 arr.map(mapObj => mapObj.recipe.id).indexOf(obj.recipe.id) === pos,
272 )
273 .map(s => s.recipe.id);
274 254
275 // Install recipes 255 // Install recipes
276 for (const recipe of recipes) { 256 for (const recipe of recipes) { // eslint-disable-line no-unused-vars
277 // eslint-disable-next-line 257 // eslint-disable-next-line
278 await this.stores.recipes._install({ recipeId: recipe }); 258 await this.stores.recipes._install({ recipeId: recipe });
279 } 259 }
280 260
281 for (const service of services) { 261 for (const service of services) { // eslint-disable-line no-unused-vars
282 this.actions.service.createFromLegacyService({ 262 this.actions.service.createFromLegacyService({
283 data: service, 263 data: service,
284 }); 264 });
@@ -301,7 +281,8 @@ export default class UserStore extends Store {
301 281
302 const { router } = this.stores; 282 const { router } = this.stores;
303 const currentRoute = window.location.hash; 283 const currentRoute = window.location.hash;
304 if (!this.isLoggedIn && currentRoute.includes('token=')) { 284 if (!this.isLoggedIn
285 && currentRoute.includes('token=')) {
305 router.push(this.WELCOME_ROUTE); 286 router.push(this.WELCOME_ROUTE);
306 const token = currentRoute.split('=')[1]; 287 const token = currentRoute.split('=')[1];
307 288
@@ -312,16 +293,17 @@ export default class UserStore extends Store {
312 this._tokenLogin(token); 293 this._tokenLogin(token);
313 }, 1000); 294 }, 1000);
314 } 295 }
315 } else if (!this.isLoggedIn && !currentRoute.includes(this.BASE_ROUTE)) { 296 } else if (!this.isLoggedIn
297 && !currentRoute.includes(this.BASE_ROUTE)) {
316 router.push(this.WELCOME_ROUTE); 298 router.push(this.WELCOME_ROUTE);
317 } else if (this.isLoggedIn && currentRoute === this.LOGOUT_ROUTE) { 299 } else if (this.isLoggedIn
300 && currentRoute === this.LOGOUT_ROUTE) {
318 this.actions.user.logout(); 301 this.actions.user.logout();
319 router.push(this.LOGIN_ROUTE); 302 router.push(this.LOGIN_ROUTE);
320 } else if ( 303 } else if (this.isLoggedIn
321 this.isLoggedIn && 304 && currentRoute.includes(this.BASE_ROUTE)
322 currentRoute.includes(this.BASE_ROUTE) && 305 && (this.hasCompletedSignup
323 (this.hasCompletedSignup || this.hasCompletedSignup === null) 306 || this.hasCompletedSignup === null)) {
324 ) {
325 if (!isDevMode) { 307 if (!isDevMode) {
326 this.stores.router.push('/'); 308 this.stores.router.push('/');
327 } 309 }
@@ -354,11 +336,11 @@ export default class UserStore extends Store {
354 try { 336 try {
355 const decoded = jwt.decode(authToken); 337 const decoded = jwt.decode(authToken);
356 338
357 return { 339 return ({
358 id: decoded.userId, 340 id: decoded.userId,
359 tokenExpiry: dayjs.unix(decoded.exp).toISOString(), 341 tokenExpiry: moment.unix(decoded.exp).toISOString(),
360 authToken, 342 authToken,
361 }; 343 });
362 } catch (err) { 344 } catch (err) {
363 this._logout(); 345 this._logout();
364 return false; 346 return false;