@portel/photon 1.32.6 → 1.33.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -1
- package/dist/auth/mcp-jwt.d.ts +59 -0
- package/dist/auth/mcp-jwt.d.ts.map +1 -0
- package/dist/auth/mcp-jwt.js +177 -0
- package/dist/auth/mcp-jwt.js.map +1 -0
- package/dist/auto-ui/beam/types.d.ts +1 -0
- package/dist/auto-ui/beam/types.d.ts.map +1 -1
- package/dist/auto-ui/beam.d.ts +1 -0
- package/dist/auto-ui/beam.d.ts.map +1 -1
- package/dist/auto-ui/beam.js +92 -9
- package/dist/auto-ui/beam.js.map +1 -1
- package/dist/auto-ui/playground-html.d.ts.map +1 -1
- package/dist/auto-ui/playground-html.js +28 -38
- package/dist/auto-ui/playground-html.js.map +1 -1
- package/dist/auto-ui/streamable-http-transport.d.ts +1 -0
- package/dist/auto-ui/streamable-http-transport.d.ts.map +1 -1
- package/dist/auto-ui/streamable-http-transport.js +9 -1
- package/dist/auto-ui/streamable-http-transport.js.map +1 -1
- package/dist/auto-ui/ui-resolver.d.ts +12 -1
- package/dist/auto-ui/ui-resolver.d.ts.map +1 -1
- package/dist/auto-ui/ui-resolver.js +19 -3
- package/dist/auto-ui/ui-resolver.js.map +1 -1
- package/dist/beam.bundle.js +6 -0
- package/dist/beam.bundle.js.map +2 -2
- package/dist/cli/commands/auth.d.ts +15 -0
- package/dist/cli/commands/auth.d.ts.map +1 -0
- package/dist/cli/commands/auth.js +105 -0
- package/dist/cli/commands/auth.js.map +1 -0
- package/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/commands/build.js +13 -5
- package/dist/cli/commands/build.js.map +1 -1
- package/dist/cli/commands/host.d.ts.map +1 -1
- package/dist/cli/commands/host.js +9 -0
- package/dist/cli/commands/host.js.map +1 -1
- package/dist/cli/commands/run.d.ts.map +1 -1
- package/dist/cli/commands/run.js +3 -0
- package/dist/cli/commands/run.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +6 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/daemon/manager.d.ts +8 -0
- package/dist/daemon/manager.d.ts.map +1 -1
- package/dist/daemon/manager.js +46 -9
- package/dist/daemon/manager.js.map +1 -1
- package/dist/deploy/cloudflare.d.ts +2 -0
- package/dist/deploy/cloudflare.d.ts.map +1 -1
- package/dist/deploy/cloudflare.js +171 -16
- package/dist/deploy/cloudflare.js.map +1 -1
- package/dist/editor-support/docblock-tag-catalog.d.ts.map +1 -1
- package/dist/editor-support/docblock-tag-catalog.js +6 -0
- package/dist/editor-support/docblock-tag-catalog.js.map +1 -1
- package/dist/loader.d.ts +3 -0
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +49 -0
- package/dist/loader.js.map +1 -1
- package/dist/photon-doc-extractor.d.ts +1 -0
- package/dist/photon-doc-extractor.d.ts.map +1 -1
- package/dist/photon-doc-extractor.js +13 -0
- package/dist/photon-doc-extractor.js.map +1 -1
- package/dist/resource-server.d.ts.map +1 -1
- package/dist/resource-server.js +5 -2
- package/dist/resource-server.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +231 -185
- package/dist/server.js.map +1 -1
- package/dist/tsx-compiler.d.ts +65 -5
- package/dist/tsx-compiler.d.ts.map +1 -1
- package/dist/tsx-compiler.js +531 -52
- package/dist/tsx-compiler.js.map +1 -1
- package/package.json +1 -1
- package/templates/cloudflare/worker.ts.template +374 -47
package/README.md
CHANGED
|
@@ -550,6 +550,8 @@ Uses Bun's compiler under the hood. The binary bundles the photon, its `@depende
|
|
|
550
550
|
| `@param ... {@format email}` | Param | Input validation and field type |
|
|
551
551
|
| `@param ... {@min N} {@max N}` | Param | Numeric range constraints |
|
|
552
552
|
| `@ui` | Class/Method | Link a custom HTML template |
|
|
553
|
+
| `@auth` | Class | Require or describe MCP authentication and populate `this.caller` |
|
|
554
|
+
| `@scope` | Method | Override the inferred OAuth scope for a protected MCP tool call |
|
|
553
555
|
| `@expose` | Method | Auto-bind to `POST /api/<kebab>` for SPA fetch (`public` skips the SameSite gate) |
|
|
554
556
|
| `@get /path` | Method | HTTP-only GET route; shown as a web app in Beam, not an MCP tool. Supports `:param` segments |
|
|
555
557
|
| `@post /path` | Method | HTTP-only POST route; shown as a web app in Beam, not an MCP tool. Supports `:param` segments |
|
|
@@ -574,6 +576,7 @@ Uses Bun's compiler under the hood. The binary bundles the photon, its `@depende
|
|
|
574
576
|
|---|---|
|
|
575
577
|
| [Getting Started](./docs/getting-started.md) | Install, build, and run your first photon in 5 minutes |
|
|
576
578
|
| [Core Concepts](./docs/concepts.md) | The 6 ideas behind Photon |
|
|
579
|
+
| [Tag Reference](./docs/reference/DOCBLOCK-TAGS.md) | Public reference for every docblock tag Photon understands |
|
|
577
580
|
| [Output Formats](./docs/formats.md) | Visual gallery of every `@format` type |
|
|
578
581
|
| [Intent Metadata](./docs/reference/INTENT-METADATA.md) | How comments, schemas, annotations, and formats map to native surfaces |
|
|
579
582
|
| [Settings](./docs/GUIDE.md#settings-user-configurable-knobs) | Declare runtime knobs with `protected settings` (the canonical config pattern) |
|
|
@@ -585,6 +588,7 @@ Uses Bun's compiler under the hood. The binary bundles the photon, its `@depende
|
|
|
585
588
|
|---|---|
|
|
586
589
|
| [Custom UI](./docs/guides/CUSTOM-UI.md) | Build rich interactive interfaces with the photon bridge API |
|
|
587
590
|
| [OAuth](./docs/guides/AUTH.md) | Built-in OAuth 2.0 with Google, GitHub, Microsoft |
|
|
591
|
+
| [MCP JWT Auth](./docs/guides/MCP-JWT-AUTH.md) | Secure deployed MCP tool calls with short-lived scoped JWTs |
|
|
588
592
|
| [MCP Client Registration](./docs/guides/mcp-client-registration.md) | Register MCP clients with Photon's AS via CIMD or DCR |
|
|
589
593
|
| [Observability](./docs/guides/observability.md) | OpenTelemetry traces, metrics, logs, and structured errors |
|
|
590
594
|
| [Protocol Features](./docs/guides/PROTOCOL-FEATURES.md) | Capability handshake, structured errors, trace correlation |
|
|
@@ -603,7 +607,7 @@ Uses Bun's compiler under the hood. The binary bundles the photon, its `@depende
|
|
|
603
607
|
| [Marketplace Publishing](./docs/guides/MARKETPLACE-PUBLISHING.md) | Create and share team marketplaces |
|
|
604
608
|
| [Best Practices](./docs/guides/BEST-PRACTICES.md) | Patterns for production photons |
|
|
605
609
|
|
|
606
|
-
**Reference:** [Complete Developer Guide](./docs/GUIDE.md) · [Tag Reference](./docs/reference/DOCBLOCK-TAGS.md) · [Naming Conventions](./docs/guides/NAMING-CONVENTIONS.md) · [Architecture](./docs/internals/ARCHITECTURE.md) · [
|
|
610
|
+
**Reference:** [Complete Developer Guide](./docs/GUIDE.md) · [Tag Reference](./docs/reference/DOCBLOCK-TAGS.md) · [Naming Conventions](./docs/guides/NAMING-CONVENTIONS.md) · [Architecture](./docs/internals/ARCHITECTURE.md) · [Lifecycle & Ingress](./docs/internals/LIFECYCLE-AND-INGRESS.md) · [PHOTON_DIR & Namespace](./docs/internals/PHOTON-DIR-AND-NAMESPACE.md) · [Changelog](./CHANGELOG.md) · [Contributing](./CONTRIBUTING.md)
|
|
607
611
|
|
|
608
612
|
---
|
|
609
613
|
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { type JsonWebKey } from 'node:crypto';
|
|
2
|
+
export interface PhotonAuthIssuer {
|
|
3
|
+
issuer: string;
|
|
4
|
+
algorithm: 'ES256';
|
|
5
|
+
kid: string;
|
|
6
|
+
defaultTtlSeconds: number;
|
|
7
|
+
}
|
|
8
|
+
export interface PhotonAuthTokenOptions {
|
|
9
|
+
agent: string;
|
|
10
|
+
audience: string;
|
|
11
|
+
tenant?: string;
|
|
12
|
+
scopes?: string[];
|
|
13
|
+
ttlSeconds?: number;
|
|
14
|
+
now?: Date;
|
|
15
|
+
jti?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface PhotonAuthVerifyOptions {
|
|
18
|
+
issuer: string;
|
|
19
|
+
audience: string;
|
|
20
|
+
jwks: {
|
|
21
|
+
keys: JsonWebKey[];
|
|
22
|
+
};
|
|
23
|
+
now?: Date;
|
|
24
|
+
clockSkewSeconds?: number;
|
|
25
|
+
requiredScopes?: string[];
|
|
26
|
+
}
|
|
27
|
+
export type PhotonJwtVerifyReason = 'missing_token' | 'malformed_token' | 'unsupported_alg' | 'unknown_kid' | 'bad_signature' | 'expired_token' | 'token_not_yet_valid' | 'wrong_issuer' | 'wrong_audience' | 'insufficient_scope' | 'tenant_mismatch';
|
|
28
|
+
export interface PhotonJwtClaims {
|
|
29
|
+
iss: string;
|
|
30
|
+
sub: string;
|
|
31
|
+
aud: string | string[];
|
|
32
|
+
tenant_id: string;
|
|
33
|
+
client_id: string;
|
|
34
|
+
scope?: string;
|
|
35
|
+
iat: number;
|
|
36
|
+
nbf: number;
|
|
37
|
+
exp: number;
|
|
38
|
+
jti: string;
|
|
39
|
+
[key: string]: unknown;
|
|
40
|
+
}
|
|
41
|
+
export type PhotonJwtVerifyResult = {
|
|
42
|
+
ok: true;
|
|
43
|
+
claims: PhotonJwtClaims;
|
|
44
|
+
} | {
|
|
45
|
+
ok: false;
|
|
46
|
+
reason: PhotonJwtVerifyReason;
|
|
47
|
+
};
|
|
48
|
+
export declare function createPhotonAuthKeypair(name: string, now?: Date): {
|
|
49
|
+
issuer: PhotonAuthIssuer;
|
|
50
|
+
privateJwk: JsonWebKey;
|
|
51
|
+
publicJwk: JsonWebKey;
|
|
52
|
+
jwks: {
|
|
53
|
+
keys: JsonWebKey[];
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
export declare function signPhotonAuthToken(issuer: PhotonAuthIssuer, privateJwk: JsonWebKey, options: PhotonAuthTokenOptions): string;
|
|
57
|
+
export declare function verifyPhotonAuthToken(token: string | null | undefined, options: PhotonAuthVerifyOptions): PhotonJwtVerifyResult;
|
|
58
|
+
export declare function normalizeScopes(scopes: string[]): string[];
|
|
59
|
+
//# sourceMappingURL=mcp-jwt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-jwt.d.ts","sourceRoot":"","sources":["../../src/auth/mcp-jwt.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,UAAU,EAChB,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE;QAAE,IAAI,EAAE,UAAU,EAAE,CAAA;KAAE,CAAC;IAC7B,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,MAAM,qBAAqB,GAC7B,eAAe,GACf,iBAAiB,GACjB,iBAAiB,GACjB,aAAa,GACb,eAAe,GACf,eAAe,GACf,qBAAqB,GACrB,cAAc,GACd,gBAAgB,GAChB,oBAAoB,GACpB,iBAAiB,CAAC;AAEtB,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,MAAM,qBAAqB,GAC7B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,GACrC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,qBAAqB,CAAA;CAAE,CAAC;AAEjD,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,GAAG,OAAa,GACf;IACD,MAAM,EAAE,gBAAgB,CAAC;IACzB,UAAU,EAAE,UAAU,CAAC;IACvB,SAAS,EAAE,UAAU,CAAC;IACtB,IAAI,EAAE;QAAE,IAAI,EAAE,UAAU,EAAE,CAAA;KAAE,CAAC;CAC9B,CAsBA;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,gBAAgB,EACxB,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,sBAAsB,GAC9B,MAAM,CAiBR;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAChC,OAAO,EAAE,uBAAuB,GAC/B,qBAAqB,CA4CvB;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAY1D"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { createPrivateKey, createPublicKey, createSign, createVerify, generateKeyPairSync, randomBytes, } from 'node:crypto';
|
|
2
|
+
export function createPhotonAuthKeypair(name, now = new Date()) {
|
|
3
|
+
const date = now.toISOString().slice(0, 10);
|
|
4
|
+
const kid = `${name}-${date}`;
|
|
5
|
+
const { privateKey, publicKey } = generateKeyPairSync('ec', { namedCurve: 'P-256' });
|
|
6
|
+
const privateJwk = privateKey.export({ format: 'jwk' });
|
|
7
|
+
const publicJwk = publicKey.export({ format: 'jwk' });
|
|
8
|
+
for (const jwk of [privateJwk, publicJwk]) {
|
|
9
|
+
jwk.alg = 'ES256';
|
|
10
|
+
jwk.kid = kid;
|
|
11
|
+
jwk.use = 'sig';
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
issuer: {
|
|
15
|
+
issuer: `photon-local:${name}`,
|
|
16
|
+
algorithm: 'ES256',
|
|
17
|
+
kid,
|
|
18
|
+
defaultTtlSeconds: 15 * 60,
|
|
19
|
+
},
|
|
20
|
+
privateJwk,
|
|
21
|
+
publicJwk,
|
|
22
|
+
jwks: { keys: [publicJwk] },
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export function signPhotonAuthToken(issuer, privateJwk, options) {
|
|
26
|
+
const nowSec = Math.floor((options.now?.getTime() ?? Date.now()) / 1000);
|
|
27
|
+
const ttl = options.ttlSeconds ?? issuer.defaultTtlSeconds;
|
|
28
|
+
const scopes = normalizeScopes(options.scopes ?? []);
|
|
29
|
+
const payload = {
|
|
30
|
+
iss: issuer.issuer,
|
|
31
|
+
sub: `agent:${options.agent}`,
|
|
32
|
+
aud: options.audience,
|
|
33
|
+
tenant_id: options.tenant ?? 'default',
|
|
34
|
+
client_id: options.agent,
|
|
35
|
+
...(scopes.length > 0 ? { scope: scopes.join(' ') } : {}),
|
|
36
|
+
iat: nowSec,
|
|
37
|
+
nbf: nowSec,
|
|
38
|
+
exp: nowSec + ttl,
|
|
39
|
+
jti: options.jti ?? `tok_${randomBytes(16).toString('base64url')}`,
|
|
40
|
+
};
|
|
41
|
+
return signJwt(payload, privateJwk, issuer.kid);
|
|
42
|
+
}
|
|
43
|
+
export function verifyPhotonAuthToken(token, options) {
|
|
44
|
+
if (!token)
|
|
45
|
+
return { ok: false, reason: 'missing_token' };
|
|
46
|
+
const parts = token.split('.');
|
|
47
|
+
if (parts.length !== 3)
|
|
48
|
+
return { ok: false, reason: 'malformed_token' };
|
|
49
|
+
let header;
|
|
50
|
+
let claims;
|
|
51
|
+
try {
|
|
52
|
+
header = JSON.parse(base64UrlDecode(parts[0]));
|
|
53
|
+
claims = JSON.parse(base64UrlDecode(parts[1]));
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return { ok: false, reason: 'malformed_token' };
|
|
57
|
+
}
|
|
58
|
+
if (header.alg !== 'ES256')
|
|
59
|
+
return { ok: false, reason: 'unsupported_alg' };
|
|
60
|
+
const kid = typeof header.kid === 'string' ? header.kid : '';
|
|
61
|
+
const jwk = options.jwks.keys.find((key) => key.kid === kid);
|
|
62
|
+
if (!kid || !jwk)
|
|
63
|
+
return { ok: false, reason: 'unknown_kid' };
|
|
64
|
+
if (!verifyJwtSignature(parts, jwk))
|
|
65
|
+
return { ok: false, reason: 'bad_signature' };
|
|
66
|
+
if (claims.iss !== options.issuer)
|
|
67
|
+
return { ok: false, reason: 'wrong_issuer' };
|
|
68
|
+
const audMatches = Array.isArray(claims.aud)
|
|
69
|
+
? claims.aud.includes(options.audience)
|
|
70
|
+
: claims.aud === options.audience;
|
|
71
|
+
if (!audMatches)
|
|
72
|
+
return { ok: false, reason: 'wrong_audience' };
|
|
73
|
+
const now = Math.floor((options.now?.getTime() ?? Date.now()) / 1000);
|
|
74
|
+
const skew = options.clockSkewSeconds ?? 60;
|
|
75
|
+
if (typeof claims.exp !== 'number' || claims.exp < now - skew) {
|
|
76
|
+
return { ok: false, reason: 'expired_token' };
|
|
77
|
+
}
|
|
78
|
+
if (typeof claims.nbf === 'number' && claims.nbf > now + skew) {
|
|
79
|
+
return { ok: false, reason: 'token_not_yet_valid' };
|
|
80
|
+
}
|
|
81
|
+
if (typeof claims.iat === 'number' && claims.iat > now + skew) {
|
|
82
|
+
return { ok: false, reason: 'token_not_yet_valid' };
|
|
83
|
+
}
|
|
84
|
+
const required = normalizeScopes(options.requiredScopes ?? []);
|
|
85
|
+
if (required.length > 0) {
|
|
86
|
+
const granted = new Set(normalizeScopes((claims.scope ?? '').split(/\s+/)));
|
|
87
|
+
for (const scope of required) {
|
|
88
|
+
if (!granted.has(scope))
|
|
89
|
+
return { ok: false, reason: 'insufficient_scope' };
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return { ok: true, claims };
|
|
93
|
+
}
|
|
94
|
+
export function normalizeScopes(scopes) {
|
|
95
|
+
const out = [];
|
|
96
|
+
const seen = new Set();
|
|
97
|
+
for (const raw of scopes) {
|
|
98
|
+
for (const scope of raw.split(/\s+/)) {
|
|
99
|
+
const trimmed = scope.trim();
|
|
100
|
+
if (!trimmed || seen.has(trimmed))
|
|
101
|
+
continue;
|
|
102
|
+
seen.add(trimmed);
|
|
103
|
+
out.push(trimmed);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return out;
|
|
107
|
+
}
|
|
108
|
+
function signJwt(payload, privateJwk, kid) {
|
|
109
|
+
const header = { alg: 'ES256', typ: 'JWT', kid };
|
|
110
|
+
const input = `${base64UrlEncode(JSON.stringify(header))}.${base64UrlEncode(JSON.stringify(payload))}`;
|
|
111
|
+
const key = createPrivateKey({ key: privateJwk, format: 'jwk' });
|
|
112
|
+
const signer = createSign('sha256');
|
|
113
|
+
signer.update(input);
|
|
114
|
+
signer.end();
|
|
115
|
+
const der = signer.sign(key);
|
|
116
|
+
return `${input}.${derToP1363(der, 32).toString('base64url')}`;
|
|
117
|
+
}
|
|
118
|
+
function verifyJwtSignature(parts, publicJwk) {
|
|
119
|
+
try {
|
|
120
|
+
const key = createPublicKey({ key: publicJwk, format: 'jwk' });
|
|
121
|
+
const verifier = createVerify('sha256');
|
|
122
|
+
verifier.update(`${parts[0]}.${parts[1]}`);
|
|
123
|
+
verifier.end();
|
|
124
|
+
return verifier.verify(key, p1363ToDer(Buffer.from(parts[2], 'base64url')));
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
function base64UrlEncode(str) {
|
|
131
|
+
return Buffer.from(str, 'utf-8').toString('base64url');
|
|
132
|
+
}
|
|
133
|
+
function base64UrlDecode(str) {
|
|
134
|
+
return Buffer.from(str, 'base64url').toString('utf-8');
|
|
135
|
+
}
|
|
136
|
+
function derToP1363(der, componentLen) {
|
|
137
|
+
if (der[0] !== 0x30)
|
|
138
|
+
throw new Error('invalid DER signature');
|
|
139
|
+
let offset = 2;
|
|
140
|
+
if ((der[1] & 0x80) !== 0)
|
|
141
|
+
offset += der[1] & 0x7f;
|
|
142
|
+
const readInt = () => {
|
|
143
|
+
if (der[offset] !== 0x02)
|
|
144
|
+
throw new Error('invalid DER signature');
|
|
145
|
+
const len = der[offset + 1];
|
|
146
|
+
const start = offset + 2;
|
|
147
|
+
let value = der.subarray(start, start + len);
|
|
148
|
+
offset = start + len;
|
|
149
|
+
while (value.length > 1 && value[0] === 0x00)
|
|
150
|
+
value = value.subarray(1);
|
|
151
|
+
if (value.length > componentLen)
|
|
152
|
+
throw new Error('ECDSA component overflow');
|
|
153
|
+
return value;
|
|
154
|
+
};
|
|
155
|
+
const r = readInt();
|
|
156
|
+
const s = readInt();
|
|
157
|
+
const out = Buffer.alloc(componentLen * 2);
|
|
158
|
+
r.copy(out, componentLen - r.length);
|
|
159
|
+
s.copy(out, componentLen * 2 - s.length);
|
|
160
|
+
return out;
|
|
161
|
+
}
|
|
162
|
+
function p1363ToDer(p1363) {
|
|
163
|
+
if (p1363.length % 2 !== 0)
|
|
164
|
+
throw new Error('invalid P1363 signature');
|
|
165
|
+
const half = p1363.length / 2;
|
|
166
|
+
const encodeInt = (value) => {
|
|
167
|
+
let v = value;
|
|
168
|
+
while (v.length > 1 && v[0] === 0x00)
|
|
169
|
+
v = v.subarray(1);
|
|
170
|
+
if ((v[0] & 0x80) !== 0)
|
|
171
|
+
v = Buffer.concat([Buffer.from([0x00]), v]);
|
|
172
|
+
return Buffer.concat([Buffer.from([0x02, v.length]), v]);
|
|
173
|
+
};
|
|
174
|
+
const body = Buffer.concat([encodeInt(p1363.subarray(0, half)), encodeInt(p1363.subarray(half))]);
|
|
175
|
+
return Buffer.concat([Buffer.from([0x30, body.length]), body]);
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=mcp-jwt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-jwt.js","sourceRoot":"","sources":["../../src/auth/mcp-jwt.ts"],"names":[],"mappings":"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"}
|
|
@@ -42,6 +42,7 @@ export interface BeamActions {
|
|
|
42
42
|
loadUIAsset: (photonName: string, uiId: string) => Promise<{
|
|
43
43
|
content: string;
|
|
44
44
|
isPhotonTemplate: boolean;
|
|
45
|
+
compiled?: import('../../tsx-compiler.js').CompiledTsx;
|
|
45
46
|
} | null>;
|
|
46
47
|
subscribeToChannel: (channel: string) => Promise<void>;
|
|
47
48
|
unsubscribeFromChannel: (channel: string) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/auto-ui/beam/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAExE,+CAA+C;AAC/C,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAChD,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC7C;AAED,mDAAmD;AACnD,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB;AAED,qDAAqD;AACrD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,sEAAsE;AACtE,MAAM,MAAM,YAAY,GAAG,CACzB,GAAG,EAAE,OAAO,MAAM,EAAE,eAAe,EACnC,GAAG,EAAE,OAAO,MAAM,EAAE,cAAc,EAClC,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,SAAS,KACb,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,uEAAuE;AACvE,MAAM,WAAW,WAAW;IAC1B,qBAAqB,EAAE,MAAM,IAAI,CAAC;IAClC,gBAAgB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;IAClE,oBAAoB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtF,WAAW,EAAE,CACX,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,KACT,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/auto-ui/beam/types.ts"],"names":[],"mappings":"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"}
|
package/dist/auto-ui/beam.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export declare function shouldServeLinkedAppForWebPath(pathname: string, searchP
|
|
|
16
16
|
export declare function selectClientAppUi(photonInfo: PhotonInfo | undefined): string | undefined;
|
|
17
17
|
export declare function shouldFallbackToClientAppForWebPath(pathname: string, searchParams: URLSearchParams, route: BeamWebRouteDef | undefined): boolean;
|
|
18
18
|
export declare function findBeamWebRoute(routes: BeamWebRouteDef[] | undefined, method: string, requestPath: string): BeamWebRouteDef | undefined;
|
|
19
|
+
export declare function rewriteBeamWebRedirectLocation(location: string | null, prefix: string, requestOrigin: string): string | null;
|
|
19
20
|
import type { PhotonInfo } from './types.js';
|
|
20
21
|
export type { PhotonConfig } from './beam/types.js';
|
|
21
22
|
export type { BeamState } from './beam/types.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"beam.d.ts","sourceRoot":"","sources":["../../src/auto-ui/beam.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAgEH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAQD,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAenF;AAYD,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,eAAe,GAC5B,OAAO,CAIT;AAUD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAmBxF;AAED,wBAAgB,mCAAmC,CACjD,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,eAAe,EAC7B,KAAK,EAAE,eAAe,GAAG,SAAS,GACjC,OAAO,CAIT;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,eAAe,EAAE,GAAG,SAAS,EACrC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAClB,eAAe,GAAG,SAAS,CAO7B;
|
|
1
|
+
{"version":3,"file":"beam.d.ts","sourceRoot":"","sources":["../../src/auto-ui/beam.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAgEH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAQD,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAenF;AAYD,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,eAAe,GAC5B,OAAO,CAIT;AAUD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAmBxF;AAED,wBAAgB,mCAAmC,CACjD,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,eAAe,EAC7B,KAAK,EAAE,eAAe,GAAG,SAAS,GACjC,OAAO,CAIT;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,eAAe,EAAE,GAAG,SAAS,EACrC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAClB,eAAe,GAAG,SAAS,CAO7B;AAwCD,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,GACpB,MAAM,GAAG,IAAI,CAaf;AAsED,OAAO,KAAK,EACV,UAAU,EAKX,MAAM,YAAY,CAAC;AAsCpB,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAqYjD,wBAAsB,SAAS,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAi7FlF;AAED;;;GAGG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAM9C"}
|
package/dist/auto-ui/beam.js
CHANGED
|
@@ -165,6 +165,22 @@ async function writeFetchResponseToNode(response, res) {
|
|
|
165
165
|
res.off('close', cancelReader);
|
|
166
166
|
}
|
|
167
167
|
}
|
|
168
|
+
export function rewriteBeamWebRedirectLocation(location, prefix, requestOrigin) {
|
|
169
|
+
if (!location)
|
|
170
|
+
return null;
|
|
171
|
+
try {
|
|
172
|
+
const target = new URL(location, requestOrigin);
|
|
173
|
+
if (target.origin !== requestOrigin)
|
|
174
|
+
return location;
|
|
175
|
+
if (target.pathname === prefix || target.pathname.startsWith(`${prefix}/`)) {
|
|
176
|
+
return target.pathname + target.search + target.hash;
|
|
177
|
+
}
|
|
178
|
+
return `${prefix}${target.pathname}${target.search}${target.hash}`;
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
return location;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
168
184
|
/**
|
|
169
185
|
* Resolve raw icon image paths to MCP Icon[] format (data URIs)
|
|
170
186
|
*/
|
|
@@ -215,7 +231,7 @@ import { ensurePhotonEditorDeclaration, writePhotonEditorDeclaration, } from '..
|
|
|
215
231
|
import { ensureDaemon } from '../daemon/manager.js';
|
|
216
232
|
import { SchemaExtractor } from '@portel/photon-core';
|
|
217
233
|
import { generateServerCard } from '../server-card.js';
|
|
218
|
-
import { resolveUIAssetPath, readUIContent } from './ui-resolver.js';
|
|
234
|
+
import { resolveUIAssetPath, readUIContent, readUICompiled } from './ui-resolver.js';
|
|
219
235
|
import { handleStreamableHTTP, broadcastNotification, broadcastToBeam, stopSessionCleanup, attachLoaderForResourceUpdates, } from './streamable-http-transport.js';
|
|
220
236
|
import { getBundledPhotonPath, BEAM_BUNDLED_PHOTONS } from '../shared-utils.js';
|
|
221
237
|
// BUNDLED_PHOTONS and getBundledPhotonPath are imported from shared-utils.js
|
|
@@ -1080,8 +1096,8 @@ export async function startBeam(rawWorkingDir, port) {
|
|
|
1080
1096
|
}
|
|
1081
1097
|
const isPhotonTemplate = resolved.isPhotonTemplate || resolved.isPhotonMarkdown;
|
|
1082
1098
|
try {
|
|
1083
|
-
const content = await
|
|
1084
|
-
return { content, isPhotonTemplate };
|
|
1099
|
+
const { content, compiled } = await readUICompiled(resolved.path);
|
|
1100
|
+
return { content, isPhotonTemplate, compiled };
|
|
1085
1101
|
}
|
|
1086
1102
|
catch {
|
|
1087
1103
|
// Fall through to check custom format renderers
|
|
@@ -2026,6 +2042,28 @@ export async function startBeam(rawWorkingDir, port) {
|
|
|
2026
2042
|
const httpRoutes = photonClass?._httpRoutes;
|
|
2027
2043
|
const route = findBeamWebRoute(httpRoutes, req.method || 'GET', photonPath);
|
|
2028
2044
|
const linkedAppUi = photonInfo?.configured ? selectClientAppUi(photonInfo) : undefined;
|
|
2045
|
+
// Compiled .tsx bundle for the linked app UI. The shell references
|
|
2046
|
+
// `./<base>.<hash>.js`, which arrives here as a /web sub-path. Serve
|
|
2047
|
+
// it from the compile cache with an immutable policy — the hash in
|
|
2048
|
+
// the filename is the cache key, so a source change yields a new URL
|
|
2049
|
+
// and the browser never runs a stale bundle.
|
|
2050
|
+
if (req.method === 'GET' && photonName && photonInfo?.configured && linkedAppUi) {
|
|
2051
|
+
const lastSeg = decodeURIComponent(pathParts[pathParts.length - 1] ?? '');
|
|
2052
|
+
if (/^[\w-]+\.[0-9a-f]{12}\.js$/.test(lastSeg)) {
|
|
2053
|
+
const appAsset = await loadUIAsset(photonName, linkedAppUi);
|
|
2054
|
+
if (appAsset?.compiled && lastSeg === appAsset.compiled.jsFileName) {
|
|
2055
|
+
const js = appAsset.compiled.js;
|
|
2056
|
+
res.writeHead(200, {
|
|
2057
|
+
'Content-Type': 'text/javascript; charset=utf-8',
|
|
2058
|
+
'Cache-Control': 'public, max-age=31536000, immutable',
|
|
2059
|
+
'Cross-Origin-Resource-Policy': 'same-origin',
|
|
2060
|
+
'Content-Length': Buffer.byteLength(js).toString(),
|
|
2061
|
+
});
|
|
2062
|
+
res.end(js);
|
|
2063
|
+
return;
|
|
2064
|
+
}
|
|
2065
|
+
}
|
|
2066
|
+
}
|
|
2029
2067
|
if (req.method === 'GET' &&
|
|
2030
2068
|
photonName &&
|
|
2031
2069
|
photonInfo?.configured &&
|
|
@@ -2034,6 +2072,13 @@ export async function startBeam(rawWorkingDir, port) {
|
|
|
2034
2072
|
const appAsset = await loadUIAsset(photonName, linkedAppUi);
|
|
2035
2073
|
if (appAsset) {
|
|
2036
2074
|
let body = appAsset.content;
|
|
2075
|
+
const shellEtag = appAsset.compiled?.hash ? `"${appAsset.compiled.hash}"` : undefined;
|
|
2076
|
+
const inm = req.headers['if-none-match'];
|
|
2077
|
+
if (shellEtag && inm && inm === shellEtag) {
|
|
2078
|
+
res.writeHead(304, { ETag: shellEtag });
|
|
2079
|
+
res.end();
|
|
2080
|
+
return;
|
|
2081
|
+
}
|
|
2037
2082
|
const prefix = `/web/${photonName}`;
|
|
2038
2083
|
const interceptor = `<script>
|
|
2039
2084
|
(function(){
|
|
@@ -2054,11 +2099,25 @@ export async function startBeam(rawWorkingDir, port) {
|
|
|
2054
2099
|
body = body.includes('<head>')
|
|
2055
2100
|
? body.replace('<head>', '<head>' + interceptor)
|
|
2056
2101
|
: interceptor + body;
|
|
2057
|
-
|
|
2102
|
+
// The compiled shell references the bundle relatively
|
|
2103
|
+
// (`./<base>.<hash>.js`). Under the /web/<photon> mount the
|
|
2104
|
+
// document URL has no trailing slash, so a relative resolve
|
|
2105
|
+
// would miss; pin it to the absolute prefixed path that the
|
|
2106
|
+
// hashed-JS handler above serves.
|
|
2107
|
+
if (appAsset.compiled?.jsFileName) {
|
|
2108
|
+
const jf = appAsset.compiled.jsFileName;
|
|
2109
|
+
body = body.replace(`src="./${jf}"`, `src="${prefix}/${jf}"`);
|
|
2110
|
+
}
|
|
2111
|
+
const shellHeaders = {
|
|
2058
2112
|
'Content-Type': 'text/html; charset=utf-8',
|
|
2059
|
-
|
|
2113
|
+
// Revalidate every load; ETag makes that a cheap 304 when the
|
|
2114
|
+
// compiled bundle (and thus the referenced hash) is unchanged.
|
|
2115
|
+
'Cache-Control': 'no-cache',
|
|
2060
2116
|
'Content-Length': Buffer.byteLength(body).toString(),
|
|
2061
|
-
}
|
|
2117
|
+
};
|
|
2118
|
+
if (shellEtag)
|
|
2119
|
+
shellHeaders['ETag'] = shellEtag;
|
|
2120
|
+
res.writeHead(200, shellHeaders);
|
|
2062
2121
|
res.end(body);
|
|
2063
2122
|
return;
|
|
2064
2123
|
}
|
|
@@ -2082,6 +2141,25 @@ export async function startBeam(rawWorkingDir, port) {
|
|
|
2082
2141
|
});
|
|
2083
2142
|
const result = await fn.call(photonClass.instance, webReq);
|
|
2084
2143
|
if (result instanceof Response) {
|
|
2144
|
+
const prefix = `/web/${photonName}`;
|
|
2145
|
+
if (result.status >= 300 && result.status < 400) {
|
|
2146
|
+
const responseHeaders = {};
|
|
2147
|
+
result.headers.forEach((value, key) => {
|
|
2148
|
+
if (key.toLowerCase() !== 'location')
|
|
2149
|
+
responseHeaders[key] = value;
|
|
2150
|
+
});
|
|
2151
|
+
const location = rewriteBeamWebRedirectLocation(result.headers.get('location'), prefix, internalUrl.origin);
|
|
2152
|
+
if (location) {
|
|
2153
|
+
responseHeaders.location = location;
|
|
2154
|
+
}
|
|
2155
|
+
const body = Buffer.from(await result.arrayBuffer());
|
|
2156
|
+
if (body.length > 0) {
|
|
2157
|
+
responseHeaders['content-length'] = String(body.length);
|
|
2158
|
+
}
|
|
2159
|
+
res.writeHead(result.status, responseHeaders);
|
|
2160
|
+
res.end(body.length > 0 ? body : undefined);
|
|
2161
|
+
return;
|
|
2162
|
+
}
|
|
2085
2163
|
const contentType = result.headers.get('content-type') || '';
|
|
2086
2164
|
if (!contentType.includes('text/html')) {
|
|
2087
2165
|
await writeFetchResponseToNode(result, res);
|
|
@@ -2094,7 +2172,6 @@ export async function startBeam(rawWorkingDir, port) {
|
|
|
2094
2172
|
responseHeaders[key] = value;
|
|
2095
2173
|
});
|
|
2096
2174
|
let body = Buffer.from(await result.arrayBuffer());
|
|
2097
|
-
const prefix = `/web/${photonName}`;
|
|
2098
2175
|
const interceptor = `<script>
|
|
2099
2176
|
(function(){
|
|
2100
2177
|
const _prefix="${prefix}";
|
|
@@ -2734,11 +2811,17 @@ export async function startBeam(rawWorkingDir, port) {
|
|
|
2734
2811
|
};
|
|
2735
2812
|
// Watch working directory recursively
|
|
2736
2813
|
try {
|
|
2814
|
+
// Directories that never hold photon source but generate huge event
|
|
2815
|
+
// volume (dependency installs, git ops, build output). The recursive
|
|
2816
|
+
// watch still descends them, but short-circuiting here stops every
|
|
2817
|
+
// write from fanning out into getPhotonForPath/handleFileChange — the
|
|
2818
|
+
// amplification that turns several Beam instances into FD/CPU pressure.
|
|
2819
|
+
const IGNORED_TOP_DIRS = new Set(['.data', 'node_modules', '.git', 'dist', '.photon-ui']);
|
|
2737
2820
|
const watcher = watch(workingDir, { recursive: true }, (eventType, filename) => {
|
|
2738
2821
|
if (!filename)
|
|
2739
2822
|
return;
|
|
2740
|
-
|
|
2741
|
-
if (
|
|
2823
|
+
const firstSeg = filename.split(path.sep)[0];
|
|
2824
|
+
if (IGNORED_TOP_DIRS.has(firstSeg))
|
|
2742
2825
|
return;
|
|
2743
2826
|
const fullPath = path.join(workingDir, filename);
|
|
2744
2827
|
logger.debug(`📂 File event: ${eventType} ${filename}`);
|