mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-03-11 20:38:47 +00:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef3eef2d08 | ||
|
|
ffbbe32e36 | ||
|
|
0a5371cdee | ||
|
|
466bb142e2 | ||
|
|
d394a4ce7f | ||
|
|
71ce76e502 | ||
|
|
ae7a7dd456 | ||
|
|
dfeac201a2 | ||
|
|
44b022f003 |
@@ -18,7 +18,7 @@ Additionally, it supports peer-to-peer synchronisation using WebRTC now (experim
|
||||
- Use open-source solutions for the server.
|
||||
- Compatible solutions are supported.
|
||||
- Support end-to-end encryption.
|
||||
- Synchronise settings, snippets, themes, and plug-ins via [Customisation Sync (Beta)](#customization-sync) or [Hidden File Sync](#hiddenfilesync).
|
||||
- Synchronise settings, snippets, themes, and plug-ins via [Customisation Sync (Beta)](docs/settings.md#6-customization-sync-advanced) or [Hidden File Sync](docs/settings.md#7-hidden-files-advanced).
|
||||
- Enable WebRTC peer-to-peer synchronisation without requiring a `host` (Experimental).
|
||||
- This feature is still in the experimental stage. Please exercise caution when using it.
|
||||
- WebRTC is a peer-to-peer synchronisation method, so **at least one device must be online to synchronise**.
|
||||
|
||||
@@ -132,6 +132,11 @@ If it results like the following:
|
||||
|
||||
Your CouchDB has been initialised successfully. If you want this manually, please read the script.
|
||||
|
||||
If you are using Docker Compose and the above command does not work or displays `ERROR: Hostname missing`, you can try running the following command, replacing the placeholders with your own values:
|
||||
```
|
||||
curl -s https://raw.githubusercontent.com/vrtmrz/obsidian-livesync/main/utils/couchdb/couchdb-init.sh | hostname=http://<YOUR SERVER IP>:5984 username=<INSERT USERNAME HERE> password=<INSERT PASSWORD HERE> bash
|
||||
```
|
||||
|
||||
## 3. Expose CouchDB to the Internet
|
||||
|
||||
- You can skip this instruction if you using only in intranet and only with desktop devices.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "obsidian-livesync",
|
||||
"name": "Self-hosted LiveSync",
|
||||
"version": "0.25.16",
|
||||
"version": "0.25.18",
|
||||
"minAppVersion": "0.9.12",
|
||||
"description": "Community implementation of self-hosted livesync. Reflect your vault changes to some other devices immediately. Please make sure to disable other synchronize solutions to avoid content corruption or duplication.",
|
||||
"author": "vorotamoroz",
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "obsidian-livesync",
|
||||
"version": "0.25.16",
|
||||
"version": "0.25.18",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "obsidian-livesync",
|
||||
"version": "0.25.16",
|
||||
"version": "0.25.18",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.808.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "obsidian-livesync",
|
||||
"version": "0.25.16",
|
||||
"version": "0.25.18",
|
||||
"description": "Reflect your vault changes to some other devices immediately. Please make sure to disable other synchronize solutions to avoid content corruption or duplication.",
|
||||
"main": "main.js",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { PersistentMap } from "../lib/src/dataobject/PersistentMap.ts";
|
||||
import { PersistentMap } from "octagonal-wheels/dataobject/PersistentMap";
|
||||
|
||||
export let sameChangePairs: PersistentMap<number[]>;
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ import { promiseWithResolver, type PromiseWithResolvers } from "octagonal-wheels
|
||||
import { AuthorizationHeaderGenerator } from "../lib/src/replication/httplib.ts";
|
||||
import type { KeyValueDatabase } from "../lib/src/interfaces/KeyValueDatabase.ts";
|
||||
|
||||
export { scheduleTask, cancelTask, cancelAllTasks } from "../lib/src/concurrency/task.ts";
|
||||
export { scheduleTask, cancelTask, cancelAllTasks } from "octagonal-wheels/concurrency/task";
|
||||
|
||||
// For backward compatibility, using the path for determining id.
|
||||
// Only CouchDB unacceptable ID (that starts with an underscore) has been prefixed with "/".
|
||||
|
||||
@@ -45,7 +45,7 @@ import {
|
||||
} from "../../lib/src/common/utils.ts";
|
||||
import { digestHash } from "../../lib/src/string_and_binary/hash.ts";
|
||||
import { arrayBufferToBase64, decodeBinary, readString } from "../../lib/src/string_and_binary/convert.ts";
|
||||
import { serialized, shareRunningResult } from "../../lib/src/concurrency/lock.ts";
|
||||
import { serialized, shareRunningResult } from "octagonal-wheels/concurrency/lock";
|
||||
import { LiveSyncCommands } from "../LiveSyncCommands.ts";
|
||||
import { stripAllPrefixes } from "../../lib/src/string_and_binary/path.ts";
|
||||
import {
|
||||
@@ -62,7 +62,7 @@ import {
|
||||
scheduleTask,
|
||||
} from "../../common/utils.ts";
|
||||
import { JsonResolveModal } from "../HiddenFileCommon/JsonResolveModal.ts";
|
||||
import { QueueProcessor } from "../../lib/src/concurrency/processor.ts";
|
||||
import { QueueProcessor } from "octagonal-wheels/concurrency/processor";
|
||||
import { pluginScanningCount } from "../../lib/src/mock_and_interop/stores.ts";
|
||||
import type ObsidianLiveSyncPlugin from "../../main.ts";
|
||||
import { base64ToArrayBuffer, base64ToString } from "octagonal-wheels/binary/base64";
|
||||
|
||||
@@ -45,11 +45,11 @@ import {
|
||||
BASE_IS_NEW,
|
||||
EVEN,
|
||||
} from "../../common/utils.ts";
|
||||
import { serialized, skipIfDuplicated } from "../../lib/src/concurrency/lock.ts";
|
||||
import { serialized, skipIfDuplicated } from "octagonal-wheels/concurrency/lock";
|
||||
import { JsonResolveModal } from "../HiddenFileCommon/JsonResolveModal.ts";
|
||||
import { LiveSyncCommands } from "../LiveSyncCommands.ts";
|
||||
import { addPrefix, stripAllPrefixes } from "../../lib/src/string_and_binary/path.ts";
|
||||
import { QueueProcessor } from "../../lib/src/concurrency/processor.ts";
|
||||
import { QueueProcessor } from "octagonal-wheels/concurrency/processor";
|
||||
import { hiddenFilesEventCount, hiddenFilesProcessingCount } from "../../lib/src/mock_and_interop/stores.ts";
|
||||
import type { IObsidianModule } from "../../modules/AbstractObsidianModule.ts";
|
||||
import { EVENT_SETTING_SAVED, eventHub } from "../../common/events.ts";
|
||||
@@ -1765,10 +1765,7 @@ ${messageFetch}${messageOverwrite}${messageMerge}
|
||||
continue L1;
|
||||
}
|
||||
}
|
||||
if (
|
||||
ignoreFilter &&
|
||||
ignoreFilter.some((e) => (e.pattern.startsWith("/") || e.pattern.startsWith("\\/")) && e.test(v))
|
||||
) {
|
||||
if (ignoreFilter && ignoreFilter.some((e) => e.test(v))) {
|
||||
continue L1;
|
||||
}
|
||||
if (await this.plugin.$$isIgnoredByIgnoreFiles(v)) {
|
||||
|
||||
2
src/lib
2
src/lib
Submodule src/lib updated: c00f62f060...f021a9a6f4
@@ -31,7 +31,7 @@ import { type KeyValueDatabase } from "./lib/src/interfaces/KeyValueDatabase.ts"
|
||||
import { LiveSyncCommands } from "./features/LiveSyncCommands.ts";
|
||||
import { HiddenFileSync } from "./features/HiddenFileSync/CmdHiddenFileSync.ts";
|
||||
import { ConfigSync } from "./features/ConfigSync/CmdConfigSync.ts";
|
||||
import { reactiveSource, type ReactiveValue } from "./lib/src/dataobject/reactive.js";
|
||||
import { reactiveSource, type ReactiveValue } from "octagonal-wheels/dataobject/reactive";
|
||||
import { type LiveSyncJournalReplicatorEnv } from "./lib/src/replication/journal/LiveSyncJournalReplicator.js";
|
||||
import { type LiveSyncCouchDBReplicatorEnv } from "./lib/src/replication/couchdb/LiveSyncReplicator.js";
|
||||
import type { CheckPointInfo } from "./lib/src/replication/journal/JournalSyncTypes.js";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { type App, TFile, type DataWriteOptions, TFolder, TAbstractFile } from "../../../deps.ts";
|
||||
import { serialized } from "../../../lib/src/concurrency/lock.ts";
|
||||
import { serialized } from "octagonal-wheels/concurrency/lock";
|
||||
import { Logger } from "../../../lib/src/common/logger.ts";
|
||||
import { isPlainText } from "../../../lib/src/string_and_binary/path.ts";
|
||||
import type { FilePath, HasSettings, UXFileInfoStub } from "../../../lib/src/common/types.ts";
|
||||
|
||||
@@ -14,14 +14,14 @@ import {
|
||||
} from "../../../lib/src/common/types.ts";
|
||||
import { delay, fireAndForget, getFileRegExp } from "../../../lib/src/common/utils.ts";
|
||||
import { type FileEventItem, type FileEventType } from "../../../common/types.ts";
|
||||
import { serialized, skipIfDuplicated } from "../../../lib/src/concurrency/lock.ts";
|
||||
import { serialized, skipIfDuplicated } from "octagonal-wheels/concurrency/lock";
|
||||
import {
|
||||
finishAllWaitingForTimeout,
|
||||
finishWaitingForTimeout,
|
||||
isWaitingForTimeout,
|
||||
waitForTimeout,
|
||||
} from "../../../lib/src/concurrency/task.ts";
|
||||
import { Semaphore } from "../../../lib/src/concurrency/semaphore.ts";
|
||||
} from "octagonal-wheels/concurrency/task";
|
||||
import { Semaphore } from "octagonal-wheels/concurrency/semaphore";
|
||||
import type { LiveSyncCore } from "../../../main.ts";
|
||||
import { InternalFileToUXFileInfoStub, TFileToUXFileInfoStub } from "./utilObsidian.ts";
|
||||
import ObsidianLiveSyncPlugin from "../../../main.ts";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { fireAndForget } from "../../../lib/src/common/utils.ts";
|
||||
import { serialized } from "../../../lib/src/concurrency/lock.ts";
|
||||
import { serialized } from "octagonal-wheels/concurrency/lock";
|
||||
import type ObsidianLiveSyncPlugin from "../../../main.ts";
|
||||
|
||||
let plugin: ObsidianLiveSyncPlugin;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Trench } from "../../../lib/src/memory/memutil.ts";
|
||||
import { Trench } from "octagonal-wheels/memory/memutil";
|
||||
import type ObsidianLiveSyncPlugin from "../../../main.ts";
|
||||
type MeasureResult = [times: number, spent: number];
|
||||
type NamedMeasureResult = [name: string, result: MeasureResult];
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { onDestroy, onMount } from "svelte";
|
||||
import { logMessages } from "../../../lib/src/mock_and_interop/stores";
|
||||
import { reactive, type ReactiveInstance } from "../../../lib/src/dataobject/reactive";
|
||||
import { reactive, type ReactiveInstance } from "octagonal-wheels/dataobject/reactive";
|
||||
import { Logger } from "../../../lib/src/common/logger";
|
||||
import { $msg as msg, currentLang as lang } from "../../../lib/src/common/i18n.ts";
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import { ConflictResolveModal } from "./InteractiveConflictResolving/ConflictRes
|
||||
import { AbstractObsidianModule, type IObsidianModule } from "../AbstractObsidianModule.ts";
|
||||
import { displayRev, getPath, getPathWithoutPrefix } from "../../common/utils.ts";
|
||||
import { fireAndForget } from "octagonal-wheels/promises";
|
||||
import { serialized } from "../../lib/src/concurrency/lock.ts";
|
||||
import { serialized } from "octagonal-wheels/concurrency/lock";
|
||||
|
||||
export class ModuleInteractiveConflictResolver extends AbstractObsidianModule implements IObsidianModule {
|
||||
$everyOnloadStart(): Promise<boolean> {
|
||||
|
||||
@@ -370,7 +370,7 @@ export class ModuleLog extends AbstractObsidianModule implements IObsidianModule
|
||||
if (level == LOG_LEVEL_DEBUG && !showDebugLog) {
|
||||
return;
|
||||
}
|
||||
if (level < LOG_LEVEL_INFO && this.settings && this.settings.lessInformationInLog) {
|
||||
if (level <= LOG_LEVEL_INFO && this.settings && this.settings.lessInformationInLog) {
|
||||
return;
|
||||
}
|
||||
if (this.settings && !this.settings.showVerboseLog && level == LOG_LEVEL_VERBOSE) {
|
||||
|
||||
@@ -17,7 +17,7 @@ import { delay, isObjectDifferent, sizeToHumanReadable } from "../../../lib/src/
|
||||
import { versionNumberString2Number } from "../../../lib/src/string_and_binary/convert.ts";
|
||||
import { Logger } from "../../../lib/src/common/logger.ts";
|
||||
import { checkSyncInfo } from "@/lib/src/pouchdb/negotiation.ts";
|
||||
import { testCrypt } from "../../../lib/src/encryption/e2ee_v2.ts";
|
||||
import { testCrypt } from "octagonal-wheels/encryption/encryption";
|
||||
import ObsidianLiveSyncPlugin from "../../../main.ts";
|
||||
import { scheduleTask } from "../../../common/utils.ts";
|
||||
import { LiveSyncCouchDBReplicator } from "../../../lib/src/replication/couchdb/LiveSyncReplicator.ts";
|
||||
|
||||
94
updates.md
94
updates.md
@@ -1,12 +1,51 @@
|
||||
## 0.25
|
||||
|
||||
Since 19th July, 2025 (beta1 in 0.25.0-beta1, 13th July, 2025)
|
||||
|
||||
After reading Issue #668, I conducted another self-review of the E2EE-related code. In retrospect, it was clearly written by someone inexperienced, which is understandable, but it is still rather embarrassing. Three years is certainly enough time for growth.
|
||||
|
||||
I have now rewritten the E2EE code to be more robust and easier to understand. It is significantly more readable and should be easier to maintain in the future. The performance issue, previously considered a concern, has been addressed by introducing a master key and deriving keys using HKDF. This approach is both fast and robust, and it provides protection against rainbow table attacks. (In addition, this implementation has been [a dedicated package on the npm registry](https://github.com/vrtmrz/octagonal-wheels), and tested in 100% branch-coverage).
|
||||
|
||||
As a result, this is the first time in a while that forward compatibility has been broken. We have also taken the opportunity to change all metadata to use encryption rather than obfuscation. Furthermore, the `Dynamic Iteration Count` setting is now redundant and has been moved to the `Patches` pane in the settings. Thanks to Rabin-Karp, the eden setting is also no longer necessary and has been relocated accordingly. Therefore, v0.25.0 represents a legitimate and correct evolution.
|
||||
|
||||
## 0.25.18
|
||||
|
||||
17th September, 2025
|
||||
|
||||
### Fixed
|
||||
|
||||
- Property encryption detection now works correctly (On Self-hosted LiveSync, it was not broken, but as a library, it was not working correctly).
|
||||
- Initialising the chunk splitter is now surely performed.
|
||||
- DirectFileManipulator now works fine (as a library)
|
||||
- Old `DirectFileManipulatorV1` is now removed.
|
||||
|
||||
### Refactored
|
||||
|
||||
- Removed some unnecessary intermediate files.
|
||||
|
||||
## 0.25.17
|
||||
|
||||
16th September, 2025
|
||||
|
||||
### Fixed
|
||||
|
||||
- No longer information-level logs have produced during toggling `Show only notifications` in the settings (#708).
|
||||
- Ignoring filters for Hidden file sync now works correctly (#709).
|
||||
|
||||
### Refactored
|
||||
|
||||
- Removed some unnecessary intermediate files.
|
||||
|
||||
## 0.25.16
|
||||
|
||||
4th September, 2025
|
||||
|
||||
### Improved
|
||||
|
||||
- Improved connectivity for P2P connections
|
||||
- The connection to the signalling server can now be disconnected while in the background or when explicitly disconnected.
|
||||
- These features use a patch that has not been incorporated upstream.
|
||||
- This patch is available at [vrtmrz/trystero](https://github.com/vrtmrz/trystero).
|
||||
- These features use a patch that has not been incorporated upstream.
|
||||
- This patch is available at [vrtmrz/trystero](https://github.com/vrtmrz/trystero).
|
||||
|
||||
## 0.25.15
|
||||
|
||||
@@ -16,7 +55,6 @@
|
||||
|
||||
- Now we can configure `forcePathStyle` for bucket synchronisation (#707).
|
||||
|
||||
|
||||
## 0.25.14
|
||||
|
||||
2nd September, 2025
|
||||
@@ -44,56 +82,6 @@
|
||||
|
||||
- Fixed an issue with automatic synchronisation starting (#702).
|
||||
|
||||
## 0.25.11
|
||||
|
||||
28th August, 2025
|
||||
|
||||
### Fixed
|
||||
|
||||
- Automatic translation detection on the first launch now works correctly (#630).
|
||||
- No errors are shown during synchronisations in offline (if not explicitly requested) (#699).
|
||||
- Missing some checking during automatic-synchronisation now works correctly.
|
||||
|
||||
## 0.25.10
|
||||
|
||||
26th August, 2025
|
||||
|
||||
### New experimental feature
|
||||
|
||||
- We can perform Garbage Collection (Beta2) without rebuilding the entire database, and also fetch the database.
|
||||
- Note that this feature is very experimental and should be used with caution.
|
||||
- This feature requires disabling `Fetch chunks on demand`.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Resetting the bucket now properly clears all uploaded files.
|
||||
|
||||
### Refactored
|
||||
|
||||
- Some files have been moved to better reflect their purpose and improve maintainability.
|
||||
- The extensive LiveSyncLocalDB has been split into separate files for each role.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Unexpected `Failed to obtain PBKDF2 salt` or similar errors during bucket-synchronisation no longer occur.
|
||||
- Unexpected long delays for chunk-missing documents when using bucket-synchronisation have been resolved.
|
||||
- Fetched remote chunks are now properly stored in the local database if `Fetch chunks on demand` is enabled.
|
||||
- The 'fetch' dialogue's message has been refined.
|
||||
- No longer overwriting any corrupted documents to the storage on boot-sequence.
|
||||
|
||||
### Refactored
|
||||
|
||||
- Type errors have been corrected.
|
||||
|
||||
## 0.25.0
|
||||
|
||||
19th July, 2025 (beta1 in 0.25.0-beta1, 13th July, 2025)
|
||||
|
||||
After reading Issue #668, I conducted another self-review of the E2EE-related code. In retrospect, it was clearly written by someone inexperienced, which is understandable, but it is still rather embarrassing. Three years is certainly enough time for growth.
|
||||
|
||||
I have now rewritten the E2EE code to be more robust and easier to understand. It is significantly more readable and should be easier to maintain in the future. The performance issue, previously considered a concern, has been addressed by introducing a master key and deriving keys using HKDF. This approach is both fast and robust, and it provides protection against rainbow table attacks. (In addition, this implementation has been [a dedicated package on the npm registry](https://github.com/vrtmrz/octagonal-wheels), and tested in 100% branch-coverage).
|
||||
|
||||
As a result, this is the first time in a while that forward compatibility has been broken. We have also taken the opportunity to change all metadata to use encryption rather than obfuscation. Furthermore, the `Dynamic Iteration Count` setting is now redundant and has been moved to the `Patches` pane in the settings. Thanks to Rabin-Karp, the eden setting is also no longer necessary and has been relocated accordingly. Therefore, v0.25.0 represents a legitimate and correct evolution.
|
||||
|
||||
Older notes are in
|
||||
[updates_old.md](https://github.com/vrtmrz/obsidian-livesync/blob/main/updates_old.md).
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# 0.25
|
||||
|
||||
## 0.25.0
|
||||
|
||||
19th July, 2025 (beta1 in 0.25.0-beta1, 13th July, 2025)
|
||||
Since 19th July, 2025 (beta1 in 0.25.0-beta1, 13th July, 2025)
|
||||
|
||||
After reading Issue #668, I conducted another self-review of the E2EE-related code. In retrospect, it was clearly written by someone inexperienced, which is understandable, but it is still rather embarrassing. Three years is certainly enough time for growth.
|
||||
|
||||
@@ -11,6 +10,48 @@ As a result, this is the first time in a while that forward compatibility has be
|
||||
|
||||
---
|
||||
|
||||
## 0.25.11
|
||||
|
||||
28th August, 2025
|
||||
|
||||
### Fixed
|
||||
|
||||
- Automatic translation detection on the first launch now works correctly (#630).
|
||||
- No errors are shown during synchronisations in offline (if not explicitly requested) (#699).
|
||||
- Missing some checking during automatic-synchronisation now works correctly.
|
||||
|
||||
|
||||
## 0.25.10
|
||||
|
||||
26th August, 2025
|
||||
|
||||
### New experimental feature
|
||||
|
||||
- We can perform Garbage Collection (Beta2) without rebuilding the entire database, and also fetch the database.
|
||||
- Note that this feature is very experimental and should be used with caution.
|
||||
- This feature requires disabling `Fetch chunks on demand`.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Resetting the bucket now properly clears all uploaded files.
|
||||
|
||||
### Refactored
|
||||
|
||||
- Some files have been moved to better reflect their purpose and improve maintainability.
|
||||
- The extensive LiveSyncLocalDB has been split into separate files for each role.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Unexpected `Failed to obtain PBKDF2 salt` or similar errors during bucket-synchronisation no longer occur.
|
||||
- Unexpected long delays for chunk-missing documents when using bucket-synchronisation have been resolved.
|
||||
- Fetched remote chunks are now properly stored in the local database if `Fetch chunks on demand` is enabled.
|
||||
- The 'fetch' dialogue's message has been refined.
|
||||
- No longer overwriting any corrupted documents to the storage on boot-sequence.
|
||||
|
||||
### Refactored
|
||||
|
||||
- Type errors have been corrected.
|
||||
|
||||
## 0.25.9
|
||||
|
||||
20th August, 2025
|
||||
|
||||
Reference in New Issue
Block a user