reslib 1.0.0 → 1.0.2
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/build/auth/index.d.ts +495 -83
- package/build/auth/index.js +2 -2
- package/build/auth/types.d.ts +88 -15
- package/build/countries/index.js +1 -1
- package/build/currency/index.d.ts +1 -1
- package/build/currency/index.js +1 -1
- package/build/currency/session.d.ts +1 -1
- package/build/currency/session.js +2 -2
- package/build/i18n/index.js +1 -1
- package/build/inputFormatter/index.js +1 -1
- package/build/logger/index.js +1 -1
- package/build/resources/index.js +3 -3
- package/build/resources/types/index.d.ts +11 -11
- package/build/session/index.d.ts +6 -6
- package/build/session/index.js +1 -1
- package/build/utils/date/dateHelper.js +1 -1
- package/build/utils/date/index.js +1 -1
- package/build/utils/index.d.ts +2 -0
- package/build/utils/index.js +2 -2
- package/build/utils/isHexadecimal.d.ts +23 -0
- package/build/utils/isHexadecimal.js +1 -0
- package/build/utils/isMongoId.d.ts +25 -0
- package/build/utils/isMongoId.js +1 -0
- package/build/utils/numbers.js +1 -1
- package/build/validator/index.js +3 -3
- package/build/validator/rules/array.d.ts +1 -1
- package/build/validator/rules/array.js +1 -1
- package/build/validator/rules/boolean.js +1 -1
- package/build/validator/rules/date.js +1 -1
- package/build/validator/rules/default.js +1 -1
- package/build/validator/rules/enum.js +1 -1
- package/build/validator/rules/file.js +1 -1
- package/build/validator/rules/format.js +2 -2
- package/build/validator/rules/index.js +3 -3
- package/build/validator/rules/multiRules.js +1 -1
- package/build/validator/rules/numeric.js +1 -1
- package/build/validator/rules/string.js +1 -1
- package/build/validator/rules/target.js +1 -1
- package/build/validator/types.d.ts +8 -13
- package/build/validator/validator.d.ts +8 -19
- package/build/validator/validator.js +1 -1
- package/package.json +1 -1
package/build/auth/index.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { Observable } from '../observable';
|
|
2
|
+
import { ClassConstructor } from '../types';
|
|
2
3
|
import { ResourceActionName, ResourceName } from '../resources/types';
|
|
3
4
|
import 'reflect-metadata';
|
|
4
5
|
import { Dictionary } from '../types/dictionary';
|
|
5
6
|
import './types';
|
|
6
|
-
import { AuthEvent, AuthPerm, AuthPerms, AuthSessionStorage, AuthUser } from './types';
|
|
7
|
+
import { AuthEvent, AuthPerm, AuthPerms, AuthSecureStorage, AuthSessionStorage, AuthUser } from './types';
|
|
7
8
|
export * from './types';
|
|
8
9
|
/***
|
|
9
10
|
* A class that provides methods for managing session data.
|
|
@@ -93,43 +94,6 @@ declare class Session {
|
|
|
93
94
|
* const sessionData = getData(null); // Returns: {}
|
|
94
95
|
*/
|
|
95
96
|
static getData(sessionName?: string): Dictionary;
|
|
96
|
-
/**
|
|
97
|
-
* Retrieves the authentication token from the session storage.
|
|
98
|
-
*
|
|
99
|
-
* This function checks the currently signed-in user and returns their token.
|
|
100
|
-
* If the user is not signed in or if there is no token available, it will return
|
|
101
|
-
* `undefined` or `null`.
|
|
102
|
-
*
|
|
103
|
-
* @returns {string | undefined | null} The authentication token of the signed user,
|
|
104
|
-
* or `undefined` if the user is not signed in, or `null` if there is no token.
|
|
105
|
-
*
|
|
106
|
-
* @example
|
|
107
|
-
* const token = getToken();
|
|
108
|
-
* if (token) {
|
|
109
|
-
* console.log("User token:", token);
|
|
110
|
-
* } else {
|
|
111
|
-
* console.log("No user is signed in or token is not available.");
|
|
112
|
-
* }
|
|
113
|
-
*/
|
|
114
|
-
static getToken(): string | undefined | null;
|
|
115
|
-
/**
|
|
116
|
-
* Sets the authentication token in the session storage for the currently signed-in user.
|
|
117
|
-
*
|
|
118
|
-
* This function updates the signed user's information by adding or updating the token
|
|
119
|
-
* in the session storage. If the token is `null`, it will remove the token from the user's
|
|
120
|
-
* session data.
|
|
121
|
-
*
|
|
122
|
-
* @param {string | null} token - The token to be set for the signed user.
|
|
123
|
-
* If `null`, the token will be removed from the user's session data.
|
|
124
|
-
*
|
|
125
|
-
* @returns {void} This function does not return a value.
|
|
126
|
-
*
|
|
127
|
-
* @example
|
|
128
|
-
* setToken("my-secret-token");
|
|
129
|
-
* // To remove the token
|
|
130
|
-
* setToken(null);
|
|
131
|
-
*/
|
|
132
|
-
static setToken(token: string | null): void;
|
|
133
97
|
/**
|
|
134
98
|
* Retrieves a session storage object that provides methods for managing session data.
|
|
135
99
|
*
|
|
@@ -153,15 +117,6 @@ declare class Session {
|
|
|
153
117
|
* // Create a session storage object with a specific session name
|
|
154
118
|
* const session = getSessionStorage('userSession');
|
|
155
119
|
*
|
|
156
|
-
* // Set a value in the session storage
|
|
157
|
-
* session.set('token', 'abc123');
|
|
158
|
-
*
|
|
159
|
-
* // Retrieve the value from session storage
|
|
160
|
-
* const token = session.get('token'); // 'abc123'
|
|
161
|
-
*
|
|
162
|
-
* // Get all data stored in the session
|
|
163
|
-
* const allData = session.getData(); // { token: 'abc123' }
|
|
164
|
-
*
|
|
165
120
|
* // Get the session key
|
|
166
121
|
* const sessionKey = session.getKey(); // 'userSession'
|
|
167
122
|
*
|
|
@@ -319,22 +274,6 @@ export declare class Auth {
|
|
|
319
274
|
* ```
|
|
320
275
|
*
|
|
321
276
|
* @example
|
|
322
|
-
* ```typescript
|
|
323
|
-
* // API request with user token
|
|
324
|
-
* async function makeAuthenticatedRequest(url: string) {
|
|
325
|
-
* const user = Auth.getSignedUser();
|
|
326
|
-
* if (!user?.token) {
|
|
327
|
-
* throw new Error("No valid authentication token");
|
|
328
|
-
* }
|
|
329
|
-
*
|
|
330
|
-
* return fetch(url, {
|
|
331
|
-
* headers: {
|
|
332
|
-
* 'Authorization': `Bearer ${user.token}`,
|
|
333
|
-
* 'Content-Type': 'application/json'
|
|
334
|
-
* }
|
|
335
|
-
* });
|
|
336
|
-
* }
|
|
337
|
-
* ```
|
|
338
277
|
*
|
|
339
278
|
* @throws {CryptoError} May throw during decryption if session data is corrupted
|
|
340
279
|
* @throws {SyntaxError} May throw during JSON parsing if decrypted data is malformed
|
|
@@ -343,7 +282,6 @@ export declare class Auth {
|
|
|
343
282
|
* @see {@link setSignedUser} - Method to store user in session
|
|
344
283
|
* @see {@link signIn} - High-level user authentication method
|
|
345
284
|
* @see {@link signOut} - Method to clear user session
|
|
346
|
-
* @see {@link Session.getToken} - Utility to get user's authentication token
|
|
347
285
|
* @see {@link checkUserPermission} - Check specific user permissions
|
|
348
286
|
*
|
|
349
287
|
*
|
|
@@ -379,7 +317,7 @@ export declare class Auth {
|
|
|
379
317
|
*
|
|
380
318
|
* ### Security Architecture:
|
|
381
319
|
* - **AES Encryption**: User data is encrypted before storage to protect sensitive information
|
|
382
|
-
* - **Session Timestamping**: Automatically adds `
|
|
320
|
+
* - **Session Timestamping**: Automatically adds `sessionCreatedAt` timestamp for session tracking
|
|
383
321
|
* - **Error Isolation**: Encryption failures don't crash the application, user reference is safely cleared
|
|
384
322
|
* - **Memory Management**: Updates local cache reference for immediate access
|
|
385
323
|
*
|
|
@@ -392,7 +330,7 @@ export declare class Auth {
|
|
|
392
330
|
* @param u - The user object to store in session, or `null` to clear the current session.
|
|
393
331
|
* When providing a user object, it should contain all necessary authentication
|
|
394
332
|
* information including permissions, roles, and tokens. The object will be
|
|
395
|
-
* automatically timestamped with `
|
|
333
|
+
* automatically timestamped with `sessionCreatedAt`.
|
|
396
334
|
*
|
|
397
335
|
* @param triggerEvent - Optional flag controlling whether to broadcast authentication events.
|
|
398
336
|
* When `true` (default), triggers either 'SIGN_IN' or 'SIGN_OUT' events
|
|
@@ -410,7 +348,6 @@ export declare class Auth {
|
|
|
410
348
|
* id: "user123",
|
|
411
349
|
* username: "john_doe",
|
|
412
350
|
* email: "john@example.com",
|
|
413
|
-
* token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
|
414
351
|
* perms: { documents: ["read", "write"] },
|
|
415
352
|
* roles: [{ name: "editor", perms: { images: ["upload"] } }]
|
|
416
353
|
* };
|
|
@@ -537,7 +474,7 @@ export declare class Auth {
|
|
|
537
474
|
*
|
|
538
475
|
* @param user - The authenticated user object containing all necessary user information.
|
|
539
476
|
* Must be a valid object conforming to the `AuthUser` interface, including
|
|
540
|
-
* properties like id, username, email, permissions, roles
|
|
477
|
+
* properties like id, username, email, permissions, roles.
|
|
541
478
|
* The object should come from a successful authentication process (login API, OAuth, etc.).
|
|
542
479
|
*
|
|
543
480
|
* @param triggerEvent - Optional flag controlling whether to broadcast authentication events.
|
|
@@ -587,7 +524,6 @@ export declare class Auth {
|
|
|
587
524
|
* id: userProfile.id,
|
|
588
525
|
* username: userProfile.login,
|
|
589
526
|
* email: userProfile.email,
|
|
590
|
-
* token: tokenResponse.access_token,
|
|
591
527
|
* perms: await fetchUserPermissions(userProfile.id),
|
|
592
528
|
* roles: await fetchUserRoles(userProfile.id),
|
|
593
529
|
* provider: 'oauth'
|
|
@@ -685,7 +621,6 @@ export declare class Auth {
|
|
|
685
621
|
* **Best Practices:**
|
|
686
622
|
* - Always validate user data before calling this method
|
|
687
623
|
* - Use try-catch blocks to handle authentication failures gracefully
|
|
688
|
-
* - Consider implementing token refresh logic for long-lived sessions
|
|
689
624
|
* - Use event listeners to initialize user-specific application features
|
|
690
625
|
*
|
|
691
626
|
* **Error Handling:**
|
|
@@ -848,9 +783,6 @@ export declare class Auth {
|
|
|
848
783
|
* return true;
|
|
849
784
|
* }
|
|
850
785
|
*
|
|
851
|
-
* // Perform API sign-out call if needed
|
|
852
|
-
* await this.notifyServerSignOut(currentUser.token);
|
|
853
|
-
*
|
|
854
786
|
* // Sign out locally
|
|
855
787
|
* await Auth.signOut();
|
|
856
788
|
*
|
|
@@ -864,16 +796,6 @@ export declare class Auth {
|
|
|
864
796
|
* return false;
|
|
865
797
|
* }
|
|
866
798
|
* }
|
|
867
|
-
*
|
|
868
|
-
* private async notifyServerSignOut(token: string): Promise<void> {
|
|
869
|
-
* await fetch('/api/auth/logout', {
|
|
870
|
-
* method: 'POST',
|
|
871
|
-
* headers: {
|
|
872
|
-
* 'Authorization': `Bearer ${token}`,
|
|
873
|
-
* 'Content-Type': 'application/json'
|
|
874
|
-
* }
|
|
875
|
-
* });
|
|
876
|
-
* }
|
|
877
799
|
* }
|
|
878
800
|
* ```
|
|
879
801
|
*
|
|
@@ -2031,4 +1953,494 @@ export declare class Auth {
|
|
|
2031
1953
|
* - Encryption features require a compatible JavaScript environment
|
|
2032
1954
|
*/
|
|
2033
1955
|
static get Session(): typeof Session;
|
|
1956
|
+
private static _secureStorage;
|
|
1957
|
+
/**
|
|
1958
|
+
* Gets the currently configured secure storage implementation for authentication data.
|
|
1959
|
+
*
|
|
1960
|
+
* This getter provides access to the secure storage adapter that handles sensitive authentication
|
|
1961
|
+
* data like tokens and encrypted user sessions. The method implements a fallback mechanism that
|
|
1962
|
+
* prioritizes custom implementations while maintaining a default secure storage as backup.
|
|
1963
|
+
*
|
|
1964
|
+
* ### Storage Resolution Priority:
|
|
1965
|
+
* 1. **Custom Storage**: Returns the user-configured storage implementation if valid
|
|
1966
|
+
* 2. **Cached Storage**: Returns the previously validated storage instance
|
|
1967
|
+
* 3. **Default Storage**: Falls back to the built-in secure storage wrapper
|
|
1968
|
+
*
|
|
1969
|
+
* ### Security Architecture:
|
|
1970
|
+
* - **Validation**: All storage implementations are validated before use
|
|
1971
|
+
* - **Metadata Storage**: Uses reflection metadata to persist custom configurations
|
|
1972
|
+
* - **Fail-Safe Design**: Always returns a working storage implementation
|
|
1973
|
+
* - **Cross-Platform**: Supports platform-specific secure storage adapters
|
|
1974
|
+
*
|
|
1975
|
+
* ### Implementation Details:
|
|
1976
|
+
* The getter checks for custom storage configurations stored via reflection metadata,
|
|
1977
|
+
* validates the implementation, and caches it for performance. If no valid custom
|
|
1978
|
+
* storage is found, it returns the default secure storage that wraps the session module.
|
|
1979
|
+
*
|
|
1980
|
+
* @returns The configured `AuthSecureStorage` implementation for secure data operations.
|
|
1981
|
+
* This will be either a custom user-provided storage adapter or the default
|
|
1982
|
+
* secure storage implementation that provides basic encrypted session storage.
|
|
1983
|
+
*
|
|
1984
|
+
* @example
|
|
1985
|
+
* ```typescript
|
|
1986
|
+
* // Get the current secure storage implementation
|
|
1987
|
+
* const storage = Auth.secureStorage;
|
|
1988
|
+
* console.log(storage.constructor.name); // "WebSecureStorage" or "DefaultAuthStorage"
|
|
1989
|
+
* ```
|
|
1990
|
+
*
|
|
1991
|
+
* @example
|
|
1992
|
+
* ```typescript
|
|
1993
|
+
* // Check if custom storage is configured
|
|
1994
|
+
* const currentStorage = Auth.secureStorage;
|
|
1995
|
+
* const isCustomStorage = currentStorage !== Auth['DefaultAuthStorage'];
|
|
1996
|
+
* console.log(`Using custom storage: ${isCustomStorage}`);
|
|
1997
|
+
* ```
|
|
1998
|
+
*
|
|
1999
|
+
* @example
|
|
2000
|
+
* ```typescript
|
|
2001
|
+
* // Access storage methods directly
|
|
2002
|
+
* const token = await Auth.secureStorage.get('auth-token');
|
|
2003
|
+
* await Auth.secureStorage.set('user-session', encryptedData);
|
|
2004
|
+
* await Auth.secureStorage.remove('expired-data');
|
|
2005
|
+
* ```
|
|
2006
|
+
*
|
|
2007
|
+
* @see {@link Auth.secureStorage} - Setter for configuring custom storage
|
|
2008
|
+
* @see {@link AuthSecureStorage} - Interface defining storage contract
|
|
2009
|
+
* @see {@link DefaultAuthStorage} - Default secure storage implementation
|
|
2010
|
+
* @see {@link Auth.getToken} - Uses this storage for token retrieval
|
|
2011
|
+
* @see {@link Auth.setToken} - Uses this storage for token storage
|
|
2012
|
+
*
|
|
2013
|
+
* @public
|
|
2014
|
+
* @readonly
|
|
2015
|
+
*
|
|
2016
|
+
* @remarks
|
|
2017
|
+
* **Performance Considerations:**
|
|
2018
|
+
* - The getter caches validated storage instances to avoid repeated validation
|
|
2019
|
+
* - Metadata lookup is performed only when necessary
|
|
2020
|
+
* - Default storage is lightweight and doesn't require external dependencies
|
|
2021
|
+
*
|
|
2022
|
+
* **Security Best Practices:**
|
|
2023
|
+
* - Never directly access the private `_secureStorage` field
|
|
2024
|
+
* - Always use this getter to ensure proper validation and fallbacks
|
|
2025
|
+
* - Custom storage implementations should handle encryption internally
|
|
2026
|
+
* - Validate storage implementations before configuration
|
|
2027
|
+
*
|
|
2028
|
+
* **Platform Compatibility:**
|
|
2029
|
+
* - Default storage works across web, Node.js, and React Native environments
|
|
2030
|
+
* - Custom implementations can provide platform-specific optimizations
|
|
2031
|
+
* - Storage validation ensures consistent behavior across platforms
|
|
2032
|
+
*/
|
|
2033
|
+
static get secureStorage(): AuthSecureStorage;
|
|
2034
|
+
/**
|
|
2035
|
+
* Configures a custom secure storage implementation for authentication data.
|
|
2036
|
+
*
|
|
2037
|
+
* This setter allows injection of platform-specific or custom secure storage adapters
|
|
2038
|
+
* that implement the `AuthSecureStorage` interface. The configured storage will be
|
|
2039
|
+
* used for all secure data operations including token storage, encrypted user sessions,
|
|
2040
|
+
* and other sensitive authentication data.
|
|
2041
|
+
*
|
|
2042
|
+
* ### Configuration Process:
|
|
2043
|
+
* 1. **Validation**: The provided storage implementation is validated for required methods
|
|
2044
|
+
* 2. **Metadata Storage**: Valid implementations are stored using reflection metadata
|
|
2045
|
+
* 3. **Caching**: The validated storage is cached for performance optimization
|
|
2046
|
+
* 4. **Fallback**: Invalid implementations are rejected, preserving existing configuration
|
|
2047
|
+
*
|
|
2048
|
+
* ### Security Requirements:
|
|
2049
|
+
* - **Method Validation**: Storage must implement `get`, `set`, and `remove` methods
|
|
2050
|
+
* - **Async Operations**: All methods must return Promises for secure storage APIs
|
|
2051
|
+
* - **Error Handling**: Implementations should handle storage failures gracefully
|
|
2052
|
+
* - **Encryption**: Sensitive data should be encrypted at the storage layer
|
|
2053
|
+
*
|
|
2054
|
+
* ### Use Cases:
|
|
2055
|
+
* - **Web Applications**: HttpOnly cookies, IndexedDB with encryption
|
|
2056
|
+
* - **React Native**: expo-secure-store, react-native-keychain
|
|
2057
|
+
* - **Node.js**: Encrypted file storage, environment variables
|
|
2058
|
+
* - **Enterprise**: Hardware security modules, key management services
|
|
2059
|
+
*
|
|
2060
|
+
* @param secureStorage - A custom storage implementation conforming to the `AuthSecureStorage` interface.
|
|
2061
|
+
* The implementation must provide secure, asynchronous storage operations.
|
|
2062
|
+
* Invalid or incomplete implementations will be rejected.
|
|
2063
|
+
*
|
|
2064
|
+
* @example
|
|
2065
|
+
* ```typescript
|
|
2066
|
+
* // Configure for web environment with HttpOnly cookies
|
|
2067
|
+
* class WebSecureStorage implements AuthSecureStorage {
|
|
2068
|
+
* async get(key: string): Promise<string | null> {
|
|
2069
|
+
* return Cookies.get(key) || null;
|
|
2070
|
+
* }
|
|
2071
|
+
* async set(key: string, value: string): Promise<void> {
|
|
2072
|
+
* Cookies.set(key, value, { httpOnly: true, secure: true });
|
|
2073
|
+
* }
|
|
2074
|
+
* async remove(key: string): Promise<void> {
|
|
2075
|
+
* Cookies.remove(key);
|
|
2076
|
+
* }
|
|
2077
|
+
* }
|
|
2078
|
+
*
|
|
2079
|
+
* Auth.secureStorage = new WebSecureStorage();
|
|
2080
|
+
* ```
|
|
2081
|
+
*
|
|
2082
|
+
* @example
|
|
2083
|
+
* ```typescript
|
|
2084
|
+
* // Configure for React Native with expo-secure-store
|
|
2085
|
+
* import * as SecureStore from 'expo-secure-store';
|
|
2086
|
+
*
|
|
2087
|
+
* class ReactNativeSecureStorage implements AuthSecureStorage {
|
|
2088
|
+
* async get(key: string): Promise<string | null> {
|
|
2089
|
+
* try {
|
|
2090
|
+
* return await SecureStore.getItemAsync(key);
|
|
2091
|
+
* } catch {
|
|
2092
|
+
* return null;
|
|
2093
|
+
* }
|
|
2094
|
+
* }
|
|
2095
|
+
* async set(key: string, value: string): Promise<void> {
|
|
2096
|
+
* await SecureStore.setItemAsync(key, value);
|
|
2097
|
+
* }
|
|
2098
|
+
* async remove(key: string): Promise<void> {
|
|
2099
|
+
* await SecureStore.deleteItemAsync(key);
|
|
2100
|
+
* }
|
|
2101
|
+
* }
|
|
2102
|
+
*
|
|
2103
|
+
* Auth.secureStorage = new ReactNativeSecureStorage();
|
|
2104
|
+
* ```
|
|
2105
|
+
*
|
|
2106
|
+
* @example
|
|
2107
|
+
* ```typescript
|
|
2108
|
+
* // Configure for Node.js with encrypted file storage
|
|
2109
|
+
* import * as fs from 'fs';
|
|
2110
|
+
* import * as crypto from 'crypto';
|
|
2111
|
+
*
|
|
2112
|
+
* class NodeSecureStorage implements AuthSecureStorage {
|
|
2113
|
+
* private encrypt(data: string): string {
|
|
2114
|
+
* const cipher = crypto.createCipher('aes-256-cbc', 'encryption-key');
|
|
2115
|
+
* return cipher.update(data, 'utf8', 'hex') + cipher.final('hex');
|
|
2116
|
+
* }
|
|
2117
|
+
*
|
|
2118
|
+
* private decrypt(data: string): string {
|
|
2119
|
+
* const decipher = crypto.createDecipher('aes-256-cbc', 'encryption-key');
|
|
2120
|
+
* return decipher.update(data, 'hex', 'utf8') + decipher.final('utf8');
|
|
2121
|
+
* }
|
|
2122
|
+
*
|
|
2123
|
+
* async get(key: string): Promise<string | null> {
|
|
2124
|
+
* try {
|
|
2125
|
+
* const filePath = `./secure/${key}.enc`;
|
|
2126
|
+
* if (!fs.existsSync(filePath)) return null;
|
|
2127
|
+
* const encrypted = fs.readFileSync(filePath, 'utf8');
|
|
2128
|
+
* return this.decrypt(encrypted);
|
|
2129
|
+
* } catch {
|
|
2130
|
+
* return null;
|
|
2131
|
+
* }
|
|
2132
|
+
* }
|
|
2133
|
+
*
|
|
2134
|
+
* async set(key: string, value: string): Promise<void> {
|
|
2135
|
+
* const encrypted = this.encrypt(value);
|
|
2136
|
+
* const filePath = `./secure/${key}.enc`;
|
|
2137
|
+
* fs.writeFileSync(filePath, encrypted);
|
|
2138
|
+
* }
|
|
2139
|
+
*
|
|
2140
|
+
* async remove(key: string): Promise<void> {
|
|
2141
|
+
* const filePath = `./secure/${key}.enc`;
|
|
2142
|
+
* if (fs.existsSync(filePath)) {
|
|
2143
|
+
* fs.unlinkSync(filePath);
|
|
2144
|
+
* }
|
|
2145
|
+
* }
|
|
2146
|
+
* }
|
|
2147
|
+
*
|
|
2148
|
+
* Auth.secureStorage = new NodeSecureStorage();
|
|
2149
|
+
* ```
|
|
2150
|
+
*
|
|
2151
|
+
* @example
|
|
2152
|
+
* ```typescript
|
|
2153
|
+
* // Error handling for invalid storage implementations
|
|
2154
|
+
* class InvalidStorage implements AuthSecureStorage {
|
|
2155
|
+
* // Missing required methods
|
|
2156
|
+
* async get(key: string): Promise<string | null> {
|
|
2157
|
+
* return null;
|
|
2158
|
+
* }
|
|
2159
|
+
* // Missing set and remove methods
|
|
2160
|
+
* }
|
|
2161
|
+
*
|
|
2162
|
+
* try {
|
|
2163
|
+
* Auth.secureStorage = new InvalidStorage(); // Will be rejected
|
|
2164
|
+
* console.log('Storage configured successfully');
|
|
2165
|
+
* } catch (error) {
|
|
2166
|
+
* console.log('Storage configuration failed:', error.message);
|
|
2167
|
+
* }
|
|
2168
|
+
* ```
|
|
2169
|
+
*
|
|
2170
|
+
* @see {@link Auth.secureStorage} - Getter for accessing configured storage
|
|
2171
|
+
* @see {@link AuthSecureStorage} - Interface defining required storage methods
|
|
2172
|
+
* @see {@link DefaultAuthStorage} - Default storage implementation
|
|
2173
|
+
* @see {@link isValidStorage} - Validation function for storage implementations
|
|
2174
|
+
* @see {@link Auth.getToken} - Uses configured storage for token operations
|
|
2175
|
+
* @see {@link Auth.setToken} - Uses configured storage for token operations
|
|
2176
|
+
*
|
|
2177
|
+
* @public
|
|
2178
|
+
*
|
|
2179
|
+
* @remarks
|
|
2180
|
+
* **Implementation Requirements:**
|
|
2181
|
+
* - All methods must be asynchronous and return Promises
|
|
2182
|
+
* - Storage implementations should handle errors gracefully
|
|
2183
|
+
* - Sensitive data should be encrypted before storage
|
|
2184
|
+
* - Implementations should be thread-safe where applicable
|
|
2185
|
+
*
|
|
2186
|
+
* **Security Considerations:**
|
|
2187
|
+
* - Never store sensitive data in plain text
|
|
2188
|
+
* - Implement proper error handling to prevent information leakage
|
|
2189
|
+
* - Use platform-specific secure storage APIs when available
|
|
2190
|
+
* - Consider data encryption and integrity verification
|
|
2191
|
+
*
|
|
2192
|
+
* **Performance Guidelines:**
|
|
2193
|
+
* - Implementations should be efficient for frequent access patterns
|
|
2194
|
+
* - Consider caching strategies for improved performance
|
|
2195
|
+
* - Avoid synchronous operations that could block the event loop
|
|
2196
|
+
* - Implement connection pooling for network-based storage
|
|
2197
|
+
*
|
|
2198
|
+
* **Testing Recommendations:**
|
|
2199
|
+
* - Test storage operations under various failure conditions
|
|
2200
|
+
* - Verify encryption/decryption works correctly
|
|
2201
|
+
* - Test concurrent access patterns
|
|
2202
|
+
* - Validate behavior across different platforms
|
|
2203
|
+
*/
|
|
2204
|
+
static set secureStorage(secureStorage: AuthSecureStorage);
|
|
2205
|
+
/**
|
|
2206
|
+
* Retrieves the authentication token from secure storage.
|
|
2207
|
+
*
|
|
2208
|
+
* This method provides secure, cross-platform access to the stored authentication token.
|
|
2209
|
+
* The token is stored separately from user data for enhanced security and to prevent
|
|
2210
|
+
* accidental exposure through session data serialization.
|
|
2211
|
+
*
|
|
2212
|
+
* @returns Promise resolving to the token string, or null if no token is stored
|
|
2213
|
+
* @example
|
|
2214
|
+
* ```typescript
|
|
2215
|
+
* const token = await Auth.getToken();
|
|
2216
|
+
* if (token) {
|
|
2217
|
+
* // Use token for API calls
|
|
2218
|
+
* }
|
|
2219
|
+
* ```
|
|
2220
|
+
*/
|
|
2221
|
+
static getToken(): Promise<string | null>;
|
|
2222
|
+
/**
|
|
2223
|
+
* Stores the authentication token in secure storage.
|
|
2224
|
+
*
|
|
2225
|
+
* This method securely stores the authentication token using the configured secure storage
|
|
2226
|
+
* implementation. The token is isolated from user session data for better security practices.
|
|
2227
|
+
*
|
|
2228
|
+
* @param token - The authentication token to store
|
|
2229
|
+
* @returns Promise that resolves when the token is stored
|
|
2230
|
+
* @example
|
|
2231
|
+
* ```typescript
|
|
2232
|
+
* await Auth.setToken('jwt-token-here');
|
|
2233
|
+
* ```
|
|
2234
|
+
*/
|
|
2235
|
+
static setToken(token: string): Promise<void>;
|
|
2236
|
+
private static readonly authStorageMetaData;
|
|
2034
2237
|
}
|
|
2238
|
+
/**
|
|
2239
|
+
* Decorator factory for automatically attaching secure storage implementations to the Auth module.
|
|
2240
|
+
*
|
|
2241
|
+
* This decorator provides a declarative way to configure custom secure storage implementations
|
|
2242
|
+
* for the authentication system. When applied to a class that implements `AuthSecureStorage`,
|
|
2243
|
+
* it automatically instantiates the class, validates the implementation, and configures it
|
|
2244
|
+
* as the active secure storage for all authentication operations.
|
|
2245
|
+
*
|
|
2246
|
+
* ### How It Works:
|
|
2247
|
+
* 1. **Class Instantiation**: Creates a new instance of the decorated storage class
|
|
2248
|
+
* 2. **Validation**: Verifies the instance implements all required `AuthSecureStorage` methods
|
|
2249
|
+
* 3. **Configuration**: Sets the validated instance as the active secure storage via `Auth.secureStorage`
|
|
2250
|
+
* 4. **Error Handling**: Gracefully handles instantiation or validation failures
|
|
2251
|
+
*
|
|
2252
|
+
* ### Use Cases:
|
|
2253
|
+
* - **Dependency Injection**: Declarative configuration of storage implementations
|
|
2254
|
+
* - **Module Registration**: Automatic registration during module initialization
|
|
2255
|
+
* - **Platform Abstraction**: Easy switching between platform-specific storage implementations
|
|
2256
|
+
* - **Testing**: Simplified setup of mock or test storage implementations
|
|
2257
|
+
*
|
|
2258
|
+
* ### Security Features:
|
|
2259
|
+
* - **Runtime Validation**: Ensures storage implementations are valid before use
|
|
2260
|
+
* - **Fail-Safe Operation**: Invalid implementations are rejected without breaking the system
|
|
2261
|
+
* - **Error Isolation**: Storage configuration errors don't prevent application startup
|
|
2262
|
+
* - **Type Safety**: TypeScript ensures decorated classes conform to the interface
|
|
2263
|
+
*
|
|
2264
|
+
* @returns A class decorator function that configures secure storage implementations.
|
|
2265
|
+
*
|
|
2266
|
+
* @example
|
|
2267
|
+
* ```typescript
|
|
2268
|
+
* // Basic usage with a custom storage implementation
|
|
2269
|
+
* @AttachAuthSecureStorage()
|
|
2270
|
+
* class CustomSecureStorage implements AuthSecureStorage {
|
|
2271
|
+
* async get(key: string): Promise<string | null> {
|
|
2272
|
+
* // Custom secure storage logic
|
|
2273
|
+
* return await this.customGet(key);
|
|
2274
|
+
* }
|
|
2275
|
+
*
|
|
2276
|
+
* async set(key: string, value: string): Promise<void> {
|
|
2277
|
+
* // Custom secure storage logic
|
|
2278
|
+
* await this.customSet(key, value);
|
|
2279
|
+
* }
|
|
2280
|
+
*
|
|
2281
|
+
* async remove(key: string): Promise<void> {
|
|
2282
|
+
* // Custom secure storage logic
|
|
2283
|
+
* await this.customRemove(key);
|
|
2284
|
+
* }
|
|
2285
|
+
* }
|
|
2286
|
+
*
|
|
2287
|
+
* // The CustomSecureStorage is automatically configured when the module loads
|
|
2288
|
+
* ```
|
|
2289
|
+
*
|
|
2290
|
+
* @example
|
|
2291
|
+
* ```typescript
|
|
2292
|
+
* // Platform-specific storage implementations
|
|
2293
|
+
* @AttachAuthSecureStorage()
|
|
2294
|
+
* class WebSecureStorage implements AuthSecureStorage {
|
|
2295
|
+
* async get(key: string): Promise<string | null> {
|
|
2296
|
+
* return Cookies.get(key) || null;
|
|
2297
|
+
* }
|
|
2298
|
+
*
|
|
2299
|
+
* async set(key: string, value: string): Promise<void> {
|
|
2300
|
+
* Cookies.set(key, value, { httpOnly: true, secure: true });
|
|
2301
|
+
* }
|
|
2302
|
+
*
|
|
2303
|
+
* async remove(key: string): Promise<void> {
|
|
2304
|
+
* Cookies.remove(key);
|
|
2305
|
+
* }
|
|
2306
|
+
* }
|
|
2307
|
+
*
|
|
2308
|
+
* @AttachAuthSecureStorage()
|
|
2309
|
+
* class ReactNativeSecureStorage implements AuthSecureStorage {
|
|
2310
|
+
* async get(key: string): Promise<string | null> {
|
|
2311
|
+
* return await SecureStore.getItemAsync(key);
|
|
2312
|
+
* }
|
|
2313
|
+
*
|
|
2314
|
+
* async set(key: string, value: string): Promise<void> {
|
|
2315
|
+
* await SecureStore.setItemAsync(key, value);
|
|
2316
|
+
* }
|
|
2317
|
+
*
|
|
2318
|
+
* async remove(key: string): Promise<void> {
|
|
2319
|
+
* await SecureStore.deleteItemAsync(key);
|
|
2320
|
+
* }
|
|
2321
|
+
* }
|
|
2322
|
+
* ```
|
|
2323
|
+
*
|
|
2324
|
+
* @example
|
|
2325
|
+
* ```typescript
|
|
2326
|
+
* // Error handling for invalid implementations
|
|
2327
|
+
* @AttachAuthSecureStorage()
|
|
2328
|
+
* class InvalidStorage {
|
|
2329
|
+
* // Missing required methods - will be rejected during validation
|
|
2330
|
+
* async get(key: string): Promise<string | null> {
|
|
2331
|
+
* return null;
|
|
2332
|
+
* }
|
|
2333
|
+
* // Missing set() and remove() methods
|
|
2334
|
+
* }
|
|
2335
|
+
*
|
|
2336
|
+
* // The decorator will log an error and skip configuration
|
|
2337
|
+
* // Auth.secureStorage will retain its previous configuration
|
|
2338
|
+
* ```
|
|
2339
|
+
*
|
|
2340
|
+
* @example
|
|
2341
|
+
* ```typescript
|
|
2342
|
+
* // Testing with mock storage
|
|
2343
|
+
* @AttachAuthSecureStorage()
|
|
2344
|
+
* class MockSecureStorage implements AuthSecureStorage {
|
|
2345
|
+
* private store = new Map<string, string>();
|
|
2346
|
+
*
|
|
2347
|
+
* async get(key: string): Promise<string | null> {
|
|
2348
|
+
* return this.store.get(key) || null;
|
|
2349
|
+
* }
|
|
2350
|
+
*
|
|
2351
|
+
* async set(key: string, value: string): Promise<void> {
|
|
2352
|
+
* this.store.set(key, value);
|
|
2353
|
+
* }
|
|
2354
|
+
*
|
|
2355
|
+
* async remove(key: string): Promise<void> {
|
|
2356
|
+
* this.store.delete(key);
|
|
2357
|
+
* }
|
|
2358
|
+
*
|
|
2359
|
+
* // Additional methods for testing
|
|
2360
|
+
* clearAll(): void {
|
|
2361
|
+
* this.store.clear();
|
|
2362
|
+
* }
|
|
2363
|
+
*
|
|
2364
|
+
* getAllData(): Map<string, string> {
|
|
2365
|
+
* return new Map(this.store);
|
|
2366
|
+
* }
|
|
2367
|
+
* }
|
|
2368
|
+
*
|
|
2369
|
+
* // In tests, you can access the configured storage
|
|
2370
|
+
* const mockStorage = Auth.secureStorage as MockSecureStorage;
|
|
2371
|
+
* mockStorage.clearAll(); // Clear all test data
|
|
2372
|
+
* ```
|
|
2373
|
+
*
|
|
2374
|
+
* @example
|
|
2375
|
+
* ```typescript
|
|
2376
|
+
* // Advanced usage with dependency injection
|
|
2377
|
+
* interface StorageDependencies {
|
|
2378
|
+
* encryptionKey: string;
|
|
2379
|
+
* storagePath: string;
|
|
2380
|
+
* }
|
|
2381
|
+
*
|
|
2382
|
+
* @AttachAuthSecureStorage()
|
|
2383
|
+
* class EncryptedFileStorage implements AuthSecureStorage {
|
|
2384
|
+
* constructor(private deps: StorageDependencies = {
|
|
2385
|
+
* encryptionKey: 'default-key',
|
|
2386
|
+
* storagePath: './secure'
|
|
2387
|
+
* }) {}
|
|
2388
|
+
*
|
|
2389
|
+
* async get(key: string): Promise<string | null> {
|
|
2390
|
+
* // Implementation using this.deps.encryptionKey and this.deps.storagePath
|
|
2391
|
+
* return null;
|
|
2392
|
+
* }
|
|
2393
|
+
*
|
|
2394
|
+
* async set(key: string, value: string): Promise<void> {
|
|
2395
|
+
* // Implementation using dependencies
|
|
2396
|
+
* }
|
|
2397
|
+
*
|
|
2398
|
+
* async remove(key: string): Promise<void> {
|
|
2399
|
+
* // Implementation using dependencies
|
|
2400
|
+
* }
|
|
2401
|
+
* }
|
|
2402
|
+
* ```
|
|
2403
|
+
*
|
|
2404
|
+
* @see {@link AuthSecureStorage} - Interface that decorated classes must implement
|
|
2405
|
+
* @see {@link Auth.secureStorage} - Property that gets configured by this decorator
|
|
2406
|
+
* @see {@link isValidStorage} - Validation function used internally
|
|
2407
|
+
* @see {@link Auth.getToken} - Uses the configured storage for token operations
|
|
2408
|
+
* @see {@link Auth.setToken} - Uses the configured storage for token operations
|
|
2409
|
+
*
|
|
2410
|
+
* @public
|
|
2411
|
+
*
|
|
2412
|
+
* @remarks
|
|
2413
|
+
* **Decorator Execution:**
|
|
2414
|
+
* - Decorators are executed when the module is loaded, not when instances are created
|
|
2415
|
+
* - Multiple decorated classes will overwrite each other (last one wins)
|
|
2416
|
+
* - Failed validations are logged but don't throw exceptions
|
|
2417
|
+
*
|
|
2418
|
+
* **Best Practices:**
|
|
2419
|
+
* - Use this decorator for singleton storage implementations
|
|
2420
|
+
* - Ensure decorated classes have parameterless constructors
|
|
2421
|
+
* - Implement proper error handling in storage methods
|
|
2422
|
+
* - Test storage implementations thoroughly before decoration
|
|
2423
|
+
*
|
|
2424
|
+
* **Security Considerations:**
|
|
2425
|
+
* - Decorated classes should implement proper encryption
|
|
2426
|
+
* - Validate storage implementations in development environments
|
|
2427
|
+
* - Monitor error logs for storage configuration failures
|
|
2428
|
+
* - Consider the security implications of automatic configuration
|
|
2429
|
+
*
|
|
2430
|
+
* **Performance Notes:**
|
|
2431
|
+
* - Storage instantiation happens once during module initialization
|
|
2432
|
+
* - Validation overhead is minimal and occurs only at startup
|
|
2433
|
+
* - Decorated storage implementations should be optimized for frequent access
|
|
2434
|
+
*
|
|
2435
|
+
* **Error Handling:**
|
|
2436
|
+
* - Instantiation errors are caught and logged
|
|
2437
|
+
* - Validation failures are logged but don't prevent module loading
|
|
2438
|
+
* - Previous storage configuration is preserved on failure
|
|
2439
|
+
* - Error messages include context for debugging
|
|
2440
|
+
*
|
|
2441
|
+
* **TypeScript Integration:**
|
|
2442
|
+
* - Provides compile-time type checking for decorated classes
|
|
2443
|
+
* - Ensures interface compliance through type constraints
|
|
2444
|
+
* - Supports IntelliSense and refactoring tools
|
|
2445
|
+
*/
|
|
2446
|
+
export declare function AttachAuthSecureStorage(): (target: ClassConstructor<AuthSecureStorage>) => void;
|