@replyke/express
Version:
Replyke: Build interactive apps with social features like comments, votes, feeds, user lists, notifications, and more.
60 lines (59 loc) • 2.3 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
const models_1 = require("../../../models");
const config_1 = require("../../../config");
exports.default = async (req, res) => {
const { refreshToken } = req.body;
const cookies = req.cookies;
const cookieJwt = cookies?.["replyke-refresh-jwt"];
const { refreshTokenSecret } = (0, config_1.getCoreConfig)();
try {
if (cookieJwt) {
// Clear the HttpOnly cookie on the client
res.clearCookie("replyke-refresh-jwt", {
httpOnly: true,
sameSite: "none",
secure: process.env.NODE_ENV === "production",
});
}
const refreshTokenJWT = cookieJwt || refreshToken;
if (!refreshTokenJWT) {
res.sendStatus(204); // No content, no refresh token to clear
return;
}
try {
// Decode and verify the refresh token JWT
const decoded = jsonwebtoken_1.default.verify(refreshTokenJWT, refreshTokenSecret);
const { jti } = decoded;
// Find the refresh token in the Token table using Sequelize
const token = (await models_1.Token.findOne({
where: { id: jti },
}));
if (token) {
// Delete the token from the database
await token.destroy();
}
}
catch (tokenError) {
// Log but do not expose details
console.error("Error handling refresh token during signout:", tokenError);
// Invalid token, but we still return 204 to avoid leaking details
res.sendStatus(204);
return;
}
// Return 204 No Content even if the token is not found, to avoid revealing details
res.sendStatus(204);
}
catch (err) {
console.error("Error signing user out:", err);
res.status(500).json({
error: "Internal server error.",
code: "auth/server-error",
details: err.message,
});
}
};