Skip to content

Instantly share code, notes, and snippets.

@luketn
Created April 3, 2019 01:40
Show Gist options
  • Save luketn/cf89a544dc47d0e0722815f081db1570 to your computer and use it in GitHub Desktop.
Save luketn/cf89a544dc47d0e0722815f081db1570 to your computer and use it in GitHub Desktop.
import {
CloudFrontRequestHandler,
CloudFrontRequestEvent,
CloudFrontRequestResult,
Context,
CloudFrontResultResponse,
CloudFrontHeaders
} from 'aws-lambda';
import {verify} from 'jsonwebtoken';
import {AUTH_PUBLIC_KEY} from './test/public_key';
interface TokenData {
'X-IFM-UID': string;
exp: number;
iat: number;
}
export const auth: CloudFrontRequestHandler = async (event: CloudFrontRequestEvent, context: Context): Promise<CloudFrontRequestResult> => {
if (!(event && event.Records && event.Records.length > 0 && event.Records[0].cf && event.Records[0].cf.request)) {
return createResult(500, 'Invalid authentication event.')
}
let request = event.Records[0].cf.request;
console.log(JSON.stringify(request));
if (request.method === 'OPTIONS') {
return handleOptions(request);
}
let authorizationHeader = request.headers['authorization'];
if (!(authorizationHeader && authorizationHeader.length > 0 && authorizationHeader[0].value)) {
return createResult(401, 'No Authorization header provided.');
}
let token = trimBearer(authorizationHeader[0].value);
if (!(token && token.length > 0)) {
return createResult(401, 'Empty token in Authorization header.');
}
let jwt: TokenData;
try {
jwt = <TokenData>verify(token, AUTH_PUBLIC_KEY);
} catch {
return createResult(401, 'An error occurred attempting to verify the Authorization header.');
}
let uid = jwt["x-ifm-uid"];
if (uid) {
setHeader(request.headers, 'x-ifm-uid', uid);
}
let expiry = String(jwt.exp);
if (expiry) {
setHeader(request.headers, 'x-expiry', expiry);
}
let issuedAt = String(jwt.iat);
if (issuedAt) {
setHeader(request.headers, 'x-issued-at', issuedAt);
}
return request;
};
const createResult = (status: number, message: string): CloudFrontResultResponse => {
return {
status: String(status),
statusDescription: message,
bodyEncoding: "text",
body: message,
headers: {}
};
};
const trimBearer = (token: string): string => {
if (token.startsWith("Bearer ")) {
return token.substr(7);
} else {
return token;
}
};
const setHeader = (headers: CloudFrontHeaders, name: string, value) => {
headers[name.toLowerCase()] = [{key: name, value: value}];
};
const getHeader = (headers: CloudFrontHeaders, name: string): string => {
let header = headers[name.toLowerCase()];
if (!header || header.length == 0) {
return null;
} else {
return header[0].value;
}
};
const handleOptions = (request) => {
let response = createResult(200, "accepted");
let origin = getHeader(request.headers, 'origin');
if (origin) {
setHeader(response.headers, 'Access-Control-Allow-Origin', origin);
} else {
setHeader(response.headers, 'Access-Control-Allow-Origin', '*');
}
let requestHeaders = getHeader(request.headers, 'access-control-request-headers');
if (requestHeaders) {
setHeader(response.headers, 'Access-Control-Allow-Headers', requestHeaders);
} else {
setHeader(response.headers, 'Access-Control-Allow-Headers', '*');
}
let requestMethod = getHeader(request.headers, 'access-control-request-method');
if (requestMethod) {
setHeader(response.headers, 'Access-Control-Allow-Methods', requestMethod);
} else {
setHeader(response.headers, 'Access-Control-Allow-Methods', 'POST, GET, HEAD, PUT, DELETE, OPTIONS');
}
setHeader(response.headers, 'Access-Control-Allow-Credentials', String(true));
return response;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment