@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
package/dist/index.js CHANGED
@@ -1,30 +1,24 @@
1
1
  /**
2
- * Better-Auth Server Exports
3
- *
4
- * Server-side authentication utilities.
5
- * For client-side auth, use @intelligo-dev/auth/client
2
+ * Server-side auth. Client components use `@intelligo-dev/auth/client`.
6
3
  */
7
- export { auth } from "./server";
8
- export { getAuthSession, requireAuth, getWorkspaceContext, getWorkspaceContextById, requireWorkspace, requireRole, requirePlatformAdmin, } from "./helpers";
9
- export { ensureUserWorkspace } from "./workspace-init";
10
- export { PLATFORM_ADMIN_ROLE } from "./roles";
11
- export { impersonateUser, stopImpersonating, } from "./impersonation";
12
- // Typed Better-Auth organization plugin wrapper
13
- export { orgApi, } from "./org-api";
14
- // Team management service (page/registry migration, section C1)
15
- export { createTeamService, } from "./team/service";
16
- export { TeamServiceError, isTeamServiceError, } from "./team/errors";
17
- export { inviteMemberSchema, updateRoleSchema, } from "./team/schemas";
18
- // Workspace management service (page/registry migration, workspace-settings family)
19
- export { createWorkspaceService, } from "./workspace/service";
20
- export { WorkspaceServiceError, isWorkspaceServiceError, } from "./workspace/errors";
21
- export { createWorkspaceSchema, updateWorkspaceSchema, } from "./workspace/schemas";
22
- // Profile management service (page/registry migration, profile-settings family)
23
- export { createProfileService, } from "./profile/service";
24
- export { ProfileServiceError, isProfileServiceError, } from "./profile/errors";
25
- export { updateProfileSchema, } from "./profile/schemas";
26
- // Onboarding service (page/registry migration, `onboarding` family)
27
- export { createOnboardingService, } from "./onboarding/service";
28
- export { OnboardingServiceError, isOnboardingServiceError, } from "./onboarding/errors";
29
- export { setStepSchema } from "./onboarding/schemas";
4
+ export { auth } from "./server.js";
5
+ export { getAuthSession, requireAuth, getWorkspaceContext, getWorkspaceContextById, requireWorkspace, requireRole, requirePlatformAdmin, } from "./helpers.js";
6
+ export { AuthGuardError, isAuthGuardError, } from "./guard-error.js";
7
+ export { ensureUserWorkspace } from "./workspace-init.js";
8
+ export { setWorkspaceCreatedHandler, clearWorkspaceCreatedHandler, } from "./workspace-bootstrap.js";
9
+ export { PLATFORM_ADMIN_ROLE } from "./roles.js";
10
+ export { impersonateUser, stopImpersonating, } from "./impersonation.js";
11
+ export { orgApi, } from "./org-api.js";
12
+ export { createTeamService, } from "./team/service.js";
13
+ export { TeamServiceError, isTeamServiceError, } from "./team/errors.js";
14
+ export { inviteMemberSchema, updateRoleSchema, } from "./team/schemas.js";
15
+ export { createWorkspaceService, } from "./workspace/service.js";
16
+ export { WorkspaceServiceError, isWorkspaceServiceError, } from "./workspace/errors.js";
17
+ export { createWorkspaceSchema, updateWorkspaceSchema, } from "./workspace/schemas.js";
18
+ export { createProfileService, } from "./profile/service.js";
19
+ export { ProfileServiceError, isProfileServiceError, } from "./profile/errors.js";
20
+ export { updateProfileSchema, } from "./profile/schemas.js";
21
+ export { createOnboardingService, } from "./onboarding/service.js";
22
+ export { OnboardingServiceError, isOnboardingServiceError, } from "./onboarding/errors.js";
23
+ export { setStepSchema } from "./onboarding/schemas.js";
30
24
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EACL,cAAc,EACd,WAAW,EACX,mBAAmB,EACnB,uBAAuB,EACvB,gBAAgB,EAChB,WAAW,EACX,oBAAoB,GACrB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,EACL,eAAe,EACf,iBAAiB,GAElB,MAAM,iBAAiB,CAAC;AAKzB,gDAAgD;AAChD,OAAO,EACL,MAAM,GAOP,MAAM,WAAW,CAAC;AAEnB,gEAAgE;AAChE,OAAO,EACL,iBAAiB,GAGlB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,gBAAgB,EAChB,kBAAkB,GAGnB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,kBAAkB,EAClB,gBAAgB,GAGjB,MAAM,gBAAgB,CAAC;AAExB,oFAAoF;AACpF,OAAO,EACL,sBAAsB,GAIvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,qBAAqB,EACrB,uBAAuB,GAGxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,qBAAqB,EACrB,qBAAqB,GAGtB,MAAM,qBAAqB,CAAC;AAE7B,gFAAgF;AAChF,OAAO,EACL,oBAAoB,GAIrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,mBAAmB,EACnB,qBAAqB,GAGtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,mBAAmB,GAEpB,MAAM,mBAAmB,CAAC;AAE3B,oEAAoE;AACpE,OAAO,EACL,uBAAuB,GAGxB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,sBAAsB,EACtB,wBAAwB,GAEzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAqB,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EACL,cAAc,EACd,WAAW,EACX,mBAAmB,EACnB,uBAAuB,EACvB,gBAAgB,EAChB,WAAW,EACX,oBAAoB,GACrB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,cAAc,EACd,gBAAgB,GAEjB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EACL,0BAA0B,EAC1B,4BAA4B,GAC7B,MAAM,uBAAuB,CAAC;AAM/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,EACL,eAAe,EACf,iBAAiB,GAElB,MAAM,iBAAiB,CAAC;AAIzB,OAAO,EACL,MAAM,GAOP,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,iBAAiB,GAGlB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,gBAAgB,EAChB,kBAAkB,GAGnB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,kBAAkB,EAClB,gBAAgB,GAGjB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,sBAAsB,GAIvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,qBAAqB,EACrB,uBAAuB,GAGxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,qBAAqB,EACrB,qBAAqB,GAGtB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,oBAAoB,GAIrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,mBAAmB,EACnB,qBAAqB,GAGtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,mBAAmB,GAEpB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,uBAAuB,GAGxB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,sBAAsB,EACtB,wBAAwB,GAEzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAqB,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * The links an invitation email carries. Both land on the invitation page,
3
+ * which offers accept and decline to the signed-in invitee; declining is a
4
+ * decision made there, never the effect of following a link.
5
+ *
6
+ * Unprefixed on purpose: the consumer's locale middleware resolves the
7
+ * invitee's locale, so the email does not have to guess one.
8
+ */
9
+ export function invitationLinks(appUrl, invitationId) {
10
+ const page = `${appUrl.replace(/\/+$/, "")}/accept-invitation/${encodeURIComponent(invitationId)}`;
11
+ return { acceptUrl: page, declineUrl: page };
12
+ }
13
+ //# sourceMappingURL=invitation-links.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invitation-links.js","sourceRoot":"","sources":["../src/invitation-links.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAC7B,MAAc,EACd,YAAoB;IAEpB,MAAM,IAAI,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,sBAAsB,kBAAkB,CAAC,YAAY,CAAC,EAAE,CAAC;IACnG,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;AAC/C,CAAC"}
@@ -1,13 +1,6 @@
1
1
  /**
2
- * Onboarding service error type.
3
- *
4
- * Mirrors `../team/errors.ts` and `../workspace/errors.ts`: the
5
- * onboarding service (./service.ts) throws this for every failure it
6
- * recognizes rather than returning an ad-hoc `{ success, error }`
7
- * envelope — that shaping is a transport concern (a Server Action, a
8
- * route handler) and belongs one layer up, alongside
9
- * revalidatePath/Sentry/toast/i18n, none of which this package may
10
- * depend on.
2
+ * Thrown for every failure the onboarding service recognizes. Shaping it for a UI
3
+ * (a `{ success, error }` envelope, i18n, revalidation) is the transport's job.
11
4
  */
12
5
  export class OnboardingServiceError extends Error {
13
6
  constructor(code, message, options) {
@@ -15,13 +8,10 @@ export class OnboardingServiceError extends Error {
15
8
  this.name = "OnboardingServiceError";
16
9
  this.code = code;
17
10
  if (options?.cause !== undefined) {
18
- // ES2020 target predates the standard `cause` constructor option;
19
- // assign it directly so `instanceof Error` consumers (and Node's
20
- // own error inspection) still see it.
11
+ // The ES2020 target predates the `cause` constructor option.
21
12
  this.cause = options.cause;
22
13
  }
23
- // Restore prototype chain (extending built-ins across some
24
- // transpilation targets loses `instanceof`).
14
+ // Extending built-ins loses `instanceof` on some transpilation targets.
25
15
  Object.setPrototypeOf(this, OnboardingServiceError.prototype);
26
16
  }
27
17
  }
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/onboarding/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAaH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAG/C,YACE,IAAgC,EAChC,OAAe,EACf,OAA6B;QAE7B,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;YACjC,kEAAkE;YAClE,iEAAiE;YACjE,sCAAsC;YACrC,IAA4B,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QACtD,CAAC;QAED,2DAA2D;QAC3D,6CAA6C;QAC7C,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAChE,CAAC;CACF;AAED,MAAM,UAAU,wBAAwB,CACtC,KAAc;IAEd,OAAO,KAAK,YAAY,sBAAsB,CAAC;AACjD,CAAC"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/onboarding/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAG/C,YACE,IAAgC,EAChC,OAAe,EACf,OAA6B;QAE7B,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;YACjC,6DAA6D;YAC5D,IAA4B,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QACtD,CAAC;QAED,wEAAwE;QACxE,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAChE,CAAC;CACF;AAED,MAAM,UAAU,wBAAwB,CACtC,KAAc;IAEd,OAAO,KAAK,YAAY,sBAAsB,CAAC;AACjD,CAAC"}
@@ -1,19 +1,7 @@
1
1
  /**
2
- * Onboarding validation schema.
3
- *
4
- * A single generic step-id validator — see the module doc comment on
5
- * `./service.ts` for why this is a bare, bounded string rather than a
6
- * product-specific enum. Ignite's original
7
- * `lib/validations/onboarding.ts` pinned this to
8
- * `z.enum(["role", "profile", "complete"])`, Career's own 3-step wizard
9
- * shape. The `users.onboarding_step` column itself is untyped `text`,
10
- * so that enum was a product-level constraint bolted onto a generic
11
- * column, not something this shared contract should require. A
12
- * consumer defines its own step ids (typically the `id` field of a
13
- * steps-config array it owns) and passes them straight through;
14
- * Ignite's cut-over copy keeps its own enum-shaped schema at the
15
- * transport layer if it wants stricter validation than "non-empty,
16
- * bounded string".
2
+ * A step id is a non-empty, bounded string, not an enum: step ids are the
3
+ * consumer's (the `id`s of its own steps config). A consumer wanting
4
+ * stricter validation keeps its own schema at the transport layer.
17
5
  */
18
6
  import { z } from "zod";
19
7
  export const setStepSchema = z
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/onboarding/schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC;KAC3B,MAAM,EAAE;KACR,IAAI,EAAE;KACN,GAAG,CAAC,CAAC,EAAE,qBAAqB,CAAC;KAC7B,GAAG,CAAC,EAAE,EAAE,uCAAuC,CAAC,CAAC"}
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/onboarding/schemas.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC;KAC3B,MAAM,EAAE;KACR,IAAI,EAAE;KACN,GAAG,CAAC,CAAC,EAAE,qBAAqB,CAAC;KAC7B,GAAG,CAAC,EAAE,EAAE,uCAAuC,CAAC,CAAC"}
@@ -1,63 +1,16 @@
1
1
  /**
2
- * Onboarding service — the durable business rules behind a user's
3
- * first-run onboarding flow, extracted from the product application's
4
- * onboarding actions (page/registry migration, `onboarding` family,
5
- * roadmap item 11).
6
- *
7
- * Unlike `../team/service.ts` and `../workspace/service.ts`, this
8
- * service has no Better-Auth organization-plugin calls to make — it
9
- * reads and writes exactly two columns on `@intelligo-dev/core`'s `users`
10
- * table (`onboardingCompleted`, `onboardingStep`) directly via Drizzle.
11
- *
12
- * No ports: `complete()` and `skip()` only flip those two columns and
13
- * return the resulting state — they do NOT provision trial credits,
14
- * record referrals, or perform any other first-workspace bootstrapping.
15
- * Ignite's original `completeOnboarding()` action did exactly that
16
- * (`provisionTrialCredits`/`recordReferralSignup`/`grantReferralUpgrade`
17
- * inline), but that work belongs to the consumer's own
18
- * `onWorkspaceCreated` binding instead — see `../workspace-init.ts`'s
19
- * `onWorkspaceCreated` port and the `app-shell` registry item's
20
- * `lib/workspace-bootstrap.ts`, which already runs once per new
21
- * workspace. Duplicating it here would either double-provision (it
22
- * would fire again on every onboarding completion, not just the first
23
- * workspace) or force this package to depend on `@intelligo-dev/billing`,
24
- * which the allowlist in
25
- * `tests/architecture/dependency-direction.test.ts` forbids.
26
- *
27
- * ---------------------------------------------------------------------
28
- * Why `setStep` takes a bare `string`, not an enum
29
- * ---------------------------------------------------------------------
30
- * See the doc comment on `./schemas.ts`'s `setStepSchema`. Short
31
- * version: the `onboarding_step` column is untyped `text`, and a
32
- * framework-owned service can't know a consumer's step ids in advance
33
- * — a different product may have two steps, or six. This module
34
- * accepts any non-empty string up to 64 characters and persists it
35
- * verbatim.
36
- *
37
- * ---------------------------------------------------------------------
38
- * Why `skip()` has the same durable effect as `complete()`
39
- * ---------------------------------------------------------------------
40
- * The `users` table has no separate "skipped" column, so there is
41
- * nothing else to persist. Ignite's original `skipOnboarding()` action
42
- * logged an analytics event and then delegated to `completeOnboarding()`
43
- * unchanged; this service mirrors that shape as two distinct methods
44
- * (rather than collapsing `skip` into an alias) so a transport can
45
- * still log/tag the skip differently before or after calling it —
46
- * that shaping, like everything else transport-level, does not belong
47
- * in this service.
48
- *
49
- * Authorization (`requireAuth`) lives INSIDE each method, not at the
50
- * transport. Every recognized failure throws `OnboardingServiceError`
51
- * with a stable `code` — no revalidatePath/Sentry/next-intl/toast here;
52
- * that shaping is the transport's job (a Server Action, a route
53
- * handler).
2
+ * The caller's first-run onboarding state: two columns on `users`
3
+ * (`onboardingCompleted`, `onboardingStep`). Completing onboarding has no
4
+ * trial or credit side effects; first-workspace bootstrapping runs once per
5
+ * workspace through `ensureUserWorkspace`'s `onWorkspaceCreated`. Each method
6
+ * authorizes itself and throws `OnboardingServiceError`.
54
7
  */
55
8
  import { eq } from "drizzle-orm";
56
9
  import { db } from "@intelligo-dev/core/db";
57
10
  import { users } from "@intelligo-dev/core/db/schema";
58
- import { requireAuth } from "../helpers";
59
- import { setStepSchema } from "./schemas";
60
- import { OnboardingServiceError, isOnboardingServiceError } from "./errors";
11
+ import { requireAuth } from "../helpers.js";
12
+ import { setStepSchema } from "./schemas.js";
13
+ import { OnboardingServiceError, isOnboardingServiceError } from "./errors.js";
61
14
  function errorMessage(error) {
62
15
  return error instanceof Error ? error.message : String(error);
63
16
  }
@@ -78,9 +31,7 @@ export function createOnboardingService() {
78
31
  throw toForbidden(error);
79
32
  }
80
33
  }
81
- /**
82
- * Get the caller's current onboarding state.
83
- */
34
+ /** The caller's current onboarding state. */
84
35
  async function getState() {
85
36
  const { user } = await callRequireAuth();
86
37
  const [row] = await db
@@ -100,9 +51,8 @@ export function createOnboardingService() {
100
51
  };
101
52
  }
102
53
  /**
103
- * Set the caller's current onboarding step. A product defines its
104
- * own step ids (see the module doc comment); this only validates
105
- * that `step` is a non-empty, bounded string and persists it
54
+ * Set the caller's current step. Step ids are the product's; this only
55
+ * checks for a non-empty string of at most 64 characters and persists it
106
56
  * verbatim. Does not touch `onboardingCompleted`.
107
57
  */
108
58
  async function setStep(step) {
@@ -118,10 +68,7 @@ export function createOnboardingService() {
118
68
  .where(eq(users.id, user.id));
119
69
  return { completed: false, currentStep: parsed.data };
120
70
  }
121
- /**
122
- * Mark onboarding complete and clear the step. No trial/referral
123
- * side effects — see the module doc comment.
124
- */
71
+ /** Mark onboarding complete and clear the step. */
125
72
  async function complete() {
126
73
  const { user } = await callRequireAuth();
127
74
  await db
@@ -135,9 +82,8 @@ export function createOnboardingService() {
135
82
  return { completed: true, currentStep: null };
136
83
  }
137
84
  /**
138
- * Skip onboarding. Same durable effect as `complete()` — see the
139
- * module doc comment for why this is its own method rather than an
140
- * alias.
85
+ * Skip onboarding. Same durable effect as `complete()` (there is no
86
+ * "skipped" column); a separate method so a transport can tell them apart.
141
87
  */
142
88
  async function skip() {
143
89
  return complete();
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/onboarding/service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/onboarding/service.ts"],"names":[],"mappings":"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"}
package/dist/org-api.js CHANGED
@@ -1,73 +1,16 @@
1
1
  /**
2
- * Typed wrapper for Better-Auth organization plugin endpoints.
3
- *
4
- * The plugin endpoints (`/organization/...`) are added at runtime by
5
- * Better-Auth's organization plugin and are not present on the inferred
6
- * `auth.api` type. Without a wrapper, consumers had to reach for
7
- * `as any as Record<...>` casts or `@ts-expect-error` comments — both
8
- * lose all type information.
9
- *
10
- * This module declares the explicit input/output shapes for every
11
- * organization endpoint the team service calls and exposes them under
12
- * the plugin's HTTP path names (`/organization/invite-member`, etc.),
13
- * which is the vocabulary the rest of this package's `team/` module
14
- * uses.
15
- *
16
- * (Ported from the product application’s Better-Auth type wrapper as part of the
17
- * team-settings backend extraction — packages/auth owns the org-api
18
- * contract now; ignite's copy is retired at cutover.)
19
- *
20
- * IMPORTANT — found while wiring the real-DB integration test for this
21
- * extraction: ignite's original module built `orgApi` as
22
- * `auth.api as unknown as OrgApi`, i.e. a bare type-cast that assumes
23
- * `auth.api` is keyed by these HTTP path strings. It is not. Better-Auth's
24
- * organization plugin (`better-auth@1.6.30`,
25
- * `plugins/organization/organization.mjs`) exposes each endpoint on
26
- * `auth.api` under its own camelCase *server* id, which does not always
27
- * match the path or the *client* SDK name documented alongside it:
28
- *
29
- * path | auth.api key (server) | authClient.organization.* (client)
30
- * /organization/invite-member | createInvitation | inviteMember
31
- * /organization/get-invitation | getInvitation | getInvitation
32
- * /organization/accept-invitation | acceptInvitation | acceptInvitation
33
- * /organization/reject-invitation | rejectInvitation | rejectInvitation
34
- * /organization/cancel-invitation | cancelInvitation | cancelInvitation
35
- * /organization/remove-member | removeMember | removeMember
36
- * /organization/update-member-role | updateMemberRole | updateMemberRole
37
- * /organization/leave | leaveOrganization | leave
38
- * /organization/list | listOrganizations | list
39
- * /organization/set-active | setActiveOrganization | setActive
40
- * /organization/list-user-invitations | listUserInvitations | listUserInvitations
41
- *
42
- * A bare `auth.api as unknown as OrgApi` cast type-checks (TypeScript
43
- * cannot see through the cast) but throws `TypeError: ... is not a
44
- * function` at runtime for every call whose row above differs in the
45
- * first two columns — i.e. invite-member, leave, list, and set-active
46
- * unconditionally, since their server ids aren't just a casing change
47
- * of the path. This was invisible in ignite's test suite because
48
- * `actions/__tests__/team.test.ts` mocks `@/types/better-auth` (the
49
- * whole `orgApi` object) rather than exercising the cast against a
50
- * real `auth.api`, and only surfaced once this extraction's
51
- * `service.integration.test.ts` called the real thing. It is a live
52
- * bug in ignite's shipped team-management actions today, not a
53
- * hypothetical — worth a fix there independent of this migration.
54
- *
55
- * `orgApi` below is therefore a real object, not a cast: each path key
56
- * forwards to the correctly-named `auth.api` method. The `OrgApi`
57
- * type and every call site elsewhere in this package (`team/service.ts`
58
- * and its tests) are unaffected — they only ever see the path-keyed
59
- * shape.
2
+ * Typed access to Better-Auth's organization-plugin endpoints, which the
3
+ * inferred `auth.api` type does not include. Keys are the plugin's HTTP
4
+ * paths; each forwards to the plugin's server id, which is not always the
5
+ * path in camelCase (`/organization/invite-member` is `createInvitation`,
6
+ * `/organization/list` is `listOrganizations`), so a blanket cast of
7
+ * `auth.api` would type-check and then throw "is not a function".
60
8
  */
61
- import { auth } from "./server";
9
+ import { auth } from "./server.js";
62
10
  /**
63
- * `auth.api`'s organization-plugin methods are typed loosely by
64
- * Better-Auth (broad `Record<string, unknown>`-ish body/query types
65
- * driven by its own zod schemas) — each is cast to its specific
66
- * `OrgApi` member signature at the point of use below, which is the
67
- * same trust boundary the rest of this codebase already accepts for
68
- * these calls (see the module doc comment above for why a *blanket*
69
- * cast is not safe: it hides the wrong key entirely, whereas casting
70
- * per-member here only relaxes the parameter/return types).
11
+ * Better-Auth types these methods loosely; each is cast to its `OrgApi`
12
+ * member signature below, which relaxes only parameter and return types,
13
+ * never which method a key names.
71
14
  */
72
15
  const api = auth.api;
73
16
  export const orgApi = {
@@ -1 +1 @@
1
- {"version":3,"file":"org-api.js","sourceRoot":"","sources":["../src/org-api.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAoGhC;;;;;;;;;GASG;AACH,MAAM,GAAG,GAAG,IAAI,CAAC,GAGhB,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GAAW;IAC5B,6BAA6B,EAC3B,GAAG,CAAC,gBAAyD;IAC/D,8BAA8B,EAC5B,GAAG,CAAC,aAAuD;IAC7D,iCAAiC,EAC/B,GAAG,CAAC,gBAA6D;IACnE,iCAAiC,EAC/B,GAAG,CAAC,gBAA6D;IACnE,iCAAiC,EAC/B,GAAG,CAAC,gBAA6D;IACnE,6BAA6B,EAC3B,GAAG,CAAC,YAAqD;IAC3D,kCAAkC,EAChC,GAAG,CAAC,gBAA8D;IACpE,qBAAqB,EAAE,GAAG,CAAC,iBAAkD;IAC7E,oBAAoB,EAAE,GAAG,CAAC,iBAAiD;IAC3E,0BAA0B,EACxB,GAAG,CAAC,qBAA2D;IACjE,qCAAqC,EACnC,GAAG,CAAC,mBAAoE;CAC3E,CAAC"}
1
+ {"version":3,"file":"org-api.js","sourceRoot":"","sources":["../src/org-api.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAoGhC;;;;GAIG;AACH,MAAM,GAAG,GAAG,IAAI,CAAC,GAGhB,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GAAW;IAC5B,6BAA6B,EAC3B,GAAG,CAAC,gBAAyD;IAC/D,8BAA8B,EAC5B,GAAG,CAAC,aAAuD;IAC7D,iCAAiC,EAC/B,GAAG,CAAC,gBAA6D;IACnE,iCAAiC,EAC/B,GAAG,CAAC,gBAA6D;IACnE,iCAAiC,EAC/B,GAAG,CAAC,gBAA6D;IACnE,6BAA6B,EAC3B,GAAG,CAAC,YAAqD;IAC3D,kCAAkC,EAChC,GAAG,CAAC,gBAA8D;IACpE,qBAAqB,EAAE,GAAG,CAAC,iBAAkD;IAC7E,oBAAoB,EAAE,GAAG,CAAC,iBAAiD;IAC3E,0BAA0B,EACxB,GAAG,CAAC,qBAA2D;IACjE,qCAAqC,EACnC,GAAG,CAAC,mBAAoE;CAC3E,CAAC"}
@@ -1,13 +1,6 @@
1
1
  /**
2
- * Profile service error type.
3
- *
4
- * The profile service (./service.ts) throws this for every failure it
5
- * recognizes rather than returning an ad-hoc `{ success, error }`
6
- * envelope — that shaping is a transport concern (a Server Action, a
7
- * route handler) and belongs one layer up, alongside
8
- * revalidatePath/Sentry/toast/i18n, none of which this package may
9
- * depend on. Mirrors `TeamServiceError`/`WorkspaceServiceError`
10
- * (../team/errors.ts, ../workspace/errors.ts).
2
+ * Thrown for every failure the profile service recognizes. Shaping it for a UI
3
+ * (a `{ success, error }` envelope, i18n, revalidation) is the transport's job.
11
4
  */
12
5
  export class ProfileServiceError extends Error {
13
6
  constructor(code, message, options) {
@@ -16,13 +9,10 @@ export class ProfileServiceError extends Error {
16
9
  this.code = code;
17
10
  this.meta = options?.meta;
18
11
  if (options?.cause !== undefined) {
19
- // ES2020 target predates the standard `cause` constructor option;
20
- // assign it directly so `instanceof Error` consumers (and Node's
21
- // own error inspection) still see it.
12
+ // The ES2020 target predates the `cause` constructor option.
22
13
  this.cause = options.cause;
23
14
  }
24
- // Restore prototype chain (extending built-ins across some
25
- // transpilation targets loses `instanceof`).
15
+ // Extending built-ins loses `instanceof` on some transpilation targets.
26
16
  Object.setPrototypeOf(this, ProfileServiceError.prototype);
27
17
  }
28
18
  }
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/profile/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAiBH,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAI5C,YACE,IAA6B,EAC7B,OAAe,EACf,OAA6D;QAE7D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;QAClC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,CAAC;QAC1B,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;YACjC,kEAAkE;YAClE,iEAAiE;YACjE,sCAAsC;YACrC,IAA4B,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QACtD,CAAC;QAED,2DAA2D;QAC3D,6CAA6C;QAC7C,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAC7D,CAAC;CACF;AAED,MAAM,UAAU,qBAAqB,CACnC,KAAc;IAEd,OAAO,KAAK,YAAY,mBAAmB,CAAC;AAC9C,CAAC"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/profile/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAeH,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAI5C,YACE,IAA6B,EAC7B,OAAe,EACf,OAA6D;QAE7D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;QAClC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,CAAC;QAC1B,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;YACjC,6DAA6D;YAC5D,IAA4B,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QACtD,CAAC;QAED,wEAAwE;QACxE,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAC7D,CAAC;CACF;AAED,MAAM,UAAU,qBAAqB,CACnC,KAAc;IAEd,OAAO,KAAK,YAAY,mBAAmB,CAAC;AAC9C,CAAC"}
@@ -1,13 +1,4 @@
1
- /**
2
- * Profile Validation Schemas
3
- *
4
- * Zod schemas for user profile updates, shared by the profile service
5
- * and its transports.
6
- *
7
- * (Ported from the product application's `lib/validations/profile.ts` —
8
- * same semantics: optional name, optional-and-nullable image URL.
9
- * Ignite's copy is retired at cutover.)
10
- */
1
+ /** Profile update input, shared by the profile service and its transports. */
11
2
  import { z } from "zod";
12
3
  export const updateProfileSchema = z.object({
13
4
  name: z
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/profile/schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,IAAI,EAAE,CAAC;SACJ,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,EAAE,oCAAoC,CAAC;SAC5C,GAAG,CAAC,GAAG,EAAE,qCAAqC,CAAC;SAC/C,QAAQ,EAAE;IACb,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CACzE,CAAC,CAAC"}
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/profile/schemas.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAE9E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,IAAI,EAAE,CAAC;SACJ,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,EAAE,oCAAoC,CAAC;SAC5C,GAAG,CAAC,GAAG,EAAE,qCAAqC,CAAC;SAC/C,QAAQ,EAAE;IACb,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CACzE,CAAC,CAAC"}
@@ -1,56 +1,18 @@
1
1
  /**
2
- * Profile management service — the durable business rules behind
3
- * reading the caller's own profile, updating it, and deleting the
4
- * account, extracted from the product application's profile actions
5
- * (page/registry migration, `profile-settings` family, roadmap item 9).
6
- *
7
- * Mirrors `createTeamService(ports)` / `createWorkspaceService(ports)`
8
- * (../team/service.ts, ../workspace/service.ts) one directory over: a
9
- * factory over optional ports, so this package's allowlisted dependency
10
- * (`@intelligo-dev/core` only — see
11
- * tests/architecture/dependency-direction.test.ts) never grows to
12
- * include an email-sending concern of its own. A consumer binds the
13
- * account-deletion confirmation email in at its composition root:
14
- *
15
- * const profileService = createProfileService({
16
- * onAccountDeleted: ({ email, name }) =>
17
- * sendEmail({ to: email, subject: ..., html: ... }), // @intelligo-dev/core/email
18
- * });
19
- *
20
- * Authorization (`requireAuth`) lives INSIDE each method, not at the
21
- * transport. Every recognized failure throws `ProfileServiceError` with
22
- * a stable `code` — no revalidatePath/Sentry/next-intl/toast here; that
23
- * shaping is the transport's job (a Server Action, a route handler).
24
- *
25
- * ---------------------------------------------------------------------
26
- * Why the confirmation email is a port, not a direct import
27
- * ---------------------------------------------------------------------
28
- * The product application's original `deleteAccount()`
29
- * calls `sendEmail` from
30
- * `@intelligo-dev/core/email` directly, inline, with a hardcoded English
31
- * HTML template. `@intelligo-dev/auth` already imports `@intelligo-dev/core/email`
32
- * elsewhere (`server.ts`'s Better-Auth hooks — verification, password
33
- * reset, welcome, invitation emails), so nothing in the allowlist
34
- * (auth → core only) would technically block importing `sendEmail`
35
- * here too. The port exists anyway, for the same reason
36
- * `TeamServicePorts.sendInvitationEmail` and
37
- * `WorkspaceServicePorts.checkWorkspaceLimit` are ports rather than
38
- * direct calls: this service should not own *content* — copy, subject
39
- * lines, template shape — for a side effect a consumer may want to
40
- * localize, skip, or replace with a different provider. `onAccountDeleted`
41
- * is fire-and-forget by design (matching ignite's `.catch(console.error)`
42
- * pattern): a failed confirmation email must never block the deletion
43
- * that already succeeded.
2
+ * The caller's own profile: read, update, delete the account. Each method
3
+ * authorizes itself and throws `ProfileServiceError`. The confirmation email
4
+ * is the `onAccountDeleted` port so its copy and provider stay the
5
+ * consumer's; it is fire-and-forget, since the deletion has already succeeded.
44
6
  */
45
- import { headers } from "next/headers";
7
+ import { getRequestHeaders } from "@intelligo-dev/core/request-context";
46
8
  import { eq } from "drizzle-orm";
47
9
  import { createLogger } from "@intelligo-dev/core/logger";
48
10
  import { db } from "@intelligo-dev/core/db";
49
11
  import { users, sessions } from "@intelligo-dev/core/db/schema";
50
- import { auth } from "../server";
51
- import { requireAuth } from "../helpers";
52
- import { updateProfileSchema } from "./schemas";
53
- import { ProfileServiceError, isProfileServiceError } from "./errors";
12
+ import { auth } from "../server.js";
13
+ import { requireAuth } from "../helpers.js";
14
+ import { updateProfileSchema } from "./schemas.js";
15
+ import { ProfileServiceError, isProfileServiceError } from "./errors.js";
54
16
  const log = createLogger("ProfileService");
55
17
  function errorMessage(error) {
56
18
  return error instanceof Error ? error.message : String(error);
@@ -80,9 +42,7 @@ export function createProfileService(ports = {}) {
80
42
  throw toForbidden(error);
81
43
  }
82
44
  }
83
- /**
84
- * Get the caller's own profile.
85
- */
45
+ /** The caller's own profile. */
86
46
  async function getProfile() {
87
47
  const { user } = await callRequireAuth();
88
48
  return {
@@ -97,13 +57,12 @@ export function createProfileService(ports = {}) {
97
57
  * Update the caller's own name/image via the Better-Auth user API.
98
58
  * Only the fields present in `input` are sent — omitting a field
99
59
  * leaves it unchanged; `image: null` is dropped rather than forwarded
100
- * (Better-Auth's `updateUser` does not accept `null`), matching
101
- * ignite's original action.
60
+ * (Better-Auth's `updateUser` does not accept `null`).
102
61
  */
103
62
  async function updateProfile(input) {
104
63
  await callRequireAuth();
105
64
  const validated = parseInput(updateProfileSchema, input);
106
- const hdrs = await headers();
65
+ const hdrs = await getRequestHeaders();
107
66
  const updateData = {};
108
67
  if (validated.name !== undefined)
109
68
  updateData.name = validated.name;
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/profile/service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/profile/service.ts"],"names":[],"mappings":"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"}
package/dist/roles.js CHANGED
@@ -1,9 +1,6 @@
1
1
  /**
2
- * The platform role.
3
- *
4
- * Deliberately a separate module from helpers.ts and server.ts: both
5
- * need the constant, and server.ts (the Better-Auth instance) cannot
6
- * import helpers.ts, which imports server.ts.
2
+ * Its own module because server.ts and helpers.ts both need it, and
3
+ * server.ts cannot import helpers.ts, which imports server.ts.
7
4
  */
8
5
  /**
9
6
  * Grants the operational console and, through Better-Auth's admin
@@ -14,4 +11,30 @@
14
11
  * on it is gated on nothing.
15
12
  */
16
13
  export const PLATFORM_ADMIN_ROLE = "platform-admin";
14
+ /**
15
+ * Where a user stands as a platform admin: `hasRole` reads `users.role`
16
+ * (comma-separated), `allowlisted` reads PLATFORM_ADMIN_EMAILS, the
17
+ * bootstrap that `requirePlatformAdmin` promotes into the column.
18
+ *
19
+ * The allowlist names an address, so it counts only once the address
20
+ * is verified: otherwise whoever registers an allowlisted address
21
+ * first — before the real admin, or on a deployment that sends no
22
+ * verification mail — would become an admin.
23
+ */
24
+ export function platformAdminStanding(user) {
25
+ const allowlist = (process.env.PLATFORM_ADMIN_EMAILS ?? "")
26
+ .split(",")
27
+ .map((e) => e.trim().toLowerCase())
28
+ .filter(Boolean);
29
+ const email = user.email?.toLowerCase();
30
+ const roles = (user.role ?? "")
31
+ .split(",")
32
+ .map((r) => r.trim())
33
+ .filter(Boolean);
34
+ return {
35
+ allowlisted: !!email && user.emailVerified === true && allowlist.includes(email),
36
+ hasRole: roles.includes(PLATFORM_ADMIN_ROLE),
37
+ roles,
38
+ };
39
+ }
17
40
  //# sourceMappingURL=roles.js.map
package/dist/roles.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"roles.js","sourceRoot":"","sources":["../src/roles.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,gBAAgB,CAAC"}
1
+ {"version":3,"file":"roles.js","sourceRoot":"","sources":["../src/roles.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,gBAAgB,CAAC;AAEpD;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAIrC;IACC,MAAM,SAAS,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,EAAE,CAAC;SACxD,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;SAClC,MAAM,CAAC,OAAO,CAAC,CAAC;IAEnB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC;IACxC,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;SAC5B,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,OAAO,CAAC,CAAC;IAEnB,OAAO;QACL,WAAW,EACT,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,aAAa,KAAK,IAAI,IAAI,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC;QACrE,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,mBAAmB,CAAC;QAC5C,KAAK;KACN,CAAC;AACJ,CAAC"}