Skip to content

Commit 50fc62b

Browse files
committed
D7 - User auth on entering interview room
1 parent c9c3b14 commit 50fc62b

File tree

21 files changed

+1044
-171
lines changed

21 files changed

+1044
-171
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { defineConfig } from 'drizzle-kit';
2+
3+
const config = {
4+
host: process.env.EXPRESS_DB_HOST!,
5+
port: Number.parseInt(process.env.EXPRESS_DB_PORT!),
6+
database: process.env.POSTGRES_DB!,
7+
user: process.env.POSTGRES_USER,
8+
password: process.env.POSTGRES_PASSWORD,
9+
};
10+
11+
export default defineConfig({
12+
schema: './src/lib/db/schema.ts',
13+
out: './drizzle',
14+
dialect: 'postgresql',
15+
dbCredentials: config,
16+
});
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
CREATE TYPE "public"."action" AS ENUM('SEED');--> statement-breakpoint
2+
CREATE TABLE IF NOT EXISTS "admin" (
3+
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
4+
"created_at" timestamp DEFAULT now(),
5+
"action" "action" NOT NULL
6+
);
7+
--> statement-breakpoint
8+
CREATE TABLE IF NOT EXISTS "rooms" (
9+
"room_id" varchar(255) PRIMARY KEY NOT NULL,
10+
"user_id_1" uuid NOT NULL,
11+
"user_id_2" uuid NOT NULL,
12+
"question_id" serial NOT NULL,
13+
"created_at" timestamp DEFAULT now()
14+
);
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
{
2+
"id": "0fa8a8f0-f2e1-432e-890f-4a1da22f1a18",
3+
"prevId": "00000000-0000-0000-0000-000000000000",
4+
"version": "7",
5+
"dialect": "postgresql",
6+
"tables": {
7+
"public.admin": {
8+
"name": "admin",
9+
"schema": "",
10+
"columns": {
11+
"id": {
12+
"name": "id",
13+
"type": "uuid",
14+
"primaryKey": true,
15+
"notNull": true,
16+
"default": "gen_random_uuid()"
17+
},
18+
"created_at": {
19+
"name": "created_at",
20+
"type": "timestamp",
21+
"primaryKey": false,
22+
"notNull": false,
23+
"default": "now()"
24+
},
25+
"action": {
26+
"name": "action",
27+
"type": "action",
28+
"typeSchema": "public",
29+
"primaryKey": false,
30+
"notNull": true
31+
}
32+
},
33+
"indexes": {},
34+
"foreignKeys": {},
35+
"compositePrimaryKeys": {},
36+
"uniqueConstraints": {},
37+
"policies": {},
38+
"checkConstraints": {},
39+
"isRLSEnabled": false
40+
},
41+
"public.rooms": {
42+
"name": "rooms",
43+
"schema": "",
44+
"columns": {
45+
"room_id": {
46+
"name": "room_id",
47+
"type": "varchar(255)",
48+
"primaryKey": true,
49+
"notNull": true
50+
},
51+
"user_id_1": {
52+
"name": "user_id_1",
53+
"type": "uuid",
54+
"primaryKey": false,
55+
"notNull": true
56+
},
57+
"user_id_2": {
58+
"name": "user_id_2",
59+
"type": "uuid",
60+
"primaryKey": false,
61+
"notNull": true
62+
},
63+
"question_id": {
64+
"name": "question_id",
65+
"type": "serial",
66+
"primaryKey": false,
67+
"notNull": true
68+
},
69+
"created_at": {
70+
"name": "created_at",
71+
"type": "timestamp",
72+
"primaryKey": false,
73+
"notNull": false,
74+
"default": "now()"
75+
}
76+
},
77+
"indexes": {},
78+
"foreignKeys": {},
79+
"compositePrimaryKeys": {},
80+
"uniqueConstraints": {},
81+
"policies": {},
82+
"checkConstraints": {},
83+
"isRLSEnabled": false
84+
}
85+
},
86+
"enums": {
87+
"public.action": {
88+
"name": "action",
89+
"schema": "public",
90+
"values": [
91+
"SEED"
92+
]
93+
}
94+
},
95+
"schemas": {},
96+
"sequences": {},
97+
"roles": {},
98+
"policies": {},
99+
"views": {},
100+
"_meta": {
101+
"columns": {},
102+
"schemas": {},
103+
"tables": {}
104+
}
105+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"version": "7",
3+
"dialect": "postgresql",
4+
"entries": [
5+
{
6+
"idx": 0,
7+
"version": "7",
8+
"when": 1731050544004,
9+
"tag": "0000_initial_schema",
10+
"breakpoints": true
11+
}
12+
]
13+
}

backend/collaboration/package.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@
88
"start": "node dist/index.js",
99
"build:local": "env-cmd -f .env.local tsc && tsc-alias",
1010
"start:local": "env-cmd -f .env.local node dist/index.js",
11+
"db:generate": "env-cmd -f .env.local drizzle-kit generate",
12+
"db:migrate": "env-cmd -f .env.local tsx ./src/lib/db/migrate.ts",
13+
"db:prod:migrate": "tsx ./src/lib/db/migrate.ts",
14+
"db:prod:seed": "tsx ./src/lib/db/seed.ts",
15+
"db:seed": "env-cmd -f .env.local tsx src/lib/db/seed.ts",
16+
"db:seed:prod": "tsx src/lib/db/seed.ts",
1117
"fmt": "prettier --config .prettierrc src --write",
1218
"test": "echo \"Error: no test specified\" && exit 1"
1319
},
@@ -18,6 +24,7 @@
1824
"dependencies": {
1925
"cors": "^2.8.5",
2026
"dotenv": "^16.4.5",
27+
"drizzle-orm": "^0.36.1",
2128
"env-cmd": "^10.1.0",
2229
"express": "^4.21.1",
2330
"http-status-codes": "^2.3.0",
@@ -33,6 +40,7 @@
3340
"yjs": "^13.6.19"
3441
},
3542
"devDependencies": {
43+
"drizzle-kit": "^0.28.0",
3644
"@types/cors": "^2.8.17",
3745
"@types/express": "^4.17.21",
3846
"@types/node": "^22.5.5",
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { eq } from 'drizzle-orm';
2+
import type { Request, Response } from 'express';
3+
import { StatusCodes } from 'http-status-codes';
4+
5+
import { db, rooms } from '@/lib/db';
6+
7+
export async function authCheck(req: Request, res: Response) {
8+
const roomId = req.query.roomId as string | undefined;
9+
const userId = req.query.userId as string | undefined;
10+
11+
if (!roomId || !userId) {
12+
return {
13+
code: StatusCodes.UNPROCESSABLE_ENTITY,
14+
error: {
15+
message: 'Malformed',
16+
},
17+
};
18+
}
19+
20+
try {
21+
const room = await db.select().from(rooms).where(eq(rooms.roomId, roomId)).limit(1);
22+
23+
if (room.length === 0) {
24+
return res.status(StatusCodes.NOT_FOUND).json({
25+
error: {
26+
message: 'Room not found',
27+
},
28+
});
29+
}
30+
31+
const { userId1, userId2 } = room[0];
32+
33+
if (userId !== userId1 && userId !== userId2) {
34+
return res.status(StatusCodes.FORBIDDEN).json({
35+
code: StatusCodes.FORBIDDEN,
36+
error: { message: 'User is not authorized to access this room' },
37+
});
38+
}
39+
40+
return res.status(StatusCodes.OK).json({
41+
code: StatusCodes.OK,
42+
data: { roomId },
43+
});
44+
} catch (error) {
45+
console.error('Error authenticating room:', error);
46+
return res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
47+
code: StatusCodes.INTERNAL_SERVER_ERROR,
48+
error: { message: 'An error occurred while authenticating the room' },
49+
});
50+
}
51+
}

backend/collaboration/src/lib/db/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { drizzle } from 'drizzle-orm/postgres-js';
12
import postgres from 'postgres';
23

34
export const config = {
@@ -8,4 +9,8 @@ export const config = {
89
password: process.env.POSTGRES_PASSWORD,
910
};
1011

11-
export const db = postgres(config);
12+
const queryClient = postgres(config);
13+
14+
export const db = drizzle(queryClient);
15+
16+
export * from './schema';
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { drizzle } from 'drizzle-orm/postgres-js';
2+
import { migrate } from 'drizzle-orm/postgres-js/migrator';
3+
import postgres from 'postgres';
4+
5+
const config = {
6+
host: process.env.EXPRESS_DB_HOST!,
7+
port: Number.parseInt(process.env.EXPRESS_DB_PORT!),
8+
database: process.env.POSTGRES_DB,
9+
user: process.env.POSTGRES_USER,
10+
password: process.env.POSTGRES_PASSWORD,
11+
};
12+
const migrationConnection = postgres({ ...config, max: 1 });
13+
14+
const db = drizzle(migrationConnection);
15+
16+
const main = async () => {
17+
await migrate(db, { migrationsFolder: 'drizzle' });
18+
await migrationConnection.end();
19+
};
20+
21+
void main();
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { pgEnum, pgTable, serial, timestamp, uuid, varchar } from 'drizzle-orm/pg-core';
2+
3+
export const rooms = pgTable('rooms', {
4+
roomId: varchar('room_id', { length: 255 }).primaryKey().notNull(),
5+
userId1: uuid('user_id_1').notNull(),
6+
userId2: uuid('user_id_2').notNull(),
7+
questionId: serial('question_id').notNull(),
8+
createdAt: timestamp('created_at').defaultNow(),
9+
});
10+
11+
export const actionEnum = pgEnum('action', ['SEED']);
12+
13+
export const admin = pgTable('admin', {
14+
id: uuid('id').primaryKey().notNull().defaultRandom(),
15+
createdAt: timestamp('created_at').defaultNow(),
16+
action: actionEnum('action').notNull(),
17+
});
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import express from 'express';
22

33
import { getCollabRoom } from '@/controller/collab-controller';
4+
import { authCheck } from '@/controller/room-auth-controller';
45

56
const router = express.Router();
67

78
router.get('/', getCollabRoom);
9+
router.get('/auth', authCheck);
810

911
export default router;

0 commit comments

Comments
 (0)