diff --git a/app/assets/utils/classes/CompanyProfileManager.php b/app/assets/utils/classes/CompanyProfileManager.php index ef048f0..bd17d2c 100644 --- a/app/assets/utils/classes/CompanyProfileManager.php +++ b/app/assets/utils/classes/CompanyProfileManager.php @@ -99,7 +99,7 @@ class CompanyProfileManager public function saveProfile(array $data, string $company_logo, string $company_seal): void { - $channel = strtolower(preg_replace('/[^a-z0-9\-_]/', '', $data['channel_name'] ?? '')); + $channel = preg_replace('/[^a-z0-9\-_]/', '', strtolower(trim($data['channel_name'] ?? ''))); $sth = $this->pdo->prepare( "UPDATE company_list SET diff --git a/app/dbconn.php b/app/dbconn.php index b1369dc..e698975 100644 --- a/app/dbconn.php +++ b/app/dbconn.php @@ -27,6 +27,11 @@ class db_statement extends PDOStatement { $this->pdo = $pdo; } + // PDOStatement::execute() is declared ?array $params = null : bool. This + // override deliberately accepts a looser signature so callers may pass + // positional arguments (see func_get_args() below), so the tightened return + // type is opted out of rather than the call sites being changed. + #[\ReturnTypeWillChange] public function execute($args = null) { // Perform logging here. PDO object is accessible // from $this->pdo. diff --git a/app/include_header.php b/app/include_header.php index d5027df..46ca22e 100644 --- a/app/include_header.php +++ b/app/include_header.php @@ -1,4 +1,23 @@ . Without a buffer that redirect depends +// entirely on php.ini's output_buffering: it is on for the dev stack but off +// in production, where every protected page answered 200 with a half-rendered +// body instead of sending the browser to the login form. session.php starts a +// buffer for the same reason. +if (ob_get_level() === 0) { + ob_start(); +} + +// Never render PHP notices/warnings into the page: they leak absolute server +// paths to anonymous visitors and corrupt the markup. Errors still reach the +// server log. This mirrors the policy db_auth.php already applies to the JSON +// API routes, and keeps the app safe even where php.ini has display_errors on. +ini_set('display_errors', '0'); +ini_set('log_errors', '1'); + // Security headers — emitted before any HTML output. header('X-Content-Type-Options: nosniff'); header('X-Frame-Options: SAMEORIGIN'); diff --git a/app/include_topbar.php b/app/include_topbar.php index 371477d..4533185 100644 --- a/app/include_topbar.php +++ b/app/include_topbar.php @@ -8,6 +8,11 @@ require_once __DIR__ . '/assets/utils/classes/UsageGuard.php'; // login_company_id is only written by login_confirm.php after OTP is verified — // using it (not "otp") ensures half-logged-in sessions are also redirected. if(empty($_SESSION["login_company_id"])){ + // Discard the markup include_header.php has already buffered so the browser + // receives a clean redirect rather than a partially rendered page body. + while (ob_get_level() > 0) { + ob_end_clean(); + } header('Location: '.$server_url.'login/index.php'); exit; } diff --git a/app/login/api/engine/onboarding.php b/app/login/api/engine/onboarding.php index db7984a..9a6c465 100644 --- a/app/login/api/engine/onboarding.php +++ b/app/login/api/engine/onboarding.php @@ -97,9 +97,9 @@ try { $company_name = trim($data['company_name'] ?? ''); $company_name2 = trim($data['company_name2'] ?? ''); - // channel_name is the URL slug / identifier — strip everything except - // lowercase letters, digits, hyphens, and underscores. - $channel_name = strtolower(preg_replace('/[^a-z0-9\-_]/', '', $data['channel_name'] ?? '')); + // channel_name is the URL slug / identifier — lowercase first, then strip + // everything except lowercase letters, digits, hyphens, and underscores. + $channel_name = preg_replace('/[^a-z0-9\-_]/', '', strtolower(trim($data['channel_name'] ?? ''))); $branch = trim($data['branch'] ?? 'สำนักงานใหญ่'); $branch_no = trim($data['branch_no'] ?? '00000'); diff --git a/app/login/onboarding.php b/app/login/onboarding.php index 1d5adda1..d9d62c7 100644 --- a/app/login/onboarding.php +++ b/app/login/onboarding.php @@ -48,7 +48,8 @@
- +
Unique identifier. Lowercase, no spaces.
diff --git a/app/session.php b/app/session.php index 5fb3a0e..3651670 100644 --- a/app/session.php +++ b/app/session.php @@ -2,6 +2,12 @@ // app/session.php ob_start(); // ensure output buffering is on regardless of php.ini — prevents stray output from corrupting JSON API responses +// The buffer is still flushed, so notices would still land in front of the JSON +// body and break the client's parse ("Server error occurred."). The login API +// engines load this file instead of db_auth.php, so apply the same policy here. +ini_set('display_errors', '0'); +ini_set('log_errors', '1'); + if (session_status() === PHP_SESSION_NONE) { // Derive cookie path dynamically from the current script location. diff --git a/app/setting/company.php b/app/setting/company.php index 9f37e9e..2a60c6e 100644 --- a/app/setting/company.php +++ b/app/setting/company.php @@ -121,7 +121,8 @@
- +
Unique identifier. Lowercase, no spaces.