first commit
This commit is contained in:
+50
@@ -0,0 +1,50 @@
|
||||
import crypto from "crypto";
|
||||
|
||||
const SECRET = process.env.JWT_SECRET || "default_ayristech_super_secure_admin_jwt_secret_key_2026";
|
||||
|
||||
// ── PASSWORD HASHING ──
|
||||
|
||||
export function hashPassword(password: string): string {
|
||||
const salt = crypto.randomBytes(16).toString("hex");
|
||||
const hash = crypto.pbkdf2Sync(password, salt, 1000, 64, "sha512").toString("hex");
|
||||
return `${salt}:${hash}`;
|
||||
}
|
||||
|
||||
export function verifyPassword(password: string, storedHash: string): boolean {
|
||||
const [salt, hash] = storedHash.split(":");
|
||||
if (!salt || !hash) return false;
|
||||
const verify = crypto.pbkdf2Sync(password, salt, 1000, 64, "sha512").toString("hex");
|
||||
return hash === verify;
|
||||
}
|
||||
|
||||
// ── NATIVE LIGHTWEIGHT JWT SIGN & VERIFY ──
|
||||
|
||||
export function signToken(payload: any): string {
|
||||
const header = Buffer.from(JSON.stringify({ alg: "HS256", typ: "JWT" })).toString("base64url");
|
||||
// Expire session in 24 hours
|
||||
const body = Buffer.from(JSON.stringify({ ...payload, exp: Date.now() + 24 * 60 * 60 * 1000 })).toString("base64url");
|
||||
const hmac = crypto.createHmac("sha256", SECRET);
|
||||
hmac.update(`${header}.${body}`);
|
||||
const signature = hmac.digest("base64url");
|
||||
return `${header}.${body}.${signature}`;
|
||||
}
|
||||
|
||||
export function verifyToken(token: string): any {
|
||||
try {
|
||||
const [header, body, signature] = token.split(".");
|
||||
if (!header || !body || !signature) return null;
|
||||
|
||||
const hmac = crypto.createHmac("sha256", SECRET);
|
||||
hmac.update(`${header}.${body}`);
|
||||
const expectedSignature = hmac.digest("base64url");
|
||||
|
||||
if (signature !== expectedSignature) return null;
|
||||
|
||||
const payload = JSON.parse(Buffer.from(body, "base64url").toString("utf8"));
|
||||
if (payload.exp < Date.now()) return null; // Expired
|
||||
|
||||
return payload;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
import { PrismaPg } from "@prisma/adapter-pg";
|
||||
import pkg from "pg";
|
||||
|
||||
const { Pool } = pkg;
|
||||
|
||||
const globalForPrisma = globalThis as unknown as {
|
||||
prisma: PrismaClient | undefined;
|
||||
};
|
||||
|
||||
const getPrismaClient = () => {
|
||||
const connectionString = process.env.DATABASE_URL;
|
||||
if (!connectionString) {
|
||||
throw new Error("DATABASE_URL is not configured in your environment variables.");
|
||||
}
|
||||
const pool = new Pool({ connectionString });
|
||||
const adapter = new PrismaPg(pool);
|
||||
return new PrismaClient({ adapter });
|
||||
};
|
||||
|
||||
export const prisma = globalForPrisma.prisma ?? getPrismaClient();
|
||||
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
globalForPrisma.prisma = prisma;
|
||||
}
|
||||
Reference in New Issue
Block a user