|
@@ -0,0 +1,102 @@
|
|
|
|
|
+import jwt from "jsonwebtoken";
|
|
|
|
|
+import redis from "../../../config/redis";
|
|
|
|
|
+import {
|
|
|
|
|
+ User
|
|
|
|
|
+} from "../../../models/User";
|
|
|
|
|
+import {
|
|
|
|
|
+ RefreshTokenResult
|
|
|
|
|
+} from "./types";
|
|
|
|
|
+
|
|
|
|
|
+const refreshToken = async (userId: string, token: string): Promise<RefreshTokenResult> => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ if (!userId || !token) {
|
|
|
|
|
+ return {
|
|
|
|
|
+ message: "userId and refreshToken required",
|
|
|
|
|
+ code: 400
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const user = await User.findById(userId);
|
|
|
|
|
+ if (!user) {
|
|
|
|
|
+ return {
|
|
|
|
|
+ message: "user-not-found",
|
|
|
|
|
+ code: 404
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ let decoded: {
|
|
|
|
|
+ companyName: string;
|
|
|
|
|
+ fullName: string;
|
|
|
|
|
+ userId: string;
|
|
|
|
|
+ mail: string;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ decoded = jwt.verify(
|
|
|
|
|
+ token,
|
|
|
|
|
+ process.env.JWT_SECRET as string
|
|
|
|
|
+ ) as typeof decoded;
|
|
|
|
|
+ } catch {
|
|
|
|
|
+ return {
|
|
|
|
|
+ message: "invalid-refresh-token",
|
|
|
|
|
+ code: 401
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (decoded.userId !== userId) {
|
|
|
|
|
+ return {
|
|
|
|
|
+ message: "invalid-refresh-token",
|
|
|
|
|
+ code: 401
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const newAccessToken = jwt.sign(
|
|
|
|
|
+ {
|
|
|
|
|
+ companyName: user.companyName,
|
|
|
|
|
+ fullName: user.fullName,
|
|
|
|
|
+ userId: user._id,
|
|
|
|
|
+ mail: user.mail,
|
|
|
|
|
+ },
|
|
|
|
|
+ process.env.JWT_SECRET as string,
|
|
|
|
|
+ {
|
|
|
|
|
+ expiresIn: "4h"
|
|
|
|
|
+ }
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ const newRefreshToken = jwt.sign(
|
|
|
|
|
+ {
|
|
|
|
|
+ companyName: user.companyName,
|
|
|
|
|
+ fullName: user.fullName,
|
|
|
|
|
+ userId: user._id,
|
|
|
|
|
+ mail: user.mail,
|
|
|
|
|
+ },
|
|
|
|
|
+ process.env.JWT_SECRET as string,
|
|
|
|
|
+ {
|
|
|
|
|
+ expiresIn: "30d"
|
|
|
|
|
+ }
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ await redis.del(`${userId}`);
|
|
|
|
|
+ await redis.setex(`${userId}`, 14400, newAccessToken);
|
|
|
|
|
+
|
|
|
|
|
+ user.refreshToken = newRefreshToken;
|
|
|
|
|
+ await user.save();
|
|
|
|
|
+
|
|
|
|
|
+ return {
|
|
|
|
|
+ code: 200,
|
|
|
|
|
+ message: "token-refreshed",
|
|
|
|
|
+ payload: {
|
|
|
|
|
+ accessToken: newAccessToken,
|
|
|
|
|
+ refreshToken: newRefreshToken,
|
|
|
|
|
+ },
|
|
|
|
|
+ };
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error("RefreshToken action error:", error);
|
|
|
|
|
+ return {
|
|
|
|
|
+ message: "internal-server-error",
|
|
|
|
|
+ code: 500
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+export default refreshToken;
|