@meistrari/auth-core 1.28.1 → 1.29.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.mjs CHANGED
@@ -8,7 +8,7 @@ import { defaultStatements } from 'better-auth/plugins/organization/access';
8
8
  import z, { z as z$1 } from 'zod';
9
9
  export { APIError } from 'better-auth';
10
10
 
11
- const version = "1.28.1";
11
+ const version = "1.29.0";
12
12
 
13
13
  function parsedEnumValues(schema) {
14
14
  return Object.fromEntries(
@@ -439,25 +439,23 @@ class AdminService {
439
439
  });
440
440
  }
441
441
  /**
442
- * Lists all Better Auth users from the user table.
442
+ * Lists users as a global admin, optionally with organization previews
443
+ * and totals when a preview size is requested.
443
444
  *
444
- * @param options - Pagination, search, filter, and ordering options
445
+ * @param options - Pagination, ordering, search, and preview options
445
446
  * @returns The paginated user listing
446
447
  */
447
448
  async listUsers(options = {}) {
448
- return await this.client.$fetch("/admin/list-users", {
449
+ return await this.client.$fetch("/admin/users", {
449
450
  method: "GET",
450
451
  query: {
451
452
  ...options.limit !== void 0 ? { limit: options.limit } : {},
452
453
  ...options.offset !== void 0 ? { offset: options.offset } : {},
453
- ...options.searchValue ? { searchValue: options.searchValue } : {},
454
- ...options.searchField ? { searchField: options.searchField } : {},
455
- ...options.searchOperator ? { searchOperator: options.searchOperator } : {},
456
454
  ...options.sortBy ? { sortBy: options.sortBy } : {},
457
455
  ...options.sortDirection ? { sortDirection: options.sortDirection } : {},
458
- ...options.filterField ? { filterField: options.filterField } : {},
459
- ...options.filterValue !== void 0 ? { filterValue: options.filterValue } : {},
460
- ...options.filterOperator ? { filterOperator: options.filterOperator } : {}
456
+ ...options.query ? { query: options.query } : {},
457
+ ...options.organizationsPreview !== void 0 ? { organizations_preview: options.organizationsPreview } : {},
458
+ ...options.includeInvitations !== void 0 ? { include_invitations: options.includeInvitations } : {}
461
459
  }
462
460
  });
463
461
  }
@@ -479,6 +477,20 @@ class AdminService {
479
477
  });
480
478
  return data;
481
479
  }
