diff --git a/package.json b/package.json index 22096f46..74be2ce0 100644 --- a/package.json +++ b/package.json @@ -50,8 +50,8 @@ "@types/node": "16.9.2", "@typescript-eslint/eslint-plugin": "5.54.0", "@typescript-eslint/parser": "5.54.0", - "aws-cdk": "^2.24.1", - "aws-cdk-lib": "2.24.1", + "aws-cdk": "^2.28.0", + "aws-cdk-lib": "2.28.0", "axios": "1.3.4", "constructs": "10.0.5", "cross-env": "7.0.3", diff --git a/packages/cdk/package.json b/packages/cdk/package.json index 1ff66f30..5bc539b0 100644 --- a/packages/cdk/package.json +++ b/packages/cdk/package.json @@ -17,7 +17,7 @@ "@pwrdrvr/microapps-app-nextjs-demo-cdk": "0.7.0", "@pwrdrvr/microapps-app-release-cdk": "0.5.3", "source-map-support": "0.5.21", - "aws-cdk-lib": "2.24.1", + "aws-cdk-lib": "2.28.0", "constructs": "10.0.5" }, "devDependencies": { diff --git a/packages/microapps-cdk/.projen/deps.json b/packages/microapps-cdk/.projen/deps.json index a99451a6..9f2fa777 100644 --- a/packages/microapps-cdk/.projen/deps.json +++ b/packages/microapps-cdk/.projen/deps.json @@ -27,7 +27,7 @@ }, { "name": "aws-cdk-lib", - "version": "2.24.1", + "version": "2.28.0", "type": "build" }, { @@ -108,7 +108,7 @@ }, { "name": "aws-cdk-lib", - "version": "^2.24.1", + "version": "^2.28.0", "type": "peer" }, { diff --git a/packages/microapps-cdk/.projenrc.js b/packages/microapps-cdk/.projenrc.js index 3db21371..72f00be1 100644 --- a/packages/microapps-cdk/.projenrc.js +++ b/packages/microapps-cdk/.projenrc.js @@ -7,7 +7,7 @@ const project = new awscdk.AwsCdkConstructLibrary({ authorOrganization: true, description: 'MicroApps framework, by PwrDrvr LLC, delivered as an AWS CDK construct that provides the DynamoDB, Router service, Deploy service, API Gateway, and CloudFront distribution.', - cdkVersion: '2.24.1', + cdkVersion: '2.28.0', copyrightOwner: 'PwrDrvr LLC', copyrightPeriod: '2020', defaultReleaseBranch: 'main', diff --git a/packages/microapps-cdk/package.json b/packages/microapps-cdk/package.json index 07a3fd92..087f6443 100644 --- a/packages/microapps-cdk/package.json +++ b/packages/microapps-cdk/package.json @@ -42,7 +42,7 @@ "@types/yargs": "^16.0.0", "@typescript-eslint/eslint-plugin": "^5", "@typescript-eslint/parser": "^5", - "aws-cdk-lib": "2.24.1", + "aws-cdk-lib": "2.28.0", "constructs": "10.0.5", "esbuild": "^0.14.11", "eslint": "^8", @@ -60,16 +60,16 @@ "typescript": "^4.5.4" }, "peerDependencies": { - "@aws-cdk/aws-apigatewayv2-alpha": "^2.24.1-alpha.0", - "@aws-cdk/aws-apigatewayv2-authorizers-alpha": "^2.24.1-alpha.0", - "@aws-cdk/aws-apigatewayv2-integrations-alpha": "^2.24.1-alpha.0", - "aws-cdk-lib": "^2.24.1", + "@aws-cdk/aws-apigatewayv2-alpha": "^2.28.0-alpha.0", + "@aws-cdk/aws-apigatewayv2-authorizers-alpha": "^2.28.0-alpha.0", + "@aws-cdk/aws-apigatewayv2-integrations-alpha": "^2.28.0-alpha.0", + "aws-cdk-lib": "^2.28.0", "constructs": "^10.0.5" }, "dependencies": { - "@aws-cdk/aws-apigatewayv2-alpha": "^2.24.1-alpha.0", - "@aws-cdk/aws-apigatewayv2-authorizers-alpha": "^2.24.1-alpha.0", - "@aws-cdk/aws-apigatewayv2-integrations-alpha": "^2.24.1-alpha.0" + "@aws-cdk/aws-apigatewayv2-alpha": "^2.28.0-alpha.0", + "@aws-cdk/aws-apigatewayv2-authorizers-alpha": "^2.28.0-alpha.0", + "@aws-cdk/aws-apigatewayv2-integrations-alpha": "^2.28.0-alpha.0" }, "keywords": [ "awscdk", @@ -116,4 +116,4 @@ "@types/prettier": "2.6.0" }, "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"." -} \ No newline at end of file +} diff --git a/packages/microapps-cdk/yarn.lock b/packages/microapps-cdk/yarn.lock index 0b70f530..a5e64ece 100644 --- a/packages/microapps-cdk/yarn.lock +++ b/packages/microapps-cdk/yarn.lock @@ -606,16 +606,16 @@ available-typed-arrays@^1.0.5: resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== -aws-cdk-lib@2.24.1: - version "2.24.1" - resolved "https://registry.yarnpkg.com/aws-cdk-lib/-/aws-cdk-lib-2.24.1.tgz#197d10216b384850c01205acc8e4818838964302" - integrity sha512-xGeEX+9wPGppSiIUdf/JTLMmqMikGhlSi7bjijl3lwncZtySkdjX0j+W2A1fuKp0S8Yd2axkwVkltIMxzNH/gw== +aws-cdk-lib@2.28.0: + version "2.28.0" + resolved "https://registry.yarnpkg.com/aws-cdk-lib/-/aws-cdk-lib-2.28.0.tgz#bf01b0233d41ba7c211c4a039258850c42459604" + integrity sha512-ZAhIQ+mX2JYx8st6enan8qBzts7o+PXFJxLABIUYZSSus/ScWx9POLIVsV28LXorM4Y2su23VfWM7iVmCNxYAQ== dependencies: "@balena/dockerignore" "^1.0.2" case "1.6.3" fs-extra "^9.1.0" ignore "^5.2.0" - jsonschema "^1.4.0" + jsonschema "^1.4.1" minimatch "^3.1.2" punycode "^2.1.1" semver "^7.3.7" @@ -2686,7 +2686,7 @@ jsonparse@^1.2.0, jsonparse@^1.3.1: resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== -jsonschema@^1.4.0: +jsonschema@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.1.tgz#cc4c3f0077fb4542982973d8a083b6b34f482dab" integrity sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ== diff --git a/packages/microapps-edge-to-origin/src/index.route.spec.ts b/packages/microapps-edge-to-origin/src/index.route.spec.ts index b9468ed9..a3bb56b4 100644 --- a/packages/microapps-edge-to-origin/src/index.route.spec.ts +++ b/packages/microapps-edge-to-origin/src/index.route.spec.ts @@ -292,6 +292,99 @@ describe('edge-to-origin - routing - without prefix', () => { expect(requestResponse?.origin?.custom?.domainName).toBe('abc123.lambda-url.us-east-1.on.aws'); }); + it('should route `iframe` app request with appName and sub-path and query string without modifying path', async () => { + theConfig.replaceHostHeader = true; + + const AppName = 'BatIFramePathQuery'; + + const app = new Application({ + AppName, + DisplayName: 'IFrame Bat App', + }); + await app.Save(dbManager); + + const version = new Version({ + AppName, + SemVer: '0.0.0', + Status: 'deployed', + Type: 'lambda-url', + StartupType: 'iframe', + URL: 'https://abc123.lambda-url.us-east-1.on.aws/', + }); + await version.Save(dbManager); + + const rules = new Rules({ + AppName, + Version: 0, + RuleSet: { default: { SemVer: '0.0.0', AttributeName: '', AttributeValue: '' } }, + }); + await rules.Save(dbManager); + + // Call the handler + // @ts-expect-error no callback + const response = await handler( + { + Records: [ + { + cf: { + config: { + distributionDomainName: 'zyz.cloudfront.net', + distributionId: '123', + eventType: 'origin-request', + requestId: '123', + }, + request: { + headers: { + host: [ + { + key: 'Host', + value: 'zyz.cloudfront.net', + }, + ], + }, + method: 'GET', + querystring: 'param1=value1¶m2=value2', + clientIp: '1.1.1.1', + uri: `/${AppName.toLowerCase()}/api/apiCall`, + origin: { + custom: { + customHeaders: {}, + domainName: 'zyz.cloudfront.net', + keepaliveTimeout: 5, + path: '', + port: 443, + protocol: 'https', + readTimeout: 30, + sslProtocols: ['TLSv1.2'], + }, + }, + }, + }, + }, + ], + } as lambda.CloudFrontRequestEvent, + {} as lambda.Context, + ); + + const requestResponse = response as lambda.CloudFrontRequest; + expect(requestResponse).toBeDefined(); + expect(requestResponse).not.toHaveProperty('status'); + expect(requestResponse).not.toHaveProperty('body'); + expect(requestResponse).toHaveProperty('headers'); + expect(requestResponse.headers).toHaveProperty('host'); + expect(requestResponse.headers.host).toHaveLength(1); + expect(requestResponse.headers.host[0].key).toBe('Host'); + expect(requestResponse.headers.host[0].value).toBe('abc123.lambda-url.us-east-1.on.aws'); + expect(requestResponse).toHaveProperty('origin'); + // Query string should be preserved + expect(requestResponse.querystring).toBe('param1=value1¶m2=value2'); + // Path should be preserved + expect(requestResponse.uri).toBe(`/${AppName.toLowerCase()}/api/apiCall`); + expect(requestResponse.origin).toHaveProperty('custom'); + expect(requestResponse?.origin?.custom).toHaveProperty('domainName'); + expect(requestResponse?.origin?.custom?.domainName).toBe('abc123.lambda-url.us-east-1.on.aws'); + }); + it('should route `direct` app request with *locale* to origin for appName', async () => { theConfig.replaceHostHeader = true; theConfig.locales = ['en', 'sv']; diff --git a/packages/microapps-edge-to-origin/src/index.ts b/packages/microapps-edge-to-origin/src/index.ts index b0204c35..dbb1ab96 100644 --- a/packages/microapps-edge-to-origin/src/index.ts +++ b/packages/microapps-edge-to-origin/src/index.ts @@ -132,7 +132,11 @@ export const handler: lambda.CloudFrontRequestHandler = async ( log.debug('got route info', { route }); // Write the app iframe to start an iframe-based app - if (route.startupType === 'iframe' && route.iFrameAppVersionPath) { + if ( + route.startupType === 'iframe' && + route.iFrameAppVersionPath && + !(route.isAPIPath ?? false) + ) { const frameHTML = appFrame.replace('{{iframeSrc}}', route.iFrameAppVersionPath); log.debug('returning app frame', { frameHTML }); diff --git a/packages/microapps-router-lib/src/get-route.ts b/packages/microapps-router-lib/src/get-route.ts index 92914cc6..51ce046f 100644 --- a/packages/microapps-router-lib/src/get-route.ts +++ b/packages/microapps-router-lib/src/get-route.ts @@ -61,6 +61,11 @@ export interface IGetRouteResult { * URL to the app if resolved */ readonly url?: string; + + /** + * Does the extra app path start with /api/ + */ + readonly isAPIPath?: boolean; } export interface IGetRouteEvent { diff --git a/packages/microapps-router-lib/src/route-app.ts b/packages/microapps-router-lib/src/route-app.ts index 7c553e45..55c1289b 100644 --- a/packages/microapps-router-lib/src/route-app.ts +++ b/packages/microapps-router-lib/src/route-app.ts @@ -73,6 +73,7 @@ export async function RouteApp(opts: { statusCode: 200, appName, semVer: possibleSemVerPathVersionInfo.SemVer, + isAPIPath: additionalParts.startsWith('api/'), ...(possibleSemVerPathVersionInfo?.URL ? { url: possibleSemVerPathVersionInfo?.URL } : {}), ...(possibleSemVerPathVersionInfo?.Type ? { @@ -172,6 +173,7 @@ export async function RouteApp(opts: { appName, semVer: versionInfoToUse.SemVer, startupType: 'iframe', + isAPIPath: additionalParts.startsWith('api/'), ...(versionInfoToUse?.URL ? { url: versionInfoToUse?.URL } : {}), ...(versionInfoToUse?.Type ? { type: versionInfoToUse?.Type === 'lambda' ? 'apigwy' : versionInfoToUse?.Type } @@ -192,6 +194,7 @@ export async function RouteApp(opts: { appName, semVer: versionInfoToUse.SemVer, startupType: 'direct', + isAPIPath: additionalParts.startsWith('api/'), ...(versionInfoToUse?.URL ? { url: versionInfoToUse?.URL } : {}), ...(versionInfoToUse?.Type ? { type: versionInfoToUse?.Type } : {}), }; diff --git a/yarn.lock b/yarn.lock index 794ec455..23f108a4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,20 +10,20 @@ "@jridgewell/gen-mapping" "^0.1.0" "@jridgewell/trace-mapping" "^0.3.9" -"@aws-cdk/aws-apigatewayv2-alpha@^2.24.1-alpha.0": - version "2.24.1-alpha.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/aws-apigatewayv2-alpha/-/aws-apigatewayv2-alpha-2.24.1-alpha.0.tgz" - integrity sha512-U7qi+mvGCJaUm8753yLs43L4PVPVaKJKU3RZ65iCj/uRB3dT2gDa7bdRQc6ptnvfZriLwDq6Au6NMbDAuNDluw== +"@aws-cdk/aws-apigatewayv2-alpha@^2.28.0-alpha.0": + version "2.28.0-alpha.0" + resolved "https://registry.yarnpkg.com/@aws-cdk/aws-apigatewayv2-alpha/-/aws-apigatewayv2-alpha-2.28.0-alpha.0.tgz#1eb7eed14a0a3b54fe64e2c9aee3bdeac964ffb0" + integrity sha512-dYze4hixfJvQiVDy6FPjpSKMQKjh1Y9pX16Q5mdjrVJpNiX5j4vRoBcrOXYCpATDzD0XMBQ6Zpr9MSjDLlGuOw== -"@aws-cdk/aws-apigatewayv2-authorizers-alpha@^2.24.1-alpha.0": - version "2.24.1-alpha.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/aws-apigatewayv2-authorizers-alpha/-/aws-apigatewayv2-authorizers-alpha-2.24.1-alpha.0.tgz#4db817ba3ade0af252cfc6ec75768bce7fa68e8c" - integrity sha512-/G7xe13xtFRwYxom/Ya3d/voRS9M2jIvPNYfhljxsE7L5bz4ldK5y3xY/5Lg9Okk4FjSInuWpCgQE5vb7+COOA== +"@aws-cdk/aws-apigatewayv2-authorizers-alpha@^2.28.0-alpha.0": + version "2.28.0-alpha.0" + resolved "https://registry.yarnpkg.com/@aws-cdk/aws-apigatewayv2-authorizers-alpha/-/aws-apigatewayv2-authorizers-alpha-2.28.0-alpha.0.tgz#53d526cefa1327f87641ecc96bc352e2e4be95d2" + integrity sha512-ZggtktYQi7r2zGVh00jGyphveMqUZgkwrushNX7qjRQ6jbGdJdoOlFyzfsjcpw+55iDkc2xKuJtkqSC73Ho9nw== -"@aws-cdk/aws-apigatewayv2-integrations-alpha@^2.24.1-alpha.0": - version "2.24.1-alpha.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/aws-apigatewayv2-integrations-alpha/-/aws-apigatewayv2-integrations-alpha-2.24.1-alpha.0.tgz" - integrity sha512-/Nu2DH9suome5w7306T3tzqPMoQB3fve4xzX5VpTC798F7cQUlMqcxzyZD3s55nuRXnhRZoLdAQlwLbEUxUIxA== +"@aws-cdk/aws-apigatewayv2-integrations-alpha@^2.28.0-alpha.0": + version "2.28.0-alpha.0" + resolved "https://registry.yarnpkg.com/@aws-cdk/aws-apigatewayv2-integrations-alpha/-/aws-apigatewayv2-integrations-alpha-2.28.0-alpha.0.tgz#5a4408a4119a940802b3306fae94217590343772" + integrity sha512-vuWQvNv7QCtQMnEnsw4DZcjETezvw3PdzbxtS6jeLriJVrCqKey73YjGYX0TkB/KTM2D7BMbPow9QvQ5FmEnVg== "@aws-crypto/crc32@2.0.0": version "2.0.0" @@ -4304,25 +4304,25 @@ available-typed-arrays@^1.0.5: resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== -aws-cdk-lib@2.24.1: - version "2.24.1" - resolved "https://registry.yarnpkg.com/aws-cdk-lib/-/aws-cdk-lib-2.24.1.tgz" - integrity sha512-xGeEX+9wPGppSiIUdf/JTLMmqMikGhlSi7bjijl3lwncZtySkdjX0j+W2A1fuKp0S8Yd2axkwVkltIMxzNH/gw== +aws-cdk-lib@2.28.0: + version "2.28.0" + resolved "https://registry.yarnpkg.com/aws-cdk-lib/-/aws-cdk-lib-2.28.0.tgz#bf01b0233d41ba7c211c4a039258850c42459604" + integrity sha512-ZAhIQ+mX2JYx8st6enan8qBzts7o+PXFJxLABIUYZSSus/ScWx9POLIVsV28LXorM4Y2su23VfWM7iVmCNxYAQ== dependencies: "@balena/dockerignore" "^1.0.2" case "1.6.3" fs-extra "^9.1.0" ignore "^5.2.0" - jsonschema "^1.4.0" + jsonschema "^1.4.1" minimatch "^3.1.2" punycode "^2.1.1" semver "^7.3.7" yaml "1.10.2" -aws-cdk@^2.24.1: - version "2.24.1" - resolved "https://registry.yarnpkg.com/aws-cdk/-/aws-cdk-2.24.1.tgz" - integrity sha512-fDcJW7tLbqsCvWB3eZY6glRrjRE45VqLT+JuKz3C2jIe6qXkwV8dBwYXElwY/tTCh/hDlpWtCNMRdhmrdE25GQ== +aws-cdk@^2.28.0: + version "2.83.1" + resolved "https://registry.yarnpkg.com/aws-cdk/-/aws-cdk-2.83.1.tgz#a71c226f806b2e2ccfff0a5b3c1037759b1c15ee" + integrity sha512-hM2fsHl2TXk3B0MTq7zRU/KqJiVrnTQ3SXbAfleQCfCf/Jpy6yD6nGqrEADFAYNLSPoA9iC3SLnO73SPqqjjRQ== optionalDependencies: fsevents "2.3.2" @@ -7961,9 +7961,9 @@ jsonparse@^1.2.0, jsonparse@^1.3.1: resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz" integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= -jsonschema@^1.4.0: +jsonschema@^1.4.0, jsonschema@^1.4.1: version "1.4.1" - resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.1.tgz" + resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.1.tgz#cc4c3f0077fb4542982973d8a083b6b34f482dab" integrity sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ== just-extend@^4.0.2: