aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar Vijay A <vraravam@users.noreply.github.com>2022-05-15 01:44:18 -0500
committerLibravatar Vijay Aravamudhan <vraravam@users.noreply.github.com>2022-05-15 19:05:55 -0500
commit082b64b6c40fcab3ecf303f53ce83e7753894a32 (patch)
tree92626869949cc671effce89cfbcd52092243de5c /src
parentfix: revert "Typescript conversion" (#153) (diff)
downloadferdium-app-082b64b6c40fcab3ecf303f53ce83e7753894a32.tar.gz
ferdium-app-082b64b6c40fcab3ecf303f53ce83e7753894a32.tar.zst
ferdium-app-082b64b6c40fcab3ecf303f53ce83e7753894a32.zip
Extract utility functions for JSON parsing
Diffstat (limited to 'src')
-rw-r--r--src/helpers/url-helpers.test.ts2
-rw-r--r--src/internal-server/app/Controllers/Http/RecipeController.js13
-rw-r--r--src/internal-server/app/Controllers/Http/ServiceController.js26
-rw-r--r--src/internal-server/app/Controllers/Http/UserController.js35
-rw-r--r--src/internal-server/app/Controllers/Http/WorkspaceController.js6
-rw-r--r--src/internal-server/start/migrate.js6
-rw-r--r--src/jsUtils.test.ts96
-rw-r--r--src/jsUtils.ts23
-rw-r--r--src/stores/AppStore.js3
-rw-r--r--src/stores/ServicesStore.js7
-rw-r--r--src/webview/lib/Userscript.ts6
11 files changed, 143 insertions, 80 deletions
diff --git a/src/helpers/url-helpers.test.ts b/src/helpers/url-helpers.test.ts
index e6036893e..5af3025e9 100644
--- a/src/helpers/url-helpers.test.ts
+++ b/src/helpers/url-helpers.test.ts
@@ -3,7 +3,7 @@ import * as url_helpers from './url-helpers'
3describe('url_helpers', () => { 3describe('url_helpers', () => {
4 describe('isValidExternalURL', () => { 4 describe('isValidExternalURL', () => {
5 describe('with string', () => { 5 describe('with string', () => {
6 it('returns false for empty string ', () => { 6 it('returns false for empty string', () => {
7 const result = url_helpers.isValidExternalURL(''); 7 const result = url_helpers.isValidExternalURL('');
8 expect(result).toBe(false); 8 expect(result).toBe(false);
9 }); 9 });
diff --git a/src/internal-server/app/Controllers/Http/RecipeController.js b/src/internal-server/app/Controllers/Http/RecipeController.js
index e88a89a0b..eac34aa5c 100644
--- a/src/internal-server/app/Controllers/Http/RecipeController.js
+++ b/src/internal-server/app/Controllers/Http/RecipeController.js
@@ -6,6 +6,7 @@ const Env = use('Env');
6const fetch = require('node-fetch'); 6const fetch = require('node-fetch');
7const debug = require('../../../../preload-safe-debug')('Ferdium:internalServer:RecipeController'); 7const debug = require('../../../../preload-safe-debug')('Ferdium:internalServer:RecipeController');
8const { LIVE_FERDIUM_API } = require('../../../../config'); 8const { LIVE_FERDIUM_API } = require('../../../../config');
9const { convertToJSON } = require('../../../../jsUtils');
9const { API_VERSION } = require('../../../../environment-remote'); 10const { API_VERSION } = require('../../../../environment-remote');
10 11
11const RECIPES_URL = `${LIVE_FERDIUM_API}/${API_VERSION}/recipes`; 12const RECIPES_URL = `${LIVE_FERDIUM_API}/${API_VERSION}/recipes`;
@@ -14,13 +15,13 @@ class RecipeController {
14 // List official and custom recipes 15 // List official and custom recipes
15 async list({ response }) { 16 async list({ response }) {
16 const recipesUrlFetch = await fetch(RECIPES_URL); 17 const recipesUrlFetch = await fetch(RECIPES_URL);
17 const officialRecipes = JSON.parse(await recipesUrlFetch.text()); 18 const officialRecipes = convertToJSON(await recipesUrlFetch.text());
18 const allRecipes = await Recipe.all(); 19 const allRecipes = await Recipe.all();
19 const customRecipesArray = allRecipes.rows; 20 const customRecipesArray = allRecipes.rows;
20 const customRecipes = customRecipesArray.map(recipe => ({ 21 const customRecipes = customRecipesArray.map(recipe => ({
21 id: recipe.recipeId, 22 id: recipe.recipeId,
22 name: recipe.name, 23 name: recipe.name,
23 ...JSON.parse(recipe.data), 24 ...convertToJSON(recipe.data),
24 })); 25 }));
25 26
26 const recipes = [...officialRecipes, ...customRecipes]; 27 const recipes = [...officialRecipes, ...customRecipes];
@@ -53,7 +54,7 @@ class RecipeController {
53 results = dbResults.map(recipe => ({ 54 results = dbResults.map(recipe => ({
54 id: recipe.recipeId, 55 id: recipe.recipeId,
55 name: recipe.name, 56 name: recipe.name,
56 ...JSON.parse(recipe.data), 57 ...convertToJSON(recipe.data),
57 })); 58 }));
58 } else { 59 } else {
59 let remoteResults = []; 60 let remoteResults = [];
@@ -62,7 +63,7 @@ class RecipeController {
62 const recipesUrlFetch = await fetch( 63 const recipesUrlFetch = await fetch(
63 `${RECIPES_URL}/search?needle=${encodeURIComponent(needle)}`, 64 `${RECIPES_URL}/search?needle=${encodeURIComponent(needle)}`,
64 ); 65 );
65 remoteResults = JSON.parse(await recipesUrlFetch.text()); 66 remoteResults = convertToJSON(await recipesUrlFetch.text());
66 } 67 }
67 68
68 debug('remoteResults:', remoteResults); 69 debug('remoteResults:', remoteResults);
@@ -74,7 +75,7 @@ class RecipeController {
74 const localResults = localResultsArray.map(recipe => ({ 75 const localResults = localResultsArray.map(recipe => ({
75 id: recipe.recipeId, 76 id: recipe.recipeId,
76 name: recipe.name, 77 name: recipe.name,
77 ...JSON.parse(recipe.data), 78 ...convertToJSON(recipe.data),
78 })); 79 }));
79 80
80 debug('localResults:', localResults); 81 debug('localResults:', localResults);
@@ -96,7 +97,7 @@ class RecipeController {
96 response, 97 response,
97 }) { 98 }) {
98 const recipesUrlFetch = await fetch(`${RECIPES_URL}/popular`); 99 const recipesUrlFetch = await fetch(`${RECIPES_URL}/popular`);
99 const featuredRecipes = JSON.parse(await recipesUrlFetch.text()); 100 const featuredRecipes = convertToJSON(await recipesUrlFetch.text());
100 return response.send(featuredRecipes); 101 return response.send(featuredRecipes);
101 } 102 }
102 103
diff --git a/src/internal-server/app/Controllers/Http/ServiceController.js b/src/internal-server/app/Controllers/Http/ServiceController.js
index f2f6e7028..81c03e5ff 100644
--- a/src/internal-server/app/Controllers/Http/ServiceController.js
+++ b/src/internal-server/app/Controllers/Http/ServiceController.js
@@ -4,6 +4,7 @@ const Env = use('Env');
4 4
5const { v4: uuid } = require('uuid'); 5const { v4: uuid } = require('uuid');
6const { LOCAL_HOSTNAME, DEFAULT_SERVICE_ORDER } = require('../../../../config'); 6const { LOCAL_HOSTNAME, DEFAULT_SERVICE_ORDER } = require('../../../../config');
7const { convertToJSON } = require('../../../../jsUtils');
7const { API_VERSION } = require('../../../../environment-remote'); 8const { API_VERSION } = require('../../../../environment-remote');
8const moveIcon = require('../../ImageHelper'); 9const moveIcon = require('../../ImageHelper');
9 10
@@ -72,10 +73,7 @@ class ServiceController {
72 const services = allServices.rows; 73 const services = allServices.rows;
73 // Convert to array with all data Franz wants 74 // Convert to array with all data Franz wants
74 const servicesArray = services.map(service => { 75 const servicesArray = services.map(service => {
75 const settings = 76 const settings = convertToJSON(service.settings);
76 typeof service.settings === 'string'
77 ? JSON.parse(service.settings)
78 : service.settings;
79 77
80 return { 78 return {
81 customRecipe: false, 79 customRecipe: false,
@@ -88,7 +86,7 @@ class ServiceController {
88 order: DEFAULT_SERVICE_ORDER, 86 order: DEFAULT_SERVICE_ORDER,
89 spellcheckerLanguage: '', 87 spellcheckerLanguage: '',
90 workspaces: [], 88 workspaces: [],
91 ...JSON.parse(service.settings), 89 ...settings,
92 iconUrl: settings.iconId 90 iconUrl: settings.iconId
93 ? `http://${hostname}:${port}/${API_VERSION}/icon/${settings.iconId}` 91 ? `http://${hostname}:${port}/${API_VERSION}/icon/${settings.iconId}`
94 : null, 92 : null,
@@ -108,10 +106,7 @@ class ServiceController {
108 const { id } = params; 106 const { id } = params;
109 const serviceQuery = await Service.query().where('serviceId', id).fetch(); 107 const serviceQuery = await Service.query().where('serviceId', id).fetch();
110 const service = serviceQuery.rows[0]; 108 const service = serviceQuery.rows[0];
111 const settings = 109 const settings = convertToJSON(service.settings);
112 typeof service.settings === 'string'
113 ? JSON.parse(service.settings)
114 : service.settings;
115 110
116 const icon = request.file('icon', { 111 const icon = request.file('icon', {
117 types: ['image'], 112 types: ['image'],
@@ -160,9 +155,7 @@ class ServiceController {
160 const serviceData = serviceQuery.rows[0]; 155 const serviceData = serviceQuery.rows[0];
161 156
162 const settings = { 157 const settings = {
163 ...(typeof serviceData.settings === 'string' 158 ...convertToJSON(serviceData.settings),
164 ? JSON.parse(serviceData.settings)
165 : serviceData.settings),
166 ...data, 159 ...data,
167 }; 160 };
168 161
@@ -205,7 +198,7 @@ class ServiceController {
205 const serviceData = serviceQuery.rows[0]; 198 const serviceData = serviceQuery.rows[0];
206 199
207 const settings = { 200 const settings = {
208 ...JSON.parse(serviceData.settings), 201 ...convertToJSON(serviceData.settings),
209 order: data[service], 202 order: data[service],
210 }; 203 };
211 204
@@ -222,10 +215,7 @@ class ServiceController {
222 const services = allServices.rows; 215 const services = allServices.rows;
223 // Convert to array with all data Franz wants 216 // Convert to array with all data Franz wants
224 const servicesArray = services.map(service => { 217 const servicesArray = services.map(service => {
225 const settings = 218 const settings = convertToJSON(service.settings);
226 typeof service.settings === 'string'
227 ? JSON.parse(service.settings)
228 : service.settings;
229 219
230 return { 220 return {
231 customRecipe: false, 221 customRecipe: false,
@@ -238,7 +228,7 @@ class ServiceController {
238 order: DEFAULT_SERVICE_ORDER, 228 order: DEFAULT_SERVICE_ORDER,
239 spellcheckerLanguage: '', 229 spellcheckerLanguage: '',
240 workspaces: [], 230 workspaces: [],
241 ...JSON.parse(service.settings), 231 ...settings,
242 iconUrl: settings.iconId 232 iconUrl: settings.iconId
243 ? `http://${hostname}:${port}/${API_VERSION}/icon/${settings.iconId}` 233 ? `http://${hostname}:${port}/${API_VERSION}/icon/${settings.iconId}`
244 : null, 234 : null,
diff --git a/src/internal-server/app/Controllers/Http/UserController.js b/src/internal-server/app/Controllers/Http/UserController.js
index 6bd4f85a7..fb1a19db6 100644
--- a/src/internal-server/app/Controllers/Http/UserController.js
+++ b/src/internal-server/app/Controllers/Http/UserController.js
@@ -9,6 +9,7 @@ const fetch = require('node-fetch');
9const { v4: uuid } = require('uuid'); 9const { v4: uuid } = require('uuid');
10const crypto = require('crypto'); 10const crypto = require('crypto');
11const { DEFAULT_APP_SETTINGS } = require('../../../../config'); 11const { DEFAULT_APP_SETTINGS } = require('../../../../config');
12const { convertToJSON } = require('../../../../jsUtils');
12const { API_VERSION } = require('../../../../environment-remote'); 13const { API_VERSION } = require('../../../../environment-remote');
13const { default: userAgent } = require('../../../../helpers/userAgent-helpers'); 14const { default: userAgent } = require('../../../../helpers/userAgent-helpers');
14 15
@@ -87,10 +88,7 @@ class UserController {
87 async me({ response }) { 88 async me({ response }) {
88 const user = await User.find(1); 89 const user = await User.find(1);
89 90
90 const settings = 91 const settings = convertToJSON(user.settings);
91 typeof user.settings === 'string'
92 ? JSON.parse(user.settings)
93 : user.settings;
94 92
95 return response.send({ 93 return response.send({
96 ...DEFAULT_USER_DATA, 94 ...DEFAULT_USER_DATA,
@@ -101,10 +99,7 @@ class UserController {
101 async updateMe({ request, response }) { 99 async updateMe({ request, response }) {
102 const user = await User.find(1); 100 const user = await User.find(1);
103 101
104 let settings = user.settings || {}; 102 const settings = convertToJSON(user.settings || {});
105 if (typeof settings === 'string') {
106 settings = JSON.parse(settings);
107 }
108 103
109 const newSettings = { 104 const newSettings = {
110 ...settings, 105 ...settings,
@@ -304,12 +299,8 @@ class UserController {
304 .rows.length > 0 299 .rows.length > 0
305 ); 300 );
306 301
307 if ( 302 if (workspace.services) {
308 workspace.services && 303 workspace.services = convertToJSON(workspace.services);
309 typeof workspace.services === 'string' &&
310 workspace.services.length > 0
311 ) {
312 workspace.services = JSON.parse(workspace.services);
313 } 304 }
314 const services = 305 const services =
315 workspace.services && typeof workspace.services === 'object' 306 workspace.services && typeof workspace.services === 'object'
@@ -317,12 +308,8 @@ class UserController {
317 oldServiceId => serviceIdTranslation[oldServiceId], 308 oldServiceId => serviceIdTranslation[oldServiceId],
318 ) 309 )
319 : []; 310 : [];
320 if ( 311 if (workspace.data) {
321 workspace.data && 312 workspace.data = convertToJSON(workspace.data);
322 typeof workspace.data === 'string' &&
323 workspace.data.length > 0
324 ) {
325 workspace.data = JSON.parse(workspace.data);
326 } 313 }
327 314
328 await Workspace.create({ 315 await Workspace.create({
@@ -347,12 +334,8 @@ class UserController {
347 // store the old serviceId as the key for future lookup 334 // store the old serviceId as the key for future lookup
348 serviceIdTranslation[service.serviceId] = newServiceId; 335 serviceIdTranslation[service.serviceId] = newServiceId;
349 336
350 if ( 337 if (service.settings) {
351 service.settings && 338 service.settings = convertToJSON(service.settings);
352 typeof service.settings === 'string' &&
353 service.settings.length > 0
354 ) {
355 service.settings = JSON.parse(service.settings);
356 } 339 }
357 340
358 await Service.create({ 341 await Service.create({
diff --git a/src/internal-server/app/Controllers/Http/WorkspaceController.js b/src/internal-server/app/Controllers/Http/WorkspaceController.js
index ee5731caf..352589567 100644
--- a/src/internal-server/app/Controllers/Http/WorkspaceController.js
+++ b/src/internal-server/app/Controllers/Http/WorkspaceController.js
@@ -2,6 +2,7 @@ const Workspace = use('App/Models/Workspace');
2const { validateAll } = use('Validator'); 2const { validateAll } = use('Validator');
3 3
4const { v4: uuid } = require('uuid'); 4const { v4: uuid } = require('uuid');
5const { convertToJSON } = require('../../../../jsUtils');
5 6
6class WorkspaceController { 7class WorkspaceController {
7 // Create a new workspace for user 8 // Create a new workspace for user
@@ -130,10 +131,7 @@ class WorkspaceController {
130 id: workspace.workspaceId, 131 id: workspace.workspaceId,
131 name: workspace.name, 132 name: workspace.name,
132 order: workspace.order, 133 order: workspace.order,
133 services: 134 services: convertToJSON(workspace.services),
134 typeof workspace.services === 'string'
135 ? JSON.parse(workspace.services)
136 : workspace.services,
137 userId: 1, 135 userId: 1,
138 })); 136 }));
139 } 137 }
diff --git a/src/internal-server/start/migrate.js b/src/internal-server/start/migrate.js
index 403f7cb86..0af33a977 100644
--- a/src/internal-server/start/migrate.js
+++ b/src/internal-server/start/migrate.js
@@ -1,3 +1,4 @@
1const { convertToJSON } = require('../../jsUtils');
1const { ferdiumVersion } = require('../../environment-remote'); 2const { ferdiumVersion } = require('../../environment-remote');
2 3
3/** 4/**
@@ -26,10 +27,7 @@ module.exports = async () => {
26 // Create new user 27 // Create new user
27 await Database.raw('INSERT INTO "users" ("id") VALUES (\'1\');'); 28 await Database.raw('INSERT INTO "users" ("id") VALUES (\'1\');');
28 } else { 29 } else {
29 settings = 30 settings = convertToJSON(user.settings);
30 typeof user.settings === 'string'
31 ? JSON.parse(user.settings)
32 : user.settings;
33 } 31 }
34 32
35 if ( 33 if (
diff --git a/src/jsUtils.test.ts b/src/jsUtils.test.ts
new file mode 100644
index 000000000..651caee5f
--- /dev/null
+++ b/src/jsUtils.test.ts
@@ -0,0 +1,96 @@
1import * as jsUtils from './jsUtils'
2
3describe('jsUtils', () => {
4 describe('ifUndefinedString', () => {
5 it('returns the default value for undefined input', () => {
6 const result = jsUtils.ifUndefinedString(undefined, 'abc');
7 expect(result).toEqual('abc');
8 });
9
10 it('returns the default value for null input', () => {
11 const result = jsUtils.ifUndefinedString(null, 'abc');
12 expect(result).toEqual('abc');
13 });
14
15 it('returns the non-default input value for regular string input', () => {
16 const result = jsUtils.ifUndefinedString('some random string', 'abc');
17 expect(result).toEqual('some random string');
18 });
19 });
20
21 describe('ifUndefinedBoolean', () => {
22 it('returns the default value for undefined input', () => {
23 const result = jsUtils.ifUndefinedBoolean(undefined, false);
24 expect(result).toEqual(false);
25 });
26
27 it('returns the default value for null input', () => {
28 const result = jsUtils.ifUndefinedBoolean(null, true);
29 expect(result).toEqual(true);
30 });
31
32 it('returns the non-default input value for regular boolean input', () => {
33 const result = jsUtils.ifUndefinedBoolean(true, false);
34 expect(result).toEqual(true);
35 });
36 });
37
38 describe('ifUndefinedNumber', () => {
39 it('returns the default value for undefined input', () => {
40 const result = jsUtils.ifUndefinedNumber(undefined, 123);
41 expect(result).toEqual(123);
42 });
43
44 it('returns the default value for null input', () => {
45 const result = jsUtils.ifUndefinedNumber(null, 234);
46 expect(result).toEqual(234);
47 });
48
49 it('returns the non-default input value for regular Number input', () => {
50 const result = jsUtils.ifUndefinedNumber(1234, 5678);
51 expect(result).toEqual(1234);
52 });
53 });
54
55 describe('convertToJSON', () => {
56 it('returns undefined for undefined input', () => {
57 const result = jsUtils.convertToJSON(undefined);
58 expect(result).toEqual(undefined);
59 });
60
61 it('returns null for null input', () => {
62 const result = jsUtils.convertToJSON(null);
63 expect(result).toEqual(null);
64 });
65
66 it('returns the object for the object input', () => {
67 const result = jsUtils.convertToJSON(['a', 'b']);
68 expect(result).toEqual(['a', 'b']);
69 });
70
71 it('returns the parsed JSON for the string input', () => {
72 const result1 = jsUtils.convertToJSON('{"a":"b","c":"d"}');
73 expect(result1).toEqual({a: 'b', c: 'd'});
74
75 const result2 = jsUtils.convertToJSON('[{"a":"b"},{"c":"d"}]');
76 expect(result2).toEqual([{a: 'b'}, {c: 'd'}]);
77 });
78 });
79
80 describe('cleanseJSObject', () => {
81 xit('throws error for undefined input', () => {
82 const result = jsUtils.cleanseJSObject(undefined);
83 expect(result).toThrow();
84 });
85
86 xit('throws error for null input', () => {
87 const result = jsUtils.cleanseJSObject(null);
88 expect(result).toThrow();
89 });
90
91 it('returns cloned object for valid input', () => {
92 const result = jsUtils.cleanseJSObject([{a: 'b'}, {c: 'd'}]);
93 expect(result).toEqual([{a: 'b'}, {c: 'd'}]);
94 });
95 });
96});
diff --git a/src/jsUtils.ts b/src/jsUtils.ts
index d7ea4eb40..250d595eb 100644
--- a/src/jsUtils.ts
+++ b/src/jsUtils.ts
@@ -1,14 +1,9 @@
1export const ifUndefinedString = ( 1export const ifUndefinedString = (source: string | undefined | null, defaultValue: string): string => (source !== undefined && source !== null ? source : defaultValue);
2 source: string | undefined | null, 2
3 defaultValue: string, 3export const ifUndefinedBoolean = (source: boolean | undefined | null, defaultValue: boolean): boolean => Boolean(source !== undefined && source !== null ? source : defaultValue);
4): string => (source !== undefined && source !== null ? source : defaultValue); 4
5export const ifUndefinedBoolean = ( 5export const ifUndefinedNumber = (source: number | undefined | null, defaultValue: number): number => Number(source !== undefined && source !== null ? source : defaultValue);
6 source: boolean | undefined | null, 6
7 defaultValue: boolean, 7export const convertToJSON = (data: string | any | undefined | null) => data && typeof data === 'string' && data.length > 0 ? JSON.parse(data) : data
8): boolean => 8
9 Boolean(source !== undefined && source !== null ? source : defaultValue); 9export const cleanseJSObject = (data: any | undefined | null) => JSON.parse(JSON.stringify(data))
10export const ifUndefinedNumber = (
11 source: number | undefined | null,
12 defaultValue: number,
13): number =>
14 Number(source !== undefined && source !== null ? source : defaultValue);
diff --git a/src/stores/AppStore.js b/src/stores/AppStore.js
index 76956fdc7..a9c92fe87 100644
--- a/src/stores/AppStore.js
+++ b/src/stores/AppStore.js
@@ -17,6 +17,7 @@ import { readJsonSync } from 'fs-extra';
17import Store from './lib/Store'; 17import Store from './lib/Store';
18import Request from './lib/Request'; 18import Request from './lib/Request';
19import { CHECK_INTERVAL, DEFAULT_APP_SETTINGS } from '../config'; 19import { CHECK_INTERVAL, DEFAULT_APP_SETTINGS } from '../config';
20import { cleanseJSObject } from '../jsUtils';
20import { isMac, isWindows, electronVersion, osRelease } from '../environment'; 21import { isMac, isWindows, electronVersion, osRelease } from '../environment';
21import { ferdiumVersion, userDataPath, ferdiumLocale } from '../environment-remote'; 22import { ferdiumVersion, userDataPath, ferdiumLocale } from '../environment-remote';
22import { generatedTranslations } from '../i18n/translations'; 23import { generatedTranslations } from '../i18n/translations';
@@ -265,7 +266,7 @@ export default class AppStore extends Store {
265 } 266 }
266 267
267 @computed get debugInfo() { 268 @computed get debugInfo() {
268 const settings = JSON.parse(JSON.stringify(this.stores.settings.app)); 269 const settings = cleanseJSObject(this.stores.settings.app);
269 settings.lockedPassword = '******'; 270 settings.lockedPassword = '******';
270 271
271 return { 272 return {
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js
index c8042e9de..3f551eddb 100644
--- a/src/stores/ServicesStore.js
+++ b/src/stores/ServicesStore.js
@@ -16,6 +16,7 @@ import {
16} from '../helpers/recipe-helpers'; 16} from '../helpers/recipe-helpers';
17import { workspaceStore } from '../features/workspaces'; 17import { workspaceStore } from '../features/workspaces';
18import { DEFAULT_SERVICE_SETTINGS, KEEP_WS_LOADED_USID } from '../config'; 18import { DEFAULT_SERVICE_SETTINGS, KEEP_WS_LOADED_USID } from '../config';
19import { cleanseJSObject } from '../jsUtils';
19import { SPELLCHECKER_LOCALES } from '../i18n/languages'; 20import { SPELLCHECKER_LOCALES } from '../i18n/languages';
20import { ferdiumVersion } from '../environment-remote'; 21import { ferdiumVersion } from '../environment-remote';
21 22
@@ -861,7 +862,7 @@ export default class ServicesStore extends Store {
861 const service = this.one(serviceId); 862 const service = this.one(serviceId);
862 863
863 // Make sure the args are clean, otherwise ElectronJS can't transmit them 864 // Make sure the args are clean, otherwise ElectronJS can't transmit them
864 const cleanArgs = JSON.parse(JSON.stringify(args)); 865 const cleanArgs = cleanseJSObject(args);
865 866
866 if (service.webview) { 867 if (service.webview) {
867 service.webview.send(channel, cleanArgs); 868 service.webview.send(channel, cleanArgs);
@@ -1273,9 +1274,7 @@ export default class ServicesStore extends Store {
1273 1274
1274 if (service.webview) { 1275 if (service.webview) {
1275 // We need to completely clone the object, otherwise Electron won't be able to send the object via IPC 1276 // We need to completely clone the object, otherwise Electron won't be able to send the object via IPC
1276 const shareWithWebview = JSON.parse( 1277 const shareWithWebview = cleanseJSObject(service.shareWithWebview);
1277 JSON.stringify(service.shareWithWebview),
1278 );
1279 1278
1280 debug('Initialize recipe', service.recipe.id, service.name); 1279 debug('Initialize recipe', service.recipe.id, service.name);
1281 service.webview.send( 1280 service.webview.send(
diff --git a/src/webview/lib/Userscript.ts b/src/webview/lib/Userscript.ts
index f02a8f135..b0e4fb805 100644
--- a/src/webview/lib/Userscript.ts
+++ b/src/webview/lib/Userscript.ts
@@ -1,3 +1,5 @@
1import { cleanseJSObject, convertToJSON } from '../../jsUtils';
2
1type Recipe = { 3type Recipe = {
2 setBadge: (direct: number, indirect: number) => void; 4 setBadge: (direct: number, indirect: number) => void;
3 setDialogTitle: (title: string) => void; 5 setDialogTitle: (title: string) => void;
@@ -34,7 +36,7 @@ export default class Userscript {
34 internal_setSettings(settings: any) { 36 internal_setSettings(settings: any) {
35 // This is needed to get a clean JS object from the settings itself to provide better accessibility 37 // This is needed to get a clean JS object from the settings itself to provide better accessibility
36 // Otherwise this will be a mobX instance 38 // Otherwise this will be a mobX instance
37 this.settings = JSON.parse(JSON.stringify(settings)); 39 this.settings = cleanseJSObject(settings);
38 } 40 }
39 41
40 /** 42 /**
@@ -101,7 +103,7 @@ export default class Userscript {
101 const ferdiumUserKey = window.localStorage.getItem(`ferdium-user-${key}`); 103 const ferdiumUserKey = window.localStorage.getItem(`ferdium-user-${key}`);
102 104
103 if (ferdiumUserKey) { 105 if (ferdiumUserKey) {
104 return JSON.parse(ferdiumUserKey); 106 return convertToJSON(ferdiumUserKey);
105 } 107 }
106 } 108 }
107} 109}