@go-to-k/cdkd 0.118.0 → 0.119.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/cli.js +70 -18
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -40448,14 +40448,23 @@ function resolveRestV1Authorizer(authorizerLogicalId, template, stackName, decla
|
|
|
40448
40448
|
if (type === "COGNITO_USER_POOLS") {
|
|
40449
40449
|
const arns = props["ProviderARNs"];
|
|
40450
40450
|
if (!Array.isArray(arns) || arns.length === 0) throw new RouteDiscoveryError(`${stackName}/${authorizerLogicalId}: COGNITO_USER_POOLS authorizer is missing ProviderARNs.`);
|
|
40451
|
-
const
|
|
40452
|
-
|
|
40451
|
+
const pools = arns.map((entry, idx) => {
|
|
40452
|
+
const arn = pickStringFromArn(entry, `${stackName}/${authorizerLogicalId}.ProviderARNs[${idx}]`);
|
|
40453
|
+
const parsed = parseCognitoUserPoolArn(arn, `${stackName}/${authorizerLogicalId}.ProviderARNs[${idx}]`);
|
|
40454
|
+
return {
|
|
40455
|
+
userPoolArn: arn,
|
|
40456
|
+
region: parsed.region,
|
|
40457
|
+
userPoolId: parsed.userPoolId
|
|
40458
|
+
};
|
|
40459
|
+
});
|
|
40460
|
+
const first = pools[0];
|
|
40453
40461
|
return {
|
|
40454
40462
|
kind: "cognito",
|
|
40455
40463
|
logicalId: authorizerLogicalId,
|
|
40456
|
-
|
|
40457
|
-
|
|
40458
|
-
|
|
40464
|
+
pools,
|
|
40465
|
+
userPoolArn: first.userPoolArn,
|
|
40466
|
+
region: first.region,
|
|
40467
|
+
userPoolId: first.userPoolId,
|
|
40459
40468
|
declaredAt
|
|
40460
40469
|
};
|
|
40461
40470
|
}
|
|
@@ -40677,7 +40686,9 @@ function parseCognitoIssuer(issuer) {
|
|
|
40677
40686
|
/**
|
|
40678
40687
|
* Pull a string out of a {Ref} / literal entry under `ProviderARNs`.
|
|
40679
40688
|
* CDK's CognitoUserPoolsAuthorizer emits a literal array of `Fn::GetAtt:
|
|
40680
|
-
* [<UserPool>, 'Arn']` entries — we accept both.
|
|
40689
|
+
* [<UserPool>, 'Arn']` entries — we accept both. The `location` argument
|
|
40690
|
+
* carries the full `<stack>/<authorizer>.ProviderARNs[<idx>]` path so the
|
|
40691
|
+
* error names the offending entry exactly.
|
|
40681
40692
|
*/
|
|
40682
40693
|
function pickStringFromArn(value, location) {
|
|
40683
40694
|
if (typeof value === "string") return value;
|
|
@@ -40685,10 +40696,10 @@ function pickStringFromArn(value, location) {
|
|
|
40685
40696
|
const obj = value;
|
|
40686
40697
|
if ("Fn::GetAtt" in obj) {
|
|
40687
40698
|
const arg = obj["Fn::GetAtt"];
|
|
40688
|
-
if (Array.isArray(arg) && arg.length === 2 && typeof arg[0] === "string" && arg[1] === "Arn") throw new RouteDiscoveryError(`${location}:
|
|
40699
|
+
if (Array.isArray(arg) && arg.length === 2 && typeof arg[0] === "string" && arg[1] === "Arn") throw new RouteDiscoveryError(`${location}: uses Fn::GetAtt against logical ID '${arg[0]}'. cdkd local start-api needs the literal ARN string to derive the JWKS URL — set the user pool ARN explicitly via 'authorizer.providerArns' on the CDK construct, or upgrade to JWT (HTTP v2) which encodes the pool in the Issuer URL.`);
|
|
40689
40700
|
}
|
|
40690
40701
|
}
|
|
40691
|
-
throw new RouteDiscoveryError(`${location}:
|
|
40702
|
+
throw new RouteDiscoveryError(`${location}: must be a literal string (got ${shortJson(value)}).`);
|
|
40692
40703
|
}
|
|
40693
40704
|
/**
|
|
40694
40705
|
* Parse and clamp a TTL value to `[0, max]` with a default fallback.
|
|
@@ -41206,21 +41217,36 @@ function buildJwksUrlFromIssuer(issuer) {
|
|
|
41206
41217
|
return `${issuer.replace(/\/+$/, "")}/.well-known/jwks.json`;
|
|
41207
41218
|
}
|
|
41208
41219
|
/**
|
|
41209
|
-
*
|
|
41210
|
-
*
|
|
41211
|
-
|
|
41212
|
-
|
|
41220
|
+
* Build the expected `iss` claim URL for a Cognito user pool. Matches the
|
|
41221
|
+
* issuer Cognito embeds in every minted JWT.
|
|
41222
|
+
*/
|
|
41223
|
+
function buildCognitoIssuer(region, userPoolId) {
|
|
41224
|
+
return `https://cognito-idp.${region}.amazonaws.com/${userPoolId}`;
|
|
41225
|
+
}
|
|
41226
|
+
/**
|
|
41227
|
+
* Verify a Bearer JWT against the Cognito user pool(s) referenced by the
|
|
41228
|
+
* authorizer. With a multi-pool authorizer (`ProviderARNs[]` of length
|
|
41229
|
+
* 1+) the request-time pool selection is driven by the JWT's unverified
|
|
41230
|
+
* `iss` claim — only the matching pool's JWKS is used for signature
|
|
41231
|
+
* verification, so a token issued by pool A cannot be verified against
|
|
41232
|
+
* pool B's keys. Issuer mismatch against EVERY configured pool rejects
|
|
41233
|
+
* with 401.
|
|
41213
41234
|
*
|
|
41214
41235
|
* Returns `{ allow: false }` on:
|
|
41215
41236
|
* - missing / malformed Authorization header (caller surfaces 401);
|
|
41216
41237
|
* - signature verification failure;
|
|
41217
41238
|
* - expired token (`exp` in the past);
|
|
41218
|
-
* - issuer mismatch (token's `iss` doesn't match
|
|
41239
|
+
* - issuer mismatch (token's `iss` doesn't match any configured pool);
|
|
41219
41240
|
* - audience mismatch (token's `aud` not in the configured allowlist).
|
|
41220
41241
|
*
|
|
41221
41242
|
* Returns `{ allow: true, principalId, context }` on:
|
|
41222
|
-
* - successful verification;
|
|
41223
|
-
* - JWKS-unreachable pass-through mode
|
|
41243
|
+
* - successful verification against the matching pool;
|
|
41244
|
+
* - JWKS-unreachable pass-through mode for the matching pool (with a
|
|
41245
|
+
* warn line on first hit; per-pool TTL handled by the cache).
|
|
41246
|
+
*
|
|
41247
|
+
* Backward compat: a single-element `ProviderARNs[]` (the historical
|
|
41248
|
+
* single-pool case) behaves identically to pre-PR — `pools[0]` is the
|
|
41249
|
+
* only candidate and the `iss` check matches it.
|
|
41224
41250
|
*/
|
|
41225
41251
|
async function verifyCognitoJwt(authorizer, authorizationHeader, jwksCache, opts = {}) {
|
|
41226
41252
|
const now = opts.now ?? (() => Date.now());
|
|
@@ -41230,7 +41256,33 @@ async function verifyCognitoJwt(authorizer, authorizationHeader, jwksCache, opts
|
|
|
41230
41256
|
identityHash: void 0,
|
|
41231
41257
|
ttlSeconds: 0
|
|
41232
41258
|
};
|
|
41233
|
-
|
|
41259
|
+
const pools = authorizer.pools && authorizer.pools.length > 0 ? authorizer.pools : [{
|
|
41260
|
+
userPoolArn: authorizer.userPoolArn,
|
|
41261
|
+
region: authorizer.region,
|
|
41262
|
+
userPoolId: authorizer.userPoolId
|
|
41263
|
+
}];
|
|
41264
|
+
const parsed = parseJwt(token);
|
|
41265
|
+
const identityHash = buildIdentityHash([token]);
|
|
41266
|
+
let selectedPool = pools[0];
|
|
41267
|
+
let issMatched = false;
|
|
41268
|
+
if (parsed && typeof parsed.payload["iss"] === "string") {
|
|
41269
|
+
const tokenIss = parsed.payload["iss"].replace(/\/+$/, "");
|
|
41270
|
+
for (const pool of pools) if (buildCognitoIssuer(pool.region, pool.userPoolId) === tokenIss) {
|
|
41271
|
+
selectedPool = pool;
|
|
41272
|
+
issMatched = true;
|
|
41273
|
+
break;
|
|
41274
|
+
}
|
|
41275
|
+
if (!issMatched) return {
|
|
41276
|
+
allow: false,
|
|
41277
|
+
identityHash,
|
|
41278
|
+
ttlSeconds: 0
|
|
41279
|
+
};
|
|
41280
|
+
} else if (pools.length > 1) return {
|
|
41281
|
+
allow: false,
|
|
41282
|
+
identityHash,
|
|
41283
|
+
ttlSeconds: 0
|
|
41284
|
+
};
|
|
41285
|
+
return verifyAndShape(token, buildCognitoJwksUrl(selectedPool.region, selectedPool.userPoolId), buildCognitoIssuer(selectedPool.region, selectedPool.userPoolId), void 0, jwksCache, opts.warned, now);
|
|
41234
41286
|
}
|
|
41235
41287
|
/**
|
|
41236
41288
|
* Verify a Bearer JWT against an HTTP v2 JWT authorizer's `JwtConfiguration`.
|
|
@@ -42712,7 +42764,7 @@ async function prewarmJwks(routesWithAuth, jwksCache) {
|
|
|
42712
42764
|
for (const entry of routesWithAuth) {
|
|
42713
42765
|
const auth = entry.authorizer;
|
|
42714
42766
|
if (!auth) continue;
|
|
42715
|
-
if (auth.kind === "cognito") urls.add(buildCognitoJwksUrl(
|
|
42767
|
+
if (auth.kind === "cognito") for (const pool of auth.pools) urls.add(buildCognitoJwksUrl(pool.region, pool.userPoolId));
|
|
42716
42768
|
else if (auth.kind === "jwt") {
|
|
42717
42769
|
const url = auth.region && auth.userPoolId ? buildCognitoJwksUrl(auth.region, auth.userPoolId) : buildJwksUrlFromIssuer(auth.issuer);
|
|
42718
42770
|
urls.add(url);
|
|
@@ -46172,7 +46224,7 @@ function reorderArgs(argv) {
|
|
|
46172
46224
|
*/
|
|
46173
46225
|
async function main() {
|
|
46174
46226
|
const program = new Command();
|
|
46175
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.
|
|
46227
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.119.0");
|
|
46176
46228
|
program.addCommand(createBootstrapCommand());
|
|
46177
46229
|
program.addCommand(createSynthCommand());
|
|
46178
46230
|
program.addCommand(createListCommand());
|