@grackle-ai/auth 0.133.1 → 0.135.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/auth-middleware.d.ts +14 -1
- package/dist/auth-middleware.d.ts.map +1 -1
- package/dist/auth-middleware.js +38 -9
- package/dist/auth-middleware.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/public-origin.d.ts +17 -0
- package/dist/public-origin.d.ts.map +1 -0
- package/dist/public-origin.js +37 -0
- package/dist/public-origin.js.map +1 -0
- package/dist/security-headers.d.ts +19 -1
- package/dist/security-headers.d.ts.map +1 -1
- package/dist/security-headers.js +26 -3
- package/dist/security-headers.js.map +1 -1
- package/dist/session.d.ts +4 -3
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +4 -3
- package/dist/session.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
import type http from "node:http";
|
|
2
2
|
import type { AuthContext } from "./auth-context.js";
|
|
3
|
+
/** Options for {@link authenticateMcpRequest}. */
|
|
4
|
+
export interface AuthenticateMcpRequestOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Canonical resource (audience) this server is reachable as, e.g.
|
|
7
|
+
* `https://mcp.example.com`. When set, an OAuth token's `aud` is validated
|
|
8
|
+
* against this configured origin instead of the loopback-derived default.
|
|
9
|
+
* Set it from a static, operator-provided origin (`GRACKLE_MCP_ORIGIN`) — never
|
|
10
|
+
* from the request `Host` header, which a client could spoof. When unset, the
|
|
11
|
+
* audience is validated against the server-controlled `http://127.0.0.1:<localPort>`.
|
|
12
|
+
*/
|
|
13
|
+
expectedResource?: string;
|
|
14
|
+
}
|
|
3
15
|
/**
|
|
4
16
|
* Authenticate an incoming MCP HTTP request.
|
|
5
17
|
*
|
|
@@ -10,7 +22,8 @@ import type { AuthContext } from "./auth-context.js";
|
|
|
10
22
|
*
|
|
11
23
|
* @param req - The incoming HTTP request.
|
|
12
24
|
* @param apiKey - The server's API key (used for both direct comparison and as the HMAC signing secret).
|
|
25
|
+
* @param options - Optional audience-validation overrides (see {@link AuthenticateMcpRequestOptions}).
|
|
13
26
|
* @returns An {@link AuthContext} if authentication succeeds, or `undefined` for a 401.
|
|
14
27
|
*/
|
|
15
|
-
export declare function authenticateMcpRequest(req: http.IncomingMessage, apiKey: string): AuthContext | undefined;
|
|
28
|
+
export declare function authenticateMcpRequest(req: http.IncomingMessage, apiKey: string, options?: AuthenticateMcpRequestOptions): AuthContext | undefined;
|
|
16
29
|
//# sourceMappingURL=auth-middleware.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-middleware.d.ts","sourceRoot":"","sources":["../src/auth-middleware.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"auth-middleware.d.ts","sourceRoot":"","sources":["../src/auth-middleware.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AA8CrD,kDAAkD;AAClD,MAAM,WAAW,6BAA6B;IAC5C;;;;;;;OAOG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,IAAI,CAAC,eAAe,EACzB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,6BAA6B,GACtC,WAAW,GAAG,SAAS,CAoEzB"}
|
package/dist/auth-middleware.js
CHANGED
|
@@ -4,8 +4,27 @@ import { isRevokedTask, verifyScopedToken } from "./scoped-token.js";
|
|
|
4
4
|
/** Expected length of API key tokens (64 hex characters). */
|
|
5
5
|
const API_KEY_LENGTH = 64;
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* Strip trailing `/` characters from a string with a linear scan.
|
|
8
|
+
*
|
|
9
|
+
* Avoids a `/\/+$/` regex, which CodeQL flags as a polynomial-ReDoS risk on
|
|
10
|
+
* uncontrolled (library) input.
|
|
11
|
+
*/
|
|
12
|
+
function stripTrailingSlashes(value) {
|
|
13
|
+
let end = value.length;
|
|
14
|
+
while (end > 0 && value.charCodeAt(end - 1) === 47 /* "/" */) {
|
|
15
|
+
end--;
|
|
16
|
+
}
|
|
17
|
+
return value.slice(0, end);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Normalize an audience URL for comparison: treat `localhost` and `127.0.0.1`
|
|
21
|
+
* as equal, and ignore a single trailing slash so `http://h/` matches `http://h`.
|
|
22
|
+
*
|
|
23
|
+
* Crucially, any non-root path, query, or fragment is **preserved** — dropping
|
|
24
|
+
* it (e.g. via `URL.origin`) would let a token minted for
|
|
25
|
+
* `https://mcp.example.com/some/path` be accepted when the expected resource is
|
|
26
|
+
* just `https://mcp.example.com`, weakening audience isolation. Falls back to a
|
|
27
|
+
* trailing-slash-trimmed copy of the raw input when the value does not parse.
|
|
9
28
|
*/
|
|
10
29
|
function normalizeLoopback(url) {
|
|
11
30
|
try {
|
|
@@ -13,10 +32,13 @@ function normalizeLoopback(url) {
|
|
|
13
32
|
if (parsed.hostname === "localhost") {
|
|
14
33
|
parsed.hostname = "127.0.0.1";
|
|
15
34
|
}
|
|
16
|
-
|
|
35
|
+
// Collapse a bare "/" path to empty so origin-only audiences match with or
|
|
36
|
+
// without a trailing slash; otherwise keep the path (minus a trailing slash).
|
|
37
|
+
const path = parsed.pathname === "/" ? "" : stripTrailingSlashes(parsed.pathname);
|
|
38
|
+
return `${parsed.origin}${path}${parsed.search}${parsed.hash}`;
|
|
17
39
|
}
|
|
18
40
|
catch {
|
|
19
|
-
return url;
|
|
41
|
+
return stripTrailingSlashes(url);
|
|
20
42
|
}
|
|
21
43
|
}
|
|
22
44
|
/**
|
|
@@ -29,9 +51,10 @@ function normalizeLoopback(url) {
|
|
|
29
51
|
*
|
|
30
52
|
* @param req - The incoming HTTP request.
|
|
31
53
|
* @param apiKey - The server's API key (used for both direct comparison and as the HMAC signing secret).
|
|
54
|
+
* @param options - Optional audience-validation overrides (see {@link AuthenticateMcpRequestOptions}).
|
|
32
55
|
* @returns An {@link AuthContext} if authentication succeeds, or `undefined` for a 401.
|
|
33
56
|
*/
|
|
34
|
-
export function authenticateMcpRequest(req, apiKey) {
|
|
57
|
+
export function authenticateMcpRequest(req, apiKey, options) {
|
|
35
58
|
const authHeader = req.headers.authorization || "";
|
|
36
59
|
const match = /^Bearer\s+(\S+)$/i.exec(authHeader);
|
|
37
60
|
if (!match) {
|
|
@@ -58,14 +81,20 @@ export function authenticateMcpRequest(req, apiKey) {
|
|
|
58
81
|
if (oauthClaims) {
|
|
59
82
|
// Validate audience if present — when non-empty, must match this server's resource URL.
|
|
60
83
|
// Empty aud is accepted because the client may omit the resource indicator (RFC 8707).
|
|
61
|
-
//
|
|
62
|
-
//
|
|
84
|
+
// When an explicit resource is configured (GRACKLE_MCP_ORIGIN, e.g. behind a
|
|
85
|
+
// TLS reverse proxy) validate against that static, operator-provided origin.
|
|
86
|
+
// Otherwise fall back to the socket's local port (server-controlled) rather than
|
|
87
|
+
// the Host header (client-controlled) to prevent token replay via Host spoofing.
|
|
63
88
|
// Normalize trailing slashes and treat "localhost" as equivalent to "127.0.0.1" since
|
|
64
89
|
// MCP clients may connect via either hostname.
|
|
65
90
|
if (oauthClaims.aud) {
|
|
66
91
|
const localPort = req.socket.localPort;
|
|
67
|
-
const expectedAudience =
|
|
68
|
-
|
|
92
|
+
const expectedAudience = options?.expectedResource
|
|
93
|
+
? normalizeLoopback(options.expectedResource)
|
|
94
|
+
: localPort
|
|
95
|
+
? `http://127.0.0.1:${localPort}`
|
|
96
|
+
: undefined;
|
|
97
|
+
const normalizedAud = normalizeLoopback(oauthClaims.aud);
|
|
69
98
|
if (!expectedAudience || normalizedAud !== expectedAudience) {
|
|
70
99
|
return undefined;
|
|
71
100
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-middleware.js","sourceRoot":"","sources":["../src/auth-middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAErE,6DAA6D;AAC7D,MAAM,cAAc,GAAW,EAAE,CAAC;AAElC
|
|
1
|
+
{"version":3,"file":"auth-middleware.js","sourceRoot":"","sources":["../src/auth-middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAErE,6DAA6D;AAC7D,MAAM,cAAc,GAAW,EAAE,CAAC;AAElC;;;;;GAKG;AACH,SAAS,oBAAoB,CAAC,KAAa;IACzC,IAAI,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC;IACvB,OAAO,GAAG,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,SAAS,EAAE,CAAC;QAC7D,GAAG,EAAE,CAAC;IACR,CAAC;IACD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAC7B,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,iBAAiB,CAAC,GAAW;IACpC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,MAAM,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;YACpC,MAAM,CAAC,QAAQ,GAAG,WAAW,CAAC;QAChC,CAAC;QACD,2EAA2E;QAC3E,8EAA8E;QAC9E,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAClF,OAAO,GAAG,MAAM,CAAC,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,oBAAoB,CAAC,GAAG,CAAC,CAAC;IACnC,CAAC;AACH,CAAC;AAeD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,sBAAsB,CACpC,GAAyB,EACzB,MAAc,EACd,OAAuC;IAEvC,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC;IACnD,MAAM,KAAK,GAAG,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACnD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACvB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,0DAA0D;IAC1D,IAAI,KAAK,CAAC,MAAM,KAAK,cAAc,IAAI,MAAM,CAAC,MAAM,KAAK,cAAc,EAAE,CAAC;QACxE,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7B,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9B,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YACnD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAC7B,CAAC;QACD,2EAA2E;QAC3E,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,kEAAkE;IAClE,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,4DAA4D;QAC5D,MAAM,WAAW,GAAG,sBAAsB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC1D,IAAI,WAAW,EAAE,CAAC;YAChB,wFAAwF;YACxF,uFAAuF;YACvF,6EAA6E;YAC7E,6EAA6E;YAC7E,iFAAiF;YACjF,iFAAiF;YACjF,sFAAsF;YACtF,+CAA+C;YAC/C,IAAI,WAAW,CAAC,GAAG,EAAE,CAAC;gBACpB,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC;gBACvC,MAAM,gBAAgB,GAAG,OAAO,EAAE,gBAAgB;oBAChD,CAAC,CAAC,iBAAiB,CAAC,OAAO,CAAC,gBAAgB,CAAC;oBAC7C,CAAC,CAAC,SAAS;wBACT,CAAC,CAAC,oBAAoB,SAAS,EAAE;wBACjC,CAAC,CAAC,SAAS,CAAC;gBAChB,MAAM,aAAa,GAAG,iBAAiB,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;gBACzD,IAAI,CAAC,gBAAgB,IAAI,aAAa,KAAK,gBAAgB,EAAE,CAAC;oBAC5D,OAAO,SAAS,CAAC;gBACnB,CAAC;YACH,CAAC;YACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,GAAG,EAAE,CAAC;QACtD,CAAC;QAED,+BAA+B;QAC/B,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAChD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,IAAI,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9B,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,MAAM,CAAC,GAAG;YAClB,WAAW,EAAE,MAAM,CAAC,GAAG,IAAI,SAAS;YACpC,SAAS,EAAE,MAAM,CAAC,GAAG;YACrB,aAAa,EAAE,MAAM,CAAC,GAAG;SAC1B,CAAC;IACJ,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export { createScopedToken, verifyScopedToken, revokeTask, isRevokedTask, pruneR
|
|
|
12
12
|
export type { ChannelTokenClaims } from "./channel-token.js";
|
|
13
13
|
export { createChannelToken, verifyChannelToken } from "./channel-token.js";
|
|
14
14
|
export type { AuthContext } from "./auth-context.js";
|
|
15
|
-
export { authenticateMcpRequest } from "./auth-middleware.js";
|
|
16
|
-
export { WEB_CONTENT_SECURITY_POLICY, setSecurityHeaders } from "./security-headers.js";
|
|
15
|
+
export { authenticateMcpRequest, type AuthenticateMcpRequestOptions } from "./auth-middleware.js";
|
|
16
|
+
export { WEB_CONTENT_SECURITY_POLICY, setSecurityHeaders, type SecurityHeaderOptions, } from "./security-headers.js";
|
|
17
|
+
export { parsePublicOrigin } from "./public-origin.js";
|
|
17
18
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGpE,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAGhE,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AAGtB,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACnF,OAAO,EACL,cAAc,EACd,SAAS,EACT,uBAAuB,EACvB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAGpB,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EACL,yBAAyB,EACzB,0BAA0B,EAC1B,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,kBAAkB,CAAC;AAG1B,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAG3B,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAG5E,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGpE,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAGhE,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AAGtB,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACnF,OAAO,EACL,cAAc,EACd,SAAS,EACT,uBAAuB,EACvB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAGpB,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EACL,yBAAyB,EACzB,0BAA0B,EAC1B,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,kBAAkB,CAAC;AAG1B,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAG3B,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAG5E,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,OAAO,EAAE,sBAAsB,EAAE,KAAK,6BAA6B,EAAE,MAAM,sBAAsB,CAAC;AAGlG,OAAO,EACL,2BAA2B,EAC3B,kBAAkB,EAClB,KAAK,qBAAqB,GAC3B,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -12,5 +12,7 @@ export { createChannelToken, verifyChannelToken } from "./channel-token.js";
|
|
|
12
12
|
// ─── Auth Middleware ────────────────────────────────────────
|
|
13
13
|
export { authenticateMcpRequest } from "./auth-middleware.js";
|
|
14
14
|
// ─── Security Headers ──────────────────────────────────────
|
|
15
|
-
export { WEB_CONTENT_SECURITY_POLICY, setSecurityHeaders } from "./security-headers.js";
|
|
15
|
+
export { WEB_CONTENT_SECURITY_POLICY, setSecurityHeaders, } from "./security-headers.js";
|
|
16
|
+
// ─── Public Origin ─────────────────────────────────────────
|
|
17
|
+
export { parsePublicOrigin } from "./public-origin.js";
|
|
16
18
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEpE,+DAA+D;AAC/D,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEhE,+DAA+D;AAC/D,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AAEtB,+DAA+D;AAC/D,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AAItB,OAAO,EACL,cAAc,EACd,SAAS,EACT,uBAAuB,EACvB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAIpB,OAAO,EACL,yBAAyB,EACzB,0BAA0B,EAC1B,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAK5E,+DAA+D;AAC/D,OAAO,EAAE,sBAAsB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEpE,+DAA+D;AAC/D,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEhE,+DAA+D;AAC/D,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AAEtB,+DAA+D;AAC/D,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AAItB,OAAO,EACL,cAAc,EACd,SAAS,EACT,uBAAuB,EACvB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAIpB,OAAO,EACL,yBAAyB,EACzB,0BAA0B,EAC1B,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAK5E,+DAA+D;AAC/D,OAAO,EAAE,sBAAsB,EAAsC,MAAM,sBAAsB,CAAC;AAElG,8DAA8D;AAC9D,OAAO,EACL,2BAA2B,EAC3B,kBAAkB,GAEnB,MAAM,uBAAuB,CAAC;AAE/B,8DAA8D;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate and normalize a browser-facing public origin (e.g. `https://grackle.home`),
|
|
3
|
+
* the value of `GRACKLE_PUBLIC_URL` / `WebServerOptions.publicUrl`.
|
|
4
|
+
*
|
|
5
|
+
* Accepts only a bare http(s) origin: leading/trailing whitespace is trimmed, and
|
|
6
|
+
* a path, query, fragment, or embedded userinfo (`user:pass@host`) is rejected.
|
|
7
|
+
* Userinfo in particular is refused rather than silently dropped by `URL.origin`,
|
|
8
|
+
* and its error message never echoes the raw value so credentials cannot leak into
|
|
9
|
+
* logs. Throws an `Error` with a clear, label-prefixed message on any invalid
|
|
10
|
+
* input so callers fail fast at startup.
|
|
11
|
+
*
|
|
12
|
+
* @param value - The raw origin string (may contain surrounding whitespace).
|
|
13
|
+
* @param label - Human-readable source name for error messages (e.g. `GRACKLE_PUBLIC_URL`).
|
|
14
|
+
* @returns The parsed `URL`; use `.origin` for the normalized string form.
|
|
15
|
+
*/
|
|
16
|
+
export declare function parsePublicOrigin(value: string, label: string): URL;
|
|
17
|
+
//# sourceMappingURL=public-origin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public-origin.d.ts","sourceRoot":"","sources":["../src/public-origin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,GAAG,CAqBnE"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate and normalize a browser-facing public origin (e.g. `https://grackle.home`),
|
|
3
|
+
* the value of `GRACKLE_PUBLIC_URL` / `WebServerOptions.publicUrl`.
|
|
4
|
+
*
|
|
5
|
+
* Accepts only a bare http(s) origin: leading/trailing whitespace is trimmed, and
|
|
6
|
+
* a path, query, fragment, or embedded userinfo (`user:pass@host`) is rejected.
|
|
7
|
+
* Userinfo in particular is refused rather than silently dropped by `URL.origin`,
|
|
8
|
+
* and its error message never echoes the raw value so credentials cannot leak into
|
|
9
|
+
* logs. Throws an `Error` with a clear, label-prefixed message on any invalid
|
|
10
|
+
* input so callers fail fast at startup.
|
|
11
|
+
*
|
|
12
|
+
* @param value - The raw origin string (may contain surrounding whitespace).
|
|
13
|
+
* @param label - Human-readable source name for error messages (e.g. `GRACKLE_PUBLIC_URL`).
|
|
14
|
+
* @returns The parsed `URL`; use `.origin` for the normalized string form.
|
|
15
|
+
*/
|
|
16
|
+
export function parsePublicOrigin(value, label) {
|
|
17
|
+
const trimmed = value.trim();
|
|
18
|
+
let parsed;
|
|
19
|
+
try {
|
|
20
|
+
parsed = new URL(trimmed);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
throw new Error(`Invalid ${label}: must be an absolute http(s) origin, e.g. https://grackle.home.`);
|
|
24
|
+
}
|
|
25
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
26
|
+
throw new Error(`Invalid ${label}: Scheme must be http or https.`);
|
|
27
|
+
}
|
|
28
|
+
if (parsed.username || parsed.password) {
|
|
29
|
+
// Do NOT echo the raw value — it contains credentials.
|
|
30
|
+
throw new Error(`Invalid ${label}: must not contain a username or password (userinfo).`);
|
|
31
|
+
}
|
|
32
|
+
if ((parsed.pathname !== "" && parsed.pathname !== "/") || parsed.search || parsed.hash) {
|
|
33
|
+
throw new Error(`Invalid ${label}: must be a bare origin with no path, query, or fragment.`);
|
|
34
|
+
}
|
|
35
|
+
return parsed;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=public-origin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public-origin.js","sourceRoot":"","sources":["../src/public-origin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAa,EAAE,KAAa;IAC5D,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,MAAW,CAAC;IAChB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,WAAW,KAAK,kEAAkE,CACnF,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CAAC,WAAW,KAAK,iCAAiC,CAAC,CAAC;IACrE,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACvC,uDAAuD;QACvD,MAAM,IAAI,KAAK,CAAC,WAAW,KAAK,uDAAuD,CAAC,CAAC;IAC3F,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,QAAQ,KAAK,EAAE,IAAI,MAAM,CAAC,QAAQ,KAAK,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QACxF,MAAM,IAAI,KAAK,CAAC,WAAW,KAAK,2DAA2D,CAAC,CAAC;IAC/F,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -4,6 +4,23 @@ import type { ServerResponse } from "node:http";
|
|
|
4
4
|
* backwards-compatible export.
|
|
5
5
|
*/
|
|
6
6
|
export declare const WEB_CONTENT_SECURITY_POLICY: string;
|
|
7
|
+
/** Optional flags controlling scheme-dependent security headers. */
|
|
8
|
+
export interface SecurityHeaderOptions {
|
|
9
|
+
/**
|
|
10
|
+
* When true, emit a `Strict-Transport-Security` header. Set this only when the
|
|
11
|
+
* browser-facing scheme is HTTPS (e.g. `GRACKLE_PUBLIC_URL` is an https
|
|
12
|
+
* origin), never for a plain-http origin.
|
|
13
|
+
*/
|
|
14
|
+
hsts?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Explicit browser-facing MCP Apps sandbox origin (`GRACKLE_SANDBOX_ORIGIN`),
|
|
17
|
+
* added to the CSP `frame-src` directive. Behind a reverse proxy the sandbox
|
|
18
|
+
* iframe may live on a *different host* than the web app, which the
|
|
19
|
+
* request-host wildcard does not cover; without this the browser would block
|
|
20
|
+
* the widget iframe. Invalid values are ignored.
|
|
21
|
+
*/
|
|
22
|
+
sandboxOrigin?: string;
|
|
23
|
+
}
|
|
7
24
|
/**
|
|
8
25
|
* Set defense-in-depth security headers on every web response.
|
|
9
26
|
*
|
|
@@ -16,6 +33,7 @@ export declare const WEB_CONTENT_SECURITY_POLICY: string;
|
|
|
16
33
|
* provided, the CSP `form-action` directive explicitly includes the
|
|
17
34
|
* request origin to work around a Chromium bug where `'self'` does not
|
|
18
35
|
* match form submissions on non-standard ports.
|
|
36
|
+
* @param options - Optional scheme-dependent headers (e.g. {@link SecurityHeaderOptions.hsts}).
|
|
19
37
|
*/
|
|
20
|
-
export declare function setSecurityHeaders(res: ServerResponse, requestHost?: string): void;
|
|
38
|
+
export declare function setSecurityHeaders(res: ServerResponse, requestHost?: string, options?: SecurityHeaderOptions): void;
|
|
21
39
|
//# sourceMappingURL=security-headers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"security-headers.d.ts","sourceRoot":"","sources":["../src/security-headers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAyBhD;;;GAGG;AACH,eAAO,MAAM,2BAA2B,EAAE,MAI9B,CAAC;
|
|
1
|
+
{"version":3,"file":"security-headers.d.ts","sourceRoot":"","sources":["../src/security-headers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAyBhD;;;GAGG;AACH,eAAO,MAAM,2BAA2B,EAAE,MAI9B,CAAC;AAUb,oEAAoE;AACpE,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,cAAc,EACnB,WAAW,CAAC,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,IAAI,CA0CN"}
|
package/dist/security-headers.js
CHANGED
|
@@ -29,6 +29,13 @@ export const WEB_CONTENT_SECURITY_POLICY = [
|
|
|
29
29
|
"frame-src 'self'",
|
|
30
30
|
"form-action 'self'",
|
|
31
31
|
].join("; ");
|
|
32
|
+
/**
|
|
33
|
+
* `Strict-Transport-Security` value emitted when the connection is served over
|
|
34
|
+
* HTTPS. One year, without `includeSubDomains` — the latter could force HTTPS
|
|
35
|
+
* onto sibling subdomains of a shared apex (e.g. `grackle.home`) and is hard to
|
|
36
|
+
* roll back, so it is intentionally omitted.
|
|
37
|
+
*/
|
|
38
|
+
const HSTS_MAX_AGE_SECONDS = 31_536_000;
|
|
32
39
|
/**
|
|
33
40
|
* Set defense-in-depth security headers on every web response.
|
|
34
41
|
*
|
|
@@ -41,10 +48,14 @@ export const WEB_CONTENT_SECURITY_POLICY = [
|
|
|
41
48
|
* provided, the CSP `form-action` directive explicitly includes the
|
|
42
49
|
* request origin to work around a Chromium bug where `'self'` does not
|
|
43
50
|
* match form submissions on non-standard ports.
|
|
51
|
+
* @param options - Optional scheme-dependent headers (e.g. {@link SecurityHeaderOptions.hsts}).
|
|
44
52
|
*/
|
|
45
|
-
export function setSecurityHeaders(res, requestHost) {
|
|
53
|
+
export function setSecurityHeaders(res, requestHost, options) {
|
|
46
54
|
res.setHeader("X-Content-Type-Options", "nosniff");
|
|
47
55
|
res.setHeader("X-Frame-Options", "DENY");
|
|
56
|
+
if (options?.hsts) {
|
|
57
|
+
res.setHeader("Strict-Transport-Security", `max-age=${HSTS_MAX_AGE_SECONDS}`);
|
|
58
|
+
}
|
|
48
59
|
// Chromium does not reliably match 'self' or explicit origin+port for
|
|
49
60
|
// form-action on non-standard ports. Use the request hostname with a
|
|
50
61
|
// wildcard port so the form POST is allowed regardless of port.
|
|
@@ -57,18 +68,30 @@ export function setSecurityHeaders(res, requestHost) {
|
|
|
57
68
|
// hostname on any port (same workaround as form-action). The framed sandbox
|
|
58
69
|
// is itself origin-isolated with its own locked-down CSP, so this only widens
|
|
59
70
|
// which origins the app may *embed*, not what runs inside them.
|
|
60
|
-
|
|
71
|
+
const frameSrcSources = ["'self'"];
|
|
61
72
|
if (requestHost) {
|
|
62
73
|
try {
|
|
63
74
|
const parsed = new URL(`http://${requestHost}`);
|
|
64
75
|
const hostname = parsed.hostname;
|
|
65
76
|
formAction = `form-action 'self' http://${hostname}:* https://${hostname}:*`;
|
|
66
|
-
|
|
77
|
+
frameSrcSources.push(`http://${hostname}:*`, `https://${hostname}:*`);
|
|
67
78
|
}
|
|
68
79
|
catch {
|
|
69
80
|
// Malformed Host header — fall back to 'self' only
|
|
70
81
|
}
|
|
71
82
|
}
|
|
83
|
+
// Allow the explicitly-configured sandbox origin (which may be a different host
|
|
84
|
+
// behind a reverse proxy, uncovered by the request-host wildcard above). Parse
|
|
85
|
+
// via URL to normalize and prevent CSP injection through a malformed value.
|
|
86
|
+
if (options?.sandboxOrigin) {
|
|
87
|
+
try {
|
|
88
|
+
frameSrcSources.push(new URL(options.sandboxOrigin).origin);
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
// Invalid sandbox origin — ignore.
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const frameSrc = `frame-src ${frameSrcSources.join(" ")}`;
|
|
72
95
|
const csp = [...BASE_CSP_DIRECTIVES, frameSrc, formAction].join("; ");
|
|
73
96
|
res.setHeader("Content-Security-Policy", csp);
|
|
74
97
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"security-headers.js","sourceRoot":"","sources":["../src/security-headers.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,MAAM,mBAAmB,GAAsB;IAC7C,oBAAoB;IACpB,mBAAmB;IACnB,kCAAkC;IAClC,sBAAsB;IACtB,iBAAiB;IACjB,oBAAoB;IACpB,mBAAmB;IACnB,wBAAwB;IACxB,iBAAiB;CAClB,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAW;IACjD,GAAG,mBAAmB;IACtB,kBAAkB;IAClB,oBAAoB;CACrB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb
|
|
1
|
+
{"version":3,"file":"security-headers.js","sourceRoot":"","sources":["../src/security-headers.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,MAAM,mBAAmB,GAAsB;IAC7C,oBAAoB;IACpB,mBAAmB;IACnB,kCAAkC;IAClC,sBAAsB;IACtB,iBAAiB;IACjB,oBAAoB;IACpB,mBAAmB;IACnB,wBAAwB;IACxB,iBAAiB;CAClB,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAW;IACjD,GAAG,mBAAmB;IACtB,kBAAkB;IAClB,oBAAoB;CACrB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb;;;;;GAKG;AACH,MAAM,oBAAoB,GAAW,UAAU,CAAC;AAoBhD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,kBAAkB,CAChC,GAAmB,EACnB,WAAoB,EACpB,OAA+B;IAE/B,GAAG,CAAC,SAAS,CAAC,wBAAwB,EAAE,SAAS,CAAC,CAAC;IACnD,GAAG,CAAC,SAAS,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;IACzC,IAAI,OAAO,EAAE,IAAI,EAAE,CAAC;QAClB,GAAG,CAAC,SAAS,CAAC,2BAA2B,EAAE,WAAW,oBAAoB,EAAE,CAAC,CAAC;IAChF,CAAC;IACD,sEAAsE;IACtE,qEAAqE;IACrE,gEAAgE;IAChE,0EAA0E;IAC1E,2CAA2C;IAC3C,IAAI,UAAU,GAAG,oBAAoB,CAAC;IACtC,6EAA6E;IAC7E,wEAAwE;IACxE,8EAA8E;IAC9E,4EAA4E;IAC5E,8EAA8E;IAC9E,gEAAgE;IAChE,MAAM,eAAe,GAAa,CAAC,QAAQ,CAAC,CAAC;IAC7C,IAAI,WAAW,EAAE,CAAC;QAChB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,UAAU,WAAW,EAAE,CAAC,CAAC;YAChD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;YACjC,UAAU,GAAG,6BAA6B,QAAQ,cAAc,QAAQ,IAAI,CAAC;YAC7E,eAAe,CAAC,IAAI,CAAC,UAAU,QAAQ,IAAI,EAAE,WAAW,QAAQ,IAAI,CAAC,CAAC;QACxE,CAAC;QAAC,MAAM,CAAC;YACP,mDAAmD;QACrD,CAAC;IACH,CAAC;IACD,gFAAgF;IAChF,+EAA+E;IAC/E,4EAA4E;IAC5E,IAAI,OAAO,EAAE,aAAa,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,eAAe,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;QAC9D,CAAC;QAAC,MAAM,CAAC;YACP,mCAAmC;QACrC,CAAC;IACH,CAAC;IACD,MAAM,QAAQ,GAAG,aAAa,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;IAC1D,MAAM,GAAG,GAAG,CAAC,GAAG,mBAAmB,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtE,GAAG,CAAC,SAAS,CAAC,yBAAyB,EAAE,GAAG,CAAC,CAAC;AAChD,CAAC"}
|
package/dist/session.d.ts
CHANGED
|
@@ -11,9 +11,10 @@ export declare function stopSessionCleanup(): void;
|
|
|
11
11
|
* is an HMAC-SHA256 of the session ID using the API key as secret.
|
|
12
12
|
*
|
|
13
13
|
* When `options.secure` is true the cookie includes the `Secure` flag,
|
|
14
|
-
* which tells browsers to only send it over HTTPS.
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* which tells browsers to only send it over HTTPS. The caller should set
|
|
15
|
+
* this from the browser-facing scheme (i.e. `GRACKLE_PUBLIC_URL` is an
|
|
16
|
+
* https origin), not from the bind address — a `Secure` cookie is refused
|
|
17
|
+
* by browsers over plain http and would break login.
|
|
17
18
|
*/
|
|
18
19
|
export declare function createSession(apiKey: string, options?: {
|
|
19
20
|
secure?: boolean;
|
package/dist/session.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAEA,mDAAmD;AACnD,eAAO,MAAM,mBAAmB,EAAE,MAA0B,CAAC;AAqB7D,6EAA6E;AAC7E,wBAAgB,mBAAmB,IAAI,IAAI,CAc1C;AAED,+CAA+C;AAC/C,wBAAgB,kBAAkB,IAAI,IAAI,CAKzC;AAUD
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAEA,mDAAmD;AACnD,eAAO,MAAM,mBAAmB,EAAE,MAA0B,CAAC;AAqB7D,6EAA6E;AAC7E,wBAAgB,mBAAmB,IAAI,IAAI,CAc1C;AAED,+CAA+C;AAC/C,wBAAgB,kBAAkB,IAAI,IAAI,CAKzC;AAUD;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAwBpF;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAenE;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAwCnF;AAED,gDAAgD;AAChD,wBAAgB,aAAa,IAAI,IAAI,CAEpC"}
|
package/dist/session.js
CHANGED
|
@@ -47,9 +47,10 @@ function sign(value, secret) {
|
|
|
47
47
|
* is an HMAC-SHA256 of the session ID using the API key as secret.
|
|
48
48
|
*
|
|
49
49
|
* When `options.secure` is true the cookie includes the `Secure` flag,
|
|
50
|
-
* which tells browsers to only send it over HTTPS.
|
|
51
|
-
*
|
|
52
|
-
*
|
|
50
|
+
* which tells browsers to only send it over HTTPS. The caller should set
|
|
51
|
+
* this from the browser-facing scheme (i.e. `GRACKLE_PUBLIC_URL` is an
|
|
52
|
+
* https origin), not from the bind address — a `Secure` cookie is refused
|
|
53
|
+
* by browsers over plain http and would break login.
|
|
53
54
|
*/
|
|
54
55
|
export function createSession(apiKey, options) {
|
|
55
56
|
const sessionId = randomBytes(SESSION_ID_BYTES).toString("hex");
|
package/dist/session.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEtD,mDAAmD;AACnD,MAAM,CAAC,MAAM,mBAAmB,GAAW,iBAAiB,CAAC;AAE7D,0CAA0C;AAC1C,MAAM,cAAc,GAAW,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEnD,oDAAoD;AACpD,MAAM,gBAAgB,GAAW,EAAE,CAAC;AAEpC,yDAAyD;AACzD,MAAM,2BAA2B,GAAW,EAAE,GAAG,IAAI,CAAC;AAOtD,mDAAmD;AACnD,MAAM,QAAQ,GAA+B,IAAI,GAAG,EAAyB,CAAC;AAE9E,IAAI,YAAwD,CAAC;AAE7D,6EAA6E;AAC7E,MAAM,UAAU,mBAAmB;IACjC,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO;IACT,CAAC;IACD,YAAY,GAAG,WAAW,CAAC,GAAG,EAAE;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,KAAK,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACpC,IAAI,GAAG,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;gBAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACtB,CAAC;QACH,CAAC;IACH,CAAC,EAAE,2BAA2B,CAAC,CAAC;IAChC,+DAA+D;IAC/D,YAAY,CAAC,KAAK,EAAE,CAAC;AACvB,CAAC;AAED,+CAA+C;AAC/C,MAAM,UAAU,kBAAkB;IAChC,IAAI,YAAY,EAAE,CAAC;QACjB,aAAa,CAAC,YAAY,CAAC,CAAC;QAC5B,YAAY,GAAG,SAAS,CAAC;IAC3B,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,IAAI,CAAC,KAAa,EAAE,MAAc;IACzC,OAAO,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAClE,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@grackle-ai/auth",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.135.0",
|
|
4
4
|
"description": "Authentication and authorization primitives for Grackle",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"dist/"
|
|
30
30
|
],
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@grackle-ai/common": "0.
|
|
32
|
+
"@grackle-ai/common": "0.135.0"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@rushstack/heft": "1.2.7",
|