Files
shop-api/src/modules/token/token.service.ts
T
2025-09-17 15:49:14 +03:30

68 lines
2.6 KiB
TypeScript

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"; //minutes
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}m` });
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, "m").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;
}
}
}