@pymthouse/builder-sdk 0.4.4 → 0.4.5
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 +120 -5
- package/dist/{client-zCskUJag.d.ts → client-BhNz0ZAA.d.ts} +9 -3
- package/dist/{client-C0HgAugK.d.cts → client-GP-mTEI7.d.cts} +9 -3
- package/dist/device.d.cts +1 -1
- package/dist/device.d.ts +1 -1
- package/dist/env.cjs +40 -3
- package/dist/env.cjs.map +1 -1
- package/dist/env.d.cts +2 -2
- package/dist/env.d.ts +2 -2
- package/dist/env.js +40 -3
- package/dist/env.js.map +1 -1
- package/dist/{index-CAIAYJv7.d.cts → index-M0tsyotJ.d.cts} +1 -1
- package/dist/{index-BL1wpOki.d.ts → index-rC8smShg.d.ts} +1 -1
- package/dist/index.cjs +40 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +40 -3
- package/dist/index.js.map +1 -1
- package/dist/{proxy-KrA1vEmh.d.ts → proxy-CZLY0IfL.d.cts} +5 -2
- package/dist/{proxy-0wa8QZIU.d.cts → proxy-D36SpZ6k.d.ts} +5 -2
- package/dist/signer/gateway.cjs +542 -0
- package/dist/signer/gateway.cjs.map +1 -0
- package/dist/signer/gateway.d.cts +81 -0
- package/dist/signer/gateway.d.ts +81 -0
- package/dist/signer/gateway.js +538 -0
- package/dist/signer/gateway.js.map +1 -0
- package/dist/signer/server.cjs +225 -0
- package/dist/signer/server.cjs.map +1 -1
- package/dist/signer/server.d.cts +35 -4
- package/dist/signer/server.d.ts +35 -4
- package/dist/signer/server.js +219 -1
- package/dist/signer/server.js.map +1 -1
- package/dist/signer/webhook/adapters/oidc.d.cts +2 -2
- package/dist/signer/webhook/adapters/oidc.d.ts +2 -2
- package/dist/signer/webhook.d.cts +3 -3
- package/dist/signer/webhook.d.ts +3 -3
- package/dist/tokens.d.cts +1 -1
- package/dist/tokens.d.ts +1 -1
- package/dist/{types-BORaHW_x.d.cts → types-CcP67AZm.d.cts} +2 -0
- package/dist/{types-BORaHW_x.d.ts → types-CcP67AZm.d.ts} +2 -0
- package/dist/verify.d.cts +1 -1
- package/dist/verify.d.ts +1 -1
- package/package.json +6 -1
package/dist/signer/server.cjs
CHANGED
|
@@ -452,6 +452,46 @@ async function mintUserSignerToken(options) {
|
|
|
452
452
|
return parseMintUserSignerTokenResponse(parsed);
|
|
453
453
|
}
|
|
454
454
|
|
|
455
|
+
// src/signer/direct-signer.ts
|
|
456
|
+
var DIRECT_SIGNER_PATHS = {
|
|
457
|
+
signOrchestratorInfo: "sign-orchestrator-info",
|
|
458
|
+
generateLivePayment: "generate-live-payment",
|
|
459
|
+
discoverOrchestrators: "discover-orchestrators"
|
|
460
|
+
};
|
|
461
|
+
function signerEndpointUrl(signerBaseUrl, path) {
|
|
462
|
+
const base = stripTrailingSlashes(signerBaseUrl.trim());
|
|
463
|
+
if (!base) {
|
|
464
|
+
throw new PmtHouseError("signerBaseUrl is required", {
|
|
465
|
+
status: 400,
|
|
466
|
+
code: "invalid_signer_url"
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
const suffix = path.replace(/^\/+/, "");
|
|
470
|
+
return `${base}/${suffix}`;
|
|
471
|
+
}
|
|
472
|
+
function signerUrlFromExchangeResponse(response) {
|
|
473
|
+
const url = response.signerUrl?.trim();
|
|
474
|
+
return url || void 0;
|
|
475
|
+
}
|
|
476
|
+
function assertDirectSignerBaseUrl(signerBaseUrl) {
|
|
477
|
+
let parsed;
|
|
478
|
+
try {
|
|
479
|
+
parsed = new URL(signerBaseUrl.trim());
|
|
480
|
+
} catch {
|
|
481
|
+
throw new PmtHouseError("signer URL must be an absolute http(s) URL", {
|
|
482
|
+
status: 400,
|
|
483
|
+
code: "invalid_signer_url"
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
const pathname = stripTrailingSlashes(parsed.pathname);
|
|
487
|
+
if (pathname === "/api/signer" || pathname.startsWith("/api/signer/")) {
|
|
488
|
+
throw new PmtHouseError(
|
|
489
|
+
"signer URL must be the remote signer DMZ base, not a dashboard /api/signer/* proxy path. Exchange at the platform facade, then call signer endpoints directly using signerUrl from the exchange response.",
|
|
490
|
+
{ status: 400, code: "invalid_signer_url" }
|
|
491
|
+
);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
455
495
|
// src/signer/device-exchange.ts
|
|
456
496
|
var TOKEN_EXCHANGE_GRANT = "urn:ietf:params:oauth:grant-type:token-exchange";
|
|
457
497
|
var SUBJECT_ACCESS_TOKEN_TYPE = "urn:ietf:params:oauth:token-type:access_token";
|
|
@@ -609,6 +649,9 @@ async function exchangeDeviceTokenForSigner(options) {
|
|
|
609
649
|
const accessToken = extractSignerAccessTokenFromExchangeBody(parsed);
|
|
610
650
|
const signerUrlRaw = parsed.signerUrl ?? parsed.signer_url;
|
|
611
651
|
const signerUrl = typeof signerUrlRaw === "string" && signerUrlRaw.trim() ? signerUrlRaw.trim() : void 0;
|
|
652
|
+
if (signerUrl) {
|
|
653
|
+
assertDirectSignerBaseUrl(signerUrl);
|
|
654
|
+
}
|
|
612
655
|
return normalizeDeviceExchangeResponse(
|
|
613
656
|
{
|
|
614
657
|
access_token: accessToken,
|
|
@@ -788,6 +831,9 @@ async function exchangeApiKeyForSigner(options) {
|
|
|
788
831
|
const accessToken = extractSignerAccessTokenFromExchangeBody(parsed);
|
|
789
832
|
const signerUrlRaw = parsed.signerUrl ?? parsed.signer_url;
|
|
790
833
|
const signerUrl = typeof signerUrlRaw === "string" && signerUrlRaw.trim() ? signerUrlRaw.trim() : void 0;
|
|
834
|
+
if (signerUrl) {
|
|
835
|
+
assertDirectSignerBaseUrl(signerUrl);
|
|
836
|
+
}
|
|
791
837
|
return normalizeDeviceExchangeResponse(
|
|
792
838
|
{
|
|
793
839
|
access_token: accessToken,
|
|
@@ -843,6 +889,178 @@ function createApiKeyExchangeHandler(config) {
|
|
|
843
889
|
};
|
|
844
890
|
}
|
|
845
891
|
|
|
892
|
+
// src/signer/gateway-token.ts
|
|
893
|
+
function requireString(value, label) {
|
|
894
|
+
if (typeof value !== "string") {
|
|
895
|
+
throw new PmtHouseError(`${label} must be a string`, {
|
|
896
|
+
status: 400,
|
|
897
|
+
code: "invalid_gateway_token"
|
|
898
|
+
});
|
|
899
|
+
}
|
|
900
|
+
return value.trim();
|
|
901
|
+
}
|
|
902
|
+
function optionalString(value, label) {
|
|
903
|
+
if (value === void 0 || value === null) {
|
|
904
|
+
return void 0;
|
|
905
|
+
}
|
|
906
|
+
return requireString(value, label) || void 0;
|
|
907
|
+
}
|
|
908
|
+
function encodeBase64Json(value) {
|
|
909
|
+
const json = JSON.stringify(value);
|
|
910
|
+
if (typeof Buffer === "undefined") {
|
|
911
|
+
const binary = Array.from(
|
|
912
|
+
new TextEncoder().encode(json),
|
|
913
|
+
(c) => String.fromCodePoint(c)
|
|
914
|
+
).join("");
|
|
915
|
+
return btoa(binary);
|
|
916
|
+
}
|
|
917
|
+
return Buffer.from(json, "utf8").toString("base64");
|
|
918
|
+
}
|
|
919
|
+
function decodeBase64Json(token) {
|
|
920
|
+
const trimmed = requireString(token, "gateway token");
|
|
921
|
+
let json;
|
|
922
|
+
try {
|
|
923
|
+
if (typeof Buffer === "undefined") {
|
|
924
|
+
json = new TextDecoder().decode(
|
|
925
|
+
Uint8Array.from(atob(trimmed), (c) => c.codePointAt(0) ?? 0)
|
|
926
|
+
);
|
|
927
|
+
} else {
|
|
928
|
+
json = Buffer.from(trimmed, "base64").toString("utf8");
|
|
929
|
+
}
|
|
930
|
+
} catch {
|
|
931
|
+
throw new PmtHouseError("Invalid gateway token: expected base64-encoded JSON", {
|
|
932
|
+
status: 400,
|
|
933
|
+
code: "invalid_gateway_token"
|
|
934
|
+
});
|
|
935
|
+
}
|
|
936
|
+
try {
|
|
937
|
+
return JSON.parse(json);
|
|
938
|
+
} catch {
|
|
939
|
+
throw new PmtHouseError("Invalid gateway token: expected UTF-8 JSON payload", {
|
|
940
|
+
status: 400,
|
|
941
|
+
code: "invalid_gateway_token"
|
|
942
|
+
});
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
function normalizeStringMap(map) {
|
|
946
|
+
if (!map) {
|
|
947
|
+
return void 0;
|
|
948
|
+
}
|
|
949
|
+
const entries = Object.entries(map).filter(
|
|
950
|
+
([key, value]) => key.trim() && typeof value === "string"
|
|
951
|
+
);
|
|
952
|
+
return entries.length > 0 ? Object.fromEntries(entries) : void 0;
|
|
953
|
+
}
|
|
954
|
+
function buildGatewayToken(input) {
|
|
955
|
+
if (input === null || typeof input !== "object") {
|
|
956
|
+
throw new PmtHouseError("buildGatewayToken requires an input object", {
|
|
957
|
+
status: 400,
|
|
958
|
+
code: "invalid_gateway_token"
|
|
959
|
+
});
|
|
960
|
+
}
|
|
961
|
+
const signer = requireString(input.signer, "signer URL");
|
|
962
|
+
if (!signer) {
|
|
963
|
+
throw new PmtHouseError("buildGatewayToken requires a non-empty signer URL", {
|
|
964
|
+
status: 400,
|
|
965
|
+
code: "invalid_gateway_token"
|
|
966
|
+
});
|
|
967
|
+
}
|
|
968
|
+
const signerHeaders = { ...input.signerHeaders };
|
|
969
|
+
const bundle = { signer };
|
|
970
|
+
const discovery = optionalString(input.discovery, "discovery URL");
|
|
971
|
+
if (discovery) {
|
|
972
|
+
bundle.discovery = discovery;
|
|
973
|
+
}
|
|
974
|
+
const rawOrchestrators = input.orchestrators ?? [];
|
|
975
|
+
if (!Array.isArray(rawOrchestrators)) {
|
|
976
|
+
throw new PmtHouseError("orchestrators must be an array of strings", {
|
|
977
|
+
status: 400,
|
|
978
|
+
code: "invalid_gateway_token"
|
|
979
|
+
});
|
|
980
|
+
}
|
|
981
|
+
const orchestrators = rawOrchestrators.map((entry) => requireString(entry, "orchestrator entry")).filter((entry) => entry.length > 0);
|
|
982
|
+
if (orchestrators.length > 0) {
|
|
983
|
+
bundle.orchestrators = orchestrators;
|
|
984
|
+
}
|
|
985
|
+
if (input.auth?.kind === "signerJwt") {
|
|
986
|
+
const accessToken = requireString(input.auth.accessToken, "signerJwt accessToken");
|
|
987
|
+
if (!accessToken) {
|
|
988
|
+
throw new PmtHouseError("signerJwt auth requires a non-empty accessToken", {
|
|
989
|
+
status: 400,
|
|
990
|
+
code: "invalid_gateway_token"
|
|
991
|
+
});
|
|
992
|
+
}
|
|
993
|
+
signerHeaders.Authorization = `Bearer ${accessToken}`;
|
|
994
|
+
} else if (input.auth?.kind === "pmthApiKey") {
|
|
995
|
+
const apiKey = requireString(input.auth.apiKey, "pmthApiKey apiKey");
|
|
996
|
+
if (!apiKey) {
|
|
997
|
+
throw new PmtHouseError("pmthApiKey auth requires a non-empty apiKey", {
|
|
998
|
+
status: 400,
|
|
999
|
+
code: "invalid_gateway_token"
|
|
1000
|
+
});
|
|
1001
|
+
}
|
|
1002
|
+
bundle.api_key = apiKey;
|
|
1003
|
+
const billing = optionalString(input.auth.billing, "pmthApiKey billing URL");
|
|
1004
|
+
if (billing) {
|
|
1005
|
+
bundle.billing = billing;
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
const normalizedSignerHeaders = normalizeStringMap(signerHeaders);
|
|
1009
|
+
if (normalizedSignerHeaders) {
|
|
1010
|
+
bundle.signer_headers = normalizedSignerHeaders;
|
|
1011
|
+
}
|
|
1012
|
+
const normalizedDiscoveryHeaders = normalizeStringMap(input.discoveryHeaders);
|
|
1013
|
+
if (normalizedDiscoveryHeaders) {
|
|
1014
|
+
bundle.discovery_headers = normalizedDiscoveryHeaders;
|
|
1015
|
+
}
|
|
1016
|
+
return encodeBase64Json(bundle);
|
|
1017
|
+
}
|
|
1018
|
+
function decodeGatewayToken(token) {
|
|
1019
|
+
const payload = decodeBase64Json(token);
|
|
1020
|
+
if (payload === null || typeof payload !== "object" || Array.isArray(payload)) {
|
|
1021
|
+
throw new PmtHouseError("Invalid gateway token: payload must be a JSON object", {
|
|
1022
|
+
status: 400,
|
|
1023
|
+
code: "invalid_gateway_token"
|
|
1024
|
+
});
|
|
1025
|
+
}
|
|
1026
|
+
return payload;
|
|
1027
|
+
}
|
|
1028
|
+
async function mintGatewayToken(options) {
|
|
1029
|
+
let accessToken;
|
|
1030
|
+
if (options.source === "m2m") {
|
|
1031
|
+
const minted = await mintUserSignerToken({
|
|
1032
|
+
issuerUrl: options.issuerUrl,
|
|
1033
|
+
m2mClientId: options.m2mClientId,
|
|
1034
|
+
m2mClientSecret: options.m2mClientSecret,
|
|
1035
|
+
externalUserId: options.externalUserId,
|
|
1036
|
+
fetch: options.fetch,
|
|
1037
|
+
allowInsecureHttp: options.allowInsecureHttp
|
|
1038
|
+
});
|
|
1039
|
+
accessToken = minted.jwt;
|
|
1040
|
+
} else {
|
|
1041
|
+
const minted = await mintSignerSessionFromApiKey({
|
|
1042
|
+
issuerUrl: options.issuerUrl,
|
|
1043
|
+
publicClientId: options.publicClientId,
|
|
1044
|
+
m2mClientId: options.m2mClientId,
|
|
1045
|
+
m2mClientSecret: options.m2mClientSecret,
|
|
1046
|
+
apiKey: options.apiKey,
|
|
1047
|
+
scope: options.scope,
|
|
1048
|
+
audience: options.audience,
|
|
1049
|
+
fetch: options.fetch,
|
|
1050
|
+
allowInsecureHttp: options.allowInsecureHttp
|
|
1051
|
+
});
|
|
1052
|
+
accessToken = minted.access_token;
|
|
1053
|
+
}
|
|
1054
|
+
return buildGatewayToken({
|
|
1055
|
+
signer: options.signer,
|
|
1056
|
+
discovery: options.discovery,
|
|
1057
|
+
orchestrators: options.orchestrators,
|
|
1058
|
+
signerHeaders: options.signerHeaders,
|
|
1059
|
+
discoveryHeaders: options.discoveryHeaders,
|
|
1060
|
+
auth: { kind: "signerJwt", accessToken }
|
|
1061
|
+
});
|
|
1062
|
+
}
|
|
1063
|
+
|
|
846
1064
|
// src/signer/proxy.ts
|
|
847
1065
|
var HTTP_DMZ_TOKEN_MAX_ENTRIES = 100;
|
|
848
1066
|
var HTTP_DMZ_TOKEN_TTL_MS = 3.5 * 60 * 1e3;
|
|
@@ -1251,12 +1469,16 @@ function createDirectSignerProxyHandler(config) {
|
|
|
1251
1469
|
return handler;
|
|
1252
1470
|
}
|
|
1253
1471
|
|
|
1472
|
+
exports.DIRECT_SIGNER_PATHS = DIRECT_SIGNER_PATHS;
|
|
1254
1473
|
exports.LIVEPEER_REMOTE_SIGNER_AUDIENCE = LIVEPEER_REMOTE_SIGNER_AUDIENCE;
|
|
1255
1474
|
exports.SIGN_MINT_USER_TOKEN_SCOPE = SIGN_MINT_USER_TOKEN_SCOPE;
|
|
1475
|
+
exports.assertDirectSignerBaseUrl = assertDirectSignerBaseUrl;
|
|
1476
|
+
exports.buildGatewayToken = buildGatewayToken;
|
|
1256
1477
|
exports.createApiKeyExchangeHandler = createApiKeyExchangeHandler;
|
|
1257
1478
|
exports.createDeviceExchangeHandler = createDeviceExchangeHandler;
|
|
1258
1479
|
exports.createDirectSignerProxyHandler = createDirectSignerProxyHandler;
|
|
1259
1480
|
exports.createSignerTokenManager = createSignerTokenManager;
|
|
1481
|
+
exports.decodeGatewayToken = decodeGatewayToken;
|
|
1260
1482
|
exports.decodeJwtPayload = decodeJwtPayload;
|
|
1261
1483
|
exports.exchangeApiKeyForSigner = exchangeApiKeyForSigner;
|
|
1262
1484
|
exports.exchangeDeviceTokenForSigner = exchangeDeviceTokenForSigner;
|
|
@@ -1266,6 +1488,7 @@ exports.forwardToSigner = forwardToSigner;
|
|
|
1266
1488
|
exports.getCachedDmzBearerToken = getCachedDmzBearerToken;
|
|
1267
1489
|
exports.identityFromJwtPayload = identityFromJwtPayload;
|
|
1268
1490
|
exports.livepeerIdentityHeaders = livepeerIdentityHeaders;
|
|
1491
|
+
exports.mintGatewayToken = mintGatewayToken;
|
|
1269
1492
|
exports.mintSignerSessionFromApiKey = mintSignerSessionFromApiKey;
|
|
1270
1493
|
exports.mintSignerTokenFromDeviceToken = mintSignerTokenFromDeviceToken;
|
|
1271
1494
|
exports.mintUserAccessTokenFromApiKey = mintUserAccessTokenFromApiKey;
|
|
@@ -1281,7 +1504,9 @@ exports.pickConflictingStringAliases = pickConflictingStringAliases;
|
|
|
1281
1504
|
exports.probeSignerHttpReachability = probeSignerHttpReachability;
|
|
1282
1505
|
exports.readSignerUpstreamBody = readSignerUpstreamBody;
|
|
1283
1506
|
exports.resolveSignerBaseUrl = resolveSignerBaseUrl;
|
|
1507
|
+
exports.signerEndpointUrl = signerEndpointUrl;
|
|
1284
1508
|
exports.signerJwtAudience = signerJwtAudience;
|
|
1509
|
+
exports.signerUrlFromExchangeResponse = signerUrlFromExchangeResponse;
|
|
1285
1510
|
exports.stripSignerUsageFromResponse = stripSignerUsageFromResponse;
|
|
1286
1511
|
//# sourceMappingURL=server.cjs.map
|
|
1287
1512
|
//# sourceMappingURL=server.cjs.map
|