mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2024-11-29 17:04:33 -05:00
auth: Add maximum token lifetime of 2 years.
Signed-off-by: Philip Molares <philip.molares@udo.edu>
This commit is contained in:
parent
6686fa58c5
commit
ad0ab648bc
5 changed files with 24 additions and 27 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
});
|
});
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
Loading…
Reference in a new issue