backend: Implement participant token handling with cookie management and validation middleware
This commit is contained in:
parent
e9882c19dc
commit
a692f8e37f
@ -5,6 +5,8 @@ import { TokenOptions } from '@typings-ce';
|
|||||||
import { OpenViduMeetError } from '../models/index.js';
|
import { OpenViduMeetError } from '../models/index.js';
|
||||||
import { ParticipantService } from '../services/participant.service.js';
|
import { ParticipantService } from '../services/participant.service.js';
|
||||||
import { RoomService } from '../services/room.service.js';
|
import { RoomService } from '../services/room.service.js';
|
||||||
|
import { MEET_PARTICIPANT_TOKEN_EXPIRATION, PARTICIPANT_TOKEN_COOKIE_NAME } from '../environment.js';
|
||||||
|
import { getCookieOptions } from '../utils/cookie-utils.js';
|
||||||
|
|
||||||
export const generateParticipantToken = async (req: Request, res: Response) => {
|
export const generateParticipantToken = async (req: Request, res: Response) => {
|
||||||
const logger = container.get(LoggerService);
|
const logger = container.get(LoggerService);
|
||||||
@ -28,8 +30,7 @@ export const generateParticipantToken = async (req: Request, res: Response) => {
|
|||||||
const secretRole = await roomService.getRoomSecretRole(roomName, secret);
|
const secretRole = await roomService.getRoomSecretRole(roomName, secret);
|
||||||
const token = await participantService.generateParticipantToken(secretRole, tokenOptions);
|
const token = await participantService.generateParticipantToken(secretRole, tokenOptions);
|
||||||
|
|
||||||
// TODO: Set the participant token in a cookie
|
res.cookie(PARTICIPANT_TOKEN_COOKIE_NAME, token, getCookieOptions('/', MEET_PARTICIPANT_TOKEN_EXPIRATION));
|
||||||
// res.cookie('ovParticipantToken', token, { httpOnly: true, expires: tokenTtl });
|
|
||||||
|
|
||||||
logger.verbose(`Participant token generated for room ${roomName}`);
|
logger.verbose(`Participant token generated for room ${roomName}`);
|
||||||
return res.status(200).json({ token });
|
return res.status(200).json({ token });
|
||||||
|
|||||||
@ -19,10 +19,11 @@ export const {
|
|||||||
MEET_SECRET = 'user',
|
MEET_SECRET = 'user',
|
||||||
MEET_ADMIN_USER = 'admin',
|
MEET_ADMIN_USER = 'admin',
|
||||||
MEET_ADMIN_SECRET = 'admin',
|
MEET_ADMIN_SECRET = 'admin',
|
||||||
|
MEET_PARTICIPANT_TOKEN_EXPIRATION = '6h',
|
||||||
MEET_ACCESS_TOKEN_EXPIRATION = '2h',
|
MEET_ACCESS_TOKEN_EXPIRATION = '2h',
|
||||||
MEET_REFRESH_TOKEN_EXPIRATION = '1d',
|
MEET_REFRESH_TOKEN_EXPIRATION = '1d',
|
||||||
MEET_PREFERENCES_STORAGE_MODE = 's3',
|
MEET_PREFERENCES_STORAGE_MODE = 's3',
|
||||||
MEET_WEBHOOK_ENABLED = 'true',
|
MEET_WEBHOOK_ENABLED = 'false',
|
||||||
MEET_WEBHOOK_URL = 'http://localhost:5080/webhook',
|
MEET_WEBHOOK_URL = 'http://localhost:5080/webhook',
|
||||||
MEET_LOG_LEVEL = 'info',
|
MEET_LOG_LEVEL = 'info',
|
||||||
|
|
||||||
@ -60,6 +61,7 @@ export const {
|
|||||||
|
|
||||||
export const MEET_API_BASE_PATH = '/meet/api';
|
export const MEET_API_BASE_PATH = '/meet/api';
|
||||||
export const MEET_API_BASE_PATH_V1 = MEET_API_BASE_PATH + '/v1';
|
export const MEET_API_BASE_PATH_V1 = MEET_API_BASE_PATH + '/v1';
|
||||||
|
export const PARTICIPANT_TOKEN_COOKIE_NAME = 'OvMeetParticipantToken';
|
||||||
export const ACCESS_TOKEN_COOKIE_NAME = 'OvMeetAccessToken';
|
export const ACCESS_TOKEN_COOKIE_NAME = 'OvMeetAccessToken';
|
||||||
export const REFRESH_TOKEN_COOKIE_NAME = 'OvMeetRefreshToken';
|
export const REFRESH_TOKEN_COOKIE_NAME = 'OvMeetRefreshToken';
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,8 @@ import {
|
|||||||
MEET_API_KEY,
|
MEET_API_KEY,
|
||||||
MEET_PRIVATE_ACCESS,
|
MEET_PRIVATE_ACCESS,
|
||||||
MEET_SECRET,
|
MEET_SECRET,
|
||||||
MEET_USER
|
MEET_USER,
|
||||||
|
PARTICIPANT_TOKEN_COOKIE_NAME
|
||||||
} from '../environment.js';
|
} from '../environment.js';
|
||||||
import { container } from '../config/dependency-injector.config.js';
|
import { container } from '../config/dependency-injector.config.js';
|
||||||
|
|
||||||
@ -35,6 +36,31 @@ export const withAdminValidToken = async (req: Request, res: Response, next: Nex
|
|||||||
next();
|
next();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const withParticipantValidToken = async (req: Request, res: Response, next: NextFunction) => {
|
||||||
|
const token = req.cookies[PARTICIPANT_TOKEN_COOKIE_NAME];
|
||||||
|
|
||||||
|
if (!token) {
|
||||||
|
return res.status(401).json({ message: 'Unauthorized' });
|
||||||
|
}
|
||||||
|
|
||||||
|
const tokenService = container.get(TokenService);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const payload = await tokenService.verifyToken(token);
|
||||||
|
|
||||||
|
// Parse metadata if it exists and add payload to request body for further processing
|
||||||
|
if (payload.metadata) {
|
||||||
|
payload.metadata = JSON.parse(payload.metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
req.body.payload = payload;
|
||||||
|
} catch (error) {
|
||||||
|
return res.status(401).json({ message: 'Invalid token' });
|
||||||
|
}
|
||||||
|
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
|
||||||
export const withValidApiKey = async (req: Request, res: Response, next: NextFunction) => {
|
export const withValidApiKey = async (req: Request, res: Response, next: NextFunction) => {
|
||||||
const apiKey = req.headers['x-api-key'];
|
const apiKey = req.headers['x-api-key'];
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,13 @@ import {
|
|||||||
SendDataOptions,
|
SendDataOptions,
|
||||||
StreamOutput
|
StreamOutput
|
||||||
} from 'livekit-server-sdk';
|
} from 'livekit-server-sdk';
|
||||||
import { LIVEKIT_API_KEY, LIVEKIT_API_SECRET, LIVEKIT_URL, LIVEKIT_URL_PRIVATE } from '../environment.js';
|
import {
|
||||||
|
LIVEKIT_API_KEY,
|
||||||
|
LIVEKIT_API_SECRET,
|
||||||
|
LIVEKIT_URL,
|
||||||
|
LIVEKIT_URL_PRIVATE,
|
||||||
|
MEET_PARTICIPANT_TOKEN_EXPIRATION
|
||||||
|
} from '../environment.js';
|
||||||
import { LoggerService } from './logger.service.js';
|
import { LoggerService } from './logger.service.js';
|
||||||
import {
|
import {
|
||||||
errorLivekitIsNotAvailable,
|
errorLivekitIsNotAvailable,
|
||||||
@ -142,7 +148,7 @@ export class LiveKitService {
|
|||||||
const at = new AccessToken(LIVEKIT_API_KEY, LIVEKIT_API_SECRET, {
|
const at = new AccessToken(LIVEKIT_API_KEY, LIVEKIT_API_SECRET, {
|
||||||
identity: participantName,
|
identity: participantName,
|
||||||
name: participantName,
|
name: participantName,
|
||||||
ttl: '24h',
|
ttl: MEET_PARTICIPANT_TOKEN_EXPIRATION,
|
||||||
metadata: JSON.stringify({
|
metadata: JSON.stringify({
|
||||||
livekitUrl: LIVEKIT_URL,
|
livekitUrl: LIVEKIT_URL,
|
||||||
role,
|
role,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user