{"record":{"id":"37c1e322b060a5f4","repo":"Mintplex-Labs/anything-llm","slug":"invalid-token","errorCode":null,"errorMessage":"Invalid token.","messagePattern":"Invalid token\\.","errorType":"exception","errorClass":null,"httpStatus":401,"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/a145d4d87d086bdb31d50f9bf9cd9c46d311780c/server/models/temporaryAuthToken.js#L64-L100","documentation":"validate() ran a findUnique on temporary_auth_tokens for the given token string and found no row. The token never existed in this database, was revoked or deleted, or belongs to a different instance. Note the token column is matched exactly - truncation or whitespace breaks the lookup.","triggerScenarios":"A typo'd or truncated token (copy missing characters, URL-decoding issues); the token was deleted after use or by an admin; the database was reset while the link was still being shared; '+' or special characters mangled by query parsing.","commonSituations":"Magic-link emails clipped by mail clients; tokens copied with surrounding whitespace or percent-encoding intact; load-balanced instances pointing at different databases.","solutions":["Generate and share a fresh temporary auth token","Copy the token completely and URL-decode it before validating","Confirm the client and server hit the same database/instance","If tokens are single-use by policy, treat consumption as expected and re-issue"],"exampleFix":"// before\nTemporaryAuthToken.validate(token.trimEnd() + '='); // accidental mutation -> Invalid token.\n\n// after\nTemporaryAuthToken.validate(decodeURIComponent(token).trim());","handlingStrategy":"try-catch","validationCode":"const publicToken = decodeURIComponent(String(rawToken ?? '')).trim();\nif (publicToken.length === 0) {\n  return res.status(400).json({ error: 'token is required' });\n}","typeGuard":null,"tryCatchPattern":"const { sessionToken, error } = await TemporaryAuthToken.validate(publicToken);\nif (error === 'Invalid token.') {\n  // unknown/revoked token: respond 401 and offer to generate a new link\n  return res.status(401).json({ error: 'Invalid login link. Request a new one.' });\n}\nif (error) return res.status(401).json({ error });","preventionTips":["URL-decode and trim tokens before validating so encoding artifacts do not break the exact match","Point all instances at the same database so issued tokens are always findable","Treat tokens as potentially consumed or revoked; always offer a re-issue path"],"tags":["auth","temporary-token","lookup"],"backgroundTag":"invalid-auth-token","analyzedSha":"a145d4d87d086bdb31d50f9bf9cd9c46d311780c","analyzedAt":"2026-08-18T10:02:21.017Z","contentChangedAt":"2026-08-18T10:02:21.017Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}