Преглед на файлове

feat: Add session model and include in jobs and sockets

Owen Diffey преди 1 година
родител
ревизия
3e47b654c4

+ 1 - 1
backend/src/Job.ts

@@ -81,7 +81,7 @@ export default class Job {
 
 		this.payload = payload;
 
-		this.context = new JobContext(this);
+		this.context = new JobContext(this, options?.session);
 
 		this.logBook = LogBook.getPrimaryInstance();
 

+ 17 - 7
backend/src/JobContext.ts

@@ -2,6 +2,7 @@ import BaseModule from "./BaseModule";
 import Job from "./Job";
 import JobQueue from "./JobQueue";
 import { Log } from "./LogBook";
+import { SessionSchema } from "./schemas/session";
 import { JobOptions } from "./types/JobOptions";
 import { Jobs, Modules } from "./types/Modules";
 
@@ -10,9 +11,12 @@ export default class JobContext {
 
 	public readonly jobQueue: JobQueue;
 
-	public constructor(job: Job) {
+	private session?: SessionSchema;
+
+	public constructor(job: Job, session?: SessionSchema) {
 		this.job = job;
 		this.jobQueue = JobQueue.getPrimaryInstance();
+		this.session = session;
 	}
 
 	/**
@@ -24,6 +28,14 @@ export default class JobContext {
 		return this.job.log(log);
 	}
 
+	public getSession() {
+		return this.session;
+	}
+
+	public setSession(session?: SessionSchema) {
+		this.session = session;
+	}
+
 	/**
 	 * executeJob - Execute a job
 	 *
@@ -49,11 +61,9 @@ export default class JobContext {
 		payload: PayloadType,
 		options?: JobOptions
 	): Promise<ReturnType> {
-		return new Job(
-			jobName.toString(),
-			moduleName,
-			payload,
-			options
-		).execute();
+		return new Job(jobName.toString(), moduleName, payload, {
+			session: this.session,
+			...(options ?? {})
+		}).execute();
 	}
 }

+ 20 - 0
backend/src/WebSocket.ts

@@ -4,6 +4,10 @@ import LogBook, { Log } from "./LogBook";
 export default class WebSocket extends WSWebSocket {
 	protected logBook: LogBook = LogBook.getPrimaryInstance();
 
+	protected socketId?: string;
+
+	protected sessionId?: string;
+
 	public dispatch(name: string, ...args: any[]) {
 		this.send(JSON.stringify([name, ...args]));
 	}
@@ -28,4 +32,20 @@ export default class WebSocket extends WSWebSocket {
 			data
 		});
 	}
+
+	public getSocketId() {
+		return this.socketId;
+	}
+
+	public setSocketId(socketId?: string) {
+		this.socketId = socketId;
+	}
+
+	public getSessionId() {
+		return this.sessionId;
+	}
+
+	public setSessionId(sessionId?: string) {
+		this.sessionId = sessionId;
+	}
 }

+ 2 - 1
backend/src/modules/DataModule.ts

@@ -221,7 +221,8 @@ export default class DataModule extends BaseModule {
 		this.models = {
 			abc: await this.loadModel("abc"),
 			news: await this.loadModel("news"),
-			station: await this.loadModel("station")
+			session: await this.loadModel("session"),
+			station: await this.loadModel("station"),
 		};
 	}
 

+ 24 - 3
backend/src/modules/WebSocketModule.ts

@@ -89,6 +89,21 @@ export default class WebSocketModule extends BaseModule {
 
 		socket.log({ type: "debug", message: "WebSocket #ID connected" });
 
+		socket.setSocketId(request.headers["sec-websocket-key"]);
+
+		const sessionCookie = request.headers.cookie
+			?.split("; ")
+			.find(
+				cookie =>
+					cookie.substring(0, cookie.indexOf("=")) ===
+					config.get("cookie")
+			);
+		const sessionId = sessionCookie?.substring(
+			sessionCookie.indexOf("=") + 1,
+			sessionCookie.length
+		);
+		socket.setSessionId(sessionId);
+
 		socket.on("error", error =>
 			socket.log({
 				type: "error",
@@ -157,9 +172,15 @@ export default class WebSocketModule extends BaseModule {
 			const [moduleName, jobName] = moduleJob.split(".");
 			const { CB_REF } = options ?? payload ?? {};
 
-			await this.jobQueue
-				.runJob(moduleName, jobName, payload)
-				.then(res => socket.dispatch("CB_REF", CB_REF, res));
+			const res = await this.jobQueue.runJob("api", "runJob", {
+				moduleName,
+				jobName,
+				payload,
+				socketId: socket.getSocketId(),
+				sessionId: socket.getSessionId()
+			});
+
+			socket.dispatch("CB_REF", CB_REF, res);
 		} catch (error) {
 			const message = error?.message ?? error;
 

+ 20 - 0
backend/src/schemas/session.ts

@@ -0,0 +1,20 @@
+import { Model, Schema, SchemaTypes, Types } from "mongoose";
+import { BaseSchema } from "../types/Schemas";
+
+export interface SessionSchema extends BaseSchema {
+	userId: Types.ObjectId;
+	socketIds: string[];
+}
+
+export type SessionModel = Model<SessionSchema>;
+
+export const schema = new Schema<SessionSchema, SessionModel>({
+	userId: {
+		type: SchemaTypes.ObjectId,
+		ref: "user",
+		required: true
+	},
+	socketIds: [SchemaTypes.String]
+});
+
+export type SessionSchemaType = typeof schema;

+ 3 - 0
backend/src/types/JobOptions.ts

@@ -1,4 +1,7 @@
+import { SessionSchema } from "../schemas/session";
+
 export type JobOptions = {
 	priority?: number;
 	longJob?: string;
+	session?: SessionSchema;
 };

+ 2 - 0
backend/src/types/Models.ts

@@ -1,9 +1,11 @@
 import { AbcModel } from "../schemas/abc";
 import { NewsModel } from "../schemas/news";
+import { SessionModel } from "../schemas/session";
 import { StationModel } from "../schemas/station";
 
 export type Models = {
 	abc: AbcModel;
 	news: NewsModel;
+	session: SessionModel;
 	station: StationModel;
 };

+ 6 - 1
backend/src/types/Schemas.ts

@@ -1,10 +1,14 @@
+import { Types } from "mongoose";
 import { DocumentVersion } from "../schemas/plugins/documentVersion";
 import { AbcSchemaType } from "../schemas/abc";
 import { NewsSchemaType } from "../schemas/news";
+import { SessionSchemaType } from "../schemas/session";
 import { StationSchemaType } from "../schemas/station";
 
 // eslint-disable-next-line
-export interface BaseSchema extends DocumentVersion, TimestampsSchema {}
+export interface BaseSchema extends DocumentVersion, TimestampsSchema {
+	_id: Types.ObjectId;
+}
 
 export interface TimestampsSchema {
 	createdAt: number;
@@ -14,5 +18,6 @@ export interface TimestampsSchema {
 export type Schemas = {
 	abc: AbcSchemaType;
 	news: NewsSchemaType;
+	session: SessionSchemaType;
 	station: StationSchemaType;
 };