@arow-software/auth-client 1.1.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 +342 -0
- package/dist/index.d.mts +251 -0
- package/dist/index.d.ts +251 -0
- package/dist/index.js +548 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +528 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +57 -0
package/README.md
ADDED
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
# @arow-software/auth-client
|
|
2
|
+
|
|
3
|
+
Reusable authentication package for ArowAuth SSO integration. Provides React context, hooks, and utilities for seamless SSO authentication with automatic token refresh.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🔐 **Token Management** - Secure storage, automatic refresh, JWT decoding
|
|
8
|
+
- 🔄 **API Interceptors** - Axios interceptors with 401 handling and request queuing
|
|
9
|
+
- ⚛️ **React Integration** - Context provider and hooks for easy auth state management
|
|
10
|
+
- 🎯 **TypeScript** - Full type definitions included
|
|
11
|
+
- 📦 **Lightweight** - Peer dependencies only (React, Axios)
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# npm
|
|
17
|
+
npm install @arow-software/auth-client
|
|
18
|
+
|
|
19
|
+
# yarn
|
|
20
|
+
yarn add @arow-software/auth-client
|
|
21
|
+
|
|
22
|
+
# pnpm
|
|
23
|
+
pnpm add @arow-software/auth-client
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Peer Dependencies
|
|
27
|
+
|
|
28
|
+
Make sure you have these installed:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install react axios
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
### 1. Wrap your app with AuthProvider
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
// App.tsx
|
|
40
|
+
import { AuthProvider } from '@arow-software/auth-client';
|
|
41
|
+
|
|
42
|
+
function App() {
|
|
43
|
+
return (
|
|
44
|
+
<AuthProvider
|
|
45
|
+
ssoBaseUrl="https://sso.arowsoftware.co.uk"
|
|
46
|
+
clientId="arowtrades"
|
|
47
|
+
apiBaseUrl="http://localhost:5001"
|
|
48
|
+
>
|
|
49
|
+
<YourApp />
|
|
50
|
+
</AuthProvider>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 2. Use the useAuth hook
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
// LoginButton.tsx
|
|
59
|
+
import { useAuth } from '@arow-software/auth-client';
|
|
60
|
+
|
|
61
|
+
function LoginButton() {
|
|
62
|
+
const { isAuthenticated, isLoading, user, login, logout } = useAuth();
|
|
63
|
+
|
|
64
|
+
if (isLoading) {
|
|
65
|
+
return <div>Loading...</div>;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (isAuthenticated) {
|
|
69
|
+
return (
|
|
70
|
+
<div>
|
|
71
|
+
<span>Welcome, {user?.displayName || user?.email}!</span>
|
|
72
|
+
<button onClick={logout}>Logout</button>
|
|
73
|
+
</div>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return <button onClick={() => login()}>Login with SSO</button>;
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### 3. Make authenticated API calls
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
// DataComponent.tsx
|
|
85
|
+
import { useAuthClient } from '@arow-software/auth-client';
|
|
86
|
+
import { useState, useEffect } from 'react';
|
|
87
|
+
|
|
88
|
+
function DataComponent() {
|
|
89
|
+
const client = useAuthClient();
|
|
90
|
+
const [data, setData] = useState(null);
|
|
91
|
+
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
const fetchData = async () => {
|
|
94
|
+
try {
|
|
95
|
+
const response = await client.get('/api/data');
|
|
96
|
+
setData(response.data);
|
|
97
|
+
} catch (error) {
|
|
98
|
+
console.error('Failed to fetch data', error);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
fetchData();
|
|
103
|
+
}, [client]);
|
|
104
|
+
|
|
105
|
+
return <div>{JSON.stringify(data)}</div>;
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## API Reference
|
|
110
|
+
|
|
111
|
+
### AuthProvider Props
|
|
112
|
+
|
|
113
|
+
| Prop | Type | Required | Description |
|
|
114
|
+
|------|------|----------|-------------|
|
|
115
|
+
| `ssoBaseUrl` | `string` | ✅ | Base URL of ArowAuth SSO server |
|
|
116
|
+
| `clientId` | `string` | ✅ | Client ID registered with ArowAuth |
|
|
117
|
+
| `apiBaseUrl` | `string` | ❌ | Base URL for your API (for axios client) |
|
|
118
|
+
| `redirectUri` | `string` | ❌ | Custom redirect URI (defaults to origin + /callback) |
|
|
119
|
+
| `scopes` | `string[]` | ❌ | OAuth scopes (defaults to ['openid', 'email', 'profile']) |
|
|
120
|
+
| `storagePrefix` | `string` | ❌ | Storage key prefix (defaults to 'arowauth') |
|
|
121
|
+
| `useSessionStorage` | `boolean` | ❌ | Use sessionStorage instead of localStorage |
|
|
122
|
+
| `onTokenRefresh` | `function` | ❌ | Callback when tokens are refreshed |
|
|
123
|
+
| `onAuthError` | `function` | ❌ | Callback when auth error occurs |
|
|
124
|
+
| `onLogout` | `function` | ❌ | Callback when user is logged out |
|
|
125
|
+
|
|
126
|
+
### useAuth Hook
|
|
127
|
+
|
|
128
|
+
Returns an object with:
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
{
|
|
132
|
+
user: User | null; // Current user object
|
|
133
|
+
isAuthenticated: boolean; // Whether user is logged in
|
|
134
|
+
isLoading: boolean; // Initial auth check in progress
|
|
135
|
+
error: string | null; // Any auth error message
|
|
136
|
+
login: (redirectPath?: string) => void; // Redirect to SSO login
|
|
137
|
+
logout: () => Promise<void>; // Clear tokens and logout
|
|
138
|
+
refreshUser: () => Promise<void>; // Refresh user from token
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### User Object
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
interface User {
|
|
146
|
+
id: string;
|
|
147
|
+
email: string;
|
|
148
|
+
firstName?: string;
|
|
149
|
+
lastName?: string;
|
|
150
|
+
displayName?: string;
|
|
151
|
+
avatarUrl?: string;
|
|
152
|
+
emailVerified: boolean;
|
|
153
|
+
roles?: string[];
|
|
154
|
+
permissions?: string[];
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### useAuthClient Hook
|
|
159
|
+
|
|
160
|
+
Returns a configured Axios instance that:
|
|
161
|
+
- Automatically attaches Bearer token to all requests
|
|
162
|
+
- Handles 401 responses by refreshing tokens and retrying
|
|
163
|
+
- Queues concurrent requests during token refresh
|
|
164
|
+
|
|
165
|
+
### Token Manager Functions
|
|
166
|
+
|
|
167
|
+
For advanced use cases, you can import token management functions directly:
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
import {
|
|
171
|
+
getAccessToken,
|
|
172
|
+
getRefreshToken,
|
|
173
|
+
setTokens,
|
|
174
|
+
clearTokens,
|
|
175
|
+
isTokenExpired,
|
|
176
|
+
hasValidToken,
|
|
177
|
+
getUserFromToken,
|
|
178
|
+
refreshTokens,
|
|
179
|
+
getValidAccessToken,
|
|
180
|
+
decodeJwt,
|
|
181
|
+
} from '@arow-software/auth-client';
|
|
182
|
+
|
|
183
|
+
// Check if token exists and is valid
|
|
184
|
+
if (hasValidToken()) {
|
|
185
|
+
const user = getUserFromToken();
|
|
186
|
+
console.log('Current user:', user);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Manually refresh tokens
|
|
190
|
+
const newTokens = await refreshTokens();
|
|
191
|
+
|
|
192
|
+
// Decode JWT without verification
|
|
193
|
+
const payload = decodeJwt(token);
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### createApiClient Function
|
|
197
|
+
|
|
198
|
+
Create a standalone axios instance with auth interceptors:
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
import axios from 'axios';
|
|
202
|
+
import { createAuthClient, initTokenManager } from '@arow-software/auth-client';
|
|
203
|
+
|
|
204
|
+
// Initialize token manager
|
|
205
|
+
initTokenManager({
|
|
206
|
+
ssoBaseUrl: 'https://sso.arowsoftware.co.uk',
|
|
207
|
+
clientId: 'myapp',
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
// Add auth to existing axios instance
|
|
211
|
+
const myAxios = axios.create({ baseURL: 'http://api.example.com' });
|
|
212
|
+
const authAxios = createAuthClient(myAxios, {
|
|
213
|
+
ssoBaseUrl: 'https://sso.arowsoftware.co.uk',
|
|
214
|
+
clientId: 'myapp',
|
|
215
|
+
});
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## SSO Callback Setup
|
|
219
|
+
|
|
220
|
+
Create a callback route in your app to handle the SSO redirect:
|
|
221
|
+
|
|
222
|
+
```tsx
|
|
223
|
+
// pages/callback.tsx (or wherever your callback route is)
|
|
224
|
+
import { useEffect } from 'react';
|
|
225
|
+
import { useAuth } from '@arow-software/auth-client';
|
|
226
|
+
import { useNavigate } from 'react-router-dom';
|
|
227
|
+
|
|
228
|
+
function CallbackPage() {
|
|
229
|
+
const { isAuthenticated, isLoading } = useAuth();
|
|
230
|
+
const navigate = useNavigate();
|
|
231
|
+
|
|
232
|
+
useEffect(() => {
|
|
233
|
+
// AuthProvider automatically handles token extraction from URL hash
|
|
234
|
+
// Just wait for auth to complete and redirect
|
|
235
|
+
if (!isLoading) {
|
|
236
|
+
if (isAuthenticated) {
|
|
237
|
+
navigate('/dashboard');
|
|
238
|
+
} else {
|
|
239
|
+
navigate('/login?error=auth_failed');
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}, [isAuthenticated, isLoading, navigate]);
|
|
243
|
+
|
|
244
|
+
return <div>Completing login...</div>;
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## Protected Routes
|
|
249
|
+
|
|
250
|
+
Example with React Router:
|
|
251
|
+
|
|
252
|
+
```tsx
|
|
253
|
+
import { useAuth } from '@arow-software/auth-client';
|
|
254
|
+
import { Navigate, useLocation } from 'react-router-dom';
|
|
255
|
+
|
|
256
|
+
function ProtectedRoute({ children }: { children: React.ReactNode }) {
|
|
257
|
+
const { isAuthenticated, isLoading } = useAuth();
|
|
258
|
+
const location = useLocation();
|
|
259
|
+
|
|
260
|
+
if (isLoading) {
|
|
261
|
+
return <div>Loading...</div>;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (!isAuthenticated) {
|
|
265
|
+
// Save the attempted location for redirect after login
|
|
266
|
+
return <Navigate to="/login" state={{ from: location }} replace />;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return <>{children}</>;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Usage
|
|
273
|
+
<Route
|
|
274
|
+
path="/dashboard"
|
|
275
|
+
element={
|
|
276
|
+
<ProtectedRoute>
|
|
277
|
+
<Dashboard />
|
|
278
|
+
</ProtectedRoute>
|
|
279
|
+
}
|
|
280
|
+
/>
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
## Role-Based Access
|
|
284
|
+
|
|
285
|
+
```tsx
|
|
286
|
+
import { useAuth } from '@arow-software/auth-client';
|
|
287
|
+
|
|
288
|
+
function AdminPanel() {
|
|
289
|
+
const { user, isAuthenticated } = useAuth();
|
|
290
|
+
|
|
291
|
+
if (!isAuthenticated) return null;
|
|
292
|
+
|
|
293
|
+
const isAdmin = user?.roles?.includes('admin');
|
|
294
|
+
|
|
295
|
+
if (!isAdmin) {
|
|
296
|
+
return <div>Access denied. Admin role required.</div>;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
return <div>Admin Panel Content</div>;
|
|
300
|
+
}
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
## Error Handling
|
|
304
|
+
|
|
305
|
+
```tsx
|
|
306
|
+
<AuthProvider
|
|
307
|
+
ssoBaseUrl="https://sso.arowsoftware.co.uk"
|
|
308
|
+
clientId="arowtrades"
|
|
309
|
+
onAuthError={(error) => {
|
|
310
|
+
console.error('Auth error:', error);
|
|
311
|
+
// Show notification, redirect to login, etc.
|
|
312
|
+
}}
|
|
313
|
+
onLogout={() => {
|
|
314
|
+
// Redirect to home, clear app state, etc.
|
|
315
|
+
window.location.href = '/';
|
|
316
|
+
}}
|
|
317
|
+
>
|
|
318
|
+
<App />
|
|
319
|
+
</AuthProvider>
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## Environment Variables
|
|
323
|
+
|
|
324
|
+
For Vite projects:
|
|
325
|
+
|
|
326
|
+
```env
|
|
327
|
+
VITE_SSO_BASE_URL=https://sso.arowsoftware.co.uk
|
|
328
|
+
VITE_SSO_CLIENT_ID=arowtrades
|
|
329
|
+
VITE_API_BASE_URL=http://localhost:5001
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
```tsx
|
|
333
|
+
<AuthProvider
|
|
334
|
+
ssoBaseUrl={import.meta.env.VITE_SSO_BASE_URL}
|
|
335
|
+
clientId={import.meta.env.VITE_SSO_CLIENT_ID}
|
|
336
|
+
apiBaseUrl={import.meta.env.VITE_API_BASE_URL}
|
|
337
|
+
>
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
## License
|
|
341
|
+
|
|
342
|
+
MIT © ArowSoftware
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
import { AxiosInstance } from 'axios';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* User object returned from ArowAuth
|
|
6
|
+
*/
|
|
7
|
+
interface User {
|
|
8
|
+
id: string;
|
|
9
|
+
email: string;
|
|
10
|
+
firstName?: string;
|
|
11
|
+
lastName?: string;
|
|
12
|
+
displayName?: string;
|
|
13
|
+
avatarUrl?: string;
|
|
14
|
+
emailVerified: boolean;
|
|
15
|
+
roles?: string[];
|
|
16
|
+
permissions?: string[];
|
|
17
|
+
createdAt?: string;
|
|
18
|
+
updatedAt?: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* JWT token payload structure
|
|
22
|
+
*/
|
|
23
|
+
interface JwtPayload {
|
|
24
|
+
sub: string;
|
|
25
|
+
email: string;
|
|
26
|
+
given_name?: string;
|
|
27
|
+
family_name?: string;
|
|
28
|
+
name?: string;
|
|
29
|
+
picture?: string;
|
|
30
|
+
email_verified?: boolean;
|
|
31
|
+
roles?: string[];
|
|
32
|
+
permissions?: string[];
|
|
33
|
+
iat: number;
|
|
34
|
+
exp: number;
|
|
35
|
+
iss: string;
|
|
36
|
+
aud: string | string[];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Token pair returned from auth endpoints
|
|
40
|
+
*/
|
|
41
|
+
interface TokenPair {
|
|
42
|
+
accessToken: string;
|
|
43
|
+
refreshToken: string;
|
|
44
|
+
expiresIn?: number;
|
|
45
|
+
tokenType?: string;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Auth context state
|
|
49
|
+
*/
|
|
50
|
+
interface AuthState {
|
|
51
|
+
user: User | null;
|
|
52
|
+
isAuthenticated: boolean;
|
|
53
|
+
isLoading: boolean;
|
|
54
|
+
error: string | null;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Auth context value including actions
|
|
58
|
+
*/
|
|
59
|
+
interface AuthContextValue extends AuthState {
|
|
60
|
+
login: (redirectPath?: string) => void;
|
|
61
|
+
logout: () => Promise<void>;
|
|
62
|
+
refreshUser: () => Promise<void>;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Configuration for the auth client
|
|
66
|
+
*/
|
|
67
|
+
interface AuthConfig {
|
|
68
|
+
/**
|
|
69
|
+
* Base URL of the ArowAuth SSO server
|
|
70
|
+
* @example "https://sso.arowsoftware.co.uk"
|
|
71
|
+
*/
|
|
72
|
+
ssoBaseUrl: string;
|
|
73
|
+
/**
|
|
74
|
+
* Client ID registered with ArowAuth
|
|
75
|
+
* @example "arowtrades"
|
|
76
|
+
*/
|
|
77
|
+
clientId: string;
|
|
78
|
+
/**
|
|
79
|
+
* Base URL of your API that will validate tokens
|
|
80
|
+
* @example "http://localhost:5001"
|
|
81
|
+
*/
|
|
82
|
+
apiBaseUrl?: string;
|
|
83
|
+
/**
|
|
84
|
+
* Custom redirect URI after SSO login (defaults to current origin + /callback)
|
|
85
|
+
*/
|
|
86
|
+
redirectUri?: string;
|
|
87
|
+
/**
|
|
88
|
+
* Scopes to request from SSO (defaults to ['openid', 'email', 'profile'])
|
|
89
|
+
*/
|
|
90
|
+
scopes?: string[];
|
|
91
|
+
/**
|
|
92
|
+
* Storage key prefix (defaults to 'arowauth')
|
|
93
|
+
*/
|
|
94
|
+
storagePrefix?: string;
|
|
95
|
+
/**
|
|
96
|
+
* Use sessionStorage instead of localStorage (defaults to false)
|
|
97
|
+
*/
|
|
98
|
+
useSessionStorage?: boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Callback when tokens are refreshed
|
|
101
|
+
*/
|
|
102
|
+
onTokenRefresh?: (tokens: TokenPair) => void;
|
|
103
|
+
/**
|
|
104
|
+
* Callback when auth error occurs
|
|
105
|
+
*/
|
|
106
|
+
onAuthError?: (error: Error) => void;
|
|
107
|
+
/**
|
|
108
|
+
* Callback when user is logged out
|
|
109
|
+
*/
|
|
110
|
+
onLogout?: () => void;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Props for AuthProvider component
|
|
114
|
+
*/
|
|
115
|
+
interface AuthProviderProps extends AuthConfig {
|
|
116
|
+
children: ReactNode;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Initialize token manager with configuration
|
|
121
|
+
*/
|
|
122
|
+
declare function initTokenManager(authConfig: AuthConfig): void;
|
|
123
|
+
/**
|
|
124
|
+
* Decode a JWT token without verification
|
|
125
|
+
*/
|
|
126
|
+
declare function decodeJwt(token: string): JwtPayload | null;
|
|
127
|
+
/**
|
|
128
|
+
* Get the access token from storage
|
|
129
|
+
*/
|
|
130
|
+
declare function getAccessToken(): string | null;
|
|
131
|
+
/**
|
|
132
|
+
* Get the refresh token from storage
|
|
133
|
+
*/
|
|
134
|
+
declare function getRefreshToken(): string | null;
|
|
135
|
+
/**
|
|
136
|
+
* Store tokens in storage
|
|
137
|
+
*/
|
|
138
|
+
declare function setTokens(accessToken: string, refreshToken: string): void;
|
|
139
|
+
/**
|
|
140
|
+
* Clear all tokens from storage
|
|
141
|
+
*/
|
|
142
|
+
declare function clearTokens(): void;
|
|
143
|
+
/**
|
|
144
|
+
* Check if the access token is expired or about to expire
|
|
145
|
+
*/
|
|
146
|
+
declare function isTokenExpired(token?: string | null): boolean;
|
|
147
|
+
/**
|
|
148
|
+
* Check if we have a valid (non-expired) access token
|
|
149
|
+
*/
|
|
150
|
+
declare function hasValidToken(): boolean;
|
|
151
|
+
/**
|
|
152
|
+
* Get user info from the current access token
|
|
153
|
+
*/
|
|
154
|
+
declare function getUserFromToken(): JwtPayload | null;
|
|
155
|
+
/**
|
|
156
|
+
* Refresh tokens using the refresh token
|
|
157
|
+
* Handles concurrent refresh requests by returning the same promise
|
|
158
|
+
*/
|
|
159
|
+
declare function refreshTokens(): Promise<TokenPair | null>;
|
|
160
|
+
/**
|
|
161
|
+
* Get a valid access token, refreshing if necessary
|
|
162
|
+
*/
|
|
163
|
+
declare function getValidAccessToken(): Promise<string | null>;
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Create and configure axios instance with auth interceptors
|
|
167
|
+
*/
|
|
168
|
+
declare function createAuthClient(axiosInstance: AxiosInstance, config: AuthConfig): AxiosInstance;
|
|
169
|
+
/**
|
|
170
|
+
* Create a new axios instance with auth interceptors
|
|
171
|
+
*/
|
|
172
|
+
declare function createApiClient(config: AuthConfig): AxiosInstance;
|
|
173
|
+
|
|
174
|
+
declare const AuthContext: React.Context<AuthContextValue | undefined>;
|
|
175
|
+
/**
|
|
176
|
+
* AuthProvider component - wraps app with auth context
|
|
177
|
+
*/
|
|
178
|
+
declare function AuthProvider(props: AuthProviderProps): React.ReactElement;
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Hook to access auth state and actions
|
|
182
|
+
*
|
|
183
|
+
* @returns Auth context value with user, isAuthenticated, login, logout, etc.
|
|
184
|
+
* @throws Error if used outside of AuthProvider
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* ```tsx
|
|
188
|
+
* function MyComponent() {
|
|
189
|
+
* const { user, isAuthenticated, login, logout, isLoading } = useAuth();
|
|
190
|
+
*
|
|
191
|
+
* if (isLoading) return <div>Loading...</div>;
|
|
192
|
+
*
|
|
193
|
+
* if (!isAuthenticated) {
|
|
194
|
+
* return <button onClick={() => login()}>Login</button>;
|
|
195
|
+
* }
|
|
196
|
+
*
|
|
197
|
+
* return (
|
|
198
|
+
* <div>
|
|
199
|
+
* <p>Welcome, {user?.displayName || user?.email}!</p>
|
|
200
|
+
* <button onClick={logout}>Logout</button>
|
|
201
|
+
* </div>
|
|
202
|
+
* );
|
|
203
|
+
* }
|
|
204
|
+
* ```
|
|
205
|
+
*/
|
|
206
|
+
declare function useAuth(): AuthContextValue;
|
|
207
|
+
/**
|
|
208
|
+
* Hook to check if user is authenticated (convenience wrapper)
|
|
209
|
+
*
|
|
210
|
+
* @returns Boolean indicating if user is authenticated
|
|
211
|
+
*/
|
|
212
|
+
declare function useIsAuthenticated(): boolean;
|
|
213
|
+
/**
|
|
214
|
+
* Hook to get current user (convenience wrapper)
|
|
215
|
+
*
|
|
216
|
+
* @returns Current user or null
|
|
217
|
+
*/
|
|
218
|
+
declare function useUser(): User | null;
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Hook to get a configured axios instance with auth interceptors
|
|
222
|
+
*
|
|
223
|
+
* The returned axios instance will:
|
|
224
|
+
* - Automatically attach Bearer token to requests
|
|
225
|
+
* - Handle 401 responses by refreshing tokens and retrying
|
|
226
|
+
* - Queue concurrent requests during token refresh
|
|
227
|
+
*
|
|
228
|
+
* @returns Configured axios instance
|
|
229
|
+
* @throws Error if used outside of AuthProvider
|
|
230
|
+
*
|
|
231
|
+
* @example
|
|
232
|
+
* ```tsx
|
|
233
|
+
* function MyComponent() {
|
|
234
|
+
* const client = useAuthClient();
|
|
235
|
+
*
|
|
236
|
+
* const fetchData = async () => {
|
|
237
|
+
* try {
|
|
238
|
+
* const response = await client.get('/api/data');
|
|
239
|
+
* console.log(response.data);
|
|
240
|
+
* } catch (error) {
|
|
241
|
+
* console.error('Failed to fetch data', error);
|
|
242
|
+
* }
|
|
243
|
+
* };
|
|
244
|
+
*
|
|
245
|
+
* return <button onClick={fetchData}>Fetch Data</button>;
|
|
246
|
+
* }
|
|
247
|
+
* ```
|
|
248
|
+
*/
|
|
249
|
+
declare function useAuthClient(): AxiosInstance;
|
|
250
|
+
|
|
251
|
+
export { type AuthConfig, AuthContext, type AuthContextValue, AuthProvider, type AuthProviderProps, type AuthState, type JwtPayload, type TokenPair, type User, clearTokens, createApiClient, createAuthClient, decodeJwt, getAccessToken, getRefreshToken, getUserFromToken, getValidAccessToken, hasValidToken, initTokenManager, isTokenExpired, refreshTokens, setTokens, useAuth, useAuthClient, useIsAuthenticated, useUser };
|