@infoxchange/make-it-so-sst-v2 1.0.0-internal-testing-disambiguate-release-id-bc6e5bb.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/.editorconfig +16 -0
- package/LICENSE +21 -0
- package/README.md +377 -0
- package/commitlint.config.ts +14 -0
- package/dist/cdk-constructs/IxApi.d.ts +12 -0
- package/dist/cdk-constructs/IxApi.d.ts.map +1 -0
- package/dist/cdk-constructs/IxApi.js +56 -0
- package/dist/cdk-constructs/IxBucket.d.ts +9 -0
- package/dist/cdk-constructs/IxBucket.d.ts.map +1 -0
- package/dist/cdk-constructs/IxBucket.js +22 -0
- package/dist/cdk-constructs/IxCertificate.d.ts +16 -0
- package/dist/cdk-constructs/IxCertificate.d.ts.map +1 -0
- package/dist/cdk-constructs/IxCertificate.js +26 -0
- package/dist/cdk-constructs/IxDnsRecord.d.ts +23 -0
- package/dist/cdk-constructs/IxDnsRecord.d.ts.map +1 -0
- package/dist/cdk-constructs/IxDnsRecord.js +43 -0
- package/dist/cdk-constructs/IxElasticache.d.ts +17 -0
- package/dist/cdk-constructs/IxElasticache.d.ts.map +1 -0
- package/dist/cdk-constructs/IxElasticache.js +70 -0
- package/dist/cdk-constructs/IxNextjsSite.d.ts +16 -0
- package/dist/cdk-constructs/IxNextjsSite.d.ts.map +1 -0
- package/dist/cdk-constructs/IxNextjsSite.js +38 -0
- package/dist/cdk-constructs/IxQuicksightWorkspace.d.ts +17 -0
- package/dist/cdk-constructs/IxQuicksightWorkspace.d.ts.map +1 -0
- package/dist/cdk-constructs/IxQuicksightWorkspace.js +29 -0
- package/dist/cdk-constructs/IxSESIdentity.d.ts +12 -0
- package/dist/cdk-constructs/IxSESIdentity.d.ts.map +1 -0
- package/dist/cdk-constructs/IxSESIdentity.js +45 -0
- package/dist/cdk-constructs/IxStaticSite.d.ts +17 -0
- package/dist/cdk-constructs/IxStaticSite.d.ts.map +1 -0
- package/dist/cdk-constructs/IxStaticSite.js +38 -0
- package/dist/cdk-constructs/IxVpcDetails.d.ts +12 -0
- package/dist/cdk-constructs/IxVpcDetails.d.ts.map +1 -0
- package/dist/cdk-constructs/IxVpcDetails.js +26 -0
- package/dist/cdk-constructs/IxWebsiteRedirect.d.ts +35 -0
- package/dist/cdk-constructs/IxWebsiteRedirect.d.ts.map +1 -0
- package/dist/cdk-constructs/IxWebsiteRedirect.js +72 -0
- package/dist/cdk-constructs/SiteOidcAuth/auth-check-handler-body.d.ts +2 -0
- package/dist/cdk-constructs/SiteOidcAuth/auth-check-handler-body.d.ts.map +1 -0
- package/dist/cdk-constructs/SiteOidcAuth/auth-check-handler-body.js +130 -0
- package/dist/cdk-constructs/SiteOidcAuth/auth-route.d.ts +2 -0
- package/dist/cdk-constructs/SiteOidcAuth/auth-route.d.ts.map +1 -0
- package/dist/cdk-constructs/SiteOidcAuth/auth-route.js +59 -0
- package/dist/cdk-constructs/SiteOidcAuth/index.d.ts +197 -0
- package/dist/cdk-constructs/SiteOidcAuth/index.d.ts.map +1 -0
- package/dist/cdk-constructs/SiteOidcAuth/index.js +188 -0
- package/dist/cdk-constructs/index.d.ts +11 -0
- package/dist/cdk-constructs/index.d.ts.map +1 -0
- package/dist/cdk-constructs/index.js +10 -0
- package/dist/deployConfig.d.ts +72 -0
- package/dist/deployConfig.d.ts.map +1 -0
- package/dist/deployConfig.js +78 -0
- package/dist/lib/auth/index.d.ts +2 -0
- package/dist/lib/auth/index.d.ts.map +1 -0
- package/dist/lib/auth/index.js +1 -0
- package/dist/lib/auth/oidc.d.ts +26 -0
- package/dist/lib/auth/oidc.d.ts.map +1 -0
- package/dist/lib/auth/oidc.js +48 -0
- package/dist/lib/proxy/fetch.d.ts +4 -0
- package/dist/lib/proxy/fetch.d.ts.map +1 -0
- package/dist/lib/proxy/fetch.js +31 -0
- package/dist/lib/proxy/index.d.ts +2 -0
- package/dist/lib/proxy/index.d.ts.map +1 -0
- package/dist/lib/proxy/index.js +1 -0
- package/dist/lib/site/support.d.ts +71 -0
- package/dist/lib/site/support.d.ts.map +1 -0
- package/dist/lib/site/support.js +262 -0
- package/dist/lib/utils/hash.d.ts +2 -0
- package/dist/lib/utils/hash.d.ts.map +1 -0
- package/dist/lib/utils/hash.js +13 -0
- package/dist/lib/utils/objects.d.ts +4 -0
- package/dist/lib/utils/objects.d.ts.map +1 -0
- package/dist/lib/utils/objects.js +7 -0
- package/eslint.config.js +11 -0
- package/package.json +66 -0
- package/src/cdk-constructs/IxApi.ts +81 -0
- package/src/cdk-constructs/IxBucket.ts +35 -0
- package/src/cdk-constructs/IxCertificate.ts +54 -0
- package/src/cdk-constructs/IxDnsRecord.ts +79 -0
- package/src/cdk-constructs/IxElasticache.ts +106 -0
- package/src/cdk-constructs/IxNextjsSite.ts +72 -0
- package/src/cdk-constructs/IxQuicksightWorkspace.ts +54 -0
- package/src/cdk-constructs/IxSESIdentity.ts +70 -0
- package/src/cdk-constructs/IxStaticSite.ts +69 -0
- package/src/cdk-constructs/IxVpcDetails.ts +38 -0
- package/src/cdk-constructs/IxWebsiteRedirect.ts +133 -0
- package/src/cdk-constructs/SiteOidcAuth/auth-check-handler-body.ts +168 -0
- package/src/cdk-constructs/SiteOidcAuth/auth-route.ts +71 -0
- package/src/cdk-constructs/SiteOidcAuth/index.ts +299 -0
- package/src/cdk-constructs/index.ts +10 -0
- package/src/deployConfig.ts +87 -0
- package/src/lib/auth/index.ts +1 -0
- package/src/lib/auth/oidc.ts +73 -0
- package/src/lib/proxy/fetch.ts +41 -0
- package/src/lib/proxy/index.ts +1 -0
- package/src/lib/site/support.ts +439 -0
- package/src/lib/utils/hash.ts +14 -0
- package/src/lib/utils/objects.ts +19 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
isIxDeploy: true;
|
|
3
|
+
appName: string;
|
|
4
|
+
environment: "dev" | "test" | "uat" | "prod";
|
|
5
|
+
workloadGroup: "ds" | "srs";
|
|
6
|
+
primaryAwsRegion: "ap-southeast-2";
|
|
7
|
+
siteDomains: string[];
|
|
8
|
+
siteDomainAliases: string[];
|
|
9
|
+
isInternalApp: boolean;
|
|
10
|
+
deploymentType: "docker" | "serverless";
|
|
11
|
+
sourceCommitRef: string;
|
|
12
|
+
sourceCommitHash: string;
|
|
13
|
+
deployTriggeredBy: string;
|
|
14
|
+
smtpHost: string;
|
|
15
|
+
smtpPort: number;
|
|
16
|
+
clamAVUrl: string;
|
|
17
|
+
vpcHttpProxy: string;
|
|
18
|
+
} | {
|
|
19
|
+
isIxDeploy: false;
|
|
20
|
+
appName: string;
|
|
21
|
+
environment: string;
|
|
22
|
+
workloadGroup: string;
|
|
23
|
+
primaryAwsRegion: string;
|
|
24
|
+
siteDomains: string[];
|
|
25
|
+
siteDomainAliases: string[];
|
|
26
|
+
deploymentType: string;
|
|
27
|
+
sourceCommitRef: string;
|
|
28
|
+
sourceCommitHash: string;
|
|
29
|
+
deployTriggeredBy: string;
|
|
30
|
+
smtpHost: string;
|
|
31
|
+
clamAVUrl: string;
|
|
32
|
+
vpcHttpProxy: string;
|
|
33
|
+
isInternalApp?: boolean | undefined;
|
|
34
|
+
smtpPort?: number | undefined;
|
|
35
|
+
};
|
|
36
|
+
export default _default;
|
|
37
|
+
export declare const getDeployConfig: () => {
|
|
38
|
+
isIxDeploy: true;
|
|
39
|
+
appName: string;
|
|
40
|
+
environment: "dev" | "test" | "uat" | "prod";
|
|
41
|
+
workloadGroup: "ds" | "srs";
|
|
42
|
+
primaryAwsRegion: "ap-southeast-2";
|
|
43
|
+
siteDomains: string[];
|
|
44
|
+
siteDomainAliases: string[];
|
|
45
|
+
isInternalApp: boolean;
|
|
46
|
+
deploymentType: "docker" | "serverless";
|
|
47
|
+
sourceCommitRef: string;
|
|
48
|
+
sourceCommitHash: string;
|
|
49
|
+
deployTriggeredBy: string;
|
|
50
|
+
smtpHost: string;
|
|
51
|
+
smtpPort: number;
|
|
52
|
+
clamAVUrl: string;
|
|
53
|
+
vpcHttpProxy: string;
|
|
54
|
+
} | {
|
|
55
|
+
isIxDeploy: false;
|
|
56
|
+
appName: string;
|
|
57
|
+
environment: string;
|
|
58
|
+
workloadGroup: string;
|
|
59
|
+
primaryAwsRegion: string;
|
|
60
|
+
siteDomains: string[];
|
|
61
|
+
siteDomainAliases: string[];
|
|
62
|
+
deploymentType: string;
|
|
63
|
+
sourceCommitRef: string;
|
|
64
|
+
sourceCommitHash: string;
|
|
65
|
+
deployTriggeredBy: string;
|
|
66
|
+
smtpHost: string;
|
|
67
|
+
clamAVUrl: string;
|
|
68
|
+
vpcHttpProxy: string;
|
|
69
|
+
isInternalApp?: boolean | undefined;
|
|
70
|
+
smtpPort?: number | undefined;
|
|
71
|
+
};
|
|
72
|
+
//# sourceMappingURL=deployConfig.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deployConfig.d.ts","sourceRoot":"","sources":["../src/deployConfig.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmFA,wBAA0C;AAG1C,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAmC,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const getEnvVars = () => ({
|
|
3
|
+
isIxDeploy: process.env.IX_DEPLOYMENT?.toLowerCase() === "true", // This needs to start as a bool for the discriminated union
|
|
4
|
+
appName: process.env.IX_APP_NAME ?? "",
|
|
5
|
+
environment: process.env.IX_ENVIRONMENT ?? "",
|
|
6
|
+
workloadGroup: process.env.IX_WORKLOAD_GROUP ?? "",
|
|
7
|
+
primaryAwsRegion: process.env.IX_PRIMARY_AWS_REGION ?? "",
|
|
8
|
+
siteDomains: process.env.IX_SITE_DOMAINS ?? "",
|
|
9
|
+
siteDomainAliases: process.env.IX_SITE_DOMAIN_ALIASES ?? "",
|
|
10
|
+
isInternalApp: process.env.IX_INTERNAL_APP ?? "",
|
|
11
|
+
deploymentType: process.env.IX_DEPLOYMENT_TYPE ?? "",
|
|
12
|
+
sourceCommitRef: process.env.IX_SOURCE_COMMIT_REF ?? "",
|
|
13
|
+
sourceCommitHash: process.env.IX_SOURCE_COMMIT_HASH ?? "",
|
|
14
|
+
deployTriggeredBy: process.env.IX_DEPLOY_TRIGGERED_BY ?? "",
|
|
15
|
+
smtpHost: process.env.SMTP_HOST ?? "",
|
|
16
|
+
smtpPort: process.env.SMTP_PORT ?? "",
|
|
17
|
+
clamAVUrl: process.env.CLAMAV_URL ?? "",
|
|
18
|
+
vpcHttpProxy: process.env.VPC_HTTP_PROXY ?? "",
|
|
19
|
+
});
|
|
20
|
+
const ixDeployConfigSchema = z
|
|
21
|
+
.object({
|
|
22
|
+
isIxDeploy: z.literal(true),
|
|
23
|
+
appName: z.string().min(1),
|
|
24
|
+
environment: z.enum(["dev", "test", "uat", "prod"]),
|
|
25
|
+
workloadGroup: z.enum(["ds", "srs"]),
|
|
26
|
+
primaryAwsRegion: z.literal("ap-southeast-2"),
|
|
27
|
+
siteDomains: z
|
|
28
|
+
.string()
|
|
29
|
+
.transform((val) => val.split(",").map((domain) => domain.trim())),
|
|
30
|
+
siteDomainAliases: z
|
|
31
|
+
.string()
|
|
32
|
+
.transform((val) => val.split(",").map((domain) => domain.trim())),
|
|
33
|
+
isInternalApp: z.coerce.boolean(),
|
|
34
|
+
deploymentType: z.enum(["docker", "serverless"]),
|
|
35
|
+
sourceCommitRef: z.string().min(1),
|
|
36
|
+
sourceCommitHash: z.string().min(1),
|
|
37
|
+
deployTriggeredBy: z.string().min(1),
|
|
38
|
+
smtpHost: z.string().min(1),
|
|
39
|
+
smtpPort: z.coerce.number().int(),
|
|
40
|
+
clamAVUrl: z.string().url(),
|
|
41
|
+
vpcHttpProxy: z.string().url(),
|
|
42
|
+
})
|
|
43
|
+
.strip();
|
|
44
|
+
const nonIxDeployConfigSchema = z
|
|
45
|
+
.object({
|
|
46
|
+
isIxDeploy: z.literal(false),
|
|
47
|
+
appName: z.string(),
|
|
48
|
+
environment: z.string(),
|
|
49
|
+
workloadGroup: z.string(),
|
|
50
|
+
primaryAwsRegion: z.string(),
|
|
51
|
+
siteDomains: z
|
|
52
|
+
.string()
|
|
53
|
+
.transform((val) => val.split(",").map((domain) => domain.trim())),
|
|
54
|
+
siteDomainAliases: z
|
|
55
|
+
.string()
|
|
56
|
+
.transform((val) => val.split(",").map((domain) => domain.trim())),
|
|
57
|
+
isInternalApp: z
|
|
58
|
+
.string()
|
|
59
|
+
.transform((val) => (val ? val.toLowerCase() === "true" : undefined)),
|
|
60
|
+
deploymentType: z.string(),
|
|
61
|
+
sourceCommitRef: z.string(),
|
|
62
|
+
sourceCommitHash: z.string(),
|
|
63
|
+
deployTriggeredBy: z.string(),
|
|
64
|
+
smtpHost: z.string(),
|
|
65
|
+
smtpPort: z
|
|
66
|
+
.string()
|
|
67
|
+
.transform((val) => isNaN(parseInt(val, 10)) ? undefined : parseInt(val, 10)),
|
|
68
|
+
clamAVUrl: z.string(),
|
|
69
|
+
vpcHttpProxy: z.string(),
|
|
70
|
+
})
|
|
71
|
+
.strip();
|
|
72
|
+
const schema = z.discriminatedUnion("isIxDeploy", [
|
|
73
|
+
ixDeployConfigSchema,
|
|
74
|
+
nonIxDeployConfigSchema,
|
|
75
|
+
]);
|
|
76
|
+
export default schema.parse(getEnvVars());
|
|
77
|
+
// process.env values can change at runtime so we provide a way to re-parse the config as needed
|
|
78
|
+
export const getDeployConfig = () => schema.parse(getEnvVars());
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./oidc.js";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { JWTPayload } from "jose";
|
|
2
|
+
type VerifyAccessTokenParams<SafeVerify extends boolean = false> = {
|
|
3
|
+
token: string;
|
|
4
|
+
issuerUrl: string;
|
|
5
|
+
audience: string;
|
|
6
|
+
safeVerify?: SafeVerify;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Checks an OIDC access token against the issuer's details to determine if it's valid.
|
|
10
|
+
*
|
|
11
|
+
* @param params - The parameters for verifying the access token.
|
|
12
|
+
* @param params.token - The JWT access token to verify.
|
|
13
|
+
* @param params.issuerUrl - The OIDC issuer URL to discover JWKS and metadata.
|
|
14
|
+
* @param params.audience - The expected audience value to match against the token's claims.
|
|
15
|
+
* @param params.safeVerify - If true, returns a result object with error and payload fields instead of throwing on error.
|
|
16
|
+
* @returns If `safeVerify` is true, returns an object with either the verified payload or an error. Otherwise, returns the verified JWT payload or throws an error.
|
|
17
|
+
*/
|
|
18
|
+
export declare function verifyAccessToken<SafeVerify extends boolean = false>({ token, issuerUrl, audience, safeVerify, }: VerifyAccessTokenParams<SafeVerify>): Promise<SafeVerify extends true ? {
|
|
19
|
+
error: Error | unknown;
|
|
20
|
+
payload: null;
|
|
21
|
+
} | {
|
|
22
|
+
error: null;
|
|
23
|
+
payload: JWTPayload;
|
|
24
|
+
} : JWTPayload>;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=oidc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oidc.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/oidc.ts"],"names":[],"mappings":"AACA,OAAO,EAAsB,UAAU,EAAa,MAAM,MAAM,CAAC;AAEjE,KAAK,uBAAuB,CAAC,UAAU,SAAS,OAAO,GAAG,KAAK,IAAI;IACjE,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,SAAS,OAAO,GAAG,KAAK,EAAE,EAC1E,KAAK,EACL,SAAS,EACT,QAAQ,EACR,UAAU,GACX,EAAE,uBAAuB,CAAC,UAAU,CAAC,GAAG,OAAO,CAC9C,UAAU,SAAS,IAAI,GAEf;IAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC;IAAC,OAAO,EAAE,IAAI,CAAA;CAAE,GACzC;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,UAAU,CAAA;CAAE,GACxC,UAAU,CACf,CAyCA"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Issuer } from "openid-client";
|
|
2
|
+
import { createRemoteJWKSet, jwtVerify } from "jose";
|
|
3
|
+
/**
|
|
4
|
+
* Checks an OIDC access token against the issuer's details to determine if it's valid.
|
|
5
|
+
*
|
|
6
|
+
* @param params - The parameters for verifying the access token.
|
|
7
|
+
* @param params.token - The JWT access token to verify.
|
|
8
|
+
* @param params.issuerUrl - The OIDC issuer URL to discover JWKS and metadata.
|
|
9
|
+
* @param params.audience - The expected audience value to match against the token's claims.
|
|
10
|
+
* @param params.safeVerify - If true, returns a result object with error and payload fields instead of throwing on error.
|
|
11
|
+
* @returns If `safeVerify` is true, returns an object with either the verified payload or an error. Otherwise, returns the verified JWT payload or throws an error.
|
|
12
|
+
*/
|
|
13
|
+
export async function verifyAccessToken({ token, issuerUrl, audience, safeVerify, }) {
|
|
14
|
+
try {
|
|
15
|
+
const issuer = await Issuer.discover(issuerUrl);
|
|
16
|
+
const jwksUri = issuer.metadata.jwks_uri;
|
|
17
|
+
if (!jwksUri) {
|
|
18
|
+
throw new Error("JWKS URI not found in issuer metadata");
|
|
19
|
+
}
|
|
20
|
+
const JWKS = createRemoteJWKSet(new URL(jwksUri));
|
|
21
|
+
// Verify the signature and basic claims
|
|
22
|
+
const { payload } = await jwtVerify(token, JWKS, {
|
|
23
|
+
issuer: issuer.metadata.issuer,
|
|
24
|
+
});
|
|
25
|
+
const tokenAud = payload.aud ?? payload.client_id;
|
|
26
|
+
let audienceMatches = false;
|
|
27
|
+
for (const aud of Array.isArray(tokenAud) ? tokenAud : [tokenAud]) {
|
|
28
|
+
if (aud === audience) {
|
|
29
|
+
audienceMatches = true;
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (!audienceMatches) {
|
|
34
|
+
console.info("Token data:", payload);
|
|
35
|
+
throw new Error(`Token audience does not match expected audience ${audience}`);
|
|
36
|
+
}
|
|
37
|
+
if (safeVerify) {
|
|
38
|
+
return { payload, error: null };
|
|
39
|
+
}
|
|
40
|
+
return payload;
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
if (safeVerify) {
|
|
44
|
+
return { error: err, payload: null };
|
|
45
|
+
}
|
|
46
|
+
throw err;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../../src/lib/proxy/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,IAAI,WAAW,EACrB,MAAM,QAAQ,CAAC;AAGhB,wBAAgB,kBAAkB,SAmBjC;AAED,wBAAgB,eAAe,uBAW9B"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { setGlobalDispatcher, getGlobalDispatcher, EnvHttpProxyAgent, fetch as undiciFetch, } from "undici";
|
|
2
|
+
import { bootstrap } from "global-agent";
|
|
3
|
+
export function setupProxyGlobally() {
|
|
4
|
+
// Make operation idempotent
|
|
5
|
+
if (getGlobalDispatcher() instanceof EnvHttpProxyAgent)
|
|
6
|
+
return;
|
|
7
|
+
if (!process.env.HTTP_PROXY || !process.env.HTTPS_PROXY)
|
|
8
|
+
return;
|
|
9
|
+
// To cover libraries that use fetch
|
|
10
|
+
// See https://nodejs.org/api/globals.html#custom-dispatcher
|
|
11
|
+
// This might stop being needed at some point: https://github.com/actions/create-github-app-token/pull/143#discussion_r1747641337
|
|
12
|
+
const envHttpProxyAgent = new EnvHttpProxyAgent();
|
|
13
|
+
setGlobalDispatcher(envHttpProxyAgent);
|
|
14
|
+
// To cover libraries that use the http/https object
|
|
15
|
+
if (!process.env.GLOBAL_AGENT_HTTP_PROXY) {
|
|
16
|
+
process.env.GLOBAL_AGENT_HTTP_PROXY = process.env.HTTP_PROXY;
|
|
17
|
+
process.env.GLOBAL_AGENT_HTTPS_PROXY =
|
|
18
|
+
process.env.HTTPS_PROXY ?? process.env.HTTP_PROXY;
|
|
19
|
+
}
|
|
20
|
+
bootstrap();
|
|
21
|
+
}
|
|
22
|
+
export function getProxiedFetch() {
|
|
23
|
+
const fetch = (input, init = {}) => {
|
|
24
|
+
if (init.dispatcher) {
|
|
25
|
+
console.warn("A custom dispatcher was provided to fetch but this is ignored as a proxy agent is being used.");
|
|
26
|
+
}
|
|
27
|
+
const envHttpProxyAgent = new EnvHttpProxyAgent();
|
|
28
|
+
return undiciFetch(input, { ...init, dispatcher: envHttpProxyAgent });
|
|
29
|
+
};
|
|
30
|
+
return fetch;
|
|
31
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/proxy/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./fetch.js";
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Construct } from "constructs";
|
|
2
|
+
import { NextjsSite, NextjsSiteProps, Stack, StaticSite, StaticSiteProps } from "sst/constructs";
|
|
3
|
+
import { type DistributionDomainProps } from "sst/constructs/Distribution.js";
|
|
4
|
+
import { type AddToSiteProps as SiteOidcAuthAddToSiteProps } from "../../cdk-constructs/SiteOidcAuth/index.js";
|
|
5
|
+
type SharedExtendedSiteProps = {
|
|
6
|
+
customDomain?: string | ExtendedCustomDomains;
|
|
7
|
+
auth?: {
|
|
8
|
+
oidc: {
|
|
9
|
+
issuerUrl: string;
|
|
10
|
+
clientId: string;
|
|
11
|
+
scope: string;
|
|
12
|
+
};
|
|
13
|
+
} & SiteOidcAuthAddToSiteProps;
|
|
14
|
+
};
|
|
15
|
+
export type ExtendedCustomDomains = DistributionDomainProps & {
|
|
16
|
+
isIxManagedDomain?: boolean;
|
|
17
|
+
additionalDomainAliases?: string[];
|
|
18
|
+
};
|
|
19
|
+
export type ExtendedNextjsSiteProps = Omit<NextjsSiteProps, "customDomain" | "environment"> & SharedExtendedSiteProps & {
|
|
20
|
+
/**
|
|
21
|
+
* An object with the key being the environment variable name. The value can either be the environment variable value
|
|
22
|
+
* as a string or as an object with `buildtime` and/or `runtime` properties where the values of `buildtime` and
|
|
23
|
+
* `runtime` is the environment variable value that will be used during that step.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```js
|
|
27
|
+
* environment: {
|
|
28
|
+
* USER_POOL_CLIENT: auth.cognitoUserPoolClient.userPoolClientId,
|
|
29
|
+
* NODE_OPTIONS: {
|
|
30
|
+
* buildtime: "--max-old-space-size=4096",
|
|
31
|
+
* },
|
|
32
|
+
* API_URL: {
|
|
33
|
+
* buildtime: "https://external.domain",
|
|
34
|
+
* runtime: "https://internal.domain",
|
|
35
|
+
* },
|
|
36
|
+
* },
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
environment?: Record<string, string | {
|
|
40
|
+
buildtime?: string;
|
|
41
|
+
runtime?: string;
|
|
42
|
+
}>;
|
|
43
|
+
};
|
|
44
|
+
export type ExtendedStaticSiteProps = Omit<StaticSiteProps, "customDomain"> & SharedExtendedSiteProps;
|
|
45
|
+
export declare function setupCustomDomain<Props extends ExtendedStaticSiteProps | ExtendedNextjsSiteProps>(scope: Construct, id: string, props: Readonly<Props>): Props;
|
|
46
|
+
export declare function setupCertificate<Props extends ExtendedStaticSiteProps | ExtendedNextjsSiteProps>(scope: Construct, id: string, props: Readonly<Props>): Props;
|
|
47
|
+
export declare function setupDomainAliasRedirect<Props extends ExtendedStaticSiteProps | ExtendedNextjsSiteProps>(scope: Construct, id: string, props: Readonly<Props>): Props;
|
|
48
|
+
export declare function setupVpcDetails<Props extends ExtendedNextjsSiteProps>(scope: Construct, id: string, props: Readonly<Props>): Props;
|
|
49
|
+
/**
|
|
50
|
+
* Ensures environment variables that are conditionally included for buildtime or runtime are only used during the
|
|
51
|
+
* appropriate phase.
|
|
52
|
+
*/
|
|
53
|
+
export declare function applyConditionalEnvironmentVariables<Props extends ExtendedNextjsSiteProps>(scope: Construct, id: string, props: Readonly<Props>): Props;
|
|
54
|
+
/**
|
|
55
|
+
* Before props reach this function they should have already been converted into something compatible with the parent
|
|
56
|
+
* SST construct. This function verifies that's the case and updates the type if so.
|
|
57
|
+
*/
|
|
58
|
+
export declare function parentCompatibleSsrProps<Props extends ExtendedNextjsSiteProps, ResultProps = Omit<Props, "environment"> & {
|
|
59
|
+
environment?: Record<string, string>;
|
|
60
|
+
}>(props: Readonly<Props>): ResultProps;
|
|
61
|
+
export declare function setupDefaultEnvVars<Props extends ExtendedNextjsSiteProps>(scope: Construct | Stack, id: string, props: Readonly<Props>): Props;
|
|
62
|
+
export declare function setupDnsRecords<Instance extends NextjsSite | StaticSite, Props extends ExtendedStaticSiteProps | ExtendedNextjsSiteProps>(instance: Instance, scope: Construct, id: string, props: Readonly<Props>): void;
|
|
63
|
+
export declare function getCustomDomains<Props extends ExtendedStaticSiteProps | ExtendedNextjsSiteProps>(props: Readonly<Props>): string[];
|
|
64
|
+
export declare function getPrimaryDomain<Instance extends NextjsSite | StaticSite, Props extends ExtendedStaticSiteProps | ExtendedNextjsSiteProps>(instance: Instance, props: Readonly<Props>): string | null;
|
|
65
|
+
export declare function getPrimaryOrigin<Instance extends NextjsSite | StaticSite, Props extends ExtendedStaticSiteProps | ExtendedNextjsSiteProps>(instance: Instance, props: Readonly<Props>): string | null;
|
|
66
|
+
export declare function getPrimaryCustomDomain<Props extends ExtendedStaticSiteProps | ExtendedNextjsSiteProps>(props: Readonly<Props>): string | null;
|
|
67
|
+
export declare function getAliasDomain<Props extends ExtendedStaticSiteProps | ExtendedNextjsSiteProps>(props: Readonly<Props>): string | null;
|
|
68
|
+
export declare function getAlternativeDomains<Props extends ExtendedStaticSiteProps | ExtendedNextjsSiteProps>(props: Readonly<Props>): string[];
|
|
69
|
+
export declare function processAuthProps<SiteType extends "StaticSite" | "SsrSite", Props extends SiteType extends "StaticSite" ? ExtendedStaticSiteProps : ExtendedNextjsSiteProps>(scope: Construct, id: string, siteType: SiteType, props: Readonly<Props>): Props;
|
|
70
|
+
export {};
|
|
71
|
+
//# sourceMappingURL=support.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"support.d.ts","sourceRoot":"","sources":["../../../src/lib/site/support.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import ixDeployConfig from "../../deployConfig.js";
|
|
2
|
+
import { IxCertificate } from "../../cdk-constructs/IxCertificate.js";
|
|
3
|
+
import { IxWebsiteRedirect } from "../../cdk-constructs/IxWebsiteRedirect.js";
|
|
4
|
+
import { IxVpcDetails } from "../../cdk-constructs/IxVpcDetails.js";
|
|
5
|
+
import { IxDnsRecord } from "../../cdk-constructs/IxDnsRecord.js";
|
|
6
|
+
import { CloudFrontTarget } from "aws-cdk-lib/aws-route53-targets";
|
|
7
|
+
import { convertToBase62Hash } from "../utils/hash.js";
|
|
8
|
+
import { SiteOidcAuth, } from "../../cdk-constructs/SiteOidcAuth/index.js";
|
|
9
|
+
export function setupCustomDomain(scope, id, props) {
|
|
10
|
+
let updatedProps = props;
|
|
11
|
+
// Default to using domains names passed in by the pipeline as the custom domain
|
|
12
|
+
if (ixDeployConfig.isIxDeploy && !("customDomain" in updatedProps)) {
|
|
13
|
+
updatedProps = {
|
|
14
|
+
...updatedProps,
|
|
15
|
+
customDomain: {
|
|
16
|
+
isIxManagedDomain: true,
|
|
17
|
+
isExternalDomain: true,
|
|
18
|
+
domainName: ixDeployConfig.siteDomains[0],
|
|
19
|
+
alternateNames: ixDeployConfig.siteDomains.slice(1),
|
|
20
|
+
domainAlias: ixDeployConfig.siteDomainAliases[0],
|
|
21
|
+
additionalDomainAliases: ixDeployConfig.siteDomainAliases.slice(1),
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
return updatedProps;
|
|
26
|
+
}
|
|
27
|
+
export function setupCertificate(scope, id, props) {
|
|
28
|
+
const updatedProps = { ...props };
|
|
29
|
+
if (!updatedProps?.customDomain)
|
|
30
|
+
return updatedProps;
|
|
31
|
+
if (typeof updatedProps.customDomain === "string") {
|
|
32
|
+
updatedProps.customDomain = { domainName: updatedProps.customDomain };
|
|
33
|
+
}
|
|
34
|
+
// No cert creation required if isIxManagedDomain is false or a cert is already provided
|
|
35
|
+
if (!updatedProps.customDomain.isIxManagedDomain &&
|
|
36
|
+
updatedProps.customDomain.cdk?.certificate) {
|
|
37
|
+
return updatedProps;
|
|
38
|
+
}
|
|
39
|
+
const domainCert = new IxCertificate(scope, id + "-IxCertificate", {
|
|
40
|
+
domainName: updatedProps.customDomain.domainName,
|
|
41
|
+
subjectAlternativeNames: updatedProps.customDomain.alternateNames,
|
|
42
|
+
region: "us-east-1", // CloudFront will only use certificates in us-east-1
|
|
43
|
+
});
|
|
44
|
+
updatedProps.customDomain.cdk = updatedProps.customDomain.cdk ?? {};
|
|
45
|
+
updatedProps.customDomain.cdk.certificate = domainCert.acmCertificate;
|
|
46
|
+
return updatedProps;
|
|
47
|
+
}
|
|
48
|
+
export function setupDomainAliasRedirect(scope, id, props) {
|
|
49
|
+
if (typeof props.customDomain !== "object" ||
|
|
50
|
+
!(props.customDomain.domainAlias ||
|
|
51
|
+
props.customDomain.additionalDomainAliases?.length) ||
|
|
52
|
+
!props.customDomain.isIxManagedDomain ||
|
|
53
|
+
!props.customDomain.cdk?.certificate) {
|
|
54
|
+
return props;
|
|
55
|
+
}
|
|
56
|
+
const domainsToRedirectFrom = [
|
|
57
|
+
...(props.customDomain.domainAlias ? [props.customDomain.domainAlias] : []),
|
|
58
|
+
...(props.customDomain.additionalDomainAliases ?? []),
|
|
59
|
+
];
|
|
60
|
+
new IxWebsiteRedirect(scope, id + "-IxWebsiteRedirect", {
|
|
61
|
+
recordNames: domainsToRedirectFrom,
|
|
62
|
+
targetDomain: props.customDomain.domainName,
|
|
63
|
+
});
|
|
64
|
+
return {
|
|
65
|
+
...props,
|
|
66
|
+
customDomain: {
|
|
67
|
+
...props.customDomain,
|
|
68
|
+
domainAlias: undefined, // SST's site constructs will complain if domainAlias is set while isExternalDomain is true
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
export function setupVpcDetails(scope, id, props) {
|
|
73
|
+
const updatedProps = { ...props };
|
|
74
|
+
// Don't make any changes if the user has set the VPC manually in any place
|
|
75
|
+
if ("vpc" in (updatedProps.cdk?.server || {}) ||
|
|
76
|
+
"vpc" in (updatedProps.cdk?.revalidation || {})) {
|
|
77
|
+
return updatedProps;
|
|
78
|
+
}
|
|
79
|
+
const vpcDetails = new IxVpcDetails(scope, id + "-IxVpcDetails");
|
|
80
|
+
updatedProps.cdk = updatedProps.cdk ?? {};
|
|
81
|
+
updatedProps.cdk.server = {
|
|
82
|
+
...updatedProps.cdk.server,
|
|
83
|
+
vpc: vpcDetails.vpc,
|
|
84
|
+
};
|
|
85
|
+
updatedProps.cdk.revalidation = {
|
|
86
|
+
...updatedProps.cdk.revalidation,
|
|
87
|
+
vpc: vpcDetails.vpc,
|
|
88
|
+
};
|
|
89
|
+
if (!ixDeployConfig.vpcHttpProxy) {
|
|
90
|
+
console.warn(`Attempting to add HTTP proxy environment variables to ${id} but the VPC_HTTP_PROXY env var is not configured.`);
|
|
91
|
+
}
|
|
92
|
+
// If we're using the AWS runner then the build stage will already be inside the VPC and required the proxy but
|
|
93
|
+
// the HTTP proxy environment variables will be already set in the environment by the pipeline and so the build
|
|
94
|
+
// stage will inherit that.
|
|
95
|
+
updatedProps.environment = {
|
|
96
|
+
HTTP_PROXY: { runtime: ixDeployConfig.vpcHttpProxy },
|
|
97
|
+
HTTPS_PROXY: { runtime: ixDeployConfig.vpcHttpProxy },
|
|
98
|
+
http_proxy: { runtime: ixDeployConfig.vpcHttpProxy },
|
|
99
|
+
https_proxy: { runtime: ixDeployConfig.vpcHttpProxy },
|
|
100
|
+
...updatedProps.environment,
|
|
101
|
+
};
|
|
102
|
+
return updatedProps;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Ensures environment variables that are conditionally included for buildtime or runtime are only used during the
|
|
106
|
+
* appropriate phase.
|
|
107
|
+
*/
|
|
108
|
+
export function applyConditionalEnvironmentVariables(scope, id, props) {
|
|
109
|
+
const updatedProps = { ...props };
|
|
110
|
+
if (!updatedProps.environment)
|
|
111
|
+
return updatedProps;
|
|
112
|
+
const buildtimeSpecificEnvVars = Object.fromEntries(Object.entries(updatedProps.environment)
|
|
113
|
+
.filter(([, value]) => typeof value === "object")
|
|
114
|
+
.map(([varName, value]) => [
|
|
115
|
+
varName,
|
|
116
|
+
typeof value === "object" && "buildtime" in value
|
|
117
|
+
? value.buildtime
|
|
118
|
+
: undefined,
|
|
119
|
+
]));
|
|
120
|
+
const runtimeSpecificEnvVars = Object.fromEntries(Object.entries(updatedProps.environment)
|
|
121
|
+
.filter(([, value]) => typeof value === "object")
|
|
122
|
+
.map(([varName, value]) => [
|
|
123
|
+
varName,
|
|
124
|
+
typeof value === "object" && "runtime" in value
|
|
125
|
+
? value.runtime
|
|
126
|
+
: undefined,
|
|
127
|
+
]));
|
|
128
|
+
// Remove runtime excluded env vars from lambda
|
|
129
|
+
updatedProps.cdk = updatedProps.cdk ?? {};
|
|
130
|
+
const oldTransform = updatedProps.cdk.transform;
|
|
131
|
+
updatedProps.cdk.transform = (plan) => {
|
|
132
|
+
oldTransform?.(plan);
|
|
133
|
+
for (const origin of Object.values(plan.origins)) {
|
|
134
|
+
if (!("function" in origin) || !origin.function.environment) {
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
for (const [envVarName, envVarValue] of Object.entries(runtimeSpecificEnvVars)) {
|
|
138
|
+
if (envVarValue !== undefined) {
|
|
139
|
+
origin.function.environment[envVarName] = envVarValue;
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
// @ts-expect-error - Environment values should generally only be strings but we need to set it to undefined
|
|
143
|
+
// as a workaround to override any environment variables that are mixed in during function creation which are
|
|
144
|
+
// only meant to be included at build time.
|
|
145
|
+
// https://github.com/sst/v2/blob/d0c9d5c1cbf8016b2a2b7ed2e247c27546b40387/packages/sst/src/constructs/SsrSite.ts#L1029
|
|
146
|
+
origin.function.environment[envVarName] = undefined;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
// Remove buildtime excluded env vars from environment object which is used during build
|
|
152
|
+
for (const [envVarName, envVarValue] of Object.entries(buildtimeSpecificEnvVars)) {
|
|
153
|
+
if (envVarValue !== undefined) {
|
|
154
|
+
updatedProps.environment[envVarName] = envVarValue;
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
delete updatedProps.environment[envVarName];
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return updatedProps;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Before props reach this function they should have already been converted into something compatible with the parent
|
|
164
|
+
* SST construct. This function verifies that's the case and updates the type if so.
|
|
165
|
+
*/
|
|
166
|
+
export function parentCompatibleSsrProps(props) {
|
|
167
|
+
for (const value of Object.values(props.environment ?? {})) {
|
|
168
|
+
if (typeof value !== "string") {
|
|
169
|
+
throw new Error("Internal make-it-so error: The environment prop contains buildtime/runtime specific environment variables which cannot be passed to the parent NextjsSite construct. Please use the applyConditionalEnvironmentVariables function to ensure only appropriate environment variables are included.");
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return props;
|
|
173
|
+
}
|
|
174
|
+
export function setupDefaultEnvVars(scope, id, props) {
|
|
175
|
+
const updatedProps = { ...props };
|
|
176
|
+
// NextjsSite functions to not use default env var unfortunately so we have to
|
|
177
|
+
// explicitly set them ourselves https://github.com/sst/sst/issues/2359
|
|
178
|
+
if ("defaultFunctionProps" in scope) {
|
|
179
|
+
for (const funcProps of scope.defaultFunctionProps) {
|
|
180
|
+
const defaultFunctionEnvVars = { ...funcProps.environment };
|
|
181
|
+
updatedProps.environment = {
|
|
182
|
+
...defaultFunctionEnvVars,
|
|
183
|
+
...updatedProps.environment,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return updatedProps;
|
|
188
|
+
}
|
|
189
|
+
export function setupDnsRecords(instance, scope, id, props) {
|
|
190
|
+
if (!instance.cdk?.distribution ||
|
|
191
|
+
typeof props.customDomain !== "object" ||
|
|
192
|
+
!props.customDomain.isIxManagedDomain)
|
|
193
|
+
return;
|
|
194
|
+
for (const domainName of getCustomDomains(props)) {
|
|
195
|
+
const domainNameLogicalId = convertToBase62Hash(domainName);
|
|
196
|
+
new IxDnsRecord(scope, `DnsRecord-${domainNameLogicalId}`, {
|
|
197
|
+
type: "ALIAS",
|
|
198
|
+
name: domainName,
|
|
199
|
+
value: instance.cdk.distribution.distributionDomainName,
|
|
200
|
+
aliasZoneId: CloudFrontTarget.getHostedZoneId(scope),
|
|
201
|
+
ttl: 900,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
export function getCustomDomains(props) {
|
|
206
|
+
const domainNames = new Set();
|
|
207
|
+
const primaryCustomDomain = getPrimaryCustomDomain(props);
|
|
208
|
+
const alternativeDomains = getAlternativeDomains(props);
|
|
209
|
+
if (primaryCustomDomain)
|
|
210
|
+
domainNames.add(primaryCustomDomain);
|
|
211
|
+
if (alternativeDomains.length)
|
|
212
|
+
alternativeDomains.forEach((domain) => domainNames.add(domain));
|
|
213
|
+
return Array.from(domainNames);
|
|
214
|
+
}
|
|
215
|
+
export function getPrimaryDomain(instance, props) {
|
|
216
|
+
return (getPrimaryCustomDomain(props) ??
|
|
217
|
+
instance.cdk?.distribution?.distributionDomainName ??
|
|
218
|
+
null);
|
|
219
|
+
}
|
|
220
|
+
export function getPrimaryOrigin(instance, props) {
|
|
221
|
+
const primaryDomain = getPrimaryDomain(instance, props);
|
|
222
|
+
return primaryDomain ? `https://${primaryDomain}` : null;
|
|
223
|
+
}
|
|
224
|
+
export function getPrimaryCustomDomain(props) {
|
|
225
|
+
if (typeof props.customDomain === "string") {
|
|
226
|
+
return props.customDomain;
|
|
227
|
+
}
|
|
228
|
+
else if (typeof props.customDomain === "object") {
|
|
229
|
+
return props.customDomain.domainName ?? null;
|
|
230
|
+
}
|
|
231
|
+
return null;
|
|
232
|
+
}
|
|
233
|
+
export function getAliasDomain(props) {
|
|
234
|
+
if (typeof props.customDomain === "object") {
|
|
235
|
+
return props.customDomain.domainAlias ?? null;
|
|
236
|
+
}
|
|
237
|
+
return null;
|
|
238
|
+
}
|
|
239
|
+
export function getAlternativeDomains(props) {
|
|
240
|
+
if (typeof props.customDomain === "object") {
|
|
241
|
+
return props.customDomain.alternateNames ?? [];
|
|
242
|
+
}
|
|
243
|
+
return [];
|
|
244
|
+
}
|
|
245
|
+
export function processAuthProps(scope, id, siteType, props) {
|
|
246
|
+
if (!props.auth)
|
|
247
|
+
return props;
|
|
248
|
+
const { oidc, ...otherAuthProps } = props.auth;
|
|
249
|
+
const auth = new SiteOidcAuth(scope, `${id}-SiteOidcAuth`, {
|
|
250
|
+
oidcIssuerUrl: oidc.issuerUrl,
|
|
251
|
+
oidcClientId: oidc.clientId,
|
|
252
|
+
oidcScope: oidc.scope,
|
|
253
|
+
});
|
|
254
|
+
if (siteType === "StaticSite") {
|
|
255
|
+
return auth.addToStaticSiteProps(scope, props, otherAuthProps);
|
|
256
|
+
}
|
|
257
|
+
else if (siteType === "SsrSite") {
|
|
258
|
+
return auth.addToSsrSiteProps(scope, props, otherAuthProps);
|
|
259
|
+
}
|
|
260
|
+
siteType;
|
|
261
|
+
throw new Error(`Unsupported site type ${siteType} when processing auth prop.`);
|
|
262
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/hash.ts"],"names":[],"mappings":"AAAA,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAa1D"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function convertToBase62Hash(string) {
|
|
2
|
+
const base62Chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
3
|
+
let hash = "";
|
|
4
|
+
let num = 0;
|
|
5
|
+
for (let i = 0; i < string.length; i++) {
|
|
6
|
+
num += string.charCodeAt(i);
|
|
7
|
+
}
|
|
8
|
+
while (num > 0) {
|
|
9
|
+
hash = base62Chars[num % 62] + hash;
|
|
10
|
+
num = Math.floor(num / 62);
|
|
11
|
+
}
|
|
12
|
+
return hash;
|
|
13
|
+
}
|