backend: refactor token expiration handling to use internal configuration constants

This commit is contained in:
juancarmore 2025-07-11 12:04:12 +02:00
parent 6dd074df57
commit 98de6fe0e8
5 changed files with 21 additions and 29 deletions

View File

@ -11,6 +11,12 @@ const INTERNAL_CONFIG = {
PARTICIPANT_TOKEN_COOKIE_NAME: 'OvMeetParticipantToken', PARTICIPANT_TOKEN_COOKIE_NAME: 'OvMeetParticipantToken',
RECORDING_TOKEN_COOKIE_NAME: 'OvMeetRecordingToken', RECORDING_TOKEN_COOKIE_NAME: 'OvMeetRecordingToken',
// Token expiration times
ACCESS_TOKEN_EXPIRATION: '2h',
REFRESH_TOKEN_EXPIRATION: '1d',
PARTICIPANT_TOKEN_EXPIRATION: '2h',
RECORDING_TOKEN_EXPIRATION: '2h',
// Headers for API requests // Headers for API requests
API_KEY_HEADER: 'x-api-key', API_KEY_HEADER: 'x-api-key',
PARTICIPANT_ROLE_HEADER: 'x-participant-role', PARTICIPANT_ROLE_HEADER: 'x-participant-role',

View File

@ -2,7 +2,6 @@ import { Request, Response } from 'express';
import { ClaimGrants } from 'livekit-server-sdk'; import { ClaimGrants } from 'livekit-server-sdk';
import { container } from '../config/index.js'; import { container } from '../config/index.js';
import INTERNAL_CONFIG from '../config/internal-config.js'; import INTERNAL_CONFIG from '../config/internal-config.js';
import { MEET_ACCESS_TOKEN_EXPIRATION, MEET_REFRESH_TOKEN_EXPIRATION } from '../environment.js';
import { import {
errorInvalidCredentials, errorInvalidCredentials,
errorInvalidRefreshToken, errorInvalidRefreshToken,
@ -35,12 +34,15 @@ export const login = async (req: Request, res: Response) => {
res.cookie( res.cookie(
INTERNAL_CONFIG.ACCESS_TOKEN_COOKIE_NAME, INTERNAL_CONFIG.ACCESS_TOKEN_COOKIE_NAME,
accessToken, accessToken,
getCookieOptions('/', MEET_ACCESS_TOKEN_EXPIRATION) getCookieOptions('/', INTERNAL_CONFIG.ACCESS_TOKEN_EXPIRATION)
); );
res.cookie( res.cookie(
INTERNAL_CONFIG.REFRESH_TOKEN_COOKIE_NAME, INTERNAL_CONFIG.REFRESH_TOKEN_COOKIE_NAME,
refreshToken, refreshToken,
getCookieOptions(`${INTERNAL_CONFIG.INTERNAL_API_BASE_PATH_V1}/auth`, MEET_REFRESH_TOKEN_EXPIRATION) getCookieOptions(
`${INTERNAL_CONFIG.INTERNAL_API_BASE_PATH_V1}/auth`,
INTERNAL_CONFIG.REFRESH_TOKEN_EXPIRATION
)
); );
logger.info(`Login succeeded for user '${username}'`); logger.info(`Login succeeded for user '${username}'`);
return res.status(200).json({ message: 'Login succeeded' }); return res.status(200).json({ message: 'Login succeeded' });
@ -94,7 +96,7 @@ export const refreshToken = async (req: Request, res: Response) => {
res.cookie( res.cookie(
INTERNAL_CONFIG.ACCESS_TOKEN_COOKIE_NAME, INTERNAL_CONFIG.ACCESS_TOKEN_COOKIE_NAME,
accessToken, accessToken,
getCookieOptions('/', MEET_ACCESS_TOKEN_EXPIRATION) getCookieOptions('/', INTERNAL_CONFIG.ACCESS_TOKEN_EXPIRATION)
); );
logger.info(`Token refreshed for user ${username}`); logger.info(`Token refreshed for user ${username}`);
return res.status(200).json({ message: 'Token refreshed' }); return res.status(200).json({ message: 'Token refreshed' });

View File

@ -2,7 +2,6 @@ import { MeetRoomFilters, MeetRoomOptions, MeetRoomRoleAndPermissions, Participa
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import { container } from '../config/index.js'; import { container } from '../config/index.js';
import INTERNAL_CONFIG from '../config/internal-config.js'; import INTERNAL_CONFIG from '../config/internal-config.js';
import { MEET_RECORDING_TOKEN_EXPIRATION } from '../environment.js';
import { handleError } from '../models/error.model.js'; import { handleError } from '../models/error.model.js';
import { LoggerService, ParticipantService, RoomService } from '../services/index.js'; import { LoggerService, ParticipantService, RoomService } from '../services/index.js';
import { getCookieOptions } from '../utils/cookie-utils.js'; import { getCookieOptions } from '../utils/cookie-utils.js';
@ -149,7 +148,7 @@ export const generateRecordingToken = async (req: Request, res: Response) => {
res.cookie( res.cookie(
INTERNAL_CONFIG.RECORDING_TOKEN_COOKIE_NAME, INTERNAL_CONFIG.RECORDING_TOKEN_COOKIE_NAME,
token, token,
getCookieOptions('/', MEET_RECORDING_TOKEN_EXPIRATION) getCookieOptions('/', INTERNAL_CONFIG.RECORDING_TOKEN_EXPIRATION)
); );
return res.status(200).json({ token }); return res.status(200).json({ token });
} catch (error) { } catch (error) {

View File

@ -32,12 +32,6 @@ export const {
MEET_ADMIN_SECRET = 'admin', MEET_ADMIN_SECRET = 'admin',
MEET_COOKIE_SECURE = 'false', MEET_COOKIE_SECURE = 'false',
// Token expiration times
MEET_ACCESS_TOKEN_EXPIRATION = '2h',
MEET_REFRESH_TOKEN_EXPIRATION = '1d',
MEET_PARTICIPANT_TOKEN_EXPIRATION = '2h',
MEET_RECORDING_TOKEN_EXPIRATION = '2h',
/** /**
* Webhook configuration * Webhook configuration
* *
@ -115,8 +109,6 @@ export const logEnvVars = () => {
console.log('MEET API KEY: ', credential('****' + MEET_API_KEY.slice(-3))); console.log('MEET API KEY: ', credential('****' + MEET_API_KEY.slice(-3)));
console.log('MEET ADMIN USER: ', credential('****' + MEET_ADMIN_USER.slice(-3))); console.log('MEET ADMIN USER: ', credential('****' + MEET_ADMIN_USER.slice(-3)));
console.log('MEET ADMIN PASSWORD: ', credential('****' + MEET_ADMIN_SECRET.slice(-3))); console.log('MEET ADMIN PASSWORD: ', credential('****' + MEET_ADMIN_SECRET.slice(-3)));
console.log('MEET ACCESS TOKEN EXPIRATION: ', text(MEET_ACCESS_TOKEN_EXPIRATION));
console.log('MEET REFRESH TOKEN EXPIRATION: ', text(MEET_REFRESH_TOKEN_EXPIRATION));
console.log('MEET PREFERENCES STORAGE:', text(MEET_PREFERENCES_STORAGE_MODE)); console.log('MEET PREFERENCES STORAGE:', text(MEET_PREFERENCES_STORAGE_MODE));
console.log('MEET_WEBHOOK_ENABLED:', text(MEET_WEBHOOK_ENABLED)); console.log('MEET_WEBHOOK_ENABLED:', text(MEET_WEBHOOK_ENABLED));

View File

@ -7,18 +7,11 @@ import {
User User
} from '@typings-ce'; } from '@typings-ce';
import { inject, injectable } from 'inversify'; import { inject, injectable } from 'inversify';
import { AccessToken, AccessTokenOptions, ClaimGrants, TokenVerifier, VideoGrant } from 'livekit-server-sdk';
import {
LIVEKIT_API_KEY,
LIVEKIT_API_SECRET,
LIVEKIT_URL,
MEET_ACCESS_TOKEN_EXPIRATION,
MEET_PARTICIPANT_TOKEN_EXPIRATION,
MEET_RECORDING_TOKEN_EXPIRATION,
MEET_REFRESH_TOKEN_EXPIRATION
} from '../environment.js';
import { LoggerService } from './index.js';
import { jwtDecode } from 'jwt-decode'; import { jwtDecode } from 'jwt-decode';
import { AccessToken, AccessTokenOptions, ClaimGrants, TokenVerifier, VideoGrant } from 'livekit-server-sdk';
import INTERNAL_CONFIG from '../config/internal-config.js';
import { LIVEKIT_API_KEY, LIVEKIT_API_SECRET, LIVEKIT_URL } from '../environment.js';
import { LoggerService } from './index.js';
@injectable() @injectable()
export class TokenService { export class TokenService {
@ -27,7 +20,7 @@ export class TokenService {
async generateAccessToken(user: User): Promise<string> { async generateAccessToken(user: User): Promise<string> {
const tokenOptions: AccessTokenOptions = { const tokenOptions: AccessTokenOptions = {
identity: user.username, identity: user.username,
ttl: MEET_ACCESS_TOKEN_EXPIRATION, ttl: INTERNAL_CONFIG.ACCESS_TOKEN_EXPIRATION,
metadata: JSON.stringify({ metadata: JSON.stringify({
roles: user.roles roles: user.roles
}) })
@ -38,7 +31,7 @@ export class TokenService {
async generateRefreshToken(user: User): Promise<string> { async generateRefreshToken(user: User): Promise<string> {
const tokenOptions: AccessTokenOptions = { const tokenOptions: AccessTokenOptions = {
identity: user.username, identity: user.username,
ttl: MEET_REFRESH_TOKEN_EXPIRATION, ttl: INTERNAL_CONFIG.REFRESH_TOKEN_EXPIRATION,
metadata: JSON.stringify({ metadata: JSON.stringify({
roles: user.roles roles: user.roles
}) })
@ -57,7 +50,7 @@ export class TokenService {
const tokenOptions: AccessTokenOptions = { const tokenOptions: AccessTokenOptions = {
identity: participantName, identity: participantName,
name: participantName, name: participantName,
ttl: MEET_PARTICIPANT_TOKEN_EXPIRATION, ttl: INTERNAL_CONFIG.PARTICIPANT_TOKEN_EXPIRATION,
metadata: JSON.stringify({ metadata: JSON.stringify({
livekitUrl: LIVEKIT_URL, livekitUrl: LIVEKIT_URL,
roles roles
@ -73,7 +66,7 @@ export class TokenService {
): Promise<string> { ): Promise<string> {
this.logger.info(`Generating recording token for room ${roomId}`); this.logger.info(`Generating recording token for room ${roomId}`);
const tokenOptions: AccessTokenOptions = { const tokenOptions: AccessTokenOptions = {
ttl: MEET_RECORDING_TOKEN_EXPIRATION, ttl: INTERNAL_CONFIG.RECORDING_TOKEN_EXPIRATION,
metadata: JSON.stringify({ metadata: JSON.stringify({
role, role,
recordingPermissions: permissions recordingPermissions: permissions