@rpcbase/auth 0.199.0 → 0.200.0

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.
Files changed (72) hide show
  1. package/dist/api/resend-otp/handler.d.ts.map +1 -1
  2. package/dist/api/resend-otp/index.d.ts +5 -0
  3. package/dist/api/resend-otp/index.d.ts.map +1 -1
  4. package/dist/api/resend-otp/index.js +16 -0
  5. package/dist/api/resend-otp/index.js.map +1 -0
  6. package/dist/api/sign-in/handler.d.ts +3 -1
  7. package/dist/api/sign-in/handler.d.ts.map +1 -1
  8. package/dist/api/sign-in/index.d.ts.map +1 -1
  9. package/dist/{sign-in-DYq3bJeH.js → api/sign-in/index.js} +5 -5
  10. package/dist/api/sign-in/index.js.map +1 -0
  11. package/dist/api/sign-up/handler.d.ts.map +1 -1
  12. package/dist/api/sign-up/index.d.ts +27 -1
  13. package/dist/api/sign-up/index.d.ts.map +1 -1
  14. package/dist/api/sign-up/index.js +32 -0
  15. package/dist/api/sign-up/index.js.map +1 -0
  16. package/dist/api/verify-otp/handler.d.ts +3 -1
  17. package/dist/api/verify-otp/handler.d.ts.map +1 -1
  18. package/dist/api/verify-otp/index.js +18 -0
  19. package/dist/api/verify-otp/index.js.map +1 -0
  20. package/dist/components/PasswordInput/index.d.ts.map +1 -1
  21. package/dist/components/SignInForm/index.d.ts.map +1 -1
  22. package/dist/emailVerification-DA9pZ0N_.js +65 -0
  23. package/dist/emailVerification-DA9pZ0N_.js.map +1 -0
  24. package/dist/emailVerification.d.ts +20 -0
  25. package/dist/emailVerification.d.ts.map +1 -0
  26. package/dist/handler-0uaKeuYp.js +213 -0
  27. package/dist/handler-0uaKeuYp.js.map +1 -0
  28. package/dist/{handler-BgjYCWF4.js → handler-B6roBozS.js} +2 -2
  29. package/dist/{handler-BgjYCWF4.js.map → handler-B6roBozS.js.map} +1 -1
  30. package/dist/handler-BPoWo5Qy.js +85 -0
  31. package/dist/handler-BPoWo5Qy.js.map +1 -0
  32. package/dist/{handler-DBbjgU-f.js → handler-BenTgwfT.js} +2 -2
  33. package/dist/{handler-DBbjgU-f.js.map → handler-BenTgwfT.js.map} +1 -1
  34. package/dist/{handler-Dbw6BOmj.js → handler-BhPmGpUq.js} +3 -3
  35. package/dist/handler-BhPmGpUq.js.map +1 -0
  36. package/dist/handler-DCk7C1pI.js +80 -0
  37. package/dist/handler-DCk7C1pI.js.map +1 -0
  38. package/dist/{handler-iT2eSHpE.js → handler-DCljRBBf.js} +3 -3
  39. package/dist/handler-DCljRBBf.js.map +1 -0
  40. package/dist/{handler-CF3fSh8e.js → handler-JKQLI2iL.js} +2 -2
  41. package/dist/{handler-CF3fSh8e.js.map → handler-JKQLI2iL.js.map} +1 -1
  42. package/dist/{handler-DgIcxthg.js → handler-b6PvhATs.js} +3 -3
  43. package/dist/handler-b6PvhATs.js.map +1 -0
  44. package/dist/handler-cj7IkJB-.js +98 -0
  45. package/dist/handler-cj7IkJB-.js.map +1 -0
  46. package/dist/index.js +13 -5
  47. package/dist/index.js.map +1 -1
  48. package/dist/oauth/index.js +30 -1
  49. package/dist/oauth/index.js.map +1 -1
  50. package/dist/oauth/lib.d.ts.map +1 -1
  51. package/dist/registrationStatus-BP6yReMw.js +7 -0
  52. package/dist/registrationStatus-BP6yReMw.js.map +1 -0
  53. package/dist/registrationStatus.d.ts +16 -0
  54. package/dist/registrationStatus.d.ts.map +1 -0
  55. package/dist/routes.js +10 -10
  56. package/dist/{schemas-CMgO_xn9.js → schemas-DABNKHVA.js} +2 -2
  57. package/dist/{schemas-CMgO_xn9.js.map → schemas-DABNKHVA.js.map} +1 -1
  58. package/package.json +21 -1
  59. package/dist/handler-1Jy7G8dM.js +0 -92
  60. package/dist/handler-1Jy7G8dM.js.map +0 -1
  61. package/dist/handler-B1Z9YpER.js +0 -77
  62. package/dist/handler-B1Z9YpER.js.map +0 -1
  63. package/dist/handler-BkZLC8Bg.js +0 -92
  64. package/dist/handler-BkZLC8Bg.js.map +0 -1
  65. package/dist/handler-D4ui5jV4.js +0 -74
  66. package/dist/handler-D4ui5jV4.js.map +0 -1
  67. package/dist/handler-Dbw6BOmj.js.map +0 -1
  68. package/dist/handler-DgIcxthg.js.map +0 -1
  69. package/dist/handler-iT2eSHpE.js.map +0 -1
  70. package/dist/sign-in-DYq3bJeH.js.map +0 -1
  71. package/dist/sign-up-CYGadNUe.js +0 -18
  72. package/dist/sign-up-CYGadNUe.js.map +0 -1
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["onPress","errorMessage","id","className","placeholder","__iconNode"],"sources":["../src/components/AuthLayout/index.tsx","../src/components/AppleSignInButton/index.tsx","../src/components/EmailInput/index.tsx","../src/utils/sanitizeNextPath.ts","../src/components/SignInForm/index.tsx","../src/components/SignUpForm/index.tsx","../src/components/RememberMeCheckbox/index.tsx","../../../node_modules/lucide-react/dist/esm/shared/src/utils/mergeClasses.mjs","../../../node_modules/lucide-react/dist/esm/shared/src/utils/toKebabCase.mjs","../../../node_modules/lucide-react/dist/esm/shared/src/utils/toCamelCase.mjs","../../../node_modules/lucide-react/dist/esm/shared/src/utils/toPascalCase.mjs","../../../node_modules/lucide-react/dist/esm/defaultAttributes.mjs","../../../node_modules/lucide-react/dist/esm/shared/src/utils/hasA11yProp.mjs","../../../node_modules/lucide-react/dist/esm/context.mjs","../../../node_modules/lucide-react/dist/esm/Icon.mjs","../../../node_modules/lucide-react/dist/esm/createLucideIcon.mjs","../../../node_modules/lucide-react/dist/esm/icons/eye-off.mjs","../../../node_modules/lucide-react/dist/esm/icons/eye.mjs","../src/components/PasswordInput/index.tsx","../src/components/ResendCodeButton/index.tsx","../src/passwordReset.ts"],"sourcesContent":["import * as React from \"react\"\nimport {Link, useLocation } from \"@rpcbase/router\"\n\n\nconst LINKS_REDIRECTION_MAP = {\n \"/auth/sign-in\": {\n \"title\": \"Sign Up\",\n \"location\": \"/auth/sign-up\"\n },\n \"/auth/sign-up\": {\n \"title\": \"Sign In\",\n \"location\": \"/auth/sign-in\"\n },\n \"/auth/logout-success\": {\n \"title\": \"Sign In\",\n \"location\": \"/auth/sign-in\"\n }\n}\n\ntype Pathname = keyof typeof LINKS_REDIRECTION_MAP\n\nexport const AuthLayout = ({\n sidePanel = null,\n children,\n}: {\n sidePanel: React.ReactElement | null\n children: React.ReactNode\n}) => {\n const location = useLocation()\n\n const linkTitle = LINKS_REDIRECTION_MAP[location.pathname as Pathname]?.title\n const linkLocation = LINKS_REDIRECTION_MAP[location.pathname as Pathname]?.location\n\n return (\n <div className=\"container relative flex min-h-dvh flex-col items-center justify-center px-4 py-20 sm:px-6 md:px-8 lg:grid lg:h-dvh lg:w-full lg:max-w-none lg:grid-cols-2 lg:px-0 lg:py-0\">\n {/* Top-right redirection link */}\n {linkTitle && linkLocation ? (\n <Link\n className=\"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 hover:bg-accent hover:text-accent-foreground h-9 px-4 py-2 absolute right-4 top-4 md:right-8 md:top-8\"\n to={linkLocation}\n >\n {linkTitle}\n </Link>\n ) : null}\n <div className=\"relative hidden h-full flex-col bg-muted p-10 text-white dark:border-r lg:flex\">\n {sidePanel}\n </div>\n <div className=\"mx-auto flex w-full flex-col justify-center gap-6 /*sm:w-[350px]*/\">\n {children}\n </div>\n </div>\n )\n}\n","import clsx from \"clsx\"\n\n\nexport const AppleSignInButton = ({\n onPress,\n className,\n}: {\n onPress: () => void;\n className?: string;\n}) => {\n\n return (\n <button\n onClick={onPress}\n className={clsx(`\n w-full\n bg-black text-white hover:bg-gray-800\n flex items-center justify-center\n px-6 py-2\n rounded-lg\n font-medium\n transition duration-150 ease-in-out\n focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-black\n `, className)}\n >\n <svg\n className=\"w-5 h-5 mr-3\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"white\"\n >\n <path d=\"M12.152 6.896c-.948 0-2.415-1.078-3.96-1.04-2.04.027-3.91 1.183-4.961 3.014-2.117 3.675-.539 9.103 1.519 12.09 1.013 1.454 2.208 3.09 3.792 3.039 1.52-.065 2.09-.987 3.935-.987 1.831 0 2.35.987 3.96.948 1.637-.026 2.676-1.48 3.676-2.948 1.156-1.688 1.636-3.325 1.662-3.415-.039-.013-3.182-1.221-3.22-4.857-.026-3.04 2.48-4.494 2.597-4.559-1.429-2.09-3.623-2.324-4.39-2.376-2-.156-3.675 1.09-4.61 1.09zM15.53 3.83c.843-1.012 1.4-2.427 1.245-3.83-1.207.052-2.662.805-3.532 1.818-.78.896-1.454 2.338-1.273 3.714 1.338.104 2.715-.688 3.559-1.701\" />\n </svg>\n <span>Continue with Apple</span>\n </button>\n )\n}\n","import {useFormContext} from \"@rpcbase/form\"\nimport { Input } from \"@rpcbase/ui\"\n\n\nexport const EmailInput = ({\n id,\n className,\n placeholder,\n}: {\n id: string\n className?: string\n placeholder?: string\n}) => {\n const {register, formState} = useFormContext()\n\n const error = formState.errors.email\n let errorMessage: string | undefined\n if (typeof error === \"string\") {\n errorMessage = error\n } else if (error && typeof error.message === \"string\") {\n errorMessage = error.message\n }\n\n return (\n <>\n <Input\n id={id}\n type=\"email\"\n required\n autoComplete=\"email\"\n className={className}\n placeholder={placeholder}\n {...register(\"email\")}\n />\n {errorMessage ? (\n <p className=\"mt-1 -mb-2 text-sm/6 text-red-500\">{errorMessage}</p>\n ) : null}\n </>\n )\n}\n","const hasUnsafeNextPathChars = (value: string) => {\n for (let i = 0; i < value.length; i++) {\n const code = value.charCodeAt(i)\n if (code === 92 || code <= 31 || code === 127) return true\n }\n return false\n}\n\nexport const sanitizeNextPath = (raw: string | null) => {\n if (!raw) return null\n\n const nextPath = raw.trim()\n if (!nextPath) return null\n\n if (!nextPath.startsWith(\"/\") || nextPath.startsWith(\"//\")) {\n return null\n }\n\n if (hasUnsafeNextPathChars(nextPath)) {\n return null\n }\n\n try {\n const base = new URL(\"http://localhost\")\n const url = new URL(nextPath, base)\n if (url.origin !== base.origin) {\n return null\n }\n return `${url.pathname}${url.search}${url.hash}`\n } catch {\n return null\n }\n}\n\n","import { ReactNode } from \"react\"\nimport { useNavigate, useSearchParams } from \"@rpcbase/router\"\nimport { useForm, FormProvider, zodResolver } from \"@rpcbase/form\"\nimport type { SubmitHandler } from \"@rpcbase/form\"\nimport { z } from \"zod\"\n\nimport {requestSchema} from \"../../api/sign-in\"\nimport { sanitizeNextPath } from \"../../utils/sanitizeNextPath\"\n\n\ntype SignInFormValues = z.input<typeof requestSchema>\n\nexport const SignInForm = ({\n children,\n className\n}: {\n children: ReactNode,\n className?: string\n}) => {\n const navigate = useNavigate()\n const [searchParams] = useSearchParams()\n\n const methods = useForm<SignInFormValues>({\n defaultValues: {\n email: \"\",\n password: \"\",\n rememberMe: true,\n },\n navigationGuard: false,\n resolver: zodResolver(requestSchema)\n })\n\n const onSubmit: SubmitHandler<SignInFormValues> = async (data) => {\n methods.clearErrors(\"root\")\n\n try {\n const res = await fetch(\"/api/rb/auth/sign-in\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(data),\n credentials: \"include\",\n })\n\n const json = await res.json().catch(() => null) as { success?: boolean; error?: string } | null\n\n if (!res.ok || !json?.success) {\n const message = json?.error === \"invalid_credentials\"\n ? \"Invalid email or password.\"\n : \"Sign-in failed. Please try again.\"\n methods.setError(\"root\", { type: \"server\", message })\n return\n }\n\n const nextPath = sanitizeNextPath(searchParams.get(\"next\")) ?? \"/\"\n navigate(nextPath, { replace: true })\n } catch (err) {\n methods.setError(\"root\", { type: \"server\", message: \"Network error. Please try again.\" })\n }\n }\n\n return (\n <FormProvider {...methods}>\n <form method=\"post\" noValidate className={className} onSubmit={methods.handleSubmit(onSubmit)}>\n {children}\n {methods.formState.errors.root?.message && (\n <p className=\"mt-2 text-sm text-red-600\" role=\"alert\">\n {methods.formState.errors.root.message}\n </p>\n )}\n </form>\n </FormProvider>\n )\n}\n","import {ReactNode, useState} from \"react\"\nimport { useNavigate } from \"@rpcbase/router\"\nimport { useForm, FormProvider, zodResolver } from \"@rpcbase/form\"\nimport type {SubmitHandler} from \"@rpcbase/form\"\nimport { z } from \"zod\"\n\nimport {requestSchema} from \"../../api/sign-up\"\n\n\ntype SignUpFormValues = z.input<typeof requestSchema>\n\n\nexport const SignUpForm = ({\n children,\n className,\n otpNextPath\n}: {\n children: ReactNode,\n className?: string\n otpNextPath?: string\n}) => {\n\n const navigate = useNavigate()\n\n const [serverMessage, setServerMessage] = useState<string | null>(null)\n const methods = useForm<SignUpFormValues>({\n defaultValues: {\n email: \"\",\n password: \"\",\n rememberMe: true,\n },\n navigationGuard: false,\n resolver: zodResolver(requestSchema)\n })\n\n const onSubmit: SubmitHandler<SignUpFormValues> = async (data) => {\n setServerMessage(null)\n methods.clearErrors(\"root\")\n\n try {\n const res = await fetch(\"/api/rb/auth/sign-up\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(data),\n credentials: \"include\",\n })\n\n const json = await res.json()\n\n if (!res.ok) {\n const message = json.error === \"user_exists\"\n ? \"An account already exists with this email.\"\n : \"Sign-up failed. Please try again.\"\n methods.setError(\"root\", { type: \"server\", message })\n return\n }\n\n if (!json.success) {\n methods.setError(\"root\", { type: \"server\", message: \"Sign-up failed. Please try again.\" })\n return\n }\n\n const search = new URLSearchParams({ email: data.email })\n if (otpNextPath) {\n search.set(\"next\", otpNextPath)\n }\n navigate(`/auth/sign-up-otp?${search.toString()}`)\n setServerMessage(\"Account created. Check your inbox to verify your email.\")\n } catch (err) {\n methods.setError(\"root\", { type: \"server\", message: \"Network error. Please try again.\" })\n }\n }\n\n return (\n <FormProvider {...methods}>\n <form method=\"post\" noValidate className={className} onSubmit={methods.handleSubmit(onSubmit)}>\n {children}\n {methods.formState.errors.root?.message && (\n <p className=\"mt-2 text-sm text-red-600\" role=\"alert\">\n {methods.formState.errors.root.message}\n </p>\n )}\n {serverMessage && (\n <p className=\"mt-2 text-sm text-green-700\" role=\"status\">\n {serverMessage}\n </p>\n )}\n </form>\n </FormProvider>\n )\n}\n","import type { ElementType } from \"react\"\nimport {useFormContext} from \"@rpcbase/form\"\n\n\nexport const RememberMeCheckbox = ({\n label,\n as: Component = \"input\"\n}: {\n label: string,\n as?: ElementType\n}) => {\n const {register} = useFormContext()\n\n return (\n <>\n <Component\n id=\"rememberMe\"\n {...register(\"rememberMe\")}\n />\n <label\n htmlFor={\"rememberMe\"}\n className=\"pl-2 block text-sm/6 text-gray-900\"\n >\n {label}\n </label>\n </>\n )\n}\n","/**\n * @license lucide-react v1.34.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst mergeClasses = (...classes) => classes.filter((className, index, array) => {\n return Boolean(className) && className.trim() !== \"\" && array.indexOf(className) === index;\n}).join(\" \").trim();\n\nexport { mergeClasses };\n//# sourceMappingURL=mergeClasses.mjs.map\n","/**\n * @license lucide-react v1.34.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, \"$1-$2\").toLowerCase();\n\nexport { toKebabCase };\n//# sourceMappingURL=toKebabCase.mjs.map\n","/**\n * @license lucide-react v1.34.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst toCamelCase = (string) => string.replace(\n /^([A-Z])|[\\s-_]+(\\w)/g,\n (match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase()\n);\n\nexport { toCamelCase };\n//# sourceMappingURL=toCamelCase.mjs.map\n","/**\n * @license lucide-react v1.34.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { toCamelCase } from './toCamelCase.mjs';\n\nconst toPascalCase = (string) => {\n const camelCase = toCamelCase(string);\n return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);\n};\n\nexport { toPascalCase };\n//# sourceMappingURL=toPascalCase.mjs.map\n","/**\n * @license lucide-react v1.34.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nvar defaultAttributes = {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: 24,\n height: 24,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n};\n\nexport { defaultAttributes as default };\n//# sourceMappingURL=defaultAttributes.mjs.map\n","/**\n * @license lucide-react v1.34.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst hasA11yProp = (props) => {\n for (const prop in props) {\n if (prop.startsWith(\"aria-\") || prop === \"role\" || prop === \"title\") {\n return true;\n }\n }\n return false;\n};\n\nexport { hasA11yProp };\n//# sourceMappingURL=hasA11yProp.mjs.map\n","\"use strict\";\n\"use client\";\n/**\n * @license lucide-react v1.34.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { createContext, useContext, useMemo, createElement } from 'react';\n\nconst LucideContext = createContext({});\nfunction LucideProvider({\n children,\n size,\n color,\n strokeWidth,\n absoluteStrokeWidth,\n className\n}) {\n const value = useMemo(\n () => ({\n size,\n color,\n strokeWidth,\n absoluteStrokeWidth,\n className\n }),\n [size, color, strokeWidth, absoluteStrokeWidth, className]\n );\n return createElement(LucideContext.Provider, { value }, children);\n}\nconst useLucideContext = () => useContext(LucideContext);\n\nexport { LucideProvider, useLucideContext };\n//# sourceMappingURL=context.mjs.map\n","\"use strict\";\n\"use client\";\n/**\n * @license lucide-react v1.34.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport defaultAttributes from './defaultAttributes.mjs';\nimport { hasA11yProp } from './shared/src/utils/hasA11yProp.mjs';\nimport { mergeClasses } from './shared/src/utils/mergeClasses.mjs';\nimport { useLucideContext } from './context.mjs';\n\nconst Icon = forwardRef(\n ({ color, size, strokeWidth, absoluteStrokeWidth, className = \"\", children, iconNode, ...rest }, ref) => {\n const {\n size: contextSize = 24,\n strokeWidth: contextStrokeWidth = 2,\n absoluteStrokeWidth: contextAbsoluteStrokeWidth = false,\n color: contextColor = \"currentColor\",\n className: contextClass = \"\"\n } = useLucideContext() ?? {};\n const calculatedStrokeWidth = absoluteStrokeWidth ?? contextAbsoluteStrokeWidth ? Number(strokeWidth ?? contextStrokeWidth) * 24 / Number(size ?? contextSize) : strokeWidth ?? contextStrokeWidth;\n return createElement(\n \"svg\",\n {\n ref,\n ...defaultAttributes,\n width: size ?? contextSize ?? defaultAttributes.width,\n height: size ?? contextSize ?? defaultAttributes.height,\n stroke: color ?? contextColor,\n strokeWidth: calculatedStrokeWidth,\n className: mergeClasses(\"lucide\", contextClass, className),\n ...!children && !hasA11yProp(rest) && { \"aria-hidden\": \"true\" },\n ...rest\n },\n [\n ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),\n ...Array.isArray(children) ? children : [children]\n ]\n );\n }\n);\n\nexport { Icon as default };\n//# sourceMappingURL=Icon.mjs.map\n","/**\n * @license lucide-react v1.34.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport { mergeClasses } from './shared/src/utils/mergeClasses.mjs';\nimport { toKebabCase } from './shared/src/utils/toKebabCase.mjs';\nimport { toPascalCase } from './shared/src/utils/toPascalCase.mjs';\nimport Icon from './Icon.mjs';\n\nconst createLucideIcon = (iconName, iconNode) => {\n const Component = forwardRef(\n ({ className, ...props }, ref) => createElement(Icon, {\n ref,\n iconNode,\n className: mergeClasses(\n `lucide-${toKebabCase(toPascalCase(iconName))}`,\n `lucide-${iconName}`,\n className\n ),\n ...props\n })\n );\n Component.displayName = toPascalCase(iconName);\n return Component;\n};\n\nexport { createLucideIcon as default };\n//# sourceMappingURL=createLucideIcon.mjs.map\n","/**\n * @license lucide-react v1.34.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49\",\n key: \"ct8e1f\"\n }\n ],\n [\"path\", { d: \"M14.084 14.158a3 3 0 0 1-4.242-4.242\", key: \"151rxh\" }],\n [\n \"path\",\n {\n d: \"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143\",\n key: \"13bj9a\"\n }\n ],\n [\"path\", { d: \"m2 2 20 20\", key: \"1ooewy\" }]\n];\nconst EyeOff = createLucideIcon(\"eye-off\", __iconNode);\n\nexport { __iconNode, EyeOff as default };\n//# sourceMappingURL=eye-off.mjs.map\n","/**\n * @license lucide-react v1.34.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0\",\n key: \"1nclc0\"\n }\n ],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"3\", key: \"1v7zrd\" }]\n];\nconst Eye = createLucideIcon(\"eye\", __iconNode);\n\nexport { __iconNode, Eye as default };\n//# sourceMappingURL=eye.mjs.map\n","import { useState } from \"react\"\nimport { Eye, EyeOff } from \"lucide-react\"\nimport { useFormContext } from \"@rpcbase/form\"\nimport { cn, Input } from \"@rpcbase/ui\"\n\n\ntype PasswordInputProps = {\n id: string\n name?: string\n className?: string\n placeholder?: string\n autoComplete?: string\n}\n\nexport const PasswordInput = ({\n id,\n name = \"password\",\n className,\n placeholder,\n autoComplete = \"current-password\",\n}: PasswordInputProps) => {\n const [showPassword, setShowPassword] = useState(false)\n const { register, formState } = useFormContext()\n\n const fieldError = formState.errors[name as keyof typeof formState.errors]\n const errorMessage =\n typeof fieldError === \"string\"\n ? fieldError\n : typeof fieldError?.message === \"string\"\n ? fieldError.message\n : undefined\n\n const inputClassName = cn(className, \"pr-11\")\n\n return (\n <>\n <div className=\"relative\">\n <Input\n id={id}\n type={showPassword ? \"text\" : \"password\"}\n autoComplete={autoComplete}\n className={inputClassName}\n placeholder={placeholder}\n {...register(name as Parameters<typeof register>[0])}\n />\n <button\n type=\"button\"\n className=\"absolute inset-y-0 right-0 flex items-center pr-3 text-gray-500\"\n onClick={() => setShowPassword((prev) => !prev)}\n aria-label={showPassword ? \"Hide characters\" : \"Show characters\"}\n >\n {showPassword ? (\n <EyeOff className=\"h-5 w-5\" aria-hidden />\n ) : (\n <Eye className=\"h-5 w-5\" aria-hidden />\n )}\n </button>\n </div>\n {errorMessage ? (\n <p className=\"mt-1 -mb-2 text-sm/6 text-red-500\">{errorMessage}</p>\n ) : null}\n </>\n )\n}\n","import {useEffect, useState} from \"react\"\nimport clsx from \"clsx\"\n\n\nexport const useResendCountdown = (seconds = 60, initiallyCountingDown = true) => {\n const [remaining, setRemaining] = useState(seconds)\n const [isCountingDown, setIsCountingDown] = useState(initiallyCountingDown)\n\n useEffect(() => {\n if (!isCountingDown) return\n\n const timer = setInterval(() => {\n setRemaining((prev) => {\n if (prev <= 1) {\n setIsCountingDown(false)\n return seconds\n }\n return prev - 1\n })\n }, 1000)\n\n return () => clearInterval(timer)\n }, [isCountingDown, seconds])\n\n const restart = (nextSeconds?: number) => {\n const value = typeof nextSeconds === \"number\" ? nextSeconds : seconds\n setRemaining(value)\n setIsCountingDown(true)\n }\n\n const minutes = Math.floor(remaining / 60)\n const secs = remaining % 60\n const formatted = `${minutes}:${secs.toString().padStart(2, \"0\")}`\n\n const canResend = !isCountingDown\n\n return {remaining, formatted, isCountingDown, canResend, restart}\n}\n\n\nexport const ResendCodeButton = ({\n seconds = 60,\n onResend,\n className,\n disabled,\n}: {\n seconds?: number\n onResend?: () => Promise<void> | void\n className?: string\n disabled?: boolean\n}) => {\n const [isSending, setIsSending] = useState(false)\n const {formatted, isCountingDown, restart, canResend} = useResendCountdown(seconds)\n\n const handleClick = async () => {\n if (!canResend || isSending || disabled) return\n\n try {\n setIsSending(true)\n if (onResend) {\n await onResend()\n }\n } finally {\n restart()\n setIsSending(false)\n }\n }\n\n const isDisabled = disabled || isCountingDown || isSending\n const showCountdown = isDisabled && (isCountingDown || isSending)\n\n return (\n <span className=\"inline-flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={isDisabled}\n aria-label=\"Resend code\"\n className={clsx(\n \"text-sm font-semibold text-sky-600 hover:underline disabled:cursor-not-allowed disabled:text-gray-400\",\n className\n )}\n >\n Resend code\n </button>\n {showCountdown ? (\n <span\n data-testid=\"resend-countdown\"\n className=\"text-sm text-gray-500\"\n aria-live=\"polite\"\n >\n ({formatted})\n </span>\n ) : null}\n </span>\n )\n}\n","import { useRef, useState } from \"react\"\n\nimport { useResendCountdown } from \"./components/ResendCodeButton\"\n\n\nexport const DEFAULT_PASSWORD_RESET_COOLDOWN_SECONDS = 60\n\nexport type PasswordResetCodeRequestResult = {\n retryAfterSeconds: number\n}\n\nexport class PasswordResetCodeRequestError extends Error {\n retryAfterSeconds?: number\n errorCode?: string\n\n constructor(retryAfterSeconds?: number, errorCode?: string) {\n super(\"Unable to request a password reset code\")\n this.name = \"PasswordResetCodeRequestError\"\n this.retryAfterSeconds = retryAfterSeconds\n this.errorCode = errorCode\n }\n}\n\nconst parseRetryAfterSeconds = (value: unknown) => {\n const seconds = typeof value === \"number\" ? value : Number(value)\n if (!Number.isFinite(seconds) || seconds <= 0) return undefined\n return Math.ceil(seconds)\n}\n\nexport const requestPasswordResetCode = async(email: string): Promise<PasswordResetCodeRequestResult> => {\n const response = await fetch(\"/api/rb/auth/request-password-reset\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ email }),\n })\n\n const payload = await response.json().catch(() => null) as {\n success?: unknown\n error?: unknown\n retryAfterSeconds?: unknown\n } | null\n const retryAfterSeconds = parseRetryAfterSeconds(payload?.retryAfterSeconds)\n ?? parseRetryAfterSeconds(response.headers.get(\"Retry-After\"))\n\n if (!response.ok || payload?.success !== true) {\n const errorCode = typeof payload?.error === \"string\" ? payload.error : undefined\n throw new PasswordResetCodeRequestError(retryAfterSeconds, errorCode)\n }\n\n return {\n retryAfterSeconds: retryAfterSeconds ?? DEFAULT_PASSWORD_RESET_COOLDOWN_SECONDS,\n }\n}\n\nexport const usePasswordResetResend = ({\n email,\n cooldownSeconds = DEFAULT_PASSWORD_RESET_COOLDOWN_SECONDS,\n}: {\n email?: string | null\n cooldownSeconds?: number\n}) => {\n const countdown = useResendCountdown(cooldownSeconds)\n const [isResending, setIsResending] = useState(false)\n const isResendingRef = useRef(false)\n\n const resend = async() => {\n if (!email || !countdown.canResend || isResendingRef.current) return null\n\n isResendingRef.current = true\n setIsResending(true)\n\n try {\n const result = await requestPasswordResetCode(email)\n countdown.restart(result.retryAfterSeconds)\n return result\n } catch (error) {\n if (error instanceof PasswordResetCodeRequestError && error.retryAfterSeconds) {\n countdown.restart(error.retryAfterSeconds)\n }\n throw error\n } finally {\n isResendingRef.current = false\n setIsResending(false)\n }\n }\n\n return {\n resend,\n isResending,\n remainingSeconds: countdown.remaining,\n formatted: countdown.formatted,\n isCountingDown: countdown.isCountingDown,\n canResend: Boolean(email) && countdown.canResend && !isResending,\n }\n}\n"],"x_google_ignoreList":[7,8,9,10,11,12,13,14,15,16,17],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["onPress","errorMessage","id","className","placeholder","nextPath","__iconNode"],"sources":["../src/components/AuthLayout/index.tsx","../src/components/AppleSignInButton/index.tsx","../src/components/EmailInput/index.tsx","../src/utils/sanitizeNextPath.ts","../src/components/SignInForm/index.tsx","../src/components/SignUpForm/index.tsx","../src/components/RememberMeCheckbox/index.tsx","../../../node_modules/lucide-react/dist/esm/shared/src/utils/mergeClasses.mjs","../../../node_modules/lucide-react/dist/esm/shared/src/utils/toKebabCase.mjs","../../../node_modules/lucide-react/dist/esm/shared/src/utils/toCamelCase.mjs","../../../node_modules/lucide-react/dist/esm/shared/src/utils/toPascalCase.mjs","../../../node_modules/lucide-react/dist/esm/defaultAttributes.mjs","../../../node_modules/lucide-react/dist/esm/shared/src/utils/hasA11yProp.mjs","../../../node_modules/lucide-react/dist/esm/context.mjs","../../../node_modules/lucide-react/dist/esm/Icon.mjs","../../../node_modules/lucide-react/dist/esm/createLucideIcon.mjs","../../../node_modules/lucide-react/dist/esm/icons/eye-off.mjs","../../../node_modules/lucide-react/dist/esm/icons/eye.mjs","../src/components/PasswordInput/index.tsx","../src/components/ResendCodeButton/index.tsx","../src/passwordReset.ts"],"sourcesContent":["import * as React from \"react\"\nimport {Link, useLocation } from \"@rpcbase/router\"\n\n\nconst LINKS_REDIRECTION_MAP = {\n \"/auth/sign-in\": {\n \"title\": \"Sign Up\",\n \"location\": \"/auth/sign-up\"\n },\n \"/auth/sign-up\": {\n \"title\": \"Sign In\",\n \"location\": \"/auth/sign-in\"\n },\n \"/auth/logout-success\": {\n \"title\": \"Sign In\",\n \"location\": \"/auth/sign-in\"\n }\n}\n\ntype Pathname = keyof typeof LINKS_REDIRECTION_MAP\n\nexport const AuthLayout = ({\n sidePanel = null,\n children,\n}: {\n sidePanel: React.ReactElement | null\n children: React.ReactNode\n}) => {\n const location = useLocation()\n\n const linkTitle = LINKS_REDIRECTION_MAP[location.pathname as Pathname]?.title\n const linkLocation = LINKS_REDIRECTION_MAP[location.pathname as Pathname]?.location\n\n return (\n <div className=\"container relative flex min-h-dvh flex-col items-center justify-center px-4 py-20 sm:px-6 md:px-8 lg:grid lg:h-dvh lg:w-full lg:max-w-none lg:grid-cols-2 lg:px-0 lg:py-0\">\n {/* Top-right redirection link */}\n {linkTitle && linkLocation ? (\n <Link\n className=\"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 hover:bg-accent hover:text-accent-foreground h-9 px-4 py-2 absolute right-4 top-4 md:right-8 md:top-8\"\n to={linkLocation}\n >\n {linkTitle}\n </Link>\n ) : null}\n <div className=\"relative hidden h-full flex-col bg-muted p-10 text-white dark:border-r lg:flex\">\n {sidePanel}\n </div>\n <div className=\"mx-auto flex w-full flex-col justify-center gap-6 /*sm:w-[350px]*/\">\n {children}\n </div>\n </div>\n )\n}\n","import clsx from \"clsx\"\n\n\nexport const AppleSignInButton = ({\n onPress,\n className,\n}: {\n onPress: () => void;\n className?: string;\n}) => {\n\n return (\n <button\n onClick={onPress}\n className={clsx(`\n w-full\n bg-black text-white hover:bg-gray-800\n flex items-center justify-center\n px-6 py-2\n rounded-lg\n font-medium\n transition duration-150 ease-in-out\n focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-black\n `, className)}\n >\n <svg\n className=\"w-5 h-5 mr-3\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"white\"\n >\n <path d=\"M12.152 6.896c-.948 0-2.415-1.078-3.96-1.04-2.04.027-3.91 1.183-4.961 3.014-2.117 3.675-.539 9.103 1.519 12.09 1.013 1.454 2.208 3.09 3.792 3.039 1.52-.065 2.09-.987 3.935-.987 1.831 0 2.35.987 3.96.948 1.637-.026 2.676-1.48 3.676-2.948 1.156-1.688 1.636-3.325 1.662-3.415-.039-.013-3.182-1.221-3.22-4.857-.026-3.04 2.48-4.494 2.597-4.559-1.429-2.09-3.623-2.324-4.39-2.376-2-.156-3.675 1.09-4.61 1.09zM15.53 3.83c.843-1.012 1.4-2.427 1.245-3.83-1.207.052-2.662.805-3.532 1.818-.78.896-1.454 2.338-1.273 3.714 1.338.104 2.715-.688 3.559-1.701\" />\n </svg>\n <span>Continue with Apple</span>\n </button>\n )\n}\n","import {useFormContext} from \"@rpcbase/form\"\nimport { Input } from \"@rpcbase/ui\"\n\n\nexport const EmailInput = ({\n id,\n className,\n placeholder,\n}: {\n id: string\n className?: string\n placeholder?: string\n}) => {\n const {register, formState} = useFormContext()\n\n const error = formState.errors.email\n let errorMessage: string | undefined\n if (typeof error === \"string\") {\n errorMessage = error\n } else if (error && typeof error.message === \"string\") {\n errorMessage = error.message\n }\n\n return (\n <>\n <Input\n id={id}\n type=\"email\"\n required\n autoComplete=\"email\"\n className={className}\n placeholder={placeholder}\n {...register(\"email\")}\n />\n {errorMessage ? (\n <p className=\"mt-1 -mb-2 text-sm/6 text-red-500\">{errorMessage}</p>\n ) : null}\n </>\n )\n}\n","const hasUnsafeNextPathChars = (value: string) => {\n for (let i = 0; i < value.length; i++) {\n const code = value.charCodeAt(i)\n if (code === 92 || code <= 31 || code === 127) return true\n }\n return false\n}\n\nexport const sanitizeNextPath = (raw: string | null) => {\n if (!raw) return null\n\n const nextPath = raw.trim()\n if (!nextPath) return null\n\n if (!nextPath.startsWith(\"/\") || nextPath.startsWith(\"//\")) {\n return null\n }\n\n if (hasUnsafeNextPathChars(nextPath)) {\n return null\n }\n\n try {\n const base = new URL(\"http://localhost\")\n const url = new URL(nextPath, base)\n if (url.origin !== base.origin) {\n return null\n }\n return `${url.pathname}${url.search}${url.hash}`\n } catch {\n return null\n }\n}\n\n","import { ReactNode } from \"react\"\nimport { useNavigate, useSearchParams } from \"@rpcbase/router\"\nimport { useForm, FormProvider, zodResolver } from \"@rpcbase/form\"\nimport type { SubmitHandler } from \"@rpcbase/form\"\nimport { z } from \"zod\"\n\nimport {requestSchema} from \"../../api/sign-in\"\nimport { sanitizeNextPath } from \"../../utils/sanitizeNextPath\"\n\n\ntype SignInFormValues = z.input<typeof requestSchema>\n\nexport const SignInForm = ({\n children,\n className\n}: {\n children: ReactNode,\n className?: string\n}) => {\n const navigate = useNavigate()\n const [searchParams] = useSearchParams()\n\n const methods = useForm<SignInFormValues>({\n defaultValues: {\n email: \"\",\n password: \"\",\n rememberMe: true,\n },\n navigationGuard: false,\n resolver: zodResolver(requestSchema)\n })\n\n const onSubmit: SubmitHandler<SignInFormValues> = async (data) => {\n methods.clearErrors(\"root\")\n\n try {\n const res = await fetch(\"/api/rb/auth/sign-in\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(data),\n credentials: \"include\",\n })\n\n const json = await res.json().catch(() => null) as { success?: boolean; error?: string } | null\n\n if (!res.ok || !json?.success) {\n if (json?.error === \"email_verification_required\") {\n const nextPath = sanitizeNextPath(searchParams.get(\"next\")) ?? \"/\"\n const search = new URLSearchParams({ email: data.email.trim().toLowerCase() })\n search.set(\"next\", nextPath)\n navigate(`/auth/sign-up-otp?${search.toString()}`)\n return\n }\n\n const message = json?.error === \"invalid_credentials\"\n ? \"Invalid email or password.\"\n : \"Sign-in failed. Please try again.\"\n methods.setError(\"root\", { type: \"server\", message })\n return\n }\n\n const nextPath = sanitizeNextPath(searchParams.get(\"next\")) ?? \"/\"\n navigate(nextPath, { replace: true })\n } catch (err) {\n methods.setError(\"root\", { type: \"server\", message: \"Network error. Please try again.\" })\n }\n }\n\n return (\n <FormProvider {...methods}>\n <form method=\"post\" noValidate className={className} onSubmit={methods.handleSubmit(onSubmit)}>\n {children}\n {methods.formState.errors.root?.message && (\n <p className=\"mt-2 text-sm text-red-600\" role=\"alert\">\n {methods.formState.errors.root.message}\n </p>\n )}\n </form>\n </FormProvider>\n )\n}\n","import {ReactNode, useState} from \"react\"\nimport { useNavigate } from \"@rpcbase/router\"\nimport { useForm, FormProvider, zodResolver } from \"@rpcbase/form\"\nimport type {SubmitHandler} from \"@rpcbase/form\"\nimport { z } from \"zod\"\n\nimport {requestSchema} from \"../../api/sign-up\"\n\n\ntype SignUpFormValues = z.input<typeof requestSchema>\n\n\nexport const SignUpForm = ({\n children,\n className,\n otpNextPath\n}: {\n children: ReactNode,\n className?: string\n otpNextPath?: string\n}) => {\n\n const navigate = useNavigate()\n\n const [serverMessage, setServerMessage] = useState<string | null>(null)\n const methods = useForm<SignUpFormValues>({\n defaultValues: {\n email: \"\",\n password: \"\",\n rememberMe: true,\n },\n navigationGuard: false,\n resolver: zodResolver(requestSchema)\n })\n\n const onSubmit: SubmitHandler<SignUpFormValues> = async (data) => {\n setServerMessage(null)\n methods.clearErrors(\"root\")\n\n try {\n const res = await fetch(\"/api/rb/auth/sign-up\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(data),\n credentials: \"include\",\n })\n\n const json = await res.json()\n\n if (!res.ok) {\n const message = json.error === \"user_exists\"\n ? \"An account already exists with this email.\"\n : \"Sign-up failed. Please try again.\"\n methods.setError(\"root\", { type: \"server\", message })\n return\n }\n\n if (!json.success) {\n methods.setError(\"root\", { type: \"server\", message: \"Sign-up failed. Please try again.\" })\n return\n }\n\n const search = new URLSearchParams({ email: data.email.trim().toLowerCase() })\n if (otpNextPath) {\n search.set(\"next\", otpNextPath)\n }\n navigate(`/auth/sign-up-otp?${search.toString()}`)\n setServerMessage(\"Account created. Check your inbox to verify your email.\")\n } catch (err) {\n methods.setError(\"root\", { type: \"server\", message: \"Network error. Please try again.\" })\n }\n }\n\n return (\n <FormProvider {...methods}>\n <form method=\"post\" noValidate className={className} onSubmit={methods.handleSubmit(onSubmit)}>\n {children}\n {methods.formState.errors.root?.message && (\n <p className=\"mt-2 text-sm text-red-600\" role=\"alert\">\n {methods.formState.errors.root.message}\n </p>\n )}\n {serverMessage && (\n <p className=\"mt-2 text-sm text-green-700\" role=\"status\">\n {serverMessage}\n </p>\n )}\n </form>\n </FormProvider>\n )\n}\n","import type { ElementType } from \"react\"\nimport {useFormContext} from \"@rpcbase/form\"\n\n\nexport const RememberMeCheckbox = ({\n label,\n as: Component = \"input\"\n}: {\n label: string,\n as?: ElementType\n}) => {\n const {register} = useFormContext()\n\n return (\n <>\n <Component\n id=\"rememberMe\"\n {...register(\"rememberMe\")}\n />\n <label\n htmlFor={\"rememberMe\"}\n className=\"pl-2 block text-sm/6 text-gray-900\"\n >\n {label}\n </label>\n </>\n )\n}\n","/**\n * @license lucide-react v1.34.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst mergeClasses = (...classes) => classes.filter((className, index, array) => {\n return Boolean(className) && className.trim() !== \"\" && array.indexOf(className) === index;\n}).join(\" \").trim();\n\nexport { mergeClasses };\n//# sourceMappingURL=mergeClasses.mjs.map\n","/**\n * @license lucide-react v1.34.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, \"$1-$2\").toLowerCase();\n\nexport { toKebabCase };\n//# sourceMappingURL=toKebabCase.mjs.map\n","/**\n * @license lucide-react v1.34.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst toCamelCase = (string) => string.replace(\n /^([A-Z])|[\\s-_]+(\\w)/g,\n (match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase()\n);\n\nexport { toCamelCase };\n//# sourceMappingURL=toCamelCase.mjs.map\n","/**\n * @license lucide-react v1.34.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { toCamelCase } from './toCamelCase.mjs';\n\nconst toPascalCase = (string) => {\n const camelCase = toCamelCase(string);\n return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);\n};\n\nexport { toPascalCase };\n//# sourceMappingURL=toPascalCase.mjs.map\n","/**\n * @license lucide-react v1.34.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nvar defaultAttributes = {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: 24,\n height: 24,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n};\n\nexport { defaultAttributes as default };\n//# sourceMappingURL=defaultAttributes.mjs.map\n","/**\n * @license lucide-react v1.34.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst hasA11yProp = (props) => {\n for (const prop in props) {\n if (prop.startsWith(\"aria-\") || prop === \"role\" || prop === \"title\") {\n return true;\n }\n }\n return false;\n};\n\nexport { hasA11yProp };\n//# sourceMappingURL=hasA11yProp.mjs.map\n","\"use strict\";\n\"use client\";\n/**\n * @license lucide-react v1.34.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { createContext, useContext, useMemo, createElement } from 'react';\n\nconst LucideContext = createContext({});\nfunction LucideProvider({\n children,\n size,\n color,\n strokeWidth,\n absoluteStrokeWidth,\n className\n}) {\n const value = useMemo(\n () => ({\n size,\n color,\n strokeWidth,\n absoluteStrokeWidth,\n className\n }),\n [size, color, strokeWidth, absoluteStrokeWidth, className]\n );\n return createElement(LucideContext.Provider, { value }, children);\n}\nconst useLucideContext = () => useContext(LucideContext);\n\nexport { LucideProvider, useLucideContext };\n//# sourceMappingURL=context.mjs.map\n","\"use strict\";\n\"use client\";\n/**\n * @license lucide-react v1.34.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport defaultAttributes from './defaultAttributes.mjs';\nimport { hasA11yProp } from './shared/src/utils/hasA11yProp.mjs';\nimport { mergeClasses } from './shared/src/utils/mergeClasses.mjs';\nimport { useLucideContext } from './context.mjs';\n\nconst Icon = forwardRef(\n ({ color, size, strokeWidth, absoluteStrokeWidth, className = \"\", children, iconNode, ...rest }, ref) => {\n const {\n size: contextSize = 24,\n strokeWidth: contextStrokeWidth = 2,\n absoluteStrokeWidth: contextAbsoluteStrokeWidth = false,\n color: contextColor = \"currentColor\",\n className: contextClass = \"\"\n } = useLucideContext() ?? {};\n const calculatedStrokeWidth = absoluteStrokeWidth ?? contextAbsoluteStrokeWidth ? Number(strokeWidth ?? contextStrokeWidth) * 24 / Number(size ?? contextSize) : strokeWidth ?? contextStrokeWidth;\n return createElement(\n \"svg\",\n {\n ref,\n ...defaultAttributes,\n width: size ?? contextSize ?? defaultAttributes.width,\n height: size ?? contextSize ?? defaultAttributes.height,\n stroke: color ?? contextColor,\n strokeWidth: calculatedStrokeWidth,\n className: mergeClasses(\"lucide\", contextClass, className),\n ...!children && !hasA11yProp(rest) && { \"aria-hidden\": \"true\" },\n ...rest\n },\n [\n ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),\n ...Array.isArray(children) ? children : [children]\n ]\n );\n }\n);\n\nexport { Icon as default };\n//# sourceMappingURL=Icon.mjs.map\n","/**\n * @license lucide-react v1.34.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport { mergeClasses } from './shared/src/utils/mergeClasses.mjs';\nimport { toKebabCase } from './shared/src/utils/toKebabCase.mjs';\nimport { toPascalCase } from './shared/src/utils/toPascalCase.mjs';\nimport Icon from './Icon.mjs';\n\nconst createLucideIcon = (iconName, iconNode) => {\n const Component = forwardRef(\n ({ className, ...props }, ref) => createElement(Icon, {\n ref,\n iconNode,\n className: mergeClasses(\n `lucide-${toKebabCase(toPascalCase(iconName))}`,\n `lucide-${iconName}`,\n className\n ),\n ...props\n })\n );\n Component.displayName = toPascalCase(iconName);\n return Component;\n};\n\nexport { createLucideIcon as default };\n//# sourceMappingURL=createLucideIcon.mjs.map\n","/**\n * @license lucide-react v1.34.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49\",\n key: \"ct8e1f\"\n }\n ],\n [\"path\", { d: \"M14.084 14.158a3 3 0 0 1-4.242-4.242\", key: \"151rxh\" }],\n [\n \"path\",\n {\n d: \"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143\",\n key: \"13bj9a\"\n }\n ],\n [\"path\", { d: \"m2 2 20 20\", key: \"1ooewy\" }]\n];\nconst EyeOff = createLucideIcon(\"eye-off\", __iconNode);\n\nexport { __iconNode, EyeOff as default };\n//# sourceMappingURL=eye-off.mjs.map\n","/**\n * @license lucide-react v1.34.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0\",\n key: \"1nclc0\"\n }\n ],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"3\", key: \"1v7zrd\" }]\n];\nconst Eye = createLucideIcon(\"eye\", __iconNode);\n\nexport { __iconNode, Eye as default };\n//# sourceMappingURL=eye.mjs.map\n","import { useState } from \"react\"\nimport { Eye, EyeOff } from \"lucide-react\"\nimport { useFormContext } from \"@rpcbase/form\"\nimport { cn, Input } from \"@rpcbase/ui\"\n\n\ntype PasswordInputProps = {\n id: string\n name?: string\n className?: string\n placeholder?: string\n autoComplete?: string\n}\n\nexport const PasswordInput = ({\n id,\n name = \"password\",\n className,\n placeholder,\n autoComplete = \"current-password\",\n}: PasswordInputProps) => {\n const [showPassword, setShowPassword] = useState(false)\n const { register, formState } = useFormContext()\n\n const fieldError = formState.errors[name as keyof typeof formState.errors]\n const errorMessage =\n typeof fieldError === \"string\"\n ? fieldError\n : typeof fieldError?.message === \"string\"\n ? fieldError.message\n : undefined\n\n const inputClassName = cn(className, \"pr-11\")\n\n return (\n <>\n <div className=\"relative\">\n <Input\n id={id}\n type={showPassword ? \"text\" : \"password\"}\n autoComplete={autoComplete}\n className={inputClassName}\n placeholder={placeholder}\n {...register(name as Parameters<typeof register>[0])}\n />\n <button\n type=\"button\"\n tabIndex={-1}\n className=\"absolute inset-y-0 right-0 flex items-center pr-3 text-gray-500\"\n onClick={() => setShowPassword((prev) => !prev)}\n aria-label={showPassword ? \"Hide characters\" : \"Show characters\"}\n >\n {showPassword ? (\n <EyeOff className=\"h-5 w-5\" aria-hidden />\n ) : (\n <Eye className=\"h-5 w-5\" aria-hidden />\n )}\n </button>\n </div>\n {errorMessage ? (\n <p className=\"mt-1 -mb-2 text-sm/6 text-red-500\">{errorMessage}</p>\n ) : null}\n </>\n )\n}\n","import {useEffect, useState} from \"react\"\nimport clsx from \"clsx\"\n\n\nexport const useResendCountdown = (seconds = 60, initiallyCountingDown = true) => {\n const [remaining, setRemaining] = useState(seconds)\n const [isCountingDown, setIsCountingDown] = useState(initiallyCountingDown)\n\n useEffect(() => {\n if (!isCountingDown) return\n\n const timer = setInterval(() => {\n setRemaining((prev) => {\n if (prev <= 1) {\n setIsCountingDown(false)\n return seconds\n }\n return prev - 1\n })\n }, 1000)\n\n return () => clearInterval(timer)\n }, [isCountingDown, seconds])\n\n const restart = (nextSeconds?: number) => {\n const value = typeof nextSeconds === \"number\" ? nextSeconds : seconds\n setRemaining(value)\n setIsCountingDown(true)\n }\n\n const minutes = Math.floor(remaining / 60)\n const secs = remaining % 60\n const formatted = `${minutes}:${secs.toString().padStart(2, \"0\")}`\n\n const canResend = !isCountingDown\n\n return {remaining, formatted, isCountingDown, canResend, restart}\n}\n\n\nexport const ResendCodeButton = ({\n seconds = 60,\n onResend,\n className,\n disabled,\n}: {\n seconds?: number\n onResend?: () => Promise<void> | void\n className?: string\n disabled?: boolean\n}) => {\n const [isSending, setIsSending] = useState(false)\n const {formatted, isCountingDown, restart, canResend} = useResendCountdown(seconds)\n\n const handleClick = async () => {\n if (!canResend || isSending || disabled) return\n\n try {\n setIsSending(true)\n if (onResend) {\n await onResend()\n }\n } finally {\n restart()\n setIsSending(false)\n }\n }\n\n const isDisabled = disabled || isCountingDown || isSending\n const showCountdown = isDisabled && (isCountingDown || isSending)\n\n return (\n <span className=\"inline-flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={isDisabled}\n aria-label=\"Resend code\"\n className={clsx(\n \"text-sm font-semibold text-sky-600 hover:underline disabled:cursor-not-allowed disabled:text-gray-400\",\n className\n )}\n >\n Resend code\n </button>\n {showCountdown ? (\n <span\n data-testid=\"resend-countdown\"\n className=\"text-sm text-gray-500\"\n aria-live=\"polite\"\n >\n ({formatted})\n </span>\n ) : null}\n </span>\n )\n}\n","import { useRef, useState } from \"react\"\n\nimport { useResendCountdown } from \"./components/ResendCodeButton\"\n\n\nexport const DEFAULT_PASSWORD_RESET_COOLDOWN_SECONDS = 60\n\nexport type PasswordResetCodeRequestResult = {\n retryAfterSeconds: number\n}\n\nexport class PasswordResetCodeRequestError extends Error {\n retryAfterSeconds?: number\n errorCode?: string\n\n constructor(retryAfterSeconds?: number, errorCode?: string) {\n super(\"Unable to request a password reset code\")\n this.name = \"PasswordResetCodeRequestError\"\n this.retryAfterSeconds = retryAfterSeconds\n this.errorCode = errorCode\n }\n}\n\nconst parseRetryAfterSeconds = (value: unknown) => {\n const seconds = typeof value === \"number\" ? value : Number(value)\n if (!Number.isFinite(seconds) || seconds <= 0) return undefined\n return Math.ceil(seconds)\n}\n\nexport const requestPasswordResetCode = async(email: string): Promise<PasswordResetCodeRequestResult> => {\n const response = await fetch(\"/api/rb/auth/request-password-reset\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ email }),\n })\n\n const payload = await response.json().catch(() => null) as {\n success?: unknown\n error?: unknown\n retryAfterSeconds?: unknown\n } | null\n const retryAfterSeconds = parseRetryAfterSeconds(payload?.retryAfterSeconds)\n ?? parseRetryAfterSeconds(response.headers.get(\"Retry-After\"))\n\n if (!response.ok || payload?.success !== true) {\n const errorCode = typeof payload?.error === \"string\" ? payload.error : undefined\n throw new PasswordResetCodeRequestError(retryAfterSeconds, errorCode)\n }\n\n return {\n retryAfterSeconds: retryAfterSeconds ?? DEFAULT_PASSWORD_RESET_COOLDOWN_SECONDS,\n }\n}\n\nexport const usePasswordResetResend = ({\n email,\n cooldownSeconds = DEFAULT_PASSWORD_RESET_COOLDOWN_SECONDS,\n}: {\n email?: string | null\n cooldownSeconds?: number\n}) => {\n const countdown = useResendCountdown(cooldownSeconds)\n const [isResending, setIsResending] = useState(false)\n const isResendingRef = useRef(false)\n\n const resend = async() => {\n if (!email || !countdown.canResend || isResendingRef.current) return null\n\n isResendingRef.current = true\n setIsResending(true)\n\n try {\n const result = await requestPasswordResetCode(email)\n countdown.restart(result.retryAfterSeconds)\n return result\n } catch (error) {\n if (error instanceof PasswordResetCodeRequestError && error.retryAfterSeconds) {\n countdown.restart(error.retryAfterSeconds)\n }\n throw error\n } finally {\n isResendingRef.current = false\n setIsResending(false)\n }\n }\n\n return {\n resend,\n isResending,\n remainingSeconds: countdown.remaining,\n formatted: countdown.formatted,\n isCountingDown: countdown.isCountingDown,\n canResend: Boolean(email) && countdown.canResend && !isResending,\n }\n}\n"],"x_google_ignoreList":[7,8,9,10,11,12,13,14,15,16,17],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { t as isPendingRegistration } from "../registrationStatus-BP6yReMw.js";
1
2
  import { n as completeAuthSignIn } from "../session-BQ06Yo3C.js";
