From ba734561857d02236db890b1dcc6cabc01f3dc44 Mon Sep 17 00:00:00 2001 From: Thanakorn Date: Mon, 14 Sep 2026 17:17:40 +0700 Subject: [PATCH 1/2] Send the chosen company when switching branch --- app/include_topbar.php | 4 +++- app/setting/api/engine/switch_branch.php | 8 ++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/app/include_topbar.php b/app/include_topbar.php index 9999cd6..a031eac 100644 --- a/app/include_topbar.php +++ b/app/include_topbar.php @@ -420,7 +420,9 @@ function do_switch_branch(company_id) { autoPrepare: true, checkRequired: 0, action: 'update', - company_id: company_id, + // Sent under its own key: prepare_form_data() always fills company_id with + // the CURRENT company, and only options.data reaches the payload. + data: { target_company_id: company_id }, onSuccess: function(res) { window.location.reload(); } diff --git a/app/setting/api/engine/switch_branch.php b/app/setting/api/engine/switch_branch.php index 4f84cb9..47a3eb7 100644 --- a/app/setting/api/engine/switch_branch.php +++ b/app/setting/api/engine/switch_branch.php @@ -3,7 +3,11 @@ * switch_branch.php — Switch the active company for the current session. * * action: 'read' → return list of companies the user belongs to - * action: 'update' → switch to the requested company_id + * action: 'update' → switch to target_company_id + * + * The target is read from target_company_id, not company_id: every request + * carries company_id = the CURRENT company (prepare_form_data in custom.js), + * so reading it made a switch silently re-select the company already active. */ session_start(); require_once '../../../assets/utils/db_auth.php'; @@ -20,7 +24,7 @@ if ($action === 'read') { } if ($action === 'update') { - $target_company_id = (int)($data['company_id'] ?? 0); + $target_company_id = (int)($data['target_company_id'] ?? 0); if (!$target_company_id) { $answer['message'] = 'Invalid company.'; From 45331948c1800cfe67f5a66e65269873d0ba9384 Mon Sep 17 00:00:00 2001 From: Thanakorn Date: Mon, 14 Sep 2026 17:18:42 +0700 Subject: [PATCH 2/2] Use absolute URLs in invitation emails --- app/setting/api/engine/manage_users.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/setting/api/engine/manage_users.php b/app/setting/api/engine/manage_users.php index 34abb3b..606303f 100644 --- a/app/setting/api/engine/manage_users.php +++ b/app/setting/api/engine/manage_users.php @@ -31,7 +31,11 @@ $result = $um->inviteUser($email, $role, $app_access); // Both new and existing users require explicit acceptance via email - $invite_url = rtrim($server_url, '/') . ($result['new_user'] + // Absolute URL: the link is opened from a mail client, where a bare + // /app/... path goes nowhere. Same construction as register.php. + $invite_url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http') + . '://' . $_SERVER['HTTP_HOST'] + . rtrim($server_url, '/') . ($result['new_user'] ? '/login/invited_onboarding.php?token=' . $result['token'] : '/login/accept_invite.php?token=' . $result['token']); @@ -89,7 +93,11 @@ $map_id = (int)($data['map_id'] ?? 0); $result = $um->resendInvite($map_id); - $invite_url = rtrim($server_url, '/') . ($result['is_new_user'] + // Absolute URL: the link is opened from a mail client, where a bare + // /app/... path goes nowhere. Same construction as register.php. + $invite_url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http') + . '://' . $_SERVER['HTTP_HOST'] + . rtrim($server_url, '/') . ($result['is_new_user'] ? '/login/invited_onboarding.php?token=' . $result['token'] : '/login/accept_invite.php?token=' . $result['token']);