1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-07-03 23:50:33 +02:00

Plugins: Fixed saving secure settings to the keychain, and added way to store plugin settings to settings.json

This commit is contained in:
Laurent Cozic
2021-06-19 15:56:37 +01:00
parent b7b12f9369
commit ab9bbcbff2
5 changed files with 66 additions and 22 deletions

View File

@ -8,15 +8,16 @@ joplin.plugins.register({
iconName: 'fas fa-music', iconName: 'fas fa-music',
}); });
await joplin.settings.registerSetting('myCustomSetting', { await joplin.settings.registerSettings({
'myCustomSetting': {
value: 123, value: 123,
type: SettingItemType.Int, type: SettingItemType.Int,
section: 'myCustomSection', section: 'myCustomSection',
public: true, public: true,
label: 'My Custom Setting', label: 'My Custom Setting',
}); },
await joplin.settings.registerSetting('multiOptionTest', { 'multiOptionTest': {
value: 'en', value: 'en',
type: SettingItemType.String, type: SettingItemType.String,
section: 'myCustomSection', section: 'myCustomSection',
@ -28,6 +29,26 @@ joplin.plugins.register({
'fr': 'French', 'fr': 'French',
'es': 'Spanish', 'es': 'Spanish',
}, },
},
'mySecureSetting': {
value: 'hunter2',
type: SettingItemType.String,
section: 'myCustomSection',
public: true,
secure: true,
label: 'My Secure Setting',
},
'myFileSetting': {
value: 'abcd',
type: SettingItemType.String,
section: 'myCustomSection',
public: true,
label: 'My file setting',
description: 'This setting will be saved to settings.json',
['storage' as any]: 2, // Should be `storage: SettingStorage.File`
},
}); });
await joplin.commands.register({ await joplin.commands.register({
@ -47,7 +68,11 @@ joplin.plugins.register({
iconName: 'fas fa-drum', iconName: 'fas fa-drum',
execute: async () => { execute: async () => {
const value = await joplin.settings.value('myCustomSetting'); const value = await joplin.settings.value('myCustomSetting');
alert('Current value is: ' + value); console.info('Current value is: ' + value);
const secureValue = await joplin.settings.value('mySecureSetting');
console.info('Secure value is: ' + secureValue);
const fileValue = await joplin.settings.value('myFileSetting');
console.info('Setting in file is: ' + fileValue);
}, },
}); });

View File

@ -4,5 +4,5 @@
# It could be used to develop plugins too. # It could be used to develop plugins too.
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
PLUGIN_PATH="$SCRIPT_DIR/../app-cli/tests/support/plugins/external_assets" PLUGIN_PATH="$SCRIPT_DIR/../app-cli/tests/support/plugins/settings"
npm i --prefix="$PLUGIN_PATH" && npm start -- --dev-plugins "$PLUGIN_PATH" npm i --prefix="$PLUGIN_PATH" && npm start -- --dev-plugins "$PLUGIN_PATH"

View File

@ -1363,10 +1363,18 @@ class Setting extends BaseModel {
} }
// Low-level method to load a setting directly from the database. Should not be used in most cases. // Low-level method to load a setting directly from the database. Should not be used in most cases.
public static async loadOne(key: string) { public static async loadOne(key: string): Promise<CacheItem> {
if (this.keyStorage(key) === SettingStorage.File) { if (this.keyStorage(key) === SettingStorage.File) {
const fromFile = await this.fileHandler.load(); const fromFile = await this.fileHandler.load();
return fromFile[key]; return {
key,
value: fromFile[key],
};
} else if (this.settingMetadata(key).secure) {
return {
key,
value: await this.keychainService().password(`setting.${key}`),
};
} else { } else {
return this.modelSelectOne('SELECT * FROM settings WHERE key = ?', [key]); return this.modelSelectOne('SELECT * FROM settings WHERE key = ?', [key]);
} }

View File

@ -65,6 +65,7 @@ export default class JoplinSettings {
if ('minimum' in setting) internalSettingItem.minimum = setting.minimum; if ('minimum' in setting) internalSettingItem.minimum = setting.minimum;
if ('maximum' in setting) internalSettingItem.maximum = setting.maximum; if ('maximum' in setting) internalSettingItem.maximum = setting.maximum;
if ('step' in setting) internalSettingItem.step = setting.step; if ('step' in setting) internalSettingItem.step = setting.step;
if ('storage' in setting) internalSettingItem.storage = setting.storage;
await Setting.registerSetting(this.namespacedKey(key), internalSettingItem); await Setting.registerSetting(this.namespacedKey(key), internalSettingItem);
} }

View File

@ -334,6 +334,11 @@ export enum SettingItemType {
Button = 6, Button = 6,
} }
export enum SettingStorage {
Database = 1,
File = 2,
}
// Redefine a simplified interface to mask internal details // Redefine a simplified interface to mask internal details
// and to remove function calls as they would have to be async. // and to remove function calls as they would have to be async.
export interface SettingItem { export interface SettingItem {
@ -393,6 +398,11 @@ export interface SettingItem {
minimum?: number; minimum?: number;
maximum?: number; maximum?: number;
step?: number; step?: number;
/**
* Either store the setting in the database or in settings.json. Defaults to database.
*/
storage?: SettingStorage;
} }
export interface SettingSection { export interface SettingSection {