mirror of
https://github.com/cpvalente/ontime.git
synced 2026-07-26 10:38:55 +00:00
refactor: create fast tracks for cookie parsing
This commit is contained in:
committed by
Carlos Valente
parent
3b38756dda
commit
3c41b40c5f
@@ -1,5 +1,3 @@
|
||||
import { LogOrigin } from 'ontime-types';
|
||||
|
||||
import express, { type Request, type Response, type NextFunction } from 'express';
|
||||
import type { IncomingMessage } from 'node:http';
|
||||
import type { WebSocket } from 'ws';
|
||||
@@ -7,7 +5,6 @@ import { parse as parseCookie } from 'cookie';
|
||||
|
||||
import { hashPassword } from '../utils/hash.js';
|
||||
import { srcFiles } from '../setup/index.js';
|
||||
import { logger } from '../classes/Logger.js';
|
||||
import { hashedPassword, hasPassword } from '../api-data/session/session.service.js';
|
||||
|
||||
import { noopMiddleware } from './noop.js';
|
||||
@@ -53,6 +50,9 @@ export function makeAuthenticateMiddleware(prefix: string) {
|
||||
return { authenticate: noopMiddleware, authenticateAndRedirect: noopMiddleware };
|
||||
}
|
||||
|
||||
// pre-compute the login redirect base URL to avoid string concatenation on every request
|
||||
const loginRedirectBase = `${prefix}/login?redirect=`;
|
||||
|
||||
function authenticate(req: Request, res: Response, next: NextFunction) {
|
||||
if (req.query.token) {
|
||||
if (req.query.token === hashedPassword) {
|
||||
@@ -98,7 +98,7 @@ export function makeAuthenticateMiddleware(prefix: string) {
|
||||
return next();
|
||||
}
|
||||
|
||||
res.redirect(`${prefix}/login?redirect=${req.originalUrl}`);
|
||||
res.redirect(loginRedirectBase + req.originalUrl);
|
||||
}
|
||||
|
||||
return { authenticate, authenticateAndRedirect };
|
||||
@@ -124,14 +124,23 @@ export function authenticateSocket(_ws: WebSocket, req: IncomingMessage, next: (
|
||||
}
|
||||
}
|
||||
|
||||
// check if token is in the params
|
||||
const url = new URL(req.url || '', `http://${req.headers.host}`);
|
||||
const token = url.searchParams.get('token');
|
||||
if (token === hashedPassword) {
|
||||
// check if token is in the params - simple string check first
|
||||
const urlString = req.url || '';
|
||||
if (urlString.includes(`token=${hashedPassword}`)) {
|
||||
return next();
|
||||
}
|
||||
|
||||
logger.warning(LogOrigin.Client, 'Unauthorized WebSocket connection attempt');
|
||||
// fallback to full URL parsing for other formats
|
||||
try {
|
||||
const url = new URL(urlString, `http://${req.headers.host}`);
|
||||
const token = url.searchParams.get('token');
|
||||
if (token === hashedPassword) {
|
||||
return next();
|
||||
}
|
||||
} catch (_) {
|
||||
// ignore URL parsing errors
|
||||
}
|
||||
|
||||
return next(new Error('Unauthorized'));
|
||||
}
|
||||
|
||||
@@ -153,6 +162,14 @@ function setSessionCookie(res: Response, token: string) {
|
||||
* And want to extract its value
|
||||
*/
|
||||
function getTokenFromCookie(cookieContents: string): string | undefined {
|
||||
// Fast path: check if the hashed password is directly in the cookie string
|
||||
// This avoids JSON parsing for the common case
|
||||
const cookieTokenString = '"token":"' + hashedPassword + '}"';
|
||||
if (cookieTokenString && cookieContents.includes(cookieTokenString)) {
|
||||
return hashedPassword;
|
||||
}
|
||||
|
||||
// Fallback to JSON parsing for other cases or validation
|
||||
try {
|
||||
const cookie = JSON.parse(cookieContents);
|
||||
if (cookie && typeof cookie.token === 'string') {
|
||||
|
||||
Reference in New Issue
Block a user