Add independent ID key configuration and recovery

This commit is contained in:
vorotamoroz committed 2026-09-29 12:58:11 +00:00
1 parent 126d6eadb8
commit bf7822f20b
51 files changed
+2572 -168

No files matched your search

+36 -8
View File
@@ -1,6 +1,5 @@
import {
type BucketSyncSetting,
type EncryptionSettings,
type ObsidianLiveSyncSettings,
type P2PSyncSetting,
LOG_LEVEL_NOTICE,
@@ -36,6 +35,7 @@ import type {
SetupRemoteCouchDBResultType,
SetupRemoteCouchDBInitialData,
SetupRemoteE2EEResultType,
SetupRemoteE2EEInitialData,
SetupRemoteP2PInitialData,
SetupRemoteP2PResultType,
SetupRemoteResultType,
@@ -58,6 +58,20 @@ function copySettingsForRemoteProfileUpdate(settings: ObsidianLiveSyncSettings):
};
}
function normaliseImportedIdDerivationSettings(settings: ObsidianLiveSyncSettings): ObsidianLiveSyncSettings {
// Setup URIs are complete imports even when their encoder omitted default-valued fields.
// Fill each missing half so a receiving device cannot supply the unrelated saved key.
return {
...settings,
idDerivationVersion: Object.prototype.hasOwnProperty.call(settings, "idDerivationVersion")
? settings.idDerivationVersion
: 0,
idDerivationKey: Object.prototype.hasOwnProperty.call(settings, "idDerivationKey")
? settings.idDerivationKey
: "",
};
}
/**
* User modes for onboarding and setup
*/
@@ -219,7 +233,7 @@ export class SetupManager extends AbstractModule {
return false;
}
this._log("Setup URI dialog closed.", LOG_LEVEL_VERBOSE);
return await this.onConfirmApplySettingsFromWizard(newSetting, userMode);
return await this.onConfirmApplySettingsFromWizard(normaliseImportedIdDerivationSettings(newSetting), userMode);
}
/**
@@ -328,9 +342,12 @@ export class SetupManager extends AbstractModule {
* @returns
*/
async onlyE2EEConfiguration(userMode: UserMode, currentSetting: ObsidianLiveSyncSettings): Promise<boolean> {
const e2eeConf = await this.dialogManager.openWithExplicitCancel<SetupRemoteE2EEResultType, EncryptionSettings>(
const e2eeConf = await this.dialogManager.openWithExplicitCancel<
SetupRemoteE2EEResultType,
SetupRemoteE2EEInitialData
>(
SetupRemoteE2EE,
currentSetting
{ settings: currentSetting, newVault: userMode === UserMode.NewUser }
);
if (e2eeConf === "cancelled") {
this._log("E2EE configuration cancelled.", LOG_LEVEL_NOTICE);
@@ -341,7 +358,9 @@ export class SetupManager extends AbstractModule {
currentSetting.encrypt === e2eeConf.encrypt &&
currentSetting.passphrase === e2eeConf.passphrase &&
currentSetting.E2EEAlgorithm === e2eeConf.E2EEAlgorithm &&
currentSetting.usePathObfuscation === e2eeConf.usePathObfuscation;
currentSetting.usePathObfuscation === e2eeConf.usePathObfuscation &&
currentSetting.idDerivationVersion === e2eeConf.idDerivationVersion &&
currentSetting.idDerivationKey === e2eeConf.idDerivationKey;
if (userMode === UserMode.Update && onlyInternalMetadataPreferenceChanged) {
if (e2eeConf.encryptInternalMetadata && currentSetting.remoteType === REMOTE_COUCHDB) {
const proceed = "Enable without rebuilding — update every other device first";
@@ -375,9 +394,12 @@ export class SetupManager extends AbstractModule {
* @returns
*/
async onConfigureManually(originalSetting: ObsidianLiveSyncSettings, userMode: UserMode): Promise<boolean> {
const e2eeConf = await this.dialogManager.openWithExplicitCancel<SetupRemoteE2EEResultType, EncryptionSettings>(
const e2eeConf = await this.dialogManager.openWithExplicitCancel<
SetupRemoteE2EEResultType,
SetupRemoteE2EEInitialData
>(
SetupRemoteE2EE,
originalSetting
{ settings: originalSetting, newVault: userMode === UserMode.NewUser }
);
if (e2eeConf === "cancelled") {
this._log("Manual configuration cancelled.", LOG_LEVEL_NOTICE);
@@ -521,7 +543,13 @@ export class SetupManager extends AbstractModule {
* @returns Promise that resolves to true if settings applied successfully, false otherwise
*/
async decodeQR(qr: string) {
const newSettings = decodeSettingsFromQRCodeData(qr);
let newSettings: ObsidianLiveSyncSettings;
try {
newSettings = normaliseImportedIdDerivationSettings(decodeSettingsFromQRCodeData(qr));
} catch {
this._log("The QR configuration could not be decoded or contains unsupported settings.", LOG_LEVEL_NOTICE);
return false;
}
return await this.onConfirmApplySettingsFromWizard(newSettings, UserMode.Unknown);
}