{"record":{"id":"37c1e322b060a5f4","repo":"Mintplex-Labs/anything-llm","slug":"invalid-token","errorCode":null,"errorMessage":"Invalid token.","messagePattern":"Invalid token\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/models/temporaryAuthToken.js","lineNumber":82,"sourceCode":"   * Validates a temporary auth token and returns the session token\n   * to be set in the browser localStorage for authentication.\n   * @param {string} publicToken - the token to validate against\n   * @returns {Promise<{sessionToken: string|null, token: import(\"@prisma/client\").temporary_auth_tokens & {user: import(\"@prisma/client\").users} | null, error: string | null}>}\n   */\n  validate: async function (publicToken = \"\") {\n    /** @type {import(\"@prisma/client\").temporary_auth_tokens & {user: import(\"@prisma/client\").users} | undefined | null} **/\n    let token;\n\n    try {\n      if (!publicToken)\n        throw new Error(\n          \"Public token is required to validate a temporary auth token.\"\n        );\n      token = await prisma.temporary_auth_tokens.findUnique({\n        where: { token: String(publicToken) },\n        include: { user: true },\n      });\n      if (!token) throw new Error(\"Invalid token.\");\n      if (token.expiresAt < new Date()) throw new Error(\"Token expired.\");\n      if (token.user.suspended) throw new Error(\"User account suspended.\");\n\n      // Create a new session token for the user valid for 30 days\n      const sessionToken = makeJWT(\n        { id: token.user.id, username: token.user.username },\n        process.env.JWT_EXPIRY\n      );\n\n      return { sessionToken, token, error: null };\n    } catch (error) {\n      console.error(\"FAILED TO VALIDATE TEMPORARY AUTH TOKEN.\", error.message);\n      return { sessionToken: null, token: null, error: error.message };\n    } finally {\n      // Delete the token after it has been used under all circumstances if it was retrieved\n      if (token)\n        await prisma.temporary_auth_tokens.delete({ where: { id: token.id } });\n    }","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/526360e320da9d1b36074be5ed64fe76e5bbfbbd/server/models/temporaryAuthToken.js#L64-L100","documentation":"Thrown by TemporaryAuthToken.validate when prisma.temporary_auth_tokens.findUnique returns null for the supplied token. Tokens are single-use: the finally block (line 98-99) deletes the row after retrieval, so a previously consumed token no longer exists. This also covers tokens that were never issued or were typed incorrectly.","triggerScenarios":"GET /request-token/sso/simple?token=<X> where X has already been used once, was never created in the DB, or contains a typo/extra whitespace.","commonSituations":"User clicks an SSO link twice (second click reuses a consumed token). User refreshes the login page that carries the token. Link was generated for a different instance/database. Clock-skewed or restored DB snapshot missing the row.","solutions":["Issue a fresh token via TemporaryAuthToken.issue(userId) and generate a new SSO link.","Ensure the SSO flow consumes the token exactly once and redirects away from the token URL immediately.","Confirm the request hits the same instance/database that issued the token."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"const { sessionToken, error } = await TemporaryAuthToken.validate(token);\nif (error === 'Invalid token.') {\n  // prompt the user to request a fresh SSO link\n}","preventionTips":["Treat SSO links as single-use: redirect away from the token URL immediately after login.","Never reuse or bookmark an SSO link.","Confirm the request reaches the same instance/database that issued the token."],"tags":["sso","temporary-auth-token","authentication","single-use"],"backgroundTag":null,"analyzedSha":"526360e320da9d1b36074be5ed64fe76e5bbfbbd","analyzedAt":"2026-08-13T01:45:47.170Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}