mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2025-12-13 17:55:56 +00:00
### Fixed
- The encryption algorithm now uses HKDF with a master key. - `Fetch everything from the remote` now works correctly. - Extra log messages during QR code decoding have been removed. ### Changed - Some settings have been moved to the `Patches` pane: ### Behavioural and API Changes - `DirectFileManipulatorV2` now requires new settings (as you may already know, E2EEAlgorithm). - The database version has been increased to `12` from `10`.
This commit is contained in:
2
src/lib
2
src/lib
Submodule src/lib updated: dfbd6358b1...ab02f72aa5
@@ -292,7 +292,8 @@ export default class ObsidianLiveSyncPlugin
|
||||
skipInfo: boolean,
|
||||
compression: boolean,
|
||||
customHeaders: Record<string, string>,
|
||||
useRequestAPI: boolean
|
||||
useRequestAPI: boolean,
|
||||
getPBKDF2Salt: () => Promise<Uint8Array>
|
||||
): Promise<
|
||||
| string
|
||||
| {
|
||||
|
||||
@@ -11,7 +11,7 @@ import { AbstractModule } from "../AbstractModule.ts";
|
||||
import type { Rebuilder } from "../interfaces/DatabaseRebuilder.ts";
|
||||
import type { ICoreModule } from "../ModuleTypes.ts";
|
||||
import type { LiveSyncCouchDBReplicator } from "../../lib/src/replication/couchdb/LiveSyncReplicator.ts";
|
||||
import { fetchAllUsedChunks } from "../../lib/src/pouchdb/utils_couchdb.ts";
|
||||
import { fetchAllUsedChunks } from "@/lib/src/pouchdb/chunks.ts";
|
||||
import { EVENT_DATABASE_REBUILT, eventHub } from "src/common/events.ts";
|
||||
|
||||
export class ModuleRebuilder extends AbstractModule implements ICoreModule, Rebuilder {
|
||||
@@ -90,8 +90,8 @@ export class ModuleRebuilder extends AbstractModule implements ICoreModule, Rebu
|
||||
return this.rebuildEverything();
|
||||
}
|
||||
|
||||
$fetchLocal(makeLocalChunkBeforeSync?: boolean): Promise<void> {
|
||||
return this.fetchLocal(makeLocalChunkBeforeSync);
|
||||
$fetchLocal(makeLocalChunkBeforeSync?: boolean, preventMakeLocalFilesBeforeSync?: boolean): Promise<void> {
|
||||
return this.fetchLocal(makeLocalChunkBeforeSync, preventMakeLocalFilesBeforeSync);
|
||||
}
|
||||
|
||||
async scheduleRebuild(): Promise<void> {
|
||||
|
||||
@@ -4,7 +4,8 @@ import { AbstractModule } from "../AbstractModule";
|
||||
import type { ICoreModule } from "../ModuleTypes";
|
||||
import { Logger, LOG_LEVEL_NOTICE, LOG_LEVEL_INFO, LOG_LEVEL_VERBOSE } from "octagonal-wheels/common/logger";
|
||||
import { isLockAcquired, shareRunningResult, skipIfDuplicated } from "octagonal-wheels/concurrency/lock";
|
||||
import { purgeUnreferencedChunks, balanceChunkPurgedDBs } from "../../lib/src/pouchdb/utils_couchdb";
|
||||
import { balanceChunkPurgedDBs } from "@/lib/src/pouchdb/chunks";
|
||||
import { purgeUnreferencedChunks } from "@/lib/src/pouchdb/chunks";
|
||||
import { LiveSyncCouchDBReplicator } from "../../lib/src/replication/couchdb/LiveSyncReplicator";
|
||||
import { throttle } from "octagonal-wheels/function";
|
||||
import { arrayToChunkedArray } from "octagonal-wheels/collection";
|
||||
@@ -79,8 +80,18 @@ export class ModuleReplicator extends AbstractModule implements ICoreModule {
|
||||
$everyOnResetDatabase(db: LiveSyncLocalDB): Promise<boolean> {
|
||||
return this.setReplicator();
|
||||
}
|
||||
async ensureReplicatorPBKDF2Salt(showMessage: boolean = false): Promise<boolean> {
|
||||
// Checking salt
|
||||
const replicator = this.core.$$getReplicator();
|
||||
return await replicator.ensurePBKDF2Salt(this.settings, showMessage, true);
|
||||
}
|
||||
|
||||
async $everyBeforeReplicate(showMessage: boolean): Promise<boolean> {
|
||||
// Checking salt
|
||||
if (!(await this.ensureReplicatorPBKDF2Salt(showMessage))) {
|
||||
Logger("Failed to ensure PBKDF2 salt for replication.", LOG_LEVEL_NOTICE);
|
||||
return false;
|
||||
}
|
||||
await this.loadQueuedFiles();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -121,9 +121,9 @@ export class ModuleRedFlag extends AbstractModule implements ICoreModule {
|
||||
}
|
||||
);
|
||||
let makeLocalChunkBeforeSync = false;
|
||||
let preventMakeLocalFilesBeforeSync = false;
|
||||
let makeLocalFilesBeforeSync = false;
|
||||
if (chunkMode === method1) {
|
||||
preventMakeLocalFilesBeforeSync = true;
|
||||
makeLocalFilesBeforeSync = true;
|
||||
} else if (chunkMode === method2) {
|
||||
makeLocalChunkBeforeSync = true;
|
||||
} else if (chunkMode === method3) {
|
||||
@@ -133,7 +133,7 @@ export class ModuleRedFlag extends AbstractModule implements ICoreModule {
|
||||
return false;
|
||||
}
|
||||
|
||||
await this.core.rebuilder.$fetchLocal(makeLocalChunkBeforeSync, preventMakeLocalFilesBeforeSync);
|
||||
await this.core.rebuilder.$fetchLocal(makeLocalChunkBeforeSync, !makeLocalFilesBeforeSync);
|
||||
|
||||
await this.deleteRedFlag3();
|
||||
if (this.settings.suspendFileWatching) {
|
||||
|
||||
@@ -84,8 +84,8 @@ export class ModuleMigration extends AbstractModule implements ICoreModule {
|
||||
$msg("Doctor.Dialogue.MainFix", {
|
||||
name: getConfName(key as AllSettingItemKey),
|
||||
current: `${this.settings[key]}`,
|
||||
reason: value.reason ?? " N/A ",
|
||||
ideal: `${value.valueDisplay ?? value.value}`,
|
||||
reason: value.reasonFunc?.(this.settings) ?? value.reason ?? " N/A ",
|
||||
ideal: `${value.valueDisplayFunc ? value.valueDisplayFunc(this.settings) : value.value}`,
|
||||
//@ts-ignore
|
||||
level: `${level}`,
|
||||
note: note,
|
||||
|
||||
@@ -3,13 +3,10 @@ import { LOG_LEVEL_DEBUG, LOG_LEVEL_NOTICE, LOG_LEVEL_VERBOSE } from "octagonal-
|
||||
import { Notice, requestUrl, type RequestUrlParam, type RequestUrlResponse } from "../../deps.ts";
|
||||
import { type CouchDBCredentials, type EntryDoc, type FilePathWithPrefix } from "../../lib/src/common/types.ts";
|
||||
import { getPathFromTFile } from "../../common/utils.ts";
|
||||
import {
|
||||
disableEncryption,
|
||||
enableEncryption,
|
||||
isCloudantURI,
|
||||
isValidRemoteCouchDBURI,
|
||||
replicationFilter,
|
||||
} from "../../lib/src/pouchdb/utils_couchdb.ts";
|
||||
import { isCloudantURI, isValidRemoteCouchDBURI } from "../../lib/src/pouchdb/utils_couchdb.ts";
|
||||
import { replicationFilter } from "@/lib/src/pouchdb/compress.ts";
|
||||
import { disableEncryption } from "@/lib/src/pouchdb/encryption.ts";
|
||||
import { enableEncryption } from "@/lib/src/pouchdb/encryption.ts";
|
||||
import { setNoticeClass } from "../../lib/src/mock_and_interop/wrapper.ts";
|
||||
import { ObsHttpHandler } from "./APILib/ObsHttpHandler.ts";
|
||||
import { PouchDB } from "../../lib/src/pouchdb/pouchdb-browser.ts";
|
||||
@@ -103,7 +100,8 @@ export class ModuleObsidianAPI extends AbstractObsidianModule implements IObsidi
|
||||
skipInfo: boolean,
|
||||
compression: boolean,
|
||||
customHeaders: Record<string, string>,
|
||||
useRequestAPI: boolean
|
||||
useRequestAPI: boolean,
|
||||
getPBKDF2Salt: () => Promise<Uint8Array>
|
||||
): Promise<string | { db: PouchDB.Database<EntryDoc>; info: PouchDB.Core.DatabaseInfo }> {
|
||||
if (!isValidRemoteCouchDBURI(uri)) return "Remote URI is not valid";
|
||||
if (uri.toLowerCase() != uri) return "Remote URI and database name could not contain capital letters.";
|
||||
@@ -229,7 +227,14 @@ export class ModuleObsidianAPI extends AbstractObsidianModule implements IObsidi
|
||||
replicationFilter(db, compression);
|
||||
disableEncryption();
|
||||
if (passphrase !== "false" && typeof passphrase === "string") {
|
||||
enableEncryption(db, passphrase, useDynamicIterationCount, false);
|
||||
enableEncryption(
|
||||
db,
|
||||
passphrase,
|
||||
useDynamicIterationCount,
|
||||
false,
|
||||
getPBKDF2Salt,
|
||||
this.settings.E2EEAlgorithm
|
||||
);
|
||||
}
|
||||
if (skipInfo) {
|
||||
return { db: db, info: { db_name: "", doc_count: 0, update_seq: "" } };
|
||||
|
||||
@@ -101,7 +101,6 @@ export class ModuleSetupObsidian extends AbstractObsidianModule implements IObsi
|
||||
//@ts-ignore
|
||||
newSettings[settingKey] = settingValue;
|
||||
}
|
||||
console.warn(newSettings);
|
||||
await this.applySettingWizard(this.settings, newSettings, "QR Code");
|
||||
}
|
||||
async command_copySetupURI(stripExtra = true) {
|
||||
|
||||
@@ -16,11 +16,9 @@ import {
|
||||
import { delay, isObjectDifferent, sizeToHumanReadable } from "../../../lib/src/common/utils.ts";
|
||||
import { versionNumberString2Number } from "../../../lib/src/string_and_binary/convert.ts";
|
||||
import { Logger } from "../../../lib/src/common/logger.ts";
|
||||
import {
|
||||
balanceChunkPurgedDBs,
|
||||
checkSyncInfo,
|
||||
purgeUnreferencedChunks,
|
||||
} from "../../../lib/src/pouchdb/utils_couchdb.ts";
|
||||
import { checkSyncInfo } from "@/lib/src/pouchdb/negotiation.ts";
|
||||
import { balanceChunkPurgedDBs } from "@/lib/src/pouchdb/chunks.ts";
|
||||
import { purgeUnreferencedChunks } from "@/lib/src/pouchdb/chunks.ts";
|
||||
import { testCrypt } from "../../../lib/src/encryption/e2ee_v2.ts";
|
||||
import ObsidianLiveSyncPlugin from "../../../main.ts";
|
||||
import { scheduleTask } from "../../../common/utils.ts";
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
import { type HashAlgorithm, LOG_LEVEL_NOTICE } from "../../../lib/src/common/types.ts";
|
||||
import {
|
||||
E2EEAlgorithmNames,
|
||||
E2EEAlgorithms,
|
||||
type HashAlgorithm,
|
||||
LOG_LEVEL_NOTICE,
|
||||
} from "../../../lib/src/common/types.ts";
|
||||
import { Logger } from "../../../lib/src/common/logger.ts";
|
||||
import { LiveSyncSetting as Setting } from "./LiveSyncSetting.ts";
|
||||
import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
|
||||
@@ -37,6 +42,19 @@ export function panePatches(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElemen
|
||||
void addPanel(paneEl, "Compatibility (Internal API Usage)").then((paneEl) => {
|
||||
new Setting(paneEl).autoWireToggle("watchInternalFileChanges", { invert: true });
|
||||
});
|
||||
void addPanel(paneEl, "Compatibility (Remote Database)").then((paneEl) => {
|
||||
new Setting(paneEl).autoWireDropDown("E2EEAlgorithm", {
|
||||
options: E2EEAlgorithmNames,
|
||||
});
|
||||
});
|
||||
new Setting(paneEl).autoWireToggle("useDynamicIterationCount", {
|
||||
holdValue: true,
|
||||
onUpdate: visibleOnly(
|
||||
() =>
|
||||
this.isConfiguredAs("E2EEAlgorithm", E2EEAlgorithms.ForceV1) ||
|
||||
this.isConfiguredAs("E2EEAlgorithm", E2EEAlgorithms.V1)
|
||||
),
|
||||
});
|
||||
|
||||
void addPanel(paneEl, "Edge case addressing (Database)").then((paneEl) => {
|
||||
new Setting(paneEl)
|
||||
@@ -79,4 +97,16 @@ export function panePatches(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElemen
|
||||
void addPanel(paneEl, "Compatibility (Trouble addressed)").then((paneEl) => {
|
||||
new Setting(paneEl).autoWireToggle("disableCheckingConfigMismatch");
|
||||
});
|
||||
|
||||
void addPanel(paneEl, "Remote Database Tweak (In sunset)").then((paneEl) => {
|
||||
new Setting(paneEl).autoWireToggle("useEden").setClass("wizardHidden");
|
||||
const onlyUsingEden = visibleOnly(() => this.isConfiguredAs("useEden", true));
|
||||
new Setting(paneEl).autoWireNumeric("maxChunksInEden", { onUpdate: onlyUsingEden }).setClass("wizardHidden");
|
||||
new Setting(paneEl)
|
||||
.autoWireNumeric("maxTotalLengthInEden", { onUpdate: onlyUsingEden })
|
||||
.setClass("wizardHidden");
|
||||
new Setting(paneEl).autoWireNumeric("maxAgeInEden", { onUpdate: onlyUsingEden }).setClass("wizardHidden");
|
||||
|
||||
new Setting(paneEl).autoWireToggle("enableCompression").setClass("wizardHidden");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,24 +2,12 @@ import { type ConfigPassphraseStore } from "../../../lib/src/common/types.ts";
|
||||
import { LiveSyncSetting as Setting } from "./LiveSyncSetting.ts";
|
||||
import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
|
||||
import type { PageFunctions } from "./SettingPane.ts";
|
||||
import { visibleOnly } from "./SettingPane.ts";
|
||||
|
||||
export function panePowerUsers(
|
||||
this: ObsidianLiveSyncSettingTab,
|
||||
paneEl: HTMLElement,
|
||||
{ addPanel }: PageFunctions
|
||||
): void {
|
||||
void addPanel(paneEl, "Remote Database Tweak").then((paneEl) => {
|
||||
new Setting(paneEl).autoWireToggle("useEden").setClass("wizardHidden");
|
||||
const onlyUsingEden = visibleOnly(() => this.isConfiguredAs("useEden", true));
|
||||
new Setting(paneEl).autoWireNumeric("maxChunksInEden", { onUpdate: onlyUsingEden }).setClass("wizardHidden");
|
||||
new Setting(paneEl)
|
||||
.autoWireNumeric("maxTotalLengthInEden", { onUpdate: onlyUsingEden })
|
||||
.setClass("wizardHidden");
|
||||
new Setting(paneEl).autoWireNumeric("maxAgeInEden", { onUpdate: onlyUsingEden }).setClass("wizardHidden");
|
||||
|
||||
new Setting(paneEl).autoWireToggle("enableCompression").setClass("wizardHidden");
|
||||
});
|
||||
|
||||
void addPanel(paneEl, "CouchDB Connection Tweak", undefined, this.onlyOnCouchDB).then((paneEl) => {
|
||||
paneEl.addClass("wizardHidden");
|
||||
|
||||
|
||||
@@ -579,12 +579,6 @@ The pane also can be launched by \`P2P Replicator\` command from the Command Pal
|
||||
holdValue: true,
|
||||
onUpdate: isEncryptEnabled,
|
||||
});
|
||||
new Setting(paneEl)
|
||||
.autoWireToggle("useDynamicIterationCount", {
|
||||
holdValue: true,
|
||||
onUpdate: isEncryptEnabled,
|
||||
})
|
||||
.setClass("wizardHidden");
|
||||
});
|
||||
|
||||
void addPanel(paneEl, $msg("obsidianLiveSyncSettingTab.titleFetchSettings")).then((paneEl) => {
|
||||
|
||||
Reference in New Issue
Block a user