swaf/src/SessionWebSocketListener.ts

52 lines
1.8 KiB
TypeScript

import config from "config";
import cookie from "cookie";
import cookieParser from "cookie-parser";
import {Request} from "express";
import {Session} from "express-session";
import {IncomingMessage} from "http";
import {WebSocket} from "ws";
import Application from "./Application.js";
import RedisComponent from "./components/RedisComponent.js";
import {logger} from "./Logger.js";
import WebSocketListener from "./WebSocketListener.js";
export default abstract class SessionWebSocketListener<A extends Application> extends WebSocketListener<A> {
public async handle(socket: WebSocket, request: IncomingMessage): Promise<void> {
socket.once('message', (data, isBinary) => {
if (isBinary) return socket.close(1003);
const cookies = cookie.parse(data.toString());
const sid = cookieParser.signedCookie(cookies['connect.sid'], config.get('session.secret'));
if (!sid) {
socket.close(1002, 'Could not decrypt provided session cookie.');
return;
}
const store = this.getApp().as(RedisComponent).getStore();
store.get(sid, (err, session) => {
if (err || !session) {
logger.error(err, 'Error while initializing session in websocket for sid ' + sid);
socket.close(1011);
return;
}
session.id = sid;
store.createSession(<Request>request, session);
this.handleSessionSocket(socket, request, session as Session).catch(err => {
logger.error(err, 'Error in websocket listener.');
});
});
});
}
protected abstract handleSessionSocket(
socket: WebSocket,
request: IncomingMessage,
session: Session,
): Promise<void>;
}