next-token-auth 1.0.0
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 +520 -0
- package/dist/index.d.mts +283 -0
- package/dist/index.d.ts +283 -0
- package/dist/index.js +619 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +606 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +63 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
type ExpiryInput = number | string;
|
|
5
|
+
type ExpiryStrategy = "backend" | "config" | "hybrid";
|
|
6
|
+
interface AuthTokens {
|
|
7
|
+
accessToken: string;
|
|
8
|
+
refreshToken: string;
|
|
9
|
+
/** Unix timestamp (ms) */
|
|
10
|
+
accessTokenExpiresAt: number;
|
|
11
|
+
/** Unix timestamp (ms) */
|
|
12
|
+
refreshTokenExpiresAt?: number;
|
|
13
|
+
}
|
|
14
|
+
interface AuthSession<User = unknown> {
|
|
15
|
+
user: User | null;
|
|
16
|
+
tokens: AuthTokens | null;
|
|
17
|
+
isAuthenticated: boolean;
|
|
18
|
+
}
|
|
19
|
+
interface LoginInput {
|
|
20
|
+
[key: string]: unknown;
|
|
21
|
+
}
|
|
22
|
+
interface LoginResponse<User = unknown> {
|
|
23
|
+
user: User;
|
|
24
|
+
accessToken: string;
|
|
25
|
+
refreshToken: string;
|
|
26
|
+
/** Seconds until access token expires (legacy field) */
|
|
27
|
+
expiresIn?: number;
|
|
28
|
+
accessTokenExpiresIn?: number | string;
|
|
29
|
+
refreshTokenExpiresIn?: number | string;
|
|
30
|
+
}
|
|
31
|
+
interface AuthConfig<User = unknown> {
|
|
32
|
+
/** Base URL of your backend API */
|
|
33
|
+
baseUrl: string;
|
|
34
|
+
endpoints: {
|
|
35
|
+
login: string;
|
|
36
|
+
register?: string;
|
|
37
|
+
refresh: string;
|
|
38
|
+
logout?: string;
|
|
39
|
+
/** Endpoint to fetch the current user profile */
|
|
40
|
+
me?: string;
|
|
41
|
+
};
|
|
42
|
+
routes?: {
|
|
43
|
+
/** Paths that are always accessible without auth */
|
|
44
|
+
public: string[];
|
|
45
|
+
/** Paths that require authentication */
|
|
46
|
+
protected: string[];
|
|
47
|
+
};
|
|
48
|
+
token: {
|
|
49
|
+
storage: "cookie" | "memory";
|
|
50
|
+
cookieName?: string;
|
|
51
|
+
secure?: boolean;
|
|
52
|
+
sameSite?: "strict" | "lax" | "none";
|
|
53
|
+
};
|
|
54
|
+
/** Secret used for encrypting stored tokens */
|
|
55
|
+
secret: string;
|
|
56
|
+
/** Automatically refresh access token before expiry */
|
|
57
|
+
autoRefresh?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Seconds before expiry to trigger a proactive refresh.
|
|
60
|
+
* @default 60
|
|
61
|
+
*/
|
|
62
|
+
refreshThreshold?: number;
|
|
63
|
+
expiry?: {
|
|
64
|
+
accessTokenExpiresIn?: ExpiryInput;
|
|
65
|
+
refreshTokenExpiresIn?: ExpiryInput;
|
|
66
|
+
/**
|
|
67
|
+
* - "backend" → trust expiresIn from API response
|
|
68
|
+
* - "config" → use config values only
|
|
69
|
+
* - "hybrid" → backend first, fallback to config
|
|
70
|
+
* @default "hybrid"
|
|
71
|
+
*/
|
|
72
|
+
strategy?: ExpiryStrategy;
|
|
73
|
+
};
|
|
74
|
+
/** Optional custom fetch implementation */
|
|
75
|
+
fetchFn?: typeof fetch;
|
|
76
|
+
/** Called after a successful login */
|
|
77
|
+
onLogin?: (session: AuthSession<User>) => void;
|
|
78
|
+
/** Called after logout */
|
|
79
|
+
onLogout?: () => void;
|
|
80
|
+
/** Called when token refresh fails */
|
|
81
|
+
onRefreshError?: (error: unknown) => void;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Manages storage, retrieval, and expiry checks for auth tokens.
|
|
86
|
+
* Supports "cookie" and "memory" storage strategies.
|
|
87
|
+
*/
|
|
88
|
+
declare class TokenManager {
|
|
89
|
+
private memoryStore;
|
|
90
|
+
private readonly config;
|
|
91
|
+
constructor(config: AuthConfig);
|
|
92
|
+
getTokens(): AuthTokens | null;
|
|
93
|
+
setTokens(tokens: AuthTokens): Promise<void>;
|
|
94
|
+
clearTokens(): void;
|
|
95
|
+
isAccessExpired(tokens: AuthTokens): boolean;
|
|
96
|
+
isRefreshExpired(tokens: AuthTokens): boolean;
|
|
97
|
+
private cookieName;
|
|
98
|
+
private readFromCookie;
|
|
99
|
+
private writeToCookie;
|
|
100
|
+
private deleteCookie;
|
|
101
|
+
/**
|
|
102
|
+
* Encrypts tokens for secure server-side cookie storage.
|
|
103
|
+
*/
|
|
104
|
+
encryptTokens(tokens: AuthTokens): Promise<string>;
|
|
105
|
+
/**
|
|
106
|
+
* Decrypts tokens from a server-side cookie value.
|
|
107
|
+
*/
|
|
108
|
+
decryptTokens(ciphertext: string): Promise<AuthTokens | null>;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
type RefreshFn = () => Promise<boolean>;
|
|
112
|
+
/**
|
|
113
|
+
* Authenticated HTTP client that:
|
|
114
|
+
* - Injects Authorization: Bearer <accessToken>
|
|
115
|
+
* - Auto-refreshes on 401 and retries the original request once
|
|
116
|
+
*/
|
|
117
|
+
declare class HttpClient {
|
|
118
|
+
private readonly config;
|
|
119
|
+
private readonly tokenManager;
|
|
120
|
+
private refreshFn;
|
|
121
|
+
private refreshPromise;
|
|
122
|
+
constructor(config: AuthConfig, tokenManager: TokenManager);
|
|
123
|
+
/** Register the refresh callback (set by AuthClient to avoid circular deps) */
|
|
124
|
+
setRefreshFn(fn: RefreshFn): void;
|
|
125
|
+
/**
|
|
126
|
+
* Authenticated fetch wrapper.
|
|
127
|
+
* Automatically injects the Bearer token and handles 401 → refresh → retry.
|
|
128
|
+
*/
|
|
129
|
+
fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
|
|
130
|
+
/**
|
|
131
|
+
* Raw fetch using the configured fetchFn or global fetch.
|
|
132
|
+
*/
|
|
133
|
+
doFetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
|
|
134
|
+
/**
|
|
135
|
+
* Builds a full URL from a path relative to baseUrl.
|
|
136
|
+
*/
|
|
137
|
+
url(path: string): string;
|
|
138
|
+
/**
|
|
139
|
+
* Ensures only one refresh request is in-flight at a time.
|
|
140
|
+
*/
|
|
141
|
+
private deduplicatedRefresh;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Derives and caches the current AuthSession from stored tokens.
|
|
146
|
+
* Fetches the user profile from the /me endpoint when available.
|
|
147
|
+
*/
|
|
148
|
+
declare class SessionManager<User = unknown> {
|
|
149
|
+
private session;
|
|
150
|
+
private readonly config;
|
|
151
|
+
private readonly tokenManager;
|
|
152
|
+
private readonly httpClient;
|
|
153
|
+
constructor(config: AuthConfig<User>, tokenManager: TokenManager, httpClient: HttpClient);
|
|
154
|
+
getSession(): AuthSession<User>;
|
|
155
|
+
setSession(session: AuthSession<User>): void;
|
|
156
|
+
/**
|
|
157
|
+
* Builds a session from stored tokens, optionally fetching the user profile.
|
|
158
|
+
*/
|
|
159
|
+
loadSession(): Promise<AuthSession<User>>;
|
|
160
|
+
/**
|
|
161
|
+
* Updates the session after a successful token refresh.
|
|
162
|
+
*/
|
|
163
|
+
refreshSession(tokens: AuthTokens): Promise<void>;
|
|
164
|
+
clearSession(): void;
|
|
165
|
+
private fetchUser;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Central orchestrator for authentication operations.
|
|
170
|
+
* Coordinates TokenManager, SessionManager, and HttpClient.
|
|
171
|
+
*/
|
|
172
|
+
declare class AuthClient<User = unknown> {
|
|
173
|
+
readonly tokenManager: TokenManager;
|
|
174
|
+
readonly sessionManager: SessionManager<User>;
|
|
175
|
+
readonly httpClient: HttpClient;
|
|
176
|
+
private readonly config;
|
|
177
|
+
private sessionListeners;
|
|
178
|
+
constructor(config: AuthConfig<User>);
|
|
179
|
+
/**
|
|
180
|
+
* Authenticates the user and stores tokens.
|
|
181
|
+
*/
|
|
182
|
+
login(input: LoginInput): Promise<AuthSession<User>>;
|
|
183
|
+
/**
|
|
184
|
+
* Logs out the user, clears tokens, and optionally calls the backend.
|
|
185
|
+
*/
|
|
186
|
+
logout(): Promise<void>;
|
|
187
|
+
/**
|
|
188
|
+
* Refreshes the access token using the stored refresh token.
|
|
189
|
+
* Returns true on success, false on failure.
|
|
190
|
+
*/
|
|
191
|
+
refresh(): Promise<boolean>;
|
|
192
|
+
/**
|
|
193
|
+
* Loads the session from stored tokens (call on app mount).
|
|
194
|
+
*/
|
|
195
|
+
initialize(): Promise<AuthSession<User>>;
|
|
196
|
+
getSession(): AuthSession<User>;
|
|
197
|
+
/**
|
|
198
|
+
* Returns the authenticated fetch wrapper.
|
|
199
|
+
*/
|
|
200
|
+
get fetch(): HttpClient["fetch"];
|
|
201
|
+
subscribe(listener: (session: AuthSession<User>) => void): () => void;
|
|
202
|
+
private buildTokens;
|
|
203
|
+
private notifyListeners;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
interface AuthProviderProps<User = unknown> {
|
|
207
|
+
config: AuthConfig<User>;
|
|
208
|
+
children: React.ReactNode;
|
|
209
|
+
}
|
|
210
|
+
declare function AuthProvider<User = unknown>({ config, children, }: AuthProviderProps<User>): react_jsx_runtime.JSX.Element;
|
|
211
|
+
|
|
212
|
+
interface UseAuthReturn<User = unknown> {
|
|
213
|
+
session: AuthSession<User>;
|
|
214
|
+
login: (input: LoginInput) => Promise<void>;
|
|
215
|
+
logout: () => Promise<void>;
|
|
216
|
+
refresh: () => Promise<void>;
|
|
217
|
+
isLoading: boolean;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Primary hook for authentication operations.
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* const { session, login, logout, isLoading } = useAuth();
|
|
224
|
+
*/
|
|
225
|
+
declare function useAuth<User = unknown>(): UseAuthReturn<User>;
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Returns the current auth session without exposing login/logout actions.
|
|
229
|
+
*
|
|
230
|
+
* @example
|
|
231
|
+
* const { user, isAuthenticated } = useSession();
|
|
232
|
+
*/
|
|
233
|
+
declare function useSession<User = unknown>(): AuthSession<User>;
|
|
234
|
+
|
|
235
|
+
interface UseRequireAuthOptions {
|
|
236
|
+
/** Path to redirect unauthenticated users to. @default "/login" */
|
|
237
|
+
redirectTo?: string;
|
|
238
|
+
/** Called when the user is not authenticated (use for custom redirect logic) */
|
|
239
|
+
onUnauthenticated?: () => void;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Redirects unauthenticated users to the login page.
|
|
243
|
+
* Works with both Next.js App Router and Pages Router.
|
|
244
|
+
*
|
|
245
|
+
* @example
|
|
246
|
+
* // App Router (client component)
|
|
247
|
+
* useRequireAuth({ redirectTo: "/login" });
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* // Custom handler
|
|
251
|
+
* useRequireAuth({ onUnauthenticated: () => router.push("/login") });
|
|
252
|
+
*/
|
|
253
|
+
declare function useRequireAuth(options?: UseRequireAuthOptions): void;
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Parses an expiry value into seconds.
|
|
257
|
+
* Accepts:
|
|
258
|
+
* - number → treated as seconds
|
|
259
|
+
* - string → e.g. "15m", "2h", "2d", "7d", "1w"
|
|
260
|
+
*
|
|
261
|
+
* @throws if the format is unrecognised
|
|
262
|
+
*/
|
|
263
|
+
declare function parseExpiry(input?: ExpiryInput): number;
|
|
264
|
+
/**
|
|
265
|
+
* Safely parses an expiry value, returning a fallback on failure.
|
|
266
|
+
*/
|
|
267
|
+
declare function safeParseExpiry(input?: ExpiryInput, fallbackSeconds?: number): number;
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Lightweight symmetric encryption using AES-GCM via the Web Crypto API.
|
|
271
|
+
* Works in both browser and Node.js (>=18) / Edge runtimes.
|
|
272
|
+
*/
|
|
273
|
+
/**
|
|
274
|
+
* Encrypts a plaintext string using AES-GCM.
|
|
275
|
+
* Returns a base64url-encoded string: `<iv>.<ciphertext>`
|
|
276
|
+
*/
|
|
277
|
+
declare function encrypt(data: string, secret: string): Promise<string>;
|
|
278
|
+
/**
|
|
279
|
+
* Decrypts a string produced by `encrypt`.
|
|
280
|
+
*/
|
|
281
|
+
declare function decrypt(data: string, secret: string): Promise<string>;
|
|
282
|
+
|
|
283
|
+
export { AuthClient, type AuthConfig, AuthProvider, type AuthSession, type AuthTokens, type ExpiryInput, type ExpiryStrategy, HttpClient, type LoginInput, type LoginResponse, SessionManager, TokenManager, type UseAuthReturn, type UseRequireAuthOptions, decrypt, encrypt, parseExpiry, safeParseExpiry, useAuth, useRequireAuth, useSession };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
type ExpiryInput = number | string;
|
|
5
|
+
type ExpiryStrategy = "backend" | "config" | "hybrid";
|
|
6
|
+
interface AuthTokens {
|
|
7
|
+
accessToken: string;
|
|
8
|
+
refreshToken: string;
|
|
9
|
+
/** Unix timestamp (ms) */
|
|
10
|
+
accessTokenExpiresAt: number;
|
|
11
|
+
/** Unix timestamp (ms) */
|
|
12
|
+
refreshTokenExpiresAt?: number;
|
|
13
|
+
}
|
|
14
|
+
interface AuthSession<User = unknown> {
|
|
15
|
+
user: User | null;
|
|
16
|
+
tokens: AuthTokens | null;
|
|
17
|
+
isAuthenticated: boolean;
|
|
18
|
+
}
|
|
19
|
+
interface LoginInput {
|
|
20
|
+
[key: string]: unknown;
|
|
21
|
+
}
|
|
22
|
+
interface LoginResponse<User = unknown> {
|
|
23
|
+
user: User;
|
|
24
|
+
accessToken: string;
|
|
25
|
+
refreshToken: string;
|
|
26
|
+
/** Seconds until access token expires (legacy field) */
|
|
27
|
+
expiresIn?: number;
|
|
28
|
+
accessTokenExpiresIn?: number | string;
|
|
29
|
+
refreshTokenExpiresIn?: number | string;
|
|
30
|
+
}
|
|
31
|
+
interface AuthConfig<User = unknown> {
|
|
32
|
+
/** Base URL of your backend API */
|
|
33
|
+
baseUrl: string;
|
|
34
|
+
endpoints: {
|
|
35
|
+
login: string;
|
|
36
|
+
register?: string;
|
|
37
|
+
refresh: string;
|
|
38
|
+
logout?: string;
|
|
39
|
+
/** Endpoint to fetch the current user profile */
|
|
40
|
+
me?: string;
|
|
41
|
+
};
|
|
42
|
+
routes?: {
|
|
43
|
+
/** Paths that are always accessible without auth */
|
|
44
|
+
public: string[];
|
|
45
|
+
/** Paths that require authentication */
|
|
46
|
+
protected: string[];
|
|
47
|
+
};
|
|
48
|
+
token: {
|
|
49
|
+
storage: "cookie" | "memory";
|
|
50
|
+
cookieName?: string;
|
|
51
|
+
secure?: boolean;
|
|
52
|
+
sameSite?: "strict" | "lax" | "none";
|
|
53
|
+
};
|
|
54
|
+
/** Secret used for encrypting stored tokens */
|
|
55
|
+
secret: string;
|
|
56
|
+
/** Automatically refresh access token before expiry */
|
|
57
|
+
autoRefresh?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Seconds before expiry to trigger a proactive refresh.
|
|
60
|
+
* @default 60
|
|
61
|
+
*/
|
|
62
|
+
refreshThreshold?: number;
|
|
63
|
+
expiry?: {
|
|
64
|
+
accessTokenExpiresIn?: ExpiryInput;
|
|
65
|
+
refreshTokenExpiresIn?: ExpiryInput;
|
|
66
|
+
/**
|
|
67
|
+
* - "backend" → trust expiresIn from API response
|
|
68
|
+
* - "config" → use config values only
|
|
69
|
+
* - "hybrid" → backend first, fallback to config
|
|
70
|
+
* @default "hybrid"
|
|
71
|
+
*/
|
|
72
|
+
strategy?: ExpiryStrategy;
|
|
73
|
+
};
|
|
74
|
+
/** Optional custom fetch implementation */
|
|
75
|
+
fetchFn?: typeof fetch;
|
|
76
|
+
/** Called after a successful login */
|
|
77
|
+
onLogin?: (session: AuthSession<User>) => void;
|
|
78
|
+
/** Called after logout */
|
|
79
|
+
onLogout?: () => void;
|
|
80
|
+
/** Called when token refresh fails */
|
|
81
|
+
onRefreshError?: (error: unknown) => void;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Manages storage, retrieval, and expiry checks for auth tokens.
|
|
86
|
+
* Supports "cookie" and "memory" storage strategies.
|
|
87
|
+
*/
|
|
88
|
+
declare class TokenManager {
|
|
89
|
+
private memoryStore;
|
|
90
|
+
private readonly config;
|
|
91
|
+
constructor(config: AuthConfig);
|
|
92
|
+
getTokens(): AuthTokens | null;
|
|
93
|
+
setTokens(tokens: AuthTokens): Promise<void>;
|
|
94
|
+
clearTokens(): void;
|
|
95
|
+
isAccessExpired(tokens: AuthTokens): boolean;
|
|
96
|
+
isRefreshExpired(tokens: AuthTokens): boolean;
|
|
97
|
+
private cookieName;
|
|
98
|
+
private readFromCookie;
|
|
99
|
+
private writeToCookie;
|
|
100
|
+
private deleteCookie;
|
|
101
|
+
/**
|
|
102
|
+
* Encrypts tokens for secure server-side cookie storage.
|
|
103
|
+
*/
|
|
104
|
+
encryptTokens(tokens: AuthTokens): Promise<string>;
|
|
105
|
+
/**
|
|
106
|
+
* Decrypts tokens from a server-side cookie value.
|
|
107
|
+
*/
|
|
108
|
+
decryptTokens(ciphertext: string): Promise<AuthTokens | null>;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
type RefreshFn = () => Promise<boolean>;
|
|
112
|
+
/**
|
|
113
|
+
* Authenticated HTTP client that:
|
|
114
|
+
* - Injects Authorization: Bearer <accessToken>
|
|
115
|
+
* - Auto-refreshes on 401 and retries the original request once
|
|
116
|
+
*/
|
|
117
|
+
declare class HttpClient {
|
|
118
|
+
private readonly config;
|
|
119
|
+
private readonly tokenManager;
|
|
120
|
+
private refreshFn;
|
|
121
|
+
private refreshPromise;
|
|
122
|
+
constructor(config: AuthConfig, tokenManager: TokenManager);
|
|
123
|
+
/** Register the refresh callback (set by AuthClient to avoid circular deps) */
|
|
124
|
+
setRefreshFn(fn: RefreshFn): void;
|
|
125
|
+
/**
|
|
126
|
+
* Authenticated fetch wrapper.
|
|
127
|
+
* Automatically injects the Bearer token and handles 401 → refresh → retry.
|
|
128
|
+
*/
|
|
129
|
+
fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
|
|
130
|
+
/**
|
|
131
|
+
* Raw fetch using the configured fetchFn or global fetch.
|
|
132
|
+
*/
|
|
133
|
+
doFetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
|
|
134
|
+
/**
|
|
135
|
+
* Builds a full URL from a path relative to baseUrl.
|
|
136
|
+
*/
|
|
137
|
+
url(path: string): string;
|
|
138
|
+
/**
|
|
139
|
+
* Ensures only one refresh request is in-flight at a time.
|
|
140
|
+
*/
|
|
141
|
+
private deduplicatedRefresh;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Derives and caches the current AuthSession from stored tokens.
|
|
146
|
+
* Fetches the user profile from the /me endpoint when available.
|
|
147
|
+
*/
|
|
148
|
+
declare class SessionManager<User = unknown> {
|
|
149
|
+
private session;
|
|
150
|
+
private readonly config;
|
|
151
|
+
private readonly tokenManager;
|
|
152
|
+
private readonly httpClient;
|
|
153
|
+
constructor(config: AuthConfig<User>, tokenManager: TokenManager, httpClient: HttpClient);
|
|
154
|
+
getSession(): AuthSession<User>;
|
|
155
|
+
setSession(session: AuthSession<User>): void;
|
|
156
|
+
/**
|
|
157
|
+
* Builds a session from stored tokens, optionally fetching the user profile.
|
|
158
|
+
*/
|
|
159
|
+
loadSession(): Promise<AuthSession<User>>;
|
|
160
|
+
/**
|
|
161
|
+
* Updates the session after a successful token refresh.
|
|
162
|
+
*/
|
|
163
|
+
refreshSession(tokens: AuthTokens): Promise<void>;
|
|
164
|
+
clearSession(): void;
|
|
165
|
+
private fetchUser;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Central orchestrator for authentication operations.
|
|
170
|
+
* Coordinates TokenManager, SessionManager, and HttpClient.
|
|
171
|
+
*/
|
|
172
|
+
declare class AuthClient<User = unknown> {
|
|
173
|
+
readonly tokenManager: TokenManager;
|
|
174
|
+
readonly sessionManager: SessionManager<User>;
|
|
175
|
+
readonly httpClient: HttpClient;
|
|
176
|
+
private readonly config;
|
|
177
|
+
private sessionListeners;
|
|
178
|
+
constructor(config: AuthConfig<User>);
|
|
179
|
+
/**
|
|
180
|
+
* Authenticates the user and stores tokens.
|
|
181
|
+
*/
|
|
182
|
+
login(input: LoginInput): Promise<AuthSession<User>>;
|
|
183
|
+
/**
|
|
184
|
+
* Logs out the user, clears tokens, and optionally calls the backend.
|
|
185
|
+
*/
|
|
186
|
+
logout(): Promise<void>;
|
|
187
|
+
/**
|
|
188
|
+
* Refreshes the access token using the stored refresh token.
|
|
189
|
+
* Returns true on success, false on failure.
|
|
190
|
+
*/
|
|
191
|
+
refresh(): Promise<boolean>;
|
|
192
|
+
/**
|
|
193
|
+
* Loads the session from stored tokens (call on app mount).
|
|
194
|
+
*/
|
|
195
|
+
initialize(): Promise<AuthSession<User>>;
|
|
196
|
+
getSession(): AuthSession<User>;
|
|
197
|
+
/**
|
|
198
|
+
* Returns the authenticated fetch wrapper.
|
|
199
|
+
*/
|
|
200
|
+
get fetch(): HttpClient["fetch"];
|
|
201
|
+
subscribe(listener: (session: AuthSession<User>) => void): () => void;
|
|
202
|
+
private buildTokens;
|
|
203
|
+
private notifyListeners;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
interface AuthProviderProps<User = unknown> {
|
|
207
|
+
config: AuthConfig<User>;
|
|
208
|
+
children: React.ReactNode;
|
|
209
|
+
}
|
|
210
|
+
declare function AuthProvider<User = unknown>({ config, children, }: AuthProviderProps<User>): react_jsx_runtime.JSX.Element;
|
|
211
|
+
|
|
212
|
+
interface UseAuthReturn<User = unknown> {
|
|
213
|
+
session: AuthSession<User>;
|
|
214
|
+
login: (input: LoginInput) => Promise<void>;
|
|
215
|
+
logout: () => Promise<void>;
|
|
216
|
+
refresh: () => Promise<void>;
|
|
217
|
+
isLoading: boolean;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Primary hook for authentication operations.
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* const { session, login, logout, isLoading } = useAuth();
|
|
224
|
+
*/
|
|
225
|
+
declare function useAuth<User = unknown>(): UseAuthReturn<User>;
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Returns the current auth session without exposing login/logout actions.
|
|
229
|
+
*
|
|
230
|
+
* @example
|
|
231
|
+
* const { user, isAuthenticated } = useSession();
|
|
232
|
+
*/
|
|
233
|
+
declare function useSession<User = unknown>(): AuthSession<User>;
|
|
234
|
+
|
|
235
|
+
interface UseRequireAuthOptions {
|
|
236
|
+
/** Path to redirect unauthenticated users to. @default "/login" */
|
|
237
|
+
redirectTo?: string;
|
|
238
|
+
/** Called when the user is not authenticated (use for custom redirect logic) */
|
|
239
|
+
onUnauthenticated?: () => void;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Redirects unauthenticated users to the login page.
|
|
243
|
+
* Works with both Next.js App Router and Pages Router.
|
|
244
|
+
*
|
|
245
|
+
* @example
|
|
246
|
+
* // App Router (client component)
|
|
247
|
+
* useRequireAuth({ redirectTo: "/login" });
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* // Custom handler
|
|
251
|
+
* useRequireAuth({ onUnauthenticated: () => router.push("/login") });
|
|
252
|
+
*/
|
|
253
|
+
declare function useRequireAuth(options?: UseRequireAuthOptions): void;
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Parses an expiry value into seconds.
|
|
257
|
+
* Accepts:
|
|
258
|
+
* - number → treated as seconds
|
|
259
|
+
* - string → e.g. "15m", "2h", "2d", "7d", "1w"
|
|
260
|
+
*
|
|
261
|
+
* @throws if the format is unrecognised
|
|
262
|
+
*/
|
|
263
|
+
declare function parseExpiry(input?: ExpiryInput): number;
|
|
264
|
+
/**
|
|
265
|
+
* Safely parses an expiry value, returning a fallback on failure.
|
|
266
|
+
*/
|
|
267
|
+
declare function safeParseExpiry(input?: ExpiryInput, fallbackSeconds?: number): number;
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Lightweight symmetric encryption using AES-GCM via the Web Crypto API.
|
|
271
|
+
* Works in both browser and Node.js (>=18) / Edge runtimes.
|
|
272
|
+
*/
|
|
273
|
+
/**
|
|
274
|
+
* Encrypts a plaintext string using AES-GCM.
|
|
275
|
+
* Returns a base64url-encoded string: `<iv>.<ciphertext>`
|
|
276
|
+
*/
|
|
277
|
+
declare function encrypt(data: string, secret: string): Promise<string>;
|
|
278
|
+
/**
|
|
279
|
+
* Decrypts a string produced by `encrypt`.
|
|
280
|
+
*/
|
|
281
|
+
declare function decrypt(data: string, secret: string): Promise<string>;
|
|
282
|
+
|
|
283
|
+
export { AuthClient, type AuthConfig, AuthProvider, type AuthSession, type AuthTokens, type ExpiryInput, type ExpiryStrategy, HttpClient, type LoginInput, type LoginResponse, SessionManager, TokenManager, type UseAuthReturn, type UseRequireAuthOptions, decrypt, encrypt, parseExpiry, safeParseExpiry, useAuth, useRequireAuth, useSession };
|