2
3
  import crypto from "crypto";
3
4
  import { createProvisionedTenant, models } from "@rpcbase/db";
@@ -458,7 +459,7 @@ var processOAuthCallback = async ({ ctx, providerId: providerIdOverride, createU
458
459
  const oauthUserEmail = typeof oauthUserRecord?.email === "string" ? oauthUserRecord.email.trim() : "";
459
460
  const oauthUserNameRecord = oauthUserRecord?.name && typeof oauthUserRecord.name === "object" ? oauthUserRecord.name : null;
460
461
  const oauthUserName = [typeof oauthUserNameRecord?.firstName === "string" ? oauthUserNameRecord.firstName.trim() : "", typeof oauthUserNameRecord?.lastName === "string" ? oauthUserNameRecord.lastName.trim() : ""].filter(Boolean).join(" ").trim();
461
- const resolvedEmail = email ?? (oauthUserEmail || void 0);
462
+ const resolvedEmail = (email?.trim() || oauthUserEmail || void 0)?.toLowerCase();
462
463
  const resolvedName = name ?? (oauthUserName || void 0);
463
464
  const [User, Tenant] = await Promise.all([models.getGlobal("RBUser", ctx), models.getGlobal("RBTenant", ctx)]);
464
465
  const subjectQueryKey = `oauthProviders.${providerId}.subject`;
@@ -507,6 +508,8 @@ var processOAuthCallback = async ({ ctx, providerId: providerIdOverride, createU
507
508
  createdAt: providerCreatedAt ?? now,
508
509
  updatedAt: now
509
510
  };
511
+ let shouldActivatePendingUser = false;
512
+ let pendingOAuthPasswordHash;
510
513
  if (!user) {
511
514
  const tenantId = crypto.randomUUID();
512
515
  user = new User({
@@ -539,6 +542,14 @@ var processOAuthCallback = async ({ ctx, providerId: providerIdOverride, createU
539
542
  }
540
543
  } else {
541
544
  const setFields = { [`oauthProviders.${providerId}`]: oauthProviderPayload };
545
+ shouldActivatePendingUser = isPendingRegistration({
546
+ registrationStatus: user.get("registrationStatus"),
547
+ emailVerificationCode: user.get("emailVerificationCode")
548
+ });
549
+ if (shouldActivatePendingUser) {
550
+ pendingOAuthPasswordHash = await hashPasswordForStorage(crypto.randomBytes(32).toString("hex"));
551
+ setFields.password = pendingOAuthPasswordHash;
552
+ }
542
553
  if (!user.email && resolvedEmail) setFields.email = resolvedEmail;
543
554
  if (!user.name && resolvedName) setFields.name = resolvedName;
544
555
  await User.updateOne({ _id: user._id }, { $set: setFields });
@@ -551,6 +562,24 @@ var processOAuthCallback = async ({ ctx, providerId: providerIdOverride, createU
551
562
  error: "tenant_unavailable",
552
563
  redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=tenant_unavailable`
553
564
  };
565
+ const tenant = await Tenant.findOne({ tenantId }, { provisioningStatus: 1 }).lean();
566
+ if (!tenant || tenant.provisioningStatus && tenant.provisioningStatus !== "active") return {
567
+ success: false,
568
+ type: "error",
569
+ error: "tenant_unavailable",
570
+ redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=tenant_unavailable`
571
+ };
572
+ if (shouldActivatePendingUser && pendingOAuthPasswordHash) await User.updateOne({ _id: user._id }, {
573
+ $set: {
574
+ registrationStatus: "active",
575
+ password: pendingOAuthPasswordHash
576
+ },
577
+ $unset: {
578
+ emailVerificationCode: "",
579
+ emailVerificationExpiresAt: "",
580
+ emailVerificationSentAt: ""
581
+ }
582
+ });
554
583
  const tenantRolesMap = user.get("tenantRoles");
555
584
  const tenantRoles = tenantRolesMap ? Object.fromEntries(tenantRolesMap.entries()) : void 0;
556
585
  if (!completeAuthSignIn(ctx, {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/oauth/config.ts","../../src/oauth/jwt.ts","../../src/oauth/oidc.ts","../../src/oauth/pkce.ts","../../src/oauth/providerId.ts","../../src/oauth/lib.ts"],"sourcesContent":["export type OAuthProviderConfig = {\n issuer: string\n clientId: string\n clientSecret?: string\n scope: string\n callbackPath: string\n}\n\ntype OAuthProvidersConfig = Record<string, OAuthProviderConfig>\n\ntype OAuthProvidersStore = {\n providers: OAuthProvidersConfig\n}\n\nconst STORE_KEY = Symbol.for(\"@rpcbase/auth/oauthProviders\")\n\nconst getStore = (): OAuthProvidersStore => {\n const anyGlobal = globalThis as unknown as Record<string | symbol, unknown>\n const existing = anyGlobal[STORE_KEY] as OAuthProvidersStore | undefined\n if (existing && typeof existing === \"object\" && existing.providers && typeof existing.providers === \"object\") {\n return existing\n }\n\n const created: OAuthProvidersStore = { providers: {} }\n anyGlobal[STORE_KEY] = created\n return created\n}\n\nconst normalizeProviders = (providers: Record<string, OAuthProviderConfig>): OAuthProvidersConfig => {\n const result: OAuthProvidersConfig = {}\n\n const isSafeRedirectPath = (candidate: string) => {\n if (!candidate.startsWith(\"/\")) return false\n if (candidate.startsWith(\"//\")) return false\n return true\n }\n\n for (const [providerIdRaw, value] of Object.entries(providers)) {\n const providerId = providerIdRaw.trim()\n if (!providerId) continue\n\n const issuer = typeof value?.issuer === \"string\" ? value.issuer.trim() : \"\"\n const clientId = typeof value?.clientId === \"string\" ? value.clientId.trim() : \"\"\n if (!issuer) throw new Error(`oauth provider \"${providerId}\" missing issuer`)\n if (!clientId) throw new Error(`oauth provider \"${providerId}\" missing clientId`)\n\n const clientSecret = typeof value?.clientSecret === \"string\" && value.clientSecret.trim()\n ? value.clientSecret\n : undefined\n\n const scope = typeof value?.scope === \"string\" ? value.scope.trim() : \"\"\n if (!scope) throw new Error(`oauth provider \"${providerId}\" missing scope`)\n\n const callbackPath = typeof value?.callbackPath === \"string\"\n ? value.callbackPath.trim()\n : \"\"\n if (!callbackPath) throw new Error(`oauth provider \"${providerId}\" missing callbackPath`)\n if (!isSafeRedirectPath(callbackPath)) throw new Error(`oauth provider \"${providerId}\" has invalid callbackPath`)\n\n result[providerId] = {\n issuer,\n clientId,\n clientSecret,\n scope,\n callbackPath,\n }\n }\n\n return result\n}\n\nexport const configureOAuthProviders = (providers: Record<string, OAuthProviderConfig>) => {\n const store = getStore()\n const normalized = normalizeProviders(providers)\n store.providers = { ...store.providers, ...normalized }\n}\n\nexport const setOAuthProviders = (providers: Record<string, OAuthProviderConfig>) => {\n const store = getStore()\n store.providers = normalizeProviders(providers)\n}\n\nexport const getOAuthProviderConfig = (providerId: string): OAuthProviderConfig | null => {\n const store = getStore()\n return store.providers[providerId] ?? null\n}\n","const decodeBase64Url = (value: string) => {\n const padded = value.replace(/-/g, \"+\").replace(/_/g, \"/\") + \"===\".slice((value.length + 3) % 4)\n return Buffer.from(padded, \"base64\").toString(\"utf8\")\n}\n\nexport const decodeJwtPayload = <T = Record<string, unknown>>(token: string): T | null => {\n const parts = token.split(\".\")\n if (parts.length < 2) return null\n\n try {\n const json = decodeBase64Url(parts[1])\n const parsed = JSON.parse(json) as T\n if (!parsed || typeof parsed !== \"object\") return null\n return parsed\n } catch {\n return null\n }\n}\n\n","export type OidcWellKnown = {\n issuer: string\n authorization_endpoint: string\n token_endpoint: string\n userinfo_endpoint?: string\n jwks_uri?: string\n}\n\nconst cache = new Map<string, Promise<OidcWellKnown>>()\n\nconst normalizeIssuer = (raw: string) => raw.trim().replace(/\\/+$/, \"\")\n\nexport const getOidcWellKnown = async (issuerRaw: string): Promise<OidcWellKnown> => {\n const issuer = normalizeIssuer(issuerRaw)\n if (!issuer) {\n throw new Error(\"OIDC issuer is required\")\n }\n\n const existing = cache.get(issuer)\n if (existing) {\n return existing\n }\n\n const loader = (async () => {\n const url = new URL(\"/.well-known/openid-configuration\", issuer)\n const response = await fetch(url, { headers: { Accept: \"application/json\" } })\n if (!response.ok) {\n const body = await response.text().catch(() => \"\")\n throw new Error(`Failed to fetch OIDC discovery document: ${response.status} ${body}`)\n }\n\n const json = await response.json().catch(() => null) as Partial<OidcWellKnown> | null\n if (!json || typeof json !== \"object\") {\n throw new Error(\"Invalid OIDC discovery document\")\n }\n\n const authorizationEndpoint = typeof json.authorization_endpoint === \"string\"\n ? json.authorization_endpoint\n : \"\"\n const tokenEndpoint = typeof json.token_endpoint === \"string\"\n ? json.token_endpoint\n : \"\"\n const issuerValue = typeof json.issuer === \"string\" ? json.issuer : issuer\n const userinfoEndpoint = typeof json.userinfo_endpoint === \"string\" ? json.userinfo_endpoint : undefined\n const jwksUri = typeof json.jwks_uri === \"string\" ? json.jwks_uri : undefined\n\n if (!authorizationEndpoint || !tokenEndpoint) {\n throw new Error(\"OIDC discovery document missing required endpoints\")\n }\n\n return {\n issuer: issuerValue,\n authorization_endpoint: authorizationEndpoint,\n token_endpoint: tokenEndpoint,\n userinfo_endpoint: userinfoEndpoint,\n jwks_uri: jwksUri,\n } satisfies OidcWellKnown\n })()\n\n cache.set(issuer, loader)\n\n try {\n return await loader\n } catch (err) {\n cache.delete(issuer)\n throw err\n }\n}\n\n","import crypto from \"crypto\"\n\n\nexport const base64UrlEncode = (input: Buffer) => input\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/g, \"\")\n\nexport const generatePkcePair = () => {\n const verifier = base64UrlEncode(crypto.randomBytes(32))\n const challenge = base64UrlEncode(crypto.createHash(\"sha256\").update(verifier).digest())\n\n return { verifier, challenge }\n}\n\n","const RESERVED_KEYS = new Set([\"__proto__\", \"prototype\", \"constructor\"])\n\nexport const isSafeOAuthProviderId = (value: string) => {\n const providerId = value.trim()\n if (!providerId) return false\n if (providerId.length > 128) return false\n if (RESERVED_KEYS.has(providerId)) return false\n return /^[a-zA-Z0-9_-]+$/.test(providerId)\n}\n\n","import crypto from \"crypto\"\n\nimport { ApiHandler, Ctx } from \"@rpcbase/api\"\nimport { createProvisionedTenant, models } from \"@rpcbase/db\"\nimport { hashPasswordForStorage } from \"@rpcbase/server\"\n\nimport { completeAuthSignIn } from \"../session\"\nimport type { AuthSessionUser } from \"../types\"\nimport { getOAuthProviderConfig } from \"./config\"\nimport { decodeJwtPayload } from \"./jwt\"\nimport { getOidcWellKnown } from \"./oidc\"\nimport { generatePkcePair } from \"./pkce\"\nimport { isSafeOAuthProviderId } from \"./providerId\"\n\n\nconst OAUTH_REQUEST_TTL_MS = 10 * 60 * 1000\nconst OAUTH_STATE_COOKIE_NAME = \"rb_oauth_state\"\ntype OAuthCtx = Ctx<AuthSessionUser>\ntype OAuthRequestRecord = {\n returnTo?: unknown\n codeVerifier?: unknown\n}\n\nconst getQueryString = (value: unknown) => {\n if (typeof value === \"string\") return value\n if (Array.isArray(value) && typeof value[0] === \"string\") return value[0]\n return null\n}\n\nconst getCookieValue = (ctx: OAuthCtx, name: string): string | null => {\n const header = ctx.req.headers?.cookie\n if (typeof header !== \"string\" || !header) return null\n\n for (const part of header.split(\";\")) {\n const [rawKey, ...rest] = part.split(\"=\")\n const key = rawKey?.trim()\n if (!key || key !== name) continue\n const rawValue = rest.join(\"=\").trim()\n if (!rawValue) return \"\"\n try {\n return decodeURIComponent(rawValue)\n } catch {\n return rawValue\n }\n }\n\n return null\n}\n\nconst isSafeRedirectPath = (candidate: string) => {\n if (!candidate.startsWith(\"/\")) return false\n if (candidate.startsWith(\"//\")) return false\n return true\n}\n\nconst getRequestOrigin = (ctx: OAuthCtx) => {\n const protoHeader = ctx.req.headers[\"x-forwarded-proto\"]\n const hostHeader = ctx.req.headers[\"x-forwarded-host\"]\n\n const protocol = typeof protoHeader === \"string\"\n ? protoHeader.split(\",\")[0].trim()\n : ctx.req.protocol\n\n const host = typeof hostHeader === \"string\"\n ? hostHeader.split(\",\")[0].trim()\n : ctx.req.get(\"host\")\n\n return protocol && host ? `${protocol}://${host}` : \"\"\n}\n\nconst resolveCallbackPath = (callbackPath: string) => {\n const trimmed = callbackPath.trim()\n return trimmed && isSafeRedirectPath(trimmed) ? trimmed : null\n}\n\nconst readTextBody = async (req: Pick<OAuthCtx[\"req\"], \"on\" | \"setEncoding\">) =>\n await new Promise<string>((resolve, reject) => {\n let body = \"\"\n if (typeof req.setEncoding === \"function\") {\n req.setEncoding(\"utf8\")\n }\n\n req.on(\"data\", (chunk) => {\n body += String(chunk)\n if (body.length > 32_768) {\n reject(new Error(\"request_body_too_large\"))\n }\n })\n req.on(\"end\", () => resolve(body))\n req.on(\"error\", reject)\n })\n\nconst getFormPostParams = async (ctx: OAuthCtx): Promise<Record<string, string> | null> => {\n if (ctx.req.method !== \"POST\") return null\n\n const contentType = typeof ctx.req.headers[\"content-type\"] === \"string\" ? ctx.req.headers[\"content-type\"] : \"\"\n if (!contentType.includes(\"application/x-www-form-urlencoded\")) return null\n\n const body = await readTextBody(ctx.req)\n const params = new URLSearchParams(body)\n\n const result: Record<string, string> = {}\n for (const [key, value] of params.entries()) {\n result[key] = value\n }\n\n return result\n}\n\nconst resolveProviderId = (ctx: OAuthCtx, providerIdOverride?: string) =>\n (providerIdOverride ?? String(ctx.req.params?.provider ?? \"\")).trim()\n\nconst RESERVED_AUTH_PARAM_KEYS = new Set([\"__proto__\", \"prototype\", \"constructor\"])\n\nconst normalizeAuthorizationParams = (value: unknown): Record<string, string> | undefined => {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return undefined\n\n const result: Record<string, string> = {}\n for (const [keyRaw, valueRaw] of Object.entries(value)) {\n const key = keyRaw.trim()\n if (!key) continue\n if (RESERVED_AUTH_PARAM_KEYS.has(key)) continue\n const val = typeof valueRaw === \"string\" ? valueRaw.trim() : \"\"\n if (!val) continue\n result[key] = val\n }\n\n return Object.keys(result).length ? result : undefined\n}\n\nexport type OAuthStartResult =\n | { success: true; redirectUrl: string }\n | { success: false; error: string; statusCode: number }\n\nexport const getOAuthStartRedirectUrl = async ({\n ctx,\n providerId: providerIdOverride,\n returnTo,\n authorizationParams,\n}: {\n ctx: OAuthCtx\n providerId?: string\n returnTo?: string | null\n authorizationParams?: Record<string, string>\n}): Promise<OAuthStartResult> => {\n const providerId = resolveProviderId(ctx, providerIdOverride)\n if (!providerId) {\n return { success: false, error: \"missing_provider\", statusCode: 400 }\n }\n\n if (!isSafeOAuthProviderId(providerId)) {\n return { success: false, error: \"invalid_provider\", statusCode: 400 }\n }\n\n const provider = getOAuthProviderConfig(providerId)\n if (!provider) {\n return { success: false, error: \"unknown_provider\", statusCode: 404 }\n }\n\n const origin = getRequestOrigin(ctx)\n if (!origin) {\n return { success: false, error: \"origin_unavailable\", statusCode: 500 }\n }\n const isHttps = origin.startsWith(\"https://\")\n\n const callbackPath = resolveCallbackPath(provider.callbackPath)\n if (!callbackPath) {\n return { success: false, error: \"invalid_callback_path\", statusCode: 500 }\n }\n\n const state = crypto.randomBytes(16).toString(\"hex\")\n const { verifier, challenge } = generatePkcePair()\n\n const safeReturnTo = typeof returnTo === \"string\" && isSafeRedirectPath(returnTo) ? returnTo : undefined\n\n try {\n const OAuthRequest = await models.getGlobal(\"RBOAuthRequest\", ctx)\n const now = new Date()\n await OAuthRequest.create({\n _id: state,\n providerId,\n codeVerifier: verifier,\n returnTo: safeReturnTo,\n createdAt: now,\n expiresAt: new Date(now.getTime() + OAUTH_REQUEST_TTL_MS),\n })\n } catch (err) {\n console.warn(\"oauth::failed_to_store_request\", err)\n return { success: false, error: \"oauth_request_store_failed\", statusCode: 500 }\n }\n\n try {\n ctx.res.cookie(OAUTH_STATE_COOKIE_NAME, `${providerId}:${state}`, {\n httpOnly: true,\n secure: isHttps,\n sameSite: isHttps ? \"none\" : \"lax\",\n path: callbackPath,\n maxAge: OAUTH_REQUEST_TTL_MS,\n })\n } catch (err) {\n console.warn(\"oauth::failed_to_set_state_cookie\", err)\n return { success: false, error: \"oauth_cookie_set_failed\", statusCode: 500 }\n }\n\n const oidc = await getOidcWellKnown(provider.issuer)\n const redirectUri = `${origin}${callbackPath}`\n\n const url = new URL(oidc.authorization_endpoint)\n url.searchParams.set(\"client_id\", provider.clientId)\n url.searchParams.set(\"redirect_uri\", redirectUri)\n url.searchParams.set(\"response_type\", \"code\")\n url.searchParams.set(\"scope\", provider.scope)\n url.searchParams.set(\"state\", state)\n url.searchParams.set(\"code_challenge\", challenge)\n url.searchParams.set(\"code_challenge_method\", \"S256\")\n const extraAuthorizationParams = normalizeAuthorizationParams(authorizationParams)\n for (const [key, value] of Object.entries(extraAuthorizationParams ?? {})) {\n if (url.searchParams.has(key)) continue\n url.searchParams.set(key, value)\n }\n\n return { success: true, redirectUrl: url.toString() }\n}\n\nexport type OAuthCallbackResult =\n | {\n success: true\n type: \"signed_in\"\n redirectPath: string\n userId: string\n tenantId: string\n signedInTenants: string[]\n }\n | {\n success: false\n type: \"missing_user\"\n providerId: string\n subject: string\n email?: string\n name?: string\n redirectPath?: string\n }\n | {\n success: false\n type: \"error\"\n error: string\n redirectPath: string\n }\n\nconst OAUTH_SUCCESS_REDIRECT_PATH = \"/onboarding\"\nconst AUTH_ERROR_REDIRECT_BASE = \"/auth/sign-in\"\n\nexport const processOAuthCallback = async ({\n ctx,\n providerId: providerIdOverride,\n createUserOnFirstSignIn,\n missingUserRedirectPath,\n successRedirectPath,\n}: {\n ctx: OAuthCtx\n providerId?: string\n createUserOnFirstSignIn?: boolean\n missingUserRedirectPath?: string\n successRedirectPath?: string\n}): Promise<OAuthCallbackResult> => {\n const providerId = resolveProviderId(ctx, providerIdOverride)\n if (!providerId) {\n return { success: false, type: \"error\", error: \"missing_provider\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=missing_provider` }\n }\n\n if (!isSafeOAuthProviderId(providerId)) {\n return { success: false, type: \"error\", error: \"invalid_provider\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=invalid_provider` }\n }\n\n const provider = getOAuthProviderConfig(providerId)\n if (!provider) {\n return { success: false, type: \"error\", error: \"unknown_provider\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=unknown_provider` }\n }\n\n const origin = getRequestOrigin(ctx)\n if (!origin) {\n return { success: false, type: \"error\", error: \"origin_unavailable\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=origin_unavailable` }\n }\n const isHttps = origin.startsWith(\"https://\")\n\n const callbackPath = resolveCallbackPath(provider.callbackPath)\n if (!callbackPath) {\n return { success: false, type: \"error\", error: \"invalid_callback_path\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=invalid_callback_path` }\n }\n\n const bodyParams = await getFormPostParams(ctx)\n\n const code = (getQueryString(bodyParams?.code) ?? getQueryString(ctx.req.query?.code))?.trim() ?? \"\"\n const state = (getQueryString(bodyParams?.state) ?? getQueryString(ctx.req.query?.state))?.trim() ?? \"\"\n const oauthUserRaw = (getQueryString(bodyParams?.user) ?? getQueryString(ctx.req.query?.user))?.trim() ?? \"\"\n\n if (!code || !state) {\n return { success: false, type: \"error\", error: \"missing_code_or_state\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=missing_code_or_state` }\n }\n\n const stateCookieValue = getCookieValue(ctx, OAUTH_STATE_COOKIE_NAME)\n if (stateCookieValue !== `${providerId}:${state}`) {\n return { success: false, type: \"error\", error: \"invalid_state\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=invalid_state` }\n }\n\n let oauthRequest: OAuthRequestRecord | null = null\n let OAuthRequestModel: Awaited<ReturnType<typeof models.getGlobal>> | null = null\n try {\n OAuthRequestModel = await models.getGlobal(\"RBOAuthRequest\", ctx)\n oauthRequest = await OAuthRequestModel.findOne({ _id: state, providerId }).lean() as OAuthRequestRecord | null\n } catch (err) {\n console.warn(\"oauth::failed_to_load_request\", err)\n return { success: false, type: \"error\", error: \"oauth_request_load_failed\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=oauth_request_load_failed` }\n }\n\n if (!oauthRequest) {\n return { success: false, type: \"error\", error: \"invalid_state\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=invalid_state` }\n }\n\n const returnTo = typeof oauthRequest.returnTo === \"string\" ? oauthRequest.returnTo : undefined\n const codeVerifier = typeof oauthRequest.codeVerifier === \"string\" ? oauthRequest.codeVerifier : \"\"\n if (!codeVerifier) {\n return { success: false, type: \"error\", error: \"missing_code_verifier\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=missing_code_verifier` }\n }\n\n const oidc = await getOidcWellKnown(provider.issuer)\n const redirectUri = `${origin}${callbackPath}`\n\n const tokenBody = new URLSearchParams()\n tokenBody.set(\"grant_type\", \"authorization_code\")\n tokenBody.set(\"code\", code)\n tokenBody.set(\"redirect_uri\", redirectUri)\n tokenBody.set(\"client_id\", provider.clientId)\n tokenBody.set(\"code_verifier\", codeVerifier)\n if (provider.clientSecret) {\n tokenBody.set(\"client_secret\", provider.clientSecret)\n }\n\n const tokenResponse = await fetch(oidc.token_endpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body: tokenBody.toString(),\n })\n\n const tokenJson = await tokenResponse.json().catch(() => null) as Record<string, unknown> | null\n\n if (!tokenResponse.ok || !tokenJson || typeof tokenJson !== \"object\") {\n const body = tokenJson ? JSON.stringify(tokenJson) : \"\"\n console.warn(\"oauth::token_exchange failed\", tokenResponse.status, body)\n return { success: false, type: \"error\", error: \"token_exchange_failed\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=token_exchange_failed` }\n }\n\n const accessToken = typeof tokenJson.access_token === \"string\" ? tokenJson.access_token : \"\"\n const refreshToken = typeof tokenJson.refresh_token === \"string\" ? tokenJson.refresh_token : undefined\n const idToken = typeof tokenJson.id_token === \"string\" ? tokenJson.id_token : undefined\n const scope = typeof tokenJson.scope === \"string\" ? tokenJson.scope : undefined\n const tokenType = typeof tokenJson.token_type === \"string\" ? tokenJson.token_type : undefined\n const expiresIn = typeof tokenJson.expires_in === \"number\"\n ? tokenJson.expires_in\n : typeof tokenJson.expires_in === \"string\"\n ? Number(tokenJson.expires_in)\n : undefined\n const expiresInSeconds = typeof expiresIn === \"number\" && Number.isFinite(expiresIn) ? expiresIn : null\n const expiresAt = expiresInSeconds !== null ? new Date(Date.now() + expiresInSeconds * 1000) : undefined\n\n let userInfo: Record<string, unknown> | null = null\n\n if (oidc.userinfo_endpoint && accessToken) {\n const userInfoResponse = await fetch(oidc.userinfo_endpoint, {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n Accept: \"application/json\",\n },\n })\n\n if (userInfoResponse.ok) {\n userInfo = await userInfoResponse.json().catch(() => null) as Record<string, unknown> | null\n }\n }\n\n const idTokenPayload = idToken ? decodeJwtPayload<Record<string, unknown>>(idToken) : null\n const accessTokenPayload = decodeJwtPayload<Record<string, unknown>>(accessToken)\n\n const subject = typeof userInfo?.sub === \"string\"\n ? userInfo.sub\n : typeof idTokenPayload?.sub === \"string\"\n ? idTokenPayload.sub\n : typeof accessTokenPayload?.sub === \"string\"\n ? accessTokenPayload.sub\n : \"\"\n\n if (!subject) {\n return { success: false, type: \"error\", error: \"missing_subject\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=missing_subject` }\n }\n\n const email = typeof userInfo?.email === \"string\"\n ? userInfo.email\n : typeof idTokenPayload?.email === \"string\"\n ? idTokenPayload.email\n : undefined\n\n const name = typeof userInfo?.name === \"string\"\n ? userInfo.name\n : typeof idTokenPayload?.name === \"string\"\n ? idTokenPayload.name\n : undefined\n\n let oauthUser: unknown = null\n if (oauthUserRaw) {\n try {\n oauthUser = JSON.parse(oauthUserRaw) as unknown\n } catch {\n oauthUser = null\n }\n }\n const oauthUserRecord = oauthUser && typeof oauthUser === \"object\"\n ? (oauthUser as Record<string, unknown>)\n : null\n const oauthUserEmail = typeof oauthUserRecord?.email === \"string\" ? oauthUserRecord.email.trim() : \"\"\n const oauthUserNameRecord = oauthUserRecord?.name && typeof oauthUserRecord.name === \"object\"\n ? (oauthUserRecord.name as Record<string, unknown>)\n : null\n const oauthUserNameFirst = typeof oauthUserNameRecord?.firstName === \"string\" ? oauthUserNameRecord.firstName.trim() : \"\"\n const oauthUserNameLast = typeof oauthUserNameRecord?.lastName === \"string\" ? oauthUserNameRecord.lastName.trim() : \"\"\n const oauthUserName = [oauthUserNameFirst, oauthUserNameLast].filter(Boolean).join(\" \").trim()\n\n const resolvedEmail = email ?? (oauthUserEmail || undefined)\n const resolvedName = name ?? (oauthUserName || undefined)\n\n const [User, Tenant] = await Promise.all([\n models.getGlobal(\"RBUser\", ctx),\n models.getGlobal(\"RBTenant\", ctx),\n ])\n\n const subjectQueryKey = `oauthProviders.${providerId}.subject`\n let user = await User.findOne({ [subjectQueryKey]: subject })\n\n if (!user && resolvedEmail) {\n user = await User.findOne({ email: resolvedEmail })\n }\n\n const shouldCreateUser = createUserOnFirstSignIn ?? true\n if (!user && !shouldCreateUser) {\n const redirectPath = missingUserRedirectPath\n\n const result: OAuthCallbackResult = {\n success: false,\n type: \"missing_user\",\n providerId,\n subject,\n email: resolvedEmail,\n name: resolvedName,\n }\n\n if (redirectPath && isSafeRedirectPath(redirectPath)) {\n const url = new URL(redirectPath, origin)\n url.searchParams.set(\"oauth_provider\", providerId)\n if (resolvedEmail) url.searchParams.set(\"email\", resolvedEmail)\n if (resolvedName) url.searchParams.set(\"name\", resolvedName)\n result.redirectPath = `${url.pathname}${url.search}`\n }\n\n return result\n }\n\n if (!ctx.req.session) {\n return { success: false, type: \"error\", error: \"session_unavailable\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=session_unavailable` }\n }\n\n const now = new Date()\n\n let providerCreatedAt: Date | undefined\n const oauthProviders = user?.get(\"oauthProviders\") as Map<string, { createdAt?: unknown }> | undefined\n const existingProvider = oauthProviders?.get(providerId)\n if (existingProvider?.createdAt instanceof Date) {\n providerCreatedAt = existingProvider.createdAt\n }\n\n const oauthProviderPayload = {\n subject,\n email: resolvedEmail,\n name: resolvedName,\n accessToken,\n refreshToken,\n idToken,\n scope,\n tokenType,\n expiresAt,\n rawUserInfo: userInfo ?? undefined,\n createdAt: providerCreatedAt ?? now,\n updatedAt: now,\n }\n\n if (!user) {\n const tenantId = crypto.randomUUID()\n const password = await hashPasswordForStorage(crypto.randomBytes(32).toString(\"hex\"))\n\n user = new User({\n email: resolvedEmail,\n name: resolvedName,\n password,\n tenants: [tenantId],\n tenantRoles: {\n [tenantId]: [\"owner\"],\n },\n oauthProviders: {\n [providerId]: oauthProviderPayload,\n },\n })\n\n await user.save()\n\n try {\n await createProvisionedTenant(Tenant, {\n tenantId,\n name: resolvedEmail || subject,\n })\n } catch (err) {\n console.error(\"oauth::failed_to_initialize_tenant\", err)\n try {\n await User.deleteOne({ _id: user._id })\n } catch (rollbackError) {\n console.error(\"oauth::failed_to_rollback_user\", rollbackError)\n }\n return {\n success: false,\n type: \"error\",\n error: \"tenant_initialization_failed\",\n redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=tenant_initialization_failed`,\n }\n }\n } else {\n const setFields: Record<string, unknown> = {\n [`oauthProviders.${providerId}`]: oauthProviderPayload,\n }\n\n if (!user.email && resolvedEmail) {\n setFields.email = resolvedEmail\n }\n\n if (!user.name && resolvedName) {\n setFields.name = resolvedName\n }\n\n await User.updateOne({ _id: user._id }, { $set: setFields })\n }\n\n const signedInTenants = (user.tenants || []).map(String)\n const tenantId = signedInTenants[0]\n if (!tenantId) {\n return {\n success: false,\n type: \"error\",\n error: \"tenant_unavailable\",\n redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=tenant_unavailable`,\n }\n }\n const tenantRolesMap = user.get(\"tenantRoles\") as Map<string, string[]> | undefined\n const tenantRoles = tenantRolesMap ? Object.fromEntries(tenantRolesMap.entries()) : undefined\n\n if (!completeAuthSignIn(ctx, {\n userId: user._id.toString(),\n currentTenantId: tenantId,\n signedInTenants: signedInTenants.length ? signedInTenants : [tenantId],\n tenantRoles,\n })) {\n return {\n success: false,\n type: \"error\",\n error: \"session_unavailable\",\n redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=session_unavailable`,\n }\n }\n\n try {\n if (OAuthRequestModel) {\n await OAuthRequestModel.deleteOne({ _id: state, providerId })\n }\n } catch (err) {\n console.warn(\"oauth::failed_to_delete_request\", err)\n }\n\n try {\n ctx.res.clearCookie(OAUTH_STATE_COOKIE_NAME, {\n httpOnly: true,\n secure: isHttps,\n sameSite: isHttps ? \"none\" : \"lax\",\n path: callbackPath,\n })\n } catch (err) {\n console.warn(\"oauth::failed_to_clear_state_cookie\", err)\n }\n\n const redirectPath = returnTo && isSafeRedirectPath(returnTo)\n ? returnTo\n : successRedirectPath && isSafeRedirectPath(successRedirectPath)\n ? successRedirectPath\n : OAUTH_SUCCESS_REDIRECT_PATH\n\n return {\n success: true,\n type: \"signed_in\",\n redirectPath,\n userId: user._id.toString(),\n tenantId,\n signedInTenants: signedInTenants.length ? signedInTenants : [tenantId],\n }\n}\n\nexport const createOAuthStartHandler = ({\n providerId,\n getAuthorizationParams,\n}: {\n providerId?: string\n getAuthorizationParams?: (providerId: string) => Record<string, string> | undefined\n} = {}): ApiHandler<unknown, { success: boolean; error?: string }, AuthSessionUser> => async (\n _payload,\n ctx,\n) => {\n const resolvedProviderId = resolveProviderId(ctx, providerId)\n const providerAuthorizationParams = resolvedProviderId && getAuthorizationParams\n ? getAuthorizationParams(resolvedProviderId)\n : undefined\n const returnTo = getQueryString(ctx.req.query?.returnTo)?.trim()\n const result = await getOAuthStartRedirectUrl({\n ctx,\n providerId: resolvedProviderId,\n returnTo,\n authorizationParams: providerAuthorizationParams,\n })\n\n if (!result.success) {\n ctx.res.status(result.statusCode)\n return { success: false, error: result.error }\n }\n\n ctx.res.redirect(result.redirectUrl)\n return { success: true }\n}\n\nexport const createOAuthCallbackHandler = ({\n providerId,\n createUserOnFirstSignIn,\n missingUserRedirectPath,\n successRedirectPath,\n}: {\n providerId?: string\n createUserOnFirstSignIn?: boolean\n missingUserRedirectPath?: string\n successRedirectPath?: string\n} = {}): ApiHandler<unknown, { success: boolean; error?: string }, AuthSessionUser> => async (\n _payload,\n ctx,\n) => {\n const result = await processOAuthCallback({\n ctx,\n providerId,\n createUserOnFirstSignIn,\n missingUserRedirectPath,\n successRedirectPath,\n })\n\n if (result.type === \"error\") {\n ctx.res.redirect(result.redirectPath)\n return { success: false, error: result.error }\n }\n\n if (result.type === \"missing_user\") {\n if (result.redirectPath) {\n ctx.res.redirect(result.redirectPath)\n } else {\n ctx.res.redirect(\"/auth/sign-up\")\n }\n return { success: false, error: \"user_not_found\" }\n }\n\n ctx.res.redirect(result.redirectPath)\n return { success: true }\n}\n\nconst base64UrlEncode = (input: Buffer | string) =>\n Buffer.from(input)\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/g, \"\")\n\nexport const createAppleClientSecret = ({\n teamId,\n clientId,\n keyId,\n privateKeyPem,\n now = new Date(),\n expiresInSeconds = 10 * 60,\n}: {\n teamId: string\n clientId: string\n keyId: string\n privateKeyPem: string\n now?: Date\n expiresInSeconds?: number\n}) => {\n const teamIdValue = teamId.trim()\n const clientIdValue = clientId.trim()\n const keyIdValue = keyId.trim()\n const privateKeyPemValue = privateKeyPem.trim()\n\n if (!teamIdValue) throw new Error(\"teamId is required\")\n if (!clientIdValue) throw new Error(\"clientId is required\")\n if (!keyIdValue) throw new Error(\"keyId is required\")\n if (!privateKeyPemValue) throw new Error(\"privateKeyPem is required\")\n\n const nowSeconds = Math.floor(now.getTime() / 1000)\n const expiresIn = Number.isFinite(expiresInSeconds) ? expiresInSeconds : 10 * 60\n const exp = nowSeconds + Math.max(60, Math.min(expiresIn, 60 * 60 * 24 * 180))\n\n const header = { alg: \"ES256\", kid: keyIdValue, typ: \"JWT\" }\n const payload = {\n iss: teamIdValue,\n iat: nowSeconds,\n exp,\n aud: \"https://appleid.apple.com\",\n sub: clientIdValue,\n }\n\n const signingInput = `${base64UrlEncode(JSON.stringify(header))}.${base64UrlEncode(JSON.stringify(payload))}`\n const signature = crypto.sign(\"sha256\", Buffer.from(signingInput), {\n key: privateKeyPemValue,\n dsaEncoding: \"ieee-p1363\",\n })\n\n return `${signingInput}.${base64UrlEncode(signature)}`\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/oauth/config.ts","../../src/oauth/jwt.ts","../../src/oauth/oidc.ts","../../src/oauth/pkce.ts","../../src/oauth/providerId.ts","../../src/oauth/lib.ts"],"sourcesContent":["export type OAuthProviderConfig = {\n issuer: string\n clientId: string\n clientSecret?: string\n scope: string\n callbackPath: string\n}\n\ntype OAuthProvidersConfig = Record<string, OAuthProviderConfig>\n\ntype OAuthProvidersStore = {\n providers: OAuthProvidersConfig\n}\n\nconst STORE_KEY = Symbol.for(\"@rpcbase/auth/oauthProviders\")\n\nconst getStore = (): OAuthProvidersStore => {\n const anyGlobal = globalThis as unknown as Record<string | symbol, unknown>\n const existing = anyGlobal[STORE_KEY] as OAuthProvidersStore | undefined\n if (existing && typeof existing === \"object\" && existing.providers && typeof existing.providers === \"object\") {\n return existing\n }\n\n const created: OAuthProvidersStore = { providers: {} }\n anyGlobal[STORE_KEY] = created\n return created\n}\n\nconst normalizeProviders = (providers: Record<string, OAuthProviderConfig>): OAuthProvidersConfig => {\n const result: OAuthProvidersConfig = {}\n\n const isSafeRedirectPath = (candidate: string) => {\n if (!candidate.startsWith(\"/\")) return false\n if (candidate.startsWith(\"//\")) return false\n return true\n }\n\n for (const [providerIdRaw, value] of Object.entries(providers)) {\n const providerId = providerIdRaw.trim()\n if (!providerId) continue\n\n const issuer = typeof value?.issuer === \"string\" ? value.issuer.trim() : \"\"\n const clientId = typeof value?.clientId === \"string\" ? value.clientId.trim() : \"\"\n if (!issuer) throw new Error(`oauth provider \"${providerId}\" missing issuer`)\n if (!clientId) throw new Error(`oauth provider \"${providerId}\" missing clientId`)\n\n const clientSecret = typeof value?.clientSecret === \"string\" && value.clientSecret.trim()\n ? value.clientSecret\n : undefined\n\n const scope = typeof value?.scope === \"string\" ? value.scope.trim() : \"\"\n if (!scope) throw new Error(`oauth provider \"${providerId}\" missing scope`)\n\n const callbackPath = typeof value?.callbackPath === \"string\"\n ? value.callbackPath.trim()\n : \"\"\n if (!callbackPath) throw new Error(`oauth provider \"${providerId}\" missing callbackPath`)\n if (!isSafeRedirectPath(callbackPath)) throw new Error(`oauth provider \"${providerId}\" has invalid callbackPath`)\n\n result[providerId] = {\n issuer,\n clientId,\n clientSecret,\n scope,\n callbackPath,\n }\n }\n\n return result\n}\n\nexport const configureOAuthProviders = (providers: Record<string, OAuthProviderConfig>) => {\n const store = getStore()\n const normalized = normalizeProviders(providers)\n store.providers = { ...store.providers, ...normalized }\n}\n\nexport const setOAuthProviders = (providers: Record<string, OAuthProviderConfig>) => {\n const store = getStore()\n store.providers = normalizeProviders(providers)\n}\n\nexport const getOAuthProviderConfig = (providerId: string): OAuthProviderConfig | null => {\n const store = getStore()\n return store.providers[providerId] ?? null\n}\n","const decodeBase64Url = (value: string) => {\n const padded = value.replace(/-/g, \"+\").replace(/_/g, \"/\") + \"===\".slice((value.length + 3) % 4)\n return Buffer.from(padded, \"base64\").toString(\"utf8\")\n}\n\nexport const decodeJwtPayload = <T = Record<string, unknown>>(token: string): T | null => {\n const parts = token.split(\".\")\n if (parts.length < 2) return null\n\n try {\n const json = decodeBase64Url(parts[1])\n const parsed = JSON.parse(json) as T\n if (!parsed || typeof parsed !== \"object\") return null\n return parsed\n } catch {\n return null\n }\n}\n\n","export type OidcWellKnown = {\n issuer: string\n authorization_endpoint: string\n token_endpoint: string\n userinfo_endpoint?: string\n jwks_uri?: string\n}\n\nconst cache = new Map<string, Promise<OidcWellKnown>>()\n\nconst normalizeIssuer = (raw: string) => raw.trim().replace(/\\/+$/, \"\")\n\nexport const getOidcWellKnown = async (issuerRaw: string): Promise<OidcWellKnown> => {\n const issuer = normalizeIssuer(issuerRaw)\n if (!issuer) {\n throw new Error(\"OIDC issuer is required\")\n }\n\n const existing = cache.get(issuer)\n if (existing) {\n return existing\n }\n\n const loader = (async () => {\n const url = new URL(\"/.well-known/openid-configuration\", issuer)\n const response = await fetch(url, { headers: { Accept: \"application/json\" } })\n if (!response.ok) {\n const body = await response.text().catch(() => \"\")\n throw new Error(`Failed to fetch OIDC discovery document: ${response.status} ${body}`)\n }\n\n const json = await response.json().catch(() => null) as Partial<OidcWellKnown> | null\n if (!json || typeof json !== \"object\") {\n throw new Error(\"Invalid OIDC discovery document\")\n }\n\n const authorizationEndpoint = typeof json.authorization_endpoint === \"string\"\n ? json.authorization_endpoint\n : \"\"\n const tokenEndpoint = typeof json.token_endpoint === \"string\"\n ? json.token_endpoint\n : \"\"\n const issuerValue = typeof json.issuer === \"string\" ? json.issuer : issuer\n const userinfoEndpoint = typeof json.userinfo_endpoint === \"string\" ? json.userinfo_endpoint : undefined\n const jwksUri = typeof json.jwks_uri === \"string\" ? json.jwks_uri : undefined\n\n if (!authorizationEndpoint || !tokenEndpoint) {\n throw new Error(\"OIDC discovery document missing required endpoints\")\n }\n\n return {\n issuer: issuerValue,\n authorization_endpoint: authorizationEndpoint,\n token_endpoint: tokenEndpoint,\n userinfo_endpoint: userinfoEndpoint,\n jwks_uri: jwksUri,\n } satisfies OidcWellKnown\n })()\n\n cache.set(issuer, loader)\n\n try {\n return await loader\n } catch (err) {\n cache.delete(issuer)\n throw err\n }\n}\n\n","import crypto from \"crypto\"\n\n\nexport const base64UrlEncode = (input: Buffer) => input\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/g, \"\")\n\nexport const generatePkcePair = () => {\n const verifier = base64UrlEncode(crypto.randomBytes(32))\n const challenge = base64UrlEncode(crypto.createHash(\"sha256\").update(verifier).digest())\n\n return { verifier, challenge }\n}\n\n","const RESERVED_KEYS = new Set([\"__proto__\", \"prototype\", \"constructor\"])\n\nexport const isSafeOAuthProviderId = (value: string) => {\n const providerId = value.trim()\n if (!providerId) return false\n if (providerId.length > 128) return false\n if (RESERVED_KEYS.has(providerId)) return false\n return /^[a-zA-Z0-9_-]+$/.test(providerId)\n}\n\n","import crypto from \"crypto\"\n\nimport { ApiHandler, Ctx } from \"@rpcbase/api\"\nimport { createProvisionedTenant, models } from \"@rpcbase/db\"\nimport { hashPasswordForStorage } from \"@rpcbase/server\"\n\nimport { isPendingRegistration } from \"../registrationStatus\"\nimport { completeAuthSignIn } from \"../session\"\nimport type { AuthSessionUser } from \"../types\"\nimport { getOAuthProviderConfig } from \"./config\"\nimport { decodeJwtPayload } from \"./jwt\"\nimport { getOidcWellKnown } from \"./oidc\"\nimport { generatePkcePair } from \"./pkce\"\nimport { isSafeOAuthProviderId } from \"./providerId\"\n\n\nconst OAUTH_REQUEST_TTL_MS = 10 * 60 * 1000\nconst OAUTH_STATE_COOKIE_NAME = \"rb_oauth_state\"\ntype OAuthCtx = Ctx<AuthSessionUser>\ntype OAuthRequestRecord = {\n returnTo?: unknown\n codeVerifier?: unknown\n}\n\nconst getQueryString = (value: unknown) => {\n if (typeof value === \"string\") return value\n if (Array.isArray(value) && typeof value[0] === \"string\") return value[0]\n return null\n}\n\nconst getCookieValue = (ctx: OAuthCtx, name: string): string | null => {\n const header = ctx.req.headers?.cookie\n if (typeof header !== \"string\" || !header) return null\n\n for (const part of header.split(\";\")) {\n const [rawKey, ...rest] = part.split(\"=\")\n const key = rawKey?.trim()\n if (!key || key !== name) continue\n const rawValue = rest.join(\"=\").trim()\n if (!rawValue) return \"\"\n try {\n return decodeURIComponent(rawValue)\n } catch {\n return rawValue\n }\n }\n\n return null\n}\n\nconst isSafeRedirectPath = (candidate: string) => {\n if (!candidate.startsWith(\"/\")) return false\n if (candidate.startsWith(\"//\")) return false\n return true\n}\n\nconst getRequestOrigin = (ctx: OAuthCtx) => {\n const protoHeader = ctx.req.headers[\"x-forwarded-proto\"]\n const hostHeader = ctx.req.headers[\"x-forwarded-host\"]\n\n const protocol = typeof protoHeader === \"string\"\n ? protoHeader.split(\",\")[0].trim()\n : ctx.req.protocol\n\n const host = typeof hostHeader === \"string\"\n ? hostHeader.split(\",\")[0].trim()\n : ctx.req.get(\"host\")\n\n return protocol && host ? `${protocol}://${host}` : \"\"\n}\n\nconst resolveCallbackPath = (callbackPath: string) => {\n const trimmed = callbackPath.trim()\n return trimmed && isSafeRedirectPath(trimmed) ? trimmed : null\n}\n\nconst readTextBody = async (req: Pick<OAuthCtx[\"req\"], \"on\" | \"setEncoding\">) =>\n await new Promise<string>((resolve, reject) => {\n let body = \"\"\n if (typeof req.setEncoding === \"function\") {\n req.setEncoding(\"utf8\")\n }\n\n req.on(\"data\", (chunk) => {\n body += String(chunk)\n if (body.length > 32_768) {\n reject(new Error(\"request_body_too_large\"))\n }\n })\n req.on(\"end\", () => resolve(body))\n req.on(\"error\", reject)\n })\n\nconst getFormPostParams = async (ctx: OAuthCtx): Promise<Record<string, string> | null> => {\n if (ctx.req.method !== \"POST\") return null\n\n const contentType = typeof ctx.req.headers[\"content-type\"] === \"string\" ? ctx.req.headers[\"content-type\"] : \"\"\n if (!contentType.includes(\"application/x-www-form-urlencoded\")) return null\n\n const body = await readTextBody(ctx.req)\n const params = new URLSearchParams(body)\n\n const result: Record<string, string> = {}\n for (const [key, value] of params.entries()) {\n result[key] = value\n }\n\n return result\n}\n\nconst resolveProviderId = (ctx: OAuthCtx, providerIdOverride?: string) =>\n (providerIdOverride ?? String(ctx.req.params?.provider ?? \"\")).trim()\n\nconst RESERVED_AUTH_PARAM_KEYS = new Set([\"__proto__\", \"prototype\", \"constructor\"])\n\nconst normalizeAuthorizationParams = (value: unknown): Record<string, string> | undefined => {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return undefined\n\n const result: Record<string, string> = {}\n for (const [keyRaw, valueRaw] of Object.entries(value)) {\n const key = keyRaw.trim()\n if (!key) continue\n if (RESERVED_AUTH_PARAM_KEYS.has(key)) continue\n const val = typeof valueRaw === \"string\" ? valueRaw.trim() : \"\"\n if (!val) continue\n result[key] = val\n }\n\n return Object.keys(result).length ? result : undefined\n}\n\nexport type OAuthStartResult =\n | { success: true; redirectUrl: string }\n | { success: false; error: string; statusCode: number }\n\nexport const getOAuthStartRedirectUrl = async ({\n ctx,\n providerId: providerIdOverride,\n returnTo,\n authorizationParams,\n}: {\n ctx: OAuthCtx\n providerId?: string\n returnTo?: string | null\n authorizationParams?: Record<string, string>\n}): Promise<OAuthStartResult> => {\n const providerId = resolveProviderId(ctx, providerIdOverride)\n if (!providerId) {\n return { success: false, error: \"missing_provider\", statusCode: 400 }\n }\n\n if (!isSafeOAuthProviderId(providerId)) {\n return { success: false, error: \"invalid_provider\", statusCode: 400 }\n }\n\n const provider = getOAuthProviderConfig(providerId)\n if (!provider) {\n return { success: false, error: \"unknown_provider\", statusCode: 404 }\n }\n\n const origin = getRequestOrigin(ctx)\n if (!origin) {\n return { success: false, error: \"origin_unavailable\", statusCode: 500 }\n }\n const isHttps = origin.startsWith(\"https://\")\n\n const callbackPath = resolveCallbackPath(provider.callbackPath)\n if (!callbackPath) {\n return { success: false, error: \"invalid_callback_path\", statusCode: 500 }\n }\n\n const state = crypto.randomBytes(16).toString(\"hex\")\n const { verifier, challenge } = generatePkcePair()\n\n const safeReturnTo = typeof returnTo === \"string\" && isSafeRedirectPath(returnTo) ? returnTo : undefined\n\n try {\n const OAuthRequest = await models.getGlobal(\"RBOAuthRequest\", ctx)\n const now = new Date()\n await OAuthRequest.create({\n _id: state,\n providerId,\n codeVerifier: verifier,\n returnTo: safeReturnTo,\n createdAt: now,\n expiresAt: new Date(now.getTime() + OAUTH_REQUEST_TTL_MS),\n })\n } catch (err) {\n console.warn(\"oauth::failed_to_store_request\", err)\n return { success: false, error: \"oauth_request_store_failed\", statusCode: 500 }\n }\n\n try {\n ctx.res.cookie(OAUTH_STATE_COOKIE_NAME, `${providerId}:${state}`, {\n httpOnly: true,\n secure: isHttps,\n sameSite: isHttps ? \"none\" : \"lax\",\n path: callbackPath,\n maxAge: OAUTH_REQUEST_TTL_MS,\n })\n } catch (err) {\n console.warn(\"oauth::failed_to_set_state_cookie\", err)\n return { success: false, error: \"oauth_cookie_set_failed\", statusCode: 500 }\n }\n\n const oidc = await getOidcWellKnown(provider.issuer)\n const redirectUri = `${origin}${callbackPath}`\n\n const url = new URL(oidc.authorization_endpoint)\n url.searchParams.set(\"client_id\", provider.clientId)\n url.searchParams.set(\"redirect_uri\", redirectUri)\n url.searchParams.set(\"response_type\", \"code\")\n url.searchParams.set(\"scope\", provider.scope)\n url.searchParams.set(\"state\", state)\n url.searchParams.set(\"code_challenge\", challenge)\n url.searchParams.set(\"code_challenge_method\", \"S256\")\n const extraAuthorizationParams = normalizeAuthorizationParams(authorizationParams)\n for (const [key, value] of Object.entries(extraAuthorizationParams ?? {})) {\n if (url.searchParams.has(key)) continue\n url.searchParams.set(key, value)\n }\n\n return { success: true, redirectUrl: url.toString() }\n}\n\nexport type OAuthCallbackResult =\n | {\n success: true\n type: \"signed_in\"\n redirectPath: string\n userId: string\n tenantId: string\n signedInTenants: string[]\n }\n | {\n success: false\n type: \"missing_user\"\n providerId: string\n subject: string\n email?: string\n name?: string\n redirectPath?: string\n }\n | {\n success: false\n type: \"error\"\n error: string\n redirectPath: string\n }\n\nconst OAUTH_SUCCESS_REDIRECT_PATH = \"/onboarding\"\nconst AUTH_ERROR_REDIRECT_BASE = \"/auth/sign-in\"\n\nexport const processOAuthCallback = async ({\n ctx,\n providerId: providerIdOverride,\n createUserOnFirstSignIn,\n missingUserRedirectPath,\n successRedirectPath,\n}: {\n ctx: OAuthCtx\n providerId?: string\n createUserOnFirstSignIn?: boolean\n missingUserRedirectPath?: string\n successRedirectPath?: string\n}): Promise<OAuthCallbackResult> => {\n const providerId = resolveProviderId(ctx, providerIdOverride)\n if (!providerId) {\n return { success: false, type: \"error\", error: \"missing_provider\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=missing_provider` }\n }\n\n if (!isSafeOAuthProviderId(providerId)) {\n return { success: false, type: \"error\", error: \"invalid_provider\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=invalid_provider` }\n }\n\n const provider = getOAuthProviderConfig(providerId)\n if (!provider) {\n return { success: false, type: \"error\", error: \"unknown_provider\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=unknown_provider` }\n }\n\n const origin = getRequestOrigin(ctx)\n if (!origin) {\n return { success: false, type: \"error\", error: \"origin_unavailable\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=origin_unavailable` }\n }\n const isHttps = origin.startsWith(\"https://\")\n\n const callbackPath = resolveCallbackPath(provider.callbackPath)\n if (!callbackPath) {\n return { success: false, type: \"error\", error: \"invalid_callback_path\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=invalid_callback_path` }\n }\n\n const bodyParams = await getFormPostParams(ctx)\n\n const code = (getQueryString(bodyParams?.code) ?? getQueryString(ctx.req.query?.code))?.trim() ?? \"\"\n const state = (getQueryString(bodyParams?.state) ?? getQueryString(ctx.req.query?.state))?.trim() ?? \"\"\n const oauthUserRaw = (getQueryString(bodyParams?.user) ?? getQueryString(ctx.req.query?.user))?.trim() ?? \"\"\n\n if (!code || !state) {\n return { success: false, type: \"error\", error: \"missing_code_or_state\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=missing_code_or_state` }\n }\n\n const stateCookieValue = getCookieValue(ctx, OAUTH_STATE_COOKIE_NAME)\n if (stateCookieValue !== `${providerId}:${state}`) {\n return { success: false, type: \"error\", error: \"invalid_state\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=invalid_state` }\n }\n\n let oauthRequest: OAuthRequestRecord | null = null\n let OAuthRequestModel: Awaited<ReturnType<typeof models.getGlobal>> | null = null\n try {\n OAuthRequestModel = await models.getGlobal(\"RBOAuthRequest\", ctx)\n oauthRequest = await OAuthRequestModel.findOne({ _id: state, providerId }).lean() as OAuthRequestRecord | null\n } catch (err) {\n console.warn(\"oauth::failed_to_load_request\", err)\n return { success: false, type: \"error\", error: \"oauth_request_load_failed\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=oauth_request_load_failed` }\n }\n\n if (!oauthRequest) {\n return { success: false, type: \"error\", error: \"invalid_state\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=invalid_state` }\n }\n\n const returnTo = typeof oauthRequest.returnTo === \"string\" ? oauthRequest.returnTo : undefined\n const codeVerifier = typeof oauthRequest.codeVerifier === \"string\" ? oauthRequest.codeVerifier : \"\"\n if (!codeVerifier) {\n return { success: false, type: \"error\", error: \"missing_code_verifier\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=missing_code_verifier` }\n }\n\n const oidc = await getOidcWellKnown(provider.issuer)\n const redirectUri = `${origin}${callbackPath}`\n\n const tokenBody = new URLSearchParams()\n tokenBody.set(\"grant_type\", \"authorization_code\")\n tokenBody.set(\"code\", code)\n tokenBody.set(\"redirect_uri\", redirectUri)\n tokenBody.set(\"client_id\", provider.clientId)\n tokenBody.set(\"code_verifier\", codeVerifier)\n if (provider.clientSecret) {\n tokenBody.set(\"client_secret\", provider.clientSecret)\n }\n\n const tokenResponse = await fetch(oidc.token_endpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body: tokenBody.toString(),\n })\n\n const tokenJson = await tokenResponse.json().catch(() => null) as Record<string, unknown> | null\n\n if (!tokenResponse.ok || !tokenJson || typeof tokenJson !== \"object\") {\n const body = tokenJson ? JSON.stringify(tokenJson) : \"\"\n console.warn(\"oauth::token_exchange failed\", tokenResponse.status, body)\n return { success: false, type: \"error\", error: \"token_exchange_failed\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=token_exchange_failed` }\n }\n\n const accessToken = typeof tokenJson.access_token === \"string\" ? tokenJson.access_token : \"\"\n const refreshToken = typeof tokenJson.refresh_token === \"string\" ? tokenJson.refresh_token : undefined\n const idToken = typeof tokenJson.id_token === \"string\" ? tokenJson.id_token : undefined\n const scope = typeof tokenJson.scope === \"string\" ? tokenJson.scope : undefined\n const tokenType = typeof tokenJson.token_type === \"string\" ? tokenJson.token_type : undefined\n const expiresIn = typeof tokenJson.expires_in === \"number\"\n ? tokenJson.expires_in\n : typeof tokenJson.expires_in === \"string\"\n ? Number(tokenJson.expires_in)\n : undefined\n const expiresInSeconds = typeof expiresIn === \"number\" && Number.isFinite(expiresIn) ? expiresIn : null\n const expiresAt = expiresInSeconds !== null ? new Date(Date.now() + expiresInSeconds * 1000) : undefined\n\n let userInfo: Record<string, unknown> | null = null\n\n if (oidc.userinfo_endpoint && accessToken) {\n const userInfoResponse = await fetch(oidc.userinfo_endpoint, {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n Accept: \"application/json\",\n },\n })\n\n if (userInfoResponse.ok) {\n userInfo = await userInfoResponse.json().catch(() => null) as Record<string, unknown> | null\n }\n }\n\n const idTokenPayload = idToken ? decodeJwtPayload<Record<string, unknown>>(idToken) : null\n const accessTokenPayload = decodeJwtPayload<Record<string, unknown>>(accessToken)\n\n const subject = typeof userInfo?.sub === \"string\"\n ? userInfo.sub\n : typeof idTokenPayload?.sub === \"string\"\n ? idTokenPayload.sub\n : typeof accessTokenPayload?.sub === \"string\"\n ? accessTokenPayload.sub\n : \"\"\n\n if (!subject) {\n return { success: false, type: \"error\", error: \"missing_subject\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=missing_subject` }\n }\n\n const email = typeof userInfo?.email === \"string\"\n ? userInfo.email\n : typeof idTokenPayload?.email === \"string\"\n ? idTokenPayload.email\n : undefined\n\n const name = typeof userInfo?.name === \"string\"\n ? userInfo.name\n : typeof idTokenPayload?.name === \"string\"\n ? idTokenPayload.name\n : undefined\n\n let oauthUser: unknown = null\n if (oauthUserRaw) {\n try {\n oauthUser = JSON.parse(oauthUserRaw) as unknown\n } catch {\n oauthUser = null\n }\n }\n const oauthUserRecord = oauthUser && typeof oauthUser === \"object\"\n ? (oauthUser as Record<string, unknown>)\n : null\n const oauthUserEmail = typeof oauthUserRecord?.email === \"string\" ? oauthUserRecord.email.trim() : \"\"\n const oauthUserNameRecord = oauthUserRecord?.name && typeof oauthUserRecord.name === \"object\"\n ? (oauthUserRecord.name as Record<string, unknown>)\n : null\n const oauthUserNameFirst = typeof oauthUserNameRecord?.firstName === \"string\" ? oauthUserNameRecord.firstName.trim() : \"\"\n const oauthUserNameLast = typeof oauthUserNameRecord?.lastName === \"string\" ? oauthUserNameRecord.lastName.trim() : \"\"\n const oauthUserName = [oauthUserNameFirst, oauthUserNameLast].filter(Boolean).join(\" \").trim()\n\n const resolvedEmail = (email?.trim() || oauthUserEmail || undefined)?.toLowerCase()\n const resolvedName = name ?? (oauthUserName || undefined)\n\n const [User, Tenant] = await Promise.all([\n models.getGlobal(\"RBUser\", ctx),\n models.getGlobal(\"RBTenant\", ctx),\n ])\n\n const subjectQueryKey = `oauthProviders.${providerId}.subject`\n let user = await User.findOne({ [subjectQueryKey]: subject })\n\n if (!user && resolvedEmail) {\n user = await User.findOne({ email: resolvedEmail })\n }\n\n const shouldCreateUser = createUserOnFirstSignIn ?? true\n if (!user && !shouldCreateUser) {\n const redirectPath = missingUserRedirectPath\n\n const result: OAuthCallbackResult = {\n success: false,\n type: \"missing_user\",\n providerId,\n subject,\n email: resolvedEmail,\n name: resolvedName,\n }\n\n if (redirectPath && isSafeRedirectPath(redirectPath)) {\n const url = new URL(redirectPath, origin)\n url.searchParams.set(\"oauth_provider\", providerId)\n if (resolvedEmail) url.searchParams.set(\"email\", resolvedEmail)\n if (resolvedName) url.searchParams.set(\"name\", resolvedName)\n result.redirectPath = `${url.pathname}${url.search}`\n }\n\n return result\n }\n\n if (!ctx.req.session) {\n return { success: false, type: \"error\", error: \"session_unavailable\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=session_unavailable` }\n }\n\n const now = new Date()\n\n let providerCreatedAt: Date | undefined\n const oauthProviders = user?.get(\"oauthProviders\") as Map<string, { createdAt?: unknown }> | undefined\n const existingProvider = oauthProviders?.get(providerId)\n if (existingProvider?.createdAt instanceof Date) {\n providerCreatedAt = existingProvider.createdAt\n }\n\n const oauthProviderPayload = {\n subject,\n email: resolvedEmail,\n name: resolvedName,\n accessToken,\n refreshToken,\n idToken,\n scope,\n tokenType,\n expiresAt,\n rawUserInfo: userInfo ?? undefined,\n createdAt: providerCreatedAt ?? now,\n updatedAt: now,\n }\n\n let shouldActivatePendingUser = false\n let pendingOAuthPasswordHash: string | undefined\n\n if (!user) {\n const tenantId = crypto.randomUUID()\n const password = await hashPasswordForStorage(crypto.randomBytes(32).toString(\"hex\"))\n\n user = new User({\n email: resolvedEmail,\n name: resolvedName,\n password,\n tenants: [tenantId],\n tenantRoles: {\n [tenantId]: [\"owner\"],\n },\n oauthProviders: {\n [providerId]: oauthProviderPayload,\n },\n })\n\n await user.save()\n\n try {\n await createProvisionedTenant(Tenant, {\n tenantId,\n name: resolvedEmail || subject,\n })\n } catch (err) {\n console.error(\"oauth::failed_to_initialize_tenant\", err)\n try {\n await User.deleteOne({ _id: user._id })\n } catch (rollbackError) {\n console.error(\"oauth::failed_to_rollback_user\", rollbackError)\n }\n return {\n success: false,\n type: \"error\",\n error: \"tenant_initialization_failed\",\n redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=tenant_initialization_failed`,\n }\n }\n } else {\n const setFields: Record<string, unknown> = {\n [`oauthProviders.${providerId}`]: oauthProviderPayload,\n }\n shouldActivatePendingUser = isPendingRegistration({\n registrationStatus: user.get(\"registrationStatus\"),\n emailVerificationCode: user.get(\"emailVerificationCode\"),\n })\n\n if (shouldActivatePendingUser) {\n pendingOAuthPasswordHash = await hashPasswordForStorage(crypto.randomBytes(32).toString(\"hex\"))\n setFields.password = pendingOAuthPasswordHash\n }\n\n if (!user.email && resolvedEmail) {\n setFields.email = resolvedEmail\n }\n\n if (!user.name && resolvedName) {\n setFields.name = resolvedName\n }\n\n await User.updateOne(\n { _id: user._id },\n {\n $set: setFields,\n },\n )\n }\n\n const signedInTenants = (user.tenants || []).map(String)\n const tenantId = signedInTenants[0]\n if (!tenantId) {\n return {\n success: false,\n type: \"error\",\n error: \"tenant_unavailable\",\n redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=tenant_unavailable`,\n }\n }\n\n const tenant = await Tenant.findOne({ tenantId }, { provisioningStatus: 1 }).lean() as {\n provisioningStatus?: unknown\n } | null\n if (!tenant || (tenant.provisioningStatus && tenant.provisioningStatus !== \"active\")) {\n return {\n success: false,\n type: \"error\",\n error: \"tenant_unavailable\",\n redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=tenant_unavailable`,\n }\n }\n\n if (shouldActivatePendingUser && pendingOAuthPasswordHash) {\n await User.updateOne(\n { _id: user._id },\n {\n $set: {\n registrationStatus: \"active\",\n password: pendingOAuthPasswordHash,\n },\n $unset: {\n emailVerificationCode: \"\",\n emailVerificationExpiresAt: \"\",\n emailVerificationSentAt: \"\",\n },\n },\n )\n }\n\n const tenantRolesMap = user.get(\"tenantRoles\") as Map<string, string[]> | undefined\n const tenantRoles = tenantRolesMap ? Object.fromEntries(tenantRolesMap.entries()) : undefined\n\n if (!completeAuthSignIn(ctx, {\n userId: user._id.toString(),\n currentTenantId: tenantId,\n signedInTenants: signedInTenants.length ? signedInTenants : [tenantId],\n tenantRoles,\n })) {\n return {\n success: false,\n type: \"error\",\n error: \"session_unavailable\",\n redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=session_unavailable`,\n }\n }\n\n try {\n if (OAuthRequestModel) {\n await OAuthRequestModel.deleteOne({ _id: state, providerId })\n }\n } catch (err) {\n console.warn(\"oauth::failed_to_delete_request\", err)\n }\n\n try {\n ctx.res.clearCookie(OAUTH_STATE_COOKIE_NAME, {\n httpOnly: true,\n secure: isHttps,\n sameSite: isHttps ? \"none\" : \"lax\",\n path: callbackPath,\n })\n } catch (err) {\n console.warn(\"oauth::failed_to_clear_state_cookie\", err)\n }\n\n const redirectPath = returnTo && isSafeRedirectPath(returnTo)\n ? returnTo\n : successRedirectPath && isSafeRedirectPath(successRedirectPath)\n ? successRedirectPath\n : OAUTH_SUCCESS_REDIRECT_PATH\n\n return {\n success: true,\n type: \"signed_in\",\n redirectPath,\n userId: user._id.toString(),\n tenantId,\n signedInTenants: signedInTenants.length ? signedInTenants : [tenantId],\n }\n}\n\nexport const createOAuthStartHandler = ({\n providerId,\n getAuthorizationParams,\n}: {\n providerId?: string\n getAuthorizationParams?: (providerId: string) => Record<string, string> | undefined\n} = {}): ApiHandler<unknown, { success: boolean; error?: string }, AuthSessionUser> => async (\n _payload,\n ctx,\n) => {\n const resolvedProviderId = resolveProviderId(ctx, providerId)\n const providerAuthorizationParams = resolvedProviderId && getAuthorizationParams\n ? getAuthorizationParams(resolvedProviderId)\n : undefined\n const returnTo = getQueryString(ctx.req.query?.returnTo)?.trim()\n const result = await getOAuthStartRedirectUrl({\n ctx,\n providerId: resolvedProviderId,\n returnTo,\n authorizationParams: providerAuthorizationParams,\n })\n\n if (!result.success) {\n ctx.res.status(result.statusCode)\n return { success: false, error: result.error }\n }\n\n ctx.res.redirect(result.redirectUrl)\n return { success: true }\n}\n\nexport const createOAuthCallbackHandler = ({\n providerId,\n createUserOnFirstSignIn,\n missingUserRedirectPath,\n successRedirectPath,\n}: {\n providerId?: string\n createUserOnFirstSignIn?: boolean\n missingUserRedirectPath?: string\n successRedirectPath?: string\n} = {}): ApiHandler<unknown, { success: boolean; error?: string }, AuthSessionUser> => async (\n _payload,\n ctx,\n) => {\n const result = await processOAuthCallback({\n ctx,\n providerId,\n createUserOnFirstSignIn,\n missingUserRedirectPath,\n successRedirectPath,\n })\n\n if (result.type === \"error\") {\n ctx.res.redirect(result.redirectPath)\n return { success: false, error: result.error }\n }\n\n if (result.type === \"missing_user\") {\n if (result.redirectPath) {\n ctx.res.redirect(result.redirectPath)\n } else {\n ctx.res.redirect(\"/auth/sign-up\")\n }\n return { success: false, error: \"user_not_found\" }\n }\n\n ctx.res.redirect(result.redirectPath)\n return { success: true }\n}\n\nconst base64UrlEncode = (input: Buffer | string) =>\n Buffer.from(input)\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/g, \"\")\n\nexport const createAppleClientSecret = ({\n teamId,\n clientId,\n keyId,\n privateKeyPem,\n now = new Date(),\n expiresInSeconds = 10 * 60,\n}: {\n teamId: string\n clientId: string\n keyId: string\n privateKeyPem: string\n now?: Date\n expiresInSeconds?: number\n}) => {\n const teamIdValue = teamId.trim()\n const clientIdValue = clientId.trim()\n const keyIdValue = keyId.trim()\n const privateKeyPemValue = privateKeyPem.trim()\n\n if (!teamIdValue) throw new Error(\"teamId is required\")\n if (!clientIdValue) throw new Error(\"clientId is required\")\n if (!keyIdValue) throw new Error(\"keyId is required\")\n if (!privateKeyPemValue) throw new Error(\"privateKeyPem is required\")\n\n const nowSeconds = Math.floor(now.getTime() / 1000)\n const expiresIn = Number.isFinite(expiresInSeconds) ? expiresInSeconds : 10 * 60\n const exp = nowSeconds + Math.max(60, Math.min(expiresIn, 60 * 60 * 24 * 180))\n\n const header = { alg: \"ES256\", kid: keyIdValue, typ: \"JWT\" }\n const payload = {\n iss: teamIdValue,\n iat: nowSeconds,\n exp,\n aud: \"https://appleid.apple.com\",\n sub: clientIdValue,\n }\n\n const signingInput = `${base64UrlEncode(JSON.stringify(header))}.${base64UrlEncode(JSON.stringify(payload))}`\n const signature = crypto.sign(\"sha256\", Buffer.from(signingInput), {\n key: privateKeyPemValue,\n dsaEncoding: \"ieee-p1363\",\n })\n\n return `${signingInput}.${base64UrlEncode(signature)}`\n}\n"],"mappings":";;;;;;AAcA,IAAM,YAAY,OAAO,IAAI,8BAA8B;AAE3D,IAAM,iBAAsC;CAC1C,MAAM,YAAY;CAClB,MAAM,WAAW,UAAU;CAC3B,IAAI,YAAY,OAAO,aAAa,YAAY,SAAS,aAAa,OAAO,SAAS,cAAc,UAClG,OAAO;CAGT,MAAM,UAA+B,EAAE,WAAW,CAAC,EAAE;CACrD,UAAU,aAAa;CACvB,OAAO;AACT;AAEA,IAAM,sBAAsB,cAAyE;CACnG,MAAM,SAA+B,CAAC;CAEtC,MAAM,sBAAsB,cAAsB;EAChD,IAAI,CAAC,UAAU,WAAW,GAAG,GAAG,OAAO;EACvC,IAAI,UAAU,WAAW,IAAI,GAAG,OAAO;EACvC,OAAO;CACT;CAEA,KAAK,MAAM,CAAC,eAAe,UAAU,OAAO,QAAQ,SAAS,GAAG;EAC9D,MAAM,aAAa,cAAc,KAAK;EACtC,IAAI,CAAC,YAAY;EAEjB,MAAM,SAAS,OAAO,OAAO,WAAW,WAAW,MAAM,OAAO,KAAK,IAAI;EACzE,MAAM,WAAW,OAAO,OAAO,aAAa,WAAW,MAAM,SAAS,KAAK,IAAI;EAC/E,IAAI,CAAC,QAAQ,MAAM,IAAI,MAAM,mBAAmB,WAAU,iBAAkB;EAC5E,IAAI,CAAC,UAAU,MAAM,IAAI,MAAM,mBAAmB,WAAU,mBAAoB;EAEhF,MAAM,eAAe,OAAO,OAAO,iBAAiB,YAAY,MAAM,aAAa,KAAK,IACpF,MAAM,eACN,KAAA;EAEJ,MAAM,QAAQ,OAAO,OAAO,UAAU,WAAW,MAAM,MAAM,KAAK,IAAI;EACtE,IAAI,CAAC,OAAO,MAAM,IAAI,MAAM,mBAAmB,WAAU,gBAAiB;EAE1E,MAAM,eAAe,OAAO,OAAO,iBAAiB,WAChD,MAAM,aAAa,KAAK,IACxB;EACJ,IAAI,CAAC,cAAc,MAAM,IAAI,MAAM,mBAAmB,WAAU,uBAAwB;EACxF,IAAI,CAAC,mBAAmB,YAAY,GAAG,MAAM,IAAI,MAAM,mBAAmB,WAAU,2BAA4B;EAEhH,OAAO,cAAc;GACnB;GACA;GACA;GACA;GACA;EACF;CACF;CAEA,OAAO;AACT;AAEA,IAAa,2BAA2B,cAAmD;CACzF,MAAM,QAAQ,SAAS;CACvB,MAAM,aAAa,mBAAmB,SAAS;CAC/C,MAAM,YAAY;EAAE,GAAG,MAAM;EAAW,GAAG;CAAW;AACxD;AAEA,IAAa,qBAAqB,cAAmD;CACnF,MAAM,QAAQ,SAAS;CACvB,MAAM,YAAY,mBAAmB,SAAS;AAChD;AAEA,IAAa,0BAA0B,eAAmD;CAExF,OADc,SACP,CAAA,CAAM,UAAU,eAAe;AACxC;;;ACrFA,IAAM,mBAAmB,UAAkB;CACzC,MAAM,SAAS,MAAM,QAAQ,MAAM,GAAG,CAAC,CAAC,QAAQ,MAAM,GAAG,IAAI,MAAM,OAAO,MAAM,SAAS,KAAK,CAAC;CAC/F,OAAO,OAAO,KAAK,QAAQ,QAAQ,CAAC,CAAC,SAAS,MAAM;AACtD;AAEA,IAAa,oBAAiD,UAA4B;CACxF,MAAM,QAAQ,MAAM,MAAM,GAAG;CAC7B,IAAI,MAAM,SAAS,GAAG,OAAO;CAE7B,IAAI;EACF,MAAM,OAAO,gBAAgB,MAAM,EAAE;EACrC,MAAM,SAAS,KAAK,MAAM,IAAI;EAC9B,IAAI,CAAC,UAAU,OAAO,WAAW,UAAU,OAAO;EAClD,OAAO;CACT,QAAQ;EACN,OAAO;CACT;AACF;;;ACTA,IAAM,wBAAQ,IAAI,IAAoC;AAEtD,IAAM,mBAAmB,QAAgB,IAAI,KAAK,CAAC,CAAC,QAAQ,QAAQ,EAAE;AAEtE,IAAa,mBAAmB,OAAO,cAA8C;CACnF,MAAM,SAAS,gBAAgB,SAAS;CACxC,IAAI,CAAC,QACH,MAAM,IAAI,MAAM,yBAAyB;CAG3C,MAAM,WAAW,MAAM,IAAI,MAAM;CACjC,IAAI,UACF,OAAO;CAGT,MAAM,UAAU,YAAY;EAC1B,MAAM,MAAM,IAAI,IAAI,qCAAqC,MAAM;EAC/D,MAAM,WAAW,MAAM,MAAM,KAAK,EAAE,SAAS,EAAE,QAAQ,mBAAmB,EAAE,CAAC;EAC7E,IAAI,CAAC,SAAS,IAAI;GAChB,MAAM,OAAO,MAAM,SAAS,KAAK,CAAC,CAAC,YAAY,EAAE;GACjD,MAAM,IAAI,MAAM,4CAA4C,SAAS,OAAM,GAAI,MAAM;EACvF;EAEA,MAAM,OAAO,MAAM,SAAS,KAAK,CAAC,CAAC,YAAY,IAAI;EACnD,IAAI,CAAC,QAAQ,OAAO,SAAS,UAC3B,MAAM,IAAI,MAAM,iCAAiC;EAGnD,MAAM,wBAAwB,OAAO,KAAK,2BAA2B,WACjE,KAAK,yBACL;EACJ,MAAM,gBAAgB,OAAO,KAAK,mBAAmB,WACjD,KAAK,iBACL;EACJ,MAAM,cAAc,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS;EACpE,MAAM,mBAAmB,OAAO,KAAK,sBAAsB,WAAW,KAAK,oBAAoB,KAAA;EAC/F,MAAM,UAAU,OAAO,KAAK,aAAa,WAAW,KAAK,WAAW,KAAA;EAEpE,IAAI,CAAC,yBAAyB,CAAC,eAC7B,MAAM,IAAI,MAAM,oDAAoD;EAGtE,OAAO;GACL,QAAQ;GACR,wBAAwB;GACxB,gBAAgB;GAChB,mBAAmB;GACnB,UAAU;EACZ;CACF,EAAA,CAAG;CAEH,MAAM,IAAI,QAAQ,MAAM;CAExB,IAAI;EACF,OAAO,MAAM;CACf,SAAS,KAAK;EACZ,MAAM,OAAO,MAAM;EACnB,MAAM;CACR;AACF;;;AChEA,IAAa,qBAAmB,UAAkB,MAC/C,SAAS,QAAQ,CAAC,CAClB,QAAQ,OAAO,GAAG,CAAC,CACnB,QAAQ,OAAO,GAAG,CAAC,CACnB,QAAQ,QAAQ,EAAE;AAErB,IAAa,yBAAyB;CACpC,MAAM,WAAW,kBAAgB,OAAO,YAAY,EAAE,CAAC;CAGvD,OAAO;EAAE;EAAU,WAFD,kBAAgB,OAAO,WAAW,QAAQ,CAAC,CAAC,OAAO,QAAQ,CAAC,CAAC,OAAO,CAEnE;CAAU;AAC/B;;;ACdA,IAAM,gCAAgB,IAAI,IAAI;CAAC;CAAa;CAAa;AAAa,CAAC;AAEvE,IAAa,yBAAyB,UAAkB;CACtD,MAAM,aAAa,MAAM,KAAK;CAC9B,IAAI,CAAC,YAAY,OAAO;CACxB,IAAI,WAAW,SAAS,KAAK,OAAO;CACpC,IAAI,cAAc,IAAI,UAAU,GAAG,OAAO;CAC1C,OAAO,mBAAmB,KAAK,UAAU;AAC3C;;;ACQA,IAAM,uBAAuB;AAC7B,IAAM,0BAA0B;AAOhC,IAAM,kBAAkB,UAAmB;CACzC,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,IAAI,MAAM,QAAQ,KAAK,KAAK,OAAO,MAAM,OAAO,UAAU,OAAO,MAAM;CACvE,OAAO;AACT;AAEA,IAAM,kBAAkB,KAAe,SAAgC;CACrE,MAAM,SAAS,IAAI,IAAI,SAAS;CAChC,IAAI,OAAO,WAAW,YAAY,CAAC,QAAQ,OAAO;CAElD,KAAK,MAAM,QAAQ,OAAO,MAAM,GAAG,GAAG;EACpC,MAAM,CAAC,QAAQ,GAAG,QAAQ,KAAK,MAAM,GAAG;EACxC,MAAM,MAAM,QAAQ,KAAK;EACzB,IAAI,CAAC,OAAO,QAAQ,MAAM;EAC1B,MAAM,WAAW,KAAK,KAAK,GAAG,CAAC,CAAC,KAAK;EACrC,IAAI,CAAC,UAAU,OAAO;EACtB,IAAI;GACF,OAAO,mBAAmB,QAAQ;EACpC,QAAQ;GACN,OAAO;EACT;CACF;CAEA,OAAO;AACT;AAEA,IAAM,sBAAsB,cAAsB;CAChD,IAAI,CAAC,UAAU,WAAW,GAAG,GAAG,OAAO;CACvC,IAAI,UAAU,WAAW,IAAI,GAAG,OAAO;CACvC,OAAO;AACT;AAEA,IAAM,oBAAoB,QAAkB;CAC1C,MAAM,cAAc,IAAI,IAAI,QAAQ;CACpC,MAAM,aAAa,IAAI,IAAI,QAAQ;CAEnC,MAAM,WAAW,OAAO,gBAAgB,WACpC,YAAY,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,IAC/B,IAAI,IAAI;CAEZ,MAAM,OAAO,OAAO,eAAe,WAC/B,WAAW,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,IAC9B,IAAI,IAAI,IAAI,MAAM;CAEtB,OAAO,YAAY,OAAO,GAAG,SAAQ,KAAM,SAAS;AACtD;AAEA,IAAM,uBAAuB,iBAAyB;CACpD,MAAM,UAAU,aAAa,KAAK;CAClC,OAAO,WAAW,mBAAmB,OAAO,IAAI,UAAU;AAC5D;AAEA,IAAM,eAAe,OAAO,QAC1B,MAAM,IAAI,SAAiB,SAAS,WAAW;CAC7C,IAAI,OAAO;CACX,IAAI,OAAO,IAAI,gBAAgB,YAC7B,IAAI,YAAY,MAAM;CAGxB,IAAI,GAAG,SAAS,UAAU;EACxB,QAAQ,OAAO,KAAK;EACpB,IAAI,KAAK,SAAS,OAChB,uBAAO,IAAI,MAAM,wBAAwB,CAAC;CAE9C,CAAC;CACD,IAAI,GAAG,aAAa,QAAQ,IAAI,CAAC;CACjC,IAAI,GAAG,SAAS,MAAM;AACxB,CAAC;AAEH,IAAM,oBAAoB,OAAO,QAA0D;CACzF,IAAI,IAAI,IAAI,WAAW,QAAQ,OAAO;CAGtC,IAAI,EADgB,OAAO,IAAI,IAAI,QAAQ,oBAAoB,WAAW,IAAI,IAAI,QAAQ,kBAAkB,GAAA,CAC3F,SAAS,mCAAmC,GAAG,OAAO;CAEvE,MAAM,OAAO,MAAM,aAAa,IAAI,GAAG;CACvC,MAAM,SAAS,IAAI,gBAAgB,IAAI;CAEvC,MAAM,SAAiC,CAAC;CACxC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,GACxC,OAAO,OAAO;CAGhB,OAAO;AACT;AAEA,IAAM,qBAAqB,KAAe,wBACvC,sBAAsB,OAAO,IAAI,IAAI,QAAQ,YAAY,EAAE,EAAA,CAAG,KAAK;AAEtE,IAAM,2CAA2B,IAAI,IAAI;CAAC;CAAa;CAAa;AAAa,CAAC;AAElF,IAAM,gCAAgC,UAAuD;CAC3F,IAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAAG,OAAO,KAAA;CAExE,MAAM,SAAiC,CAAC;CACxC,KAAK,MAAM,CAAC,QAAQ,aAAa,OAAO,QAAQ,KAAK,GAAG;EACtD,MAAM,MAAM,OAAO,KAAK;EACxB,IAAI,CAAC,KAAK;EACV,IAAI,yBAAyB,IAAI,GAAG,GAAG;EACvC,MAAM,MAAM,OAAO,aAAa,WAAW,SAAS,KAAK,IAAI;EAC7D,IAAI,CAAC,KAAK;EACV,OAAO,OAAO;CAChB;CAEA,OAAO,OAAO,KAAK,MAAM,CAAC,CAAC,SAAS,SAAS,KAAA;AAC/C;AAMA,IAAa,2BAA2B,OAAO,EAC7C,KACA,YAAY,oBACZ,UACA,0BAM+B;CAC/B,MAAM,aAAa,kBAAkB,KAAK,kBAAkB;CAC5D,IAAI,CAAC,YACH,OAAO;EAAE,SAAS;EAAO,OAAO;EAAoB,YAAY;CAAI;CAGtE,IAAI,CAAC,sBAAsB,UAAU,GACnC,OAAO;EAAE,SAAS;EAAO,OAAO;EAAoB,YAAY;CAAI;CAGtE,MAAM,WAAW,uBAAuB,UAAU;CAClD,IAAI,CAAC,UACH,OAAO;EAAE,SAAS;EAAO,OAAO;EAAoB,YAAY;CAAI;CAGtE,MAAM,SAAS,iBAAiB,GAAG;CACnC,IAAI,CAAC,QACH,OAAO;EAAE,SAAS;EAAO,OAAO;EAAsB,YAAY;CAAI;CAExE,MAAM,UAAU,OAAO,WAAW,UAAU;CAE5C,MAAM,eAAe,oBAAoB,SAAS,YAAY;CAC9D,IAAI,CAAC,cACH,OAAO;EAAE,SAAS;EAAO,OAAO;EAAyB,YAAY;CAAI;CAG3E,MAAM,QAAQ,OAAO,YAAY,EAAE,CAAC,CAAC,SAAS,KAAK;CACnD,MAAM,EAAE,UAAU,cAAc,iBAAiB;CAEjD,MAAM,eAAe,OAAO,aAAa,YAAY,mBAAmB,QAAQ,IAAI,WAAW,KAAA;CAE/F,IAAI;EACF,MAAM,eAAe,MAAM,OAAO,UAAU,kBAAkB,GAAG;EACjE,MAAM,sBAAM,IAAI,KAAK;EACrB,MAAM,aAAa,OAAO;GACxB,KAAK;GACL;GACA,cAAc;GACd,UAAU;GACV,WAAW;GACX,WAAW,IAAI,KAAK,IAAI,QAAQ,IAAI,oBAAoB;EAC1D,CAAC;CACH,SAAS,KAAK;EACZ,QAAQ,KAAK,kCAAkC,GAAG;EAClD,OAAO;GAAE,SAAS;GAAO,OAAO;GAA8B,YAAY;EAAI;CAChF;CAEA,IAAI;EACF,IAAI,IAAI,OAAO,yBAAyB,GAAG,WAAU,GAAI,SAAS;GAChE,UAAU;GACV,QAAQ;GACR,UAAU,UAAU,SAAS;GAC7B,MAAM;GACN,QAAQ;EACV,CAAC;CACH,SAAS,KAAK;EACZ,QAAQ,KAAK,qCAAqC,GAAG;EACrD,OAAO;GAAE,SAAS;GAAO,OAAO;GAA2B,YAAY;EAAI;CAC7E;CAEA,MAAM,OAAO,MAAM,iBAAiB,SAAS,MAAM;CACnD,MAAM,cAAc,GAAG,SAAS;CAEhC,MAAM,MAAM,IAAI,IAAI,KAAK,sBAAsB;CAC/C,IAAI,aAAa,IAAI,aAAa,SAAS,QAAQ;CACnD,IAAI,aAAa,IAAI,gBAAgB,WAAW;CAChD,IAAI,aAAa,IAAI,iBAAiB,MAAM;CAC5C,IAAI,aAAa,IAAI,SAAS,SAAS,KAAK;CAC5C,IAAI,aAAa,IAAI,SAAS,KAAK;CACnC,IAAI,aAAa,IAAI,kBAAkB,SAAS;CAChD,IAAI,aAAa,IAAI,yBAAyB,MAAM;CACpD,MAAM,2BAA2B,6BAA6B,mBAAmB;CACjF,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,4BAA4B,CAAC,CAAC,GAAG;EACzE,IAAI,IAAI,aAAa,IAAI,GAAG,GAAG;EAC/B,IAAI,aAAa,IAAI,KAAK,KAAK;CACjC;CAEA,OAAO;EAAE,SAAS;EAAM,aAAa,IAAI,SAAS;CAAE;AACtD;AA2BA,IAAM,8BAA8B;AACpC,IAAM,2BAA2B;AAEjC,IAAa,uBAAuB,OAAO,EACzC,KACA,YAAY,oBACZ,yBACA,yBACA,0BAOkC;CAClC,MAAM,aAAa,kBAAkB,KAAK,kBAAkB;CAC5D,IAAI,CAAC,YACH,OAAO;EAAE,SAAS;EAAO,MAAM;EAAS,OAAO;EAAoB,cAAc,GAAG,yBAAwB;CAA0B;CAGxI,IAAI,CAAC,sBAAsB,UAAU,GACnC,OAAO;EAAE,SAAS;EAAO,MAAM;EAAS,OAAO;EAAoB,cAAc,GAAG,yBAAwB;CAA0B;CAGxI,MAAM,WAAW,uBAAuB,UAAU;CAClD,IAAI,CAAC,UACH,OAAO;EAAE,SAAS;EAAO,MAAM;EAAS,OAAO;EAAoB,cAAc,GAAG,yBAAwB;CAA0B;CAGxI,MAAM,SAAS,iBAAiB,GAAG;CACnC,IAAI,CAAC,QACH,OAAO;EAAE,SAAS;EAAO,MAAM;EAAS,OAAO;EAAsB,cAAc,GAAG,yBAAwB;CAA4B;CAE5I,MAAM,UAAU,OAAO,WAAW,UAAU;CAE5C,MAAM,eAAe,oBAAoB,SAAS,YAAY;CAC9D,IAAI,CAAC,cACH,OAAO;EAAE,SAAS;EAAO,MAAM;EAAS,OAAO;EAAyB,cAAc,GAAG,yBAAwB;CAA+B;CAGlJ,MAAM,aAAa,MAAM,kBAAkB,GAAG;CAE9C,MAAM,QAAQ,eAAe,YAAY,IAAI,KAAK,eAAe,IAAI,IAAI,OAAO,IAAI,EAAA,EAAI,KAAK,KAAK;CAClG,MAAM,SAAS,eAAe,YAAY,KAAK,KAAK,eAAe,IAAI,IAAI,OAAO,KAAK,EAAA,EAAI,KAAK,KAAK;CACrG,MAAM,gBAAgB,eAAe,YAAY,IAAI,KAAK,eAAe,IAAI,IAAI,OAAO,IAAI,EAAA,EAAI,KAAK,KAAK;CAE1G,IAAI,CAAC,QAAQ,CAAC,OACZ,OAAO;EAAE,SAAS;EAAO,MAAM;EAAS,OAAO;EAAyB,cAAc,GAAG,yBAAwB;CAA+B;CAIlJ,IADyB,eAAe,KAAK,uBACzC,MAAqB,GAAG,WAAU,GAAI,SACxC,OAAO;EAAE,SAAS;EAAO,MAAM;EAAS,OAAO;EAAiB,cAAc,GAAG,yBAAwB;CAAuB;CAGlI,IAAI,eAA0C;CAC9C,IAAI,oBAAyE;CAC7E,IAAI;EACF,oBAAoB,MAAM,OAAO,UAAU,kBAAkB,GAAG;EAChE,eAAe,MAAM,kBAAkB,QAAQ;GAAE,KAAK;GAAO;EAAW,CAAC,CAAC,CAAC,KAAK;CAClF,SAAS,KAAK;EACZ,QAAQ,KAAK,iCAAiC,GAAG;EACjD,OAAO;GAAE,SAAS;GAAO,MAAM;GAAS,OAAO;GAA6B,cAAc,GAAG,yBAAwB;EAAmC;CAC1J;CAEA,IAAI,CAAC,cACH,OAAO;EAAE,SAAS;EAAO,MAAM;EAAS,OAAO;EAAiB,cAAc,GAAG,yBAAwB;CAAuB;CAGlI,MAAM,WAAW,OAAO,aAAa,aAAa,WAAW,aAAa,WAAW,KAAA;CACrF,MAAM,eAAe,OAAO,aAAa,iBAAiB,WAAW,aAAa,eAAe;CACjG,IAAI,CAAC,cACH,OAAO;EAAE,SAAS;EAAO,MAAM;EAAS,OAAO;EAAyB,cAAc,GAAG,yBAAwB;CAA+B;CAGlJ,MAAM,OAAO,MAAM,iBAAiB,SAAS,MAAM;CACnD,MAAM,cAAc,GAAG,SAAS;CAEhC,MAAM,YAAY,IAAI,gBAAgB;CACtC,UAAU,IAAI,cAAc,oBAAoB;CAChD,UAAU,IAAI,QAAQ,IAAI;CAC1B,UAAU,IAAI,gBAAgB,WAAW;CACzC,UAAU,IAAI,aAAa,SAAS,QAAQ;CAC5C,UAAU,IAAI,iBAAiB,YAAY;CAC3C,IAAI,SAAS,cACX,UAAU,IAAI,iBAAiB,SAAS,YAAY;CAGtD,MAAM,gBAAgB,MAAM,MAAM,KAAK,gBAAgB;EACrD,QAAQ;EACR,SAAS;GACP,gBAAgB;GAChB,QAAQ;EACV;EACA,MAAM,UAAU,SAAS;CAC3B,CAAC;CAED,MAAM,YAAY,MAAM,cAAc,KAAK,CAAC,CAAC,YAAY,IAAI;CAE7D,IAAI,CAAC,cAAc,MAAM,CAAC,aAAa,OAAO,cAAc,UAAU;EACpE,MAAM,OAAO,YAAY,KAAK,UAAU,SAAS,IAAI;EACrD,QAAQ,KAAK,gCAAgC,cAAc,QAAQ,IAAI;EACvE,OAAO;GAAE,SAAS;GAAO,MAAM;GAAS,OAAO;GAAyB,cAAc,GAAG,yBAAwB;EAA+B;CAClJ;CAEA,MAAM,cAAc,OAAO,UAAU,iBAAiB,WAAW,UAAU,eAAe;CAC1F,MAAM,eAAe,OAAO,UAAU,kBAAkB,WAAW,UAAU,gBAAgB,KAAA;CAC7F,MAAM,UAAU,OAAO,UAAU,aAAa,WAAW,UAAU,WAAW,KAAA;CAC9E,MAAM,QAAQ,OAAO,UAAU,UAAU,WAAW,UAAU,QAAQ,KAAA;CACtE,MAAM,YAAY,OAAO,UAAU,eAAe,WAAW,UAAU,aAAa,KAAA;CACpF,MAAM,YAAY,OAAO,UAAU,eAAe,WAC9C,UAAU,aACV,OAAO,UAAU,eAAe,WAC9B,OAAO,UAAU,UAAU,IAC3B,KAAA;CACN,MAAM,mBAAmB,OAAO,cAAc,YAAY,OAAO,SAAS,SAAS,IAAI,YAAY;CACnG,MAAM,YAAY,qBAAqB,OAAO,IAAI,KAAK,KAAK,IAAI,IAAI,mBAAmB,GAAI,IAAI,KAAA;CAE/F,IAAI,WAA2C;CAE/C,IAAI,KAAK,qBAAqB,aAAa;EACzC,MAAM,mBAAmB,MAAM,MAAM,KAAK,mBAAmB,EAC3D,SAAS;GACP,eAAe,UAAU;GACzB,QAAQ;EACV,EACF,CAAC;EAED,IAAI,iBAAiB,IACnB,WAAW,MAAM,iBAAiB,KAAK,CAAC,CAAC,YAAY,IAAI;CAE7D;CAEA,MAAM,iBAAiB,UAAU,iBAA0C,OAAO,IAAI;CACtF,MAAM,qBAAqB,iBAA0C,WAAW;CAEhF,MAAM,UAAU,OAAO,UAAU,QAAQ,WACrC,SAAS,MACT,OAAO,gBAAgB,QAAQ,WAC7B,eAAe,MACf,OAAO,oBAAoB,QAAQ,WACjC,mBAAmB,MACnB;CAER,IAAI,CAAC,SACH,OAAO;EAAE,SAAS;EAAO,MAAM;EAAS,OAAO;EAAmB,cAAc,GAAG,yBAAwB;CAAyB;CAGtI,MAAM,QAAQ,OAAO,UAAU,UAAU,WACrC,SAAS,QACT,OAAO,gBAAgB,UAAU,WAC/B,eAAe,QACf,KAAA;CAEN,MAAM,OAAO,OAAO,UAAU,SAAS,WACnC,SAAS,OACT,OAAO,gBAAgB,SAAS,WAC9B,eAAe,OACf,KAAA;CAEN,IAAI,YAAqB;CACzB,IAAI,cACF,IAAI;EACF,YAAY,KAAK,MAAM,YAAY;CACrC,QAAQ;EACN,YAAY;CACd;CAEF,MAAM,kBAAkB,aAAa,OAAO,cAAc,WACrD,YACD;CACJ,MAAM,iBAAiB,OAAO,iBAAiB,UAAU,WAAW,gBAAgB,MAAM,KAAK,IAAI;CACnG,MAAM,sBAAsB,iBAAiB,QAAQ,OAAO,gBAAgB,SAAS,WAChF,gBAAgB,OACjB;CAGJ,MAAM,gBAAgB,CAFK,OAAO,qBAAqB,cAAc,WAAW,oBAAoB,UAAU,KAAK,IAAI,IAC7F,OAAO,qBAAqB,aAAa,WAAW,oBAAoB,SAAS,KAAK,IAAI,EACxD,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK;CAE7F,MAAM,iBAAiB,OAAO,KAAK,KAAK,kBAAkB,KAAA,EAAA,EAAY,YAAY;CAClF,MAAM,eAAe,SAAS,iBAAiB,KAAA;CAE/C,MAAM,CAAC,MAAM,UAAU,MAAM,QAAQ,IAAI,CACvC,OAAO,UAAU,UAAU,GAAG,GAC9B,OAAO,UAAU,YAAY,GAAG,CAAC,CAClC;CAED,MAAM,kBAAkB,kBAAkB,WAAU;CACpD,IAAI,OAAO,MAAM,KAAK,QAAQ,GAAG,kBAAkB,QAAQ,CAAC;CAE5D,IAAI,CAAC,QAAQ,eACX,OAAO,MAAM,KAAK,QAAQ,EAAE,OAAO,cAAc,CAAC;CAIpD,IAAI,CAAC,QAAQ,EADY,2BAA2B,OACpB;EAC9B,MAAM,eAAe;EAErB,MAAM,SAA8B;GAClC,SAAS;GACT,MAAM;GACN;GACA;GACA,OAAO;GACP,MAAM;EACR;EAEA,IAAI,gBAAgB,mBAAmB,YAAY,GAAG;GACpD,MAAM,MAAM,IAAI,IAAI,cAAc,MAAM;GACxC,IAAI,aAAa,IAAI,kBAAkB,UAAU;GACjD,IAAI,eAAe,IAAI,aAAa,IAAI,SAAS,aAAa;GAC9D,IAAI,cAAc,IAAI,aAAa,IAAI,QAAQ,YAAY;GAC3D,OAAO,eAAe,GAAG,IAAI,WAAW,IAAI;EAC9C;EAEA,OAAO;CACT;CAEA,IAAI,CAAC,IAAI,IAAI,SACX,OAAO;EAAE,SAAS;EAAO,MAAM;EAAS,OAAO;EAAuB,cAAc,GAAG,yBAAwB;CAA6B;CAG9I,MAAM,sBAAM,IAAI,KAAK;CAErB,IAAI;CAEJ,MAAM,oBADiB,MAAM,IAAI,gBAAgB,EAAA,EACR,IAAI,UAAU;CACvD,IAAI,kBAAkB,qBAAqB,MACzC,oBAAoB,iBAAiB;CAGvC,MAAM,uBAAuB;EAC3B;EACA,OAAO;EACP,MAAM;EACN;EACA;EACA;EACA;EACA;EACA;EACA,aAAa,YAAY,KAAA;EACzB,WAAW,qBAAqB;EAChC,WAAW;CACb;CAEA,IAAI,4BAA4B;CAChC,IAAI;CAEJ,IAAI,CAAC,MAAM;EACT,MAAM,WAAW,OAAO,WAAW;EAGnC,OAAO,IAAI,KAAK;GACd,OAAO;GACP,MAAM;GACN,UAAA,MALqB,uBAAuB,OAAO,YAAY,EAAE,CAAC,CAAC,SAAS,KAAK,CAAC;GAMlF,SAAS,CAAC,QAAQ;GAClB,aAAa,GACV,WAAW,CAAC,OAAO,EACtB;GACA,gBAAgB,GACb,aAAa,qBAChB;EACF,CAAC;EAED,MAAM,KAAK,KAAK;EAEhB,IAAI;GACF,MAAM,wBAAwB,QAAQ;IACpC;IACA,MAAM,iBAAiB;GACzB,CAAC;EACH,SAAS,KAAK;GACZ,QAAQ,MAAM,sCAAsC,GAAG;GACvD,IAAI;IACF,MAAM,KAAK,UAAU,EAAE,KAAK,KAAK,IAAI,CAAC;GACxC,SAAS,eAAe;IACtB,QAAQ,MAAM,kCAAkC,aAAa;GAC/D;GACA,OAAO;IACL,SAAS;IACT,MAAM;IACN,OAAO;IACP,cAAc,GAAG,yBAAwB;GAC3C;EACF;CACF,OAAO;EACL,MAAM,YAAqC,GACxC,kBAAkB,eAAe,qBACpC;EACA,4BAA4B,sBAAsB;GAChD,oBAAoB,KAAK,IAAI,oBAAoB;GACjD,uBAAuB,KAAK,IAAI,uBAAuB;EACzD,CAAC;EAED,IAAI,2BAA2B;GAC7B,2BAA2B,MAAM,uBAAuB,OAAO,YAAY,EAAE,CAAC,CAAC,SAAS,KAAK,CAAC;GAC9F,UAAU,WAAW;EACvB;EAEA,IAAI,CAAC,KAAK,SAAS,eACjB,UAAU,QAAQ;EAGpB,IAAI,CAAC,KAAK,QAAQ,cAChB,UAAU,OAAO;EAGnB,MAAM,KAAK,UACT,EAAE,KAAK,KAAK,IAAI,GAChB,EACE,MAAM,UACR,CACF;CACF;CAEA,MAAM,mBAAmB,KAAK,WAAW,CAAA,EAAA,CAAI,IAAI,MAAM;CACvD,MAAM,WAAW,gBAAgB;CACjC,IAAI,CAAC,UACH,OAAO;EACL,SAAS;EACT,MAAM;EACN,OAAO;EACP,cAAc,GAAG,yBAAwB;CAC3C;CAGF,MAAM,SAAS,MAAM,OAAO,QAAQ,EAAE,SAAS,GAAG,EAAE,oBAAoB,EAAE,CAAC,CAAC,CAAC,KAAK;CAGlF,IAAI,CAAC,UAAW,OAAO,sBAAsB,OAAO,uBAAuB,UACzE,OAAO;EACL,SAAS;EACT,MAAM;EACN,OAAO;EACP,cAAc,GAAG,yBAAwB;CAC3C;CAGF,IAAI,6BAA6B,0BAC/B,MAAM,KAAK,UACT,EAAE,KAAK,KAAK,IAAI,GAChB;EACE,MAAM;GACJ,oBAAoB;GACpB,UAAU;EACZ;EACA,QAAQ;GACN,uBAAuB;GACvB,4BAA4B;GAC5B,yBAAyB;EAC3B;CACF,CACF;CAGF,MAAM,iBAAiB,KAAK,IAAI,aAAa;CAC7C,MAAM,cAAc,iBAAiB,OAAO,YAAY,eAAe,QAAQ,CAAC,IAAI,KAAA;CAEpF,IAAI,CAAC,mBAAmB,KAAK;EAC3B,QAAQ,KAAK,IAAI,SAAS;EAC1B,iBAAiB;EACjB,iBAAiB,gBAAgB,SAAS,kBAAkB,CAAC,QAAQ;EACrE;CACF,CAAC,GACC,OAAO;EACL,SAAS;EACT,MAAM;EACN,OAAO;EACP,cAAc,GAAG,yBAAwB;CAC3C;CAGF,IAAI;EACF,IAAI,mBACF,MAAM,kBAAkB,UAAU;GAAE,KAAK;GAAO;EAAW,CAAC;CAEhE,SAAS,KAAK;EACZ,QAAQ,KAAK,mCAAmC,GAAG;CACrD;CAEA,IAAI;EACF,IAAI,IAAI,YAAY,yBAAyB;GAC3C,UAAU;GACV,QAAQ;GACR,UAAU,UAAU,SAAS;GAC7B,MAAM;EACR,CAAC;CACH,SAAS,KAAK;EACZ,QAAQ,KAAK,uCAAuC,GAAG;CACzD;CAQA,OAAO;EACL,SAAS;EACT,MAAM;EACN,cATmB,YAAY,mBAAmB,QAAQ,IACxD,WACA,uBAAuB,mBAAmB,mBAAmB,IAC3D,sBACA;EAMJ,QAAQ,KAAK,IAAI,SAAS;EAC1B;EACA,iBAAiB,gBAAgB,SAAS,kBAAkB,CAAC,QAAQ;CACvE;AACF;AAEA,IAAa,2BAA2B,EACtC,YACA,2BAIE,CAAC,MAAkF,OACrF,UACA,QACG;CACH,MAAM,qBAAqB,kBAAkB,KAAK,UAAU;CAC5D,MAAM,8BAA8B,sBAAsB,yBACtD,uBAAuB,kBAAkB,IACzC,KAAA;CACJ,MAAM,WAAW,eAAe,IAAI,IAAI,OAAO,QAAQ,CAAC,EAAE,KAAK;CAC/D,MAAM,SAAS,MAAM,yBAAyB;EAC5C;EACA,YAAY;EACZ;EACA,qBAAqB;CACvB,CAAC;CAED,IAAI,CAAC,OAAO,SAAS;EACnB,IAAI,IAAI,OAAO,OAAO,UAAU;EAChC,OAAO;GAAE,SAAS;GAAO,OAAO,OAAO;EAAM;CAC/C;CAEA,IAAI,IAAI,SAAS,OAAO,WAAW;CACnC,OAAO,EAAE,SAAS,KAAK;AACzB;AAEA,IAAa,8BAA8B,EACzC,YACA,yBACA,yBACA,wBAME,CAAC,MAAkF,OACrF,UACA,QACG;CACH,MAAM,SAAS,MAAM,qBAAqB;EACxC;EACA;EACA;EACA;EACA;CACF,CAAC;CAED,IAAI,OAAO,SAAS,SAAS;EAC3B,IAAI,IAAI,SAAS,OAAO,YAAY;EACpC,OAAO;GAAE,SAAS;GAAO,OAAO,OAAO;EAAM;CAC/C;CAEA,IAAI,OAAO,SAAS,gBAAgB;EAClC,IAAI,OAAO,cACT,IAAI,IAAI,SAAS,OAAO,YAAY;OAEpC,IAAI,IAAI,SAAS,eAAe;EAElC,OAAO;GAAE,SAAS;GAAO,OAAO;EAAiB;CACnD;CAEA,IAAI,IAAI,SAAS,OAAO,YAAY;CACpC,OAAO,EAAE,SAAS,KAAK;AACzB;AAEA,IAAM,mBAAmB,UACvB,OAAO,KAAK,KAAK,CAAC,CACf,SAAS,QAAQ,CAAC,CAClB,QAAQ,OAAO,GAAG,CAAC,CACnB,QAAQ,OAAO,GAAG,CAAC,CACnB,QAAQ,QAAQ,EAAE;AAEvB,IAAa,2BAA2B,EACtC,QACA,UACA,OACA,eACA,sBAAM,IAAI,KAAK,GACf,mBAAmB,UAQf;CACJ,MAAM,cAAc,OAAO,KAAK;CAChC,MAAM,gBAAgB,SAAS,KAAK;CACpC,MAAM,aAAa,MAAM,KAAK;CAC9B,MAAM,qBAAqB,cAAc,KAAK;CAE9C,IAAI,CAAC,aAAa,MAAM,IAAI,MAAM,oBAAoB;CACtD,IAAI,CAAC,eAAe,MAAM,IAAI,MAAM,sBAAsB;CAC1D,IAAI,CAAC,YAAY,MAAM,IAAI,MAAM,mBAAmB;CACpD,IAAI,CAAC,oBAAoB,MAAM,IAAI,MAAM,2BAA2B;CAEpE,MAAM,aAAa,KAAK,MAAM,IAAI,QAAQ,IAAI,GAAI;CAElD,MAAM,MAAM,aAAa,KAAK,IAAI,IAAI,KAAK,IADzB,OAAO,SAAS,gBAAgB,IAAI,mBAAmB,KACf,OAAkB,CAAC;CAE7E,MAAM,SAAS;EAAE,KAAK;EAAS,KAAK;EAAY,KAAK;CAAM;CAC3D,MAAM,UAAU;EACd,KAAK;EACL,KAAK;EACL;EACA,KAAK;EACL,KAAK;CACP;CAEA,MAAM,eAAe,GAAG,gBAAgB,KAAK,UAAU,MAAM,CAAC,EAAC,GAAI,gBAAgB,KAAK,UAAU,OAAO,CAAC;CAM1G,OAAO,GAAG,aAAY,GAAI,gBALR,OAAO,KAAK,UAAU,OAAO,KAAK,YAAY,GAAG;EACjE,KAAK;EACL,aAAa;CACf,CAE0C,CAAS;AACrD"}
@@ -1 +1 @@
1
- {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../../src/oauth/lib.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../../src/oauth/lib.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ //#region src/registrationStatus.ts
2
+ var pendingRegistrationCondition = () => ({ $or: [{ registrationStatus: "pending_verification" }, { emailVerificationCode: { $exists: true } }] });
3
+ var isPendingRegistration = ({ registrationStatus, emailVerificationCode }) => registrationStatus === "pending_verification" || typeof emailVerificationCode === "string";
4
+ //#endregion
5
+ export { pendingRegistrationCondition as n, isPendingRegistration as t };
6
+
7
+ //# sourceMappingURL=registrationStatus-BP6yReMw.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registrationStatus-BP6yReMw.js","names":[],"sources":["../src/registrationStatus.ts"],"sourcesContent":["export const pendingRegistrationCondition = () => ({\n $or: [\n { registrationStatus: \"pending_verification\" },\n { emailVerificationCode: { $exists: true } },\n ],\n})\n\nexport const isPendingRegistration = ({\n registrationStatus,\n emailVerificationCode,\n}: {\n registrationStatus?: unknown\n emailVerificationCode?: unknown\n}): boolean => (\n registrationStatus === \"pending_verification\"\n || typeof emailVerificationCode === \"string\"\n)\n"],"mappings":";AAAA,IAAa,sCAAsC,EACjD,KAAK,CACH,EAAE,oBAAoB,uBAAuB,GAC7C,EAAE,uBAAuB,EAAE,SAAS,KAAK,EAAE,CAC7C,EACF;AAEA,IAAa,yBAAyB,EACpC,oBACA,4BAKA,uBAAuB,0BACpB,OAAO,0BAA0B"}
@@ -0,0 +1,16 @@
1
+ export declare const pendingRegistrationCondition: () => {
2
+ $or: ({
3
+ registrationStatus: string;
4
+ emailVerificationCode?: undefined;
5
+ } | {
6
+ emailVerificationCode: {
7
+ $exists: boolean;
8
+ };
9
+ registrationStatus?: undefined;
10
+ })[];
11
+ };
12
+ export declare const isPendingRegistration: ({ registrationStatus, emailVerificationCode, }: {
13
+ registrationStatus?: unknown;
14
+ emailVerificationCode?: unknown;
15
+ }) => boolean;
16
+ //# sourceMappingURL=registrationStatus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registrationStatus.d.ts","sourceRoot":"","sources":["../src/registrationStatus.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,4BAA4B;;;;;;;;;;CAKvC,CAAA;AAEF,eAAO,MAAM,qBAAqB,GAAI,gDAGnC;IACD,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAChC,KAAG,OAGH,CAAA"}
package/dist/routes.js CHANGED
@@ -1,15 +1,15 @@
1
1
  //#region src/routes.ts
2
2
  var routes = Object.entries({ .../* #__PURE__ */ Object.assign({
3
- "./api/me/handler.ts": () => import("./handler-BgjYCWF4.js"),
4
- "./api/request-password-reset/handler.ts": () => import("./handler-Dbw6BOmj.js"),
5
- "./api/resend-otp/handler.ts": () => import("./handler-B1Z9YpER.js"),
6
- "./api/set-active-account/handler.ts": () => import("./handler-CF3fSh8e.js"),
7
- "./api/set-new-password/handler.ts": () => import("./handler-DgIcxthg.js"),
8
- "./api/sign-in/handler.ts": () => import("./handler-D4ui5jV4.js"),
9
- "./api/sign-out/handler.ts": () => import("./handler-DBbjgU-f.js"),
10
- "./api/sign-up/handler.ts": () => import("./handler-BkZLC8Bg.js"),
11
- "./api/verify-otp/handler.ts": () => import("./handler-1Jy7G8dM.js"),
12
- "./api/verify-password-reset-otp/handler.ts": () => import("./handler-iT2eSHpE.js")
3
+ "./api/me/handler.ts": () => import("./handler-B6roBozS.js"),
4
+ "./api/request-password-reset/handler.ts": () => import("./handler-BhPmGpUq.js"),
5
+ "./api/resend-otp/handler.ts": () => import("./handler-DCk7C1pI.js"),
6
+ "./api/set-active-account/handler.ts": () => import("./handler-JKQLI2iL.js"),
7
+ "./api/set-new-password/handler.ts": () => import("./handler-b6PvhATs.js"),
8
+ "./api/sign-in/handler.ts": () => import("./handler-BPoWo5Qy.js"),
9
+ "./api/sign-out/handler.ts": () => import("./handler-BenTgwfT.js"),
10
+ "./api/sign-up/handler.ts": () => import("./handler-0uaKeuYp.js"),
11
+ "./api/verify-otp/handler.ts": () => import("./handler-cj7IkJB-.js"),
12
+ "./api/verify-password-reset-otp/handler.ts": () => import("./handler-DCljRBBf.js")
13
13
  }) }).reduce((acc, [path, mod]) => {
14
14
  acc[path.replace("./api/", "@rpcbase/auth/api/")] = mod;
15
15
  return acc;
@@ -3990,6 +3990,6 @@ function superRefine(fn, params) {
3990
3990
  return /* @__PURE__ */ _superRefine(fn, params);
3991
3991
  }
3992
3992
  //#endregion
3993
- export { string as a, object as i, boolean as n, number as r, array as t };
3993
+ export { object as a, number as i, array as n, string as o, boolean as r, _enum as t };
3994
3994
 
3995
- //# sourceMappingURL=schemas-CMgO_xn9.js.map
3995
+ //# sourceMappingURL=schemas-DABNKHVA.js.map