@infuro/cms-core 1.0.31 → 1.0.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/dist/admin.cjs +929 -345
- package/dist/admin.cjs.map +1 -1
- package/dist/admin.js +947 -362
- package/dist/admin.js.map +1 -1
- package/dist/api.cjs +839 -59
- package/dist/api.cjs.map +1 -1
- package/dist/api.d.cts +1 -1
- package/dist/api.d.ts +1 -1
- package/dist/api.js +833 -53
- package/dist/api.js.map +1 -1
- package/dist/auth.cjs +159 -14
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.d.cts +37 -22
- package/dist/auth.d.ts +37 -22
- package/dist/auth.js +153 -14
- package/dist/auth.js.map +1 -1
- package/dist/cli.cjs +3 -2
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +3 -2
- package/dist/cli.js.map +1 -1
- package/dist/{index-Bda8D1Rm.d.ts → index-DWd5Gjc4.d.ts} +2 -2
- package/dist/{index-BcMRGNjS.d.cts → index-rZTnpK7y.d.cts} +2 -2
- package/dist/index.cjs +1141 -254
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +41 -30
- package/dist/index.d.ts +41 -30
- package/dist/index.js +1135 -254
- package/dist/index.js.map +1 -1
- package/dist/migrations/1778660000003-AddQrTokenToOrders.ts +32 -0
- package/dist/migrations/1779100000000-ChatConversationLeadEmailSent.ts +16 -0
- package/dist/migrations/1779200000000-LlmAgentScope.ts +72 -0
- package/package.json +2 -1
package/dist/auth.d.cts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { S as SessionUser, E as EntityCrudAction, b as EntityPermissionFlags } from './vendor-scope-DTYhJk_I.cjs';
|
|
2
2
|
export { A as ADMIN_GROUP_NAME, a as AuthHelpers, G as GetSession, O as OPEN_ENDPOINTS, P as PERMISSION_REQUIRED_ENDPOINTS, R as RBAC_ADMIN_ONLY_ENTITIES, V as VENDOR_OWNER_GROUP_NAME, c as VENDOR_SCOPED_STORE_ENTITIES, d as VENDOR_STORE_RBAC_ENTITIES, f as canManageRoles, g as canManageVendorRoles, h as canManageVendorTeam, i as canOnboardVendors, j as createAuthHelpers, k as createCmsAuthBundle, l as getPermissionableEntityKeys, m as getRequiredPermission, n as hasEntityPermission, o as isOpenEndpoint, p as isPlatformAdministrator, q as isPublicMethod, r as isSuperAdminGroupName, s as isVendorGroupName, t as isVendorOwner, u as isVendorPortalUser, v as isVendorStaff, w as permissionRowsToRecord, x as resolveVendorScopeFromSessionUser, y as sessionHasEntityAccess, z as vendorPortalFlagsFromUser } from './vendor-scope-DTYhJk_I.cjs';
|
|
3
3
|
import { DataSource } from 'typeorm';
|
|
4
|
+
import { getToken } from 'next-auth/jwt';
|
|
4
5
|
import { NextAuthOptions } from 'next-auth';
|
|
5
6
|
|
|
6
7
|
/**
|
|
@@ -79,40 +80,45 @@ declare function logEntityAccessDecision(dataSource: RbacDebugDataSource | undef
|
|
|
79
80
|
*/
|
|
80
81
|
declare function seedAdministratorPermissions(dataSource: DataSource, entityMap: Record<string, unknown>): Promise<void>;
|
|
81
82
|
|
|
83
|
+
interface CmsMiddlewareRequest {
|
|
84
|
+
nextUrl: {
|
|
85
|
+
pathname: string;
|
|
86
|
+
};
|
|
87
|
+
url: string;
|
|
88
|
+
method: string;
|
|
89
|
+
cookies: {
|
|
90
|
+
get: (name: string) => {
|
|
91
|
+
value?: string;
|
|
92
|
+
} | undefined;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Full Next.js request (e.g. `NextRequest`). When provided, session is resolved via
|
|
96
|
+
* `getToken()` so chunked `next-auth.session-token.N` cookies work.
|
|
97
|
+
*/
|
|
98
|
+
req?: Parameters<typeof getToken>[0]['req'];
|
|
99
|
+
}
|
|
82
100
|
interface CmsMiddlewareConfig {
|
|
83
101
|
publicAdminPaths?: string[];
|
|
84
102
|
publicApiPaths?: string[];
|
|
85
103
|
/** path -> allowed methods */
|
|
86
104
|
publicApiMethods?: Record<string, string[]>;
|
|
87
105
|
signInPath?: string;
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
value?: string;
|
|
92
|
-
} | undefined;
|
|
93
|
-
};
|
|
94
|
-
}) => string | undefined;
|
|
106
|
+
/** @deprecated Prefer passing `req` on the request; used only when `req` is omitted. */
|
|
107
|
+
getSessionToken?: (request: CmsMiddlewareRequest) => string | undefined;
|
|
108
|
+
secret?: string;
|
|
95
109
|
}
|
|
96
110
|
/** Default public API paths (no auth). Sites should extend this with their own routes. */
|
|
97
111
|
declare const defaultPublicApiMethods: Record<string, string[]>;
|
|
98
112
|
/**
|
|
99
113
|
* Returns middleware logic. Use from Next.js middleware:
|
|
100
114
|
* import { createCmsMiddleware } from '@infuro/cms-core';
|
|
101
|
-
* export
|
|
115
|
+
* export async function middleware(request: NextRequest) {
|
|
116
|
+
* const result = await cmsMiddleware({ ...request fields, req: request });
|
|
117
|
+
* ...
|
|
118
|
+
* }
|
|
102
119
|
* export const config = { matcher: ['/admin/:path*', '/api/:path*'] };
|
|
103
120
|
*/
|
|
104
|
-
declare function createCmsMiddleware(config?: CmsMiddlewareConfig): (request: {
|
|
105
|
-
nextUrl: {
|
|
106
|
-
pathname: string;
|
|
107
|
-
};
|
|
108
|
-
url: string;
|
|
109
|
-
method: string;
|
|
110
|
-
cookies: {
|
|
111
|
-
get: (name: string) => {
|
|
112
|
-
value?: string;
|
|
113
|
-
} | undefined;
|
|
114
|
-
};
|
|
115
|
-
}) => {
|
|
121
|
+
declare function createCmsMiddleware(config?: CmsMiddlewareConfig): (request: CmsMiddlewareRequest) => Promise<{
|
|
116
122
|
type: "next";
|
|
117
123
|
} | {
|
|
118
124
|
type: "redirect";
|
|
@@ -121,6 +127,15 @@ declare function createCmsMiddleware(config?: CmsMiddlewareConfig): (request: {
|
|
|
121
127
|
type: "json";
|
|
122
128
|
status: number;
|
|
123
129
|
body: unknown;
|
|
124
|
-
}
|
|
130
|
+
}>;
|
|
131
|
+
|
|
132
|
+
/** Set `CMS_AUTH_DEBUG=false` to silence server auth logs in development. */
|
|
133
|
+
declare function isAuthDebugEnabled(): boolean;
|
|
134
|
+
/** Browser console logs; set `NEXT_PUBLIC_CMS_AUTH_DEBUG=false` to silence. */
|
|
135
|
+
declare function isAuthDebugClientEnabled(): boolean;
|
|
136
|
+
declare function logAuth(message: string, data?: Record<string, unknown>): void;
|
|
137
|
+
declare function logAuthClient(message: string, data?: Record<string, unknown>): void;
|
|
138
|
+
declare function summarizeSessionUserForLog(user: unknown): Record<string, unknown>;
|
|
139
|
+
declare function nextAuthCookieDebugInfo(): Record<string, unknown>;
|
|
125
140
|
|
|
126
|
-
export { type AuthorizeOtpInput, type CmsMiddlewareConfig, EntityCrudAction, EntityPermissionFlags, type NextAuthOptionsConfig, type NextAuthUser, SessionUser, createCmsMiddleware, defaultPublicApiMethods, explainSessionEntityAccess, getNextAuthOptions, isRbacDebugEnabled, logEntityAccessDecision, logRbac, seedAdministratorPermissions, summarizeEntityPerms };
|
|
141
|
+
export { type AuthorizeOtpInput, type CmsMiddlewareConfig, type CmsMiddlewareRequest, EntityCrudAction, EntityPermissionFlags, type NextAuthOptionsConfig, type NextAuthUser, SessionUser, createCmsMiddleware, defaultPublicApiMethods, explainSessionEntityAccess, getNextAuthOptions, isAuthDebugClientEnabled, isAuthDebugEnabled, isRbacDebugEnabled, logAuth, logAuthClient, logEntityAccessDecision, logRbac, nextAuthCookieDebugInfo, seedAdministratorPermissions, summarizeEntityPerms, summarizeSessionUserForLog };
|
package/dist/auth.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { S as SessionUser, E as EntityCrudAction, b as EntityPermissionFlags } from './vendor-scope-DTYhJk_I.js';
|
|
2
2
|
export { A as ADMIN_GROUP_NAME, a as AuthHelpers, G as GetSession, O as OPEN_ENDPOINTS, P as PERMISSION_REQUIRED_ENDPOINTS, R as RBAC_ADMIN_ONLY_ENTITIES, V as VENDOR_OWNER_GROUP_NAME, c as VENDOR_SCOPED_STORE_ENTITIES, d as VENDOR_STORE_RBAC_ENTITIES, f as canManageRoles, g as canManageVendorRoles, h as canManageVendorTeam, i as canOnboardVendors, j as createAuthHelpers, k as createCmsAuthBundle, l as getPermissionableEntityKeys, m as getRequiredPermission, n as hasEntityPermission, o as isOpenEndpoint, p as isPlatformAdministrator, q as isPublicMethod, r as isSuperAdminGroupName, s as isVendorGroupName, t as isVendorOwner, u as isVendorPortalUser, v as isVendorStaff, w as permissionRowsToRecord, x as resolveVendorScopeFromSessionUser, y as sessionHasEntityAccess, z as vendorPortalFlagsFromUser } from './vendor-scope-DTYhJk_I.js';
|
|
3
3
|
import { DataSource } from 'typeorm';
|
|
4
|
+
import { getToken } from 'next-auth/jwt';
|
|
4
5
|
import { NextAuthOptions } from 'next-auth';
|
|
5
6
|
|
|
6
7
|
/**
|
|
@@ -79,40 +80,45 @@ declare function logEntityAccessDecision(dataSource: RbacDebugDataSource | undef
|
|
|
79
80
|
*/
|
|
80
81
|
declare function seedAdministratorPermissions(dataSource: DataSource, entityMap: Record<string, unknown>): Promise<void>;
|
|
81
82
|
|
|
83
|
+
interface CmsMiddlewareRequest {
|
|
84
|
+
nextUrl: {
|
|
85
|
+
pathname: string;
|
|
86
|
+
};
|
|
87
|
+
url: string;
|
|
88
|
+
method: string;
|
|
89
|
+
cookies: {
|
|
90
|
+
get: (name: string) => {
|
|
91
|
+
value?: string;
|
|
92
|
+
} | undefined;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Full Next.js request (e.g. `NextRequest`). When provided, session is resolved via
|
|
96
|
+
* `getToken()` so chunked `next-auth.session-token.N` cookies work.
|
|
97
|
+
*/
|
|
98
|
+
req?: Parameters<typeof getToken>[0]['req'];
|
|
99
|
+
}
|
|
82
100
|
interface CmsMiddlewareConfig {
|
|
83
101
|
publicAdminPaths?: string[];
|
|
84
102
|
publicApiPaths?: string[];
|
|
85
103
|
/** path -> allowed methods */
|
|
86
104
|
publicApiMethods?: Record<string, string[]>;
|
|
87
105
|
signInPath?: string;
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
value?: string;
|
|
92
|
-
} | undefined;
|
|
93
|
-
};
|
|
94
|
-
}) => string | undefined;
|
|
106
|
+
/** @deprecated Prefer passing `req` on the request; used only when `req` is omitted. */
|
|
107
|
+
getSessionToken?: (request: CmsMiddlewareRequest) => string | undefined;
|
|
108
|
+
secret?: string;
|
|
95
109
|
}
|
|
96
110
|
/** Default public API paths (no auth). Sites should extend this with their own routes. */
|
|
97
111
|
declare const defaultPublicApiMethods: Record<string, string[]>;
|
|
98
112
|
/**
|
|
99
113
|
* Returns middleware logic. Use from Next.js middleware:
|
|
100
114
|
* import { createCmsMiddleware } from '@infuro/cms-core';
|
|
101
|
-
* export
|
|
115
|
+
* export async function middleware(request: NextRequest) {
|
|
116
|
+
* const result = await cmsMiddleware({ ...request fields, req: request });
|
|
117
|
+
* ...
|
|
118
|
+
* }
|
|
102
119
|
* export const config = { matcher: ['/admin/:path*', '/api/:path*'] };
|
|
103
120
|
*/
|
|
104
|
-
declare function createCmsMiddleware(config?: CmsMiddlewareConfig): (request: {
|
|
105
|
-
nextUrl: {
|
|
106
|
-
pathname: string;
|
|
107
|
-
};
|
|
108
|
-
url: string;
|
|
109
|
-
method: string;
|
|
110
|
-
cookies: {
|
|
111
|
-
get: (name: string) => {
|
|
112
|
-
value?: string;
|
|
113
|
-
} | undefined;
|
|
114
|
-
};
|
|
115
|
-
}) => {
|
|
121
|
+
declare function createCmsMiddleware(config?: CmsMiddlewareConfig): (request: CmsMiddlewareRequest) => Promise<{
|
|
116
122
|
type: "next";
|
|
117
123
|
} | {
|
|
118
124
|
type: "redirect";
|
|
@@ -121,6 +127,15 @@ declare function createCmsMiddleware(config?: CmsMiddlewareConfig): (request: {
|
|
|
121
127
|
type: "json";
|
|
122
128
|
status: number;
|
|
123
129
|
body: unknown;
|
|
124
|
-
}
|
|
130
|
+
}>;
|
|
131
|
+
|
|
132
|
+
/** Set `CMS_AUTH_DEBUG=false` to silence server auth logs in development. */
|
|
133
|
+
declare function isAuthDebugEnabled(): boolean;
|
|
134
|
+
/** Browser console logs; set `NEXT_PUBLIC_CMS_AUTH_DEBUG=false` to silence. */
|
|
135
|
+
declare function isAuthDebugClientEnabled(): boolean;
|
|
136
|
+
declare function logAuth(message: string, data?: Record<string, unknown>): void;
|
|
137
|
+
declare function logAuthClient(message: string, data?: Record<string, unknown>): void;
|
|
138
|
+
declare function summarizeSessionUserForLog(user: unknown): Record<string, unknown>;
|
|
139
|
+
declare function nextAuthCookieDebugInfo(): Record<string, unknown>;
|
|
125
140
|
|
|
126
|
-
export { type AuthorizeOtpInput, type CmsMiddlewareConfig, EntityCrudAction, EntityPermissionFlags, type NextAuthOptionsConfig, type NextAuthUser, SessionUser, createCmsMiddleware, defaultPublicApiMethods, explainSessionEntityAccess, getNextAuthOptions, isRbacDebugEnabled, logEntityAccessDecision, logRbac, seedAdministratorPermissions, summarizeEntityPerms };
|
|
141
|
+
export { type AuthorizeOtpInput, type CmsMiddlewareConfig, type CmsMiddlewareRequest, EntityCrudAction, EntityPermissionFlags, type NextAuthOptionsConfig, type NextAuthUser, SessionUser, createCmsMiddleware, defaultPublicApiMethods, explainSessionEntityAccess, getNextAuthOptions, isAuthDebugClientEnabled, isAuthDebugEnabled, isRbacDebugEnabled, logAuth, logAuthClient, logEntityAccessDecision, logRbac, nextAuthCookieDebugInfo, seedAdministratorPermissions, summarizeEntityPerms, summarizeSessionUserForLog };
|
package/dist/auth.js
CHANGED
|
@@ -491,6 +491,59 @@ async function seedAdministratorPermissions(dataSource, entityMap) {
|
|
|
491
491
|
}
|
|
492
492
|
}
|
|
493
493
|
|
|
494
|
+
// src/auth/middleware.ts
|
|
495
|
+
import { getToken } from "next-auth/jwt";
|
|
496
|
+
|
|
497
|
+
// src/auth/auth-debug.ts
|
|
498
|
+
var LOG_PREFIX2 = "[cms-auth]";
|
|
499
|
+
function isAuthDebugEnabled() {
|
|
500
|
+
const v = process.env.CMS_AUTH_DEBUG?.trim().toLowerCase();
|
|
501
|
+
if (v === "1" || v === "true" || v === "yes") return true;
|
|
502
|
+
if (v === "0" || v === "false" || v === "no") return false;
|
|
503
|
+
return process.env.NODE_ENV === "development";
|
|
504
|
+
}
|
|
505
|
+
function isAuthDebugClientEnabled() {
|
|
506
|
+
if (typeof window === "undefined") return false;
|
|
507
|
+
const v = process.env.NEXT_PUBLIC_CMS_AUTH_DEBUG?.trim().toLowerCase();
|
|
508
|
+
if (v === "1" || v === "true" || v === "yes") return true;
|
|
509
|
+
if (v === "0" || v === "false" || v === "no") return false;
|
|
510
|
+
return process.env.NODE_ENV === "development";
|
|
511
|
+
}
|
|
512
|
+
function logAuth(message, data) {
|
|
513
|
+
if (!isAuthDebugEnabled()) return;
|
|
514
|
+
if (data) console.info(LOG_PREFIX2, message, data);
|
|
515
|
+
else console.info(LOG_PREFIX2, message);
|
|
516
|
+
}
|
|
517
|
+
function logAuthClient(message, data) {
|
|
518
|
+
if (!isAuthDebugClientEnabled()) return;
|
|
519
|
+
if (data) console.info(LOG_PREFIX2, message, data);
|
|
520
|
+
else console.info(LOG_PREFIX2, message);
|
|
521
|
+
}
|
|
522
|
+
function summarizeSessionUserForLog(user) {
|
|
523
|
+
if (!user || typeof user !== "object") return { present: false };
|
|
524
|
+
const u = user;
|
|
525
|
+
return {
|
|
526
|
+
present: true,
|
|
527
|
+
email: u.email ?? null,
|
|
528
|
+
id: u.id ?? null,
|
|
529
|
+
adminAccess: u.adminAccess ?? null,
|
|
530
|
+
isRBACAdmin: u.isRBACAdmin ?? null,
|
|
531
|
+
isVendorPortal: u.isVendorPortal ?? null,
|
|
532
|
+
groupName: u.groupName ?? null
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
function nextAuthCookieDebugInfo() {
|
|
536
|
+
const nextAuthUrl = process.env.NEXTAUTH_URL ?? "(unset)";
|
|
537
|
+
const isHttps = nextAuthUrl.startsWith("https");
|
|
538
|
+
return {
|
|
539
|
+
nextAuthUrl,
|
|
540
|
+
hasSecret: Boolean(process.env.NEXTAUTH_SECRET),
|
|
541
|
+
cookieName: isHttps ? "__Secure-next-auth.session-token" : "next-auth.session-token",
|
|
542
|
+
cookieSecure: isHttps,
|
|
543
|
+
nodeEnv: process.env.NODE_ENV ?? "(unset)"
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
|
|
494
547
|
// src/auth/middleware.ts
|
|
495
548
|
var defaultPublicApiMethods = {
|
|
496
549
|
"/api/contacts": ["POST"],
|
|
@@ -503,8 +556,21 @@ var defaultPublicApiMethods = {
|
|
|
503
556
|
"/api/users/set-password": ["POST"],
|
|
504
557
|
"/api/users/invite": ["POST"]
|
|
505
558
|
};
|
|
506
|
-
function
|
|
507
|
-
|
|
559
|
+
function legacyGetSessionToken(request) {
|
|
560
|
+
const secure = request.cookies.get("__Secure-next-auth.session-token")?.value;
|
|
561
|
+
const regular = request.cookies.get("next-auth.session-token")?.value;
|
|
562
|
+
return secure ?? regular;
|
|
563
|
+
}
|
|
564
|
+
function sessionCookiePresence(request) {
|
|
565
|
+
const secure = request.cookies.get("__Secure-next-auth.session-token")?.value;
|
|
566
|
+
const regular = request.cookies.get("next-auth.session-token")?.value;
|
|
567
|
+
const hasChunked = Boolean(request.cookies.get("next-auth.session-token.0")?.value) || Boolean(request.cookies.get("__Secure-next-auth.session-token.0")?.value);
|
|
568
|
+
return {
|
|
569
|
+
hasSecureToken: Boolean(secure),
|
|
570
|
+
hasRegularToken: Boolean(regular),
|
|
571
|
+
hasChunkedToken: hasChunked,
|
|
572
|
+
resolved: Boolean(secure ?? regular)
|
|
573
|
+
};
|
|
508
574
|
}
|
|
509
575
|
function isPublicMethod2(pathname, method, publicApiMethods) {
|
|
510
576
|
for (const [endpoint, methods] of Object.entries(publicApiMethods)) {
|
|
@@ -512,31 +578,59 @@ function isPublicMethod2(pathname, method, publicApiMethods) {
|
|
|
512
578
|
}
|
|
513
579
|
return false;
|
|
514
580
|
}
|
|
581
|
+
async function hasValidSession(request, secret, legacyGetToken) {
|
|
582
|
+
if (request.req) {
|
|
583
|
+
const token = await getToken({ req: request.req, secret });
|
|
584
|
+
return token != null;
|
|
585
|
+
}
|
|
586
|
+
return Boolean(legacyGetToken(request));
|
|
587
|
+
}
|
|
515
588
|
function createCmsMiddleware(config = {}) {
|
|
516
589
|
const {
|
|
517
590
|
publicAdminPaths = ["/admin/signin", "/admin/forgot-password", "/admin/reset-password", "/admin/invite"],
|
|
518
591
|
publicApiMethods = defaultPublicApiMethods,
|
|
519
592
|
signInPath = "/admin/signin",
|
|
520
|
-
getSessionToken =
|
|
593
|
+
getSessionToken = legacyGetSessionToken,
|
|
594
|
+
secret = process.env.NEXTAUTH_SECRET
|
|
521
595
|
} = config;
|
|
522
|
-
return function cmsMiddleware(request) {
|
|
596
|
+
return async function cmsMiddleware(request) {
|
|
523
597
|
const pathname = request.nextUrl.pathname;
|
|
524
598
|
const method = request.method;
|
|
525
599
|
if (publicAdminPaths.some((p) => pathname === p || pathname.startsWith(p + "/"))) {
|
|
526
600
|
return { type: "next" };
|
|
527
601
|
}
|
|
528
602
|
if (pathname.startsWith("/admin")) {
|
|
529
|
-
const
|
|
530
|
-
|
|
603
|
+
const authenticated = await hasValidSession(request, secret, getSessionToken);
|
|
604
|
+
const cookies = sessionCookiePresence(request);
|
|
605
|
+
if (!authenticated) {
|
|
606
|
+
logAuth("middleware: admin redirect to signin (no session)", {
|
|
607
|
+
pathname,
|
|
608
|
+
method,
|
|
609
|
+
usesGetToken: Boolean(request.req),
|
|
610
|
+
...cookies,
|
|
611
|
+
expectedCookieName: process.env.NEXTAUTH_URL?.startsWith("https") ? "__Secure-next-auth.session-token" : "next-auth.session-token"
|
|
612
|
+
});
|
|
531
613
|
return { type: "redirect", url: new URL(signInPath, request.url).toString() };
|
|
532
614
|
}
|
|
615
|
+
logAuth("middleware: admin allowed", {
|
|
616
|
+
pathname,
|
|
617
|
+
method,
|
|
618
|
+
usesGetToken: Boolean(request.req),
|
|
619
|
+
...cookies
|
|
620
|
+
});
|
|
533
621
|
}
|
|
534
622
|
if (pathname.startsWith("/api")) {
|
|
535
623
|
if (isPublicMethod2(pathname, method, publicApiMethods)) {
|
|
536
624
|
return { type: "next" };
|
|
537
625
|
}
|
|
538
|
-
const
|
|
539
|
-
if (!
|
|
626
|
+
const authenticated = await hasValidSession(request, secret, getSessionToken);
|
|
627
|
+
if (!authenticated) {
|
|
628
|
+
logAuth("middleware: api 401 (no session)", {
|
|
629
|
+
pathname,
|
|
630
|
+
method,
|
|
631
|
+
usesGetToken: Boolean(request.req),
|
|
632
|
+
...sessionCookiePresence(request)
|
|
633
|
+
});
|
|
540
634
|
return { type: "json", status: 401, body: { error: "Unauthorized" } };
|
|
541
635
|
}
|
|
542
636
|
}
|
|
@@ -591,6 +685,7 @@ function getNextAuthOptions(config) {
|
|
|
591
685
|
enableOtpLogin = false,
|
|
592
686
|
authorizeOtp
|
|
593
687
|
} = config;
|
|
688
|
+
logAuth("getNextAuthOptions init", nextAuthCookieDebugInfo());
|
|
594
689
|
const providers = [];
|
|
595
690
|
if (enablePasswordLogin) {
|
|
596
691
|
providers.push(
|
|
@@ -601,15 +696,43 @@ function getNextAuthOptions(config) {
|
|
|
601
696
|
password: { label: "Password", type: "password" }
|
|
602
697
|
},
|
|
603
698
|
async authorize(credentials) {
|
|
604
|
-
|
|
699
|
+
const email = credentials?.email?.trim() ?? "";
|
|
700
|
+
if (!email || !credentials?.password) {
|
|
701
|
+
logAuth("authorize(credentials) rejected", { reason: "missing_email_or_password" });
|
|
702
|
+
return null;
|
|
703
|
+
}
|
|
605
704
|
try {
|
|
606
|
-
const user = await getUserByEmail(
|
|
607
|
-
if (!user
|
|
705
|
+
const user = await getUserByEmail(email);
|
|
706
|
+
if (!user) {
|
|
707
|
+
logAuth("authorize(credentials) rejected", { reason: "user_not_found", email });
|
|
708
|
+
return null;
|
|
709
|
+
}
|
|
710
|
+
if (user.blocked) {
|
|
711
|
+
logAuth("authorize(credentials) rejected", { reason: "blocked", email, userId: user.id });
|
|
712
|
+
return null;
|
|
713
|
+
}
|
|
714
|
+
if (user.deleted) {
|
|
715
|
+
logAuth("authorize(credentials) rejected", { reason: "deleted", email, userId: user.id });
|
|
716
|
+
return null;
|
|
717
|
+
}
|
|
718
|
+
if (!user.password) {
|
|
719
|
+
logAuth("authorize(credentials) rejected", { reason: "no_password", email, userId: user.id });
|
|
720
|
+
return null;
|
|
721
|
+
}
|
|
608
722
|
const valid = await comparePassword(credentials.password, user.password);
|
|
609
|
-
if (!valid)
|
|
610
|
-
|
|
723
|
+
if (!valid) {
|
|
724
|
+
logAuth("authorize(credentials) rejected", { reason: "invalid_password", email, userId: user.id });
|
|
725
|
+
return null;
|
|
726
|
+
}
|
|
727
|
+
const sessionUser = sessionUserFromNextAuthUser(user);
|
|
728
|
+
logAuth("authorize(credentials) ok", summarizeSessionUserForLog(sessionUser));
|
|
729
|
+
return sessionUser;
|
|
611
730
|
} catch (err) {
|
|
612
731
|
console.error("[cms-auth] authorize error (credentials):", err instanceof Error ? err.message : err);
|
|
732
|
+
logAuth("authorize(credentials) error", {
|
|
733
|
+
email,
|
|
734
|
+
message: err instanceof Error ? err.message : String(err)
|
|
735
|
+
});
|
|
613
736
|
return null;
|
|
614
737
|
}
|
|
615
738
|
}
|
|
@@ -662,6 +785,10 @@ function getNextAuthOptions(config) {
|
|
|
662
785
|
callbacks: {
|
|
663
786
|
async jwt({ token, user, trigger, session }) {
|
|
664
787
|
if (user) {
|
|
788
|
+
logAuth("jwt callback: new sign-in", {
|
|
789
|
+
trigger,
|
|
790
|
+
user: summarizeSessionUserForLog(user)
|
|
791
|
+
});
|
|
665
792
|
const u = user;
|
|
666
793
|
token.id = u.id;
|
|
667
794
|
token.groupId = u.groupId;
|
|
@@ -676,6 +803,7 @@ function getNextAuthOptions(config) {
|
|
|
676
803
|
token.isVendorOwner = u.isVendorOwner;
|
|
677
804
|
}
|
|
678
805
|
if (trigger === "update" && session && typeof session === "object") {
|
|
806
|
+
logAuth("jwt callback: session update", { trigger });
|
|
679
807
|
const s = session;
|
|
680
808
|
const t = token;
|
|
681
809
|
if (typeof s.name === "string") t.name = s.name;
|
|
@@ -685,8 +813,13 @@ function getNextAuthOptions(config) {
|
|
|
685
813
|
return token;
|
|
686
814
|
},
|
|
687
815
|
async session({ session, token }) {
|
|
816
|
+
const t = token;
|
|
817
|
+
logAuth("session callback", {
|
|
818
|
+
tokenHasId: t.id != null,
|
|
819
|
+
tokenEmail: typeof t.email === "string" ? t.email : null,
|
|
820
|
+
sessionUser: summarizeSessionUserForLog(session.user)
|
|
821
|
+
});
|
|
688
822
|
if (session.user) {
|
|
689
|
-
const t = token;
|
|
690
823
|
if (typeof t.name === "string") session.user.name = t.name;
|
|
691
824
|
if (typeof t.email === "string") session.user.email = t.email;
|
|
692
825
|
session.user.id = t.id;
|
|
@@ -728,6 +861,8 @@ export {
|
|
|
728
861
|
getPermissionableEntityKeys,
|
|
729
862
|
getRequiredPermission,
|
|
730
863
|
hasEntityPermission,
|
|
864
|
+
isAuthDebugClientEnabled,
|
|
865
|
+
isAuthDebugEnabled,
|
|
731
866
|
isOpenEndpoint,
|
|
732
867
|
isPlatformAdministrator,
|
|
733
868
|
isPublicMethod,
|
|
@@ -737,13 +872,17 @@ export {
|
|
|
737
872
|
isVendorOwner,
|
|
738
873
|
isVendorPortalUser,
|
|
739
874
|
isVendorStaff,
|
|
875
|
+
logAuth,
|
|
876
|
+
logAuthClient,
|
|
740
877
|
logEntityAccessDecision,
|
|
741
878
|
logRbac,
|
|
879
|
+
nextAuthCookieDebugInfo,
|
|
742
880
|
permissionRowsToRecord,
|
|
743
881
|
resolveVendorScopeFromSessionUser,
|
|
744
882
|
seedAdministratorPermissions,
|
|
745
883
|
sessionHasEntityAccess,
|
|
746
884
|
summarizeEntityPerms,
|
|
885
|
+
summarizeSessionUserForLog,
|
|
747
886
|
vendorPortalFlagsFromUser
|
|
748
887
|
};
|
|
749
888
|
//# sourceMappingURL=auth.js.map
|