import { inject, injectable } from 'inversify' import { DomainEventPublisherInterface } from '@standardnotes/domain-events' import { TimerInterface } from '@standardnotes/time' import { Logger } from 'winston' import TYPES from '../../Bootstrap/Types' import { SessionServiceInterface } from '../Session/SessionServiceInterface' import { DomainEventFactoryInterface } from '../Event/DomainEventFactoryInterface' import { RefreshSessionTokenResponse } from './RefreshSessionTokenResponse' import { RefreshSessionTokenDTO } from './RefreshSessionTokenDTO' @injectable() export class RefreshSessionToken { constructor( @inject(TYPES.Auth_SessionService) private sessionService: SessionServiceInterface, @inject(TYPES.Auth_DomainEventFactory) private domainEventFactory: DomainEventFactoryInterface, @inject(TYPES.Auth_DomainEventPublisher) private domainEventPublisher: DomainEventPublisherInterface, @inject(TYPES.Auth_Timer) private timer: TimerInterface, @inject(TYPES.Auth_Logger) private logger: Logger, ) {} async execute(dto: RefreshSessionTokenDTO): Promise { const { session, isEphemeral } = await this.sessionService.getSessionFromToken(dto.accessToken) if (!session) { return { success: false, errorTag: 'invalid-parameters', errorMessage: 'The provided parameters are not valid.', } } if (!this.sessionService.isRefreshTokenMatchingHashedSessionToken(session, dto.refreshToken)) { return { success: false, errorTag: 'invalid-refresh-token', errorMessage: 'The refresh token is not valid.', } } if (session.refreshExpiration < this.timer.getUTCDate()) { return { success: false, errorTag: 'expired-refresh-token', errorMessage: 'The refresh token has expired.', } } session.userAgent = dto.userAgent const sessionPayload = await this.sessionService.refreshTokens({ session, isEphemeral }) try { await this.domainEventPublisher.publish( this.domainEventFactory.createSessionRefreshedEvent({ userUuid: session.userUuid }), ) } catch (error) { this.logger.error(`Failed to publish session refreshed event: ${(error as Error).message}`) } return { success: true, sessionPayload, userUuid: session.userUuid, } } }