{"record":{"id":"25d30da2de9414a0","repo":"passbolt/passbolt_api","slug":"the-authentication-token-should-be-a-valid-uuid-25d30d","errorCode":null,"errorMessage":"The authentication token should be a valid UUID.","messagePattern":"The authentication token should be a valid UUID\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":500,"severity":"error","filePath":"plugins/PassboltCe/MultiFactorAuthentication/src/Service/Duo/MfaDuoEnableService.php","lineNumber":83,"sourceCode":"     * Enable Duo for the operator.\n     *\n     * @param \\App\\Utility\\UserAccessControl $uac The user access control\n     * @param \\Passbolt\\MultiFactorAuthentication\\Model\\Dto\\MfaDuoCallbackDto $duoCallbackDto The Duo callback data\n     * @param string $token The authentication token.\n     * @return \\App\\Model\\Entity\\AuthenticationToken\n     * @throws \\InvalidArgumentException if the provided token is not a UUID\n     * @throws \\Cake\\Http\\Exception\\UnauthorizedException If no active Duo callback authentication can be found.\n     * @throws \\Cake\\Http\\Exception\\UnauthorizedException If the duo state cannot be verified.\n     * @throws \\Cake\\Http\\Exception\\UnauthorizedException If the Duo code cannot be verified.\n     * @throws \\Cake\\Http\\Exception\\InternalErrorException if the Duo provider cannot be enabled for the user.\n     */\n    public function enable(\n        UserAccessControl $uac,\n        MfaDuoCallbackDto $duoCallbackDto,\n        string $token\n    ): AuthenticationToken {\n        if (!Validation::uuid($token)) {\n            throw new InvalidArgumentException('The authentication token should be a valid UUID.');\n        }\n        $authenticationTokenType = AuthenticationToken::TYPE_MFA_SETUP;\n        $authenticationToken = (new MfaDuoCallbackAuthenticationTokenService())\n            ->consumeAndVerifyAuthenticationToken(\n                $uac,\n                $authenticationTokenType,\n                $token,\n                $duoCallbackDto->state\n            );\n        try {\n            (new MfaDuoVerifyDuoCodeService($authenticationTokenType, $this->duoClient))\n                ->verify($uac, $duoCallbackDto->duoCode);\n        } catch (Throwable $th) {\n            throw new BadRequestException(__('Unable to verify Duo authentication.'), null, $th);\n        }\n        $this->enableProvider($uac);\n\n        return $authenticationToken;","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltCe/MultiFactorAuthentication/src/Service/Duo/MfaDuoEnableService.php#L65-L101","documentation":"MfaDuoEnableService::enable performs the same UUID pre-validation as the callback token service: the $token argument must be a valid UUID before it is forwarded to MfaDuoCallbackAuthenticationTokenService::consumeAndVerifyAuthenticationToken. A non-UUID token is rejected with this InvalidArgumentException without any database lookup.","triggerScenarios":"Calling enable() with a token string that is not a UUID — empty string, garbage from a tampered callback URL, or the Duo authorization code passed where the passbolt setup token was expected.","commonSituations":"Mixing up the Duo 'code' parameter with the passbolt MFA token in the callback handler; client sends the token URL-decoded/truncated; a test passes a placeholder token string like 'test-token'.","solutions":["Pass the UUID token issued when the Duo setup flow started (AuthenticationToken::TYPE_MFA_SETUP token)","Validate with Validation::uuid($token) in the caller before calling enable()","Fix the callback controller mapping so the passbolt token parameter — not the Duo code — is passed as $token","If the token was lost, restart the Duo setup flow to get a new one"],"exampleFix":"// before\n(new MfaDuoEnableService())->enable($uac, $dto, $duoCallbackDto->duoCode); // wrong value\n// after\n(new MfaDuoEnableService())->enable($uac, $duoCallbackDto, $mfaSetupTokenUuid);","handlingStrategy":"validation","validationCode":"if (!\\Cake\\Validation\\Validation::uuid($token)) {\n    throw new \\Cake\\Http\\Exception\\BadRequestException('MFA setup token must be a UUID.');\n}","typeGuard":null,"tryCatchPattern":"try {\n    $service->enable($uac, $dto, $token);\n} catch (\\InvalidArgumentException $e) {\n    throw new \\Cake\\Http\\Exception\\BadRequestException($e->getMessage());\n}","preventionTips":["Keep the Duo 'code' and the passbolt token UUID as clearly separate parameters in the callback handler","Validate token format at the controller before the service layer","Add integration tests covering the full callback payload mapping"],"tags":["validation","uuid","mfa","duo"],"backgroundTag":"invalid-argument-format","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}