@haverstack/server 0.11.0 → 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/queryWorker/protocol.d.ts +1 -1
- package/dist/lib/queryWorker/worker.js +1 -1
- package/dist/lib/queryWorker/worker.js.map +1 -1
- package/dist/lib/resumeBuffer.d.ts +0 -1
- package/dist/lib/resumeBuffer.d.ts.map +1 -1
- package/dist/lib/resumeBuffer.js +2 -1
- package/dist/lib/resumeBuffer.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 +3 -5
- package/dist/middleware/params.d.ts.map +1 -1
- package/dist/middleware/params.js +3 -12
- package/dist/middleware/params.js.map +1 -1
- package/dist/routes/attachments.d.ts.map +1 -1
- package/dist/routes/attachments.js +5 -5
- package/dist/routes/attachments.js.map +1 -1
- package/dist/routes/auth.d.ts.map +1 -1
- package/dist/routes/auth.js +9 -20
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/changes.d.ts.map +1 -1
- package/dist/routes/changes.js +6 -7
- package/dist/routes/changes.js.map +1 -1
- package/dist/routes/entity.d.ts.map +1 -1
- package/dist/routes/entity.js +9 -11
- package/dist/routes/entity.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 +105 -165
- package/dist/routes/records.js.map +1 -1
- package/dist/routes/types.d.ts.map +1 -1
- package/dist/routes/types.js +7 -39
- package/dist/routes/types.js.map +1 -1
- package/dist/routes/wellknown.d.ts.map +1 -1
- package/dist/routes/wellknown.js +2 -0
- 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 +28 -6
- package/dist/stack.js.map +1 -1
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +13 -2
- package/dist/testing.js.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":"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
|
+
{"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,11 +1,12 @@
|
|
|
1
1
|
import { Hono } from 'hono';
|
|
2
2
|
import { bodyLimit } from 'hono/body-limit';
|
|
3
3
|
import { StackPermissionError, StackPayloadTooLargeError, StackValidationError, } from '@haverstack/core';
|
|
4
|
-
import { resolveAttachmentDownloadContentType, resolveReferencedAttachment, parseUploadFilename, NOSNIFF_HEADER_NAME, NOSNIFF_HEADER_VALUE, } from '@haverstack/core/wire';
|
|
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
6
|
import { knownParams } from '../middleware/params.js';
|
|
7
7
|
import { requireAuth, requireOwner } from '../middleware/auth.js';
|
|
8
8
|
import { readJson } from '../lib/json.js';
|
|
9
|
+
import { wireError } from '../wireError.js';
|
|
9
10
|
export function attachmentRoutes(ctx, maxAttachmentBytes) {
|
|
10
11
|
const app = new Hono();
|
|
11
12
|
const { stack } = ctx;
|
|
@@ -34,9 +35,10 @@ export function attachmentRoutes(ctx, maxAttachmentBytes) {
|
|
|
34
35
|
return c.json(serializeRecord(record), 200);
|
|
35
36
|
});
|
|
36
37
|
// GET /attachments/:fileId — download
|
|
37
|
-
app.get('/:fileId',
|
|
38
|
+
app.get('/:fileId', async (c) => {
|
|
38
39
|
const fileId = c.req.param('fileId');
|
|
39
40
|
const auth = c.get('auth');
|
|
41
|
+
const { contentTypeParam, filenameParam } = parseDownloadParams(new URL(c.req.url));
|
|
40
42
|
let data;
|
|
41
43
|
try {
|
|
42
44
|
data = await (auth ? stack.asActor(auth) : stack.asEntity(null)).getAttachment(fileId);
|
|
@@ -48,7 +50,7 @@ export function attachmentRoutes(ctx, maxAttachmentBytes) {
|
|
|
48
50
|
// for missing and forbidden, so this handler owes no anti-oracle
|
|
49
51
|
// logic of its own — only to leave that answer intact.
|
|
50
52
|
if (!auth && e instanceof StackPermissionError) {
|
|
51
|
-
return c
|
|
53
|
+
return wireError(c, 401, 'unauthorized', 'Missing or invalid bearer token');
|
|
52
54
|
}
|
|
53
55
|
throw e;
|
|
54
56
|
}
|
|
@@ -63,8 +65,6 @@ export function attachmentRoutes(ctx, maxAttachmentBytes) {
|
|
|
63
65
|
const referenced = resolveReferencedAttachment(metaRecords, {
|
|
64
66
|
requesterEntityId: auth?.subjectId,
|
|
65
67
|
});
|
|
66
|
-
const contentTypeParam = c.req.query('contentType');
|
|
67
|
-
const filenameParam = c.req.query('filename');
|
|
68
68
|
const { contentType, forced } = resolveAttachmentDownloadContentType({
|
|
69
69
|
contentTypeParam,
|
|
70
70
|
filenameParam,
|
|
@@ -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,EACL,oBAAoB,EACpB,yBAAyB,EACzB,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,oCAAoC,EACpC,2BAA2B,EAC3B,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,
|
|
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,15 +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
5
|
import { knownParams } from '../middleware/params.js';
|
|
6
6
|
import { readJson } from '../lib/json.js';
|
|
7
7
|
import { createExpiredTokenSweeper } from '../lib/tokenSweep.js';
|
|
8
|
+
import { SELF_SERVICE_TTL_MS } from '../lib/selfService.js';
|
|
8
9
|
// The handshake never issues a delegated token: proving key possession
|
|
9
|
-
// proves the principal and nothing about whom it may act for. It gets
|
|
10
|
-
//
|
|
11
|
-
// anyone can mint for themselves owes a bounded lifetime.
|
|
12
|
-
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.
|
|
13
12
|
// Stamped on every handshake-issued token. GET /tokens is the owner's only
|
|
14
13
|
// view of what exists, and without this a self-service token is
|
|
15
14
|
// indistinguishable from one the owner minted deliberately — so "revoke
|
|
@@ -30,8 +29,8 @@ export function authRoutes(ctx, authOrigin, logger) {
|
|
|
30
29
|
// POST /auth/challenge — issues a nonce bound to the requested DID.
|
|
31
30
|
// Unauthenticated: this is how a token is earned in the first place.
|
|
32
31
|
app.post('/challenge', knownParams(), async (c) => {
|
|
33
|
-
const body = await readJson(c
|
|
34
|
-
if (
|
|
32
|
+
const body = parseAuthChallengeBody(await readJson(c));
|
|
33
|
+
if (!isValidDidKey(body.did)) {
|
|
35
34
|
return authError(c, 'invalid_did', 'Not a valid did:key');
|
|
36
35
|
}
|
|
37
36
|
const { nonce, expiresAt } = ctx.nonces.issue(body.did);
|
|
@@ -41,20 +40,10 @@ export function authRoutes(ctx, authOrigin, logger) {
|
|
|
41
40
|
// POST /auth/token — redeems a signed nonce for a bearer token.
|
|
42
41
|
// Unauthenticated for the same reason.
|
|
43
42
|
app.post('/token', knownParams(), async (c) => {
|
|
44
|
-
const body = await readJson(c
|
|
45
|
-
if (
|
|
43
|
+
const body = parseAuthTokenBody(await readJson(c));
|
|
44
|
+
if (!isValidDidKey(body.did)) {
|
|
46
45
|
return authError(c, 'invalid_did', 'Not a valid did:key');
|
|
47
46
|
}
|
|
48
|
-
// Checked ahead of the signature so a nonce issued to a different DID
|
|
49
|
-
// is refused as unknown_nonce even when the caller's own signature over
|
|
50
|
-
// it is perfectly valid — the nonce belongs to the DID it was issued
|
|
51
|
-
// for, not to whoever can produce a valid signature.
|
|
52
|
-
if (typeof body.nonce !== 'string') {
|
|
53
|
-
return authError(c, 'unknown_nonce', 'Unknown or already-used nonce');
|
|
54
|
-
}
|
|
55
|
-
if (typeof body.signature !== 'string') {
|
|
56
|
-
return authError(c, 'invalid_signature', 'Signature does not verify');
|
|
57
|
-
}
|
|
58
47
|
// Spent on this call regardless of what happens next — single-use
|
|
59
48
|
// means a redemption attempt consumes the nonce, not merely a
|
|
60
49
|
// successful one.
|
|
@@ -83,7 +72,7 @@ export function authRoutes(ctx, authOrigin, logger) {
|
|
|
83
72
|
await sweepExpiredTokens();
|
|
84
73
|
// Undelegated by construction: principalId and subjectId are both the
|
|
85
74
|
// proven DID. Never let a client name its own subject.
|
|
86
|
-
const expiresAt = new Date(Date.now() +
|
|
75
|
+
const expiresAt = new Date(Date.now() + SELF_SERVICE_TTL_MS);
|
|
87
76
|
const { token } = await ctx.tokens.createToken({ subjectId: body.did, principalId: body.did }, {
|
|
88
77
|
expiresAt,
|
|
89
78
|
label: AUTH_TOKEN_LABEL,
|
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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"}
|
|
@@ -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;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,
|
|
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"}
|
package/dist/routes/changes.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Hono } from 'hono';
|
|
2
2
|
import { streamSSE } from 'hono/streaming';
|
|
3
3
|
import { StackBadRequestError, StackPermissionError } from '@haverstack/core';
|
|
4
|
-
import { parseChangeParams } from '@haverstack/core/wire';
|
|
4
|
+
import { parseChangeParams, isOwnerActingAlone } from '@haverstack/core/wire';
|
|
5
5
|
import { serializeChange, isValidCursor } from '@haverstack/wire-types';
|
|
6
|
-
import { safeCompare
|
|
6
|
+
import { safeCompare } from '../middleware/auth.js';
|
|
7
7
|
import { FrameGate } from '../lib/frameGate.js';
|
|
8
8
|
import { decodeCursor } from '../lib/resumeCursor.js';
|
|
9
9
|
import { ResumeBufferRegistry, resumeBufferKey } from '../lib/resumeBuffer.js';
|
|
@@ -54,13 +54,13 @@ export function changeRoutes(ctx, config, logger, opts = {}) {
|
|
|
54
54
|
app.get('/', async (c) => {
|
|
55
55
|
const url = new URL(c.req.url);
|
|
56
56
|
const auth = c.get('auth');
|
|
57
|
-
const { filter, includeRecords
|
|
57
|
+
const { filter, includeRecords } = parseChangeParams(url);
|
|
58
58
|
const presentedRaw = presentedCursorRaw(c, url);
|
|
59
59
|
// Refused before the stream opens: a throw from subscribe() after
|
|
60
60
|
// streaming starts is caught below and merely closes the connection,
|
|
61
61
|
// silently, having already answered 200. includeUnlisted owes a real
|
|
62
62
|
// 403, the same one GET /records answers with.
|
|
63
|
-
if (includeUnlisted && !isOwnerActingAlone(auth, ctx.stack.ownerEntityId)) {
|
|
63
|
+
if (filter.includeUnlisted && !(auth && isOwnerActingAlone(auth, ctx.stack.ownerEntityId))) {
|
|
64
64
|
throw new StackPermissionError('includeUnlisted is owner-only');
|
|
65
65
|
}
|
|
66
66
|
// A charset-invalid cursor is refused rather than treated as a cache
|
|
@@ -106,7 +106,7 @@ export function changeRoutes(ctx, config, logger, opts = {}) {
|
|
|
106
106
|
}
|
|
107
107
|
unsubscribe = await scopeFor(auth).subscribe((change) => {
|
|
108
108
|
send('record', serializeChange(change));
|
|
109
|
-
}, { filter, includeRecords
|
|
109
|
+
}, { filter, includeRecords });
|
|
110
110
|
}
|
|
111
111
|
else {
|
|
112
112
|
const key = resumeBufferKey({
|
|
@@ -114,10 +114,9 @@ export function changeRoutes(ctx, config, logger, opts = {}) {
|
|
|
114
114
|
subjectId: auth?.subjectId ?? null,
|
|
115
115
|
filter,
|
|
116
116
|
includeRecords,
|
|
117
|
-
includeUnlisted,
|
|
118
117
|
});
|
|
119
118
|
const scoped = scopeFor(auth);
|
|
120
|
-
const buffer = await resumeBuffers.acquire(key, (onChange) => scoped.subscribe(onChange, { filter, includeRecords
|
|
119
|
+
const buffer = await resumeBuffers.acquire(key, (onChange) => scoped.subscribe(onChange, { filter, includeRecords }));
|
|
121
120
|
// Attached before anything below awaits, so there is no gap
|
|
122
121
|
// between what the backlog snapshot covers and what the live
|
|
123
122
|
// buffer reports. `replaying` holds live arrivals until the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"changes.js","sourceRoot":"","sources":["../../src/routes/changes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAM3C,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"changes.js","sourceRoot":"","sources":["../../src/routes/changes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAM3C,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAGxE,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAoB,MAAM,wBAAwB,CAAC;AAEjG,0EAA0E;AAC1E,yEAAyE;AACzE,2EAA2E;AAC3E,8EAA8E;AAC9E,MAAM,oBAAoB,GAAG,MAAM,CAAC;AACpC,MAAM,wBAAwB,GAAG,MAAM,CAAC;AACxC,0EAA0E;AAC1E,uEAAuE;AACvE,4DAA4D;AAC5D,MAAM,0BAA0B,GAAG,IAAI,CAAC;AACxC,wEAAwE;AACxE,yEAAyE;AACzE,sEAAsE;AACtE,sDAAsD;AACtD,MAAM,2BAA2B,GAAG,IAAI,CAAC;AACzC,MAAM,2BAA2B,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAkBlD;;;;;GAKG;AACH,SAAS,kBAAkB,CAAC,CAAkB,EAAE,GAAQ;IACtD,OAAO,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,SAAS,CAAC;AACrF,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,GAAiB,EACjB,MAAc,EACd,MAAc,EACd,OAA2B,EAAE;IAE7B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAU,CAAC;IAC/B,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,oBAAoB,CAAC;IAC7D,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,IAAI,wBAAwB,CAAC;IACvE,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,IAAI,0BAA0B,CAAC;IAC7E,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC;IAC1C,MAAM,aAAa,GAAG,IAAI,oBAAoB,CAAC;QAC7C,KAAK,EAAE,IAAI,CAAC,iBAAiB,IAAI,2BAA2B;QAC5D,WAAW,EAAE,IAAI,CAAC,iBAAiB,IAAI,2BAA2B;KACnE,CAAC,CAAC;IAEH,kFAAkF;IAClF,SAAS,QAAQ,CAAC,IAAyB;QACzC,OAAO,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACnE,CAAC;IAED,mEAAmE;IACnE,kEAAkE;IAClE,wEAAwE;IACxE,yEAAyE;IACzE,+DAA+D;IAC/D,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACvB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC/B,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC3B,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;QAC1D,MAAM,YAAY,GAAG,kBAAkB,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAEhD,kEAAkE;QAClE,qEAAqE;QACrE,qEAAqE;QACrE,+CAA+C;QAC/C,IAAI,MAAM,CAAC,eAAe,IAAI,CAAC,CAAC,IAAI,IAAI,kBAAkB,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC;YAC3F,MAAM,IAAI,oBAAoB,CAAC,+BAA+B,CAAC,CAAC;QAClE,CAAC;QAED,qEAAqE;QACrE,uEAAuE;QACvE,2EAA2E;QAC3E,mCAAmC;QACnC,IAAI,aAAa,IAAI,YAAY,KAAK,SAAS,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,EAAE,CAAC;YAChF,MAAM,IAAI,oBAAoB,CAAC,oBAAoB,YAAY,GAAG,CAAC,CAAC;QACtE,CAAC;QAED,qEAAqE;QACrE,kEAAkE;QAClE,uEAAuE;QACvE,uEAAuE;QACvE,MAAM,WAAW,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAE3E,OAAO,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YACnC,IAAI,WAAwB,CAAC;YAC7B,MAAM,IAAI,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;gBACzC,WAAW,GAAG,OAAO,CAAC;YACxB,CAAC,CAAC,CAAC;YACH,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;YACpC,MAAM,UAAU,GAAG,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;YAE9D,MAAM,IAAI,GAAG,IAAI,SAAS,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;YAClE,4EAA4E;YAC5E,SAAS,IAAI,CAAC,KAAa,EAAE,IAAa,EAAE,EAAW;gBACrD,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CACpB,MAAM,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,SAAS,IAAI,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CACxF,CAAC;YACJ,CAAC;YAED,sEAAsE;YACtE,oEAAoE;YACpE,qEAAqE;YACrE,mEAAmE;YACnE,IAAI,WAAqC,CAAC;YAC1C,IAAI,SAAqC,CAAC;YAC1C,IAAI,YAAwC,CAAC;YAE7C,IAAI,CAAC;gBACH,IAAI,CAAC,aAAa,EAAE,CAAC;oBACnB,gEAAgE;oBAChE,gEAAgE;oBAChE,wBAAwB;oBACxB,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;oBAClB,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;wBAC/B,MAAM,MAAM,GAAsB,eAAe,CAAC;wBAClD,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;oBAC5B,CAAC;oBACD,WAAW,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC,SAAS,CAC1C,CAAC,MAAoB,EAAE,EAAE;wBACvB,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;oBAC1C,CAAC,EACD,EAAE,MAAM,EAAE,cAAc,EAAE,CAC3B,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,MAAM,GAAG,GAAG,eAAe,CAAC;wBAC1B,WAAW,EAAE,IAAI,EAAE,WAAW,IAAI,IAAI;wBACtC,SAAS,EAAE,IAAI,EAAE,SAAS,IAAI,IAAI;wBAClC,MAAM;wBACN,cAAc;qBACf,CAAC,CAAC;oBACH,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;oBAC9B,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,EAAE,CAC3D,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CACvD,CAAC;oBAEF,4DAA4D;oBAC5D,6DAA6D;oBAC7D,4DAA4D;oBAC5D,8DAA8D;oBAC9D,mEAAmE;oBACnE,IAAI,SAAS,GAAG,IAAI,CAAC;oBACrB,MAAM,MAAM,GAAkB,EAAE,CAAC;oBACjC,MAAM,UAAU,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC,KAAK,EAAE,EAAE;wBAChD,IAAI,SAAS;4BAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;;4BAC7B,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;oBACvD,CAAC,CAAC,CAAC;oBACH,+DAA+D;oBAC/D,8DAA8D;oBAC9D,8DAA8D;oBAC9D,WAAW,GAAG,GAAG,EAAE;wBACjB,UAAU,EAAE,CAAC;wBACb,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;oBAC7B,CAAC,CAAC;oBAEF,IAAI,WAA0C,CAAC;oBAC/C,IAAI,OAAO,GAAkB,EAAE,CAAC;oBAChC,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;wBAC/B,MAAM,OAAO,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC;wBAC3C,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,QAAQ,KAAK,MAAM,CAAC,EAAE,EAAE,CAAC;4BAC/C,+DAA+D;4BAC/D,6DAA6D;4BAC7D,8DAA8D;4BAC9D,WAAW,GAAG,gBAAgB,CAAC;wBACjC,CAAC;6BAAM,CAAC;4BACN,MAAM,OAAO,GAAG,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;4BAC/C,IAAI,OAAO,CAAC,MAAM,KAAK,IAAI;gCAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;;gCAClD,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;wBACpC,CAAC;oBACH,CAAC;oBAED,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;oBAE/C,IAAI,WAAW,EAAE,CAAC;wBAChB,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;oBACzC,CAAC;yBAAM,CAAC;wBACN,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;4BAC5B,sDAAsD;4BACtD,8CAA8C;4BAC9C,8DAA8D;4BAC9D,wDAAwD;4BACxD,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;gCACnB,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gCACvD,IAAI,CAAC,aAAa;oCAAE,SAAS;4BAC/B,CAAC;4BACD,yDAAyD;4BACzD,4DAA4D;4BAC5D,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC;gCAAE,MAAM;wBAC9D,CAAC;oBACH,CAAC;oBAED,SAAS,GAAG,KAAK,CAAC;oBAClB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;wBAC3B,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC;4BAAE,MAAM;oBAC9D,CAAC;gBACH,CAAC;gBAED,mEAAmE;gBACnE,gEAAgE;gBAChE,gEAAgE;gBAChE,wCAAwC;gBACxC,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE;oBAC3B,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;gBACnD,CAAC,EAAE,WAAW,CAAC,CAAC;gBAEhB,+DAA+D;gBAC/D,gEAAgE;gBAChE,qEAAqE;gBACrE,+DAA+D;gBAC/D,MAAM,YAAY,GAChB,WAAW,KAAK,SAAS,IAAI,WAAW,CAAC,WAAW,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;gBAC3E,YAAY;oBACV,IAAI,IAAI,CAAC,YAAY,IAAI,WAAW;wBAClC,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE;4BACf,KAAK,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,IAAI,CAC3C,CAAC,OAAO,EAAE,EAAE;gCACV,IAAI,CAAC,OAAO;oCAAE,WAAW,EAAE,CAAC;4BAC9B,CAAC;4BACD,wDAAwD;4BACxD,sDAAsD;4BACtD,uDAAuD;4BACvD,+CAA+C;4BAC/C,GAAG,EAAE,CAAC,WAAW,EAAE,CACpB,CAAC;wBACJ,CAAC,EAAE,cAAc,CAAC;wBACpB,CAAC,CAAC,SAAS,CAAC;gBAEhB,MAAM,IAAI,CAAC;YACb,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,+DAA+D;gBAC/D,qEAAqE;gBACrE,kEAAkE;gBAClE,+DAA+D;gBAC/D,MAAM,CAAC,KAAK,CACV,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,EACtC,4CAA4C,CAC7C,CAAC;YACJ,CAAC;oBAAS,CAAC;gBACT,IAAI,SAAS;oBAAE,aAAa,CAAC,SAAS,CAAC,CAAC;gBACxC,IAAI,YAAY;oBAAE,aAAa,CAAC,YAAY,CAAC,CAAC;gBAC9C,WAAW,EAAE,EAAE,CAAC;gBAChB,UAAU,EAAE,CAAC;YACf,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entity.d.ts","sourceRoot":"","sources":["../../src/routes/entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"entity.d.ts","sourceRoot":"","sources":["../../src/routes/entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAQhD,wBAAgB,YAAY,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,CAyB5D"}
|
package/dist/routes/entity.js
CHANGED
|
@@ -3,7 +3,9 @@ import { knownParams } from '../middleware/params.js';
|
|
|
3
3
|
import { requireAuth, requireOwner } from '../middleware/auth.js';
|
|
4
4
|
import { readJson } from '../lib/json.js';
|
|
5
5
|
import { serializeRecord } from '@haverstack/wire-types';
|
|
6
|
-
import {
|
|
6
|
+
import { parseContentPatchBody } from '@haverstack/core/wire';
|
|
7
|
+
import { ifMatchVersion } from '../lib/ifMatch.js';
|
|
8
|
+
import { StackNotFoundError } from '@haverstack/core';
|
|
7
9
|
export function entityRoutes(ctx) {
|
|
8
10
|
const app = new Hono();
|
|
9
11
|
const { stack } = ctx;
|
|
@@ -15,20 +17,16 @@ export function entityRoutes(ctx) {
|
|
|
15
17
|
throw new StackNotFoundError('Entity record not found');
|
|
16
18
|
return c.json(serializeRecord(record));
|
|
17
19
|
});
|
|
18
|
-
|
|
20
|
+
// An alias for PATCH /records/:id/content on the owner's entity record,
|
|
21
|
+
// so it takes the same bare patch and the same If-Match.
|
|
22
|
+
// See docs/spec/wire-format.md § Entity.
|
|
23
|
+
app.patch('/content', knownParams(), requireOwner(ownerEntityId), async (c) => {
|
|
19
24
|
const auth = c.get('auth');
|
|
20
|
-
const
|
|
21
|
-
const content = body.content;
|
|
22
|
-
if (content === undefined)
|
|
23
|
-
throw new StackBadRequestError('content is required');
|
|
24
|
-
if (typeof content !== 'object' || content === null || Array.isArray(content))
|
|
25
|
-
throw new StackValidationError([{ path: 'content', message: 'Must be an object' }]);
|
|
25
|
+
const patch = parseContentPatchBody(await readJson(c));
|
|
26
26
|
const record = await stack.asActor(auth).getOwnerEntity();
|
|
27
27
|
if (!record)
|
|
28
28
|
throw new StackNotFoundError('Entity record not found');
|
|
29
|
-
const updated = await stack
|
|
30
|
-
.asActor(auth)
|
|
31
|
-
.patchContent(record.id, content);
|
|
29
|
+
const updated = await stack.asActor(auth).patchContent(record.id, patch, ifMatchVersion(c));
|
|
32
30
|
return c.json(serializeRecord(updated));
|
|
33
31
|
});
|
|
34
32
|
return app;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entity.js","sourceRoot":"","sources":["../../src/routes/entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"entity.js","sourceRoot":"","sources":["../../src/routes/entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,UAAU,YAAY,CAAC,GAAiB;IAC5C,MAAM,GAAG,GAAG,IAAI,IAAI,EAAU,CAAC;IAC/B,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC;IACtB,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC;IAE1C,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,EAAE,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACrD,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,cAAc,EAAE,CAAC;QAC1D,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,kBAAkB,CAAC,yBAAyB,CAAC,CAAC;QACrE,OAAO,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,wEAAwE;IACxE,yDAAyD;IACzD,yCAAyC;IACzC,GAAG,CAAC,KAAK,CAAC,UAAU,EAAE,WAAW,EAAE,EAAE,YAAY,CAAC,aAAa,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC5E,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,qBAAqB,CAAC,MAAM,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,cAAc,EAAE,CAAC;QAC1D,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,kBAAkB,CAAC,yBAAyB,CAAC,CAAC;QACrE,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5F,OAAO,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import type { AppEnv } from '../types.js';
|
|
3
|
+
import type { StackContext } from '../stack.js';
|
|
4
|
+
/**
|
|
5
|
+
* The two halves of an app install. POST /installs is the app's, and the
|
|
6
|
+
* wire contract pins it: a key presents its manifest and learns whether
|
|
7
|
+
* it was approved. /installs/requests is the owner's, which the spec
|
|
8
|
+
* leaves to the server: review what a pending request would change, then
|
|
9
|
+
* approve or decline it. Underneath, both are Stack.planInstall(), and
|
|
10
|
+
* approval is Stack.installApp(). See docs/spec/apps.md § Over the wire.
|
|
11
|
+
*/
|
|
12
|
+
export declare function installRoutes(ctx: StackContext): Hono<AppEnv>;
|
|
13
|
+
//# sourceMappingURL=installs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installs.d.ts","sourceRoot":"","sources":["../../src/routes/installs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAM5B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAKhD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,CA6D7D"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import { StackNotFoundError, isPlanEmpty } from '@haverstack/core';
|
|
3
|
+
import { parseInstallBody } from '@haverstack/core/wire';
|
|
4
|
+
import { serializeRecord } from '@haverstack/wire-types';
|
|
5
|
+
import { knownParams } from '../middleware/params.js';
|
|
6
|
+
import { requireActingAlone, requireOwner } from '../middleware/auth.js';
|
|
7
|
+
import { readJson } from '../lib/json.js';
|
|
8
|
+
/**
|
|
9
|
+
* The two halves of an app install. POST /installs is the app's, and the
|
|
10
|
+
* wire contract pins it: a key presents its manifest and learns whether
|
|
11
|
+
* it was approved. /installs/requests is the owner's, which the spec
|
|
12
|
+
* leaves to the server: review what a pending request would change, then
|
|
13
|
+
* approve or decline it. Underneath, both are Stack.planInstall(), and
|
|
14
|
+
* approval is Stack.installApp(). See docs/spec/apps.md § Over the wire.
|
|
15
|
+
*/
|
|
16
|
+
export function installRoutes(ctx) {
|
|
17
|
+
const app = new Hono();
|
|
18
|
+
const { stack, installRequests } = ctx;
|
|
19
|
+
const ownerEntityId = stack.ownerEntityId;
|
|
20
|
+
// The key being installed is the session's principal, never named in
|
|
21
|
+
// the body, so no app can ask on behalf of a key it does not hold.
|
|
22
|
+
// Planning writes nothing; only an empty plan is answered as installed.
|
|
23
|
+
// See docs/spec/wire-format.md § Installs.
|
|
24
|
+
app.post('/', knownParams(), requireActingAlone(), async (c) => {
|
|
25
|
+
const auth = c.get('auth');
|
|
26
|
+
const manifest = parseInstallBody(await readJson(c));
|
|
27
|
+
const plan = await stack.planInstall(manifest, { did: auth.principalId });
|
|
28
|
+
if (isPlanEmpty(plan)) {
|
|
29
|
+
const pending = installRequests.forKey(auth.principalId);
|
|
30
|
+
if (pending)
|
|
31
|
+
installRequests.remove(pending.id);
|
|
32
|
+
const body = {
|
|
33
|
+
status: 'installed',
|
|
34
|
+
install: serializeRecord(plan.existing),
|
|
35
|
+
};
|
|
36
|
+
return c.json(body, 200);
|
|
37
|
+
}
|
|
38
|
+
installRequests.put(auth.principalId, manifest);
|
|
39
|
+
const body = { status: 'pending' };
|
|
40
|
+
return c.json(body, 202);
|
|
41
|
+
});
|
|
42
|
+
app.get('/requests', knownParams(), requireOwner(ownerEntityId), (c) => {
|
|
43
|
+
return c.json({ requests: installRequests.list().map(serializeRequest) });
|
|
44
|
+
});
|
|
45
|
+
// Planned on every read rather than stored, since what a manifest would
|
|
46
|
+
// change depends on the stack as it stands now.
|
|
47
|
+
app.get('/requests/:id', knownParams(), requireOwner(ownerEntityId), async (c) => {
|
|
48
|
+
const entry = requestOrNotFound(c.req.param('id'));
|
|
49
|
+
const plan = await stack.planInstall(entry.manifest, { did: entry.did });
|
|
50
|
+
return c.json({ ...serializeRequest(entry), plan: serializePlan(plan) });
|
|
51
|
+
});
|
|
52
|
+
// Applies the manifest the id names, planned afresh at approval.
|
|
53
|
+
app.post('/requests/:id/approve', knownParams(), requireOwner(ownerEntityId), async (c) => {
|
|
54
|
+
const entry = requestOrNotFound(c.req.param('id'));
|
|
55
|
+
const plan = await stack.planInstall(entry.manifest, { did: entry.did });
|
|
56
|
+
const install = await stack.installApp(plan);
|
|
57
|
+
installRequests.remove(entry.id);
|
|
58
|
+
const body = { status: 'installed', install: serializeRecord(install) };
|
|
59
|
+
return c.json(body);
|
|
60
|
+
});
|
|
61
|
+
app.delete('/requests/:id', knownParams(), requireOwner(ownerEntityId), (c) => {
|
|
62
|
+
installRequests.remove(requestOrNotFound(c.req.param('id')).id);
|
|
63
|
+
return c.body(null, 204);
|
|
64
|
+
});
|
|
65
|
+
function requestOrNotFound(id) {
|
|
66
|
+
const entry = installRequests.get(id);
|
|
67
|
+
if (!entry)
|
|
68
|
+
throw new StackNotFoundError('Install request not found');
|
|
69
|
+
return entry;
|
|
70
|
+
}
|
|
71
|
+
return app;
|
|
72
|
+
}
|
|
73
|
+
function serializeRequest(entry) {
|
|
74
|
+
return {
|
|
75
|
+
id: entry.id,
|
|
76
|
+
did: entry.did,
|
|
77
|
+
manifest: entry.manifest,
|
|
78
|
+
requestedAt: entry.requestedAt.toISOString(),
|
|
79
|
+
expiresAt: entry.expiresAt.toISOString(),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* What a plan would change; its manifest and key are already on the request.
|
|
84
|
+
* Every field is named, so nothing reaches the wire unchosen, and the return
|
|
85
|
+
* type covers every InstallPlan field, so a field core adds fails to compile
|
|
86
|
+
* here until someone decides whether the owner's review shows it.
|
|
87
|
+
*/
|
|
88
|
+
function serializePlan(plan) {
|
|
89
|
+
return {
|
|
90
|
+
existing: plan.existing ? serializeRecord(plan.existing) : null,
|
|
91
|
+
newFamilies: plan.newFamilies,
|
|
92
|
+
newVersions: plan.newVersions,
|
|
93
|
+
requestsAdded: plan.requestsAdded,
|
|
94
|
+
requestsRemoved: plan.requestsRemoved,
|
|
95
|
+
foreignRequests: plan.foreignRequests,
|
|
96
|
+
typeChanges: plan.typeChanges,
|
|
97
|
+
newKey: plan.newKey,
|
|
98
|
+
linkedKeys: plan.linkedKeys,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=installs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installs.js","sourceRoot":"","sources":["../../src/routes/installs.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"records.d.ts","sourceRoot":"","sources":["../../src/routes/records.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"records.d.ts","sourceRoot":"","sources":["../../src/routes/records.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA2ChD,wBAAgB,YAAY,CAAC,GAAG,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAwPpF"}
|