Skip to content

Commit

Permalink
redid logic for easier ux
Browse files Browse the repository at this point in the history
  • Loading branch information
finnholland committed Jan 17, 2025
1 parent a966838 commit 317149a
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 38 deletions.
4 changes: 2 additions & 2 deletions packages/geoip-redirect/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import { RedirectFunction, GeoIpRegion, RedirectFunctionOptions } from "./lib/redirect-construct";
import { RedirectFunction, RedirectFunctionOptions } from "./lib/redirect-construct";

export { RedirectFunction, GeoIpRegion, RedirectFunctionOptions };
export { RedirectFunction, RedirectFunctionOptions };
57 changes: 32 additions & 25 deletions packages/geoip-redirect/lib/handlers/redirect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,46 @@ import {
CloudFrontResponse,
CloudFrontRequest,
} from "aws-lambda";
import { DomainOverwrite, RedirectFunctionOptions } from '../redirect-construct'

import { GeoIpRegion } from '../redirect-construct'


const options: RedirectFunctionOptions = {
defaultDomain: '',
defaultRegionCode: '',
supportedRegions: { '': '' }
}

export const handler = async (
event: CloudFrontRequestEvent
): Promise<CloudFrontResponse | CloudFrontRequest> => {
const DEFAULT_DOMAIN: string = process.env.DEFAULT_DOMAIN ?? "";
const DEFAULT_REGION_CODE: string = process.env.DEFAULT_REGION_CODE ?? "";
const SUPPORTED_REGIONS: GeoIpRegion[] = process.env.SUPPORTED_REGIONS as GeoIpRegion[] ?? [{ // this seems to not be correct, not passing as string!
regionDomain: DEFAULT_DOMAIN,
supportedSubRegions: { absoluteDomain: DEFAULT_DOMAIN, regionPath: DEFAULT_REGION_CODE.toLowerCase() },
}];
const request = event.Records[0].cf.request;
options.defaultDomain = process.env.DEFAULT_DOMAIN ?? "";
options.defaultRegionCode = process.env.DEFAULT_REGION_CODE ?? "";
const defaultRegion = options.defaultRegionCode.split("|")[0].toLowerCase();
options.supportedRegions = {
...process.env.SUPPORTED_REGIONS as Record<string, DomainOverwrite> ?? "{}",
...{ [options.defaultRegionCode]: options.defaultDomain }
};

let redirectURL = `https://${DEFAULT_DOMAIN}/`;
if (request.headers["cloudfront-viewer-country"]) {
const countryCode = request.headers["cloudfront-viewer-country"][0].value;
const matchingRegionURL = SUPPORTED_REGIONS.map(region => {
// Check if any key in supportedSubRegions matches the countryCode using regex
const recordKey = Object.keys(region.supportedSubRegions).find(pattern =>
new RegExp(`^(${pattern})$`).test(countryCode)
);
if (recordKey) {
return region.supportedSubRegions[recordKey]
}
return null
}).find((value) => value !== null);
if (options.supportedRegions) {
options.supportedRegions = Object.keys(options.supportedRegions).reduce((newRecord, key) => {
newRecord[key.toLowerCase()] = options.supportedRegions ? options.supportedRegions[key] : "";
return newRecord;
}, {});
}

redirectURL = `${redirectURL}${countryCode.toLowerCase()}${request.uri}`
if (matchingRegionURL) {
redirectURL = `https://${matchingRegionURL}${request.uri}`
let redirectURL = `https://${options.defaultDomain}/`;
if (request.headers["cloudfront-viewer-country"]) {
const countryCode = request.headers["cloudfront-viewer-country"][0].value.toLowerCase();
// Check if any key in supportedSubRegions matches the countryCode using regex
const recordKey = Object.keys(options.supportedRegions).find(pattern =>
new RegExp(`^(${pattern.toLowerCase()})$`).test(countryCode)
)?.toLowerCase();
if (recordKey) {
redirectURL = `https://${options.supportedRegions[recordKey]}/`;
if (recordKey.includes('|'))
redirectURL = redirectURL + countryCode.toLowerCase()
} else {
redirectURL = `${redirectURL}${defaultRegion}${request.uri}`
}

return {
Expand Down
28 changes: 17 additions & 11 deletions packages/geoip-redirect/lib/redirect-construct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,24 @@ import { Construct } from "constructs";
import { join } from "path";
import { Esbuild } from "@aligent/cdk-esbuild";

export interface GeoIpRegion {
// The domain that services a region (www.example.com for US/CA www.example.com.au for AU/NZ)
regionDomain: string;
// Case-sensitive regular expression matching cloudfront-viewer-country
supportedSubRegions: Record<string, string | null>;
} // add an aboslute redirect URL such as yd.co.nz for eg
export type DomainOverwrite = string | null

/**
* The default region, domain, and other supported regions for a website to redirect to.
*/
export interface RedirectFunctionOptions {
supportedRegions: GeoIpRegion[]
// default region code to use when not matched
/**
* Regex formatted string to match region codes and redirect to the DomainOverwrite destination.
* @default undefined
*/
supportedRegions?: Record<string, DomainOverwrite>;
/**
* Regex for supported domain paths on the default domain eg .com/au
*/
defaultRegionCode: string;
/**
* Default domain to redirect to unless otherwise specified.
*/
defaultDomain: string;
}

Expand Down Expand Up @@ -48,9 +55,8 @@ export class RedirectFunction extends Construct {
entryPoints: [join(__dirname, "handlers/redirect.ts")],
define: {
"process.env.DEFAULT_DOMAIN": JSON.stringify(options.defaultDomain),
"process.env.DEFAULT_REGION_CODE": JSON.stringify(options.defaultRegionCode),
"process.env.SUPPORTED_REGIONS": // find out if this is passing as string or not, cloudW says not
JSON.stringify(options.supportedRegions)
"process.env.DEFAULT_REGION_CODE": JSON.stringify(options.defaultRegionCode.toLowerCase()),
"process.env.SUPPORTED_REGIONS": JSON.stringify(options.supportedRegions) ?? "{}"
},
}),
},
Expand Down

0 comments on commit 317149a

Please sign in to comment.