480
+ /**
481
+ * Fetches the per-organization access report for a single user: their
482
+ * organizations with role, membership ID, and teams, plus each
483
+ * organization's entitled applications with the user's effective role.
484
+ *
485
+ * @param userId - The ID of the user to fetch access for
486
+ * @returns The user access report
487
+ */
488
+ async getUserAccess(userId) {
489
+ const { data } = await this.client.$fetch(`/admin/users/${encodeURIComponent(userId)}/access`, {
490
+ method: "GET"
491
+ });
492
+ return data;
493
+ }
482
494
  /**
483
495
  * Lists active members for one organization as a global admin.
484
496
  *
@@ -491,7 +503,11 @@ class AdminService {
491
503
  query: {
492
504
  ...options.limit !== void 0 ? { limit: options.limit } : {},
493
505
  ...options.offset !== void 0 ? { offset: options.offset } : {},
494
- ...options.query ? { query: options.query } : {}
506
+ ...options.query ? { query: options.query } : {},
507
+ ...options.role ? { role: options.role } : {},
508
+ ...options.teamIds !== void 0 && options.teamIds.length > 0 ? { team_ids: options.teamIds } : {},
509
+ ...options.includeInvitations !== void 0 ? { include_invitations: options.includeInvitations } : {},
510
+ ...options.includeAccess !== void 0 ? { include_access: options.includeAccess } : {}
495
511
  }
496
512
  });
497
513
  }
@@ -555,6 +571,63 @@ class AdminService {
555
571
  });
556
572
  return data;
557
573
  }
574
+ /**
575
+ * Updates an organization member's role.
576
+ *
577
+ * @param options - Membership ID and the new role
578
+ * @returns The updated membership
579
+ */
580
+ async updateMemberRole(options) {
581
+ const { data } = await this.client.$fetch("/admin/organizations/members/update-role", {
582
+ method: "POST",
583
+ body: options
584
+ });
585
+ return data;
586
+ }
587
+ /**
588
+ * Removes an organization member.
589
+ *
590
+ * @param options - Membership ID to remove
591
+ * @returns The removed membership
592
+ */
593
+ async removeMember(options) {
594
+ const { data } = await this.client.$fetch("/admin/organizations/members/remove", {
595
+ method: "POST",
596
+ body: options
597
+ });
598
+ return data;
599
+ }
600
+ /**
601
+ * Sets a user's effective application role within an organization. A
602
+ * non-null role grants access, a null role denies access (leave
603
+ * application), and clear removes the user-specific override.
604
+ *
605
+ * @param options - User, organization, application, and the role or clear flag
606
+ */
607
+ async setUserApplicationRole(options) {
608
+ await this.client.$fetch(`/admin/users/${encodeURIComponent(options.userId)}/applications/role`, {
609
+ method: "POST",
610
+ body: {
611
+ organizationId: options.organizationId,
612
+ applicationId: options.applicationId,
613
+ ...options.clear === true ? { clear: true } : { role: options.role }
614
+ }
615
+ });
616
+ }
617
+ /**
618
+ * Reconciles a user's team memberships within an organization to a given set.
619
+ *
620
+ * @param options - User, organization, and the desired teams (empty to clear)
621
+ */
622
+ async setUserTeam(options) {
623
+ await this.client.$fetch(`/admin/users/${encodeURIComponent(options.userId)}/team`, {
624
+ method: "POST",
625
+ body: {
626
+ organizationId: options.organizationId,
627
+ teamIds: options.teamIds
628
+ }
629
+ });
630
+ }
558
631
  /**
559
632
  * Bans a user from the auth system and invalidates all their sessions.
560
633
  * @param userId - The ID of the user to ban
@@ -562,6 +635,51 @@ class AdminService {
562
635
  async banUser(userId) {
563
636
  await this.client.$fetch("/admin/ban-user", { method: "POST", body: { userId } });
564
637
  }
638
+ /**
639
+ * Lifts a user's ban.
640
+ * @param userId - The ID of the user to unban
641
+ */
642
+ async unbanUser(userId) {
643
+ await this.client.$fetch("/admin/unban-user", { method: "POST", body: { userId } });
644
+ }
645
+ /**
646
+ * Permanently removes a user from the auth system.
647
+ * @param userId - The ID of the user to remove
648
+ */
649
+ async removeUser(userId) {
650
+ await this.client.$fetch("/admin/remove-user", { method: "POST", body: { userId } });
651
+ }
652
+ /**
653
+ * Cancels a pending invitation as a global admin.
654
+ * @param invitationId - The ID of the invitation to cancel
655
+ */
656
+ async cancelInvite(invitationId) {
657
+ await this.client.$fetch("/admin/invites/cancel", { method: "POST", body: { invitationId } });
658
+ }
659
+ /**
660
+ * Re-sends an organization invitation email as a global admin.
661
+ * @param options - Organization, email, role, and optional application and teams
662
+ */
663
+ async resendInvite(options) {
664
+ await this.client.$fetch("/admin/organizations/users", {
665
+ method: "POST",
666
+ body: { ...options, sendInvite: true, resend: true }
667
+ });
668
+ }
669
+ /**
670
+ * Invites several users to an organization in one call. Failures are
671
+ * isolated per email in the results payload.
672
+ *
673
+ * @param options - Organization, emails, role, and optional teams/application
674
+ * @returns Per-email invite outcomes
675
+ */
676
+ async inviteOrganizationUsers(options) {
677
+ const { data } = await this.client.$fetch("/admin/organizations/users", {
678
+ method: "POST",
679
+ body: { ...options, sendInvite: true }
680
+ });
681
+ return data;
682
+ }
565
683
  }
566
684
 
