{"record":{"id":"8e8bf68293124c01","repo":"Mintplex-Labs/anything-llm","slug":"token-expired","errorCode":null,"errorMessage":"Token expired.","messagePattern":"Token expired\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/models/temporaryAuthToken.js","lineNumber":83,"sourceCode":"   * 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    }\n  },","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/526360e320da9d1b36074be5ed64fe76e5bbfbbd/server/models/temporaryAuthToken.js#L65-L101","documentation":"Thrown by TemporaryAuthToken.validate when token.expiresAt < new Date(). Tokens are created with a fixed lifetime (this.expiry). The finally block still deletes the token afterward, so an expired token is also consumed by the failed attempt.","triggerScenarios":"GET /request-token/sso/simple?token=<X> where more than the configured expiry window has elapsed since TemporaryAuthToken.issue created the row.","commonSituations":"The SSO link sat in an email/chat for too long before the user clicked it. The user's device was offline. Note: the source comment says '1 hour' but this.expiry is 1000*60*6 (6 minutes) — treat the effective window as ~6 minutes unless the constant is corrected.","solutions":["Issue a new token; the old one is now deleted and cannot be reused.","If the window is too short for your workflow, increase TemporaryAuthToken.expiry to a larger value (e.g. 1000*60*60 for one hour) and fix the misleading comment.","Deliver SSO links through a channel the user will act on promptly."],"exampleFix":"// before (expiry is ~6 minutes despite the comment)\nexpiry: 1000 * 60 * 6, // 1 hour\n// after\nexpiry: 1000 * 60 * 60, // 1 hour","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"const { error } = await TemporaryAuthToken.validate(token);\nif (error === 'Token expired.') {\n  const { token: fresh } = await TemporaryAuthToken.issue(userId);\n  // send a new link\n}","preventionTips":["Deliver SSO links through a channel the user checks immediately.","If the default 6-minute window is too short, raise TemporaryAuthToken.expiry and correct the misleading '1 hour' comment.","Discard expired links rather than retrying them."],"tags":["sso","temporary-auth-token","authentication","expiry"],"backgroundTag":null,"analyzedSha":"526360e320da9d1b36074be5ed64fe76e5bbfbbd","analyzedAt":"2026-08-13T01:45:47.170Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}