mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
Desktop: Fixes #8143: Fixes crash when using multiple profiles along with certain plugins
This commit is contained in:
parent
f390eca4de
commit
6672f63981
@ -1,4 +1,4 @@
|
||||
import Setting, { SettingSectionSource, SettingStorage } from '../models/Setting';
|
||||
import Setting, { SettingItemType, SettingSectionSource, SettingStorage } from '../models/Setting';
|
||||
import { setupDatabaseAndSynchronizer, switchClient, expectThrow, expectNotThrow, msleep } from '../testing/test-utils';
|
||||
import { readFile, stat, mkdirp, writeFile, pathExists, readdir } from 'fs-extra';
|
||||
import Logger from '../Logger';
|
||||
@ -297,12 +297,21 @@ describe('models/Setting', () => {
|
||||
expect(Setting.isSet('spellChecker.languages')).toBe(false);
|
||||
}));
|
||||
|
||||
it('should load sub-profile settings - 1', async () => {
|
||||
it('should load sub-profile settings', async () => {
|
||||
await Setting.reset();
|
||||
|
||||
await Setting.registerSetting('non_builtin', {
|
||||
public: true,
|
||||
storage: SettingStorage.File,
|
||||
isGlobal: true,
|
||||
type: SettingItemType.Bool,
|
||||
value: false,
|
||||
});
|
||||
|
||||
Setting.setValue('locale', 'fr_FR'); // Global setting
|
||||
Setting.setValue('theme', Setting.THEME_DARK); // Global setting
|
||||
Setting.setValue('sync.target', 9); // Local setting
|
||||
Setting.setValue('non_builtin', true); // Local setting
|
||||
await Setting.saveAll();
|
||||
|
||||
await switchToSubProfileSettings();
|
||||
@ -311,6 +320,9 @@ describe('models/Setting', () => {
|
||||
expect(Setting.value('theme')).toBe(Setting.THEME_DARK); // Should come from the root profile
|
||||
expect(Setting.value('sync.target')).toBe(0); // Should come from the local profile
|
||||
|
||||
// Non-built-in variables are not copied
|
||||
expect(() => Setting.value('non_builtin')).toThrow();
|
||||
|
||||
// Also check that the special loadOne() function works as expected
|
||||
|
||||
expect((await Setting.loadOne('locale')).value).toBe('fr_FR');
|
||||
@ -318,7 +330,7 @@ describe('models/Setting', () => {
|
||||
expect((await Setting.loadOne('sync.target')).value).toBe(undefined);
|
||||
});
|
||||
|
||||
it('should save sub-profile settings - 2', async () => {
|
||||
it('should save sub-profile settings', async () => {
|
||||
await Setting.reset();
|
||||
Setting.setValue('locale', 'fr_FR'); // Global setting
|
||||
Setting.setValue('theme', Setting.THEME_DARK); // Global setting
|
||||
|
@ -313,6 +313,7 @@ class Setting extends BaseModel {
|
||||
private static fileHandler_: FileHandler = null;
|
||||
private static rootFileHandler_: FileHandler = null;
|
||||
private static settingFilename_: string = 'settings.json';
|
||||
private static buildInMetadata_: SettingItems = null;
|
||||
|
||||
public static tableName() {
|
||||
return 'settings';
|
||||
@ -407,7 +408,7 @@ class Setting extends BaseModel {
|
||||
return output;
|
||||
};
|
||||
|
||||
this.metadata_ = {
|
||||
this.buildInMetadata_ = {
|
||||
'clientId': {
|
||||
value: '',
|
||||
type: SettingItemType.String,
|
||||
@ -1697,6 +1698,8 @@ class Setting extends BaseModel {
|
||||
|
||||
};
|
||||
|
||||
this.metadata_ = { ...this.buildInMetadata_ };
|
||||
|
||||
this.metadata_ = Object.assign(this.metadata_, this.customMetadata_);
|
||||
|
||||
if (this.constants_.env === Env.Dev) this.validateMetadata(this.metadata_);
|
||||
@ -1710,6 +1713,10 @@ class Setting extends BaseModel {
|
||||
}
|
||||
}
|
||||
|
||||
public static isBuiltinKey(key: string): boolean {
|
||||
return key in this.buildInMetadata_;
|
||||
}
|
||||
|
||||
public static customCssFilePath(filename: string): string {
|
||||
return `${this.value('rootProfileDir')}/${filename}`;
|
||||
}
|
||||
@ -2256,7 +2263,7 @@ class Setting extends BaseModel {
|
||||
|
||||
public static enumOptions(key: string) {
|
||||
const metadata = this.metadata();
|
||||
if (!metadata[key]) throw new Error(`Unknown key: ${key}`);
|
||||
if (!metadata[key]) throw new JoplinError(`Unknown key: ${key}`, 'unknown_key');
|
||||
if (!metadata[key].options) throw new Error(`No options for: ${key}`);
|
||||
return metadata[key].options();
|
||||
}
|
||||
|
@ -7,14 +7,32 @@ export default (rootSettings: Record<string, any>, subProfileSettings: Record<st
|
||||
const output: Record<string, any> = { ...subProfileSettings };
|
||||
|
||||
for (const k of Object.keys(output)) {
|
||||
const md = Setting.settingMetadata(k);
|
||||
if (md.isGlobal) {
|
||||
delete output[k];
|
||||
if (k in rootSettings) output[k] = rootSettings[k];
|
||||
try {
|
||||
const md = Setting.settingMetadata(k);
|
||||
if (md.isGlobal) {
|
||||
delete output[k];
|
||||
if (k in rootSettings) output[k] = rootSettings[k];
|
||||
}
|
||||
} catch (error) {
|
||||
if (error.code === 'unknown_key') {
|
||||
// The root settings may contain plugin parameters, but the
|
||||
// sub-profile won't necessarily have these plugins. In that
|
||||
// case, the app will throw an error, but we can ignore it since
|
||||
// we don't need this particular setting.
|
||||
// https://github.com/laurent22/joplin/issues/8143
|
||||
logger.info(`Ignoring unknown key in root settings: ${k}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const k of Object.keys(rootSettings)) {
|
||||
// We only copy built-in key and not, for example, plugin keys, because
|
||||
// those are plugin-specific
|
||||
if (!Setting.isBuiltinKey(k)) {
|
||||
logger.info(`Skipping non-built-in key: ${k}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
const md = Setting.settingMetadata(k);
|
||||
if (md.isGlobal) {
|
||||
|
Loading…
Reference in New Issue
Block a user