mirror of
https://github.com/WowUp/WowUp.git
synced 2026-04-22 06:49:05 -04:00
Store api key in separate storage to prevent accidentally leaking when asking for the config file for support
This commit is contained in:
@@ -8,14 +8,17 @@ import {
|
||||
IPC_STORE_REMOVE_OBJECT,
|
||||
IPC_STORE_SET_OBJECT,
|
||||
PREFERENCE_STORE_NAME,
|
||||
SENSITIVE_STORE_NAME,
|
||||
} from "../src/common/constants";
|
||||
|
||||
export const addonStore = new Store({ name: ADDON_STORE_NAME });
|
||||
export const preferenceStore = new Store({ name: PREFERENCE_STORE_NAME });
|
||||
export const sensitiveStore = new Store({ name: SENSITIVE_STORE_NAME });
|
||||
|
||||
const stores: { [storeName: string]: Store } = {
|
||||
[ADDON_STORE_NAME]: addonStore,
|
||||
[PREFERENCE_STORE_NAME]: preferenceStore,
|
||||
[SENSITIVE_STORE_NAME]: sensitiveStore,
|
||||
};
|
||||
|
||||
export function initializeStoreIpcHandlers(): void {
|
||||
|
||||
@@ -50,7 +50,7 @@ import { AddonProvider, GetAllBatchResult, GetAllResult, SearchByUrlResult } fro
|
||||
import { strictFilter } from "../utils/array.utils";
|
||||
import { TocService } from "../services/toc/toc.service";
|
||||
import { WarcraftService } from "../services/warcraft/warcraft.service";
|
||||
import { PreferenceStorageService } from "../services/storage/preference-storage.service";
|
||||
import { SensitiveStorageService } from "../services/storage/sensitive-storage.service";
|
||||
|
||||
interface ProtocolData {
|
||||
addonId: number;
|
||||
@@ -99,7 +99,7 @@ export class CurseAddonV2Provider extends AddonProvider {
|
||||
private _wowupApiService: WowUpApiService,
|
||||
private _warcraftService: WarcraftService,
|
||||
private _tocService: TocService,
|
||||
private _preferenceStorageService: PreferenceStorageService,
|
||||
private _sensitiveStorageService: SensitiveStorageService,
|
||||
_networkService: NetworkService
|
||||
) {
|
||||
super();
|
||||
@@ -1045,7 +1045,7 @@ export class CurseAddonV2Provider extends AddonProvider {
|
||||
return this._cfClient;
|
||||
}
|
||||
|
||||
const apiKey = await this._preferenceStorageService.getAsync(PREF_CF2_API_KEY);
|
||||
const apiKey = await this._sensitiveStorageService.getAsync(PREF_CF2_API_KEY);
|
||||
if (typeof apiKey !== "string" || apiKey.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { MatSelectionListChange } from "@angular/material/list";
|
||||
import { AddonProviderFactory } from "../../../services/addons/addon.provider.factory";
|
||||
import { AddonProviderType } from "../../../addon-providers/addon-provider";
|
||||
import { BehaviorSubject, catchError, debounceTime, first, from, map, of, Subject, switchMap, takeUntil } from "rxjs";
|
||||
import { PreferenceStorageService } from "../../../services/storage/preference-storage.service";
|
||||
import { SensitiveStorageService } from "../../../services/storage/sensitive-storage.service";
|
||||
import { PREF_CF2_API_KEY } from "../../../../common/constants";
|
||||
import { FormControl, FormGroup } from "@angular/forms";
|
||||
|
||||
@@ -29,7 +29,7 @@ export class OptionsAddonSectionComponent implements OnInit, OnDestroy {
|
||||
|
||||
public constructor(
|
||||
private _addonProviderService: AddonProviderFactory,
|
||||
private _preferenceStorageService: PreferenceStorageService
|
||||
private _sensitiveStorageService: SensitiveStorageService
|
||||
) {
|
||||
this._addonProviderService.addonProviderChange$.subscribe(() => {
|
||||
this.loadProviderStates();
|
||||
@@ -41,7 +41,7 @@ export class OptionsAddonSectionComponent implements OnInit, OnDestroy {
|
||||
debounceTime(300),
|
||||
switchMap((ch) => {
|
||||
if (ch.cfV2ApiKey) {
|
||||
return from(this._preferenceStorageService.setAsync(PREF_CF2_API_KEY, ch.cfV2ApiKey));
|
||||
return from(this._sensitiveStorageService.setAsync(PREF_CF2_API_KEY, ch.cfV2ApiKey));
|
||||
}
|
||||
return of(undefined);
|
||||
}),
|
||||
@@ -71,7 +71,7 @@ export class OptionsAddonSectionComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
private loadCfV2ApiKey() {
|
||||
from(this._preferenceStorageService.getAsync(PREF_CF2_API_KEY))
|
||||
from(this._sensitiveStorageService.getAsync(PREF_CF2_API_KEY))
|
||||
.pipe(
|
||||
first(),
|
||||
map((apiKey) => {
|
||||
|
||||
@@ -16,6 +16,20 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- SHOW CONFIG FILES -->
|
||||
<div class="section">
|
||||
<div class="row align-items-center">
|
||||
<div class="flex-grow-1">
|
||||
<div>{{ "PAGES.OPTIONS.DEBUG.CONFIG_FILES_LABEL" | translate }}</div>
|
||||
<small class="text-2">{{ "PAGES.OPTIONS.DEBUG.CONFIG_FILES_DESCRIPTION" | translate }}</small>
|
||||
</div>
|
||||
<div>
|
||||
<button id="show-config-btn" mat-flat-button color="primary" (click)="onShowConfig()">
|
||||
{{ "PAGES.OPTIONS.DEBUG.CONFIG_FILES_BUTTON" | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- DUMP DEBUG DATA -->
|
||||
<div class="section">
|
||||
<div class="row align-items-center">
|
||||
|
||||
@@ -22,6 +22,10 @@ export class OptionsDebugSectionComponent {
|
||||
await this._wowupService.showLogsFolder();
|
||||
}
|
||||
|
||||
public async onShowConfig(): Promise<void> {
|
||||
await this._wowupService.showConfigFolder();
|
||||
}
|
||||
|
||||
public async onLogDebugData(): Promise<void> {
|
||||
try {
|
||||
this.dumpingDebugData = true;
|
||||
|
||||
@@ -23,6 +23,7 @@ import { Subject } from "rxjs";
|
||||
import { PreferenceStorageService } from "../storage/preference-storage.service";
|
||||
import { CurseAddonV2Provider } from "../../addon-providers/curse-addon-v2-provider";
|
||||
import { CurseAddonProvider } from "../../addon-providers/curse-addon-provider";
|
||||
import { SensitiveStorageService } from "../storage/sensitive-storage.service";
|
||||
|
||||
@Injectable({
|
||||
providedIn: "root",
|
||||
@@ -44,7 +45,8 @@ export class AddonProviderFactory {
|
||||
private _tocService: TocService,
|
||||
private _warcraftService: WarcraftService,
|
||||
private _wowupApiService: WowUpApiService,
|
||||
private _preferenceStorageService: PreferenceStorageService
|
||||
private _preferenceStorageService: PreferenceStorageService,
|
||||
private _sensitiveStorageService: SensitiveStorageService,
|
||||
) {}
|
||||
|
||||
/** This is part of the APP_INITIALIZER and called before the app is bootstrapped */
|
||||
@@ -134,7 +136,7 @@ export class AddonProviderFactory {
|
||||
this._wowupApiService,
|
||||
this._warcraftService,
|
||||
this._tocService,
|
||||
this._preferenceStorageService,
|
||||
this._sensitiveStorageService,
|
||||
this._networkService
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,38 +1,17 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
|
||||
import {
|
||||
IPC_STORE_GET_OBJECT,
|
||||
IPC_STORE_GET_OBJECT_SYNC,
|
||||
IPC_STORE_SET_OBJECT,
|
||||
PREFERENCE_STORE_NAME,
|
||||
TRUE_STR,
|
||||
} from "../../../common/constants";
|
||||
import { PREFERENCE_STORE_NAME } from "../../../common/constants";
|
||||
import { StorageService } from "./storage.service";
|
||||
import { ElectronService } from "../electron/electron.service";
|
||||
|
||||
@Injectable({
|
||||
providedIn: "root",
|
||||
})
|
||||
export class PreferenceStorageService {
|
||||
public constructor(private _electronService: ElectronService) {}
|
||||
export class PreferenceStorageService extends StorageService {
|
||||
protected readonly storageName = PREFERENCE_STORE_NAME;
|
||||
|
||||
public async getBool(key: string): Promise<boolean> {
|
||||
const val = await this.getAsync(key);
|
||||
return val === TRUE_STR;
|
||||
}
|
||||
|
||||
public getAsync<T = string>(key: string): Promise<T> {
|
||||
return this._electronService.invoke(IPC_STORE_GET_OBJECT, PREFERENCE_STORE_NAME, key);
|
||||
}
|
||||
|
||||
public getSync<T = string>(key: string): T {
|
||||
return this._electronService.sendSync<T>(IPC_STORE_GET_OBJECT_SYNC, PREFERENCE_STORE_NAME, key);
|
||||
}
|
||||
|
||||
public async setAsync(key: string, value: unknown): Promise<void> {
|
||||
return await this._electronService.invoke(IPC_STORE_SET_OBJECT, PREFERENCE_STORE_NAME, key, value);
|
||||
}
|
||||
|
||||
public getObjectAsync<T>(key: string): Promise<T | undefined> {
|
||||
return this._electronService.invoke(IPC_STORE_GET_OBJECT, PREFERENCE_STORE_NAME, key);
|
||||
public constructor(electronService: ElectronService) {
|
||||
super(electronService);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
|
||||
import { SENSITIVE_STORE_NAME } from "../../../common/constants";
|
||||
import { StorageService } from "./storage.service";
|
||||
import { ElectronService } from "../electron/electron.service";
|
||||
|
||||
@Injectable({
|
||||
providedIn: "root",
|
||||
})
|
||||
export class SensitiveStorageService extends StorageService {
|
||||
protected readonly storageName = SENSITIVE_STORE_NAME;
|
||||
|
||||
public constructor(electronService: ElectronService) {
|
||||
super(electronService);
|
||||
}
|
||||
}
|
||||
34
wowup-electron/src/app/services/storage/storage.service.ts
Normal file
34
wowup-electron/src/app/services/storage/storage.service.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import {
|
||||
IPC_STORE_GET_OBJECT,
|
||||
IPC_STORE_GET_OBJECT_SYNC,
|
||||
IPC_STORE_SET_OBJECT,
|
||||
TRUE_STR,
|
||||
} from "../../../common/constants";
|
||||
import { ElectronService } from "../electron/electron.service";
|
||||
|
||||
export abstract class StorageService {
|
||||
protected abstract readonly storageName: string;
|
||||
|
||||
protected constructor(private _electronService: ElectronService) {}
|
||||
|
||||
public async getBool(key: string): Promise<boolean> {
|
||||
const val = await this.getAsync(key);
|
||||
return val === TRUE_STR;
|
||||
}
|
||||
|
||||
public getAsync<T = string>(key: string): Promise<T> {
|
||||
return this._electronService.invoke(IPC_STORE_GET_OBJECT, this.storageName, key);
|
||||
}
|
||||
|
||||
public getSync<T = string>(key: string): T {
|
||||
return this._electronService.sendSync<T>(IPC_STORE_GET_OBJECT_SYNC, this.storageName, key);
|
||||
}
|
||||
|
||||
public async setAsync(key: string, value: unknown): Promise<void> {
|
||||
return await this._electronService.invoke(IPC_STORE_SET_OBJECT, this.storageName, key, value);
|
||||
}
|
||||
|
||||
public getObjectAsync<T>(key: string): Promise<T | undefined> {
|
||||
return this._electronService.invoke(IPC_STORE_GET_OBJECT, this.storageName, key);
|
||||
}
|
||||
}
|
||||
@@ -328,6 +328,10 @@ export class WowUpService {
|
||||
await this._fileService.showDirectory(this.applicationLogsFolderPath);
|
||||
}
|
||||
|
||||
public async showConfigFolder(): Promise<void> {
|
||||
await this._fileService.showDirectory(this.applicationFolderPath);
|
||||
}
|
||||
|
||||
public checkForAppUpdate(): void {
|
||||
this._electronService.send(IPC_APP_CHECK_UPDATE);
|
||||
}
|
||||
|
||||
@@ -531,6 +531,9 @@
|
||||
"USE_SYMLINK_SUPPORT_DESCRIPTION": "Allow WowUp to scan symlink folders in your addon folder. Warning: they will be replaced when updating/installing."
|
||||
},
|
||||
"DEBUG": {
|
||||
"CONFIG_FILES_BUTTON": "Show Config Files",
|
||||
"CONFIG_FILES_DESCRIPTION": "Open the folder where for example your addons.json and preferences.json are stored.",
|
||||
"CONFIG_FILES_LABEL": "Config Files",
|
||||
"DEBUG_DATA_BUTTON": "Uložit debugovací data",
|
||||
"DEBUG_DATA_DESCRIPTION": "Zaloguje debugovací data do logovacího souboru pro případnou diagnostiku problémů s aplikací. Pro zvědavce: Tato data naleznete v nejnovějším logovacím souboru.",
|
||||
"DEBUG_DATA_LABEL": "Debug data",
|
||||
|
||||
@@ -531,6 +531,9 @@
|
||||
"USE_SYMLINK_SUPPORT_DESCRIPTION": "Erlaubt WowUp Symlink-Ordner in deinem Addon-Ordner zu scannen. Warnung: Diese werden beim Aktualisieren/Installieren ersetzt."
|
||||
},
|
||||
"DEBUG": {
|
||||
"CONFIG_FILES_BUTTON": "Show Config Files",
|
||||
"CONFIG_FILES_DESCRIPTION": "Open the folder where for example your addons.json and preferences.json are stored.",
|
||||
"CONFIG_FILES_LABEL": "Config Files",
|
||||
"DEBUG_DATA_BUTTON": "Debug-Daten speichern",
|
||||
"DEBUG_DATA_DESCRIPTION": "Protokolliere Debug-Daten, um mögliche Probleme zu diagnostizieren. Dies findest Du in Deiner aktuellen Protokolldatei (für Neugierige).",
|
||||
"DEBUG_DATA_LABEL": "Debug-Daten",
|
||||
|
||||
@@ -531,6 +531,9 @@
|
||||
"USE_SYMLINK_SUPPORT_DESCRIPTION": "Allow WowUp to scan symlink folders in your addon folder. Warning: they will be replaced when updating/installing."
|
||||
},
|
||||
"DEBUG": {
|
||||
"CONFIG_FILES_BUTTON": "Show Config Files",
|
||||
"CONFIG_FILES_DESCRIPTION": "Open the folder where for example your addons.json and preferences.json are stored.",
|
||||
"CONFIG_FILES_LABEL": "Config Files",
|
||||
"DEBUG_DATA_BUTTON": "Dump Debug Data",
|
||||
"DEBUG_DATA_DESCRIPTION": "Log debug data to help with diagnosing potential issues. This can be found in your latest log file for the curious.",
|
||||
"DEBUG_DATA_LABEL": "Debug Data",
|
||||
|
||||
@@ -531,6 +531,9 @@
|
||||
"USE_SYMLINK_SUPPORT_DESCRIPTION": "Permite a WowUp escanear enlaces simbólicos en la carpeta de addons.\nAdvertecia: Los enlaces serán reemplazados al actualizar/instalar los addons."
|
||||
},
|
||||
"DEBUG": {
|
||||
"CONFIG_FILES_BUTTON": "Show Config Files",
|
||||
"CONFIG_FILES_DESCRIPTION": "Open the folder where for example your addons.json and preferences.json are stored.",
|
||||
"CONFIG_FILES_LABEL": "Config Files",
|
||||
"DEBUG_DATA_BUTTON": "Eliminar datos de depuración",
|
||||
"DEBUG_DATA_DESCRIPTION": "Registra datos de depuración y ayuda a diagnosticar problemas potenciales. Puede curiosearlo abriendo el último archivo de registro.",
|
||||
"DEBUG_DATA_LABEL": "Datos de depuración",
|
||||
|
||||
@@ -531,6 +531,9 @@
|
||||
"USE_SYMLINK_SUPPORT_DESCRIPTION": "Allow WowUp to scan symlink folders in your addon folder. Warning: they will be replaced when updating/installing."
|
||||
},
|
||||
"DEBUG": {
|
||||
"CONFIG_FILES_BUTTON": "Show Config Files",
|
||||
"CONFIG_FILES_DESCRIPTION": "Open the folder where for example your addons.json and preferences.json are stored.",
|
||||
"CONFIG_FILES_LABEL": "Config Files",
|
||||
"DEBUG_DATA_BUTTON": "Dump des données de débogage",
|
||||
"DEBUG_DATA_DESCRIPTION": "Log les données de débogage pour aider à diagnostiquer les problèmes potentiels. Cela peut être trouvé dans votre dernier fichier journal pour les curieux.",
|
||||
"DEBUG_DATA_LABEL": "Déboguer les données",
|
||||
|
||||
@@ -531,6 +531,9 @@
|
||||
"USE_SYMLINK_SUPPORT_DESCRIPTION": "Consenti a WowUp di scansionare le cartelle dei symlinks nella cartella dell'addon. Attenzione: verranno sostituiti durante l'aggiornamento/installazione."
|
||||
},
|
||||
"DEBUG": {
|
||||
"CONFIG_FILES_BUTTON": "Show Config Files",
|
||||
"CONFIG_FILES_DESCRIPTION": "Open the folder where for example your addons.json and preferences.json are stored.",
|
||||
"CONFIG_FILES_LABEL": "Config Files",
|
||||
"DEBUG_DATA_BUTTON": "Dump Dati Di Debug",
|
||||
"DEBUG_DATA_DESCRIPTION": "Registra i dati di debug per aiutare a diagnosticare potenziali problemi. Questi dati possono essere trovati nei tuoi ultimi file di log.",
|
||||
"DEBUG_DATA_LABEL": "Dati di Debug",
|
||||
|
||||
@@ -531,6 +531,9 @@
|
||||
"USE_SYMLINK_SUPPORT_DESCRIPTION": "Allow WowUp to scan symlink folders in your addon folder. Warning: they will be replaced when updating/installing."
|
||||
},
|
||||
"DEBUG": {
|
||||
"CONFIG_FILES_BUTTON": "Show Config Files",
|
||||
"CONFIG_FILES_DESCRIPTION": "Open the folder where for example your addons.json and preferences.json are stored.",
|
||||
"CONFIG_FILES_LABEL": "Config Files",
|
||||
"DEBUG_DATA_BUTTON": "디버그 데이터 덤프",
|
||||
"DEBUG_DATA_DESCRIPTION": "잠재적인 문제를 진단하는데 도움을 주기 위해 디버그 데이터를 기록합니다. 궁금하시다면 최신 로그 파일에서 확인하실 수 있습니다.",
|
||||
"DEBUG_DATA_LABEL": "디버그 데이터",
|
||||
|
||||
@@ -531,6 +531,9 @@
|
||||
"USE_SYMLINK_SUPPORT_DESCRIPTION": "Allow WowUp to scan symlink folders in your addon folder. Warning: they will be replaced when updating/installing."
|
||||
},
|
||||
"DEBUG": {
|
||||
"CONFIG_FILES_BUTTON": "Show Config Files",
|
||||
"CONFIG_FILES_DESCRIPTION": "Open the folder where for example your addons.json and preferences.json are stored.",
|
||||
"CONFIG_FILES_LABEL": "Config Files",
|
||||
"DEBUG_DATA_BUTTON": "Dump Debugdata",
|
||||
"DEBUG_DATA_DESCRIPTION": "Loggfør debugdata for å hjelpe til med å diagnotisere eventuelle problemer. Hvis du er nyskgjerrig kan du finne dette i din siste loggfil.",
|
||||
"DEBUG_DATA_LABEL": "Debugdata",
|
||||
|
||||
@@ -149,6 +149,8 @@
|
||||
"IGNORED": "Zignorowany",
|
||||
"INSTALL": "Zainstaluj",
|
||||
"PENDING": "W toku",
|
||||
"UNAVAILABLE": "Unavailable",
|
||||
"UNAVAILABLE_TOOLTIP": "This author or provider has made this addon unavailable",
|
||||
"UNINSTALL": "Odinstaluj",
|
||||
"UNKNOWN": "",
|
||||
"UPDATE": "Aktualizacja",
|
||||
@@ -469,6 +471,11 @@
|
||||
"OPTIONS": {
|
||||
"ADDON": {
|
||||
"AD_REQUIRED_HINT": "Reklama wymagana",
|
||||
"CURSE_FORGE_V2": {
|
||||
"API_KEY_DESCRIPTION": "If you have requested a CurseForge API key you can input it here to connect to their API.",
|
||||
"API_KEY_TITLE": "CurseForge API Key",
|
||||
"PROVIDER_NOTE": "API Key Required"
|
||||
},
|
||||
"ENABLED_PROVIDERS": {
|
||||
"DESCRIPTION": "Wybierz, którzy dostawcy mogą być używani do wyszukiwania i instalowania nowych addonów",
|
||||
"FIELD_LABEL": "Włączone addony dostawców",
|
||||
@@ -524,6 +531,9 @@
|
||||
"USE_SYMLINK_SUPPORT_DESCRIPTION": "Pozwól WowUp na skanowanie folderów z symlinkami w folderze addonów. Ostrzeżenie: zostaną one zastąpione podczas aktualizacji/instalacji."
|
||||
},
|
||||
"DEBUG": {
|
||||
"CONFIG_FILES_BUTTON": "Show Config Files",
|
||||
"CONFIG_FILES_DESCRIPTION": "Open the folder where for example your addons.json and preferences.json are stored.",
|
||||
"CONFIG_FILES_LABEL": "Config Files",
|
||||
"DEBUG_DATA_BUTTON": "Zrzut danych debugowania",
|
||||
"DEBUG_DATA_DESCRIPTION": "Rejestruj dane debugowania, aby pomóc w diagnozowaniu potencjalnych problemów. Można je znaleźć w najnowszym pliku dziennika dla ciekawskich.",
|
||||
"DEBUG_DATA_LABEL": "Dane debugowania",
|
||||
|
||||
@@ -531,6 +531,9 @@
|
||||
"USE_SYMLINK_SUPPORT_DESCRIPTION": "Permitir ao WowUp escanear pastas symlink na sua pasta de Addons. Aviso: elas serão substituidas quando atualizar/instalar."
|
||||
},
|
||||
"DEBUG": {
|
||||
"CONFIG_FILES_BUTTON": "Show Config Files",
|
||||
"CONFIG_FILES_DESCRIPTION": "Open the folder where for example your addons.json and preferences.json are stored.",
|
||||
"CONFIG_FILES_LABEL": "Config Files",
|
||||
"DEBUG_DATA_BUTTON": "Esvaziar log de depuração de dados",
|
||||
"DEBUG_DATA_DESCRIPTION": "Registra os dados de depuração e ajuda a diagnosticar problemas potenciais. Apenas por o curiosidade, isso pode ser encontrado em seu último arquivo de registro.",
|
||||
"DEBUG_DATA_LABEL": "Depurar Dados",
|
||||
|
||||
@@ -531,6 +531,9 @@
|
||||
"USE_SYMLINK_SUPPORT_DESCRIPTION": "Разрешает WowUp сканировать папки символических ссылок в папке вашей модификации. Предупреждение: они будут заменены при обновлении/установке."
|
||||
},
|
||||
"DEBUG": {
|
||||
"CONFIG_FILES_BUTTON": "Show Config Files",
|
||||
"CONFIG_FILES_DESCRIPTION": "Open the folder where for example your addons.json and preferences.json are stored.",
|
||||
"CONFIG_FILES_LABEL": "Config Files",
|
||||
"DEBUG_DATA_BUTTON": "Дамп отладочных данных",
|
||||
"DEBUG_DATA_DESCRIPTION": "Записывать отладочные данные, чтобы помочь в диагностике потенциальных проблем. Его можно найти в последнем лог-файле, если необходимо.",
|
||||
"DEBUG_DATA_LABEL": "Отладка данных",
|
||||
|
||||
@@ -531,6 +531,9 @@
|
||||
"USE_SYMLINK_SUPPORT_DESCRIPTION": "允許 WowUp 掃描插件所在路徑下的符號連結。警告:符號連結在安裝或更新插件時會被替換。"
|
||||
},
|
||||
"DEBUG": {
|
||||
"CONFIG_FILES_BUTTON": "Show Config Files",
|
||||
"CONFIG_FILES_DESCRIPTION": "Open the folder where for example your addons.json and preferences.json are stored.",
|
||||
"CONFIG_FILES_LABEL": "Config Files",
|
||||
"DEBUG_DATA_BUTTON": "轉儲除錯資料",
|
||||
"DEBUG_DATA_DESCRIPTION": "記錄除錯資料以幫助診斷潛在的問題。除錯資料可以在最新的日誌檔案中找到。",
|
||||
"DEBUG_DATA_LABEL": "除錯資料",
|
||||
|
||||
@@ -531,6 +531,9 @@
|
||||
"USE_SYMLINK_SUPPORT_DESCRIPTION": "允许 WowUp 扫描插件所在路径下的符号链接。警告:符号链接在安装或更新插件时会被替换。"
|
||||
},
|
||||
"DEBUG": {
|
||||
"CONFIG_FILES_BUTTON": "Show Config Files",
|
||||
"CONFIG_FILES_DESCRIPTION": "Open the folder where for example your addons.json and preferences.json are stored.",
|
||||
"CONFIG_FILES_LABEL": "Config Files",
|
||||
"DEBUG_DATA_BUTTON": "转储调试数据",
|
||||
"DEBUG_DATA_DESCRIPTION": "记录调试数据以帮助诊断潜在的问题。调试数据可以在最新的日志文件中找到。",
|
||||
"DEBUG_DATA_LABEL": "调试数据",
|
||||
|
||||
@@ -109,6 +109,7 @@ export const IPC_STORE_REMOVE_OBJECT = "store-remove-object";
|
||||
// STORES
|
||||
export const ADDON_STORE_NAME = "addons";
|
||||
export const PREFERENCE_STORE_NAME = "preferences";
|
||||
export const SENSITIVE_STORE_NAME = "sensitive";
|
||||
export const STORAGE_WOWUP_AUTH_TOKEN = "wowup-auth-token";
|
||||
|
||||
// PREFERENCES
|
||||
|
||||
Reference in New Issue
Block a user