Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/api/esbuild.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { build, context } from 'esbuild';
import { readFileSync } from 'fs';
import { resolve } from 'path';
import copyStaticFiles from 'esbuild-copy-static-files';

const isWatching = !!process.argv.includes('--watch')
const nodePackage = JSON.parse(readFileSync(resolve(process.cwd(), 'package.json'), 'utf8'));
Expand All @@ -24,14 +25,17 @@ const buildOptions = {
},
banner: {
js: `
import path from 'path';
import { fileURLToPath } from 'url';
import { createRequire as topLevelCreateRequire } from 'module';
const require = topLevelCreateRequire(import.meta.url);
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
`.trim(),
}, // Banner for compatibility with CommonJS
plugins: [copyStaticFiles({
src: './public',
dest: resolve(process.cwd(), '../', '../', 'dist_devel', 'public'),
})],
};

if (isWatching) {
Expand Down
24 changes: 20 additions & 4 deletions src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { randomUUID } from "crypto";
import fastify, { FastifyInstance } from "fastify";
import FastifyAuthProvider from "@fastify/auth";
import fastifyStatic from "@fastify/static";
import fastifyAuthPlugin from "./plugins/auth.js";
import protectedRoute from "./routes/protected.js";
import errorHandlerPlugin from "./plugins/errorHandler.js";
Expand All @@ -24,23 +25,35 @@ import { SecretsManagerClient } from "@aws-sdk/client-secrets-manager";
import mobileWalletRoute from "./routes/mobileWallet.js";
import stripeRoutes from "./routes/stripe.js";
import membershipPlugin from "./routes/membership.js";
import path from "path"; // eslint-disable-line import/no-nodejs-modules

dotenv.config();

const now = () => Date.now();

async function init() {
async function init(prettyPrint: boolean = false) {
const dynamoClient = new DynamoDBClient({
region: genericConfig.AwsRegion,
});

const secretsManagerClient = new SecretsManagerClient({
region: genericConfig.AwsRegion,
});

const transport = prettyPrint
? {
target: "pino-pretty",
options: {
colorize: true,
translateTime: "SYS:standard",
ignore: "pid,hostname",
singleLine: false,
},
}
: undefined;
const app: FastifyInstance = fastify({
logger: {
level: process.env.LOG_LEVEL || "info",
transport,
},
rewriteUrl: (req) => {
const url = req.url;
Expand Down Expand Up @@ -71,6 +84,10 @@ async function init() {
await app.register(fastifyZodValidationPlugin);
await app.register(FastifyAuthProvider);
await app.register(errorHandlerPlugin);
await app.register(fastifyStatic, {
root: path.join(__dirname, "public"),
prefix: "/",
});
if (!process.env.RunEnvironment) {
process.env.RunEnvironment = "dev";
}
Expand Down Expand Up @@ -104,7 +121,6 @@ async function init() {
);
done();
});
app.get("/", (_, reply) => reply.send("Welcome to the ACM @ UIUC Core API!"));
app.get("/api/v1/healthz", (_, reply) => reply.send({ message: "UP" }));
await app.register(
async (api, _options) => {
Expand Down Expand Up @@ -143,7 +159,7 @@ if (import.meta.url === `file://${process.argv[1]}`) {
);
process.exit(1);
}
const app = await init();
const app = await init(true);
app.listen({ port: 8080 }, async (err) => {
/* eslint no-console: ["error", {"allow": ["log", "error"]}] */
if (err) console.error(err);
Expand Down
5 changes: 4 additions & 1 deletion src/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"@fastify/aws-lambda": "^5.0.0",
"@fastify/caching": "^9.0.1",
"@fastify/cors": "^10.0.1",
"@fastify/static": "^8.1.1",
"@middy/core": "^6.0.0",
"@middy/event-normalizer": "^6.0.0",
"@middy/sqs-partial-batch-failure": "^6.0.0",
Expand Down Expand Up @@ -57,6 +58,8 @@
"@tsconfig/node22": "^22.0.0",
"@types/aws-lambda": "^8.10.147",
"@types/qrcode": "^1.5.5",
"nodemon": "^3.1.9"
"esbuild-copy-static-files": "^0.1.0",
"nodemon": "^3.1.9",
"pino-pretty": "^13.0.0"
}
}
Binary file added src/api/public/favicon.ico
Binary file not shown.
33 changes: 33 additions & 0 deletions tests/live/protected.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { expect, test, describe } from "vitest";
import { createJwt } from "./utils";
import { allAppRoles } from "../../src/common/roles";

const baseEndpoint = `https://core.aws.qa.acmuiuc.org`;

describe("Role checking live API tests", async () => {
const token = await createJwt();
test(
"Test that auth is present on the GET route",
{ timeout: 10000 },
async () => {
const response = await fetch(`${baseEndpoint}/api/v1/protected/`, {
method: "GET",
});
expect(response.status).toBe(403);
},
);
test("Test that getting metadata succeeds", { timeout: 10000 }, async () => {
const response = await fetch(`${baseEndpoint}/api/v1/protected`, {
method: "GET",
headers: {
Authorization: `Bearer ${token}`,
},
});
expect(response.status).toBe(200);
const responseBody = await response.json();
expect(responseBody).toStrictEqual({
username: "[email protected]",
roles: allAppRoles,
});
});
});
32 changes: 32 additions & 0 deletions tests/live/tickets.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { expect, test, describe } from "vitest";
import { createJwt } from "./utils";

const baseEndpoint = `https://core.aws.qa.acmuiuc.org`;

describe("Tickets live API tests", async () => {
const token = await createJwt();
test(
"Test that auth is present on the GET route",
{ timeout: 10000 },
async () => {
const response = await fetch(`${baseEndpoint}/api/v1/tickets/`, {
method: "GET",
});
expect(response.status).toBe(403);
},
);
test("Test that getting metadata succeeds", { timeout: 10000 }, async () => {
const response = await fetch(`${baseEndpoint}/api/v1/tickets`, {
method: "GET",
headers: {
Authorization: `Bearer ${token}`,
},
});
expect(response.status).toBe(200);
const responseBody = await response.json();
expect(responseBody).toHaveProperty("merch");
expect(responseBody).toHaveProperty("tickets");
expect(Array.isArray(responseBody["merch"])).toBe(true);
expect(Array.isArray(responseBody["tickets"])).toBe(true);
});
});
23 changes: 23 additions & 0 deletions tests/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"compilerOptions": {
"target": "ES2020",
"module": "NodeNext",
"moduleResolution": "node",
"esModuleInterop": true,
"strict": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"outDir": "../dist/tests",
"rootDir": ".",
"resolveJsonModule": true,
},
"include": [
"./e2e/**/*.ts",
"./live/**/*.ts",
"./unit/**/*.ts"
],
"exclude": [
"../node_modules",
"../dist"
]
}
Loading
Loading