@payez/next-mvp 4.5.3 → 4.5.4
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/dist/middleware/create-middleware.js +16 -2
- package/package.json +1042 -1042
- package/src/middleware/create-middleware.ts +16 -2
|
@@ -741,7 +741,16 @@ async function checkViability(
|
|
|
741
741
|
// booleans for unknown/not_configured. The booleans are read ONLY when
|
|
742
742
|
// revocationStatus is ABSENT (idealresume.online's older boolean route).
|
|
743
743
|
sessionStatus.forceInvalid = decideForceInvalid(data, revocationFailMode);
|
|
744
|
-
|
|
744
|
+
// PAY-2216: a STALE session - the cookie resolved to a token, but no store holds the session - used to set
|
|
745
|
+
// pointer.exists=false, so makeAuthDecision took no_session (login, cookie NOT cleared) and its stale_session
|
|
746
|
+
// arm (clearCookies) was unreachable: a dead cookie lingered and re-ran viability on every request.
|
|
747
|
+
// Stale is a POSITIVE signal and needs ALL of: this 2xx read, exists === false, a sessionTokenId (every
|
|
748
|
+
// producer sets it only when a cookie resolved to a token: routes/auth/viability.ts, api-handlers/session/
|
|
749
|
+
// viability.ts, refresh-viability.ts 'session_not_found'), and a session cookie on THIS request (plain or
|
|
750
|
+
// __Secure-). A FAILED read never gets here (exists=null -> service_error, PAY-2147); a store error throws
|
|
751
|
+
// inside every producer and answers 5xx or 'unknown' WITHOUT a sessionTokenId; no cookie -> no_session.
|
|
752
|
+
const stale = sessionStatus.exists === false && !!data.sessionTokenId && hasSessionCookie(request);
|
|
753
|
+
sessionPointer.exists = stale ? true : (sessionStatus.exists ?? false);
|
|
745
754
|
sessionPointer.sessionTokenId = data.sessionTokenId ?? null;
|
|
746
755
|
sessionPointer.expired = data.accessTokenExpired || false;
|
|
747
756
|
sessionPointer.hasRefreshToken = data.hasRefreshToken ?? data.canRefresh ?? false;
|
|
@@ -815,7 +824,12 @@ async function handleAllow(
|
|
|
815
824
|
): Promise<NextResponse> {
|
|
816
825
|
const isPublic = isUnauthenticatedRoute(pathname);
|
|
817
826
|
|
|
818
|
-
|
|
827
|
+
// PAY-2216: RBAC needs a session that viability CONFIRMED. A stale /api request (pointer.exists only says the
|
|
828
|
+
// cookie is present, status.exists is false) is allowed through so the route handler answers its own 401 - not an
|
|
829
|
+
// RBAC 401 here. TRUTHY, not `=== true` (NightHawk 71960): status.exists carries the producer's JSON value as-is,
|
|
830
|
+
// and a consumer route may answer authenticated: 1 / "true"; `=== true` skipped RBAC for those healthy sessions
|
|
831
|
+
// (fail-OPEN). Truthy keeps 4.5.3's RBAC coverage exactly and still excludes stale (false) and a failed read (null).
|
|
832
|
+
if (isRBACEnabled() && !isPublic && sessionPointer.exists && sessionStatus.exists) {
|
|
819
833
|
// Skip RBAC for error/fallback pages (prevent redirect loops) and app-configured exempt paths
|
|
820
834
|
if (RBAC_EXEMPT_PATHS.some(p => pathname.startsWith(p)) ||
|
|
821
835
|
rbacExemptPaths.some(p => pathname.startsWith(p))) {
|