@objectstack/plugin-security 6.8.1 → 6.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -927,6 +927,14 @@ declare const securityObjects: ((Omit<{
927
927
  } | undefined;
928
928
  recordTypes?: string[] | undefined;
929
929
  sharingModel?: "read" | "full" | "private" | "read_write" | undefined;
930
+ publicSharing?: {
931
+ enabled: boolean;
932
+ allowedAudiences?: ("email" | "public" | "link_only" | "signed_in")[] | undefined;
933
+ allowedPermissions?: ("edit" | "view" | "comment")[] | undefined;
934
+ maxExpiryDays?: number | undefined;
935
+ redactFields?: string[] | undefined;
936
+ eligibility?: string | undefined;
937
+ } | undefined;
930
938
  keyPrefix?: string | undefined;
931
939
  detail?: {
932
940
  [x: string]: unknown;
@@ -3366,6 +3374,14 @@ declare const securityObjects: ((Omit<{
3366
3374
  } | undefined;
3367
3375
  recordTypes?: string[] | undefined;
3368
3376
  sharingModel?: "read" | "full" | "private" | "read_write" | undefined;
3377
+ publicSharing?: {
3378
+ enabled: boolean;
3379
+ allowedAudiences?: ("email" | "public" | "link_only" | "signed_in")[] | undefined;
3380
+ allowedPermissions?: ("edit" | "view" | "comment")[] | undefined;
3381
+ maxExpiryDays?: number | undefined;
3382
+ redactFields?: string[] | undefined;
3383
+ eligibility?: string | undefined;
3384
+ } | undefined;
3369
3385
  keyPrefix?: string | undefined;
3370
3386
  detail?: {
3371
3387
  [x: string]: unknown;
@@ -5769,6 +5785,14 @@ declare const securityObjects: ((Omit<{
5769
5785
  } | undefined;
5770
5786
  recordTypes?: string[] | undefined;
5771
5787
  sharingModel?: "read" | "full" | "private" | "read_write" | undefined;
5788
+ publicSharing?: {
5789
+ enabled: boolean;
5790
+ allowedAudiences?: ("email" | "public" | "link_only" | "signed_in")[] | undefined;
5791
+ allowedPermissions?: ("edit" | "view" | "comment")[] | undefined;
5792
+ maxExpiryDays?: number | undefined;
5793
+ redactFields?: string[] | undefined;
5794
+ eligibility?: string | undefined;
5795
+ } | undefined;
5772
5796
  keyPrefix?: string | undefined;
5773
5797
  detail?: {
5774
5798
  [x: string]: unknown;
@@ -7694,6 +7718,14 @@ declare const securityObjects: ((Omit<{
7694
7718
  } | undefined;
7695
7719
  recordTypes?: string[] | undefined;
7696
7720
  sharingModel?: "read" | "full" | "private" | "read_write" | undefined;
7721
+ publicSharing?: {
7722
+ enabled: boolean;
7723
+ allowedAudiences?: ("email" | "public" | "link_only" | "signed_in")[] | undefined;
7724
+ allowedPermissions?: ("edit" | "view" | "comment")[] | undefined;
7725
+ maxExpiryDays?: number | undefined;
7726
+ redactFields?: string[] | undefined;
7727
+ eligibility?: string | undefined;
7728
+ } | undefined;
7697
7729
  keyPrefix?: string | undefined;
7698
7730
  detail?: {
7699
7731
  [x: string]: unknown;
@@ -8730,69 +8762,6 @@ declare const securityPluginManifestHeader: {
8730
8762
  description: string;
8731
8763
  };
8732
8764
 
8733
- /**
8734
- * ensureUserHasOrganization — auto-create a personal org for new users.
8735
- *
8736
- * In multi-tenant mode, every record visible through the default
8737
- * `tenant_isolation` RLS policy must have an `organization_id`, and
8738
- * every authenticated user must have an `activeOrganizationId` on their
8739
- * session for that policy to evaluate to anything other than "deny
8740
- * all". A user with zero `sys_member` rows, however, can sign in
8741
- * successfully and reach the dashboard — the dashboard's
8742
- * `RequireOrganization` guard has a single-tenant carve-out that lets
8743
- * users with empty organization lists through, so they land on a UI
8744
- * that simply hides every record. The standard remedy ("invite users
8745
- * via an admin") doesn't apply to self-service signup.
8746
- *
8747
- * This helper, run right after a `sys_user` insert, ensures the new
8748
- * user has at least one organization by creating a personal workspace
8749
- * (named "<User>'s Workspace", slug `<username>-workspace`) and an
8750
- * owner-role `sys_member` row. The user's session will pick this up as
8751
- * their `activeOrganizationId` on the next sign-in / org-list refresh
8752
- * (better-auth's `setActiveOrganization` runs lazily when the picker
8753
- * sees exactly one membership).
8754
- *
8755
- * Idempotent: bails out if the user already has any `sys_member` row.
8756
- * Slug collisions retry with a numeric suffix; a cap of 5 attempts
8757
- * means a pathological username will fail loudly rather than loop.
8758
- */
8759
- interface EnsureOptions {
8760
- logger?: {
8761
- info: (message: string, meta?: Record<string, any>) => void;
8762
- warn: (message: string, meta?: Record<string, any>) => void;
8763
- };
8764
- /**
8765
- * Optional hook called after a personal org is successfully created.
8766
- * Used by SecurityPlugin to wire in `cloneTenantSeedData` so each
8767
- * new workspace gets its own copy of demo data. Pulled in via DI
8768
- * to keep this helper free of a hard import on the cloner (which
8769
- * keeps the tenant-claim and ensure-org test surfaces narrow).
8770
- */
8771
- cloneSeedData?: (ql: any, targetOrgId: string, opts: {
8772
- logger?: EnsureOptions['logger'];
8773
- }) => Promise<{
8774
- object: string;
8775
- count: number;
8776
- }[]>;
8777
- }
8778
- /**
8779
- * Ensure `user` has at least one `sys_member` row. Creates a personal
8780
- * organization owned by them if not.
8781
- *
8782
- * Returns `{ created: true, organizationId }` when a new org was made,
8783
- * or `{ created: false, reason }` when the user already has memberships
8784
- * or the operation was skipped.
8785
- */
8786
- declare function ensureUserHasOrganization(ql: any, user: {
8787
- id: string;
8788
- name?: string;
8789
- email?: string;
8790
- }, options?: EnsureOptions): Promise<{
8791
- created: boolean;
8792
- organizationId?: string;
8793
- reason?: string;
8794
- }>;
8795
-
8796
8765
  interface CloneOptions {
8797
8766
  logger?: {
8798
8767
  info: (message: string, meta?: Record<string, any>) => void;
@@ -8804,4 +8773,4 @@ declare function cloneTenantSeedData(ql: any, targetOrgId: string, options?: Clo
8804
8773
  count: number;
8805
8774
  }[]>;
8806
8775
 
8807
- export { FieldMasker, PermissionDeniedError, PermissionEvaluator, RLSCompiler, RLS_DENY_FILTER, SECURITY_PLUGIN_ID, SECURITY_PLUGIN_VERSION, SecurityPlugin, cloneTenantSeedData, ensureUserHasOrganization, isPermissionDeniedError, securityDefaultPermissionSets, securityObjects, securityPluginManifestHeader };
8776
+ export { FieldMasker, PermissionDeniedError, PermissionEvaluator, RLSCompiler, RLS_DENY_FILTER, SECURITY_PLUGIN_ID, SECURITY_PLUGIN_VERSION, SecurityPlugin, cloneTenantSeedData, isPermissionDeniedError, securityDefaultPermissionSets, securityObjects, securityPluginManifestHeader };
package/dist/index.d.ts CHANGED
@@ -927,6 +927,14 @@ declare const securityObjects: ((Omit<{
927
927
  } | undefined;
928
928
  recordTypes?: string[] | undefined;
929
929
  sharingModel?: "read" | "full" | "private" | "read_write" | undefined;
930
+ publicSharing?: {
931
+ enabled: boolean;
932
+ allowedAudiences?: ("email" | "public" | "link_only" | "signed_in")[] | undefined;
933
+ allowedPermissions?: ("edit" | "view" | "comment")[] | undefined;
934
+ maxExpiryDays?: number | undefined;
935
+ redactFields?: string[] | undefined;
936
+ eligibility?: string | undefined;
937
+ } | undefined;
930
938
  keyPrefix?: string | undefined;
931
939
  detail?: {
932
940
  [x: string]: unknown;
@@ -3366,6 +3374,14 @@ declare const securityObjects: ((Omit<{
3366
3374
  } | undefined;
3367
3375
  recordTypes?: string[] | undefined;
3368
3376
  sharingModel?: "read" | "full" | "private" | "read_write" | undefined;
3377
+ publicSharing?: {
3378
+ enabled: boolean;
3379
+ allowedAudiences?: ("email" | "public" | "link_only" | "signed_in")[] | undefined;
3380
+ allowedPermissions?: ("edit" | "view" | "comment")[] | undefined;
3381
+ maxExpiryDays?: number | undefined;
3382
+ redactFields?: string[] | undefined;
3383
+ eligibility?: string | undefined;
3384
+ } | undefined;
3369
3385
  keyPrefix?: string | undefined;
3370
3386
  detail?: {
3371
3387
  [x: string]: unknown;
@@ -5769,6 +5785,14 @@ declare const securityObjects: ((Omit<{
5769
5785
  } | undefined;
5770
5786
  recordTypes?: string[] | undefined;
5771
5787
  sharingModel?: "read" | "full" | "private" | "read_write" | undefined;
5788
+ publicSharing?: {
5789
+ enabled: boolean;
5790
+ allowedAudiences?: ("email" | "public" | "link_only" | "signed_in")[] | undefined;
5791
+ allowedPermissions?: ("edit" | "view" | "comment")[] | undefined;
5792
+ maxExpiryDays?: number | undefined;
5793
+ redactFields?: string[] | undefined;
5794
+ eligibility?: string | undefined;
5795
+ } | undefined;
5772
5796
  keyPrefix?: string | undefined;
5773
5797
  detail?: {
5774
5798
  [x: string]: unknown;
@@ -7694,6 +7718,14 @@ declare const securityObjects: ((Omit<{
7694
7718
  } | undefined;
7695
7719
  recordTypes?: string[] | undefined;
7696
7720
  sharingModel?: "read" | "full" | "private" | "read_write" | undefined;
7721
+ publicSharing?: {
7722
+ enabled: boolean;
7723
+ allowedAudiences?: ("email" | "public" | "link_only" | "signed_in")[] | undefined;
7724
+ allowedPermissions?: ("edit" | "view" | "comment")[] | undefined;
7725
+ maxExpiryDays?: number | undefined;
7726
+ redactFields?: string[] | undefined;
7727
+ eligibility?: string | undefined;
7728
+ } | undefined;
7697
7729
  keyPrefix?: string | undefined;
7698
7730
  detail?: {
7699
7731
  [x: string]: unknown;
@@ -8730,69 +8762,6 @@ declare const securityPluginManifestHeader: {
8730
8762
  description: string;
8731
8763
  };
8732
8764
 
8733
- /**
8734
- * ensureUserHasOrganization — auto-create a personal org for new users.
8735
- *
8736
- * In multi-tenant mode, every record visible through the default
8737
- * `tenant_isolation` RLS policy must have an `organization_id`, and
8738
- * every authenticated user must have an `activeOrganizationId` on their
8739
- * session for that policy to evaluate to anything other than "deny
8740
- * all". A user with zero `sys_member` rows, however, can sign in
8741
- * successfully and reach the dashboard — the dashboard's
8742
- * `RequireOrganization` guard has a single-tenant carve-out that lets
8743
- * users with empty organization lists through, so they land on a UI
8744
- * that simply hides every record. The standard remedy ("invite users
8745
- * via an admin") doesn't apply to self-service signup.
8746
- *
8747
- * This helper, run right after a `sys_user` insert, ensures the new
8748
- * user has at least one organization by creating a personal workspace
8749
- * (named "<User>'s Workspace", slug `<username>-workspace`) and an
8750
- * owner-role `sys_member` row. The user's session will pick this up as
8751
- * their `activeOrganizationId` on the next sign-in / org-list refresh
8752
- * (better-auth's `setActiveOrganization` runs lazily when the picker
8753
- * sees exactly one membership).
8754
- *
8755
- * Idempotent: bails out if the user already has any `sys_member` row.
8756
- * Slug collisions retry with a numeric suffix; a cap of 5 attempts
8757
- * means a pathological username will fail loudly rather than loop.
8758
- */
8759
- interface EnsureOptions {
8760
- logger?: {
8761
- info: (message: string, meta?: Record<string, any>) => void;
8762
- warn: (message: string, meta?: Record<string, any>) => void;
8763
- };
8764
- /**
8765
- * Optional hook called after a personal org is successfully created.
8766
- * Used by SecurityPlugin to wire in `cloneTenantSeedData` so each
8767
- * new workspace gets its own copy of demo data. Pulled in via DI
8768
- * to keep this helper free of a hard import on the cloner (which
8769
- * keeps the tenant-claim and ensure-org test surfaces narrow).
8770
- */
8771
- cloneSeedData?: (ql: any, targetOrgId: string, opts: {
8772
- logger?: EnsureOptions['logger'];
8773
- }) => Promise<{
8774
- object: string;
8775
- count: number;
8776
- }[]>;
8777
- }
8778
- /**
8779
- * Ensure `user` has at least one `sys_member` row. Creates a personal
8780
- * organization owned by them if not.
8781
- *
8782
- * Returns `{ created: true, organizationId }` when a new org was made,
8783
- * or `{ created: false, reason }` when the user already has memberships
8784
- * or the operation was skipped.
8785
- */
8786
- declare function ensureUserHasOrganization(ql: any, user: {
8787
- id: string;
8788
- name?: string;
8789
- email?: string;
8790
- }, options?: EnsureOptions): Promise<{
8791
- created: boolean;
8792
- organizationId?: string;
8793
- reason?: string;
8794
- }>;
8795
-
8796
8765
  interface CloneOptions {
8797
8766
  logger?: {
8798
8767
  info: (message: string, meta?: Record<string, any>) => void;
@@ -8804,4 +8773,4 @@ declare function cloneTenantSeedData(ql: any, targetOrgId: string, options?: Clo
8804
8773
  count: number;
8805
8774
  }[]>;
8806
8775
 
8807
- export { FieldMasker, PermissionDeniedError, PermissionEvaluator, RLSCompiler, RLS_DENY_FILTER, SECURITY_PLUGIN_ID, SECURITY_PLUGIN_VERSION, SecurityPlugin, cloneTenantSeedData, ensureUserHasOrganization, isPermissionDeniedError, securityDefaultPermissionSets, securityObjects, securityPluginManifestHeader };
8776
+ export { FieldMasker, PermissionDeniedError, PermissionEvaluator, RLSCompiler, RLS_DENY_FILTER, SECURITY_PLUGIN_ID, SECURITY_PLUGIN_VERSION, SecurityPlugin, cloneTenantSeedData, isPermissionDeniedError, securityDefaultPermissionSets, securityObjects, securityPluginManifestHeader };
package/dist/index.js CHANGED
@@ -29,7 +29,6 @@ __export(index_exports, {
29
29
  SECURITY_PLUGIN_VERSION: () => SECURITY_PLUGIN_VERSION,
30
30
  SecurityPlugin: () => SecurityPlugin,
31
31
  cloneTenantSeedData: () => cloneTenantSeedData,
32
- ensureUserHasOrganization: () => ensureUserHasOrganization,
33
32
  isPermissionDeniedError: () => isPermissionDeniedError,
34
33
  securityDefaultPermissionSets: () => securityDefaultPermissionSets,
35
34
  securityObjects: () => securityObjects,
@@ -378,6 +377,7 @@ function genId(prefix) {
378
377
  }
379
378
  async function bootstrapPlatformAdmin(ql, bootstrapPermissionSets, options = {}) {
380
379
  const logger = options.logger;
380
+ const multiTenant = options.multiTenant === true;
381
381
  if (!ql || typeof ql.find !== "function" || typeof ql.insert !== "function") {
382
382
  return { seeded: 0, adminPromoted: false, reason: "objectql_unavailable" };
383
383
  }
@@ -439,7 +439,48 @@ async function bootstrapPlatformAdmin(ql, bootstrapPermissionSets, options = {})
439
439
  return { seeded: seededCount, adminPromoted: false, reason: "insert_failed" };
440
440
  }
441
441
  logger?.info?.(`[security] first user promoted to platform admin: ${target.email ?? target.id}`);
442
- return { seeded: seededCount, adminPromoted: true };
442
+ let defaultOrgCreated = false;
443
+ let defaultOrgId;
444
+ if (multiTenant) {
445
+ const memberships = await tryFind(ql, "sys_member", { user_id: target.id }, 1);
446
+ if (memberships.length === 0) {
447
+ const existingDefault = await tryFind(ql, "sys_organization", { slug: "default" }, 1);
448
+ if (existingDefault.length > 0 && existingDefault[0].id) {
449
+ defaultOrgId = String(existingDefault[0].id);
450
+ } else {
451
+ const newOrgId = genId("org");
452
+ const orgRow = await tryInsert(ql, "sys_organization", {
453
+ id: newOrgId,
454
+ name: "Default Organization",
455
+ slug: "default",
456
+ logo: null,
457
+ metadata: null
458
+ });
459
+ if (orgRow) {
460
+ defaultOrgId = orgRow?.id ?? newOrgId;
461
+ defaultOrgCreated = true;
462
+ } else {
463
+ logger?.warn?.("[security] failed to create default organization for platform admin");
464
+ }
465
+ }
466
+ if (defaultOrgId) {
467
+ const memRow = await tryInsert(ql, "sys_member", {
468
+ id: genId("mem"),
469
+ organization_id: defaultOrgId,
470
+ user_id: target.id,
471
+ role: "owner"
472
+ });
473
+ if (memRow) {
474
+ logger?.info?.(
475
+ `[security] bound platform admin to default organization (${defaultOrgId}): ${target.email ?? target.id}`
476
+ );
477
+ } else {
478
+ logger?.warn?.("[security] failed to bind platform admin to default organization");
479
+ }
480
+ }
481
+ }
482
+ }
483
+ return { seeded: seededCount, adminPromoted: true, defaultOrgCreated, defaultOrgId };
443
484
  }
444
485
 
445
486
  // src/claim-orphan-tenant-rows.ts
@@ -688,126 +729,6 @@ async function cloneTenantSeedData(ql, targetOrgId, options = {}) {
688
729
  return summary;
689
730
  }
690
731
 
691
- // src/ensure-user-has-organization.ts
692
- var SYSTEM_CTX4 = { isSystem: true };
693
- function genId2(prefix) {
694
- const rand = Math.random().toString(36).slice(2, 10);
695
- const ts = Date.now().toString(36);
696
- return `${prefix}_${ts}${rand}`;
697
- }
698
- function slugify(input, fallback = "workspace") {
699
- const cleaned = input.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40);
700
- return cleaned || fallback;
701
- }
702
- function deriveSlugFallback(user) {
703
- if (user.email) {
704
- const local = user.email.split("@")[0] ?? "";
705
- const localSlug = local.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40);
706
- if (localSlug) return localSlug;
707
- }
708
- const idTail = user.id.replace(/[^a-z0-9]/gi, "").slice(-8).toLowerCase();
709
- return idTail ? `user-${idTail}` : "user";
710
- }
711
- function deriveBaseName(user) {
712
- if (user.name && user.name.trim()) return user.name.trim();
713
- if (user.email) {
714
- const local = user.email.split("@")[0];
715
- if (local) return local;
716
- }
717
- return user.id;
718
- }
719
- async function tryFind2(ql, object, where, limit = 1) {
720
- try {
721
- const rows = await ql.find(object, { where, limit }, { context: SYSTEM_CTX4 });
722
- return Array.isArray(rows) ? rows : [];
723
- } catch {
724
- return [];
725
- }
726
- }
727
- async function ensureUserHasOrganization(ql, user, options = {}) {
728
- const logger = options.logger;
729
- const cloneSeedData = options.cloneSeedData;
730
- if (!ql || typeof ql.find !== "function" || typeof ql.insert !== "function") {
731
- return { created: false, reason: "objectql_unavailable" };
732
- }
733
- if (!user?.id) return { created: false, reason: "invalid_user" };
734
- const existing = await tryFind2(ql, "sys_member", { user_id: user.id }, 1);
735
- if (existing.length > 0) {
736
- return { created: false, reason: "already_member" };
737
- }
738
- const base = deriveBaseName(user);
739
- const orgName = `${base}'s Workspace`;
740
- const slugFallback = deriveSlugFallback(user);
741
- const baseSlug = slugify(base, slugFallback);
742
- let slug = `${baseSlug}-workspace`;
743
- for (let attempt = 1; attempt <= 5; attempt += 1) {
744
- const collision = await tryFind2(ql, "sys_organization", { slug }, 1);
745
- if (collision.length === 0) break;
746
- slug = `${baseSlug}-workspace-${attempt + 1}`;
747
- if (attempt === 5) {
748
- logger?.warn?.(
749
- `[security] could not find a free slug for personal org of ${user.email ?? user.id}`
750
- );
751
- return { created: false, reason: "slug_exhausted" };
752
- }
753
- }
754
- const orgId = genId2("org");
755
- let orgRow = null;
756
- try {
757
- orgRow = await ql.insert(
758
- "sys_organization",
759
- { id: orgId, name: orgName, slug, logo: null, metadata: null },
760
- { context: SYSTEM_CTX4 }
761
- );
762
- } catch (e) {
763
- logger?.warn?.(`[security] failed to create personal org for ${user.email ?? user.id}`, {
764
- error: e.message
765
- });
766
- return { created: false, reason: "org_insert_failed" };
767
- }
768
- const finalOrgId = orgRow?.id ?? orgId;
769
- try {
770
- await ql.insert(
771
- "sys_member",
772
- {
773
- id: genId2("mem"),
774
- organization_id: finalOrgId,
775
- user_id: user.id,
776
- role: "owner"
777
- },
778
- { context: SYSTEM_CTX4 }
779
- );
780
- } catch (e) {
781
- logger?.warn?.(`[security] failed to create owner-member row for ${user.email ?? user.id}`, {
782
- error: e.message
783
- });
784
- return { created: false, reason: "member_insert_failed", organizationId: finalOrgId };
785
- }
786
- logger?.info?.(
787
- `[security] created personal organization "${orgName}" (${finalOrgId}) for ${user.email ?? user.id}`
788
- );
789
- if (cloneSeedData) {
790
- void cloneSeedData(ql, finalOrgId, { logger }).then(
791
- (summary) => {
792
- if (summary.length > 0) {
793
- const total = summary.reduce((s, c) => s + c.count, 0);
794
- logger?.info?.(
795
- `[security] cloned ${total} seed row(s) into personal organization ${finalOrgId}`,
796
- { breakdown: summary }
797
- );
798
- }
799
- },
800
- (e) => {
801
- logger?.warn?.("[security] cloneTenantSeedData failed", {
802
- organizationId: finalOrgId,
803
- error: e.message
804
- });
805
- }
806
- );
807
- }
808
- return { created: true, organizationId: finalOrgId };
809
- }
810
-
811
732
  // src/manifest.ts
812
733
  var import_security = require("@objectstack/platform-objects/security");
813
734
  var SECURITY_PLUGIN_ID = "com.objectstack.plugin-security";
@@ -1042,7 +963,8 @@ var SecurityPlugin = class {
1042
963
  const runBootstrap = async () => {
1043
964
  try {
1044
965
  const report = await bootstrapPlatformAdmin(ql, this.bootstrapPermissionSets, {
1045
- logger: ctx.logger
966
+ logger: ctx.logger,
967
+ multiTenant: this.multiTenant
1046
968
  });
1047
969
  bootstrapRanOnce = true;
1048
970
  ctx.logger.info("[security] platform bootstrap complete", report);
@@ -1063,21 +985,6 @@ var SecurityPlugin = class {
1063
985
  if (bootstrapRanOnce) {
1064
986
  await runBootstrap();
1065
987
  }
1066
- if (this.multiTenant) {
1067
- const newUser = opCtx?.result ?? opCtx?.data;
1068
- if (newUser?.id) {
1069
- try {
1070
- await ensureUserHasOrganization(ql, newUser, {
1071
- logger: ctx.logger,
1072
- cloneSeedData: cloneTenantSeedData
1073
- });
1074
- } catch (e) {
1075
- ctx.logger.warn("[security] ensure-user-has-organization failed", {
1076
- error: e.message
1077
- });
1078
- }
1079
- }
1080
- }
1081
988
  }
1082
989
  });
1083
990
  if (this.multiTenant) {
@@ -1255,7 +1162,6 @@ var SecurityPlugin = class {
1255
1162
  SECURITY_PLUGIN_VERSION,
1256
1163
  SecurityPlugin,
1257
1164
  cloneTenantSeedData,
1258
- ensureUserHasOrganization,
1259
1165
  isPermissionDeniedError,
1260
1166
  securityDefaultPermissionSets,
1261
1167
  securityObjects,