@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/dist/index.d.ts
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 };
|