diff --git a/__tests__/create-token.test.ts b/__tests__/create-token.test.ts index 5a25dc4..2fb65d4 100644 --- a/__tests__/create-token.test.ts +++ b/__tests__/create-token.test.ts @@ -58,6 +58,26 @@ describe('creating tokens', () => { } }); + it('should not encode validity_in_seconds in the payload', () => { + const token = client.generateUserToken({ + user_id: userId, + validity_in_seconds: 120, + }); + const decodedToken = jwt.verify(token, secret) as any; + + expect(decodedToken).not.toHaveProperty('validity_in_seconds'); + expect(Object.keys(decodedToken).sort()).toEqual( + ['exp', 'iat', 'user_id'].sort(), + ); + }); + + it('should not mutate the provided payload', () => { + const payload = { user_id: userId, validity_in_seconds: 120 }; + client.generateUserToken(payload); + + expect(payload).toEqual({ user_id: userId, validity_in_seconds: 120 }); + }); + it(`should make sure iat is correct`, () => { for (let i = 0; i < 5; i++) { const token = client.generateUserToken({ user_id: userId }); @@ -118,6 +138,18 @@ describe('creating tokens', () => { expect(decodedToken.exp).toBeDefined(); }); + it('should not encode validity_in_seconds in the payload', () => { + const token = client.generateCallToken({ + user_id: userId, + call_cids, + validity_in_seconds: 120, + }); + const decodedToken = jwt.verify(token, secret) as any; + + expect(decodedToken).not.toHaveProperty('validity_in_seconds'); + expect(decodedToken.exp - decodedToken.iat).toBe(120); + }); + it('with default expiration', () => { for (let i = 0; i < 5; i++) { const token = client.generateCallToken({ user_id: userId, call_cids }); diff --git a/src/StreamClient.ts b/src/StreamClient.ts index 1cd8efb..f38ac43 100644 --- a/src/StreamClient.ts +++ b/src/StreamClient.ts @@ -133,12 +133,17 @@ export class StreamClient extends CommonApi { iat?: number; } & Record, ) => { + // validity_in_seconds is only used to compute exp, don't encode it + const { validity_in_seconds, ...claims } = payload; const defaultIat = Math.floor((Date.now() - 1000) / 1000); - payload.iat = payload.iat ?? defaultIat; - const validityInSeconds = payload.validity_in_seconds ?? 60 * 60; - payload.exp = payload.exp ?? payload.iat + validityInSeconds; + const iat = claims.iat ?? defaultIat; + const exp = claims.exp ?? iat + (validity_in_seconds ?? 60 * 60); - return JWTUserToken(this.secret, payload as UserTokenPayload); + return JWTUserToken(this.secret, { + ...claims, + iat, + exp, + } as UserTokenPayload); }; /** @@ -154,9 +159,11 @@ export class StreamClient extends CommonApi { } & Record, ) => { const defaultIat = Math.floor((Date.now() - 1000) / 1000); - payload.iat = payload.iat ?? defaultIat; - return JWTUserToken(this.secret, payload as UserTokenPayload); + return JWTUserToken(this.secret, { + ...payload, + iat: payload.iat ?? defaultIat, + } as UserTokenPayload); }; /**