@betterportal/framework 0.0.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 +13 -0
- package/lib/adapters/h3.d.ts +51 -0
- package/lib/adapters/h3.d.ts.map +1 -0
- package/lib/adapters/h3.js +1120 -0
- package/lib/adapters/h3.js.map +1 -0
- package/lib/codegen/cli.d.ts +3 -0
- package/lib/codegen/cli.d.ts.map +1 -0
- package/lib/codegen/cli.js +82 -0
- package/lib/codegen/cli.js.map +1 -0
- package/lib/codegen/emitter.d.ts +7 -0
- package/lib/codegen/emitter.d.ts.map +1 -0
- package/lib/codegen/emitter.js +453 -0
- package/lib/codegen/emitter.js.map +1 -0
- package/lib/codegen/init.d.ts +3 -0
- package/lib/codegen/init.d.ts.map +1 -0
- package/lib/codegen/init.js +90 -0
- package/lib/codegen/init.js.map +1 -0
- package/lib/codegen/scanner.d.ts +56 -0
- package/lib/codegen/scanner.d.ts.map +1 -0
- package/lib/codegen/scanner.js +484 -0
- package/lib/codegen/scanner.js.map +1 -0
- package/lib/codegen/validate.d.ts +14 -0
- package/lib/codegen/validate.d.ts.map +1 -0
- package/lib/codegen/validate.js +166 -0
- package/lib/codegen/validate.js.map +1 -0
- package/lib/contracts/auth.d.ts +160 -0
- package/lib/contracts/auth.d.ts.map +1 -0
- package/lib/contracts/auth.js +123 -0
- package/lib/contracts/auth.js.map +1 -0
- package/lib/contracts/binding.d.ts +169 -0
- package/lib/contracts/binding.d.ts.map +1 -0
- package/lib/contracts/binding.js +69 -0
- package/lib/contracts/binding.js.map +1 -0
- package/lib/contracts/common.d.ts +23 -0
- package/lib/contracts/common.d.ts.map +1 -0
- package/lib/contracts/common.js +18 -0
- package/lib/contracts/common.js.map +1 -0
- package/lib/contracts/config.d.ts +93 -0
- package/lib/contracts/config.d.ts.map +1 -0
- package/lib/contracts/config.js +62 -0
- package/lib/contracts/config.js.map +1 -0
- package/lib/contracts/controlPlane.d.ts +63 -0
- package/lib/contracts/controlPlane.d.ts.map +1 -0
- package/lib/contracts/controlPlane.js +2 -0
- package/lib/contracts/controlPlane.js.map +1 -0
- package/lib/contracts/json.d.ts +9 -0
- package/lib/contracts/json.d.ts.map +1 -0
- package/lib/contracts/json.js +6 -0
- package/lib/contracts/json.js.map +1 -0
- package/lib/contracts/manifest.d.ts +158 -0
- package/lib/contracts/manifest.d.ts.map +1 -0
- package/lib/contracts/manifest.js +40 -0
- package/lib/contracts/manifest.js.map +1 -0
- package/lib/contracts/observability.d.ts +77 -0
- package/lib/contracts/observability.d.ts.map +1 -0
- package/lib/contracts/observability.js +99 -0
- package/lib/contracts/observability.js.map +1 -0
- package/lib/contracts/platformConfig.d.ts +635 -0
- package/lib/contracts/platformConfig.d.ts.map +1 -0
- package/lib/contracts/platformConfig.js +256 -0
- package/lib/contracts/platformConfig.js.map +1 -0
- package/lib/contracts/registry.d.ts +104 -0
- package/lib/contracts/registry.d.ts.map +1 -0
- package/lib/contracts/registry.js +2 -0
- package/lib/contracts/registry.js.map +1 -0
- package/lib/contracts/route.d.ts +199 -0
- package/lib/contracts/route.d.ts.map +1 -0
- package/lib/contracts/route.js +26 -0
- package/lib/contracts/route.js.map +1 -0
- package/lib/contracts/serviceConfig.d.ts +88 -0
- package/lib/contracts/serviceConfig.d.ts.map +1 -0
- package/lib/contracts/serviceConfig.js +45 -0
- package/lib/contracts/serviceConfig.js.map +1 -0
- package/lib/contracts/streaming.d.ts +76 -0
- package/lib/contracts/streaming.d.ts.map +1 -0
- package/lib/contracts/streaming.js +31 -0
- package/lib/contracts/streaming.js.map +1 -0
- package/lib/contracts/view.d.ts +149 -0
- package/lib/contracts/view.d.ts.map +1 -0
- package/lib/contracts/view.js +82 -0
- package/lib/contracts/view.js.map +1 -0
- package/lib/controlPlane/store.d.ts +24 -0
- package/lib/controlPlane/store.d.ts.map +1 -0
- package/lib/controlPlane/store.js +70 -0
- package/lib/controlPlane/store.js.map +1 -0
- package/lib/controlPlane/sync.d.ts +8 -0
- package/lib/controlPlane/sync.d.ts.map +1 -0
- package/lib/controlPlane/sync.js +24 -0
- package/lib/controlPlane/sync.js.map +1 -0
- package/lib/controlPlane/types.d.ts +15 -0
- package/lib/controlPlane/types.d.ts.map +1 -0
- package/lib/controlPlane/types.js +2 -0
- package/lib/controlPlane/types.js.map +1 -0
- package/lib/index.d.ts +40 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +40 -0
- package/lib/index.js.map +1 -0
- package/lib/runtime/auth/envelope.d.ts +32 -0
- package/lib/runtime/auth/envelope.d.ts.map +1 -0
- package/lib/runtime/auth/envelope.js +123 -0
- package/lib/runtime/auth/envelope.js.map +1 -0
- package/lib/runtime/auth/issuer.d.ts +44 -0
- package/lib/runtime/auth/issuer.d.ts.map +1 -0
- package/lib/runtime/auth/issuer.js +82 -0
- package/lib/runtime/auth/issuer.js.map +1 -0
- package/lib/runtime/auth/jwks.d.ts +7 -0
- package/lib/runtime/auth/jwks.d.ts.map +1 -0
- package/lib/runtime/auth/jwks.js +69 -0
- package/lib/runtime/auth/jwks.js.map +1 -0
- package/lib/runtime/auth/keypair.d.ts +21 -0
- package/lib/runtime/auth/keypair.d.ts.map +1 -0
- package/lib/runtime/auth/keypair.js +50 -0
- package/lib/runtime/auth/keypair.js.map +1 -0
- package/lib/runtime/auth/tokens.d.ts +25 -0
- package/lib/runtime/auth/tokens.d.ts.map +1 -0
- package/lib/runtime/auth/tokens.js +137 -0
- package/lib/runtime/auth/tokens.js.map +1 -0
- package/lib/runtime/auth/verifier.d.ts +45 -0
- package/lib/runtime/auth/verifier.d.ts.map +1 -0
- package/lib/runtime/auth/verifier.js +76 -0
- package/lib/runtime/auth/verifier.js.map +1 -0
- package/lib/runtime/bpHeaders.d.ts +10 -0
- package/lib/runtime/bpHeaders.d.ts.map +1 -0
- package/lib/runtime/bpHeaders.js +53 -0
- package/lib/runtime/bpHeaders.js.map +1 -0
- package/lib/runtime/configProvider.d.ts +41 -0
- package/lib/runtime/configProvider.d.ts.map +1 -0
- package/lib/runtime/configProvider.js +232 -0
- package/lib/runtime/configProvider.js.map +1 -0
- package/lib/runtime/configStore.d.ts +34 -0
- package/lib/runtime/configStore.d.ts.map +1 -0
- package/lib/runtime/configStore.js +197 -0
- package/lib/runtime/configStore.js.map +1 -0
- package/lib/runtime/configTicket.d.ts +49 -0
- package/lib/runtime/configTicket.d.ts.map +1 -0
- package/lib/runtime/configTicket.js +168 -0
- package/lib/runtime/configTicket.js.map +1 -0
- package/lib/runtime/h3.d.ts +28 -0
- package/lib/runtime/h3.d.ts.map +1 -0
- package/lib/runtime/h3.js +199 -0
- package/lib/runtime/h3.js.map +1 -0
- package/lib/runtime/handler.d.ts +55 -0
- package/lib/runtime/handler.d.ts.map +1 -0
- package/lib/runtime/handler.js +51 -0
- package/lib/runtime/handler.js.map +1 -0
- package/lib/runtime/http.d.ts +13 -0
- package/lib/runtime/http.d.ts.map +1 -0
- package/lib/runtime/http.js +114 -0
- package/lib/runtime/http.js.map +1 -0
- package/lib/runtime/jsonSchema.d.ts +4 -0
- package/lib/runtime/jsonSchema.d.ts.map +1 -0
- package/lib/runtime/jsonSchema.js +28 -0
- package/lib/runtime/jsonSchema.js.map +1 -0
- package/lib/runtime/manifest.d.ts +3 -0
- package/lib/runtime/manifest.d.ts.map +1 -0
- package/lib/runtime/manifest.js +5 -0
- package/lib/runtime/manifest.js.map +1 -0
- package/lib/runtime/media.d.ts +20 -0
- package/lib/runtime/media.d.ts.map +1 -0
- package/lib/runtime/media.js +70 -0
- package/lib/runtime/media.js.map +1 -0
- package/lib/runtime/registry.d.ts +67 -0
- package/lib/runtime/registry.d.ts.map +1 -0
- package/lib/runtime/registry.js +290 -0
- package/lib/runtime/registry.js.map +1 -0
- package/lib/runtime/serviceConfig.d.ts +38 -0
- package/lib/runtime/serviceConfig.d.ts.map +1 -0
- package/lib/runtime/serviceConfig.js +152 -0
- package/lib/runtime/serviceConfig.js.map +1 -0
- package/lib/runtime/statusViews.d.ts +23 -0
- package/lib/runtime/statusViews.d.ts.map +1 -0
- package/lib/runtime/statusViews.js +48 -0
- package/lib/runtime/statusViews.js.map +1 -0
- package/lib/runtime/stream.d.ts +41 -0
- package/lib/runtime/stream.d.ts.map +1 -0
- package/lib/runtime/stream.js +92 -0
- package/lib/runtime/stream.js.map +1 -0
- package/lib/runtime/streamHandler.d.ts +48 -0
- package/lib/runtime/streamHandler.d.ts.map +1 -0
- package/lib/runtime/streamHandler.js +49 -0
- package/lib/runtime/streamHandler.js.map +1 -0
- package/lib/runtime/tenantResolution.d.ts +4 -0
- package/lib/runtime/tenantResolution.d.ts.map +1 -0
- package/lib/runtime/tenantResolution.js +19 -0
- package/lib/runtime/tenantResolution.js.map +1 -0
- package/lib/runtime/uuid.d.ts +6 -0
- package/lib/runtime/uuid.d.ts.map +1 -0
- package/lib/runtime/uuid.js +27 -0
- package/lib/runtime/uuid.js.map +1 -0
- package/lib/runtime/view.d.ts +48 -0
- package/lib/runtime/view.d.ts.map +1 -0
- package/lib/runtime/view.js +111 -0
- package/lib/runtime/view.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type JwtClaims, type TokenType } from "../../contracts/auth.js";
|
|
2
|
+
import { type JwksLookupOptions } from "./jwks.js";
|
|
3
|
+
export interface SignJwtOptions {
|
|
4
|
+
privateKeyPem: string;
|
|
5
|
+
kid: string;
|
|
6
|
+
claims: Omit<JwtClaims, "iss" | "aud" | "exp" | "iat" | "jti"> & {
|
|
7
|
+
iss: string;
|
|
8
|
+
aud: string | string[];
|
|
9
|
+
expiresInSeconds: number;
|
|
10
|
+
jti?: string;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export type KeyResolver = (kid: string) => Promise<string>;
|
|
14
|
+
export interface VerifyJwtOptions {
|
|
15
|
+
jwks?: JwksLookupOptions;
|
|
16
|
+
keyResolver?: KeyResolver;
|
|
17
|
+
expectedIssuer: string;
|
|
18
|
+
expectedAudience: string;
|
|
19
|
+
expectedTokenType?: TokenType;
|
|
20
|
+
clockToleranceSeconds?: number;
|
|
21
|
+
}
|
|
22
|
+
export declare function signJwt(options: SignJwtOptions): string;
|
|
23
|
+
export declare function verifyJwt(token: string, options: VerifyJwtOptions): Promise<JwtClaims>;
|
|
24
|
+
export declare function unsafeDecodeJwtPayload(token: string): unknown;
|
|
25
|
+
//# sourceMappingURL=tokens.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../../src/runtime/auth/tokens.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAE1F,OAAO,EAAuB,KAAK,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAMxE,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC,GAAG;QAC/D,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QACvB,gBAAgB,EAAE,MAAM,CAAC;QACzB,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAE3D,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAC9B,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAmBvD;AAED,wBAAsB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,CAAC,CAmF5F;AAgCD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAI7D"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import jwt from "jsonwebtoken";
|
|
2
|
+
import { JwtClaimsSchema } from "../../contracts/auth.js";
|
|
3
|
+
import { uuidv7 } from "../uuid.js";
|
|
4
|
+
import { getSigningKeyForKid } from "./jwks.js";
|
|
5
|
+
const ALLOWED_ALGORITHM = "RS256";
|
|
6
|
+
const ALLOWED_TYP = "JWT";
|
|
7
|
+
const KID_PATTERN = /^[A-Za-z0-9_-]+$/;
|
|
8
|
+
export function signJwt(options) {
|
|
9
|
+
const now = Math.floor(Date.now() / 1000);
|
|
10
|
+
const { expiresInSeconds, jti, ...rest } = options.claims;
|
|
11
|
+
const fullClaims = {
|
|
12
|
+
...rest,
|
|
13
|
+
iat: now,
|
|
14
|
+
exp: now + expiresInSeconds,
|
|
15
|
+
jti: jti ?? generateJti()
|
|
16
|
+
};
|
|
17
|
+
const validated = JwtClaimsSchema.parse(fullClaims);
|
|
18
|
+
const signOptions = {
|
|
19
|
+
algorithm: ALLOWED_ALGORITHM,
|
|
20
|
+
keyid: options.kid,
|
|
21
|
+
header: { alg: ALLOWED_ALGORITHM, typ: ALLOWED_TYP, kid: options.kid }
|
|
22
|
+
};
|
|
23
|
+
return jwt.sign(validated, options.privateKeyPem, signOptions);
|
|
24
|
+
}
|
|
25
|
+
export async function verifyJwt(token, options) {
|
|
26
|
+
if (typeof token !== "string" || token.length === 0) {
|
|
27
|
+
throw new Error("Token is empty");
|
|
28
|
+
}
|
|
29
|
+
const parts = token.split(".");
|
|
30
|
+
if (parts.length !== 3) {
|
|
31
|
+
throw new Error("Token must have exactly three parts");
|
|
32
|
+
}
|
|
33
|
+
const [encodedHeader] = parts;
|
|
34
|
+
const header = parseHeader(encodedHeader);
|
|
35
|
+
if (header.alg !== ALLOWED_ALGORITHM) {
|
|
36
|
+
throw new Error(`Algorithm not allowed: ${String(header.alg)}`);
|
|
37
|
+
}
|
|
38
|
+
if (header.typ !== ALLOWED_TYP) {
|
|
39
|
+
throw new Error(`Token typ not allowed: ${String(header.typ)}`);
|
|
40
|
+
}
|
|
41
|
+
if (typeof header.kid !== "string") {
|
|
42
|
+
throw new Error("Token header missing kid");
|
|
43
|
+
}
|
|
44
|
+
if ("jku" in header || "x5u" in header) {
|
|
45
|
+
throw new Error("Token header contains untrusted reference (jku/x5u)");
|
|
46
|
+
}
|
|
47
|
+
if (!KID_PATTERN.test(header.kid) || header.kid.length > 256) {
|
|
48
|
+
throw new Error(`Invalid kid: must match ${KID_PATTERN.source}`);
|
|
49
|
+
}
|
|
50
|
+
const publicKeyPem = options.keyResolver
|
|
51
|
+
? await options.keyResolver(header.kid)
|
|
52
|
+
: await getSigningKeyForKid(requireJwks(options), header.kid);
|
|
53
|
+
let libVerified;
|
|
54
|
+
try {
|
|
55
|
+
libVerified = jwt.verify(token, publicKeyPem, {
|
|
56
|
+
algorithms: [ALLOWED_ALGORITHM],
|
|
57
|
+
issuer: options.expectedIssuer,
|
|
58
|
+
audience: options.expectedAudience,
|
|
59
|
+
clockTolerance: options.clockToleranceSeconds ?? 0,
|
|
60
|
+
complete: false
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
throw new Error(`Library verification failed: ${error.message}`);
|
|
65
|
+
}
|
|
66
|
+
if (!libVerified || typeof libVerified !== "object") {
|
|
67
|
+
throw new Error("Library returned non-object claims");
|
|
68
|
+
}
|
|
69
|
+
const claims = JwtClaimsSchema.parse(libVerified);
|
|
70
|
+
const now = Math.floor(Date.now() / 1000);
|
|
71
|
+
const tolerance = options.clockToleranceSeconds ?? 0;
|
|
72
|
+
if (claims.exp <= now - tolerance) {
|
|
73
|
+
throw new Error("Token is expired (manual re-check)");
|
|
74
|
+
}
|
|
75
|
+
if (typeof claims.nbf === "number" && claims.nbf > now + tolerance) {
|
|
76
|
+
throw new Error("Token is not yet valid (manual re-check)");
|
|
77
|
+
}
|
|
78
|
+
if (claims.iss !== options.expectedIssuer) {
|
|
79
|
+
throw new Error(`EIssuer mismatch (manual re-check) (${claims.iss} != ${options.expectedIssuer}`);
|
|
80
|
+
}
|
|
81
|
+
const auds = Array.isArray(claims.aud) ? claims.aud : [claims.aud];
|
|
82
|
+
if (!auds.includes(options.expectedAudience)) {
|
|
83
|
+
throw new Error(`Audience mismatch (manual re-check) (${options.expectedAudience} != ${auds.join(',')})`);
|
|
84
|
+
}
|
|
85
|
+
if (typeof claims.tenantId !== "string" || claims.tenantId.length === 0) {
|
|
86
|
+
throw new Error("tenantId missing or empty");
|
|
87
|
+
}
|
|
88
|
+
if (typeof claims.appId !== "string" || claims.appId.length === 0) {
|
|
89
|
+
throw new Error("appId missing or empty");
|
|
90
|
+
}
|
|
91
|
+
if (!Array.isArray(claims.roles)) {
|
|
92
|
+
throw new Error("roles missing");
|
|
93
|
+
}
|
|
94
|
+
if (claims.roles.some((role) => typeof role !== "string" || role.length === 0)) {
|
|
95
|
+
throw new Error("roles entries invalid");
|
|
96
|
+
}
|
|
97
|
+
if (options.expectedTokenType && claims.tokenType !== options.expectedTokenType) {
|
|
98
|
+
throw new Error(`Token type mismatch: expected ${options.expectedTokenType}, got ${claims.tokenType}`);
|
|
99
|
+
}
|
|
100
|
+
return claims;
|
|
101
|
+
}
|
|
102
|
+
function parseHeader(encodedHeader) {
|
|
103
|
+
let json;
|
|
104
|
+
try {
|
|
105
|
+
json = Buffer.from(encodedHeader, "base64url").toString("utf8");
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
throw new Error("Token header is not valid base64url");
|
|
109
|
+
}
|
|
110
|
+
let parsed;
|
|
111
|
+
try {
|
|
112
|
+
parsed = JSON.parse(json);
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
throw new Error("Token header is not valid JSON");
|
|
116
|
+
}
|
|
117
|
+
if (!parsed || typeof parsed !== "object") {
|
|
118
|
+
throw new Error("Token header is not an object");
|
|
119
|
+
}
|
|
120
|
+
return parsed;
|
|
121
|
+
}
|
|
122
|
+
function generateJti() {
|
|
123
|
+
return uuidv7();
|
|
124
|
+
}
|
|
125
|
+
function requireJwks(options) {
|
|
126
|
+
if (!options.jwks) {
|
|
127
|
+
throw new Error("verifyJwt requires either jwks or keyResolver");
|
|
128
|
+
}
|
|
129
|
+
return options.jwks;
|
|
130
|
+
}
|
|
131
|
+
export function unsafeDecodeJwtPayload(token) {
|
|
132
|
+
const parts = token.split(".");
|
|
133
|
+
if (parts.length !== 3)
|
|
134
|
+
throw new Error("Token must have exactly three parts");
|
|
135
|
+
return JSON.parse(Buffer.from(parts[1], "base64url").toString("utf8"));
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=tokens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../../src/runtime/auth/tokens.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { TokenType } from "../../contracts/auth.js";
|
|
2
|
+
import type { JwtVerifier } from "../../contracts/route.js";
|
|
3
|
+
import { type KeyResolver } from "./tokens.js";
|
|
4
|
+
export interface CreateJwksVerifierOptions {
|
|
5
|
+
jwksUri: string;
|
|
6
|
+
expectedIssuer: string;
|
|
7
|
+
expectedAudience: string;
|
|
8
|
+
expectedTokenType?: TokenType;
|
|
9
|
+
clockToleranceSeconds?: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Build a JwtVerifier that fetches signing keys from a remote JWKS endpoint.
|
|
13
|
+
* Use when verifying tokens issued by a separate auth service.
|
|
14
|
+
*/
|
|
15
|
+
export declare function createJwksVerifier(options: CreateJwksVerifierOptions): JwtVerifier;
|
|
16
|
+
export interface CreateLocalVerifierOptions {
|
|
17
|
+
keyResolver: KeyResolver;
|
|
18
|
+
expectedIssuer: string;
|
|
19
|
+
expectedAudience: string;
|
|
20
|
+
expectedTokenType?: TokenType;
|
|
21
|
+
clockToleranceSeconds?: number;
|
|
22
|
+
}
|
|
23
|
+
export interface CreateStaticJwksVerifierOptions {
|
|
24
|
+
/** JWKS document - keys pushed by the auth service at /install. */
|
|
25
|
+
jwks: {
|
|
26
|
+
keys: ReadonlyArray<Record<string, unknown>>;
|
|
27
|
+
};
|
|
28
|
+
expectedIssuer: string;
|
|
29
|
+
expectedAudience: string;
|
|
30
|
+
expectedTokenType?: TokenType;
|
|
31
|
+
clockToleranceSeconds?: number;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Build a JwtVerifier that resolves signing keys from an in-memory JWKS doc.
|
|
35
|
+
* Use when the CP cannot reach the issuer for live JWKS fetches - keys are
|
|
36
|
+
* pushed by the auth service at /install (and on rotation) and cached in
|
|
37
|
+
* app.auth.publicKeys.
|
|
38
|
+
*/
|
|
39
|
+
export declare function createStaticJwksVerifier(options: CreateStaticJwksVerifierOptions): JwtVerifier;
|
|
40
|
+
/**
|
|
41
|
+
* Build a JwtVerifier that uses an in-process key resolver.
|
|
42
|
+
* Use when the verifying service is the same as the issuer (auth provider verifying its own refresh tokens).
|
|
43
|
+
*/
|
|
44
|
+
export declare function createLocalVerifier(options: CreateLocalVerifierOptions): JwtVerifier;
|
|
45
|
+
//# sourceMappingURL=verifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifier.d.ts","sourceRoot":"","sources":["../../../src/runtime/auth/verifier.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAa,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1D,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAC9B,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,WAAW,CAYlF;AAED,MAAM,WAAW,0BAA0B;IACzC,WAAW,EAAE,WAAW,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAC9B,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,+BAA+B;IAC9C,mEAAmE;IACnE,IAAI,EAAE;QAAE,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;KAAE,CAAC;IACvD,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAC9B,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,+BAA+B,GAAG,WAAW,CA6B9F;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B,GAAG,WAAW,CAYpF"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { createPublicKey } from "node:crypto";
|
|
2
|
+
import { verifyJwt } from "./tokens.js";
|
|
3
|
+
/**
|
|
4
|
+
* Build a JwtVerifier that fetches signing keys from a remote JWKS endpoint.
|
|
5
|
+
* Use when verifying tokens issued by a separate auth service.
|
|
6
|
+
*/
|
|
7
|
+
export function createJwksVerifier(options) {
|
|
8
|
+
return {
|
|
9
|
+
verify(token) {
|
|
10
|
+
return verifyJwt(token, {
|
|
11
|
+
jwks: { jwksUri: options.jwksUri, issuer: options.expectedIssuer },
|
|
12
|
+
expectedIssuer: options.expectedIssuer,
|
|
13
|
+
expectedAudience: options.expectedAudience,
|
|
14
|
+
expectedTokenType: options.expectedTokenType,
|
|
15
|
+
clockToleranceSeconds: options.clockToleranceSeconds
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Build a JwtVerifier that resolves signing keys from an in-memory JWKS doc.
|
|
22
|
+
* Use when the CP cannot reach the issuer for live JWKS fetches - keys are
|
|
23
|
+
* pushed by the auth service at /install (and on rotation) and cached in
|
|
24
|
+
* app.auth.publicKeys.
|
|
25
|
+
*/
|
|
26
|
+
export function createStaticJwksVerifier(options) {
|
|
27
|
+
const byKid = new Map();
|
|
28
|
+
for (const jwk of options.jwks.keys) {
|
|
29
|
+
const kid = jwk.kid;
|
|
30
|
+
if (typeof kid !== "string" || kid.length === 0)
|
|
31
|
+
continue;
|
|
32
|
+
try {
|
|
33
|
+
const pem = createPublicKey({ key: jwk, format: "jwk" })
|
|
34
|
+
.export({ type: "spki", format: "pem" });
|
|
35
|
+
byKid.set(kid, pem);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// Skip unparseable key; verifier will reject tokens that need it.
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const keyResolver = async (kid) => {
|
|
42
|
+
const pem = byKid.get(kid);
|
|
43
|
+
if (!pem)
|
|
44
|
+
throw new Error(`No public key for kid ${kid}`);
|
|
45
|
+
return pem;
|
|
46
|
+
};
|
|
47
|
+
return {
|
|
48
|
+
verify(token) {
|
|
49
|
+
return verifyJwt(token, {
|
|
50
|
+
keyResolver,
|
|
51
|
+
expectedIssuer: options.expectedIssuer,
|
|
52
|
+
expectedAudience: options.expectedAudience,
|
|
53
|
+
expectedTokenType: options.expectedTokenType,
|
|
54
|
+
clockToleranceSeconds: options.clockToleranceSeconds
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Build a JwtVerifier that uses an in-process key resolver.
|
|
61
|
+
* Use when the verifying service is the same as the issuer (auth provider verifying its own refresh tokens).
|
|
62
|
+
*/
|
|
63
|
+
export function createLocalVerifier(options) {
|
|
64
|
+
return {
|
|
65
|
+
verify(token) {
|
|
66
|
+
return verifyJwt(token, {
|
|
67
|
+
keyResolver: options.keyResolver,
|
|
68
|
+
expectedIssuer: options.expectedIssuer,
|
|
69
|
+
expectedAudience: options.expectedAudience,
|
|
70
|
+
expectedTokenType: options.expectedTokenType,
|
|
71
|
+
clockToleranceSeconds: options.clockToleranceSeconds
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=verifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifier.js","sourceRoot":"","sources":["../../../src/runtime/auth/verifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG9C,OAAO,EAAE,SAAS,EAAoB,MAAM,aAAa,CAAC;AAU1D;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAkC;IACnE,OAAO;QACL,MAAM,CAAC,KAAa;YAClB,OAAO,SAAS,CAAC,KAAK,EAAE;gBACtB,IAAI,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,cAAc,EAAE;gBAClE,cAAc,EAAE,OAAO,CAAC,cAAc;gBACtC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;gBAC1C,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;gBAC5C,qBAAqB,EAAE,OAAO,CAAC,qBAAqB;aACrD,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC;AAmBD;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CAAC,OAAwC;IAC/E,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACpC,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC;QACpB,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAC1D,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,eAAe,CAAC,EAAE,GAAG,EAAE,GAAY,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;iBAC9D,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAW,CAAC;YACrD,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACtB,CAAC;QAAC,MAAM,CAAC;YACP,kEAAkE;QACpE,CAAC;IACH,CAAC;IACD,MAAM,WAAW,GAAgB,KAAK,EAAE,GAAW,EAAE,EAAE;QACrD,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC3B,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,GAAG,EAAE,CAAC,CAAC;QAC1D,OAAO,GAAG,CAAC;IACb,CAAC,CAAC;IACF,OAAO;QACL,MAAM,CAAC,KAAa;YAClB,OAAO,SAAS,CAAC,KAAK,EAAE;gBACtB,WAAW;gBACX,cAAc,EAAE,OAAO,CAAC,cAAc;gBACtC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;gBAC1C,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;gBAC5C,qBAAqB,EAAE,OAAO,CAAC,qBAAqB;aACrD,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAmC;IACrE,OAAO;QACL,MAAM,CAAC,KAAa;YAClB,OAAO,SAAS,CAAC,KAAK,EAAE;gBACtB,WAAW,EAAE,OAAO,CAAC,WAAW;gBAChC,cAAc,EAAE,OAAO,CAAC,cAAc;gBACtC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;gBAC1C,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;gBAC5C,qBAAqB,EAAE,OAAO,CAAC,qBAAqB;aACrD,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { BpHeadersApi } from "../contracts/route.js";
|
|
2
|
+
export interface BpHeadersCollector extends BpHeadersApi {
|
|
3
|
+
/** Render directives as a list of HTTP response headers. */
|
|
4
|
+
emit(): {
|
|
5
|
+
setHeaders: string[];
|
|
6
|
+
removeHeaders: string[];
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export declare function createBpHeadersCollector(): BpHeadersCollector;
|
|
10
|
+
//# sourceMappingURL=bpHeaders.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bpHeaders.d.ts","sourceRoot":"","sources":["../../src/runtime/bpHeaders.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAsB,MAAM,uBAAuB,CAAC;AAa9E,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACtD,4DAA4D;IAC5D,IAAI,IAAI;QAAE,UAAU,EAAE,MAAM,EAAE,CAAC;QAAC,aAAa,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CAC3D;AAED,wBAAgB,wBAAwB,IAAI,kBAAkB,CA2C7D"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const BP_HEADER_PREFIX_PATTERN = /^[A-Za-z0-9_-]+$/;
|
|
2
|
+
export function createBpHeadersCollector() {
|
|
3
|
+
const pending = new Map();
|
|
4
|
+
const removed = new Set();
|
|
5
|
+
return {
|
|
6
|
+
set(name, value, options = {}) {
|
|
7
|
+
validateHeaderName(name);
|
|
8
|
+
pending.set(name, {
|
|
9
|
+
value,
|
|
10
|
+
locked: options.locked ?? false,
|
|
11
|
+
scoped: options.scopeToOwner ?? Boolean(options.scopeServiceId),
|
|
12
|
+
expires: options.expiresInSeconds
|
|
13
|
+
? Math.floor(Date.now() / 1000) + options.expiresInSeconds
|
|
14
|
+
: undefined,
|
|
15
|
+
refreshPath: options.refreshPath,
|
|
16
|
+
refreshBeforeSeconds: options.refreshBeforeSeconds
|
|
17
|
+
});
|
|
18
|
+
removed.delete(name);
|
|
19
|
+
},
|
|
20
|
+
remove(name) {
|
|
21
|
+
validateHeaderName(name);
|
|
22
|
+
pending.delete(name);
|
|
23
|
+
removed.add(name);
|
|
24
|
+
},
|
|
25
|
+
emit() {
|
|
26
|
+
const setHeaders = [];
|
|
27
|
+
for (const [name, entry] of pending.entries()) {
|
|
28
|
+
const parts = [`${name}=${entry.value}`];
|
|
29
|
+
if (entry.locked)
|
|
30
|
+
parts.push("locked=true");
|
|
31
|
+
if (entry.scoped)
|
|
32
|
+
parts.push("scope=true");
|
|
33
|
+
if (entry.expires)
|
|
34
|
+
parts.push(`expires=${entry.expires}`);
|
|
35
|
+
if (entry.refreshPath)
|
|
36
|
+
parts.push(`refresh=${entry.refreshPath}`);
|
|
37
|
+
if (entry.refreshBeforeSeconds)
|
|
38
|
+
parts.push(`refreshBefore=${entry.refreshBeforeSeconds}`);
|
|
39
|
+
setHeaders.push(parts.join("; "));
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
setHeaders,
|
|
43
|
+
removeHeaders: Array.from(removed)
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function validateHeaderName(name) {
|
|
49
|
+
if (!BP_HEADER_PREFIX_PATTERN.test(name) || name.length === 0 || name.length > 128) {
|
|
50
|
+
throw new Error(`Invalid BP header name: ${name}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=bpHeaders.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bpHeaders.js","sourceRoot":"","sources":["../../src/runtime/bpHeaders.ts"],"names":[],"mappings":"AAEA,MAAM,wBAAwB,GAAG,kBAAkB,CAAC;AAgBpD,MAAM,UAAU,wBAAwB;IACtC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAyB,CAAC;IACjD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAElC,OAAO;QACL,GAAG,CAAC,IAAY,EAAE,KAAa,EAAE,UAA8B,EAAE;YAC/D,kBAAkB,CAAC,IAAI,CAAC,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE;gBAChB,KAAK;gBACL,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK;gBAC/B,MAAM,EAAE,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC;gBAC/D,OAAO,EAAE,OAAO,CAAC,gBAAgB;oBAC/B,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,gBAAgB;oBAC1D,CAAC,CAAC,SAAS;gBACb,WAAW,EAAE,OAAO,CAAC,WAAW;gBAChC,oBAAoB,EAAE,OAAO,CAAC,oBAAoB;aACnD,CAAC,CAAC;YACH,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;QAED,MAAM,CAAC,IAAY;YACjB,kBAAkB,CAAC,IAAI,CAAC,CAAC;YACzB,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;QAED,IAAI;YACF,MAAM,UAAU,GAAa,EAAE,CAAC;YAChC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;gBAC9C,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;gBACzC,IAAI,KAAK,CAAC,MAAM;oBAAE,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;gBAC5C,IAAI,KAAK,CAAC,MAAM;oBAAE,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBAC3C,IAAI,KAAK,CAAC,OAAO;oBAAE,KAAK,CAAC,IAAI,CAAC,WAAW,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC1D,IAAI,KAAK,CAAC,WAAW;oBAAE,KAAK,CAAC,IAAI,CAAC,WAAW,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;gBAClE,IAAI,KAAK,CAAC,oBAAoB;oBAAE,KAAK,CAAC,IAAI,CAAC,iBAAiB,KAAK,CAAC,oBAAoB,EAAE,CAAC,CAAC;gBAC1F,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YACpC,CAAC;YACD,OAAO;gBACL,UAAU;gBACV,aAAa,EAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;aACnC,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAY;IACtC,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;QACnF,MAAM,IAAI,KAAK,CAAC,2BAA2B,IAAI,EAAE,CAAC,CAAC;IACrD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { BetterPortalApp, BetterPortalConfig, BetterPortalOriginPolicy, BetterPortalResolvedRequestContext, BetterPortalResolvedServiceBinding, BetterPortalRouteMount } from "../contracts/platformConfig.js";
|
|
2
|
+
import { type BetterPortalHeaderTrustOptions, HeaderMap } from "./http.js";
|
|
3
|
+
export interface BetterPortalConfigProvider {
|
|
4
|
+
loadConfig(): Promise<BetterPortalConfig>;
|
|
5
|
+
}
|
|
6
|
+
export type BetterPortalConfigProviderOptions = {
|
|
7
|
+
readonly backend?: "file";
|
|
8
|
+
readonly configPath: string;
|
|
9
|
+
};
|
|
10
|
+
export declare class FileBackedBetterPortalConfigProvider implements BetterPortalConfigProvider {
|
|
11
|
+
private readonly configPath;
|
|
12
|
+
constructor(configPath: string);
|
|
13
|
+
loadConfig(): Promise<BetterPortalConfig>;
|
|
14
|
+
}
|
|
15
|
+
export declare function createBetterPortalConfigProvider(options: BetterPortalConfigProviderOptions): BetterPortalConfigProvider;
|
|
16
|
+
export declare function describeEmbeddedContextResolution(config: BetterPortalConfig, headers: HeaderMap, headerTrust?: BetterPortalHeaderTrustOptions): {
|
|
17
|
+
candidates: string[];
|
|
18
|
+
appHosts: Array<{
|
|
19
|
+
appId: string;
|
|
20
|
+
hosts: string[];
|
|
21
|
+
}>;
|
|
22
|
+
};
|
|
23
|
+
export declare function resolveThemeRequestContext(config: BetterPortalConfig, headers: HeaderMap, requestHost?: string, headerTrust?: BetterPortalHeaderTrustOptions): BetterPortalResolvedRequestContext | null;
|
|
24
|
+
export declare function resolveEmbeddedRequestContext(config: BetterPortalConfig, headers: HeaderMap, headerTrust?: BetterPortalHeaderTrustOptions): BetterPortalResolvedRequestContext | null;
|
|
25
|
+
export declare function resolveServiceForTenant(config: BetterPortalConfig, serviceId: string, context: BetterPortalResolvedRequestContext): BetterPortalResolvedServiceBinding | null;
|
|
26
|
+
export declare function buildOriginPolicy(context: BetterPortalResolvedRequestContext): BetterPortalOriginPolicy;
|
|
27
|
+
export declare function isAllowedOriginForContext(context: BetterPortalResolvedRequestContext, origin: string | null): boolean;
|
|
28
|
+
export declare function isAllowedRefererForContext(context: BetterPortalResolvedRequestContext, referer: string | null): boolean;
|
|
29
|
+
export declare function serviceBaseUrl(service: {
|
|
30
|
+
hostname: string;
|
|
31
|
+
} | {
|
|
32
|
+
endpointBaseUrl: string;
|
|
33
|
+
}): string;
|
|
34
|
+
export declare function resolveAppRoute(app: BetterPortalApp, pathname: string): BetterPortalRouteMount | null;
|
|
35
|
+
export declare function inferServicePathFromViewId(viewId: string): string;
|
|
36
|
+
export declare function buildServiceViewUrl(binding: {
|
|
37
|
+
hostname: string;
|
|
38
|
+
} | {
|
|
39
|
+
endpointBaseUrl: string;
|
|
40
|
+
}, route: BetterPortalRouteMount, currentPath: string): string;
|
|
41
|
+
//# sourceMappingURL=configProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configProvider.d.ts","sourceRoot":"","sources":["../../src/runtime/configProvider.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,eAAe,EACf,kBAAkB,EAElB,wBAAwB,EAExB,kCAAkC,EAClC,kCAAkC,EAClC,sBAAsB,EACvB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,KAAK,8BAA8B,EACnC,SAAS,EAIV,MAAM,WAAW,CAAC;AAEnB,MAAM,WAAW,0BAA0B;IACzC,UAAU,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAAC;CAC3C;AAED,MAAM,MAAM,iCAAiC,GACzC;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAM/D,qBAAa,oCAAqC,YAAW,0BAA0B;IACzE,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,EAAE,MAAM;IAEzC,UAAU,IAAI,OAAO,CAAC,kBAAkB,CAAC;CAehD;AAED,wBAAgB,gCAAgC,CAAC,OAAO,EAAE,iCAAiC,GAAG,0BAA0B,CAEvH;AA6BD,wBAAgB,iCAAiC,CAC/C,MAAM,EAAE,kBAAkB,EAC1B,OAAO,EAAE,SAAS,EAClB,WAAW,GAAE,8BAAmC,GAC/C;IACD,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CACrD,CAaA;AAoBD,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,kBAAkB,EAC1B,OAAO,EAAE,SAAS,EAClB,WAAW,CAAC,EAAE,MAAM,EACpB,WAAW,GAAE,8BAAmC,GAC/C,kCAAkC,GAAG,IAAI,CAW3C;AAED,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,kBAAkB,EAC1B,OAAO,EAAE,SAAS,EAClB,WAAW,GAAE,8BAAmC,GAC/C,kCAAkC,GAAG,IAAI,CAQ3C;AAED,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,kBAAkB,EAC1B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,kCAAkC,GAC1C,kCAAkC,GAAG,IAAI,CAkC3C;AAiBD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kCAAkC,GAAG,wBAAwB,CAQvG;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,kCAAkC,EAC3C,MAAM,EAAE,MAAM,GAAG,IAAI,GACpB,OAAO,CAMT;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,kCAAkC,EAC3C,OAAO,EAAE,MAAM,GAAG,IAAI,GACrB,OAAO,CAMT;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,eAAe,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAGlG;AA4BD,wBAAgB,eAAe,CAAC,GAAG,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,GAAG,sBAAsB,GAAG,IAAI,CAGrG;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGjE;AAsCD,wBAAgB,mBAAmB,CACjC,OAAO,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,eAAe,EAAE,MAAM,CAAA;CAAE,EAC3D,KAAK,EAAE,sBAAsB,EAC7B,WAAW,EAAE,MAAM,GAClB,MAAM,CAWR"}
|