@lupinum/better-convex-nuxt 0.8.0-beta.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (268) hide show
  1. package/LICENSE +21 -0
  2. package/LICENSES/Apache-2.0.txt +201 -0
  3. package/README.md +151 -0
  4. package/THIRD_PARTY_NOTICES.md +38 -0
  5. package/dist/module.d.mts +55 -0
  6. package/dist/module.json +12 -0
  7. package/dist/module.mjs +309 -0
  8. package/dist/runtime/auth/auth-identity.d.ts +31 -0
  9. package/dist/runtime/auth/auth-identity.js +21 -0
  10. package/dist/runtime/auth/better-auth-browser-adapter.d.ts +33 -0
  11. package/dist/runtime/auth/better-auth-browser-adapter.js +215 -0
  12. package/dist/runtime/auth/client-engine-types.d.ts +4 -0
  13. package/dist/runtime/auth/client-engine-types.js +0 -0
  14. package/dist/runtime/auth/integrated-client.d.ts +25 -0
  15. package/dist/runtime/auth/integrated-client.js +132 -0
  16. package/dist/runtime/auth/operation-tracker.d.ts +7 -0
  17. package/dist/runtime/auth/operation-tracker.js +14 -0
  18. package/dist/runtime/auth/session-synchronization.d.ts +23 -0
  19. package/dist/runtime/auth/session-synchronization.js +156 -0
  20. package/dist/runtime/auth/token-fetcher.d.ts +66 -0
  21. package/dist/runtime/auth/token-fetcher.js +131 -0
  22. package/dist/runtime/auth/validate-auth-client-definition.d.ts +12 -0
  23. package/dist/runtime/auth/validate-auth-client-definition.js +47 -0
  24. package/dist/runtime/auth-client/convex-client-plugin.d.ts +31 -0
  25. package/dist/runtime/auth-client/convex-client-plugin.js +14 -0
  26. package/dist/runtime/auth-client/definition-types.d.ts +6 -0
  27. package/dist/runtime/auth-client/definition-types.js +0 -0
  28. package/dist/runtime/auth-client/empty-definition.d.ts +2 -0
  29. package/dist/runtime/auth-client/empty-definition.js +2 -0
  30. package/dist/runtime/auth-client/index.d.ts +71 -0
  31. package/dist/runtime/auth-client/index.js +3 -0
  32. package/dist/runtime/cli/auth-schema.d.ts +2 -0
  33. package/dist/runtime/cli/auth-schema.js +169 -0
  34. package/dist/runtime/cli/convex.d.ts +11 -0
  35. package/dist/runtime/cli/convex.js +274 -0
  36. package/dist/runtime/composables/useConvex.d.ts +4 -0
  37. package/dist/runtime/composables/useConvex.js +9 -0
  38. package/dist/runtime/composables/useConvexAction.d.ts +4 -0
  39. package/dist/runtime/composables/useConvexAction.js +18 -0
  40. package/dist/runtime/composables/useConvexAttachment.d.ts +9 -0
  41. package/dist/runtime/composables/useConvexAttachment.js +14 -0
  42. package/dist/runtime/composables/useConvexAuth.d.ts +10 -0
  43. package/dist/runtime/composables/useConvexAuth.js +37 -0
  44. package/dist/runtime/composables/useConvexConfig.d.ts +12 -0
  45. package/dist/runtime/composables/useConvexConfig.js +7 -0
  46. package/dist/runtime/composables/useConvexConnectionState.d.ts +33 -0
  47. package/dist/runtime/composables/useConvexConnectionState.js +24 -0
  48. package/dist/runtime/composables/useConvexFileUpload.d.ts +169 -0
  49. package/dist/runtime/composables/useConvexFileUpload.js +198 -0
  50. package/dist/runtime/composables/useConvexMutation.d.ts +13 -0
  51. package/dist/runtime/composables/useConvexMutation.js +24 -0
  52. package/dist/runtime/composables/useConvexPaginatedQuery.d.ts +13 -0
  53. package/dist/runtime/composables/useConvexPaginatedQuery.js +256 -0
  54. package/dist/runtime/composables/useConvexQuery.d.ts +19 -0
  55. package/dist/runtime/composables/useConvexQuery.js +308 -0
  56. package/dist/runtime/convex-auth/adapter/create-adapter.d.ts +33 -0
  57. package/dist/runtime/convex-auth/adapter/create-adapter.js +308 -0
  58. package/dist/runtime/convex-auth/adapter/define-functions.d.ts +160 -0
  59. package/dist/runtime/convex-auth/adapter/define-functions.js +497 -0
  60. package/dist/runtime/convex-auth/adapter/generate-schema.d.ts +16 -0
  61. package/dist/runtime/convex-auth/adapter/generate-schema.js +332 -0
  62. package/dist/runtime/convex-auth/adapter/metadata.d.ts +44 -0
  63. package/dist/runtime/convex-auth/adapter/metadata.js +91 -0
  64. package/dist/runtime/convex-auth/adapter/query.d.ts +32 -0
  65. package/dist/runtime/convex-auth/adapter/query.js +275 -0
  66. package/dist/runtime/convex-auth/adapter/relationships.d.ts +20 -0
  67. package/dist/runtime/convex-auth/adapter/relationships.js +128 -0
  68. package/dist/runtime/convex-auth/component/_generated/api.js +5 -0
  69. package/dist/runtime/convex-auth/component/_generated/component.d.ts +116 -0
  70. package/dist/runtime/convex-auth/component/_generated/component.js +0 -0
  71. package/dist/runtime/convex-auth/component/_generated/dataModel.js +0 -0
  72. package/dist/runtime/convex-auth/component/_generated/server.js +16 -0
  73. package/dist/runtime/convex-auth/component/adapter.d.ts +142 -0
  74. package/dist/runtime/convex-auth/component/adapter.js +16 -0
  75. package/dist/runtime/convex-auth/component/convex.config.d.ts +2 -0
  76. package/dist/runtime/convex-auth/component/convex.config.js +3 -0
  77. package/dist/runtime/convex-auth/component/schema.d.ts +799 -0
  78. package/dist/runtime/convex-auth/component/schema.js +180 -0
  79. package/dist/runtime/convex-auth/component/schemaMetadata.d.ts +2094 -0
  80. package/dist/runtime/convex-auth/component/schemaMetadata.js +2161 -0
  81. package/dist/runtime/convex-auth/context.d.ts +5 -0
  82. package/dist/runtime/convex-auth/context.js +8 -0
  83. package/dist/runtime/convex-auth/create-auth-component.d.ts +41 -0
  84. package/dist/runtime/convex-auth/create-auth-component.js +157 -0
  85. package/dist/runtime/convex-auth/index.d.ts +11 -0
  86. package/dist/runtime/convex-auth/index.js +7 -0
  87. package/dist/runtime/convex-auth/internal-session.d.ts +2 -0
  88. package/dist/runtime/convex-auth/internal-session.js +1 -0
  89. package/dist/runtime/convex-auth/jwks-rotation.d.ts +58 -0
  90. package/dist/runtime/convex-auth/jwks-rotation.js +163 -0
  91. package/dist/runtime/convex-auth/oauth-live-access.d.ts +17 -0
  92. package/dist/runtime/convex-auth/oauth-live-access.js +78 -0
  93. package/dist/runtime/convex-auth/oauth-provider-compat.d.ts +10 -0
  94. package/dist/runtime/convex-auth/oauth-provider-compat.js +170 -0
  95. package/dist/runtime/convex-auth/oauth-resource.d.ts +39 -0
  96. package/dist/runtime/convex-auth/oauth-resource.js +118 -0
  97. package/dist/runtime/convex-auth/oauth-security.d.ts +82 -0
  98. package/dist/runtime/convex-auth/oauth-security.js +454 -0
  99. package/dist/runtime/convex-auth/origin.d.ts +4 -0
  100. package/dist/runtime/convex-auth/origin.js +9 -0
  101. package/dist/runtime/convex-auth/plugin.d.ts +18 -0
  102. package/dist/runtime/convex-auth/plugin.js +605 -0
  103. package/dist/runtime/convex-auth/provider.d.ts +2 -0
  104. package/dist/runtime/convex-auth/provider.js +11 -0
  105. package/dist/runtime/convex-auth/test.d.ts +410 -0
  106. package/dist/runtime/convex-auth/test.js +9 -0
  107. package/dist/runtime/convex-auth/types.d.ts +18 -0
  108. package/dist/runtime/convex-auth/types.js +0 -0
  109. package/dist/runtime/convex-auth/user-projection.d.ts +106 -0
  110. package/dist/runtime/convex-auth/user-projection.js +128 -0
  111. package/dist/runtime/devtools/auth-proxy-registry.d.ts +4 -0
  112. package/dist/runtime/devtools/auth-proxy-registry.js +47 -0
  113. package/dist/runtime/devtools/bridge-setup.d.ts +21 -0
  114. package/dist/runtime/devtools/bridge-setup.js +165 -0
  115. package/dist/runtime/devtools/path-utils.d.ts +2 -0
  116. package/dist/runtime/devtools/path-utils.js +12 -0
  117. package/dist/runtime/devtools/server.d.ts +2 -0
  118. package/dist/runtime/devtools/server.js +108 -0
  119. package/dist/runtime/devtools/setup-client.d.ts +16 -0
  120. package/dist/runtime/devtools/setup-client.js +43 -0
  121. package/dist/runtime/devtools/sink.d.ts +18 -0
  122. package/dist/runtime/devtools/sink.js +110 -0
  123. package/dist/runtime/devtools/transport.d.ts +16 -0
  124. package/dist/runtime/devtools/transport.js +149 -0
  125. package/dist/runtime/devtools/types.d.ts +167 -0
  126. package/dist/runtime/devtools/types.js +1 -0
  127. package/dist/runtime/devtools/ui/dist/200.html +1 -0
  128. package/dist/runtime/devtools/ui/dist/404.html +1 -0
  129. package/dist/runtime/devtools/ui/dist/_nuxt/C4MASuCh.js +1 -0
  130. package/dist/runtime/devtools/ui/dist/_nuxt/DJHkqtZq.js +3 -0
  131. package/dist/runtime/devtools/ui/dist/_nuxt/DWwrCltl.js +2 -0
  132. package/dist/runtime/devtools/ui/dist/_nuxt/DZ_UiYoH.js +1 -0
  133. package/dist/runtime/devtools/ui/dist/_nuxt/_m9ujb-i.js +1 -0
  134. package/dist/runtime/devtools/ui/dist/_nuxt/builds/latest.json +1 -0
  135. package/dist/runtime/devtools/ui/dist/_nuxt/builds/meta/better-convex-nuxt-devtools.json +1 -0
  136. package/dist/runtime/devtools/ui/dist/_nuxt/entry.DpFDKYZ5.css +1 -0
  137. package/dist/runtime/devtools/ui/dist/_nuxt/error-404.DYUJo5xt.css +1 -0
  138. package/dist/runtime/devtools/ui/dist/_nuxt/error-500.DQdoJJXg.css +1 -0
  139. package/dist/runtime/devtools/ui/dist/convex-logo.svg +5 -0
  140. package/dist/runtime/devtools/ui/dist/index.html +1 -0
  141. package/dist/runtime/errors/index.d.ts +7 -0
  142. package/dist/runtime/errors/index.js +5 -0
  143. package/dist/runtime/middleware/convex-auth.global.d.ts +2 -0
  144. package/dist/runtime/middleware/convex-auth.global.js +31 -0
  145. package/dist/runtime/plugin.auth.client.d.ts +3 -0
  146. package/dist/runtime/plugin.auth.client.js +217 -0
  147. package/dist/runtime/plugin.client.d.ts +3 -0
  148. package/dist/runtime/plugin.client.js +43 -0
  149. package/dist/runtime/plugin.server.d.ts +12 -0
  150. package/dist/runtime/plugin.server.js +98 -0
  151. package/dist/runtime/plugins/convex-call-error-payload.d.ts +14 -0
  152. package/dist/runtime/plugins/convex-call-error-payload.js +12 -0
  153. package/dist/runtime/runtime-context.d.ts +26 -0
  154. package/dist/runtime/runtime-context.js +48 -0
  155. package/dist/runtime/server/api/auth/[...].d.ts +10 -0
  156. package/dist/runtime/server/api/auth/[...].js +509 -0
  157. package/dist/runtime/server/api/auth/authorization-server-metadata.d.ts +2 -0
  158. package/dist/runtime/server/api/auth/authorization-server-metadata.js +6 -0
  159. package/dist/runtime/server/api/auth/body-size.d.ts +15 -0
  160. package/dist/runtime/server/api/auth/body-size.js +179 -0
  161. package/dist/runtime/server/api/auth/headers.d.ts +6 -0
  162. package/dist/runtime/server/api/auth/headers.js +98 -0
  163. package/dist/runtime/server/api/auth/jwks.d.ts +2 -0
  164. package/dist/runtime/server/api/auth/jwks.js +6 -0
  165. package/dist/runtime/server/api/auth/security.d.ts +14 -0
  166. package/dist/runtime/server/api/auth/security.js +85 -0
  167. package/dist/runtime/server/api/release-fingerprint.d.ts +2 -0
  168. package/dist/runtime/server/api/release-fingerprint.js +36 -0
  169. package/dist/runtime/server/index.d.ts +1 -0
  170. package/dist/runtime/server/index.js +3 -0
  171. package/dist/runtime/server/plugins/runtime-config.d.ts +7 -0
  172. package/dist/runtime/server/plugins/runtime-config.js +7 -0
  173. package/dist/runtime/server/utils/auth-snapshot.d.ts +26 -0
  174. package/dist/runtime/server/utils/auth-snapshot.js +165 -0
  175. package/dist/runtime/server/utils/http.d.ts +16 -0
  176. package/dist/runtime/server/utils/http.js +133 -0
  177. package/dist/runtime/server/utils/server-convex-caller.d.ts +31 -0
  178. package/dist/runtime/server/utils/server-convex-caller.js +151 -0
  179. package/dist/runtime/server/utils/server-convex-options.d.ts +83 -0
  180. package/dist/runtime/server/utils/server-convex-options.js +69 -0
  181. package/dist/runtime/server/utils/signed-client-ip.d.ts +6 -0
  182. package/dist/runtime/server/utils/signed-client-ip.js +29 -0
  183. package/dist/runtime/server/utils/ssr-auth-headers.d.ts +26 -0
  184. package/dist/runtime/server/utils/ssr-auth-headers.js +49 -0
  185. package/dist/runtime/server/utils/token-exchange.d.ts +27 -0
  186. package/dist/runtime/server/utils/token-exchange.js +96 -0
  187. package/dist/runtime/shared/auth-cookie.d.ts +4 -0
  188. package/dist/runtime/shared/auth-cookie.js +25 -0
  189. package/dist/runtime/shared/auth-origin.d.ts +15 -0
  190. package/dist/runtime/shared/auth-origin.js +42 -0
  191. package/dist/runtime/shared/bounded-stream.d.ts +2 -0
  192. package/dist/runtime/shared/bounded-stream.js +50 -0
  193. package/dist/runtime/shared/client-ip.d.ts +21 -0
  194. package/dist/runtime/shared/client-ip.js +123 -0
  195. package/dist/runtime/shared/release-fingerprint.d.ts +5 -0
  196. package/dist/runtime/shared/release-fingerprint.js +17 -0
  197. package/dist/runtime/types.d.ts +19 -0
  198. package/dist/runtime/utils/auth-config.d.ts +24 -0
  199. package/dist/runtime/utils/auth-config.js +45 -0
  200. package/dist/runtime/utils/auth-contract.d.ts +22 -0
  201. package/dist/runtime/utils/auth-contract.js +0 -0
  202. package/dist/runtime/utils/auth-errors.d.ts +5 -0
  203. package/dist/runtime/utils/auth-errors.js +22 -0
  204. package/dist/runtime/utils/auth-identity-state.d.ts +4 -0
  205. package/dist/runtime/utils/auth-identity-state.js +8 -0
  206. package/dist/runtime/utils/auth-pending-state.d.ts +13 -0
  207. package/dist/runtime/utils/auth-pending-state.js +4 -0
  208. package/dist/runtime/utils/auth-pending.d.ts +10 -0
  209. package/dist/runtime/utils/auth-pending.js +30 -0
  210. package/dist/runtime/utils/auth-route-protection.d.ts +16 -0
  211. package/dist/runtime/utils/auth-route-protection.js +58 -0
  212. package/dist/runtime/utils/auth-status.d.ts +47 -0
  213. package/dist/runtime/utils/auth-status.js +8 -0
  214. package/dist/runtime/utils/bounded-convex-fetch.d.ts +18 -0
  215. package/dist/runtime/utils/bounded-convex-fetch.js +152 -0
  216. package/dist/runtime/utils/callable-devtools.d.ts +17 -0
  217. package/dist/runtime/utils/callable-devtools.js +49 -0
  218. package/dist/runtime/utils/callable-observer.d.ts +2 -0
  219. package/dist/runtime/utils/callable-observer.js +1 -0
  220. package/dist/runtime/utils/composable-scope.d.ts +2 -0
  221. package/dist/runtime/utils/composable-scope.js +8 -0
  222. package/dist/runtime/utils/config-defaults.d.ts +8 -0
  223. package/dist/runtime/utils/config-defaults.js +8 -0
  224. package/dist/runtime/utils/convex-cache.d.ts +68 -0
  225. package/dist/runtime/utils/convex-cache.js +47 -0
  226. package/dist/runtime/utils/convex-config.d.ts +16 -0
  227. package/dist/runtime/utils/convex-config.js +50 -0
  228. package/dist/runtime/utils/convex-shared.d.ts +67 -0
  229. package/dist/runtime/utils/convex-shared.js +134 -0
  230. package/dist/runtime/utils/identity-changed-error.d.ts +4 -0
  231. package/dist/runtime/utils/identity-changed-error.js +12 -0
  232. package/dist/runtime/utils/identity-key.d.ts +19 -0
  233. package/dist/runtime/utils/identity-key.js +10 -0
  234. package/dist/runtime/utils/integrated-auth-client.d.ts +5 -0
  235. package/dist/runtime/utils/integrated-auth-client.js +0 -0
  236. package/dist/runtime/utils/logger.d.ts +42 -0
  237. package/dist/runtime/utils/logger.js +190 -0
  238. package/dist/runtime/utils/mime-type.d.ts +33 -0
  239. package/dist/runtime/utils/mime-type.js +10 -0
  240. package/dist/runtime/utils/query-execution-gate.d.ts +47 -0
  241. package/dist/runtime/utils/query-execution-gate.js +63 -0
  242. package/dist/runtime/utils/query-execution.d.ts +8 -0
  243. package/dist/runtime/utils/query-execution.js +19 -0
  244. package/dist/runtime/utils/query-foundation.d.ts +20 -0
  245. package/dist/runtime/utils/query-foundation.js +39 -0
  246. package/dist/runtime/utils/query-state.d.ts +12 -0
  247. package/dist/runtime/utils/query-state.js +12 -0
  248. package/dist/runtime/utils/reactive-args.d.ts +5 -0
  249. package/dist/runtime/utils/reactive-args.js +42 -0
  250. package/dist/runtime/utils/runtime-config-normalize.d.ts +22 -0
  251. package/dist/runtime/utils/runtime-config-normalize.js +28 -0
  252. package/dist/runtime/utils/runtime-config.d.ts +4 -0
  253. package/dist/runtime/utils/runtime-config.js +8 -0
  254. package/dist/runtime/utils/sanitize-diagnostic.d.ts +6 -0
  255. package/dist/runtime/utils/sanitize-diagnostic.js +81 -0
  256. package/dist/runtime/utils/shared-helpers.d.ts +46 -0
  257. package/dist/runtime/utils/shared-helpers.js +139 -0
  258. package/dist/runtime/utils/site-url.d.ts +4 -0
  259. package/dist/runtime/utils/site-url.js +15 -0
  260. package/dist/runtime/utils/ssr-pagination-state.d.ts +3 -0
  261. package/dist/runtime/utils/ssr-pagination-state.js +3 -0
  262. package/dist/runtime/utils/types.d.ts +29 -0
  263. package/dist/runtime/utils/types.js +0 -0
  264. package/dist/runtime/utils/upload-core.d.ts +16 -0
  265. package/dist/runtime/utils/upload-core.js +116 -0
  266. package/dist/types.d.mts +21 -0
  267. package/package.json +253 -0
  268. package/security/upstream-convex-better-auth.json +477 -0
