auth: Add cron to clean old tokens

Rename AuthToken.identifier to label

Signed-off-by: Philip Molares <philip.molares@udo.edu>
This commit is contained in:
Philip Molares 2021-01-24 20:37:04 +01:00 committed by David Mehren
parent 14a4872f49
commit 8f008c7cc5
No known key found for this signature in database
GPG key ID: 185982BA4C42B7C3
6 changed files with 27 additions and 17 deletions

View file

@ -30,7 +30,7 @@ entity "auth_token"{
*userId : uuid
*keyId: text
*accessToken : text
*identifier: text
*label: text
*createdAt: date
lastUsed: number
validUntil: number

View file

@ -30,9 +30,11 @@
"@nestjs/passport": "^7.1.5",
"@nestjs/platform-express": "7.6.5",
"@nestjs/swagger": "4.7.12",
"@nestjs/schedule": "^0.4.2",
"@nestjs/typeorm": "7.1.5",
"@types/passport-http-bearer": "^1.0.36",
"@types/bcrypt": "^3.0.0",
"@types/cron": "^1.7.2",
"@types/passport-http-bearer": "^1.0.36",
"bcrypt": "^5.0.0",
"class-transformer": "0.3.2",
"class-validator": "0.13.1",

View file

@ -26,6 +26,7 @@ import cspConfig from './config/csp.config';
import databaseConfig from './config/database.config';
import authConfig from './config/auth.config';
import { PrivateApiModule } from './api/private/private-api.module';
import { ScheduleModule } from '@nestjs/schedule';
@Module({
imports: [
@ -46,6 +47,7 @@ import { PrivateApiModule } from './api/private/private-api.module';
],
isGlobal: true,
}),
ScheduleModule.forRoot(),
NotesModule,
UsersModule,
RevisionsModule,

View file

@ -25,7 +25,7 @@ export class AuthToken {
user: User;
@Column()
identifier: string;
label: string;
@CreateDateColumn()
createdAt: Date;
@ -51,16 +51,11 @@ export class AuthToken {
validUntil?: Date,
): Pick<
AuthToken,
| 'user'
| 'identifier'
| 'keyId'
| 'accessTokenHash'
| 'createdAt'
| 'validUntil'
'user' | 'label' | 'keyId' | 'accessTokenHash' | 'createdAt' | 'validUntil'
> {
const newToken = new AuthToken();
newToken.user = user;
newToken.identifier = identifier;
newToken.label = identifier;
newToken.keyId = keyId;
newToken.accessTokenHash = accessToken;
newToken.createdAt = new Date();

View file

@ -35,7 +35,7 @@ describe('AuthService', () => {
accessTokenHash: '',
createdAt: new Date(),
id: 1,
identifier: 'testIdentifier',
label: 'testIdentifier',
keyId: 'abc',
lastUsed: null,
user: null,
@ -186,7 +186,7 @@ describe('AuthService', () => {
const tokenDto = await service.toAuthTokenDto(authToken);
expect(tokenDto.keyId).toEqual(authToken.keyId);
expect(tokenDto.lastUsed).toBeNull();
expect(tokenDto.label).toEqual(authToken.identifier);
expect(tokenDto.label).toEqual(authToken.label);
expect(tokenDto.validUntil).toBeNull();
expect(tokenDto.createdAt.getTime()).toEqual(
authToken.createdAt.getTime(),

View file

@ -17,6 +17,7 @@ import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { ConsoleLoggerService } from '../logger/console-logger.service';
import { TimestampMillis } from '../utils/timestamp';
import { Cron } from '@nestjs/schedule';
@Injectable()
export class AuthService {
@ -32,11 +33,11 @@ export class AuthService {
async validateToken(token: string): Promise<User> {
const [keyId, secret] = token.split('.');
const accessToken = await this.getAuthTokenAndValidate(keyId, secret);
await this.setLastUsedToken(keyId);
const user = await this.usersService.getUserByUsername(
accessToken.user.userName,
);
if (user) {
await this.setLastUsedToken(keyId);
return user;
}
return null;
@ -125,9 +126,7 @@ export class AuthService {
) {
// tokens validUntil Date lies in the past
throw new TokenNotValidError(
`AuthToken '${token}' is not valid since ${new Date(
accessToken.validUntil,
)}.`,
`AuthToken '${token}' is not valid since ${accessToken.validUntil}.`,
);
}
return accessToken;
@ -156,7 +155,7 @@ export class AuthService {
const tokenDto: AuthTokenDto = {
lastUsed: null,
validUntil: null,
label: authToken.identifier,
label: authToken.label,
keyId: authToken.keyId,
createdAt: authToken.createdAt,
};
@ -182,4 +181,16 @@ export class AuthService {
secret: secret,
};
}
// Delete all non valid tokens every sunday on 3:00 AM
@Cron('0 0 3 * * 0')
async handleCron() {
const currentTime = new Date().getTime();
const tokens: AuthToken[] = await this.authTokenRepository.find();
for (const token of tokens) {
if (token.validUntil && token.validUntil.getTime() <= currentTime) {
await this.authTokenRepository.remove(token);
}
}
}
}