diff --git a/src/lib/app_components/e_app_sign_in_out.svelte b/src/lib/app_components/e_app_sign_in_out.svelte index 63b1bd76..aac57127 100644 --- a/src/lib/app_components/e_app_sign_in_out.svelte +++ b/src/lib/app_components/e_app_sign_in_out.svelte @@ -73,9 +73,13 @@ let is_changing_password = $state(false); let show_password_text = $state('password'); // password or text - // Email sign-in status: null | 'sending' | 'sent' | 'not_found' | 'error' + // Email sign-in status: null | 'sending' | 'sent' | 'not_found' | 'no_email' | 'error' let email_send_status: null | string = $state(null); + // Username/password sign-in status: null | 'signing_in' | 'error' | 'no_credentials' + let user_signin_status: null | string = $state(null); + let user_signin_error: null | string = $state(null); + function sign_in() { $ae_loc.jwt = user_obj.jwt; // Store the JSON Web Token $ae_loc.person_id = person_id; // Set the person_id in the ae_loc store @@ -445,9 +449,15 @@ // WARNING: Logging in as a global user does not work yet. The API needs to be updated. Currently it returns multiple user records from the v_user view if there is more than one person record linked to the user ID. + // Helper to set error state without repeating the pattern + const set_error = (msg: string) => { + user_signin_status = 'error'; + user_signin_error = msg; + }; + if ($ae_sess.auth__entered_user_id && $ae_sess.auth__entered_user_key) { - // Try to use the user ID and user auth key passed in the URL params for authentication - alert('Attempting to authenticate with User ID and Auth Key.'); + user_signin_status = 'signing_in'; + user_signin_error = null; ae_promises['user'] = await core_func .auth_ae_obj__user_id_user_auth_key({ @@ -459,93 +469,60 @@ log_lvl: 0 }) .then((user_response) => { - // console.log(`HERE:`, user_response); if (user_response?.user_id) { - console.log( - `Successfully authenticated in with User ID and User Auth Key: ${user_response.username}`, - user_response - ); - user_obj = user_response; // Store the user object for later use - user_id = user_obj.user_id; // Use the user_id for further API calls - // person_id = user_obj.person_id_random; + console.log(`Successfully authenticated with User ID and Auth Key: ${user_response.username}`, user_response); + user_obj = user_response; + user_id = user_obj.user_id; } else if (!user_response) { - alert('Sign in failed: No response from the server. Check your connection and try again.'); + set_error('No server response. Check your connection and retry.'); } else { // API returns 'detail' for validation errors (FastAPI standard), 'error' for app-level errors const reason = user_response?.detail || user_response?.error || 'Invalid User ID or Auth Key.'; - alert('Sign in failed: ' + reason); + set_error(reason); } }) - .then((response) => { + .then(() => { if (!user_id) { - // Auth failed in the previous .then() — user has already been alerted + // Auth failed above — status already set console.error('Auth (user_id+key): user_id not set after authentication attempt.'); return; } - - // Next we need to get the person's information. This is odd because we need to look it up based on the account_id and user_id. There should only be one account person record per user. 99% of the time the user's account ID will be the same as the person's account ID. The exception is for AE Global users (Super or Manager) who can have multiple accounts but only one person record per account. - - // let params = { - // user_id_random: user_id, // The user_id_random from the above authentication - // } - - // let params_json: key_val = {}; - - // params_json['and_qry'] = {}; - - // if (user_id) { - // params_json['and_qry']['user_id_random'] = user_id; - // } - - // WARNING: This function returns a list. We only want the first one. There should be no more than 1 record returned. - // WARNING: This function returns a list. We only want the first one. There should be no more than 1 record returned. - // We use enabled: 'all' and hidden: 'all' to ensure we find the person record even if + // Look up the person record linked to this user. + // We use enabled:'all' and hidden:'all' to find the record even if // technical fields like 'hide' are NULL or the record is temporarily disabled. ae_promises['person'] = core_func .load_ae_obj_li__person({ api_cfg: $ae_api, for_obj_type: 'account', for_obj_id: $ae_loc.account_id, - qry_user_id: user_id, // The user_id_random from the above authentication + qry_user_id: user_id, enabled: 'all', hidden: 'all', - // params_json: params_json, - // params: params, log_lvl: 0 }) .then((person_response) => { - // Safety Check: Ensure the response is valid and contains at least one record before accessing index 0. // V3 CRUD returns 'id' as the random identifier; 'person_id_random' is a legacy field name. const person_rec = person_response?.[0]; if (person_rec && (person_rec.id || person_rec.person_id_random)) { - console.log( - `Successfully loaded person (${user_id}):`, - person_rec - ); + console.log(`Successfully loaded person (${user_id}):`, person_rec); person_obj = person_rec; person_id = person_rec.id ?? person_rec.person_id_random; - - trigger = true; // Set trigger to true to indicate we can now sign in + trigger = true; // triggers sign_in() via $effect → page redirect } else { - alert( - 'Sign in failed: No person record is linked to this user account. Please contact your administrator.' - ); + set_error('No person record linked to this account. Contact your administrator.'); } }) .then(() => { - if (user_id && person_id) { - console.log(`Successfully authenticated and loaded user and person records: user_id: ${user_id}, person_id: ${person_id}`); - } else { - console.error( - 'Auth (user_id+key): finished but missing user_id or person_id — sign_in() will not be called.' - ); + if (!user_id || !person_id) { + console.error('Auth (user_id+key): finished but missing user_id or person_id — sign_in() will not be called.'); } }); }); - // console.log('DONE???', ae_promises); + } else if ($ae_sess.auth__entered_username && $ae_sess.auth__entered_password) { - // Try to use the username/password for authentication - // alert('Attempting to authenticate with Username and Password.'); + user_signin_status = 'signing_in'; + user_signin_error = null; + ae_promises['user'] = await core_func .auth_ae_obj__username_password({ api_cfg: $ae_api, @@ -557,94 +534,58 @@ }) .then((user_response) => { if (user_response?.user_id) { - console.log( - `Successfully authenticated in with Username (${user_response.username}) and Password:`, - user_response - ); - user_obj = user_response; // Store the user object for later use - user_id = user_obj.user_id; // Use the user_id for further API calls - // person_id = user_obj.person_id_random; + console.log(`Successfully authenticated with Username (${user_response.username}) and Password:`, user_response); + user_obj = user_response; + user_id = user_obj.user_id; } else if (!user_response) { - alert('Sign in failed: No response from the server. Check your connection and try again.'); + set_error('No server response. Check your connection and retry.'); } else { // API returns 'detail' for validation errors (FastAPI standard), 'error' for app-level errors const reason = user_response?.detail || user_response?.error || 'Invalid username or password.'; - alert('Sign in failed: ' + reason); + set_error(reason); } }) - .then((response) => { + .then(() => { if (!user_id) { - // Auth failed in the previous .then() — user has already been alerted + // Auth failed above — status already set console.error('Auth (username+password): user_id not set after authentication attempt.'); return; } - - // Next we need to get the person's information. This is odd because we need to look it up based on the account_id and user_id. There should only be one account person record per user. 99% of the time the user's account ID will be the same as the person's account ID. The exception is for AE Global users (Super or Manager) who can have multiple accounts but only one person record per account. - - // let params = { - // user_id_random: user_id, // The user_id_random from the above authentication - // } - - // let params_json: key_val = {}; - - // params_json['and_qry'] = {}; - - // if (user_id) { - // params_json['and_qry']['user_id_random'] = user_id; - // } - - // WARNING: This function returns a list. We only want the first one. There should be no more than 1 record returned. - // WARNING: This function returns a list. We only want the first one. There should be no more than 1 record returned. - // We use enabled: 'all' and hidden: 'all' to ensure we find the person record even if + // Look up the person record linked to this user. + // We use enabled:'all' and hidden:'all' to find the record even if // technical fields like 'hide' are NULL or the record is temporarily disabled. ae_promises['person'] = core_func .load_ae_obj_li__person({ api_cfg: $ae_api, for_obj_type: 'account', for_obj_id: $ae_loc.account_id, - qry_user_id: user_id, // The user_id_random from the above authentication + qry_user_id: user_id, enabled: 'all', hidden: 'all', - // params_json: params_json, - // params: params, log_lvl: 0 }) .then((person_response) => { - // Safety Check: Ensure the response is valid and contains at least one record before accessing index 0. // V3 CRUD returns 'id' as the random identifier; 'person_id_random' is a legacy field name. const person_rec = person_response?.[0]; if (person_rec && (person_rec.id || person_rec.person_id_random)) { - console.log( - `Successfully loaded person (${user_id}):`, - person_rec - ); + console.log(`Successfully loaded person (${user_id}):`, person_rec); person_obj = person_rec; person_id = person_rec.id ?? person_rec.person_id_random; - - trigger = true; // Set trigger to true to indicate we can now sign in + trigger = true; // triggers sign_in() via $effect → page redirect } else { - alert( - 'Sign in failed: No person record is linked to this user account. Please contact your administrator.' - ); + set_error('No person record linked to this account. Contact your administrator.'); } }) .then(() => { - if (user_id && person_id) { - console.log(`Successfully authenticated and loaded user and person records: user_id: ${user_id}, person_id: ${person_id}`); - } else { - console.error( - 'Auth (username+password): finished but missing user_id or person_id — sign_in() will not be called.' - ); + if (!user_id || !person_id) { + console.error('Auth (username+password): finished but missing user_id or person_id — sign_in() will not be called.'); } }); }); - // console.log('DONE???', ae_promises); } else { - alert( - 'Please enter either a User ID and Auth Key or Username and Password.' - ); - return false; // Prevent form submission if no credentials are provided + user_signin_status = 'no_credentials'; + return false; } }} > @@ -689,15 +630,33 @@ + {#if user_signin_error} +

+ {user_signin_error} +

+ {/if} {:else}