@jini-ai/http-kit 0.3.2 → 0.3.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/dist/delegated-tools.d.ts +89 -0
- package/dist/delegated-tools.d.ts.map +1 -1
- package/dist/delegated-tools.js +106 -1
- package/dist/delegated-tools.js.map +1 -1
- package/package.json +6 -6
- package/dist/express/run-stream.d.ts +0 -15
- package/dist/express/run-stream.d.ts.map +0 -1
- package/dist/express/run-stream.js +0 -11
- package/dist/express/run-stream.js.map +0 -1
- package/dist/express-index.d.ts +0 -32
- package/dist/express-index.d.ts.map +0 -1
- package/dist/express-index.js +0 -14
- package/dist/express-index.js.map +0 -1
- package/dist/fastify/adapter.d.ts +0 -31
- package/dist/fastify/adapter.d.ts.map +0 -1
- package/dist/fastify/adapter.js +0 -64
- package/dist/fastify/adapter.js.map +0 -1
- package/dist/fastify/agents.d.ts +0 -13
- package/dist/fastify/agents.d.ts.map +0 -1
- package/dist/fastify/agents.js +0 -7
- package/dist/fastify/agents.js.map +0 -1
- package/dist/fastify/api-security-middleware.d.ts +0 -64
- package/dist/fastify/api-security-middleware.d.ts.map +0 -1
- package/dist/fastify/api-security-middleware.js +0 -139
- package/dist/fastify/api-security-middleware.js.map +0 -1
- package/dist/fastify/compat.d.ts +0 -22
- package/dist/fastify/compat.d.ts.map +0 -1
- package/dist/fastify/compat.js +0 -16
- package/dist/fastify/compat.js.map +0 -1
- package/dist/fastify/daemon-status.d.ts +0 -22
- package/dist/fastify/daemon-status.d.ts.map +0 -1
- package/dist/fastify/daemon-status.js +0 -9
- package/dist/fastify/daemon-status.js.map +0 -1
- package/dist/fastify/host-tools.d.ts +0 -13
- package/dist/fastify/host-tools.d.ts.map +0 -1
- package/dist/fastify/host-tools.js +0 -8
- package/dist/fastify/host-tools.js.map +0 -1
- package/dist/fastify/index.d.ts +0 -36
- package/dist/fastify/index.d.ts.map +0 -1
- package/dist/fastify/index.js +0 -18
- package/dist/fastify/index.js.map +0 -1
- package/dist/fastify/local-daemon-request.d.ts +0 -43
- package/dist/fastify/local-daemon-request.d.ts.map +0 -1
- package/dist/fastify/local-daemon-request.js +0 -155
- package/dist/fastify/local-daemon-request.js.map +0 -1
- package/dist/fastify/origin.d.ts +0 -21
- package/dist/fastify/origin.d.ts.map +0 -1
- package/dist/fastify/origin.js +0 -14
- package/dist/fastify/origin.js.map +0 -1
- package/dist/fastify/request.d.ts +0 -20
- package/dist/fastify/request.d.ts.map +0 -1
- package/dist/fastify/request.js +0 -25
- package/dist/fastify/request.js.map +0 -1
- package/dist/fastify/response.d.ts +0 -20
- package/dist/fastify/response.d.ts.map +0 -1
- package/dist/fastify/response.js +0 -41
- package/dist/fastify/response.js.map +0 -1
- package/dist/fastify/route-registration-guard.d.ts +0 -70
- package/dist/fastify/route-registration-guard.d.ts.map +0 -1
- package/dist/fastify/route-registration-guard.js +0 -69
- package/dist/fastify/route-registration-guard.js.map +0 -1
- package/dist/fastify/run-stream.d.ts +0 -18
- package/dist/fastify/run-stream.d.ts.map +0 -1
- package/dist/fastify/run-stream.js +0 -10
- package/dist/fastify/run-stream.js.map +0 -1
- package/dist/fastify/runs.d.ts +0 -17
- package/dist/fastify/runs.d.ts.map +0 -1
- package/dist/fastify/runs.js +0 -33
- package/dist/fastify/runs.js.map +0 -1
- package/dist/run-stream.d.ts +0 -60
- package/dist/run-stream.d.ts.map +0 -1
- package/dist/run-stream.js +0 -108
- package/dist/run-stream.js.map +0 -1
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
import { apiTokenFromEnv, isApiTokenMiddlewareEnabled, } from '@jini/core';
|
|
2
|
-
import { isLoopbackPeerAddress } from './local-daemon-request.js';
|
|
3
|
-
import { allowedBrowserPorts, isAllowedBrowserOrigin } from '../origin-validation.js';
|
|
4
|
-
/** Health/readiness/version probes stay reachable without a bearer token so monitoring never needs one. Both the mount-relative and `/api`-prefixed forms are kept for parity with the Express version's set (only the `/api`-prefixed forms are ever reachable here, since both hooks below already require the path to start with `/api` before this set is even consulted). */
|
|
5
|
-
const OPEN_PROBE_PATHS = new Set([
|
|
6
|
-
'/health',
|
|
7
|
-
'/api/health',
|
|
8
|
-
'/ready',
|
|
9
|
-
'/api/ready',
|
|
10
|
-
'/version',
|
|
11
|
-
'/api/version',
|
|
12
|
-
]);
|
|
13
|
-
const BEARER_TOKEN_PATTERN = /^Bearer\s+(\S+)\s*$/i;
|
|
14
|
-
const DEFAULT_TOKEN_CONFIG = {
|
|
15
|
-
tokenEnvVar: 'JINI_API_TOKEN',
|
|
16
|
-
disableEnvVar: 'JINI_DISABLE_API_AUTH',
|
|
17
|
-
};
|
|
18
|
-
/**
|
|
19
|
-
* The request path with no query string — Fastify's `request.url` (unlike Express's
|
|
20
|
-
* `request.path`) always includes the query string, so this strips it to match Express's
|
|
21
|
-
* comparison semantics. `req.url` is typed as a required `string` on `FastifyRequest`
|
|
22
|
-
* (never `undefined`), and `String.prototype.split` on a string separator always returns an
|
|
23
|
-
* array with at least one element, so the `[0]` index is provably defined — the non-null
|
|
24
|
-
* assertion documents that guarantee instead of masking it behind an unreachable `?? ''` fallback
|
|
25
|
-
* that could never be exercised by a real request.
|
|
26
|
-
*/
|
|
27
|
-
function requestPath(req) {
|
|
28
|
-
return req.url.split('?')[0];
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Registers a bearer-token gate on every `/api/*` route, active only when
|
|
32
|
-
* {@link isApiTokenMiddlewareEnabled} says a token is configured and auth hasn't been disabled.
|
|
33
|
-
* When active: open-probe paths and loopback peers skip the check unconditionally; every other
|
|
34
|
-
* request must send `Authorization: Bearer <token>` matching the configured token exactly, or the
|
|
35
|
-
* request is rejected with 401 before reaching any route handler.
|
|
36
|
-
*
|
|
37
|
-
* @param app - The Fastify instance to register the gate on.
|
|
38
|
-
* @param deps - See {@link ApiBearerAuthMiddlewareDeps}. Both fields are optional; omitting `deps`
|
|
39
|
-
* entirely reads `JINI_API_TOKEN`/`JINI_DISABLE_API_AUTH` from real `process.env`.
|
|
40
|
-
* @returns Nothing. Registers zero hooks (a deliberate no-op, not a bug) when no token is configured.
|
|
41
|
-
* @complexity Setup is O(1). Each gated request is O(1) (one Set lookup, one regex match).
|
|
42
|
-
* @overallScore 100/100
|
|
43
|
-
*/
|
|
44
|
-
export function registerApiBearerAuthMiddleware(app, deps = {}) {
|
|
45
|
-
const tokenConfig = deps.tokenConfig ?? DEFAULT_TOKEN_CONFIG;
|
|
46
|
-
const env = deps.env ?? process.env;
|
|
47
|
-
if (!isApiTokenMiddlewareEnabled(tokenConfig, env))
|
|
48
|
-
return;
|
|
49
|
-
const apiToken = apiTokenFromEnv(tokenConfig, env);
|
|
50
|
-
app.addHook('onRequest', (req, reply, done) => {
|
|
51
|
-
const path = requestPath(req);
|
|
52
|
-
if (!path.startsWith('/api')) {
|
|
53
|
-
done();
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
if (OPEN_PROBE_PATHS.has(path)) {
|
|
57
|
-
done();
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
// Loopback short-circuit: the desktop UI / local CLI never carry a bearer, and a reverse
|
|
61
|
-
// proxy in front of a non-loopback bind must always forward the real bearer itself — so this
|
|
62
|
-
// is intentionally not fooled by a proxied `X-Forwarded-For` header.
|
|
63
|
-
if (isLoopbackPeerAddress(req.socket?.remoteAddress)) {
|
|
64
|
-
done();
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
const match = BEARER_TOKEN_PATTERN.exec(req.headers.authorization ?? '');
|
|
68
|
-
if (!match || match[1] !== apiToken) {
|
|
69
|
-
reply.code(401).send({
|
|
70
|
-
error: {
|
|
71
|
-
code: 'API_TOKEN_REQUIRED',
|
|
72
|
-
message: `Authorization: Bearer <${tokenConfig.tokenEnvVar}> required`,
|
|
73
|
-
},
|
|
74
|
-
});
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
done();
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Chrome may strip the port from the `Origin` header on same-origin GET requests. Used only as a
|
|
82
|
-
* narrow fallback for safe, idempotent GET requests once the exact-match check below has already
|
|
83
|
-
* failed — mutating routes always require an exact origin/host match.
|
|
84
|
-
*/
|
|
85
|
-
function isPortlessLoopbackOrigin(origin) {
|
|
86
|
-
return /^https?:\/\/(127\.0\.0\.1|localhost|\[::1\])$/.test(origin);
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Registers an unconditional cross-origin gate on every `/api/*` route: non-browser clients (no
|
|
90
|
-
* `Origin` header) and requests whose `Origin` resolves to a loopback, private-LAN, or explicitly
|
|
91
|
-
* allow-listed origin are let through; everything else is rejected with 403. `Origin: null`
|
|
92
|
-
* (typically a sandboxed iframe) is always rejected — see the Express version's doc for why the
|
|
93
|
-
* origin daemon's safe-GET exemption for that case was dropped.
|
|
94
|
-
*
|
|
95
|
-
* @param app - The Fastify instance to register the gate on.
|
|
96
|
-
* @param deps - See {@link ApiOriginGuardMiddlewareDeps}.
|
|
97
|
-
* @returns Nothing. Unlike the bearer-token gate, this always registers its hook — there is
|
|
98
|
-
* no "disabled" state.
|
|
99
|
-
* @complexity Setup is O(1). Each gated request is O(p) in the number of allowed ports (typically 1-2).
|
|
100
|
-
* @overallScore 100/100
|
|
101
|
-
*/
|
|
102
|
-
export function registerApiOriginGuardMiddleware(app, deps) {
|
|
103
|
-
const { host, getResolvedPort } = deps;
|
|
104
|
-
const extraAllowedOrigins = deps.extraAllowedOrigins ?? [];
|
|
105
|
-
const env = deps.env ?? process.env;
|
|
106
|
-
app.addHook('onRequest', (req, reply, done) => {
|
|
107
|
-
const path = requestPath(req);
|
|
108
|
-
if (!path.startsWith('/api')) {
|
|
109
|
-
done();
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
const origin = req.headers.origin;
|
|
113
|
-
if (origin == null || origin === '') {
|
|
114
|
-
done();
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
if (origin === 'null') {
|
|
118
|
-
reply.code(403).send({ error: 'Origin: null not allowed for this route' });
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
// Fail-closed: block every browser origin until the daemon's real listen port is known, so a
|
|
122
|
-
// request arriving in the brief window before `.listen()` resolves can never be compared
|
|
123
|
-
// against a wrong or default port.
|
|
124
|
-
const resolvedPort = getResolvedPort();
|
|
125
|
-
if (!resolvedPort) {
|
|
126
|
-
reply.code(403).send({ error: 'Server initializing' });
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
const ports = allowedBrowserPorts(resolvedPort, env);
|
|
130
|
-
if (!isAllowedBrowserOrigin(origin, req.headers.host, ports, host, [...extraAllowedOrigins])) {
|
|
131
|
-
if (req.method !== 'GET' || !isPortlessLoopbackOrigin(String(origin))) {
|
|
132
|
-
reply.code(403).send({ error: 'Cross-origin requests are not allowed' });
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
done();
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
//# sourceMappingURL=api-security-middleware.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"api-security-middleware.js","sourceRoot":"","sources":["../../src/fastify/api-security-middleware.ts"],"names":[],"mappings":"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"}
|
package/dist/fastify/compat.d.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Legacy-shaped error helpers: build/send an `ApiError` from separate `code`/`message`/`init`
|
|
3
|
-
* arguments, matching call sites that predate `JsonRouteSpec`/`mountJsonRoute` (e.g. a host
|
|
4
|
-
* application's own hand-mounted routes). No internal dependencies. `sendApiError` here is
|
|
5
|
-
* deliberately the same name as `response.ts`'s `ApiError`-object-taking `sendApiError` — they
|
|
6
|
-
* are different signatures for the same "send an error" job at two call-site generations; the
|
|
7
|
-
* package's `fastify/index.ts` barrel re-exports this one as `sendCompatApiError` to keep both
|
|
8
|
-
* addressable without a collision. Deliberately duplicated from `../express/compat.ts` — see
|
|
9
|
-
* `./response.ts`'s top-of-module doc for why this subtree does not import from `express/`.
|
|
10
|
-
*/
|
|
11
|
-
import type { ApiError, ApiErrorCode, ApiErrorResponse } from '@jini/protocol';
|
|
12
|
-
import type { FastifyReply } from 'fastify';
|
|
13
|
-
/** Builds an `ApiError` from separate `code`/`message`/`init` arguments (legacy call shape). */
|
|
14
|
-
export declare function createCompatApiError(code: ApiErrorCode, message: string, init?: Omit<ApiError, 'code' | 'message'>): ApiError;
|
|
15
|
-
/** Wraps `createCompatApiError`'s result in the standard `{ error }` envelope. */
|
|
16
|
-
export declare function createCompatApiErrorResponse(code: ApiErrorCode, message: string, init?: Omit<ApiError, 'code' | 'message'>): ApiErrorResponse;
|
|
17
|
-
/**
|
|
18
|
-
* Writes an `ApiError` response built from separate `code`/`message`/`init` arguments (legacy
|
|
19
|
-
* call shape) with the given status code. Exported from `fastify/index.ts` as `sendCompatApiError`.
|
|
20
|
-
*/
|
|
21
|
-
export declare function sendApiError(reply: FastifyReply, status: number, code: ApiErrorCode, message: string, init?: Omit<ApiError, 'code' | 'message'>): FastifyReply;
|
|
22
|
-
//# sourceMappingURL=compat.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"compat.d.ts","sourceRoot":"","sources":["../../src/fastify/compat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,gGAAgG;AAChG,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,YAAY,EAClB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAM,GAC5C,QAAQ,CAEV;AAED,kFAAkF;AAClF,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,YAAY,EAClB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAM,GAC5C,gBAAgB,CAElB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,YAAY,EAClB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAM,GAC5C,YAAY,CAEd"}
|
package/dist/fastify/compat.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/** Builds an `ApiError` from separate `code`/`message`/`init` arguments (legacy call shape). */
|
|
2
|
-
export function createCompatApiError(code, message, init = {}) {
|
|
3
|
-
return { code, message, ...init };
|
|
4
|
-
}
|
|
5
|
-
/** Wraps `createCompatApiError`'s result in the standard `{ error }` envelope. */
|
|
6
|
-
export function createCompatApiErrorResponse(code, message, init = {}) {
|
|
7
|
-
return { error: createCompatApiError(code, message, init) };
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Writes an `ApiError` response built from separate `code`/`message`/`init` arguments (legacy
|
|
11
|
-
* call shape) with the given status code. Exported from `fastify/index.ts` as `sendCompatApiError`.
|
|
12
|
-
*/
|
|
13
|
-
export function sendApiError(reply, status, code, message, init = {}) {
|
|
14
|
-
return reply.code(status).send(createCompatApiErrorResponse(code, message, init));
|
|
15
|
-
}
|
|
16
|
-
//# sourceMappingURL=compat.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"compat.js","sourceRoot":"","sources":["../../src/fastify/compat.ts"],"names":[],"mappings":"AAaA,gGAAgG;AAChG,MAAM,UAAU,oBAAoB,CAClC,IAAkB,EAClB,OAAe,EACf,OAA2C,EAAE;IAE7C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,CAAC;AACpC,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,4BAA4B,CAC1C,IAAkB,EAClB,OAAe,EACf,OAA2C,EAAE;IAE7C,OAAO,EAAE,KAAK,EAAE,oBAAoB,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;AAC9D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC1B,KAAmB,EACnB,MAAc,EACd,IAAkB,EAClB,OAAe,EACf,OAA2C,EAAE;IAE7C,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,4BAA4B,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;AACpF,CAAC"}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module fastify/daemon-status
|
|
3
|
-
*
|
|
4
|
-
* Mounts the generic daemon status + shutdown routes through the Fastify Adapter. The route
|
|
5
|
-
* SPECS themselves (`daemonStatusRoute`/`daemonShutdownRoute` — pure `defineJsonRoute`-shaped
|
|
6
|
-
* data plus framework-agnostic `parse`/`handle` functions, see `../daemon-status.ts`'s own doc
|
|
7
|
-
* for their full provenance) are intentionally NOT duplicated here: they never reference Express
|
|
8
|
-
* at runtime (`../daemon-status.ts` only imports `type { Express }` for its own
|
|
9
|
-
* `registerDaemonStatusRoutes`'s parameter — a type-only import that TypeScript's
|
|
10
|
-
* `verbatimModuleSyntax` erases from the compiled output entirely, so importing the specs from
|
|
11
|
-
* that module does not pull the `express` package into this subtree at runtime). This file's own
|
|
12
|
-
* job is only the Fastify-specific mounting wrapper, calling `./adapter.js`'s Fastify
|
|
13
|
-
* `mountJsonRoute` instead of the Express one.
|
|
14
|
-
*/
|
|
15
|
-
import type { FastifyInstance } from 'fastify';
|
|
16
|
-
import { daemonShutdownRoute, daemonStatusRoute, type DaemonShutdownResponse, type DaemonStatusDeps, type DaemonStatusResponse } from '../daemon-status.js';
|
|
17
|
-
import { type AdapterContext } from './adapter.js';
|
|
18
|
-
export { daemonShutdownRoute, daemonStatusRoute };
|
|
19
|
-
export type { DaemonShutdownResponse, DaemonStatusDeps, DaemonStatusResponse };
|
|
20
|
-
/** Mounts both daemon-status routes on `app`. A pack's `http(app, services)` calls this directly. */
|
|
21
|
-
export declare function registerDaemonStatusRoutes(app: FastifyInstance, deps: DaemonStatusDeps, adapter: AdapterContext): void;
|
|
22
|
-
//# sourceMappingURL=daemon-status.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"daemon-status.d.ts","sourceRoot":"","sources":["../../src/fastify/daemon-status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EAC1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnE,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,CAAC;AAClD,YAAY,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,CAAC;AAE/E,qGAAqG;AACrG,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI,CAGtH"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { daemonShutdownRoute, daemonStatusRoute, } from '../daemon-status.js';
|
|
2
|
-
import { mountJsonRoute } from './adapter.js';
|
|
3
|
-
export { daemonShutdownRoute, daemonStatusRoute };
|
|
4
|
-
/** Mounts both daemon-status routes on `app`. A pack's `http(app, services)` calls this directly. */
|
|
5
|
-
export function registerDaemonStatusRoutes(app, deps, adapter) {
|
|
6
|
-
mountJsonRoute(app, daemonStatusRoute, deps, adapter);
|
|
7
|
-
mountJsonRoute(app, daemonShutdownRoute, deps, adapter);
|
|
8
|
-
}
|
|
9
|
-
//# sourceMappingURL=daemon-status.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"daemon-status.js","sourceRoot":"","sources":["../../src/fastify/daemon-status.ts"],"names":[],"mappings":"AAeA,OAAO,EACL,mBAAmB,EACnB,iBAAiB,GAIlB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAuB,MAAM,cAAc,CAAC;AAEnE,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,CAAC;AAGlD,qGAAqG;AACrG,MAAM,UAAU,0BAA0B,CAAC,GAAoB,EAAE,IAAsB,EAAE,OAAuB;IAC9G,cAAc,CAAC,GAAG,EAAE,iBAAiB,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IACtD,cAAc,CAAC,GAAG,EAAE,mBAAmB,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AAC1D,CAAC"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module fastify/host-tools
|
|
3
|
-
*
|
|
4
|
-
* Fastify-mounting glue for `../host-tools.js`'s `hostEditorsRoute`/`openResourceInEditorRoute` —
|
|
5
|
-
* the exact same `JsonRouteSpec` objects the Express mounting in `../host-tools.js` uses, just
|
|
6
|
-
* mounted through this subtree's own `mountJsonRoute` instead.
|
|
7
|
-
*/
|
|
8
|
-
import type { FastifyInstance } from 'fastify';
|
|
9
|
-
import { type HostToolsOpenInDeps } from '../host-tools.js';
|
|
10
|
-
import { type AdapterContext } from './adapter.js';
|
|
11
|
-
/** Mounts `GET /api/editors` and `POST /api/resources/:resourceRef/open-in` on `app` — the Fastify-native equivalent of `../host-tools.js`'s `registerHostToolsRoutes`. */
|
|
12
|
-
export declare function registerHostToolsRoutes(app: FastifyInstance, adapter: AdapterContext, openInDeps?: HostToolsOpenInDeps): void;
|
|
13
|
-
//# sourceMappingURL=host-tools.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"host-tools.d.ts","sourceRoot":"","sources":["../../src/fastify/host-tools.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAA+C,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACzG,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnE,2KAA2K;AAC3K,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,eAAe,EACpB,OAAO,EAAE,cAAc,EACvB,UAAU,GAAE,mBAAwB,GACnC,IAAI,CAGN"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { hostEditorsRoute, openResourceInEditorRoute } from '../host-tools.js';
|
|
2
|
-
import { mountJsonRoute } from './adapter.js';
|
|
3
|
-
/** Mounts `GET /api/editors` and `POST /api/resources/:resourceRef/open-in` on `app` — the Fastify-native equivalent of `../host-tools.js`'s `registerHostToolsRoutes`. */
|
|
4
|
-
export function registerHostToolsRoutes(app, adapter, openInDeps = {}) {
|
|
5
|
-
mountJsonRoute(app, hostEditorsRoute, {}, adapter);
|
|
6
|
-
mountJsonRoute(app, openResourceInEditorRoute, openInDeps, adapter);
|
|
7
|
-
}
|
|
8
|
-
//# sourceMappingURL=host-tools.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"host-tools.js","sourceRoot":"","sources":["../../src/fastify/host-tools.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,gBAAgB,EAAE,yBAAyB,EAA4B,MAAM,kBAAkB,CAAC;AACzG,OAAO,EAAE,cAAc,EAAuB,MAAM,cAAc,CAAC;AAEnE,2KAA2K;AAC3K,MAAM,UAAU,uBAAuB,CACrC,GAAoB,EACpB,OAAuB,EACvB,aAAkC,EAAE;IAEpC,cAAc,CAAC,GAAG,EAAE,gBAAgB,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;IACnD,cAAc,CAAC,GAAG,EAAE,yBAAyB,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;AACtE,CAAC"}
|
package/dist/fastify/index.d.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module @jini/http/fastify
|
|
3
|
-
*
|
|
4
|
-
* The Fastify-native transport implementation: request parsing, response serialization, the
|
|
5
|
-
* Fastify-mounting Adapter (`defineJsonRoute`/`mountJsonRoute`, built on `fastify.route(...)`),
|
|
6
|
-
* the `/api` bearer-auth and origin-guard `onRequest` hooks, a loopback-only request guard, a
|
|
7
|
-
* route-registration inventory/guard built on Fastify's native `onRoute` application hook, legacy-
|
|
8
|
-
* shaped compat error helpers, the generic daemon-status/shutdown routes, and full Fastify
|
|
9
|
-
* mounting for the runs/agents/host-tools route packs (`registerRunRoutes` including its SSE
|
|
10
|
-
* event stream, `registerAgentRoutes`, `registerHostToolsRoutes`) — every one mounting the exact
|
|
11
|
-
* same `JsonRouteSpec` objects (and, for the SSE stream, the exact same
|
|
12
|
-
* `handleRunEventStreamRequest` core) the `express`/root-barrel Express mounting uses, so
|
|
13
|
-
* `transport: 'fastify'` serves identical routes to the Express default, not a reduced set. Every
|
|
14
|
-
* export here operates on Fastify's `FastifyRequest`/`FastifyReply`/`FastifyInstance` types.
|
|
15
|
-
* Import the shared, framework-agnostic pieces (`Result`, `JsonRouteSpec`, origin-validation
|
|
16
|
-
* predicates, `mountPackHttp`) from the package root instead of duplicating them here.
|
|
17
|
-
*/
|
|
18
|
-
export type { AdapterContext } from './adapter.js';
|
|
19
|
-
export { defineJsonRoute, mountJsonRoute } from './adapter.js';
|
|
20
|
-
export type { ApiBearerAuthMiddlewareDeps, ApiOriginGuardMiddlewareDeps } from './api-security-middleware.js';
|
|
21
|
-
export { registerApiBearerAuthMiddleware, registerApiOriginGuardMiddleware } from './api-security-middleware.js';
|
|
22
|
-
export { createCompatApiError, createCompatApiErrorResponse, sendApiError as sendCompatApiError, } from './compat.js';
|
|
23
|
-
export type { DaemonShutdownResponse, DaemonStatusDeps, DaemonStatusResponse, } from './daemon-status.js';
|
|
24
|
-
export { daemonShutdownRoute, daemonStatusRoute, registerDaemonStatusRoutes } from './daemon-status.js';
|
|
25
|
-
export { isLoopbackHostname, isLoopbackPeerAddress, localOriginFromHeader, normalizeLocalAuthority, requireLocalDaemonRequest, validateLocalDaemonRequest, } from './local-daemon-request.js';
|
|
26
|
-
export type { OriginContext } from './origin.js';
|
|
27
|
-
export { guardSameOrigin } from './origin.js';
|
|
28
|
-
export { rawInput, validationError } from './request.js';
|
|
29
|
-
export { registerRunStreamRoute } from './run-stream.js';
|
|
30
|
-
export { sendApiError, sendJson, statusForError } from './response.js';
|
|
31
|
-
export type { InstallRouteRegistrationGuardOptions, RouteRegistration } from './route-registration-guard.js';
|
|
32
|
-
export { getRouteRegistrationInventory, guardedRouteKey, installRouteRegistrationGuard, } from './route-registration-guard.js';
|
|
33
|
-
export { registerRunEventStream, registerRunRoutes } from './runs.js';
|
|
34
|
-
export { registerAgentRoutes } from './agents.js';
|
|
35
|
-
export { registerHostToolsRoutes } from './host-tools.js';
|
|
36
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fastify/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE/D,YAAY,EAAE,2BAA2B,EAAE,4BAA4B,EAAE,MAAM,8BAA8B,CAAC;AAC9G,OAAO,EAAE,+BAA+B,EAAE,gCAAgC,EAAE,MAAM,8BAA8B,CAAC;AAMjH,OAAO,EACL,oBAAoB,EACpB,4BAA4B,EAC5B,YAAY,IAAI,kBAAkB,GACnC,MAAM,aAAa,CAAC;AAErB,YAAY,EACV,sBAAsB,EACtB,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAExG,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,EACvB,yBAAyB,EACzB,0BAA0B,GAC3B,MAAM,2BAA2B,CAAC;AAEnC,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEvE,YAAY,EAAE,oCAAoC,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAC7G,OAAO,EACL,6BAA6B,EAC7B,eAAe,EACf,6BAA6B,GAC9B,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/fastify/index.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export { defineJsonRoute, mountJsonRoute } from './adapter.js';
|
|
2
|
-
export { registerApiBearerAuthMiddleware, registerApiOriginGuardMiddleware } from './api-security-middleware.js';
|
|
3
|
-
// Legacy-shaped compat error helpers (separate code/message/init call shape). `sendApiError`
|
|
4
|
-
// below (from `response.ts`) takes a single `ApiError` object; this compat `sendApiError` takes
|
|
5
|
-
// `(code, message, init)` — same job, different call-site generation, so it is re-exported here
|
|
6
|
-
// under a distinct name to avoid a duplicate export.
|
|
7
|
-
export { createCompatApiError, createCompatApiErrorResponse, sendApiError as sendCompatApiError, } from './compat.js';
|
|
8
|
-
export { daemonShutdownRoute, daemonStatusRoute, registerDaemonStatusRoutes } from './daemon-status.js';
|
|
9
|
-
export { isLoopbackHostname, isLoopbackPeerAddress, localOriginFromHeader, normalizeLocalAuthority, requireLocalDaemonRequest, validateLocalDaemonRequest, } from './local-daemon-request.js';
|
|
10
|
-
export { guardSameOrigin } from './origin.js';
|
|
11
|
-
export { rawInput, validationError } from './request.js';
|
|
12
|
-
export { registerRunStreamRoute } from './run-stream.js';
|
|
13
|
-
export { sendApiError, sendJson, statusForError } from './response.js';
|
|
14
|
-
export { getRouteRegistrationInventory, guardedRouteKey, installRouteRegistrationGuard, } from './route-registration-guard.js';
|
|
15
|
-
export { registerRunEventStream, registerRunRoutes } from './runs.js';
|
|
16
|
-
export { registerAgentRoutes } from './agents.js';
|
|
17
|
-
export { registerHostToolsRoutes } from './host-tools.js';
|
|
18
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/fastify/index.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG/D,OAAO,EAAE,+BAA+B,EAAE,gCAAgC,EAAE,MAAM,8BAA8B,CAAC;AAEjH,6FAA6F;AAC7F,gGAAgG;AAChG,gGAAgG;AAChG,qDAAqD;AACrD,OAAO,EACL,oBAAoB,EACpB,4BAA4B,EAC5B,YAAY,IAAI,kBAAkB,GACnC,MAAM,aAAa,CAAC;AAOrB,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAExG,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,EACvB,yBAAyB,EACzB,0BAA0B,GAC3B,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGvE,OAAO,EACL,6BAA6B,EAC7B,eAAe,EACf,6BAA6B,GAC9B,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import type { FastifyReply, FastifyRequest } from 'fastify';
|
|
2
|
-
interface LocalAuthority {
|
|
3
|
-
hostname: string;
|
|
4
|
-
port: string;
|
|
5
|
-
}
|
|
6
|
-
interface LocalDaemonValidation {
|
|
7
|
-
ok: true;
|
|
8
|
-
origin: string | null;
|
|
9
|
-
}
|
|
10
|
-
interface LocalDaemonValidationError {
|
|
11
|
-
ok: false;
|
|
12
|
-
message: string;
|
|
13
|
-
details: Record<string, string>;
|
|
14
|
-
}
|
|
15
|
-
/** Parses a `Host`-header-shaped authority string, rejecting anything with a path/userinfo/query. */
|
|
16
|
-
export declare function normalizeLocalAuthority(value: unknown): LocalAuthority | null;
|
|
17
|
-
/** True when `hostname` is `localhost`, an IPv6 loopback literal, or a `127.0.0.0/8` IPv4 literal. */
|
|
18
|
-
export declare function isLoopbackHostname(hostname: unknown): boolean;
|
|
19
|
-
/** True when `address` (typically `req.socket.remoteAddress`) is a loopback peer, unwrapping an IPv4-mapped IPv6 prefix first. */
|
|
20
|
-
export declare function isLoopbackPeerAddress(address: unknown): boolean;
|
|
21
|
-
/** Parses an `Origin` header value into its origin string, requiring a bare `scheme://loopback-host[:port]` with no path/query/userinfo. */
|
|
22
|
-
export declare function localOriginFromHeader(value: unknown): string | null;
|
|
23
|
-
/**
|
|
24
|
-
* Validates that `req` is a loopback request: the TCP peer address, the `Host` header, and (when
|
|
25
|
-
* present) the `Origin` header must all resolve to a loopback host.
|
|
26
|
-
*
|
|
27
|
-
* @param req - The incoming request.
|
|
28
|
-
* @returns `{ ok: true, origin }` on success (`origin` is the validated `Origin` header value, or
|
|
29
|
-
* `null` when the request carried none); otherwise `{ ok: false, message, details }` naming which
|
|
30
|
-
* check failed.
|
|
31
|
-
*/
|
|
32
|
-
export declare function validateLocalDaemonRequest(req: FastifyRequest): LocalDaemonValidation | LocalDaemonValidationError;
|
|
33
|
-
/**
|
|
34
|
-
* Fastify `onRequest` hook that rejects any non-loopback request with a 403, and otherwise sets
|
|
35
|
-
* permissive same-machine CORS headers before calling `done()`.
|
|
36
|
-
*
|
|
37
|
-
* @param req - The incoming request.
|
|
38
|
-
* @param reply - The reply to reject on, or set CORS headers on before continuing.
|
|
39
|
-
* @param done - Called (with no error) when the request validates as loopback, continuing the hook chain.
|
|
40
|
-
*/
|
|
41
|
-
export declare function requireLocalDaemonRequest(req: FastifyRequest, reply: FastifyReply, done: (err?: Error) => void): void;
|
|
42
|
-
export {};
|
|
43
|
-
//# sourceMappingURL=local-daemon-request.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"local-daemon-request.d.ts","sourceRoot":"","sources":["../../src/fastify/local-daemon-request.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAG5D,UAAU,cAAc;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,qBAAqB;IAC7B,EAAE,EAAE,IAAI,CAAC;IACT,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,UAAU,0BAA0B;IAClC,EAAE,EAAE,KAAK,CAAC;IACV,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,qGAAqG;AACrG,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,GAAG,IAAI,CAkB7E;AAED,sGAAsG;AACtG,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAS7D;AAED,kIAAkI;AAClI,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAQ/D;AAED,4IAA4I;AAC5I,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAcnE;AAOD;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,cAAc,GAAG,qBAAqB,GAAG,0BAA0B,CA4BlH;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAerH"}
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module fastify/local-daemon-request
|
|
3
|
-
*
|
|
4
|
-
* A loopback-only request guard: validates that a request's peer address, `Host` header, and (if
|
|
5
|
-
* present) `Origin` header are all loopback, and sets the CORS headers a same-machine caller
|
|
6
|
-
* needs. Distinct from `./origin.js`'s `guardSameOrigin` (which checks a browser tab's origin
|
|
7
|
-
* against a configured allow-list) — this guard instead restricts an endpoint to same-machine
|
|
8
|
-
* callers only (e.g. a local companion process), regardless of origin allow-list configuration.
|
|
9
|
-
*
|
|
10
|
-
* The header-parsing/classification predicates (`normalizeLocalAuthority`, `isLoopbackHostname`,
|
|
11
|
-
* `isLoopbackPeerAddress`, `localOriginFromHeader`) are pure and operate on plain string/unknown
|
|
12
|
-
* values, not a framework request object — deliberately duplicated from
|
|
13
|
-
* `../express/local-daemon-request.ts` rather than shared; see `./response.ts`'s top-of-module
|
|
14
|
-
* doc for why this subtree does not import from `express/`. Only `validateLocalDaemonRequest`
|
|
15
|
-
* and `requireLocalDaemonRequest` below are Fastify-specific (they read `FastifyRequest`/
|
|
16
|
-
* `FastifyReply` instead of Express's `Request`/`Response`/`req.get(...)`).
|
|
17
|
-
*/
|
|
18
|
-
import net from 'node:net';
|
|
19
|
-
import { sendApiError } from './compat.js';
|
|
20
|
-
/** Parses a `Host`-header-shaped authority string, rejecting anything with a path/userinfo/query. */
|
|
21
|
-
export function normalizeLocalAuthority(value) {
|
|
22
|
-
if (typeof value !== 'string')
|
|
23
|
-
return null;
|
|
24
|
-
const trimmed = value.trim();
|
|
25
|
-
if (!trimmed || /[\s/@]/.test(trimmed) || trimmed.includes(','))
|
|
26
|
-
return null;
|
|
27
|
-
try {
|
|
28
|
-
// The guard above already rejects any `/`, `@`, or whitespace in `trimmed`, and the WHATWG
|
|
29
|
-
// URL parser requires a non-empty host for an `http:` URL — so `parsed.hostname` is always
|
|
30
|
-
// non-empty and `parsed.pathname` is always `/` for every `trimmed` value that reaches this
|
|
31
|
-
// line without throwing. `hostname` below can still end up empty after stripping a trailing
|
|
32
|
-
// dot (e.g. `trimmed === '.'` parses to `parsed.hostname === '.'`), so that check stays.
|
|
33
|
-
const parsed = new URL(`http://${trimmed}`);
|
|
34
|
-
const hostname = parsed.hostname.toLowerCase().replace(/\.$/, '');
|
|
35
|
-
if (!hostname)
|
|
36
|
-
return null;
|
|
37
|
-
return { hostname, port: parsed.port };
|
|
38
|
-
}
|
|
39
|
-
catch {
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
/** True when `hostname` is `localhost`, an IPv6 loopback literal, or a `127.0.0.0/8` IPv4 literal. */
|
|
44
|
-
export function isLoopbackHostname(hostname) {
|
|
45
|
-
const normalized = String(hostname || '')
|
|
46
|
-
.toLowerCase()
|
|
47
|
-
.replace(/^\[|\]$/g, '')
|
|
48
|
-
.replace(/\.$/, '');
|
|
49
|
-
if (normalized === 'localhost')
|
|
50
|
-
return true;
|
|
51
|
-
if (normalized === '::1' || normalized === '0:0:0:0:0:0:0:1')
|
|
52
|
-
return true;
|
|
53
|
-
if (net.isIP(normalized) === 4)
|
|
54
|
-
return normalized === '127.0.0.1' || normalized.startsWith('127.');
|
|
55
|
-
return false;
|
|
56
|
-
}
|
|
57
|
-
/** True when `address` (typically `req.socket.remoteAddress`) is a loopback peer, unwrapping an IPv4-mapped IPv6 prefix first. */
|
|
58
|
-
export function isLoopbackPeerAddress(address) {
|
|
59
|
-
if (typeof address !== 'string')
|
|
60
|
-
return false;
|
|
61
|
-
const normalized = address.trim().toLowerCase().replace(/^\[|\]$/g, '');
|
|
62
|
-
if (!normalized)
|
|
63
|
-
return false;
|
|
64
|
-
if (normalized.startsWith('::ffff:'))
|
|
65
|
-
return isLoopbackPeerAddress(normalized.slice('::ffff:'.length));
|
|
66
|
-
if (normalized === '::1' || normalized === '0:0:0:0:0:0:0:1')
|
|
67
|
-
return true;
|
|
68
|
-
if (net.isIP(normalized) === 4)
|
|
69
|
-
return normalized === '127.0.0.1' || normalized.startsWith('127.');
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
|
-
/** Parses an `Origin` header value into its origin string, requiring a bare `scheme://loopback-host[:port]` with no path/query/userinfo. */
|
|
73
|
-
export function localOriginFromHeader(value) {
|
|
74
|
-
if (typeof value !== 'string')
|
|
75
|
-
return null;
|
|
76
|
-
const trimmed = value.trim();
|
|
77
|
-
if (!trimmed || trimmed === 'null' || trimmed.includes(','))
|
|
78
|
-
return null;
|
|
79
|
-
try {
|
|
80
|
-
const parsed = new URL(trimmed);
|
|
81
|
-
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:')
|
|
82
|
-
return null;
|
|
83
|
-
if (parsed.pathname !== '/' || parsed.search || parsed.hash || parsed.username || parsed.password)
|
|
84
|
-
return null;
|
|
85
|
-
if (!isLoopbackHostname(parsed.hostname))
|
|
86
|
-
return null;
|
|
87
|
-
return parsed.origin;
|
|
88
|
-
}
|
|
89
|
-
catch {
|
|
90
|
-
return null;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
/** Reads a single-value request header, collapsing Node's `string | string[] | undefined` shape (Fastify headers are Node's raw `IncomingHttpHeaders`) to the first value. */
|
|
94
|
-
function headerValue(value) {
|
|
95
|
-
return Array.isArray(value) ? value[0] : value;
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Validates that `req` is a loopback request: the TCP peer address, the `Host` header, and (when
|
|
99
|
-
* present) the `Origin` header must all resolve to a loopback host.
|
|
100
|
-
*
|
|
101
|
-
* @param req - The incoming request.
|
|
102
|
-
* @returns `{ ok: true, origin }` on success (`origin` is the validated `Origin` header value, or
|
|
103
|
-
* `null` when the request carried none); otherwise `{ ok: false, message, details }` naming which
|
|
104
|
-
* check failed.
|
|
105
|
-
*/
|
|
106
|
-
export function validateLocalDaemonRequest(req) {
|
|
107
|
-
if (!isLoopbackPeerAddress(req.socket?.remoteAddress)) {
|
|
108
|
-
return {
|
|
109
|
-
ok: false,
|
|
110
|
-
message: 'request peer must be a loopback address',
|
|
111
|
-
details: { peer: 'remoteAddress' },
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
const host = normalizeLocalAuthority(headerValue(req.headers.host));
|
|
115
|
-
if (!host || !isLoopbackHostname(host.hostname)) {
|
|
116
|
-
return {
|
|
117
|
-
ok: false,
|
|
118
|
-
message: 'request host must be a loopback daemon address',
|
|
119
|
-
details: { header: 'host' },
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
const originHeader = headerValue(req.headers.origin);
|
|
123
|
-
if (originHeader !== undefined && !localOriginFromHeader(originHeader)) {
|
|
124
|
-
return {
|
|
125
|
-
ok: false,
|
|
126
|
-
message: 'request origin must be a loopback daemon origin',
|
|
127
|
-
details: { header: 'origin' },
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
return { ok: true, origin: localOriginFromHeader(originHeader) };
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Fastify `onRequest` hook that rejects any non-loopback request with a 403, and otherwise sets
|
|
134
|
-
* permissive same-machine CORS headers before calling `done()`.
|
|
135
|
-
*
|
|
136
|
-
* @param req - The incoming request.
|
|
137
|
-
* @param reply - The reply to reject on, or set CORS headers on before continuing.
|
|
138
|
-
* @param done - Called (with no error) when the request validates as loopback, continuing the hook chain.
|
|
139
|
-
*/
|
|
140
|
-
export function requireLocalDaemonRequest(req, reply, done) {
|
|
141
|
-
const validation = validateLocalDaemonRequest(req);
|
|
142
|
-
if (!validation.ok) {
|
|
143
|
-
sendApiError(reply, 403, 'FORBIDDEN', validation.message, { details: validation.details });
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
reply.header('Vary', 'Origin');
|
|
147
|
-
if (validation.origin) {
|
|
148
|
-
reply.header('Access-Control-Allow-Origin', validation.origin);
|
|
149
|
-
}
|
|
150
|
-
reply.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
|
|
151
|
-
reply.header('Access-Control-Allow-Headers', 'Content-Type');
|
|
152
|
-
reply.header('Access-Control-Max-Age', '600');
|
|
153
|
-
done();
|
|
154
|
-
}
|
|
155
|
-
//# sourceMappingURL=local-daemon-request.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"local-daemon-request.js","sourceRoot":"","sources":["../../src/fastify/local-daemon-request.ts"],"names":[],"mappings":"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"}
|
package/dist/fastify/origin.d.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Same-origin security guard: wraps the shared, framework-agnostic `isLocalSameOrigin` in the
|
|
3
|
-
* module's `Result` pipeline so the Fastify Adapter can treat an origin failure the same as a
|
|
4
|
-
* parse/handle failure. `isLocalSameOrigin` is imported from the shared root (`../origin-validation.js`)
|
|
5
|
-
* rather than duplicated, since it operates on plain header values (not a framework `Request`) and
|
|
6
|
-
* is already framework-agnostic — see `../pack-http.ts`'s doc for the same reasoning applied there.
|
|
7
|
-
*/
|
|
8
|
-
import type { FastifyRequest } from 'fastify';
|
|
9
|
-
import { type Result } from '../types.js';
|
|
10
|
-
/** The subset of server startup state `guardSameOrigin` needs: the resolved local port. */
|
|
11
|
-
export interface OriginContext {
|
|
12
|
-
resolvedPortRef: {
|
|
13
|
-
current: number;
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Wraps `isLocalSameOrigin` so the Fastify Adapter can fold the origin decision into the same
|
|
18
|
-
* error-handling pipeline as parse/handle failures.
|
|
19
|
-
*/
|
|
20
|
-
export declare function guardSameOrigin(req: FastifyRequest, origin: OriginContext): Result<void>;
|
|
21
|
-
//# sourceMappingURL=origin.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"origin.d.ts","sourceRoot":"","sources":["../../src/fastify/origin.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAG9C,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAEnD,2FAA2F;AAC3F,MAAM,WAAW,aAAa;IAC5B,eAAe,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CACtC;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,CAKxF"}
|
package/dist/fastify/origin.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { createApiError } from '@jini/protocol';
|
|
2
|
-
import { isLocalSameOrigin } from '../origin-validation.js';
|
|
3
|
-
import { err, ok } from '../types.js';
|
|
4
|
-
/**
|
|
5
|
-
* Wraps `isLocalSameOrigin` so the Fastify Adapter can fold the origin decision into the same
|
|
6
|
-
* error-handling pipeline as parse/handle failures.
|
|
7
|
-
*/
|
|
8
|
-
export function guardSameOrigin(req, origin) {
|
|
9
|
-
if (isLocalSameOrigin(req, origin.resolvedPortRef.current)) {
|
|
10
|
-
return ok(undefined);
|
|
11
|
-
}
|
|
12
|
-
return err(createApiError('FORBIDDEN', 'cross-origin request rejected'));
|
|
13
|
-
}
|
|
14
|
-
//# sourceMappingURL=origin.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"origin.js","sourceRoot":"","sources":["../../src/fastify/origin.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,GAAG,EAAE,EAAE,EAAe,MAAM,aAAa,CAAC;AAOnD;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,GAAmB,EAAE,MAAqB;IACxE,IAAI,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3D,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,GAAG,CAAC,cAAc,CAAC,WAAW,EAAE,+BAA+B,CAAC,CAAC,CAAC;AAC3E,CAAC"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Request-side normalization: turns a raw Fastify `FastifyRequest` into the framework-independent
|
|
3
|
-
* `RouteInputContext` the rest of the module operates on, and builds a standard `BAD_REQUEST`
|
|
4
|
-
* `ApiError` for validation failures. Deliberately duplicated from `../express/request.ts` — see
|
|
5
|
-
* `./response.ts`'s top-of-module doc for why this subtree does not import from `express/`.
|
|
6
|
-
*/
|
|
7
|
-
import type { FastifyRequest } from 'fastify';
|
|
8
|
-
import { type ApiError, type ApiValidationIssue } from '@jini/protocol';
|
|
9
|
-
import type { RouteInputContext } from '../types.js';
|
|
10
|
-
/**
|
|
11
|
-
* Extracts `body`/`query`/`params` from a Fastify `FastifyRequest` into a `RouteInputContext`, so
|
|
12
|
-
* a route's `parse` function can be unit-tested without constructing a real `FastifyRequest`.
|
|
13
|
-
*/
|
|
14
|
-
export declare function rawInput(request: FastifyRequest): RouteInputContext;
|
|
15
|
-
/**
|
|
16
|
-
* Builds a `BAD_REQUEST` `ApiError` for a failed parse. When `issues` is non-empty, attaches
|
|
17
|
-
* them as structured validation details so clients can render per-field errors.
|
|
18
|
-
*/
|
|
19
|
-
export declare function validationError(message: string, issues?: Pick<ApiValidationIssue, 'path' | 'message'>[]): ApiError;
|
|
20
|
-
//# sourceMappingURL=request.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/fastify/request.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,EAAkB,KAAK,QAAQ,EAAE,KAAK,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACxF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,cAAc,GAAG,iBAAiB,CAMnE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,IAAI,CAAC,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC,EAAO,GAC1D,QAAQ,CAOV"}
|