@glance-apps/sync 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -1
- package/README.md +2 -1
- package/package.json +1 -1
- package/src/crypto.js +1 -0
- package/src/index.js +1 -0
- package/src/providers.js +5 -5
- package/types/index.d.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.0.3] - 2026-05-23
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **Generic WebDAV — `appFolderName` not used in URLs**: `getFileUrl` and
|
|
15
|
+
`getDirUrl` now insert `appFolderName` between the server root and the sync
|
|
16
|
+
filename, matching the behaviour of the Nextcloud and Koofr providers.
|
|
17
|
+
`webdavUrl` is now expected to be a server root (e.g. `https://dav.example.com`)
|
|
18
|
+
rather than a full folder path. Callers with an existing `webdavUrl` that
|
|
19
|
+
already includes the folder path should migrate it into `syncFolder`/`appFolderName`
|
|
20
|
+
and strip the path back to the origin.
|
|
21
|
+
- **Generic WebDAV — Apache 403 on missing parent directories**: `upload` now
|
|
22
|
+
calls `mkcolWithParents` when PUT returns 403 in addition to 404/409. Apache
|
|
23
|
+
`mod_dav` returns 403 (not 409) when both the target directory and its parent
|
|
24
|
+
are absent. The `if (res.status === 403) throw FORBIDDEN` guard that follows
|
|
25
|
+
still catches genuine auth failures after the retry.
|
|
26
|
+
|
|
27
|
+
## [1.0.2] - 2026-05-22
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
|
|
31
|
+
- `getSessionKey()` export — returns the cached non-extractable `CryptoKey` for reuse by sibling packages (e.g., `@glance-apps/intents` encryption helpers).
|
|
32
|
+
|
|
10
33
|
## [1.0.1] - 2026-05-18
|
|
11
34
|
|
|
12
35
|
### Fixed
|
|
@@ -52,5 +75,8 @@ entire sync infrastructure can be shared across the GLANCE app family.
|
|
|
52
75
|
- TypeScript declarations in `types/index.d.ts`.
|
|
53
76
|
- WebDAV CORS proxy handler in `api/webdav-proxy.js`.
|
|
54
77
|
|
|
55
|
-
[Unreleased]: https://github.com/glance-apps/glance-sync/compare/v1.0.
|
|
78
|
+
[Unreleased]: https://github.com/glance-apps/glance-sync/compare/v1.0.3...HEAD
|
|
79
|
+
[1.0.3]: https://github.com/glance-apps/glance-sync/compare/v1.0.2...v1.0.3
|
|
80
|
+
[1.0.2]: https://github.com/glance-apps/glance-sync/compare/v1.0.1...v1.0.2
|
|
81
|
+
[1.0.1]: https://github.com/glance-apps/glance-sync/compare/v1.0.0...v1.0.1
|
|
56
82
|
[1.0.0]: https://github.com/glance-apps/glance-sync/releases/tag/v1.0.0
|
package/README.md
CHANGED
|
@@ -147,6 +147,7 @@ Pass `encryptionEnabled: true` in the sync config object stored via `engine.setC
|
|
|
147
147
|
| `isEncryptedEnvelope(value)` | Type guard — returns `true` if the value looks like an `EncryptedEnvelope`. |
|
|
148
148
|
| `setSyncPassphrase(p)` / `getSyncPassphrase()` | Store/retrieve the passphrase in session memory (not persisted). |
|
|
149
149
|
| `hasEncryptionReady()` | Returns `true` if the session key is loaded. |
|
|
150
|
+
| `getSessionKey()` | Returns the cached non-extractable `CryptoKey`, or `null` if no key is loaded — intended for sibling packages (e.g., `@glance-apps/intents`) that need to reuse the same key. |
|
|
150
151
|
|
|
151
152
|
### Transport & providers
|
|
152
153
|
|
|
@@ -168,7 +169,7 @@ TypeScript declarations for all of the above are in `types/index.d.ts`.
|
|
|
168
169
|
|
|
169
170
|
## Versioning
|
|
170
171
|
|
|
171
|
-
This package
|
|
172
|
+
This package follows [Semantic Versioning](https://semver.org/). Breaking changes to the public API or the sync envelope schema will result in a major version bump.
|
|
172
173
|
|
|
173
174
|
## License
|
|
174
175
|
|
package/package.json
CHANGED
package/src/crypto.js
CHANGED
|
@@ -17,6 +17,7 @@ let _sessionSalt = null; // Uint8Array | null — the salt used to derive
|
|
|
17
17
|
export function setSyncPassphrase(p) { _sessionPassphrase = p; }
|
|
18
18
|
export function getSyncPassphrase() { return _sessionPassphrase; }
|
|
19
19
|
export function hasEncryptionReady() { return _sessionKey !== null; }
|
|
20
|
+
export function getSessionKey() { return _sessionKey; }
|
|
20
21
|
|
|
21
22
|
// ---------------------------------------------------------------------------
|
|
22
23
|
// IndexedDB key store
|
package/src/index.js
CHANGED
package/src/providers.js
CHANGED
|
@@ -261,9 +261,9 @@ export function createProviders(engineConfig) {
|
|
|
261
261
|
webdav: {
|
|
262
262
|
name: 'Generic WebDAV',
|
|
263
263
|
getFileUrl: (config) =>
|
|
264
|
-
`${config.webdavUrl.replace(/\/+$/, '')}/${syncFilename}`,
|
|
264
|
+
`${config.webdavUrl.replace(/\/+$/, '')}/${appFolderName}/${syncFilename}`,
|
|
265
265
|
getDirUrl: (config) =>
|
|
266
|
-
`${config.webdavUrl.replace(/\/+$/, '')}/`,
|
|
266
|
+
`${config.webdavUrl.replace(/\/+$/, '')}/${appFolderName}/`,
|
|
267
267
|
getAuthHeaders: (config) => ({
|
|
268
268
|
'X-WebDAV-Auth': 'Basic ' + toBase64(config.username + ':' + config.appPassword)
|
|
269
269
|
}),
|
|
@@ -277,7 +277,7 @@ export function createProviders(engineConfig) {
|
|
|
277
277
|
if (etag) extraHeaders['If-Match'] = etag;
|
|
278
278
|
const doUpload = () => wf('PUT', fileUrl, authHeaders, body, extraHeaders);
|
|
279
279
|
let res = await doUpload();
|
|
280
|
-
if (res.status === 404 || res.status === 409) {
|
|
280
|
+
if (res.status === 404 || res.status === 409 || res.status === 403) {
|
|
281
281
|
await mkcol(dirUrl, authHeaders);
|
|
282
282
|
res = await doUpload();
|
|
283
283
|
}
|
|
@@ -307,11 +307,11 @@ export function createProviders(engineConfig) {
|
|
|
307
307
|
return { success: false, error: `Unexpected response: ${res.status}${res.statusText ? ' ' + res.statusText : ''}` };
|
|
308
308
|
},
|
|
309
309
|
configFields: [
|
|
310
|
-
{ key: 'webdavUrl', label: 'WebDAV URL', type: 'url', placeholder: 'https://dav.example.com
|
|
310
|
+
{ key: 'webdavUrl', label: 'WebDAV URL', type: 'url', placeholder: 'https://dav.example.com' },
|
|
311
311
|
{ key: 'username', label: 'Username', type: 'text', placeholder: 'your-username' },
|
|
312
312
|
{ key: 'appPassword', label: 'Password / App Password', type: 'password', placeholder: 'your-password' }
|
|
313
313
|
],
|
|
314
|
-
helpText: 'Enter the
|
|
314
|
+
helpText: 'Enter the server root URL (e.g. https://dav.example.com). The sync folder is configured separately via the Sync Folder setting. pCloud, Seafile, and most self-hosted WebDAV providers are supported.'
|
|
315
315
|
}
|
|
316
316
|
};
|
|
317
317
|
}
|
package/types/index.d.ts
CHANGED
|
@@ -155,6 +155,7 @@ export function clearEncryptionKey(config: CryptoConfig): Promise<void>;
|
|
|
155
155
|
export function setSyncPassphrase(passphrase: string | null): void;
|
|
156
156
|
export function getSyncPassphrase(): string | null;
|
|
157
157
|
export function hasEncryptionReady(): boolean;
|
|
158
|
+
export function getSessionKey(): CryptoKey | null;
|
|
158
159
|
export function encryptData<T>(data: T, config?: CryptoConfig): Promise<EncryptedEnvelope>;
|
|
159
160
|
export function decryptData<T = unknown>(envelope: EncryptedEnvelope, config?: CryptoConfig): Promise<T>;
|
|
160
161
|
export function isEncryptedEnvelope(value: unknown): value is EncryptedEnvelope;
|