@robelest/convex-auth 0.0.4-preview.21 → 0.0.4-preview.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/authorization/index.d.ts +1 -1
- package/dist/authorization/index.js +1 -1
- package/dist/authorization/index.js.map +1 -1
- package/dist/client/index.d.ts +1 -2
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +36 -39
- package/dist/client/index.js.map +1 -1
- package/dist/component/client/index.d.ts +1 -2
- package/dist/component/convex.config.d.ts +2 -2
- package/dist/component/convex.config.d.ts.map +1 -1
- package/dist/component/model.d.ts +5 -5
- package/dist/component/model.d.ts.map +1 -1
- package/dist/component/public/enterprise/audit.d.ts.map +1 -1
- package/dist/component/public/enterprise/audit.js.map +1 -1
- package/dist/component/public/enterprise/core.d.ts.map +1 -1
- package/dist/component/public/enterprise/core.js.map +1 -1
- package/dist/component/public/enterprise/domains.d.ts.map +1 -1
- package/dist/component/public/enterprise/domains.js.map +1 -1
- package/dist/component/public/enterprise/scim.d.ts.map +1 -1
- package/dist/component/public/enterprise/scim.js.map +1 -1
- package/dist/component/public/enterprise/secrets.d.ts.map +1 -1
- package/dist/component/public/enterprise/secrets.js.map +1 -1
- package/dist/component/public/enterprise/webhooks.d.ts.map +1 -1
- package/dist/component/public/enterprise/webhooks.js.map +1 -1
- package/dist/component/public/factors/devices.d.ts.map +1 -1
- package/dist/component/public/factors/devices.js.map +1 -1
- package/dist/component/public/factors/passkeys.d.ts.map +1 -1
- package/dist/component/public/factors/passkeys.js.map +1 -1
- package/dist/component/public/factors/totp.d.ts.map +1 -1
- package/dist/component/public/factors/totp.js.map +1 -1
- package/dist/component/public/groups/core.js.map +1 -1
- package/dist/component/public/groups/invites.d.ts.map +1 -1
- package/dist/component/public/groups/invites.js.map +1 -1
- package/dist/component/public/groups/members.d.ts.map +1 -1
- package/dist/component/public/groups/members.js.map +1 -1
- package/dist/component/public/identity/accounts.d.ts.map +1 -1
- package/dist/component/public/identity/accounts.js.map +1 -1
- package/dist/component/public/identity/codes.d.ts.map +1 -1
- package/dist/component/public/identity/codes.js.map +1 -1
- package/dist/component/public/identity/sessions.d.ts.map +1 -1
- package/dist/component/public/identity/sessions.js.map +1 -1
- package/dist/component/public/identity/tokens.d.ts.map +1 -1
- package/dist/component/public/identity/tokens.js.map +1 -1
- package/dist/component/public/identity/users.d.ts.map +1 -1
- package/dist/component/public/identity/users.js.map +1 -1
- package/dist/component/public/identity/verifiers.d.ts.map +1 -1
- package/dist/component/public/identity/verifiers.js.map +1 -1
- package/dist/component/public/security/keys.d.ts.map +1 -1
- package/dist/component/public/security/keys.js.map +1 -1
- package/dist/component/public/security/limits.d.ts.map +1 -1
- package/dist/component/public/security/limits.js.map +1 -1
- package/dist/component/schema.d.ts +39 -39
- package/dist/component/server/auth.d.ts +95 -52
- package/dist/component/server/auth.d.ts.map +1 -1
- package/dist/component/server/auth.js +63 -43
- package/dist/component/server/auth.js.map +1 -1
- package/dist/component/server/core.js +116 -235
- package/dist/component/server/core.js.map +1 -1
- package/dist/component/server/crypto.js +25 -7
- package/dist/component/server/crypto.js.map +1 -1
- package/dist/component/server/device.js +58 -15
- package/dist/component/server/device.js.map +1 -1
- package/dist/component/server/enterprise/domain.js +148 -59
- package/dist/component/server/enterprise/domain.js.map +1 -1
- package/dist/component/server/enterprise/http.js +36 -15
- package/dist/component/server/enterprise/http.js.map +1 -1
- package/dist/component/server/enterprise/oidc.js +1 -1
- package/dist/component/server/http.js +26 -21
- package/dist/component/server/http.js.map +1 -1
- package/dist/component/server/identity.js +5 -2
- package/dist/component/server/identity.js.map +1 -1
- package/dist/component/server/limits.js +21 -30
- package/dist/component/server/limits.js.map +1 -1
- package/dist/component/server/mutations/account.js +12 -10
- package/dist/component/server/mutations/account.js.map +1 -1
- package/dist/component/server/mutations/code.js +5 -2
- package/dist/component/server/mutations/code.js.map +1 -1
- package/dist/component/server/mutations/invalidate.js +1 -1
- package/dist/component/server/mutations/invalidate.js.map +1 -1
- package/dist/component/server/mutations/oauth.js +10 -4
- package/dist/component/server/mutations/oauth.js.map +1 -1
- package/dist/component/server/mutations/refresh.js +2 -2
- package/dist/component/server/mutations/refresh.js.map +1 -1
- package/dist/component/server/mutations/register.js +46 -42
- package/dist/component/server/mutations/register.js.map +1 -1
- package/dist/component/server/mutations/retrieve.js +21 -25
- package/dist/component/server/mutations/retrieve.js.map +1 -1
- package/dist/component/server/mutations/signature.js +10 -4
- package/dist/component/server/mutations/signature.js.map +1 -1
- package/dist/component/server/mutations/signout.js.map +1 -1
- package/dist/component/server/mutations/store.js +9 -24
- package/dist/component/server/mutations/store.js.map +1 -1
- package/dist/component/server/mutations/verifier.js.map +1 -1
- package/dist/component/server/mutations/verify.js +1 -1
- package/dist/component/server/mutations/verify.js.map +1 -1
- package/dist/component/server/oauth.js +53 -16
- package/dist/component/server/oauth.js.map +1 -1
- package/dist/component/server/passkey.js +115 -31
- package/dist/component/server/passkey.js.map +1 -1
- package/dist/component/server/redirects.js +9 -3
- package/dist/component/server/redirects.js.map +1 -1
- package/dist/component/server/refresh.js +10 -7
- package/dist/component/server/refresh.js.map +1 -1
- package/dist/component/server/runtime.d.ts +3 -3
- package/dist/component/server/runtime.d.ts.map +1 -1
- package/dist/component/server/runtime.js +62 -20
- package/dist/component/server/runtime.js.map +1 -1
- package/dist/component/server/signin.js +34 -10
- package/dist/component/server/signin.js.map +1 -1
- package/dist/component/server/totp.js +79 -19
- package/dist/component/server/totp.js.map +1 -1
- package/dist/component/server/types.d.ts +12 -20
- package/dist/component/server/types.d.ts.map +1 -1
- package/dist/component/server/types.js.map +1 -1
- package/dist/component/server/users.js +6 -3
- package/dist/component/server/users.js.map +1 -1
- package/dist/component/server/utils.js +10 -4
- package/dist/component/server/utils.js.map +1 -1
- package/dist/core/types.d.ts +14 -22
- package/dist/core/types.d.ts.map +1 -1
- package/dist/factors/device.js +8 -9
- package/dist/factors/device.js.map +1 -1
- package/dist/factors/passkey.js +18 -21
- package/dist/factors/passkey.js.map +1 -1
- package/dist/providers/password.js +66 -81
- package/dist/providers/password.js.map +1 -1
- package/dist/runtime/invite.js +2 -8
- package/dist/runtime/invite.js.map +1 -1
- package/dist/server/auth.d.ts +95 -52
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +63 -43
- package/dist/server/auth.js.map +1 -1
- package/dist/server/core.d.ts +71 -159
- package/dist/server/core.d.ts.map +1 -1
- package/dist/server/core.js +116 -235
- package/dist/server/core.js.map +1 -1
- package/dist/server/crypto.d.ts.map +1 -1
- package/dist/server/crypto.js +25 -7
- package/dist/server/crypto.js.map +1 -1
- package/dist/server/device.js +58 -15
- package/dist/server/device.js.map +1 -1
- package/dist/server/enterprise/domain.d.ts +0 -8
- package/dist/server/enterprise/domain.d.ts.map +1 -1
- package/dist/server/enterprise/domain.js +148 -59
- package/dist/server/enterprise/domain.js.map +1 -1
- package/dist/server/enterprise/http.d.ts.map +1 -1
- package/dist/server/enterprise/http.js +35 -14
- package/dist/server/enterprise/http.js.map +1 -1
- package/dist/server/http.d.ts +2 -2
- package/dist/server/http.d.ts.map +1 -1
- package/dist/server/http.js +25 -20
- package/dist/server/http.js.map +1 -1
- package/dist/server/identity.js +5 -2
- package/dist/server/identity.js.map +1 -1
- package/dist/server/index.d.ts +2 -2
- package/dist/server/limits.js +21 -30
- package/dist/server/limits.js.map +1 -1
- package/dist/server/mounts.d.ts +26 -64
- package/dist/server/mounts.d.ts.map +1 -1
- package/dist/server/mounts.js +45 -106
- package/dist/server/mounts.js.map +1 -1
- package/dist/server/mutations/account.d.ts +8 -9
- package/dist/server/mutations/account.d.ts.map +1 -1
- package/dist/server/mutations/account.js +11 -9
- package/dist/server/mutations/account.js.map +1 -1
- package/dist/server/mutations/code.d.ts +13 -13
- package/dist/server/mutations/code.d.ts.map +1 -1
- package/dist/server/mutations/code.js +5 -2
- package/dist/server/mutations/code.js.map +1 -1
- package/dist/server/mutations/invalidate.d.ts +4 -4
- package/dist/server/mutations/invalidate.d.ts.map +1 -1
- package/dist/server/mutations/invalidate.js.map +1 -1
- package/dist/server/mutations/oauth.d.ts +12 -10
- package/dist/server/mutations/oauth.d.ts.map +1 -1
- package/dist/server/mutations/oauth.js +9 -3
- package/dist/server/mutations/oauth.js.map +1 -1
- package/dist/server/mutations/refresh.d.ts +3 -3
- package/dist/server/mutations/refresh.d.ts.map +1 -1
- package/dist/server/mutations/refresh.js +1 -1
- package/dist/server/mutations/refresh.js.map +1 -1
- package/dist/server/mutations/register.d.ts +11 -11
- package/dist/server/mutations/register.d.ts.map +1 -1
- package/dist/server/mutations/register.js +45 -41
- package/dist/server/mutations/register.js.map +1 -1
- package/dist/server/mutations/retrieve.d.ts +6 -6
- package/dist/server/mutations/retrieve.d.ts.map +1 -1
- package/dist/server/mutations/retrieve.js +20 -24
- package/dist/server/mutations/retrieve.js.map +1 -1
- package/dist/server/mutations/signature.d.ts +6 -7
- package/dist/server/mutations/signature.d.ts.map +1 -1
- package/dist/server/mutations/signature.js +9 -3
- package/dist/server/mutations/signature.js.map +1 -1
- package/dist/server/mutations/signin.d.ts +5 -5
- package/dist/server/mutations/signin.d.ts.map +1 -1
- package/dist/server/mutations/signout.js.map +1 -1
- package/dist/server/mutations/store.d.ts +97 -97
- package/dist/server/mutations/store.d.ts.map +1 -1
- package/dist/server/mutations/store.js +8 -23
- package/dist/server/mutations/store.js.map +1 -1
- package/dist/server/mutations/verifier.js.map +1 -1
- package/dist/server/mutations/verify.d.ts +10 -10
- package/dist/server/mutations/verify.d.ts.map +1 -1
- package/dist/server/mutations/verify.js.map +1 -1
- package/dist/server/oauth.js +53 -16
- package/dist/server/oauth.js.map +1 -1
- package/dist/server/passkey.d.ts +2 -2
- package/dist/server/passkey.d.ts.map +1 -1
- package/dist/server/passkey.js +114 -30
- package/dist/server/passkey.js.map +1 -1
- package/dist/server/redirects.js +9 -3
- package/dist/server/redirects.js.map +1 -1
- package/dist/server/refresh.js +10 -7
- package/dist/server/refresh.js.map +1 -1
- package/dist/server/runtime.d.ts +14 -14
- package/dist/server/runtime.d.ts.map +1 -1
- package/dist/server/runtime.js +61 -19
- package/dist/server/runtime.js.map +1 -1
- package/dist/server/signin.js +34 -10
- package/dist/server/signin.js.map +1 -1
- package/dist/server/ssr.d.ts.map +1 -1
- package/dist/server/ssr.js +175 -184
- package/dist/server/ssr.js.map +1 -1
- package/dist/server/totp.js +78 -18
- package/dist/server/totp.js.map +1 -1
- package/dist/server/types.d.ts +13 -21
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/types.js.map +1 -1
- package/dist/server/users.js +6 -3
- package/dist/server/users.js.map +1 -1
- package/dist/server/utils.js +10 -4
- package/dist/server/utils.js.map +1 -1
- package/package.json +2 -6
- package/src/authorization/index.ts +1 -1
- package/src/cli/index.ts +1 -1
- package/src/client/core/types.ts +14 -14
- package/src/client/factors/device.ts +10 -12
- package/src/client/factors/passkey.ts +23 -26
- package/src/client/index.ts +54 -64
- package/src/client/runtime/invite.ts +5 -7
- package/src/component/index.ts +1 -0
- package/src/component/public/enterprise/audit.ts +6 -1
- package/src/component/public/enterprise/core.ts +1 -0
- package/src/component/public/enterprise/domains.ts +5 -1
- package/src/component/public/enterprise/scim.ts +1 -0
- package/src/component/public/enterprise/secrets.ts +1 -0
- package/src/component/public/enterprise/webhooks.ts +1 -0
- package/src/component/public/factors/devices.ts +1 -0
- package/src/component/public/factors/passkeys.ts +1 -0
- package/src/component/public/factors/totp.ts +1 -0
- package/src/component/public/groups/core.ts +1 -1
- package/src/component/public/groups/invites.ts +7 -1
- package/src/component/public/groups/members.ts +1 -0
- package/src/component/public/identity/accounts.ts +1 -0
- package/src/component/public/identity/codes.ts +1 -0
- package/src/component/public/identity/sessions.ts +1 -0
- package/src/component/public/identity/tokens.ts +1 -0
- package/src/component/public/identity/users.ts +1 -0
- package/src/component/public/identity/verifiers.ts +1 -0
- package/src/component/public/security/keys.ts +1 -0
- package/src/component/public/security/limits.ts +1 -0
- package/src/providers/password.ts +89 -110
- package/src/server/auth.ts +177 -111
- package/src/server/core.ts +197 -233
- package/src/server/crypto.ts +31 -29
- package/src/server/device.ts +65 -32
- package/src/server/enterprise/domain.ts +158 -170
- package/src/server/enterprise/http.ts +46 -39
- package/src/server/http.ts +36 -30
- package/src/server/identity.ts +5 -5
- package/src/server/index.ts +2 -0
- package/src/server/limits.ts +53 -80
- package/src/server/mounts.ts +47 -74
- package/src/server/mutations/account.ts +22 -36
- package/src/server/mutations/code.ts +6 -6
- package/src/server/mutations/invalidate.ts +1 -1
- package/src/server/mutations/oauth.ts +14 -8
- package/src/server/mutations/refresh.ts +5 -4
- package/src/server/mutations/register.ts +87 -132
- package/src/server/mutations/retrieve.ts +44 -44
- package/src/server/mutations/signature.ts +13 -6
- package/src/server/mutations/signout.ts +1 -1
- package/src/server/mutations/store.ts +16 -31
- package/src/server/mutations/verifier.ts +1 -1
- package/src/server/mutations/verify.ts +3 -5
- package/src/server/oauth.ts +60 -69
- package/src/server/passkey.ts +567 -517
- package/src/server/redirects.ts +10 -6
- package/src/server/refresh.ts +14 -18
- package/src/server/runtime.ts +70 -55
- package/src/server/signin.ts +44 -37
- package/src/server/ssr.ts +390 -407
- package/src/server/totp.ts +85 -35
- package/src/server/types.ts +19 -22
- package/src/server/users.ts +7 -6
- package/src/server/utils.ts +10 -12
- package/dist/component/server/authError.js +0 -34
- package/dist/component/server/authError.js.map +0 -1
- package/dist/component/server/errors.d.ts +0 -1
- package/dist/component/server/errors.js +0 -137
- package/dist/component/server/errors.js.map +0 -1
- package/dist/server/authError.d.ts +0 -46
- package/dist/server/authError.d.ts.map +0 -1
- package/dist/server/authError.js +0 -34
- package/dist/server/authError.js.map +0 -1
- package/dist/server/errors.d.ts +0 -177
- package/dist/server/errors.d.ts.map +0 -1
- package/dist/server/errors.js +0 -212
- package/dist/server/errors.js.map +0 -1
- package/src/server/authError.ts +0 -44
- package/src/server/errors.ts +0 -290
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* map where each role has an `id` (matching its key), an optional `label`,
|
|
12
12
|
* and a typed `grants` array. The returned object is fully type-safe:
|
|
13
13
|
* role IDs and grant strings are narrowed to their literal types, so
|
|
14
|
-
* `member.
|
|
14
|
+
* `member.inspect()` / `member.require()` and `member.create()` calls are checked at compile time.
|
|
15
15
|
* This is the canonical way to define role metadata for the auth library.
|
|
16
16
|
*
|
|
17
17
|
* @param roles - An object mapping role IDs to their configuration.
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* map where each role has an `id` (matching its key), an optional `label`,
|
|
12
12
|
* and a typed `grants` array. The returned object is fully type-safe:
|
|
13
13
|
* role IDs and grant strings are narrowed to their literal types, so
|
|
14
|
-
* `member.
|
|
14
|
+
* `member.inspect()` / `member.require()` and `member.create()` calls are checked at compile time.
|
|
15
15
|
* This is the canonical way to define role metadata for the auth library.
|
|
16
16
|
*
|
|
17
17
|
* @param roles - An object mapping role IDs to their configuration.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/authorization/index.ts"],"sourcesContent":["/**\n * Lightweight authorization helpers.\n *\n * @module\n */\n\n/**\n * Define typed role definitions for authorization.\n *\n * Transforms a declarative roles configuration object into a normalized\n * map where each role has an `id` (matching its key), an optional `label`,\n * and a typed `grants` array. The returned object is fully type-safe:\n * role IDs and grant strings are narrowed to their literal types, so\n * `member.
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/authorization/index.ts"],"sourcesContent":["/**\n * Lightweight authorization helpers.\n *\n * @module\n */\n\n/**\n * Define typed role definitions for authorization.\n *\n * Transforms a declarative roles configuration object into a normalized\n * map where each role has an `id` (matching its key), an optional `label`,\n * and a typed `grants` array. The returned object is fully type-safe:\n * role IDs and grant strings are narrowed to their literal types, so\n * `member.inspect()` / `member.require()` and `member.create()` calls are checked at compile time.\n * This is the canonical way to define role metadata for the auth library.\n *\n * @param roles - An object mapping role IDs to their configuration.\n * Each entry must include a `grants` array of permission strings and\n * may include an optional human-readable `label`.\n * @typeParam TRoles - The object literal shape of your role definitions.\n * @returns An object with the same keys as `roles`, where each value\n * is `{ id, label?, grants }` — `id` is the role key as a string,\n * and `grants` is a mutable array of the declared grant strings.\n *\n * @example\n * ```ts\n * import { defineRoles } from \"@robelest/convex-auth/authorization\";\n *\n * const roles = defineRoles({\n * admin: { label: \"Administrator\", grants: [\"issues:write\", \"members:manage\"] },\n * member: { label: \"Member\", grants: [\"issues:write\"] },\n * viewer: { grants: [\"issues:read\"] },\n * });\n *\n * // roles.admin.id === \"admin\"\n * // roles.admin.grants === [\"issues:write\", \"members:manage\"]\n *\n * // Pass to createAuth:\n * const auth = createAuth(components.auth, {\n * providers: [...],\n * authorization: { roles },\n * });\n * ```\n *\n * @example\n * ```ts\n * type RoleId = keyof typeof roles;\n * // RoleId = \"admin\" | \"member\" | \"viewer\"\n * ```\n *\n * @see {@link ConvexAuthConfig}\n */\nexport function defineRoles<\n const TRoles extends Record<\n string,\n { label?: string; grants: readonly string[] }\n >,\n>(\n roles: TRoles,\n): {\n [K in keyof TRoles]: {\n id: K & string;\n label?: TRoles[K][\"label\"];\n grants: Array<TRoles[K][\"grants\"][number] & string>;\n };\n} {\n return Object.fromEntries(\n Object.entries(roles).map(([id, role]) => [\n id,\n {\n id,\n ...(role.label ? { label: role.label } : {}),\n grants: [...role.grants],\n },\n ]),\n ) as {\n [K in keyof TRoles]: {\n id: K & string;\n label?: TRoles[K][\"label\"];\n grants: Array<TRoles[K][\"grants\"][number] & string>;\n };\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoDA,SAAgB,YAMd,OAOA;AACA,QAAO,OAAO,YACZ,OAAO,QAAQ,MAAM,CAAC,KAAK,CAAC,IAAI,UAAU,CACxC,IACA;EACE;EACA,GAAI,KAAK,QAAQ,EAAE,OAAO,KAAK,OAAO,GAAG,EAAE;EAC3C,QAAQ,CAAC,GAAG,KAAK,OAAO;EACzB,CACF,CAAC,CACH"}
|
package/dist/client/index.d.ts
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
import { AuthApiRefs } from "./core/types.js";
|
|
2
|
-
import { AUTH_ERRORS, AuthErrorCode, isAuthError, parseAuthError } from "../server/errors.js";
|
|
1
|
+
import { AuthApiRefs } from "./core/types.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/client/index.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/client/index.ts"],"mappings":";;;;AAgHA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAgB,MAAA,aACF,WAAA,8BAAyC,WAAA,CAAA,CACrD,OAAA,EAAS,aAAA,CAAc,GAAA,IAAO,UAAA,CAAW,GAAA"}
|
package/dist/client/index.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { AUTH_ERRORS, isAuthError, parseAuthError } from "../server/errors.js";
|
|
2
|
-
import { browserMutex, getStorageListenerRegistry } from "../runtime/browser.js";
|
|
3
1
|
import { createDeviceClient } from "../factors/device.js";
|
|
4
|
-
import {
|
|
2
|
+
import { browserMutex, getStorageListenerRegistry } from "../runtime/browser.js";
|
|
5
3
|
import { createPasskeyClient } from "../factors/passkey.js";
|
|
4
|
+
import { createTotpClient } from "../factors/totp.js";
|
|
5
|
+
import { createInviteManager } from "../runtime/invite.js";
|
|
6
6
|
import { createProxyHelpers, isRetriableProxyRefreshError, isTransientNetworkError } from "../runtime/proxy.js";
|
|
7
7
|
import { createStorageHelpers } from "../runtime/storage.js";
|
|
8
|
-
import { createTotpClient } from "../factors/totp.js";
|
|
9
8
|
import { Fx } from "@robelest/fx";
|
|
10
9
|
import { ConvexHttpClient } from "convex/browser";
|
|
11
10
|
import { ConvexError } from "convex/values";
|
|
@@ -142,10 +141,14 @@ function client(options) {
|
|
|
142
141
|
token
|
|
143
142
|
};
|
|
144
143
|
let handlingCodeFlow = false;
|
|
144
|
+
const HANDSHAKE_ERROR_MESSAGES = {
|
|
145
|
+
AUTH_HANDSHAKE_TIMEOUT: "Sign-in succeeded but authentication confirmation timed out.",
|
|
146
|
+
AUTH_HANDSHAKE_REJECTED: "Authentication was rejected while confirming the session."
|
|
147
|
+
};
|
|
145
148
|
const createHandshakeError = (code, context) => {
|
|
146
149
|
return new ConvexError({
|
|
147
150
|
code,
|
|
148
|
-
message:
|
|
151
|
+
message: HANDSHAKE_ERROR_MESSAGES[code],
|
|
149
152
|
...context
|
|
150
153
|
});
|
|
151
154
|
};
|
|
@@ -359,18 +362,15 @@ function client(options) {
|
|
|
359
362
|
})() : args ?? {};
|
|
360
363
|
const flow = typeof params.flow === "string" && params.flow.length > 0 ? params.flow : "signIn";
|
|
361
364
|
const handleSignInActionResult = async (result, options$1) => Fx.run(Fx.match(result, result.kind, {
|
|
362
|
-
redirect: (redirectResult) => Fx.
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
};
|
|
372
|
-
},
|
|
373
|
-
err: (e) => e
|
|
365
|
+
redirect: (redirectResult) => Fx.promise(async () => {
|
|
366
|
+
const redirectUrl = new URL(redirectResult.redirect);
|
|
367
|
+
if (options$1.persistVerifier) await storageSet(VERIFIER_STORAGE_KEY, redirectResult.verifier);
|
|
368
|
+
if (typeof window !== "undefined") window.location.href = redirectUrl.toString();
|
|
369
|
+
return {
|
|
370
|
+
kind: "redirect",
|
|
371
|
+
redirect: redirectUrl,
|
|
372
|
+
verifier: redirectResult.verifier
|
|
373
|
+
};
|
|
374
374
|
}),
|
|
375
375
|
totpRequired: (totpRequiredResult) => Fx.succeed({
|
|
376
376
|
kind: "totpRequired",
|
|
@@ -380,27 +380,24 @@ function client(options) {
|
|
|
380
380
|
kind: "deviceCode",
|
|
381
381
|
deviceCode: normalizeDeviceCodeResult(deviceCodeResult.deviceCode)
|
|
382
382
|
}),
|
|
383
|
-
signedIn: (signedInResult) => Fx.
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
}) ? { kind: "signedIn" } : { kind: "started" };
|
|
402
|
-
},
|
|
403
|
-
err: (e) => e
|
|
383
|
+
signedIn: (signedInResult) => Fx.promise(async () => {
|
|
384
|
+
return await setTokenAndMaybeWait(options$1.shouldStore ? {
|
|
385
|
+
shouldStore: true,
|
|
386
|
+
tokens: signedInResult.tokens,
|
|
387
|
+
waitForHandshake: true,
|
|
388
|
+
context: {
|
|
389
|
+
provider,
|
|
390
|
+
flow
|
|
391
|
+
}
|
|
392
|
+
} : {
|
|
393
|
+
shouldStore: false,
|
|
394
|
+
tokens: signedInResult.tokens === null ? null : { token: signedInResult.tokens.token },
|
|
395
|
+
waitForHandshake: true,
|
|
396
|
+
context: {
|
|
397
|
+
provider,
|
|
398
|
+
flow
|
|
399
|
+
}
|
|
400
|
+
}) ? { kind: "signedIn" } : { kind: "started" };
|
|
404
401
|
}),
|
|
405
402
|
started: (_startedResult) => Fx.succeed({ kind: "started" }),
|
|
406
403
|
passkeyOptions: (_passkeyOptionsResult) => Fx.succeed({ kind: "started" }),
|
|
@@ -649,5 +646,5 @@ function client(options) {
|
|
|
649
646
|
}
|
|
650
647
|
|
|
651
648
|
//#endregion
|
|
652
|
-
export {
|
|
649
|
+
export { client };
|
|
653
650
|
//# sourceMappingURL=index.js.map
|
package/dist/client/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["url","key","options"],"sources":["../../src/client/index.ts"],"sourcesContent":["import { Fx } from \"@robelest/fx\";\nimport { ConvexHttpClient } from \"convex/browser\";\nimport { ConvexError, Value } from \"convex/values\";\n\nimport { AUTH_ERRORS } from \"../server/errors\";\nimport { browserMutex, getStorageListenerRegistry } from \"./runtime/browser\";\nimport { createDeviceClient } from \"./factors/device\";\nimport { createInviteManager } from \"./runtime/invite\";\nimport { createPasskeyClient } from \"./factors/passkey\";\nimport {\n createProxyHelpers,\n isRetriableProxyRefreshError,\n isTransientNetworkError,\n} from \"./runtime/proxy\";\nimport { createStorageHelpers } from \"./runtime/storage\";\nimport { createTotpClient } from \"./factors/totp\";\nimport type {\n AuthApiRefs,\n AuthClient,\n AuthFlowContext,\n AuthHandshakeErrorCode,\n AuthSession,\n AuthState,\n ClientOptions,\n ConvexTransport,\n DeviceClient,\n DeviceCodeResult,\n HandshakeWaiter,\n PasskeyClient,\n PendingInvite,\n SignInActionResult,\n SignInResult,\n Storage,\n TotpClient,\n} from \"./core/types\";\n\n// Re-export error utilities so consumers can import from `@robelest/convex-auth/client`.\nexport {\n isAuthError,\n parseAuthError,\n AUTH_ERRORS,\n type AuthErrorCode,\n} from \"../server/errors\";\nexport type {\n AuthApiRefs,\n AuthClient,\n AuthState,\n ClientOptions,\n DeviceClient,\n DeviceCodeResult,\n PasskeyClient,\n PendingInvite,\n SignInResult,\n Storage,\n TotpClient,\n} from \"./core/types\";\n\nconst VERIFIER_STORAGE_KEY = \"__convexAuthOAuthVerifier\";\nconst JWT_STORAGE_KEY = \"__convexAuthJWT\";\nconst REFRESH_TOKEN_STORAGE_KEY = \"__convexAuthRefreshToken\";\nconst INVITE_TOKEN_KEY = \"__convexAuthPendingInvite\";\nconst INVITE_EMAIL_KEY = \"__convexAuthPendingInviteEmail\";\n\nconst RETRY_BASE_MS = 500;\nconst RETRY_MAX_RETRIES = 2;\nconst AUTH_HANDSHAKE_TIMEOUT_MS = 5000;\n\n/**\n * Resolve the Convex deployment URL from the client.\n *\n * `ConvexReactClient` exposes `.url` directly.\n * `ConvexClient` exposes `.client.url` via `BaseConvexClient`.\n */\nfunction resolveUrl(convex: ConvexTransport, explicit?: string): string {\n if (explicit) return explicit;\n const c = convex as any;\n const url: unknown = c.url ?? c.client?.url;\n if (typeof url === \"string\") return url;\n throw new Error(\n \"Could not determine Convex deployment URL. Pass `url` explicitly.\",\n );\n}\n\n/**\n * Create a framework-agnostic auth client.\n *\n * Returns an object with `signIn`, `signOut`, `onChange`, `state`,\n * `passkey`, and `totp` — everything needed for client-side auth.\n *\n * ### SPA mode (default)\n *\n * ```ts\n * import { ConvexClient } from 'convex/browser';\n * import { client } from '@robelest/convex-auth/client';\n * import { api } from '../convex/_generated/api';\n *\n * const convex = new ConvexClient(CONVEX_URL);\n * const auth = client({ convex, api: api.auth });\n * ```\n *\n * ### SSR / proxy mode\n *\n * ```ts\n * const auth = client({\n * convex,\n * proxyPath: '/api/auth',\n * tokenSeed: tokenFromServer, // JWT read from httpOnly cookie during SSR\n * });\n * ```\n *\n * In proxy mode all auth operations go through the proxy URL.\n * Tokens are stored in httpOnly cookies server-side — the client\n * holds the JWT in memory only.\n *\n * @param options - Client configuration. See {@link ClientOptions}.\n * @typeParam Api - An AuthApiRefs type determining which factor helpers are available.\n * @returns Auth client with conditional `passkey`, `totp`, and `device` helpers.\n * @throws {Error} When the Convex deployment URL cannot be determined and `url` is not passed explicitly.\n * @throws {Error} When `proxyPath` is not set and the `api` option is missing.\n */\nexport function client<\n Api extends AuthApiRefs<boolean, boolean, boolean> = AuthApiRefs,\n>(options: ClientOptions<Api>): AuthClient<Api> {\n const { convex, proxyPath, api: apiRefs } = options;\n const proxy = proxyPath;\n\n function requireApiRefs() {\n if (!apiRefs) {\n throw new Error(\n \"The `api` option is required when `proxyPath` is not set. \" +\n \"Pass { api: api.auth }.\",\n );\n }\n return apiRefs;\n }\n\n // In proxy mode, default storage to null (cookies handle persistence).\n const storage =\n options.storage !== undefined\n ? options.storage\n : proxy\n ? null\n : typeof window === \"undefined\"\n ? null\n : window.localStorage;\n\n const replaceUrl =\n options.replaceUrl ??\n ((url: string) => {\n if (typeof window !== \"undefined\") {\n window.history.replaceState({}, \"\", url);\n }\n });\n\n // ---------------------------------------------------------------------------\n // Location — SSR-safe URL reading\n // ---------------------------------------------------------------------------\n\n function getLocation(): URL | null {\n if (typeof options.location === \"function\") return options.location();\n if (options.location instanceof URL) return options.location;\n if (typeof window !== \"undefined\") return new URL(window.location.href);\n return null;\n }\n\n /**\n * SSR-safe URL parameter reader.\n *\n * Uses the `location` option if provided, otherwise falls back to\n * `window.location` (returns `null` during SSR where `window` is unavailable).\n *\n * @param name - The query parameter name.\n * @returns The parameter value, or `null` if not present or in SSR.\n *\n * @example\n * ```ts\n * const workspaceId = auth.param(\"workspace\");\n * const tab = auth.param(\"tab\") ?? \"issues\";\n * ```\n */\n function param(name: string): string | null {\n const loc = getLocation();\n return loc?.searchParams.get(name) ?? null;\n }\n\n function cleanUrlParams(params: string[]) {\n const loc = getLocation();\n if (!loc) return;\n const searchParams = new URLSearchParams(loc.search);\n let changed = false;\n for (const p of params) {\n if (searchParams.has(p)) {\n searchParams.delete(p);\n changed = true;\n }\n }\n if (changed) {\n const next = searchParams.toString()\n ? `${loc.pathname}?${searchParams}`\n : loc.pathname;\n void replaceUrl(next);\n }\n }\n\n const url = proxy ? undefined : resolveUrl(convex, options.url);\n const escapedNamespace = proxy\n ? proxy.replace(/[^a-zA-Z0-9]/g, \"\")\n : url!.replace(/[^a-zA-Z0-9]/g, \"\");\n const key = (name: string) => `${name}_${escapedNamespace}`;\n const {\n get: storageGet,\n set: storageSet,\n remove: storageRemove,\n } = createStorageHelpers({ storage, key });\n const { isAbsoluteUrl, proxyFetch, resolveProxyUrl } = createProxyHelpers({\n proxy,\n });\n const subscribers = new Set<() => void>();\n let disposeStorageListener: (() => void) | null = null;\n\n // Unauthenticated HTTP client for code verification & OAuth exchange.\n // Only needed in SPA mode — proxy mode routes everything through the proxy.\n const httpClient = proxy ? null : new ConvexHttpClient(url!);\n\n // ---------------------------------------------------------------------------\n // State\n // ---------------------------------------------------------------------------\n\n // If a server-provided token was supplied (SSR hydration), treat it as\n // immediately authenticated to avoid a handshake-only loading screen.\n const serverToken =\n typeof options.tokenSeed === \"string\" && options.tokenSeed.trim().length > 0\n ? options.tokenSeed\n : null;\n const hasServerToken = serverToken !== null;\n\n let token: string | null = serverToken;\n let isLoading = !hasServerToken;\n let authConfirmed = hasServerToken;\n let handshakePending = false;\n let authEpoch = 0;\n let destroyed = false;\n const handshakeWaiters = new Set<HandshakeWaiter>();\n let snapshot: AuthState = {\n phase: hasServerToken\n ? \"authenticated\"\n : isLoading\n ? \"loading\"\n : \"unauthenticated\",\n isLoading,\n isAuthenticated: hasServerToken,\n token,\n };\n let handlingCodeFlow = false;\n\n const createHandshakeError = (\n code: AuthHandshakeErrorCode,\n context: Record<string, unknown>,\n ) => {\n return new ConvexError({\n code,\n message: AUTH_ERRORS[code],\n ...context,\n } as Value);\n };\n\n const settleHandshakeWaiters = (\n epoch: number,\n outcome:\n | { type: \"resolve\" }\n | { type: \"reject\"; error: ConvexError<Value> },\n ) => {\n for (const waiter of Array.from(handshakeWaiters)) {\n if (waiter.epoch !== epoch) {\n continue;\n }\n clearTimeout(waiter.timeoutId);\n handshakeWaiters.delete(waiter);\n if (outcome.type === \"resolve\") {\n waiter.resolve();\n } else {\n waiter.reject(outcome.error);\n }\n }\n };\n\n const rejectObsoleteHandshakeWaiters = (activeEpoch: number) => {\n for (const waiter of Array.from(handshakeWaiters)) {\n if (waiter.epoch >= activeEpoch) {\n continue;\n }\n clearTimeout(waiter.timeoutId);\n handshakeWaiters.delete(waiter);\n waiter.reject(\n createHandshakeError(\"AUTH_HANDSHAKE_REJECTED\", {\n ...waiter.context,\n reason: \"token_changed\",\n }),\n );\n }\n };\n\n const waitForAuthHandshake = async (context: AuthFlowContext) => {\n if (token === null) {\n return;\n }\n if (authConfirmed && !handshakePending) {\n return;\n }\n if (!handshakePending) {\n throw createHandshakeError(\"AUTH_HANDSHAKE_REJECTED\", {\n ...context,\n reason: \"auth_rejected\",\n });\n }\n\n const epoch = authEpoch;\n await new Promise<void>((resolve, reject) => {\n const waiterRef: { current: HandshakeWaiter | null } = { current: null };\n const timeoutId = setTimeout(() => {\n if (waiterRef.current !== null) {\n handshakeWaiters.delete(waiterRef.current);\n }\n reject(\n createHandshakeError(\"AUTH_HANDSHAKE_TIMEOUT\", {\n ...context,\n timeoutMs: AUTH_HANDSHAKE_TIMEOUT_MS,\n }),\n );\n }, AUTH_HANDSHAKE_TIMEOUT_MS);\n\n const waiter: HandshakeWaiter = {\n epoch,\n context,\n resolve,\n reject,\n timeoutId,\n };\n waiterRef.current = waiter;\n handshakeWaiters.add(waiter);\n });\n };\n\n const handleConvexAuthChange = (isAuthenticated: boolean) => {\n if (destroyed) {\n return;\n }\n\n if (isAuthenticated) {\n authConfirmed = true;\n handshakePending = false;\n settleHandshakeWaiters(authEpoch, { type: \"resolve\" });\n } else {\n authConfirmed = false;\n // Do not reject immediately while a handshake is pending.\n // Convex can transiently emit `false` while reauth is still in flight,\n // and a subsequent `true` confirms the same session.\n }\n\n if (updateSnapshot()) {\n notify();\n }\n };\n\n const notify = () => {\n for (const cb of subscribers) cb();\n };\n\n const updateSnapshot = () => {\n const phaseDispatch = {\n tag:\n token !== null && handshakePending\n ? \"handshake\"\n : isLoading\n ? \"loading\"\n : token !== null && authConfirmed\n ? \"authenticated\"\n : \"unauthenticated\",\n } as const;\n\n const phase = {\n handshake: \"handshake\",\n loading: \"loading\",\n authenticated: \"authenticated\",\n unauthenticated: \"unauthenticated\",\n }[phaseDispatch.tag] as AuthState[\"phase\"];\n\n const next: AuthState = {\n phase,\n isLoading: phase === \"loading\" || phase === \"handshake\",\n isAuthenticated: phase === \"authenticated\",\n token,\n };\n if (\n snapshot.phase === next.phase &&\n snapshot.isLoading === next.isLoading &&\n snapshot.isAuthenticated === next.isAuthenticated &&\n snapshot.token === next.token\n ) {\n return false;\n }\n snapshot = next;\n return true;\n };\n\n const finalizeLoadingState = () => {\n if (!isLoading) {\n return;\n }\n isLoading = false;\n if (updateSnapshot()) {\n notify();\n }\n };\n\n const inviteManager = createInviteManager({\n param,\n storageGet,\n storageSet,\n storageRemove,\n cleanUrlParams,\n tokenKey: INVITE_TOKEN_KEY,\n emailKey: INVITE_EMAIL_KEY,\n });\n const getPendingInvite = () => inviteManager.getPendingInvite();\n const persistInvite = () => inviteManager.persistInvite();\n const acceptInvite = () => inviteManager.acceptInvite();\n\n // ---------------------------------------------------------------------------\n // Token management\n // ---------------------------------------------------------------------------\n\n const bindConvexAuth = () => {\n convex.setAuth(fetchAccessToken, handleConvexAuthChange);\n };\n\n const setToken = async (\n args:\n | {\n shouldStore: true;\n tokens: AuthSession | null;\n requireHandshake?: boolean;\n resyncConvexAuth?: boolean;\n }\n | {\n shouldStore: false;\n tokens: { token: string } | null;\n requireHandshake?: boolean;\n resyncConvexAuth?: boolean;\n },\n ) => {\n const previousToken = token;\n\n if (args.tokens === null) {\n token = null;\n if (args.shouldStore) {\n await storageRemove(JWT_STORAGE_KEY);\n await storageRemove(REFRESH_TOKEN_STORAGE_KEY);\n }\n } else {\n token = args.tokens.token;\n if (args.shouldStore && \"refreshToken\" in args.tokens) {\n await storageSet(JWT_STORAGE_KEY, args.tokens.token);\n await storageSet(REFRESH_TOKEN_STORAGE_KEY, args.tokens.refreshToken);\n }\n }\n\n if (token !== previousToken) {\n authEpoch += 1;\n rejectObsoleteHandshakeWaiters(authEpoch);\n }\n\n if (token === null) {\n authConfirmed = false;\n handshakePending = false;\n settleHandshakeWaiters(authEpoch, {\n type: \"reject\",\n error: createHandshakeError(\"AUTH_HANDSHAKE_REJECTED\", {\n reason: \"token_cleared\",\n }),\n });\n } else {\n const shouldEnterHandshake =\n args.requireHandshake === true || !authConfirmed;\n if (shouldEnterHandshake) {\n authConfirmed = false;\n handshakePending = true;\n } else {\n handshakePending = false;\n }\n }\n\n const hadPendingLoad = isLoading;\n isLoading = false;\n const changed = updateSnapshot();\n if (args.resyncConvexAuth !== false) {\n bindConvexAuth();\n }\n if (hadPendingLoad || changed) {\n notify();\n }\n };\n\n const setTokenAndMaybeWait = async (\n args:\n | {\n shouldStore: true;\n tokens: AuthSession | null;\n waitForHandshake: boolean;\n context: AuthFlowContext;\n }\n | {\n shouldStore: false;\n tokens: { token: string } | null;\n waitForHandshake: boolean;\n context: AuthFlowContext;\n },\n ): Promise<boolean> => {\n const { waitForHandshake, context, ...tokenArgs } = args;\n await setToken({\n ...(tokenArgs as\n | { shouldStore: true; tokens: AuthSession | null }\n | { shouldStore: false; tokens: { token: string } | null }),\n requireHandshake: waitForHandshake,\n });\n if (tokenArgs.tokens === null) {\n return false;\n }\n if (waitForHandshake) {\n await waitForAuthHandshake(context);\n }\n return true;\n };\n\n // ---------------------------------------------------------------------------\n // Code verification with retries (SPA mode only)\n // ---------------------------------------------------------------------------\n\n const verifyCode = async (\n args: { code: string; verifier?: string } | { refreshToken: string },\n ) => {\n const verifyCodeRetryPolicy = Fx.retry.while(\n Fx.retry.compose(\n Fx.retry.jittered(Fx.retry.exponential(RETRY_BASE_MS)),\n Fx.retry.recurs(RETRY_MAX_RETRIES),\n ),\n (meta) => isTransientNetworkError(meta.input),\n );\n\n return Fx.run(\n Fx.from({\n ok: () =>\n httpClient!.action(\n requireApiRefs().signIn,\n \"code\" in args\n ? { params: { code: args.code }, verifier: args.verifier }\n : args,\n ),\n err: (e) => e,\n }).pipe(\n Fx.retry(verifyCodeRetryPolicy),\n Fx.recover((e) => Fx.fatal(e)),\n ),\n );\n };\n\n const verifyCodeAndSetToken = async (\n args: { code: string; verifier?: string } | { refreshToken: string },\n opts?: { resyncConvexAuth?: boolean },\n ) => {\n const { tokens } = await verifyCode(args);\n await setToken({\n shouldStore: true,\n tokens: (tokens as AuthSession | null) ?? null,\n resyncConvexAuth: opts?.resyncConvexAuth,\n });\n return tokens !== null;\n };\n\n const normalizeDeviceCodeResult = (device_code: any): DeviceCodeResult => {\n return {\n deviceCode: device_code.deviceCode,\n userCode: device_code.userCode,\n verificationUri:\n device_code.verification_uri ?? device_code.verificationUri,\n verificationUriComplete:\n device_code.verification_uri_complete ??\n device_code.verificationUriComplete,\n expiresIn: device_code.expiresIn,\n interval: device_code.interval,\n };\n };\n\n // ---------------------------------------------------------------------------\n // signIn\n // ---------------------------------------------------------------------------\n\n /**\n * Sign in with a provider.\n *\n * @param provider - Provider ID (e.g. `\"email\"`, `\"password\"`, `\"google\"`).\n * Omit when exchanging an OAuth code (the code carries the provider info).\n * @param args - Provider-specific arguments. Pass a `Record<string, Value>`\n * or `FormData`. Common fields: `email`, `password`, `code`, `redirectTo`.\n * @returns A {@link SignInResult} indicating the outcome.\n * @throws {ConvexError} When the server action rejects the sign-in attempt (e.g. invalid credentials, provider error, or rate limiting).\n *\n * @example Email magic link\n * ```ts\n * await auth.signIn('email', { email: 'user@example.com' });\n * ```\n *\n * @example Password\n * ```ts\n * const result = await auth.signIn('password', { email, password, flow: 'signIn' });\n * if (result.kind === 'totpRequired') {\n * await auth.totp.verify({ code: totpCode, verifier: result.verifier });\n * }\n * ```\n *\n * @example OAuth (triggers redirect)\n * ```ts\n * await auth.signIn('google'); // redirects to Google\n * ```\n */\n const signIn = async (\n provider?: string,\n args?: FormData | Record<string, Value>,\n ): Promise<SignInResult> => {\n // Persist invite before potential OAuth redirect\n await persistInvite();\n\n const params =\n args instanceof FormData\n ? (() => {\n const formParams: Record<string, Value> = {};\n args.forEach((value, key) => {\n formParams[key] = typeof value === \"string\" ? value : value.name;\n });\n return formParams;\n })()\n : (args ?? {});\n const flow =\n typeof params.flow === \"string\" && params.flow.length > 0\n ? params.flow\n : \"signIn\";\n\n const handleSignInActionResult = async (\n result: SignInActionResult,\n options: { shouldStore: boolean; persistVerifier: boolean },\n ): Promise<SignInResult> =>\n Fx.run(\n Fx.match(result, result.kind, {\n redirect: (redirectResult) =>\n Fx.from({\n ok: async () => {\n const redirectUrl = new URL(redirectResult.redirect);\n if (options.persistVerifier) {\n await storageSet(\n VERIFIER_STORAGE_KEY,\n redirectResult.verifier,\n );\n }\n if (typeof window !== \"undefined\") {\n window.location.href = redirectUrl.toString();\n }\n return {\n kind: \"redirect\" as const,\n redirect: redirectUrl,\n verifier: redirectResult.verifier,\n };\n },\n err: (e) => e as never,\n }),\n totpRequired: (totpRequiredResult) =>\n Fx.succeed({\n kind: \"totpRequired\" as const,\n verifier: totpRequiredResult.verifier,\n }),\n deviceCode: (deviceCodeResult) =>\n Fx.succeed({\n kind: \"deviceCode\" as const,\n deviceCode: normalizeDeviceCodeResult(\n deviceCodeResult.deviceCode,\n ),\n }),\n signedIn: (signedInResult) =>\n Fx.from({\n ok: async () => {\n const signingIn = await setTokenAndMaybeWait(\n options.shouldStore\n ? {\n shouldStore: true as const,\n tokens: signedInResult.tokens,\n waitForHandshake: true,\n context: { provider, flow },\n }\n : {\n shouldStore: false as const,\n tokens:\n signedInResult.tokens === null\n ? null\n : { token: signedInResult.tokens.token },\n waitForHandshake: true,\n context: { provider, flow },\n },\n );\n return signingIn\n ? ({ kind: \"signedIn\" as const } as SignInResult)\n : ({ kind: \"started\" as const } as SignInResult);\n },\n err: (e) => e as never,\n }),\n started: (_startedResult) => Fx.succeed({ kind: \"started\" as const }),\n passkeyOptions: (_passkeyOptionsResult) =>\n Fx.succeed({ kind: \"started\" as const }),\n totpSetup: (_totpSetupResult) =>\n Fx.succeed({ kind: \"started\" as const }),\n }),\n );\n\n if (proxy) {\n const result = (await proxyFetch({\n action: \"auth:signIn\",\n args: { provider, params },\n })) as SignInActionResult;\n return handleSignInActionResult(result, {\n shouldStore: false,\n persistVerifier: false,\n });\n }\n\n // SPA mode: call Convex directly.\n const verifier = (await storageGet(VERIFIER_STORAGE_KEY)) ?? undefined;\n await storageRemove(VERIFIER_STORAGE_KEY);\n const result = (await convex.action(requireApiRefs().signIn, {\n provider,\n params,\n verifier,\n })) as SignInActionResult;\n return handleSignInActionResult(result, {\n shouldStore: true,\n persistVerifier: true,\n });\n };\n\n // ---------------------------------------------------------------------------\n // signOut\n // ---------------------------------------------------------------------------\n\n /**\n * Sign out the current user.\n *\n * Invalidates the server session and clears local token state.\n * Errors are silently caught — calling `signOut` on an already\n * signed-out user is a no-op.\n */\n const signOut = async () => {\n if (proxy) {\n await Fx.run(\n Fx.from({\n ok: () => proxyFetch({ action: \"auth:signOut\", args: {} }),\n err: () => undefined,\n }).pipe(Fx.recover(() => Fx.succeed(undefined))),\n );\n await setToken({ shouldStore: false, tokens: null });\n if (convex.clearAuth) convex.clearAuth();\n return;\n }\n\n // SPA mode.\n await Fx.run(\n Fx.from({\n ok: () => convex.action(requireApiRefs().signOut, {}),\n err: () => undefined,\n }).pipe(Fx.recover(() => Fx.succeed(undefined))),\n );\n await setToken({ shouldStore: true, tokens: null });\n if (convex.clearAuth) convex.clearAuth();\n };\n\n // ---------------------------------------------------------------------------\n // fetchAccessToken — called by convex.setAuth()\n // ---------------------------------------------------------------------------\n\n const fetchAccessToken = async ({\n forceRefreshToken,\n }: {\n forceRefreshToken: boolean;\n }): Promise<string | null> => {\n if (!forceRefreshToken) return token;\n\n if (proxy) {\n // Proxy mode: POST to the proxy to refresh.\n // The proxy reads the real refresh token from the httpOnly cookie.\n const resolvedProxyUrl = await resolveProxyUrl();\n if (\n typeof window === \"undefined\" &&\n !(await isAbsoluteUrl(resolvedProxyUrl))\n ) {\n finalizeLoadingState();\n return token;\n }\n\n const tokenBeforeRefresh = token;\n return await browserMutex(\"__convexAuthProxyRefresh\", async () => {\n // Another tab/call may have already refreshed.\n if (token !== tokenBeforeRefresh) return token;\n\n const proxyRefreshRetryPolicy = Fx.retry.while(\n Fx.retry.compose(\n Fx.retry.jittered(Fx.retry.exponential(RETRY_BASE_MS)),\n Fx.retry.recurs(RETRY_MAX_RETRIES),\n ),\n (meta) => isRetriableProxyRefreshError(meta.input),\n );\n\n await Fx.run(\n Fx.from({\n ok: () =>\n proxyFetch({\n action: \"auth:signIn\",\n args: { refreshToken: true },\n }),\n err: (e) => e,\n }).pipe(\n Fx.retry(proxyRefreshRetryPolicy),\n Fx.chain((result: any) =>\n Fx.from({\n ok: async () => {\n if (result.tokens) {\n await setToken({\n shouldStore: false,\n tokens: { token: result.tokens.token },\n resyncConvexAuth: false,\n });\n } else {\n await setToken({\n shouldStore: false,\n tokens: null,\n resyncConvexAuth: false,\n });\n }\n },\n err: (e) => e,\n }),\n ),\n Fx.inspect((error) =>\n Fx.sync(() =>\n console.error(\"[convex-auth] Proxy refresh failed:\", error),\n ),\n ),\n Fx.recover(() => {\n if (token === null) {\n finalizeLoadingState();\n }\n return Fx.succeed(undefined);\n }),\n ),\n );\n return token;\n });\n }\n\n // SPA mode: refresh via localStorage + httpClient.\n const tokenBeforeLockAcquisition = token;\n return await browserMutex(REFRESH_TOKEN_STORAGE_KEY, async () => {\n const tokenAfterLockAcquisition = token;\n if (tokenAfterLockAcquisition !== tokenBeforeLockAcquisition) {\n return tokenAfterLockAcquisition;\n }\n const refreshToken =\n (await storageGet(REFRESH_TOKEN_STORAGE_KEY)) ?? null;\n if (!refreshToken) {\n finalizeLoadingState();\n return null;\n }\n await verifyCodeAndSetToken(\n { refreshToken },\n { resyncConvexAuth: false },\n );\n return token;\n });\n };\n\n // ---------------------------------------------------------------------------\n // OAuth code flow (SPA mode only — server handles this in proxy mode)\n // ---------------------------------------------------------------------------\n\n const handleCodeFlow = async () => {\n if (typeof window === \"undefined\") return;\n if (handlingCodeFlow) return;\n const code = new URLSearchParams(window.location.search).get(\"code\");\n if (!code) return;\n handlingCodeFlow = true;\n await Fx.run(\n Fx.from({\n ok: async () => {\n await signIn(undefined, { code });\n const codeUrl = new URL(window.location.href);\n codeUrl.searchParams.delete(\"code\");\n await replaceUrl(codeUrl.pathname + codeUrl.search + codeUrl.hash);\n },\n err: (e) => e,\n }).pipe(\n Fx.recover(() => Fx.succeed(undefined)),\n Fx.tap(() =>\n Fx.sync(() => {\n handlingCodeFlow = false;\n }),\n ),\n Fx.inspect(() =>\n Fx.sync(() => {\n handlingCodeFlow = false;\n }),\n ),\n ),\n );\n // The flag is always reset — Fx.recover above ensures success path,\n // but reset defensively here too.\n handlingCodeFlow = false;\n };\n\n // ---------------------------------------------------------------------------\n // Hydrate from storage (SPA mode only)\n // ---------------------------------------------------------------------------\n\n const hydrateFromStorage = async () => {\n const storedToken = (await storageGet(JWT_STORAGE_KEY)) ?? null;\n await setToken({\n shouldStore: false,\n tokens: storedToken === null ? null : { token: storedToken },\n });\n };\n\n // ---------------------------------------------------------------------------\n // Subscribe\n // ---------------------------------------------------------------------------\n\n /**\n * Subscribe to auth state changes. Invokes the callback immediately\n * with the current state, then again on every state transition.\n *\n * ```ts\n * const unsub = auth.onChange(setState);\n * ```\n *\n * @param cb - Callback receiving the latest {@link AuthState}.\n * @returns An unsubscribe function.\n */\n const onChange = (cb: (state: AuthState) => void): (() => void) => {\n cb(snapshot);\n const wrapped = () => cb(snapshot);\n subscribers.add(wrapped);\n return () => {\n subscribers.delete(wrapped);\n };\n };\n\n // ---------------------------------------------------------------------------\n // Initialization\n // ---------------------------------------------------------------------------\n\n // Cross-tab sync via storage events (SPA mode only).\n if (!proxy && typeof window !== \"undefined\") {\n const registryKey = key(JWT_STORAGE_KEY);\n const registry = getStorageListenerRegistry();\n const existingListener = registry[registryKey];\n if (existingListener !== undefined) {\n window.removeEventListener(\"storage\", existingListener);\n }\n\n const onStorage = (event: StorageEvent) => {\n Fx.detach(async () => {\n if (event.key !== key(JWT_STORAGE_KEY)) return;\n await setToken({\n shouldStore: false,\n tokens: event.newValue === null ? null : { token: event.newValue },\n });\n }, \"[convex-auth] Storage event handler failed:\");\n };\n window.addEventListener(\"storage\", onStorage);\n registry[registryKey] = onStorage;\n disposeStorageListener = () => {\n if (registry[registryKey] === onStorage) {\n delete registry[registryKey];\n }\n window.removeEventListener(\"storage\", onStorage);\n };\n }\n\n // Auto-wire: feed our tokens into the Convex client so\n // queries and mutations are automatically authenticated.\n bindConvexAuth();\n\n // Auto-hydrate and handle code flow.\n if (typeof window !== \"undefined\") {\n if (proxy) {\n // Proxy mode: eagerly resolve auth once on startup so routes that only\n // read auth state (and do not issue Convex queries yet) don't stay in\n // the initial loading phase.\n if (!hasServerToken) {\n Fx.detach(\n () => fetchAccessToken({ forceRefreshToken: true }),\n \"[convex-auth] Proxy token refresh failed:\",\n );\n }\n } else {\n // SPA mode: hydrate from localStorage, then handle OAuth code flow.\n Fx.detach(async () => {\n await Fx.run(\n Fx.from({\n ok: async () => {\n await hydrateFromStorage();\n await handleCodeFlow();\n },\n err: (e) => e,\n }).pipe(\n Fx.inspect((error) =>\n Fx.sync(() =>\n console.error(\n \"[convex-auth] Client initialization failed:\",\n error,\n ),\n ),\n ),\n Fx.recover((_error) =>\n Fx.from({\n ok: () => setToken({ shouldStore: false, tokens: null }),\n err: (e) => e,\n }).pipe(Fx.recover(() => Fx.succeed(undefined))),\n ),\n ),\n );\n }, \"[convex-auth] SPA initialization failed:\");\n }\n }\n\n // ---------------------------------------------------------------------------\n // Auth factor helpers\n // ---------------------------------------------------------------------------\n\n const passkey = createPasskeyClient({\n proxy,\n convex,\n requireApiRefs,\n proxyFetch,\n setTokenAndMaybeWait,\n });\n\n const totp = createTotpClient({\n proxy,\n convex,\n requireApiRefs,\n proxyFetch,\n setTokenAndMaybeWait,\n });\n\n const device = createDeviceClient({\n proxy,\n convex,\n requireApiRefs,\n proxyFetch,\n setTokenAndMaybeWait,\n });\n\n return {\n /** Current auth state snapshot. */\n get state(): AuthState {\n return snapshot;\n },\n /** SSR-safe URL param reader. */\n param,\n /** Pending invite from URL or recovered from storage. Null if none. */\n get invite(): PendingInvite | null {\n const pendingInvite = getPendingInvite();\n if (!pendingInvite) return null;\n return {\n token: pendingInvite.token,\n email: pendingInvite.email,\n accept: acceptInvite,\n };\n },\n /** Sign in with a provider. See {@link SignInResult} for return shape. */\n signIn,\n /** Sign out and clear all token state. */\n signOut,\n /** Subscribe to auth state changes. Returns an unsubscribe function. */\n onChange,\n /** Passkey (WebAuthn) authentication helpers. */\n passkey,\n /** TOTP two-factor authentication helpers. */\n totp,\n /** Device authorization (RFC 8628) helpers. */\n device,\n /**\n * Tear down this auth client instance.\n *\n * Removes the cross-tab `storage` event listener, clears all\n * `onChange` subscribers, and rejects any in-flight handshake\n * waiters. Call this when the client is no longer needed\n * (e.g. on SPA unmount or hot-module replacement) to prevent\n * memory leaks and stale callbacks.\n *\n * @example\n * ```ts\n * // SvelteKit onDestroy\n * import { onDestroy } from \"svelte\";\n * const auth = client({ convex, api: api.auth });\n * onDestroy(() => auth.destroy());\n * ```\n *\n * @example\n * ```ts\n * const unsubscribe = auth.onChange((state) => console.log(state.phase));\n *\n * // Later, during cleanup:\n * unsubscribe();\n * auth.destroy();\n * ```\n */\n destroy: () => {\n destroyed = true;\n settleHandshakeWaiters(authEpoch, {\n type: \"reject\",\n error: createHandshakeError(\"AUTH_HANDSHAKE_REJECTED\", {\n reason: \"destroyed\",\n }),\n });\n disposeStorageListener?.();\n subscribers.clear();\n },\n } as AuthClient<Api>;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["url","key","options"],"sources":["../../src/client/index.ts"],"sourcesContent":["import { Fx } from \"@robelest/fx\";\nimport { ConvexHttpClient } from \"convex/browser\";\nimport { ConvexError, Value } from \"convex/values\";\n\nimport type {\n AuthApiRefs,\n AuthClient,\n AuthFlowContext,\n AuthHandshakeErrorCode,\n AuthSession,\n AuthState,\n ClientOptions,\n ConvexTransport,\n DeviceClient,\n DeviceCodeResult,\n HandshakeWaiter,\n PasskeyClient,\n PendingInvite,\n SignInActionResult,\n SignInResult,\n Storage,\n TotpClient,\n} from \"./core/types\";\nimport { createDeviceClient } from \"./factors/device\";\nimport { createPasskeyClient } from \"./factors/passkey\";\nimport { createTotpClient } from \"./factors/totp\";\nimport { browserMutex, getStorageListenerRegistry } from \"./runtime/browser\";\nimport { createInviteManager } from \"./runtime/invite\";\nimport {\n createProxyHelpers,\n isRetriableProxyRefreshError,\n isTransientNetworkError,\n} from \"./runtime/proxy\";\nimport { createStorageHelpers } from \"./runtime/storage\";\n\nexport type {\n AuthApiRefs,\n AuthClient,\n AuthState,\n ClientOptions,\n DeviceClient,\n DeviceCodeResult,\n PasskeyClient,\n PendingInvite,\n SignInResult,\n Storage,\n TotpClient,\n} from \"./core/types\";\n\nconst VERIFIER_STORAGE_KEY = \"__convexAuthOAuthVerifier\";\nconst JWT_STORAGE_KEY = \"__convexAuthJWT\";\nconst REFRESH_TOKEN_STORAGE_KEY = \"__convexAuthRefreshToken\";\nconst INVITE_TOKEN_KEY = \"__convexAuthPendingInvite\";\nconst INVITE_EMAIL_KEY = \"__convexAuthPendingInviteEmail\";\n\nconst RETRY_BASE_MS = 500;\nconst RETRY_MAX_RETRIES = 2;\nconst AUTH_HANDSHAKE_TIMEOUT_MS = 5000;\n\n/**\n * Resolve the Convex deployment URL from the client.\n *\n * `ConvexReactClient` exposes `.url` directly.\n * `ConvexClient` exposes `.client.url` via `BaseConvexClient`.\n */\nfunction resolveUrl(convex: ConvexTransport, explicit?: string): string {\n if (explicit) return explicit;\n const c = convex as any;\n const url: unknown = c.url ?? c.client?.url;\n if (typeof url === \"string\") return url;\n throw new Error(\n \"Could not determine Convex deployment URL. Pass `url` explicitly.\",\n );\n}\n\n/**\n * Create a framework-agnostic auth client.\n *\n * Returns an object with `signIn`, `signOut`, `onChange`, `state`,\n * `passkey`, and `totp` — everything needed for client-side auth.\n *\n * ### SPA mode (default)\n *\n * ```ts\n * import { ConvexClient } from 'convex/browser';\n * import { client } from '@robelest/convex-auth/client';\n * import { api } from '../convex/_generated/api';\n *\n * const convex = new ConvexClient(CONVEX_URL);\n * const auth = client({ convex, api: api.auth });\n * ```\n *\n * ### SSR / proxy mode\n *\n * ```ts\n * const auth = client({\n * convex,\n * proxyPath: '/api/auth',\n * tokenSeed: tokenFromServer, // JWT read from httpOnly cookie during SSR\n * });\n * ```\n *\n * In proxy mode all auth operations go through the proxy URL.\n * Tokens are stored in httpOnly cookies server-side — the client\n * holds the JWT in memory only.\n *\n * @param options - Client configuration. See {@link ClientOptions}.\n * @typeParam Api - An AuthApiRefs type determining which factor helpers are available.\n * @returns Auth client with conditional `passkey`, `totp`, and `device` helpers.\n * @throws {Error} When the Convex deployment URL cannot be determined and `url` is not passed explicitly.\n * @throws {Error} When `proxyPath` is not set and the `api` option is missing.\n */\nexport function client<\n Api extends AuthApiRefs<boolean, boolean, boolean> = AuthApiRefs,\n>(options: ClientOptions<Api>): AuthClient<Api> {\n const { convex, proxyPath, api: apiRefs } = options;\n const proxy = proxyPath;\n\n function requireApiRefs() {\n if (!apiRefs) {\n throw new Error(\n \"The `api` option is required when `proxyPath` is not set. \" +\n \"Pass { api: api.auth }.\",\n );\n }\n return apiRefs;\n }\n\n // In proxy mode, default storage to null (cookies handle persistence).\n const storage =\n options.storage !== undefined\n ? options.storage\n : proxy\n ? null\n : typeof window === \"undefined\"\n ? null\n : window.localStorage;\n\n const replaceUrl =\n options.replaceUrl ??\n ((url: string) => {\n if (typeof window !== \"undefined\") {\n window.history.replaceState({}, \"\", url);\n }\n });\n\n // ---------------------------------------------------------------------------\n // Location — SSR-safe URL reading\n // ---------------------------------------------------------------------------\n\n function getLocation(): URL | null {\n if (typeof options.location === \"function\") return options.location();\n if (options.location instanceof URL) return options.location;\n if (typeof window !== \"undefined\") return new URL(window.location.href);\n return null;\n }\n\n /**\n * SSR-safe URL parameter reader.\n *\n * Uses the `location` option if provided, otherwise falls back to\n * `window.location` (returns `null` during SSR where `window` is unavailable).\n *\n * @param name - The query parameter name.\n * @returns The parameter value, or `null` if not present or in SSR.\n *\n * @example\n * ```ts\n * const workspaceId = auth.param(\"workspace\");\n * const tab = auth.param(\"tab\") ?? \"issues\";\n * ```\n */\n function param(name: string): string | null {\n const loc = getLocation();\n return loc?.searchParams.get(name) ?? null;\n }\n\n function cleanUrlParams(params: string[]) {\n const loc = getLocation();\n if (!loc) return;\n const searchParams = new URLSearchParams(loc.search);\n let changed = false;\n for (const p of params) {\n if (searchParams.has(p)) {\n searchParams.delete(p);\n changed = true;\n }\n }\n if (changed) {\n const next = searchParams.toString()\n ? `${loc.pathname}?${searchParams}`\n : loc.pathname;\n void replaceUrl(next);\n }\n }\n\n const url = proxy ? undefined : resolveUrl(convex, options.url);\n const escapedNamespace = proxy\n ? proxy.replace(/[^a-zA-Z0-9]/g, \"\")\n : url!.replace(/[^a-zA-Z0-9]/g, \"\");\n const key = (name: string) => `${name}_${escapedNamespace}`;\n const {\n get: storageGet,\n set: storageSet,\n remove: storageRemove,\n } = createStorageHelpers({ storage, key });\n const { isAbsoluteUrl, proxyFetch, resolveProxyUrl } = createProxyHelpers({\n proxy,\n });\n const subscribers = new Set<() => void>();\n let disposeStorageListener: (() => void) | null = null;\n\n // Unauthenticated HTTP client for code verification & OAuth exchange.\n // Only needed in SPA mode — proxy mode routes everything through the proxy.\n const httpClient = proxy ? null : new ConvexHttpClient(url!);\n\n // ---------------------------------------------------------------------------\n // State\n // ---------------------------------------------------------------------------\n\n // If a server-provided token was supplied (SSR hydration), treat it as\n // immediately authenticated to avoid a handshake-only loading screen.\n const serverToken =\n typeof options.tokenSeed === \"string\" && options.tokenSeed.trim().length > 0\n ? options.tokenSeed\n : null;\n const hasServerToken = serverToken !== null;\n\n let token: string | null = serverToken;\n let isLoading = !hasServerToken;\n let authConfirmed = hasServerToken;\n let handshakePending = false;\n let authEpoch = 0;\n let destroyed = false;\n const handshakeWaiters = new Set<HandshakeWaiter>();\n let snapshot: AuthState = {\n phase: hasServerToken\n ? \"authenticated\"\n : isLoading\n ? \"loading\"\n : \"unauthenticated\",\n isLoading,\n isAuthenticated: hasServerToken,\n token,\n };\n let handlingCodeFlow = false;\n\n const HANDSHAKE_ERROR_MESSAGES: Record<AuthHandshakeErrorCode, string> = {\n AUTH_HANDSHAKE_TIMEOUT:\n \"Sign-in succeeded but authentication confirmation timed out.\",\n AUTH_HANDSHAKE_REJECTED:\n \"Authentication was rejected while confirming the session.\",\n };\n\n const createHandshakeError = (\n code: AuthHandshakeErrorCode,\n context: Record<string, unknown>,\n ) => {\n return new ConvexError({\n code,\n message: HANDSHAKE_ERROR_MESSAGES[code],\n ...context,\n } as Value);\n };\n\n const settleHandshakeWaiters = (\n epoch: number,\n outcome:\n | { type: \"resolve\" }\n | { type: \"reject\"; error: ConvexError<Value> },\n ) => {\n for (const waiter of Array.from(handshakeWaiters)) {\n if (waiter.epoch !== epoch) {\n continue;\n }\n clearTimeout(waiter.timeoutId);\n handshakeWaiters.delete(waiter);\n if (outcome.type === \"resolve\") {\n waiter.resolve();\n } else {\n waiter.reject(outcome.error);\n }\n }\n };\n\n const rejectObsoleteHandshakeWaiters = (activeEpoch: number) => {\n for (const waiter of Array.from(handshakeWaiters)) {\n if (waiter.epoch >= activeEpoch) {\n continue;\n }\n clearTimeout(waiter.timeoutId);\n handshakeWaiters.delete(waiter);\n waiter.reject(\n createHandshakeError(\"AUTH_HANDSHAKE_REJECTED\", {\n ...waiter.context,\n reason: \"token_changed\",\n }),\n );\n }\n };\n\n const waitForAuthHandshake = async (context: AuthFlowContext) => {\n if (token === null) {\n return;\n }\n if (authConfirmed && !handshakePending) {\n return;\n }\n if (!handshakePending) {\n throw createHandshakeError(\"AUTH_HANDSHAKE_REJECTED\", {\n ...context,\n reason: \"auth_rejected\",\n });\n }\n\n const epoch = authEpoch;\n await new Promise<void>((resolve, reject) => {\n const waiterRef: { current: HandshakeWaiter | null } = { current: null };\n const timeoutId = setTimeout(() => {\n if (waiterRef.current !== null) {\n handshakeWaiters.delete(waiterRef.current);\n }\n reject(\n createHandshakeError(\"AUTH_HANDSHAKE_TIMEOUT\", {\n ...context,\n timeoutMs: AUTH_HANDSHAKE_TIMEOUT_MS,\n }),\n );\n }, AUTH_HANDSHAKE_TIMEOUT_MS);\n\n const waiter: HandshakeWaiter = {\n epoch,\n context,\n resolve,\n reject,\n timeoutId,\n };\n waiterRef.current = waiter;\n handshakeWaiters.add(waiter);\n });\n };\n\n const handleConvexAuthChange = (isAuthenticated: boolean) => {\n if (destroyed) {\n return;\n }\n\n if (isAuthenticated) {\n authConfirmed = true;\n handshakePending = false;\n settleHandshakeWaiters(authEpoch, { type: \"resolve\" });\n } else {\n authConfirmed = false;\n // Do not reject immediately while a handshake is pending.\n // Convex can transiently emit `false` while reauth is still in flight,\n // and a subsequent `true` confirms the same session.\n }\n\n if (updateSnapshot()) {\n notify();\n }\n };\n\n const notify = () => {\n for (const cb of subscribers) cb();\n };\n\n const updateSnapshot = () => {\n const phaseDispatch = {\n tag:\n token !== null && handshakePending\n ? \"handshake\"\n : isLoading\n ? \"loading\"\n : token !== null && authConfirmed\n ? \"authenticated\"\n : \"unauthenticated\",\n } as const;\n\n const phase = {\n handshake: \"handshake\",\n loading: \"loading\",\n authenticated: \"authenticated\",\n unauthenticated: \"unauthenticated\",\n }[phaseDispatch.tag] as AuthState[\"phase\"];\n\n const next: AuthState = {\n phase,\n isLoading: phase === \"loading\" || phase === \"handshake\",\n isAuthenticated: phase === \"authenticated\",\n token,\n };\n if (\n snapshot.phase === next.phase &&\n snapshot.isLoading === next.isLoading &&\n snapshot.isAuthenticated === next.isAuthenticated &&\n snapshot.token === next.token\n ) {\n return false;\n }\n snapshot = next;\n return true;\n };\n\n const finalizeLoadingState = () => {\n if (!isLoading) {\n return;\n }\n isLoading = false;\n if (updateSnapshot()) {\n notify();\n }\n };\n\n const inviteManager = createInviteManager({\n param,\n storageGet,\n storageSet,\n storageRemove,\n cleanUrlParams,\n tokenKey: INVITE_TOKEN_KEY,\n emailKey: INVITE_EMAIL_KEY,\n });\n const getPendingInvite = () => inviteManager.getPendingInvite();\n const persistInvite = () => inviteManager.persistInvite();\n const acceptInvite = () => inviteManager.acceptInvite();\n\n // ---------------------------------------------------------------------------\n // Token management\n // ---------------------------------------------------------------------------\n\n const bindConvexAuth = () => {\n convex.setAuth(fetchAccessToken, handleConvexAuthChange);\n };\n\n const setToken = async (\n args:\n | {\n shouldStore: true;\n tokens: AuthSession | null;\n requireHandshake?: boolean;\n resyncConvexAuth?: boolean;\n }\n | {\n shouldStore: false;\n tokens: { token: string } | null;\n requireHandshake?: boolean;\n resyncConvexAuth?: boolean;\n },\n ) => {\n const previousToken = token;\n\n if (args.tokens === null) {\n token = null;\n if (args.shouldStore) {\n await storageRemove(JWT_STORAGE_KEY);\n await storageRemove(REFRESH_TOKEN_STORAGE_KEY);\n }\n } else {\n token = args.tokens.token;\n if (args.shouldStore && \"refreshToken\" in args.tokens) {\n await storageSet(JWT_STORAGE_KEY, args.tokens.token);\n await storageSet(REFRESH_TOKEN_STORAGE_KEY, args.tokens.refreshToken);\n }\n }\n\n if (token !== previousToken) {\n authEpoch += 1;\n rejectObsoleteHandshakeWaiters(authEpoch);\n }\n\n if (token === null) {\n authConfirmed = false;\n handshakePending = false;\n settleHandshakeWaiters(authEpoch, {\n type: \"reject\",\n error: createHandshakeError(\"AUTH_HANDSHAKE_REJECTED\", {\n reason: \"token_cleared\",\n }),\n });\n } else {\n const shouldEnterHandshake =\n args.requireHandshake === true || !authConfirmed;\n if (shouldEnterHandshake) {\n authConfirmed = false;\n handshakePending = true;\n } else {\n handshakePending = false;\n }\n }\n\n const hadPendingLoad = isLoading;\n isLoading = false;\n const changed = updateSnapshot();\n if (args.resyncConvexAuth !== false) {\n bindConvexAuth();\n }\n if (hadPendingLoad || changed) {\n notify();\n }\n };\n\n const setTokenAndMaybeWait = async (\n args:\n | {\n shouldStore: true;\n tokens: AuthSession | null;\n waitForHandshake: boolean;\n context: AuthFlowContext;\n }\n | {\n shouldStore: false;\n tokens: { token: string } | null;\n waitForHandshake: boolean;\n context: AuthFlowContext;\n },\n ): Promise<boolean> => {\n const { waitForHandshake, context, ...tokenArgs } = args;\n await setToken({\n ...(tokenArgs as\n | { shouldStore: true; tokens: AuthSession | null }\n | { shouldStore: false; tokens: { token: string } | null }),\n requireHandshake: waitForHandshake,\n });\n if (tokenArgs.tokens === null) {\n return false;\n }\n if (waitForHandshake) {\n await waitForAuthHandshake(context);\n }\n return true;\n };\n\n // ---------------------------------------------------------------------------\n // Code verification with retries (SPA mode only)\n // ---------------------------------------------------------------------------\n\n const verifyCode = async (\n args: { code: string; verifier?: string } | { refreshToken: string },\n ) => {\n const verifyCodeRetryPolicy = Fx.retry.while(\n Fx.retry.compose(\n Fx.retry.jittered(Fx.retry.exponential(RETRY_BASE_MS)),\n Fx.retry.recurs(RETRY_MAX_RETRIES),\n ),\n (meta) => isTransientNetworkError(meta.input),\n );\n\n return Fx.run(\n Fx.from({\n ok: () =>\n httpClient!.action(\n requireApiRefs().signIn,\n \"code\" in args\n ? { params: { code: args.code }, verifier: args.verifier }\n : args,\n ),\n err: (e) => e,\n }).pipe(\n Fx.retry(verifyCodeRetryPolicy),\n Fx.recover((e) => Fx.fatal(e)),\n ),\n );\n };\n\n const verifyCodeAndSetToken = async (\n args: { code: string; verifier?: string } | { refreshToken: string },\n opts?: { resyncConvexAuth?: boolean },\n ) => {\n const { tokens } = await verifyCode(args);\n await setToken({\n shouldStore: true,\n tokens: (tokens as AuthSession | null) ?? null,\n resyncConvexAuth: opts?.resyncConvexAuth,\n });\n return tokens !== null;\n };\n\n const normalizeDeviceCodeResult = (device_code: any): DeviceCodeResult => {\n return {\n deviceCode: device_code.deviceCode,\n userCode: device_code.userCode,\n verificationUri:\n device_code.verification_uri ?? device_code.verificationUri,\n verificationUriComplete:\n device_code.verification_uri_complete ??\n device_code.verificationUriComplete,\n expiresIn: device_code.expiresIn,\n interval: device_code.interval,\n };\n };\n\n // ---------------------------------------------------------------------------\n // signIn\n // ---------------------------------------------------------------------------\n\n /**\n * Sign in with a provider.\n *\n * @param provider - Provider ID (e.g. `\"email\"`, `\"password\"`, `\"google\"`).\n * Omit when exchanging an OAuth code (the code carries the provider info).\n * @param args - Provider-specific arguments. Pass a `Record<string, Value>`\n * or `FormData`. Common fields: `email`, `password`, `code`, `redirectTo`.\n * @returns A {@link SignInResult} indicating the outcome.\n * @throws {ConvexError} When the server action rejects the sign-in attempt (e.g. invalid credentials, provider error, or rate limiting).\n *\n * @example Email magic link\n * ```ts\n * await auth.signIn('email', { email: 'user@example.com' });\n * ```\n *\n * @example Password\n * ```ts\n * const result = await auth.signIn('password', { email, password, flow: 'signIn' });\n * if (result.kind === 'totpRequired') {\n * await auth.totp.verify({ code: totpCode, verifier: result.verifier });\n * }\n * ```\n *\n * @example OAuth (triggers redirect)\n * ```ts\n * await auth.signIn('google'); // redirects to Google\n * ```\n */\n const signIn = async (\n provider?: string,\n args?: FormData | Record<string, Value>,\n ): Promise<SignInResult> => {\n // Persist invite before potential OAuth redirect\n await persistInvite();\n\n const params =\n args instanceof FormData\n ? (() => {\n const formParams: Record<string, Value> = {};\n args.forEach((value, key) => {\n formParams[key] = typeof value === \"string\" ? value : value.name;\n });\n return formParams;\n })()\n : (args ?? {});\n const flow =\n typeof params.flow === \"string\" && params.flow.length > 0\n ? params.flow\n : \"signIn\";\n\n const handleSignInActionResult = async (\n result: SignInActionResult,\n options: { shouldStore: boolean; persistVerifier: boolean },\n ): Promise<SignInResult> =>\n Fx.run(\n Fx.match(result, result.kind, {\n redirect: (redirectResult) =>\n Fx.promise(async () => {\n const redirectUrl = new URL(redirectResult.redirect);\n if (options.persistVerifier) {\n await storageSet(VERIFIER_STORAGE_KEY, redirectResult.verifier);\n }\n if (typeof window !== \"undefined\") {\n window.location.href = redirectUrl.toString();\n }\n return {\n kind: \"redirect\" as const,\n redirect: redirectUrl,\n verifier: redirectResult.verifier,\n };\n }),\n totpRequired: (totpRequiredResult) =>\n Fx.succeed({\n kind: \"totpRequired\" as const,\n verifier: totpRequiredResult.verifier,\n }),\n deviceCode: (deviceCodeResult) =>\n Fx.succeed({\n kind: \"deviceCode\" as const,\n deviceCode: normalizeDeviceCodeResult(\n deviceCodeResult.deviceCode,\n ),\n }),\n signedIn: (signedInResult) =>\n Fx.promise(async () => {\n const signingIn = await setTokenAndMaybeWait(\n options.shouldStore\n ? {\n shouldStore: true as const,\n tokens: signedInResult.tokens,\n waitForHandshake: true,\n context: { provider, flow },\n }\n : {\n shouldStore: false as const,\n tokens:\n signedInResult.tokens === null\n ? null\n : { token: signedInResult.tokens.token },\n waitForHandshake: true,\n context: { provider, flow },\n },\n );\n return signingIn\n ? ({ kind: \"signedIn\" as const } as SignInResult)\n : ({ kind: \"started\" as const } as SignInResult);\n }),\n started: (_startedResult) => Fx.succeed({ kind: \"started\" as const }),\n passkeyOptions: (_passkeyOptionsResult) =>\n Fx.succeed({ kind: \"started\" as const }),\n totpSetup: (_totpSetupResult) =>\n Fx.succeed({ kind: \"started\" as const }),\n }),\n );\n\n if (proxy) {\n const result = (await proxyFetch({\n action: \"auth:signIn\",\n args: { provider, params },\n })) as SignInActionResult;\n return handleSignInActionResult(result, {\n shouldStore: false,\n persistVerifier: false,\n });\n }\n\n // SPA mode: call Convex directly.\n const verifier = (await storageGet(VERIFIER_STORAGE_KEY)) ?? undefined;\n await storageRemove(VERIFIER_STORAGE_KEY);\n const result = (await convex.action(requireApiRefs().signIn, {\n provider,\n params,\n verifier,\n })) as SignInActionResult;\n return handleSignInActionResult(result, {\n shouldStore: true,\n persistVerifier: true,\n });\n };\n\n // ---------------------------------------------------------------------------\n // signOut\n // ---------------------------------------------------------------------------\n\n /**\n * Sign out the current user.\n *\n * Invalidates the server session and clears local token state.\n * Errors are silently caught — calling `signOut` on an already\n * signed-out user is a no-op.\n */\n const signOut = async () => {\n if (proxy) {\n await Fx.run(\n Fx.from({\n ok: () => proxyFetch({ action: \"auth:signOut\", args: {} }),\n err: () => undefined,\n }).pipe(Fx.recover(() => Fx.succeed(undefined))),\n );\n await setToken({ shouldStore: false, tokens: null });\n if (convex.clearAuth) convex.clearAuth();\n return;\n }\n\n // SPA mode.\n await Fx.run(\n Fx.from({\n ok: () => convex.action(requireApiRefs().signOut, {}),\n err: () => undefined,\n }).pipe(Fx.recover(() => Fx.succeed(undefined))),\n );\n await setToken({ shouldStore: true, tokens: null });\n if (convex.clearAuth) convex.clearAuth();\n };\n\n // ---------------------------------------------------------------------------\n // fetchAccessToken — called by convex.setAuth()\n // ---------------------------------------------------------------------------\n\n const fetchAccessToken = async ({\n forceRefreshToken,\n }: {\n forceRefreshToken: boolean;\n }): Promise<string | null> => {\n if (!forceRefreshToken) return token;\n\n if (proxy) {\n // Proxy mode: POST to the proxy to refresh.\n // The proxy reads the real refresh token from the httpOnly cookie.\n const resolvedProxyUrl = await resolveProxyUrl();\n if (\n typeof window === \"undefined\" &&\n !(await isAbsoluteUrl(resolvedProxyUrl))\n ) {\n finalizeLoadingState();\n return token;\n }\n\n const tokenBeforeRefresh = token;\n return await browserMutex(\"__convexAuthProxyRefresh\", async () => {\n // Another tab/call may have already refreshed.\n if (token !== tokenBeforeRefresh) return token;\n\n const proxyRefreshRetryPolicy = Fx.retry.while(\n Fx.retry.compose(\n Fx.retry.jittered(Fx.retry.exponential(RETRY_BASE_MS)),\n Fx.retry.recurs(RETRY_MAX_RETRIES),\n ),\n (meta) => isRetriableProxyRefreshError(meta.input),\n );\n\n await Fx.run(\n Fx.from({\n ok: () =>\n proxyFetch({\n action: \"auth:signIn\",\n args: { refreshToken: true },\n }),\n err: (e) => e,\n }).pipe(\n Fx.retry(proxyRefreshRetryPolicy),\n Fx.chain((result: any) =>\n Fx.from({\n ok: async () => {\n if (result.tokens) {\n await setToken({\n shouldStore: false,\n tokens: { token: result.tokens.token },\n resyncConvexAuth: false,\n });\n } else {\n await setToken({\n shouldStore: false,\n tokens: null,\n resyncConvexAuth: false,\n });\n }\n },\n err: (e) => e,\n }),\n ),\n Fx.inspect((error) =>\n Fx.sync(() =>\n console.error(\"[convex-auth] Proxy refresh failed:\", error),\n ),\n ),\n Fx.recover(() => {\n if (token === null) {\n finalizeLoadingState();\n }\n return Fx.succeed(undefined);\n }),\n ),\n );\n return token;\n });\n }\n\n // SPA mode: refresh via localStorage + httpClient.\n const tokenBeforeLockAcquisition = token;\n return await browserMutex(REFRESH_TOKEN_STORAGE_KEY, async () => {\n const tokenAfterLockAcquisition = token;\n if (tokenAfterLockAcquisition !== tokenBeforeLockAcquisition) {\n return tokenAfterLockAcquisition;\n }\n const refreshToken =\n (await storageGet(REFRESH_TOKEN_STORAGE_KEY)) ?? null;\n if (!refreshToken) {\n finalizeLoadingState();\n return null;\n }\n await verifyCodeAndSetToken(\n { refreshToken },\n { resyncConvexAuth: false },\n );\n return token;\n });\n };\n\n // ---------------------------------------------------------------------------\n // OAuth code flow (SPA mode only — server handles this in proxy mode)\n // ---------------------------------------------------------------------------\n\n const handleCodeFlow = async () => {\n if (typeof window === \"undefined\") return;\n if (handlingCodeFlow) return;\n const code = new URLSearchParams(window.location.search).get(\"code\");\n if (!code) return;\n handlingCodeFlow = true;\n await Fx.run(\n Fx.from({\n ok: async () => {\n await signIn(undefined, { code });\n const codeUrl = new URL(window.location.href);\n codeUrl.searchParams.delete(\"code\");\n await replaceUrl(codeUrl.pathname + codeUrl.search + codeUrl.hash);\n },\n err: (e) => e,\n }).pipe(\n Fx.recover(() => Fx.succeed(undefined)),\n Fx.tap(() =>\n Fx.sync(() => {\n handlingCodeFlow = false;\n }),\n ),\n Fx.inspect(() =>\n Fx.sync(() => {\n handlingCodeFlow = false;\n }),\n ),\n ),\n );\n // The flag is always reset — Fx.recover above ensures success path,\n // but reset defensively here too.\n handlingCodeFlow = false;\n };\n\n // ---------------------------------------------------------------------------\n // Hydrate from storage (SPA mode only)\n // ---------------------------------------------------------------------------\n\n const hydrateFromStorage = async () => {\n const storedToken = (await storageGet(JWT_STORAGE_KEY)) ?? null;\n await setToken({\n shouldStore: false,\n tokens: storedToken === null ? null : { token: storedToken },\n });\n };\n\n // ---------------------------------------------------------------------------\n // Subscribe\n // ---------------------------------------------------------------------------\n\n /**\n * Subscribe to auth state changes. Invokes the callback immediately\n * with the current state, then again on every state transition.\n *\n * ```ts\n * const unsub = auth.onChange(setState);\n * ```\n *\n * @param cb - Callback receiving the latest {@link AuthState}.\n * @returns An unsubscribe function.\n */\n const onChange = (cb: (state: AuthState) => void): (() => void) => {\n cb(snapshot);\n const wrapped = () => cb(snapshot);\n subscribers.add(wrapped);\n return () => {\n subscribers.delete(wrapped);\n };\n };\n\n // ---------------------------------------------------------------------------\n // Initialization\n // ---------------------------------------------------------------------------\n\n // Cross-tab sync via storage events (SPA mode only).\n if (!proxy && typeof window !== \"undefined\") {\n const registryKey = key(JWT_STORAGE_KEY);\n const registry = getStorageListenerRegistry();\n const existingListener = registry[registryKey];\n if (existingListener !== undefined) {\n window.removeEventListener(\"storage\", existingListener);\n }\n\n const onStorage = (event: StorageEvent) => {\n Fx.detach(async () => {\n if (event.key !== key(JWT_STORAGE_KEY)) return;\n await setToken({\n shouldStore: false,\n tokens: event.newValue === null ? null : { token: event.newValue },\n });\n }, \"[convex-auth] Storage event handler failed:\");\n };\n window.addEventListener(\"storage\", onStorage);\n registry[registryKey] = onStorage;\n disposeStorageListener = () => {\n if (registry[registryKey] === onStorage) {\n delete registry[registryKey];\n }\n window.removeEventListener(\"storage\", onStorage);\n };\n }\n\n // Auto-wire: feed our tokens into the Convex client so\n // queries and mutations are automatically authenticated.\n bindConvexAuth();\n\n // Auto-hydrate and handle code flow.\n if (typeof window !== \"undefined\") {\n if (proxy) {\n // Proxy mode: eagerly resolve auth once on startup so routes that only\n // read auth state (and do not issue Convex queries yet) don't stay in\n // the initial loading phase.\n if (!hasServerToken) {\n Fx.detach(\n () => fetchAccessToken({ forceRefreshToken: true }),\n \"[convex-auth] Proxy token refresh failed:\",\n );\n }\n } else {\n // SPA mode: hydrate from localStorage, then handle OAuth code flow.\n Fx.detach(async () => {\n await Fx.run(\n Fx.from({\n ok: async () => {\n await hydrateFromStorage();\n await handleCodeFlow();\n },\n err: (e) => e,\n }).pipe(\n Fx.inspect((error) =>\n Fx.sync(() =>\n console.error(\n \"[convex-auth] Client initialization failed:\",\n error,\n ),\n ),\n ),\n Fx.recover((_error) =>\n Fx.from({\n ok: () => setToken({ shouldStore: false, tokens: null }),\n err: (e) => e,\n }).pipe(Fx.recover(() => Fx.succeed(undefined))),\n ),\n ),\n );\n }, \"[convex-auth] SPA initialization failed:\");\n }\n }\n\n // ---------------------------------------------------------------------------\n // Auth factor helpers\n // ---------------------------------------------------------------------------\n\n const passkey = createPasskeyClient({\n proxy,\n convex,\n requireApiRefs,\n proxyFetch,\n setTokenAndMaybeWait,\n });\n\n const totp = createTotpClient({\n proxy,\n convex,\n requireApiRefs,\n proxyFetch,\n setTokenAndMaybeWait,\n });\n\n const device = createDeviceClient({\n proxy,\n convex,\n requireApiRefs,\n proxyFetch,\n setTokenAndMaybeWait,\n });\n\n return {\n /** Current auth state snapshot. */\n get state(): AuthState {\n return snapshot;\n },\n /** SSR-safe URL param reader. */\n param,\n /** Pending invite from URL or recovered from storage. Null if none. */\n get invite(): PendingInvite | null {\n const pendingInvite = getPendingInvite();\n if (!pendingInvite) return null;\n return {\n token: pendingInvite.token,\n email: pendingInvite.email,\n accept: acceptInvite,\n };\n },\n /** Sign in with a provider. See {@link SignInResult} for return shape. */\n signIn,\n /** Sign out and clear all token state. */\n signOut,\n /** Subscribe to auth state changes. Returns an unsubscribe function. */\n onChange,\n /** Passkey (WebAuthn) authentication helpers. */\n passkey,\n /** TOTP two-factor authentication helpers. */\n totp,\n /** Device authorization (RFC 8628) helpers. */\n device,\n /**\n * Tear down this auth client instance.\n *\n * Removes the cross-tab `storage` event listener, clears all\n * `onChange` subscribers, and rejects any in-flight handshake\n * waiters. Call this when the client is no longer needed\n * (e.g. on SPA unmount or hot-module replacement) to prevent\n * memory leaks and stale callbacks.\n *\n * @example\n * ```ts\n * // SvelteKit onDestroy\n * import { onDestroy } from \"svelte\";\n * const auth = client({ convex, api: api.auth });\n * onDestroy(() => auth.destroy());\n * ```\n *\n * @example\n * ```ts\n * const unsubscribe = auth.onChange((state) => console.log(state.phase));\n *\n * // Later, during cleanup:\n * unsubscribe();\n * auth.destroy();\n * ```\n */\n destroy: () => {\n destroyed = true;\n settleHandshakeWaiters(authEpoch, {\n type: \"reject\",\n error: createHandshakeError(\"AUTH_HANDSHAKE_REJECTED\", {\n reason: \"destroyed\",\n }),\n });\n disposeStorageListener?.();\n subscribers.clear();\n },\n } as AuthClient<Api>;\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
import "./core/types.js";
|
|
2
|
-
import "../server/errors.js";
|
|
1
|
+
import "./core/types.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as convex_server0 from "convex/server";
|
|
2
2
|
|
|
3
3
|
//#region src/component/convex.config.d.ts
|
|
4
|
-
declare const component:
|
|
4
|
+
declare const component: convex_server0.ComponentDefinition<any>;
|
|
5
5
|
//#endregion
|
|
6
6
|
export { component as default };
|
|
7
7
|
//# sourceMappingURL=convex.config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convex.config.d.ts","names":[],"sources":["../../src/component/convex.config.ts"],"mappings":";;;cAEM,SAAA,EAAmC,
|
|
1
|
+
{"version":3,"file":"convex.config.d.ts","names":[],"sources":["../../src/component/convex.config.ts"],"mappings":";;;cAEM,SAAA,EAAmC,cAAA,CAA1B,mBAAA"}
|
|
@@ -40,7 +40,7 @@ declare const vPasskeyDoc: convex_values474.VObject<{
|
|
|
40
40
|
lastUsedAt: convex_values474.VFloat64<number | undefined, "optional">;
|
|
41
41
|
_id: convex_values474.VId<convex_values474.GenericId<"Passkey">, "required">;
|
|
42
42
|
_creationTime: convex_values474.VFloat64<number, "required">;
|
|
43
|
-
}, "required", "
|
|
43
|
+
}, "required", "name" | "userId" | "_creationTime" | "credentialId" | "publicKey" | "algorithm" | "counter" | "transports" | "deviceType" | "backedUp" | "createdAt" | "lastUsedAt" | "_id">;
|
|
44
44
|
declare const vTotpFactorDoc: convex_values474.VObject<{
|
|
45
45
|
name?: string | undefined;
|
|
46
46
|
lastUsedAt?: number | undefined;
|
|
@@ -63,7 +63,7 @@ declare const vTotpFactorDoc: convex_values474.VObject<{
|
|
|
63
63
|
lastUsedAt: convex_values474.VFloat64<number | undefined, "optional">;
|
|
64
64
|
_id: convex_values474.VId<convex_values474.GenericId<"TotpFactor">, "required">;
|
|
65
65
|
_creationTime: convex_values474.VFloat64<number, "required">;
|
|
66
|
-
}, "required", "
|
|
66
|
+
}, "required", "name" | "userId" | "secret" | "_creationTime" | "createdAt" | "lastUsedAt" | "digits" | "period" | "verified" | "_id">;
|
|
67
67
|
declare const vApiKeyDoc: convex_values474.VObject<{
|
|
68
68
|
lastUsedAt?: number | undefined;
|
|
69
69
|
expiresAt?: number | undefined;
|
|
@@ -76,8 +76,8 @@ declare const vApiKeyDoc: convex_values474.VObject<{
|
|
|
76
76
|
attemptsLeft: number;
|
|
77
77
|
lastAttemptTime: number;
|
|
78
78
|
} | undefined;
|
|
79
|
-
userId: convex_values474.GenericId<"User">;
|
|
80
79
|
name: string;
|
|
80
|
+
userId: convex_values474.GenericId<"User">;
|
|
81
81
|
_creationTime: number;
|
|
82
82
|
createdAt: number;
|
|
83
83
|
revoked: boolean;
|
|
@@ -124,7 +124,7 @@ declare const vApiKeyDoc: convex_values474.VObject<{
|
|
|
124
124
|
metadata: convex_values474.VAny<any, "optional", string>;
|
|
125
125
|
_id: convex_values474.VId<convex_values474.GenericId<"ApiKey">, "required">;
|
|
126
126
|
_creationTime: convex_values474.VFloat64<number, "required">;
|
|
127
|
-
}, "required", "
|
|
127
|
+
}, "required", "name" | "userId" | "_creationTime" | "createdAt" | "lastUsedAt" | "expiresAt" | "revoked" | "metadata" | `metadata.${string}` | "prefix" | "hashedKey" | "scopes" | "rateLimit" | "rateLimitState" | "rateLimit.maxRequests" | "rateLimit.windowMs" | "rateLimitState.attemptsLeft" | "rateLimitState.lastAttemptTime" | "_id">;
|
|
128
128
|
declare const vDeviceCodeDoc: convex_values474.VObject<{
|
|
129
129
|
userId?: convex_values474.GenericId<"User"> | undefined;
|
|
130
130
|
sessionId?: convex_values474.GenericId<"Session"> | undefined;
|
|
@@ -147,7 +147,7 @@ declare const vDeviceCodeDoc: convex_values474.VObject<{
|
|
|
147
147
|
lastPolledAt: convex_values474.VFloat64<number | undefined, "optional">;
|
|
148
148
|
_id: convex_values474.VId<convex_values474.GenericId<"DeviceCode">, "required">;
|
|
149
149
|
_creationTime: convex_values474.VFloat64<number, "required">;
|
|
150
|
-
}, "required", "
|
|
150
|
+
}, "required", "status" | "userId" | "sessionId" | "_creationTime" | "deviceCodeHash" | "userCode" | "expiresAt" | "interval" | "lastPolledAt" | "_id">;
|
|
151
151
|
//#endregion
|
|
152
152
|
export { vApiKeyDoc, vAuthVerifierDoc, vDeviceCodeDoc, vPasskeyDoc, vTotpFactorDoc };
|
|
153
153
|
//# sourceMappingURL=model.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","names":[],"sources":["../../src/component/model.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"model.d.ts","names":[],"sources":["../../src/component/model.ts"],"mappings":";;;cAqMa,gBAAA,mBAAgB,OAAA;cAI3B,gBAAA,CAAA,SAAA;;;;;;;;;;cAqBW,WAAA,mBAAW,OAAA;;;;UAatB,gBAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;cAEW,cAAA,mBAAc,OAAA;;;UAUzB,gBAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;cA8CW,UAAA,mBAAU,OAAA;;;;;;;;;;;;;UAcrB,gBAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAEW,cAAA,mBAAc,OAAA;WAUzB,gBAAA,CAAA,SAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.d.ts","names":[],"sources":["../../../../src/component/public/enterprise/audit.ts"],"mappings":";;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"audit.d.ts","names":[],"sources":["../../../../src/component/public/enterprise/audit.ts"],"mappings":";;;;;;;;;;AAiDA;;;;;AA8CA;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA9Ca,0BAAA;;;;;;;;;;;;;;;;;;;;;;;;;;cA8CA,wBAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.js","names":[],"sources":["../../../../src/component/public/enterprise/audit.ts"],"sourcesContent":["import { v } from \"convex/values\";\nimport { mutation, query } from \"../../functions\";\nimport {
|
|
1
|
+
{"version":3,"file":"audit.js","names":[],"sources":["../../../../src/component/public/enterprise/audit.ts"],"sourcesContent":["import { v } from \"convex/values\";\n\nimport { mutation, query } from \"../../functions\";\nimport {\n vAuditActorType,\n vAuditStatus,\n vEnterpriseAuditEventDoc,\n} from \"../../model\";\n\n/**\n * Record a new audit event for an enterprise.\n *\n * Inserts an immutable audit log entry capturing who performed what action,\n * on which subject, and whether it succeeded or failed. Use this to maintain\n * a tamper-evident trail of security-relevant events.\n *\n * @param args.enterpriseId - The ID of the enterprise this event belongs to.\n * @param args.groupId - The ID of the root group that owns the enterprise.\n * @param args.eventType - A string identifying the type of event (e.g. `\"user.login\"`, `\"scim.provision\"`).\n * @param args.actorType - The kind of actor: `\"user\"`, `\"system\"`, `\"scim\"`, `\"api_key\"`, or `\"webhook\"`.\n * @param args.actorId - An optional identifier for the actor (e.g. a user ID or API key ID).\n * @param args.subjectType - The type of the resource being acted upon (e.g. `\"user\"`, `\"group\"`).\n * @param args.subjectId - An optional identifier for the subject resource.\n * @param args.status - Whether the event represents a `\"success\"` or `\"failure\"`.\n * @param args.occurredAt - Epoch timestamp (ms) when the event occurred.\n * @param args.requestId - An optional correlation ID tying this event to a specific request.\n * @param args.ip - An optional IP address of the actor.\n * @param args.metadata - An optional arbitrary object with additional event details.\n * @returns The ID of the newly created `EnterpriseAuditEvent` document.\n *\n * @example\n * ```ts\n * const eventId = await ctx.runMutation(\n * components.auth.enterprise.enterpriseAuditEventCreate,\n * {\n * enterpriseId,\n * groupId: orgGroupId,\n * eventType: \"user.login\",\n * actorType: \"user\",\n * actorId: userId,\n * subjectType: \"session\",\n * subjectId: sessionId,\n * status: \"success\",\n * occurredAt: Date.now(),\n * ip: \"203.0.113.42\",\n * },\n * );\n * ```\n */\nexport const enterpriseAuditEventCreate = mutation({\n args: {\n enterpriseId: v.id(\"Enterprise\"),\n groupId: v.id(\"Group\"),\n eventType: v.string(),\n actorType: vAuditActorType,\n actorId: v.optional(v.string()),\n subjectType: v.string(),\n subjectId: v.optional(v.string()),\n status: vAuditStatus,\n occurredAt: v.number(),\n requestId: v.optional(v.string()),\n ip: v.optional(v.string()),\n metadata: v.optional(v.any()),\n },\n returns: v.id(\"EnterpriseAuditEvent\"),\n handler: async (ctx, args) => {\n return await ctx.db.insert(\"EnterpriseAuditEvent\", args);\n },\n});\n\n/**\n * List audit events, optionally filtered by enterprise or group.\n *\n * Returns audit events in reverse chronological order. When `enterpriseId` is\n * provided, events are filtered using the `enterprise_id_occurred_at` index.\n * When only `groupId` is provided, the `group_id_occurred_at` index is used.\n * If neither filter is given, the most recent events across all enterprises\n * are returned.\n *\n * @param args.enterpriseId - An optional enterprise ID to scope events to a single enterprise.\n * @param args.groupId - An optional group ID to scope events to a single group.\n * @param args.limit - Maximum number of events to return (clamped between 1 and 100, defaults to 50).\n * @returns An array of audit event documents, most recent first.\n *\n * @example\n * ```ts\n * const events = await ctx.runQuery(\n * components.auth.enterprise.enterpriseAuditEventList,\n * { enterpriseId, limit: 20 },\n * );\n * for (const event of events) {\n * console.log(event.eventType, event.actorType, event.status);\n * }\n * ```\n */\nexport const enterpriseAuditEventList = query({\n args: {\n enterpriseId: v.optional(v.id(\"Enterprise\")),\n groupId: v.optional(v.id(\"Group\")),\n limit: v.optional(v.number()),\n },\n returns: v.array(vEnterpriseAuditEventDoc),\n handler: async (ctx, args) => {\n const limit = Math.min(Math.max(args.limit ?? 50, 1), 100);\n if (args.enterpriseId !== undefined) {\n return await ctx.db\n .query(\"EnterpriseAuditEvent\")\n .withIndex(\"enterprise_id_occurred_at\", (idx) =>\n idx.eq(\"enterpriseId\", args.enterpriseId!),\n )\n .order(\"desc\")\n .take(limit);\n }\n if (args.groupId !== undefined) {\n return await ctx.db\n .query(\"EnterpriseAuditEvent\")\n .withIndex(\"group_id_occurred_at\", (idx) =>\n idx.eq(\"groupId\", args.groupId!),\n )\n .order(\"desc\")\n .take(limit);\n }\n return await ctx.db.query(\"EnterpriseAuditEvent\").order(\"desc\").take(limit);\n },\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiDA,MAAa,6BAA6B,SAAS;CACjD,MAAM;EACJ,cAAc,EAAE,GAAG,aAAa;EAChC,SAAS,EAAE,GAAG,QAAQ;EACtB,WAAW,EAAE,QAAQ;EACrB,WAAW;EACX,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC;EAC/B,aAAa,EAAE,QAAQ;EACvB,WAAW,EAAE,SAAS,EAAE,QAAQ,CAAC;EACjC,QAAQ;EACR,YAAY,EAAE,QAAQ;EACtB,WAAW,EAAE,SAAS,EAAE,QAAQ,CAAC;EACjC,IAAI,EAAE,SAAS,EAAE,QAAQ,CAAC;EAC1B,UAAU,EAAE,SAAS,EAAE,KAAK,CAAC;EAC9B;CACD,SAAS,EAAE,GAAG,uBAAuB;CACrC,SAAS,OAAO,KAAK,SAAS;AAC5B,SAAO,MAAM,IAAI,GAAG,OAAO,wBAAwB,KAAK;;CAE3D,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BF,MAAa,2BAA2B,MAAM;CAC5C,MAAM;EACJ,cAAc,EAAE,SAAS,EAAE,GAAG,aAAa,CAAC;EAC5C,SAAS,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC;EAClC,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC;EAC9B;CACD,SAAS,EAAE,MAAM,yBAAyB;CAC1C,SAAS,OAAO,KAAK,SAAS;EAC5B,MAAM,QAAQ,KAAK,IAAI,KAAK,IAAI,KAAK,SAAS,IAAI,EAAE,EAAE,IAAI;AAC1D,MAAI,KAAK,iBAAiB,OACxB,QAAO,MAAM,IAAI,GACd,MAAM,uBAAuB,CAC7B,UAAU,8BAA8B,QACvC,IAAI,GAAG,gBAAgB,KAAK,aAAc,CAC3C,CACA,MAAM,OAAO,CACb,KAAK,MAAM;AAEhB,MAAI,KAAK,YAAY,OACnB,QAAO,MAAM,IAAI,GACd,MAAM,uBAAuB,CAC7B,UAAU,yBAAyB,QAClC,IAAI,GAAG,WAAW,KAAK,QAAS,CACjC,CACA,MAAM,OAAO,CACb,KAAK,MAAM;AAEhB,SAAO,MAAM,IAAI,GAAG,MAAM,uBAAuB,CAAC,MAAM,OAAO,CAAC,KAAK,MAAM;;CAE9E,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","names":[],"sources":["../../../../src/component/public/enterprise/core.ts"],"mappings":";;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"core.d.ts","names":[],"sources":["../../../../src/component/public/enterprise/core.ts"],"mappings":";;;;;;;;;;;;;;;AAwCA;;;;;AAiDA;;;;;AAyBA;;;;;AAiCA;;cA3Ga,gBAAA;;;AAuKb;;;;;AA2FA;;;;;AA4BA;;;;;;;;cA7Oa,aAAA;;;;;;;;;;;;;;;;;;cAyBA,oBAAA;;;;;;;;;;;;;;;;;;;;;;;cAiCA,qBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA4DA,cAAA;;;;;;;;;;;;;;;;;;;;;;cA2FA,gBAAA;;;;;;;;;;;;;;;;;;;;cA4BA,gBAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.js","names":[],"sources":["../../../../src/component/public/enterprise/core.ts"],"sourcesContent":["import { ConvexError, v } from \"convex/values\";\nimport { mutation, query } from \"../../functions\";\nimport {\n vEnterpriseDoc,\n vEnterpriseDomainDoc,\n vEnterprisePolicy,\n vEnterpriseStatus,\n vPaginated,\n} from \"../../model\";\n\n/**\n * Create a new enterprise record attached to a root group.\n *\n * Each group may only have one enterprise record. If an enterprise already\n * exists for the given group, a `ENTERPRISE_ALREADY_EXISTS` error is thrown.\n * The enterprise status defaults to `\"draft\"` when not explicitly provided.\n *\n * @param args.groupId - The ID of the root group that owns this enterprise.\n * @param args.slug - An optional URL-friendly identifier for the enterprise.\n * @param args.name - An optional human-readable display name for the enterprise.\n * @param args.status - The lifecycle status (`\"draft\"`, `\"active\"`, or `\"disabled\"`). Defaults to `\"draft\"`.\n * @param args.policy - An optional enterprise policy object controlling identity linking, provisioning, and deprovisioning behavior.\n * @param args.config - An optional arbitrary configuration blob for enterprise-specific settings.\n * @param args.extend - An optional arbitrary extension object for custom fields.\n * @returns The ID of the newly created `Enterprise` document.\n *\n * @example\n * ```ts\n * const enterpriseId = await ctx.runMutation(\n * components.auth.enterprise.enterpriseCreate,\n * {\n * groupId: orgGroupId,\n * slug: \"acme-corp\",\n * name: \"Acme Corporation\",\n * status: \"active\",\n * },\n * );\n * ```\n */\nexport const enterpriseCreate = mutation({\n args: {\n groupId: v.id(\"Group\"),\n slug: v.optional(v.string()),\n name: v.optional(v.string()),\n status: v.optional(vEnterpriseStatus),\n policy: v.optional(vEnterprisePolicy),\n config: v.optional(v.any()),\n extend: v.optional(v.any()),\n },\n returns: v.id(\"Enterprise\"),\n handler: async (ctx, args) => {\n const existing = await ctx.db\n .query(\"Enterprise\")\n .withIndex(\"group_id\", (idx) => idx.eq(\"groupId\", args.groupId))\n .first();\n if (existing) {\n throw new ConvexError({\n code: \"ENTERPRISE_ALREADY_EXISTS\",\n message: \"An enterprise record already exists for this group.\",\n });\n }\n return await ctx.db.insert(\"Enterprise\", {\n ...args,\n status: args.status ?? \"draft\",\n });\n },\n});\n\n/**\n * Retrieve a single enterprise record by its document ID.\n *\n * Returns the full enterprise document if it exists, or `null` if no\n * enterprise is found with the given ID.\n *\n * @param args.enterpriseId - The document ID of the enterprise to retrieve.\n * @returns The enterprise document, or `null` if not found.\n *\n * @example\n * ```ts\n * const enterprise = await ctx.runQuery(\n * components.auth.enterprise.enterpriseGet,\n * { enterpriseId },\n * );\n * if (enterprise) {\n * console.log(enterprise.name, enterprise.status);\n * }\n * ```\n */\nexport const enterpriseGet = query({\n args: { enterpriseId: v.id(\"Enterprise\") },\n returns: v.union(vEnterpriseDoc, v.null()),\n handler: async (ctx, { enterpriseId }) => {\n return await ctx.db.get(\"Enterprise\", enterpriseId);\n },\n});\n\n/**\n * Retrieve an enterprise record by the ID of its owning group.\n *\n * Looks up the enterprise that is linked to the specified group using the\n * `group_id` index. Returns `null` if no enterprise is associated with the group.\n *\n * @param args.groupId - The ID of the root group whose enterprise record to look up.\n * @returns The enterprise document, or `null` if the group has no enterprise.\n *\n * @example\n * ```ts\n * const enterprise = await ctx.runQuery(\n * components.auth.enterprise.enterpriseGetByGroup,\n * { groupId: orgGroupId },\n * );\n * ```\n */\nexport const enterpriseGetByGroup = query({\n args: { groupId: v.id(\"Group\") },\n returns: v.union(vEnterpriseDoc, v.null()),\n handler: async (ctx, { groupId }) => {\n return await ctx.db\n .query(\"Enterprise\")\n .withIndex(\"group_id\", (idx) => idx.eq(\"groupId\", groupId))\n .first();\n },\n});\n\n/**\n * Retrieve an enterprise record by one of its linked domain names.\n *\n * Looks up an `EnterpriseDomain` row matching the given domain string, then\n * resolves the parent enterprise. Returns both the enterprise and the matched\n * domain document, or `null` if the domain is not registered or its enterprise\n * no longer exists.\n *\n * @param args.domain - The domain name to search for (e.g. `\"acme.com\"`).\n * @returns An object containing the `enterprise` and `domain` documents, or `null` if not found.\n *\n * @example\n * ```ts\n * const result = await ctx.runQuery(\n * components.auth.enterprise.enterpriseGetByDomain,\n * { domain: \"acme.com\" },\n * );\n * if (result) {\n * console.log(result.enterprise.name, result.domain.verifiedAt);\n * }\n * ```\n */\nexport const enterpriseGetByDomain = query({\n args: { domain: v.string() },\n returns: v.union(\n v.object({\n enterprise: vEnterpriseDoc,\n domain: vEnterpriseDomainDoc,\n }),\n v.null(),\n ),\n handler: async (ctx, { domain }) => {\n const domainRow = await ctx.db\n .query(\"EnterpriseDomain\")\n .withIndex(\"domain\", (idx) => idx.eq(\"domain\", domain))\n .first();\n if (!domainRow) {\n return null;\n }\n const enterprise = await ctx.db.get(\"Enterprise\", domainRow.enterpriseId);\n if (!enterprise) {\n return null;\n }\n return { enterprise, domain: domainRow };\n },\n});\n\n/**\n * List enterprise records with optional filtering and cursor-based pagination.\n *\n * Supports filtering by `groupId`, `slug`, and/or `status`. The query selects\n * the most specific index available for the primary filter, then applies\n * remaining predicates as post-filters. Results are ordered by creation time\n * (or the specified field) and paginated using an opaque cursor.\n *\n * @param args.where - Optional filter criteria: `groupId`, `slug`, and/or `status`.\n * @param args.limit - Maximum number of items per page (clamped between 1 and 100, defaults to 50).\n * @param args.cursor - An opaque cursor string returned from a previous call to fetch the next page, or `null` / omitted for the first page.\n * @param args.orderBy - The field to sort results by: `\"_creationTime\"`, `\"name\"`, `\"slug\"`, or `\"status\"`.\n * @param args.order - Sort direction: `\"asc\"` or `\"desc\"` (defaults to `\"desc\"`).\n * @returns A paginated result containing `items` (array of enterprise documents) and `nextCursor` (`string | null`).\n *\n * @example\n * ```ts\n * const page = await ctx.runQuery(\n * components.auth.enterprise.enterpriseList,\n * {\n * where: { status: \"active\" },\n * limit: 25,\n * order: \"asc\",\n * },\n * );\n * for (const ent of page.items) {\n * console.log(ent.name);\n * }\n * // Fetch next page:\n * const nextPage = await ctx.runQuery(\n * components.auth.enterprise.enterpriseList,\n * { where: { status: \"active\" }, cursor: page.nextCursor },\n * );\n * ```\n */\nexport const enterpriseList = query({\n args: {\n where: v.optional(\n v.object({\n groupId: v.optional(v.id(\"Group\")),\n slug: v.optional(v.string()),\n status: v.optional(vEnterpriseStatus),\n }),\n ),\n limit: v.optional(v.number()),\n cursor: v.optional(v.union(v.string(), v.null())),\n orderBy: v.optional(\n v.union(\n v.literal(\"_creationTime\"),\n v.literal(\"name\"),\n v.literal(\"slug\"),\n v.literal(\"status\"),\n ),\n ),\n order: v.optional(v.union(v.literal(\"asc\"), v.literal(\"desc\"))),\n },\n returns: vPaginated(vEnterpriseDoc),\n handler: async (ctx, args) => {\n const where = args.where ?? {};\n const limit = Math.min(Math.max(args.limit ?? 50, 1), 100);\n const order = args.order ?? \"desc\";\n\n let q;\n if (where.groupId !== undefined) {\n q = ctx.db\n .query(\"Enterprise\")\n .withIndex(\"group_id\", (idx) => idx.eq(\"groupId\", where.groupId!));\n } else if (where.slug !== undefined) {\n q = ctx.db\n .query(\"Enterprise\")\n .withIndex(\"slug\", (idx) => idx.eq(\"slug\", where.slug!));\n } else if (where.status !== undefined) {\n q = ctx.db\n .query(\"Enterprise\")\n .withIndex(\"status\", (idx) => idx.eq(\"status\", where.status!));\n } else {\n q = ctx.db.query(\"Enterprise\");\n }\n\n if (where.groupId !== undefined && where.slug !== undefined) {\n q = q.filter((f) => f.eq(f.field(\"slug\"), where.slug!));\n }\n if (where.status !== undefined && where.groupId === undefined) {\n // already handled by index in the dedicated branch\n } else if (where.status !== undefined) {\n q = q.filter((f) => f.eq(f.field(\"status\"), where.status!));\n }\n\n q = q.order(order);\n const all = await q.collect();\n let startIdx = 0;\n if (args.cursor) {\n const cursorIdx = all.findIndex((doc) => doc._id === args.cursor);\n if (cursorIdx !== -1) {\n startIdx = cursorIdx + 1;\n }\n }\n const page = all.slice(startIdx, startIdx + limit + 1);\n const hasMore = page.length > limit;\n const items = hasMore ? page.slice(0, limit) : page;\n const nextCursor = hasMore ? items[items.length - 1]._id : null;\n return { items, nextCursor };\n },\n});\n\n/**\n * Partially update (patch) an existing enterprise record.\n *\n * Merges the provided `data` fields into the existing enterprise document.\n * Only the fields present in `data` are changed; all other fields are preserved.\n *\n * @param args.enterpriseId - The document ID of the enterprise to update.\n * @param args.data - An object containing the fields to update (e.g. `{ name, status, policy }`).\n * @returns `null` on success.\n *\n * @example\n * ```ts\n * await ctx.runMutation(\n * components.auth.enterprise.enterpriseUpdate,\n * {\n * enterpriseId,\n * data: { status: \"active\", name: \"Acme Corp (Renamed)\" },\n * },\n * );\n * ```\n */\nexport const enterpriseUpdate = mutation({\n args: { enterpriseId: v.id(\"Enterprise\"), data: v.any() },\n returns: v.null(),\n handler: async (ctx, { enterpriseId, data }) => {\n await ctx.db.patch(enterpriseId, data);\n return null;\n },\n});\n\n/**\n * Delete an enterprise record and all of its associated child data.\n *\n * This cascading delete removes the enterprise document along with all linked\n * domain records, domain verification records, and enterprise secrets. Callers\n * should ensure that higher-level cleanup (e.g. SCIM identities, webhook\n * endpoints) is handled separately if needed.\n *\n * @param args.enterpriseId - The document ID of the enterprise to delete.\n * @returns `null` on success.\n *\n * @example\n * ```ts\n * await ctx.runMutation(\n * components.auth.enterprise.enterpriseDelete,\n * { enterpriseId },\n * );\n * ```\n */\nexport const enterpriseDelete = mutation({\n args: { enterpriseId: v.id(\"Enterprise\") },\n returns: v.null(),\n handler: async (ctx, { enterpriseId }) => {\n const domains = await ctx.db\n .query(\"EnterpriseDomain\")\n .withIndex(\"enterprise_id\", (idx) => idx.eq(\"enterpriseId\", enterpriseId))\n .collect();\n for (const domain of domains) {\n const verification = await ctx.db\n .query(\"EnterpriseDomainVerification\")\n .withIndex(\"domain_id\", (idx) => idx.eq(\"domainId\", domain._id))\n .first();\n if (verification) {\n await ctx.db.delete(verification._id);\n }\n await ctx.db.delete(domain._id);\n }\n const secrets = await ctx.db\n .query(\"EnterpriseSecret\")\n .withIndex(\"enterprise_id\", (idx) => idx.eq(\"enterpriseId\", enterpriseId))\n .collect();\n for (const secret of secrets) {\n await ctx.db.delete(secret._id);\n }\n await ctx.db.delete(enterpriseId);\n return null;\n },\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"core.js","names":[],"sources":["../../../../src/component/public/enterprise/core.ts"],"sourcesContent":["import { ConvexError, v } from \"convex/values\";\n\nimport { mutation, query } from \"../../functions\";\nimport {\n vEnterpriseDoc,\n vEnterpriseDomainDoc,\n vEnterprisePolicy,\n vEnterpriseStatus,\n vPaginated,\n} from \"../../model\";\n\n/**\n * Create a new enterprise record attached to a root group.\n *\n * Each group may only have one enterprise record. If an enterprise already\n * exists for the given group, a `ENTERPRISE_ALREADY_EXISTS` error is thrown.\n * The enterprise status defaults to `\"draft\"` when not explicitly provided.\n *\n * @param args.groupId - The ID of the root group that owns this enterprise.\n * @param args.slug - An optional URL-friendly identifier for the enterprise.\n * @param args.name - An optional human-readable display name for the enterprise.\n * @param args.status - The lifecycle status (`\"draft\"`, `\"active\"`, or `\"disabled\"`). Defaults to `\"draft\"`.\n * @param args.policy - An optional enterprise policy object controlling identity linking, provisioning, and deprovisioning behavior.\n * @param args.config - An optional arbitrary configuration blob for enterprise-specific settings.\n * @param args.extend - An optional arbitrary extension object for custom fields.\n * @returns The ID of the newly created `Enterprise` document.\n *\n * @example\n * ```ts\n * const enterpriseId = await ctx.runMutation(\n * components.auth.enterprise.enterpriseCreate,\n * {\n * groupId: orgGroupId,\n * slug: \"acme-corp\",\n * name: \"Acme Corporation\",\n * status: \"active\",\n * },\n * );\n * ```\n */\nexport const enterpriseCreate = mutation({\n args: {\n groupId: v.id(\"Group\"),\n slug: v.optional(v.string()),\n name: v.optional(v.string()),\n status: v.optional(vEnterpriseStatus),\n policy: v.optional(vEnterprisePolicy),\n config: v.optional(v.any()),\n extend: v.optional(v.any()),\n },\n returns: v.id(\"Enterprise\"),\n handler: async (ctx, args) => {\n const existing = await ctx.db\n .query(\"Enterprise\")\n .withIndex(\"group_id\", (idx) => idx.eq(\"groupId\", args.groupId))\n .first();\n if (existing) {\n throw new ConvexError({\n code: \"ENTERPRISE_ALREADY_EXISTS\",\n message: \"An enterprise record already exists for this group.\",\n });\n }\n return await ctx.db.insert(\"Enterprise\", {\n ...args,\n status: args.status ?? \"draft\",\n });\n },\n});\n\n/**\n * Retrieve a single enterprise record by its document ID.\n *\n * Returns the full enterprise document if it exists, or `null` if no\n * enterprise is found with the given ID.\n *\n * @param args.enterpriseId - The document ID of the enterprise to retrieve.\n * @returns The enterprise document, or `null` if not found.\n *\n * @example\n * ```ts\n * const enterprise = await ctx.runQuery(\n * components.auth.enterprise.enterpriseGet,\n * { enterpriseId },\n * );\n * if (enterprise) {\n * console.log(enterprise.name, enterprise.status);\n * }\n * ```\n */\nexport const enterpriseGet = query({\n args: { enterpriseId: v.id(\"Enterprise\") },\n returns: v.union(vEnterpriseDoc, v.null()),\n handler: async (ctx, { enterpriseId }) => {\n return await ctx.db.get(\"Enterprise\", enterpriseId);\n },\n});\n\n/**\n * Retrieve an enterprise record by the ID of its owning group.\n *\n * Looks up the enterprise that is linked to the specified group using the\n * `group_id` index. Returns `null` if no enterprise is associated with the group.\n *\n * @param args.groupId - The ID of the root group whose enterprise record to look up.\n * @returns The enterprise document, or `null` if the group has no enterprise.\n *\n * @example\n * ```ts\n * const enterprise = await ctx.runQuery(\n * components.auth.enterprise.enterpriseGetByGroup,\n * { groupId: orgGroupId },\n * );\n * ```\n */\nexport const enterpriseGetByGroup = query({\n args: { groupId: v.id(\"Group\") },\n returns: v.union(vEnterpriseDoc, v.null()),\n handler: async (ctx, { groupId }) => {\n return await ctx.db\n .query(\"Enterprise\")\n .withIndex(\"group_id\", (idx) => idx.eq(\"groupId\", groupId))\n .first();\n },\n});\n\n/**\n * Retrieve an enterprise record by one of its linked domain names.\n *\n * Looks up an `EnterpriseDomain` row matching the given domain string, then\n * resolves the parent enterprise. Returns both the enterprise and the matched\n * domain document, or `null` if the domain is not registered or its enterprise\n * no longer exists.\n *\n * @param args.domain - The domain name to search for (e.g. `\"acme.com\"`).\n * @returns An object containing the `enterprise` and `domain` documents, or `null` if not found.\n *\n * @example\n * ```ts\n * const result = await ctx.runQuery(\n * components.auth.enterprise.enterpriseGetByDomain,\n * { domain: \"acme.com\" },\n * );\n * if (result) {\n * console.log(result.enterprise.name, result.domain.verifiedAt);\n * }\n * ```\n */\nexport const enterpriseGetByDomain = query({\n args: { domain: v.string() },\n returns: v.union(\n v.object({\n enterprise: vEnterpriseDoc,\n domain: vEnterpriseDomainDoc,\n }),\n v.null(),\n ),\n handler: async (ctx, { domain }) => {\n const domainRow = await ctx.db\n .query(\"EnterpriseDomain\")\n .withIndex(\"domain\", (idx) => idx.eq(\"domain\", domain))\n .first();\n if (!domainRow) {\n return null;\n }\n const enterprise = await ctx.db.get(\"Enterprise\", domainRow.enterpriseId);\n if (!enterprise) {\n return null;\n }\n return { enterprise, domain: domainRow };\n },\n});\n\n/**\n * List enterprise records with optional filtering and cursor-based pagination.\n *\n * Supports filtering by `groupId`, `slug`, and/or `status`. The query selects\n * the most specific index available for the primary filter, then applies\n * remaining predicates as post-filters. Results are ordered by creation time\n * (or the specified field) and paginated using an opaque cursor.\n *\n * @param args.where - Optional filter criteria: `groupId`, `slug`, and/or `status`.\n * @param args.limit - Maximum number of items per page (clamped between 1 and 100, defaults to 50).\n * @param args.cursor - An opaque cursor string returned from a previous call to fetch the next page, or `null` / omitted for the first page.\n * @param args.orderBy - The field to sort results by: `\"_creationTime\"`, `\"name\"`, `\"slug\"`, or `\"status\"`.\n * @param args.order - Sort direction: `\"asc\"` or `\"desc\"` (defaults to `\"desc\"`).\n * @returns A paginated result containing `items` (array of enterprise documents) and `nextCursor` (`string | null`).\n *\n * @example\n * ```ts\n * const page = await ctx.runQuery(\n * components.auth.enterprise.enterpriseList,\n * {\n * where: { status: \"active\" },\n * limit: 25,\n * order: \"asc\",\n * },\n * );\n * for (const ent of page.items) {\n * console.log(ent.name);\n * }\n * // Fetch next page:\n * const nextPage = await ctx.runQuery(\n * components.auth.enterprise.enterpriseList,\n * { where: { status: \"active\" }, cursor: page.nextCursor },\n * );\n * ```\n */\nexport const enterpriseList = query({\n args: {\n where: v.optional(\n v.object({\n groupId: v.optional(v.id(\"Group\")),\n slug: v.optional(v.string()),\n status: v.optional(vEnterpriseStatus),\n }),\n ),\n limit: v.optional(v.number()),\n cursor: v.optional(v.union(v.string(), v.null())),\n orderBy: v.optional(\n v.union(\n v.literal(\"_creationTime\"),\n v.literal(\"name\"),\n v.literal(\"slug\"),\n v.literal(\"status\"),\n ),\n ),\n order: v.optional(v.union(v.literal(\"asc\"), v.literal(\"desc\"))),\n },\n returns: vPaginated(vEnterpriseDoc),\n handler: async (ctx, args) => {\n const where = args.where ?? {};\n const limit = Math.min(Math.max(args.limit ?? 50, 1), 100);\n const order = args.order ?? \"desc\";\n\n let q;\n if (where.groupId !== undefined) {\n q = ctx.db\n .query(\"Enterprise\")\n .withIndex(\"group_id\", (idx) => idx.eq(\"groupId\", where.groupId!));\n } else if (where.slug !== undefined) {\n q = ctx.db\n .query(\"Enterprise\")\n .withIndex(\"slug\", (idx) => idx.eq(\"slug\", where.slug!));\n } else if (where.status !== undefined) {\n q = ctx.db\n .query(\"Enterprise\")\n .withIndex(\"status\", (idx) => idx.eq(\"status\", where.status!));\n } else {\n q = ctx.db.query(\"Enterprise\");\n }\n\n if (where.groupId !== undefined && where.slug !== undefined) {\n q = q.filter((f) => f.eq(f.field(\"slug\"), where.slug!));\n }\n if (where.status !== undefined && where.groupId === undefined) {\n // already handled by index in the dedicated branch\n } else if (where.status !== undefined) {\n q = q.filter((f) => f.eq(f.field(\"status\"), where.status!));\n }\n\n q = q.order(order);\n const all = await q.collect();\n let startIdx = 0;\n if (args.cursor) {\n const cursorIdx = all.findIndex((doc) => doc._id === args.cursor);\n if (cursorIdx !== -1) {\n startIdx = cursorIdx + 1;\n }\n }\n const page = all.slice(startIdx, startIdx + limit + 1);\n const hasMore = page.length > limit;\n const items = hasMore ? page.slice(0, limit) : page;\n const nextCursor = hasMore ? items[items.length - 1]._id : null;\n return { items, nextCursor };\n },\n});\n\n/**\n * Partially update (patch) an existing enterprise record.\n *\n * Merges the provided `data` fields into the existing enterprise document.\n * Only the fields present in `data` are changed; all other fields are preserved.\n *\n * @param args.enterpriseId - The document ID of the enterprise to update.\n * @param args.data - An object containing the fields to update (e.g. `{ name, status, policy }`).\n * @returns `null` on success.\n *\n * @example\n * ```ts\n * await ctx.runMutation(\n * components.auth.enterprise.enterpriseUpdate,\n * {\n * enterpriseId,\n * data: { status: \"active\", name: \"Acme Corp (Renamed)\" },\n * },\n * );\n * ```\n */\nexport const enterpriseUpdate = mutation({\n args: { enterpriseId: v.id(\"Enterprise\"), data: v.any() },\n returns: v.null(),\n handler: async (ctx, { enterpriseId, data }) => {\n await ctx.db.patch(enterpriseId, data);\n return null;\n },\n});\n\n/**\n * Delete an enterprise record and all of its associated child data.\n *\n * This cascading delete removes the enterprise document along with all linked\n * domain records, domain verification records, and enterprise secrets. Callers\n * should ensure that higher-level cleanup (e.g. SCIM identities, webhook\n * endpoints) is handled separately if needed.\n *\n * @param args.enterpriseId - The document ID of the enterprise to delete.\n * @returns `null` on success.\n *\n * @example\n * ```ts\n * await ctx.runMutation(\n * components.auth.enterprise.enterpriseDelete,\n * { enterpriseId },\n * );\n * ```\n */\nexport const enterpriseDelete = mutation({\n args: { enterpriseId: v.id(\"Enterprise\") },\n returns: v.null(),\n handler: async (ctx, { enterpriseId }) => {\n const domains = await ctx.db\n .query(\"EnterpriseDomain\")\n .withIndex(\"enterprise_id\", (idx) => idx.eq(\"enterpriseId\", enterpriseId))\n .collect();\n for (const domain of domains) {\n const verification = await ctx.db\n .query(\"EnterpriseDomainVerification\")\n .withIndex(\"domain_id\", (idx) => idx.eq(\"domainId\", domain._id))\n .first();\n if (verification) {\n await ctx.db.delete(verification._id);\n }\n await ctx.db.delete(domain._id);\n }\n const secrets = await ctx.db\n .query(\"EnterpriseSecret\")\n .withIndex(\"enterprise_id\", (idx) => idx.eq(\"enterpriseId\", enterpriseId))\n .collect();\n for (const secret of secrets) {\n await ctx.db.delete(secret._id);\n }\n await ctx.db.delete(enterpriseId);\n return null;\n },\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCA,MAAa,mBAAmB,SAAS;CACvC,MAAM;EACJ,SAAS,EAAE,GAAG,QAAQ;EACtB,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC;EAC5B,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC;EAC5B,QAAQ,EAAE,SAAS,kBAAkB;EACrC,QAAQ,EAAE,SAAS,kBAAkB;EACrC,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC;EAC3B,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC;EAC5B;CACD,SAAS,EAAE,GAAG,aAAa;CAC3B,SAAS,OAAO,KAAK,SAAS;AAK5B,MAJiB,MAAM,IAAI,GACxB,MAAM,aAAa,CACnB,UAAU,aAAa,QAAQ,IAAI,GAAG,WAAW,KAAK,QAAQ,CAAC,CAC/D,OAAO,CAER,OAAM,IAAI,YAAY;GACpB,MAAM;GACN,SAAS;GACV,CAAC;AAEJ,SAAO,MAAM,IAAI,GAAG,OAAO,cAAc;GACvC,GAAG;GACH,QAAQ,KAAK,UAAU;GACxB,CAAC;;CAEL,CAAC;;;;;;;;;;;;;;;;;;;;;AAsBF,MAAa,gBAAgB,MAAM;CACjC,MAAM,EAAE,cAAc,EAAE,GAAG,aAAa,EAAE;CAC1C,SAAS,EAAE,MAAM,gBAAgB,EAAE,MAAM,CAAC;CAC1C,SAAS,OAAO,KAAK,EAAE,mBAAmB;AACxC,SAAO,MAAM,IAAI,GAAG,IAAI,cAAc,aAAa;;CAEtD,CAAC;;;;;;;;;;;;;;;;;;AAmBF,MAAa,uBAAuB,MAAM;CACxC,MAAM,EAAE,SAAS,EAAE,GAAG,QAAQ,EAAE;CAChC,SAAS,EAAE,MAAM,gBAAgB,EAAE,MAAM,CAAC;CAC1C,SAAS,OAAO,KAAK,EAAE,cAAc;AACnC,SAAO,MAAM,IAAI,GACd,MAAM,aAAa,CACnB,UAAU,aAAa,QAAQ,IAAI,GAAG,WAAW,QAAQ,CAAC,CAC1D,OAAO;;CAEb,CAAC;;;;;;;;;;;;;;;;;;;;;;;AAwBF,MAAa,wBAAwB,MAAM;CACzC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE;CAC5B,SAAS,EAAE,MACT,EAAE,OAAO;EACP,YAAY;EACZ,QAAQ;EACT,CAAC,EACF,EAAE,MAAM,CACT;CACD,SAAS,OAAO,KAAK,EAAE,aAAa;EAClC,MAAM,YAAY,MAAM,IAAI,GACzB,MAAM,mBAAmB,CACzB,UAAU,WAAW,QAAQ,IAAI,GAAG,UAAU,OAAO,CAAC,CACtD,OAAO;AACV,MAAI,CAAC,UACH,QAAO;EAET,MAAM,aAAa,MAAM,IAAI,GAAG,IAAI,cAAc,UAAU,aAAa;AACzE,MAAI,CAAC,WACH,QAAO;AAET,SAAO;GAAE;GAAY,QAAQ;GAAW;;CAE3C,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCF,MAAa,iBAAiB,MAAM;CAClC,MAAM;EACJ,OAAO,EAAE,SACP,EAAE,OAAO;GACP,SAAS,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC;GAClC,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC;GAC5B,QAAQ,EAAE,SAAS,kBAAkB;GACtC,CAAC,CACH;EACD,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC;EAC7B,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,MAAM,CAAC,CAAC;EACjD,SAAS,EAAE,SACT,EAAE,MACA,EAAE,QAAQ,gBAAgB,EAC1B,EAAE,QAAQ,OAAO,EACjB,EAAE,QAAQ,OAAO,EACjB,EAAE,QAAQ,SAAS,CACpB,CACF;EACD,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,MAAM,EAAE,EAAE,QAAQ,OAAO,CAAC,CAAC;EAChE;CACD,SAAS,WAAW,eAAe;CACnC,SAAS,OAAO,KAAK,SAAS;EAC5B,MAAM,QAAQ,KAAK,SAAS,EAAE;EAC9B,MAAM,QAAQ,KAAK,IAAI,KAAK,IAAI,KAAK,SAAS,IAAI,EAAE,EAAE,IAAI;EAC1D,MAAM,QAAQ,KAAK,SAAS;EAE5B,IAAI;AACJ,MAAI,MAAM,YAAY,OACpB,KAAI,IAAI,GACL,MAAM,aAAa,CACnB,UAAU,aAAa,QAAQ,IAAI,GAAG,WAAW,MAAM,QAAS,CAAC;WAC3D,MAAM,SAAS,OACxB,KAAI,IAAI,GACL,MAAM,aAAa,CACnB,UAAU,SAAS,QAAQ,IAAI,GAAG,QAAQ,MAAM,KAAM,CAAC;WACjD,MAAM,WAAW,OAC1B,KAAI,IAAI,GACL,MAAM,aAAa,CACnB,UAAU,WAAW,QAAQ,IAAI,GAAG,UAAU,MAAM,OAAQ,CAAC;MAEhE,KAAI,IAAI,GAAG,MAAM,aAAa;AAGhC,MAAI,MAAM,YAAY,UAAa,MAAM,SAAS,OAChD,KAAI,EAAE,QAAQ,MAAM,EAAE,GAAG,EAAE,MAAM,OAAO,EAAE,MAAM,KAAM,CAAC;AAEzD,MAAI,MAAM,WAAW,UAAa,MAAM,YAAY,QAAW,YAEpD,MAAM,WAAW,OAC1B,KAAI,EAAE,QAAQ,MAAM,EAAE,GAAG,EAAE,MAAM,SAAS,EAAE,MAAM,OAAQ,CAAC;AAG7D,MAAI,EAAE,MAAM,MAAM;EAClB,MAAM,MAAM,MAAM,EAAE,SAAS;EAC7B,IAAI,WAAW;AACf,MAAI,KAAK,QAAQ;GACf,MAAM,YAAY,IAAI,WAAW,QAAQ,IAAI,QAAQ,KAAK,OAAO;AACjE,OAAI,cAAc,GAChB,YAAW,YAAY;;EAG3B,MAAM,OAAO,IAAI,MAAM,UAAU,WAAW,QAAQ,EAAE;EACtD,MAAM,UAAU,KAAK,SAAS;EAC9B,MAAM,QAAQ,UAAU,KAAK,MAAM,GAAG,MAAM,GAAG;AAE/C,SAAO;GAAE;GAAO,YADG,UAAU,MAAM,MAAM,SAAS,GAAG,MAAM;GAC/B;;CAE/B,CAAC;;;;;;;;;;;;;;;;;;;;;;AAuBF,MAAa,mBAAmB,SAAS;CACvC,MAAM;EAAE,cAAc,EAAE,GAAG,aAAa;EAAE,MAAM,EAAE,KAAK;EAAE;CACzD,SAAS,EAAE,MAAM;CACjB,SAAS,OAAO,KAAK,EAAE,cAAc,WAAW;AAC9C,QAAM,IAAI,GAAG,MAAM,cAAc,KAAK;AACtC,SAAO;;CAEV,CAAC;;;;;;;;;;;;;;;;;;;;AAqBF,MAAa,mBAAmB,SAAS;CACvC,MAAM,EAAE,cAAc,EAAE,GAAG,aAAa,EAAE;CAC1C,SAAS,EAAE,MAAM;CACjB,SAAS,OAAO,KAAK,EAAE,mBAAmB;EACxC,MAAM,UAAU,MAAM,IAAI,GACvB,MAAM,mBAAmB,CACzB,UAAU,kBAAkB,QAAQ,IAAI,GAAG,gBAAgB,aAAa,CAAC,CACzE,SAAS;AACZ,OAAK,MAAM,UAAU,SAAS;GAC5B,MAAM,eAAe,MAAM,IAAI,GAC5B,MAAM,+BAA+B,CACrC,UAAU,cAAc,QAAQ,IAAI,GAAG,YAAY,OAAO,IAAI,CAAC,CAC/D,OAAO;AACV,OAAI,aACF,OAAM,IAAI,GAAG,OAAO,aAAa,IAAI;AAEvC,SAAM,IAAI,GAAG,OAAO,OAAO,IAAI;;EAEjC,MAAM,UAAU,MAAM,IAAI,GACvB,MAAM,mBAAmB,CACzB,UAAU,kBAAkB,QAAQ,IAAI,GAAG,gBAAgB,aAAa,CAAC,CACzE,SAAS;AACZ,OAAK,MAAM,UAAU,QACnB,OAAM,IAAI,GAAG,OAAO,OAAO,IAAI;AAEjC,QAAM,IAAI,GAAG,OAAO,aAAa;AACjC,SAAO;;CAEV,CAAC"}
|