|
|
@@ -1,4 +1,3 @@
|
|
|
-// lib/auth/session.js
|
|
|
import { cookies } from "next/headers";
|
|
|
import { SignJWT, jwtVerify } from "jose";
|
|
|
|
|
|
@@ -15,16 +14,6 @@ function getSessionSecretKey() {
|
|
|
return new TextEncoder().encode(secret);
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * Resolve whether the session cookie should be marked as "Secure".
|
|
|
- *
|
|
|
- * Default:
|
|
|
- * - Secure in production (`NODE_ENV=production`)
|
|
|
- *
|
|
|
- * Override (useful for local HTTP testing):
|
|
|
- * - SESSION_COOKIE_SECURE=false
|
|
|
- * - SESSION_COOKIE_SECURE=true
|
|
|
- */
|
|
|
function resolveCookieSecureFlag() {
|
|
|
const raw = (process.env.SESSION_COOKIE_SECURE || "").trim().toLowerCase();
|
|
|
if (raw === "true") return true;
|
|
|
@@ -33,10 +22,18 @@ function resolveCookieSecureFlag() {
|
|
|
return process.env.NODE_ENV === "production";
|
|
|
}
|
|
|
|
|
|
+function normalizeEmailOrNull(value) {
|
|
|
+ if (typeof value !== "string") return null;
|
|
|
+ const s = value.trim();
|
|
|
+ if (!s) return null;
|
|
|
+ // Email is not case-sensitive; keep it normalized for UI consistency.
|
|
|
+ return s.toLowerCase();
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* Create a signed session JWT and store it in a HTTP-only cookie.
|
|
|
*/
|
|
|
-export async function createSession({ userId, role, branchId }) {
|
|
|
+export async function createSession({ userId, role, branchId, email }) {
|
|
|
if (!userId || !role) {
|
|
|
throw new Error("createSession requires userId and role");
|
|
|
}
|
|
|
@@ -45,6 +42,7 @@ export async function createSession({ userId, role, branchId }) {
|
|
|
userId,
|
|
|
role,
|
|
|
branchId: branchId ?? null,
|
|
|
+ email: normalizeEmailOrNull(email),
|
|
|
};
|
|
|
|
|
|
const jwt = await new SignJWT(payload)
|
|
|
@@ -82,7 +80,7 @@ export async function getSession() {
|
|
|
try {
|
|
|
const { payload } = await jwtVerify(cookie.value, secretKey);
|
|
|
|
|
|
- const { userId, role, branchId } = payload;
|
|
|
+ const { userId, role, branchId, email } = payload;
|
|
|
|
|
|
if (typeof userId !== "string" || typeof role !== "string") {
|
|
|
return null;
|
|
|
@@ -92,9 +90,9 @@ export async function getSession() {
|
|
|
userId,
|
|
|
role,
|
|
|
branchId: typeof branchId === "string" ? branchId : null,
|
|
|
+ email: typeof email === "string" ? email : null,
|
|
|
};
|
|
|
} catch {
|
|
|
- // Invalid or expired token: clear cookie and return null
|
|
|
const store = await cookies();
|
|
|
store.set(SESSION_COOKIE_NAME, "", {
|
|
|
httpOnly: true,
|
|
|
@@ -108,9 +106,6 @@ export async function getSession() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * Destroy the current session by clearing the session cookie.
|
|
|
- */
|
|
|
export async function destroySession() {
|
|
|
const cookieStore = await cookies();
|
|
|
|