livekit-server-sdk
Version:
Server-side SDK for LiveKit
151 lines (126 loc) • 4.7 kB
text/typescript
// SPDX-FileCopyrightText: 2024 LiveKit, Inc.
//
// SPDX-License-Identifier: Apache-2.0
import {
RoomAgentDispatch,
RoomCompositeEgressRequest,
RoomConfiguration,
RoomEgress,
} from '@livekit/protocol';
import * as jose from 'jose';
import { describe, expect, it } from 'vitest';
import { AccessToken, TokenVerifier } from './AccessToken.js';
import type { ClaimGrants } from './grants.js';
const testApiKey = 'abcdefg';
const testSecret = 'abababa';
describe('encoded tokens are valid', () => {
const t = new AccessToken(testApiKey, testSecret, {
identity: 'me',
name: 'myname',
});
t.addGrant({ room: 'myroom' });
const EncodedTestSecret = new TextEncoder().encode(testSecret);
it('can be decoded', async () => {
const { payload } = await jose.jwtVerify(await t.toJwt(), EncodedTestSecret, {
issuer: testApiKey,
});
expect(payload).not.toBe(undefined);
});
it('has name set', async () => {
const { payload } = await jose.jwtVerify(await t.toJwt(), EncodedTestSecret, {
issuer: testApiKey,
});
expect(payload.name).toBe('myname');
});
it('has video grants set', async () => {
const { payload } = await jose.jwtVerify(await t.toJwt(), EncodedTestSecret, {
issuer: testApiKey,
});
expect(payload.video).toBeTruthy();
expect((payload as ClaimGrants).video?.room).toEqual('myroom');
});
});
describe('identity is required for only join grants', () => {
it('allows empty identity for create', async () => {
const t = new AccessToken(testApiKey, testSecret);
t.addGrant({ roomCreate: true });
expect(await t.toJwt()).toBeTruthy();
});
it('throws error when identity is not provided for join', async () => {
const t = new AccessToken(testApiKey, testSecret);
t.addGrant({ roomJoin: true });
await expect(t.toJwt()).rejects.toThrow();
});
});
describe('verify token is valid', () => {
it('can decode encoded token', async () => {
const t = new AccessToken(testApiKey, testSecret);
t.sha256 = 'abcdefg';
t.kind = 'agent';
t.addGrant({ roomCreate: true });
t.attributes = { foo: 'bar', live: 'kit' };
const v = new TokenVerifier(testApiKey, testSecret);
const decoded = await v.verify(await t.toJwt());
expect(decoded).not.toBe(undefined);
expect(decoded.sha256).toEqual('abcdefg');
expect(decoded.video?.roomCreate).toBeTruthy();
expect(decoded.kind).toEqual('agent');
expect(decoded.attributes).toEqual(t.attributes);
});
});
describe('adding grants should not overwrite existing grants', () => {
const EncodedTestSecret = new TextEncoder().encode(testSecret);
it('should not overwrite existing grants', async () => {
const t = new AccessToken(testApiKey, testSecret, {
identity: 'me',
name: 'myname',
});
t.addGrant({ roomCreate: true });
t.addGrant({ roomJoin: true });
const { payload }: jose.JWTVerifyResult<ClaimGrants> = await jose.jwtVerify(
await t.toJwt(),
EncodedTestSecret,
{ issuer: testApiKey },
);
expect(payload.video?.roomCreate).toBeTruthy();
expect(payload.video?.roomJoin).toBeTruthy();
});
});
describe('room configuration with agents and egress', () => {
it('should set agents and egress in room configuration', async () => {
const t = new AccessToken(testApiKey, testSecret, {
identity: 'test-identity',
});
const roomConfig = new RoomConfiguration({
name: 'test-room',
maxParticipants: 10,
});
const agents: RoomAgentDispatch[] = [
new RoomAgentDispatch({
agentName: 'agent1',
metadata: 'metadata-1',
}),
new RoomAgentDispatch({
agentName: 'agent2',
metadata: 'metadata-2',
}),
];
const egress = new RoomEgress({
room: new RoomCompositeEgressRequest({ roomName: 'test-room' }),
});
roomConfig.agents = agents;
roomConfig.egress = egress;
t.roomConfig = roomConfig;
const v = new TokenVerifier(testApiKey, testSecret);
const decoded = await v.verify(await t.toJwt());
expect(decoded.roomConfig).toBeDefined();
expect(decoded.roomConfig?.name).toEqual('test-room');
expect(decoded.roomConfig?.maxParticipants).toEqual(10);
expect(decoded.roomConfig?.agents).toHaveLength(2);
expect(decoded.roomConfig?.agents?.[0]?.agentName).toEqual('agent1');
expect(decoded.roomConfig?.agents?.[0]?.metadata).toEqual('metadata-1');
expect(decoded.roomConfig?.agents?.[1]?.agentName).toEqual('agent2');
expect(decoded.roomConfig?.agents?.[1]?.metadata).toEqual('metadata-2');
expect(decoded.roomConfig?.egress?.room?.roomName).toEqual('test-room');
});
});