{"record":{"id":"75783a5d21e951e4","repo":"passbolt/passbolt_api","slug":"the-authentication-token-does-not-exist-or-has-been-deleted-75783a","errorCode":null,"errorMessage":"The authentication token does not exist or has been deleted.","messagePattern":"The authentication token does not exist or has been deleted\\.","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"plugins/PassboltEe/SsoRecover/src/Controller/Azure/AzureRecoverSuccessController.php","lineNumber":56,"sourceCode":"    }\n\n    /**\n     * @return void\n     * @throws \\League\\OAuth2\\Client\\Provider\\Exception\\IdentityProviderException\n     */\n    public function ssoRecoverSuccess(): void\n    {\n        if ($this->request->is('json')) {\n            throw new BadRequestException(__('Ajax/Json request not supported.'));\n        }\n\n        $this->User->assertNotLoggedIn();\n        $token = $this->getTokenFromUrlQuery();\n\n        try {\n            (new SsoAuthenticationTokenGetService())->getActiveNotExpiredOrFail($token, SsoState::TYPE_SSO_RECOVER);\n        } catch (RecordNotFoundException $e) {\n            throw new BadRequestException(\n                __('The authentication token does not exist or has been deleted.'),\n                null,\n                $e\n            );\n        } catch (CustomValidationException $e) {\n            throw new BadRequestException(\n                __('The authentication token has been expired.'),\n                null,\n                $e\n            );\n        }\n\n        $this->viewBuilder()\n            ->setTheme('Passbolt/Sso')\n            ->setLayout('default')\n            ->setTemplatePath('success')\n            ->setTemplate('stage3');\n    }","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/SsoRecover/src/Controller/Azure/AzureRecoverSuccessController.php#L38-L74","documentation":"Thrown when the SSO authentication token taken from the URL query cannot be found as an active, non-expired token of type SSO_RECOVER. The underlying SsoAuthenticationTokenGetService::getActiveNotExpiredOrFail raised a RecordNotFoundException (token absent or deleted) which the controller converts to this BadRequestException.","triggerScenarios":"GET /sso/recover/success/azure?token=... where the token value does not match any sso_authentication_tokens row: token already consumed by a previous success call, manually deleted, mistyped, or from a different environment/database.","commonSituations":"User refreshes the success page after the token was already used (single-use token consumed), replaying an old recovery link, or pointing a staging URL at a database where the token was never created.","solutions":["Restart the SSO recover flow from the beginning to obtain a fresh token, then use the new link only once.","Verify the URL query token value is complete and unmodified (check for truncation by email clients or redirects).","Check you are on the same passbolt instance/environment that issued the token.","If tokens are being deleted prematurely, inspect cleanup/cron jobs and the sso_authentication_tokens table for the expected record."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Client-side: ensure the token query param is present and non-empty before navigating\nconst token = new URLSearchParams(window.location.search).get('token');\nif (!token || token.length < 8) console.warn('Missing or truncated SSO recover token');","typeGuard":"function hasValidTokenShape(params) {\n  const t = params.get('token');\n  return typeof t === 'string' && /^[A-Za-z0-9_-]+$/.test(t) && t.length >= 16;\n}","tryCatchPattern":"try {\n  await completeSsoRecoverSuccess(token);\n} catch (e) {\n  if (e.message.includes('does not exist or has been deleted')) {\n    restartSsoRecoverFlow(); // token consumed/missing: get a fresh one\n  }\n}","preventionTips":["Treat SSO recover tokens as strictly single-use; never reuse the success URL.","Copy recovery links without truncation (email clients often wrap URLs).","Keep the recovery flow within one environment/instance.","Avoid refreshing the success page; restart the flow if it fails."],"tags":["sso","authentication-token","token-not-found","recover"],"backgroundTag":"record-not-found","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"}