567
685
  class BaseError extends Error {
@@ -668,6 +786,7 @@ const SENSITIVE_ACTION_ASSURANCE_POLICY = {
668
786
  minAal: AALs.Aal2,
669
787
  acceptedAmr: [AMRs.Pwd, AMRs.Otp, AMRs.Oauth]
670
788
  };
789
+ const STEP_UP_MAX_AGE_SECONDS = 15 * 60;
671
790
  function getAalRank(aal) {
672
791
  switch (aal) {
673
792
  case AALs.Aal3:
@@ -683,7 +802,7 @@ function getAalRank(aal) {
683
802
  function maxAal(left, right) {
684
803
  return getAalRank(left) >= getAalRank(right) ? left : right;
685
804
  }
686
- function isAssuranceSufficientForPolicy(assurance, policy) {
805
+ function isAssuranceSufficientForPolicy(assurance, policy, now = /* @__PURE__ */ new Date()) {
687
806
  if (!assurance) {
688
807
  return false;
689
808
  }
@@ -693,7 +812,16 @@ function isAssuranceSufficientForPolicy(assurance, policy) {
693
812
  if (!assurance.amr.length) {
694
813
  return false;
695
814
  }
696
- return assurance.amr.some((amr) => policy.acceptedAmr.includes(amr));
815
+ if (!assurance.amr.some((amr) => policy.acceptedAmr.includes(amr))) {
816
+ return false;
817
+ }
818
+ if (getAalRank(policy.minAal) >= getAalRank(AALs.Aal2)) {
819
+ const assuredAtMs = Date.parse(assurance.assuredAt);
820
+ if (Number.isNaN(assuredAtMs) || now.getTime() - assuredAtMs > STEP_UP_MAX_AGE_SECONDS * 1e3) {
821
+ return false;
822
+ }
823
+ }
824
+ return true;
697
825
  }
698
826
  function canStepUpWithAmr(assurance, amr) {
699
827
  return !assurance.amr.includes(amr);
@@ -1841,4 +1969,4 @@ function extractTokenPayload(token) {
1841
1969
  return payload;
1842
1970
  }
1843
1971
 
1844
- export { AAL, AALBrand, AALs, ACR, ACRBrand, ACRs, AMR, AMRBrand, AMRs, ApiKeyMetadata, ApplicationConfig, ApplicationError, ApplicationSessionAssuranceConfig, ApplicationSessionAssuranceError, AuthClient, AuthMethod, AuthMethodBrand, AuthMethods, AuthorizationFlowError, DEFAULT_APPLICATION_CONFIG, DEFAULT_JWT_ASSURANCE, DEFAULT_SESSION_ASSURANCE_CONFIG, DeviceAccessDeniedError, DeviceAuthorizationPendingError, DeviceAuthorizationSlowDownError, DeviceCodeExpiredError, DeviceTransientServerError, EmailOTPService, EmailRequired, InvalidCallbackURL, InvalidSocialProvider, JWTPayload, JWTPayloadAssurance, JWTPayloadUser, JWTPayloadWorkspace, OAuthStepUpProvider, RefreshTokenExpiredError, Roles, SENSITIVE_ACTION_ASSURANCE_POLICY, SessionAssurancePolicy, SessionAssuranceRequiredError, SessionAssuranceRequiredPayload, SessionAssuranceService, StepUpOption, UserNotLoggedInError, ac, assuranceFields, canStepUpWithAmr, extractTokenPayload, getAalRank, invitationAdditionalFields, isAssuranceSufficientForPolicy, isSessionAssuranceSufficient, isTokenExpired, memberAdditionalFields, mergeStepUpAssurance, organizationAdditionalFields, parseSessionAssuranceRequiredPayload, rolesAccessControl, sessionAssurancePluginClient, userAdditionalFields, validateToken };
1972
+ export { AAL, AALBrand, AALs, ACR, ACRBrand, ACRs, AMR, AMRBrand, AMRs, ApiKeyMetadata, ApplicationConfig, ApplicationError, ApplicationSessionAssuranceConfig, ApplicationSessionAssuranceError, AuthClient, AuthMethod, AuthMethodBrand, AuthMethods, AuthorizationFlowError, DEFAULT_APPLICATION_CONFIG, DEFAULT_JWT_ASSURANCE, DEFAULT_SESSION_ASSURANCE_CONFIG, DeviceAccessDeniedError, DeviceAuthorizationPendingError, DeviceAuthorizationSlowDownError, DeviceCodeExpiredError, DeviceTransientServerError, EmailOTPService, EmailRequired, InvalidCallbackURL, InvalidSocialProvider, JWTPayload, JWTPayloadAssurance, JWTPayloadUser, JWTPayloadWorkspace, OAuthStepUpProvider, RefreshTokenExpiredError, Roles, SENSITIVE_ACTION_ASSURANCE_POLICY, STEP_UP_MAX_AGE_SECONDS, SessionAssurancePolicy, SessionAssuranceRequiredError, SessionAssuranceRequiredPayload, SessionAssuranceService, StepUpOption, UserNotLoggedInError, ac, assuranceFields, canStepUpWithAmr, extractTokenPayload, getAalRank, invitationAdditionalFields, isAssuranceSufficientForPolicy, isSessionAssuranceSufficient, isTokenExpired, memberAdditionalFields, mergeStepUpAssurance, organizationAdditionalFields, parseSessionAssuranceRequiredPayload, rolesAccessControl, sessionAssurancePluginClient, userAdditionalFields, validateToken };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meistrari/auth-core",
3
- "version": "1.28.1",
3
+ "version": "1.29.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {