{"version":3,"file":"error.mjs","names":[],"sources":["../../../src/api/routes/error.ts"],"sourcesContent":["import type { BetterAuthOptions } from \"@better-auth/core\";\nimport { createAuthEndpoint } from \"@better-auth/core/api\";\nimport { isProduction } from \"@better-auth/core/env\";\nimport { HIDE_METADATA } from \"../../utils/hide-metadata\";\n\nfunction sanitize(input: string): string {\n\t// Replace & last to avoid double-encoding existing HTML entities\n\t// Match & only when it's not already part of an HTML entity\n\treturn input\n\t\t.replace(/</g, \"&lt;\")\n\t\t.replace(/>/g, \"&gt;\")\n\t\t.replace(/\"/g, \"&quot;\")\n\t\t.replace(/'/g, \"&#39;\")\n\t\t.replace(/&(?!amp;|lt;|gt;|quot;|#39;|#x[0-9a-fA-F]+;|#[0-9]+;)/g, \"&amp;\");\n}\n\nconst html = (\n\toptions: BetterAuthOptions,\n\tcode: string = \"Unknown\",\n\tdescription: string | null = null,\n) => {\n\tconst custom = options.onAPIError?.customizeDefaultErrorPage;\n\treturn `<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>Error</title>\n    <style>\n      * {\n        box-sizing: border-box;\n      }\n      body {\n        font-family: ${custom?.font?.defaultFamily || \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif\"};\n        background: ${custom?.colors?.background || \"var(--background)\"};\n        color: var(--foreground);\n        margin: 0;\n      }\n      :root,\n      :host {\n        --spacing: 0.25rem;\n        --container-md: 28rem;\n        --text-sm: ${custom?.size?.textSm || \"0.875rem\"};\n        --text-sm--line-height: calc(1.25 / 0.875);\n        --text-2xl: ${custom?.size?.text2xl || \"1.5rem\"};\n        --text-2xl--line-height: calc(2 / 1.5);\n        --text-4xl: ${custom?.size?.text4xl || \"2.25rem\"};\n        --text-4xl--line-height: calc(2.5 / 2.25);\n        --text-6xl: ${custom?.size?.text6xl || \"3rem\"};\n        --text-6xl--line-height: 1;\n        --font-weight-medium: 500;\n        --font-weight-semibold: 600;\n        --font-weight-bold: 700;\n        --default-transition-duration: 150ms;\n        --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n        --radius: ${custom?.size?.radiusSm || \"0.625rem\"};\n        --default-mono-font-family: ${custom?.font?.monoFamily || \"var(--font-geist-mono)\"};\n        --primary: ${custom?.colors?.primary || \"black\"};\n        --primary-foreground: ${custom?.colors?.primaryForeground || \"white\"};\n        --background: ${custom?.colors?.background || \"white\"};\n        --foreground: ${custom?.colors?.foreground || \"oklch(0.271 0 0)\"};\n        --border: ${custom?.colors?.border || \"oklch(0.89 0 0)\"};\n        --destructive: ${custom?.colors?.destructive || \"oklch(0.55 0.15 25.723)\"};\n        --muted-foreground: ${custom?.colors?.mutedForeground || \"oklch(0.545 0 0)\"};\n        --corner-border: ${custom?.colors?.cornerBorder || \"#404040\"};\n      }\n\n      button, .btn {\n        cursor: pointer;\n        background: none;\n        border: none;\n        color: inherit;\n        font: inherit;\n        transition: all var(--default-transition-duration)\n          var(--default-transition-timing-function);\n      }\n      button:hover, .btn:hover {\n        opacity: 0.8;\n      }\n\n      @media (prefers-color-scheme: dark) {\n        :root,\n        :host {\n          --primary: ${custom?.colors?.primary || \"white\"};\n          --primary-foreground: ${custom?.colors?.primaryForeground || \"black\"};\n          --background: ${custom?.colors?.background || \"oklch(0.15 0 0)\"};\n          --foreground: ${custom?.colors?.foreground || \"oklch(0.98 0 0)\"};\n          --border: ${custom?.colors?.border || \"oklch(0.27 0 0)\"};\n          --destructive: ${custom?.colors?.destructive || \"oklch(0.65 0.15 25.723)\"};\n          --muted-foreground: ${custom?.colors?.mutedForeground || \"oklch(0.65 0 0)\"};\n          --corner-border: ${custom?.colors?.cornerBorder || \"#a0a0a0\"};\n        }\n      }\n      @media (max-width: 640px) {\n        :root, :host {\n          --text-6xl: 2.5rem;\n          --text-2xl: 1.25rem;\n          --text-sm: 0.8125rem;\n        }\n      }\n      @media (max-width: 480px) {\n        :root, :host {\n          --text-6xl: 2rem;\n          --text-2xl: 1.125rem;\n        }\n      }\n    </style>\n  </head>\n  <body style=\"width: 100vw; min-height: 100vh; overflow-x: hidden; overflow-y: auto;\">\n    <div\n        style=\"\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            justify-content: center;\n            gap: 1.5rem;\n            position: relative;\n            width: 100%;\n            min-height: 100vh;\n            padding: 1rem;\n        \"\n        >\n${\n\tcustom?.disableBackgroundGrid\n\t\t? \"\"\n\t\t: `\n      <div\n        style=\"\n          position: absolute;\n          inset: 0;\n          background-image: linear-gradient(to right, ${custom?.colors?.gridColor || \"var(--border)\"} 1px, transparent 1px),\n            linear-gradient(to bottom, ${custom?.colors?.gridColor || \"var(--border)\"} 1px, transparent 1px);\n          background-size: 40px 40px;\n          opacity: 0.6;\n          pointer-events: none;\n          width: 100vw;\n          height: 100vh;\n        \"\n      ></div>\n      <div\n        style=\"\n          position: absolute;\n          inset: 0;\n          display: flex;\n          align-items: center;\n          justify-content: center;\n          background: ${custom?.colors?.background || \"var(--background)\"};\n          mask-image: radial-gradient(ellipse at center, transparent 20%, black);\n          -webkit-mask-image: radial-gradient(ellipse at center, transparent 20%, black);\n          pointer-events: none;\n        \"\n      ></div>\n`\n}\n\n<div\n  style=\"\n    position: relative;\n    z-index: 10;\n    border: 2px solid var(--border);\n    background: ${custom?.colors?.cardBackground || \"var(--background)\"};\n    padding: 1.5rem;\n    max-width: 42rem;\n    width: 100%;\n  \"\n>\n    ${\n\t\t\tcustom?.disableCornerDecorations\n\t\t\t\t? \"\"\n\t\t\t\t: `\n        <!-- Corner decorations -->\n        <div\n          style=\"\n            position: absolute;\n            top: -2px;\n            left: -2px;\n            width: 2rem;\n            height: 2rem;\n            border-top: 4px solid var(--corner-border);\n            border-left: 4px solid var(--corner-border);\n          \"\n        ></div>\n        <div\n          style=\"\n            position: absolute;\n            top: -2px;\n            right: -2px;\n            width: 2rem;\n            height: 2rem;\n            border-top: 4px solid var(--corner-border);\n            border-right: 4px solid var(--corner-border);\n          \"\n        ></div>\n  \n        <div\n          style=\"\n            position: absolute;\n            bottom: -2px;\n            left: -2px;\n            width: 2rem;\n            height: 2rem;\n            border-bottom: 4px solid var(--corner-border);\n            border-left: 4px solid var(--corner-border);\n          \"\n        ></div>\n        <div\n          style=\"\n            position: absolute;\n            bottom: -2px;\n            right: -2px;\n            width: 2rem;\n            height: 2rem;\n            border-bottom: 4px solid var(--corner-border);\n            border-right: 4px solid var(--corner-border);\n          \"\n        ></div>`\n\t\t}\n\n        <div style=\"text-align: center; margin-bottom: 1.5rem;\">\n          <div style=\"margin-bottom: 1.5rem;\">\n            <div\n              style=\"\n                display: inline-block;\n                border: 2px solid ${custom?.disableTitleBorder ? \"transparent\" : custom?.colors?.titleBorder || \"var(--destructive)\"};\n                padding: 0.375rem 1rem;\n              \"\n            >\n              <h1\n                style=\"\n                  font-size: var(--text-6xl);\n                  font-weight: var(--font-weight-semibold);\n                  color: ${custom?.colors?.titleColor || \"var(--foreground)\"};\n                  letter-spacing: -0.02em;\n                  margin: 0;\n                \"\n              >\n                ERROR\n              </h1>\n            </div>\n            <div\n              style=\"\n                height: 2px;\n                background-color: var(--border);\n                width: calc(100% + 3rem);\n                margin-left: -1.5rem;\n                margin-top: 1.5rem;\n              \"\n            ></div>\n          </div>\n\n          <h2\n            style=\"\n              font-size: var(--text-2xl);\n              font-weight: var(--font-weight-semibold);\n              color: var(--foreground);\n              margin: 0 0 1rem;\n            \"\n          >\n            Something went wrong\n          </h2>\n\n          <div\n            style=\"\n                display: inline-flex;\n                align-items: center;\n                gap: 0.5rem;\n                border: 2px solid var(--border);\n                background-color: var(--muted);\n                padding: 0.375rem 0.75rem;\n                margin: 0 0 1rem;\n                flex-wrap: wrap;\n                justify-content: center;\n            \"\n            >\n            <span\n                style=\"\n                font-size: 0.75rem;\n                color: var(--muted-foreground);\n                font-weight: var(--font-weight-semibold);\n                \"\n            >\n                CODE:\n            </span>\n            <span\n                style=\"\n                font-size: var(--text-sm);\n                font-family: var(--default-mono-font-family, monospace);\n                color: var(--foreground);\n                word-break: break-all;\n                \"\n            >\n                ${sanitize(code)}\n            </span>\n            </div>\n\n          <p\n            style=\"\n              color: var(--muted-foreground);\n              max-width: 28rem;\n              margin: 0 auto;\n              font-size: var(--text-sm);\n              line-height: 1.5;\n              text-wrap: pretty;\n            \"\n          >\n            ${\n\t\t\t\t\t\t\t!description\n\t\t\t\t\t\t\t\t? \"We encountered an unexpected error. Please try again or return to the home page. If you're a developer, you can find more information about the error \" +\n\t\t\t\t\t\t\t\t\t`<a href='https://better-auth.com/docs/reference/errors/${encodeURIComponent(code)}' target='_blank' rel=\"noopener noreferrer\" style='color: var(--foreground); text-decoration: underline;'>here</a>.`\n\t\t\t\t\t\t\t\t: description\n\t\t\t\t\t\t}\n          </p>\n        </div>\n\n        <div\n          style=\"\n            display: flex;\n            gap: 0.75rem;\n            margin-top: 1.5rem;\n            justify-content: center;\n            flex-wrap: wrap;\n          \"\n        >\n          <a\n            href=\"/\"\n            style=\"\n              text-decoration: none;\n            \"\n          >\n            <div\n              style=\"\n                border: 2px solid var(--border);\n                background: var(--primary);\n                color: var(--primary-foreground);\n                padding: 0.5rem 1rem;\n                border-radius: 0;\n                white-space: nowrap;\n              \"\n              class=\"btn\"\n            >\n              Go Home\n            </div>\n          </a>\n          <a\n            href=\"https://better-auth.com/docs/reference/errors/${encodeURIComponent(code)}?askai=${encodeURIComponent(`What does the error code ${code} mean?`)}\"\n            target=\"_blank\"\n            rel=\"noopener noreferrer\"\n            style=\"\n              text-decoration: none;\n            \"\n          >\n            <div\n              style=\"\n                border: 2px solid var(--border);\n                background: transparent;\n                color: var(--foreground);\n                padding: 0.5rem 1rem;\n                border-radius: 0;\n                white-space: nowrap;\n              \"\n              class=\"btn\"\n            >\n              Ask AI\n            </div>\n          </a>\n        </div>\n      </div>\n    </div>\n  </body>\n</html>`;\n};\n\nexport const error = createAuthEndpoint(\n\t\"/error\",\n\t{\n\t\tmethod: \"GET\",\n\t\tmetadata: {\n\t\t\t...HIDE_METADATA,\n\t\t\topenapi: {\n\t\t\t\tdescription: \"Displays an error page\",\n\t\t\t\tresponses: {\n\t\t\t\t\t\"200\": {\n\t\t\t\t\t\tdescription: \"Success\",\n\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\"text/html\": {\n\t\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\tdescription: \"The HTML content of the error page\",\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t},\n\tasync (c) => {\n\t\tconst url = new URL(c.request?.url || \"\");\n\t\tconst unsanitizedCode = url.searchParams.get(\"error\") || \"UNKNOWN\";\n\t\tconst unsanitizedDescription =\n\t\t\turl.searchParams.get(\"error_description\") || null;\n\n\t\tconst isValid = /^[\\'A-Za-z0-9_-]+$/.test(unsanitizedCode || \"\");\n\t\tconst safeCode = isValid ? unsanitizedCode : \"UNKNOWN\";\n\t\tconst safeDescription = unsanitizedDescription\n\t\t\t? sanitize(unsanitizedDescription)\n\t\t\t: null;\n\n\t\tconst queryParams = new URLSearchParams();\n\t\tqueryParams.set(\"error\", safeCode);\n\t\tif (unsanitizedDescription) {\n\t\t\tqueryParams.set(\"error_description\", unsanitizedDescription);\n\t\t}\n\n\t\tconst options = c.context.options;\n\t\tconst errorURL = options.onAPIError?.errorURL;\n\n\t\tif (errorURL) {\n\t\t\treturn new Response(null, {\n\t\t\t\tstatus: 302,\n\t\t\t\theaders: {\n\t\t\t\t\tLocation: `${errorURL}${errorURL.includes(\"?\") ? \"&\" : \"?\"}${queryParams.toString()}`,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\tif (isProduction && !options.onAPIError?.customizeDefaultErrorPage) {\n\t\t\treturn new Response(null, {\n\t\t\t\tstatus: 302,\n\t\t\t\theaders: {\n\t\t\t\t\tLocation: `/?${queryParams.toString()}`,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\treturn new Response(html(c.context.options, safeCode, safeDescription), {\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"text/html\",\n\t\t\t},\n\t\t});\n\t},\n);\n"],"mappings":"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"}