From ad0ab648bc45c85371d8f62612aaec1b0abdec28 Mon Sep 17 00:00:00 2001 From: Philip Molares Date: Mon, 25 Jan 2021 12:14:26 +0100 Subject: [PATCH] auth: Add maximum token lifetime of 2 years. Signed-off-by: Philip Molares --- src/api/private/tokens/tokens.controller.ts | 4 ++-- src/auth/auth-token.entity.ts | 9 ++++++--- src/auth/auth.service.spec.ts | 7 +++++-- src/auth/auth.service.ts | 13 +++++++++++-- src/users/auth-token.dto.ts | 18 ------------------ 5 files changed, 24 insertions(+), 27 deletions(-) delete mode 100644 src/users/auth-token.dto.ts diff --git a/src/api/private/tokens/tokens.controller.ts b/src/api/private/tokens/tokens.controller.ts index af2aa792f..e5aaf8e30 100644 --- a/src/api/private/tokens/tokens.controller.ts +++ b/src/api/private/tokens/tokens.controller.ts @@ -14,10 +14,10 @@ import { Post, } from '@nestjs/common'; import { ConsoleLoggerService } from '../../../logger/console-logger.service'; -import { AuthTokenDto } from '../../../auth/auth-token.dto'; -import { AuthTokenWithSecretDto } from '../../../auth/auth-token-with-secret.dto'; import { AuthService } from '../../../auth/auth.service'; import { TimestampMillis } from '../../../utils/timestamp'; +import { AuthTokenDto } from '../../../auth/auth-token.dto'; +import { AuthTokenWithSecretDto } from '../../../auth/auth-token-with-secret.dto'; @Controller('tokens') export class TokensController { diff --git a/src/auth/auth-token.entity.ts b/src/auth/auth-token.entity.ts index 299b7df30..22f5a965f 100644 --- a/src/auth/auth-token.entity.ts +++ b/src/auth/auth-token.entity.ts @@ -45,14 +45,17 @@ export class AuthToken { public static create( user: User, - identifier: string, + label: string, keyId: string, accessToken: string, validUntil: Date, - ): Pick { + ): Pick< + AuthToken, + 'user' | 'label' | 'keyId' | 'accessTokenHash' | 'createdAt' | 'validUntil' + > { const newToken = new AuthToken(); newToken.user = user; - newToken.label = identifier; + newToken.label = label; newToken.keyId = keyId; newToken.accessTokenHash = accessToken; newToken.createdAt = new Date(); diff --git a/src/auth/auth.service.spec.ts b/src/auth/auth.service.spec.ts index 515868d6f..271973dd5 100644 --- a/src/auth/auth.service.spec.ts +++ b/src/auth/auth.service.spec.ts @@ -8,11 +8,11 @@ import { Test, TestingModule } from '@nestjs/testing'; import { AuthService } from './auth.service'; import { PassportModule } from '@nestjs/passport'; import { getRepositoryToken } from '@nestjs/typeorm'; -import { AuthToken } from '../users/auth-token.entity'; import { User } from '../users/user.entity'; import { UsersModule } from '../users/users.module'; import { Identity } from '../users/identity.entity'; import { LoggerModule } from '../logger/logger.module'; +import { AuthToken } from './auth-token.entity'; describe('AuthService', () => { let service: AuthService; @@ -165,7 +165,10 @@ describe('AuthService', () => { 0, ); expect(token.label).toEqual(identifier); - expect(token.validUntil).toBeNull(); + expect( + token.validUntil.getTime() - + (new Date().getTime() + 2 * 365 * 24 * 60 * 60 * 1000), + ).toBeLessThanOrEqual(10000); expect(token.lastUsed).toBeNull(); expect(token.secret.startsWith(token.keyId)).toBeTruthy(); }); diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts index 5fa99ecca..fc2dcfcfc 100644 --- a/src/auth/auth.service.ts +++ b/src/auth/auth.service.ts @@ -93,8 +93,17 @@ export class AuthService { const accessTokenString = await this.hashPassword(secret.toString()); const accessToken = this.BufferToBase64Url(Buffer.from(accessTokenString)); let token; - if (validUntil === 0) { - token = AuthToken.create(user, identifier, keyId, accessToken); + // Tokens can only be valid for a maximum of 2 years + const maximumTokenValidity = + new Date().getTime() + 2 * 365 * 24 * 60 * 60 * 1000; + if (validUntil === 0 || validUntil > maximumTokenValidity) { + token = AuthToken.create( + user, + identifier, + keyId, + accessToken, + new Date(maximumTokenValidity), + ); } else { token = AuthToken.create( user, diff --git a/src/users/auth-token.dto.ts b/src/users/auth-token.dto.ts deleted file mode 100644 index c4fc8ffba..000000000 --- a/src/users/auth-token.dto.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file) - * - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import { IsNumber, IsString } from 'class-validator'; - -export class AuthTokenDto { - @IsString() - label: string; - @IsNumber() - created: number; - @IsNumber() - validUntil: number | null; - @IsNumber() - lastUsed: number | null; -}