0, 'message' => 'Only the owner can modify this setting.'])); } $action = $data['action'] ?? ''; $um = new UserManager($pdo1, $company_id, $user_id); try { // All valid app_access values: every registered app key + 'all' $all_app_keys = array_keys($app_registry); $all_valid_apps = array_merge($all_app_keys, ['all']); // What the current owner's license permits assigning to others $owner_access = $_SESSION['login_app_access'] ?? 'wms'; $owner_allowed_access = $owner_access === 'all' ? $all_valid_apps : [$owner_access]; if ($action === 'create') { $email = strtolower(trim($data['invite_email'] ?? '')); $role = trim($data['invite_role'] ?? ''); $app_access = trim($data['invite_app_access'] ?? ''); if (!in_array($app_access, $owner_allowed_access, true)) { throw new Exception('App access selection exceeds your license.'); } $result = $um->inviteUser($email, $role, $app_access); // Both new and existing users require explicit acceptance via email // 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']); $subject = $result['new_user'] ? 'You have been invited to join the team' : 'You have been invited to join a new company'; $body_intro = $result['new_user'] ? 'You have been invited to join the team. Click the button below to set up your account:' : 'You have been invited to join a new company. Click the button below to accept:'; require_once '../../../assets/utils/module/mailer.php'; $mailer = new mailer(['pdo1' => $pdo1]); $mailer->send_email([ 'company_id' => $company_id, 'to' => $result['email'], 'subject' => $subject, 'message' => implode("\n", [ $body_intro, "", "Accept Invitation", "", "Or copy and paste this link into your browser:", "{$invite_url}", "", "This link will expire in 7 days.", "", "If you did not expect this invitation, you can ignore this email.", ]), 'channel_name' => 'WMS', 'key' => $pinkey, ]); $answer['message'] = htmlspecialchars($result['email']) . ' has been invited. An email has been sent.'; $answer['success'] = 1; } elseif ($action === 'update') { $map_id = (int)($data['map_id'] ?? 0); $role = trim($data['role'] ?? ''); $app_access = trim($data['app_access'] ?? ''); $um->updateRole($map_id, $role); if ($app_access !== '') { if (!in_array($app_access, $owner_allowed_access, true)) { throw new Exception('App access selection exceeds your license.'); } $um->updateAppAccess($map_id, $app_access); } $answer['success'] = 1; $answer['message'] = 'Access updated successfully.'; } elseif ($action === 'resend') { $map_id = (int)($data['map_id'] ?? 0); $result = $um->resendInvite($map_id); // 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']); $body_intro = $result['is_new_user'] ? 'Your invitation link has been refreshed. Click below to set up your account:' : 'Your invitation link has been refreshed. Click below to accept the invitation:'; require_once '../../../assets/utils/module/mailer.php'; $mailer = new mailer(['pdo1' => $pdo1]); $mailer->send_email([ 'company_id' => $company_id, 'to' => $result['email'], 'subject' => 'Your invitation link has been resent', 'message' => implode("\n", [ $body_intro, "", "Accept Invitation", "", "Or copy and paste this link into your browser:", "{$invite_url}", "", "This link will expire in 7 days.", ]), 'channel_name' => 'WMS', 'key' => $pinkey, ]); $answer['success'] = 1; $answer['message'] = 'Invitation resent to ' . htmlspecialchars($result['email']) . '.'; } elseif ($action === 'delete') { $map_id = (int)($data['map_id'] ?? 0); $um->removeUser($map_id); $answer['success'] = 1; $answer['message'] = 'User has been removed from this company.'; } else { $answer['message'] = 'Unknown action.'; http_response_code(400); } } catch (Exception $e) { $answer['message'] = $e->getMessage(); http_response_code(400); } exit(json_encode($answer)); ?>