@arex95/vue-core 1.1.10 → 1.1.11

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.
@@ -0,0 +1 @@
1
+ export * from "./useAuth";
@@ -15,6 +15,7 @@ export declare function configureAuth(options: AuthConfig): void;
15
15
  * @returns {Object} Auth composable methods and properties.
16
16
  */
17
17
  export declare function useAuth(secretKey?: string): {
18
+ isAuthenticated: import("vue").ComputedRef<boolean>;
18
19
  jwt: import("vue").ComputedRef<string | null>;
19
20
  refresh_token: import("vue").ComputedRef<string | null>;
20
21
  tokenExpiry: import("vue").ComputedRef<number | null>;
@@ -3,3 +3,4 @@ export * from './breakpoints';
3
3
  export * from './filters';
4
4
  export * from './paginators';
5
5
  export * from './sorters';
6
+ export * from './auth';
@@ -1,2 +1,3 @@
1
- export * from './tokenConfig';
1
+ export * from './tokensConfig';
2
2
  export * from './endpointsConfig';
3
+ export * from './sessionConfig';
@@ -0,0 +1,31 @@
1
+ import { TokensConfig } from "@/types";
2
+ /**
3
+ * Configures the global keys for access and refresh tokens.
4
+ * Once set, they cannot be modified.
5
+ *
6
+ * @param {string} accessTokenKey - The name of the access token key.
7
+ * @param {string} refreshTokenKey - The name of the refresh token key.
8
+ *
9
+ * @returns {void} Does not return anything but freezes the token configuration object.
10
+ */
11
+ export declare function configTokenKeys(accessTokenKey: string, refreshTokenKey: string): void;
12
+ /**
13
+ * Retrieves the current token configuration.
14
+ *
15
+ * @returns {TokensConfig} The configuration of the access and refresh token keys.
16
+ */
17
+ export declare function getTokenConfig(): TokensConfig;
18
+ /**
19
+ * Sets the secret key for use in authentication.
20
+ *
21
+ * @param {string} key - The new secret key.
22
+ *
23
+ * @returns {void} Does not return anything, but updates the secret key.
24
+ */
25
+ export declare function setSecretKey(key: string): void;
26
+ /**
27
+ * Retrieves the current secret key.
28
+ *
29
+ * @returns {string} The configured secret key.
30
+ */
31
+ export declare function getSecretKey(): string;
package/dist/index.mjs CHANGED
@@ -3,6 +3,9 @@ import axios from 'axios';
3
3
  import { useRouter } from 'vue-router';
4
4
  import { useQuery } from '@tanstack/vue-query';
5
5
  import { ref, watch, onServerPrefetch, onMounted, computed } from 'vue';
6
+ import * as CryptoJS from 'crypto-js';
7
+ import { jwtDecode } from 'jwt-decode';
8
+ import { v4 } from 'uuid';
6
9
 
7
10
  /**
8
11
  * Creates and downloads a file from Blob data.
@@ -2385,7 +2388,7 @@ function inferErrorType(error) {
2385
2388
  }
2386
2389
 
2387
2390
  let secretKey = "12345678901234567890123456789012";
2388
- let tokenConfig = Object.freeze({
2391
+ let tokensConfig$1 = Object.freeze({
2389
2392
  ACCESS_TOKEN: "authToken",
2390
2393
  REFRESH_TOKEN: "refreshToken",
2391
2394
  });
@@ -2398,8 +2401,8 @@ let tokenConfig = Object.freeze({
2398
2401
  *
2399
2402
  * @returns {void} Does not return anything but freezes the token configuration object.
2400
2403
  */
2401
- function configTokens(accessTokenKey, refreshTokenKey) {
2402
- tokenConfig = Object.freeze({
2404
+ function configTokenKeys(accessTokenKey, refreshTokenKey) {
2405
+ tokensConfig$1 = Object.freeze({
2403
2406
  ACCESS_TOKEN: accessTokenKey,
2404
2407
  REFRESH_TOKEN: refreshTokenKey,
2405
2408
  });
@@ -2407,10 +2410,10 @@ function configTokens(accessTokenKey, refreshTokenKey) {
2407
2410
  /**
2408
2411
  * Retrieves the current token configuration.
2409
2412
  *
2410
- * @returns {TokenConfig} The configuration of the access and refresh token keys.
2413
+ * @returns {TokensConfig} The configuration of the access and refresh token keys.
2411
2414
  */
2412
2415
  function getTokenConfig() {
2413
- return tokenConfig;
2416
+ return tokensConfig$1;
2414
2417
  }
2415
2418
  /**
2416
2419
  * Sets the secret key for use in authentication.
@@ -2431,7 +2434,7 @@ function getSecretKey() {
2431
2434
  return secretKey;
2432
2435
  }
2433
2436
 
2434
- let endpointsConfig = {
2437
+ let endpointsConfig$1 = {
2435
2438
  LOGIN: "/login",
2436
2439
  REFRESH: "/refresh",
2437
2440
  LOGOUT: "/logout",
@@ -2447,7 +2450,7 @@ let endpointsConfig = {
2447
2450
  * @returns {void} Does not return anything but freezes the endpoint configuration object.
2448
2451
  */
2449
2452
  function configEndpoints(loginEndpoint, refreshEndpoint, logoutEndpoint) {
2450
- endpointsConfig = Object.freeze({
2453
+ endpointsConfig$1 = Object.freeze({
2451
2454
  LOGIN: loginEndpoint,
2452
2455
  REFRESH: refreshEndpoint,
2453
2456
  LOGOUT: logoutEndpoint,
@@ -2462,7 +2465,7 @@ function configEndpoints(loginEndpoint, refreshEndpoint, logoutEndpoint) {
2462
2465
  * @property {string} LOGOUT - URL of the logout endpoint.
2463
2466
  */
2464
2467
  function getEndpointsConfig() {
2465
- return endpointsConfig;
2468
+ return endpointsConfig$1;
2466
2469
  }
2467
2470
 
2468
2471
  /**
@@ -2591,13 +2594,13 @@ class AxiosService {
2591
2594
  }
2592
2595
  }
2593
2596
 
2594
- let axiosInstance;
2597
+ let axiosInstance$1;
2595
2598
  /**
2596
2599
  * Configures the global Axios instance with a base URL.
2597
2600
  * @param {string} baseURL - The base URL for the Axios instance.
2598
2601
  */
2599
2602
  const configAxios = (baseURL) => {
2600
- axiosInstance = new AxiosService(baseURL);
2603
+ axiosInstance$1 = new AxiosService(baseURL);
2601
2604
  };
2602
2605
  /**
2603
2606
  * Retrieves the configured Axios instance.
@@ -2605,10 +2608,10 @@ const configAxios = (baseURL) => {
2605
2608
  * @throws Will throw an error if the Axios instance is not configured.
2606
2609
  */
2607
2610
  const getAxiosInstance = () => {
2608
- if (!axiosInstance) {
2611
+ if (!axiosInstance$1) {
2609
2612
  throw new Error('Axios instance not configured. Call configureAxios first.');
2610
2613
  }
2611
- return axiosInstance.getAxiosInstance();
2614
+ return axiosInstance$1.getAxiosInstance();
2612
2615
  };
2613
2616
  /**
2614
2617
  * Creates a new AxiosService instance with custom headers.
@@ -2987,4 +2990,273 @@ function useSorter(items, criteriaList, selectedCriteria) {
2987
2990
  }).value;
2988
2991
  }
2989
2992
 
2990
- export { AppTypes, ArchiveTypes, AudioTypes, AxiosService, ContentTypeEnum, DocumentTypes, ERROR_MESSAGES, ERROR_STYLES, ErrorEnum, ErrorMessages, ErrorStyles, ExceptionEnum, FontTypes, ImageTypes, KeyCodeEnum, OtherTypes, RestStd, ScreenBreakpoint, ScreenSize, StorageKeyEnum, StorageTypeEnum, TextTypes, VideoTypes, addCustomKeyboardShortcut, addDays, addDoubleClickListener, addKeyListener, ageAtDate, axiosFetch, blobToFormData, bufferToBlob, calculateAge, clickOutside, compareObject, configAxios, configEndpoints, configTokens, copyToClipboard, countWords, createCustomAxiosInstance, createFetch, createKeyMap, customShortcut, daysBetween, daysToNextBirthday, debounce, debounceAsync, debounceAsyncValidator, debounceAsyncWithImmediate, debounceLeading, debounceLeadingTrailing, debounceTrailing, deepClone, deepEqual, deepMerge, detectKeyHold, disableCopy, disableF12Key, disableMouseButtons, disableRightClick, disableSpecificKeys, downloadBlob, enableMouseButtons, enableRightClick, enableSpecificKeys, exportToCSV, exportToExcel, exportToJSON, exportToText, exportToXML, filterObjectByKeys, flattenObject, formDataToObject, formatDate, generateRandomString, getAxiosInstance, getEndOfMonth, getEndpointsConfig, getObjectDifferences, getObjectKeys, getQueryParam, getSecretKey, getStartOfMonth, getTokenConfig, hasNestedProperties, isEmptyObject, isLeapYear, isStrongPassword, isValidAge, isValidCreditCard, isValidDate, isValidEmail, isValidExpiryDate, isValidHexColor, isValidHexColorAlpha, isValidHexNumber, isValidIP, isValidPhoneNumber, isValidSSN, isValidTime, isValidURL, isValidUsername, isValidZIP, lowerFirst, objectToFormData, objectToFormDataEnhanced, objectToQueryString, openWindow, parseDate, proxyToPlainObject, readFileAsDataURL, readFileAsText, registerKeyboardShortcuts, removeAccent, removeClickOutside, removeCustomKeyboardShortcut, removeCustomShortcuts, removeDoubleClickListener, removeEmptyProperties, removeKeyListeners, replaceAll, reverseString, safeGet, screenMap, scrollToTop, setSecretKey, simulateKeyPress, stopDetectingKeyHold, stringToBlob, subtractDays, throttle, toCamelCase, toKebabCase, toggleTabNavigation, truncateString, unregisterKeyboardShortcuts, upperFirst, useBreakpoint, useFilter, usePagination, useSorter, useVueQuery, validateAlphanumeric, validateLetters, validateNumbers };
2993
+ const axiosInstance = getAxiosInstance();
2994
+ const tokensConfig = getTokenConfig();
2995
+ const endpointsConfig = getEndpointsConfig();
2996
+ const config = {
2997
+ endpoints: endpointsConfig,
2998
+ storageKeys: tokensConfig,
2999
+ };
3000
+ /**
3001
+ * Configures authentication settings globally.
3002
+ * Allows modifying default endpoints and storage keys.
3003
+ *
3004
+ * @param {Object} options - Custom configuration options.
3005
+ * @param {Object} [options.endpoints] - Custom endpoints for login, refresh, and logout.
3006
+ * @param {Object} [options.storageKeys] - Custom storage keys for tokens.
3007
+ */
3008
+ function configureAuth(options) {
3009
+ if (options.endpoints) {
3010
+ config.endpoints = { ...config.endpoints, ...options.endpoints };
3011
+ }
3012
+ if (options.storageKeys) {
3013
+ config.storageKeys = { ...config.storageKeys, ...options.storageKeys };
3014
+ }
3015
+ }
3016
+ /**
3017
+ * Encrypts a value using AES encryption.
3018
+ *
3019
+ * @param {string} value - The value to encrypt.
3020
+ * @param {string} key - The encryption key.
3021
+ * @returns {string} The encrypted string.
3022
+ */
3023
+ const encrypt = (value, key) => {
3024
+ return CryptoJS.AES.encrypt(value, key).toString();
3025
+ };
3026
+ /**
3027
+ * Decrypts an AES encrypted value.
3028
+ *
3029
+ * @param {string} value - The encrypted value.
3030
+ * @param {string} key - The encryption key.
3031
+ * @returns {string} The decrypted string.
3032
+ */
3033
+ const decrypt = (value, key) => {
3034
+ const bytes = CryptoJS.AES.decrypt(value, key);
3035
+ return bytes.toString(CryptoJS.enc.Utf8);
3036
+ };
3037
+ /**
3038
+ * Stores an encrypted value in sessionStorage or localStorage.
3039
+ *
3040
+ * @param {string} key - Storage key.
3041
+ * @param {any} value - Value to store.
3042
+ * @param {string} secretKey - Encryption key.
3043
+ * @param {boolean} isRememberMe - Whether to store in localStorage.
3044
+ * @param {number} [attempt=0] - Retry attempt count.
3045
+ * @returns {Promise<void>}
3046
+ */
3047
+ const storeEncryptedItem = async (value, key, secretKey, isRememberMe, attempt = 0) => {
3048
+ const storage = isRememberMe ? localStorage : sessionStorage;
3049
+ if (typeof window !== "undefined" && storage) {
3050
+ try {
3051
+ storage.setItem(key, encrypt(value, secretKey));
3052
+ return;
3053
+ }
3054
+ catch (error) {
3055
+ handleError(error, false);
3056
+ if (attempt < 5) {
3057
+ await new Promise((resolve) => setTimeout(resolve, 100));
3058
+ return await storeEncryptedItem(key, value, secretKey, isRememberMe, attempt + 1);
3059
+ }
3060
+ throw new Error(`Storage not available for key ${key} after multiple attempts`);
3061
+ }
3062
+ }
3063
+ else {
3064
+ if (attempt < 5) {
3065
+ await new Promise((resolve) => setTimeout(resolve, 100));
3066
+ return await storeEncryptedItem(key, value, secretKey, isRememberMe, attempt + 1);
3067
+ }
3068
+ throw new Error(`Storage not available for key ${key} after multiple attempts`);
3069
+ }
3070
+ };
3071
+ /**
3072
+ * Retrieves and decrypts a stored value.
3073
+ *
3074
+ * @param {string} key - Storage key.
3075
+ * @param {string} secretKey - Decryption key.
3076
+ * @param {boolean} isRememberMe - Whether to retrieve from localStorage.
3077
+ * @returns {string|null} The decrypted value or null.
3078
+ */
3079
+ function getDecryptedValue(key, secretKey, isRememberMe) {
3080
+ const storage = sessionStorage;
3081
+ try {
3082
+ const value = storage.getItem(key);
3083
+ return value ? decrypt(value, secretKey) : null;
3084
+ }
3085
+ catch (error) {
3086
+ handleError(error, false);
3087
+ return null;
3088
+ }
3089
+ }
3090
+ /**
3091
+ * Provides authentication utilities.
3092
+ *
3093
+ * @param {string} [secretKey=getSecretKey()] - Encryption key.
3094
+ * @returns {Object} Auth composable methods and properties.
3095
+ */
3096
+ function useAuth(secretKey = getSecretKey()) {
3097
+ const jwt = computed(() => getDecryptedValue(config.storageKeys.ACCESS_TOKEN, secretKey));
3098
+ const refresh_token = computed(() => getDecryptedValue(config.storageKeys.REFRESH_TOKEN, secretKey));
3099
+ /**
3100
+ * Computes token expiration timestamp.
3101
+ */
3102
+ const tokenExpiry = computed(() => {
3103
+ if (!jwt.value)
3104
+ return null;
3105
+ try {
3106
+ const decoded = jwtDecode(jwt.value);
3107
+ return decoded.exp ? decoded.exp * 1000 : null;
3108
+ }
3109
+ catch (error) {
3110
+ handleError(error, false);
3111
+ return null;
3112
+ }
3113
+ });
3114
+ /**
3115
+ * Checks if the user is authenticated.
3116
+ */
3117
+ const isAuthenticated = computed(() => {
3118
+ if (!jwt.value || jwt.value.length === 0) {
3119
+ return false;
3120
+ }
3121
+ if (tokenExpiry.value === null) {
3122
+ return false;
3123
+ }
3124
+ return tokenExpiry.value > Date.now();
3125
+ });
3126
+ /**
3127
+ * Handles user login.
3128
+ */
3129
+ const login = async (params = {}, isRememberMe) => {
3130
+ try {
3131
+ const response = await axiosInstance.post(config.endpoints.LOGIN, params);
3132
+ await storeEncryptedItem(config.storageKeys.ACCESS_TOKEN, response.data.token, secretKey, isRememberMe);
3133
+ await storeEncryptedItem(config.storageKeys.REFRESH_TOKEN, response.data.refresh_token, secretKey, isRememberMe);
3134
+ return response;
3135
+ }
3136
+ catch (error) {
3137
+ handleError(error, false);
3138
+ throw error;
3139
+ }
3140
+ };
3141
+ /**
3142
+ * Refreshes authentication token.
3143
+ */
3144
+ const refresh = async () => {
3145
+ try {
3146
+ const response = await axiosInstance.post(config.endpoints.REFRESH, {});
3147
+ await storeEncryptedItem(config.storageKeys.ACCESS_TOKEN, response.data.token, secretKey, false);
3148
+ await storeEncryptedItem(config.storageKeys.REFRESH_TOKEN, response.data.refresh_token, secretKey, false);
3149
+ return response;
3150
+ }
3151
+ catch (error) {
3152
+ handleError(error, false);
3153
+ await logout();
3154
+ }
3155
+ };
3156
+ /**
3157
+ * Logs out the user.
3158
+ */
3159
+ const logout = async (params = {}) => {
3160
+ try {
3161
+ await axiosInstance.post(config.endpoints.LOGOUT, params);
3162
+ }
3163
+ catch (error) {
3164
+ handleError(error, false);
3165
+ }
3166
+ finally {
3167
+ await cleanStorage();
3168
+ location.reload();
3169
+ }
3170
+ };
3171
+ /**
3172
+ * Clears stored authentication data.
3173
+ */
3174
+ const cleanStorage = async () => {
3175
+ Object.keys(config.storageKeys).forEach(key => {
3176
+ sessionStorage.removeItem(config.storageKeys[key]);
3177
+ localStorage.removeItem(config.storageKeys[key]);
3178
+ });
3179
+ };
3180
+ /**
3181
+ * Verifies token validity.
3182
+ */
3183
+ const verifyToken = async () => {
3184
+ if (!jwt.value) {
3185
+ handleError('TOKEN_MISSING: No valid token found', true, '/auth-error', 'query');
3186
+ await cleanStorage();
3187
+ throw new Error('TOKEN_MISSING: No valid token found');
3188
+ }
3189
+ try {
3190
+ const decoded = jwtDecode(jwt.value);
3191
+ if (decoded.exp ? decoded.exp * 1000 < Date.now() : false) {
3192
+ handleError("TOKEN_EXPIRED", false);
3193
+ await refresh();
3194
+ }
3195
+ }
3196
+ catch (error) {
3197
+ let errorMessage = "TOKEN_INVALID: Token verification failed";
3198
+ if (error instanceof Error) {
3199
+ errorMessage = `${errorMessage} - ${error.message}`;
3200
+ }
3201
+ handleError(errorMessage, true, "/auth-error", "query");
3202
+ await cleanStorage();
3203
+ throw new Error(errorMessage);
3204
+ }
3205
+ };
3206
+ return {
3207
+ isAuthenticated,
3208
+ jwt,
3209
+ refresh_token,
3210
+ tokenExpiry,
3211
+ login,
3212
+ refresh,
3213
+ logout,
3214
+ cleanStorage,
3215
+ verifyToken
3216
+ };
3217
+ }
3218
+
3219
+ let sessionId = v4();
3220
+ let sessionConfig = Object.freeze({
3221
+ SESSION_ID: sessionId,
3222
+ });
3223
+ /**
3224
+ * Configures the session identifier for the active browser session.
3225
+ * Once configured, it cannot be modified.
3226
+ *
3227
+ * @param {string} sessionIdParam - The unique session identifier.
3228
+ *
3229
+ * @returns {void} Does not return anything, but freezes the session configuration.
3230
+ */
3231
+ function configSession(sessionIdParam) {
3232
+ sessionConfig = Object.freeze({
3233
+ SESSION_ID: sessionIdParam,
3234
+ });
3235
+ }
3236
+ /**
3237
+ * Retrieves the current session identifier configuration.
3238
+ *
3239
+ * @returns {string} The unique session identifier.
3240
+ */
3241
+ function getSessionConfig() {
3242
+ return sessionConfig.SESSION_ID;
3243
+ }
3244
+ /**
3245
+ * Generates a new UUID for the current session.
3246
+ *
3247
+ * @returns {void} Does not return anything, but updates the session identifier.
3248
+ */
3249
+ function regenerateSessionId() {
3250
+ sessionId = v4();
3251
+ configSession(sessionId);
3252
+ }
3253
+ /**
3254
+ * Retrieves the current session identifier.
3255
+ *
3256
+ * @returns {string} The unique session identifier.
3257
+ */
3258
+ function getSessionId() {
3259
+ return sessionId;
3260
+ }
3261
+
3262
+ export { AppTypes, ArchiveTypes, AudioTypes, AxiosService, ContentTypeEnum, DocumentTypes, ERROR_MESSAGES, ERROR_STYLES, ErrorEnum, ErrorMessages, ErrorStyles, ExceptionEnum, FontTypes, ImageTypes, KeyCodeEnum, OtherTypes, RestStd, ScreenBreakpoint, ScreenSize, StorageKeyEnum, StorageTypeEnum, TextTypes, VideoTypes, addCustomKeyboardShortcut, addDays, addDoubleClickListener, addKeyListener, ageAtDate, axiosFetch, blobToFormData, bufferToBlob, calculateAge, clickOutside, compareObject, configAxios, configEndpoints, configSession, configTokenKeys, configureAuth, copyToClipboard, countWords, createCustomAxiosInstance, createFetch, createKeyMap, customShortcut, daysBetween, daysToNextBirthday, debounce, debounceAsync, debounceAsyncValidator, debounceAsyncWithImmediate, debounceLeading, debounceLeadingTrailing, debounceTrailing, deepClone, deepEqual, deepMerge, detectKeyHold, disableCopy, disableF12Key, disableMouseButtons, disableRightClick, disableSpecificKeys, downloadBlob, enableMouseButtons, enableRightClick, enableSpecificKeys, exportToCSV, exportToExcel, exportToJSON, exportToText, exportToXML, filterObjectByKeys, flattenObject, formDataToObject, formatDate, generateRandomString, getAxiosInstance, getEndOfMonth, getEndpointsConfig, getObjectDifferences, getObjectKeys, getQueryParam, getSecretKey, getSessionConfig, getSessionId, getStartOfMonth, getTokenConfig, hasNestedProperties, isEmptyObject, isLeapYear, isStrongPassword, isValidAge, isValidCreditCard, isValidDate, isValidEmail, isValidExpiryDate, isValidHexColor, isValidHexColorAlpha, isValidHexNumber, isValidIP, isValidPhoneNumber, isValidSSN, isValidTime, isValidURL, isValidUsername, isValidZIP, lowerFirst, objectToFormData, objectToFormDataEnhanced, objectToQueryString, openWindow, parseDate, proxyToPlainObject, readFileAsDataURL, readFileAsText, regenerateSessionId, registerKeyboardShortcuts, removeAccent, removeClickOutside, removeCustomKeyboardShortcut, removeCustomShortcuts, removeDoubleClickListener, removeEmptyProperties, removeKeyListeners, replaceAll, reverseString, safeGet, screenMap, scrollToTop, setSecretKey, simulateKeyPress, stopDetectingKeyHold, stringToBlob, subtractDays, throttle, toCamelCase, toKebabCase, toggleTabNavigation, truncateString, unregisterKeyboardShortcuts, upperFirst, useAuth, useBreakpoint, useFilter, usePagination, useSorter, useVueQuery, validateAlphanumeric, validateLetters, validateNumbers };
@@ -1,5 +1,5 @@
1
- import { TokenConfig, EndpointsConfig } from "@/types";
1
+ import { TokensConfig, EndpointsConfig } from "@/types";
2
2
  export type AuthConfig = {
3
3
  endpoints: EndpointsConfig;
4
- storageKeys: TokenConfig;
4
+ storageKeys: TokensConfig;
5
5
  };
@@ -1,4 +1,4 @@
1
- export type TokenConfig = {
1
+ export type TokensConfig = {
2
2
  readonly ACCESS_TOKEN: string;
3
3
  readonly REFRESH_TOKEN: string;
4
4
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arex95/vue-core",
3
- "version": "1.1.10",
3
+ "version": "1.1.11",
4
4
  "description": "Opinionated Vue Core",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",