From b967eed0a54026da82fdbd35aa9cae2ab9451a1b Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Fri, 4 Apr 2025 18:31:31 -0400 Subject: [PATCH] Lots of work on user person security. Also some general clean up. Wrapping up for the day. --- src/lib/ae_core/ae_core_functions.ts | 12 + src/lib/ae_core/core__person.ts | 39 +- src/lib/ae_core/core__user.ts | 136 +++++ src/lib/ae_journals/db_journals.ts | 1 + src/lib/ae_stores.ts | 32 ++ src/lib/element_access_type.svelte | 28 - src/lib/element_app_cfg.svelte | 4 +- src/lib/element_sign_in_out.svelte | 516 ++++++++++++++++++ src/routes/+layout.svelte | 10 +- src/routes/+layout.ts | 2 +- src/routes/core/+page.svelte | 6 +- .../[presenter_id]/presenter_view.svelte | 2 +- .../session/[session_id]/session_view.svelte | 2 +- .../ae_comp__event_session_obj_li.svelte | 2 +- src/routes/journals/+page.svelte | 11 +- 15 files changed, 749 insertions(+), 54 deletions(-) create mode 100644 src/lib/ae_core/core__user.ts create mode 100644 src/lib/element_sign_in_out.svelte diff --git a/src/lib/ae_core/ae_core_functions.ts b/src/lib/ae_core/ae_core_functions.ts index cf0425b5..42b42252 100644 --- a/src/lib/ae_core/ae_core_functions.ts +++ b/src/lib/ae_core/ae_core_functions.ts @@ -18,6 +18,16 @@ import { // handle_db_save_ae_obj_li__person } from "$lib/ae_core/core__person"; +import { + auth_ae_obj__username_password, + auth_ae_obj__user_id_user_auth_key, + // handle_load_ae_obj_id__user, + // handle_load_ae_obj_li__user, + // handle_create_ae_obj__user, + // handle_update_ae_obj__user, + // handle_db_save_ae_obj_li__user +} from "$lib/ae_core/core__user"; + import { generate_qr_code, } from "$lib/ae_core/core__qr_code"; @@ -430,6 +440,8 @@ let export_obj = { handle_load_ae_obj_li__person: handle_load_ae_obj_li__person, handle_create_ae_obj__person: handle_create_ae_obj__person, handle_update_ae_obj__person: handle_update_ae_obj__person, + auth_ae_obj__username_password: auth_ae_obj__username_password, + auth_ae_obj__user_id_user_auth_key: auth_ae_obj__user_id_user_auth_key, handle_update_ae_obj_id_crud: handle_update_ae_obj_id_crud, handle_download_export__obj_type: handle_download_export__obj_type, generate_qr_code: generate_qr_code diff --git a/src/lib/ae_core/core__person.ts b/src/lib/ae_core/core__person.ts index 53eada10..f76c59b8 100644 --- a/src/lib/ae_core/core__person.ts +++ b/src/lib/ae_core/core__person.ts @@ -55,37 +55,46 @@ export async function handle_load_ae_obj_id__person( export async function handle_load_ae_obj_li__person( { api_cfg, - account_id, + for_obj_type = 'account', + for_obj_id, + enabled = 'enabled', + hidden = 'not_hidden', + limit = 99, + offset = 0, + order_by_li = {'start_datetime': 'DESC', 'name': 'ASC', 'updated_on': 'DESC', 'created_on': 'DESC'}, + params_json = null, params={}, try_cache=true, log_lvl=0 }: { api_cfg: any, - account_id: string, + for_obj_type: string, + for_obj_id: string, + enabled?: string, + hidden?: string, + limit?: number, + offset?: number, + order_by_li?: key_val, + params_json?: null|key_val, params?: key_val, try_cache?: boolean, log_lvl?: number } ) { - console.log(`*** handle_load_ae_obj_li__person() *** account_id=${account_id}`); - - let enabled: string = (params.qry__enabled ?? 'enabled'); // all, disabled, enabled - let hidden: string = (params.qry__hidden ?? 'not_hidden'); // all, hidden, not_hidden - let limit: number = (params.qry__limit ?? 99); // 99 - let offset: number = (params.qry__offset ?? 0); // 0 - - - let params_json: key_val = {}; + console.log(`*** handle_load_ae_obj_li__person() *** for_obj_type=${for_obj_type} for_obj_id=${for_obj_id} enabled=${enabled} hidden=${hidden} limit=${limit} offset=${offset}`); // console.log('params_json:', params_json); - ae_promises.load__person_obj_li = await api.get_ae_obj_li_for_obj_id_crud({ + ae_promises.load__person_obj_li = await api.get_ae_obj_li_for_obj_id_crud_v2({ api_cfg: api_cfg, obj_type: 'person', for_obj_type: 'account', - for_obj_id: account_id, - use_alt_table: false, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config. - use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value + for_obj_id: for_obj_id, + use_alt_tbl: false, + use_alt_mdl: false, + use_alt_exp: false, + // use_alt_table: false, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config. + // use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value enabled: enabled, hidden: hidden, order_by_li: {'given_name': 'ASC', 'family_name': 'ASC', 'updated_on': 'DESC', 'created_on': 'DESC'}, diff --git a/src/lib/ae_core/core__user.ts b/src/lib/ae_core/core__user.ts new file mode 100644 index 00000000..e58ef61f --- /dev/null +++ b/src/lib/ae_core/core__user.ts @@ -0,0 +1,136 @@ +import type { key_val } from '$lib/ae_stores'; +import { api } from '$lib/api'; + +import { db_core } from "$lib/ae_core/db_core"; + +let ae_promises: key_val = {}; + + +// Updated 2025-04-04 +export async function auth_ae_obj__username_password( + { + api_cfg, + account_id, + null_account_id = false, + username, + password, + params = {}, + try_cache = true, + log_lvl = 1 + }: { + api_cfg: any, + account_id: string, + null_account_id?: boolean, + username: string, + password: string, + params?: key_val, + try_cache?: boolean, + log_lvl?: number + } + ) { + if (log_lvl) { + console.log(`*** auth_ae_obj__username_password() *** account_id=${account_id} username=${username} password=${password}`); + } + + let endpoint = '/user/authenticate'; + + if (null_account_id) { + params['null_account_id'] = true; + } + params['username'] = username; // Required + params['password'] = password; // Required + if (log_lvl > 1) { + console.log(`auth_ae_obj__username_password() - params:`, params); + } + + ae_promises.auth__username_password = await api.get_object({ + api_cfg: api_cfg, + endpoint: endpoint, + params: params, + // data: {}, + log_lvl: log_lvl + }) + .then(async function (user_obj_get_result) { + if (user_obj_get_result) { + // if (try_cache) { + // // This is expecting a list + // db_save_ae_obj_li__user({ + // obj_type: 'user', + // obj_li: [user_obj_get_result], + // log_lvl: log_lvl + // }); + // } + return user_obj_get_result; + } else { + console.log('No results returned.'); + return null; + } + }) + .catch(function (error) { + console.log('No results returned or failed.', error); + }); + + + + if (log_lvl) { + console.log('ae_promises.auth__username_password:', ae_promises.auth__username_password); + } + return ae_promises.auth__username_password; +} + + +// Updated 2025-04-04 +export async function auth_ae_obj__user_id_user_auth_key( + { + api_cfg, + account_id, + user_id, + user_auth_key, + params = {}, + try_cache = true, + log_lvl = 1 + }: { + api_cfg: any, + account_id: string, + user_id: string, + user_auth_key: string, + params?: key_val, + try_cache?: boolean, + log_lvl?: number + } + ) { + if (log_lvl) { + console.log(`*** auth_ae_obj__user_id_user_auth_key() *** account_id=${account_id} user_id=${user_id}`); + } + + let endpoint = '/user/authenticate'; + + params['user_id'] = user_id; // Required + params['auth_key'] = user_auth_key; // Required + if (log_lvl > 1) { + console.log(`auth_ae_obj__user_id_user_auth_key() - params:`, params); + } + + ae_promises.auth__user_id_user_key = await api.get_object({ + api_cfg: api_cfg, + endpoint: endpoint, + params: params, + log_lvl: log_lvl + }) + .then(async function (user_obj_get_result) { + if (user_obj_get_result) { + return user_obj_get_result; + } else { + console.log('No results returned.'); + return null; + } + }) + .catch(function (error) { + console.log('No results returned or failed.', error); + }); + + if (log_lvl) { + console.log('ae_promises.auth__user_id_user_key:', ae_promises.auth__user_id_user_key); + } + return ae_promises.auth__user_id_user_key; +} \ No newline at end of file diff --git a/src/lib/ae_journals/db_journals.ts b/src/lib/ae_journals/db_journals.ts index d564ecf4..ad9d3c7a 100644 --- a/src/lib/ae_journals/db_journals.ts +++ b/src/lib/ae_journals/db_journals.ts @@ -299,6 +299,7 @@ export class MySubClassedDexie extends Dexie { id, journal_id, code, account_id, + person_id, conference, type, name, start_datetime, end_datetime, diff --git a/src/lib/ae_stores.ts b/src/lib/ae_stores.ts index 7c628df2..0f07890b 100644 --- a/src/lib/ae_stores.ts +++ b/src/lib/ae_stores.ts @@ -102,6 +102,37 @@ export let ae_app_local_data_struct: key_val = { 'user_email': null, // Currently used with Sponsorships only? + // Added 2025-04-04 + person_id: null, // The current person_id of the logged-in user (if any) + person: { + id: null, // The current person_id of the logged-in user + // profile_id: null, // The current person_profile_id of the logged-in user + // pronouns: null, + // informal_name: null, + // given_name: null, + // family_name: null, + // professional_title: null, + full_name: null, // convenience + // affiliations: null, + primary_email: null, // The primary email of the logged-in person/user + user_id: null, // The user ID of the logged-in user + }, + + // Added 2025-04-04 + user_id: null, // The current user_id of the logged-in user (if any) + user: { + id: null, // The current user_id of the logged-in user + username: null, + name: null, + email: null, // The email of the logged-in user + allow_auth_key: null, // For sign in without password + 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 + public: false, // Is the user a public user (can view public content) + person_id: null, // The person ID of the logged-in user + }, + 'qry__enabled': 'enabled', // all, disabled, enabled 'qry__hidden': 'not_hidden', // all, hidden, not_hidden 'qry__limit': 20, @@ -118,6 +149,7 @@ export let ae_app_local_data_struct: key_val = { show_element__access_type: true, show_element__cfg: true, show_element__cfg_detail: false, + show_element__sign_in_out: true, // Show the sign-in/out button in the UI show_opt__debug: true, show_opt__permissions: true, show_opt__reset: true, diff --git a/src/lib/element_access_type.svelte b/src/lib/element_access_type.svelte index bce8e05f..09369da0 100644 --- a/src/lib/element_access_type.svelte +++ b/src/lib/element_access_type.svelte @@ -166,34 +166,6 @@ function handle_clear_access() { return true; } - -// function dispatch_access_type_changed() { -// if (log_lvl) { -// console.log('*** dispatch_access_type_changed() ***'); - -// console.log(ae_util); -// console.log($ae_loc); -// } - -// dispatch('access_type_changed', { -// access_type: $ae_loc.access_type -// }); -// } - -// function dispatch_edit_mode_changed() { -// if (log_lvl) { -// console.log('*** dispatch_edit_mode_changed() ***'); - -// console.log(ae_util); -// console.log($ae_loc); -// } - -// window.localStorage.setItem('edit_mode', $ae_loc.edit_mode); - -// dispatch('edit_mode_changed', { -// edit_mode: $ae_loc.edit_mode -// }); -// } diff --git a/src/lib/element_app_cfg.svelte b/src/lib/element_app_cfg.svelte index d426ed90..284b0f42 100644 --- a/src/lib/element_app_cfg.svelte +++ b/src/lib/element_app_cfg.svelte @@ -288,8 +288,8 @@ function handle_clear_storage(item: null|string) { /* position: relative; */ /* position: static; */ /* position: sticky; */ - /* top: 1em; */ - bottom: 1.5rem; + top: 4.5em; + /* bottom: 9.5rem; */ left: 0rem; padding: .5rem; diff --git a/src/lib/element_sign_in_out.svelte b/src/lib/element_sign_in_out.svelte new file mode 100644 index 00000000..58588763 --- /dev/null +++ b/src/lib/element_sign_in_out.svelte @@ -0,0 +1,516 @@ + + + + + +
+ + +
+

+ {#if $ae_loc?.person_id && $ae_loc?.user_id} + + {$ae_loc?.person.full_name ?? '-- not set --'} + + + + {:else} + + Sign In + + {/if} +

+
+ + + {#if !$ae_loc?.person_id && !$ae_loc?.user_id} + + + + + {:else} + +
+ + {$ae_loc?.user.username ?? '-- not set --'} + + + +
+ + {/if} + +
+ +
+ + diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 5b66812b..3a38a103 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -47,6 +47,7 @@ import { events_loc, events_slct } from '$lib/ae_events_stores'; import Element_access_type from '$lib/element_access_type.svelte'; import Element_app_cfg from '$lib/element_app_cfg.svelte'; +import Element_sign_in_out from '$lib/element_sign_in_out.svelte'; // import Element_data_store from '$lib/element_data_store_v2.svelte'; interface Props { @@ -444,6 +445,13 @@ $effect(() => { {/if} +{#if $ae_loc.app_cfg?.show_element__sign_in_out} +