@synonymdev/pubky 0.16.2 → 0.18.0
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/README.md +58 -2
- package/index.cjs +227 -51
- package/index.js +228 -52
- package/package.json +4 -3
- package/pubky.d.ts +167 -29
- package/pubky_bg.wasm +0 -0
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@synonymdev/pubky",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"description": "Decentralized identity, auth flows, and user-owned storage",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.18.0",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"@types/tape": "^5.6.4",
|
|
42
42
|
"browser-resolve": "^2.0.0",
|
|
43
43
|
"browserify": "^17.0.1",
|
|
44
|
-
"electron": "
|
|
44
|
+
"electron": "45.1.0",
|
|
45
45
|
"esmify": "^2.1.1",
|
|
46
46
|
"tape": "^5.8.1",
|
|
47
47
|
"tape-run": "^11.0.0",
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
"fetch-cookie": "^3.0.1"
|
|
53
53
|
},
|
|
54
54
|
"overrides": {
|
|
55
|
-
"electron": "
|
|
55
|
+
"electron": "45.1.0",
|
|
56
|
+
"minimist": "^1.2.8"
|
|
56
57
|
}
|
|
57
58
|
}
|
package/pubky.d.ts
CHANGED
|
@@ -25,6 +25,33 @@ export interface RecoveredEncryptionKeys {
|
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
|
|
28
|
+
/** The individual limits of a quota. A limit is a number, a rate string such as
|
|
29
|
+
* `"100mb/m"`, or `"unlimited"`. Absent in `overrides` means the system default. */
|
|
30
|
+
export interface AccountQuotaLimits {
|
|
31
|
+
/** Storage quota in megabytes, or "unlimited". */
|
|
32
|
+
storageQuotaMb?: number | "unlimited";
|
|
33
|
+
/** Read bandwidth limit, e.g. "100mb/m", or "unlimited". */
|
|
34
|
+
rateRead?: string;
|
|
35
|
+
/** Write bandwidth limit, e.g. "50mb/s", or "unlimited". */
|
|
36
|
+
rateWrite?: string;
|
|
37
|
+
/** Burst allowance for reads, in the rate's unit. Absent means burst equals rate. */
|
|
38
|
+
rateReadBurst?: number;
|
|
39
|
+
/** Burst allowance for writes, in the rate's unit. Absent means burst equals rate. */
|
|
40
|
+
rateWriteBurst?: number;
|
|
41
|
+
/** Path prefixes the user may write to. Absent means unrestricted; empty means read-only. */
|
|
42
|
+
allowedWritePaths?: string[];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** A user's quota, both as it applies and as it was customised. */
|
|
46
|
+
export interface AccountQuota {
|
|
47
|
+
/** Overrides merged with the homeserver's defaults. */
|
|
48
|
+
effective: AccountQuotaLimits;
|
|
49
|
+
/** Only the per-user overrides. */
|
|
50
|
+
overrides: AccountQuotaLimits;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
28
55
|
export type JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue };
|
|
29
56
|
/** Root-signed grant claims. Public keys are z-base-32; times are Unix seconds. */
|
|
30
57
|
export interface VerifiedGrantClaims {
|
|
@@ -45,7 +72,7 @@ export interface VerifiedGrantClaims {
|
|
|
45
72
|
* Provides a simplified, actionable set of error categories for developers
|
|
46
73
|
* to handle in their code.
|
|
47
74
|
*/
|
|
48
|
-
export type PubkyErrorName = "RequestError" | "InvalidInput" | "AuthenticationError" | "PkarrError" | "ClientStateError" | "InternalError";
|
|
75
|
+
export type PubkyErrorName = "RequestError" | "CredentialRefreshError" | "InvalidInput" | "AuthenticationError" | "PkarrError" | "ClientStateError" | "InternalError";
|
|
49
76
|
|
|
50
77
|
/**
|
|
51
78
|
* Optional x-callback-url metadata carried by a Pubky deep link.
|
|
@@ -96,6 +123,15 @@ export interface GrantAuthFlowOptions {
|
|
|
96
123
|
* `signedApprovalV1` sets `af=v1` in the authorization link.
|
|
97
124
|
*/
|
|
98
125
|
approvalFormat?: GrantApprovalFormat;
|
|
126
|
+
/**
|
|
127
|
+
* Optional expected identity: public key of the signed-in user that must
|
|
128
|
+
* approve, as raw z32 or `pubky<z32>`. Set it only when the app already
|
|
129
|
+
* knows the user, e.g. to re-authorize or request more capabilities. It
|
|
130
|
+
* adds `spk` to the link; signers approve with that key or refuse, and the
|
|
131
|
+
* flow rejects approvals from any other key. Switching accounts takes a
|
|
132
|
+
* flow without it. Sign-up flows reject it.
|
|
133
|
+
*/
|
|
134
|
+
expectedSigner?: string | null;
|
|
99
135
|
}
|
|
100
136
|
|
|
101
137
|
/**
|
|
@@ -152,7 +188,7 @@ export type GrantApprovalFormat = "bareGrant" | "signedApprovalV1";
|
|
|
152
188
|
*
|
|
153
189
|
* @property name - A machine-readable error code from {@link PubkyErrorName}. Use this for programmatic error handling.
|
|
154
190
|
* @property message - A human-readable, descriptive error message suitable for logging.
|
|
155
|
-
* @property data -
|
|
191
|
+
* @property data - Optional structured context. For a `RequestError` it is a {@link RequestErrorData}, e.g. `{ reason: "Http", statusCode: 404 }`.
|
|
156
192
|
*
|
|
157
193
|
* @example
|
|
158
194
|
* ```typescript
|
|
@@ -160,14 +196,11 @@ export type GrantApprovalFormat = "bareGrant" | "signedApprovalV1";
|
|
|
160
196
|
* await client.signup(...);
|
|
161
197
|
* } catch (e) {
|
|
162
198
|
* const error = e as PubkyError;
|
|
163
|
-
* if (
|
|
164
|
-
* error.
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
* (error.data as { statusCode?: number }).statusCode === 404
|
|
169
|
-
* ) {
|
|
170
|
-
* // Handle not found...
|
|
199
|
+
* if (error.name === "RequestError") {
|
|
200
|
+
* const data = error.data as RequestErrorData;
|
|
201
|
+
* if (data.statusCode === 404) {
|
|
202
|
+
* // Handle not found...
|
|
203
|
+
* }
|
|
171
204
|
* }
|
|
172
205
|
* }
|
|
173
206
|
* ```
|
|
@@ -178,13 +211,35 @@ export interface PubkyError extends Error {
|
|
|
178
211
|
data?: unknown;
|
|
179
212
|
}
|
|
180
213
|
|
|
214
|
+
/** The classified cause of a `RequestError`, carried in `PubkyError.data.reason`. */
|
|
215
|
+
export type RequestErrorReason =
|
|
216
|
+
| "Http"
|
|
217
|
+
| "Timeout"
|
|
218
|
+
| "Connection"
|
|
219
|
+
| "TlsVerification"
|
|
220
|
+
| "Body"
|
|
221
|
+
| "Decode"
|
|
222
|
+
| "InvalidRequest"
|
|
223
|
+
| "Other";
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* `PubkyError.data` for a `RequestError`.
|
|
227
|
+
*
|
|
228
|
+
* `statusCode` is present when `reason` is `"Http"`. A reason describes the
|
|
229
|
+
* failure, not whether retrying is safe.
|
|
230
|
+
*/
|
|
231
|
+
export interface RequestErrorData {
|
|
232
|
+
reason: RequestErrorReason;
|
|
233
|
+
statusCode?: number;
|
|
234
|
+
}
|
|
235
|
+
|
|
181
236
|
/**
|
|
182
237
|
* Represents the standard error structure for all exceptions thrown by the Pubky
|
|
183
238
|
* WASM client.
|
|
184
239
|
*
|
|
185
240
|
* @property name - A machine-readable error code from {@link PubkyErrorName}. Use this for programmatic error handling.
|
|
186
241
|
* @property message - A human-readable, descriptive error message suitable for logging.
|
|
187
|
-
* @property data -
|
|
242
|
+
* @property data - Optional structured context. For a `RequestError` it is a {@link RequestErrorData}, e.g. `{ reason: "Http", statusCode: 404 }`.
|
|
188
243
|
*
|
|
189
244
|
* @example
|
|
190
245
|
* ```typescript
|
|
@@ -192,14 +247,11 @@ export interface PubkyError extends Error {
|
|
|
192
247
|
* await client.signup(...);
|
|
193
248
|
* } catch (e) {
|
|
194
249
|
* const error = e as PubkyError;
|
|
195
|
-
* if (
|
|
196
|
-
* error.
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
* (error.data as { statusCode?: number }).statusCode === 404
|
|
201
|
-
* ) {
|
|
202
|
-
* // Handle not found...
|
|
250
|
+
* if (error.name === 'RequestError') {
|
|
251
|
+
* const data = error.data as RequestErrorData;
|
|
252
|
+
* if (data.statusCode === 404) {
|
|
253
|
+
* // Handle not found...
|
|
254
|
+
* }
|
|
203
255
|
* }
|
|
204
256
|
* }
|
|
205
257
|
* ```
|
|
@@ -304,6 +356,39 @@ export type Capabilities = "" | CapabilityEntry | `${CapabilityEntry}${Capabilit
|
|
|
304
356
|
export type Path = `/pub/${string}` | `/priv/${string}`;
|
|
305
357
|
|
|
306
358
|
|
|
359
|
+
/**
|
|
360
|
+
* A user's account as returned by `session.grant.account()`.
|
|
361
|
+
*/
|
|
362
|
+
export class AccountInfo {
|
|
363
|
+
private constructor();
|
|
364
|
+
free(): void;
|
|
365
|
+
[Symbol.dispose](): void;
|
|
366
|
+
/**
|
|
367
|
+
* When the user signed up, as an ISO 8601 date and time without a UTC
|
|
368
|
+
* offset (e.g. `2026-10-22T10:11:12.123456`).
|
|
369
|
+
*/
|
|
370
|
+
readonly createdAt: string;
|
|
371
|
+
/**
|
|
372
|
+
* Whether the account is disabled. Disabled accounts can read and delete
|
|
373
|
+
* but not write.
|
|
374
|
+
*/
|
|
375
|
+
readonly disabled: boolean;
|
|
376
|
+
/**
|
|
377
|
+
* The user this account belongs to.
|
|
378
|
+
*/
|
|
379
|
+
readonly pubky: PublicKey;
|
|
380
|
+
/**
|
|
381
|
+
* The quota that applies and the per-user overrides behind it.
|
|
382
|
+
*
|
|
383
|
+
* @returns {AccountQuota}
|
|
384
|
+
*/
|
|
385
|
+
readonly quota: AccountQuota;
|
|
386
|
+
/**
|
|
387
|
+
* Bytes of storage currently used.
|
|
388
|
+
*/
|
|
389
|
+
readonly usedBytes: number;
|
|
390
|
+
}
|
|
391
|
+
|
|
307
392
|
/**
|
|
308
393
|
* Start and control a pubkyauth authorization flow.
|
|
309
394
|
*
|
|
@@ -1054,7 +1139,7 @@ export class GrantAuthFlow {
|
|
|
1054
1139
|
* The kind of authentication flow to perform.
|
|
1055
1140
|
*
|
|
1056
1141
|
* @param {GrantAuthFlowOptions} options
|
|
1057
|
-
* Options for the grant flow: `{ clientId, relay?, xCallback? }`.
|
|
1142
|
+
* Options for the grant flow: `{ clientId, relay?, xCallback?, approvalFormat?, expectedSigner? }`.
|
|
1058
1143
|
*
|
|
1059
1144
|
* @returns {GrantAuthFlow}
|
|
1060
1145
|
* A running grant auth flow. Call `authorizationUrl()` to show the deep link,
|
|
@@ -1154,6 +1239,17 @@ export class GrantSession {
|
|
|
1154
1239
|
private constructor();
|
|
1155
1240
|
free(): void;
|
|
1156
1241
|
[Symbol.dispose](): void;
|
|
1242
|
+
/**
|
|
1243
|
+
* Fetch this user's account: storage used, whether it is disabled, and
|
|
1244
|
+
* the quota that applies.
|
|
1245
|
+
*
|
|
1246
|
+
* Requires read permission on the root scope (`/:r`, `/:rw`, ...).
|
|
1247
|
+
* Path-scoped sessions surface the homeserver `403` as the standard
|
|
1248
|
+
* request error.
|
|
1249
|
+
*
|
|
1250
|
+
* @returns {Promise<AccountInfo>}
|
|
1251
|
+
*/
|
|
1252
|
+
account(): Promise<AccountInfo>;
|
|
1157
1253
|
/**
|
|
1158
1254
|
* Sign JSON data and return both the custom proof and its root-signed grant.
|
|
1159
1255
|
* Data follows `JSON.stringify` semantics, e.g. `undefined` properties are omitted.
|
|
@@ -1596,7 +1692,7 @@ export class Pubky {
|
|
|
1596
1692
|
* @param {string} capabilities Comma-separated caps, e.g. `"/pub/app/:rw,/pub/foo/file:r"`.
|
|
1597
1693
|
* @param {AuthFlowKind} kind The kind of authentication flow to perform.
|
|
1598
1694
|
* @param {GrantAuthFlowOptions} options Options for the grant flow:
|
|
1599
|
-
* `{ clientId, relay?, xCallback?, approvalFormat? }`.
|
|
1695
|
+
* `{ clientId, relay?, xCallback?, approvalFormat?, expectedSigner? }`.
|
|
1600
1696
|
* @returns {Promise<GrantAuthFlow>}
|
|
1601
1697
|
* A running grant auth flow. Show `authorizationUrl` as QR/deeplink,
|
|
1602
1698
|
* then `awaitApproval()` to obtain a grant-backed `Session`.
|
|
@@ -1697,7 +1793,8 @@ export class PubkyResource {
|
|
|
1697
1793
|
*/
|
|
1698
1794
|
static parse(value: string): PubkyResource;
|
|
1699
1795
|
/**
|
|
1700
|
-
* Render as `pubky://<owner
|
|
1796
|
+
* Render as `pubky://<owner><path>` (deep-link form), the form listings
|
|
1797
|
+
* and events use.
|
|
1701
1798
|
*/
|
|
1702
1799
|
toPubkyUrl(): string;
|
|
1703
1800
|
/**
|
|
@@ -1709,7 +1806,7 @@ export class PubkyResource {
|
|
|
1709
1806
|
*/
|
|
1710
1807
|
readonly owner: PublicKey;
|
|
1711
1808
|
/**
|
|
1712
|
-
* Get the absolute path (e.g., "/pub/
|
|
1809
|
+
* Get the absolute path (e.g., "/pub/My File.txt").
|
|
1713
1810
|
*/
|
|
1714
1811
|
readonly path: string;
|
|
1715
1812
|
}
|
|
@@ -1779,10 +1876,10 @@ export class PublicStorage {
|
|
|
1779
1876
|
*/
|
|
1780
1877
|
get(address: Address): Promise<Response>;
|
|
1781
1878
|
/**
|
|
1782
|
-
* List a directory. Results are `pubky
|
|
1879
|
+
* List a directory. Results are `pubky://<pk><path>` entries.
|
|
1783
1880
|
*
|
|
1784
1881
|
* @param {Address} address Addressed directory (must end with `/`).
|
|
1785
|
-
* @param {string|null=} cursor Optional suffix or
|
|
1882
|
+
* @param {string|null=} cursor Optional suffix or entry (as returned) to start **after**.
|
|
1786
1883
|
* @param {boolean=} reverse Default `false`. When `true`, newest/lexicographically-last first.
|
|
1787
1884
|
* @param {number=} limit Optional result limit.
|
|
1788
1885
|
* @param {boolean=} shallow Default `false`. When `true`, lists only first-level entries.
|
|
@@ -1937,8 +2034,10 @@ export class SessionInfo {
|
|
|
1937
2034
|
*
|
|
1938
2035
|
* Failures reject with a {@link PubkyError}. Path validation, transport, and HTTP
|
|
1939
2036
|
* failures use `RequestError`; only HTTP errors include `data.statusCode`.
|
|
1940
|
-
*
|
|
1941
|
-
*
|
|
2037
|
+
* Automatic grant refresh failures use `CredentialRefreshError`, with the
|
|
2038
|
+
* refresh HTTP status in `data.statusCode` when available. URL parsing failures
|
|
2039
|
+
* use `InvalidInput`. Other credential preparation and reading response bodies
|
|
2040
|
+
* can also fail.
|
|
1942
2041
|
*
|
|
1943
2042
|
* Only {@link SessionStorage.exists} and {@link SessionStorage.stats} treat
|
|
1944
2043
|
* HTTP 404/410 as missing. Other HTTP failures, including 401/403 and 5xx, reject.
|
|
@@ -2017,11 +2116,11 @@ export class SessionStorage {
|
|
|
2017
2116
|
* List a directory (absolute session path).
|
|
2018
2117
|
*
|
|
2019
2118
|
* @param {Path} path Must end with `/`.
|
|
2020
|
-
* @param {string|null=} cursor Optional last entry
|
|
2119
|
+
* @param {string|null=} cursor Optional last entry (as returned) to start **after**.
|
|
2021
2120
|
* @param {boolean=} reverse Default `false`.
|
|
2022
2121
|
* @param {number=} limit Optional result limit.
|
|
2023
2122
|
* @param {boolean=} shallow Default `false`.
|
|
2024
|
-
* @returns {Promise<string[]>} `pubky
|
|
2123
|
+
* @returns {Promise<string[]>} `pubky://<pk><path>` entries, or an empty array for an empty page.
|
|
2025
2124
|
* @throws {PubkyError} Missing directory (404), invalid cursor (400), invalid response
|
|
2026
2125
|
* entries, or shared errors (see {@link SessionStorage}).
|
|
2027
2126
|
*/
|
|
@@ -2044,6 +2143,38 @@ export class SessionStorage {
|
|
|
2044
2143
|
* See {@link SessionStorage} for shared errors.
|
|
2045
2144
|
*/
|
|
2046
2145
|
lock(path: Path, timeout_seconds: number): Promise<StorageLock>;
|
|
2146
|
+
/**
|
|
2147
|
+
* Upload a Blob or File to a locked path without copying its contents into
|
|
2148
|
+
* WASM memory.
|
|
2149
|
+
*
|
|
2150
|
+
* @param {StorageLock} lock A lock you hold. The upload uses the lock's path.
|
|
2151
|
+
* @param {Blob} body A Blob or File to upload.
|
|
2152
|
+
* @returns {Promise<void>}
|
|
2153
|
+
* @throws {PubkyError} An expired or released lock rejects with status `412`.
|
|
2154
|
+
* A file that changed since the write was prepared rejects with status `409`.
|
|
2155
|
+
* See {@link SessionStorage.putBytesLocked} for recovery and
|
|
2156
|
+
* {@link SessionStorage.putBlob} for input validation and shared errors.
|
|
2157
|
+
* @example
|
|
2158
|
+
* const lock = await session.storage.lock("/pub/example.com/file.bin", 30);
|
|
2159
|
+
* try {
|
|
2160
|
+
* await session.storage.putBlobLocked(lock, file);
|
|
2161
|
+
* } finally {
|
|
2162
|
+
* await session.storage.unlock(lock);
|
|
2163
|
+
* }
|
|
2164
|
+
*/
|
|
2165
|
+
putBlobLocked(lock: StorageLock, body: Blob): Promise<void>;
|
|
2166
|
+
/**
|
|
2167
|
+
* Upload a Blob or File without copying its contents into WASM memory.
|
|
2168
|
+
*
|
|
2169
|
+
* @param {Path} path File path; must not end with `/`.
|
|
2170
|
+
* @param {Blob} body A Blob or File to upload.
|
|
2171
|
+
* @returns {Promise<void>}
|
|
2172
|
+
* @throws {PubkyError} `InvalidInput` if body is not a Blob or File;
|
|
2173
|
+
* otherwise upload or shared write/request errors (see {@link SessionStorage}).
|
|
2174
|
+
* @example
|
|
2175
|
+
* await session.storage.putBlob("/pub/example.com/file.bin", file);
|
|
2176
|
+
*/
|
|
2177
|
+
putBlob(path: Path, body: Blob): Promise<void>;
|
|
2047
2178
|
/**
|
|
2048
2179
|
* `PUT` binary data to the path of a lock this client holds.
|
|
2049
2180
|
*
|
|
@@ -2325,6 +2456,13 @@ export class SigninGrantDeepLink {
|
|
|
2325
2456
|
* @returns {Uint8Array|undefined}
|
|
2326
2457
|
*/
|
|
2327
2458
|
readonly ephemeralPublicKey: Uint8Array | undefined;
|
|
2459
|
+
/**
|
|
2460
|
+
* Expected identity (`spk`): the public key that must approve this
|
|
2461
|
+
* request, or `undefined`. Signers approve with this key or refuse.
|
|
2462
|
+
*
|
|
2463
|
+
* @returns {PublicKey|undefined}
|
|
2464
|
+
*/
|
|
2465
|
+
readonly expectedSigner: PublicKey | undefined;
|
|
2328
2466
|
/**
|
|
2329
2467
|
* Shared relay secret, or `undefined` for an HPKE link.
|
|
2330
2468
|
* Keep this secret confidential until the flow completes or is abandoned.
|
package/pubky_bg.wasm
CHANGED
|
Binary file
|