Skip to content

Commit ef1c727

Browse files
Auto-update feature branch with changes from the main branch
2 parents 88d5aa2 + 41d85f4 commit ef1c727

21 files changed

+80
-35
lines changed

cloudformation/iam.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ Resources:
4343
Effect: Allow
4444
Resource:
4545
- Fn::Sub: arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:infra-core-api-config*
46+
- Fn::Sub: arn:aws:secretsmanager:${AWS::Region}:427040638965:secret:infra-core-api-testing-credentials* # this secret only exists in awsdev account
4647

4748
- Action:
4849
- dynamodb:DescribeLimits

generate_jwt.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export const getSecretValue = async (secretId) => {
2020
}
2121
};
2222

23-
const secrets = await getSecretValue("infra-core-api-config");
23+
const secrets = await getSecretValue("infra-core-api-testing-credentials");
2424
const client = new STSClient({ region: "us-east-1" });
2525
const command = new GetCallerIdentityCommand({});
2626
let data;

src/api/index.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
environmentConfig,
1616
genericConfig,
1717
SecretConfig,
18+
SecretTesting,
1819
} from "../common/config.js";
1920
import organizationsPlugin from "./routes/organizations.js";
2021
import authorizeFromSchemaPlugin from "./plugins/authorizeFromSchema.js";
@@ -253,13 +254,20 @@ async function init(prettyPrint: boolean = false) {
253254
app.dynamoClient = dynamoClient;
254255
app.secretsManagerClient = secretsManagerClient;
255256
app.redisClient = redisClient;
256-
app.secretConfig = secret;
257257
app.refreshSecretConfig = async () => {
258258
app.secretConfig = (await getSecretValue(
259259
app.secretsManagerClient,
260260
genericConfig.ConfigSecretName,
261261
)) as SecretConfig;
262+
if (app.environmentConfig.TestingCredentialsSecret) {
263+
const temp = (await getSecretValue(
264+
app.secretsManagerClient,
265+
app.environmentConfig.TestingCredentialsSecret,
266+
)) as SecretTesting;
267+
app.secretConfig = { ...app.secretConfig, ...temp };
268+
}
262269
};
270+
app.refreshSecretConfig();
263271
app.addHook("onRequest", (req, _, done) => {
264272
req.startTime = now();
265273
const hostname = req.hostname;

src/api/lambda.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import "zod-openapi/extend";
2-
import awsLambdaFastify from "@fastify/aws-lambda";
2+
import awsLambdaFastify, { LambdaResponse } from "@fastify/aws-lambda";
33
import init from "./index.js";
44
import warmer from "lambda-warmer";
55
import { type APIGatewayEvent, type Context } from "aws-lambda";
6+
import { InternalServerError } from "common/errors/index.js";
67

78
const app = await init();
89
const realHandler = awsLambdaFastify(app, {
@@ -16,7 +17,21 @@ const handler = async (event: APIGatewayEvent, context: Context) => {
1617
return "warmed";
1718
}
1819
// else proceed with handler logic
19-
return realHandler(event, context);
20+
return realHandler(event, context).catch((e) => {
21+
console.error(e);
22+
const newError = new InternalServerError({
23+
message: "Failed to initialize application.",
24+
});
25+
const json = JSON.stringify(newError.toJson());
26+
return {
27+
statusCode: newError.httpStatusCode,
28+
body: json,
29+
headers: {
30+
"Content-Type": "application/json",
31+
},
32+
isBase64Encoded: false,
33+
};
34+
});
2035
};
2136

2237
await app.ready(); // needs to be placed after awsLambdaFastify call because of the decoration: https://github.com/fastify/aws-lambda-fastify/blob/master/index.js#L9

src/api/plugins/auth.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
UnauthenticatedError,
1414
UnauthorizedError,
1515
} from "../../common/errors/index.js";
16-
import { SecretConfig } from "../../common/config.js";
16+
import { SecretConfig, SecretTesting } from "../../common/config.js";
1717
import {
1818
AUTH_DECISION_CACHE_SECONDS,
1919
getGroupRoles,
@@ -195,7 +195,7 @@ const authPlugin: FastifyPluginAsync = async (fastify, _options) => {
195195
}
196196
signingKey =
197197
process.env.JwtSigningKey ||
198-
(fastify.secretConfig.jwt_key as string) ||
198+
((fastify.secretConfig as SecretTesting).jwt_key as string) ||
199199
"";
200200
if (signingKey === "") {
201201
throw new UnauthenticatedError({

src/api/types.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import { FastifyRequest, FastifyInstance, FastifyReply } from "fastify";
33
import { AppRoles, RunEnvironment } from "../common/roles.js";
44
import { AadToken } from "./plugins/auth.js";
5-
import { ConfigType, SecretConfig } from "../common/config.js";
5+
import { ConfigType, SecretConfig, SecretTesting } from "../common/config.js";
66
import NodeCache from "node-cache";
77
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
88
import { SecretsManagerClient } from "@aws-sdk/client-secrets-manager";
@@ -36,7 +36,7 @@ declare module "fastify" {
3636
redisClient: Redis;
3737
secretsManagerClient: SecretsManagerClient;
3838
cloudfrontKvClient: CloudFrontKeyValueStoreClient;
39-
secretConfig: SecretConfig;
39+
secretConfig: SecretConfig | (SecretConfig & SecretTesting);
4040
refreshSecretConfig: CallableFunction;
4141
}
4242
interface FastifyRequest {

src/common/config.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export type ConfigType = {
2323
PaidMemberPriceId: string;
2424
AadValidReadOnlyClientId: string;
2525
LinkryCloudfrontKvArn?: string;
26+
TestingCredentialsSecret?: string;
2627
};
2728

2829
export type GenericConfigType = {
@@ -108,6 +109,7 @@ const environmentConfig: EnvironmentConfigType = {
108109
/^https:\/\/(?:.*\.)?acmuiuc\.pages\.dev$/,
109110
/http:\/\/localhost:\d+$/,
110111
],
112+
TestingCredentialsSecret: "infra-core-api-testing-credentials",
111113
AadValidClientId: "39c28870-94e4-47ee-b4fb-affe0bf96c9f",
112114
LinkryBaseUrl: "https://core.aws.qa.acmuiuc.org",
113115
PasskitIdentifier: "pass.org.acmuiuc.qa.membership",
@@ -147,7 +149,6 @@ const environmentConfig: EnvironmentConfigType = {
147149
};
148150

149151
export type SecretConfig = {
150-
jwt_key?: string;
151152
discord_guild_id: string;
152153
discord_bot_token: string;
153154
entra_id_private_key?: string;
@@ -161,6 +162,10 @@ export type SecretConfig = {
161162
redis_url: string;
162163
};
163164

165+
export type SecretTesting = {
166+
jwt_key: string;
167+
}
168+
164169
const roleArns = {
165170
Entra: process.env.EntraRoleArn,
166171
};

tests/e2e/base.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ async function getSecrets() {
3030
let response = { PLAYWRIGHT_USERNAME: "", PLAYWRIGHT_PASSWORD: "" };
3131
let keyData;
3232
if (!process.env.PLAYWRIGHT_USERNAME || !process.env.PLAYWRIGHT_PASSWORD) {
33-
keyData = await getSecretValue("infra-core-api-config");
33+
keyData = await getSecretValue("infra-core-api-testing-credentials");
3434
}
3535
response["PLAYWRIGHT_USERNAME"] =
3636
process.env.PLAYWRIGHT_USERNAME ||

tests/live/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ async function getSecrets() {
3030
const response = { JWTKEY: "" };
3131
let keyData;
3232
if (!process.env.JWT_KEY) {
33-
keyData = await getSecretValue("infra-core-api-config");
33+
keyData = await getSecretValue("infra-core-api-testing-credentials");
3434
}
3535
response["JWTKEY"] =
3636
process.env.JWT_KEY || ((keyData ? keyData["jwt_key"] : "") as string);

tests/unit/apiKey.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { afterAll, expect, test, beforeEach, vi, describe } from "vitest";
22
import { mockClient } from "aws-sdk-client-mock";
33
import init from "../../src/api/index.js";
44
import { createJwt } from "./auth.test.js";
5-
import { secretObject } from "./secret.testdata.js";
5+
import { testSecretObject } from "./secret.testdata.js";
66
import supertest from "supertest";
77
import {
88
ConditionalCheckFailedException,
@@ -31,7 +31,7 @@ vi.mock("../../src/api/functions/apiKey.js", () => {
3131
// Mock DynamoDB client
3232
const dynamoMock = mockClient(DynamoDBClient);
3333
const sqsMock = mockClient(SQSClient);
34-
const jwt_secret = secretObject["jwt_key"];
34+
const jwt_secret = testSecretObject["jwt_key"];
3535

3636
vi.stubEnv("JwtSigningKey", jwt_secret);
3737

0 commit comments

Comments
 (0)