Skip to content

Commit 88799b6

Browse files
committed
Documentation Updates
1 parent 036f7e2 commit 88799b6

File tree

8 files changed

+91
-30
lines changed

8 files changed

+91
-30
lines changed

cloudformation/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -845,7 +845,7 @@ Resources:
845845
Origins:
846846
- Id: LambdaOrigin
847847
DomainName: !Select [0, !Split ['/', !Select [1, !Split ['https://', !GetAtt AppLambdaUrl.FunctionUrl]]]]
848-
OriginPath: "/api/v1/ical"
848+
OriginPath: "/api/v1/ical/"
849849
CustomOriginConfig:
850850
HTTPPort: 80
851851
HTTPSPort: 443

src/api/components/index.ts

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { AppRoles } from "common/roles.js";
1+
import { AppRoleHumanMapper, AppRoles } from "common/roles.js";
22
import { FastifyZodOpenApiSchema } from "fastify-zod-openapi";
33
import * as z from "zod/v4";
44
import { CoreOrganizationList } from "@acm-uiuc/js-shared";
@@ -208,10 +208,30 @@ export function withRoles<T extends FastifyZodOpenApiSchema>(
208208
security,
209209
"x-required-roles": roles,
210210
"x-disable-api-key-auth": disableApiKeyAuth,
211-
description:
212-
roles.length > 0
213-
? `${disableApiKeyAuth ? "API key authentication is not permitted for this route.\n\n" : ""}Requires one of the following roles: ${roles.join(", ")}.${schema.description ? `\n\n${schema.description}` : ""}`
214-
: "Requires valid authentication but no specific role.",
211+
description: `
212+
${
213+
disableApiKeyAuth
214+
? `
215+
> [!important]
216+
> This resource cannot be accessed with an API key.
217+
`
218+
: ""
219+
}
220+
221+
${
222+
schema.description
223+
? `
224+
#### Description
225+
<hr />
226+
${schema.description}
227+
`
228+
: ""
229+
}
230+
231+
#### Authorization
232+
<hr />
233+
${roles.length > 0 ? `Requires any of the following roles:\n\n${roles.map((item) => `* ${AppRoleHumanMapper[item]} (<code>${item}</code>)`).join("\n")}` : "Requires valid authentication but no specific authorization."}
234+
`,
215235
...schema,
216236
response: responses,
217237
};

src/api/createSwagger.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import path from "node:path";
33
import { writeFile, mkdir } from "fs/promises";
44
import init from "./index.js"; // Assuming this is your Fastify app initializer
55

6-
const html = `
6+
export const docsHtml = `
77
<!doctype html>
88
<html>
99
<head>
@@ -157,7 +157,7 @@ async function createSwaggerFiles() {
157157
const yamlSpec = app.swagger({ yaml: true });
158158
await writeFile(path.join(outputDir, "openapi.json"), jsonSpec);
159159
await writeFile(path.join(outputDir, "openapi.yaml"), yamlSpec);
160-
await writeFile(path.join(outputDir, "index.html"), html);
160+
await writeFile(path.join(outputDir, "index.html"), docsHtml);
161161

162162
console.log(`✅ Swagger files successfully generated in ${outputDir}`);
163163
await app.close();
@@ -166,5 +166,6 @@ async function createSwaggerFiles() {
166166
process.exit(1);
167167
}
168168
}
169-
170-
createSwaggerFiles();
169+
if (import.meta.url === `file://createSwagger.ts`) {
170+
createSwaggerFiles();
171+
}

src/api/index.ts

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ import protectedRoute from "./routes/protected.js";
6060
import eventsPlugin from "./routes/events.js";
6161
import mobileWalletV2Route from "./routes/v2/mobileWallet.js";
6262
import membershipV2Plugin from "./routes/v2/membership.js";
63+
import { docsHtml } from "./createSwagger.js";
6364
/** END ROUTES */
6465

