Skip to content

Commit

Permalink
Fix runtime function which was not a valid compilation target.
Browse files Browse the repository at this point in the history
  • Loading branch information
Happy0 committed Jan 22, 2024
1 parent 3e99af6 commit 709da06
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 48 deletions.
16 changes: 10 additions & 6 deletions examples/api-gateway-authorizer/runtime/user.fn.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import type { LambdaConfig } from "@notation/aws/lambda.fn";
import { handle, json } from "@notation/aws/lambda.fn";
import { EventWithJWTToken } from "@notation/aws/shared";
import {
JWTAuthorizedApiGatewayHandler,
EventWithJWTToken,
} from "@notation/aws/shared";
import { Context } from "aws-lambda";

export const getUserHandler = handle.jwtAuthorizedApiRequest(
(event: EventWithJWTToken, context: Context) => {
return json({ userId: "" });
},
);
export const getUserHandler: JWTAuthorizedApiGatewayHandler =
handle.jwtAuthorizedApiRequest(
(event: EventWithJWTToken, context: Context) => {
return json({ userId: "" });
},
);

export const config: LambdaConfig = {
service: "aws/lambda",
Expand Down
11 changes: 3 additions & 8 deletions packages/aws/src/api-gateway/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,16 @@ import * as aws from "@notation/aws.iac";
import { lambda } from "src/lambda";
import { api } from "./api";
import { AuthorizerConfig, JWTAuthorizerConfig, NO_AUTH } from "./auth";
import { mapAuthConfig, mapAuthType, toApiGatewayHandler } from "./utils";
import { mapAuthConfig, mapAuthType } from "./utils";

export const jwtAuthorizedRoute = (
apiGroup: ReturnType<typeof api>,
method: string, // todo: http methods only
path: `/${string}`,
auth: JWTAuthorizerConfig,
handler: JWTAuthorizedApiGatewayHandler,
handler: ApiGatewayHandler,
) => {
// We require a 'JWTAuthorizedApiGatewayHandler' to be passed in for type safety (since only a jwtAuthorizedRoute notation resource
// will have the JWT header.) However, the AWS lambda resource itself must have the API gateway handler type for compatibility.
const apiGatewayHandler = toApiGatewayHandler(handler);

return routeResource(apiGroup, method, path, auth, apiGatewayHandler);
return routeResource(apiGroup, method, path, auth, handler);
};

export const route = (
Expand All @@ -38,7 +34,6 @@ const routeResource = (
auth: AuthorizerConfig,
handler: ApiGatewayHandler,
) => {

const apiResource = apiGroup.findResource(aws.apiGateway.Api)!;

// at compile time becomes infra module
Expand Down
3 changes: 1 addition & 2 deletions packages/aws/src/api-gateway/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ export const jwtAuthenticatedUserRouter = (
jwtAuthorizerConfig: JWTAuthorizerConfig,
) => {
const createRouteCallback =
(method: string) =>
(path: `/${string}`, handler: JWTAuthorizedApiGatewayHandler) => {
(method: string) => (path: `/${string}`, handler: ApiGatewayHandler) => {
return jwtAuthorizedRoute(
apiGroup,
method,
Expand Down
27 changes: 0 additions & 27 deletions packages/aws/src/api-gateway/utils.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
import { decomposeUnverifiedJwt } from "aws-jwt-verify/jwt";
import { AuthorizerConfig, JWTAuthorizerConfig } from "./auth";
import { APIGatewayProxyEventV2, Context } from "aws-lambda";
import type {
ApiGatewayHandler,
JWTAuthorizedApiGatewayHandler,
} from "src/shared";

export const mapAuthConfig = (config: JWTAuthorizerConfig) => {
const jwtType: "JWT" = "JWT";
Expand All @@ -23,24 +17,3 @@ export const mapAuthConfig = (config: JWTAuthorizerConfig) => {
export const mapAuthType = (config: AuthorizerConfig) => {
return config?.type === "jwt" ? "JWT" : "NONE";
};

export const toApiGatewayHandler = (
handler: JWTAuthorizedApiGatewayHandler,
): ApiGatewayHandler => {
const apiGatewayHandler: ApiGatewayHandler = (event: APIGatewayProxyEventV2, context: Context) => {
const authorizationHeader = event.headers.Authorization!;

// Remove the 'Bearer ' prefix that preceeds the token itself
const jwtToken = authorizationHeader?.slice(7);
const jwt = decomposeUnverifiedJwt(jwtToken);

const eventWithJwt = {
token: jwt.payload,
event: event,
};

return handler(eventWithJwt, context);
};

return apiGatewayHandler
};
33 changes: 29 additions & 4 deletions packages/aws/src/lambda.fn/handlers.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { decomposeUnverifiedJwt } from "aws-jwt-verify/jwt";
import { APIGatewayProxyEventV2, Context } from "aws-lambda";
import type {
ApiGatewayHandler,
DynamoDbBatchHandler,
Expand All @@ -14,10 +16,9 @@ export const handle = {
async (...args) =>
handler(...args),

jwtAuthorizedApiRequest:
(handler: JWTAuthorizedApiGatewayHandler): JWTAuthorizedApiGatewayHandler =>
async (...args) =>
handler(...args),
jwtAuthorizedApiRequest: (
handler: JWTAuthorizedApiGatewayHandler,
): ApiGatewayHandler => toApiGatewayHandler(handler),

eventBridgeScheduledEvent:
(
Expand All @@ -42,3 +43,27 @@ export const handle = {
async (...args) =>
handler(...args),
};

const toApiGatewayHandler = (
handler: JWTAuthorizedApiGatewayHandler,
): ApiGatewayHandler => {
const apiGatewayHandler: ApiGatewayHandler = (
event: APIGatewayProxyEventV2,
context: Context,
) => {
const authorizationHeader = event.headers.Authorization!;

// Remove the 'Bearer ' prefix that preceeds the token itself
const jwtToken = authorizationHeader?.slice(7);
const jwt = decomposeUnverifiedJwt(jwtToken);

const eventWithJwt = {
token: jwt.payload,
event: event,
};

return handler(eventWithJwt, context);
};

return apiGatewayHandler;
};
10 changes: 9 additions & 1 deletion packages/aws/test/lambda.fn.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,15 @@ beforeEach(() => {
test("handlers wrap user-provided handlers", async () => {
const fn = async () => ({ body: "{}" });
for (const handler of Object.values(handle)) {
const result = await handler(fn)({} as any, {} as any);
const result = await handler(fn)(
{
headers: {
Authorization:
"Bearer eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJzdWIiOiAiMTIzNDU2Nzg5MCIsICJuYW1lIjogIkpvaG4gRG9lIiwgImlhdCI6IDE1MTYyMzkwMjJ9.vBbO0bfWhxupD6Gp6gIyWzgSZDvQewYV23j9LKm7nV8",
},
} as any,
{} as any,
);
expect(result).toEqual({ body: "{}" });
}
});
Expand Down

0 comments on commit 709da06

Please sign in to comment.