@intelligo-dev/auth 1.0.0-beta.1 → 1.0.0-beta.13

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 (81) hide show
  1. package/NOTICE +6 -0
  2. package/README.md +59 -0
  3. package/dist/client.js +6 -16
  4. package/dist/client.js.map +1 -1
  5. package/dist/edge.js +22 -28
  6. package/dist/edge.js.map +1 -1
  7. package/dist/guard-error.js +23 -0
  8. package/dist/guard-error.js.map +1 -0
  9. package/dist/helpers.js +77 -97
  10. package/dist/helpers.js.map +1 -1
  11. package/dist/impersonation.js +46 -18
  12. package/dist/impersonation.js.map +1 -1
  13. package/dist/index.js +21 -27
  14. package/dist/index.js.map +1 -1
  15. package/dist/invitation-links.js +13 -0
  16. package/dist/invitation-links.js.map +1 -0
  17. package/dist/onboarding/errors.js +4 -14
  18. package/dist/onboarding/errors.js.map +1 -1
  19. package/dist/onboarding/schemas.js +3 -15
  20. package/dist/onboarding/schemas.js.map +1 -1
  21. package/dist/onboarding/service.js +14 -68
  22. package/dist/onboarding/service.js.map +1 -1
  23. package/dist/org-api.js +10 -67
  24. package/dist/org-api.js.map +1 -1
  25. package/dist/profile/errors.js +4 -14
  26. package/dist/profile/errors.js.map +1 -1
  27. package/dist/profile/schemas.js +1 -10
  28. package/dist/profile/schemas.js.map +1 -1
  29. package/dist/profile/service.js +12 -53
  30. package/dist/profile/service.js.map +1 -1
  31. package/dist/roles.js +28 -5
  32. package/dist/roles.js.map +1 -1
  33. package/dist/server.js +80 -98
  34. package/dist/server.js.map +1 -1
  35. package/dist/team/errors.js +4 -13
  36. package/dist/team/errors.js.map +1 -1
  37. package/dist/team/schemas.js +4 -18
  38. package/dist/team/schemas.js.map +1 -1
  39. package/dist/team/service.js +80 -157
  40. package/dist/team/service.js.map +1 -1
  41. package/dist/trusted-origins.js +25 -0
  42. package/dist/trusted-origins.js.map +1 -0
  43. package/dist/workspace/errors.js +4 -14
  44. package/dist/workspace/errors.js.map +1 -1
  45. package/dist/workspace/schemas.js +2 -18
  46. package/dist/workspace/schemas.js.map +1 -1
  47. package/dist/workspace/service.js +31 -91
  48. package/dist/workspace/service.js.map +1 -1
  49. package/dist/workspace-bootstrap.js +33 -0
  50. package/dist/workspace-bootstrap.js.map +1 -0
  51. package/dist/workspace-init.js +46 -51
  52. package/dist/workspace-init.js.map +1 -1
  53. package/dist/workspace-slug.js +29 -0
  54. package/dist/workspace-slug.js.map +1 -0
  55. package/package.json +36 -14
  56. package/src/client.ts +6 -16
  57. package/src/edge.ts +22 -28
  58. package/src/guard-error.ts +36 -0
  59. package/src/helpers.ts +99 -114
  60. package/src/impersonation.ts +52 -17
  61. package/src/index.ts +14 -10
  62. package/src/invitation-links.ts +15 -0
  63. package/src/onboarding/errors.ts +5 -17
  64. package/src/onboarding/schemas.ts +3 -15
  65. package/src/onboarding/service.ts +11 -65
  66. package/src/org-api.ts +9 -66
  67. package/src/profile/errors.ts +5 -17
  68. package/src/profile/schemas.ts +1 -10
  69. package/src/profile/service.ts +8 -49
  70. package/src/roles.ts +36 -5
  71. package/src/server.ts +86 -104
  72. package/src/team/errors.ts +4 -13
  73. package/src/team/schemas.ts +4 -18
  74. package/src/team/service.ts +100 -174
  75. package/src/trusted-origins.ts +26 -0
  76. package/src/workspace/errors.ts +4 -14
  77. package/src/workspace/schemas.ts +2 -18
  78. package/src/workspace/service.ts +40 -92
  79. package/src/workspace-bootstrap.ts +57 -0
  80. package/src/workspace-init.ts +55 -56
  81. package/src/workspace-slug.ts +32 -0
@@ -1,78 +1,17 @@
1
1
  /**
2
- * Workspace management service — the durable business rules behind
3
- * workspace listing, creation, switching, editing and deletion,
4
- * extracted from the product application's workspace actions (page/
5
- * registry migration, `workspace-settings` family, roadmap item 8).
6
- *
7
- * Mirrors `createTeamService(ports)` (./../team/service.ts) one
8
- * directory over: a factory over optional ports, so this package's
9
- * allowlisted dependency (`@intelligo-dev/core` only — see
10
- * tests/architecture/dependency-direction.test.ts) never grows to
11
- * include billing. A consumer binds that in at its composition root:
12
- *
13
- * const workspaceService = createWorkspaceService({
14
- * checkWorkspaceLimit: ..., // adapts @intelligo-dev/billing's checkPlanLimit
15
- * });
16
- *
17
- * Authorization (`requireAuth`/`requireWorkspace`/`requireRole`) lives
18
- * INSIDE each method, not at the transport. Every recognized failure
19
- * throws `WorkspaceServiceError` with a stable `code` — no
20
- * revalidatePath/Sentry/next-intl/toast here; that shaping is the
21
- * transport's job (a Server Action, a route handler).
22
- *
23
- * ---------------------------------------------------------------------
24
- * Why `checkWorkspaceLimit` takes a `userId`, not a `workspaceId`
25
- * ---------------------------------------------------------------------
26
- * `createWorkspace` has no workspace to check the plan of yet — it is
27
- * the thing being created. Ignite's original action worked around this
28
- * by reading the caller's *existing* workspaces and using the first
29
- * one's id to look up a plan via `@intelligo-dev/billing`'s
30
- * `checkPlanLimit(workspaceId, "workspaces", currentCount)`, i.e. it
31
- * borrowed an arbitrary existing workspace's subscription as a stand-in
32
- * for "the caller's plan". That borrowing is a binding-layer concern,
33
- * not a service-layer one: this service only knows the caller's
34
- * `userId` and how many workspaces they already have. The composition
35
- * root's binding (`checkWorkspaceLimit`) is where a consumer decides
36
- * how to resolve "this user's plan" — by reading their first workspace
37
- * the same way ignite did, or by a real per-user plan lookup if one
38
- * exists.
39
- *
40
- * ---------------------------------------------------------------------
41
- * The two Better-Auth pitfalls (already solved in ../team/service.ts —
42
- * copied here rather than re-derived)
43
- * ---------------------------------------------------------------------
44
- * 1. Method-name mismatch: the typed `orgApi` wrapper (../org-api.ts)
45
- * exists precisely because `auth.api`'s organization-plugin methods
46
- * are keyed by their own camelCase *server* id, which does not
47
- * always match the HTTP path or the client SDK name. This service
48
- * uses `orgApi["/organization/list"]` and
49
- * `orgApi["/organization/set-active"]` for the two calls the
50
- * wrapper covers, and calls `auth.api.{createOrganization,
51
- * updateOrganization, deleteOrganization, getFullOrganization}`
52
- * directly for the base organization CRUD surface, which is not
53
- * part of `orgApi`'s typed table (the same approach
54
- * `../team/service.ts` takes for `getFullOrganization`). Ignite's
55
- * original `actions/workspace.ts` already called these four by
56
- * their correct `auth.api` names directly (it never went through a
57
- * path-keyed cast), so there is no method-name bug to fix here.
58
- * 2. `sessions.activeOrganizationId` does not exist on this repo's
59
- * Drizzle schema. Ignite's original `getActiveWorkspace()` called
60
- * `auth.api.getFullOrganization({ headers })` with no
61
- * `organizationId` — the exact bug documented in
62
- * `../team/service.ts`'s module comment: that resolves to *no*
63
- * organization regardless of what the caller most recently
64
- * activated. This service's `getActiveWorkspace` instead resolves
65
- * the caller's workspace via `requireWorkspace()` first (which has
66
- * its own explicit-id fallback) and passes that id explicitly to
67
- * `getFullOrganization`.
2
+ * Workspace listing, creation, switching, editing and deletion. Each method
3
+ * authorizes itself and throws `WorkspaceServiceError`; the plan limit
4
+ * arrives as the `checkWorkspaceLimit` port bound at the composition root.
5
+ * `getFullOrganization` always gets an explicit `organizationId`, because a
6
+ * bare call resolves to nothing when the session has no active organization.
68
7
  */
69
- import { headers } from "next/headers";
8
+ import { getRequestHeaders } from "@intelligo-dev/core/request-context";
70
9
  import { createLogger } from "@intelligo-dev/core/logger";
71
- import { auth } from "../server";
72
- import { requireAuth, requireRole, requireWorkspace } from "../helpers";
73
- import { orgApi } from "../org-api";
74
- import { createWorkspaceSchema, updateWorkspaceSchema, } from "./schemas";
75
- import { WorkspaceServiceError, isWorkspaceServiceError } from "./errors";
10
+ import { auth } from "../server.js";
11
+ import { requireAuth, requireRole, requireWorkspace } from "../helpers.js";
12
+ import { orgApi } from "../org-api.js";
13
+ import { createWorkspaceSchema, updateWorkspaceSchema, } from "./schemas.js";
14
+ import { WorkspaceServiceError, isWorkspaceServiceError } from "./errors.js";
76
15
  const log = createLogger("WorkspaceService");
77
16
  function errorMessage(error) {
78
17
  return error instanceof Error ? error.message : String(error);
@@ -138,12 +77,10 @@ export function createWorkspaceService(ports = {}) {
138
77
  throw new WorkspaceServiceError("provider_error", `Better-Auth organization API call failed (${context})`, { cause: error });
139
78
  }
140
79
  }
141
- /**
142
- * List all workspaces for the current user.
143
- */
80
+ /** Every workspace the current user belongs to. */
144
81
  async function listWorkspaces() {
145
82
  await callRequireAuth();
146
- const hdrs = await headers();
83
+ const hdrs = await getRequestHeaders();
147
84
  const orgs = await callOrgApi("list", () => orgApi["/organization/list"]({ headers: hdrs }));
148
85
  return orgs ?? [];
149
86
  }
@@ -157,7 +94,7 @@ export function createWorkspaceService(ports = {}) {
157
94
  async function createWorkspace(input) {
158
95
  const { user } = await callRequireAuth();
159
96
  const validated = parseInput(createWorkspaceSchema, input);
160
- const hdrs = await headers();
97
+ const hdrs = await getRequestHeaders();
161
98
  const existing = await callOrgApi("list", () => orgApi["/organization/list"]({ headers: hdrs }));
162
99
  const existingCount = existing?.length ?? 0;
163
100
  if (ports.checkWorkspaceLimit && existingCount > 0) {
@@ -182,27 +119,23 @@ export function createWorkspaceService(ports = {}) {
182
119
  }));
183
120
  return org;
184
121
  }
185
- /**
186
- * Switch the caller's active workspace.
187
- */
122
+ /** Switch the caller's active workspace. */
188
123
  async function switchWorkspace(organizationId) {
189
124
  await callRequireAuth();
190
125
  if (typeof organizationId !== "string" || organizationId.length === 0) {
191
126
  throw new WorkspaceServiceError("invalid_input", "Invalid workspace id");
192
127
  }
193
- const hdrs = await headers();
128
+ const hdrs = await getRequestHeaders();
194
129
  await callOrgApi("set-active", () => orgApi["/organization/set-active"]({
195
130
  headers: hdrs,
196
131
  body: { organizationId },
197
132
  }));
198
133
  }
199
- /**
200
- * Update workspace settings (name/slug/logo). Owner/admin only.
201
- */
134
+ /** Update workspace settings (name/slug/logo). Owner/admin only. */
202
135
  async function updateWorkspace(input) {
203
136
  const { workspace } = await callRequireRole(["owner", "admin"]);
204
137
  const validated = parseInput(updateWorkspaceSchema, input);
205
- const hdrs = await headers();
138
+ const hdrs = await getRequestHeaders();
206
139
  const updateData = {};
207
140
  if (validated.name)
208
141
  updateData.name = validated.name;
@@ -225,7 +158,15 @@ export function createWorkspaceService(ports = {}) {
225
158
  */
226
159
  async function deleteWorkspace() {
227
160
  const { workspace } = await callRequireRole(["owner"]);
228
- const hdrs = await headers();
161
+ const hdrs = await getRequestHeaders();
162
+ if (ports.beforeDeleteWorkspace) {
163
+ try {
164
+ await ports.beforeDeleteWorkspace(workspace.id);
165
+ }
166
+ catch (error) {
167
+ throw new WorkspaceServiceError("provider_error", `Could not prepare the workspace for deletion: ${errorMessage(error)}`, { cause: error });
168
+ }
169
+ }
229
170
  await callOrgApi("delete", () => auth.api.deleteOrganization({
230
171
  headers: hdrs,
231
172
  body: { organizationId: workspace.id },
@@ -239,14 +180,13 @@ export function createWorkspaceService(ports = {}) {
239
180
  }
240
181
  }
241
182
  /**
242
- * Get the caller's active workspace, fully resolved. Unlike
243
- * ignite's original (see the module doc comment), this resolves the
244
- * workspace id explicitly via `requireWorkspace()` rather than
245
- * relying on a non-existent `sessions.activeOrganizationId` fallback.
183
+ * The caller's active workspace, fully resolved. The id comes from
184
+ * `requireWorkspace()`, which falls back to the first workspace when the
185
+ * session has none active.
246
186
  */
247
187
  async function getActiveWorkspace() {
248
188
  const { workspace } = await callRequireWorkspace();
249
- const hdrs = await headers();
189
+ const hdrs = await getRequestHeaders();
250
190
  const org = (await callOrgApi("getFullOrganization", () => auth.api.getFullOrganization({
251
191
  headers: hdrs,
252
192
  query: { organizationId: workspace.id },
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/workspace/service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACxE,OAAO,EAAE,MAAM,EAAoB,MAAM,YAAY,CAAC;AACtD,OAAO,EACL,qBAAqB,EACrB,qBAAqB,GAGtB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAE1E,MAAM,GAAG,GAAG,YAAY,CAAC,kBAAkB,CAAC,CAAC;AA0B7C,SAAS,YAAY,CAAC,KAAc;IAClC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC;AAED,6EAA6E;AAC7E,SAAS,WAAW,CAAC,KAAc;IACjC,IAAI,uBAAuB,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACjD,OAAO,IAAI,qBAAqB,CAAC,WAAW,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE;QACjE,KAAK,EAAE,KAAK;KACb,CAAC,CAAC;AACL,CAAC;AAED,SAAS,UAAU,CAAI,MAAkB,EAAE,KAAc;IACvD,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,qBAAqB,CAC7B,eAAe,EACf,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;YAC1D,eAAe,EACjB,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CACxB,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC;AAED,0DAA0D;AAC1D,SAAS,OAAO,CAAC,IAAY;IAC3B,OAAO,IAAI;SACR,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,QAA+B,EAAE;IACtE,KAAK,UAAU,eAAe;QAC5B,IAAI,CAAC;YACH,OAAO,MAAM,WAAW,EAAE,CAAC;QAC7B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,WAAW,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,KAAK,UAAU,oBAAoB;QACjC,IAAI,CAAC;YACH,OAAO,MAAM,gBAAgB,EAAE,CAAC;QAClC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,WAAW,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,KAAK,UAAU,eAAe,CAC5B,YAAiD;QAEjD,IAAI,CAAC;YACH,OAAO,MAAM,WAAW,CAAC,YAAY,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,WAAW,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,0FAA0F;IAC1F,KAAK,UAAU,UAAU,CACvB,OAAe,EACf,EAAoB;QAEpB,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,uBAAuB,CAAC,KAAK,CAAC;gBAAE,MAAM,KAAK,CAAC;YAChD,GAAG,CAAC,KAAK,CAAC,qBAAqB,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC1E,MAAM,IAAI,qBAAqB,CAC7B,gBAAgB,EAChB,6CAA6C,OAAO,GAAG,EACvD,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,UAAU,cAAc;QAC3B,MAAM,eAAe,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC;QAE7B,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,GAAG,EAAE,CACzC,MAAM,CAAC,oBAAoB,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAChD,CAAC;QAEF,OAAO,IAAI,IAAI,EAAE,CAAC;IACpB,CAAC;IAED;;;;;;OAMG;IACH,KAAK,UAAU,eAAe,CAC5B,KAA2B;QAE3B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,eAAe,EAAE,CAAC;QACzC,MAAM,SAAS,GAAG,UAAU,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;QAC3D,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC;QAE7B,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,GAAG,EAAE,CAC7C,MAAM,CAAC,oBAAoB,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAChD,CAAC;QACF,MAAM,aAAa,GAAG,QAAQ,EAAE,MAAM,IAAI,CAAC,CAAC;QAE5C,IAAI,KAAK,CAAC,mBAAmB,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;YACnD,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,mBAAmB,CAChD,IAAI,CAAC,EAAE,EACP,aAAa,CACd,CAAC;YACF,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;gBACxB,MAAM,IAAI,qBAAqB,CAC7B,yBAAyB,EACzB,0BAA0B,UAAU,CAAC,KAAK,aACxC,UAAU,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAChC,sCAAsC,EACtC,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,EAAE,CACtC,CAAC;YACJ,CAAC;QACH,CAAC;QAED,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,IAAI,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC3D,uEAAuE;QACvE,MAAM,IAAI,GAAG,GAAG,QAAQ,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;QAEtD,MAAM,GAAG,GAAG,CAAC,MAAM,UAAU,CAAC,QAAQ,EAAE,GAAG,EAAE,CAC3C,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC;YAC1B,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE;SACrC,CAAC,CACH,CAA2B,CAAC;QAE7B,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,qBAAqB,CAC7B,gBAAgB,EAChB,4BAA4B,CAC7B,CAAC;QACJ,CAAC;QAED,MAAM,UAAU,CAAC,YAAY,EAAE,GAAG,EAAE,CAClC,MAAM,CAAC,0BAA0B,CAAC,CAAC;YACjC,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,EAAE,cAAc,EAAE,GAAG,CAAC,EAAE,EAAE;SACjC,CAAC,CACH,CAAC;QAEF,OAAO,GAAG,CAAC;IACb,CAAC;IAED;;OAEG;IACH,KAAK,UAAU,eAAe,CAAC,cAAsB;QACnD,MAAM,eAAe,EAAE,CAAC;QAExB,IAAI,OAAO,cAAc,KAAK,QAAQ,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtE,MAAM,IAAI,qBAAqB,CAAC,eAAe,EAAE,sBAAsB,CAAC,CAAC;QAC3E,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC;QAE7B,MAAM,UAAU,CAAC,YAAY,EAAE,GAAG,EAAE,CAClC,MAAM,CAAC,0BAA0B,CAAC,CAAC;YACjC,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,EAAE,cAAc,EAAE;SACzB,CAAC,CACH,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,UAAU,eAAe,CAC5B,KAA2B;QAE3B,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,eAAe,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QAChE,MAAM,SAAS,GAAG,UAAU,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;QAC3D,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC;QAE7B,MAAM,UAAU,GAAoD,EAAE,CAAC;QACvE,IAAI,SAAS,CAAC,IAAI;YAAE,UAAU,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC;QACrD,IAAI,SAAS,CAAC,IAAI;YAAE,UAAU,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC;QACrD,IAAI,SAAS,CAAC,IAAI;YAAE,UAAU,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC;QAErD,MAAM,MAAM,GAAG,CAAC,MAAM,UAAU,CAAC,QAAQ,EAAE,GAAG,EAAE,CAC9C,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC;YAC1B,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,cAAc,EAAE,SAAS,CAAC,EAAE,EAAE;SACzD,CAAC,CACH,CAA2B,CAAC;QAE7B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,qBAAqB,CAC7B,gBAAgB,EAChB,4BAA4B,CAC7B,CAAC;QACJ,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;OAGG;IACH,KAAK,UAAU,eAAe;QAC5B,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,eAAe,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;QACvD,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC;QAE7B,MAAM,UAAU,CAAC,QAAQ,EAAE,GAAG,EAAE,CAC9B,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC;YAC1B,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,EAAE,cAAc,EAAE,SAAS,CAAC,EAAE,EAAE;SACvC,CAAC,CACH,CAAC;QAEF,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,GAAG,EAAE,CACzC,MAAM,CAAC,oBAAoB,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAChD,CAAC;QACF,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,MAAM,UAAU,CAAC,YAAY,EAAE,GAAG,EAAE,CAClC,MAAM,CAAC,0BAA0B,CAAC,CAAC;gBACjC,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE,EAAE,cAAc,EAAE,IAAI,CAAC,CAAC,CAAE,CAAC,EAAE,EAAE;aACtC,CAAC,CACH,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,KAAK,UAAU,kBAAkB;QAC/B,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,oBAAoB,EAAE,CAAC;QACnD,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC;QAE7B,MAAM,GAAG,GAAG,CAAC,MAAM,UAAU,CAAC,qBAAqB,EAAE,GAAG,EAAE,CACxD,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC;YAC3B,OAAO,EAAE,IAAI;YACb,KAAK,EAAE,EAAE,cAAc,EAAE,SAAS,CAAC,EAAE,EAAE;SACxC,CAAC,CACH,CAA2B,CAAC;QAE7B,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,qBAAqB,CAAC,WAAW,EAAE,qBAAqB,CAAC,CAAC;QACtE,CAAC;QAED,OAAO,GAAG,CAAC;IACb,CAAC;IAED,OAAO;QACL,cAAc;QACd,eAAe;QACf,eAAe;QACf,eAAe;QACf,eAAe;QACf,kBAAkB;KACnB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/workspace/service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * What runs once a user's personal workspace exists: trial credits, a
3
+ * welcome note, a referral bonus. The product decides, so auth takes it
4
+ * as a handler set from the composition root and never imports billing.
5
+ *
6
+ * The workspace is created by the `user.create` hook at signup, or by
7
+ * `ensureUserWorkspace` when that hook did not get to it; both call the
8
+ * handler, for the one workspace each of them created.
9
+ */
10
+ import { createLogger } from "@intelligo-dev/core/logger";
11
+ import { createRegistryRef } from "@intelligo-dev/core/registry";
12
+ const log = createLogger("WorkspaceBootstrap");
13
+ const handler = createRegistryRef("auth/workspace-created", null);
14
+ /** Set from the composition root; the last call wins. */
15
+ export function setWorkspaceCreatedHandler(next) {
16
+ handler.set(next);
17
+ }
18
+ export function clearWorkspaceCreatedHandler() {
19
+ handler.set(null);
20
+ }
21
+ /**
22
+ * Runs the handler without waiting for it: a failed bootstrap is
23
+ * logged and never fails the signup that created the workspace.
24
+ */
25
+ export function workspaceCreated(created, run = handler.get()) {
26
+ if (!run)
27
+ return;
28
+ run(created).catch((error) => log.error("Workspace bootstrap failed", {
29
+ workspaceId: created.workspaceId,
30
+ error: error instanceof Error ? error.message : String(error),
31
+ }));
32
+ }
33
+ //# sourceMappingURL=workspace-bootstrap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-bootstrap.js","sourceRoot":"","sources":["../src/workspace-bootstrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEjE,MAAM,GAAG,GAAG,YAAY,CAAC,oBAAoB,CAAC,CAAC;AAY/C,MAAM,OAAO,GAAG,iBAAiB,CAC/B,wBAAwB,EACxB,IAAI,CACL,CAAC;AAEF,yDAAyD;AACzD,MAAM,UAAU,0BAA0B,CACxC,IAA6B;IAE7B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,4BAA4B;IAC1C,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACpB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,OAAyB,EACzB,MAAsC,OAAO,CAAC,GAAG,EAAE;IAEnD,IAAI,CAAC,GAAG;QAAE,OAAO;IACjB,GAAG,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAC3B,GAAG,CAAC,KAAK,CAAC,4BAA4B,EAAE;QACtC,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;KAC9D,CAAC,CACH,CAAC;AACJ,CAAC"}
@@ -1,51 +1,45 @@
1
1
  /**
2
- * Workspace Initialization
3
- *
4
- * Ensures every authenticated user has at least one workspace.
5
- * Called from the (app) layout to guarantee workspace exists.
6
- * Idempotent - safe to call on every page load.
7
- *
8
- * Pattern: "Belt-and-suspenders" approach consistent with Phase 9.
9
- * Better-Auth doesn't provide a reliable hook for post-signup workspace creation,
10
- * so we check + create on every authenticated page load.
11
- *
12
- * Dependency Inversion (Phase 42, PKG-01 preparation):
13
- * Post-creation logic (e.g., trial provisioning) is injected via callback,
14
- * so this module has ZERO billing imports. The actual billing call lives
15
- * in the consumer application's authenticated layout, which already
16
- * imports billing.
17
- * This breaks the auth → billing circular dependency before Phase 43 extraction.
2
+ * Ensures every authenticated user has a workspace; called from the
3
+ * authenticated layout on every render. Post-creation work (trial
4
+ * provisioning) is the handler set with `setWorkspaceCreatedHandler`,
5
+ * so auth never imports billing.
18
6
  */
19
- import { auth } from "./server";
7
+ import { auth } from "./server.js";
20
8
  import { createLogger } from "@intelligo-dev/core/logger";
9
+ import { personalWorkspaceSlug } from "./workspace-slug.js";
10
+ import { workspaceCreated, } from "./workspace-bootstrap.js";
21
11
  const log = createLogger("WorkspaceInit");
22
12
  /**
23
- * Ensure user has at least one workspace (WORK-01).
13
+ * Ensure the user has at least one workspace.
24
14
  *
25
- * If user has organizations, sets the first as active. If none exist,
26
- * creates a personal workspace — this serves as a fallback in case the
27
- * user.create hook (server.ts databaseHooks) hasn't completed yet, and
28
- * also handles users created via non-Better-Auth flows (e.g. admin panel).
29
- *
30
- * Idempotent - safe to call repeatedly. Returns quickly if workspace exists.
15
+ * If the session already has a valid active workspace, returns it
16
+ * untouched; otherwise sets the first workspace as active. If none
17
+ * exist, creates a personal workspace, in case the user.create hook has not
18
+ * completed yet or the user was created outside Better-Auth. Idempotent.
31
19
  *
32
20
  * @param user - Authenticated user from session
33
21
  * @param headers - Request headers (required for Better-Auth API)
34
- * @param options.onWorkspaceCreated - Optional callback invoked after a new workspace is created.
35
- * Receives workspaceId and email. Failure does NOT block workspace creation (same fire-and-forget
36
- * behavior as the previous inline trial provisioning call).
22
+ * @param options.onWorkspaceCreated - Runs after this call creates a workspace, in place of
23
+ * the handler set with `setWorkspaceCreatedHandler`. Fire-and-forget: a failure is logged,
24
+ * never thrown.
37
25
  * @returns The organization ID that was set as active (useful for immediate access before session updates)
38
26
  */
39
27
  export async function ensureUserWorkspace(user, headers, options) {
40
28
  log.info("Starting workspace check", { email: user.email });
41
- // Check if user has any organizations
42
29
  const orgs = await auth.api.listOrganizations({
43
30
  headers,
44
31
  });
45
32
  log.info("Found organizations", { count: orgs?.length ?? 0 });
46
33
  if (orgs && orgs.length > 0 && orgs[0]) {
47
- log.debug("User has workspaces, setting first as active");
48
- // User has workspaces - ensure one is active
34
+ // Keep a workspace the user switched to while they are still a
35
+ // member; resetting to orgs[0] would undo every switch on re-render.
36
+ const current = await auth.api.getSession({ headers });
37
+ const active = current?.session?.activeOrganizationId;
38
+ if (active && orgs.some((org) => org.id === active)) {
39
+ log.debug("Active workspace still valid, keeping it", { orgId: active });
40
+ return active;
41
+ }
42
+ log.debug("No valid active workspace, setting first as active");
49
43
  try {
50
44
  await auth.api.setActiveOrganization({
51
45
  headers,
@@ -61,25 +55,20 @@ export async function ensureUserWorkspace(user, headers, options) {
61
55
  }
62
56
  return orgs[0].id;
63
57
  }
64
- // TR-DB03 fix: No organizations found — the user.create hook may not have
65
- // completed yet, or user was created via a non-Better-Auth flow.
66
- // Create the workspace here as a fallback rather than throwing.
67
- // Idempotent: the unique constraint on organization.slug prevents duplicates
68
- // if both this fallback and the hook fire for the same signup.
58
+ // No workspace yet: create one. The unique index on organization.slug
59
+ // prevents duplicates when the hook or a concurrent request also creates
60
+ // it, because `personalWorkspaceSlug` is derived from the user; the loser
61
+ // takes the adopt-the-winner path below.
69
62
  log.warn("No workspace found, creating one (hook may still fire)", {
70
63
  email: user.email,
71
64
  });
72
- const slug = ((user.email || "user").split("@")[0] || "user")
73
- .toLowerCase()
74
- .replace(/[^a-z0-9-]/g, "-")
75
- .slice(0, 30);
76
65
  let workspaceId;
77
66
  try {
78
67
  const result = await auth.api.createOrganization({
79
68
  headers,
80
69
  body: {
81
70
  name: `${user.name || "User"}'s Workspace`,
82
- slug: `${slug}-${Date.now().toString(36)}`,
71
+ slug: personalWorkspaceSlug(user.email, user.id),
83
72
  userId: user.id,
84
73
  },
85
74
  });
@@ -90,9 +79,8 @@ export async function ensureUserWorkspace(user, headers, options) {
90
79
  log.info("Created fallback workspace", { workspaceId });
91
80
  }
92
81
  catch (error) {
93
- // If creation failed because the unique constraint was hit (hook already
94
- // created), the error message contains the duplicate key info.
95
- // List orgs again — if one now exists, use it.
82
+ // A concurrent creator may have won the unique index; if a workspace
83
+ // now exists, use it.
96
84
  const orgsAfter = await auth.api.listOrganizations({ headers });
97
85
  if (orgsAfter && orgsAfter.length > 0 && orgsAfter[0]) {
98
86
  log.info("Workspace created concurrently by hook, using it");
@@ -102,20 +90,27 @@ export async function ensureUserWorkspace(user, headers, options) {
102
90
  });
103
91
  return orgsAfter[0].id;
104
92
  }
105
- // Genuine failure
106
93
  log.error("Failed to create fallback workspace", {
107
94
  error: error instanceof Error ? error.message : String(error),
108
95
  });
109
96
  throw error;
110
97
  }
111
- // Fire the optional callback (trial credits, referral tracking, etc.)
112
- if (options?.onWorkspaceCreated) {
113
- options
114
- .onWorkspaceCreated({ workspaceId, email: user.email })
115
- .catch((err) => log.error("onWorkspaceCreated callback failed", {
116
- error: err instanceof Error ? err.message : String(err),
117
- }));
98
+ // Point the session at the new workspace, or later requests that resolve
99
+ // one from the session alone find none. Not fatal (the next request sets
100
+ // it), so a failure is logged rather than thrown.
101
+ try {
102
+ await auth.api.setActiveOrganization({
103
+ headers,
104
+ body: { organizationId: workspaceId },
105
+ });
106
+ log.info("Set new workspace active", { workspaceId });
107
+ }
108
+ catch (error) {
109
+ log.error("Failed to set the new workspace active", {
110
+ error: error instanceof Error ? error.message : String(error),
111
+ });
118
112
  }
113
+ workspaceCreated({ workspaceId, userId: user.id, email: user.email }, options?.onWorkspaceCreated);
119
114
  return workspaceId;
120
115
  }
121
116
  //# sourceMappingURL=workspace-init.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-init.js","sourceRoot":"","sources":["../src/workspace-init.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workspace-init.js","sourceRoot":"","sources":["../src/workspace-init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * The slug an auto-provisioned personal workspace gets.
3
+ *
4
+ * Deterministic on purpose. Two paths provision a first workspace —
5
+ * the `user.create` hook in `server.ts` and the layout's
6
+ * `ensureUserWorkspace` fallback — and several requests can reach the
7
+ * fallback at once, because the `(app)` layout re-renders for every
8
+ * request that enters the group (the document, each prefetched sibling
9
+ * route, an error-boundary retry).
10
+ *
11
+ * A slug derived from the user makes `organization.slug`'s unique index
12
+ * the arbiter: the first caller wins, every other one gets
13
+ * `ORGANIZATION_ALREADY_EXISTS` and adopts the winner's workspace. A
14
+ * per-attempt suffix would let each racer create a workspace of its own.
15
+ *
16
+ * Only the automatic personal workspace is named this way; a workspace
17
+ * someone creates by hand names itself.
18
+ */
19
+ export function personalWorkspaceSlug(email, userId) {
20
+ const base = ((email || "user").split("@")[0] || "user").slice(0, 30);
21
+ // The id fragment is normalised with the rest: Better-Auth ids are
22
+ // mixed-case, and a slug the workspace settings form refuses
23
+ // (`[a-z0-9-]+`) makes the personal workspace impossible to rename.
24
+ return toSlug(`${base}-${userId.slice(0, 8)}`);
25
+ }
26
+ function toSlug(value) {
27
+ return value.toLowerCase().replace(/[^a-z0-9-]/g, "-");
28
+ }
29
+ //# sourceMappingURL=workspace-slug.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-slug.js","sourceRoot":"","sources":["../src/workspace-slug.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,qBAAqB,CACnC,KAAgC,EAChC,MAAc;IAEd,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,IAAI,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACtE,mEAAmE;IACnE,6DAA6D;IAC7D,oEAAoE;IACpE,OAAO,MAAM,CAAC,GAAG,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,MAAM,CAAC,KAAa;IAC3B,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;AACzD,CAAC"}
package/package.json CHANGED
@@ -1,15 +1,28 @@
1
1
  {
2
2
  "name": "@intelligo-dev/auth",
3
- "version": "1.0.0-beta.1",
3
+ "version": "1.0.0-beta.13",
4
+ "description": "Multi-tenant authentication on Better-Auth: sign-up, workspaces, invitations and role-based access control.",
5
+ "keywords": [
6
+ "intelligo",
7
+ "ai-saas",
8
+ "saas",
9
+ "typescript",
10
+ "authentication",
11
+ "better-auth",
12
+ "multi-tenant",
13
+ "rbac",
14
+ "workspaces"
15
+ ],
4
16
  "license": "Apache-2.0",
17
+ "author": "Turtuvshin Byambaa <toroo.byamba@gmail.com>",
5
18
  "repository": {
6
19
  "type": "git",
7
- "url": "git+https://github.com/intelligo-mn/framework.git",
20
+ "url": "git+https://github.com/intelligo-dev/intelligo.git",
8
21
  "directory": "packages/auth"
9
22
  },
10
- "homepage": "https://github.com/intelligo-mn/framework#readme",
23
+ "homepage": "https://intelligo.dev/docs/packages/auth",
11
24
  "bugs": {
12
- "url": "https://github.com/intelligo-mn/framework/issues"
25
+ "url": "https://github.com/intelligo-dev/intelligo/issues"
13
26
  },
14
27
  "type": "module",
15
28
  "exports": {
@@ -27,32 +40,41 @@
27
40
  }
28
41
  },
29
42
  "dependencies": {
30
- "better-auth": "~1.6.30",
31
- "drizzle-orm": "^0.45.1",
32
43
  "server-only": "^0.0.1",
33
- "zod": "^3.24.1",
34
- "@intelligo-dev/core": "1.0.0-beta.1"
44
+ "@intelligo-dev/core": "1.0.0-beta.13"
35
45
  },
36
46
  "peerDependencies": {
37
- "next": "^15.0.0 || ^16.0.0"
47
+ "better-auth": "~1.6.30",
48
+ "drizzle-orm": "^0.45.1",
49
+ "zod": "^3.25.76 || ^4.0.0"
38
50
  },
39
51
  "devDependencies": {
40
- "@types/react": "^19.0.10",
41
- "next": "^16.0.7",
42
- "typescript": "^5.7.2"
52
+ "@types/react": "19.2.18",
53
+ "better-auth": "~1.6.33",
54
+ "drizzle-orm": "^0.45.2",
55
+ "typescript": "^5.9.3",
56
+ "zod": "^4.6.5"
43
57
  },
44
58
  "files": [
45
59
  "dist",
46
60
  "src",
47
61
  "!src/**/*.test.ts",
48
- "!src/**/*.test.tsx"
62
+ "!src/**/*.test.tsx",
63
+ "!src/**/__tests__/**",
64
+ "LICENSE",
65
+ "NOTICE",
66
+ "README.md",
67
+ "!dist/**/*.tsbuildinfo"
49
68
  ],
50
69
  "publishConfig": {
51
70
  "access": "public"
52
71
  },
72
+ "engines": {
73
+ "node": ">=22.14"
74
+ },
53
75
  "scripts": {
54
76
  "type-check": "tsc --noEmit",
55
77
  "lint": "eslint .",
56
- "build": "tsc -p tsconfig.build.json"
78
+ "build": "tsc -p tsconfig.build.json && node ../../scripts/fix-esm-extensions.mjs dist"
57
79
  }
58
80
  }
package/src/client.ts CHANGED
@@ -1,27 +1,17 @@
1
1
  /**
2
- * Better-Auth Client
3
- *
4
- * Client-side authentication utilities for React components.
5
- * This module uses "better-auth/react" which is a client-side module.
6
- *
7
- * IMPORTANT: Only import this in "use client" components.
8
- * For server-side auth, use @intelligo-dev/auth (server.ts)
2
+ * The Better-Auth React client. Import only from "use client" components;
3
+ * server code uses `@intelligo-dev/auth`.
9
4
  */
10
5
 
11
6
  import { createAuthClient } from "better-auth/react";
12
7
  import { organizationClient } from "better-auth/client/plugins";
13
8
 
14
- // No `baseURL`: the client and the Better-Auth server always live on the
15
- // same origin (this app's own `/api/auth/*` routes), so Better-Auth's
16
- // client defaults to `window.location.origin` and every request is
17
- // same-origin. Do not reintroduce an absolute `NEXT_PUBLIC_APP_URL`
18
- // baseURL here — the dev port has drifted before (3000 -> 3001 -> 4000)
19
- // and an absolute cross-origin URL is blocked by the app's CSP
20
- // (`connect-src 'self'`) whenever it doesn't match the port the app is
21
- // actually served on.
9
+ // No `baseURL`: the client and server share an origin (`/api/auth/*`), so
10
+ // Better-Auth defaults to `window.location.origin`. An absolute URL is
11
+ // blocked by the app's CSP (`connect-src 'self'`) whenever its port differs
12
+ // from the one the app is served on.
22
13
  export const authClient = createAuthClient({
23
14
  plugins: [organizationClient()],
24
15
  });
25
16
 
26
- // Export commonly used hooks and methods for convenience
27
17
  export const { useSession, signIn, signUp, signOut } = authClient;