say-auth 1.0.0 → 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/CHANGELOG.md +45 -0
- package/dist/index.d.mts +75 -5
- package/dist/index.d.ts +75 -5
- package/dist/index.js +471 -32
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +466 -35
- package/dist/index.mjs.map +1 -1
- package/package.json +28 -19
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [1.1.0] - 2024-01-XX
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- New `useAuthContext` hook for better React 19 compatibility
|
|
7
|
+
- Added `LoginForm` component with built-in validation
|
|
8
|
+
- Added `MFAVerification` component for 2FA flows
|
|
9
|
+
- Added `SessionWarning` component for session expiry notifications
|
|
10
|
+
- Added `setupAuthInterceptors` for automatic token refresh
|
|
11
|
+
- Added environment validation utilities
|
|
12
|
+
- Added error tracking integration support
|
|
13
|
+
- Added security headers utility
|
|
14
|
+
- Added comprehensive TypeScript types
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
- Improved React 16.8+ through 19 compatibility
|
|
18
|
+
- Enhanced token storage with versioning and migration support
|
|
19
|
+
- Better error messages and debugging information
|
|
20
|
+
- Improved performance with memoized context values
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
- Fixed `createContext` error in React 19
|
|
24
|
+
- Fixed token refresh race conditions
|
|
25
|
+
- Fixed MFA verification timing issues
|
|
26
|
+
- Fixed localStorage SSR issues
|
|
27
|
+
|
|
28
|
+
## [1.0.0] - 2024-01-XX
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
- Initial release of say-auth
|
|
32
|
+
- JWT authentication with refresh tokens
|
|
33
|
+
- MFA/2FA support with TOTP
|
|
34
|
+
- Role-Based Access Control (RBAC)
|
|
35
|
+
- Auto token refresh mechanism
|
|
36
|
+
- Rate limiting for login attempts
|
|
37
|
+
- Audit logging for security events
|
|
38
|
+
- Session management across devices
|
|
39
|
+
- Token blacklisting for secure logout
|
|
40
|
+
- Device fingerprinting for trusted devices
|
|
41
|
+
- Secure encrypted token storage
|
|
42
|
+
- React hooks: `useAuth`, `useProtectedRoute`
|
|
43
|
+
- Components: `AuthProvider`, `ProtectedRoute`, `MFASetup`
|
|
44
|
+
- TypeScript support with full type definitions
|
|
45
|
+
- Next.js 13+ App Router support
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { AxiosInstance } from 'axios';
|
|
2
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
|
-
import React$1 from 'react';
|
|
3
|
+
import * as React$1 from 'react';
|
|
4
|
+
import React__default from 'react';
|
|
4
5
|
|
|
5
6
|
interface User {
|
|
6
7
|
id: string;
|
|
@@ -35,6 +36,11 @@ interface AuthState {
|
|
|
35
36
|
isLoading: boolean;
|
|
36
37
|
error: string | null;
|
|
37
38
|
}
|
|
39
|
+
interface MFASetup$1 {
|
|
40
|
+
secret: string;
|
|
41
|
+
qrCode: string;
|
|
42
|
+
backupCodes: string[];
|
|
43
|
+
}
|
|
38
44
|
interface MFAVerify {
|
|
39
45
|
userId: string;
|
|
40
46
|
code: string;
|
|
@@ -87,6 +93,9 @@ declare class AuthService {
|
|
|
87
93
|
getAxiosInstance(): AxiosInstance;
|
|
88
94
|
getUser(): User | null;
|
|
89
95
|
getState(): AuthState;
|
|
96
|
+
setupMFA(): Promise<MFASetup$1>;
|
|
97
|
+
disableMFA(code: string): Promise<void>;
|
|
98
|
+
updateUser(userData: Partial<User>): Promise<User>;
|
|
90
99
|
}
|
|
91
100
|
|
|
92
101
|
declare class SecureTokenStorage {
|
|
@@ -244,18 +253,59 @@ declare function useProtectedRoute(redirectTo?: string, requiredRole?: string |
|
|
|
244
253
|
isLoading: boolean;
|
|
245
254
|
};
|
|
246
255
|
|
|
256
|
+
interface AuthContextValue extends AuthState {
|
|
257
|
+
login: (credentials: LoginCredentials) => Promise<{
|
|
258
|
+
requiresMFA: boolean;
|
|
259
|
+
user?: User;
|
|
260
|
+
}>;
|
|
261
|
+
register: (data: RegisterData) => Promise<User>;
|
|
262
|
+
logout: () => Promise<void>;
|
|
263
|
+
logoutAllDevices: () => Promise<void>;
|
|
264
|
+
refreshSession: () => Promise<void>;
|
|
265
|
+
changePassword: (currentPassword: string, newPassword: string) => Promise<void>;
|
|
266
|
+
hasRole: (role: string | string[]) => boolean;
|
|
267
|
+
getAxiosInstance: () => any;
|
|
268
|
+
getUser: () => User | null;
|
|
269
|
+
verifyMFA: (code: string, trustDevice?: boolean) => Promise<User>;
|
|
270
|
+
setupMFA: () => Promise<MFASetup$1>;
|
|
271
|
+
disableMFA: (code: string) => Promise<void>;
|
|
272
|
+
updateUser: (userData: Partial<User>) => Promise<void>;
|
|
273
|
+
clearError: () => void;
|
|
274
|
+
isTokenExpired: () => boolean;
|
|
275
|
+
getAccessToken: () => string | null;
|
|
276
|
+
healthCheck: () => Promise<boolean>;
|
|
277
|
+
refreshTokens: () => Promise<void>;
|
|
278
|
+
getRemainingSessionTime: () => number;
|
|
279
|
+
extendSession: () => Promise<void>;
|
|
280
|
+
}
|
|
247
281
|
interface AuthProviderProps {
|
|
248
|
-
children:
|
|
282
|
+
children: React__default.ReactNode;
|
|
249
283
|
apiUrl?: string;
|
|
284
|
+
onError?: (error: string) => void;
|
|
285
|
+
onSessionExpired?: () => void;
|
|
286
|
+
onLogin?: (user: User) => void;
|
|
287
|
+
onLogout?: () => void;
|
|
288
|
+
autoRefresh?: boolean;
|
|
289
|
+
refreshThreshold?: number;
|
|
250
290
|
}
|
|
251
|
-
declare function AuthProvider({ children, apiUrl }: AuthProviderProps): react_jsx_runtime.JSX.Element;
|
|
291
|
+
declare function AuthProvider({ children, apiUrl, onError, onSessionExpired, onLogin, onLogout, autoRefresh, refreshThreshold }: AuthProviderProps): react_jsx_runtime.JSX.Element;
|
|
292
|
+
declare function useAuthContext(): AuthContextValue;
|
|
252
293
|
|
|
253
294
|
interface ProtectedRouteProps {
|
|
254
295
|
children: React.ReactNode;
|
|
255
296
|
requiredRole?: string | string[];
|
|
256
297
|
fallback?: React.ReactNode;
|
|
298
|
+
redirectTo?: string;
|
|
257
299
|
}
|
|
258
|
-
declare function ProtectedRoute({ children, requiredRole, fallback }: ProtectedRouteProps): react_jsx_runtime.JSX.Element | null;
|
|
300
|
+
declare function ProtectedRoute({ children, requiredRole, fallback, redirectTo }: ProtectedRouteProps): string | number | true | Iterable<React$1.ReactNode> | react_jsx_runtime.JSX.Element | null;
|
|
301
|
+
|
|
302
|
+
interface LoginFormProps {
|
|
303
|
+
onSubmit: (email: string, password: string) => Promise<void>;
|
|
304
|
+
isLoading?: boolean;
|
|
305
|
+
error?: string;
|
|
306
|
+
className?: string;
|
|
307
|
+
}
|
|
308
|
+
declare function LoginForm({ onSubmit, isLoading, error, className }: LoginFormProps): react_jsx_runtime.JSX.Element;
|
|
259
309
|
|
|
260
310
|
interface MFASetupProps {
|
|
261
311
|
userId: string;
|
|
@@ -280,6 +330,8 @@ declare function setupAuthInterceptors(axiosInstance: AxiosInstance, baseURL: st
|
|
|
280
330
|
declare function cn(...classes: (string | undefined | false)[]): string;
|
|
281
331
|
declare function getErrorMessage(error: unknown): string;
|
|
282
332
|
declare function isValidEmail(email: string): boolean;
|
|
333
|
+
declare function formatDate(date: Date): string;
|
|
334
|
+
declare function generateRandomString(length: number): string;
|
|
283
335
|
|
|
284
336
|
declare const AUTH_CONFIG: {
|
|
285
337
|
tokenRefreshThreshold: number;
|
|
@@ -309,4 +361,22 @@ declare const API_ENDPOINTS: {
|
|
|
309
361
|
audit: string;
|
|
310
362
|
};
|
|
311
363
|
|
|
312
|
-
|
|
364
|
+
declare function validateEnvironment(): void;
|
|
365
|
+
|
|
366
|
+
interface ErrorTracker {
|
|
367
|
+
captureException(error: Error, context?: Record<string, any>): void;
|
|
368
|
+
captureMessage(message: string, context?: Record<string, any>): void;
|
|
369
|
+
}
|
|
370
|
+
declare let errorTracker: ErrorTracker;
|
|
371
|
+
declare function initErrorTracker(tracker: ErrorTracker): void;
|
|
372
|
+
|
|
373
|
+
declare const securityHeaders: {
|
|
374
|
+
'X-Frame-Options': string;
|
|
375
|
+
'X-Content-Type-Options': string;
|
|
376
|
+
'X-XSS-Protection': string;
|
|
377
|
+
'Referrer-Policy': string;
|
|
378
|
+
'Permissions-Policy': string;
|
|
379
|
+
};
|
|
380
|
+
declare function applySecurityHeaders(response: Response): Response;
|
|
381
|
+
|
|
382
|
+
export { API_ENDPOINTS, AUTH_CONFIG, AuditAction, type AuditEntry$1 as AuditEntry, AuditLogger, AuthProvider, AuthService, type AuthState, type AuthTokens, DeviceFingerprint, type LoginCredentials, LoginForm, MFAService, MFASetup, MFAVerification, type MFAVerify, ProtectedRoute, RateLimiter, type RegisterData, STORAGE_KEYS, SessionManager, SessionWarning, TokenBlacklist, type TokenBlacklistEntry, TokenManager, SecureTokenStorage as TokenStorage, type User, applySecurityHeaders, cn, errorTracker, formatDate, generateRandomString, getErrorMessage, initErrorTracker, isValidEmail, securityHeaders, setupAuthInterceptors, useAuth, useAuthContext, useProtectedRoute, validateEnvironment };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { AxiosInstance } from 'axios';
|
|
2
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
|
-
import React$1 from 'react';
|
|
3
|
+
import * as React$1 from 'react';
|
|
4
|
+
import React__default from 'react';
|
|
4
5
|
|
|
5
6
|
interface User {
|
|
6
7
|
id: string;
|
|
@@ -35,6 +36,11 @@ interface AuthState {
|
|
|
35
36
|
isLoading: boolean;
|
|
36
37
|
error: string | null;
|
|
37
38
|
}
|
|
39
|
+
interface MFASetup$1 {
|
|
40
|
+
secret: string;
|
|
41
|
+
qrCode: string;
|
|
42
|
+
backupCodes: string[];
|
|
43
|
+
}
|
|
38
44
|
interface MFAVerify {
|
|
39
45
|
userId: string;
|
|
40
46
|
code: string;
|
|
@@ -87,6 +93,9 @@ declare class AuthService {
|
|
|
87
93
|
getAxiosInstance(): AxiosInstance;
|
|
88
94
|
getUser(): User | null;
|
|
89
95
|
getState(): AuthState;
|
|
96
|
+
setupMFA(): Promise<MFASetup$1>;
|
|
97
|
+
disableMFA(code: string): Promise<void>;
|
|
98
|
+
updateUser(userData: Partial<User>): Promise<User>;
|
|
90
99
|
}
|
|
91
100
|
|
|
92
101
|
declare class SecureTokenStorage {
|
|
@@ -244,18 +253,59 @@ declare function useProtectedRoute(redirectTo?: string, requiredRole?: string |
|
|
|
244
253
|
isLoading: boolean;
|
|
245
254
|
};
|
|
246
255
|
|
|
256
|
+
interface AuthContextValue extends AuthState {
|
|
257
|
+
login: (credentials: LoginCredentials) => Promise<{
|
|
258
|
+
requiresMFA: boolean;
|
|
259
|
+
user?: User;
|
|
260
|
+
}>;
|
|
261
|
+
register: (data: RegisterData) => Promise<User>;
|
|
262
|
+
logout: () => Promise<void>;
|
|
263
|
+
logoutAllDevices: () => Promise<void>;
|
|
264
|
+
refreshSession: () => Promise<void>;
|
|
265
|
+
changePassword: (currentPassword: string, newPassword: string) => Promise<void>;
|
|
266
|
+
hasRole: (role: string | string[]) => boolean;
|
|
267
|
+
getAxiosInstance: () => any;
|
|
268
|
+
getUser: () => User | null;
|
|
269
|
+
verifyMFA: (code: string, trustDevice?: boolean) => Promise<User>;
|
|
270
|
+
setupMFA: () => Promise<MFASetup$1>;
|
|
271
|
+
disableMFA: (code: string) => Promise<void>;
|
|
272
|
+
updateUser: (userData: Partial<User>) => Promise<void>;
|
|
273
|
+
clearError: () => void;
|
|
274
|
+
isTokenExpired: () => boolean;
|
|
275
|
+
getAccessToken: () => string | null;
|
|
276
|
+
healthCheck: () => Promise<boolean>;
|
|
277
|
+
refreshTokens: () => Promise<void>;
|
|
278
|
+
getRemainingSessionTime: () => number;
|
|
279
|
+
extendSession: () => Promise<void>;
|
|
280
|
+
}
|
|
247
281
|
interface AuthProviderProps {
|
|
248
|
-
children:
|
|
282
|
+
children: React__default.ReactNode;
|
|
249
283
|
apiUrl?: string;
|
|
284
|
+
onError?: (error: string) => void;
|
|
285
|
+
onSessionExpired?: () => void;
|
|
286
|
+
onLogin?: (user: User) => void;
|
|
287
|
+
onLogout?: () => void;
|
|
288
|
+
autoRefresh?: boolean;
|
|
289
|
+
refreshThreshold?: number;
|
|
250
290
|
}
|
|
251
|
-
declare function AuthProvider({ children, apiUrl }: AuthProviderProps): react_jsx_runtime.JSX.Element;
|
|
291
|
+
declare function AuthProvider({ children, apiUrl, onError, onSessionExpired, onLogin, onLogout, autoRefresh, refreshThreshold }: AuthProviderProps): react_jsx_runtime.JSX.Element;
|
|
292
|
+
declare function useAuthContext(): AuthContextValue;
|
|
252
293
|
|
|
253
294
|
interface ProtectedRouteProps {
|
|
254
295
|
children: React.ReactNode;
|
|
255
296
|
requiredRole?: string | string[];
|
|
256
297
|
fallback?: React.ReactNode;
|
|
298
|
+
redirectTo?: string;
|
|
257
299
|
}
|
|
258
|
-
declare function ProtectedRoute({ children, requiredRole, fallback }: ProtectedRouteProps): react_jsx_runtime.JSX.Element | null;
|
|
300
|
+
declare function ProtectedRoute({ children, requiredRole, fallback, redirectTo }: ProtectedRouteProps): string | number | true | Iterable<React$1.ReactNode> | react_jsx_runtime.JSX.Element | null;
|
|
301
|
+
|
|
302
|
+
interface LoginFormProps {
|
|
303
|
+
onSubmit: (email: string, password: string) => Promise<void>;
|
|
304
|
+
isLoading?: boolean;
|
|
305
|
+
error?: string;
|
|
306
|
+
className?: string;
|
|
307
|
+
}
|
|
308
|
+
declare function LoginForm({ onSubmit, isLoading, error, className }: LoginFormProps): react_jsx_runtime.JSX.Element;
|
|
259
309
|
|
|
260
310
|
interface MFASetupProps {
|
|
261
311
|
userId: string;
|
|
@@ -280,6 +330,8 @@ declare function setupAuthInterceptors(axiosInstance: AxiosInstance, baseURL: st
|
|
|
280
330
|
declare function cn(...classes: (string | undefined | false)[]): string;
|
|
281
331
|
declare function getErrorMessage(error: unknown): string;
|
|
282
332
|
declare function isValidEmail(email: string): boolean;
|
|
333
|
+
declare function formatDate(date: Date): string;
|
|
334
|
+
declare function generateRandomString(length: number): string;
|
|
283
335
|
|
|
284
336
|
declare const AUTH_CONFIG: {
|
|
285
337
|
tokenRefreshThreshold: number;
|
|
@@ -309,4 +361,22 @@ declare const API_ENDPOINTS: {
|
|
|
309
361
|
audit: string;
|
|
310
362
|
};
|
|
311
363
|
|
|
312
|
-
|
|
364
|
+
declare function validateEnvironment(): void;
|
|
365
|
+
|
|
366
|
+
interface ErrorTracker {
|
|
367
|
+
captureException(error: Error, context?: Record<string, any>): void;
|
|
368
|
+
captureMessage(message: string, context?: Record<string, any>): void;
|
|
369
|
+
}
|
|
370
|
+
declare let errorTracker: ErrorTracker;
|
|
371
|
+
declare function initErrorTracker(tracker: ErrorTracker): void;
|
|
372
|
+
|
|
373
|
+
declare const securityHeaders: {
|
|
374
|
+
'X-Frame-Options': string;
|
|
375
|
+
'X-Content-Type-Options': string;
|
|
376
|
+
'X-XSS-Protection': string;
|
|
377
|
+
'Referrer-Policy': string;
|
|
378
|
+
'Permissions-Policy': string;
|
|
379
|
+
};
|
|
380
|
+
declare function applySecurityHeaders(response: Response): Response;
|
|
381
|
+
|
|
382
|
+
export { API_ENDPOINTS, AUTH_CONFIG, AuditAction, type AuditEntry$1 as AuditEntry, AuditLogger, AuthProvider, AuthService, type AuthState, type AuthTokens, DeviceFingerprint, type LoginCredentials, LoginForm, MFAService, MFASetup, MFAVerification, type MFAVerify, ProtectedRoute, RateLimiter, type RegisterData, STORAGE_KEYS, SessionManager, SessionWarning, TokenBlacklist, type TokenBlacklistEntry, TokenManager, SecureTokenStorage as TokenStorage, type User, applySecurityHeaders, cn, errorTracker, formatDate, generateRandomString, getErrorMessage, initErrorTracker, isValidEmail, securityHeaders, setupAuthInterceptors, useAuth, useAuthContext, useProtectedRoute, validateEnvironment };
|