@webiny/pulumi-aws 5.43.6 → 5.43.7-beta.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/apps/tenantRouter.d.ts +2 -1
- package/apps/tenantRouter.js +22 -4
- package/apps/tenantRouter.js.map +1 -1
- package/apps/website/createWebsitePulumiApp.d.ts +20 -1
- package/apps/website/createWebsitePulumiApp.js +2 -1
- package/apps/website/createWebsitePulumiApp.js.map +1 -1
- package/components/tenantRouter/functions/origin/matchRedirect.d.ts +14 -0
- package/components/tenantRouter/functions/origin/matchRedirect.js +49 -0
- package/components/tenantRouter/functions/origin/matchRedirect.js.map +1 -0
- package/components/tenantRouter/functions/origin/request.js +8 -0
- package/components/tenantRouter/functions/origin/request.js.map +1 -1
- package/index.d.ts +0 -1
- package/index.js +0 -13
- package/index.js.map +1 -1
- package/package.json +12 -12
- package/components/tenantRouter/WebsiteTenantRouter.d.ts +0 -12
- package/components/tenantRouter/WebsiteTenantRouter.js +0 -91
- package/components/tenantRouter/WebsiteTenantRouter.js.map +0 -1
package/apps/tenantRouter.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as aws from "@pulumi/aws";
|
|
2
2
|
import { PulumiApp, PulumiAppResource } from "@webiny/pulumi";
|
|
3
|
-
|
|
3
|
+
import type { WebsiteRedirect } from "./website/index.js";
|
|
4
|
+
export declare function applyTenantRouter(app: PulumiApp, cloudfront: PulumiAppResource<typeof aws.cloudfront.Distribution>, redirects: WebsiteRedirect[]): {
|
|
4
5
|
originLambda: PulumiAppResource<typeof import("@pulumi/aws/lambda/function").Function>;
|
|
5
6
|
};
|
package/apps/tenantRouter.js
CHANGED
|
@@ -11,18 +11,35 @@ var aws = _interopRequireWildcard(require("@pulumi/aws"));
|
|
|
11
11
|
var _common = require("./common");
|
|
12
12
|
var _constants = require("../constants");
|
|
13
13
|
var _awsRegion = require("../env/awsRegion");
|
|
14
|
+
const PERMANENT_CACHE = 31536000;
|
|
15
|
+
const TEMPORARY_CACHE = 86400;
|
|
14
16
|
function createFunctionArchive({
|
|
15
17
|
dynamoDbTable,
|
|
16
|
-
region
|
|
18
|
+
region,
|
|
19
|
+
redirects
|
|
17
20
|
}) {
|
|
18
21
|
const handler = (0, _fs.readFileSync)(__dirname + "/../components/tenantRouter/functions/origin/request.js", "utf-8");
|
|
22
|
+
const matchRedirect = (0, _fs.readFileSync)(__dirname + "/../components/tenantRouter/functions/origin/matchRedirect.js", "utf-8");
|
|
23
|
+
const redirectsMap = redirects.reduce((acc, redirect) => {
|
|
24
|
+
const maxAge = redirect.permanent ? PERMANENT_CACHE : TEMPORARY_CACHE;
|
|
25
|
+
return {
|
|
26
|
+
...acc,
|
|
27
|
+
[redirect.from]: {
|
|
28
|
+
to: redirect.to,
|
|
29
|
+
permanent: redirect.permanent,
|
|
30
|
+
maxAge: redirect.maxAge ?? maxAge
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}, {});
|
|
19
34
|
const source = handler.replace("{DB_TABLE_NAME}", dynamoDbTable).replace("{DB_TABLE_REGION}", region);
|
|
20
35
|
return new pulumi.asset.AssetArchive({
|
|
21
|
-
"index.js": new pulumi.asset.StringAsset(source)
|
|
36
|
+
"index.js": new pulumi.asset.StringAsset(source),
|
|
37
|
+
"matchRedirect.js": new pulumi.asset.StringAsset(matchRedirect),
|
|
38
|
+
"redirects.json": new pulumi.asset.StringAsset(JSON.stringify(redirectsMap))
|
|
22
39
|
});
|
|
23
40
|
}
|
|
24
41
|
const PREFIX = "website-router";
|
|
25
|
-
function applyTenantRouter(app, cloudfront) {
|
|
42
|
+
function applyTenantRouter(app, cloudfront, redirects) {
|
|
26
43
|
const region = (0, _awsRegion.getEnvVariableAwsRegion)();
|
|
27
44
|
|
|
28
45
|
// Get Core app output
|
|
@@ -78,7 +95,8 @@ function applyTenantRouter(app, cloudfront) {
|
|
|
78
95
|
code: dynamoDbTable.apply(dynamoDbTable => {
|
|
79
96
|
return createFunctionArchive({
|
|
80
97
|
region,
|
|
81
|
-
dynamoDbTable
|
|
98
|
+
dynamoDbTable,
|
|
99
|
+
redirects
|
|
82
100
|
});
|
|
83
101
|
})
|
|
84
102
|
},
|
package/apps/tenantRouter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_fs","require","pulumi","_interopRequireWildcard","aws","_common","_constants","_awsRegion","createFunctionArchive","dynamoDbTable","region","handler","readFileSync","__dirname","source","replace","asset","AssetArchive","StringAsset","PREFIX","applyTenantRouter","app","cloudfront","getEnvVariableAwsRegion","core","getModule","CoreOutput","primaryDynamodbTableName","inlinePolicies","all","getCallerIdentity","apply","identity","name","policy","JSON","stringify","Version","Statement","Sid","Effect","Action","Resource","accountId","role","addResource","iam","Role","config","managedPolicyArns","ManagedPolicies","AWSLambdaBasicExecutionRole","assumeRolePolicy","Principal","Principals","LambdaPrincipal","EdgeLambdaPrincipal","awsUsEast1","Provider","originLambda","lambda","Function","publish","runtime","LAMBDA_RUNTIME","output","arn","timeout","memorySize","code","opts","provider","retainOnDelete","meta","canUseVpc","defaultCacheBehavior","value","forwardedValues","queryString","cookies","forward","headers","lambdaFunctionAssociations","eventType","includeBody","lambdaArn","qualifiedArn"],"sources":["tenantRouter.ts"],"sourcesContent":["import { readFileSync } from \"fs\";\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport { PulumiApp, PulumiAppResource } from \"@webiny/pulumi\";\nimport { CoreOutput } from \"./common\";\nimport { LAMBDA_RUNTIME } from \"~/constants\";\nimport { getEnvVariableAwsRegion } from \"~/env/awsRegion\";\n\ninterface Params {\n region: string;\n dynamoDbTable: string;\n}\n\nfunction createFunctionArchive({ dynamoDbTable, region }: Params) {\n const handler = readFileSync(\n __dirname + \"/../components/tenantRouter/functions/origin/request.js\",\n \"utf-8\"\n );\n\n const source = handler\n .replace(\"{DB_TABLE_NAME}\", dynamoDbTable)\n .replace(\"{DB_TABLE_REGION}\", region);\n\n return new pulumi.asset.AssetArchive({\n \"index.js\": new pulumi.asset.StringAsset(source)\n });\n}\n\nconst PREFIX = \"website-router\";\n\nexport function applyTenantRouter(\n app: PulumiApp,\n cloudfront: PulumiAppResource<typeof aws.cloudfront.Distribution>\n) {\n const region = getEnvVariableAwsRegion();\n\n // Get Core app output\n const core = app.getModule(CoreOutput);\n\n // `primaryDynamodbTableName` is a string, hence the type cast here.\n const dynamoDbTable = core.primaryDynamodbTableName;\n\n // Because of JSON.stringify, we need to resolve promises upfront.\n const inlinePolicies = pulumi\n .all([aws.getCallerIdentity({}), dynamoDbTable])\n .apply(([identity, dynamoDbTable]) => [\n {\n name: \"tenant-router-policy\",\n policy: JSON.stringify({\n Version: \"2012-10-17\",\n Statement: [\n {\n Sid: \"PermissionForDynamodb\",\n Effect: \"Allow\",\n Action: [\"dynamodb:GetItem\", \"dynamodb:Query\"],\n Resource: [\n `arn:aws:dynamodb:${region}:${identity.accountId}:table/${dynamoDbTable}`,\n `arn:aws:dynamodb:${region}:${identity.accountId}:table/${dynamoDbTable}/*`\n ]\n }\n ]\n })\n }\n ]);\n\n const role = app.addResource(aws.iam.Role, {\n name: `${PREFIX}-role`,\n config: {\n inlinePolicies,\n managedPolicyArns: [aws.iam.ManagedPolicies.AWSLambdaBasicExecutionRole],\n assumeRolePolicy: {\n Version: \"2012-10-17\",\n Statement: [\n {\n Action: \"sts:AssumeRole\",\n Principal: aws.iam.Principals.LambdaPrincipal,\n Effect: \"Allow\"\n },\n {\n Action: \"sts:AssumeRole\",\n Principal: aws.iam.Principals.EdgeLambdaPrincipal,\n Effect: \"Allow\"\n }\n ]\n }\n }\n });\n\n const awsUsEast1 = new aws.Provider(\"us-east-1\", { region: \"us-east-1\" });\n\n const originLambda = app.addResource(aws.lambda.Function, {\n name: `${PREFIX}-origin-request`,\n config: {\n publish: true,\n runtime: LAMBDA_RUNTIME,\n handler: \"index.handler\",\n role: role.output.arn,\n timeout: 5,\n memorySize: 128,\n code: dynamoDbTable.apply(dynamoDbTable => {\n return createFunctionArchive({\n region,\n dynamoDbTable\n });\n })\n },\n // With the `retainOnDelete` option set to `true`, the Lambda function will not be deleted when\n // the environment is destroyed. Users need to delete the function manually. We decided to use\n // this option here because it enables us to avoid annoying AWS Lambda function replication\n // errors upon destroying the stack (see https://github.com/pulumi/pulumi-aws/issues/2178).\n opts: { provider: awsUsEast1, retainOnDelete: true },\n meta: {\n canUseVpc: false\n }\n });\n\n cloudfront.config.defaultCacheBehavior(value => {\n return {\n ...value,\n // We need to forward the `Host` header so the Lambda@Edge knows what custom domain was requested.\n forwardedValues: {\n ...value.forwardedValues,\n queryString: value.forwardedValues?.queryString || false,\n cookies: value.forwardedValues?.cookies || { forward: \"none\" },\n headers: [...(value.forwardedValues?.headers || []), \"Host\"]\n },\n lambdaFunctionAssociations: [\n ...(value.lambdaFunctionAssociations || []),\n {\n eventType: \"origin-request\",\n includeBody: false,\n lambdaArn: originLambda.output.qualifiedArn\n }\n ]\n };\n });\n\n return { originLambda };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["_fs","require","pulumi","_interopRequireWildcard","aws","_common","_constants","_awsRegion","PERMANENT_CACHE","TEMPORARY_CACHE","createFunctionArchive","dynamoDbTable","region","redirects","handler","readFileSync","__dirname","matchRedirect","redirectsMap","reduce","acc","redirect","maxAge","permanent","from","to","source","replace","asset","AssetArchive","StringAsset","JSON","stringify","PREFIX","applyTenantRouter","app","cloudfront","getEnvVariableAwsRegion","core","getModule","CoreOutput","primaryDynamodbTableName","inlinePolicies","all","getCallerIdentity","apply","identity","name","policy","Version","Statement","Sid","Effect","Action","Resource","accountId","role","addResource","iam","Role","config","managedPolicyArns","ManagedPolicies","AWSLambdaBasicExecutionRole","assumeRolePolicy","Principal","Principals","LambdaPrincipal","EdgeLambdaPrincipal","awsUsEast1","Provider","originLambda","lambda","Function","publish","runtime","LAMBDA_RUNTIME","output","arn","timeout","memorySize","code","opts","provider","retainOnDelete","meta","canUseVpc","defaultCacheBehavior","value","forwardedValues","queryString","cookies","forward","headers","lambdaFunctionAssociations","eventType","includeBody","lambdaArn","qualifiedArn"],"sources":["tenantRouter.ts"],"sourcesContent":["import { readFileSync } from \"fs\";\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport { PulumiApp, PulumiAppResource } from \"@webiny/pulumi\";\nimport { CoreOutput } from \"./common\";\nimport { LAMBDA_RUNTIME } from \"~/constants\";\nimport { getEnvVariableAwsRegion } from \"~/env/awsRegion\";\nimport type { WebsiteRedirect } from \"~/apps/website/index.js\";\n\ninterface Params {\n region: string;\n dynamoDbTable: string;\n redirects: WebsiteRedirect[];\n}\n\nconst PERMANENT_CACHE = 31536000;\nconst TEMPORARY_CACHE = 86400;\n\nfunction createFunctionArchive({ dynamoDbTable, region, redirects }: Params) {\n const handler = readFileSync(\n __dirname + \"/../components/tenantRouter/functions/origin/request.js\",\n \"utf-8\"\n );\n\n const matchRedirect = readFileSync(\n __dirname + \"/../components/tenantRouter/functions/origin/matchRedirect.js\",\n \"utf-8\"\n );\n\n const redirectsMap = redirects.reduce((acc, redirect) => {\n const maxAge = redirect.permanent ? PERMANENT_CACHE : TEMPORARY_CACHE;\n\n return {\n ...acc,\n [redirect.from]: {\n to: redirect.to,\n permanent: redirect.permanent,\n maxAge: redirect.maxAge ?? maxAge\n }\n };\n }, {});\n\n const source = handler\n .replace(\"{DB_TABLE_NAME}\", dynamoDbTable)\n .replace(\"{DB_TABLE_REGION}\", region);\n\n return new pulumi.asset.AssetArchive({\n \"index.js\": new pulumi.asset.StringAsset(source),\n \"matchRedirect.js\": new pulumi.asset.StringAsset(matchRedirect),\n \"redirects.json\": new pulumi.asset.StringAsset(JSON.stringify(redirectsMap))\n });\n}\n\nconst PREFIX = \"website-router\";\n\nexport function applyTenantRouter(\n app: PulumiApp,\n cloudfront: PulumiAppResource<typeof aws.cloudfront.Distribution>,\n redirects: WebsiteRedirect[]\n) {\n const region = getEnvVariableAwsRegion();\n\n // Get Core app output\n const core = app.getModule(CoreOutput);\n\n // `primaryDynamodbTableName` is a string, hence the type cast here.\n const dynamoDbTable = core.primaryDynamodbTableName;\n\n // Because of JSON.stringify, we need to resolve promises upfront.\n const inlinePolicies = pulumi\n .all([aws.getCallerIdentity({}), dynamoDbTable])\n .apply(([identity, dynamoDbTable]) => [\n {\n name: \"tenant-router-policy\",\n policy: JSON.stringify({\n Version: \"2012-10-17\",\n Statement: [\n {\n Sid: \"PermissionForDynamodb\",\n Effect: \"Allow\",\n Action: [\"dynamodb:GetItem\", \"dynamodb:Query\"],\n Resource: [\n `arn:aws:dynamodb:${region}:${identity.accountId}:table/${dynamoDbTable}`,\n `arn:aws:dynamodb:${region}:${identity.accountId}:table/${dynamoDbTable}/*`\n ]\n }\n ]\n })\n }\n ]);\n\n const role = app.addResource(aws.iam.Role, {\n name: `${PREFIX}-role`,\n config: {\n inlinePolicies,\n managedPolicyArns: [aws.iam.ManagedPolicies.AWSLambdaBasicExecutionRole],\n assumeRolePolicy: {\n Version: \"2012-10-17\",\n Statement: [\n {\n Action: \"sts:AssumeRole\",\n Principal: aws.iam.Principals.LambdaPrincipal,\n Effect: \"Allow\"\n },\n {\n Action: \"sts:AssumeRole\",\n Principal: aws.iam.Principals.EdgeLambdaPrincipal,\n Effect: \"Allow\"\n }\n ]\n }\n }\n });\n\n const awsUsEast1 = new aws.Provider(\"us-east-1\", { region: \"us-east-1\" });\n\n const originLambda = app.addResource(aws.lambda.Function, {\n name: `${PREFIX}-origin-request`,\n config: {\n publish: true,\n runtime: LAMBDA_RUNTIME,\n handler: \"index.handler\",\n role: role.output.arn,\n timeout: 5,\n memorySize: 128,\n code: dynamoDbTable.apply(dynamoDbTable => {\n return createFunctionArchive({\n region,\n dynamoDbTable,\n redirects\n });\n })\n },\n // With the `retainOnDelete` option set to `true`, the Lambda function will not be deleted when\n // the environment is destroyed. Users need to delete the function manually. We decided to use\n // this option here because it enables us to avoid annoying AWS Lambda function replication\n // errors upon destroying the stack (see https://github.com/pulumi/pulumi-aws/issues/2178).\n opts: { provider: awsUsEast1, retainOnDelete: true },\n meta: {\n canUseVpc: false\n }\n });\n\n cloudfront.config.defaultCacheBehavior(value => {\n return {\n ...value,\n // We need to forward the `Host` header so the Lambda@Edge knows what custom domain was requested.\n forwardedValues: {\n ...value.forwardedValues,\n queryString: value.forwardedValues?.queryString || false,\n cookies: value.forwardedValues?.cookies || { forward: \"none\" },\n headers: [...(value.forwardedValues?.headers || []), \"Host\"]\n },\n lambdaFunctionAssociations: [\n ...(value.lambdaFunctionAssociations || []),\n {\n eventType: \"origin-request\",\n includeBody: false,\n lambdaArn: originLambda.output.qualifiedArn\n }\n ]\n };\n });\n\n return { originLambda };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -3,6 +3,17 @@ import * as aws from "@pulumi/aws";
|
|
|
3
3
|
import { PulumiAppParam, PulumiAppParamCallback } from "@webiny/pulumi";
|
|
4
4
|
import { CustomDomainParams } from "../customDomain";
|
|
5
5
|
export type WebsitePulumiApp = ReturnType<typeof createWebsitePulumiApp>;
|
|
6
|
+
export type WebsiteRedirect = {
|
|
7
|
+
from: string;
|
|
8
|
+
to: string;
|
|
9
|
+
permanent: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Cache duration in seconds.
|
|
12
|
+
* For permanent redirects, the default value is 1 year (31536000 seconds).
|
|
13
|
+
* For temporary redirects, the default value is 1 day (86400 seconds).
|
|
14
|
+
*/
|
|
15
|
+
maxAge?: number;
|
|
16
|
+
};
|
|
6
17
|
export interface CreateWebsitePulumiAppParams {
|
|
7
18
|
/**
|
|
8
19
|
* Custom domain(s) configuration.
|
|
@@ -22,6 +33,10 @@ export interface CreateWebsitePulumiAppParams {
|
|
|
22
33
|
* or add additional ones into the mix.
|
|
23
34
|
*/
|
|
24
35
|
pulumi?: (app: WebsitePulumiApp) => void | Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Define redirects to be handled by website Lambda@Edge function.
|
|
38
|
+
*/
|
|
39
|
+
redirects?: () => Promise<WebsiteRedirect[]> | WebsiteRedirect[];
|
|
25
40
|
/**
|
|
26
41
|
* Prefixes names of all Pulumi cloud infrastructure resource with given prefix.
|
|
27
42
|
*/
|
|
@@ -45,7 +60,11 @@ export declare const createWebsitePulumiApp: (projectAppParams?: CreateWebsitePu
|
|
|
45
60
|
};
|
|
46
61
|
renderer: {
|
|
47
62
|
policy: pulumi.Output<import("@pulumi/aws/iam/policy").Policy>;
|
|
48
|
-
role: import("@webiny/pulumi").PulumiAppResource<typeof import("@pulumi/aws/iam/role").Role>;
|
|
63
|
+
role: import("@webiny/pulumi").PulumiAppResource<typeof import("@pulumi/aws/iam/role").Role>; /**
|
|
64
|
+
* We need to have a Cloudfront Function to perform a simple request rewrite, so the request always includes
|
|
65
|
+
* an "/index.html". This is necessary because our buckets are not "website" buckets, and we need to
|
|
66
|
+
* have an exact object key when requesting page paths.
|
|
67
|
+
*/
|
|
49
68
|
lambda: import("@webiny/pulumi").PulumiAppResource<typeof import("@pulumi/aws/lambda/function").Function>;
|
|
50
69
|
eventSourceMapping: import("@webiny/pulumi").PulumiAppResource<typeof import("@pulumi/aws/lambda/eventSourceMapping").EventSourceMapping>;
|
|
51
70
|
};
|
|
@@ -231,9 +231,10 @@ const createWebsitePulumiApp = (projectAppParams = {}) => {
|
|
|
231
231
|
(0, _customDomain.applyCustomDomain)(appCloudfront, previewDomains);
|
|
232
232
|
}
|
|
233
233
|
if (process.env.WCP_PROJECT_ENVIRONMENT || process.env.WEBINY_MULTI_TENANCY === "true") {
|
|
234
|
+
const redirects = projectAppParams.redirects ? await projectAppParams.redirects() : [];
|
|
234
235
|
const {
|
|
235
236
|
originLambda
|
|
236
|
-
} = (0, _tenantRouter.applyTenantRouter)(app, deliveryCloudfront);
|
|
237
|
+
} = (0, _tenantRouter.applyTenantRouter)(app, deliveryCloudfront, redirects);
|
|
237
238
|
app.addHandler(() => {
|
|
238
239
|
app.addOutputs({
|
|
239
240
|
websiteRouterOriginRequestFunction: originLambda.output.name
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["pulumi","_interopRequireWildcard","require","aws","_fs","_interopRequireDefault","_pulumi2","_createAppBucket","_customDomain","_WebsitePrerendering","_","_utils","_tenantRouter","_withServiceManifest","_constants","_variant","_env","_projectName","createWebsitePulumiApp","projectAppParams","baseApp","createPulumiApp","name","path","config","program","app","pulumiResourceNamePrefix","getParam","onResource","resource","startsWith","addHandler","productionEnvironments","params","create","DEFAULT_PROD_ENV_NAMES","isProduction","includes","run","env","core","addModule","CoreOutput","ApiOutput","vpcEnabled","vpc","VpcConfig","enabled","appBucket","createPrivateAppBucket","appCloudfront","addResource","cloudfront","Distribution","waitForDeployment","origins","origin","defaultRootObject","defaultCacheBehavior","compress","targetOriginId","originId","viewerProtocolPolicy","allowedMethods","cachedMethods","forwardedValues","cookies","forward","queryString","minTtl","defaultTtl","maxTtl","priceClass","customErrorResponses","errorCode","responseCode","responsePagePath","restrictions","geoRestriction","restrictionType","viewerCertificate","cloudfrontDefaultCertificate","opts","ignoreChanges","deliveryBucket","viewerRequest","Function","runtime","publish","code","fs","readFileSync","__dirname","deliveryCloudfront","originRequestPolicyId","functionAssociations","functionArn","output","arn","eventType","orderedCacheBehaviors","headers","pathPattern","prerendering","createPrerenderingService","dbTableName","primaryDynamodbTableName","dbTableHashKey","primaryDynamodbTableHashKey","dbTableRangeKey","primaryDynamodbTableRangeKey","logDbTableName","logDynamodbTableName","appUrl","interpolate","domainName","deliveryUrl","bucket","cloudfrontId","id","domains","applyCustomDomain","previewDomains","process","WCP_PROJECT_ENVIRONMENT","WEBINY_MULTI_TENANCY","originLambda","applyTenantRouter","addOutputs","websiteRouterOriginRequestFunction","appId","appStorage","deliveryId","deliveryStorage","addDomainsUrlsOutputs","cloudfrontDistribution","map","distributionDomain","distributionUrl","usedDomain","usedUrl","tagResources","WbyProjectName","getEnvVariableWebinyProjectName","WbyEnvironment","getEnvVariableWebinyEnv","WbyEnvironmentVariant","getEnvVariableWebinyVariant","preview","delivery","withServiceManifest","withCommonLambdaEnvVariables","resources","addServiceManifest","manifest","distributionId","bucketDomainName","bucketRegionalDomainName","exports"],"sources":["createWebsitePulumiApp.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport fs from \"fs\";\nimport { createPulumiApp, PulumiAppParam, PulumiAppParamCallback } from \"@webiny/pulumi\";\nimport { createPrivateAppBucket } from \"../createAppBucket\";\nimport { applyCustomDomain, CustomDomainParams } from \"../customDomain\";\nimport { createPrerenderingService } from \"./WebsitePrerendering\";\nimport { ApiOutput, CoreOutput, VpcConfig } from \"~/apps\";\nimport { addDomainsUrlsOutputs, tagResources, withCommonLambdaEnvVariables } from \"~/utils\";\nimport { applyTenantRouter } from \"~/apps/tenantRouter\";\nimport { withServiceManifest } from \"~/utils/withServiceManifest\";\nimport { DEFAULT_PROD_ENV_NAMES } from \"~/constants\";\nimport { getEnvVariableWebinyVariant } from \"~/env/variant\";\nimport { getEnvVariableWebinyEnv } from \"~/env/env\";\nimport { getEnvVariableWebinyProjectName } from \"~/env/projectName\";\n\nexport type WebsitePulumiApp = ReturnType<typeof createWebsitePulumiApp>;\n\nexport interface CreateWebsitePulumiAppParams {\n /**\n * Custom domain(s) configuration.\n */\n domains?: PulumiAppParamCallback<CustomDomainParams>;\n\n /**\n * Custom preview domain(s) configuration.\n */\n previewDomains?: PulumiAppParamCallback<CustomDomainParams>;\n\n /**\n * Enables or disables VPC for the API.\n * For VPC to work you also have to enable it in the `core` application.\n */\n vpc?: PulumiAppParam<boolean | undefined>;\n\n /**\n * Provides a way to adjust existing Pulumi code (cloud infrastructure resources)\n * or add additional ones into the mix.\n */\n pulumi?: (app: WebsitePulumiApp) => void | Promise<void>;\n\n /**\n * Prefixes names of all Pulumi cloud infrastructure resource with given prefix.\n */\n pulumiResourceNamePrefix?: PulumiAppParam<string>;\n\n /**\n * Treats provided environments as production environments, which\n * are deployed in production deployment mode.\n * https://www.webiny.com/docs/architecture/deployment-modes/production\n */\n productionEnvironments?: PulumiAppParam<string[]>;\n}\n\nexport const createWebsitePulumiApp = (projectAppParams: CreateWebsitePulumiAppParams = {}) => {\n const baseApp = createPulumiApp({\n name: \"website\",\n path: \"apps/website\",\n config: projectAppParams,\n program: async app => {\n const pulumiResourceNamePrefix = app.getParam(\n projectAppParams.pulumiResourceNamePrefix\n );\n if (pulumiResourceNamePrefix) {\n app.onResource(resource => {\n if (!resource.name.startsWith(pulumiResourceNamePrefix)) {\n resource.name = `${pulumiResourceNamePrefix}${resource.name}`;\n }\n });\n }\n\n // Overrides must be applied via a handler, registered at the very start of the program.\n // By doing this, we're ensuring user's adjustments are not applied to late.\n if (projectAppParams.pulumi) {\n app.addHandler(() => {\n return projectAppParams.pulumi!(app as WebsitePulumiApp);\n });\n }\n\n const productionEnvironments =\n app.params.create.productionEnvironments || DEFAULT_PROD_ENV_NAMES;\n const isProduction = productionEnvironments.includes(app.params.run.env);\n\n // Register core and api output as a module, to be available to all other modules.\n const core = app.addModule(CoreOutput);\n app.addModule(ApiOutput);\n\n // Register VPC config module to be available to other modules.\n const vpcEnabled = app.getParam(projectAppParams?.vpc) ?? isProduction;\n app.addModule(VpcConfig, { enabled: vpcEnabled });\n\n const appBucket = createPrivateAppBucket(app, \"app\");\n\n const appCloudfront = app.addResource(aws.cloudfront.Distribution, {\n name: \"app\",\n config: {\n enabled: true,\n waitForDeployment: true,\n origins: [appBucket.origin],\n defaultRootObject: \"index.html\",\n defaultCacheBehavior: {\n compress: true,\n targetOriginId: appBucket.origin.originId,\n viewerProtocolPolicy: \"redirect-to-https\",\n allowedMethods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n cachedMethods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n forwardedValues: {\n cookies: { forward: \"none\" },\n queryString: false\n },\n // MinTTL <= DefaultTTL <= MaxTTL\n minTtl: 0,\n defaultTtl: 0,\n maxTtl: 0\n },\n priceClass: \"PriceClass_100\",\n customErrorResponses: [\n { errorCode: 404, responseCode: 404, responsePagePath: \"/index.html\" }\n ],\n restrictions: {\n geoRestriction: {\n restrictionType: \"none\"\n }\n },\n viewerCertificate: {\n cloudfrontDefaultCertificate: true\n }\n },\n opts: {\n // We are ignoring changes to the \"staging\" property. This is because of the following.\n // With the 5.41.0 release of Webiny, we also upgraded Pulumi to v6. This introduced a change\n // with how Cloudfront distributions are deployed, where Pulumi now also controls the new\n // `staging` property.\n // If not set, Pulumi will default it to `false`. Which is fine, but, the problem is\n // that, because this property did not exist before, it will always be considered as a change\n // upon deployment.\n // We might think this is fine, but, the problem is that a change in this property causes\n // a full replacement of the Cloudfront distribution, which is not acceptable. Especially\n // if a custom domain has already been associated with the distribution. This then would\n // require the user to disassociate the domain, wait for the distribution to be replaced,\n // and then re-associate the domain. This is not a good experience.\n ignoreChanges: [\"staging\"]\n }\n });\n\n const deliveryBucket = createPrivateAppBucket(app, \"delivery\");\n\n /**\n * We need to have a Cloudfront Function to perform a simple request rewrite, so the request always includes\n * an \"/index.html\". This is necessary because our buckets are not \"website\" buckets, and we need to\n * have an exact object key when requesting page paths.\n */\n const viewerRequest = app.addResource(aws.cloudfront.Function, {\n name: \"cfViewerRequest\",\n config: {\n runtime: \"cloudfront-js-1.0\",\n publish: true,\n code: fs.readFileSync(__dirname + `/deliveryViewerRequest.js`, \"utf8\")\n }\n });\n\n const deliveryCloudfront = app.addResource(aws.cloudfront.Distribution, {\n name: \"delivery\",\n config: {\n enabled: true,\n waitForDeployment: true,\n origins: [deliveryBucket.origin, appBucket.origin],\n defaultRootObject: \"index.html\",\n defaultCacheBehavior: {\n compress: true,\n targetOriginId: deliveryBucket.origin.originId,\n viewerProtocolPolicy: \"redirect-to-https\",\n allowedMethods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n cachedMethods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n originRequestPolicyId: \"\",\n forwardedValues: {\n cookies: { forward: \"none\" },\n queryString: true\n },\n // MinTTL <= DefaultTTL <= MaxTTL\n minTtl: 0,\n defaultTtl: 30,\n maxTtl: 30,\n functionAssociations: [\n { functionArn: viewerRequest.output.arn, eventType: \"viewer-request\" }\n ]\n },\n orderedCacheBehaviors: [\n {\n compress: true,\n allowedMethods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n cachedMethods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n forwardedValues: {\n cookies: {\n forward: \"none\"\n },\n headers: [],\n queryString: false\n },\n pathPattern: \"/static/*\",\n viewerProtocolPolicy: \"allow-all\",\n targetOriginId: appBucket.origin.originId,\n // MinTTL <= DefaultTTL <= MaxTTL\n minTtl: 0,\n defaultTtl: 2592000, // 30 days\n maxTtl: 2592000\n },\n // This forward is necessary for non-WCP projects. For WCP projects, the\n // forwarding is performed by the `website-router` Lambda@Edge function.\n {\n compress: true,\n allowedMethods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n cachedMethods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n forwardedValues: {\n cookies: {\n forward: \"none\"\n },\n headers: [],\n queryString: false\n },\n pathPattern: \"/robots.txt\",\n viewerProtocolPolicy: \"allow-all\",\n targetOriginId: appBucket.origin.originId\n }\n ],\n customErrorResponses: [\n {\n errorCode: 404,\n responseCode: 404,\n responsePagePath: \"/_NOT_FOUND_PAGE_/index.html\"\n }\n ],\n priceClass: \"PriceClass_100\",\n restrictions: {\n geoRestriction: {\n restrictionType: \"none\"\n }\n },\n viewerCertificate: {\n cloudfrontDefaultCertificate: true\n }\n },\n opts: {\n // Check the comment in the `appCloudfront` resource above for more info.\n ignoreChanges: [\"staging\"]\n }\n });\n\n const prerendering = createPrerenderingService(app, {\n dbTableName: core.primaryDynamodbTableName,\n dbTableHashKey: core.primaryDynamodbTableHashKey,\n dbTableRangeKey: core.primaryDynamodbTableRangeKey,\n logDbTableName: core.logDynamodbTableName,\n appUrl: pulumi.interpolate`https://${appCloudfront.output.domainName}`,\n deliveryUrl: pulumi.interpolate`https://${deliveryCloudfront.output.domainName}`,\n bucket: deliveryBucket.bucket.output.bucket,\n cloudfrontId: deliveryCloudfront.output.id\n });\n\n const domains = app.getParam(projectAppParams.domains);\n if (domains) {\n applyCustomDomain(deliveryCloudfront, domains);\n }\n\n const previewDomains = app.getParam(projectAppParams.previewDomains);\n if (previewDomains) {\n applyCustomDomain(appCloudfront, previewDomains);\n }\n\n if (\n process.env.WCP_PROJECT_ENVIRONMENT ||\n process.env.WEBINY_MULTI_TENANCY === \"true\"\n ) {\n const { originLambda } = applyTenantRouter(app, deliveryCloudfront);\n\n app.addHandler(() => {\n app.addOutputs({\n websiteRouterOriginRequestFunction: originLambda.output.name\n });\n });\n }\n\n app.addOutputs({\n // Cloudfront and S3 bucket used to host the single-page application (SPA). The URL of the distribution is mainly\n // utilized by the Page Builder app's prerendering engine. Using this URL, it accesses the SPA and creates HTML snapshots.\n // The files that are generated in that process are stored in the `deliveryStorage` S3 bucket further below.\n appId: appCloudfront.output.id,\n appStorage: appBucket.bucket.output.id,\n\n // These are the Cloudfront and S3 bucket that will deliver static pages to the actual website visitors.\n // The static HTML snapshots delivered from them still rely on the app's S3 bucket\n // defined above, for serving static assets (JS, CSS, images).\n deliveryId: deliveryCloudfront.output.id,\n deliveryStorage: deliveryBucket.bucket.output.id\n });\n\n app.addHandler(() => {\n addDomainsUrlsOutputs({\n app,\n cloudfrontDistribution: appCloudfront,\n map: {\n distributionDomain: \"cloudfrontAppDomain\",\n distributionUrl: \"cloudfrontAppUrl\",\n usedDomain: \"appDomain\",\n usedUrl: \"appUrl\"\n }\n });\n\n addDomainsUrlsOutputs({\n app,\n cloudfrontDistribution: deliveryCloudfront,\n map: {\n distributionDomain: \"cloudfrontDeliveryDomain\",\n distributionUrl: \"cloudfrontDeliveryUrl\",\n usedDomain: \"deliveryDomain\",\n usedUrl: \"deliveryUrl\"\n }\n });\n });\n\n tagResources({\n WbyProjectName: getEnvVariableWebinyProjectName(),\n WbyEnvironment: getEnvVariableWebinyEnv(),\n WbyEnvironmentVariant: getEnvVariableWebinyVariant()\n });\n\n return {\n prerendering,\n\n // \"preview\" and \"app\" are the same.\n // We introduced \"preview\" just because it's the word we use when talking about\n // Page Builder and \"previewing\" pages. In other words, the \"preview\" property\n // contains all resources related to serving page previews, unlike \"delivery\",\n // which is used to serve published pages to actual website visitors.\n // The \"app\" property was still left here just for backwards compatibility.\n preview: {\n ...appBucket,\n cloudfront: appCloudfront\n },\n app: {\n ...appBucket,\n cloudfront: appCloudfront\n },\n\n delivery: {\n ...deliveryBucket,\n cloudfront: deliveryCloudfront\n }\n };\n }\n });\n\n const app = withServiceManifest(withCommonLambdaEnvVariables(baseApp));\n\n app.addHandler(() => {\n const preview = baseApp.resources.preview;\n const delivery = baseApp.resources.delivery;\n\n app.addServiceManifest({\n name: \"website\",\n manifest: {\n preview: {\n cloudfront: {\n distributionId: preview.cloudfront.output.id,\n domainName: preview.cloudfront.output.domainName\n },\n bucket: {\n name: preview.bucket.output.id,\n arn: preview.bucket.output.arn,\n bucketDomainName: preview.bucket.output.bucketDomainName,\n bucketRegionalDomainName: preview.bucket.output.bucketRegionalDomainName\n }\n },\n delivery: {\n cloudfront: {\n distributionId: delivery.cloudfront.output.id,\n domainName: delivery.cloudfront.output.domainName\n },\n bucket: {\n name: delivery.bucket.output.id,\n arn: delivery.bucket.output.arn,\n bucketDomainName: delivery.bucket.output.bucketDomainName,\n bucketRegionalDomainName: delivery.bucket.output.bucketRegionalDomainName\n }\n }\n }\n });\n });\n\n return app;\n};\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["pulumi","_interopRequireWildcard","require","aws","_fs","_interopRequireDefault","_pulumi2","_createAppBucket","_customDomain","_WebsitePrerendering","_","_utils","_tenantRouter","_withServiceManifest","_constants","_variant","_env","_projectName","createWebsitePulumiApp","projectAppParams","baseApp","createPulumiApp","name","path","config","program","app","pulumiResourceNamePrefix","getParam","onResource","resource","startsWith","addHandler","productionEnvironments","params","create","DEFAULT_PROD_ENV_NAMES","isProduction","includes","run","env","core","addModule","CoreOutput","ApiOutput","vpcEnabled","vpc","VpcConfig","enabled","appBucket","createPrivateAppBucket","appCloudfront","addResource","cloudfront","Distribution","waitForDeployment","origins","origin","defaultRootObject","defaultCacheBehavior","compress","targetOriginId","originId","viewerProtocolPolicy","allowedMethods","cachedMethods","forwardedValues","cookies","forward","queryString","minTtl","defaultTtl","maxTtl","priceClass","customErrorResponses","errorCode","responseCode","responsePagePath","restrictions","geoRestriction","restrictionType","viewerCertificate","cloudfrontDefaultCertificate","opts","ignoreChanges","deliveryBucket","viewerRequest","Function","runtime","publish","code","fs","readFileSync","__dirname","deliveryCloudfront","originRequestPolicyId","functionAssociations","functionArn","output","arn","eventType","orderedCacheBehaviors","headers","pathPattern","prerendering","createPrerenderingService","dbTableName","primaryDynamodbTableName","dbTableHashKey","primaryDynamodbTableHashKey","dbTableRangeKey","primaryDynamodbTableRangeKey","logDbTableName","logDynamodbTableName","appUrl","interpolate","domainName","deliveryUrl","bucket","cloudfrontId","id","domains","applyCustomDomain","previewDomains","process","WCP_PROJECT_ENVIRONMENT","WEBINY_MULTI_TENANCY","redirects","originLambda","applyTenantRouter","addOutputs","websiteRouterOriginRequestFunction","appId","appStorage","deliveryId","deliveryStorage","addDomainsUrlsOutputs","cloudfrontDistribution","map","distributionDomain","distributionUrl","usedDomain","usedUrl","tagResources","WbyProjectName","getEnvVariableWebinyProjectName","WbyEnvironment","getEnvVariableWebinyEnv","WbyEnvironmentVariant","getEnvVariableWebinyVariant","preview","delivery","withServiceManifest","withCommonLambdaEnvVariables","resources","addServiceManifest","manifest","distributionId","bucketDomainName","bucketRegionalDomainName","exports"],"sources":["createWebsitePulumiApp.ts"],"sourcesContent":["import * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport fs from \"fs\";\nimport { createPulumiApp, PulumiAppParam, PulumiAppParamCallback } from \"@webiny/pulumi\";\nimport { createPrivateAppBucket } from \"../createAppBucket\";\nimport { applyCustomDomain, CustomDomainParams } from \"../customDomain\";\nimport { createPrerenderingService } from \"./WebsitePrerendering\";\nimport { ApiOutput, CoreOutput, VpcConfig } from \"~/apps\";\nimport { addDomainsUrlsOutputs, tagResources, withCommonLambdaEnvVariables } from \"~/utils\";\nimport { applyTenantRouter } from \"~/apps/tenantRouter\";\nimport { withServiceManifest } from \"~/utils/withServiceManifest\";\nimport { DEFAULT_PROD_ENV_NAMES } from \"~/constants\";\nimport { getEnvVariableWebinyVariant } from \"~/env/variant\";\nimport { getEnvVariableWebinyEnv } from \"~/env/env\";\nimport { getEnvVariableWebinyProjectName } from \"~/env/projectName\";\n\nexport type WebsitePulumiApp = ReturnType<typeof createWebsitePulumiApp>;\n\nexport type WebsiteRedirect = {\n from: string;\n to: string;\n permanent: boolean;\n /**\n * Cache duration in seconds.\n * For permanent redirects, the default value is 1 year (31536000 seconds).\n * For temporary redirects, the default value is 1 day (86400 seconds).\n */\n maxAge?: number;\n};\n\nexport interface CreateWebsitePulumiAppParams {\n /**\n * Custom domain(s) configuration.\n */\n domains?: PulumiAppParamCallback<CustomDomainParams>;\n\n /**\n * Custom preview domain(s) configuration.\n */\n previewDomains?: PulumiAppParamCallback<CustomDomainParams>;\n\n /**\n * Enables or disables VPC for the API.\n * For VPC to work you also have to enable it in the `core` application.\n */\n vpc?: PulumiAppParam<boolean | undefined>;\n\n /**\n * Provides a way to adjust existing Pulumi code (cloud infrastructure resources)\n * or add additional ones into the mix.\n */\n pulumi?: (app: WebsitePulumiApp) => void | Promise<void>;\n\n /**\n * Define redirects to be handled by website Lambda@Edge function.\n */\n redirects?: () => Promise<WebsiteRedirect[]> | WebsiteRedirect[];\n\n /**\n * Prefixes names of all Pulumi cloud infrastructure resource with given prefix.\n */\n pulumiResourceNamePrefix?: PulumiAppParam<string>;\n\n /**\n * Treats provided environments as production environments, which\n * are deployed in production deployment mode.\n * https://www.webiny.com/docs/architecture/deployment-modes/production\n */\n productionEnvironments?: PulumiAppParam<string[]>;\n}\n\nexport const createWebsitePulumiApp = (projectAppParams: CreateWebsitePulumiAppParams = {}) => {\n const baseApp = createPulumiApp({\n name: \"website\",\n path: \"apps/website\",\n config: projectAppParams,\n program: async app => {\n const pulumiResourceNamePrefix = app.getParam(\n projectAppParams.pulumiResourceNamePrefix\n );\n if (pulumiResourceNamePrefix) {\n app.onResource(resource => {\n if (!resource.name.startsWith(pulumiResourceNamePrefix)) {\n resource.name = `${pulumiResourceNamePrefix}${resource.name}`;\n }\n });\n }\n\n // Overrides must be applied via a handler, registered at the very start of the program.\n // By doing this, we're ensuring user's adjustments are not applied to late.\n if (projectAppParams.pulumi) {\n app.addHandler(() => {\n return projectAppParams.pulumi!(app as WebsitePulumiApp);\n });\n }\n\n const productionEnvironments =\n app.params.create.productionEnvironments || DEFAULT_PROD_ENV_NAMES;\n const isProduction = productionEnvironments.includes(app.params.run.env);\n\n // Register core and api output as a module, to be available to all other modules.\n const core = app.addModule(CoreOutput);\n app.addModule(ApiOutput);\n\n // Register VPC config module to be available to other modules.\n const vpcEnabled = app.getParam(projectAppParams?.vpc) ?? isProduction;\n app.addModule(VpcConfig, { enabled: vpcEnabled });\n\n const appBucket = createPrivateAppBucket(app, \"app\");\n\n const appCloudfront = app.addResource(aws.cloudfront.Distribution, {\n name: \"app\",\n config: {\n enabled: true,\n waitForDeployment: true,\n origins: [appBucket.origin],\n defaultRootObject: \"index.html\",\n defaultCacheBehavior: {\n compress: true,\n targetOriginId: appBucket.origin.originId,\n viewerProtocolPolicy: \"redirect-to-https\",\n allowedMethods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n cachedMethods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n forwardedValues: {\n cookies: { forward: \"none\" },\n queryString: false\n },\n // MinTTL <= DefaultTTL <= MaxTTL\n minTtl: 0,\n defaultTtl: 0,\n maxTtl: 0\n },\n priceClass: \"PriceClass_100\",\n customErrorResponses: [\n { errorCode: 404, responseCode: 404, responsePagePath: \"/index.html\" }\n ],\n restrictions: {\n geoRestriction: {\n restrictionType: \"none\"\n }\n },\n viewerCertificate: {\n cloudfrontDefaultCertificate: true\n }\n },\n opts: {\n // We are ignoring changes to the \"staging\" property. This is because of the following.\n // With the 5.41.0 release of Webiny, we also upgraded Pulumi to v6. This introduced a change\n // with how Cloudfront distributions are deployed, where Pulumi now also controls the new\n // `staging` property.\n // If not set, Pulumi will default it to `false`. Which is fine, but, the problem is\n // that, because this property did not exist before, it will always be considered as a change\n // upon deployment.\n // We might think this is fine, but, the problem is that a change in this property causes\n // a full replacement of the Cloudfront distribution, which is not acceptable. Especially\n // if a custom domain has already been associated with the distribution. This then would\n // require the user to disassociate the domain, wait for the distribution to be replaced,\n // and then re-associate the domain. This is not a good experience.\n ignoreChanges: [\"staging\"]\n }\n });\n\n const deliveryBucket = createPrivateAppBucket(app, \"delivery\");\n\n /**\n * We need to have a Cloudfront Function to perform a simple request rewrite, so the request always includes\n * an \"/index.html\". This is necessary because our buckets are not \"website\" buckets, and we need to\n * have an exact object key when requesting page paths.\n */\n const viewerRequest = app.addResource(aws.cloudfront.Function, {\n name: \"cfViewerRequest\",\n config: {\n runtime: \"cloudfront-js-1.0\",\n publish: true,\n code: fs.readFileSync(__dirname + `/deliveryViewerRequest.js`, \"utf8\")\n }\n });\n\n const deliveryCloudfront = app.addResource(aws.cloudfront.Distribution, {\n name: \"delivery\",\n config: {\n enabled: true,\n waitForDeployment: true,\n origins: [deliveryBucket.origin, appBucket.origin],\n defaultRootObject: \"index.html\",\n defaultCacheBehavior: {\n compress: true,\n targetOriginId: deliveryBucket.origin.originId,\n viewerProtocolPolicy: \"redirect-to-https\",\n allowedMethods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n cachedMethods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n originRequestPolicyId: \"\",\n forwardedValues: {\n cookies: { forward: \"none\" },\n queryString: true\n },\n // MinTTL <= DefaultTTL <= MaxTTL\n minTtl: 0,\n defaultTtl: 30,\n maxTtl: 30,\n functionAssociations: [\n { functionArn: viewerRequest.output.arn, eventType: \"viewer-request\" }\n ]\n },\n orderedCacheBehaviors: [\n {\n compress: true,\n allowedMethods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n cachedMethods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n forwardedValues: {\n cookies: {\n forward: \"none\"\n },\n headers: [],\n queryString: false\n },\n pathPattern: \"/static/*\",\n viewerProtocolPolicy: \"allow-all\",\n targetOriginId: appBucket.origin.originId,\n // MinTTL <= DefaultTTL <= MaxTTL\n minTtl: 0,\n defaultTtl: 2592000, // 30 days\n maxTtl: 2592000\n },\n // This forward is necessary for non-WCP projects. For WCP projects, the\n // forwarding is performed by the `website-router` Lambda@Edge function.\n {\n compress: true,\n allowedMethods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n cachedMethods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n forwardedValues: {\n cookies: {\n forward: \"none\"\n },\n headers: [],\n queryString: false\n },\n pathPattern: \"/robots.txt\",\n viewerProtocolPolicy: \"allow-all\",\n targetOriginId: appBucket.origin.originId\n }\n ],\n customErrorResponses: [\n {\n errorCode: 404,\n responseCode: 404,\n responsePagePath: \"/_NOT_FOUND_PAGE_/index.html\"\n }\n ],\n priceClass: \"PriceClass_100\",\n restrictions: {\n geoRestriction: {\n restrictionType: \"none\"\n }\n },\n viewerCertificate: {\n cloudfrontDefaultCertificate: true\n }\n },\n opts: {\n // Check the comment in the `appCloudfront` resource above for more info.\n ignoreChanges: [\"staging\"]\n }\n });\n\n const prerendering = createPrerenderingService(app, {\n dbTableName: core.primaryDynamodbTableName,\n dbTableHashKey: core.primaryDynamodbTableHashKey,\n dbTableRangeKey: core.primaryDynamodbTableRangeKey,\n logDbTableName: core.logDynamodbTableName,\n appUrl: pulumi.interpolate`https://${appCloudfront.output.domainName}`,\n deliveryUrl: pulumi.interpolate`https://${deliveryCloudfront.output.domainName}`,\n bucket: deliveryBucket.bucket.output.bucket,\n cloudfrontId: deliveryCloudfront.output.id\n });\n\n const domains = app.getParam(projectAppParams.domains);\n if (domains) {\n applyCustomDomain(deliveryCloudfront, domains);\n }\n\n const previewDomains = app.getParam(projectAppParams.previewDomains);\n if (previewDomains) {\n applyCustomDomain(appCloudfront, previewDomains);\n }\n\n if (\n process.env.WCP_PROJECT_ENVIRONMENT ||\n process.env.WEBINY_MULTI_TENANCY === \"true\"\n ) {\n const redirects = projectAppParams.redirects\n ? await projectAppParams.redirects()\n : [];\n\n const { originLambda } = applyTenantRouter(app, deliveryCloudfront, redirects);\n\n app.addHandler(() => {\n app.addOutputs({\n websiteRouterOriginRequestFunction: originLambda.output.name\n });\n });\n }\n\n app.addOutputs({\n // Cloudfront and S3 bucket used to host the single-page application (SPA). The URL of the distribution is mainly\n // utilized by the Page Builder app's prerendering engine. Using this URL, it accesses the SPA and creates HTML snapshots.\n // The files that are generated in that process are stored in the `deliveryStorage` S3 bucket further below.\n appId: appCloudfront.output.id,\n appStorage: appBucket.bucket.output.id,\n\n // These are the Cloudfront and S3 bucket that will deliver static pages to the actual website visitors.\n // The static HTML snapshots delivered from them still rely on the app's S3 bucket\n // defined above, for serving static assets (JS, CSS, images).\n deliveryId: deliveryCloudfront.output.id,\n deliveryStorage: deliveryBucket.bucket.output.id\n });\n\n app.addHandler(() => {\n addDomainsUrlsOutputs({\n app,\n cloudfrontDistribution: appCloudfront,\n map: {\n distributionDomain: \"cloudfrontAppDomain\",\n distributionUrl: \"cloudfrontAppUrl\",\n usedDomain: \"appDomain\",\n usedUrl: \"appUrl\"\n }\n });\n\n addDomainsUrlsOutputs({\n app,\n cloudfrontDistribution: deliveryCloudfront,\n map: {\n distributionDomain: \"cloudfrontDeliveryDomain\",\n distributionUrl: \"cloudfrontDeliveryUrl\",\n usedDomain: \"deliveryDomain\",\n usedUrl: \"deliveryUrl\"\n }\n });\n });\n\n tagResources({\n WbyProjectName: getEnvVariableWebinyProjectName(),\n WbyEnvironment: getEnvVariableWebinyEnv(),\n WbyEnvironmentVariant: getEnvVariableWebinyVariant()\n });\n\n return {\n prerendering,\n\n // \"preview\" and \"app\" are the same.\n // We introduced \"preview\" just because it's the word we use when talking about\n // Page Builder and \"previewing\" pages. In other words, the \"preview\" property\n // contains all resources related to serving page previews, unlike \"delivery\",\n // which is used to serve published pages to actual website visitors.\n // The \"app\" property was still left here just for backwards compatibility.\n preview: {\n ...appBucket,\n cloudfront: appCloudfront\n },\n app: {\n ...appBucket,\n cloudfront: appCloudfront\n },\n\n delivery: {\n ...deliveryBucket,\n cloudfront: deliveryCloudfront\n }\n };\n }\n });\n\n const app = withServiceManifest(withCommonLambdaEnvVariables(baseApp));\n\n app.addHandler(() => {\n const preview = baseApp.resources.preview;\n const delivery = baseApp.resources.delivery;\n\n app.addServiceManifest({\n name: \"website\",\n manifest: {\n preview: {\n cloudfront: {\n distributionId: preview.cloudfront.output.id,\n domainName: preview.cloudfront.output.domainName\n },\n bucket: {\n name: preview.bucket.output.id,\n arn: preview.bucket.output.arn,\n bucketDomainName: preview.bucket.output.bucketDomainName,\n bucketRegionalDomainName: preview.bucket.output.bucketRegionalDomainName\n }\n },\n delivery: {\n cloudfront: {\n distributionId: delivery.cloudfront.output.id,\n domainName: delivery.cloudfront.output.domainName\n },\n bucket: {\n name: delivery.bucket.output.id,\n arn: delivery.bucket.output.arn,\n bucketDomainName: delivery.bucket.output.bucketDomainName,\n bucketRegionalDomainName: delivery.bucket.output.bucketRegionalDomainName\n }\n }\n }\n });\n });\n\n return app;\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function matchRedirect(request: any, redirects: any): (() => {
|
|
2
|
+
status: string;
|
|
3
|
+
statusDescription: string;
|
|
4
|
+
headers: {
|
|
5
|
+
location: {
|
|
6
|
+
key: string;
|
|
7
|
+
value: any;
|
|
8
|
+
}[];
|
|
9
|
+
"cache-control": {
|
|
10
|
+
key: string;
|
|
11
|
+
value: string;
|
|
12
|
+
}[];
|
|
13
|
+
};
|
|
14
|
+
}) | null;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.matchRedirect = (request, redirects) => {
|
|
4
|
+
const headers = request.headers;
|
|
5
|
+
|
|
6
|
+
// Build the full URL from the request
|
|
7
|
+
const protocol = headers["cloudfront-forwarded-proto"] ? headers["cloudfront-forwarded-proto"][0].value : "https";
|
|
8
|
+
const hostname = headers.host[0].value;
|
|
9
|
+
const uri = request.uri.replace("/index.html", "");
|
|
10
|
+
const querystring = request.querystring ? `?${request.querystring}` : "";
|
|
11
|
+
const fullUrl = `${protocol}://${hostname}${uri}${querystring}`;
|
|
12
|
+
const fullUrlNoQuery = `${protocol}://${hostname}${uri}`;
|
|
13
|
+
|
|
14
|
+
// Try to find a match (priority: with query > without query > path only)
|
|
15
|
+
let redirectConfig = redirects[fullUrl] || redirects[fullUrlNoQuery] || redirects[uri];
|
|
16
|
+
|
|
17
|
+
// If no match found, return null
|
|
18
|
+
if (!redirectConfig) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Return a function that generates the redirect response
|
|
23
|
+
return () => {
|
|
24
|
+
// Build redirect URL
|
|
25
|
+
let redirectTo = redirectConfig.to;
|
|
26
|
+
|
|
27
|
+
// If redirect.to is a path (not full URL), prepend current domain
|
|
28
|
+
if (!redirectTo.startsWith("http://") && !redirectTo.startsWith("https://")) {
|
|
29
|
+
redirectTo = `${protocol}://${hostname}${redirectTo}`;
|
|
30
|
+
}
|
|
31
|
+
console.log("REDIRECTING!", redirectTo);
|
|
32
|
+
return {
|
|
33
|
+
status: redirectConfig.permanent ? "301" : "302",
|
|
34
|
+
statusDescription: redirectConfig.permanent ? "Moved Permanently" : "Found",
|
|
35
|
+
headers: {
|
|
36
|
+
location: [{
|
|
37
|
+
key: "Location",
|
|
38
|
+
value: redirectTo
|
|
39
|
+
}],
|
|
40
|
+
"cache-control": [{
|
|
41
|
+
key: "Cache-Control",
|
|
42
|
+
value: "max-age=" + redirectConfig.maxAge
|
|
43
|
+
}]
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
//# sourceMappingURL=matchRedirect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["exports","matchRedirect","request","redirects","headers","protocol","value","hostname","host","uri","replace","querystring","fullUrl","fullUrlNoQuery","redirectConfig","redirectTo","to","startsWith","console","log","status","permanent","statusDescription","location","key","maxAge"],"sources":["matchRedirect.js"],"sourcesContent":["exports.matchRedirect = (request, redirects) => {\n const headers = request.headers;\n\n // Build the full URL from the request\n const protocol = headers[\"cloudfront-forwarded-proto\"]\n ? headers[\"cloudfront-forwarded-proto\"][0].value\n : \"https\";\n const hostname = headers.host[0].value;\n const uri = request.uri.replace(\"/index.html\", \"\");\n const querystring = request.querystring ? `?${request.querystring}` : \"\";\n\n const fullUrl = `${protocol}://${hostname}${uri}${querystring}`;\n const fullUrlNoQuery = `${protocol}://${hostname}${uri}`;\n\n // Try to find a match (priority: with query > without query > path only)\n let redirectConfig = redirects[fullUrl] || redirects[fullUrlNoQuery] || redirects[uri];\n\n // If no match found, return null\n if (!redirectConfig) {\n return null;\n }\n\n // Return a function that generates the redirect response\n return () => {\n // Build redirect URL\n let redirectTo = redirectConfig.to;\n\n // If redirect.to is a path (not full URL), prepend current domain\n if (!redirectTo.startsWith(\"http://\") && !redirectTo.startsWith(\"https://\")) {\n redirectTo = `${protocol}://${hostname}${redirectTo}`;\n }\n\n console.log(\"REDIRECTING!\", redirectTo);\n\n return {\n status: redirectConfig.permanent ? \"301\" : \"302\",\n statusDescription: redirectConfig.permanent ? \"Moved Permanently\" : \"Found\",\n headers: {\n location: [\n {\n key: \"Location\",\n value: redirectTo\n }\n ],\n \"cache-control\": [\n {\n key: \"Cache-Control\",\n value: \"max-age=\" + redirectConfig.maxAge\n }\n ]\n }\n };\n };\n};\n"],"mappings":";;AAAAA,OAAO,CAACC,aAAa,GAAG,CAACC,OAAO,EAAEC,SAAS,KAAK;EAC5C,MAAMC,OAAO,GAAGF,OAAO,CAACE,OAAO;;EAE/B;EACA,MAAMC,QAAQ,GAAGD,OAAO,CAAC,4BAA4B,CAAC,GAChDA,OAAO,CAAC,4BAA4B,CAAC,CAAC,CAAC,CAAC,CAACE,KAAK,GAC9C,OAAO;EACb,MAAMC,QAAQ,GAAGH,OAAO,CAACI,IAAI,CAAC,CAAC,CAAC,CAACF,KAAK;EACtC,MAAMG,GAAG,GAAGP,OAAO,CAACO,GAAG,CAACC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC;EAClD,MAAMC,WAAW,GAAGT,OAAO,CAACS,WAAW,GAAG,IAAIT,OAAO,CAACS,WAAW,EAAE,GAAG,EAAE;EAExE,MAAMC,OAAO,GAAG,GAAGP,QAAQ,MAAME,QAAQ,GAAGE,GAAG,GAAGE,WAAW,EAAE;EAC/D,MAAME,cAAc,GAAG,GAAGR,QAAQ,MAAME,QAAQ,GAAGE,GAAG,EAAE;;EAExD;EACA,IAAIK,cAAc,GAAGX,SAAS,CAACS,OAAO,CAAC,IAAIT,SAAS,CAACU,cAAc,CAAC,IAAIV,SAAS,CAACM,GAAG,CAAC;;EAEtF;EACA,IAAI,CAACK,cAAc,EAAE;IACjB,OAAO,IAAI;EACf;;EAEA;EACA,OAAO,MAAM;IACT;IACA,IAAIC,UAAU,GAAGD,cAAc,CAACE,EAAE;;IAElC;IACA,IAAI,CAACD,UAAU,CAACE,UAAU,CAAC,SAAS,CAAC,IAAI,CAACF,UAAU,CAACE,UAAU,CAAC,UAAU,CAAC,EAAE;MACzEF,UAAU,GAAG,GAAGV,QAAQ,MAAME,QAAQ,GAAGQ,UAAU,EAAE;IACzD;IAEAG,OAAO,CAACC,GAAG,CAAC,cAAc,EAAEJ,UAAU,CAAC;IAEvC,OAAO;MACHK,MAAM,EAAEN,cAAc,CAACO,SAAS,GAAG,KAAK,GAAG,KAAK;MAChDC,iBAAiB,EAAER,cAAc,CAACO,SAAS,GAAG,mBAAmB,GAAG,OAAO;MAC3EjB,OAAO,EAAE;QACLmB,QAAQ,EAAE,CACN;UACIC,GAAG,EAAE,UAAU;UACflB,KAAK,EAAES;QACX,CAAC,CACJ;QACD,eAAe,EAAE,CACb;UACIS,GAAG,EAAE,eAAe;UACpBlB,KAAK,EAAE,UAAU,GAAGQ,cAAc,CAACW;QACvC,CAAC;MAET;IACJ,CAAC;EACL,CAAC;AACL,CAAC","ignoreList":[]}
|
|
@@ -8,6 +8,10 @@ const {
|
|
|
8
8
|
QueryCommand,
|
|
9
9
|
GetCommand
|
|
10
10
|
} = require("@aws-sdk/lib-dynamodb");
|
|
11
|
+
const redirects = require("./redirects.json");
|
|
12
|
+
const {
|
|
13
|
+
matchRedirect
|
|
14
|
+
} = require("./matchRedirect.js");
|
|
11
15
|
|
|
12
16
|
// Since Lambda@Edge doesn't support ENV variables, the easiest way to pass
|
|
13
17
|
// config values to it is to inject them into the source code before deploy.
|
|
@@ -85,6 +89,10 @@ async function handleOriginRequest(request) {
|
|
|
85
89
|
const isCustomOrigin = Boolean(origin.custom);
|
|
86
90
|
const requestedDomain = request.headers.host[0].value;
|
|
87
91
|
const originDomain = isCustomOrigin ? origin.custom.domainName : origin.s3.domainName;
|
|
92
|
+
const redirect = matchRedirect(request, redirects);
|
|
93
|
+
if (redirect) {
|
|
94
|
+
return redirect();
|
|
95
|
+
}
|
|
88
96
|
let tenant;
|
|
89
97
|
if (await hasMultipleTenants()) {
|
|
90
98
|
// Find tenant by domain. This record is stored to the DB using the Tenant Manager app.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["DynamoDBClient","require","DynamoDBDocument","QueryCommand","GetCommand","DB_TABLE_NAME","DB_TABLE_REGION","client","region","documentClient","from","marshallOptions","convertEmptyValues","removeUndefinedValues","sanitizeRequestURI","uri","parts","split","filter","Boolean","length","lastPart","includes","join","getTenantIdByDomain","domain","cmd","TableName","Key","PK","SK","Item","send","tenant","undefined","hasMultipleTenants","IndexName","Limit","Select","KeyConditionExpression","ExpressionAttributeValues","Count","handleOriginRequest","request","origin","isCustomOrigin","custom","requestedDomain","headers","host","value","originDomain","domainName","s3","console","log","startsWith","status","statusDescription","exports","handler","event","config","Records","cf","eventType"],"sources":["request.js"],"sourcesContent":["const { DynamoDBClient } = require(\"@aws-sdk/client-dynamodb\");\nconst { DynamoDBDocument, QueryCommand, GetCommand } = require(\"@aws-sdk/lib-dynamodb\");\n\n// Since Lambda@Edge doesn't support ENV variables, the easiest way to pass\n// config values to it is to inject them into the source code before deploy.\nconst DB_TABLE_NAME = \"{DB_TABLE_NAME}\";\nconst DB_TABLE_REGION = \"{DB_TABLE_REGION}\";\n\nconst client = new DynamoDBClient({\n region: DB_TABLE_REGION\n});\n\nconst documentClient = DynamoDBDocument.from(client, {\n marshallOptions: {\n convertEmptyValues: true,\n removeUndefinedValues: true\n }\n});\n\nfunction sanitizeRequestURI(uri) {\n // Make sure that `/` is not appended to index.html, or any path with extension.\n // We remove all slashes, filter out empty values, and reconstruct the path following\n // the fact that every page (slug) has a dedicated folder in the S3 bucket, and an `index.html`\n // file with the actual page HTML.\n const parts = uri.split(\"/\").filter(Boolean);\n\n // This means that a `/` (homepage) was requested. When the homepage is prerendered, we place its files\n // into the root of the tenant subfolder, e.g., `/root/index.html`.\n if (!parts.length) {\n return \"/index.html\";\n }\n\n const lastPart = parts[parts.length - 1];\n\n // If there's a `.` in the last part of the path, we assume it's a file extension.\n // In this case, we can reconstruct the path by joining parts with slashes.\n if (lastPart.includes(\".\")) {\n return [\"\", ...parts].join(\"/\");\n }\n\n // Otherwise, we assume it's a page slug, which needs to point to page's subfolder.\n // We construct a valid S3 bucket path to an HTML file.\n return [\"\", ...parts, \"index.html\"].join(\"/\");\n}\n\nasync function getTenantIdByDomain(domain) {\n const cmd = new GetCommand({\n TableName: DB_TABLE_NAME,\n Key: {\n PK: `DOMAIN#${domain}`,\n SK: \"A\"\n }\n });\n\n const { Item } = await documentClient.send(cmd);\n return Item ? Item.tenant : undefined;\n}\n\n/**\n * Check if \"root\" tenant has at least one child tenant.\n */\nasync function hasMultipleTenants() {\n const cmd = new QueryCommand({\n TableName: DB_TABLE_NAME,\n IndexName: \"GSI1\",\n Limit: 1,\n Select: \"COUNT\",\n KeyConditionExpression: \"GSI1_PK = :GSI1_PK and begins_with(GSI1_SK, :GSI1_SK)\",\n ExpressionAttributeValues: {\n \":GSI1_PK\": \"TENANTS\",\n \":GSI1_SK\": \"T#root#\"\n }\n });\n\n const { Count } = await documentClient.send(cmd);\n\n return Count > 0;\n}\n\nasync function handleOriginRequest(request) {\n const origin = request.origin;\n const isCustomOrigin = Boolean(origin.custom);\n const requestedDomain = request.headers.host[0].value;\n const originDomain = isCustomOrigin ? origin.custom.domainName : origin.s3.domainName;\n\n let tenant;\n if (await hasMultipleTenants()) {\n // Find tenant by domain. This record is stored to the DB using the Tenant Manager app.\n console.log(`Multiple tenants are present; loading by domain...`);\n tenant = await getTenantIdByDomain(requestedDomain);\n } else {\n console.log(`Only one tenant is present; falling back to \"root\".`);\n // If the system only has one tenant, we don't need to map by domain at all.\n tenant = \"root\";\n }\n\n if (tenant) {\n const uri = sanitizeRequestURI(request.uri);\n\n // To be on the safe side, make sure the requested uri doesn't already include the tenant ID.\n if (uri.startsWith(`/${tenant}/`)) {\n request.uri = uri;\n } else {\n // Prepend the tenant ID, to point to the correct S3 bucket folder.\n request.uri = `/${tenant}${uri}`;\n }\n\n console.log(`Rewriting request from \"${uri}\" to \"${request.uri}\"`);\n } else {\n console.log(`Failed to find a tenant for domain \"${requestedDomain}\"`);\n return {\n status: 400,\n statusDescription: \"Unable to map tenant. Check your tenant to domain mapping.\"\n };\n }\n\n // At this point, the value of the `Host` header is set to the custom domain.\n // Before forwarding the request to the S3 bucket, we need to set the `Host` header\n // to the value of the origin (S3 bucket URL).\n request.headers.host[0].value = originDomain;\n\n return request;\n}\n\nexports.handler = async event => {\n const { request, config } = event.Records[0].cf;\n\n if (config.eventType === \"origin-request\") {\n return handleOriginRequest(request);\n }\n\n return request;\n};\n"],"mappings":";;AAAA,MAAM;EAAEA;AAAe,CAAC,GAAGC,OAAO,CAAC,0BAA0B,CAAC;AAC9D,MAAM;EAAEC,gBAAgB;EAAEC,YAAY;EAAEC;AAAW,CAAC,GAAGH,OAAO,CAAC,uBAAuB,CAAC;;
|
|
1
|
+
{"version":3,"names":["DynamoDBClient","require","DynamoDBDocument","QueryCommand","GetCommand","redirects","matchRedirect","DB_TABLE_NAME","DB_TABLE_REGION","client","region","documentClient","from","marshallOptions","convertEmptyValues","removeUndefinedValues","sanitizeRequestURI","uri","parts","split","filter","Boolean","length","lastPart","includes","join","getTenantIdByDomain","domain","cmd","TableName","Key","PK","SK","Item","send","tenant","undefined","hasMultipleTenants","IndexName","Limit","Select","KeyConditionExpression","ExpressionAttributeValues","Count","handleOriginRequest","request","origin","isCustomOrigin","custom","requestedDomain","headers","host","value","originDomain","domainName","s3","redirect","console","log","startsWith","status","statusDescription","exports","handler","event","config","Records","cf","eventType"],"sources":["request.js"],"sourcesContent":["const { DynamoDBClient } = require(\"@aws-sdk/client-dynamodb\");\nconst { DynamoDBDocument, QueryCommand, GetCommand } = require(\"@aws-sdk/lib-dynamodb\");\nconst redirects = require(\"./redirects.json\");\nconst { matchRedirect } = require(\"./matchRedirect.js\");\n\n// Since Lambda@Edge doesn't support ENV variables, the easiest way to pass\n// config values to it is to inject them into the source code before deploy.\nconst DB_TABLE_NAME = \"{DB_TABLE_NAME}\";\nconst DB_TABLE_REGION = \"{DB_TABLE_REGION}\";\n\nconst client = new DynamoDBClient({\n region: DB_TABLE_REGION\n});\n\nconst documentClient = DynamoDBDocument.from(client, {\n marshallOptions: {\n convertEmptyValues: true,\n removeUndefinedValues: true\n }\n});\n\nfunction sanitizeRequestURI(uri) {\n // Make sure that `/` is not appended to index.html, or any path with extension.\n // We remove all slashes, filter out empty values, and reconstruct the path following\n // the fact that every page (slug) has a dedicated folder in the S3 bucket, and an `index.html`\n // file with the actual page HTML.\n const parts = uri.split(\"/\").filter(Boolean);\n\n // This means that a `/` (homepage) was requested. When the homepage is prerendered, we place its files\n // into the root of the tenant subfolder, e.g., `/root/index.html`.\n if (!parts.length) {\n return \"/index.html\";\n }\n\n const lastPart = parts[parts.length - 1];\n\n // If there's a `.` in the last part of the path, we assume it's a file extension.\n // In this case, we can reconstruct the path by joining parts with slashes.\n if (lastPart.includes(\".\")) {\n return [\"\", ...parts].join(\"/\");\n }\n\n // Otherwise, we assume it's a page slug, which needs to point to page's subfolder.\n // We construct a valid S3 bucket path to an HTML file.\n return [\"\", ...parts, \"index.html\"].join(\"/\");\n}\n\nasync function getTenantIdByDomain(domain) {\n const cmd = new GetCommand({\n TableName: DB_TABLE_NAME,\n Key: {\n PK: `DOMAIN#${domain}`,\n SK: \"A\"\n }\n });\n\n const { Item } = await documentClient.send(cmd);\n return Item ? Item.tenant : undefined;\n}\n\n/**\n * Check if \"root\" tenant has at least one child tenant.\n */\nasync function hasMultipleTenants() {\n const cmd = new QueryCommand({\n TableName: DB_TABLE_NAME,\n IndexName: \"GSI1\",\n Limit: 1,\n Select: \"COUNT\",\n KeyConditionExpression: \"GSI1_PK = :GSI1_PK and begins_with(GSI1_SK, :GSI1_SK)\",\n ExpressionAttributeValues: {\n \":GSI1_PK\": \"TENANTS\",\n \":GSI1_SK\": \"T#root#\"\n }\n });\n\n const { Count } = await documentClient.send(cmd);\n\n return Count > 0;\n}\n\nasync function handleOriginRequest(request) {\n const origin = request.origin;\n const isCustomOrigin = Boolean(origin.custom);\n const requestedDomain = request.headers.host[0].value;\n const originDomain = isCustomOrigin ? origin.custom.domainName : origin.s3.domainName;\n\n const redirect = matchRedirect(request, redirects);\n if (redirect) {\n return redirect();\n }\n\n let tenant;\n if (await hasMultipleTenants()) {\n // Find tenant by domain. This record is stored to the DB using the Tenant Manager app.\n console.log(`Multiple tenants are present; loading by domain...`);\n tenant = await getTenantIdByDomain(requestedDomain);\n } else {\n console.log(`Only one tenant is present; falling back to \"root\".`);\n // If the system only has one tenant, we don't need to map by domain at all.\n tenant = \"root\";\n }\n\n if (tenant) {\n const uri = sanitizeRequestURI(request.uri);\n\n // To be on the safe side, make sure the requested uri doesn't already include the tenant ID.\n if (uri.startsWith(`/${tenant}/`)) {\n request.uri = uri;\n } else {\n // Prepend the tenant ID, to point to the correct S3 bucket folder.\n request.uri = `/${tenant}${uri}`;\n }\n\n console.log(`Rewriting request from \"${uri}\" to \"${request.uri}\"`);\n } else {\n console.log(`Failed to find a tenant for domain \"${requestedDomain}\"`);\n return {\n status: 400,\n statusDescription: \"Unable to map tenant. Check your tenant to domain mapping.\"\n };\n }\n\n // At this point, the value of the `Host` header is set to the custom domain.\n // Before forwarding the request to the S3 bucket, we need to set the `Host` header\n // to the value of the origin (S3 bucket URL).\n request.headers.host[0].value = originDomain;\n\n return request;\n}\n\nexports.handler = async event => {\n const { request, config } = event.Records[0].cf;\n\n if (config.eventType === \"origin-request\") {\n return handleOriginRequest(request);\n }\n\n return request;\n};\n"],"mappings":";;AAAA,MAAM;EAAEA;AAAe,CAAC,GAAGC,OAAO,CAAC,0BAA0B,CAAC;AAC9D,MAAM;EAAEC,gBAAgB;EAAEC,YAAY;EAAEC;AAAW,CAAC,GAAGH,OAAO,CAAC,uBAAuB,CAAC;AACvF,MAAMI,SAAS,GAAGJ,OAAO,mBAAmB,CAAC;AAC7C,MAAM;EAAEK;AAAc,CAAC,GAAGL,OAAO,qBAAqB,CAAC;;AAEvD;AACA;AACA,MAAMM,aAAa,GAAG,iBAAiB;AACvC,MAAMC,eAAe,GAAG,mBAAmB;AAE3C,MAAMC,MAAM,GAAG,IAAIT,cAAc,CAAC;EAC9BU,MAAM,EAAEF;AACZ,CAAC,CAAC;AAEF,MAAMG,cAAc,GAAGT,gBAAgB,CAACU,IAAI,CAACH,MAAM,EAAE;EACjDI,eAAe,EAAE;IACbC,kBAAkB,EAAE,IAAI;IACxBC,qBAAqB,EAAE;EAC3B;AACJ,CAAC,CAAC;AAEF,SAASC,kBAAkBA,CAACC,GAAG,EAAE;EAC7B;EACA;EACA;EACA;EACA,MAAMC,KAAK,GAAGD,GAAG,CAACE,KAAK,CAAC,GAAG,CAAC,CAACC,MAAM,CAACC,OAAO,CAAC;;EAE5C;EACA;EACA,IAAI,CAACH,KAAK,CAACI,MAAM,EAAE;IACf,OAAO,aAAa;EACxB;EAEA,MAAMC,QAAQ,GAAGL,KAAK,CAACA,KAAK,CAACI,MAAM,GAAG,CAAC,CAAC;;EAExC;EACA;EACA,IAAIC,QAAQ,CAACC,QAAQ,CAAC,GAAG,CAAC,EAAE;IACxB,OAAO,CAAC,EAAE,EAAE,GAAGN,KAAK,CAAC,CAACO,IAAI,CAAC,GAAG,CAAC;EACnC;;EAEA;EACA;EACA,OAAO,CAAC,EAAE,EAAE,GAAGP,KAAK,EAAE,YAAY,CAAC,CAACO,IAAI,CAAC,GAAG,CAAC;AACjD;AAEA,eAAeC,mBAAmBA,CAACC,MAAM,EAAE;EACvC,MAAMC,GAAG,GAAG,IAAIxB,UAAU,CAAC;IACvByB,SAAS,EAAEtB,aAAa;IACxBuB,GAAG,EAAE;MACDC,EAAE,EAAE,UAAUJ,MAAM,EAAE;MACtBK,EAAE,EAAE;IACR;EACJ,CAAC,CAAC;EAEF,MAAM;IAAEC;EAAK,CAAC,GAAG,MAAMtB,cAAc,CAACuB,IAAI,CAACN,GAAG,CAAC;EAC/C,OAAOK,IAAI,GAAGA,IAAI,CAACE,MAAM,GAAGC,SAAS;AACzC;;AAEA;AACA;AACA;AACA,eAAeC,kBAAkBA,CAAA,EAAG;EAChC,MAAMT,GAAG,GAAG,IAAIzB,YAAY,CAAC;IACzB0B,SAAS,EAAEtB,aAAa;IACxB+B,SAAS,EAAE,MAAM;IACjBC,KAAK,EAAE,CAAC;IACRC,MAAM,EAAE,OAAO;IACfC,sBAAsB,EAAE,uDAAuD;IAC/EC,yBAAyB,EAAE;MACvB,UAAU,EAAE,SAAS;MACrB,UAAU,EAAE;IAChB;EACJ,CAAC,CAAC;EAEF,MAAM;IAAEC;EAAM,CAAC,GAAG,MAAMhC,cAAc,CAACuB,IAAI,CAACN,GAAG,CAAC;EAEhD,OAAOe,KAAK,GAAG,CAAC;AACpB;AAEA,eAAeC,mBAAmBA,CAACC,OAAO,EAAE;EACxC,MAAMC,MAAM,GAAGD,OAAO,CAACC,MAAM;EAC7B,MAAMC,cAAc,GAAG1B,OAAO,CAACyB,MAAM,CAACE,MAAM,CAAC;EAC7C,MAAMC,eAAe,GAAGJ,OAAO,CAACK,OAAO,CAACC,IAAI,CAAC,CAAC,CAAC,CAACC,KAAK;EACrD,MAAMC,YAAY,GAAGN,cAAc,GAAGD,MAAM,CAACE,MAAM,CAACM,UAAU,GAAGR,MAAM,CAACS,EAAE,CAACD,UAAU;EAErF,MAAME,QAAQ,GAAGlD,aAAa,CAACuC,OAAO,EAAExC,SAAS,CAAC;EAClD,IAAImD,QAAQ,EAAE;IACV,OAAOA,QAAQ,CAAC,CAAC;EACrB;EAEA,IAAIrB,MAAM;EACV,IAAI,MAAME,kBAAkB,CAAC,CAAC,EAAE;IAC5B;IACAoB,OAAO,CAACC,GAAG,CAAC,oDAAoD,CAAC;IACjEvB,MAAM,GAAG,MAAMT,mBAAmB,CAACuB,eAAe,CAAC;EACvD,CAAC,MAAM;IACHQ,OAAO,CAACC,GAAG,CAAC,qDAAqD,CAAC;IAClE;IACAvB,MAAM,GAAG,MAAM;EACnB;EAEA,IAAIA,MAAM,EAAE;IACR,MAAMlB,GAAG,GAAGD,kBAAkB,CAAC6B,OAAO,CAAC5B,GAAG,CAAC;;IAE3C;IACA,IAAIA,GAAG,CAAC0C,UAAU,CAAC,IAAIxB,MAAM,GAAG,CAAC,EAAE;MAC/BU,OAAO,CAAC5B,GAAG,GAAGA,GAAG;IACrB,CAAC,MAAM;MACH;MACA4B,OAAO,CAAC5B,GAAG,GAAG,IAAIkB,MAAM,GAAGlB,GAAG,EAAE;IACpC;IAEAwC,OAAO,CAACC,GAAG,CAAC,2BAA2BzC,GAAG,SAAS4B,OAAO,CAAC5B,GAAG,GAAG,CAAC;EACtE,CAAC,MAAM;IACHwC,OAAO,CAACC,GAAG,CAAC,uCAAuCT,eAAe,GAAG,CAAC;IACtE,OAAO;MACHW,MAAM,EAAE,GAAG;MACXC,iBAAiB,EAAE;IACvB,CAAC;EACL;;EAEA;EACA;EACA;EACAhB,OAAO,CAACK,OAAO,CAACC,IAAI,CAAC,CAAC,CAAC,CAACC,KAAK,GAAGC,YAAY;EAE5C,OAAOR,OAAO;AAClB;AAEAiB,OAAO,CAACC,OAAO,GAAG,MAAMC,KAAK,IAAI;EAC7B,MAAM;IAAEnB,OAAO;IAAEoB;EAAO,CAAC,GAAGD,KAAK,CAACE,OAAO,CAAC,CAAC,CAAC,CAACC,EAAE;EAE/C,IAAIF,MAAM,CAACG,SAAS,KAAK,gBAAgB,EAAE;IACvC,OAAOxB,mBAAmB,CAACC,OAAO,CAAC;EACvC;EAEA,OAAOA,OAAO;AAClB,CAAC","ignoreList":[]}
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -3,20 +3,9 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
var _exportNames = {
|
|
7
|
-
WebsiteTenantRouter: true
|
|
8
|
-
};
|
|
9
|
-
Object.defineProperty(exports, "WebsiteTenantRouter", {
|
|
10
|
-
enumerable: true,
|
|
11
|
-
get: function () {
|
|
12
|
-
return _WebsiteTenantRouter.WebsiteTenantRouter;
|
|
13
|
-
}
|
|
14
|
-
});
|
|
15
|
-
var _WebsiteTenantRouter = require("./components/tenantRouter/WebsiteTenantRouter");
|
|
16
6
|
var _apps = require("./apps");
|
|
17
7
|
Object.keys(_apps).forEach(function (key) {
|
|
18
8
|
if (key === "default" || key === "__esModule") return;
|
|
19
|
-
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
20
9
|
if (key in exports && exports[key] === _apps[key]) return;
|
|
21
10
|
Object.defineProperty(exports, key, {
|
|
22
11
|
enumerable: true,
|
|
@@ -28,7 +17,6 @@ Object.keys(_apps).forEach(function (key) {
|
|
|
28
17
|
var _utils = require("./utils");
|
|
29
18
|
Object.keys(_utils).forEach(function (key) {
|
|
30
19
|
if (key === "default" || key === "__esModule") return;
|
|
31
|
-
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
32
20
|
if (key in exports && exports[key] === _utils[key]) return;
|
|
33
21
|
Object.defineProperty(exports, key, {
|
|
34
22
|
enumerable: true,
|
|
@@ -40,7 +28,6 @@ Object.keys(_utils).forEach(function (key) {
|
|
|
40
28
|
var _constants = require("./constants");
|
|
41
29
|
Object.keys(_constants).forEach(function (key) {
|
|
42
30
|
if (key === "default" || key === "__esModule") return;
|
|
43
|
-
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
44
31
|
if (key in exports && exports[key] === _constants[key]) return;
|
|
45
32
|
Object.defineProperty(exports, key, {
|
|
46
33
|
enumerable: true,
|
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["
|
|
1
|
+
{"version":3,"names":["_apps","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_utils","_constants"],"sources":["index.ts"],"sourcesContent":["export * from \"./apps\";\nexport * from \"./utils\";\nexport * from \"./constants\";\n"],"mappings":";;;;;AAAA,IAAAA,KAAA,GAAAC,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAH,KAAA,EAAAI,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAL,KAAA,CAAAK,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAT,KAAA,CAAAK,GAAA;IAAA;EAAA;AAAA;AACA,IAAAK,MAAA,GAAAT,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAO,MAAA,EAAAN,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAK,MAAA,CAAAL,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAC,MAAA,CAAAL,GAAA;IAAA;EAAA;AAAA;AACA,IAAAM,UAAA,GAAAV,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAQ,UAAA,EAAAP,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAM,UAAA,CAAAN,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAE,UAAA,CAAAN,GAAA;IAAA;EAAA;AAAA","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webiny/pulumi-aws",
|
|
3
|
-
"version": "5.43.
|
|
3
|
+
"version": "5.43.7-beta.1",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/webiny/webiny-js.git"
|
|
@@ -16,22 +16,22 @@
|
|
|
16
16
|
"@pulumi/aws": "6.67.0",
|
|
17
17
|
"@pulumi/pulumi": "3.147.0",
|
|
18
18
|
"@pulumi/random": "4.17.0",
|
|
19
|
-
"@webiny/aws-sdk": "5.43.
|
|
20
|
-
"@webiny/cli-plugin-deploy-pulumi": "5.43.
|
|
21
|
-
"@webiny/pulumi": "5.43.
|
|
22
|
-
"@webiny/utils": "5.43.
|
|
23
|
-
"@webiny/wcp": "5.43.
|
|
19
|
+
"@webiny/aws-sdk": "5.43.7-beta.1",
|
|
20
|
+
"@webiny/cli-plugin-deploy-pulumi": "5.43.7-beta.1",
|
|
21
|
+
"@webiny/pulumi": "5.43.7-beta.1",
|
|
22
|
+
"@webiny/utils": "5.43.7-beta.1",
|
|
23
|
+
"@webiny/wcp": "5.43.7-beta.1",
|
|
24
24
|
"form-data": "4.0.4",
|
|
25
25
|
"lodash": "4.17.21",
|
|
26
26
|
"node-fetch": "2.6.7",
|
|
27
27
|
"zod": "3.23.8"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@webiny/api-page-builder": "5.43.
|
|
31
|
-
"@webiny/aws-layers": "5.43.
|
|
32
|
-
"@webiny/cli": "5.43.
|
|
33
|
-
"@webiny/feature-flags": "5.43.
|
|
34
|
-
"@webiny/project-utils": "5.43.
|
|
30
|
+
"@webiny/api-page-builder": "5.43.7-beta.1",
|
|
31
|
+
"@webiny/aws-layers": "5.43.7-beta.1",
|
|
32
|
+
"@webiny/cli": "5.43.7-beta.1",
|
|
33
|
+
"@webiny/feature-flags": "5.43.7-beta.1",
|
|
34
|
+
"@webiny/project-utils": "5.43.7-beta.1",
|
|
35
35
|
"chalk": "4.1.2",
|
|
36
36
|
"mime": "3.0.0",
|
|
37
37
|
"rimraf": "6.0.1",
|
|
@@ -54,5 +54,5 @@
|
|
|
54
54
|
]
|
|
55
55
|
}
|
|
56
56
|
},
|
|
57
|
-
"gitHead": "
|
|
57
|
+
"gitHead": "a84a4d84564b6d9b69972cea297d6edd6ea824bb"
|
|
58
58
|
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import * as pulumi from "@pulumi/pulumi";
|
|
2
|
-
import * as aws from "@pulumi/aws";
|
|
3
|
-
interface Config {
|
|
4
|
-
apiFolder?: string;
|
|
5
|
-
apiEnv?: string;
|
|
6
|
-
apiVariant: string;
|
|
7
|
-
}
|
|
8
|
-
export declare class WebsiteTenantRouter extends pulumi.ComponentResource {
|
|
9
|
-
readonly originRequest: aws.lambda.Function;
|
|
10
|
-
constructor(name: string, config?: Config, opts?: {});
|
|
11
|
-
}
|
|
12
|
-
export {};
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
|
|
4
|
-
Object.defineProperty(exports, "__esModule", {
|
|
5
|
-
value: true
|
|
6
|
-
});
|
|
7
|
-
exports.WebsiteTenantRouter = void 0;
|
|
8
|
-
var _fs = require("fs");
|
|
9
|
-
var pulumi = _interopRequireWildcard(require("@pulumi/pulumi"));
|
|
10
|
-
var aws = _interopRequireWildcard(require("@pulumi/aws"));
|
|
11
|
-
var _utils = require("@webiny/cli-plugin-deploy-pulumi/utils");
|
|
12
|
-
var _constants = require("../../constants");
|
|
13
|
-
var _variant = require("../../env/variant");
|
|
14
|
-
var _env = require("../../env/env");
|
|
15
|
-
function createFunctionArchive({
|
|
16
|
-
dynamoDbTable,
|
|
17
|
-
region
|
|
18
|
-
}) {
|
|
19
|
-
const handler = (0, _fs.readFileSync)(__dirname + "/functions/origin/request.js", "utf-8");
|
|
20
|
-
const source = handler.replace("{DB_TABLE_NAME}", dynamoDbTable).replace("{DB_TABLE_REGION}", region);
|
|
21
|
-
return new pulumi.asset.AssetArchive({
|
|
22
|
-
"index.js": new pulumi.asset.StringAsset(source)
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
class WebsiteTenantRouter extends pulumi.ComponentResource {
|
|
26
|
-
constructor(name, config, opts = {}) {
|
|
27
|
-
super("webiny:aws:WebsiteTenantRouter", name, {}, opts);
|
|
28
|
-
const {
|
|
29
|
-
region,
|
|
30
|
-
dynamoDbTable
|
|
31
|
-
} = (0, _utils.getStackOutput)({
|
|
32
|
-
folder: config?.apiFolder || "api",
|
|
33
|
-
env: config?.apiEnv || (0, _env.getEnvVariableWebinyEnv)(),
|
|
34
|
-
variant: config?.apiVariant || (0, _variant.getEnvVariableWebinyVariant)()
|
|
35
|
-
});
|
|
36
|
-
const inlinePolicies = Promise.all([aws.getCallerIdentity({})]).then(([callerIdentity]) => [{
|
|
37
|
-
name: "dynamodb-policy",
|
|
38
|
-
policy: JSON.stringify({
|
|
39
|
-
Version: "2012-10-17",
|
|
40
|
-
Statement: [{
|
|
41
|
-
Sid: "PermissionForDynamodb",
|
|
42
|
-
Effect: "Allow",
|
|
43
|
-
Action: ["dynamodb:GetItem", "dynamodb:Query"],
|
|
44
|
-
Resource: [`arn:aws:dynamodb:${region}:${callerIdentity.accountId}:table/${dynamoDbTable}`, `arn:aws:dynamodb:${region}:${callerIdentity.accountId}:table/${dynamoDbTable}/*`]
|
|
45
|
-
}]
|
|
46
|
-
})
|
|
47
|
-
}]);
|
|
48
|
-
const role = new aws.iam.Role(`${name}-role`, {
|
|
49
|
-
inlinePolicies,
|
|
50
|
-
managedPolicyArns: [aws.iam.ManagedPolicies.AWSLambdaBasicExecutionRole],
|
|
51
|
-
assumeRolePolicy: {
|
|
52
|
-
Version: "2012-10-17",
|
|
53
|
-
Statement: [{
|
|
54
|
-
Action: "sts:AssumeRole",
|
|
55
|
-
Principal: aws.iam.Principals.LambdaPrincipal,
|
|
56
|
-
Effect: "Allow"
|
|
57
|
-
}, {
|
|
58
|
-
Action: "sts:AssumeRole",
|
|
59
|
-
Principal: aws.iam.Principals.EdgeLambdaPrincipal,
|
|
60
|
-
Effect: "Allow"
|
|
61
|
-
}]
|
|
62
|
-
}
|
|
63
|
-
}, {
|
|
64
|
-
parent: this
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
// Some resources _must_ be put in us-east-1, such as Lambda at Edge.
|
|
68
|
-
const awsUsEast1 = new aws.Provider("us-east-1", {
|
|
69
|
-
region: "us-east-1"
|
|
70
|
-
});
|
|
71
|
-
this.originRequest = new aws.lambda.Function(`${name}-origin-request`, {
|
|
72
|
-
publish: true,
|
|
73
|
-
runtime: _constants.LAMBDA_RUNTIME,
|
|
74
|
-
handler: "index.handler",
|
|
75
|
-
role: role.arn,
|
|
76
|
-
timeout: 5,
|
|
77
|
-
memorySize: 128,
|
|
78
|
-
code: createFunctionArchive({
|
|
79
|
-
region,
|
|
80
|
-
dynamoDbTable
|
|
81
|
-
})
|
|
82
|
-
}, {
|
|
83
|
-
provider: awsUsEast1,
|
|
84
|
-
parent: this
|
|
85
|
-
});
|
|
86
|
-
this.registerOutputs();
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
exports.WebsiteTenantRouter = WebsiteTenantRouter;
|
|
90
|
-
|
|
91
|
-
//# sourceMappingURL=WebsiteTenantRouter.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["_fs","require","pulumi","_interopRequireWildcard","aws","_utils","_constants","_variant","_env","createFunctionArchive","dynamoDbTable","region","handler","readFileSync","__dirname","source","replace","asset","AssetArchive","StringAsset","WebsiteTenantRouter","ComponentResource","constructor","name","config","opts","getStackOutput","folder","apiFolder","env","apiEnv","getEnvVariableWebinyEnv","variant","apiVariant","getEnvVariableWebinyVariant","inlinePolicies","Promise","all","getCallerIdentity","then","callerIdentity","policy","JSON","stringify","Version","Statement","Sid","Effect","Action","Resource","accountId","role","iam","Role","managedPolicyArns","ManagedPolicies","AWSLambdaBasicExecutionRole","assumeRolePolicy","Principal","Principals","LambdaPrincipal","EdgeLambdaPrincipal","parent","awsUsEast1","Provider","originRequest","lambda","Function","publish","runtime","LAMBDA_RUNTIME","arn","timeout","memorySize","code","provider","registerOutputs","exports"],"sources":["WebsiteTenantRouter.ts"],"sourcesContent":["import { readFileSync } from \"fs\";\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport { getStackOutput } from \"@webiny/cli-plugin-deploy-pulumi/utils\";\nimport { LAMBDA_RUNTIME } from \"~/constants\";\nimport { getEnvVariableWebinyVariant } from \"~/env/variant\";\nimport { getEnvVariableWebinyEnv } from \"~/env/env\";\n\ninterface Config {\n apiFolder?: string;\n apiEnv?: string;\n apiVariant: string;\n}\n\ninterface Params {\n region: string;\n dynamoDbTable: string;\n}\n\nfunction createFunctionArchive({ dynamoDbTable, region }: Params) {\n const handler = readFileSync(__dirname + \"/functions/origin/request.js\", \"utf-8\");\n\n const source = handler\n .replace(\"{DB_TABLE_NAME}\", dynamoDbTable)\n .replace(\"{DB_TABLE_REGION}\", region);\n\n return new pulumi.asset.AssetArchive({\n \"index.js\": new pulumi.asset.StringAsset(source)\n });\n}\n\nexport class WebsiteTenantRouter extends pulumi.ComponentResource {\n public readonly originRequest: aws.lambda.Function;\n\n constructor(name: string, config?: Config, opts = {}) {\n super(\"webiny:aws:WebsiteTenantRouter\", name, {}, opts);\n\n const { region, dynamoDbTable } = getStackOutput({\n folder: config?.apiFolder || \"api\",\n env: config?.apiEnv || getEnvVariableWebinyEnv(),\n variant: config?.apiVariant || getEnvVariableWebinyVariant()\n });\n\n const inlinePolicies = Promise.all([aws.getCallerIdentity({})]).then(([callerIdentity]) => [\n {\n name: \"dynamodb-policy\",\n policy: JSON.stringify({\n Version: \"2012-10-17\",\n Statement: [\n {\n Sid: \"PermissionForDynamodb\",\n Effect: \"Allow\",\n Action: [\"dynamodb:GetItem\", \"dynamodb:Query\"],\n Resource: [\n `arn:aws:dynamodb:${region}:${callerIdentity.accountId}:table/${dynamoDbTable}`,\n `arn:aws:dynamodb:${region}:${callerIdentity.accountId}:table/${dynamoDbTable}/*`\n ]\n }\n ]\n })\n }\n ]);\n\n const role = new aws.iam.Role(\n `${name}-role`,\n {\n inlinePolicies,\n managedPolicyArns: [aws.iam.ManagedPolicies.AWSLambdaBasicExecutionRole],\n assumeRolePolicy: {\n Version: \"2012-10-17\",\n Statement: [\n {\n Action: \"sts:AssumeRole\",\n Principal: aws.iam.Principals.LambdaPrincipal,\n Effect: \"Allow\"\n },\n {\n Action: \"sts:AssumeRole\",\n Principal: aws.iam.Principals.EdgeLambdaPrincipal,\n Effect: \"Allow\"\n }\n ]\n }\n },\n { parent: this }\n );\n\n // Some resources _must_ be put in us-east-1, such as Lambda at Edge.\n const awsUsEast1 = new aws.Provider(\"us-east-1\", { region: \"us-east-1\" });\n\n this.originRequest = new aws.lambda.Function(\n `${name}-origin-request`,\n {\n publish: true,\n runtime: LAMBDA_RUNTIME,\n handler: \"index.handler\",\n role: role.arn,\n timeout: 5,\n memorySize: 128,\n code: createFunctionArchive({ region, dynamoDbTable })\n },\n { provider: awsUsEast1, parent: this }\n );\n\n this.registerOutputs();\n }\n}\n"],"mappings":"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","ignoreList":[]}
|