mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2024-11-25 19:26:31 -05:00
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:
parent
cc2fcac532
commit
0a3247492a
6 changed files with 27 additions and 17 deletions
|
@ -30,7 +30,7 @@ entity "auth_token"{
|
|||
*userId : uuid
|
||||
*keyId: text
|
||||
*accessToken : text
|
||||
*identifier: text
|
||||
*label: text
|
||||
*createdAt: date
|
||||
lastUsed: number
|
||||
validUntil: number
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue