新增本地认证与管理接口服务
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
const crypto = require("node:crypto");
|
||||
const { tokenSecret } = require("./config.cjs");
|
||||
|
||||
function nowIso() {
|
||||
return new Date().toISOString();
|
||||
}
|
||||
|
||||
function addYears(date, years) {
|
||||
const next = new Date(date);
|
||||
next.setFullYear(next.getFullYear() + years);
|
||||
return next;
|
||||
}
|
||||
|
||||
function addHours(date, hours) {
|
||||
return new Date(date.getTime() + Number(hours || 0) * 3600000);
|
||||
}
|
||||
|
||||
function sign(value) {
|
||||
return crypto.createHmac("sha256", tokenSecret).update(value).digest("base64url");
|
||||
}
|
||||
|
||||
function createToken(userId) {
|
||||
const payload = Buffer.from(JSON.stringify({ userId, issuedAt: Date.now() })).toString("base64url");
|
||||
return `${payload}.${sign(payload)}`;
|
||||
}
|
||||
|
||||
function verifyToken(token) {
|
||||
if (!token || typeof token !== "string" || !token.includes(".")) return null;
|
||||
const [payload, signature] = token.split(".");
|
||||
if (!payload || !signature || sign(payload) !== signature) return null;
|
||||
|
||||
try {
|
||||
return JSON.parse(Buffer.from(payload, "base64url").toString("utf8"));
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function passwordHash(password, salt = crypto.randomBytes(16).toString("hex")) {
|
||||
const hash = crypto.pbkdf2Sync(String(password), salt, 120000, 32, "sha256").toString("hex");
|
||||
return `${salt}:${hash}`;
|
||||
}
|
||||
|
||||
function checkPassword(password, stored) {
|
||||
const [salt] = String(stored || "").split(":");
|
||||
if (!salt) return false;
|
||||
return passwordHash(password, salt) === stored;
|
||||
}
|
||||
|
||||
function daysRemaining(expiresAt) {
|
||||
return Math.max(0, Math.ceil((new Date(expiresAt).getTime() - Date.now()) / 86400000));
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
nowIso,
|
||||
addYears,
|
||||
addHours,
|
||||
createToken,
|
||||
verifyToken,
|
||||
passwordHash,
|
||||
checkPassword,
|
||||
daysRemaining,
|
||||
};
|
||||
Reference in New Issue
Block a user