@@ -0,0 +1,5 @@
1
+ import type { GenericActionCtx, GenericDataModel, GenericMutationCtx, GenericQueryCtx } from 'convex/server';
2
+ export type AuthCtx<DataModel extends GenericDataModel = GenericDataModel> = GenericQueryCtx<DataModel> | GenericMutationCtx<DataModel> | GenericActionCtx<DataModel>;
3
+ export type WritableAuthCtx<DataModel extends GenericDataModel = GenericDataModel> = GenericMutationCtx<DataModel> | GenericActionCtx<DataModel>;
4
+ export declare function isWritableAuthCtx<DataModel extends GenericDataModel>(ctx: AuthCtx<DataModel>): ctx is WritableAuthCtx<DataModel>;
5
+ export declare function requireWritableAuthCtx<DataModel extends GenericDataModel>(ctx: AuthCtx<DataModel>): asserts ctx is WritableAuthCtx<DataModel>;
@@ -0,0 +1,8 @@
1
+ export function isWritableAuthCtx(ctx) {
2
+ return "runMutation" in ctx && typeof ctx.runMutation === "function";
3
+ }
4
+ export function requireWritableAuthCtx(ctx) {
5
+ if (!isWritableAuthCtx(ctx)) {
6
+ throw new Error("AUTH_WRITE_REQUIRES_MUTATION_OR_ACTION");
7
+ }
8
+ }
@@ -0,0 +1,41 @@
1
+ import { type GenericDataModel, type HttpRouter } from 'convex/server';
2
+ import type { AuthCtx, WritableAuthCtx } from './context.js';
3
+ import { type OAuthLiveAccess } from './oauth-live-access.js';
4
+ import type { AuthAdapterComponentApi, AuthComponentTriggers, AuthFunctions, CreateAuth } from './types.js';
5
+ interface CreateAuthComponentOptions<DataModel extends GenericDataModel> {
6
+ authFunctions?: AuthFunctions;
7
+ triggers?: AuthComponentTriggers<DataModel>;
8
+ }
9
+ export declare function createAuthComponent<DataModel extends GenericDataModel, Api extends AuthAdapterComponentApi = AuthAdapterComponentApi>(component: Api, options?: CreateAuthComponentOptions<DataModel>): {
10
+ adapter: (ctx: AuthCtx<DataModel>) => import("better-auth/adapters").AdapterFactory<import("better-auth").BetterAuthOptions>;
11
+ safeGetAuthUser: (ctx: AuthCtx<DataModel>) => Promise<Record<string, unknown> | null>;
12
+ getAuthUser: (ctx: AuthCtx<DataModel>) => Promise<Record<string, unknown>>;
13
+ validateOAuthAccess: (ctx: AuthCtx<DataModel>, access: OAuthLiveAccess) => Promise<boolean>;
14
+ getAuth: <Auth>(createAuth: CreateAuth<DataModel, Auth>, ctx: WritableAuthCtx<DataModel>) => Promise<{
15
+ auth: Awaited<Auth>;
16
+ headers: Headers;
17
+ }>;
18
+ triggerFunctions: () => {
19
+ onCreate: import("convex/server").RegisteredMutation<"internal", {
20
+ model: string;
21
+ doc: any;
22
+ }, Promise<void | undefined>>;
23
+ onDelete: import("convex/server").RegisteredMutation<"internal", {
24
+ model: string;
25
+ doc: any;
26
+ }, Promise<void | undefined>>;
27
+ onUpdate: import("convex/server").RegisteredMutation<"internal", {
28
+ model: string;
29
+ newDoc: any;
30
+ oldDoc: any;
31
+ }, Promise<void | undefined>>;
32
+ };
33
+ jwksOperatorFunctions: <Auth>(createAuth: CreateAuth<DataModel, Auth>) => {
34
+ rotateSigningKey: import("convex/server").RegisteredAction<"internal", {}, Promise<import("./jwks-rotation.js").SigningKeyRotationMetadata>>;
35
+ };
36
+ registerRoutes: <Auth extends {
37
+ $context: Promise<unknown>;
38
+ handler: (request: Request) => Promise<Response>;
39
+ }>(http: HttpRouter, createAuth: CreateAuth<DataModel, Auth>) => void;
40
+ };
41
+ export {};
@@ -0,0 +1,157 @@
1
+ import {
2
+ httpActionGeneric,
3
+ internalActionGeneric,
4
+ internalMutationGeneric
5
+ } from "convex/server";
6
+ import { ConvexError, v } from "convex/values";
7
+ import {
8
+ CLIENT_IP_HEADER,
9
+ CLIENT_IP_SIGNATURE_HEADER,
10
+ VERIFIED_CLIENT_IP_HEADER,
11
+ normalizeClientIp,
12
+ verifySignedClientIp
13
+ } from "../shared/client-ip.js";
14
+ import { createConvexAuthAdapter } from "./adapter/create-adapter.js";
15
+ import { INTERNAL_SESSION_HEADER } from "./internal-session.js";
16
+ import { rotateSigningKeyWithOfficialJwt } from "./jwks-rotation.js";
17
+ import { validateOAuthAccess } from "./oauth-live-access.js";
18
+ import { requireAuthOrigin } from "./origin.js";
19
+ function rewriteToPublicOrigin(request, publicOrigin, verifiedClientIp) {
20
+ const incoming = new URL(request.url);
21
+ const target = new URL(publicOrigin);
22
+ target.pathname = incoming.pathname;
23
+ target.search = incoming.search;
24
+ const headers = new Headers(request.headers);
25
+ for (const name of [...headers.keys()]) {
26
+ if (name.toLowerCase().startsWith("x-bcn-")) headers.delete(name);
27
+ }
28
+ headers.set(VERIFIED_CLIENT_IP_HEADER, verifiedClientIp);
29
+ return new Request(new Request(target, request), { headers });
30
+ }
31
+ async function resolveVerifiedClientIp(request, getDirectClientIp, proxyIpSecret) {
32
+ const clientIp = request.headers.get(CLIENT_IP_HEADER);
33
+ const signature = request.headers.get(CLIENT_IP_SIGNATURE_HEADER);
34
+ if (clientIp === null && signature === null) {
35
+ const directClientIp = normalizeClientIp(await getDirectClientIp());
36
+ if (!directClientIp) throw new TypeError("Trusted request metadata did not contain a client IP");
37
+ return directClientIp;
38
+ }
39
+ const forwardedClientIp = await verifySignedClientIp(clientIp, signature, proxyIpSecret);
40
+ if (!forwardedClientIp) {
41
+ throw new TypeError("Signed client IP headers are incomplete or invalid");
42
+ }
43
+ return forwardedClientIp;
44
+ }
45
+ function identityClaim(identity, name) {
46
+ const value = identity[name];
47
+ return typeof value === "string" && value.length > 0 ? value : void 0;
48
+ }
49
+ export function createAuthComponent(component, options = {}) {
50
+ const safeGetAuthSession = async (ctx) => {
51
+ const identity = await ctx.auth.getUserIdentity();
52
+ if (!identity) return null;
53
+ const claims = identity;
54
+ if (identityClaim(claims, "token_use") !== "convex-session") return null;
55
+ const sessionId = identityClaim(claims, "sid");
56
+ if (!sessionId) return null;
57
+ const session = await ctx.runQuery(component.adapter.findOne, {
58
+ model: "session",
59
+ where: [
60
+ { field: "id", value: sessionId },
61
+ { field: "userId", value: identity.subject },
62
+ { field: "expiresAt", operator: "gt", value: Date.now() }
63
+ ]
64
+ });
65
+ return session ? { identity, session } : null;
66
+ };
67
+ const safeGetAuthUser = async (ctx) => {
68
+ const authenticated = await safeGetAuthSession(ctx);
69
+ if (!authenticated) return null;
70
+ return await ctx.runQuery(component.adapter.findOne, {
71
+ model: "user",
72
+ where: [{ field: "id", value: authenticated.identity.subject }]
73
+ });
74
+ };
75
+ return {
76
+ adapter: (ctx) => createConvexAuthAdapter(ctx, component, {
77
+ authFunctions: options.authFunctions,
78
+ triggers: options.triggers
79
+ }),
80
+ safeGetAuthUser,
81
+ getAuthUser: async (ctx) => {
82
+ const user = await safeGetAuthUser(ctx);
83
+ if (!user) throw new ConvexError("Unauthenticated");
84
+ return user;
85
+ },
86
+ validateOAuthAccess: (ctx, access) => validateOAuthAccess(ctx, component, access),
87
+ getAuth: async (createAuth, ctx) => {
88
+ const authenticated = await safeGetAuthSession(ctx);
89
+ if (!authenticated || typeof authenticated.session.token !== "string") {
90
+ throw new ConvexError("Unauthenticated");
91
+ }
92
+ const auth = await createAuth(ctx);
93
+ if (auth && typeof auth === "object" && "$context" in auth) {
94
+ await auth.$context;
95
+ }
96
+ return {
97
+ auth,
98
+ headers: new Headers({
99
+ authorization: `Bearer ${authenticated.session.token}`,
100
+ [INTERNAL_SESSION_HEADER]: "1"
101
+ })
102
+ };
103
+ },
104
+ triggerFunctions: () => ({
105
+ onCreate: internalMutationGeneric({
106
+ args: { doc: v.any(), model: v.string() },
107
+ handler: async (ctx, args) => options.triggers?.[args.model]?.onCreate?.(ctx, args.doc)
108
+ }),
109
+ onDelete: internalMutationGeneric({
110
+ args: { doc: v.any(), model: v.string() },
111
+ handler: async (ctx, args) => options.triggers?.[args.model]?.onDelete?.(ctx, args.doc)
112
+ }),
113
+ onUpdate: internalMutationGeneric({
114
+ args: { model: v.string(), newDoc: v.any(), oldDoc: v.any() },
115
+ handler: async (ctx, args) => options.triggers?.[args.model]?.onUpdate?.(ctx, args.newDoc, args.oldDoc)
116
+ })
117
+ }),
118
+ jwksOperatorFunctions: (createAuth) => ({
119
+ rotateSigningKey: internalActionGeneric({
120
+ args: {},
121
+ handler: async (ctx) => {
122
+ const auth = await createAuth(ctx);
123
+ if (!auth || typeof auth !== "object" || !("$context" in auth)) {
124
+ throw new Error("AUTH_JWT_PLUGIN_REQUIRED");
125
+ }
126
+ const authContext = await auth.$context;
127
+ const jwtPlugin = authContext.getPlugin("jwt");
128
+ if (!jwtPlugin) throw new Error("AUTH_JWT_PLUGIN_REQUIRED");
129
+ return rotateSigningKeyWithOfficialJwt(
130
+ authContext,
131
+ jwtPlugin.options,
132
+ async (next) => ctx.runMutation(component.adapter.rotateSigningKey, { next })
133
+ );
134
+ }
135
+ })
136
+ }),
137
+ registerRoutes: (http, createAuth) => {
138
+ const handler = httpActionGeneric(async (ctx, request) => {
139
+ try {
140
+ const publicOrigin = requireAuthOrigin("SITE_URL");
141
+ const verifiedClientIp = await resolveVerifiedClientIp(
142
+ request,
143
+ async () => (await ctx.meta.getRequestMetadata()).ip,
144
+ process.env.BCN_AUTH_PROXY_IP_SECRET
145
+ );
146
+ const auth = await createAuth(ctx);
147
+ await auth.$context;
148
+ return await auth.handler(rewriteToPublicOrigin(request, publicOrigin, verifiedClientIp));
149
+ } catch {
150
+ return Response.json({ code: "AUTH_CONFIG_INVALID" }, { status: 500 });
151
+ }
152
+ });
153
+ http.route({ handler, method: "GET", pathPrefix: "/api/auth/" });
154
+ http.route({ handler, method: "POST", pathPrefix: "/api/auth/" });
155
+ }
156
+ };
157
+ }
@@ -0,0 +1,11 @@
1
+ export { defineAuthAdapterFunctions } from './adapter/define-functions.js';
2
+ export { createAuthComponent } from './create-auth-component.js';
3
+ export { requireAuthOrigin } from './origin.js';
4
+ export { convexAuth } from './plugin.js';
5
+ export { getConvexAuthProvider } from './provider.js';
6
+ export { createBetterAuthMcpAccessVerifier, verifyOAuthBearerToken } from './oauth-resource.js';
7
+ export { createUserProjectionTriggers } from './user-projection.js';
8
+ export type { AuthCtx } from './context.js';
9
+ export type { AuthComponentTriggers, AuthFunctions, CreateAuth } from './types.js';
10
+ export type { BetterAuthMcpAccessVerifierOptions, VerifyOAuthBearerTokenOptions, } from './oauth-resource.js';
11
+ export type { BetterAuthUserProjectionSource, CreateUserProjectionTriggersOptions, } from './user-projection.js';
@@ -0,0 +1,7 @@
1
+ export { defineAuthAdapterFunctions } from "./adapter/define-functions.js";
2
+ export { createAuthComponent } from "./create-auth-component.js";
3
+ export { requireAuthOrigin } from "./origin.js";
4
+ export { convexAuth } from "./plugin.js";
5
+ export { getConvexAuthProvider } from "./provider.js";
6
+ export { createBetterAuthMcpAccessVerifier, verifyOAuthBearerToken } from "./oauth-resource.js";
7
+ export { createUserProjectionTriggers } from "./user-projection.js";
@@ -0,0 +1,2 @@
1
+ /** Removed by both public HTTP boundaries; used only for in-process Better Auth API calls. */
2
+ export declare const INTERNAL_SESSION_HEADER = "x-bcn-internal-session";
@@ -0,0 +1 @@
1
+ export const INTERNAL_SESSION_HEADER = "x-bcn-internal-session";
@@ -0,0 +1,58 @@
1
+ import type { Jwk, JwtOptions } from 'better-auth/plugins';
2
+ import { createJwk } from 'better-auth/plugins';
3
+ export declare const JWKS_MAX_TOKEN_LIFETIME_SECONDS: number;
4
+ export declare const JWKS_CACHE_LIFETIME_SECONDS: number;
5
+ export declare const JWKS_CLOCK_SKEW_SECONDS = 60;
6
+ export declare const JWKS_GRACE_PERIOD_SECONDS: number;
7
+ export declare const JWKS_CACHE_CONTROL = "public, max-age=300, must-revalidate";
8
+ export declare const signingKeyCandidateValidator: import("convex/values").VObject<{
9
+ id: string;
10
+ alg: "RS256";
11
+ crv: null;
12
+ privateKey: string;
13
+ publicKey: string;
14
+ }, {
15
+ alg: import("convex/values").VLiteral<"RS256", "required">;
16
+ crv: import("convex/values").VNull<null, "required">;
17
+ id: import("convex/values").VString<string, "required">;
18
+ privateKey: import("convex/values").VString<string, "required">;
19
+ publicKey: import("convex/values").VString<string, "required">;
20
+ }, "required", "id" | "alg" | "crv" | "privateKey" | "publicKey">;
21
+ export interface SigningKeyCandidate {
22
+ alg: 'RS256';
23
+ crv: null;
24
+ id: string;
25
+ privateKey: string;
26
+ publicKey: string;
27
+ }
28
+ export interface SigningKeyRotationMetadata {
29
+ createdAt: number;
30
+ newKid: string;
31
+ previousKids: string[];
32
+ previousVerifyUntil: number;
33
+ rotatedAt: number;
34
+ }
35
+ type BetterAuthEndpointContext = Parameters<typeof createJwk>[0]['context'];
36
+ type CreateJwkAdapter = NonNullable<NonNullable<JwtOptions['adapter']>['createJwk']>;
37
+ /**
38
+ * Validate and canonicalize the one public key shape emitted by the pinned
39
+ * Better Auth RS256 generator. A tuple update must review this projection.
40
+ */
41
+ export declare function canonicalizePublicRsaJwk(value: string): string;
42
+ export declare function normalizeSigningKeyCandidate(candidate: SigningKeyCandidate): SigningKeyCandidate;
43
+ /**
44
+ * The JWT plugin reads these rows for both signing and public serialization.
45
+ * Keep the encrypted private field for signing, but replace the public JSON
46
+ * with the exact public projection before Better Auth spreads it into `/jwks`.
47
+ */
48
+ export declare function sanitizeStoredJwk(jwk: Jwk): Jwk;
49
+ export declare function createPublicJwksResponse(rows: Jwk[], method: string, now?: number): Response;
50
+ export declare const rejectImplicitSigningKeyCreation: CreateJwkAdapter;
51
+ export declare function assertSupportedJwksOptions(options: JwtOptions | undefined, code: string): void;
52
+ /**
53
+ * Generate and encrypt a key through Better Auth, then let one Convex mutation
54
+ * own insertion and retirement. The generated action timestamp and any
55
+ * rotationInterval expiry are deliberately not forwarded to the mutation.
56
+ */
57
+ export declare function rotateSigningKeyWithOfficialJwt(context: BetterAuthEndpointContext, options: JwtOptions, commit: (candidate: SigningKeyCandidate) => Promise<SigningKeyRotationMetadata>): Promise<SigningKeyRotationMetadata>;
58
+ export {};
@@ -0,0 +1,163 @@
1
+ import { createJwk } from "better-auth/plugins";
2
+ import { v } from "convex/values";
3
+ export const JWKS_MAX_TOKEN_LIFETIME_SECONDS = 15 * 60;
4
+ export const JWKS_CACHE_LIFETIME_SECONDS = 5 * 60;
5
+ export const JWKS_CLOCK_SKEW_SECONDS = 60;
6
+ export const JWKS_GRACE_PERIOD_SECONDS = JWKS_MAX_TOKEN_LIFETIME_SECONDS + JWKS_CACHE_LIFETIME_SECONDS + JWKS_CLOCK_SKEW_SECONDS;
7
+ export const JWKS_CACHE_CONTROL = `public, max-age=${JWKS_CACHE_LIFETIME_SECONDS}, must-revalidate`;
8
+ const MAX_KEY_ID_LENGTH = 256;
9
+ const MAX_PUBLIC_JWK_LENGTH = 16 * 1024;
10
+ const MAX_ENCRYPTED_PRIVATE_JWK_LENGTH = 64 * 1024;
11
+ const PRIVATE_JWK_MEMBERS = /* @__PURE__ */ new Set(["d", "p", "q", "dp", "dq", "qi", "oth", "k"]);
12
+ const PUBLIC_RSA_JWK_MEMBERS = /* @__PURE__ */ new Set(["e", "kty", "n"]);
13
+ const VERSIONED_CIPHERTEXT_PATTERN = /^\$ba\$(?:0|[1-9]\d*)\$(?:[0-9a-f]{2})+$/u;
14
+ export const signingKeyCandidateValidator = v.object({
15
+ alg: v.literal("RS256"),
16
+ crv: v.null(),
17
+ id: v.string(),
18
+ privateKey: v.string(),
19
+ publicKey: v.string()
20
+ });
21
+ function assertBoundedString(value, maximum, code) {
22
+ if (value.length === 0 || value.length > maximum) throw new Error(code);
23
+ }
24
+ function parseJson(value, maximum, code) {
25
+ assertBoundedString(value, maximum, code);
26
+ try {
27
+ return JSON.parse(value);
28
+ } catch {
29
+ throw new Error(code);
30
+ }
31
+ }
32
+ function assertNoPrivateJwkMembers(value) {
33
+ if (Array.isArray(value)) {
34
+ for (const entry of value) assertNoPrivateJwkMembers(entry);
35
+ return;
36
+ }
37
+ if (!value || typeof value !== "object") return;
38
+ for (const [name, entry] of Object.entries(value)) {
39
+ if (PRIVATE_JWK_MEMBERS.has(name)) throw new Error("AUTH_JWKS_PUBLIC_KEY_INVALID");
40
+ assertNoPrivateJwkMembers(entry);
41
+ }
42
+ }
43
+ export function canonicalizePublicRsaJwk(value) {
44
+ const parsed = parseJson(value, MAX_PUBLIC_JWK_LENGTH, "AUTH_JWKS_PUBLIC_KEY_INVALID");
45
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
46
+ throw new Error("AUTH_JWKS_PUBLIC_KEY_INVALID");
47
+ }
48
+ assertNoPrivateJwkMembers(parsed);
49
+ const key = parsed;
50
+ if (Object.keys(key).some((name) => !PUBLIC_RSA_JWK_MEMBERS.has(name)) || key.kty !== "RSA" || typeof key.n !== "string" || key.n.length === 0 || typeof key.e !== "string" || key.e.length === 0) {
51
+ throw new Error("AUTH_JWKS_PUBLIC_KEY_INVALID");
52
+ }
53
+ return JSON.stringify({ kty: "RSA", n: key.n, e: key.e });
54
+ }
55
+ function assertVersionedEncryptedPrivateJwk(value) {
56
+ const parsed = parseJson(
57
+ value,
58
+ MAX_ENCRYPTED_PRIVATE_JWK_LENGTH,
59
+ "AUTH_JWKS_PRIVATE_KEY_NOT_ENCRYPTED"
60
+ );
61
+ if (typeof parsed !== "string" || !VERSIONED_CIPHERTEXT_PATTERN.test(parsed)) {
62
+ throw new Error("AUTH_JWKS_PRIVATE_KEY_NOT_ENCRYPTED");
63
+ }
64
+ }
65
+ export function normalizeSigningKeyCandidate(candidate) {
66
+ assertBoundedString(candidate.id, MAX_KEY_ID_LENGTH, "AUTH_JWKS_KEY_ID_INVALID");
67
+ if (/\p{C}/u.test(candidate.id)) throw new Error("AUTH_JWKS_KEY_ID_INVALID");
68
+ if (candidate.alg !== "RS256" || candidate.crv !== null) {
69
+ throw new Error("AUTH_JWKS_ALGORITHM_INVALID");
70
+ }
71
+ assertVersionedEncryptedPrivateJwk(candidate.privateKey);
72
+ return {
73
+ ...candidate,
74
+ publicKey: canonicalizePublicRsaJwk(candidate.publicKey)
75
+ };
76
+ }
77
+ export function sanitizeStoredJwk(jwk) {
78
+ return { ...jwk, publicKey: canonicalizePublicRsaJwk(jwk.publicKey) };
79
+ }
80
+ export function createPublicJwksResponse(rows, method, now = Date.now()) {
81
+ const live = rows.filter((row) => {
82
+ if (row.expiresAt === null || row.expiresAt === void 0) return true;
83
+ if (!(row.expiresAt instanceof Date) || !Number.isFinite(row.expiresAt.getTime())) {
84
+ throw new TypeError("AUTH_JWKS_EXPIRY_INVALID");
85
+ }
86
+ return row.expiresAt.getTime() + JWKS_GRACE_PERIOD_SECONDS * 1e3 > now;
87
+ });
88
+ if (live.length === 0) {
89
+ return new Response(
90
+ method === "HEAD" ? null : JSON.stringify({ code: "SERVICE_UNAVAILABLE", message: "Signing keys are not ready" }),
91
+ {
92
+ headers: {
93
+ "Cache-Control": "private, no-store",
94
+ "Content-Type": "application/json"
95
+ },
96
+ status: 503
97
+ }
98
+ );
99
+ }
100
+ const keys = live.map((stored) => {
101
+ const row = sanitizeStoredJwk(stored);
102
+ assertBoundedString(row.id, MAX_KEY_ID_LENGTH, "AUTH_JWKS_PUBLIC_KEY_INVALID");
103
+ if (/\p{C}/u.test(row.id) || row.alg !== "RS256" || row.crv !== null && row.crv !== void 0) {
104
+ throw new Error("AUTH_JWKS_PUBLIC_KEY_INVALID");
105
+ }
106
+ return {
107
+ alg: "RS256",
108
+ ...JSON.parse(row.publicKey),
109
+ kid: row.id
110
+ };
111
+ });
112
+ const headers = {
113
+ "Cache-Control": JWKS_CACHE_CONTROL,
114
+ "Content-Type": "application/json"
115
+ };
116
+ return method === "HEAD" ? new Response(null, { headers, status: 200 }) : Response.json({ keys }, { headers });
117
+ }
118
+ export const rejectImplicitSigningKeyCreation = async () => {
119
+ throw new Error("AUTH_JWKS_OPERATOR_SETUP_REQUIRED");
120
+ };
121
+ export function assertSupportedJwksOptions(options, code) {
122
+ if (!options || options.disableSettingJwtHeader !== true || options.jwks?.disablePrivateKeyEncryption !== false || options.jwks.gracePeriod !== JWKS_GRACE_PERIOD_SECONDS || options.jwks.keyPairConfig?.alg !== "RS256" || options.jwks.rotationInterval !== void 0 || options.jwks.remoteUrl !== void 0 || options.jwks.jwksPath !== void 0 && options.jwks.jwksPath !== "/jwks" || options.jwks.keyPairConfigs !== void 0 && options.jwks.keyPairConfigs.length !== 0 || options.adapter?.createJwk !== void 0 && options.adapter.createJwk !== rejectImplicitSigningKeyCreation) {
123
+ throw new Error(code);
124
+ }
125
+ }
126
+ export async function rotateSigningKeyWithOfficialJwt(context, options, commit) {
127
+ assertSupportedJwksOptions(options, "AUTH_JWKS_CONFIG_INVALID");
128
+ let committed;
129
+ await createJwk({ context }, {
130
+ ...options,
131
+ adapter: {
132
+ ...options.adapter,
133
+ createJwk: async (generated, endpointContext) => {
134
+ if (generated.alg !== "RS256" || generated.crv !== void 0) {
135
+ throw new Error("AUTH_JWKS_ALGORITHM_INVALID");
136
+ }
137
+ const id = endpointContext.context.generateId({ model: "jwks" });
138
+ if (typeof id !== "string" || id.length === 0) {
139
+ throw new Error("AUTH_JWKS_KEY_ID_INVALID");
140
+ }
141
+ const candidate = normalizeSigningKeyCandidate({
142
+ alg: generated.alg,
143
+ crv: null,
144
+ id,
145
+ privateKey: generated.privateKey,
146
+ publicKey: generated.publicKey
147
+ });
148
+ committed = await commit(candidate);
149
+ return {
150
+ ...generated,
151
+ alg: "RS256",
152
+ createdAt: new Date(committed.createdAt),
153
+ crv: void 0,
154
+ expiresAt: void 0,
155
+ id,
156
+ publicKey: candidate.publicKey
157
+ };
158
+ }
159
+ }
160
+ });
161
+ if (!committed) throw new Error("AUTH_JWKS_ROTATION_NOT_COMMITTED");
162
+ return committed;
163
+ }
@@ -0,0 +1,17 @@
1
+ import type { GenericDataModel } from 'convex/server';
2
+ import type { AuthCtx } from './context.js';
3
+ import type { AuthAdapterComponentApi } from './types.js';
4
+ /** Provider-owned authority needed to revalidate a verified OAuth access token. */
5
+ export interface OAuthLiveAccess {
6
+ readonly clientId: string;
7
+ readonly issuer: string;
8
+ readonly resource: string;
9
+ readonly scopes: readonly string[];
10
+ readonly sessionId: string;
11
+ readonly subject: string;
12
+ }
13
+ /**
14
+ * Rechecks provider-owned authority from indexed Better Auth records. A disabled resource remains
15
+ * valid for an already-issued token, matching the pinned provider; deleting it revokes access.
16
+ */
17
+ export declare function validateOAuthAccess<DataModel extends GenericDataModel>(ctx: AuthCtx<DataModel>, component: AuthAdapterComponentApi, access: OAuthLiveAccess): Promise<boolean>;
@@ -0,0 +1,78 @@
1
+ function nonEmptyString(value) {
2
+ return typeof value === "string" && value.length > 0;
3
+ }
4
+ function stringArray(value) {
5
+ return Array.isArray(value) && value.every(nonEmptyString) && new Set(value).size === value.length ? value : void 0;
6
+ }
7
+ function containsEvery(values, required) {
8
+ const available = new Set(values);
9
+ return required.every((value) => available.has(value));
10
+ }
11
+ function validAccess(value) {
12
+ if (!value || !nonEmptyString(value.clientId) || !nonEmptyString(value.issuer) || !nonEmptyString(value.resource) || !nonEmptyString(value.sessionId) || !nonEmptyString(value.subject) || !Array.isArray(value.scopes) || value.scopes.length === 0 || !value.scopes.every(nonEmptyString)) {
13
+ return false;
14
+ }
15
+ return new Set(value.scopes).size === value.scopes.length;
16
+ }
17
+ async function findOne(ctx, component, model, where, select) {
18
+ return await ctx.runQuery(component.adapter.findOne, {
19
+ model,
20
+ select: [...select],
21
+ where: [...where]
22
+ });
23
+ }
24
+ export async function validateOAuthAccess(ctx, component, access) {
25
+ if (!validAccess(access)) return false;
26
+ try {
27
+ const [session, user, client, resource, link, consent] = await Promise.all([
28
+ findOne(
29
+ ctx,
30
+ component,
31
+ "session",
32
+ [{ field: "id", value: access.sessionId }],
33
+ ["expiresAt", "id", "userId"]
34
+ ),
35
+ findOne(ctx, component, "user", [{ field: "id", value: access.subject }], ["id"]),
36
+ findOne(
37
+ ctx,
38
+ component,
39
+ "oauthClient",
40
+ [{ field: "clientId", value: access.clientId }],
41
+ ["clientId", "disabled", "scopes"]
42
+ ),
43
+ findOne(
44
+ ctx,
45
+ component,
46
+ "oauthResource",
47
+ [{ field: "identifier", value: access.resource }],
48
+ ["allowedScopes", "identifier"]
49
+ ),
50
+ findOne(
51
+ ctx,
52
+ component,
53
+ "oauthClientResource",
54
+ [{ field: "id", value: `${access.clientId}::${access.resource}` }],
55
+ ["clientId", "id", "resourceId"]
56
+ ),
57
+ findOne(
58
+ ctx,
59
+ component,
60
+ "oauthConsent",
61
+ [
62
+ { field: "clientId", value: access.clientId },
63
+ { field: "userId", value: access.subject }
64
+ ],
65
+ ["clientId", "resources", "scopes", "userId"]
66
+ )
67
+ ]);
68
+ const clientScopes = stringArray(client?.scopes);
69
+ const resourceScopes = resource?.allowedScopes === null ? null : stringArray(resource?.allowedScopes);
70
+ const consentResources = stringArray(consent?.resources);
71
+ const consentScopes = stringArray(consent?.scopes);
72
+ return Boolean(
73
+ session && session.id === access.sessionId && session.userId === access.subject && typeof session.expiresAt === "number" && Number.isFinite(session.expiresAt) && session.expiresAt > Date.now() && user?.id === access.subject && client && client.clientId === access.clientId && client.disabled !== true && clientScopes && containsEvery(clientScopes, access.scopes) && resource && resource.identifier === access.resource && resourceScopes !== void 0 && (resourceScopes === null || containsEvery(resourceScopes, access.scopes)) && link && link.id === `${access.clientId}::${access.resource}` && link.clientId === access.clientId && link.resourceId === access.resource && consent && consent.clientId === access.clientId && consent.userId === access.subject && consentResources?.includes(access.resource) && consentScopes && containsEvery(consentScopes, access.scopes)
74
+ );
75
+ } catch {
76
+ return false;
77
+ }
78
+ }
@@ -0,0 +1,10 @@
1
+ import type { BetterAuthPlugin } from 'better-auth';
2
+ import { type hardenOAuthProviderCallbacks, type PinnedOAuthProviderProfile } from './oauth-security.js';
3
+ interface InstalledOAuthProviderPlugin extends BetterAuthPlugin {
4
+ options?: Record<string, unknown>;
5
+ }
6
+ export declare function validatePinnedOAuthProviderRuntime(context: Parameters<NonNullable<BetterAuthPlugin['init']>>[0], options: PinnedOAuthProviderProfile, hardened: ReturnType<typeof hardenOAuthProviderCallbacks>): InstalledOAuthProviderPlugin['options'];
7
+ export declare function assertSafePinnedClientProvisioning(method: unknown, body: unknown, allowedScopes: readonly string[]): void;
8
+ export declare function assertSafePinnedClientUpdate(method: unknown, body: unknown, allowedScopes: readonly string[]): void;
9
+ export declare function assertSafePinnedResourceProvisioning(method: unknown, body: unknown, allowedScopes: readonly string[]): void;
10
+ export {};