first
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
import { randomBytes } from "node:crypto";
|
||||
|
||||
import DayJs from "dayjs";
|
||||
import { inject, injectable } from "inversify";
|
||||
import jwt, { SignOptions, TokenExpiredError } from "jsonwebtoken";
|
||||
|
||||
import { TokenRepository } from "./token.repository";
|
||||
import { AuthTokenPayload, TokenType } from "../../common/types/jwt.type";
|
||||
import { jwtExpiredErr } from "../../core/app/app.errors";
|
||||
import { Logger } from "../../core/logging/logger";
|
||||
import { IOCTYPES } from "../../IOC/ioc.types";
|
||||
|
||||
@injectable()
|
||||
export class TokenService {
|
||||
private logger = new Logger(TokenService.name);
|
||||
@inject(IOCTYPES.TokenRepository) private tokenRepository: TokenRepository;
|
||||
private jwtSecret: string = process.env.JWT_SECRET;
|
||||
private jwt_access_expire: string = process.env.JWT_EXPIRE_ACCESS || "2"; //hours
|
||||
private jwt_refresh_expire: string = process.env.JWT_EXPIRE_REFRESH || "2"; //day
|
||||
|
||||
public _generateToken(type: TokenType, payload: AuthTokenPayload, option?: SignOptions) {
|
||||
if (type == "Access" && option?.expiresIn) return jwt.sign(payload, this.jwtSecret, { ...option });
|
||||
const refToken = randomBytes(24).toString("hex");
|
||||
return refToken;
|
||||
}
|
||||
public async generateAuthTokens(payload: AuthTokenPayload) {
|
||||
const accessToken = this._generateToken("Access", payload, { expiresIn: `${this.jwt_access_expire}h` });
|
||||
const refreshToken = this._generateToken("Refresh", payload);
|
||||
const RefreshExpire = DayJs().add(+this.jwt_refresh_expire, "day").toDate();
|
||||
|
||||
const oldToken = await this.tokenRepository.findByUserId(payload.sub);
|
||||
if (oldToken) {
|
||||
await this.tokenRepository.delete(oldToken._id.toString());
|
||||
}
|
||||
await this.tokenRepository.model.create({ refreshToken, userId: payload.sub, refreshTokenExpire: RefreshExpire });
|
||||
|
||||
const tokens = {
|
||||
accessToken: {
|
||||
token: accessToken,
|
||||
expires: DayJs().add(+this.jwt_access_expire, "h").unix().toString(),
|
||||
},
|
||||
refreshToken: {
|
||||
token: refreshToken,
|
||||
expires: DayJs().add(+this.jwt_refresh_expire, "day").unix().toString(),
|
||||
},
|
||||
};
|
||||
return tokens;
|
||||
}
|
||||
|
||||
public async revokeTokens(id: string) {
|
||||
// const deletedToken = await this.tokenRepository.delete(id);
|
||||
// if (!deletedToken) return false;
|
||||
// return true;
|
||||
|
||||
return !!(await this.tokenRepository.delete(id));
|
||||
}
|
||||
public verifyToken(token: string): AuthTokenPayload {
|
||||
try {
|
||||
const decoded = jwt.verify(token, this.jwtSecret);
|
||||
return decoded as AuthTokenPayload;
|
||||
} catch (error) {
|
||||
if (error instanceof TokenExpiredError) throw new jwtExpiredErr();
|
||||
this.logger.error("error in jwt verify", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user