openvidu/backend/src/services/token.service.ts

96 lines
2.8 KiB
TypeScript

import { ParticipantOptions, ParticipantPermissions, ParticipantRole, RecordingPermissions, User } from '@typings-ce';
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';
@injectable()
export class TokenService {
constructor(@inject(LoggerService) protected logger: LoggerService) {}
async generateAccessToken(user: User): Promise<string> {
const tokenOptions: AccessTokenOptions = {
identity: user.username,
ttl: MEET_ACCESS_TOKEN_EXPIRATION,
metadata: JSON.stringify({
roles: user.roles
})
};
return await this.generateJwtToken(tokenOptions);
}
async generateRefreshToken(user: User): Promise<string> {
const tokenOptions: AccessTokenOptions = {
identity: user.username,
ttl: MEET_REFRESH_TOKEN_EXPIRATION,
metadata: JSON.stringify({
roles: user.roles
})
};
return await this.generateJwtToken(tokenOptions);
}
async generateParticipantToken(
participantOptions: ParticipantOptions,
permissions: ParticipantPermissions,
role: ParticipantRole
): Promise<string> {
const { roomId, participantName } = participantOptions;
this.logger.info(`Generating token for ${participantName} in room ${roomId}`);
const tokenOptions: AccessTokenOptions = {
identity: participantName,
name: participantName,
ttl: MEET_PARTICIPANT_TOKEN_EXPIRATION,
metadata: JSON.stringify({
livekitUrl: LIVEKIT_URL,
role,
permissions: permissions.openvidu
})
};
return await this.generateJwtToken(tokenOptions, permissions.livekit as VideoGrant);
}
async generateRecordingToken(
roomId: string,
role: ParticipantRole,
permissions: RecordingPermissions
): Promise<string> {
this.logger.info(`Generating recording token for room ${roomId}`);
const tokenOptions: AccessTokenOptions = {
ttl: MEET_RECORDING_TOKEN_EXPIRATION,
metadata: JSON.stringify({
role,
recordingPermissions: permissions
})
};
const grants: VideoGrant = {
room: roomId
};
return await this.generateJwtToken(tokenOptions, grants);
}
private async generateJwtToken(tokenOptions: AccessTokenOptions, grants?: VideoGrant): Promise<string> {
const at = new AccessToken(LIVEKIT_API_KEY, LIVEKIT_API_SECRET, tokenOptions);
if (grants) {
at.addGrant(grants);
}
return await at.toJwt();
}
async verifyToken(token: string): Promise<ClaimGrants> {
const verifyer = new TokenVerifier(LIVEKIT_API_KEY, LIVEKIT_API_SECRET);
return await verifyer.verify(token);
}
}