6566
export const instanceId = randomUUID();
@@ -114,14 +115,31 @@ async function init(prettyPrint: boolean = false, initClients: boolean = true) {
114115
if (!isRunningInLambda) {
115116
try {
116117
const fastifySwagger = import("@fastify/swagger");
117-
const fastifySwaggerUI = import("@fastify/swagger-ui");
118118
await app.register(fastifySwagger, {
119119
openapi: {
120120
info: {
121121
title: "ACM @ UIUC Core API",
122-
description:
123-
"The ACM @ UIUC Core API provides services for managing chapter operations.",
124-
version: "2.0.0",
122+
description: `
123+
The ACM @ UIUC Core API provides services for managing chapter operations.
124+
125+
## Usage
126+
127+
The primary consumer of the Core API is the Management Portal, which allows members to manage the chapter.
128+
Others may call the API with an API key; please contact us to obtain one.
129+
130+
This API also integrates into the ACM website and other suborganization to provide calendar services.
131+
132+
Calendar clients call the iCal endpoints (available through [ical.acm.illinois.edu](https://ical.acm.illinois.edu)) for calendar services.
133+
134+
## Contact
135+
<hr />
136+
137+
If you are an ACM @ UIUC member, please join the Infra Committee Discord for support.
138+
Otherwise, email [[email protected]](mailto:[email protected]) for support.
139+
140+
**For all security concerns, please email [[email protected]](mailto:[email protected]) with the subject "Security Concern".**
141+
`,
142+
version: "2.0.1",
125143
contact: {
126144
name: "ACM @ UIUC Infrastructure Team",
127145
@@ -215,9 +233,23 @@ async function init(prettyPrint: boolean = false, initClients: boolean = true) {
215233
transform: fastifyZodOpenApiTransform,
216234
transformObject: fastifyZodOpenApiTransformObject,
217235
});
218-
await app.register(fastifySwaggerUI, {
219-
routePrefix: "/api/documentation",
236+
app.get("/docs", { schema: { hide: true } }, (_request, reply) => {
237+
reply.type("text/html").send(docsHtml);
220238
});
239+
app.get(
240+
"/docs/openapi.json",
241+
{ schema: { hide: true } },
242+
(_request, reply) => {
243+
reply.send(app.swagger());
244+
},
245+
);
246+
app.get(
247+
"/docs/openapi.yml",
248+
{ schema: { hide: true } },
249+
(_request, reply) => {
250+
reply.send(app.swagger({ yaml: true }));
251+
},
252+
);
221253
isSwaggerServer = true;
222254
} catch (e) {
223255
app.log.error(e);

src/api/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@
6363
"@fastify/swagger": "^9.5.0"
6464
},
6565
"devDependencies": {
66-
"@fastify/swagger-ui": "^5.2.2",
6766
"@tsconfig/node22": "^22.0.1",
6867
"@types/aws-lambda": "^8.10.149",
6968
"@types/qrcode": "^1.5.5",

src/api/routes/mobileWallet.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ const mobileWalletRoute: FastifyPluginAsync = async (fastify, _options) => {
4343
}),
4444
},
4545
async (request, reply) => {
46+
reply.header(
47+
"Deprecation",
48+
"The V1 endpoint will soon be deprecated. Please use the V2 endpoint moving forward.",
49+
);
4650
const isPaidMember =
4751
(fastify.runEnvironment === "dev" &&
4852
request.query.email === "[email protected]") ||

src/common/roles.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,19 @@ export enum AppRoles {
1919
export const allAppRoles = Object.values(AppRoles).filter(
2020
(value) => typeof value === "string",
2121
);
22+
23+
export const AppRoleHumanMapper: Record<AppRoles, string> = {
24+
[AppRoles.EVENTS_MANAGER]: "Events Manager",
25+
[AppRoles.TICKETS_SCANNER]: "Tickets Scanner",
26+
[AppRoles.TICKETS_MANAGER]: "Tickets Manager",
27+
[AppRoles.IAM_ADMIN]: "IAM Admin",
28+
[AppRoles.IAM_INVITE_ONLY]: "IAM Inviter",
29+
[AppRoles.LINKS_MANAGER]: "Links Manager",
30+
[AppRoles.LINKS_ADMIN]: "Links Admin",
31+
[AppRoles.STRIPE_LINK_CREATOR]: "Stripe Link Creator",
32+
[AppRoles.BYPASS_OBJECT_LEVEL_AUTH]: "Object Level Auth Bypass",
33+
[AppRoles.ROOM_REQUEST_CREATE]: "Room Request Creator",
34+
[AppRoles.ROOM_REQUEST_UPDATE]: "Room Request Updater",
35+
[AppRoles.AUDIT_LOG_VIEWER]: "Audit Log Viewer",
36+
[AppRoles.MANAGE_ORG_API_KEYS]: "Org API Keys Manager"
37+
}

yarn.lock

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,7 +1457,7 @@
14571457
http-errors "^2.0.0"
14581458
mime "^3"
14591459

1460-
"@fastify/static@^8.0.0", "@fastify/static@^8.1.1":
1460+
"@fastify/static@^8.1.1":
14611461
version "8.2.0"
14621462
resolved "https://registry.yarnpkg.com/@fastify/static/-/static-8.2.0.tgz#5ad4878f13f415d1ee78448020a6f522ac7af595"
14631463
integrity sha512-PejC/DtT7p1yo3p+W7LiUtLMsV8fEvxAK15sozHy9t8kwo5r0uLYmhV/inURmGz1SkHZFz/8CNtHLPyhKcx4SQ==
@@ -1469,17 +1469,6 @@
14691469
fastq "^1.17.1"
14701470
glob "^11.0.0"
14711471

1472-
"@fastify/swagger-ui@^5.2.2":
1473-
version "5.2.3"
1474-
resolved "https://registry.yarnpkg.com/@fastify/swagger-ui/-/swagger-ui-5.2.3.tgz#3dc7f5ed3c226f55d894cdc2d45490efd22f3c4a"
1475-
integrity sha512-e7ivEJi9EpFcxTONqICx4llbpB2jmlI+LI1NQ/mR7QGQnyDOqZybPK572zJtcdHZW4YyYTBHcP3a03f1pOh0SA==
1476-
dependencies:
1477-
"@fastify/static" "^8.0.0"
1478-
fastify-plugin "^5.0.0"
1479-
openapi-types "^12.1.3"
1480-
rfdc "^1.3.1"
1481-
yaml "^2.4.1"
1482-
14831472
"@fastify/swagger@^9.5.0":
14841473
version "9.5.1"
14851474
resolved "https://registry.yarnpkg.com/@fastify/swagger/-/swagger-9.5.1.tgz#8ec9e2e6e8390a674cf3da9f339c9e59466e46fa"
@@ -10433,7 +10422,7 @@ yallist@^4.0.0:
1043310422
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
1043410423
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
1043510424

10436-
yaml@^2.4.1, yaml@^2.4.2:
10425+
yaml@^2.4.2:
1043710426
version "2.8.0"
1043810427
resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.8.0.tgz#15f8c9866211bdc2d3781a0890e44d4fa1a5fff6"
1043910428
integrity sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==

0 commit comments

Comments
 (0)