Invalidate old Token
This commit is contained in:
@@ -57,6 +57,10 @@ export class User {
|
|||||||
@ManyToMany(() => Client, (client) => client.admins)
|
@ManyToMany(() => Client, (client) => client.admins)
|
||||||
clients?: Client[];
|
clients?: Client[];
|
||||||
|
|
||||||
|
@Exclude()
|
||||||
|
@Column({ type: 'int', default: 0 })
|
||||||
|
pwRevision?: number; // wird hochgezählt wenn das PW geändert wird. somit kann der Token invalid gesetzt werden.
|
||||||
|
|
||||||
accessToken?: string;
|
accessToken?: string;
|
||||||
refreshToken?: string;
|
refreshToken?: string;
|
||||||
session_key?: string;
|
session_key?: string;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
export * from './authenticated.request';
|
export * from './authenticated.request';
|
||||||
export * from './logger.interface';
|
export * from './logger.interface';
|
||||||
export * from './mailconfig.interface';
|
export * from './mailconfig.interface';
|
||||||
|
export * from './payload.interface';
|
||||||
|
|||||||
18
idp/src/model/interface/payload.interface.ts
Normal file
18
idp/src/model/interface/payload.interface.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
export interface IAccessPayload {
|
||||||
|
username: string;
|
||||||
|
firstName: string;
|
||||||
|
lastName: string;
|
||||||
|
id: string;
|
||||||
|
iss: string;
|
||||||
|
aud: string;
|
||||||
|
iat: number;
|
||||||
|
exp: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IRefreshPayload {
|
||||||
|
type: string;
|
||||||
|
id: string;
|
||||||
|
token_revision: number;
|
||||||
|
iat: number;
|
||||||
|
exp: number;
|
||||||
|
}
|
||||||
@@ -15,6 +15,8 @@ import {
|
|||||||
AuthorizationCodeRepository,
|
AuthorizationCodeRepository,
|
||||||
AuthorizationCode,
|
AuthorizationCode,
|
||||||
ActivityLogRepository,
|
ActivityLogRepository,
|
||||||
|
IAccessPayload,
|
||||||
|
IRefreshPayload,
|
||||||
} from 'src/model';
|
} from 'src/model';
|
||||||
import { CustomLogger } from './logger/custom.logger';
|
import { CustomLogger } from './logger/custom.logger';
|
||||||
|
|
||||||
@@ -126,7 +128,6 @@ export class UsersService {
|
|||||||
if (getUserAccessToken) {
|
if (getUserAccessToken) {
|
||||||
user.accessToken = this.createAccessToken(user);
|
user.accessToken = this.createAccessToken(user);
|
||||||
user.refreshToken = this.createRefreshToken(user);
|
user.refreshToken = this.createRefreshToken(user);
|
||||||
console.log(this.jwtService.verify(user.accessToken))
|
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,25 +207,30 @@ export class UsersService {
|
|||||||
{
|
{
|
||||||
type: 'refresh',
|
type: 'refresh',
|
||||||
id: user.id,
|
id: user.id,
|
||||||
|
token_revision: user.pwRevision,
|
||||||
},
|
},
|
||||||
{ expiresIn: '365d' },
|
{ expiresIn: '365d' },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getNewAccessToken(refreshToken: string) {
|
async getNewAccessToken(refreshToken: string) {
|
||||||
const payload = this.jwtService.verify(refreshToken);
|
const payload: IRefreshPayload = this.jwtService.verify(refreshToken);
|
||||||
if (payload.type !== 'refresh') {
|
if (payload.type !== 'refresh') {
|
||||||
this.logger.error(`Token ${refreshToken} is not a refresh token`);
|
this.logger.error(`Token ${refreshToken} is not a refresh token`);
|
||||||
throw new HttpException('Invalid token', 401);
|
throw new HttpException('Invalid token', 401);
|
||||||
}
|
}
|
||||||
const user = await this.userRepo.findById(payload.id);
|
const user = await this.userRepo.findById(payload.id);
|
||||||
if (!user) {
|
if (
|
||||||
|
!user ||
|
||||||
|
payload['token_revision'] == undefined ||
|
||||||
|
payload['token_revision'] != user.pwRevision
|
||||||
|
) {
|
||||||
this.logger.error(`User ${payload.id} not found for refresh token`);
|
this.logger.error(`User ${payload.id} not found for refresh token`);
|
||||||
throw new HttpException('Invalid token', 401);
|
throw new HttpException('Invalid token', 401);
|
||||||
}
|
}
|
||||||
|
|
||||||
const token = this.createAccessToken(user);
|
const token = this.createAccessToken(user);
|
||||||
const pay = this.jwtService.decode(token);
|
const pay: IAccessPayload = this.jwtService.decode(token);
|
||||||
const result = {
|
const result = {
|
||||||
access_token: token,
|
access_token: token,
|
||||||
expires_in: pay.exp - pay.iat,
|
expires_in: pay.exp - pay.iat,
|
||||||
@@ -238,7 +244,7 @@ export class UsersService {
|
|||||||
try {
|
try {
|
||||||
const decoded = this.jwtService.verify(token);
|
const decoded = this.jwtService.verify(token);
|
||||||
this.activityRepo.logAccessTokenVerification();
|
this.activityRepo.logAccessTokenVerification();
|
||||||
console.log(decoded)
|
console.log(decoded, '-');
|
||||||
return decoded;
|
return decoded;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.logger.error(`Token ${token} is invalid. Error: ${e.message}`);
|
this.logger.error(`Token ${token} is invalid. Error: ${e.message}`);
|
||||||
@@ -305,6 +311,7 @@ export class UsersService {
|
|||||||
if (savedCode && savedCode.user) {
|
if (savedCode && savedCode.user) {
|
||||||
const hashedPassword = await bcrypt.hash(dto.password, 10);
|
const hashedPassword = await bcrypt.hash(dto.password, 10);
|
||||||
savedCode.user.password = hashedPassword;
|
savedCode.user.password = hashedPassword;
|
||||||
|
savedCode.user.pwRevision += 1;
|
||||||
await this.userRepo.save(savedCode.user);
|
await this.userRepo.save(savedCode.user);
|
||||||
await this.resetPwRepo.remove(savedCode);
|
await this.resetPwRepo.remove(savedCode);
|
||||||
await this.sessionRepo.delete({ user: { id: savedCode.user.id } });
|
await this.sessionRepo.delete({ user: { id: savedCode.user.id } });
|
||||||
|
|||||||
Reference in New Issue
Block a user