Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 28 additions & 19 deletions packages/obsidian/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import { TMDBSeasonAPI } from 'packages/obsidian/src/api/apis/TMDBSeasonAPI';
import { TMDBSeriesAPI } from 'packages/obsidian/src/api/apis/TMDBSeriesAPI';
import { VNDBAPI } from 'packages/obsidian/src/api/apis/VNDBAPI';
import { WikipediaAPI } from 'packages/obsidian/src/api/apis/WikipediaAPI';
import type { LegacyApiKeyEntry } from 'packages/obsidian/src/modals/LegacyApiKeysModal';
import { LegacyApiKeysModal } from 'packages/obsidian/src/modals/LegacyApiKeysModal';
import { PropertyMapper } from 'packages/obsidian/src/settings/PropertyMapper';
import { PropertyMappingModel } from 'packages/obsidian/src/settings/PropertyMapping';
import type { MediaDbPluginSettings } from 'packages/obsidian/src/settings/Settings';
Expand Down Expand Up @@ -168,35 +170,42 @@ export default class MediaDbPlugin extends Plugin {
});
}

private getLegacyApiKeyEntries(diskSettings: Record<string, unknown>): LegacyApiKeyEntry[] {
return this.settings.LegacyApiKeys.filter(key => typeof diskSettings[key] === 'string' && diskSettings[key].length > 0).map(key => ({
key,
value: diskSettings[key] as string,
}));
}

private removeLegacyApiKeys(settings: Record<string, unknown>): void {
for (const key of this.settings.LegacyApiKeys) {
delete settings[key];
}
}

async loadSettings(): Promise<void> {
const diskSettings: MediaDbPluginSettings = (await this.loadData()) as MediaDbPluginSettings;
const diskSettings = (await this.loadData()) as Record<string, unknown>;
const defaultSettings: MediaDbPluginSettings = getDefaultSettings(this);
const loadedSettings: MediaDbPluginSettings = Object.assign({}, defaultSettings, diskSettings);

// delete old api keys
// @ts-ignore
delete loadedSettings.BoardgameGeekKey;
// @ts-ignore
delete loadedSettings.ComicVineKey;
// @ts-ignore
delete loadedSettings.GiantBombKey;
// @ts-ignore
delete loadedSettings.MobyGamesKey;
// @ts-ignore
delete loadedSettings.OMDbKey;
// @ts-ignore
delete loadedSettings.TMDBKey;
const loadedSettings = Object.assign({}, defaultSettings, diskSettings) as MediaDbPluginSettings;

const migratedModels = PropertyMappingModel.migrateModels(
loadedSettings.propertyMappingModels || [],
defaultSettings.propertyMappingModels.map(m => PropertyMappingModel.fromJSON(m)),
);

loadedSettings.propertyMappingModels = migratedModels.map(m => m.toJSON());

this.settings = loadedSettings;

await this.saveSettings();
const legacyEntries = this.getLegacyApiKeyEntries(diskSettings);
if (legacyEntries.length > 0) {
this.app.workspace.onLayoutReady((): void => {
window.setTimeout((): void => {
new LegacyApiKeysModal(this.app, legacyEntries, (): void => {
this.removeLegacyApiKeys(this.settings as unknown as Record<string, unknown>);
void this.saveSettings();
}).open();
}, 0);
});
}
}

async saveSettings(): Promise<void> {
Expand Down
93 changes: 93 additions & 0 deletions packages/obsidian/src/modals/LegacyApiKeysModal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import type { App } from 'obsidian';
import { Modal, Setting, Notice } from 'obsidian';

export interface LegacyApiKeyEntry {
key: string;
value: string;
}

export class LegacyApiKeysModal extends Modal {
private entries: LegacyApiKeyEntry[];
private onConfirm: () => void;

constructor(app: App, entries: LegacyApiKeyEntry[], onConfirm: () => void) {
super(app);
this.entries = entries;
this.onConfirm = onConfirm;
}

onOpen(): void {
const { contentEl } = this;
contentEl.addClass('media-db-plugin-legacy-keys-modal');

contentEl.createEl('h2', { text: 'Media DB plugin: Legacy API keys found' });

const wrapper = contentEl.createDiv({ cls: 'media-db-plugin-legacy-keys-wrapper' });

const intro = wrapper.createDiv({ cls: 'media-db-plugin-legacy-keys-intro' });
intro.createEl('p', {
text: 'Media DB plugin has found old plaintext API keys in your settings. Copy them now if needed, they should be removed for safety.',
});

intro.createEl('p', {
text: 'The new keychain-backed system will be used instead. The plugin will not be usable until the old plaintext keys have been deleted.',
});

const textarea = wrapper.createEl('textarea', {
cls: 'media-db-plugin-legacy-keys-textarea',
attr: {
readonly: 'true',
spellcheck: 'false',
},
});

textarea.value = this.entries.map(e => `${e.key}: ${e.value}`).join('\n');
textarea.addClass('media-db-plugin-hidden');

contentEl.createDiv({ cls: 'media-db-plugin-spacer' });

const bottomSettingRow = new Setting(contentEl);

bottomSettingRow.addButton(btn => {
btn.setButtonText('Copy');
btn.onClick(async () => {
await navigator.clipboard.writeText(textarea.value);
new Notice('Legacy API keys copied to clipboard.');
});
btn.buttonEl.addClass('media-db-plugin-button');
});

bottomSettingRow.addButton(btn => {
btn.setButtonText('Show keys');

btn.onClick(() => {
const isHidden = textarea.hasClass('media-db-plugin-hidden');
if (isHidden) {
textarea.removeClass('media-db-plugin-hidden');
btn.setButtonText('Hide keys');
} else {
textarea.addClass('media-db-plugin-hidden');
btn.setButtonText('Show keys');
}
});

btn.buttonEl.addClass('media-db-plugin-button');
});

bottomSettingRow.addButton(btn => {
btn.setButtonText('Delete plaintext keys');
btn.setCta();
btn.onClick(() => {
this.close();
this.onConfirm();
});
btn.buttonEl.addClass('media-db-plugin-button');
btn.buttonEl.addClass('mod-warning');
btn.buttonEl.addClass('mod-danger');
});
}

onClose(): void {
this.contentEl.empty();
}
}
84 changes: 44 additions & 40 deletions packages/obsidian/src/settings/Settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,16 @@ function createPropertyMappingsDescription(): DocumentFragment {
export interface MediaDbPluginSettings {
OMDbKeyId: string;
TMDBKeyId: string;
MobyGamesKeyId: string;
GiantBombKeyId: string;
//MobyGamesKeyId: string;
//GiantBombKeyId: string;
IGDBClientId: string;
IGDBClientSecret: string;
RAWGAPIKeyId: string;
ComicVineKeyId: string;
BoardgameGeekKeyId: string;

LegacyApiKeys: readonly ['OMDbKey', 'TMDBKey', 'MobyGamesKey', 'GiantBombKey', 'ComicVineKey', 'BoardgameGeekKey'];

sfwFilter: boolean;
templates: boolean;
customDateFormat: string;
Expand All @@ -69,12 +71,12 @@ export interface MediaDbPluginSettings {

BoardgameGeekAPI_disabledMediaTypes: MediaType[];
ComicVineAPI_disabledMediaTypes: MediaType[];
GiantBombAPI_disabledMediaTypes: MediaType[];
//GiantBombAPI_disabledMediaTypes: MediaType[];
IGDBAPI_disabledMediaTypes: MediaType[];
RAWGAPI_disabledMediaTypes: MediaType[];
MALAPI_disabledMediaTypes: MediaType[];
MALAPIManga_disabledMediaTypes: MediaType[];
MobyGamesAPI_disabledMediaTypes: MediaType[];
//MobyGamesAPI_disabledMediaTypes: MediaType[];
MusicBrainzAPI_disabledMediaTypes: MediaType[];
OMDbAPI_disabledMediaTypes: MediaType[];
OpenLibraryAPI_disabledMediaTypes: MediaType[];
Expand Down Expand Up @@ -309,14 +311,16 @@ class MediaTypeMappedSettings {
const DEFAULT_SETTINGS: MediaDbPluginSettings = {
OMDbKeyId: '',
TMDBKeyId: '',
MobyGamesKeyId: '',
GiantBombKeyId: '',
//MobyGamesKeyId: '',
//GiantBombKeyId: '',
IGDBClientId: '',
IGDBClientSecret: '',
RAWGAPIKeyId: '',
ComicVineKeyId: '',
BoardgameGeekKeyId: '',

LegacyApiKeys: ['OMDbKey', 'TMDBKey', 'MobyGamesKey', 'GiantBombKey', 'ComicVineKey', 'BoardgameGeekKey'],

sfwFilter: true,
templates: true,
customDateFormat: 'L',
Expand All @@ -328,12 +332,12 @@ const DEFAULT_SETTINGS: MediaDbPluginSettings = {

BoardgameGeekAPI_disabledMediaTypes: [],
ComicVineAPI_disabledMediaTypes: [],
GiantBombAPI_disabledMediaTypes: [],
//GiantBombAPI_disabledMediaTypes: [],
IGDBAPI_disabledMediaTypes: [],
RAWGAPI_disabledMediaTypes: [],
MALAPI_disabledMediaTypes: [],
MALAPIManga_disabledMediaTypes: [],
MobyGamesAPI_disabledMediaTypes: [],
//MobyGamesAPI_disabledMediaTypes: [],
MusicBrainzAPI_disabledMediaTypes: [],
OMDbAPI_disabledMediaTypes: [],
OpenLibraryAPI_disabledMediaTypes: [],
Expand Down Expand Up @@ -610,38 +614,38 @@ export class MediaDbSettingTab extends PluginSettingTab {
return component;
}),
);
apiKeyGroup.addSetting(
setting =>
void setting
.setName('Moby Games key')
.setDesc('API key for "www.mobygames.com".')
.addComponent(el => {
const component = new SecretComponent(this.app, el);

component.setValue(this.plugin.settings.MobyGamesKeyId).onChange(data => {
this.plugin.settings.MobyGamesKeyId = data;
void this.plugin.saveSettings();
});

return component;
}),
);
apiKeyGroup.addSetting(
setting =>
void setting
.setName('Giant Bomb Key')
.setDesc('API key for "www.giantbomb.com".')
.addComponent(el => {
const component = new SecretComponent(this.app, el);

component.setValue(this.plugin.settings.GiantBombKeyId).onChange(data => {
this.plugin.settings.GiantBombKeyId = data;
void this.plugin.saveSettings();
});

return component;
}),
);
// apiKeyGroup.addSetting(
// setting =>
// void setting
// .setName('Moby Games key')
// .setDesc('API key for "www.mobygames.com".')
// .addComponent(el => {
// const component = new SecretComponent(this.app, el);

// component.setValue(this.plugin.settings.MobyGamesKeyId).onChange(data => {
// this.plugin.settings.MobyGamesKeyId = data;
// void this.plugin.saveSettings();
// });

// return component;
// }),
// );
// apiKeyGroup.addSetting(
// setting =>
// void setting
// .setName('Giant Bomb Key')
// .setDesc('API key for "www.giantbomb.com".')
// .addComponent(el => {
// const component = new SecretComponent(this.app, el);

// component.setValue(this.plugin.settings.GiantBombKeyId).onChange(data => {
// this.plugin.settings.GiantBombKeyId = data;
// void this.plugin.saveSettings();
// });

// return component;
// }),
// );
apiKeyGroup.addSetting(
setting =>
void setting
Expand Down
37 changes: 37 additions & 0 deletions packages/obsidian/src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -295,3 +295,40 @@ small.media-db-plugin-list-text {
width: var(--checkbox-size);
height: var(--checkbox-size);
}

.media-db-plugin-legacy-keys-modal {
display: contents;
}

.media-db-plugin-legacy-keys-intro {
color: var(--text-normal);
}

.media-db-plugin-legacy-keys-wrapper {
display: flex;
flex-direction: column;
gap: var(--size-4-3);
width: 100%;
max-width: 100%;
}

.media-db-plugin-legacy-keys-textarea {
width: 100%;
max-width: 100%;
min-height: var(--size-4-5);
min-width: var(--size-4-7);
box-sizing: border-box;
resize: vertical;
padding: var(--size-4-3);
border-radius: var(--radius-s);
border: 1px solid var(--background-modifier-border);
background: var(--background-primary);
color: var(--text-normal);
font-family: var(--font-monospace);
font-size: var(--font-ui-smaller);
line-height: 1.5;
white-space: pre;
}
.media-db-plugin-hidden {
display: none;
}
Loading