Skip to content

Commit da56f72

Browse files
Add dashboard service (#280)
* Add super admin to dev email roles * Add ws dep * Add dashboard service
1 parent dc87fc8 commit da56f72

10 files changed

Lines changed: 816 additions & 3 deletions

File tree

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
"typescript": "^5.4.5",
5454
"uuid": "^11.1.0",
5555
"webidl-conversions": "^7.0.0",
56+
"ws": "^8.18.3",
5657
"zod": "^3.22.4"
5758
},
5859
"devDependencies": {

src/app.ts

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ import errorHandler from "./middleware/error-handler";
1414
import attendeeRouter from "./services/attendee/attendee-router";
1515
import staffRouter from "./services/staff/staff-router";
1616
import checkinRouter from "./services/checkin/checkin-router";
17+
import dashboardRouter, {
18+
handleWs as handleWsDashboard,
19+
} from "./services/dashboard/dashboard-router";
1720
import authRouter from "./services/auth/auth-router";
1821
import eventsRouter from "./services/events/events-router";
1922
import notificationsRouter from "./services/notifications/notifications-router";
@@ -29,8 +32,13 @@ import leaderboardRouter from "./services/leaderboard/leaderboard-router";
2932

3033
import cors from "cors";
3134
import { JwtPayloadValidator } from "./services/auth/auth-models";
35+
import { createServer } from "http";
36+
import { WebSocketServer } from "ws";
3237

3338
const app = express();
39+
const server = createServer(app);
40+
const wss = new WebSocketServer({ server });
41+
3442
app.enable("trust proxy");
3543

3644
// to prevent server-side caching/returning status code 200
@@ -84,6 +92,7 @@ app.use("/attendee", attendeeRouter);
8492
app.use("/staff", staffRouter);
8593
app.use("/auth", authRouter);
8694
app.use("/checkin", checkinRouter);
95+
app.use("/dashboard", dashboardRouter);
8796
app.use("/events", eventsRouter);
8897
app.use("/leaderboard", leaderboardRouter);
8998
app.use("/notifications", notificationsRouter);
@@ -113,10 +122,30 @@ app.use("/", (req, res) =>
113122

114123
app.use(errorHandler);
115124

125+
// Websocket handling
126+
wss.on("connection", (ws, request) => {
127+
try {
128+
if (request.url === "/dashboard") {
129+
handleWsDashboard(ws);
130+
} else {
131+
ws.send("Unknown url");
132+
ws.close(1008); // 1008 = policy violation
133+
}
134+
} catch (err) {
135+
console.error("WebSocket connection handle issue:", err);
136+
ws.close(1008); // 1008 = policy violation
137+
}
138+
});
139+
140+
wss.on("error", (err) => {
141+
console.error("WebSocket server issue:", err);
142+
});
143+
144+
// Start the server
116145
if (!isTest()) {
117-
app.listen(Config.DEFAULT_APP_PORT, async () => {
146+
server.listen(Config.DEFAULT_APP_PORT, async () => {
118147
process.send?.("ready");
119148
console.log("Server is listening on port 3000...");
120149
});
121150
}
122-
export default app;
151+
export { app, server };

src/config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ export const Config = {
108108
VERIFY_EXP_TIME_MS: 10 * 60 * 1000,
109109
SPONSOR_ENTIRES_PER_PAGE: 60,
110110

111+
DASHBOARD_PING_EVERY_MS: 5 * 1000,
112+
DASHBOARD_TIMEOUT_MS: 15 * 1000,
113+
111114
// QR Scanning
112115
QR_HASH_ITERATIONS: 10000,
113116
QR_HASH_SECRET: getEnv("QR_HASH_SECRET"),

src/services/auth/auth-utils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ export async function updateDatabaseWithAuthPayload(
6363
Config.DEV_ADMIN_EMAIL &&
6464
email === Config.DEV_ADMIN_EMAIL
6565
) {
66+
await SupabaseDB.AUTH_ROLES.upsert({
67+
userId,
68+
role: Role.Enum.SUPER_ADMIN,
69+
});
6670
await SupabaseDB.AUTH_ROLES.upsert({
6771
userId,
6872
role: Role.Enum.ADMIN,

0 commit comments

Comments
 (0)