token refresh
This commit is contained in:
parent
bcfba8b448
commit
55caf69bf0
4 changed files with 102 additions and 8 deletions
|
@ -3,6 +3,6 @@ export interface CreateRefreshCommand {
|
|||
}
|
||||
|
||||
export interface DeleteRefreshCommand {
|
||||
id: number;
|
||||
token: string;
|
||||
userId: number;
|
||||
}
|
||||
|
|
|
@ -2,9 +2,10 @@ import { dataSource } from "../data-source";
|
|||
import { refresh } from "../entity/refresh";
|
||||
import InternalException from "../exceptions/internalException";
|
||||
import { JWTHelper } from "../helpers/jwtHelper";
|
||||
import { StringHelper } from "../helpers/stringHelper";
|
||||
import UserService from "../service/userService";
|
||||
import { JWTRefresh } from "../type/jwtTypes";
|
||||
import { CreateRefreshCommand } from "./refreshCommand";
|
||||
import { CreateRefreshCommand, DeleteRefreshCommand } from "./refreshCommand";
|
||||
import ms from "ms";
|
||||
|
||||
export default abstract class RefreshCommandHandler {
|
||||
|
@ -14,10 +15,11 @@ export default abstract class RefreshCommandHandler {
|
|||
* @returns {Promise<string>}
|
||||
*/
|
||||
static async create(createRefresh: CreateRefreshCommand): Promise<string> {
|
||||
let createRefreshToken: JWTRefresh = {
|
||||
userId: createRefresh.userId,
|
||||
};
|
||||
const refreshToken = await JWTHelper.create(createRefreshToken);
|
||||
// let createRefreshToken: JWTRefresh = {
|
||||
// userId: createRefresh.userId,
|
||||
// };
|
||||
// const refreshToken = await JWTHelper.create(createRefreshToken);
|
||||
const refreshToken = StringHelper.random(32);
|
||||
|
||||
return await dataSource
|
||||
.createQueryBuilder()
|
||||
|
@ -26,7 +28,7 @@ export default abstract class RefreshCommandHandler {
|
|||
.values({
|
||||
token: refreshToken,
|
||||
user: await UserService.getById(createRefresh.userId),
|
||||
expiry: ms(process.env.REFRESH_EXPIRATION),
|
||||
expiry: new Date(Date.now() + ms(process.env.REFRESH_EXPIRATION)),
|
||||
})
|
||||
.execute()
|
||||
.then((result) => {
|
||||
|
@ -36,4 +38,23 @@ export default abstract class RefreshCommandHandler {
|
|||
throw new InternalException("Failed saving refresh token");
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description delete refresh by user and token
|
||||
* @param DeleteRefreshCommand
|
||||
* @returns {Promise<refresh>}
|
||||
*/
|
||||
static async deleteByToken(deleteRefresh: DeleteRefreshCommand): Promise<any> {
|
||||
return await dataSource
|
||||
.createQueryBuilder()
|
||||
.delete()
|
||||
.from(refresh)
|
||||
.where("refresh.token = :token", { token: deleteRefresh.token })
|
||||
.andWhere("refresh.userId = :userId", { userId: deleteRefresh.userId })
|
||||
.execute()
|
||||
.then((res) => {})
|
||||
.catch((err) => {
|
||||
throw new InternalException("failed refresh removal");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Request, Response } from "express";
|
||||
import { JWTHelper } from "../helpers/jwtHelper";
|
||||
import { JWTToken } from "../type/jwtTypes";
|
||||
import { JWTData, JWTToken } from "../type/jwtTypes";
|
||||
import InternalException from "../exceptions/internalException";
|
||||
import RefreshCommandHandler from "../command/refreshCommandHandler";
|
||||
import { CreateRefreshCommand } from "../command/refreshCommand";
|
||||
|
@ -10,6 +10,8 @@ import UnauthorizedRequestException from "../exceptions/unauthorizedRequestExcep
|
|||
import QRCode from "qrcode";
|
||||
import { CreateUserCommand } from "../command/userCommand";
|
||||
import UserCommandHandler from "../command/userCommandHandler";
|
||||
import RefreshService from "../service/refreshService";
|
||||
import BadRequestException from "../exceptions/badRequestException";
|
||||
|
||||
/**
|
||||
* @description Check authentication status by token
|
||||
|
@ -80,6 +82,51 @@ export async function logout(req: Request, res: Response): Promise<any> {}
|
|||
export async function refresh(req: Request, res: Response): Promise<any> {
|
||||
let token = req.body.token;
|
||||
let refresh = req.body.refresh;
|
||||
|
||||
const tokenUser = await JWTHelper.decode(token);
|
||||
if (typeof tokenUser == "string" || !tokenUser) {
|
||||
throw new InternalException("process failed");
|
||||
}
|
||||
|
||||
let tokenUserId = (tokenUser as JWTToken).userId;
|
||||
|
||||
let { user } = await RefreshService.getByToken(refresh);
|
||||
|
||||
if (tokenUserId != user.id) {
|
||||
throw new UnauthorizedRequestException("user not identified with token and refresh");
|
||||
}
|
||||
|
||||
let { id, username } = await UserService.getById(tokenUserId);
|
||||
|
||||
let jwtData: JWTToken = {
|
||||
userId: id,
|
||||
username: username,
|
||||
rights: [],
|
||||
};
|
||||
|
||||
let accessToken: string;
|
||||
let refreshToken: string;
|
||||
|
||||
JWTHelper.create(jwtData)
|
||||
.then((result) => {
|
||||
accessToken = result;
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
throw new InternalException("Failed accessToken creation");
|
||||
});
|
||||
|
||||
let refreshCommand: CreateRefreshCommand = {
|
||||
userId: id,
|
||||
};
|
||||
refreshToken = await RefreshCommandHandler.create(refreshCommand);
|
||||
|
||||
await RefreshCommandHandler.deleteByToken(refresh);
|
||||
|
||||
res.json({
|
||||
accessToken,
|
||||
refreshToken,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
26
src/service/refreshService.ts
Normal file
26
src/service/refreshService.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
import { dataSource } from "../data-source";
|
||||
import { refresh } from "../entity/refresh";
|
||||
import InternalException from "../exceptions/internalException";
|
||||
|
||||
export default abstract class RefreshService {
|
||||
/**
|
||||
* @description get refresh by token
|
||||
* @param token string
|
||||
* @returns {Promise<refresh>}
|
||||
*/
|
||||
static async getByToken(token: string): Promise<refresh> {
|
||||
return await dataSource
|
||||
.getRepository(refresh)
|
||||
.createQueryBuilder("refresh")
|
||||
.leftJoinAndSelect("refresh.user", "user")
|
||||
.where("refresh.token = :token", { token: token })
|
||||
.andWhere("refresh.expiry >= :expiry", { expiry: new Date() })
|
||||
.getOneOrFail()
|
||||
.then((res) => {
|
||||
return res;
|
||||
})
|
||||
.catch((err) => {
|
||||
throw new InternalException("refresh not found");
|
||||
});
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue