najm-auth 3.0.0 → 3.1.1

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 CHANGED
@@ -198,13 +198,13 @@ All routes are prefixed with `/auth` and auto-registered by the plugin.
198
198
 
199
199
  ### Identity presets
200
200
 
201
- Login lookup, lockout accounting, and rate-limit bucketing all normalize the
202
- submitted identifier the same way. The pipeline is: email (lowercased) →
203
- project extensions → the country preset → generic E.164.
204
-
205
- The resolved pipeline belongs to the specific `auth()` plugin/server instance.
206
- Multiple isolated Najm servers can therefore use different country presets in
207
- one process without replacing each other's login or rate-limit behavior.
201
+ Login lookup, lockout accounting, and rate-limit bucketing all normalize the
202
+ submitted identifier the same way. The pipeline is: email (lowercased) →
203
+ project extensions → the country preset → generic E.164.
204
+
205
+ The resolved pipeline belongs to the specific `auth()` plugin/server instance.
206
+ Multiple isolated Najm servers can therefore use different country presets in
207
+ one process without replacing each other's login or rate-limit behavior.
208
208
 
209
209
  Morocco is the default, so `0612345678`, `212612345678`, and `+212612345678`
210
210
  all resolve to `+212612345678` with no configuration.
@@ -249,10 +249,10 @@ await authService.provisionUser({
249
249
  });
250
250
  ```
251
251
 
252
- Supplying both `password` and `temporaryCredential` is rejected, so an account
253
- can never hold a permanent password that something also treats as temporary.
254
- Typed helpers such as `moroccanCinTemporaryCredential()` validate their value,
255
- and every temporary credential remains limited to bcrypt's 72-byte boundary.
252
+ Supplying both `password` and `temporaryCredential` is rejected, so an account
253
+ can never hold a permanent password that something also treats as temporary.
254
+ Typed helpers such as `moroccanCinTemporaryCredential()` validate their value,
255
+ and every temporary credential remains limited to bcrypt's 72-byte boundary.
256
256
 
257
257
  Login then answers a discriminated result instead of a token pair:
258
258
 
@@ -743,6 +743,174 @@ auth({
743
743
 
744
744
  ---
745
745
 
746
+ ## Next.js App Router Structure
747
+
748
+ Every App Router application keeps the same three files. Copying more than this
749
+ between apps means logic that belongs in the package has leaked into them.
750
+
751
+ ```text
752
+ src/lib/auth.ts defineAuth() configuration — browser, server, and proxy safe
753
+ src/lib/session.ts one createReactServerAuth() instance for Server Components
754
+ src/proxy.ts imports auth.ts only, and exports auth.middleware
755
+ ```
756
+
757
+ ```typescript
758
+ // src/lib/auth.ts
759
+ import { defineAuth } from 'najm-auth/client/server';
760
+
761
+ export const auth = defineAuth({
762
+ apiBaseURL: '/api',
763
+ loginRoute: '/login',
764
+ forbiddenRoute: '/forbidden',
765
+ publicRoutes: ['/', '/login'],
766
+ protectedRoutes: ['/dashboard/:path*', '/admin/:path*'],
767
+ roleRoutes: { '/admin/:path*': ['admin'] },
768
+ });
769
+ ```
770
+
771
+ ```typescript
772
+ // src/lib/session.ts
773
+ import 'server-only';
774
+
775
+ import { createReactServerAuth } from 'najm-auth/client/server/react';
776
+
777
+ import { auth } from './auth';
778
+
779
+ export const serverAuth = createReactServerAuth(auth);
780
+ ```
781
+
782
+ ```typescript
783
+ // src/proxy.ts
784
+ import { auth } from './lib/auth';
785
+
786
+ export default auth.middleware;
787
+ export const config = auth.config;
788
+ ```
789
+
790
+ ### Why `session.ts` exists
791
+
792
+ A Next.js page is not one function. The root layout, each nested layout, and the
793
+ page render separately, and each one that asks for the session pays for its own
794
+ cookie verification and possibly its own recovery round trip. React's `cache()`
795
+ collapses those into one — but only for callers that go through the *same*
796
+ memoized function, which means the application has to own one module that
797
+ creates it. `session.ts` is that module and nothing else; strictness, redirect
798
+ targets, role fallback, and error classification all stay in the package.
799
+
800
+ ```tsx
801
+ // Root layout, nested layout, and page: one resolution between them.
802
+ const session = await serverAuth.getSession(); // null when anonymous
803
+ const session = await serverAuth.requireSession(); // redirects to loginRoute
804
+ const session = await serverAuth.requireRole(['admin', 'operator']);
805
+ ```
806
+
807
+ - `requireSession()` redirects to `loginRoute` when the visitor is missing,
808
+ invalid, or revoked. An unreachable recovery endpoint or an unset session
809
+ secret is an operational fault, not an anonymous visitor: those stay visible
810
+ errors instead of becoming a login redirect that hides the outage.
811
+ - `requireRole()` redirects to `forbiddenRoute`, never to login — the visitor is
812
+ already authenticated, so signing in again cannot change the answer.
813
+ - `session.roles` is authoritative when present, with `user.role` as the
814
+ single-role fallback.
815
+
816
+ ### Scope and limits
817
+
818
+ - **React Server Components only.** Route handlers, server actions, proxy/Edge
819
+ code, and scripts keep using `auth.getSession()`, `auth.requireSession()`, and
820
+ `auth.requireRole()`. Outside a render there is no request cache for `cache()`
821
+ to write to, so the adapter would resolve the session again on every call.
822
+ - **Call the factory once, at module scope.** Calling it inside a layout, page,
823
+ or component builds a fresh memoized resolver per call and shares nothing.
824
+ - **The snapshot is stable for one render.** Code that mutates authentication
825
+ must redirect or refresh into a new render to observe the result.
826
+ - **Requests never share.** The cache is React's per-request cache — no module
827
+ map, no global, no Redis, no `unstable_cache`, no `"use cache"`.
828
+ - **Requires React 18.3 or newer** (the first version exporting `cache()`); the
829
+ factory throws a named error on older versions. The subpath is opt-in, so
830
+ non-React consumers of `najm-auth` are unaffected. Importing it from a Client
831
+ Component or the Edge runtime fails at build time.
832
+
833
+ ### `auth.ts` and `session.ts` cannot be merged
834
+
835
+ Two files looks like one too many until you try it. Both directions fail, for
836
+ the same reason in mirror image:
837
+
838
+ | Module | Must be reachable from | Must never be reachable from |
839
+ |---|---|---|
840
+ | the `defineAuth()` module | browser, Edge, server | — |
841
+ | the `createReactServerAuth()` module | server only | browser, Edge |
842
+
843
+ `auth.client` and `auth.api` are what Client Components call, and
844
+ `auth.middleware` is what the Edge proxy calls, so the `defineAuth()` module is
845
+ always in the browser and Edge graphs. The adapter must never be. Putting both
846
+ in one file puts the adapter everywhere `auth` already is, and the `browser`
847
+ export condition — which exists precisely to catch this — resolves to a module
848
+ that throws:
849
+
850
+ ```text
851
+ The export createReactServerAuth was not found in module
852
+ …/najm-auth/dist/client/server/reactClientGuard.js [app-client]
853
+
854
+ Import traces:
855
+ Middleware: ./src/lib/auth.ts → ./src/proxy.ts
856
+ Client Component Browser: ./src/lib/auth.ts → … → ./src/app/dashboard/page.tsx
857
+ Client Component SSR: ./src/lib/auth.ts → … → ./src/app/dashboard/page.tsx
858
+ Server Component: ./src/lib/auth.ts → ./src/lib/session.ts → layout.tsx
859
+ ```
860
+
861
+ Renaming the files changes nothing; there simply have to be two. This is a
862
+ property of the runtime boundary, not of the package.
863
+
864
+ ### Protected trees must opt out of prerendering
865
+
866
+ `requireSession()` reads a per-request cookie. A route Next.js tries to
867
+ prerender has no request, so the read fails and the guard reports a
868
+ configuration error — correct behavior, wrong context. Mark the protected
869
+ segment dynamic:
870
+
871
+ ```tsx
872
+ // src/app/(dashboard)/layout.tsx
873
+ export const dynamic = 'force-dynamic';
874
+
875
+ export default async function DashboardLayout({ children }) {
876
+ await serverAuth.requireSession();
877
+ return <Shell>{children}</Shell>;
878
+ }
879
+ ```
880
+
881
+ `getSession()` needs no such opt-out — it returns `null` rather than throwing,
882
+ so a prerendered public page renders anonymous. Do not "fix" a prerender failure
883
+ by wrapping a strict guard in `.catch(() => null)`; that turns a real outage
884
+ into a silently anonymous page.
885
+
886
+ ### What the app owns, what the package owns
887
+
888
+ | App, via `defineAuth()` | Package |
889
+ |---|---|
890
+ | `loginRoute`, `forbiddenRoute`, route matchers, `roleRoutes` | when to redirect where |
891
+ | cookie names, `apiBaseURL`, `authPrefix`, recovery URL | request memoization |
892
+ | `refreshThreshold`, `tabSync`, `verifyAlways` | strict vs optional semantics |
893
+ | — | `session.roles` / `user.role` fallback |
894
+ | — | error classification |
895
+
896
+ If a new app has to copy anything beyond the three files above, that logic
897
+ belongs in the package instead.
898
+
899
+ ### What a new app must prove
900
+
901
+ At its real Next.js production boundary, not with mocks:
902
+
903
+ - two concurrent renders never observe each other's session;
904
+ - root layout, nested layout, and page resolve once per render — measurable by
905
+ counting recovery round trips;
906
+ - anonymous navigation to a protected route redirects to `loginRoute`;
907
+ - an authenticated role mismatch reaches `forbiddenRoute` without a login loop;
908
+ - an unset session secret or an unreachable recovery endpoint stays a visible
909
+ failure rather than a login redirect;
910
+ - the Edge/proxy bundle builds without pulling in React.
911
+
912
+ ---
913
+
746
914
  ## TypeScript Types
747
915
 
748
916
  ```typescript
@@ -0,0 +1,120 @@
1
+ import { R as RetryConfig, a as RequestOptions, A as AuthUser, b as AuthClientConfig, L as LoginCredentials, c as LoginResult, O as OAuthProvider, d as OAuthLoginOptions, e as AuthState, f as AuthEvent, g as AuthEventHandler } from './types-BaSfgxqE.js';
2
+
3
+ interface FetchClientConfig {
4
+ baseURL: string;
5
+ credentials?: RequestCredentials;
6
+ timeout?: number;
7
+ getToken?: () => string | null;
8
+ onUnauthorized?: () => Promise<string | null>;
9
+ retry?: RetryConfig;
10
+ defaultHeaders?: Record<string, string>;
11
+ }
12
+ declare class FetchClient {
13
+ private config;
14
+ constructor(config: FetchClientConfig);
15
+ get<T>(path: string, opts?: RequestOptions): Promise<T>;
16
+ post<T>(path: string, opts?: RequestOptions): Promise<T>;
17
+ put<T>(path: string, opts?: RequestOptions): Promise<T>;
18
+ patch<T>(path: string, opts?: RequestOptions): Promise<T>;
19
+ delete<T>(path: string, opts?: RequestOptions): Promise<T>;
20
+ private request;
21
+ private execute;
22
+ private doFetch;
23
+ private parseBody;
24
+ }
25
+
26
+ interface HydrateSession {
27
+ user: AuthUser | null;
28
+ accessToken?: string | null;
29
+ roles?: string[];
30
+ permissions?: string[];
31
+ }
32
+ declare class NajmAuthClient {
33
+ private config;
34
+ private static readonly MAX_REFRESH_FAILURES;
35
+ private static readonly CIRCUIT_RESET_MS;
36
+ private state;
37
+ private refreshTimer;
38
+ private refreshCircuitTimer;
39
+ private refreshPromise;
40
+ private fetchUserPromise;
41
+ private refreshFailures;
42
+ private _hydrated;
43
+ private listeners;
44
+ private eventListeners;
45
+ private tabSync;
46
+ api: FetchClient;
47
+ private readonly prefix;
48
+ private readonly threshold;
49
+ constructor(config: AuthClientConfig);
50
+ login(credentials: LoginCredentials): Promise<LoginResult>;
51
+ register(data: Record<string, unknown>): Promise<AuthUser>;
52
+ getOAuthLoginUrl(provider: OAuthProvider, options?: OAuthLoginOptions): string;
53
+ loginWithOAuth(provider: OAuthProvider, options?: OAuthLoginOptions): void;
54
+ loginWithGoogle(options?: OAuthLoginOptions): void;
55
+ linkOAuthAccount(provider: OAuthProvider, options?: OAuthLoginOptions): Promise<void>;
56
+ completeOAuthLogin(): Promise<AuthUser>;
57
+ logout(): Promise<void>;
58
+ refresh(): Promise<void>;
59
+ fetchUser(): Promise<AuthUser | null>;
60
+ private _doFetchUser;
61
+ forgotPassword(data: {
62
+ email: string;
63
+ }): Promise<void>;
64
+ changePassword(data: {
65
+ currentPassword: string;
66
+ newPassword: string;
67
+ }): Promise<void>;
68
+ resetPassword(data: {
69
+ token: string;
70
+ newPassword: string;
71
+ }): Promise<void>;
72
+ can(permission: string): boolean;
73
+ hasRole(role: string): boolean;
74
+ hasAnyRole(roles: string[]): boolean;
75
+ hasPermission(permission: string): boolean;
76
+ getUser(): AuthUser | null;
77
+ getAccessToken(): string | null;
78
+ isAuthenticated(): boolean;
79
+ getState(): AuthState;
80
+ /**
81
+ * Hydrate the client with a session resolved server-side.
82
+ * Use to skip the initial loading flicker on SSR-rendered pages.
83
+ * Safe to call multiple times — subsequent calls are no-ops.
84
+ */
85
+ hydrate(session: HydrateSession | null): void;
86
+ isHydrated(): boolean;
87
+ /**
88
+ * A fresh client with the same config — unhydrated, and without tab sync.
89
+ *
90
+ * Server rendering needs one client per request. A single process serves
91
+ * every user, so the hydration latch on a shared client would otherwise pin
92
+ * every later render to the first request's session.
93
+ */
94
+ fork(): NajmAuthClient;
95
+ on<K extends AuthEvent>(event: K, handler: AuthEventHandler<K>): void;
96
+ off<K extends AuthEvent>(event: K, handler: AuthEventHandler<K>): void;
97
+ subscribe(listener: (state: AuthState) => void): () => void;
98
+ destroy(): void;
99
+ private _refreshWithCircuit;
100
+ private _doRefresh;
101
+ private handleUnauthorized;
102
+ private applyTokens;
103
+ private scheduleRefresh;
104
+ private clearRefreshTimer;
105
+ private clearRefreshCircuitTimer;
106
+ private resetRefreshFailures;
107
+ private registerRefreshFailure;
108
+ private resetState;
109
+ private getSyncPayload;
110
+ private handleTabMessage;
111
+ private notify;
112
+ private emit;
113
+ private validateReturnTo;
114
+ }
115
+ /**
116
+ * Factory function to create an auth client.
117
+ */
118
+ declare function createAuthClient(config: AuthClientConfig): NajmAuthClient;
119
+
120
+ export { FetchClient as F, type HydrateSession as H, NajmAuthClient as N, createAuthClient as c };
@@ -1,21 +1,6 @@
1
1
  import * as next_server from 'next/server';
2
-
3
- type SessionRecoveryFailureReason = 'invalid-cookie-name' | 'invalid-refresh-cookie' | 'invalid-endpoint' | 'fetch-error' | 'http-status' | 'missing-set-cookie' | 'session-cookie-parse' | 'session-cookie-hmac' | 'session-cookie-payload';
4
- interface SessionRecoveryErrorDetails {
5
- name: string;
6
- message: string;
7
- code?: string;
8
- cause?: {
9
- name: string;
10
- message: string;
11
- code?: string;
12
- };
13
- }
14
- interface SessionRecoveryFailure {
15
- reason: SessionRecoveryFailureReason;
16
- httpStatus?: number;
17
- error?: SessionRecoveryErrorDetails;
18
- }
2
+ import { S as SessionRecoveryFailure } from '../sessionRecovery-D5Fa0yZ1.js';
3
+ export { a as SessionRecoveryErrorDetails, b as SessionRecoveryFailureReason } from '../sessionRecovery-D5Fa0yZ1.js';
19
4
 
20
5
  interface AuthMiddlewareConfig {
21
6
  /** Routes that require authentication (glob patterns) */
@@ -82,4 +67,4 @@ interface AuthMiddlewareConfig {
82
67
  */
83
68
  declare function withAuthMiddleware(config: AuthMiddlewareConfig): (request: Request) => Promise<next_server.NextResponse<unknown>>;
84
69
 
85
- export { type AuthMiddlewareConfig, type SessionRecoveryErrorDetails, type SessionRecoveryFailure, type SessionRecoveryFailureReason, withAuthMiddleware };
70
+ export { type AuthMiddlewareConfig, SessionRecoveryFailure, withAuthMiddleware };
@@ -1,5 +1,6 @@
1
- import { D as DecodedToken, T as TabSyncMessage, S as SyncPayload } from '../NajmAuthClient-D2fSvQ_H.js';
2
- export { A as AuthClientConfig, a as AuthError, b as AuthEvent, c as AuthEventHandler, d as AuthEventMap, e as AuthState, f as AuthUser, g as AuthenticatedLogin, C as CredentialSetupPending, F as FetchClient, H as HydrateSession, L as LoginCredentials, h as LoginResult, N as NajmAuthClient, O as OAuthLoginOptions, i as OAuthProvider, R as RequestOptions, j as RetryConfig, k as ServerResponse, l as TokenPair, m as createAuthClient } from '../NajmAuthClient-D2fSvQ_H.js';
1
+ export { F as FetchClient, H as HydrateSession, N as NajmAuthClient, c as createAuthClient } from '../NajmAuthClient-DqGucYXi.js';
2
+ import { D as DecodedToken, T as TabSyncMessage, S as SyncPayload } from '../types-BaSfgxqE.js';
3
+ export { b as AuthClientConfig, h as AuthError, f as AuthEvent, g as AuthEventHandler, i as AuthEventMap, e as AuthState, A as AuthUser, j as AuthenticatedLogin, C as CredentialSetupPending, L as LoginCredentials, c as LoginResult, d as OAuthLoginOptions, O as OAuthProvider, a as RequestOptions, R as RetryConfig, k as ServerResponse, l as TokenPair } from '../types-BaSfgxqE.js';
3
4
 
4
5
  /**
5
6
  * Decode a JWT token payload without verification.
@@ -1,7 +1,8 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as react from 'react';
3
3
  import { ReactNode, CSSProperties, ReactElement } from 'react';
4
- import { N as NajmAuthClient, H as HydrateSession, e as AuthState, f as AuthUser, h as LoginResult, a as AuthError, L as LoginCredentials, O as OAuthLoginOptions, b as AuthEvent, d as AuthEventMap } from '../../NajmAuthClient-D2fSvQ_H.js';
4
+ import { N as NajmAuthClient, H as HydrateSession } from '../../NajmAuthClient-DqGucYXi.js';
5
+ import { e as AuthState, A as AuthUser, c as LoginResult, h as AuthError, L as LoginCredentials, d as OAuthLoginOptions, f as AuthEvent, i as AuthEventMap } from '../../types-BaSfgxqE.js';
5
6
 
6
7
  interface AuthProviderProps {
7
8
  client: NajmAuthClient;
@@ -1,6 +1,10 @@
1
- import { f as AuthUser, F as FetchClient, N as NajmAuthClient, j as RetryConfig } from '../../NajmAuthClient-D2fSvQ_H.js';
2
- import { SessionRecoveryFailure } from '../edge.js';
3
- export { SessionRecoveryErrorDetails, SessionRecoveryFailureReason, withAuthMiddleware } from '../edge.js';
1
+ import { A as AuthUser, R as RetryConfig } from '../../types-BaSfgxqE.js';
2
+ import { F as FetchClient, N as NajmAuthClient } from '../../NajmAuthClient-DqGucYXi.js';
3
+ export { withAuthMiddleware } from '../edge.js';
4
+ import { G as GetSessionConfig, S as ServerSession$1 } from '../../getSession-BthP85UA.js';
5
+ export { A as AuthConfigError, a as AuthTransportError, N as NoSessionError, g as getSession } from '../../getSession-BthP85UA.js';
6
+ import { S as SessionRecoveryFailure } from '../../sessionRecovery-D5Fa0yZ1.js';
7
+ export { a as SessionRecoveryErrorDetails, b as SessionRecoveryFailureReason } from '../../sessionRecovery-D5Fa0yZ1.js';
4
8
  import 'next/server';
5
9
 
6
10
  interface GetServerSessionOptions {
@@ -11,7 +15,7 @@ interface GetServerSessionOptions {
11
15
  /** Additional headers to forward (e.g., Authorization) */
12
16
  headers?: Record<string, string>;
13
17
  }
14
- interface ServerSession$1 {
18
+ interface ServerSession {
15
19
  user: AuthUser;
16
20
  }
17
21
  /**
@@ -35,7 +39,7 @@ interface ServerSession$1 {
35
39
  * }
36
40
  * ```
37
41
  */
38
- declare function getServerSession(opts: GetServerSessionOptions): Promise<ServerSession$1 | null>;
42
+ declare function getServerSession(opts: GetServerSessionOptions): Promise<ServerSession | null>;
39
43
 
40
44
  interface ServerClientConfig {
41
45
  /** API base URL (e.g., 'http://localhost:3000/api') */
@@ -65,70 +69,6 @@ interface ServerClientConfig {
65
69
  */
66
70
  declare function createServerClient(config: ServerClientConfig): FetchClient;
67
71
 
68
- interface ServerSession {
69
- user: AuthUser;
70
- roles?: string[];
71
- permissions?: string[];
72
- }
73
- interface GetSessionConfig {
74
- /**
75
- * Base URL for auth endpoints.
76
- * Defaults to `NEXT_PUBLIC_API_URL` or the same-origin `/api` path.
77
- */
78
- baseURL?: string;
79
- /** Auth route prefix appended to baseURL (default: '/auth'). */
80
- authPrefix?: string;
81
- /** Refresh token cookie name (default: 'refreshToken'). */
82
- cookieName?: string;
83
- /** Signed session cookie name (default: 'najm.session'). */
84
- sessionCookieName?: string;
85
- /**
86
- * Secret used to verify the session cookie HMAC signature.
87
- * Falls back to NAJM_SESSION_SECRET or JWT_ACCESS_SECRET env vars.
88
- */
89
- sessionSecret?: string;
90
- /**
91
- * Maximum accepted session-cookie age in seconds.
92
- * Must match the auth plugin's `session.maxAge`. Default: 300.
93
- */
94
- sessionMaxAge?: number;
95
- /**
96
- * Session-recovery endpoint. Defaults to
97
- * `${baseURL}${authPrefix}/session/recover`. Set to false to disable fallback.
98
- */
99
- recoveryURL?: string | false;
100
- /** Loopback-only recovery endpoint for self-hosted reverse-proxy setups. */
101
- internalRecoveryURL?: string;
102
- /**
103
- * Error handling mode:
104
- * - 'nullable' (default): returns null on any failure
105
- * - 'strict': throws typed errors for debugging
106
- */
107
- mode?: 'nullable' | 'strict';
108
- /** Secret-free diagnostic hook for failed recovery attempts. */
109
- onRecoveryFailure?: (failure: SessionRecoveryFailure) => void;
110
- }
111
- declare class NoSessionError extends Error {
112
- readonly code = "NO_SESSION";
113
- constructor(message?: string);
114
- }
115
- declare class AuthConfigError extends Error {
116
- readonly code = "AUTH_CONFIG_ERROR";
117
- constructor(message: string);
118
- }
119
- declare class AuthTransportError extends Error {
120
- readonly status?: number;
121
- readonly code = "AUTH_TRANSPORT_ERROR";
122
- constructor(message: string, status?: number);
123
- }
124
- /**
125
- * Resolve a session in a Next.js Server Component, Route Handler, or Server
126
- * Action. Recovery returns claims for the current render but cannot persist
127
- * response cookies during Server Component rendering; middleware performs that
128
- * persistence for protected navigation.
129
- */
130
- declare function getSession(config?: GetSessionConfig): Promise<ServerSession | null>;
131
-
132
72
  interface WithAuthOptions extends GetSessionConfig {
133
73
  /** Where to redirect unauthenticated requests (default: '/login') */
134
74
  redirectTo?: string;
@@ -138,7 +78,7 @@ interface WithAuthOptions extends GetSessionConfig {
138
78
  permission?: string;
139
79
  }
140
80
  interface WithAuthProps<P> {
141
- session: ServerSession;
81
+ session: ServerSession$1;
142
82
  props: P;
143
83
  }
144
84
  /**
@@ -219,9 +159,9 @@ interface AuthKit {
219
159
  /** Shortcut for `client.api` — the underlying FetchClient with auth attached. */
220
160
  readonly api: FetchClient;
221
161
  /** Resolve session — signed-cookie first, then non-rotating recovery. */
222
- getSession: (opts?: Pick<GetSessionConfig, 'mode'>) => Promise<ServerSession | null>;
162
+ getSession: (opts?: Pick<GetSessionConfig, 'mode'>) => Promise<ServerSession$1 | null>;
223
163
  /** Require session — throws if unauthenticated */
224
- requireSession: () => Promise<ServerSession>;
164
+ requireSession: () => Promise<ServerSession$1>;
225
165
  /**
226
166
  * Require one of `roles` — redirects to `loginRoute` when unauthenticated and
227
167
  * to `forbiddenRoute` when authenticated as the wrong role.
@@ -230,7 +170,7 @@ interface AuthKit {
230
170
  * const session = await auth.requireRole(['admin', 'operator']);
231
171
  * ```
232
172
  */
233
- requireRole: (roles: string[]) => Promise<ServerSession>;
173
+ requireRole: (roles: string[]) => Promise<ServerSession$1>;
234
174
  /** Generated Next.js middleware function */
235
175
  middleware: (request: Request) => Promise<Response>;
236
176
  /** Next.js middleware config with matcher */
@@ -242,7 +182,7 @@ interface AuthKit {
242
182
  * Passes session to the wrapped component.
243
183
  */
244
184
  protect: <P extends Record<string, unknown> = Record<string, unknown>>(Page: (args: {
245
- session: ServerSession;
185
+ session: ServerSession$1;
246
186
  children?: unknown;
247
187
  } & P) => Promise<unknown> | unknown, options?: {
248
188
  role?: string;
@@ -332,4 +272,4 @@ declare function makeSessionCookie(setCookie: string, authCookieNames?: string[]
332
272
  */
333
273
  declare function withAuthCookiePersistence(handler: RequestHandler, options?: AuthCookiePersistenceOptions): RequestHandler;
334
274
 
335
- export { AuthConfigError, type AuthCookiePersistenceOptions, type AuthKit, AuthTransportError, type DefineAuthConfig, type GetSessionConfig, NoSessionError, type SafeRedirectOptions, type ServerSession, SessionRecoveryFailure, type WithAuthOptions, type WithAuthProps, createServerClient, defineAuth, getSafeRedirectPath, getServerSession, getSession, makeSessionCookie, withAuth, withAuthCookiePersistence };
275
+ export { type AuthCookiePersistenceOptions, type AuthKit, type DefineAuthConfig, GetSessionConfig, type SafeRedirectOptions, ServerSession$1 as ServerSession, SessionRecoveryFailure, type WithAuthOptions, type WithAuthProps, createServerClient, defineAuth, getSafeRedirectPath, getServerSession, makeSessionCookie, withAuth, withAuthCookiePersistence };