auth: Add maximum token lifetime of 2 years.

Signed-off-by: Philip Molares <philip.molares@udo.edu>
This commit is contained in:
Philip Molares 2021-01-25 12:14:26 +01:00 committed by David Mehren
parent 6686fa58c5
commit ad0ab648bc
No known key found for this signature in database
GPG key ID: 185982BA4C42B7C3
5 changed files with 24 additions and 27 deletions

View file

@ -14,10 +14,10 @@ import {
Post, Post,
} from '@nestjs/common'; } from '@nestjs/common';
import { ConsoleLoggerService } from '../../../logger/console-logger.service'; 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 { AuthService } from '../../../auth/auth.service';
import { TimestampMillis } from '../../../utils/timestamp'; import { TimestampMillis } from '../../../utils/timestamp';
import { AuthTokenDto } from '../../../auth/auth-token.dto';
import { AuthTokenWithSecretDto } from '../../../auth/auth-token-with-secret.dto';
@Controller('tokens') @Controller('tokens')
export class TokensController { export class TokensController {

View file

@ -45,14 +45,17 @@ export class AuthToken {
public static create( public static create(
user: User, user: User,
identifier: string, label: string,
keyId: string, keyId: string,
accessToken: string, accessToken: string,
validUntil: Date, validUntil: Date,
): Pick<AuthToken, 'user' | 'accessToken'> { ): Pick<
AuthToken,
'user' | 'label' | 'keyId' | 'accessTokenHash' | 'createdAt' | 'validUntil'
> {
const newToken = new AuthToken(); const newToken = new AuthToken();
newToken.user = user; newToken.user = user;
newToken.label = identifier; newToken.label = label;
newToken.keyId = keyId; newToken.keyId = keyId;
newToken.accessTokenHash = accessToken; newToken.accessTokenHash = accessToken;
newToken.createdAt = new Date(); newToken.createdAt = new Date();

View file

@ -8,11 +8,11 @@ import { Test, TestingModule } from '@nestjs/testing';
import { AuthService } from './auth.service'; import { AuthService } from './auth.service';
import { PassportModule } from '@nestjs/passport'; import { PassportModule } from '@nestjs/passport';
import { getRepositoryToken } from '@nestjs/typeorm'; import { getRepositoryToken } from '@nestjs/typeorm';
import { AuthToken } from '../users/auth-token.entity';
import { User } from '../users/user.entity'; import { User } from '../users/user.entity';
import { UsersModule } from '../users/users.module'; import { UsersModule } from '../users/users.module';
import { Identity } from '../users/identity.entity'; import { Identity } from '../users/identity.entity';
import { LoggerModule } from '../logger/logger.module'; import { LoggerModule } from '../logger/logger.module';
import { AuthToken } from './auth-token.entity';
describe('AuthService', () => { describe('AuthService', () => {
let service: AuthService; let service: AuthService;
@ -165,7 +165,10 @@ describe('AuthService', () => {
0, 0,
); );
expect(token.label).toEqual(identifier); 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.lastUsed).toBeNull();
expect(token.secret.startsWith(token.keyId)).toBeTruthy(); expect(token.secret.startsWith(token.keyId)).toBeTruthy();
}); });

View file

@ -93,8 +93,17 @@ export class AuthService {
const accessTokenString = await this.hashPassword(secret.toString()); const accessTokenString = await this.hashPassword(secret.toString());
const accessToken = this.BufferToBase64Url(Buffer.from(accessTokenString)); const accessToken = this.BufferToBase64Url(Buffer.from(accessTokenString));
let token; let token;
if (validUntil === 0) { // Tokens can only be valid for a maximum of 2 years
token = AuthToken.create(user, identifier, keyId, accessToken); 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 { } else {
token = AuthToken.create( token = AuthToken.create(
user, user,

View file

@ -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;
}