@haverstack/server 0.10.3 → 0.12.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/dist/app.d.ts.map +1 -1
- package/dist/app.js +2 -0
- package/dist/app.js.map +1 -1
- package/dist/lib/canonicalJson.d.ts +7 -0
- package/dist/lib/canonicalJson.d.ts.map +1 -0
- package/dist/lib/canonicalJson.js +18 -0
- package/dist/lib/canonicalJson.js.map +1 -0
- package/dist/lib/historyPage.d.ts +12 -0
- package/dist/lib/historyPage.d.ts.map +1 -0
- package/dist/lib/historyPage.js +24 -0
- package/dist/lib/historyPage.js.map +1 -0
- package/dist/lib/ifMatch.d.ts +11 -0
- package/dist/lib/ifMatch.d.ts.map +1 -0
- package/dist/lib/ifMatch.js +11 -0
- package/dist/lib/ifMatch.js.map +1 -0
- package/dist/lib/installRequestStore.d.ts +46 -0
- package/dist/lib/installRequestStore.d.ts.map +1 -0
- package/dist/lib/installRequestStore.js +102 -0
- package/dist/lib/installRequestStore.js.map +1 -0
- package/dist/lib/json.d.ts +7 -1
- package/dist/lib/json.d.ts.map +1 -1
- package/dist/lib/json.js +18 -4
- package/dist/lib/json.js.map +1 -1
- package/dist/lib/queryWorker/pool.d.ts +2 -1
- package/dist/lib/queryWorker/pool.d.ts.map +1 -1
- package/dist/lib/queryWorker/pool.js.map +1 -1
- package/dist/lib/queryWorker/protocol.d.ts +3 -2
- package/dist/lib/queryWorker/protocol.d.ts.map +1 -1
- package/dist/lib/queryWorker/worker.js +3 -3
- package/dist/lib/queryWorker/worker.js.map +1 -1
- package/dist/lib/resumeBuffer.d.ts +4 -4
- package/dist/lib/resumeBuffer.d.ts.map +1 -1
- package/dist/lib/resumeBuffer.js +23 -9
- package/dist/lib/resumeBuffer.js.map +1 -1
- package/dist/lib/resumeCursor.d.ts +1 -1
- package/dist/lib/resumeCursor.d.ts.map +1 -1
- package/dist/lib/resumeCursor.js +3 -3
- package/dist/lib/resumeCursor.js.map +1 -1
- package/dist/lib/selfService.d.ts +2 -0
- package/dist/lib/selfService.d.ts.map +1 -0
- package/dist/lib/selfService.js +6 -0
- package/dist/lib/selfService.js.map +1 -0
- package/dist/middleware/auth.d.ts +10 -9
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +21 -10
- package/dist/middleware/auth.js.map +1 -1
- package/dist/middleware/errors.js +1 -1
- package/dist/middleware/errors.js.map +1 -1
- package/dist/middleware/params.d.ts +10 -0
- package/dist/middleware/params.d.ts.map +1 -0
- package/dist/middleware/params.js +18 -0
- package/dist/middleware/params.js.map +1 -0
- package/dist/routes/attachments.d.ts.map +1 -1
- package/dist/routes/attachments.js +24 -14
- package/dist/routes/attachments.js.map +1 -1
- package/dist/routes/auth.d.ts.map +1 -1
- package/dist/routes/auth.js +13 -23
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/changes.d.ts +1 -1
- package/dist/routes/changes.d.ts.map +1 -1
- package/dist/routes/changes.js +17 -18
- package/dist/routes/changes.js.map +1 -1
- package/dist/routes/entity.d.ts.map +1 -1
- package/dist/routes/entity.js +12 -8
- package/dist/routes/entity.js.map +1 -1
- package/dist/routes/health.d.ts.map +1 -1
- package/dist/routes/health.js +2 -1
- package/dist/routes/health.js.map +1 -1
- package/dist/routes/installs.d.ts +13 -0
- package/dist/routes/installs.d.ts.map +1 -0
- package/dist/routes/installs.js +101 -0
- package/dist/routes/installs.js.map +1 -0
- package/dist/routes/records.d.ts.map +1 -1
- package/dist/routes/records.js +114 -173
- package/dist/routes/records.js.map +1 -1
- package/dist/routes/tokens.d.ts.map +1 -1
- package/dist/routes/tokens.js +22 -18
- package/dist/routes/tokens.js.map +1 -1
- package/dist/routes/types.d.ts.map +1 -1
- package/dist/routes/types.js +11 -25
- package/dist/routes/types.js.map +1 -1
- package/dist/routes/wellknown.d.ts.map +1 -1
- package/dist/routes/wellknown.js +6 -3
- package/dist/routes/wellknown.js.map +1 -1
- package/dist/shutdown.d.ts.map +1 -1
- package/dist/shutdown.js +1 -0
- package/dist/shutdown.js.map +1 -1
- package/dist/stack.d.ts +2 -0
- package/dist/stack.d.ts.map +1 -1
- package/dist/stack.js +30 -8
- package/dist/stack.js.map +1 -1
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +15 -4
- package/dist/testing.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -6
- package/dist/lib/queryLimit.d.ts +0 -6
- package/dist/lib/queryLimit.d.ts.map +0 -1
- package/dist/lib/queryLimit.js +0 -20
- package/dist/lib/queryLimit.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resumeBuffer.js","sourceRoot":"","sources":["../../src/lib/resumeBuffer.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAiBjD,wGAAwG;AACxG,MAAM,OAAO,YAAY;IAYM;IAXpB,EAAE,GAAW,MAAM,CAAC,UAAU,EAAE,CAAC;IACzB,OAAO,GAAkB,EAAE,CAAC;IACrC,QAAQ,GAAG,CAAC,CAAC;IACb,WAAW,GAAG,CAAC,CAAC;IACP,SAAS,GAAG,IAAI,GAAG,EAAgC,CAAC;IAErE,wEAAwE;IACxE,SAAS,GAAG,CAAC,CAAC;IACd,2EAA2E;IAC3E,cAAc,GAAkB,IAAI,CAAC;IAErC,YAA6B,KAAa;QAAb,UAAK,GAAL,KAAK,CAAQ;IAAG,CAAC;IAE9C,+EAA+E;IAC/E,UAAU;QACR,OAAO,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,MAAoB;QACzB,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC;QACnB,MAAM,
|
|
1
|
+
{"version":3,"file":"resumeBuffer.js","sourceRoot":"","sources":["../../src/lib/resumeBuffer.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,5 +12,5 @@ export declare function encodeCursor(bufferId: string, n: number): string;
|
|
|
12
12
|
* (A charset-*invalid* cursor is refused before this is ever called — see
|
|
13
13
|
* `src/routes/changes.ts`.)
|
|
14
14
|
*/
|
|
15
|
-
export declare function decodeCursor(
|
|
15
|
+
export declare function decodeCursor(cursor: string): DecodedCursor | null;
|
|
16
16
|
//# sourceMappingURL=resumeCursor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resumeCursor.d.ts","sourceRoot":"","sources":["../../src/lib/resumeCursor.ts"],"names":[],"mappings":"AAcA,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,CAAC,EAAE,MAAM,CAAC;CACX,CAAC;AAEF,+DAA+D;AAC/D,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,
|
|
1
|
+
{"version":3,"file":"resumeCursor.d.ts","sourceRoot":"","sources":["../../src/lib/resumeCursor.ts"],"names":[],"mappings":"AAcA,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,CAAC,EAAE,MAAM,CAAC;CACX,CAAC;AAEF,+DAA+D;AAC/D,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAejE"}
|
package/dist/lib/resumeCursor.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Resume cursor codec. A cursor is opaque and base64url by wire contract
|
|
3
|
-
* (`
|
|
3
|
+
* (`isValidCursor()` in @haverstack/wire-types), but this server's own are
|
|
4
4
|
* self-describing: `base64url(bufferId + ":" + n)`. That makes a presented
|
|
5
5
|
* cursor's origin checkable — a reconnect naming a buffer this server
|
|
6
6
|
* doesn't hold (a different filter, a restart, a buffer past its retention
|
|
@@ -23,10 +23,10 @@ export function encodeCursor(bufferId, n) {
|
|
|
23
23
|
* (A charset-*invalid* cursor is refused before this is ever called — see
|
|
24
24
|
* `src/routes/changes.ts`.)
|
|
25
25
|
*/
|
|
26
|
-
export function decodeCursor(
|
|
26
|
+
export function decodeCursor(cursor) {
|
|
27
27
|
let text;
|
|
28
28
|
try {
|
|
29
|
-
text = new TextDecoder('utf-8', { fatal: true }).decode(base64urlDecode(
|
|
29
|
+
text = new TextDecoder('utf-8', { fatal: true }).decode(base64urlDecode(cursor));
|
|
30
30
|
}
|
|
31
31
|
catch {
|
|
32
32
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resumeCursor.js","sourceRoot":"","sources":["../../src/lib/resumeCursor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAOzE,+DAA+D;AAC/D,MAAM,UAAU,YAAY,CAAC,QAAgB,EAAE,CAAS;IACtD,OAAO,eAAe,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,QAAQ,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;AACvE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,
|
|
1
|
+
{"version":3,"file":"resumeCursor.js","sourceRoot":"","sources":["../../src/lib/resumeCursor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAOzE,+DAA+D;AAC/D,MAAM,UAAU,YAAY,CAAC,QAAgB,EAAE,CAAS;IACtD,OAAO,eAAe,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,QAAQ,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;AACvE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;IACnF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACzC,IAAI,UAAU,KAAK,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;IACzC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACxB,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selfService.d.ts","sourceRoot":"","sources":["../../src/lib/selfService.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,mBAAmB,QAA0B,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// What any key that completes the DID handshake can leave behind on its own
|
|
2
|
+
// — a bearer token, a pending install request — lives at most this long
|
|
3
|
+
// unless it is renewed. Self-service state owes a bounded lifetime, and one
|
|
4
|
+
// bound for all of it keeps a stranger's footprint a single number.
|
|
5
|
+
export const SELF_SERVICE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
6
|
+
//# sourceMappingURL=selfService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selfService.js","sourceRoot":"","sources":["../../src/lib/selfService.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,wEAAwE;AACxE,4EAA4E;AAC5E,oEAAoE;AACpE,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { MiddlewareHandler } from 'hono';
|
|
2
|
-
import type { TokenSession } from '@haverstack/core';
|
|
3
2
|
import type { AppEnv } from '../types.js';
|
|
4
3
|
import type { StackContext } from '../stack.js';
|
|
5
4
|
/**
|
|
@@ -12,14 +11,16 @@ export declare function safeCompare(a: string, b: string): boolean;
|
|
|
12
11
|
export declare function authMiddleware(ownerToken: string, ctx: StackContext): MiddlewareHandler<AppEnv>;
|
|
13
12
|
export declare function requireAuth(): MiddlewareHandler<AppEnv>;
|
|
14
13
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* `ScopedStack`'s own owner-only gates (e.g. hard delete). See
|
|
20
|
-
* docs/spec/access-control.md § Delegation.
|
|
14
|
+
* Gates a route to the owner acting alone: undelegated, and authenticated
|
|
15
|
+
* as the owner rather than merely delegated for it — the same test
|
|
16
|
+
* `ScopedStack`'s own owner-only gates apply. See
|
|
17
|
+
* docs/spec/access-control.md § Delegation: principal and subject.
|
|
21
18
|
*/
|
|
22
|
-
export declare function isOwnerActingAlone(auth: TokenSession | null, ownerEntityId: string): boolean;
|
|
23
|
-
/** Gates a route to the owner acting alone; see `isOwnerActingAlone()`. */
|
|
24
19
|
export declare function requireOwner(ownerEntityId: string): MiddlewareHandler<AppEnv>;
|
|
20
|
+
/**
|
|
21
|
+
* Gates a route to a session acting as itself — not a principal acting
|
|
22
|
+
* for someone else. Checked before the body is read, like requireOwner(),
|
|
23
|
+
* so a refused identity is refused whatever it sent.
|
|
24
|
+
*/
|
|
25
|
+
export declare function requireActingAlone(): MiddlewareHandler<AppEnv>;
|
|
25
26
|
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAG9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAIzD;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAyB/F;AAED,wBAAgB,WAAW,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAKvD;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,aAAa,EAAE,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAS7E;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAS9D"}
|
package/dist/middleware/auth.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { timingSafeEqual } from 'node:crypto';
|
|
2
2
|
import { StackPermissionError } from '@haverstack/core';
|
|
3
|
+
import { isOwnerActingAlone } from '@haverstack/core/wire';
|
|
3
4
|
import { wireError } from '../wireError.js';
|
|
4
5
|
/**
|
|
5
6
|
* Constant-time string equality, for comparing a presented credential
|
|
@@ -49,17 +50,11 @@ export function requireAuth() {
|
|
|
49
50
|
};
|
|
50
51
|
}
|
|
51
52
|
/**
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* `ScopedStack`'s own owner-only gates (e.g. hard delete). See
|
|
57
|
-
* docs/spec/access-control.md § Delegation.
|
|
53
|
+
* Gates a route to the owner acting alone: undelegated, and authenticated
|
|
54
|
+
* as the owner rather than merely delegated for it — the same test
|
|
55
|
+
* `ScopedStack`'s own owner-only gates apply. See
|
|
56
|
+
* docs/spec/access-control.md § Delegation: principal and subject.
|
|
58
57
|
*/
|
|
59
|
-
export function isOwnerActingAlone(auth, ownerEntityId) {
|
|
60
|
-
return auth?.principalId === ownerEntityId && auth?.subjectId === ownerEntityId;
|
|
61
|
-
}
|
|
62
|
-
/** Gates a route to the owner acting alone; see `isOwnerActingAlone()`. */
|
|
63
58
|
export function requireOwner(ownerEntityId) {
|
|
64
59
|
return async (c, next) => {
|
|
65
60
|
const auth = c.get('auth');
|
|
@@ -71,4 +66,20 @@ export function requireOwner(ownerEntityId) {
|
|
|
71
66
|
await next();
|
|
72
67
|
};
|
|
73
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Gates a route to a session acting as itself — not a principal acting
|
|
71
|
+
* for someone else. Checked before the body is read, like requireOwner(),
|
|
72
|
+
* so a refused identity is refused whatever it sent.
|
|
73
|
+
*/
|
|
74
|
+
export function requireActingAlone() {
|
|
75
|
+
return async (c, next) => {
|
|
76
|
+
const auth = c.get('auth');
|
|
77
|
+
if (!auth)
|
|
78
|
+
return wireError(c, 401, 'unauthorized', 'Missing or invalid bearer token');
|
|
79
|
+
if (auth.principalId !== auth.subjectId) {
|
|
80
|
+
throw new StackPermissionError('This request must come from the key acting as itself');
|
|
81
|
+
}
|
|
82
|
+
await next();
|
|
83
|
+
};
|
|
84
|
+
}
|
|
74
85
|
//# sourceMappingURL=auth.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -36,7 +36,7 @@ export function errorMiddleware(logger, stack) {
|
|
|
36
36
|
if (err instanceof StackNotFoundError && auth) {
|
|
37
37
|
const recordId = c.req.param('id');
|
|
38
38
|
if (recordId) {
|
|
39
|
-
const existing = await stack.get(recordId);
|
|
39
|
+
const existing = await stack.get(recordId, { includeDeleted: true });
|
|
40
40
|
logger.debug({
|
|
41
41
|
requestId: c.get('requestId'),
|
|
42
42
|
principalId: auth.principalId,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/middleware/errors.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAc,MAAM,kBAAkB,CAAC;AAExF,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe,CAAC,MAAc,EAAE,KAAY;IAC1D,OAAO,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE;QACtB,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,IAAI,EAAE,CAAC;YACT,kEAAkE;YAClE,+DAA+D;YAC/D,mEAAmE;YACnE,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC3B,IAAI,GAAG,YAAY,oBAAoB,IAAI,IAAI,EAAE,CAAC;gBAChD,MAAM,CAAC,IAAI,CACT;oBACE,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC;oBAC7B,WAAW,EAAE,IAAI,CAAC,WAAW;oBAC7B,SAAS,EAAE,IAAI,CAAC,SAAS;iBAC1B,EACD,6BAA6B,CAC9B,CAAC;YACJ,CAAC;YACD,mEAAmE;YACnE,6DAA6D;YAC7D,kEAAkE;YAClE,mEAAmE;YACnE,oEAAoE;YACpE,sEAAsE;YACtE,yCAAyC;YACzC,IAAI,GAAG,YAAY,kBAAkB,IAAI,IAAI,EAAE,CAAC;gBAC9C,MAAM,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACnC,IAAI,QAAQ,EAAE,CAAC;oBACb,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/middleware/errors.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAc,MAAM,kBAAkB,CAAC;AAExF,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe,CAAC,MAAc,EAAE,KAAY;IAC1D,OAAO,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE;QACtB,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,IAAI,EAAE,CAAC;YACT,kEAAkE;YAClE,+DAA+D;YAC/D,mEAAmE;YACnE,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC3B,IAAI,GAAG,YAAY,oBAAoB,IAAI,IAAI,EAAE,CAAC;gBAChD,MAAM,CAAC,IAAI,CACT;oBACE,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC;oBAC7B,WAAW,EAAE,IAAI,CAAC,WAAW;oBAC7B,SAAS,EAAE,IAAI,CAAC,SAAS;iBAC1B,EACD,6BAA6B,CAC9B,CAAC;YACJ,CAAC;YACD,mEAAmE;YACnE,6DAA6D;YAC7D,kEAAkE;YAClE,mEAAmE;YACnE,oEAAoE;YACpE,sEAAsE;YACtE,yCAAyC;YACzC,IAAI,GAAG,YAAY,kBAAkB,IAAI,IAAI,EAAE,CAAC;gBAC9C,MAAM,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACnC,IAAI,QAAQ,EAAE,CAAC;oBACb,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC;oBACrE,MAAM,CAAC,KAAK,CACV;wBACE,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC;wBAC7B,WAAW,EAAE,IAAI,CAAC,WAAW;wBAC7B,SAAS,EAAE,IAAI,CAAC,SAAS;wBACzB,QAAQ;wBACR,OAAO,EAAE,QAAQ,KAAK,IAAI;wBAC1B,6DAA6D;wBAC7D,4DAA4D;wBAC5D,KAAK,EAAE,MAAM;qBACd,EACD,oCAAoC,CACrC,CAAC;gBACJ,CAAC;YACH,CAAC;YACD,+DAA+D;YAC/D,qEAAqE;YACrE,mEAAmE;YACnE,gEAAgE;YAChE,mEAAmE;YACnE,IAAI,IAAI,CAAC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI;gBAAE,CAAC,CAAC,MAAM,CAAC,kBAAkB,EAAE,QAAQ,CAAC,CAAC;YACzE,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAA8B,CAAC,CAAC;QAChE,CAAC;QACD,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,EAAE,yBAAyB,CAAC,CAAC;QAChF,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,uBAAuB,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;IACxF,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { MiddlewareHandler } from 'hono';
|
|
2
|
+
import type { AppEnv } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Refuse any query param the route doesn't define, for the same reason
|
|
5
|
+
* `rejectUnknownKeys()` refuses body keys. A route whose params one of
|
|
6
|
+
* core's wire parsers reads leaves the check to that parser; this is for
|
|
7
|
+
* the rest. See docs/spec/wire-format.md § Unrecognized input.
|
|
8
|
+
*/
|
|
9
|
+
export declare function knownParams(...names: string[]): MiddlewareHandler<AppEnv>;
|
|
10
|
+
//# sourceMappingURL=params.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"params.d.ts","sourceRoot":"","sources":["../../src/middleware/params.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAE9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAazE"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { StackBadRequestError } from '@haverstack/core';
|
|
2
|
+
/**
|
|
3
|
+
* Refuse any query param the route doesn't define, for the same reason
|
|
4
|
+
* `rejectUnknownKeys()` refuses body keys. A route whose params one of
|
|
5
|
+
* core's wire parsers reads leaves the check to that parser; this is for
|
|
6
|
+
* the rest. See docs/spec/wire-format.md § Unrecognized input.
|
|
7
|
+
*/
|
|
8
|
+
export function knownParams(...names) {
|
|
9
|
+
return async (c, next) => {
|
|
10
|
+
const unknown = [...new Set(new URL(c.req.url).searchParams.keys())].filter((name) => !names.includes(name));
|
|
11
|
+
if (unknown.length > 0) {
|
|
12
|
+
throw new StackBadRequestError(`Unknown query param${unknown.length > 1 ? 's' : ''}: ${unknown.join(', ')}. ` +
|
|
13
|
+
`This endpoint takes: ${names.join(', ') || 'none'}.`);
|
|
14
|
+
}
|
|
15
|
+
await next();
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=params.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"params.js","sourceRoot":"","sources":["../../src/middleware/params.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAGxD;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,GAAG,KAAe;IAC5C,OAAO,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;QACvB,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CACzE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAChC,CAAC;QACF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,oBAAoB,CAC5B,sBAAsB,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;gBAC5E,wBAAwB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,GAAG,CACxD,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,EAAE,CAAC;IACf,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attachments.d.ts","sourceRoot":"","sources":["../../src/routes/attachments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"attachments.d.ts","sourceRoot":"","sources":["../../src/routes/attachments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAgB5B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAKhD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CA0H5F"}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { Hono } from 'hono';
|
|
2
2
|
import { bodyLimit } from 'hono/body-limit';
|
|
3
|
-
import { StackPermissionError, StackPayloadTooLargeError } from '@haverstack/core';
|
|
4
|
-
import { resolveAttachmentDownloadContentType, resolveReferencedAttachment, parseUploadFilename, NOSNIFF_HEADER_NAME, NOSNIFF_HEADER_VALUE, } from '@haverstack/core/wire';
|
|
3
|
+
import { StackPermissionError, StackPayloadTooLargeError, StackValidationError, } from '@haverstack/core';
|
|
4
|
+
import { resolveAttachmentDownloadContentType, resolveReferencedAttachment, parseUploadFilename, NOSNIFF_HEADER_NAME, NOSNIFF_HEADER_VALUE, parseDownloadParams, } from '@haverstack/core/wire';
|
|
5
5
|
import { serializeRecord } from '@haverstack/wire-types';
|
|
6
|
+
import { knownParams } from '../middleware/params.js';
|
|
6
7
|
import { requireAuth, requireOwner } from '../middleware/auth.js';
|
|
8
|
+
import { readJson } from '../lib/json.js';
|
|
9
|
+
import { wireError } from '../wireError.js';
|
|
7
10
|
export function attachmentRoutes(ctx, maxAttachmentBytes) {
|
|
8
11
|
const app = new Hono();
|
|
9
12
|
const { stack } = ctx;
|
|
@@ -22,22 +25,23 @@ export function attachmentRoutes(ctx, maxAttachmentBytes) {
|
|
|
22
25
|
// _attachment@1 runs before a single byte is written: an authenticated
|
|
23
26
|
// requester with no grant is refused, not merely denied a metadata
|
|
24
27
|
// record afterward. See docs/spec/wire-format.md § Upload.
|
|
25
|
-
app.post('/', attachmentBodyLimit, requireAuth(), async (c) => {
|
|
28
|
+
app.post('/', knownParams('appId'), attachmentBodyLimit, requireAuth(), async (c) => {
|
|
26
29
|
const auth = c.get('auth');
|
|
27
30
|
const mimeType = c.req.header('Content-Type') || 'application/octet-stream';
|
|
28
31
|
const filename = parseUploadFilename(c.req.header('Content-Disposition'));
|
|
29
32
|
const appId = c.req.query('appId') || undefined;
|
|
30
33
|
const data = new Uint8Array(await c.req.arrayBuffer());
|
|
31
|
-
const record = await stack.
|
|
34
|
+
const record = await stack.asActor(auth).putAttachment(data, { mimeType, filename, appId });
|
|
32
35
|
return c.json(serializeRecord(record), 200);
|
|
33
36
|
});
|
|
34
37
|
// GET /attachments/:fileId — download
|
|
35
38
|
app.get('/:fileId', async (c) => {
|
|
36
39
|
const fileId = c.req.param('fileId');
|
|
37
40
|
const auth = c.get('auth');
|
|
41
|
+
const { contentTypeParam, filenameParam } = parseDownloadParams(new URL(c.req.url));
|
|
38
42
|
let data;
|
|
39
43
|
try {
|
|
40
|
-
data = await (auth ? stack.
|
|
44
|
+
data = await (auth ? stack.asActor(auth) : stack.asEntity(null)).getAttachment(fileId);
|
|
41
45
|
}
|
|
42
46
|
catch (e) {
|
|
43
47
|
// Anonymous and denied is a transport-auth failure, distinct from an
|
|
@@ -46,7 +50,7 @@ export function attachmentRoutes(ctx, maxAttachmentBytes) {
|
|
|
46
50
|
// for missing and forbidden, so this handler owes no anti-oracle
|
|
47
51
|
// logic of its own — only to leave that answer intact.
|
|
48
52
|
if (!auth && e instanceof StackPermissionError) {
|
|
49
|
-
return c
|
|
53
|
+
return wireError(c, 401, 'unauthorized', 'Missing or invalid bearer token');
|
|
50
54
|
}
|
|
51
55
|
throw e;
|
|
52
56
|
}
|
|
@@ -61,8 +65,6 @@ export function attachmentRoutes(ctx, maxAttachmentBytes) {
|
|
|
61
65
|
const referenced = resolveReferencedAttachment(metaRecords, {
|
|
62
66
|
requesterEntityId: auth?.subjectId,
|
|
63
67
|
});
|
|
64
|
-
const contentTypeParam = c.req.query('contentType');
|
|
65
|
-
const filenameParam = c.req.query('filename');
|
|
66
68
|
const { contentType, forced } = resolveAttachmentDownloadContentType({
|
|
67
69
|
contentTypeParam,
|
|
68
70
|
filenameParam,
|
|
@@ -84,7 +86,7 @@ export function attachmentRoutes(ctx, maxAttachmentBytes) {
|
|
|
84
86
|
});
|
|
85
87
|
});
|
|
86
88
|
// DELETE /attachments/:fileId
|
|
87
|
-
app.delete('/:fileId', requireOwner(ownerEntityId), async (c) => {
|
|
89
|
+
app.delete('/:fileId', knownParams(), requireOwner(ownerEntityId), async (c) => {
|
|
88
90
|
const fileId = c.req.param('fileId');
|
|
89
91
|
await stack.deleteAttachment(fileId);
|
|
90
92
|
return c.body(null, 204);
|
|
@@ -93,12 +95,20 @@ export function attachmentRoutes(ctx, maxAttachmentBytes) {
|
|
|
93
95
|
// Owner-only, invoke-only (no built-in scheduling): dryRun makes a
|
|
94
96
|
// cron-from-outside workflow safe. Body is entirely optional — every
|
|
95
97
|
// field defaults inside ScopedStack.collectAttachmentGarbage().
|
|
96
|
-
app.post('/gc', requireOwner(ownerEntityId), async (c) => {
|
|
98
|
+
app.post('/gc', knownParams(), requireOwner(ownerEntityId), async (c) => {
|
|
97
99
|
const auth = c.get('auth');
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
const body = (await c.req.text())
|
|
101
|
+
? await readJson(c, ['graceMs', 'dryRun'])
|
|
102
|
+
: {};
|
|
103
|
+
if (body.graceMs !== undefined &&
|
|
104
|
+
(typeof body.graceMs !== 'number' || !Number.isInteger(body.graceMs) || body.graceMs < 0))
|
|
105
|
+
throw new StackValidationError([
|
|
106
|
+
{ path: 'graceMs', message: 'Must be a non-negative integer' },
|
|
107
|
+
]);
|
|
108
|
+
if (body.dryRun !== undefined && typeof body.dryRun !== 'boolean')
|
|
109
|
+
throw new StackValidationError([{ path: 'dryRun', message: 'Must be a boolean' }]);
|
|
110
|
+
const result = await stack.asActor(auth).collectAttachmentGarbage({
|
|
111
|
+
...(body.graceMs !== undefined && { graceMs: body.graceMs }),
|
|
102
112
|
...(body.dryRun === true && { dryRun: true }),
|
|
103
113
|
});
|
|
104
114
|
return c.json(result, 200);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../src/routes/attachments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,
|
|
1
|
+
{"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../src/routes/attachments.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/routes/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/routes/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAgB5B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAyBhD,wBAAgB,UAAU,CAAC,GAAG,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAwF9F"}
|
package/dist/routes/auth.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { Hono } from 'hono';
|
|
2
|
-
import { verifyAuthChallenge, base64urlDecode } from '@haverstack/core/wire';
|
|
2
|
+
import { verifyAuthChallenge, base64urlDecode, parseAuthChallengeBody, parseAuthTokenBody, } from '@haverstack/core/wire';
|
|
3
3
|
import { isValidDidKey } from '@haverstack/core/did';
|
|
4
4
|
import { WIRE_AUTH_ERROR_STATUS } from '@haverstack/wire-types';
|
|
5
|
+
import { knownParams } from '../middleware/params.js';
|
|
5
6
|
import { readJson } from '../lib/json.js';
|
|
6
7
|
import { createExpiredTokenSweeper } from '../lib/tokenSweep.js';
|
|
8
|
+
import { SELF_SERVICE_TTL_MS } from '../lib/selfService.js';
|
|
7
9
|
// The handshake never issues a delegated token: proving key possession
|
|
8
|
-
// proves the principal and nothing about whom it may act for. It gets
|
|
9
|
-
//
|
|
10
|
-
// anyone can mint for themselves owes a bounded lifetime.
|
|
11
|
-
const AUTH_TOKEN_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
10
|
+
// proves the principal and nothing about whom it may act for. It gets the
|
|
11
|
+
// self-service lifetime rather than the owner's choice of one.
|
|
12
12
|
// Stamped on every handshake-issued token. GET /tokens is the owner's only
|
|
13
13
|
// view of what exists, and without this a self-service token is
|
|
14
14
|
// indistinguishable from one the owner minted deliberately — so "revoke
|
|
@@ -28,9 +28,9 @@ export function authRoutes(ctx, authOrigin, logger) {
|
|
|
28
28
|
const sweepExpiredTokens = createExpiredTokenSweeper(ctx.tokens, logger);
|
|
29
29
|
// POST /auth/challenge — issues a nonce bound to the requested DID.
|
|
30
30
|
// Unauthenticated: this is how a token is earned in the first place.
|
|
31
|
-
app.post('/challenge', async (c) => {
|
|
32
|
-
const body = await readJson(c);
|
|
33
|
-
if (
|
|
31
|
+
app.post('/challenge', knownParams(), async (c) => {
|
|
32
|
+
const body = parseAuthChallengeBody(await readJson(c));
|
|
33
|
+
if (!isValidDidKey(body.did)) {
|
|
34
34
|
return authError(c, 'invalid_did', 'Not a valid did:key');
|
|
35
35
|
}
|
|
36
36
|
const { nonce, expiresAt } = ctx.nonces.issue(body.did);
|
|
@@ -39,21 +39,11 @@ export function authRoutes(ctx, authOrigin, logger) {
|
|
|
39
39
|
});
|
|
40
40
|
// POST /auth/token — redeems a signed nonce for a bearer token.
|
|
41
41
|
// Unauthenticated for the same reason.
|
|
42
|
-
app.post('/token', async (c) => {
|
|
43
|
-
const body = await readJson(c);
|
|
44
|
-
if (
|
|
42
|
+
app.post('/token', knownParams(), async (c) => {
|
|
43
|
+
const body = parseAuthTokenBody(await readJson(c));
|
|
44
|
+
if (!isValidDidKey(body.did)) {
|
|
45
45
|
return authError(c, 'invalid_did', 'Not a valid did:key');
|
|
46
46
|
}
|
|
47
|
-
// Checked ahead of the signature so a nonce issued to a different DID
|
|
48
|
-
// is refused as unknown_nonce even when the caller's own signature over
|
|
49
|
-
// it is perfectly valid — the nonce belongs to the DID it was issued
|
|
50
|
-
// for, not to whoever can produce a valid signature.
|
|
51
|
-
if (typeof body.nonce !== 'string') {
|
|
52
|
-
return authError(c, 'unknown_nonce', 'Unknown or already-used nonce');
|
|
53
|
-
}
|
|
54
|
-
if (typeof body.signature !== 'string') {
|
|
55
|
-
return authError(c, 'invalid_signature', 'Signature does not verify');
|
|
56
|
-
}
|
|
57
47
|
// Spent on this call regardless of what happens next — single-use
|
|
58
48
|
// means a redemption attempt consumes the nonce, not merely a
|
|
59
49
|
// successful one.
|
|
@@ -82,8 +72,8 @@ export function authRoutes(ctx, authOrigin, logger) {
|
|
|
82
72
|
await sweepExpiredTokens();
|
|
83
73
|
// Undelegated by construction: principalId and subjectId are both the
|
|
84
74
|
// proven DID. Never let a client name its own subject.
|
|
85
|
-
const expiresAt = new Date(Date.now() +
|
|
86
|
-
const { token } = await ctx.tokens.createToken(body.did, {
|
|
75
|
+
const expiresAt = new Date(Date.now() + SELF_SERVICE_TTL_MS);
|
|
76
|
+
const { token } = await ctx.tokens.createToken({ subjectId: body.did, principalId: body.did }, {
|
|
87
77
|
expiresAt,
|
|
88
78
|
label: AUTH_TOKEN_LABEL,
|
|
89
79
|
});
|
package/dist/routes/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/routes/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/routes/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/routes/changes.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export type ChangeRouteOptions = {
|
|
|
11
11
|
* Whether a presented cursor is honored at all. Default true and never
|
|
12
12
|
* false in production, since discovery advertises resume unconditionally.
|
|
13
13
|
* It exists because `resume: false` is real, spec-defined behavior
|
|
14
|
-
* (`ready` with no `
|
|
14
|
+
* (`ready` with no `cursor`, then `reset` with reason `not_supported`) that
|
|
15
15
|
* a conformance fixture needs a way to reach.
|
|
16
16
|
*/
|
|
17
17
|
resume?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"changes.d.ts","sourceRoot":"","sources":["../../src/routes/changes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"changes.d.ts","sourceRoot":"","sources":["../../src/routes/changes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAO3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAuBnC,MAAM,MAAM,kBAAkB,GAAG;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAYF,wBAAgB,YAAY,CAC1B,GAAG,EAAE,YAAY,EACjB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,kBAAuB,GAC5B,IAAI,CAAC,MAAM,CAAC,CAoNd"}
|