create-croissant 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +3 -3
- package/package.json +16 -8
- package/template/.prettierignore +10 -0
- package/template/.prettierrc +11 -0
- package/template/README.md +88 -0
- package/template/apps/web/.env.example +4 -0
- package/template/apps/web/components.json +23 -0
- package/template/apps/web/drizzle.config.ts +11 -0
- package/template/apps/web/eslint.config.js +10 -0
- package/template/apps/web/node_modules/@better-auth/core/LICENSE.md +20 -0
- package/template/apps/web/node_modules/@better-auth/core/README.md +17 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/api/index.d.mts +278 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/api/index.mjs +56 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/async_hooks/index.d.mts +6 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/async_hooks/index.mjs +20 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/async_hooks/pure.index.d.mts +6 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/async_hooks/pure.index.mjs +33 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/context/endpoint-context.d.mts +18 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/context/endpoint-context.mjs +29 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/context/global.d.mts +6 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/context/global.mjs +36 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/context/index.d.mts +5 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/context/index.mjs +5 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/context/request-state.d.mts +27 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/context/request-state.mjs +47 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/context/transaction.d.mts +24 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/context/transaction.mjs +93 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/adapter/factory.d.mts +17 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/adapter/factory.mjs +754 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/adapter/get-default-field-name.d.mts +18 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/adapter/get-default-field-name.mjs +36 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/adapter/get-default-model-name.d.mts +12 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/adapter/get-default-model-name.mjs +30 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/adapter/get-field-attributes.d.mts +26 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/adapter/get-field-attributes.mjs +37 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/adapter/get-field-name.d.mts +18 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/adapter/get-field-name.mjs +31 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/adapter/get-id-field.d.mts +36 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/adapter/get-id-field.mjs +64 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/adapter/get-model-name.d.mts +12 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/adapter/get-model-name.mjs +21 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/adapter/index.d.mts +525 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/adapter/index.mjs +24 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/adapter/types.d.mts +105 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/adapter/utils.d.mts +7 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/adapter/utils.mjs +37 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/get-tables.d.mts +6 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/get-tables.mjs +265 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/index.d.mts +10 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/index.mjs +8 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/plugin.d.mts +12 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/schema/account.d.mts +28 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/schema/account.mjs +17 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/schema/rate-limit.d.mts +18 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/schema/rate-limit.mjs +9 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/schema/session.d.mts +23 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/schema/session.mjs +12 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/schema/shared.d.mts +10 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/schema/shared.mjs +9 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/schema/user.d.mts +22 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/schema/user.mjs +11 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/schema/verification.d.mts +21 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/schema/verification.mjs +10 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/db/type.d.mts +167 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/env/color-depth.d.mts +4 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/env/color-depth.mjs +86 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/env/env-impl.d.mts +32 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/env/env-impl.mjs +81 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/env/index.d.mts +4 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/env/index.mjs +4 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/env/logger.d.mts +48 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/env/logger.mjs +79 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/error/codes.d.mts +68 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/error/codes.mjs +54 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/error/index.d.mts +19 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/error/index.mjs +27 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/index.d.mts +9 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/index.mjs +1 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/instrumentation/api.mjs +12 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/instrumentation/attributes.d.mts +11 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/instrumentation/attributes.mjs +10 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/instrumentation/index.d.mts +3 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/instrumentation/index.mjs +3 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/instrumentation/noop.mjs +42 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/instrumentation/pure.index.d.mts +7 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/instrumentation/pure.index.mjs +7 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/instrumentation/tracer.d.mts +13 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/instrumentation/tracer.mjs +53 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/oauth2/client-credentials-token.d.mts +56 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/oauth2/client-credentials-token.mjs +64 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/oauth2/create-authorization-url.d.mts +44 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/oauth2/create-authorization-url.mjs +41 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/oauth2/index.d.mts +8 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/oauth2/index.mjs +7 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/oauth2/oauth-provider.d.mts +192 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/oauth2/refresh-access-token.d.mts +54 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/oauth2/refresh-access-token.mjs +73 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/oauth2/utils.d.mts +16 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/oauth2/utils.mjs +37 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/oauth2/validate-authorization-code.d.mts +85 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/oauth2/validate-authorization-code.mjs +79 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/oauth2/verify.d.mts +42 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/oauth2/verify.mjs +92 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/apple.d.mts +126 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/apple.mjs +107 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/atlassian.d.mts +70 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/atlassian.mjs +80 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/cognito.d.mts +85 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/cognito.mjs +162 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/discord.d.mts +124 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/discord.mjs +62 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/dropbox.d.mts +69 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/dropbox.mjs +72 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/facebook.d.mts +79 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/facebook.mjs +124 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/figma.d.mts +61 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/figma.mjs +83 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/github.d.mts +102 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/github.mjs +92 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/gitlab.d.mts +123 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/gitlab.mjs +79 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/google.d.mts +97 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/google.mjs +109 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/huggingface.d.mts +83 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/huggingface.mjs +73 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/index.d.mts +1834 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/index.mjs +78 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/kakao.d.mts +161 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/kakao.mjs +70 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/kick.d.mts +73 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/kick.mjs +68 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/line.d.mts +105 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/line.mjs +110 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/linear.d.mts +68 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/linear.mjs +85 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/linkedin.d.mts +67 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/linkedin.mjs +73 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/microsoft-entra-id.d.mts +174 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/microsoft-entra-id.mjs +140 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/naver.d.mts +92 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/naver.mjs +65 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/notion.d.mts +64 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/notion.mjs +72 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/paybin.d.mts +71 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/paybin.mjs +81 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/paypal.d.mts +129 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/paypal.mjs +140 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/polar.d.mts +74 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/polar.mjs +71 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/railway.d.mts +65 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/railway.mjs +74 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/reddit.d.mts +62 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/reddit.mjs +80 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/roblox.d.mts +70 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/roblox.mjs +57 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/salesforce.d.mts +79 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/salesforce.mjs +87 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/slack.d.mts +83 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/slack.mjs +66 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/spotify.d.mts +63 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/spotify.mjs +69 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/tiktok.d.mts +168 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/tiktok.mjs +60 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/twitch.d.mts +79 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/twitch.mjs +75 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/twitter.d.mts +126 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/twitter.mjs +85 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/vercel.d.mts +62 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/vercel.mjs +58 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/vk.d.mts +70 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/vk.mjs +81 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/wechat.d.mts +113 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/wechat.mjs +81 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/zoom.d.mts +163 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/social-providers/zoom.mjs +69 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/types/context.d.mts +277 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/types/cookie.d.mts +15 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/types/helper.d.mts +10 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/types/index.d.mts +9 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/types/init-options.d.mts +1358 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/types/plugin-client.d.mts +113 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/types/plugin.d.mts +124 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/types/secret.d.mts +11 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/utils/async.d.mts +22 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/utils/async.mjs +32 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/utils/db.d.mts +9 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/utils/db.mjs +15 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/utils/deprecate.d.mts +9 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/utils/deprecate.mjs +16 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/utils/error-codes.d.mts +13 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/utils/error-codes.mjs +10 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/utils/fetch-metadata.d.mts +4 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/utils/fetch-metadata.mjs +6 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/utils/host.d.mts +147 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/utils/host.mjs +291 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/utils/id.d.mts +4 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/utils/id.mjs +7 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/utils/ip.d.mts +54 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/utils/ip.mjs +116 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/utils/is-api-error.d.mts +6 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/utils/is-api-error.mjs +8 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/utils/json.d.mts +4 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/utils/json.mjs +41 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/utils/string.d.mts +4 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/utils/string.mjs +6 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/utils/url.d.mts +20 -0
- package/template/apps/web/node_modules/@better-auth/core/dist/utils/url.mjs +31 -0
- package/template/apps/web/node_modules/@better-auth/core/package.json +193 -0
- package/template/apps/web/node_modules/@better-auth/core/src/api/index.ts +140 -0
- package/template/apps/web/node_modules/@better-auth/core/src/async_hooks/index.ts +40 -0
- package/template/apps/web/node_modules/@better-auth/core/src/async_hooks/pure.index.ts +46 -0
- package/template/apps/web/node_modules/@better-auth/core/src/context/endpoint-context.ts +50 -0
- package/template/apps/web/node_modules/@better-auth/core/src/context/global.ts +57 -0
- package/template/apps/web/node_modules/@better-auth/core/src/context/index.ts +23 -0
- package/template/apps/web/node_modules/@better-auth/core/src/context/request-state.ts +91 -0
- package/template/apps/web/node_modules/@better-auth/core/src/context/transaction.ts +136 -0
- package/template/apps/web/node_modules/@better-auth/core/src/db/adapter/factory.ts +1440 -0
- package/template/apps/web/node_modules/@better-auth/core/src/db/adapter/get-default-field-name.ts +59 -0
- package/template/apps/web/node_modules/@better-auth/core/src/db/adapter/get-default-model-name.ts +51 -0
- package/template/apps/web/node_modules/@better-auth/core/src/db/adapter/get-field-attributes.ts +62 -0
- package/template/apps/web/node_modules/@better-auth/core/src/db/adapter/get-field-name.ts +43 -0
- package/template/apps/web/node_modules/@better-auth/core/src/db/adapter/get-id-field.ts +150 -0
- package/template/apps/web/node_modules/@better-auth/core/src/db/adapter/get-model-name.ts +36 -0
- package/template/apps/web/node_modules/@better-auth/core/src/db/adapter/index.ts +567 -0
- package/template/apps/web/node_modules/@better-auth/core/src/db/adapter/types.ts +132 -0
- package/template/apps/web/node_modules/@better-auth/core/src/db/adapter/utils.ts +61 -0
- package/template/apps/web/node_modules/@better-auth/core/src/db/get-tables.ts +296 -0
- package/template/apps/web/node_modules/@better-auth/core/src/db/index.ts +43 -0
- package/template/apps/web/node_modules/@better-auth/core/src/db/plugin.ts +11 -0
- package/template/apps/web/node_modules/@better-auth/core/src/db/schema/account.ts +47 -0
- package/template/apps/web/node_modules/@better-auth/core/src/db/schema/rate-limit.ts +36 -0
- package/template/apps/web/node_modules/@better-auth/core/src/db/schema/session.ts +29 -0
- package/template/apps/web/node_modules/@better-auth/core/src/db/schema/shared.ts +7 -0
- package/template/apps/web/node_modules/@better-auth/core/src/db/schema/user.ts +28 -0
- package/template/apps/web/node_modules/@better-auth/core/src/db/schema/verification.ts +28 -0
- package/template/apps/web/node_modules/@better-auth/core/src/db/type.ts +333 -0
- package/template/apps/web/node_modules/@better-auth/core/src/env/color-depth.ts +172 -0
- package/template/apps/web/node_modules/@better-auth/core/src/env/env-impl.ts +124 -0
- package/template/apps/web/node_modules/@better-auth/core/src/env/index.ts +23 -0
- package/template/apps/web/node_modules/@better-auth/core/src/env/logger.ts +145 -0
- package/template/apps/web/node_modules/@better-auth/core/src/error/codes.ts +71 -0
- package/template/apps/web/node_modules/@better-auth/core/src/error/index.ts +35 -0
- package/template/apps/web/node_modules/@better-auth/core/src/index.ts +1 -0
- package/template/apps/web/node_modules/@better-auth/core/src/instrumentation/api.ts +17 -0
- package/template/apps/web/node_modules/@better-auth/core/src/instrumentation/attributes.ts +22 -0
- package/template/apps/web/node_modules/@better-auth/core/src/instrumentation/index.ts +2 -0
- package/template/apps/web/node_modules/@better-auth/core/src/instrumentation/noop.ts +74 -0
- package/template/apps/web/node_modules/@better-auth/core/src/instrumentation/pure.index.ts +31 -0
- package/template/apps/web/node_modules/@better-auth/core/src/instrumentation/tracer.ts +95 -0
- package/template/apps/web/node_modules/@better-auth/core/src/oauth2/client-credentials-token.ts +126 -0
- package/template/apps/web/node_modules/@better-auth/core/src/oauth2/create-authorization-url.ts +89 -0
- package/template/apps/web/node_modules/@better-auth/core/src/oauth2/index.ts +33 -0
- package/template/apps/web/node_modules/@better-auth/core/src/oauth2/oauth-provider.ts +222 -0
- package/template/apps/web/node_modules/@better-auth/core/src/oauth2/refresh-access-token.ts +157 -0
- package/template/apps/web/node_modules/@better-auth/core/src/oauth2/utils.ts +51 -0
- package/template/apps/web/node_modules/@better-auth/core/src/oauth2/validate-authorization-code.ts +180 -0
- package/template/apps/web/node_modules/@better-auth/core/src/oauth2/verify.ts +221 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/apple.ts +231 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/atlassian.ts +133 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/cognito.ts +281 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/discord.ts +170 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/dropbox.ts +112 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/facebook.ts +215 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/figma.ts +118 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/github.ts +184 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/gitlab.ts +155 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/google.ts +204 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/huggingface.ts +119 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/index.ts +132 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/kakao.ts +179 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/kick.ts +109 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/line.ts +169 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/linear.ts +121 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/linkedin.ts +110 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/microsoft-entra-id.ts +352 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/naver.ts +113 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/notion.ts +108 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/paybin.ts +118 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/paypal.ts +263 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/polar.ts +111 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/railway.ts +100 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/reddit.ts +122 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/roblox.ts +112 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/salesforce.ts +159 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/slack.ts +112 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/spotify.ts +94 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/tiktok.ts +211 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/twitch.ts +112 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/twitter.ts +199 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/vercel.ts +87 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/vk.ts +125 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/wechat.ts +213 -0
- package/template/apps/web/node_modules/@better-auth/core/src/social-providers/zoom.ts +230 -0
- package/template/apps/web/node_modules/@better-auth/core/src/types/context.ts +415 -0
- package/template/apps/web/node_modules/@better-auth/core/src/types/cookie.ts +10 -0
- package/template/apps/web/node_modules/@better-auth/core/src/types/helper.ts +27 -0
- package/template/apps/web/node_modules/@better-auth/core/src/types/index.ts +40 -0
- package/template/apps/web/node_modules/@better-auth/core/src/types/init-options.ts +1610 -0
- package/template/apps/web/node_modules/@better-auth/core/src/types/plugin-client.ts +129 -0
- package/template/apps/web/node_modules/@better-auth/core/src/types/plugin.ts +163 -0
- package/template/apps/web/node_modules/@better-auth/core/src/types/secret.ts +8 -0
- package/template/apps/web/node_modules/@better-auth/core/src/utils/async.ts +53 -0
- package/template/apps/web/node_modules/@better-auth/core/src/utils/db.ts +20 -0
- package/template/apps/web/node_modules/@better-auth/core/src/utils/deprecate.ts +21 -0
- package/template/apps/web/node_modules/@better-auth/core/src/utils/error-codes.ts +68 -0
- package/template/apps/web/node_modules/@better-auth/core/src/utils/fetch-metadata.ts +3 -0
- package/template/apps/web/node_modules/@better-auth/core/src/utils/host.ts +401 -0
- package/template/apps/web/node_modules/@better-auth/core/src/utils/id.ts +5 -0
- package/template/apps/web/node_modules/@better-auth/core/src/utils/ip.ts +211 -0
- package/template/apps/web/node_modules/@better-auth/core/src/utils/is-api-error.ts +10 -0
- package/template/apps/web/node_modules/@better-auth/core/src/utils/json.ts +56 -0
- package/template/apps/web/node_modules/@better-auth/core/src/utils/string.ts +3 -0
- package/template/apps/web/node_modules/@better-auth/core/src/utils/url.ts +43 -0
- package/template/apps/web/node_modules/@better-auth/drizzle-adapter/LICENSE.md +20 -0
- package/template/apps/web/node_modules/@better-auth/drizzle-adapter/README.md +17 -0
- package/template/apps/web/node_modules/@better-auth/drizzle-adapter/dist/index.d.mts +47 -0
- package/template/apps/web/node_modules/@better-auth/drizzle-adapter/dist/index.mjs +458 -0
- package/template/apps/web/node_modules/@better-auth/drizzle-adapter/package.json +62 -0
- package/template/apps/web/node_modules/@better-auth/utils/README.md +384 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/base32.cjs +104 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/base32.d.cts +44 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/base32.d.mts +44 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/base32.d.ts +44 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/base32.mjs +101 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/base64.cjs +80 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/base64.d.cts +16 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/base64.d.mts +16 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/base64.d.ts +16 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/base64.mjs +77 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/binary.cjs +16 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/binary.d.cts +8 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/binary.d.mts +8 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/binary.d.ts +8 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/binary.mjs +14 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/ecdsa.cjs +90 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/ecdsa.d.cts +19 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/ecdsa.d.mts +19 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/ecdsa.d.ts +19 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/ecdsa.mjs +88 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/hash.cjs +31 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/hash.d.cts +7 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/hash.d.mts +7 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/hash.d.ts +7 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/hash.mjs +29 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/hex.cjs +40 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/hex.d.cts +8 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/hex.d.mts +8 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/hex.d.ts +8 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/hex.mjs +38 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/hmac.cjs +58 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/hmac.d.cts +9 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/hmac.d.mts +9 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/hmac.d.ts +9 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/hmac.mjs +56 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/index.cjs +10 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/index.d.cts +3 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/index.d.mts +3 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/index.d.ts +3 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/index.mjs +8 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/otp.cjs +90 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/otp.d.cts +13 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/otp.d.mts +13 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/otp.d.ts +13 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/otp.mjs +88 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/password.cjs +36 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/password.d.cts +4 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/password.d.mts +4 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/password.d.ts +4 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/password.mjs +33 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/password.node.cjs +47 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/password.node.d.cts +4 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/password.node.d.mts +4 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/password.node.d.ts +4 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/password.node.mjs +44 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/random.cjs +55 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/random.d.cts +4 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/random.d.mts +4 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/random.d.ts +4 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/random.mjs +53 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/rsa.cjs +76 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/rsa.d.cts +16 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/rsa.d.mts +16 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/rsa.d.ts +16 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/rsa.mjs +74 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/shared/utils.ecd028f7.d.cts +22 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/shared/utils.ecd028f7.d.mts +22 -0
- package/template/apps/web/node_modules/@better-auth/utils/dist/shared/utils.ecd028f7.d.ts +22 -0
- package/template/apps/web/node_modules/@better-auth/utils/package.json +95 -0
- package/template/apps/web/node_modules/better-call/LICENSE +21 -0
- package/template/apps/web/node_modules/better-call/dist/_virtual/_rolldown/runtime.cjs +29 -0
- package/template/apps/web/node_modules/better-call/dist/adapters/node/request.cjs +181 -0
- package/template/apps/web/node_modules/better-call/dist/adapters/node/request.cjs.map +1 -0
- package/template/apps/web/node_modules/better-call/dist/adapters/node/request.d.cts +16 -0
- package/template/apps/web/node_modules/better-call/dist/adapters/node/request.d.mts +16 -0
- package/template/apps/web/node_modules/better-call/dist/adapters/node/request.mjs +178 -0
- package/template/apps/web/node_modules/better-call/dist/adapters/node/request.mjs.map +1 -0
- package/template/apps/web/node_modules/better-call/dist/client.cjs +23 -0
- package/template/apps/web/node_modules/better-call/dist/client.cjs.map +1 -0
- package/template/apps/web/node_modules/better-call/dist/client.d.cts +53 -0
- package/template/apps/web/node_modules/better-call/dist/client.d.mts +53 -0
- package/template/apps/web/node_modules/better-call/dist/client.mjs +14 -0
- package/template/apps/web/node_modules/better-call/dist/client.mjs.map +1 -0
- package/template/apps/web/node_modules/better-call/dist/context.cjs +103 -0
- package/template/apps/web/node_modules/better-call/dist/context.cjs.map +1 -0
- package/template/apps/web/node_modules/better-call/dist/context.d.cts +341 -0
- package/template/apps/web/node_modules/better-call/dist/context.d.mts +341 -0
- package/template/apps/web/node_modules/better-call/dist/context.mjs +103 -0
- package/template/apps/web/node_modules/better-call/dist/context.mjs.map +1 -0
- package/template/apps/web/node_modules/better-call/dist/cookies.cjs +87 -0
- package/template/apps/web/node_modules/better-call/dist/cookies.cjs.map +1 -0
- package/template/apps/web/node_modules/better-call/dist/cookies.d.cts +103 -0
- package/template/apps/web/node_modules/better-call/dist/cookies.d.mts +103 -0
- package/template/apps/web/node_modules/better-call/dist/cookies.mjs +84 -0
- package/template/apps/web/node_modules/better-call/dist/cookies.mjs.map +1 -0
- package/template/apps/web/node_modules/better-call/dist/crypto.cjs +39 -0
- package/template/apps/web/node_modules/better-call/dist/crypto.cjs.map +1 -0
- package/template/apps/web/node_modules/better-call/dist/crypto.mjs +36 -0
- package/template/apps/web/node_modules/better-call/dist/crypto.mjs.map +1 -0
- package/template/apps/web/node_modules/better-call/dist/endpoint.cjs +70 -0
- package/template/apps/web/node_modules/better-call/dist/endpoint.cjs.map +1 -0
- package/template/apps/web/node_modules/better-call/dist/endpoint.d.cts +475 -0
- package/template/apps/web/node_modules/better-call/dist/endpoint.d.mts +475 -0
- package/template/apps/web/node_modules/better-call/dist/endpoint.mjs +70 -0
- package/template/apps/web/node_modules/better-call/dist/endpoint.mjs.map +1 -0
- package/template/apps/web/node_modules/better-call/dist/error.cjs +141 -0
- package/template/apps/web/node_modules/better-call/dist/error.cjs.map +1 -0
- package/template/apps/web/node_modules/better-call/dist/error.d.cts +103 -0
- package/template/apps/web/node_modules/better-call/dist/error.d.mts +103 -0
- package/template/apps/web/node_modules/better-call/dist/error.mjs +133 -0
- package/template/apps/web/node_modules/better-call/dist/error.mjs.map +1 -0
- package/template/apps/web/node_modules/better-call/dist/helper.d.cts +12 -0
- package/template/apps/web/node_modules/better-call/dist/helper.d.mts +12 -0
- package/template/apps/web/node_modules/better-call/dist/index.cjs +28 -0
- package/template/apps/web/node_modules/better-call/dist/index.d.cts +11 -0
- package/template/apps/web/node_modules/better-call/dist/index.d.mts +11 -0
- package/template/apps/web/node_modules/better-call/dist/index.mjs +10 -0
- package/template/apps/web/node_modules/better-call/dist/middleware.cjs +52 -0
- package/template/apps/web/node_modules/better-call/dist/middleware.cjs.map +1 -0
- package/template/apps/web/node_modules/better-call/dist/middleware.d.cts +123 -0
- package/template/apps/web/node_modules/better-call/dist/middleware.d.mts +123 -0
- package/template/apps/web/node_modules/better-call/dist/middleware.mjs +52 -0
- package/template/apps/web/node_modules/better-call/dist/middleware.mjs.map +1 -0
- package/template/apps/web/node_modules/better-call/dist/node.cjs +18 -0
- package/template/apps/web/node_modules/better-call/dist/node.cjs.map +1 -0
- package/template/apps/web/node_modules/better-call/dist/node.d.cts +9 -0
- package/template/apps/web/node_modules/better-call/dist/node.d.mts +9 -0
- package/template/apps/web/node_modules/better-call/dist/node.mjs +15 -0
- package/template/apps/web/node_modules/better-call/dist/node.mjs.map +1 -0
- package/template/apps/web/node_modules/better-call/dist/openapi.cjs +191 -0
- package/template/apps/web/node_modules/better-call/dist/openapi.cjs.map +1 -0
- package/template/apps/web/node_modules/better-call/dist/openapi.d.cts +113 -0
- package/template/apps/web/node_modules/better-call/dist/openapi.d.mts +113 -0
- package/template/apps/web/node_modules/better-call/dist/openapi.mjs +189 -0
- package/template/apps/web/node_modules/better-call/dist/openapi.mjs.map +1 -0
- package/template/apps/web/node_modules/better-call/dist/router.cjs +118 -0
- package/template/apps/web/node_modules/better-call/dist/router.cjs.map +1 -0
- package/template/apps/web/node_modules/better-call/dist/router.d.cts +103 -0
- package/template/apps/web/node_modules/better-call/dist/router.d.mts +103 -0
- package/template/apps/web/node_modules/better-call/dist/router.mjs +117 -0
- package/template/apps/web/node_modules/better-call/dist/router.mjs.map +1 -0
- package/template/apps/web/node_modules/better-call/dist/standard-schema.d.cts +59 -0
- package/template/apps/web/node_modules/better-call/dist/standard-schema.d.mts +59 -0
- package/template/apps/web/node_modules/better-call/dist/to-response.cjs +153 -0
- package/template/apps/web/node_modules/better-call/dist/to-response.cjs.map +1 -0
- package/template/apps/web/node_modules/better-call/dist/to-response.d.cts +12 -0
- package/template/apps/web/node_modules/better-call/dist/to-response.d.mts +12 -0
- package/template/apps/web/node_modules/better-call/dist/to-response.mjs +153 -0
- package/template/apps/web/node_modules/better-call/dist/to-response.mjs.map +1 -0
- package/template/apps/web/node_modules/better-call/dist/utils.cjs +86 -0
- package/template/apps/web/node_modules/better-call/dist/utils.cjs.map +1 -0
- package/template/apps/web/node_modules/better-call/dist/utils.mjs +82 -0
- package/template/apps/web/node_modules/better-call/dist/utils.mjs.map +1 -0
- package/template/apps/web/node_modules/better-call/dist/validator.cjs +58 -0
- package/template/apps/web/node_modules/better-call/dist/validator.cjs.map +1 -0
- package/template/apps/web/node_modules/better-call/dist/validator.mjs +57 -0
- package/template/apps/web/node_modules/better-call/dist/validator.mjs.map +1 -0
- package/template/apps/web/node_modules/better-call/package.json +96 -0
- package/template/apps/web/node_modules/set-cookie-parser/LICENSE +21 -0
- package/template/apps/web/node_modules/set-cookie-parser/README.md +169 -0
- package/template/apps/web/node_modules/set-cookie-parser/dist/.eslintrc.cjs +16 -0
- package/template/apps/web/node_modules/set-cookie-parser/dist/set-cookie.cjs +260 -0
- package/template/apps/web/node_modules/set-cookie-parser/lib/set-cookie.d.ts +119 -0
- package/template/apps/web/node_modules/set-cookie-parser/lib/set-cookie.js +265 -0
- package/template/apps/web/node_modules/set-cookie-parser/package.json +61 -0
- package/template/apps/web/package.json +44 -0
- package/template/apps/web/public/favicon.ico +0 -0
- package/template/apps/web/public/manifest.json +25 -0
- package/template/apps/web/public/robots.txt +3 -0
- package/template/apps/web/src/components/app-sidebar.tsx +139 -0
- package/template/apps/web/src/components/login-form.tsx +111 -0
- package/template/apps/web/src/components/search-form.tsx +27 -0
- package/template/apps/web/src/components/signup-form.tsx +137 -0
- package/template/apps/web/src/components/version-switcher.tsx +64 -0
- package/template/apps/web/src/hooks/use-mobile.ts +19 -0
- package/template/apps/web/src/lib/auth-client.ts +3 -0
- package/template/apps/web/src/lib/auth-utils.ts +15 -0
- package/template/apps/web/src/lib/orpc.ts +32 -0
- package/template/apps/web/src/routeTree.gen.ts +282 -0
- package/template/apps/web/src/router.tsx +20 -0
- package/template/apps/web/src/routes/__root.tsx +53 -0
- package/template/apps/web/src/routes/api/auth/$.ts +15 -0
- package/template/apps/web/src/routes/api/rpc.$.ts +34 -0
- package/template/apps/web/src/routes/client-orpc-auth.tsx +62 -0
- package/template/apps/web/src/routes/client-orpc.tsx +43 -0
- package/template/apps/web/src/routes/dashboard.tsx +59 -0
- package/template/apps/web/src/routes/index.tsx +57 -0
- package/template/apps/web/src/routes/isr.tsx +33 -0
- package/template/apps/web/src/routes/login.tsx +16 -0
- package/template/apps/web/src/routes/signup.tsx +16 -0
- package/template/apps/web/src/routes/ssr-orpc-auth.tsx +53 -0
- package/template/apps/web/src/routes/ssr-orpc.tsx +36 -0
- package/template/apps/web/tsconfig.json +29 -0
- package/template/apps/web/vite.config.ts +19 -0
- package/template/docker-compose.yml +16 -0
- package/template/package.json +35 -0
- package/template/packages/auth/eslint.config.ts +3 -0
- package/template/packages/auth/package.json +24 -0
- package/template/packages/auth/src/lib/auth.ts +13 -0
- package/template/packages/auth/tsconfig.json +17 -0
- package/template/packages/auth/tsconfig.lint.json +14 -0
- package/template/packages/db/eslint.config.ts +3 -0
- package/template/packages/db/package.json +27 -0
- package/template/packages/db/src/auth-schema.ts +93 -0
- package/template/packages/db/src/index.ts +7 -0
- package/template/packages/db/src/planets-schema.ts +13 -0
- package/template/packages/db/src/schema.ts +2 -0
- package/template/packages/db/tsconfig.json +17 -0
- package/template/packages/db/tsconfig.lint.json +14 -0
- package/template/packages/orpc/eslint.config.ts +3 -0
- package/template/packages/orpc/package.json +21 -0
- package/template/packages/orpc/src/lib/router.ts +52 -0
- package/template/packages/orpc/tsconfig.json +17 -0
- package/template/packages/orpc/tsconfig.lint.json +14 -0
- package/template/packages/ui/components.json +23 -0
- package/template/packages/ui/eslint.config.ts +3 -0
- package/template/packages/ui/package.json +48 -0
- package/template/packages/ui/src/components/.gitkeep +0 -0
- package/template/packages/ui/src/components/accordion.tsx +72 -0
- package/template/packages/ui/src/components/alert-dialog.tsx +187 -0
- package/template/packages/ui/src/components/alert.tsx +77 -0
- package/template/packages/ui/src/components/aspect-ratio.tsx +22 -0
- package/template/packages/ui/src/components/avatar.tsx +107 -0
- package/template/packages/ui/src/components/badge.tsx +53 -0
- package/template/packages/ui/src/components/breadcrumb.tsx +125 -0
- package/template/packages/ui/src/components/button-group.tsx +88 -0
- package/template/packages/ui/src/components/button.tsx +59 -0
- package/template/packages/ui/src/components/calendar.tsx +229 -0
- package/template/packages/ui/src/components/card.tsx +103 -0
- package/template/packages/ui/src/components/carousel.tsx +240 -0
- package/template/packages/ui/src/components/chart.tsx +371 -0
- package/template/packages/ui/src/components/checkbox.tsx +29 -0
- package/template/packages/ui/src/components/collapsible.tsx +19 -0
- package/template/packages/ui/src/components/combobox.tsx +295 -0
- package/template/packages/ui/src/components/command.tsx +196 -0
- package/template/packages/ui/src/components/context-menu.tsx +271 -0
- package/template/packages/ui/src/components/dialog.tsx +158 -0
- package/template/packages/ui/src/components/direction.tsx +4 -0
- package/template/packages/ui/src/components/drawer.tsx +134 -0
- package/template/packages/ui/src/components/dropdown-menu.tsx +266 -0
- package/template/packages/ui/src/components/empty.tsx +105 -0
- package/template/packages/ui/src/components/field.tsx +237 -0
- package/template/packages/ui/src/components/hover-card.tsx +51 -0
- package/template/packages/ui/src/components/input-group.tsx +159 -0
- package/template/packages/ui/src/components/input-otp.tsx +85 -0
- package/template/packages/ui/src/components/input.tsx +20 -0
- package/template/packages/ui/src/components/item.tsx +202 -0
- package/template/packages/ui/src/components/kbd.tsx +26 -0
- package/template/packages/ui/src/components/label.tsx +20 -0
- package/template/packages/ui/src/components/menubar.tsx +280 -0
- package/template/packages/ui/src/components/native-select.tsx +61 -0
- package/template/packages/ui/src/components/navigation-menu.tsx +168 -0
- package/template/packages/ui/src/components/pagination.tsx +130 -0
- package/template/packages/ui/src/components/popover.tsx +88 -0
- package/template/packages/ui/src/components/progress.tsx +83 -0
- package/template/packages/ui/src/components/radio-group.tsx +36 -0
- package/template/packages/ui/src/components/resizable.tsx +50 -0
- package/template/packages/ui/src/components/scroll-area.tsx +53 -0
- package/template/packages/ui/src/components/select.tsx +201 -0
- package/template/packages/ui/src/components/separator.tsx +23 -0
- package/template/packages/ui/src/components/sheet.tsx +138 -0
- package/template/packages/ui/src/components/sidebar.tsx +726 -0
- package/template/packages/ui/src/components/skeleton.tsx +13 -0
- package/template/packages/ui/src/components/slider.tsx +52 -0
- package/template/packages/ui/src/components/sonner.tsx +50 -0
- package/template/packages/ui/src/components/spinner.tsx +10 -0
- package/template/packages/ui/src/components/switch.tsx +30 -0
- package/template/packages/ui/src/components/table.tsx +116 -0
- package/template/packages/ui/src/components/tabs.tsx +81 -0
- package/template/packages/ui/src/components/textarea.tsx +18 -0
- package/template/packages/ui/src/components/toggle-group.tsx +87 -0
- package/template/packages/ui/src/components/toggle.tsx +46 -0
- package/template/packages/ui/src/components/tooltip.tsx +64 -0
- package/template/packages/ui/src/hooks/.gitkeep +0 -0
- package/template/packages/ui/src/hooks/use-mobile.ts +19 -0
- package/template/packages/ui/src/lib/.gitkeep +0 -0
- package/template/packages/ui/src/lib/utils.ts +7 -0
- package/template/packages/ui/src/styles/globals.css +130 -0
- package/template/packages/ui/tsconfig.json +17 -0
- package/template/packages/ui/tsconfig.lint.json +14 -0
- package/template/tsconfig.json +9 -0
- package/template/turbo.json +24 -0
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { isValidIP, normalizeIP } from "./ip.mjs";
|
|
2
|
+
//#region src/utils/host.ts
|
|
3
|
+
/**
|
|
4
|
+
* Cloud provider instance metadata service FQDNs. These resolve to link-local
|
|
5
|
+
* IPs (usually `169.254.169.254`) inside their respective clouds and are
|
|
6
|
+
* prime SSRF targets.
|
|
7
|
+
*
|
|
8
|
+
* The IPs themselves are already caught by the `linkLocal` kind; this set
|
|
9
|
+
* only exists for the FQDN form that a naive server-side fetch might resolve
|
|
10
|
+
* via its own resolver.
|
|
11
|
+
*/
|
|
12
|
+
const CLOUD_METADATA_HOSTS = new Set([
|
|
13
|
+
"metadata.google.internal",
|
|
14
|
+
"metadata.goog",
|
|
15
|
+
"metadata",
|
|
16
|
+
"instance-data",
|
|
17
|
+
"instance-data.ec2.internal"
|
|
18
|
+
]);
|
|
19
|
+
/** Strip `[...]` if the entire input is bracketed (IPv6 literal form). */
|
|
20
|
+
function stripBrackets(host) {
|
|
21
|
+
if (host.length >= 2 && host.startsWith("[") && host.endsWith("]")) return host.slice(1, -1);
|
|
22
|
+
return host;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Strip trailing `:port` from host-with-port strings.
|
|
26
|
+
*
|
|
27
|
+
* - Bracketed IPv6 with port: `[::1]:8080` → `[::1]`
|
|
28
|
+
* - IPv4/FQDN with port: `127.0.0.1:3000` / `example.com:443` → base form
|
|
29
|
+
* - Bare IPv6: `::1` / `fe80::1` → unchanged (multiple colons means no port)
|
|
30
|
+
*/
|
|
31
|
+
function stripPort(host) {
|
|
32
|
+
if (host.startsWith("[")) {
|
|
33
|
+
const end = host.indexOf("]");
|
|
34
|
+
if (end === -1) return host;
|
|
35
|
+
return host.slice(0, end + 1);
|
|
36
|
+
}
|
|
37
|
+
const firstColon = host.indexOf(":");
|
|
38
|
+
if (firstColon === -1) return host;
|
|
39
|
+
if (host.indexOf(":", firstColon + 1) !== -1) return host;
|
|
40
|
+
return host.slice(0, firstColon);
|
|
41
|
+
}
|
|
42
|
+
/** Strip IPv6 zone identifier: `fe80::1%eth0` → `fe80::1`. */
|
|
43
|
+
function stripZoneId(host) {
|
|
44
|
+
const zone = host.indexOf("%");
|
|
45
|
+
if (zone === -1) return host;
|
|
46
|
+
return host.slice(0, zone);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Strip trailing dots (RFC 1034 absolute DNS form): `localhost.` → `localhost`.
|
|
50
|
+
* Without this, `metadata.google.internal.` would fall through to `public` and
|
|
51
|
+
* bypass the cloud-metadata / `.localhost` checks, since WHATWG URL parsing
|
|
52
|
+
* preserves the trailing dot in `url.hostname`.
|
|
53
|
+
*/
|
|
54
|
+
function stripTrailingDot(host) {
|
|
55
|
+
return host.replace(/\.+$/, "");
|
|
56
|
+
}
|
|
57
|
+
/** Fast dotted-decimal shape check. Does NOT validate octet bounds. */
|
|
58
|
+
function looksLikeIPv4(host) {
|
|
59
|
+
return /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(host);
|
|
60
|
+
}
|
|
61
|
+
/** Pack a validated dotted-decimal IPv4 into a 32-bit unsigned integer. */
|
|
62
|
+
function ipv4ToUint32(ip) {
|
|
63
|
+
const parts = ip.split(".");
|
|
64
|
+
return (Number(parts[0]) << 24 | Number(parts[1]) << 16 | Number(parts[2]) << 8 | Number(parts[3])) >>> 0;
|
|
65
|
+
}
|
|
66
|
+
/** Check whether a 32-bit value matches `prefix/length` (both unsigned). */
|
|
67
|
+
function inIPv4Range(value, prefix, length) {
|
|
68
|
+
if (length === 0) return true;
|
|
69
|
+
const mask = length === 32 ? 4294967295 : -1 << 32 - length >>> 0;
|
|
70
|
+
return (value & mask) === (prefix & mask);
|
|
71
|
+
}
|
|
72
|
+
function classifyIPv4(ip) {
|
|
73
|
+
if (ip === "0.0.0.0") return "unspecified";
|
|
74
|
+
if (ip === "255.255.255.255") return "broadcast";
|
|
75
|
+
const n = ipv4ToUint32(ip);
|
|
76
|
+
if (inIPv4Range(n, ipv4ToUint32("127.0.0.0"), 8)) return "loopback";
|
|
77
|
+
if (inIPv4Range(n, ipv4ToUint32("10.0.0.0"), 8)) return "private";
|
|
78
|
+
if (inIPv4Range(n, ipv4ToUint32("172.16.0.0"), 12)) return "private";
|
|
79
|
+
if (inIPv4Range(n, ipv4ToUint32("192.168.0.0"), 16)) return "private";
|
|
80
|
+
if (inIPv4Range(n, ipv4ToUint32("169.254.0.0"), 16)) return "linkLocal";
|
|
81
|
+
if (inIPv4Range(n, ipv4ToUint32("100.64.0.0"), 10)) return "sharedAddressSpace";
|
|
82
|
+
if (inIPv4Range(n, ipv4ToUint32("192.0.2.0"), 24)) return "documentation";
|
|
83
|
+
if (inIPv4Range(n, ipv4ToUint32("198.51.100.0"), 24)) return "documentation";
|
|
84
|
+
if (inIPv4Range(n, ipv4ToUint32("203.0.113.0"), 24)) return "documentation";
|
|
85
|
+
if (inIPv4Range(n, ipv4ToUint32("198.18.0.0"), 15)) return "benchmarking";
|
|
86
|
+
if (inIPv4Range(n, ipv4ToUint32("224.0.0.0"), 4)) return "multicast";
|
|
87
|
+
if (inIPv4Range(n, ipv4ToUint32("0.0.0.0"), 8)) return "reserved";
|
|
88
|
+
if (inIPv4Range(n, ipv4ToUint32("192.0.0.0"), 24)) return "reserved";
|
|
89
|
+
if (inIPv4Range(n, ipv4ToUint32("240.0.0.0"), 4)) return "reserved";
|
|
90
|
+
return "public";
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Extract an IPv4 address embedded in an expanded IPv6 literal.
|
|
94
|
+
*
|
|
95
|
+
* Used to recurse into tunnel/translation forms (6to4, NAT64, Teredo) so a
|
|
96
|
+
* private destination cannot be smuggled behind a syntactically-public IPv6
|
|
97
|
+
* literal. `startGroup` is the index of the first of two 16-bit groups in the
|
|
98
|
+
* expanded form (`0000:0000:...`). With `xor: true`, the 32-bit value is XORed
|
|
99
|
+
* with `0xffffffff` before decoding (Teredo obfuscates the client IPv4 this
|
|
100
|
+
* way).
|
|
101
|
+
*/
|
|
102
|
+
function extractEmbeddedIPv4(expanded, startGroup, options = {}) {
|
|
103
|
+
const offset = startGroup * 5;
|
|
104
|
+
const g1 = Number.parseInt(expanded.slice(offset, offset + 4), 16);
|
|
105
|
+
const g2 = Number.parseInt(expanded.slice(offset + 5, offset + 9), 16);
|
|
106
|
+
if (!Number.isFinite(g1) || !Number.isFinite(g2)) return null;
|
|
107
|
+
let combined = (g1 << 16 | g2) >>> 0;
|
|
108
|
+
if (options.xor) combined = (combined ^ 4294967295) >>> 0;
|
|
109
|
+
return `${combined >>> 24 & 255}.${combined >>> 16 & 255}.${combined >>> 8 & 255}.${combined & 255}`;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Classify an expanded, full-form, lowercase IPv6 address (no IPv4-mapped
|
|
113
|
+
* input — those are unmapped to IPv4 before reaching here).
|
|
114
|
+
*
|
|
115
|
+
* 6to4 (`2002::/16`), NAT64 (`64:ff9b::/96`) and Teredo (`2001:0000::/32`)
|
|
116
|
+
* embed an IPv4 that can route to private/loopback space. If the embedded
|
|
117
|
+
* IPv4 classifies as non-`public`, return `reserved` — blocks SSRF without
|
|
118
|
+
* advertising the address as a loopback literal for RFC 8252 §7.3 matching.
|
|
119
|
+
*/
|
|
120
|
+
function classifyIPv6(expanded) {
|
|
121
|
+
if (expanded === "0000:0000:0000:0000:0000:0000:0000:0000") return "unspecified";
|
|
122
|
+
if (expanded === "0000:0000:0000:0000:0000:0000:0000:0001") return "loopback";
|
|
123
|
+
const firstByte = Number.parseInt(expanded.slice(0, 2), 16);
|
|
124
|
+
const secondByte = Number.parseInt(expanded.slice(2, 4), 16);
|
|
125
|
+
if (firstByte === 255) return "multicast";
|
|
126
|
+
if (firstByte === 254 && (secondByte & 192) === 128) return "linkLocal";
|
|
127
|
+
if ((firstByte & 254) === 252) return "private";
|
|
128
|
+
if (expanded.startsWith("2001:0db8:")) return "documentation";
|
|
129
|
+
if (expanded.startsWith("2002:")) {
|
|
130
|
+
const embedded = extractEmbeddedIPv4(expanded, 1);
|
|
131
|
+
if (embedded && classifyIPv4(embedded) !== "public") return "reserved";
|
|
132
|
+
return "public";
|
|
133
|
+
}
|
|
134
|
+
if (expanded.startsWith("0064:ff9b:0000:0000:0000:0000:")) {
|
|
135
|
+
const embedded = extractEmbeddedIPv4(expanded, 6);
|
|
136
|
+
if (embedded && classifyIPv4(embedded) !== "public") return "reserved";
|
|
137
|
+
return "reserved";
|
|
138
|
+
}
|
|
139
|
+
if (expanded.startsWith("2001:0000:")) {
|
|
140
|
+
const embedded = extractEmbeddedIPv4(expanded, 6, { xor: true });
|
|
141
|
+
if (embedded && classifyIPv4(embedded) !== "public") return "reserved";
|
|
142
|
+
return "reserved";
|
|
143
|
+
}
|
|
144
|
+
if (expanded.startsWith("0100:0000:0000:0000:")) return "reserved";
|
|
145
|
+
return "public";
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Classify a host string according to RFC 6890 / RFC 6761.
|
|
149
|
+
*
|
|
150
|
+
* Accepts inputs in any of these shapes and normalizes before classifying:
|
|
151
|
+
*
|
|
152
|
+
* - Bare IPv4: `127.0.0.1`
|
|
153
|
+
* - Bare IPv6: `::1`, `fe80::1%eth0`
|
|
154
|
+
* - Bracketed IPv6: `[::1]`
|
|
155
|
+
* - Host with port: `localhost:3000`, `127.0.0.1:443`, `[::1]:8080`
|
|
156
|
+
* - FQDN: `example.com`, `tenant.localhost`
|
|
157
|
+
* - IPv4-mapped IPv6: `::ffff:192.0.2.1` (reported as `literal: "ipv4"`)
|
|
158
|
+
*
|
|
159
|
+
* Invalid or non-resolvable FQDNs are returned as `{ kind: "public", literal: "fqdn" }`
|
|
160
|
+
* — this function never throws. Callers that need structural validation must
|
|
161
|
+
* combine this with a URL/hostname validator upstream.
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* classifyHost("127.0.0.1")
|
|
165
|
+
* // { kind: "loopback", literal: "ipv4", canonical: "127.0.0.1" }
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* classifyHost("[::1]:8080")
|
|
169
|
+
* // { kind: "loopback", literal: "ipv6", canonical: "0000:0000:...:0001" }
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* classifyHost("::ffff:192.0.2.1")
|
|
173
|
+
* // { kind: "documentation", literal: "ipv4", canonical: "192.0.2.1" }
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* classifyHost("tenant-a.localhost")
|
|
177
|
+
* // { kind: "localhost", literal: "fqdn", canonical: "tenant-a.localhost" }
|
|
178
|
+
*/
|
|
179
|
+
function classifyHost(host) {
|
|
180
|
+
const lowered = stripTrailingDot(stripZoneId(stripBrackets(stripPort(host.trim())))).toLowerCase();
|
|
181
|
+
if (lowered === "") return {
|
|
182
|
+
kind: "reserved",
|
|
183
|
+
literal: "fqdn",
|
|
184
|
+
canonical: ""
|
|
185
|
+
};
|
|
186
|
+
if (!isValidIP(lowered)) {
|
|
187
|
+
if (lowered === "localhost" || lowered.endsWith(".localhost")) return {
|
|
188
|
+
kind: "localhost",
|
|
189
|
+
literal: "fqdn",
|
|
190
|
+
canonical: lowered
|
|
191
|
+
};
|
|
192
|
+
if (CLOUD_METADATA_HOSTS.has(lowered)) return {
|
|
193
|
+
kind: "cloudMetadata",
|
|
194
|
+
literal: "fqdn",
|
|
195
|
+
canonical: lowered
|
|
196
|
+
};
|
|
197
|
+
return {
|
|
198
|
+
kind: "public",
|
|
199
|
+
literal: "fqdn",
|
|
200
|
+
canonical: lowered
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
if (looksLikeIPv4(lowered)) return {
|
|
204
|
+
kind: classifyIPv4(lowered),
|
|
205
|
+
literal: "ipv4",
|
|
206
|
+
canonical: lowered
|
|
207
|
+
};
|
|
208
|
+
const canonical = normalizeIP(lowered, { ipv6Subnet: 128 });
|
|
209
|
+
if (looksLikeIPv4(canonical)) return {
|
|
210
|
+
kind: classifyIPv4(canonical),
|
|
211
|
+
literal: "ipv4",
|
|
212
|
+
canonical
|
|
213
|
+
};
|
|
214
|
+
return {
|
|
215
|
+
kind: classifyIPv6(canonical),
|
|
216
|
+
literal: "ipv6",
|
|
217
|
+
canonical
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Strict loopback-IP-literal check per RFC 8252 §7.3.
|
|
222
|
+
*
|
|
223
|
+
* Returns true ONLY for IPv4 `127.0.0.0/8` or IPv6 `::1`. The DNS name
|
|
224
|
+
* `localhost` returns false — RFC 8252 §8.3 explicitly recommends against
|
|
225
|
+
* relying on name resolution for loopback redirect URIs.
|
|
226
|
+
*
|
|
227
|
+
* Use this for OAuth redirect URI matching.
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* isLoopbackIP("127.0.0.1") // true
|
|
231
|
+
* isLoopbackIP("::1") // true
|
|
232
|
+
* isLoopbackIP("[::1]:8080") // true
|
|
233
|
+
* isLoopbackIP("localhost") // false (use isLoopbackHost for DNS names)
|
|
234
|
+
* isLoopbackIP("0.0.0.0") // false (unspecified, not loopback)
|
|
235
|
+
*/
|
|
236
|
+
function isLoopbackIP(host) {
|
|
237
|
+
return classifyHost(host).kind === "loopback";
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Permissive loopback check for developer-ergonomics code paths.
|
|
241
|
+
*
|
|
242
|
+
* Returns true for IPv4 `127.0.0.0/8`, IPv6 `::1`, the literal name `localhost`,
|
|
243
|
+
* and any RFC 6761 `.localhost` subdomain (`tenant.localhost`, `app.localhost`).
|
|
244
|
+
*
|
|
245
|
+
* Use this for things like: allowing HTTP for dev servers, skipping Secure
|
|
246
|
+
* cookie requirements, browser-trust heuristics. Do NOT use this for OAuth
|
|
247
|
+
* redirect URI matching — use {@link isLoopbackIP} there.
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* isLoopbackHost("localhost") // true
|
|
251
|
+
* isLoopbackHost("tenant.localhost") // true (RFC 6761)
|
|
252
|
+
* isLoopbackHost("127.0.0.1") // true
|
|
253
|
+
* isLoopbackHost("0.0.0.0") // false (unspecified, NOT loopback)
|
|
254
|
+
*/
|
|
255
|
+
function isLoopbackHost(host) {
|
|
256
|
+
const kind = classifyHost(host).kind;
|
|
257
|
+
return kind === "loopback" || kind === "localhost";
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* First-line SSRF gate: returns true ONLY for hosts that classify as `public`.
|
|
261
|
+
*
|
|
262
|
+
* Every RFC 6890 special-purpose range (loopback, private, link-local,
|
|
263
|
+
* unspecified, documentation, multicast, broadcast, reserved, shared address
|
|
264
|
+
* space, benchmarking) and cloud-metadata FQDN returns false.
|
|
265
|
+
*
|
|
266
|
+
* Use this BEFORE issuing a server-side fetch to a user-supplied URL, e.g.
|
|
267
|
+
* OAuth introspection endpoints, webhook targets, or metadata-document
|
|
268
|
+
* fetches (CIMD).
|
|
269
|
+
*
|
|
270
|
+
* Limitations (this is a syntactic check, not a complete SSRF mitigation):
|
|
271
|
+
* - No DNS resolution: a public-looking FQDN that resolves to a private IP
|
|
272
|
+
* passes this check. Re-verify the resolved address before connecting, or
|
|
273
|
+
* pin the socket to the resolved IP.
|
|
274
|
+
* - No DNS-rebinding defense: attackers can return a public IP on the first
|
|
275
|
+
* lookup and a private IP on the second. Resolve once and reuse the IP.
|
|
276
|
+
* - No redirect following: HTTP 3xx responses can redirect to private hosts.
|
|
277
|
+
* Re-run this check on every redirect target, or disable auto-follow.
|
|
278
|
+
*
|
|
279
|
+
* @example
|
|
280
|
+
* isPublicRoutableHost("example.com") // true
|
|
281
|
+
* isPublicRoutableHost("127.0.0.1") // false (loopback)
|
|
282
|
+
* isPublicRoutableHost("169.254.169.254") // false (linkLocal / AWS IMDS)
|
|
283
|
+
* isPublicRoutableHost("metadata.google.internal") // false (cloudMetadata)
|
|
284
|
+
* isPublicRoutableHost("10.0.0.1") // false (private)
|
|
285
|
+
* isPublicRoutableHost("::ffff:127.0.0.1") // false (mapped loopback)
|
|
286
|
+
*/
|
|
287
|
+
function isPublicRoutableHost(host) {
|
|
288
|
+
return classifyHost(host).kind === "public";
|
|
289
|
+
}
|
|
290
|
+
//#endregion
|
|
291
|
+
export { classifyHost, isLoopbackHost, isLoopbackIP, isPublicRoutableHost };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
//#region src/utils/ip.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Normalizes an IP address for consistent rate limiting.
|
|
4
|
+
*
|
|
5
|
+
* Features:
|
|
6
|
+
* - Normalizes IPv6 to canonical lowercase form
|
|
7
|
+
* - Converts IPv4-mapped IPv6 to IPv4
|
|
8
|
+
* - Supports IPv6 subnet extraction
|
|
9
|
+
* - Handles all edge cases (::1, ::, etc.)
|
|
10
|
+
*/
|
|
11
|
+
interface NormalizeIPOptions {
|
|
12
|
+
/**
|
|
13
|
+
* For IPv6 addresses, extract the subnet prefix instead of full address.
|
|
14
|
+
* Common values: 32, 48, 64, 128 (default: 128 = full address)
|
|
15
|
+
*
|
|
16
|
+
* @default 128
|
|
17
|
+
*/
|
|
18
|
+
ipv6Subnet?: 128 | 64 | 48 | 32;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Checks if an IP is valid IPv4 or IPv6
|
|
22
|
+
*/
|
|
23
|
+
declare function isValidIP(ip: string): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Normalizes an IP address (IPv4 or IPv6) for consistent rate limiting.
|
|
26
|
+
*
|
|
27
|
+
* @param ip - The IP address to normalize
|
|
28
|
+
* @param options - Normalization options
|
|
29
|
+
* @returns Normalized IP address
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* normalizeIP("2001:DB8::1")
|
|
33
|
+
* // -> "2001:0db8:0000:0000:0000:0000:0000:0000"
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* normalizeIP("::ffff:192.0.2.1")
|
|
37
|
+
* // -> "192.0.2.1" (converted to IPv4)
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* normalizeIP("2001:db8::1", { ipv6Subnet: 64 })
|
|
41
|
+
* // -> "2001:0db8:0000:0000:0000:0000:0000:0000" (subnet /64)
|
|
42
|
+
*/
|
|
43
|
+
declare function normalizeIP(ip: string, options?: NormalizeIPOptions): string;
|
|
44
|
+
/**
|
|
45
|
+
* Creates a rate limit key from IP and path
|
|
46
|
+
* Uses a separator to prevent collision attacks
|
|
47
|
+
*
|
|
48
|
+
* @param ip - The IP address (should be normalized)
|
|
49
|
+
* @param path - The request path
|
|
50
|
+
* @returns Rate limit key
|
|
51
|
+
*/
|
|
52
|
+
declare function createRateLimitKey(ip: string, path: string): string;
|
|
53
|
+
//#endregion
|
|
54
|
+
export { createRateLimitKey, isValidIP, normalizeIP };
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
//#region src/utils/ip.ts
|
|
3
|
+
/**
|
|
4
|
+
* Checks if an IP is valid IPv4 or IPv6
|
|
5
|
+
*/
|
|
6
|
+
function isValidIP(ip) {
|
|
7
|
+
return z.ipv4().safeParse(ip).success || z.ipv6().safeParse(ip).success;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Checks if an IP is IPv6
|
|
11
|
+
*/
|
|
12
|
+
function isIPv6(ip) {
|
|
13
|
+
return z.ipv6().safeParse(ip).success;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Converts IPv4-mapped IPv6 address to IPv4
|
|
17
|
+
* e.g., "::ffff:192.0.2.1" -> "192.0.2.1"
|
|
18
|
+
*/
|
|
19
|
+
function extractIPv4FromMapped(ipv6) {
|
|
20
|
+
const lower = ipv6.toLowerCase();
|
|
21
|
+
if (lower.startsWith("::ffff:")) {
|
|
22
|
+
const ipv4Part = lower.substring(7);
|
|
23
|
+
if (z.ipv4().safeParse(ipv4Part).success) return ipv4Part;
|
|
24
|
+
}
|
|
25
|
+
const parts = ipv6.split(":");
|
|
26
|
+
if (parts.length === 7 && parts[5]?.toLowerCase() === "ffff") {
|
|
27
|
+
const ipv4Part = parts[6];
|
|
28
|
+
if (ipv4Part && z.ipv4().safeParse(ipv4Part).success) return ipv4Part;
|
|
29
|
+
}
|
|
30
|
+
if (lower.includes("::ffff:") || lower.includes(":ffff:")) {
|
|
31
|
+
const groups = expandIPv6(ipv6);
|
|
32
|
+
if (groups.length === 8 && groups[0] === "0000" && groups[1] === "0000" && groups[2] === "0000" && groups[3] === "0000" && groups[4] === "0000" && groups[5] === "ffff" && groups[6] && groups[7]) return `${Number.parseInt(groups[6].substring(0, 2), 16)}.${Number.parseInt(groups[6].substring(2, 4), 16)}.${Number.parseInt(groups[7].substring(0, 2), 16)}.${Number.parseInt(groups[7].substring(2, 4), 16)}`;
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Expands a compressed IPv6 address to full form
|
|
38
|
+
* e.g., "2001:db8::1" -> ["2001", "0db8", "0000", "0000", "0000", "0000", "0000", "0001"]
|
|
39
|
+
*/
|
|
40
|
+
function expandIPv6(ipv6) {
|
|
41
|
+
if (ipv6.includes("::")) {
|
|
42
|
+
const sides = ipv6.split("::");
|
|
43
|
+
const left = sides[0] ? sides[0].split(":") : [];
|
|
44
|
+
const right = sides[1] ? sides[1].split(":") : [];
|
|
45
|
+
const missingGroups = 8 - left.length - right.length;
|
|
46
|
+
const zeros = Array(missingGroups).fill("0000");
|
|
47
|
+
const paddedLeft = left.map((g) => g.padStart(4, "0"));
|
|
48
|
+
const paddedRight = right.map((g) => g.padStart(4, "0"));
|
|
49
|
+
return [
|
|
50
|
+
...paddedLeft,
|
|
51
|
+
...zeros,
|
|
52
|
+
...paddedRight
|
|
53
|
+
];
|
|
54
|
+
}
|
|
55
|
+
return ipv6.split(":").map((g) => g.padStart(4, "0"));
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Normalizes an IPv6 address to canonical form
|
|
59
|
+
* e.g., "2001:DB8::1" -> "2001:0db8:0000:0000:0000:0000:0000:0001"
|
|
60
|
+
*/
|
|
61
|
+
function normalizeIPv6(ipv6, subnetPrefix) {
|
|
62
|
+
const groups = expandIPv6(ipv6);
|
|
63
|
+
if (subnetPrefix && subnetPrefix < 128) {
|
|
64
|
+
let bitsRemaining = subnetPrefix;
|
|
65
|
+
return groups.map((group) => {
|
|
66
|
+
if (bitsRemaining <= 0) return "0000";
|
|
67
|
+
if (bitsRemaining >= 16) {
|
|
68
|
+
bitsRemaining -= 16;
|
|
69
|
+
return group;
|
|
70
|
+
}
|
|
71
|
+
const masked = Number.parseInt(group, 16) & (65535 << 16 - bitsRemaining & 65535);
|
|
72
|
+
bitsRemaining = 0;
|
|
73
|
+
return masked.toString(16).padStart(4, "0");
|
|
74
|
+
}).join(":").toLowerCase();
|
|
75
|
+
}
|
|
76
|
+
return groups.join(":").toLowerCase();
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Normalizes an IP address (IPv4 or IPv6) for consistent rate limiting.
|
|
80
|
+
*
|
|
81
|
+
* @param ip - The IP address to normalize
|
|
82
|
+
* @param options - Normalization options
|
|
83
|
+
* @returns Normalized IP address
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* normalizeIP("2001:DB8::1")
|
|
87
|
+
* // -> "2001:0db8:0000:0000:0000:0000:0000:0000"
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* normalizeIP("::ffff:192.0.2.1")
|
|
91
|
+
* // -> "192.0.2.1" (converted to IPv4)
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* normalizeIP("2001:db8::1", { ipv6Subnet: 64 })
|
|
95
|
+
* // -> "2001:0db8:0000:0000:0000:0000:0000:0000" (subnet /64)
|
|
96
|
+
*/
|
|
97
|
+
function normalizeIP(ip, options = {}) {
|
|
98
|
+
if (z.ipv4().safeParse(ip).success) return ip.toLowerCase();
|
|
99
|
+
if (!isIPv6(ip)) return ip.toLowerCase();
|
|
100
|
+
const ipv4 = extractIPv4FromMapped(ip);
|
|
101
|
+
if (ipv4) return ipv4.toLowerCase();
|
|
102
|
+
return normalizeIPv6(ip, options.ipv6Subnet || 64);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Creates a rate limit key from IP and path
|
|
106
|
+
* Uses a separator to prevent collision attacks
|
|
107
|
+
*
|
|
108
|
+
* @param ip - The IP address (should be normalized)
|
|
109
|
+
* @param path - The request path
|
|
110
|
+
* @returns Rate limit key
|
|
111
|
+
*/
|
|
112
|
+
function createRateLimitKey(ip, path) {
|
|
113
|
+
return `${ip}|${path}`;
|
|
114
|
+
}
|
|
115
|
+
//#endregion
|
|
116
|
+
export { createRateLimitKey, isValidIP, normalizeIP };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { APIError as APIError$1 } from "../error/index.mjs";
|
|
2
|
+
import { APIError } from "better-call";
|
|
3
|
+
//#region src/utils/is-api-error.ts
|
|
4
|
+
function isAPIError(error) {
|
|
5
|
+
return error instanceof APIError || error instanceof APIError$1 || error?.name === "APIError";
|
|
6
|
+
}
|
|
7
|
+
//#endregion
|
|
8
|
+
export { isAPIError };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { logger } from "../env/logger.mjs";
|
|
2
|
+
//#region src/utils/json.ts
|
|
3
|
+
const iso8601Regex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z$/;
|
|
4
|
+
function reviveDate(value) {
|
|
5
|
+
if (typeof value === "string" && iso8601Regex.test(value)) {
|
|
6
|
+
const date = new Date(value);
|
|
7
|
+
if (!isNaN(date.getTime())) return date;
|
|
8
|
+
}
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Recursively walk a pre-parsed object and convert ISO 8601 date strings
|
|
13
|
+
* to Date instances. This handles the case where a Redis client (or similar)
|
|
14
|
+
* returns already-parsed JSON objects whose date fields are still strings.
|
|
15
|
+
*/
|
|
16
|
+
function reviveDates(value) {
|
|
17
|
+
if (value === null || value === void 0) return value;
|
|
18
|
+
if (typeof value === "string") return reviveDate(value);
|
|
19
|
+
if (value instanceof Date) return value;
|
|
20
|
+
if (Array.isArray(value)) return value.map(reviveDates);
|
|
21
|
+
if (typeof value === "object") {
|
|
22
|
+
const result = {};
|
|
23
|
+
for (const key of Object.keys(value)) result[key] = reviveDates(value[key]);
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
28
|
+
function safeJSONParse(data) {
|
|
29
|
+
try {
|
|
30
|
+
if (typeof data !== "string") {
|
|
31
|
+
if (data === null || data === void 0) return null;
|
|
32
|
+
return reviveDates(data);
|
|
33
|
+
}
|
|
34
|
+
return JSON.parse(data, (_, value) => reviveDate(value));
|
|
35
|
+
} catch (e) {
|
|
36
|
+
logger.error("Error parsing JSON", { error: e });
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
export { safeJSONParse };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
//#region src/utils/url.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Normalizes a request pathname by removing the basePath prefix and trailing slashes.
|
|
4
|
+
* This is useful for matching paths against configured path lists.
|
|
5
|
+
*
|
|
6
|
+
* @param requestUrl - The full request URL
|
|
7
|
+
* @param basePath - The base path of the auth API (e.g., "/api/auth")
|
|
8
|
+
* @returns The normalized path without basePath prefix or trailing slashes,
|
|
9
|
+
* or "/" if URL parsing fails
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* normalizePathname("http://localhost:3000/api/auth/sso/saml2/callback/provider1", "/api/auth")
|
|
13
|
+
* // Returns: "/sso/saml2/callback/provider1"
|
|
14
|
+
*
|
|
15
|
+
* normalizePathname("http://localhost:3000/sso/saml2/callback/provider1/", "/")
|
|
16
|
+
* // Returns: "/sso/saml2/callback/provider1"
|
|
17
|
+
*/
|
|
18
|
+
declare function normalizePathname(requestUrl: string, basePath: string): string;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { normalizePathname };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
//#region src/utils/url.ts
|
|
2
|
+
/**
|
|
3
|
+
* Normalizes a request pathname by removing the basePath prefix and trailing slashes.
|
|
4
|
+
* This is useful for matching paths against configured path lists.
|
|
5
|
+
*
|
|
6
|
+
* @param requestUrl - The full request URL
|
|
7
|
+
* @param basePath - The base path of the auth API (e.g., "/api/auth")
|
|
8
|
+
* @returns The normalized path without basePath prefix or trailing slashes,
|
|
9
|
+
* or "/" if URL parsing fails
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* normalizePathname("http://localhost:3000/api/auth/sso/saml2/callback/provider1", "/api/auth")
|
|
13
|
+
* // Returns: "/sso/saml2/callback/provider1"
|
|
14
|
+
*
|
|
15
|
+
* normalizePathname("http://localhost:3000/sso/saml2/callback/provider1/", "/")
|
|
16
|
+
* // Returns: "/sso/saml2/callback/provider1"
|
|
17
|
+
*/
|
|
18
|
+
function normalizePathname(requestUrl, basePath) {
|
|
19
|
+
let pathname;
|
|
20
|
+
try {
|
|
21
|
+
pathname = new URL(requestUrl).pathname.replace(/\/+$/, "") || "/";
|
|
22
|
+
} catch {
|
|
23
|
+
return "/";
|
|
24
|
+
}
|
|
25
|
+
if (basePath === "/" || basePath === "") return pathname;
|
|
26
|
+
if (pathname === basePath) return "/";
|
|
27
|
+
if (pathname.startsWith(basePath + "/")) return pathname.slice(basePath.length).replace(/\/+$/, "") || "/";
|
|
28
|
+
return pathname;
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
export { normalizePathname };
|