From 6efd336f3407e7204a0c5d385ea9df5c02c7e5f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karol=20S=C3=B3jko?= Date: Thu, 22 Sep 2022 16:24:23 +0200 Subject: [PATCH] fix(auth): subscription token ttl --- .../Domain/Subscription/SubscriptionToken.ts | 2 +- .../CreateSubscriptionToken.spec.ts | 10 ++------ .../CreateSubscriptionToken.ts | 4 +--- .../RedisSubscriptionTokenRepository.spec.ts | 24 ++++++------------- .../Redis/RedisSubscriptionTokenRepository.ts | 12 +++------- 5 files changed, 14 insertions(+), 38 deletions(-) diff --git a/packages/auth/src/Domain/Subscription/SubscriptionToken.ts b/packages/auth/src/Domain/Subscription/SubscriptionToken.ts index f069483ee..b2d4c0dd5 100644 --- a/packages/auth/src/Domain/Subscription/SubscriptionToken.ts +++ b/packages/auth/src/Domain/Subscription/SubscriptionToken.ts @@ -1,5 +1,5 @@ export type SubscriptionToken = { userUuid: string token: string - expiresAt: number + ttl: number } diff --git a/packages/auth/src/Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionToken.spec.ts b/packages/auth/src/Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionToken.spec.ts index 613981cc2..aa4992078 100644 --- a/packages/auth/src/Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionToken.spec.ts +++ b/packages/auth/src/Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionToken.spec.ts @@ -1,7 +1,6 @@ import 'reflect-metadata' import { CryptoNode } from '@standardnotes/sncrypto-node' -import { TimerInterface } from '@standardnotes/time' import { SubscriptionTokenRepositoryInterface } from '../../Subscription/SubscriptionTokenRepositoryInterface' import { CreateSubscriptionToken } from './CreateSubscriptionToken' @@ -10,10 +9,9 @@ import { Logger } from 'winston' describe('CreateSubscriptionToken', () => { let subscriptionTokenRepository: SubscriptionTokenRepositoryInterface let cryptoNode: CryptoNode - let timer: TimerInterface let logger: Logger - const createUseCase = () => new CreateSubscriptionToken(subscriptionTokenRepository, cryptoNode, timer, logger) + const createUseCase = () => new CreateSubscriptionToken(subscriptionTokenRepository, cryptoNode, logger) beforeEach(() => { subscriptionTokenRepository = {} as jest.Mocked @@ -22,10 +20,6 @@ describe('CreateSubscriptionToken', () => { cryptoNode = {} as jest.Mocked cryptoNode.generateRandomKey = jest.fn().mockReturnValueOnce('random-string') - timer = {} as jest.Mocked - timer.convertStringDateToMicroseconds = jest.fn().mockReturnValue(1) - timer.getUTCDateNHoursAhead = jest.fn().mockReturnValue(new Date(1)) - logger = {} as jest.Mocked logger.error = jest.fn() }) @@ -38,7 +32,7 @@ describe('CreateSubscriptionToken', () => { expect(subscriptionTokenRepository.save).toHaveBeenCalledWith({ userUuid: '1-2-3', token: 'random-string', - expiresAt: 1, + ttl: 10_800, }) }) diff --git a/packages/auth/src/Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionToken.ts b/packages/auth/src/Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionToken.ts index 5b2492cfd..6d3a06784 100644 --- a/packages/auth/src/Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionToken.ts +++ b/packages/auth/src/Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionToken.ts @@ -1,5 +1,4 @@ import { CryptoNode } from '@standardnotes/sncrypto-node' -import { TimerInterface } from '@standardnotes/time' import { inject, injectable } from 'inversify' import { Logger } from 'winston' @@ -15,7 +14,6 @@ export class CreateSubscriptionToken implements UseCaseInterface { @inject(TYPES.SubscriptionTokenRepository) private subscriptionTokenRepository: SubscriptionTokenRepositoryInterface, @inject(TYPES.CryptoNode) private cryptoNode: CryptoNode, - @inject(TYPES.Timer) private timer: TimerInterface, @inject(TYPES.Logger) private logger: Logger, ) {} @@ -25,7 +23,7 @@ export class CreateSubscriptionToken implements UseCaseInterface { const subscriptionToken = { userUuid: dto.userUuid, token, - expiresAt: this.timer.convertStringDateToMicroseconds(this.timer.getUTCDateNHoursAhead(3).toString()), + ttl: 10_800, } const subscriptionTokenWasSaved = await this.subscriptionTokenRepository.save(subscriptionToken) diff --git a/packages/auth/src/Infra/Redis/RedisSubscriptionTokenRepository.spec.ts b/packages/auth/src/Infra/Redis/RedisSubscriptionTokenRepository.spec.ts index c7a68790b..a19b33b8f 100644 --- a/packages/auth/src/Infra/Redis/RedisSubscriptionTokenRepository.spec.ts +++ b/packages/auth/src/Infra/Redis/RedisSubscriptionTokenRepository.spec.ts @@ -1,25 +1,19 @@ import 'reflect-metadata' import * as IORedis from 'ioredis' -import { TimerInterface } from '@standardnotes/time' import { RedisSubscriptionTokenRepository } from './RedisSubscriptionTokenRepository' import { SubscriptionToken } from '../../Domain/Subscription/SubscriptionToken' describe('RedisSubscriptionTokenRepository', () => { let redisClient: IORedis.Redis - let timer: TimerInterface - const createRepository = () => new RedisSubscriptionTokenRepository(redisClient, timer) + const createRepository = () => new RedisSubscriptionTokenRepository(redisClient) beforeEach(() => { redisClient = {} as jest.Mocked - redisClient.set = jest.fn().mockReturnValue('OK') + redisClient.setex = jest.fn().mockReturnValue('OK') redisClient.get = jest.fn() - redisClient.expireat = jest.fn().mockReturnValue(1) - - timer = {} as jest.Mocked - timer.convertMicrosecondsToSeconds = jest.fn().mockReturnValue(1) }) it('should get a user uuid in exchange for an subscription token', async () => { @@ -42,29 +36,25 @@ describe('RedisSubscriptionTokenRepository', () => { const subscriptionToken: SubscriptionToken = { userUuid: '1-2-3', token: 'random-string', - expiresAt: 123, + ttl: 123, } expect(await createRepository().save(subscriptionToken)).toBeTruthy() - expect(redisClient.set).toHaveBeenCalledWith('subscription-token:random-string', '1-2-3') - - expect(redisClient.expireat).toHaveBeenCalledWith('subscription-token:random-string', 1) + expect(redisClient.setex).toHaveBeenCalledWith('subscription-token:random-string', 123, '1-2-3') }) it('should indicate subscription token was not saved', async () => { - redisClient.set = jest.fn().mockReturnValue(null) + redisClient.setex = jest.fn().mockReturnValue(null) const subscriptionToken: SubscriptionToken = { userUuid: '1-2-3', token: 'random-string', - expiresAt: 123, + ttl: 123, } expect(await createRepository().save(subscriptionToken)).toBeFalsy() - expect(redisClient.set).toHaveBeenCalledWith('subscription-token:random-string', '1-2-3') - - expect(redisClient.expireat).toHaveBeenCalledWith('subscription-token:random-string', 1) + expect(redisClient.setex).toHaveBeenCalledWith('subscription-token:random-string', 123, '1-2-3') }) }) diff --git a/packages/auth/src/Infra/Redis/RedisSubscriptionTokenRepository.ts b/packages/auth/src/Infra/Redis/RedisSubscriptionTokenRepository.ts index a578edca7..3bba3fcb8 100644 --- a/packages/auth/src/Infra/Redis/RedisSubscriptionTokenRepository.ts +++ b/packages/auth/src/Infra/Redis/RedisSubscriptionTokenRepository.ts @@ -4,16 +4,12 @@ import { inject, injectable } from 'inversify' import TYPES from '../../Bootstrap/Types' import { SubscriptionToken } from '../../Domain/Subscription/SubscriptionToken' import { SubscriptionTokenRepositoryInterface } from '../../Domain/Subscription/SubscriptionTokenRepositoryInterface' -import { TimerInterface } from '@standardnotes/time' @injectable() export class RedisSubscriptionTokenRepository implements SubscriptionTokenRepositoryInterface { private readonly PREFIX = 'subscription-token' - constructor( - @inject(TYPES.Redis) private redisClient: IORedis.Redis, - @inject(TYPES.Timer) private timer: TimerInterface, - ) {} + constructor(@inject(TYPES.Redis) private redisClient: IORedis.Redis) {} async getUserUuidByToken(token: string): Promise { const userUuid = await this.redisClient.get(`${this.PREFIX}:${token}`) @@ -26,11 +22,9 @@ export class RedisSubscriptionTokenRepository implements SubscriptionTokenReposi async save(subscriptionToken: SubscriptionToken): Promise { const key = `${this.PREFIX}:${subscriptionToken.token}` - const expiresAtTimestampInSeconds = this.timer.convertMicrosecondsToSeconds(subscriptionToken.expiresAt) - const wasSet = await this.redisClient.set(key, subscriptionToken.userUuid) - const timeoutWasSet = await this.redisClient.expireat(key, expiresAtTimestampInSeconds) + const wasSet = await this.redisClient.setex(key, subscriptionToken.ttl, subscriptionToken.userUuid) - return wasSet === 'OK' && timeoutWasSet !== 0 + return wasSet === 'OK' } }