From 9687fe0c9005857c3c0c5df3497bfb8f173ca605 Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Thu, 1 May 2025 17:09:06 -0400 Subject: [PATCH] Improvements to access type and sign in and out process. --- src/lib/ae_stores.ts | 17 ++-- src/lib/element_access_type.svelte | 113 ++++++++++++++++++----- src/lib/element_sign_in_out.svelte | 32 ++++++- src/routes/+layout.svelte | 138 +++++++++++++++++++++-------- 4 files changed, 232 insertions(+), 68 deletions(-) diff --git a/src/lib/ae_stores.ts b/src/lib/ae_stores.ts index 6f5660c0..4040dbb9 100644 --- a/src/lib/ae_stores.ts +++ b/src/lib/ae_stores.ts @@ -97,14 +97,15 @@ const ae_app_local_data_defaults: key_val = { // 'trusted_passcode': '19111', // 'authenticated_passcode': 'auth2024', - 'access_type': 'anonymous', - 'administrator_access': false, - 'trusted_access': false, - 'public_access': false, - 'authenticated_access': false, - 'anonymous_access': true, + access_type: 'anonymous', + administrator_access: false, + trusted_access: false, + public_access: false, + authenticated_access: false, + anonymous_access: true, - 'user_email': null, // Currently used with Sponsorships only? + user_email: null, // Currently used with Sponsorships only? + user_access_type: null, // Used to revert back to the user's access type after quick access (temporarily escalate permissions) turned off. // Added 2025-04-04 person_id: null, // The current person_id of the logged-in user (if any) @@ -135,8 +136,10 @@ const ae_app_local_data_defaults: key_val = { super: false, // Is the user a super user manager: false, // Is the user a global manager (can manage accounts and users) administrator: false, // Is the user an account administrator + verified: false, // Is the user verified public: false, // Is the user a public user (can view public content) person_id: null, // The person ID of the logged-in user + access_type: null, // The access type of the logged-in user }, 'qry__enabled': 'enabled', // all, disabled, enabled diff --git a/src/lib/element_access_type.svelte b/src/lib/element_access_type.svelte index 3c29b280..e951c1f5 100644 --- a/src/lib/element_access_type.svelte +++ b/src/lib/element_access_type.svelte @@ -6,6 +6,10 @@ import { afterNavigate } from '$app/navigation'; // *** Import other supporting libraries // import { liveQuery } from "dexie"; +import { + ShieldEllipsis, ShieldMinus, ShieldPlus, ShieldUser, + User, UserCheck + } from '@lucide/svelte'; // *** Import Aether specific variables and functions import { ae_util } from '$lib/ae_utils/ae_utils'; @@ -183,13 +187,18 @@ function handle_check_access_type_passcode() { $ae_loc.access_type = 'authenticated'; } else { - console.log('Passcode does not match'); + if (log_lvl > 1) { + console.log('Entered passcode does not match any of the site access codes.'); + } - window.localStorage.setItem('access_type', 'anonymous'); + if ($ae_loc.access_type != 'anonymous') { + console.log('Access type is not anonymous'); + } + // window.localStorage.setItem('access_type', 'anonymous'); - $ae_loc.access_type = 'anonymous'; + // $ae_loc.access_type = 'anonymous'; - trigger = 'process_permission_check'; + // trigger = 'process_permission_check'; // $ae_loc = $ae_loc; // Trigger Svelte just in case // ae_loc.set($ae_loc); @@ -241,11 +250,12 @@ function handle_clear_access() { window.localStorage.setItem('access_type', 'anonymous'); // $ae_loc.access_type = null; // 'anonymous'; - $ae_loc.access_type = 'anonymous'; + // Revert back to the user's access type after quick access (temporarily escalate permissions) is turned off. + $ae_loc.access_type = $ae_loc.user_access_type ?? 'anonymous'; trigger = 'process_permission_check'; entered_passcode = ''; // Clear the entered passcode - show_passcode_input = false; + show_passcode_input = true; $ae_loc.app_cfg.show_element__menu = false; $ae_loc.app_cfg.show_element__menu_btn = true; @@ -382,9 +392,36 @@ function handle_clear_access() { {/if} -
- {#if $ae_loc.access_type && $ae_loc.access_type != 'anonymous'} - +
+ + {#if $ae_loc?.access_type && $ae_loc?.access_type == 'anonymous' && 1==3} + + + + {/if} + + {#if ($ae_loc?.access_type && $ae_loc?.access_type != 'anonymous')} + + + - - {:else} + {#if $ae_loc?.user_access_type && $ae_loc?.access_type == $ae_loc?.user_access_type && !show_passcode_input} + + {:else if (!show_passcode_input)} + + {/if} + + {/if} + + {#if (show_passcode_input)} + + + Passcode? + + {/if} +
diff --git a/src/lib/element_sign_in_out.svelte b/src/lib/element_sign_in_out.svelte index fd680801..82a33216 100644 --- a/src/lib/element_sign_in_out.svelte +++ b/src/lib/element_sign_in_out.svelte @@ -2,7 +2,7 @@ // *** Import Svelte specific import { browser } from '$app/environment'; -import { goto } from '$app/navigation'; +import { goto, invalidateAll } from '$app/navigation'; import { Modal } from 'flowbite-svelte'; // *** Import other supporting libraries @@ -90,6 +90,7 @@ function sign_in() { } else { $ae_loc.access_type = 'authenticated'; } + $ae_loc.user_access_type = $ae_loc.access_type; // Used to revert back to the user's access type after quick access (temporarily escalate permissions) is turned off. let access_checks_results = ae_util.process_permission_checks($ae_loc.access_type); // WARNING: I think this is causing a loop in Svelte or something. @@ -138,6 +139,35 @@ function sign_out() { // $ae_sess.auth__entered_username = null; // Keeping the username $ae_sess.auth__entered_password = null; + indexedDB.deleteDatabase('ae_archives_db'); // Archives module + indexedDB.deleteDatabase('ae_core_db'); + indexedDB.deleteDatabase('ae_events_db'); // Events module + indexedDB.deleteDatabase('ae_journals_db'); // Journals module + indexedDB.deleteDatabase('ae_posts_db'); // Posts module + indexedDB.deleteDatabase('ae_sponsorships_db'); // Sponsorships module + + // $ae_loc.allow_access = false; + $ae_loc.authenticated_access = false; + $ae_loc.edit_mode = false; + + localStorage.clear(); + sessionStorage.clear(); + + console.log('Remove the sign out fields from the URL.'); + data.url.searchParams.delete('user_id'); + data.url.searchParams.delete('user_key'); + data.url.searchParams.delete('username'); + data.url.searchParams.delete('user_email'); + data.url.searchParams.delete('valid_email'); // Part of sign in email for possible future use + + let new_url = data.url.toString(); + + // We need to set browser history and force all load functions to rerun. + // goto(new_url, {replaceState: true, invalidateAll: true}); + + // invalidateAll(); + window.location.reload(); + console.log('Signed out successfully.'); } diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 86586aa6..4fae9d0f 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -32,7 +32,7 @@ import { LogIn, LogOut, LockKeyhole, Mail, MailCheck, Menu, - ShieldUser, + ShieldEllipsis, ShieldMinus, ShieldPlus, ShieldUser, User, UserCheck } from '@lucide/svelte'; @@ -173,12 +173,16 @@ if ($ae_loc && $ae_sess && ($ae_loc.ver != $ae_sess.ver)) { // Minutes reference: // 240 = 4 hours; 720 = 12 hours; 2880 = 48 hours; // 10080 = 1 week; 20160 = 2 weeks; 43200 = 1 month; -let default_refresh_minutes: number = 60; -let trusted_refresh_minutes: number = 120; -let manager_refresh_minutes: number = 2880; +let default_refresh_minutes: number = 120; +let authenticated_refresh_minutes: number = 240; +let trusted_refresh_minutes: number = 10080; +let manager_refresh_minutes: number = 20160; if ($ae_loc?.site_cfg_json?.default_refresh_minutes) { default_refresh_minutes = $ae_loc.site_cfg_json.default_refresh_minutes; } +if ($ae_loc?.site_cfg_json?.authenticated_refresh_minutes) { + authenticated_refresh_minutes = $ae_loc.site_cfg_json.authenticated_refresh_minutes; +} if ($ae_loc?.site_cfg_json?.trusted_refresh_minutes) { trusted_refresh_minutes = $ae_loc.site_cfg_json.trusted_refresh_minutes; } @@ -186,13 +190,14 @@ if ($ae_loc?.site_cfg_json?.manager_refresh_minutes) { manager_refresh_minutes = $ae_loc.site_cfg_json.manager_refresh_minutes; } -let default_refresh_time = default_refresh_minutes * 60 * 1000; // 48 hours or 2880 minutes? 48 * 60 * -let trusted_refresh_time = trusted_refresh_minutes * 60 * 1000; // 1 week or 10080 minutes? -let manager_refresh_time = manager_refresh_minutes * 60 * 1000; // 1 week or 10080 minutes? +let default_refresh_time = default_refresh_minutes * 60 * 1000; +let authenticated_refresh_time = authenticated_refresh_minutes * 60 * 1000; +let trusted_refresh_time = trusted_refresh_minutes * 60 * 1000; +let manager_refresh_time = manager_refresh_minutes * 60 * 1000; // IDB caches - Check if the last refresh timestamp for $ae_loc.last_cache_refresh is no more than 15 minutes ago. let default_idb_refresh_time = 120 * 60 * 60 * 1000; // 15 minutes? -let trusted_idb_refresh_time = 120 * 60 * 60 * 1000; // 4 hours or 120 minutes? +let trusted_idb_refresh_time = 240 * 60 * 60 * 1000; // 4 hours or 120 minutes? if (!$ae_loc?.last_cache_refresh) { // Default is null, currently... console.log(`ROOT: Last reload not found. Need to set!`); @@ -215,7 +220,18 @@ if (!$ae_loc?.last_cache_refresh) { // Default is null, currently... console.log(`ROOT: Last diff: ${Date.now() - $ae_loc?.last_cache_refresh}`); } - if ($ae_loc?.trusted_access && (Date.now() - $ae_loc?.last_cache_refresh) > trusted_refresh_time) { + if ($ae_loc?.manager_access && (Date.now() - $ae_loc?.last_cache_refresh) > manager_refresh_time) { + console.log(`ROOT: Last (manager) local config reload too old for all caches: ${$ae_loc.last_cache_refresh}`); + + flag_clear_idb = true; + flag_clear_local = true; + flag_clear_sess = true; + flag_reload = true; + flag_expired = true; + + $ae_loc.cache_expired = true; + $ae_loc.allow_access = false; + } else if ($ae_loc?.trusted_access && (Date.now() - $ae_loc?.last_cache_refresh) > trusted_refresh_time) { console.log(`ROOT: Last (trusted) local config reload too old for all caches: ${$ae_loc.last_cache_refresh}`); flag_clear_idb = true; @@ -226,8 +242,8 @@ if (!$ae_loc?.last_cache_refresh) { // Default is null, currently... $ae_loc.cache_expired = true; $ae_loc.allow_access = false; - } else if (!$ae_loc?.trusted_access && (Date.now() - $ae_loc?.last_cache_refresh) > default_refresh_time) { - console.log(`ROOT: Last (default) local config reload too old for all caches: ${$ae_loc.last_cache_refresh}`); + } else if ($ae_loc?.authenticated_access && (Date.now() - $ae_loc?.last_cache_refresh) > authenticated_refresh_time) { + console.log(`ROOT: Last (authenticated) local config reload too old for all caches: ${$ae_loc.last_cache_refresh}`); flag_clear_idb = true; flag_clear_local = true; @@ -237,8 +253,8 @@ if (!$ae_loc?.last_cache_refresh) { // Default is null, currently... $ae_loc.cache_expired = true; $ae_loc.allow_access = false; - } else if ($ae_loc?.manager_access && (Date.now() - $ae_loc?.last_cache_refresh) > manager_refresh_time) { - console.log(`ROOT: Last (manager) local config reload too old for all caches: ${$ae_loc.last_cache_refresh}`); + } else if ((Date.now() - $ae_loc?.last_cache_refresh) > default_refresh_time) { + console.log(`ROOT: Last (default) local config reload too old for all caches: ${$ae_loc.last_cache_refresh}`); flag_clear_idb = true; flag_clear_local = true; @@ -254,6 +270,7 @@ if (!$ae_loc?.last_cache_refresh) { // Default is null, currently... } } + // Only clear IDB, not the local or session storage. if ($ae_loc?.trusted_access && (Date.now() - $ae_loc?.last_cache_refresh) > trusted_idb_refresh_time) { console.log(`ROOT: Last (trusted) IDB reload too old for IDB: ${$ae_loc.last_cache_refresh}`); @@ -432,7 +449,7 @@ function clear_idb() { // indexedDB.deleteDatabase('presenters'); // Events module <-- WARNING // indexedDB.deleteDatabase('sessions'); // Events module <-- WARNING // indexedDB.deleteDatabase('file'); // Core - Hosted Files module - indexedDB.deleteDatabase('ae_journals_db'); + indexedDB.deleteDatabase('ae_journals_db'); // Journals module // indexedDB.deleteDatabase('journal_entry'); // indexedDB.deleteDatabase('notes'); indexedDB.deleteDatabase('ae_posts_db'); // Posts module @@ -913,12 +930,13 @@ max-w-max --> {/if} -
+
{#if $ae_loc.access_type && $ae_loc.access_type != 'anonymous'} - + + {#if $ae_loc.access_type == 'super'} @@ -946,25 +964,63 @@ max-w-max --> {/if} - + if ($ae_loc?.app_cfg?.show_element__menu_btn) { + $ae_loc.app_cfg.show_element__menu = true; + $ae_loc.app_cfg.show_element__menu_btn = false; + $ae_loc.app_cfg.show_element__access_type = true; + $ae_loc.app_cfg.show_element__passcode_input = true; + } else { + $ae_loc.app_cfg.show_element__menu = false; + $ae_loc.app_cfg.show_element__menu_btn = true; + } + }} + class="btn btn-sm variant-outline-surface hover:variant-ghost-warning transition-all *:hover:inline" + title="Access mode is currently enabled/unlocked. Click to exit and lock." + > + + + + + + + {:else} + + {/if} {:else} {/if} @@ -1009,7 +1065,13 @@ max-w-max --> $ae_loc.app_cfg.show_element__menu = true; $ae_loc.app_cfg.show_element__menu_btn = false; $ae_loc.app_cfg.show_element__access_type = true; - $ae_loc.app_cfg.show_element__passcode_input = true; + + if ($ae_loc?.access_type == 'anonymous') { + $ae_loc.app_cfg.show_element__passcode_input = true; + } else { + $ae_loc.app_cfg.show_element__passcode_input = false; + } + // $ae_loc.app_cfg.show_element__passcode_input = true; await tick(); console.log('Layout button click: Focus on passcode input!'); /** @type {HTMLElement | null} */ @@ -1018,6 +1080,7 @@ max-w-max --> } else { $ae_loc.app_cfg.show_element__menu = false; $ae_loc.app_cfg.show_element__menu_btn = true; + $ae_loc.app_cfg.show_element__passcode_input = false; } // $ae_loc.app_cfg.show_element__menu_btn = !$ae_loc?.app_cfg?.show_element__menu_btn; }} @@ -1039,6 +1102,7 @@ max-w-max --> +