diff --git a/services/nginx/app/routes/authRoute.php b/services/nginx/app/routes/authRoute.php index 562c7d34..60dcbd13 100644 --- a/services/nginx/app/routes/authRoute.php +++ b/services/nginx/app/routes/authRoute.php @@ -416,7 +416,7 @@ class authRoute if ($matchingEconomicCustomer !== null) { if ($localUserExists) { - $response->error('Company phone number already registered 01', 400); + $response->error('Company phone number already registered', 400); } $this->bootstrapLocalCustomerOrFail($companyPhone); @@ -441,12 +441,35 @@ class authRoute } if ($localUserExists) { - $response->error('Company phone number already registered 02', 400); + $response->error('Company phone number already registered', 400); } // Get the CVR company information used for the e-conomic customer payload. - $companyInformation = (new virkdata())->getCompanyInformation($cvr, '', []); - $name = (string)($companyInformation->name ?? ''); + $companyInformation = null; + try { + $companyInformation = (new virkdata())->getCompanyInformation((string)$cvr, '', []); + } catch (Exception $exception) { + $this->logRegisterCvrIssue('AUTH_REGISTER_CVR_LOOKUP_FAILED', [ + 'phase' => 'cvr_lookup', + 'cvr' => (string)$cvr, + 'requestedCustomerNumber' => $companyPhone, + 'message' => $exception->getMessage(), + ]); + $response->error('CVR could not be verified. Please check the CVR number and try again.', 400); + return; + } + + $name = trim((string)($companyInformation->name ?? '')); + if ($name === '') { + $this->logRegisterCvrIssue('AUTH_REGISTER_CVR_LOOKUP_INVALID_RESPONSE', [ + 'phase' => 'cvr_lookup', + 'cvr' => (string)$cvr, + 'requestedCustomerNumber' => $companyPhone, + ]); + $response->error('CVR could not be verified. Please check the CVR number and try again.', 400); + return; + } + try { $result = $economic->createCustomer( (int)$companyPhone, @@ -765,7 +788,7 @@ class authRoute private function localCustomerNumberExists(int $customerNumber): bool { $rows = (new users_o())->getFieldsWhere([ - 'customer_number' => (int)$customerNumber, + 'customer_number' => (string)$customerNumber, ], ['id']); return count($rows) > 0; diff --git a/services/nginx/app/tests/auth/RegisterCvrTest.php b/services/nginx/app/tests/auth/RegisterCvrTest.php index e654effb..6b37250b 100644 --- a/services/nginx/app/tests/auth/RegisterCvrTest.php +++ b/services/nginx/app/tests/auth/RegisterCvrTest.php @@ -142,9 +142,14 @@ namespace classes { public static int $mock_zipcode = 2630; public static string $mock_city = 'Taastrup'; public static string $mock_website = 'https://demo.test'; + public static ?\RuntimeException $mock_exception = null; public function getCompanyInformation($cvr, $endpoint, $data): object { + if (self::$mock_exception !== null) { + throw self::$mock_exception; + } + $result = new \stdClass(); $result->name = self::$mock_name; $result->address = self::$mock_address; @@ -419,6 +424,40 @@ namespace { 'expected_error' => 'Parameter cvr must be at least 8 characters long', 'expected_status' => 400, ], + [ + 'name' => 'CVR lookup failure returns validation error without creating customer', + 'params' => array_merge($baseParams, ['cvr' => '11111112']), + 'setup' => static function (): void { + \classes\virkdata::$mock_exception = new \RuntimeException('An error occurred'); + }, + 'expected_error' => 'CVR could not be verified. Please check the CVR number and try again.', + 'expected_status' => 400, + 'assert' => static function (): void { + assert_true(count(\classes\economic::$create_calls) === 0, 'CVR lookup failures must not create e-conomic customers.'); + assert_true(count(\classes\email::$sent) === 0, 'CVR lookup failures must not send welcome emails.'); + assert_true(count(\classes\email::$superuser_notifications) === 0, 'CVR lookup failures must not send superuser notifications.'); + assert_true(count(\classes\slack::$customer_registration_notifications) === 0, 'CVR lookup failures must not send Slack customer registration notifications.'); + assert_true(count(\objects\logs_o::$entries) === 1, 'CVR lookup failures should be logged for diagnostics.'); + assert_true(\objects\logs_o::$entries[0]['event'] === 'AUTH_REGISTER_CVR_LOOKUP_FAILED', 'CVR lookup failure should use the lookup failure log event.'); + }, + ], + [ + 'name' => 'CVR lookup without company name returns validation error without creating customer', + 'params' => array_merge($baseParams, ['cvr' => '11111112']), + 'setup' => static function (): void { + \classes\virkdata::$mock_name = ''; + }, + 'expected_error' => 'CVR could not be verified. Please check the CVR number and try again.', + 'expected_status' => 400, + 'assert' => static function (): void { + assert_true(count(\classes\economic::$create_calls) === 0, 'CVR lookup responses without a company name must not create e-conomic customers.'); + assert_true(count(\classes\email::$sent) === 0, 'CVR lookup responses without a company name must not send welcome emails.'); + assert_true(count(\classes\email::$superuser_notifications) === 0, 'CVR lookup responses without a company name must not send superuser notifications.'); + assert_true(count(\classes\slack::$customer_registration_notifications) === 0, 'CVR lookup responses without a company name must not send Slack customer registration notifications.'); + assert_true(count(\objects\logs_o::$entries) === 1, 'CVR lookup responses without a company name should be logged for diagnostics.'); + assert_true(\objects\logs_o::$entries[0]['event'] === 'AUTH_REGISTER_CVR_LOOKUP_INVALID_RESPONSE', 'CVR lookup response without a company name should use the invalid response log event.'); + }, + ], [ 'name' => 'Existing company phone with local customer stays blocked', 'params' => $baseParams, @@ -654,6 +693,7 @@ namespace { \classes\virkdata::$mock_zipcode = 2630; \classes\virkdata::$mock_city = 'Taastrup'; \classes\virkdata::$mock_website = 'https://demo.test'; + \classes\virkdata::$mock_exception = null; \objects\users_o::reset(); \objects\logs_o::reset();