UNPKG

@trap_stevo/legendarybuilderproreact-ui

Version:

The legendary UI & utility API that makes your application a legendary application. ~ Created by Steven Compton

895 lines (882 loc) 37.8 kB
import _typeof from "@babel/runtime/helpers/typeof"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator"; import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } import _regeneratorRuntime from "@babel/runtime/regenerator"; /* Created by Hassan Steven Compton. March 7, 2024. */ import React, { createContext, useContext, useState, useEffect, useRef, useMemo, useCallback } from "react"; import { generateIdentityKey, getCryptoKey, encryptData, decryptData } from "../HUDManagers/HUDUniversalEncryptionUtilitiesManager.js"; import { UpdateObject } from "../HUDManagers/HUDUniversalHUDUtilityManager.js"; var AuthContext = /*#__PURE__*/createContext(); /** * AuthProvider provides user authentication encapsulation within an application; * keeping track of user credentials and user authenticated state. * * @component * * @param {boolean} [saveSessionCacheOnTimeout=false] - Determines whether to save session cache on timeout. * @param {number} [signedSessionTimeout=18000] - Session timeout in seconds. Default is 5 hours. * @param {number} [sessionCheckInterval=1000] - How often (in milliseconds) to check for session expiration. * @param {Array} [keysToClearOnTimeout=[]] - List of keys to clear from session cache on timeout. * @param {boolean} [autoSignIn=false] - Determines whether to automatically sign in the user if session data is found in localStorage. * @param {boolean} [useAbsoluteExpiration=false] - Whether to use absolute expiration timestamp instead of session duration. * @param {string} [signedUserExpirationKey=null] - Key in signedUser object for token-based absolute expiration (e.g. "expiresAt"). * @param {number} [sessionWarningThreshold=300] - Time (in seconds) to trigger onSessionTimeWarning. * @param {function} [onSessionTimeWarning] - Callback triggered when time left is under threshold. * * @param {boolean} [shouldExtendSessionOnActivity=true] - Automatically extend the session when user activity is detected. * @param {number} [sessionExtensionThreshold=300000] - Remaining time threshold (in ms) under which session auto-extension is triggered. * @param {number} [minExtendInterval=20000] - Minimum interval (in ms) between successive auto-extension attempts. * * @param {function} [onSessionExpire] - Callback triggered when the session fully expires. * @param {function} [onSessionRenew] - Callback triggered whenever the session is successfully renewed. * * @param {function} [onEncryptionError] - Callback for handling errors during encryption/decryption. * @param {function} [getExpiryTs] - Custom function to resolve session expiration timestamp dynamically. * @param {function} [extendSession] - Custom function to handle session extension logic. * * @param {boolean} [encryptAuthIdentity=false] - Enables persistent encryption of signed user identity. * @param {number} [identityDepth=100000] - PBKDF2 iteration depth for deriving crypto key. * @param {string} [identitySeed] - Optional passphrase for key derivation. * @param {string} [identityOffset] - Optional salt for key derivation. * * @param {React.ReactNode} children - The content wrapped by this component. * @returns {JSX.Element} The AuthProvider component encapsulating children with authentication context. */ export var AuthProvider = function AuthProvider(_ref) { var _ref$saveSessionCache = _ref.saveSessionCacheOnTimeout, saveSessionCacheOnTimeout = _ref$saveSessionCache === void 0 ? false : _ref$saveSessionCache, _ref$signedSessionTim = _ref.signedSessionTimeout, signedSessionTimeout = _ref$signedSessionTim === void 0 ? 18000 : _ref$signedSessionTim, _ref$sessionCheckInte = _ref.sessionCheckInterval, sessionCheckInterval = _ref$sessionCheckInte === void 0 ? 1000 : _ref$sessionCheckInte, _ref$keysToClearOnTim = _ref.keysToClearOnTimeout, keysToClearOnTimeout = _ref$keysToClearOnTim === void 0 ? [] : _ref$keysToClearOnTim, _ref$autoSignIn = _ref.autoSignIn, autoSignIn = _ref$autoSignIn === void 0 ? false : _ref$autoSignIn, _ref$useAbsoluteExpir = _ref.useAbsoluteExpiration, useAbsoluteExpiration = _ref$useAbsoluteExpir === void 0 ? false : _ref$useAbsoluteExpir, _ref$signedUserExpira = _ref.signedUserExpirationKey, signedUserExpirationKey = _ref$signedUserExpira === void 0 ? null : _ref$signedUserExpira, _ref$sessionWarningTh = _ref.sessionWarningThreshold, sessionWarningThreshold = _ref$sessionWarningTh === void 0 ? 300 : _ref$sessionWarningTh, _ref$shouldExtendSess = _ref.shouldExtendSessionOnActivity, shouldExtendSessionOnActivity = _ref$shouldExtendSess === void 0 ? true : _ref$shouldExtendSess, _ref$sessionExtension = _ref.sessionExtensionThreshold, sessionExtensionThreshold = _ref$sessionExtension === void 0 ? 5 * 60 * 1000 : _ref$sessionExtension, _ref$minExtendInterva = _ref.minExtendInterval, minExtendInterval = _ref$minExtendInterva === void 0 ? 20 * 1000 : _ref$minExtendInterva, _ref$onSessionTimeWar = _ref.onSessionTimeWarning, onSessionTimeWarning = _ref$onSessionTimeWar === void 0 ? null : _ref$onSessionTimeWar, _ref$onSessionExpire = _ref.onSessionExpire, onSessionExpire = _ref$onSessionExpire === void 0 ? null : _ref$onSessionExpire, _ref$onSessionRenew = _ref.onSessionRenew, onSessionRenew = _ref$onSessionRenew === void 0 ? null : _ref$onSessionRenew, _ref$onEncryptionErro = _ref.onEncryptionError, onEncryptionError = _ref$onEncryptionErro === void 0 ? null : _ref$onEncryptionErro, _ref$getExpiryTs = _ref.getExpiryTs, getExpiryTs = _ref$getExpiryTs === void 0 ? null : _ref$getExpiryTs, _ref$extendSession = _ref.extendSession, extendSession = _ref$extendSession === void 0 ? null : _ref$extendSession, _ref$encryptAuthIdent = _ref.encryptAuthIdentity, encryptAuthIdentity = _ref$encryptAuthIdent === void 0 ? false : _ref$encryptAuthIdent, _ref$identityDepth = _ref.identityDepth, identityDepth = _ref$identityDepth === void 0 ? 100000 : _ref$identityDepth, identitySeed = _ref.identitySeed, identityOffset = _ref.identityOffset, children = _ref.children; var resolvedSeed = useMemo(function () { if (identitySeed) { return identitySeed; } var existing = localStorage.getItem("_session_identity_seed"); if (existing) { return existing; } var key = generateIdentityKey(); localStorage.setItem("_session_identity_seed", key); return key; }, [identitySeed]); var resolvedOffset = useMemo(function () { if (identityOffset) { return identityOffset; } var existing = localStorage.getItem("_session_identity_offset"); if (existing) { return existing; } var key = generateIdentityKey(); localStorage.setItem("_session_identity_offset", key); return key; }, [identityOffset]); /** * Initializes the current signed state from cache. * * @function * @name currentSignedState * @returns {Object} The current signed user and signed-in status. */ var currentSignedState = useCallback(function () { var savedUser = localStorage.getItem("SignedUserCredential"); var userSignedIn = localStorage.getItem("UserSignedIn"); return { currentSignedUser: savedUser, currentSignedIn: userSignedIn ? JSON.parse(userSignedIn) : false }; }, []); var _useState = useState(shouldExtendSessionOnActivity), _useState2 = _slicedToArray(_useState, 2), autoExtendOnActivity = _useState2[0], setAutoExtendOnActivity = _useState2[1]; /** * Responsible for the user's credentials. * * @type {Object} */ var _useState3 = useState({}), _useState4 = _slicedToArray(_useState3, 2), signedUser = _useState4[0], setSignedUser = _useState4[1]; /** * Allows for checking the user's authentication state. * * @type {boolean} */ var _useState5 = useState(function () { return currentSignedState().currentSignedIn; }), _useState6 = _slicedToArray(_useState5, 2), signedIn = _useState6[0], setSignedIn = _useState6[1]; var extendFnRef = useRef(extendSession || null); var getExpiryRef = useRef(getExpiryTs || null); var sessionRenewalEnabledRef = useRef(true); var sessionInitialized = useRef(false); var lastExtendAtRef = useRef(0); /** * Synchronizes the current state to the cache. * * @function * @name syncStateToCache * @param {Object} user - The user's credentials. * @param {boolean} signedIn - The user's signed-in status. */ var syncStateToCache = useCallback( /*#__PURE__*/function () { var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(user, signedIn) { var now, encrypted, expiresAt; return _regeneratorRuntime.wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: now = Date.now(); if (!(encryptAuthIdentity && resolvedSeed && resolvedOffset)) { _context.next = 14; break; } _context.prev = 2; _context.next = 5; return encryptData(user, resolvedSeed, resolvedOffset, identityDepth); case 5: encrypted = _context.sent; localStorage.setItem("SignedUserCredential", encrypted); _context.next = 12; break; case 9: _context.prev = 9; _context.t0 = _context["catch"](2); if (onEncryptionError) { onEncryptionError(_context.t0); } case 12: _context.next = 15; break; case 14: localStorage.setItem("SignedUserCredential", JSON.stringify(user)); case 15: localStorage.setItem("UserSignedIn", JSON.stringify(signedIn)); localStorage.setItem("SignedSessionStart", now.toString()); localStorage.setItem("SignedSessionTimeout", signedSessionTimeout.toString()); if (!useAbsoluteExpiration) { _context.next = 22; break; } expiresAt = now + signedSessionTimeout * 1000; localStorage.setItem("SignedSessionExpiresAt", expiresAt.toString()); return _context.abrupt("return"); case 22: if (!localStorage.getItem("SignedSessionStart")) { localStorage.setItem("SignedSessionStart", now.toString()); } case 23: case "end": return _context.stop(); } }, _callee, null, [[2, 9]]); })); return function (_x, _x2) { return _ref2.apply(this, arguments); }; }(), [encryptAuthIdentity, onEncryptionError, resolvedSeed, resolvedOffset, identityDepth, signedSessionTimeout, useAbsoluteExpiration]); /** * Signs in user. * * @function * @name signIn * @description Sets the user's authentication state to true. */ var signIn = useCallback(function () { setSignedIn(true); }, []); /** * Signs out the user and manages session cache. * * @function * @name signOut * @param {boolean} [saveSessionCache=false] - Whether to preserve the entire session cache. * @param {string[]} [preserveKeys=["AuthenticatedOnWebApp"]] - Keys to keep when clearing the cache. * @param {string[]} [keysToClear=[]] - Specific keys to remove from the cache. * @param {Object} [options={}] - Optional configuration for cache handling and callbacks. * @returns {Object} Result object containing: * @returns {boolean} result.ok - Indicates success. * @returns {string} result.reason - Reason or status message. * @returns {string[]} result.preservedKeys - Keys that were preserved. * @returns {string[]} result.clearedKeys - Keys that were cleared. * @returns {Object|null} result.cacheBefore - Cache snapshot before sign-out. * @returns {Object|null} result.cacheAfter - Cache snapshot after sign-out. */ var signOut = useCallback(function () { var saveSessionCache = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; var keysToClear = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; var preserveKeys = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; var _ref3 = options || {}, clearFromSessionCache = _ref3.clearFromSessionCache, updateSessionCache = _ref3.updateSessionCache, clearSessionCache = _ref3.clearSessionCache, getSessionCache = _ref3.getSessionCache, _ref3$storageKey = _ref3.storageKey, storageKey = _ref3$storageKey === void 0 ? "HUDSessionCache" : _ref3$storageKey, onAfterClear = _ref3.onAfterClear, onError = _ref3.onError; var result = { ok: true, reason: "ok", preservedKeys: [], clearedKeys: [], cacheBefore: null, cacheAfter: null }; var windowAllowed = typeof window !== "undefined" && typeof window.localStorage !== "undefined"; var safeCall = function safeCall(fn) { var fallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; try { return fn(); } catch (error) { if (typeof onError === "function") { try { onError(error); } catch (_unused) {} } return fallback; } }; var readLocal = function readLocal() { return safeCall(function () { if (!windowAllowed) { return {}; } var raw = window.localStorage.getItem(storageKey); if (!raw) { return {}; } try { return JSON.parse(raw) || {}; } catch (_unused2) { return {}; } }, {}); }; var writeLocal = function writeLocal(obj) { return safeCall(function () { if (!windowAllowed) { return; } if (!obj || Object.keys(obj).length === 0) { window.localStorage.removeItem(storageKey); return; } window.localStorage.setItem(storageKey, JSON.stringify(obj)); }); }; var removeLocal = function removeLocal() { return safeCall(function () { if (!windowAllowed) { return; } window.localStorage.removeItem(storageKey); }); }; var removeKey = function removeKey(key) { return safeCall(function () { if (!windowAllowed) { return; } window.localStorage.removeItem(key); }); }; var normArray = function normArray(arr) { return Array.isArray(arr) ? Array.from(new Set(arr.filter(function (k) { return typeof k === "string" && k.length > 0; }))) : []; }; var clearList = normArray(keysToClear); var preserveList = normArray(preserveKeys); setSignedIn(false); setSignedUser({}); removeKey("SignedUserCredential"); removeKey("UserSignedIn"); removeKey("SignedSessionStart"); removeKey("SignedSessionExpiresAt"); removeKey("SignedSessionTimeout"); if (saveSessionCache === true) { return result; } var cacheBefore = typeof getSessionCache === "function" ? safeCall(function () { return getSessionCache(); }) || {} : readLocal(); result.cacheBefore = cacheBefore ? JSON.parse(JSON.stringify(cacheBefore)) : {}; if (clearList.length > 0) { if (typeof clearFromSessionCache === "function") { safeCall(function () { return clearFromSessionCache(clearList); }); } else { var cache = _objectSpread({}, cacheBefore || {}); var _iterator = _createForOfIteratorHelper(clearList), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var k = _step.value; if (k in cache) { delete cache[k]; result.clearedKeys.push(k); } } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } if (typeof updateSessionCache === "function") { safeCall(function () { return updateSessionCache(cache); }); } else { writeLocal(cache); } } var _after = typeof getSessionCache === "function" ? safeCall(function () { return getSessionCache(); }) || {} : readLocal(); result.cacheAfter = _after ? JSON.parse(JSON.stringify(_after)) : {}; result.preservedKeys = Object.keys(result.cacheAfter); if (typeof onAfterClear === "function") { safeCall(function () { return onAfterClear(result); }); } return result; } var preserved = {}; for (var _i = 0, _Object$keys = Object.keys(cacheBefore || {}); _i < _Object$keys.length; _i++) { var _k = _Object$keys[_i]; if (preserveList.includes(_k)) { preserved[_k] = cacheBefore[_k]; result.preservedKeys.push(_k); } else { result.clearedKeys.push(_k); } } if (typeof clearSessionCache === "function" && preserveList.length === 0) { safeCall(function () { return clearSessionCache(); }); } else { if (typeof updateSessionCache === "function") { safeCall(function () { return updateSessionCache(preserved); }); } else { if (Object.keys(preserved).length === 0) { removeLocal(); } else { writeLocal(preserved); } } } var after = typeof getSessionCache === "function" ? safeCall(function () { return getSessionCache(); }) || {} : readLocal(); result.cacheAfter = after ? JSON.parse(JSON.stringify(after)) : {}; if (typeof onAfterClear === "function") { safeCall(function () { return onAfterClear(result); }); } return result; }, []); var computeExpiryTs = useCallback(function () { var ctx = { signedUser: signedUser, signedIn: signedIn, localStorage: localStorage, useAbsoluteExpiration: useAbsoluteExpiration, signedSessionTimeout: signedSessionTimeout, signedUserExpirationKey: signedUserExpirationKey }; if (typeof getExpiryRef.current === "function") { var ts = getExpiryRef.current(ctx); if (typeof ts === "number" && !Number.isNaN(ts)) { return ts; } } if (signedUserExpirationKey && signedUser !== null && signedUser !== void 0 && signedUser[signedUserExpirationKey]) { var raw = signedUser[signedUserExpirationKey]; var asNum = typeof raw === "number" ? raw : parseInt(raw, 10); if (!Number.isNaN(asNum)) { return asNum; } var asDate = new Date(raw).getTime(); if (!Number.isNaN(asDate)) { return asDate; } } if (useAbsoluteExpiration) { var stored = parseInt(localStorage.getItem("SignedSessionExpiresAt"), 10); if (!Number.isNaN(stored)) { return stored; } } else { var start = parseInt(localStorage.getItem("SignedSessionStart"), 10); var timeout = parseInt(localStorage.getItem("SignedSessionTimeout"), 10) || signedSessionTimeout; if (!Number.isNaN(start)) { return start + timeout * 1000; } } return null; }, [signedUser, signedIn, useAbsoluteExpiration, signedSessionTimeout, signedUserExpirationKey]); /** * Checks if the user authentication session timed out. * * @function * @name checkSignedSessionTimeout */ var checkSignedSessionTimeout = useCallback(function () { var now = Date.now(); var expiresAt = computeExpiryTs(); if (expiresAt) { var timeLeft = Math.max(0, Math.floor((expiresAt - now) / 1000)); if (timeLeft <= 0) { signOut(saveSessionCacheOnTimeout, keysToClearOnTimeout); if (onSessionExpire) { onSessionExpire(); } } else if (onSessionTimeWarning && timeLeft <= sessionWarningThreshold) { onSessionTimeWarning(timeLeft); } } }, [computeExpiryTs, signOut, saveSessionCacheOnTimeout, keysToClearOnTimeout, onSessionTimeWarning, sessionWarningThreshold, onSessionExpire]); var shouldExtendNow = useCallback(function () { if (!signedIn) { return false; } var expiry = computeExpiryTs(); if (!expiry) { return false; } return expiry - Date.now() <= sessionExtensionThreshold; }, [signedIn, computeExpiryTs, sessionExtensionThreshold]); var requestSessionExtend = useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() { var reason, now, ctx, maybeNewTs, _args2 = arguments; return _regeneratorRuntime.wrap(function _callee2$(_context2) { while (1) switch (_context2.prev = _context2.next) { case 0: reason = _args2.length > 0 && _args2[0] !== undefined ? _args2[0] : "manual|activity"; if (sessionRenewalEnabledRef.current) { _context2.next = 3; break; } return _context2.abrupt("return"); case 3: now = Date.now(); if (!(now - lastExtendAtRef.current < minExtendInterval)) { _context2.next = 6; break; } return _context2.abrupt("return"); case 6: lastExtendAtRef.current = now; if (!(typeof extendFnRef.current !== "function")) { _context2.next = 9; break; } return _context2.abrupt("return"); case 9: ctx = { reason: reason, signedUser: signedUser, signedIn: signedIn, localStorage: localStorage, previousExpiryTs: computeExpiryTs(), useAbsoluteExpiration: useAbsoluteExpiration }; _context2.prev = 10; _context2.next = 13; return extendFnRef.current(ctx); case 13: maybeNewTs = _context2.sent; if (typeof maybeNewTs === "number" && !Number.isNaN(maybeNewTs) && useAbsoluteExpiration) { localStorage.setItem("SignedSessionExpiresAt", String(maybeNewTs)); } if (onSessionRenew) { onSessionRenew(typeof maybeNewTs === "number" ? maybeNewTs : null); } _context2.next = 20; break; case 18: _context2.prev = 18; _context2.t0 = _context2["catch"](10); case 20: case "end": return _context2.stop(); } }, _callee2, null, [[10, 18]]); })), [computeExpiryTs, signedUser, signedIn, useAbsoluteExpiration, minExtendInterval, onSessionRenew]); var activityHandler = useCallback(function () { if (shouldExtendNow()) { requestSessionExtend("activity"); } }, [shouldExtendNow, requestSessionExtend]); var relativeSessionExtend = useCallback(function (_ref5) { var useAbsoluteExpiration = _ref5.useAbsoluteExpiration, localStorage = _ref5.localStorage; if (useAbsoluteExpiration) { return; } var now = Date.now(); var timeoutSec = parseInt(localStorage.getItem("SignedSessionTimeout"), 10) || signedSessionTimeout; localStorage.setItem("SignedSessionStart", String(now)); return now + timeoutSec * 1000; }, [useAbsoluteExpiration, signedSessionTimeout]); var updateSignedUser = useCallback( /*#__PURE__*/function () { var _ref6 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(updater) { var _ref7, _ref7$persist, persist, _ref7$extend, extend, _ref7$extendReason, extendReason, next, _args3 = arguments; return _regeneratorRuntime.wrap(function _callee3$(_context3) { while (1) switch (_context3.prev = _context3.next) { case 0: _ref7 = _args3.length > 1 && _args3[1] !== undefined ? _args3[1] : {}, _ref7$persist = _ref7.persist, persist = _ref7$persist === void 0 ? true : _ref7$persist, _ref7$extend = _ref7.extend, extend = _ref7$extend === void 0 ? false : _ref7$extend, _ref7$extendReason = _ref7.extendReason, extendReason = _ref7$extendReason === void 0 ? "manual|credential-update" : _ref7$extendReason; next = typeof updater === "function" ? updater(signedUser) : updater; setSignedUser(next); if (!(persist && signedIn)) { _context3.next = 6; break; } _context3.next = 6; return syncStateToCache(next, true); case 6: if (extend) { requestSessionExtend(extendReason); } return _context3.abrupt("return", next); case 8: case "end": return _context3.stop(); } }, _callee3); })); return function (_x3) { return _ref6.apply(this, arguments); }; }(), [signedUser, signedIn, syncStateToCache, requestSessionExtend]); var updateSignedUserProperty = useCallback( /*#__PURE__*/function () { var _ref8 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4(path, value, options) { return _regeneratorRuntime.wrap(function _callee4$(_context4) { while (1) switch (_context4.prev = _context4.next) { case 0: return _context4.abrupt("return", updateSignedUser(function (prev) { return UpdateObject(prev, path, value); }, options)); case 1: case "end": return _context4.stop(); } }, _callee4); })); return function (_x4, _x5, _x6) { return _ref8.apply(this, arguments); }; }(), [updateSignedUser]); useEffect(function () { extendFnRef.current = extendSession || relativeSessionExtend; }, [extendSession, relativeSessionExtend]); useEffect(function () { getExpiryRef.current = getExpiryTs || null; }, [getExpiryTs]); useEffect(function () { if (!signedIn || useAbsoluteExpiration) { return; } var timeout = parseInt(localStorage.getItem("SignedSessionTimeout"), 10); var start = parseInt(localStorage.getItem("SignedSessionStart"), 10); if (Number.isNaN(start) || Number.isNaN(timeout)) { var now = Date.now(); localStorage.setItem("SignedSessionTimeout", String(signedSessionTimeout)); localStorage.setItem("SignedSessionStart", String(now)); } }, [signedIn, useAbsoluteExpiration, signedSessionTimeout]); useEffect(function () { if (!autoExtendOnActivity) { return; } var events = ["mousemove", "keydown", "click", "scroll"]; events.forEach(function (e) { return window.addEventListener(e, activityHandler); }); return function () { return events.forEach(function (e) { return window.removeEventListener(e, activityHandler); }); }; }, [autoExtendOnActivity, activityHandler]); useEffect(function () { if (!autoSignIn) { return; } var _currentSignedState = currentSignedState(), currentSignedUser = _currentSignedState.currentSignedUser, currentSignedIn = _currentSignedState.currentSignedIn; _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee5() { var parsed; return _regeneratorRuntime.wrap(function _callee5$(_context5) { while (1) switch (_context5.prev = _context5.next) { case 0: _context5.prev = 0; if (!encryptAuthIdentity) { _context5.next = 7; break; } _context5.next = 4; return decryptData(currentSignedUser, resolvedSeed, resolvedOffset, identityDepth); case 4: _context5.t0 = _context5.sent; _context5.next = 8; break; case 7: _context5.t0 = JSON.parse(currentSignedUser); case 8: parsed = _context5.t0; if (parsed && _typeof(parsed) === "object") { setSignedUser(parsed); setSignedIn(currentSignedIn); sessionInitialized.current = true; } _context5.next = 17; break; case 12: _context5.prev = 12; _context5.t1 = _context5["catch"](0); setSignedUser({}); setSignedIn(false); sessionInitialized.current = false; case 17: case "end": return _context5.stop(); } }, _callee5, null, [[0, 12]]); }))(); }, [autoSignIn, encryptAuthIdentity, resolvedSeed, resolvedOffset, identityDepth]); useEffect(function () { if (sessionInitialized.current) { return; } if (signedIn && signedUser && Object.keys(signedUser).length > 0) { syncStateToCache(signedUser, true); } }, [signedIn, signedUser, syncStateToCache]); useEffect(function () { checkSignedSessionTimeout(); var interval = setInterval(checkSignedSessionTimeout, sessionCheckInterval); return function () { return clearInterval(interval); }; }, [signedIn, checkSignedSessionTimeout, sessionCheckInterval]); return /*#__PURE__*/React.createElement(AuthContext.Provider, { value: { setAutoExtendSessionOnActivity: function setAutoExtendSessionOnActivity(v) { setAutoExtendOnActivity(!!v); }, setGetSessionExpiry: function setGetSessionExpiry(fn) { getExpiryRef.current = fn; }, setExtendSession: function setExtendSession(fn) { extendFnRef.current = fn; }, setSessionRenewal: function setSessionRenewal() { var enabled = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; sessionRenewalEnabledRef.current = !!enabled; }, requestSessionExtend: requestSessionExtend, updateSignedUserProperty: updateSignedUserProperty, updateSignedUser: updateSignedUser, signedUser: signedUser, setSignedUser: setSignedUser, signedIn: signedIn, signIn: signIn, signOut: signOut } }, children); }; /** * Allows access to the signed user's credentials and provides functions to checking the user's authentication state to signing a user out. * This component allows access to signedUser, setSignedUser, signedIn, signIn, signOut. * * @hook * @returns {Object} The authentication context including user state and auth functions. * @example * const { signedUser, signedIn, signIn, signOut } = useAuth(); */ export var useAuth = function useAuth() { var context = useContext(AuthContext); if (!context) { throw new Error("Must use within an AuthProvider"); } return context; }; /** * useAuthSessionMonitor provides real-time monitoring of the current session. * * @hook * @param {Object} options * @param {number} [sessionTimeout] - Override session timeout in seconds. If not provided, uses AuthProvider fallback. * @param {boolean} [useAbsoluteExpiration=false] - Whether to use localStorage "SignedSessionExpiresAt". * @param {string|null} [signedUserExpirationKey=null] - Key from signedUser object for expiration. * @param {function} [onExpire] - Called once when session expires. * @param {function} [onTimeUpdate] - Called on each timeLeft update. * @param {function} [onWarning] - Called once when timeLeft drops below threshold. * @param {number} [warningThreshold=300] - Seconds before expiration to trigger onWarning. * @returns {{ timeLeft: number, expiresAt: number|null, expired: boolean }} */ export function useAuthSessionMonitor() { var _ref10 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, sessionTimeout = _ref10.sessionTimeout, _ref10$useAbsoluteExp = _ref10.useAbsoluteExpiration, useAbsoluteExpiration = _ref10$useAbsoluteExp === void 0 ? false : _ref10$useAbsoluteExp, _ref10$signedUserExpi = _ref10.signedUserExpirationKey, signedUserExpirationKey = _ref10$signedUserExpi === void 0 ? null : _ref10$signedUserExpi, onExpire = _ref10.onExpire, onTimeUpdate = _ref10.onTimeUpdate, onWarning = _ref10.onWarning, _ref10$warningThresho = _ref10.warningThreshold, warningThreshold = _ref10$warningThresho === void 0 ? 300 : _ref10$warningThresho; var _useAuth = useAuth(), signedUser = _useAuth.signedUser, signedIn = _useAuth.signedIn; var _useState7 = useState(null), _useState8 = _slicedToArray(_useState7, 2), timeLeft = _useState8[0], setTimeLeft = _useState8[1]; var _useState9 = useState(null), _useState10 = _slicedToArray(_useState9, 2), expiresAt = _useState10[0], setExpiresAt = _useState10[1]; var _useState11 = useState(false), _useState12 = _slicedToArray(_useState11, 2), warned = _useState12[0], setWarned = _useState12[1]; var _useState13 = useState(false), _useState14 = _slicedToArray(_useState13, 2), expired = _useState14[0], setExpired = _useState14[1]; useEffect(function () { var interval = setInterval(function () { if (!signedIn) { setTimeLeft(null); setExpiresAt(null); setWarned(false); setExpired(false); return; } var now = Date.now(); var resolvedExpiresAt = null; if (signedUserExpirationKey && signedUser !== null && signedUser !== void 0 && signedUser[signedUserExpirationKey]) { resolvedExpiresAt = parseInt(signedUser[signedUserExpirationKey], 10); } else if (useAbsoluteExpiration) { var stored = localStorage.getItem("SignedSessionExpiresAt"); if (stored) { resolvedExpiresAt = parseInt(stored, 10); } } else { var _ref11; var start = parseInt(localStorage.getItem("SignedSessionStart"), 10); var timeout = (_ref11 = sessionTimeout !== null && sessionTimeout !== void 0 ? sessionTimeout : parseInt(localStorage.getItem("SignedSessionTimeout"), 10)) !== null && _ref11 !== void 0 ? _ref11 : 18000; if (!isNaN(start)) { resolvedExpiresAt = start + timeout * 1000; } } if (resolvedExpiresAt) { var left = Math.max(0, Math.floor((resolvedExpiresAt - now) / 1000)); setTimeLeft(left); setExpiresAt(resolvedExpiresAt); if (typeof onTimeUpdate === "function") { onTimeUpdate(left); } if (left <= 0 && !expired) { setExpired(true); if (typeof onExpire === "function") { onExpire(); } } if (left <= warningThreshold && !warned) { setWarned(true); if (typeof onWarning === "function") { onWarning(left); } } if (left > warningThreshold) { setWarned(false); } } else { setTimeLeft(null); setExpiresAt(null); } }, 1000); return function () { return clearInterval(interval); }; }, [signedUser, signedIn, sessionTimeout, signedUserExpirationKey, useAbsoluteExpiration, onExpire, onTimeUpdate, onWarning, warningThreshold, warned, expired]); return { timeLeft: timeLeft, expiresAt: expiresAt, expired: typeof timeLeft === "number" ? timeLeft <= 0 : false }; } ;