Skip to content

Commit

Permalink
fix: iat can be in the future
Browse files Browse the repository at this point in the history
  • Loading branch information
szuperaz committed May 30, 2024
1 parent 73d1ced commit 7215826
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 43 deletions.
155 changes: 116 additions & 39 deletions __tests__/create-token.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import jwt from 'jsonwebtoken';
import { beforeAll, describe, expect, it } from 'vitest';
import { StreamClient } from '../src/StreamClient';
import { createTestClient } from './create-test-client';
import { beforeEach } from 'node:test';

Check failure on line 6 in __tests__/create-token.test.ts

View workflow job for this annotation

GitHub Actions / lint

'beforeEach' is defined but never used

const secret = process.env.STREAM_SECRET!;

Expand All @@ -14,51 +15,127 @@ describe('creating tokens', () => {
client = createTestClient();
});

it('with default expiration', () => {
const token = client.createToken(userId);
const decodedToken = jwt.verify(token, secret) as any;

expect(decodedToken.user_id).toBe(userId);
expect(
new Date(decodedToken.iat * 1000).getTime() -
(Date.now() + 60 * 60 * 1000),
).toBeLessThan(1000);
expect(
new Date(decodedToken.iat * 1000).getTime() - Date.now(),
).toBeLessThan(1000);
});
describe('user token', () => {
it('with default expiration', () => {
for (let i = 0; i < 5; i++) {
const token = client.createToken(userId);
const decodedToken = jwt.verify(token, secret) as any;
const now = Date.now();
const oneHour = 60 * 60 * 1000;
const oneSec = 1000;
const exp = new Date(decodedToken.exp * 1000).getTime();
const tokenValidity = exp - now;

it('with expiration provided', () => {
const exp = Math.round(new Date().getTime() / 1000) + 58 * 60;
const token = client.createToken(userId, exp);
const decodedToken = jwt.verify(token, secret) as any;
expect(decodedToken.user_id).toBe(userId);
expect(tokenValidity).toBeLessThanOrEqual(oneHour + oneSec);
expect(tokenValidity).toBeGreaterThanOrEqual(oneHour - oneSec);
}
});

expect(decodedToken.exp).toBe(exp);
});
it(`should make sure iat is correct`, () => {
for (let i = 0; i < 5; i++) {
const token = client.createToken(userId);
const decodedToken = jwt.verify(token, secret) as any;
const now = Date.now();
const nowMinus1sec = now - 1000;
const nowMinus2secs = now - 2000;
const iat = new Date(decodedToken.iat * 1000).getTime();

it('with call IDs provided', () => {
const call_cids = ['default:call1', 'livestream:call2'];
const token = client.createCallToken(userId, call_cids);
const decodedToken = jwt.verify(token, secret) as any;
expect(iat).toBeLessThanOrEqual(nowMinus1sec);
expect(iat).toBeGreaterThanOrEqual(nowMinus2secs);
}
});

it('with expiration provided', () => {
const exp = Math.round(new Date().getTime() / 1000) + 58 * 60;
const token = client.createToken(userId, exp);
const decodedToken = jwt.verify(token, secret) as any;

expect(decodedToken.exp).toBe(exp);
});

expect(decodedToken.user_id).toEqual(userId);
expect(decodedToken.call_cids).toEqual(call_cids);
expect(decodedToken.iat).toBeDefined();
expect(decodedToken.exp).toBeDefined();
it('with iat provided', () => {
const iat = Math.round(new Date().getTime() / 1000) + 60 * 60;
const token = client.createToken(userId, undefined, iat);
const decodedToken = jwt.verify(token, secret) as any;

expect(decodedToken.iat).toBe(iat);
expect(decodedToken.exp).toBeDefined();
});
});

it('with call IDs and role provided', () => {
describe('call token', () => {
const call_cids = ['default:call1', 'livestream:call2'];
const token = client.createCallToken(
{ user_id: userId, role: 'admin' },
call_cids,
);
const decodedToken = jwt.verify(token, secret) as any;

expect(decodedToken.call_cids).toEqual(call_cids);
expect(decodedToken.role).toEqual('admin');
expect(decodedToken.user_id).toEqual(userId);
expect(decodedToken.iat).toBeDefined();
expect(decodedToken.exp).toBeDefined();

it('with call IDs provided', () => {
const token = client.createCallToken(userId, call_cids);
const decodedToken = jwt.verify(token, secret) as any;

expect(decodedToken.user_id).toEqual(userId);
expect(decodedToken.call_cids).toEqual(call_cids);
expect(decodedToken.iat).toBeDefined();
expect(decodedToken.exp).toBeDefined();
});

it('with call IDs and role provided', () => {
const token = client.createCallToken(
{ user_id: userId, role: 'admin' },
call_cids,
);
const decodedToken = jwt.verify(token, secret) as any;

expect(decodedToken.call_cids).toEqual(call_cids);
expect(decodedToken.role).toEqual('admin');
expect(decodedToken.user_id).toEqual(userId);
expect(decodedToken.iat).toBeDefined();
expect(decodedToken.exp).toBeDefined();
});

it('with default expiration', () => {
for (let i = 0; i < 5; i++) {
const token = client.createCallToken(userId, call_cids);
const decodedToken = jwt.verify(token, secret) as any;
const now = Date.now();
const oneHour = 60 * 60 * 1000;
const oneSec = 1000;
const exp = new Date(decodedToken.exp * 1000).getTime();
const tokenValidity = exp - now;

expect(decodedToken.user_id).toBe(userId);
expect(tokenValidity).toBeLessThanOrEqual(oneHour + oneSec);
expect(tokenValidity).toBeGreaterThanOrEqual(oneHour - oneSec);
}
});

it(`should make sure iat is correct`, () => {
for (let i = 0; i < 5; i++) {
const token = client.createCallToken(userId, call_cids);
const decodedToken = jwt.verify(token, secret) as any;
const now = Date.now();
const nowMinus1sec = now - 1000;
const nowMinus2secs = now - 2000;
const iat = new Date(decodedToken.iat * 1000).getTime();

expect(iat).toBeLessThanOrEqual(nowMinus1sec);
expect(iat).toBeGreaterThanOrEqual(nowMinus2secs);
}
});

it('with expiration provided', () => {
const exp = Math.round(new Date().getTime() / 1000) + 58 * 60;
const token = client.createCallToken(userId, call_cids, exp);
const decodedToken = jwt.verify(token, secret) as any;

expect(decodedToken.exp).toBe(exp);
});

it('with iat provided', () => {
const iat = Math.round(new Date().getTime() / 1000) + 60 * 60;
const token = client.createCallToken(userId, call_cids, undefined, iat);
const decodedToken = jwt.verify(token, secret) as any;

expect(decodedToken.iat).toBe(iat);
expect(decodedToken.exp).toBeDefined();
});
});
});
8 changes: 4 additions & 4 deletions src/StreamClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,8 @@ export class StreamClient {
*/
createToken(
userID: string,
exp = Math.round(new Date().getTime() / 1000) + 60 * 60,
iat = Math.round(Date.now() / 1000),
exp = Math.round(Date.now() / 1000) + 60 * 60,
iat = Math.floor((Date.now() - 1000) / 1000),
call_cids?: string[],
) {
const payload: UserTokenPayload = {
Expand Down Expand Up @@ -169,8 +169,8 @@ export class StreamClient {
createCallToken(
userIdOrObject: string | { user_id: string; role?: string },
call_cids: string[],
exp = Math.round(new Date().getTime() / 1000) + 60 * 60,
iat = Math.round(Date.now() / 1000),
exp = Math.round(Date.now() / 1000) + 60 * 60,
iat = Math.floor((Date.now() - 1000) / 1000),
) {
const payload: CallTokenPayload = {
exp,
Expand Down

0 comments on commit 7215826

Please sign in to comment.