reslib 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.
Files changed (200) hide show
  1. package/README.md +298 -0
  2. package/build/auth/index.d.ts +2034 -0
  3. package/build/auth/index.js +5 -0
  4. package/build/auth/types.d.ts +465 -0
  5. package/build/auth/types.js +1 -0
  6. package/build/countries/countries.d.ts +1454 -0
  7. package/build/countries/countries.js +1 -0
  8. package/build/countries/index.d.ts +159 -0
  9. package/build/countries/index.js +5 -0
  10. package/build/countries/types.d.ts +65 -0
  11. package/build/countries/types.js +1 -0
  12. package/build/currency/currencies.d.ts +8 -0
  13. package/build/currency/currencies.js +1 -0
  14. package/build/currency/index.d.ts +51 -0
  15. package/build/currency/index.js +5 -0
  16. package/build/currency/session.d.ts +23 -0
  17. package/build/currency/session.js +5 -0
  18. package/build/currency/types.d.ts +1039 -0
  19. package/build/currency/types.js +1 -0
  20. package/build/currency/utils.d.ts +25 -0
  21. package/build/currency/utils.js +1 -0
  22. package/build/i18n/index.d.ts +640 -0
  23. package/build/i18n/index.js +5 -0
  24. package/build/inputFormatter/index.d.ts +396 -0
  25. package/build/inputFormatter/index.js +5 -0
  26. package/build/inputFormatter/types.d.ts +544 -0
  27. package/build/inputFormatter/types.js +1 -0
  28. package/build/logger/index.d.ts +235 -0
  29. package/build/logger/index.js +5 -0
  30. package/build/observable/index.d.ts +329 -0
  31. package/build/observable/index.js +1 -0
  32. package/build/platform/index.d.ts +32 -0
  33. package/build/platform/index.js +1 -0
  34. package/build/resources/ResourcePaginationHelper.d.ts +537 -0
  35. package/build/resources/ResourcePaginationHelper.js +2 -0
  36. package/build/resources/decorators/create.decorator.d.ts +20 -0
  37. package/build/resources/decorators/create.decorator.js +1 -0
  38. package/build/resources/decorators/index.d.ts +41 -0
  39. package/build/resources/decorators/index.js +1 -0
  40. package/build/resources/fields/index.d.ts +33 -0
  41. package/build/resources/fields/index.js +1 -0
  42. package/build/resources/filters.d.ts +62 -0
  43. package/build/resources/filters.js +1 -0
  44. package/build/resources/index.d.ts +854 -0
  45. package/build/resources/index.js +6 -0
  46. package/build/resources/types/filters.d.ts +508 -0
  47. package/build/resources/types/filters.js +1 -0
  48. package/build/resources/types/index.d.ts +4138 -0
  49. package/build/resources/types/index.js +1 -0
  50. package/build/session/index.d.ts +1474 -0
  51. package/build/session/index.js +1 -0
  52. package/build/translations/auth.en.d.ts +3 -0
  53. package/build/translations/auth.en.js +1 -0
  54. package/build/translations/countries.en.d.ts +6 -0
  55. package/build/translations/countries.en.js +1 -0
  56. package/build/translations/currencies.en.d.ts +5 -0
  57. package/build/translations/currencies.en.js +1 -0
  58. package/build/translations/date.en.d.ts +19 -0
  59. package/build/translations/date.en.js +1 -0
  60. package/build/translations/index.d.ts +1583 -0
  61. package/build/translations/index.js +5 -0
  62. package/build/translations/resources.en.d.ts +6 -0
  63. package/build/translations/resources.en.js +1 -0
  64. package/build/translations/validator.en.d.ts +104 -0
  65. package/build/translations/validator.en.js +5 -0
  66. package/build/types/date.d.ts +44 -0
  67. package/build/types/date.js +1 -0
  68. package/build/types/dictionary.d.ts +29 -0
  69. package/build/types/dictionary.js +1 -0
  70. package/build/types/i18n.d.ts +121 -0
  71. package/build/types/i18n.js +1 -0
  72. package/build/types/index.d.ts +145 -0
  73. package/build/types/index.js +1 -0
  74. package/build/utils/areEquals.d.ts +19 -0
  75. package/build/utils/areEquals.js +1 -0
  76. package/build/utils/date/dateHelper.d.ts +371 -0
  77. package/build/utils/date/dateHelper.js +5 -0
  78. package/build/utils/date/index.d.ts +212 -0
  79. package/build/utils/date/index.js +5 -0
  80. package/build/utils/date/isDateObj.d.ts +14 -0
  81. package/build/utils/date/isDateObj.js +1 -0
  82. package/build/utils/debounce.d.ts +52 -0
  83. package/build/utils/debounce.js +1 -0
  84. package/build/utils/defaultArray.d.ts +18 -0
  85. package/build/utils/defaultArray.js +1 -0
  86. package/build/utils/defaultBool.d.ts +14 -0
  87. package/build/utils/defaultBool.js +1 -0
  88. package/build/utils/defaultStr.d.ts +17 -0
  89. package/build/utils/defaultStr.js +1 -0
  90. package/build/utils/defaultVal.d.ts +18 -0
  91. package/build/utils/defaultVal.js +1 -0
  92. package/build/utils/dom/index.d.ts +65 -0
  93. package/build/utils/dom/index.js +1 -0
  94. package/build/utils/dom/isDOMElement.d.ts +11 -0
  95. package/build/utils/dom/isDOMElement.js +1 -0
  96. package/build/utils/file/index.d.ts +26 -0
  97. package/build/utils/file/index.js +1 -0
  98. package/build/utils/global.d.ts +53 -0
  99. package/build/utils/global.js +1 -0
  100. package/build/utils/image.d.ts +56 -0
  101. package/build/utils/image.js +1 -0
  102. package/build/utils/index.d.ts +39 -0
  103. package/build/utils/index.js +6 -0
  104. package/build/utils/interpolate.d.ts +105 -0
  105. package/build/utils/interpolate.js +1 -0
  106. package/build/utils/isEmail.d.ts +57 -0
  107. package/build/utils/isEmail.js +1 -0
  108. package/build/utils/isEmpty.d.ts +18 -0
  109. package/build/utils/isEmpty.js +1 -0
  110. package/build/utils/isNonNullString.d.ts +17 -0
  111. package/build/utils/isNonNullString.js +1 -0
  112. package/build/utils/isNullable.d.ts +7 -0
  113. package/build/utils/isNullable.js +1 -0
  114. package/build/utils/isNumber.d.ts +36 -0
  115. package/build/utils/isNumber.js +1 -0
  116. package/build/utils/isPrimitive.d.ts +16 -0
  117. package/build/utils/isPrimitive.js +1 -0
  118. package/build/utils/isPromise.d.ts +14 -0
  119. package/build/utils/isPromise.js +1 -0
  120. package/build/utils/isRegex.d.ts +15 -0
  121. package/build/utils/isRegex.js +1 -0
  122. package/build/utils/isTime.d.ts +18 -0
  123. package/build/utils/isTime.js +1 -0
  124. package/build/utils/json.d.ts +224 -0
  125. package/build/utils/json.js +1 -0
  126. package/build/utils/numbers.d.ts +148 -0
  127. package/build/utils/numbers.js +5 -0
  128. package/build/utils/object.d.ts +567 -0
  129. package/build/utils/object.js +1 -0
  130. package/build/utils/sort.d.ts +67 -0
  131. package/build/utils/sort.js +1 -0
  132. package/build/utils/string.d.ts +165 -0
  133. package/build/utils/string.js +1 -0
  134. package/build/utils/stringify.d.ts +23 -0
  135. package/build/utils/stringify.js +1 -0
  136. package/build/utils/uniqid.d.ts +18 -0
  137. package/build/utils/uniqid.js +1 -0
  138. package/build/utils/uri/index.d.ts +333 -0
  139. package/build/utils/uri/index.js +2 -0
  140. package/build/validator/index.d.ts +4 -0
  141. package/build/validator/index.js +6 -0
  142. package/build/validator/rules/array.d.ts +848 -0
  143. package/build/validator/rules/array.js +5 -0
  144. package/build/validator/rules/boolean.d.ts +87 -0
  145. package/build/validator/rules/boolean.js +5 -0
  146. package/build/validator/rules/date.d.ts +551 -0
  147. package/build/validator/rules/date.js +5 -0
  148. package/build/validator/rules/default.d.ts +367 -0
  149. package/build/validator/rules/default.js +5 -0
  150. package/build/validator/rules/enum.d.ts +155 -0
  151. package/build/validator/rules/enum.js +5 -0
  152. package/build/validator/rules/file.d.ts +356 -0
  153. package/build/validator/rules/file.js +5 -0
  154. package/build/validator/rules/format.d.ts +2825 -0
  155. package/build/validator/rules/format.js +6 -0
  156. package/build/validator/rules/index.d.ts +16 -0
  157. package/build/validator/rules/index.js +6 -0
  158. package/build/validator/rules/multiRules.d.ts +475 -0
  159. package/build/validator/rules/multiRules.js +5 -0
  160. package/build/validator/rules/numeric.d.ts +1135 -0
  161. package/build/validator/rules/numeric.js +5 -0
  162. package/build/validator/rules/string.d.ts +504 -0
  163. package/build/validator/rules/string.js +5 -0
  164. package/build/validator/rules/target.d.ts +137 -0
  165. package/build/validator/rules/target.js +5 -0
  166. package/build/validator/rules/utils.d.ts +1 -0
  167. package/build/validator/rules/utils.js +1 -0
  168. package/build/validator/rulesMarkers.d.ts +11 -0
  169. package/build/validator/rulesMarkers.js +1 -0
  170. package/build/validator/types.d.ts +2906 -0
  171. package/build/validator/types.js +1 -0
  172. package/build/validator/validator.d.ts +3692 -0
  173. package/build/validator/validator.js +5 -0
  174. package/lib/cjs/auth.js +1 -0
  175. package/lib/cjs/countries.js +1 -0
  176. package/lib/cjs/currency.js +1 -0
  177. package/lib/cjs/i18n.js +1 -0
  178. package/lib/cjs/inputFormatter.js +1 -0
  179. package/lib/cjs/logger.js +1 -0
  180. package/lib/cjs/observable.js +1 -0
  181. package/lib/cjs/platform.js +1 -0
  182. package/lib/cjs/resources.js +1 -0
  183. package/lib/cjs/session.js +1 -0
  184. package/lib/cjs/types.js +1 -0
  185. package/lib/cjs/utils.js +1 -0
  186. package/lib/cjs/validator.js +1 -0
  187. package/lib/esm/auth.mjs +1 -0
  188. package/lib/esm/countries.mjs +1 -0
  189. package/lib/esm/currency.mjs +1 -0
  190. package/lib/esm/i18n.mjs +1 -0
  191. package/lib/esm/inputFormatter.mjs +1 -0
  192. package/lib/esm/logger.mjs +1 -0
  193. package/lib/esm/observable.mjs +1 -0
  194. package/lib/esm/platform.mjs +1 -0
  195. package/lib/esm/resources.mjs +1 -0
  196. package/lib/esm/session.mjs +1 -0
  197. package/lib/esm/types.mjs +1 -0
  198. package/lib/esm/utils.mjs +1 -0
  199. package/lib/esm/validator.mjs +1 -0
  200. package/package.json +244 -0
@@ -0,0 +1,2034 @@
1
+ import { Observable } from '../observable';
2
+ import { ResourceActionName, ResourceName } from '../resources/types';
3
+ import 'reflect-metadata';
4
+ import { Dictionary } from '../types/dictionary';
5
+ import './types';
6
+ import { AuthEvent, AuthPerm, AuthPerms, AuthSessionStorage, AuthUser } from './types';
7
+ export * from './types';
8
+ /***
9
+ * A class that provides methods for managing session data.
10
+ *
11
+ */
12
+ declare class Session {
13
+ /**
14
+ * Retrieves a specific value from the session data based on the provided session name and key.
15
+ *
16
+ * This function first checks if the provided key is a non-null string. If it is not, it returns undefined.
17
+ * It then retrieves the session data using `getData` and returns the value associated with the specified key.
18
+ *
19
+ * @param sessionName - An optional string that represents the name of the session.
20
+ * @param key - A string representing the key of the value to retrieve from the session data.
21
+ *
22
+ * @returns The value associated with the specified key in the session data, or undefined if the key is invalid.
23
+ *
24
+ * @example
25
+ * // Example of retrieving a specific value from session data
26
+ * const value = get('mySession', 'userPreference'); // Returns: 'darkMode'
27
+ *
28
+ * @example
29
+ * // Example of trying to retrieve a value with an invalid key
30
+ * const value = get('mySession', null); // Returns: undefined
31
+ */
32
+ static get(sessionName?: string, key?: string): any;
33
+ /**
34
+ * Sets a value or an object in the session data for a specific session name.
35
+ *
36
+ * This function retrieves the current session data using `getData`. If a valid key is provided, it sets the
37
+ * corresponding value in the session data. If an object is provided as the key, it replaces the entire session data.
38
+ * Finally, it saves the updated session data back to the session storage.
39
+ *
40
+ * @param sessionName - An optional string that represents the name of the session.
41
+ * @param key - A string representing the key to set a value for, or an object containing multiple key-value pairs.
42
+ * @param value - The value to set for the specified key. This parameter is ignored if an object is provided as the key.
43
+ *
44
+ * @returns The updated session data as an object.
45
+ *
46
+ * @example
47
+ * // Example of setting a single value in session data
48
+ * const updatedData = set('mySession', 'userPreference', 'darkMode'); // Returns: { userPreference: 'darkMode' }
49
+ *
50
+ * @example
51
+ * // Example of replacing the entire session data with an object
52
+ * const updatedData = set('mySession', { userPreference: 'lightMode', language: ' English' }); // Returns: { userPreference: 'lightMode', language: 'English' }
53
+ */
54
+ static set(sessionName?: string, key?: string | Dictionary, value?: any): Dictionary;
55
+ /**
56
+ * Generates a unique session key based on the authenticated user's ID and an optional session name.
57
+ *
58
+ * The session key is constructed in the format: `auth-{userId}-{sessionName}`. If the user is not signed in,
59
+ * the user ID will be an empty string. This key is used to store and retrieve session data.
60
+ *
61
+ * @param sessionName - An optional string that represents the name of the session. If not provided,
62
+ * an empty string will be used in the key.
63
+ *
64
+ * @returns A string representing the unique session key.
65
+ *
66
+ * @example
67
+ * // Example of generating a session key for a user with ID '12345'
68
+ * const sessionKey = getKey('mySession'); // Returns: 'auth-12345-mySession'
69
+ *
70
+ * @example
71
+ * // Example of generating a session key when no user is signed in
72
+ * const sessionKey = getKey(); // Returns: 'auth--'
73
+ */
74
+ static getKey(sessionName?: string): string;
75
+ /**
76
+ * Retrieves session data associated with a specific session name.
77
+ *
78
+ * This function checks if the provided session name is a non-null string. If it is not, an empty object is returned.
79
+ * Otherwise, it constructs a key using `getKey` and retrieves the corresponding data from the session storage.
80
+ *
81
+ * @param sessionName - An optional string that represents the name of the session. If not provided or invalid,
82
+ * an empty object will be returned.
83
+ *
84
+ * @returns An object containing the session data associated with the specified session name.
85
+ * If the session name is invalid, an empty object is returned.
86
+ *
87
+ * @example
88
+ * // Example of retrieving session data for a specific session name
89
+ * const sessionData = getData('mySession'); // Returns: { }
90
+ *
91
+ * @example
92
+ * // Example of retrieving session data with an invalid session name
93
+ * const sessionData = getData(null); // Returns: {}
94
+ */
95
+ 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
+ /**
134
+ * Retrieves a session storage object that provides methods for managing session data.
135
+ *
136
+ * This function creates an object that allows you to interact with session storage
137
+ * using a specified session name. It provides methods to get, set, and retrieve data
138
+ * associated with the session, as well as to retrieve the session key.
139
+ *
140
+ * @param sessionName - An optional string that represents the name of the session.
141
+ * If provided, it will be used as a prefix for the keys stored
142
+ * in session storage. If not provided, the session will be
143
+ * treated as anonymous.
144
+ *
145
+ * @returns An object implementing the `AuthSessionStorage` interface, which includes
146
+ * methods for session management:
147
+ * - `get(key?: string): any`: Retrieves the value associated with the specified key.
148
+ * - `set(key?: string | Dictionary, value?: any): void`: Stores a value under the specified key.
149
+ * - `getData(): Dictionary`: Returns all data stored in the session as a dictionary.
150
+ * - `getKey(): string`: Returns the session key used for storage.
151
+ *
152
+ * @example
153
+ * // Create a session storage object with a specific session name
154
+ * const session = getSessionStorage('userSession');
155
+ *
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
+ * // Get the session key
166
+ * const sessionKey = session.getKey(); // 'userSession'
167
+ *
168
+ * @remarks
169
+ * This function is particularly useful for managing user authentication sessions
170
+ * in web applications. By using session storage, data persists across page reloads
171
+ * but is cleared when the tab or browser is closed.
172
+ *
173
+ * Ensure that the keys used for storing data are unique to avoid collisions with
174
+ * other session data. Consider using a structured naming convention for keys.
175
+ */
176
+ static getStorage(sessionName?: string): AuthSessionStorage;
177
+ }
178
+ export declare class Auth {
179
+ /**
180
+ * Authentication event handler.
181
+ * Initializes an observable event handler for authentication Auth.events.
182
+ *
183
+ * This constant `events` is assigned an instance of `Observable<AuthEvent>`, which is used to manage
184
+ * authentication-related events in the application. The initialization checks if the global
185
+ * `Global.eventsResourcesObservableHandler` exists and is an object. If it does, it assigns it to
186
+ * `events`; otherwise, it defaults to an empty object cast as `Observable<AuthEvent>`.
187
+ *
188
+ * This pattern allows for flexible handling of events, ensuring that the application can respond
189
+ * to authentication actions such as sign-in, sign-out, and sign-up.
190
+ *
191
+ * @type {Observable<AuthEvent>}
192
+ *
193
+ * @example
194
+ * import {Auth} from 'reslib/auth';
195
+ * Auth.events.on('SIGN_IN', (user) => {
196
+ * console.log(`User signed in: ${user.username}`);
197
+ * });
198
+ *
199
+ * function userSignIn(user) {
200
+ * Auth.events.trigger('SIGN_IN', user);
201
+ * }
202
+ */
203
+ static events: Observable<AuthEvent>;
204
+ private static localUserRef;
205
+ /**
206
+ * Checks if the user is a master admin.
207
+ *
208
+ * The `isMasterAdmin` function determines whether the provided user
209
+ * has master admin privileges. If no user is provided, it will
210
+ * attempt to retrieve the signed user from the session.
211
+ *
212
+ * ### Parameters
213
+ *
214
+ * - `user` (AuthUser , optional): The user object to check. If not
215
+ * provided, the function will attempt to retrieve the signed user
216
+ * from the session.
217
+ *
218
+ * ### Returns
219
+ *
220
+ * - `boolean`: Returns `true` if the user is a master admin, or `false` otherwise.
221
+ *
222
+ * ### Example Usage
223
+ *
224
+ * ```typescript
225
+ * const user: AuthUser = { id: "admin123" };
226
+ * Auth.isMasterAdmin = (user)=>{
227
+ * return checkSomeCondition(user);
228
+ * }; // false (assuming the user is not a master admin)
229
+ * ```
230
+ * @see {@link AuthUser} for the `AuthUser` type.
231
+ */
232
+ static isMasterAdmin?: (user?: AuthUser) => boolean;
233
+ private static _isMasterAdmin;
234
+ /**
235
+ * Retrieves the currently authenticated user from secure session storage.
236
+ *
237
+ * This method implements a secure user session retrieval system that handles encrypted
238
+ * user data storage. It first checks for a cached user reference in memory for performance
239
+ * optimization, then attempts to decrypt and parse the user data from session storage
240
+ * if no cached version exists. The method includes comprehensive error handling for
241
+ * decryption failures and data corruption scenarios.
242
+ *
243
+ * ### Security Features:
244
+ * - **Encrypted Storage**: User data is encrypted using AES encryption before storage
245
+ * - **Memory Caching**: Cached in `localUserRef` for improved performance and reduced decryption overhead
246
+ * - **Safe Parsing**: Uses `JsonHelper.parse` for secure JSON deserialization
247
+ * - **Error Recovery**: Gracefully handles corrupted or invalid session data
248
+ *
249
+ * ### Performance Optimization:
250
+ * The method implements a two-tier retrieval strategy:
251
+ * 1. **Memory Cache**: Returns immediately if user is already loaded in memory
252
+ * 2. **Session Storage**: Decrypts and parses data from persistent storage only when needed
253
+ *
254
+ * @returns The authenticated user object containing user information, permissions, and roles,
255
+ * or `null` if no user is currently signed in, session data is corrupted, or
256
+ * decryption fails. The returned object conforms to the `AuthUser` interface.
257
+ *
258
+ * @example
259
+ * ```typescript
260
+ * // Basic usage - check if user is signed in
261
+ * const currentUser = Auth.getSignedUser();
262
+ * if (currentUser) {
263
+ * console.log(`Welcome back, ${currentUser.username}!`);
264
+ * console.log(`User ID: ${currentUser.id}`);
265
+ * } else {
266
+ * console.log("No user is currently signed in");
267
+ * }
268
+ * ```
269
+ *
270
+ * @example
271
+ * ```typescript
272
+ * // Using with permission checking
273
+ * const user = Auth.getSignedUser();
274
+ * if (user) {
275
+ * const canEditDocuments = Auth.checkUserPermission(user, "documents", "update");
276
+ * if (canEditDocuments) {
277
+ * showEditButton();
278
+ * }
279
+ * }
280
+ * ```
281
+ *
282
+ * @example
283
+ * ```typescript
284
+ * // Handling authentication state in React component
285
+ * function UserProfile() {
286
+ * const [user, setUser] = useState<AuthUser | null>(null);
287
+ *
288
+ * useEffect(() => {
289
+ * const currentUser = Auth.getSignedUser();
290
+ * setUser(currentUser);
291
+ *
292
+ * if (!currentUser) {
293
+ * // Redirect to login page
294
+ * router.push('/login');
295
+ * }
296
+ * }, []);
297
+ *
298
+ * return user ? <div>Hello, {user.username}</div> : <div>Loading...</div>;
299
+ * }
300
+ * ```
301
+ *
302
+ * @example
303
+ * ```typescript
304
+ * // Using with authentication guards
305
+ * class AuthGuard {
306
+ * static requireAuth(): boolean {
307
+ * const user = Auth.getSignedUser();
308
+ * if (!user) {
309
+ * throw new Error("Authentication required");
310
+ * }
311
+ * return true;
312
+ * }
313
+ *
314
+ * static requireRole(roleName: string): boolean {
315
+ * const user = Auth.getSignedUser();
316
+ * return user?.roles?.some(role => role.name === roleName) ?? false;
317
+ * }
318
+ * }
319
+ * ```
320
+ *
321
+ * @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
+ *
339
+ * @throws {CryptoError} May throw during decryption if session data is corrupted
340
+ * @throws {SyntaxError} May throw during JSON parsing if decrypted data is malformed
341
+ *
342
+ * @see {@link AuthUser} - Complete user object interface definition
343
+ * @see {@link setSignedUser} - Method to store user in session
344
+ * @see {@link signIn} - High-level user authentication method
345
+ * @see {@link signOut} - Method to clear user session
346
+ * @see {@link Session.getToken} - Utility to get user's authentication token
347
+ * @see {@link checkUserPermission} - Check specific user permissions
348
+ *
349
+ *
350
+ * @public
351
+ *
352
+ * @remarks
353
+ * **Security Considerations:**
354
+ * - Session data is automatically encrypted using AES encryption
355
+ * - The encryption key `SESSION_ENCRYPT_KEY` should be kept secure
356
+ * - User data includes sensitive information like tokens and permissions
357
+ * - Always validate user data before using in security-critical operations
358
+ *
359
+ * **Performance Notes:**
360
+ * - First call after page load requires decryption (slower)
361
+ * - Subsequent calls return cached data (faster)
362
+ * - Cache is automatically cleared when user signs out
363
+ * - Consider the performance impact in render loops
364
+ *
365
+ * **Error Handling:**
366
+ * - Returns `null` instead of throwing errors for better UX
367
+ * - Logs errors to console for debugging purposes
368
+ * - Gracefully handles session storage corruption
369
+ * - Automatically recovers from temporary decryption failures
370
+ */
371
+ static getSignedUser(): AuthUser | null;
372
+ /**
373
+ * Securely stores an authenticated user in encrypted session storage with event broadcasting.
374
+ *
375
+ * This method is the core user session management function that handles secure storage of user
376
+ * authentication data. It encrypts user information using AES encryption before persisting to
377
+ * session storage, maintains local memory cache for performance, and optionally broadcasts
378
+ * authentication events to notify other parts of the application about user state changes.
379
+ *
380
+ * ### Security Architecture:
381
+ * - **AES Encryption**: User data is encrypted before storage to protect sensitive information
382
+ * - **Session Timestamping**: Automatically adds `authSessionCreatedAt` timestamp for session tracking
383
+ * - **Error Isolation**: Encryption failures don't crash the application, user reference is safely cleared
384
+ * - **Memory Management**: Updates local cache reference for immediate access
385
+ *
386
+ * ### Event System Integration:
387
+ * The method integrates with the authentication event system to broadcast state changes:
388
+ * - **SIGN_IN Event**: Triggered when a valid user is stored with successful encryption
389
+ * - **SIGN_OUT Event**: Triggered when user is cleared (null) or encryption fails
390
+ * - **Event Payload**: Includes the user object for event handlers to process
391
+ *
392
+ * @param u - The user object to store in session, or `null` to clear the current session.
393
+ * When providing a user object, it should contain all necessary authentication
394
+ * information including permissions, roles, and tokens. The object will be
395
+ * automatically timestamped with `authSessionCreatedAt`.
396
+ *
397
+ * @param triggerEvent - Optional flag controlling whether to broadcast authentication events.
398
+ * When `true` (default), triggers either 'SIGN_IN' or 'SIGN_OUT' events
399
+ * based on the operation result. Set to `false` to perform silent
400
+ * session updates without notifying event listeners.
401
+ *
402
+ * @returns A promise that resolves to the result of the session storage operation.
403
+ * The promise completes after the encrypted data has been written to storage.
404
+ * Returns the storage operation result, typically indicating success or failure.
405
+ *
406
+ * @example
407
+ * ```typescript
408
+ * // Standard user sign-in with event broadcasting
409
+ * const user: AuthUser = {
410
+ * id: "user123",
411
+ * username: "john_doe",
412
+ * email: "john@example.com",
413
+ * token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
414
+ * perms: { documents: ["read", "write"] },
415
+ * roles: [{ name: "editor", perms: { images: ["upload"] } }]
416
+ * };
417
+ *
418
+ * await Auth.setSignedUser(user, true);
419
+ * console.log("User signed in with events triggered");
420
+ * ```
421
+ *
422
+ * @example
423
+ * ```typescript
424
+ * // Silent session update without triggering events
425
+ * const updatedUser = { ...currentUser, lastActivity: new Date() };
426
+ * await Auth.setSignedUser(updatedUser, false);
427
+ * console.log("User session updated silently");
428
+ * ```
429
+ *
430
+ * @example
431
+ * ```typescript
432
+ * // Clear user session (sign out)
433
+ * await Auth.setSignedUser(null, true);
434
+ * console.log("User signed out, SIGN_OUT event triggered");
435
+ * ```
436
+ *
437
+ * @example
438
+ * ```typescript
439
+ * // Using with event listeners
440
+ * Auth.events.on('SIGN_IN', (user) => {
441
+ * console.log(`Welcome ${user.username}!`);
442
+ * initializeUserDashboard(user);
443
+ * trackUserLogin(user.id);
444
+ * });
445
+ *
446
+ * Auth.events.on('SIGN_OUT', () => {
447
+ * console.log('User signed out');
448
+ * clearUserDashboard();
449
+ * redirectToLogin();
450
+ * });
451
+ *
452
+ * // Now when we set a user, events will fire automatically
453
+ * await Auth.setSignedUser(authenticatedUser);
454
+ * ```
455
+ *
456
+ * @example
457
+ * ```typescript
458
+ * // Error handling with session management
459
+ * try {
460
+ * await Auth.setSignedUser(userFromAPI);
461
+ * showSuccessMessage("Login successful");
462
+ * } catch (error) {
463
+ * console.error("Failed to store user session:", error);
464
+ * showErrorMessage("Login failed, please try again");
465
+ * }
466
+ * ```
467
+ *
468
+ * @example
469
+ * ```typescript
470
+ * // Updating user permissions after role change
471
+ * const currentUser = Auth.getSignedUser();
472
+ * if (currentUser) {
473
+ * const updatedUser = {
474
+ * ...currentUser,
475
+ * roles: [...currentUser.roles, newRole],
476
+ * perms: { ...currentUser.perms, ...newPermissions }
477
+ * };
478
+ *
479
+ * await Auth.setSignedUser(updatedUser, false); // Silent update
480
+ * console.log("User permissions updated");
481
+ * }
482
+ * ```
483
+ *
484
+ * @throws {CryptoError} May throw if encryption fails due to invalid encryption key
485
+ * @throws {StorageError} May throw if session storage is unavailable or quota exceeded
486
+ *
487
+ * @see {@link AuthUser} - Complete user object interface with all required fields
488
+ * @see {@link getSignedUser} - Retrieve the currently stored user from session
489
+ * @see {@link signIn} - High-level user authentication wrapper
490
+ * @see {@link signOut} - High-level user sign-out wrapper
491
+ * @see {@link Auth.events} - Authentication event system for state change notifications
492
+ * @see {@link AuthEvent} - Available authentication event types and payloads
493
+ *
494
+ *
495
+ * @public
496
+ * @async
497
+ *
498
+ * @remarks
499
+ * **Security Best Practices:**
500
+ * - User objects should be validated before storage
501
+ * - Sensitive data like tokens are automatically encrypted
502
+ * - Session timestamps help with security auditing
503
+ * - Always handle encryption errors gracefully
504
+ *
505
+ * **Performance Considerations:**
506
+ * - Encryption/decryption adds computational overhead
507
+ * - Local cache is updated synchronously for immediate access
508
+ * - Event broadcasting may trigger multiple listeners
509
+ * - Consider batching multiple user updates to reduce I/O
510
+ *
511
+ * **Event System:**
512
+ * - Events are asynchronous and don't block the storage operation
513
+ * - Multiple listeners can subscribe to the same event
514
+ * - Event payload includes the full user object for flexibility
515
+ * - Use `triggerEvent: false` for internal operations to avoid recursion
516
+ */
517
+ static setSignedUser(u: AuthUser | null, triggerEvent?: boolean): Promise<AuthUser | null>;
518
+ /**
519
+ * Authenticates a user and establishes a secure session with comprehensive validation.
520
+ *
521
+ * This high-level authentication method provides a complete user sign-in workflow with
522
+ * input validation, secure session establishment, and event broadcasting. It serves as
523
+ * the primary entry point for user authentication in applications, handling all the
524
+ * complexity of secure session management while providing a simple, promise-based API.
525
+ *
526
+ * ### Authentication Workflow:
527
+ * 1. **Input Validation**: Validates that the provided user object is properly structured
528
+ * 2. **Session Creation**: Calls `setSignedUser` to securely store user data
529
+ * 3. **Event Broadcasting**: Optionally triggers authentication events for app-wide notifications
530
+ * 4. **Return Confirmation**: Returns the authenticated user object on successful completion
531
+ *
532
+ * ### Security Features:
533
+ * - **Object Validation**: Ensures user object is valid before processing
534
+ * - **Encrypted Storage**: Leverages `setSignedUser` for secure data persistence
535
+ * - **Error Handling**: Provides meaningful error messages for failed authentication
536
+ * - **Session Timestamping**: Automatically tracks when authentication session was created
537
+ *
538
+ * @param user - The authenticated user object containing all necessary user information.
539
+ * Must be a valid object conforming to the `AuthUser` interface, including
540
+ * properties like id, username, email, permissions, roles, and authentication token.
541
+ * The object should come from a successful authentication process (login API, OAuth, etc.).
542
+ *
543
+ * @param triggerEvent - Optional flag controlling whether to broadcast authentication events.
544
+ * When `true` (default), triggers a 'SIGN_IN' event that other parts of
545
+ * the application can listen to for initialization, analytics, or UI updates.
546
+ * Set to `false` for silent authentication without event notifications.
547
+ *
548
+ * @returns A promise that resolves to the authenticated user object when sign-in is successful.
549
+ * The returned user object is the same as the input but may include additional
550
+ * properties added during the authentication process (like session timestamps).
551
+ *
552
+ * @throws {Error} Throws an error with internationalized message if the user object is invalid,
553
+ * null, undefined, or not a proper object structure. The error message is
554
+ * retrieved from the i18n system using key "auth.invalidSignInUser".
555
+ *
556
+ * @example
557
+ * ```typescript
558
+ * // Basic user sign-in after successful API authentication
559
+ * try {
560
+ * const response = await fetch('/api/auth/login', {
561
+ * method: 'POST',
562
+ * body: JSON.stringify({ username, password }),
563
+ * headers: { 'Content-Type': 'application/json' }
564
+ * });
565
+ *
566
+ * const userData = await response.json();
567
+ * const authenticatedUser = await Auth.signIn(userData);
568
+ *
569
+ * console.log(`Welcome ${authenticatedUser.username}!`);
570
+ * router.push('/dashboard');
571
+ * } catch (error) {
572
+ * console.error('Sign-in failed:', error.message);
573
+ * showErrorMessage('Invalid credentials');
574
+ * }
575
+ * ```
576
+ *
577
+ * @example
578
+ * ```typescript
579
+ * // OAuth authentication workflow
580
+ * async function handleOAuthCallback(authCode: string) {
581
+ * try {
582
+ * // Exchange auth code for user data
583
+ * const tokenResponse = await exchangeCodeForToken(authCode);
584
+ * const userProfile = await fetchUserProfile(tokenResponse.access_token);
585
+ *
586
+ * const user: AuthUser = {
587
+ * id: userProfile.id,
588
+ * username: userProfile.login,
589
+ * email: userProfile.email,
590
+ * token: tokenResponse.access_token,
591
+ * perms: await fetchUserPermissions(userProfile.id),
592
+ * roles: await fetchUserRoles(userProfile.id),
593
+ * provider: 'oauth'
594
+ * };
595
+ *
596
+ * await Auth.signIn(user);
597
+ * console.log('OAuth sign-in successful');
598
+ * } catch (error) {
599
+ * console.error('OAuth sign-in failed:', error);
600
+ * }
601
+ * }
602
+ * ```
603
+ *
604
+ * @example
605
+ * ```typescript
606
+ * // Silent authentication without triggering events
607
+ * async function silentAuth(sessionToken: string) {
608
+ * try {
609
+ * const userData = await validateSessionToken(sessionToken);
610
+ * const user = await Auth.signIn(userData, false); // No events
611
+ *
612
+ * console.log('Silent authentication successful');
613
+ * return user;
614
+ * } catch (error) {
615
+ * console.log('Silent auth failed, user needs to login');
616
+ * return null;
617
+ * }
618
+ * }
619
+ * ```
620
+ *
621
+ * @example
622
+ * ```typescript
623
+ * // Complete authentication flow with event handling
624
+ * // Set up event listeners first
625
+ * Auth.events.on('SIGN_IN', (user) => {
626
+ * // Initialize user-specific features
627
+ * initializeUserPreferences(user.id);
628
+ * loadUserDashboard(user.perms);
629
+ * trackAnalyticsEvent('user_signin', { userId: user.id });
630
+ *
631
+ * // Update UI state
632
+ * updateNavigationForUser(user.roles);
633
+ * showWelcomeMessage(user.username);
634
+ * });
635
+ *
636
+ * // Perform authentication
637
+ * async function loginUser(credentials: LoginCredentials) {
638
+ * try {
639
+ * const authResult = await authenticateWithAPI(credentials);
640
+ * const user = await Auth.signIn(authResult.user); // Events will fire
641
+ *
642
+ * return { success: true, user };
643
+ * } catch (error) {
644
+ * return { success: false, error: error.message };
645
+ * }
646
+ * }
647
+ * ```
648
+ *
649
+ * @example
650
+ * ```typescript
651
+ * // Multi-step authentication with role-based redirection
652
+ * async function signInWithRoleRedirect(userData: any) {
653
+ * try {
654
+ * const user = await Auth.signIn(userData);
655
+ *
656
+ * // Redirect based on user role
657
+ * if (user.roles?.some(role => role.name === 'admin')) {
658
+ * router.push('/admin/dashboard');
659
+ * } else if (user.roles?.some(role => role.name === 'moderator')) {
660
+ * router.push('/moderator/panel');
661
+ * } else {
662
+ * router.push('/user/dashboard');
663
+ * }
664
+ *
665
+ * return user;
666
+ * } catch (error) {
667
+ * console.error('Role-based sign-in failed:', error);
668
+ * throw error;
669
+ * }
670
+ * }
671
+ * ```
672
+ *
673
+ * @see {@link AuthUser} - Complete user object interface specification
674
+ * @see {@link setSignedUser} - Lower-level method for secure user storage
675
+ * @see {@link getSignedUser} - Retrieve currently authenticated user
676
+ * @see {@link signOut} - Sign out and clear user session
677
+ * @see {@link Auth.events} - Authentication event system for state notifications
678
+ * @see {@link isAllowed} - Check user permissions for access control
679
+ *
680
+ *
681
+ * @public
682
+ * @async
683
+ *
684
+ * @remarks
685
+ * **Best Practices:**
686
+ * - Always validate user data before calling this method
687
+ * - Use try-catch blocks to handle authentication failures gracefully
688
+ * - Consider implementing token refresh logic for long-lived sessions
689
+ * - Use event listeners to initialize user-specific application features
690
+ *
691
+ * **Error Handling:**
692
+ * - The method throws immediately on invalid input for fast failure
693
+ * - Use internationalized error messages for better user experience
694
+ * - Consider logging authentication attempts for security monitoring
695
+ * - Implement retry logic for transient authentication failures
696
+ *
697
+ * **Integration Notes:**
698
+ * - Works seamlessly with any authentication provider (JWT, OAuth, custom)
699
+ * - Integrates with the permission system for access control
700
+ * - Compatible with SSR/SPA applications through secure session storage
701
+ * - Supports both traditional and modern authentication workflows
702
+ */
703
+ static signIn(user: AuthUser, triggerEvent?: boolean): Promise<AuthUser>;
704
+ /**
705
+ * Signs out the currently authenticated user and securely clears their session.
706
+ *
707
+ * This method provides a high-level, convenient interface for user sign-out operations.
708
+ * It handles the complete user session termination workflow by clearing the encrypted
709
+ * user data from session storage, removing the cached user reference from memory, and
710
+ * optionally broadcasting sign-out events to notify other parts of the application
711
+ * about the authentication state change.
712
+ *
713
+ * ### Sign-Out Workflow:
714
+ * 1. **Session Clearing**: Calls `setSignedUser(null)` to remove user data from encrypted storage
715
+ * 2. **Memory Cleanup**: Clears the local user reference cache for immediate effect
716
+ * 3. **Event Broadcasting**: Optionally triggers 'SIGN_OUT' events for application-wide notifications
717
+ * 4. **Security Cleanup**: Ensures no sensitive user data remains in browser storage
718
+ *
719
+ * ### Security Features:
720
+ * - **Complete Data Removal**: Eliminates all traces of user session from storage
721
+ * - **Memory Safety**: Clears in-memory user references to prevent data leakage
722
+ * - **Event Coordination**: Allows other components to perform cleanup operations
723
+ * - **Immediate Effect**: Session termination is effective immediately after method completion
724
+ *
725
+ * ### Application Integration:
726
+ * The method integrates seamlessly with the authentication event system, allowing
727
+ * other parts of the application to react to sign-out events by clearing user-specific
728
+ * data, redirecting to login pages, or performing cleanup operations.
729
+ *
730
+ * @param triggerEvent - Optional flag controlling whether to broadcast authentication events.
731
+ * When `true` (default), triggers a 'SIGN_OUT' event that other parts
732
+ * of the application can listen to for cleanup operations, analytics,
733
+ * or UI state updates. Set to `false` to perform silent sign-out
734
+ * without notifying event listeners (useful for internal operations).
735
+ *
736
+ * @returns A promise that resolves when the sign-out operation is complete and all
737
+ * user session data has been successfully removed from storage. The promise
738
+ * resolves to `void` as no return value is needed after successful sign-out.
739
+ *
740
+ * @example
741
+ * ```typescript
742
+ * // Standard user sign-out with event broadcasting
743
+ * async function handleUserSignOut() {
744
+ * try {
745
+ * await Auth.signOut();
746
+ * console.log('User signed out successfully');
747
+ *
748
+ * // Redirect to login page
749
+ * window.location.href = '/login';
750
+ * } catch (error) {
751
+ * console.error('Sign-out failed:', error);
752
+ * showErrorMessage('Failed to sign out');
753
+ * }
754
+ * }
755
+ * ```
756
+ *
757
+ * @example
758
+ * ```typescript
759
+ * // Silent sign-out without triggering events
760
+ * async function silentSignOut() {
761
+ * await Auth.signOut(false); // No events triggered
762
+ * console.log('Silent sign-out completed');
763
+ *
764
+ * // Manually handle post-signout operations
765
+ * clearUserSpecificData();
766
+ * redirectToPublicArea();
767
+ * }
768
+ * ```
769
+ *
770
+ * @example
771
+ * ```typescript
772
+ * // Sign-out with comprehensive event handling
773
+ * // Set up event listener first
774
+ * Auth.events.on('SIGN_OUT', () => {
775
+ * console.log('User signed out - cleaning up...');
776
+ *
777
+ * // Clear user-specific application state
778
+ * clearUserPreferences();
779
+ * clearUserCache();
780
+ * resetApplicationState();
781
+ *
782
+ * // Update UI
783
+ * hideUserMenus();
784
+ * showGuestContent();
785
+ *
786
+ * // Analytics and logging
787
+ * trackAnalyticsEvent('user_signout');
788
+ * logSecurityEvent('session_terminated');
789
+ * });
790
+ *
791
+ * // Perform sign-out - events will fire automatically
792
+ * await Auth.signOut();
793
+ * ```
794
+ *
795
+ * @example
796
+ * ```typescript
797
+ * // Session timeout handling
798
+ * class SessionManager {
799
+ * private timeoutId: NodeJS.Timeout | null = null;
800
+ *
801
+ * startSessionTimer(durationMs: number) {
802
+ * this.clearSessionTimer();
803
+ *
804
+ * this.timeoutId = setTimeout(async () => {
805
+ * console.log('Session expired - signing out user');
806
+ * await Auth.signOut(); // Will trigger events
807
+ *
808
+ * showNotification('Session expired. Please sign in again.');
809
+ * }, durationMs);
810
+ * }
811
+ *
812
+ * clearSessionTimer() {
813
+ * if (this.timeoutId) {
814
+ * clearTimeout(this.timeoutId);
815
+ * this.timeoutId = null;
816
+ * }
817
+ * }
818
+ * }
819
+ * ```
820
+ *
821
+ * @example
822
+ * ```typescript
823
+ * // Multi-tab sign-out coordination
824
+ * // Listen for storage events to handle sign-out in other tabs
825
+ * window.addEventListener('storage', (event) => {
826
+ * if (event.key === USER_SESSION_KEY && event.newValue === null) {
827
+ * console.log('User signed out in another tab');
828
+ *
829
+ * // Perform silent sign-out in this tab without triggering events
830
+ * Auth.signOut(false);
831
+ *
832
+ * // Update UI to reflect signed-out state
833
+ * updateUIForSignedOutUser();
834
+ * }
835
+ * });
836
+ * ```
837
+ *
838
+ * @example
839
+ * ```typescript
840
+ * // Complete authentication flow with error handling
841
+ * class AuthenticationService {
842
+ * async performSignOut(): Promise<boolean> {
843
+ * try {
844
+ * // Check if user is actually signed in
845
+ * const currentUser = Auth.getSignedUser();
846
+ * if (!currentUser) {
847
+ * console.log('No user to sign out');
848
+ * return true;
849
+ * }
850
+ *
851
+ * // Perform API sign-out call if needed
852
+ * await this.notifyServerSignOut(currentUser.token);
853
+ *
854
+ * // Sign out locally
855
+ * await Auth.signOut();
856
+ *
857
+ * console.log('Complete sign-out successful');
858
+ * return true;
859
+ * } catch (error) {
860
+ * console.error('Sign-out process failed:', error);
861
+ *
862
+ * // Force local sign-out even if server call failed
863
+ * await Auth.signOut(false);
864
+ * return false;
865
+ * }
866
+ * }
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
+ * }
878
+ * ```
879
+ *
880
+ * @throws {StorageError} May throw if session storage is unavailable during cleanup
881
+ * @throws {CryptoError} May throw if there are issues clearing encrypted session data
882
+ *
883
+ * @see {@link setSignedUser} - Lower-level method used internally for session management
884
+ * @see {@link getSignedUser} - Check if a user is currently signed in before sign-out
885
+ * @see {@link signIn} - Corresponding method for user authentication
886
+ * @see {@link Auth.events} - Event system for handling sign-out notifications
887
+ * @see {@link AuthEvent} - Authentication event types including 'SIGN_OUT'
888
+ * @see {@link USER_SESSION_KEY} - Storage key used for session data
889
+ *
890
+ *
891
+ * @public
892
+ * @async
893
+ *
894
+ * @remarks
895
+ * **Security Considerations:**
896
+ * - Always sign out users when suspicious activity is detected
897
+ * - Consider notifying the server about client-side sign-outs for security auditing
898
+ * - Be aware that local sign-out doesn't invalidate server-side sessions automatically
899
+ * - Use HTTPS to prevent session hijacking during the sign-out process
900
+ *
901
+ * **Best Practices:**
902
+ * - Always handle sign-out errors gracefully to avoid leaving users in inconsistent states
903
+ * - Use event listeners to coordinate sign-out across multiple application components
904
+ * - Consider implementing automatic sign-out for security-sensitive applications
905
+ * - Provide clear feedback to users about successful sign-out operations
906
+ *
907
+ * **Performance Notes:**
908
+ * - Sign-out is typically fast as it only involves storage cleanup
909
+ * - Event broadcasting may trigger multiple listeners, consider the performance impact
910
+ * - Silent sign-out (`triggerEvent: false`) is faster as it skips event processing
911
+ * - Consider batching multiple sign-out operations if needed programmatically
912
+ *
913
+ * **Multi-Tab Considerations:**
914
+ * - Sign-out in one tab affects session storage visible to all tabs
915
+ * - Other tabs should listen for storage events to stay synchronized
916
+ * - Consider implementing cross-tab communication for better user experience
917
+ * - Be careful with silent sign-outs in multi-tab scenarios to avoid confusion
918
+ */
919
+ static signOut(triggerEvent?: boolean): Promise<AuthUser | null>;
920
+ private static isResourceActionTupleArray;
921
+ private static isResourceActionTupleObject;
922
+ /**
923
+ * Determines whether a user has permission to access a resource or perform an action.
924
+ *
925
+ * This comprehensive authorization method evaluates various types of permission configurations
926
+ * to determine if the specified user (or currently signed-in user) is allowed to perform
927
+ * the requested operation. It supports multiple permission formats including boolean flags,
928
+ * function-based permissions, resource-action tuples, and complex permission arrays.
929
+ *
930
+ * The method follows a priority-based evaluation system:
931
+ * 1. Boolean permissions are returned directly
932
+ * 2. Master admin users are always granted access
933
+ * 3. Null/undefined permissions default to `true` (open access)
934
+ * 4. Function permissions are evaluated with the user context
935
+ * 5. Resource-action permissions are checked against user's role permissions
936
+ * 6. Array permissions are evaluated with OR logic (any match grants access)
937
+ *
938
+ * @template TResourceName - The resource name type, extending ResourceName
939
+ *
940
+ * @param perm - The permission configuration to evaluate. Can be:
941
+ * - `boolean`: Direct permission flag (true = allowed, false = denied)
942
+ * - `function`: Custom permission evaluator receiving user context
943
+ * - `ResourceActionTupleObject`: Object with resourceName and action properties
944
+ * - `ResourceActionTupleArray`: Array tuple [resourceName, action]
945
+ * - `Array<AuthPerm>`: Multiple permission configurations (OR logic)
946
+ * - `null|undefined`: Defaults to allowing access
947
+ *
948
+ * @param user - Optional user object to check permissions against.
949
+ * If not provided, uses the currently signed-in user from session.
950
+ * The user object should contain permissions and role information.
951
+ *
952
+ * @returns `true` if the user is authorized to perform the action, `false` otherwise
953
+ *
954
+ * @example
955
+ * ```typescript
956
+ * // Boolean permission - direct access control
957
+ * const canAccess = Auth.isAllowed(true); // Returns: true
958
+ * const cannotAccess = Auth.isAllowed(false); // Returns: false
959
+ *
960
+ * // Function-based permission - custom logic
961
+ * const customPerm = (user: AuthUser) => user.age >= 18;
962
+ * const canAccessAdultContent = Auth.isAllowed(customPerm); // Returns: true if user is 18+
963
+ * ```
964
+ *
965
+ * @example
966
+ * ```typescript
967
+ * // Resource-action tuple object - structured permissions
968
+ * const documentEditPerm = { resourceName: "documents", action: "update" };
969
+ * const canEditDocs = Auth.isAllowed(documentEditPerm);
970
+ * // Returns: true if user has "update" permission on "documents" resource
971
+ *
972
+ * // Resource-action tuple array - compact format
973
+ * const userDeletePerm: [string, string] = ["users", "delete"];
974
+ * const canDeleteUsers = Auth.isAllowed(userDeletePerm);
975
+ * // Returns: true if user has "delete" permission on "users" resource
976
+ * ```
977
+ *
978
+ * @example
979
+ * ```typescript
980
+ * // Array of permissions - OR logic (any match grants access)
981
+ * const multiplePerms = [
982
+ * { resourceName: "documents", action: "read" },
983
+ * { resourceName: "documents", action: "update" },
984
+ * ["admin", "all"]
985
+ * ];
986
+ * const canAccessDocs = Auth.isAllowed(multiplePerms);
987
+ * // Returns: true if user has any of the specified permissions
988
+ * ```
989
+ *
990
+ * @example
991
+ * ```typescript
992
+ * // Checking permissions for a specific user
993
+ * const specificUser: AuthUser = {
994
+ * id: "user123",
995
+ * perms: { documents: ["read", "update"] },
996
+ * roles: [{ name: "editor", perms: { images: ["upload"] } }]
997
+ * };
998
+ *
999
+ * const canEdit = Auth.isAllowed(
1000
+ * { resourceName: "documents", action: "update" },
1001
+ * specificUser
1002
+ * ); // Returns: true
1003
+ * ```
1004
+ *
1005
+ * @example
1006
+ * ```typescript
1007
+ * // Master admin bypass - always returns true
1008
+ * Auth.isMasterAdmin = (user) => user.id === "admin";
1009
+ * const adminUser = { id: "admin" };
1010
+ * const canDoAnything = Auth.isAllowed(
1011
+ * { resourceName: "secret", action: "delete" },
1012
+ * adminUser
1013
+ * ); // Returns: true (master admin bypass)
1014
+ * ```
1015
+ *
1016
+ * @see {@link AuthPerm} - Permission configuration type definitions
1017
+ * @see {@link AuthUser} - User object structure with permissions and roles
1018
+ * @see {@link ResourceName} - Valid resource name types
1019
+ * @see {@link ResourceActionName} - Valid action name types
1020
+ * @see {@link checkUserPermission} - Low-level permission checking
1021
+ * @see {@link isMasterAdmin} - Master admin detection function
1022
+ *
1023
+ *
1024
+ * @public
1025
+ */
1026
+ static isAllowed<TResourceName extends ResourceName = ResourceName>(perm: AuthPerm<TResourceName>, user?: AuthUser): boolean;
1027
+ /**
1028
+ * Validates whether a specific user has permission to perform an action on a resource.
1029
+ *
1030
+ * This core authorization method performs comprehensive permission checking by evaluating
1031
+ * both direct user permissions and role-based permissions. It serves as the foundation
1032
+ * for access control throughout the application, providing a reliable and secure way to
1033
+ * determine if a user is authorized to perform specific operations on protected resources.
1034
+ *
1035
+ * ### Permission Evaluation Strategy:
1036
+ * The method implements a hierarchical permission checking system:
1037
+ * 1. **Input Validation**: Ensures the user object is valid and properly structured
1038
+ * 2. **Direct Permissions**: Checks permissions directly assigned to the user
1039
+ * 3. **Role-Based Permissions**: Iterates through user roles to check role-specific permissions
1040
+ * 4. **First Match Wins**: Returns `true` as soon as any valid permission is found
1041
+ * 5. **Secure Default**: Returns `false` if no matching permissions are discovered
1042
+ *
1043
+ * ### Security Architecture:
1044
+ * - **Fail-Safe Design**: Defaults to denying access when permissions are unclear
1045
+ * - **Comprehensive Validation**: Validates user object structure and permission data
1046
+ * - **Role Inheritance**: Supports complex permission models through role-based access
1047
+ * - **Performance Optimized**: Uses early return to minimize computation time
1048
+ *
1049
+ * ### Permission Hierarchy:
1050
+ * The method checks permissions in the following order:
1051
+ * 1. User's direct permissions (`user.perms`)
1052
+ * 2. Permissions inherited from user roles (`user.roles[].perms`)
1053
+ *
1054
+ * @param user - The user object containing permission and role information.
1055
+ * Must be a valid `AuthUser` object with properly structured
1056
+ * permissions and roles. The object should include `perms` for
1057
+ * direct permissions and optionally `roles` array for role-based permissions.
1058
+ *
1059
+ * @param resource - The resource name to check permissions against.
1060
+ * Should be a valid resource identifier from the `ResourceName` type.
1061
+ * Examples include "documents", "users", "admin", "reports", etc.
1062
+ * The resource name is case-sensitive and should match exactly.
1063
+ *
1064
+ * @param action - The specific action to check permission for on the given resource.
1065
+ * Defaults to "read" if not specified. Common actions include:
1066
+ * "read", "create", "update", "delete", "all", or custom actions
1067
+ * specific to your application's permission model.
1068
+ *
1069
+ * @returns `true` if the user has permission to perform the specified action
1070
+ * on the resource, either through direct permissions or role inheritance.
1071
+ * Returns `false` if the user lacks permission, has invalid data,
1072
+ * or if any validation checks fail.
1073
+ *
1074
+ * @example
1075
+ * ```typescript
1076
+ * // Basic permission checking - user with direct permissions
1077
+ * const user: AuthUser = {
1078
+ * id: "user123",
1079
+ * username: "john_doe",
1080
+ * perms: {
1081
+ * documents: ["read", "create", "update"],
1082
+ * reports: ["read"]
1083
+ * }
1084
+ * };
1085
+ *
1086
+ * const canReadDocs = Auth.checkUserPermission(user, "documents", "read");
1087
+ * console.log(canReadDocs); // true
1088
+ *
1089
+ * const canDeleteDocs = Auth.checkUserPermission(user, "documents", "delete");
1090
+ * console.log(canDeleteDocs); // false
1091
+ * ```
1092
+ *
1093
+ * @example
1094
+ * ```typescript
1095
+ * // Role-based permission checking
1096
+ * const userWithRoles: AuthUser = {
1097
+ * id: "user456",
1098
+ * username: "jane_smith",
1099
+ * perms: {
1100
+ * profile: ["read", "update"]
1101
+ * },
1102
+ * roles: [
1103
+ * {
1104
+ * name: "editor",
1105
+ * perms: {
1106
+ * documents: ["read", "create", "update"],
1107
+ * images: ["upload", "edit"]
1108
+ * }
1109
+ * },
1110
+ * {
1111
+ * name: "moderator",
1112
+ * perms: {
1113
+ * comments: ["read", "update", "delete"],
1114
+ * users: ["read", "suspend"]
1115
+ * }
1116
+ * }
1117
+ * ]
1118
+ * };
1119
+ *
1120
+ * // Check direct permission
1121
+ * const canUpdateProfile = Auth.checkUserPermission(userWithRoles, "profile", "update");
1122
+ * console.log(canUpdateProfile); // true (from direct perms)
1123
+ *
1124
+ * // Check role-inherited permission
1125
+ * const canEditDocs = Auth.checkUserPermission(userWithRoles, "documents", "update");
1126
+ * console.log(canEditDocs); // true (from editor role)
1127
+ *
1128
+ * // Check another role permission
1129
+ * const canDeleteComments = Auth.checkUserPermission(userWithRoles, "comments", "delete");
1130
+ * console.log(canDeleteComments); // true (from moderator role)
1131
+ * ```
1132
+ *
1133
+ * @example
1134
+ * ```typescript
1135
+ * // Default action parameter (read)
1136
+ * const user: AuthUser = {
1137
+ * id: "reader",
1138
+ * perms: {
1139
+ * articles: ["read"],
1140
+ * news: ["read", "create"]
1141
+ * }
1142
+ * };
1143
+ *
1144
+ * // These calls are equivalent
1145
+ * const canRead1 = Auth.checkUserPermission(user, "articles", "read");
1146
+ * const canRead2 = Auth.checkUserPermission(user, "articles"); // defaults to "read"
1147
+ * console.log(canRead1 === canRead2); // true
1148
+ * ```
1149
+ *
1150
+ * @example
1151
+ * ```typescript
1152
+ * // Error handling and validation
1153
+ * const invalidUser = null;
1154
+ * const emptyUser = {};
1155
+ * const validUser = { id: "test", perms: { docs: ["read"] } };
1156
+ *
1157
+ * console.log(Auth.checkUserPermission(invalidUser, "documents", "read")); // false
1158
+ * console.log(Auth.checkUserPermission(emptyUser, "documents", "read")); // false
1159
+ * console.log(Auth.checkUserPermission(validUser, "docs", "read")); // true
1160
+ * ```
1161
+ *
1162
+ * @example
1163
+ * ```typescript
1164
+ * // Integration with access control middleware
1165
+ * class PermissionGuard {
1166
+ * static requirePermission(resource: ResourceName, action: ResourceActionName = "read") {
1167
+ * return (req: Request, res: Response, next: NextFunction) => {
1168
+ * const user = Auth.getSignedUser();
1169
+ *
1170
+ * if (!user) {
1171
+ * return res.status(401).json({ error: "Authentication required" });
1172
+ * }
1173
+ *
1174
+ * if (!Auth.checkUserPermission(user, resource, action)) {
1175
+ * return res.status(403).json({
1176
+ * error: `Permission denied: ${action} on ${resource}`
1177
+ * });
1178
+ * }
1179
+ *
1180
+ * next();
1181
+ * };
1182
+ * }
1183
+ * }
1184
+ *
1185
+ * // Usage in Express routes
1186
+ * app.get('/documents', PermissionGuard.requirePermission('documents', 'read'), getDocuments);
1187
+ * app.post('/documents', PermissionGuard.requirePermission('documents', 'create'), createDocument);
1188
+ * app.delete('/documents/:id', PermissionGuard.requirePermission('documents', 'delete'), deleteDocument);
1189
+ * ```
1190
+ *
1191
+ * @example
1192
+ * ```typescript
1193
+ * // Batch permission checking for UI elements
1194
+ * function getUserCapabilities(user: AuthUser) {
1195
+ * const capabilities = {
1196
+ * canReadDocs: Auth.checkUserPermission(user, "documents", "read"),
1197
+ * canCreateDocs: Auth.checkUserPermission(user, "documents", "create"),
1198
+ * canUpdateDocs: Auth.checkUserPermission(user, "documents", "update"),
1199
+ * canDeleteDocs: Auth.checkUserPermission(user, "documents", "delete"),
1200
+ * canManageUsers: Auth.checkUserPermission(user, "users", "update"),
1201
+ * canViewReports: Auth.checkUserPermission(user, "reports", "read"),
1202
+ * canConfigureSystem: Auth.checkUserPermission(user, "system", "configure")
1203
+ * };
1204
+ *
1205
+ * return capabilities;
1206
+ * }
1207
+ *
1208
+ * // Usage in React component
1209
+ * function DocumentToolbar() {
1210
+ * const user = Auth.getSignedUser();
1211
+ * const capabilities = getUserCapabilities(user);
1212
+ *
1213
+ * return (
1214
+ * <div className="toolbar">
1215
+ * {capabilities.canCreateDocs && <CreateButton />}
1216
+ * {capabilities.canUpdateDocs && <EditButton />}
1217
+ * {capabilities.canDeleteDocs && <DeleteButton />}
1218
+ * </div>
1219
+ * );
1220
+ * }
1221
+ * ```
1222
+ *
1223
+ * @example
1224
+ * ```typescript
1225
+ * // Complex permission scenarios with multiple roles
1226
+ * const adminUser: AuthUser = {
1227
+ * id: "admin001",
1228
+ * perms: {
1229
+ * profile: ["read", "update"]
1230
+ * },
1231
+ * roles: [
1232
+ * {
1233
+ * name: "super_admin",
1234
+ * perms: {
1235
+ * users: ["all"],
1236
+ * system: ["all"],
1237
+ * reports: ["all"]
1238
+ * }
1239
+ * },
1240
+ * {
1241
+ * name: "content_manager",
1242
+ * perms: {
1243
+ * documents: ["read", "create", "update", "delete"],
1244
+ * media: ["upload", "edit", "delete"]
1245
+ * }
1246
+ * }
1247
+ * ]
1248
+ * };
1249
+ *
1250
+ * // Check various permissions
1251
+ * console.log(Auth.checkUserPermission(adminUser, "users", "delete")); // true (super_admin role)
1252
+ * console.log(Auth.checkUserPermission(adminUser, "documents", "create")); // true (content_manager role)
1253
+ * console.log(Auth.checkUserPermission(adminUser, "profile", "update")); // true (direct permission)
1254
+ * console.log(Auth.checkUserPermission(adminUser, "billing", "read")); // false (no permission)
1255
+ * ```
1256
+ *
1257
+ * @see {@link AuthUser} - Complete user object interface with permissions and roles
1258
+ * @see {@link ResourceName} - Valid resource name types for permission checking
1259
+ * @see {@link ResourceActionName} - Valid action types for permission operations
1260
+ * @see {@link checkPermission} - Lower-level permission checking against permission objects
1261
+ * @see {@link isAllowed} - Higher-level permission checking with multiple formats
1262
+ * @see {@link AuthPerms} - Permission object structure and format
1263
+ * @see {@link AuthRole} - Role object structure with embedded permissions
1264
+ *
1265
+ *
1266
+ * @public
1267
+ *
1268
+ * @remarks
1269
+ * **Security Best Practices:**
1270
+ * - Always validate user input before calling this method
1271
+ * - Use this method as the primary gate for access control decisions
1272
+ * - Consider implementing audit logging for permission checks in security-sensitive applications
1273
+ * - Regularly review and update permission models as application requirements evolve
1274
+ *
1275
+ * **Performance Considerations:**
1276
+ * - The method uses early return for optimal performance
1277
+ * - Role iteration stops at the first matching permission found
1278
+ * - Consider caching results for frequently checked permissions
1279
+ * - Large role hierarchies may impact performance; consider flattening permissions when possible
1280
+ *
1281
+ * **Design Patterns:**
1282
+ * - Implements the "Fail-Safe Defaults" security pattern
1283
+ * - Supports both direct and inherited permission models
1284
+ * - Compatible with Role-Based Access Control (RBAC) systems
1285
+ * - Integrates seamlessly with middleware and guard patterns
1286
+ *
1287
+ * **Error Handling:**
1288
+ * - Returns `false` for any invalid or malformed input
1289
+ * - Gracefully handles missing permission structures
1290
+ * - Does not throw exceptions, making it safe for use in conditional statements
1291
+ * - Logs errors internally for debugging purposes without exposing sensitive information
1292
+ */
1293
+ static checkUserPermission<TResourceName extends ResourceName = ResourceName>(user: AuthUser, resource: TResourceName, action?: ResourceActionName<TResourceName>): boolean;
1294
+ /**
1295
+ * Evaluates whether a permission object grants access to perform a specific action on a resource.
1296
+ *
1297
+ * This fundamental permission checking method serves as the core authorization engine for
1298
+ * the authentication system. It performs low-level permission validation by examining
1299
+ * permission objects and determining if they contain the necessary action permissions
1300
+ * for a given resource. The method implements case-insensitive resource matching and
1301
+ * supports both specific action permissions and universal "all" permissions.
1302
+ *
1303
+ * ### Permission Evaluation Algorithm:
1304
+ * 1. **Input Sanitization**: Normalizes and validates input parameters for consistent processing
1305
+ * 2. **Resource Matching**: Performs case-insensitive resource name matching in permission object
1306
+ * 3. **Action Discovery**: Extracts the list of allowed actions for the matched resource
1307
+ * 4. **Universal Permission Check**: Returns `true` immediately if "all" permission is found
1308
+ * 5. **Specific Action Validation**: Iterates through actions to find exact or compatible matches
1309
+ * 6. **Fail-Safe Return**: Returns `false` if no matching permissions are discovered
1310
+ *
1311
+ * ### Security Features:
1312
+ * - **Defensive Programming**: Validates all inputs and handles malformed data gracefully
1313
+ * - **Case-Insensitive Matching**: Prevents permission bypass through case manipulation
1314
+ * - **Universal Permission Support**: Recognizes "all" as a wildcard permission
1315
+ * - **Strict Validation**: Requires exact resource and action matches for security
1316
+ *
1317
+ * ### Performance Optimization:
1318
+ * - **Early Exit Strategy**: Returns immediately when "all" permission is found
1319
+ * - **Efficient Iteration**: Stops processing at the first matching permission
1320
+ * - **Memory Safety**: Creates defensive copies of input objects to prevent mutation
1321
+ * - **Minimal Processing**: Only processes relevant permission entries
1322
+ *
1323
+ * @template TResourceName - The resource name type constraint extending ResourceName
1324
+ *
1325
+ * @param perms - The permission object containing resource-to-actions mappings.
1326
+ * Must be a valid `AuthPerms` object where keys are resource names
1327
+ * and values are arrays of allowed actions. The object is defensively
1328
+ * copied to prevent external mutations during processing.
1329
+ *
1330
+ * @param resource - The resource name to check permissions for.
1331
+ * Should be a valid identifier from the `ResourceName` type.
1332
+ * The resource name undergoes case-insensitive matching, so
1333
+ * "Documents", "documents", and "DOCUMENTS" are treated as equivalent.
1334
+ * Empty or invalid resource names result in permission denial.
1335
+ *
1336
+ * @param action - The specific action to validate against the resource permissions.
1337
+ * Defaults to "read" if not specified. The action must match exactly
1338
+ * (case-insensitive) with one of the allowed actions in the permission
1339
+ * array, or the resource must have "all" permission for universal access.
1340
+ *
1341
+ * @returns `true` if the permission object grants the specified action on the resource,
1342
+ * either through explicit action permission or universal "all" permission.
1343
+ * Returns `false` if permissions are insufficient, invalid, or if input
1344
+ * validation fails.
1345
+ *
1346
+ * @example
1347
+ * ```typescript
1348
+ * // Basic permission checking with explicit actions
1349
+ * const permissions: AuthPerms = {
1350
+ * documents: ["read", "create", "update"],
1351
+ * users: ["read"],
1352
+ * reports: ["read", "export"]
1353
+ * };
1354
+ *
1355
+ * // Check various permissions
1356
+ * const canReadDocs = Auth.checkPermission(permissions, "documents", "read");
1357
+ * console.log(canReadDocs); // true
1358
+ *
1359
+ * const canDeleteDocs = Auth.checkPermission(permissions, "documents", "delete");
1360
+ * console.log(canDeleteDocs); // false
1361
+ *
1362
+ * const canCreateUsers = Auth.checkPermission(permissions, "users", "create");
1363
+ * console.log(canCreateUsers); // false
1364
+ * ```
1365
+ *
1366
+ * @example
1367
+ * ```typescript
1368
+ * // Universal "all" permission handling
1369
+ * const adminPermissions: AuthPerms = {
1370
+ * system: ["all"],
1371
+ * documents: ["read", "create"],
1372
+ * users: ["all"]
1373
+ * };
1374
+ *
1375
+ * // "all" permission grants access to any action
1376
+ * console.log(Auth.checkPermission(adminPermissions, "system", "configure")); // true
1377
+ * console.log(Auth.checkPermission(adminPermissions, "system", "delete")); // true
1378
+ * console.log(Auth.checkPermission(adminPermissions, "system", "custom_action")); // true
1379
+ *
1380
+ * // Specific permissions still work normally
1381
+ * console.log(Auth.checkPermission(adminPermissions, "documents", "read")); // true
1382
+ * console.log(Auth.checkPermission(adminPermissions, "documents", "delete")); // false
1383
+ * ```
1384
+ *
1385
+ * @example
1386
+ * ```typescript
1387
+ * // Case-insensitive resource matching
1388
+ * const permissions: AuthPerms = {
1389
+ * Documents: ["read", "write"],
1390
+ * USERS: ["read"],
1391
+ * api_endpoints: ["access"]
1392
+ * };
1393
+ *
1394
+ * // All of these will match the "Documents" resource
1395
+ * console.log(Auth.checkPermission(permissions, "documents", "read")); // true
1396
+ * console.log(Auth.checkPermission(permissions, "DOCUMENTS", "read")); // true
1397
+ * console.log(Auth.checkPermission(permissions, "DoCtMeNtS", "read")); // true
1398
+ *
1399
+ * // Case-insensitive matching for all resources
1400
+ * console.log(Auth.checkPermission(permissions, "users", "read")); // true
1401
+ * console.log(Auth.checkPermission(permissions, "API_ENDPOINTS", "access")); // true
1402
+ * ```
1403
+ *
1404
+ * @example
1405
+ * ```typescript
1406
+ * // Default action parameter behavior
1407
+ * const readOnlyPermissions: AuthPerms = {
1408
+ * articles: ["read"],
1409
+ * news: ["read", "comment"],
1410
+ * profiles: ["read", "update"]
1411
+ * };
1412
+ *
1413
+ * // These calls are equivalent (default action is "read")
1414
+ * const canRead1 = Auth.checkPermission(readOnlyPermissions, "articles", "read");
1415
+ * const canRead2 = Auth.checkPermission(readOnlyPermissions, "articles");
1416
+ * console.log(canRead1 === canRead2); // true, both return true
1417
+ *
1418
+ * // Default "read" action checking
1419
+ * console.log(Auth.checkPermission(readOnlyPermissions, "news")); // true (has read)
1420
+ * console.log(Auth.checkPermission(readOnlyPermissions, "profiles")); // true (has read)
1421
+ * ```
1422
+ *
1423
+ * @example
1424
+ * ```typescript
1425
+ * // Error handling and edge cases
1426
+ * const validPermissions: AuthPerms = { docs: ["read"] };
1427
+ * const emptyPermissions: AuthPerms = {};
1428
+ * const nullPermissions = null;
1429
+ *
1430
+ * // Valid permission object
1431
+ * console.log(Auth.checkPermission(validPermissions, "docs", "read")); // true
1432
+ *
1433
+ * // Empty permission object
1434
+ * console.log(Auth.checkPermission(emptyPermissions, "docs", "read")); // false
1435
+ *
1436
+ * // Invalid permission object
1437
+ * console.log(Auth.checkPermission(nullPermissions as any, "docs", "read")); // false
1438
+ *
1439
+ * // Invalid resource name
1440
+ * console.log(Auth.checkPermission(validPermissions, "" as ResourceName, "read")); // false
1441
+ * console.log(Auth.checkPermission(validPermissions, null as any, "read")); // false
1442
+ * ```
1443
+ *
1444
+ * @example
1445
+ * ```typescript
1446
+ * // Permission validation utility function
1447
+ * function validateUserAccess(
1448
+ * userPerms: AuthPerms,
1449
+ * requiredResource: ResourceName,
1450
+ * requiredAction: ResourceActionName
1451
+ * ): { allowed: boolean; reason: string } {
1452
+ * if (!userPerms || typeof userPerms !== 'object') {
1453
+ * return { allowed: false, reason: 'Invalid permission object' };
1454
+ * }
1455
+ *
1456
+ * if (!requiredResource) {
1457
+ * return { allowed: false, reason: 'Resource name is required' };
1458
+ * }
1459
+ *
1460
+ * const hasPermission = Auth.checkPermission(userPerms, requiredResource, requiredAction);
1461
+ *
1462
+ * return {
1463
+ * allowed: hasPermission,
1464
+ * reason: hasPermission
1465
+ * ? `Access granted for ${requiredAction} on ${requiredResource}`
1466
+ * : `Access denied: insufficient permissions for ${requiredAction} on ${requiredResource}`
1467
+ * };
1468
+ * }
1469
+ *
1470
+ * // Usage example
1471
+ * const userPermissions: AuthPerms = {
1472
+ * documents: ["read", "create"],
1473
+ * users: ["read"]
1474
+ * };
1475
+ *
1476
+ * const result = validateUserAccess(userPermissions, "documents", "update");
1477
+ * console.log(result); // { allowed: false, reason: "Access denied: insufficient permissions..." }
1478
+ * ```
1479
+ *
1480
+ * @example
1481
+ * ```typescript
1482
+ * // Integration with role-based permission systems
1483
+ * class PermissionManager {
1484
+ * static combinePermissions(...permissionSets: AuthPerms[]): AuthPerms {
1485
+ * const combined: AuthPerms = {};
1486
+ *
1487
+ * for (const perms of permissionSets) {
1488
+ * if (!perms) continue;
1489
+ *
1490
+ * for (const [resource, actions] of Object.entries(perms)) {
1491
+ * if (!combined[resource as keyof AuthPerms]) {
1492
+ * combined[resource as keyof AuthPerms] = [];
1493
+ * }
1494
+ *
1495
+ * const existingActions = combined[resource as keyof AuthPerms] as ResourceActionName[];
1496
+ * const newActions = actions as ResourceActionName[];
1497
+ *
1498
+ * // Merge actions, avoiding duplicates
1499
+ * for (const action of newActions) {
1500
+ * if (!existingActions.includes(action)) {
1501
+ * existingActions.push(action);
1502
+ * }
1503
+ * }
1504
+ * }
1505
+ * }
1506
+ *
1507
+ * return combined;
1508
+ * }
1509
+ *
1510
+ * static hasAnyPermission(perms: AuthPerms, checks: Array<[ResourceName, ResourceActionName]>): boolean {
1511
+ * return checks.some(([resource, action]) =>
1512
+ * Auth.checkPermission(perms, resource, action)
1513
+ * );
1514
+ * }
1515
+ *
1516
+ * static hasAllPermissions(perms: AuthPerms, checks: Array<[ResourceName, ResourceActionName]>): boolean {
1517
+ * return checks.every(([resource, action]) =>
1518
+ * Auth.checkPermission(perms, resource, action)
1519
+ * );
1520
+ * }
1521
+ * }
1522
+ *
1523
+ * // Usage
1524
+ * const userPerms: AuthPerms = { documents: ["read"], users: ["read", "update"] };
1525
+ * const rolePerms: AuthPerms = { documents: ["create"], reports: ["read"] };
1526
+ *
1527
+ * const combinedPerms = PermissionManager.combinePermissions(userPerms, rolePerms);
1528
+ * console.log(Auth.checkPermission(combinedPerms, "documents", "create")); // true
1529
+ * ```
1530
+ *
1531
+ * @see {@link AuthPerms} - Permission object structure and type definitions
1532
+ * @see {@link ResourceName} - Valid resource name types for permission checking
1533
+ * @see {@link ResourceActionName} - Valid action types for permission operations
1534
+ * @see {@link checkUserPermission} - Higher-level user permission checking method
1535
+ * @see {@link isAllowed} - Comprehensive permission evaluation with multiple formats
1536
+ * @see {@link isAllowedForAction} - Action-specific permission matching utility
1537
+ *
1538
+ *
1539
+ * @public
1540
+ *
1541
+ * @remarks
1542
+ * **Security Considerations:**
1543
+ * - This method performs case-insensitive matching to prevent security bypasses
1544
+ * - Always validates input parameters to prevent injection or manipulation attacks
1545
+ * - Returns `false` by default for any ambiguous or invalid scenarios
1546
+ * - The "all" permission should be used carefully as it grants universal access
1547
+ *
1548
+ * **Performance Best Practices:**
1549
+ * - The method creates defensive copies of input objects, consider caching results for frequently checked permissions
1550
+ * - Early termination when "all" permission is found improves performance for administrative users
1551
+ * - Use this method as the foundation for higher-level permission checking utilities
1552
+ * - Consider implementing permission result caching for high-frequency checks
1553
+ *
1554
+ * **Design Patterns:**
1555
+ * - Implements the "Secure by Default" principle with fail-safe returns
1556
+ * - Supports the Strategy pattern through flexible action matching
1557
+ * - Compatible with Role-Based Access Control (RBAC) and Attribute-Based Access Control (ABAC) systems
1558
+ * - Follows the Single Responsibility Principle by focusing solely on permission object evaluation
1559
+ *
1560
+ * **Error Handling Strategy:**
1561
+ * - Never throws exceptions, always returns boolean values for predictable behavior
1562
+ * - Handles null, undefined, and malformed inputs gracefully
1563
+ * - Provides meaningful return values that can be safely used in conditional statements
1564
+ * - Logs internal errors for debugging without exposing sensitive permission details
1565
+ */
1566
+ static checkPermission<TResourceName extends ResourceName = ResourceName>(perms: AuthPerms, resource: TResourceName, action?: ResourceActionName<TResourceName>): boolean;
1567
+ /**
1568
+ * Determines whether a specific permission action matches a requested action.
1569
+ *
1570
+ * This utility method performs precise action-to-action comparison for permission validation.
1571
+ * It serves as the atomic-level matching function in the permission checking hierarchy,
1572
+ * providing case-insensitive string comparison with proper normalization. The method
1573
+ * ensures that permission actions are evaluated consistently and securely across the
1574
+ * entire authentication system.
1575
+ *
1576
+ * ### Matching Algorithm:
1577
+ * 1. **Input Validation**: Ensures both parameters are valid non-null strings
1578
+ * 2. **String Normalization**: Trims whitespace and converts to lowercase for comparison
1579
+ * 3. **Exact Matching**: Performs strict equality comparison after normalization
1580
+ * 4. **Binary Result**: Returns boolean result for immediate conditional usage
1581
+ *
1582
+ * ### Security Features:
1583
+ * - **Case-Insensitive Matching**: Prevents permission bypass through case manipulation
1584
+ * - **Whitespace Normalization**: Eliminates accidental whitespace-based security issues
1585
+ * - **Strict Validation**: Rejects null, undefined, or non-string inputs for security
1586
+ * - **Deterministic Behavior**: Always produces consistent results for identical inputs
1587
+ *
1588
+ * ### Performance Characteristics:
1589
+ * - **Minimal Overhead**: Lightweight string operations with O(1) complexity
1590
+ * - **Early Termination**: Returns immediately on validation failure
1591
+ * - **String Optimization**: Uses native JavaScript string methods for efficiency
1592
+ * - **Memory Efficient**: No intermediate object creation or complex processing
1593
+ *
1594
+ * @template TResourceName - The resource name type constraint extending ResourceName
1595
+ *
1596
+ * @param permFromResource - The permission action to check against.
1597
+ * Must be a valid string conforming to `ResourceActionName<TResourceName>`.
1598
+ * This represents the action that is granted by a permission entry.
1599
+ * Examples: "read", "write", "delete", "create", "all", "custom_action".
1600
+ * Empty strings, null, or undefined values will result in `false`.
1601
+ *
1602
+ * @param action - The requested action to validate.
1603
+ * Must be a valid string conforming to `ResourceActionName<TResourceName>`.
1604
+ * This represents the action that a user is attempting to perform.
1605
+ * The comparison is performed case-insensitively with whitespace trimming.
1606
+ * Examples: "READ", "Write", " delete ", "CREATE", "All".
1607
+ *
1608
+ * @returns `true` if the permission action exactly matches the requested action
1609
+ * after case-insensitive comparison and whitespace normalization.
1610
+ * Returns `false` if either parameter is invalid, null, undefined,
1611
+ * empty, or if the normalized strings do not match exactly.
1612
+ *
1613
+ * @example
1614
+ * ```typescript
1615
+ * // Basic exact matching (case-insensitive)
1616
+ * console.log(Auth.isAllowedForAction("read", "read")); // true
1617
+ * console.log(Auth.isAllowedForAction("READ", "read")); // true
1618
+ * console.log(Auth.isAllowedForAction("Read", "READ")); // true
1619
+ * console.log(Auth.isAllowedForAction("write", "read")); // false
1620
+ * ```
1621
+ *
1622
+ * @example
1623
+ * ```typescript
1624
+ * // Whitespace handling and normalization
1625
+ * console.log(Auth.isAllowedForAction(" read ", "read")); // true
1626
+ * console.log(Auth.isAllowedForAction("update", " UPDATE ")); // true
1627
+ * console.log(Auth.isAllowedForAction("\tdelete\n", "delete")); // true
1628
+ * console.log(Auth.isAllowedForAction("create ", " create")); // true
1629
+ * ```
1630
+ *
1631
+ * @example
1632
+ * ```typescript
1633
+ * // Input validation and edge cases
1634
+ * console.log(Auth.isAllowedForAction("", "read")); // false (empty permission)
1635
+ * console.log(Auth.isAllowedForAction("read", "")); // false (empty action)
1636
+ * console.log(Auth.isAllowedForAction(null as any, "read")); // false (null permission)
1637
+ * console.log(Auth.isAllowedForAction("read", undefined as any)); // false (undefined action)
1638
+ * console.log(Auth.isAllowedForAction("valid", "valid")); // true (both valid)
1639
+ * ```
1640
+ *
1641
+ * @example
1642
+ * ```typescript
1643
+ * // Integration with permission checking workflow
1644
+ * function checkSpecificPermission(
1645
+ * userActions: ResourceActionName[],
1646
+ * requiredAction: ResourceActionName
1647
+ * ): boolean {
1648
+ * // Check if user has "all" permission (universal access)
1649
+ * if (userActions.includes("all")) {
1650
+ * return true;
1651
+ * }
1652
+ *
1653
+ * // Check each specific action permission
1654
+ * for (const userAction of userActions) {
1655
+ * if (Auth.isAllowedForAction(userAction, requiredAction)) {
1656
+ * return true;
1657
+ * }
1658
+ * }
1659
+ *
1660
+ * return false;
1661
+ * }
1662
+ *
1663
+ * // Usage example
1664
+ * const userPermissions: ResourceActionName[] = ["read", "UPDATE", " create "];
1665
+ *
1666
+ * console.log(checkSpecificPermission(userPermissions, "read")); // true
1667
+ * console.log(checkSpecificPermission(userPermissions, "update")); // true (case-insensitive)
1668
+ * console.log(checkSpecificPermission(userPermissions, "create")); // true (whitespace normalized)
1669
+ * console.log(checkSpecificPermission(userPermissions, "delete")); // false
1670
+ * ```
1671
+ *
1672
+ * @example
1673
+ * ```typescript
1674
+ * // Custom action validation system
1675
+ * class ActionValidator {
1676
+ * private static readonly VALID_ACTIONS = [
1677
+ * "read", "create", "update", "delete",
1678
+ * "list", "search", "export", "import", "all"
1679
+ * ];
1680
+ *
1681
+ * static isValidAction(action: string): boolean {
1682
+ * return this.VALID_ACTIONS.some(validAction =>
1683
+ * Auth.isAllowedForAction(validAction, action)
1684
+ * );
1685
+ * }
1686
+ *
1687
+ * static normalizeAction(action: string): string {
1688
+ * if (!action || typeof action !== 'string') {
1689
+ * return '';
1690
+ * }
1691
+ * return action.trim().toLowerCase();
1692
+ * }
1693
+ *
1694
+ * static compareActions(action1: string, action2: string): boolean {
1695
+ * return Auth.isAllowedForAction(action1, action2);
1696
+ * }
1697
+ * }
1698
+ *
1699
+ * // Usage
1700
+ * console.log(ActionValidator.isValidAction("READ")); // true
1701
+ * console.log(ActionValidator.isValidAction("INVALID")); // false
1702
+ * console.log(ActionValidator.compareActions("Create", "create")); // true
1703
+ * ```
1704
+ *
1705
+ * @example
1706
+ * ```typescript
1707
+ * // Permission matrix validation
1708
+ * interface PermissionCheck {
1709
+ * granted: ResourceActionName;
1710
+ * requested: ResourceActionName;
1711
+ * expected: boolean;
1712
+ * }
1713
+ *
1714
+ * function validatePermissionMatrix(checks: PermissionCheck[]): boolean {
1715
+ * return checks.every(check => {
1716
+ * const result = Auth.isAllowedForAction(check.granted, check.requested);
1717
+ * if (result !== check.expected) {
1718
+ * console.error(`Permission check failed: ${check.granted} vs ${check.requested}`);
1719
+ * return false;
1720
+ * }
1721
+ * return true;
1722
+ * });
1723
+ * }
1724
+ *
1725
+ * // Test matrix
1726
+ * const permissionTests: PermissionCheck[] = [
1727
+ * { granted: "read", requested: "read", expected: true },
1728
+ * { granted: "READ", requested: "read", expected: true },
1729
+ * { granted: "write", requested: "read", expected: false },
1730
+ * { granted: " update ", requested: "UPDATE", expected: true },
1731
+ * { granted: "all", requested: "anything", expected: true }
1732
+ * ];
1733
+ *
1734
+ * const allTestsPassed = validatePermissionMatrix(permissionTests);
1735
+ * console.log(`All permission tests passed: ${allTestsPassed}`);
1736
+ * ```
1737
+ *
1738
+ * @example
1739
+ * ```typescript
1740
+ * // Real-world usage in permission engine
1741
+ * class PermissionEngine {
1742
+ * static evaluateActionPermission(
1743
+ * grantedActions: ResourceActionName[],
1744
+ * requestedAction: ResourceActionName
1745
+ * ): { allowed: boolean; matchedAction?: ResourceActionName } {
1746
+ * // Check for universal permission first
1747
+ * if (grantedActions.includes("all")) {
1748
+ * return { allowed: true, matchedAction: "all" };
1749
+ * }
1750
+ *
1751
+ * // Find specific matching action
1752
+ * for (const grantedAction of grantedActions) {
1753
+ * if (Auth.isAllowedForAction(grantedAction, requestedAction)) {
1754
+ * return { allowed: true, matchedAction: grantedAction };
1755
+ * }
1756
+ * }
1757
+ *
1758
+ * return { allowed: false };
1759
+ * }
1760
+ * }
1761
+ *
1762
+ * // Usage
1763
+ * const result = PermissionEngine.evaluateActionPermission(
1764
+ * ["read", "CREATE", " update "],
1765
+ * "create"
1766
+ * );
1767
+ * console.log(result); // { allowed: true, matchedAction: "CREATE" }
1768
+ * ```
1769
+ *
1770
+ * @see {@link ResourceActionName} - Type definition for valid action names
1771
+ * @see {@link checkPermission} - Higher-level permission checking method that uses this function
1772
+ * @see {@link checkUserPermission} - User-specific permission validation
1773
+ * @see {@link isAllowed} - Comprehensive permission evaluation system
1774
+ *
1775
+ *
1776
+ * @public
1777
+ *
1778
+ * @remarks
1779
+ * **Implementation Notes:**
1780
+ * - This method is used internally by `checkPermission` for action matching
1781
+ * - The case-insensitive comparison helps prevent common permission configuration errors
1782
+ * - Whitespace trimming ensures that formatting inconsistencies don't affect security
1783
+ * - The method is designed to be called frequently, so performance is optimized
1784
+ *
1785
+ * **Security Considerations:**
1786
+ * - Input validation prevents type confusion attacks
1787
+ * - Normalization prevents case-based permission bypass attempts
1788
+ * - Exact matching after normalization ensures no unexpected permission grants
1789
+ * - No regular expressions are used to avoid ReDoS vulnerabilities
1790
+ *
1791
+ * **Performance Optimization:**
1792
+ * - Uses native string methods for maximum performance
1793
+ * - Early return on invalid inputs minimizes processing time
1794
+ * - No object allocation or complex logic for minimal memory footprint
1795
+ * - Suitable for high-frequency permission checking scenarios
1796
+ *
1797
+ * **Testing Strategy:**
1798
+ * - Test with various case combinations (lowercase, uppercase, mixed)
1799
+ * - Verify whitespace handling (leading, trailing, internal spaces)
1800
+ * - Validate edge cases (empty strings, null, undefined)
1801
+ * - Ensure consistent behavior across different JavaScript environments
1802
+ */
1803
+ static isAllowedForAction<TResourceName extends ResourceName = ResourceName>(permFromResource: ResourceActionName<TResourceName>, action: ResourceActionName<TResourceName>): boolean;
1804
+ /**
1805
+ * Provides access to the Session utility class for authentication-related session management.
1806
+ *
1807
+ * This static getter exposes the Session class, which contains utility methods and properties
1808
+ * for managing browser session storage, encrypted data persistence, and session-related
1809
+ * operations. It serves as a convenient access point to session functionality without
1810
+ * requiring separate imports, maintaining the cohesive design of the Auth class API.
1811
+ *
1812
+ * ### Session Management Features:
1813
+ * The Session class provides comprehensive session management capabilities including:
1814
+ * - **Encrypted Storage**: Secure storage and retrieval of sensitive session data
1815
+ * - **Cross-Tab Synchronization**: Session state management across multiple browser tabs
1816
+ * - **Storage Abstraction**: Unified interface for localStorage and sessionStorage
1817
+ * - **Data Serialization**: Automatic JSON serialization/deserialization with error handling
1818
+ * - **Storage Events**: Event-driven session updates and notifications
1819
+ *
1820
+ * ### Integration Benefits:
1821
+ * - **Unified API**: Access session functionality through the Auth class namespace
1822
+ * - **Consistent Interface**: Maintains the same design patterns as other Auth methods
1823
+ * - **Type Safety**: Full TypeScript support with proper type definitions
1824
+ * - **Documentation**: Comprehensive JSDoc documentation for all session methods
1825
+ *
1826
+ * @returns The Session class containing static methods for session management.
1827
+ * This includes methods for storing, retrieving, and managing encrypted
1828
+ * session data, as well as utilities for session lifecycle management.
1829
+ *
1830
+ * @example
1831
+ * ```typescript
1832
+ * // Basic session storage operations
1833
+ * const session = Auth.Session;
1834
+ *
1835
+ * // Store data in session
1836
+ * await session.set('user_preferences', { theme: 'dark', language: 'en' });
1837
+ *
1838
+ * // Retrieve data from session
1839
+ * const preferences = session.get('user_preferences');
1840
+ * console.log(preferences); // { theme: 'dark', language: 'en' }
1841
+ *
1842
+ * // Remove data from session
1843
+ * await session.remove('user_preferences');
1844
+ * ```
1845
+ *
1846
+ * @example
1847
+ * ```typescript
1848
+ * // Encrypted session data management
1849
+ * const session = Auth.Session;
1850
+ *
1851
+ * // Store sensitive data with encryption
1852
+ * const sensitiveData = {
1853
+ * apiKey: 'secret_api_key_12345',
1854
+ * userToken: 'bearer_token_xyz789',
1855
+ * personalInfo: { ssn: '123-45-6789', creditCard: '4111-1111-1111-1111' }
1856
+ * };
1857
+ *
1858
+ * await session.setEncrypted('sensitive_data', sensitiveData, 'encryption_key');
1859
+ *
1860
+ * // Retrieve and decrypt sensitive data
1861
+ * const decryptedData = session.getEncrypted('sensitive_data', 'encryption_key');
1862
+ * console.log(decryptedData.apiKey); // 'secret_api_key_12345'
1863
+ * ```
1864
+ *
1865
+ * @example
1866
+ * ```typescript
1867
+ * // Session lifecycle management
1868
+ * const session = Auth.Session;
1869
+ *
1870
+ * // Initialize session with configuration
1871
+ * session.configure({
1872
+ * storageType: 'sessionStorage', // or 'localStorage'
1873
+ * encryptionEnabled: true,
1874
+ * keyPrefix: 'myapp_',
1875
+ * maxAge: 3600000 // 1 hour in milliseconds
1876
+ * });
1877
+ *
1878
+ * // Check session validity
1879
+ * const isValid = session.isValid('user_session');
1880
+ * if (isValid) {
1881
+ * console.log('Session is still valid');
1882
+ * } else {
1883
+ * console.log('Session has expired or is invalid');
1884
+ * }
1885
+ *
1886
+ * // Clear expired sessions
1887
+ * session.clearExpired();
1888
+ * ```
1889
+ *
1890
+ * @example
1891
+ * ```typescript
1892
+ * // Cross-tab session synchronization
1893
+ * const session = Auth.Session;
1894
+ *
1895
+ * // Listen for session changes across tabs
1896
+ * session.onStorageChange((event) => {
1897
+ * console.log('Session changed in another tab:', event);
1898
+ * if (event.key === 'user_session' && event.newValue === null) {
1899
+ * console.log('User logged out in another tab');
1900
+ * handleCrossTabLogout();
1901
+ * }
1902
+ * });
1903
+ *
1904
+ * // Broadcast session updates to other tabs
1905
+ * await session.broadcast('user_status_change', { status: 'online' });
1906
+ * ```
1907
+ *
1908
+ * @example
1909
+ * ```typescript
1910
+ * // Session-based caching system
1911
+ * class SessionCache {
1912
+ * private static session = Auth.Session;
1913
+ *
1914
+ * static async cacheApiResponse<T>(key: string, data: T, ttl: number = 300000): Promise<void> {
1915
+ * const cacheEntry = {
1916
+ * data,
1917
+ * timestamp: Date.now(),
1918
+ * ttl
1919
+ * };
1920
+ *
1921
+ * await this.session.set(`cache_${key}`, cacheEntry);
1922
+ * }
1923
+ *
1924
+ * static getCachedData<T>(key: string): T | null {
1925
+ * const cacheEntry = this.session.get(`cache_${key}`);
1926
+ *
1927
+ * if (!cacheEntry) return null;
1928
+ *
1929
+ * const { data, timestamp, ttl } = cacheEntry;
1930
+ * const isExpired = Date.now() - timestamp > ttl;
1931
+ *
1932
+ * if (isExpired) {
1933
+ * this.session.remove(`cache_${key}`);
1934
+ * return null;
1935
+ * }
1936
+ *
1937
+ * return data;
1938
+ * }
1939
+ *
1940
+ * static clearCache(): void {
1941
+ * this.session.clearByPrefix('cache_');
1942
+ * }
1943
+ * }
1944
+ *
1945
+ * // Usage
1946
+ * await SessionCache.cacheApiResponse('user_profile', userData, 600000); // 10 minutes
1947
+ * const cachedProfile = SessionCache.getCachedData('user_profile');
1948
+ * ```
1949
+ *
1950
+ * @example
1951
+ * ```typescript
1952
+ * // Integration with authentication workflow
1953
+ * class AuthSessionManager {
1954
+ * private static session = Auth.Session;
1955
+ *
1956
+ * static async storeAuthSession(user: AuthUser, rememberMe: boolean = false): Promise<void> {
1957
+ * const sessionData = {
1958
+ * user,
1959
+ * timestamp: Date.now(),
1960
+ * rememberMe,
1961
+ * sessionId: crypto.randomUUID()
1962
+ * };
1963
+ *
1964
+ * const storageType = rememberMe ? 'localStorage' : 'sessionStorage';
1965
+ *
1966
+ * await this.session.setWithOptions('auth_session', sessionData, {
1967
+ * storage: storageType,
1968
+ * encrypted: true,
1969
+ * maxAge: rememberMe ? 2592000000 : 86400000 // 30 days or 1 day
1970
+ * });
1971
+ * }
1972
+ *
1973
+ * static getAuthSession(): { user: AuthUser; sessionId: string } | null {
1974
+ * const sessionData = this.session.getDecrypted('auth_session');
1975
+ *
1976
+ * if (!sessionData || this.isSessionExpired(sessionData)) {
1977
+ * this.clearAuthSession();
1978
+ * return null;
1979
+ * }
1980
+ *
1981
+ * return {
1982
+ * user: sessionData.user,
1983
+ * sessionId: sessionData.sessionId
1984
+ * };
1985
+ * }
1986
+ *
1987
+ * static clearAuthSession(): void {
1988
+ * this.session.remove('auth_session');
1989
+ * this.session.clearByPrefix('user_');
1990
+ * }
1991
+ *
1992
+ * private static isSessionExpired(sessionData: any): boolean {
1993
+ * const maxAge = sessionData.rememberMe ? 2592000000 : 86400000;
1994
+ * return Date.now() - sessionData.timestamp > maxAge;
1995
+ * }
1996
+ * }
1997
+ * ```
1998
+ *
1999
+ * @see {@link Session} - The Session class with complete session management functionality
2000
+ * @see {@link setSignedUser} - Method that uses Session for storing encrypted user data
2001
+ * @see {@link getSignedUser} - Method that uses Session for retrieving encrypted user data
2002
+ * @see {@link AuthUser} - User interface that may be stored in session
2003
+ *
2004
+ *
2005
+ * @public
2006
+ * @readonly
2007
+ *
2008
+ * @remarks
2009
+ * **Usage Patterns:**
2010
+ * - Use `Auth.Session` for all session-related operations within authentication workflows
2011
+ * - The Session class provides both synchronous and asynchronous methods for flexibility
2012
+ * - Encrypted storage methods should be used for sensitive authentication data
2013
+ * - Consider session storage vs local storage based on data persistence requirements
2014
+ *
2015
+ * **Security Considerations:**
2016
+ * - Always use encrypted storage methods for sensitive authentication data
2017
+ * - Be aware that session storage is cleared when the browser tab closes
2018
+ * - Local storage persists across browser sessions and should be used carefully
2019
+ * - Implement proper session timeout and cleanup mechanisms
2020
+ *
2021
+ * **Performance Notes:**
2022
+ * - Session operations are generally fast but may involve encryption/decryption overhead
2023
+ * - Consider caching frequently accessed session data to reduce storage operations
2024
+ * - Be mindful of storage quotas when storing large amounts of session data
2025
+ * - Use appropriate storage types (sessionStorage vs localStorage) based on use case
2026
+ *
2027
+ * **Browser Compatibility:**
2028
+ * - Session functionality is supported in all modern browsers
2029
+ * - Fallback mechanisms are available for environments without storage support
2030
+ * - Storage events work consistently across different browser implementations
2031
+ * - Encryption features require a compatible JavaScript environment
2032
+ */
2033
+ static get Session(): typeof Session;
2034
+ }