@meistrari/auth-core 1.18.0 → 1.20.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/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Identity Provider SDK - Core
1
+ # @meistrari/auth-core
2
2
 
3
3
  A TypeScript/JavaScript SDK for interacting with the Auth API service.
4
4
 
@@ -14,11 +14,18 @@ A TypeScript/JavaScript SDK for interacting with the Auth API service.
14
14
  - Team management
15
15
  - Member invitations
16
16
  - **JWT Token Validation**
17
+ - **Application Authentication**
18
+ - OAuth PKCE application flows
19
+ - OAuth Device Authorization Grant endpoints
20
+ - Application token refresh, logout, and organization switching
21
+ - **API Keys**
22
+ - User-scoped API key CRUD
23
+ - Active-organization API key listing
17
24
 
18
25
  ## Installation
19
26
 
20
27
  ```bash
21
- npm install @meistrari/auth-core
28
+ bun add @meistrari/auth-core
22
29
  ```
23
30
 
24
31
  ## Quick Start
@@ -38,6 +45,16 @@ await authClient.session.signInWithEmailAndPassword({
38
45
  // List user's organizations
39
46
  const organizations = await authClient.organization.listOrganizations()
40
47
  console.log('Organizations:', organizations)
48
+
49
+ // Application auth helpers
50
+ const { code } = await authClient.application.startAuthorizationFlow(
51
+ 'application-id',
52
+ 'https://your-app.com/auth/callback',
53
+ 'pkce-code-challenge',
54
+ 'organization-id',
55
+ )
56
+ const tokens = await authClient.application.completeAuthorizationFlow(code, 'pkce-code-verifier')
57
+ console.log('Application user:', tokens.user.email)
41
58
  ```
42
59
 
43
60
  ## API Reference
package/dist/index.d.mts CHANGED
@@ -2,7 +2,7 @@ import * as better_auth_plugins from 'better-auth/plugins';
2
2
  import * as better_auth from 'better-auth';
3
3
  import { JWTPayload as JWTPayload$1 } from 'better-auth';
4
4
  export { APIError } from 'better-auth';
5
- import { z } from 'zod';
5
+ import z$1, { z } from 'zod';
6
6
  import * as better_auth_client from 'better-auth/client';
7
7
  import { BetterFetchOption } from 'better-auth/client';
8
8
  import * as jose from 'jose';
@@ -261,21 +261,24 @@ declare const JWTPayload: z.ZodObject<{
261
261
  }, z.core.$strip>;
262
262
  type JWTPayload = JWTPayload$1 & z.infer<typeof JWTPayload>;
263
263
 
264
+ declare const ApiKeyMetadata: z$1.ZodObject<{
265
+ user: z$1.ZodObject<{
266
+ id: z$1.ZodString;
267
+ email: z$1.ZodString;
268
+ }, z$1.core.$strip>;
269
+ workspace: z$1.ZodObject<{
270
+ id: z$1.ZodString;
271
+ title: z$1.ZodString;
272
+ }, z$1.core.$strip>;
273
+ application: z$1.ZodNullable<z$1.ZodOptional<z$1.ZodObject<{
274
+ id: z$1.ZodString;
275
+ name: z$1.ZodString;
276
+ }, z$1.core.$strip>>>;
277
+ }, z$1.core.$strip>;
264
278
  /**
265
279
  * Metadata attached to an API key, identifying the owning user and workspace.
266
280
  */
267
- type ApiKeyMetadata = {
268
- /** The user who owns this API key. */
269
- user: {
270
- id: string;
271
- email: string;
272
- };
273
- /** The workspace this API key belongs to. */
274
- workspace: {
275
- id: string;
276
- title: string;
277
- };
278
- } & Record<string, unknown>;
281
+ type ApiKeyMetadata = z$1.infer<typeof ApiKeyMetadata> & Record<string, unknown>;
279
282
  /**
280
283
  * A full API key including the secret key value.
281
284
  *
@@ -3390,32 +3393,8 @@ declare function createAPIClient(apiUrl: string, fetchOptions?: BetterFetchOptio
3390
3393
  };
3391
3394
  }>;
3392
3395
  listCandidateOrganizations: (applicationId: string) => Promise<{
3393
- data: {
3394
- organizations: FullOrganization[];
3395
- application?: Application | undefined;
3396
- };
3397
- error: {
3398
- message?: string | undefined;
3399
- status: number;
3400
- statusText: string;
3401
- };
3402
- } | {
3403
- data: {
3404
- organizations: FullOrganization[];
3405
- application?: Application | undefined;
3406
- };
3407
- error: null;
3408
- }>;
3409
- inviteUserToApplication: (options: InviteUserToApplicationOptions) => Promise<{
3410
- data: null;
3411
- error: {
3412
- message?: string | undefined;
3413
- status: number;
3414
- statusText: string;
3415
- };
3416
- } | {
3417
- data: CreateApplicationInvitationResponse;
3418
- error: null;
3396
+ data: ListCandidateOrganizationsResponse;
3397
+ error?: unknown;
3419
3398
  }>;
3420
3399
  startAuthorizationFlow: (applicationId: string, redirectUri: string, codeChallenge: string, organizationId: string) => Promise<{
3421
3400
  data: null;
@@ -4505,8 +4484,7 @@ type ExtendedOrganization = BaseOrganization & {
4505
4484
  /**
4506
4485
  * A complete organization object including its members, invitations, and teams.
4507
4486
  */
4508
- type FullOrganization = Omit<ExtendedOrganization, 'slug'> & {
4509
- slug: string | null;
4487
+ type FullOrganization = ExtendedOrganization & {
4510
4488
  members: Member[];
4511
4489
  invitations: Invitation[];
4512
4490
  teams: Team[];
@@ -4556,12 +4534,7 @@ type Application = {
4556
4534
  /**
4557
4535
  * Response returned when listing candidate organizations for an application.
4558
4536
  */
4559
- type ListCandidateOrganizationsResponse = {
4560
- /** The application being queried. */
4561
- application: Application;
4562
- /** Organizations where the user is a member and the application is entitled. */
4563
- organizations: FullOrganization[];
4564
- };
4537
+ type ListCandidateOrganizationsResponse = FullOrganization[];
4565
4538
  /**
4566
4539
  * Public application context used to preserve continuity during auth redirects.
4567
4540
  */
@@ -4612,30 +4585,6 @@ type WhoAmIOptions = {
4612
4585
  */
4613
4586
  include?: WhoAmIInclude[];
4614
4587
  };
4615
- type InviteUserToApplicationOptions = {
4616
- organizationId: string;
4617
- applicationId: string;
4618
- email: string;
4619
- role: Role;
4620
- teamId?: string;
4621
- resend?: boolean;
4622
- sendEmail?: boolean;
4623
- };
4624
- type ApplicationInvitationResponse = {
4625
- id: string;
4626
- organizationId: string;
4627
- email: string;
4628
- role: string | null;
4629
- teamId: string | null;
4630
- applicationId: string | null;
4631
- status: string;
4632
- expiresAt: Date | string;
4633
- inviterId: string;
4634
- createdAt: Date | string;
4635
- };
4636
- type CreateApplicationInvitationResponse = {
4637
- data?: ApplicationInvitationResponse;
4638
- };
4639
4588
  /**
4640
4589
  * Response returned when starting a device authorization flow (RFC 8628).
4641
4590
  */
@@ -4810,22 +4759,9 @@ declare class ApplicationService {
4810
4759
  * the application has been enabled with appropriate entitlement rules.
4811
4760
  *
4812
4761
  * @param applicationId - The application ID to get candidate organizations for
4813
- * @returns The application details and list of candidate organizations
4762
+ * @returns The list of candidate organizations
4814
4763
  */
4815
- listCandidateOrganizations(applicationId: string): Promise<{
4816
- organizations: FullOrganization[];
4817
- application?: Application | undefined;
4818
- } | {
4819
- organizations: FullOrganization[];
4820
- application?: Application | undefined;
4821
- }>;
4822
- /**
4823
- * Invites a user to an application through an organization entitlement.
4824
- *
4825
- * @param options - Invitation details including organization, application, email, and role
4826
- * @returns The created invitation
4827
- */
4828
- inviteUserToApplication(options: InviteUserToApplicationOptions): Promise<CreateApplicationInvitationResponse>;
4764
+ listCandidateOrganizations(applicationId: string): Promise<ListCandidateOrganizationsResponse>;
4829
4765
  /**
4830
4766
  * Starts an authorization flow for a specific application.
4831
4767
  *
@@ -4952,6 +4888,10 @@ type ListMembersOptions = {
4952
4888
  };
4953
4889
  /**
4954
4890
  * Options for inviting a user to the active organization.
4891
+ *
4892
+ * When the SDK is authenticated with an application-scoped session, the invitation
4893
+ * is automatically scoped to that application. First-party callers receive a
4894
+ * plain organization invitation.
4955
4895
  */
4956
4896
  type InviteUserToOrganizationOptions = {
4957
4897
  /** Email address of the user to invite. */
@@ -4962,16 +4902,6 @@ type InviteUserToOrganizationOptions = {
4962
4902
  teamId?: string;
4963
4903
  /** Whether to resend the invitation if one already exists for this email. */
4964
4904
  resend?: boolean;
4965
- /**
4966
- * Application scope for legacy callers that still pass this option through
4967
- * the organization invitation path.
4968
- *
4969
- * New app-scoped invitations should use
4970
- * `applications.inviteUserToApplication`, which calls
4971
- * `POST /api/auth/applications/invitations`. The server rejects legacy
4972
- * organization invitation creation when this field is present.
4973
- */
4974
- applicationId?: string;
4975
4905
  };
4976
4906
  /**
4977
4907
  * Options for removing a user from the active organization.
@@ -5156,15 +5086,17 @@ declare class OrganizationService {
5156
5086
  /**
5157
5087
  * Invites a user to join the active organization.
5158
5088
  *
5089
+ * When the SDK runs with an application-scoped session, the server
5090
+ * automatically scopes the resulting invitation to that application.
5091
+ *
5159
5092
  * @param options - Invitation configuration
5160
5093
  * @param options.userEmail - Email address of the user to invite
5161
5094
  * @param options.role - Role to assign to the invited user
5162
5095
  * @param options.teamId - Team ID to add the user to
5163
- * @param options.applicationId - Legacy application scope; prefer applications.inviteUserToApplication for new app-scoped invites
5164
5096
  * @param options.resend - Whether to resend if invitation already exists
5165
5097
  * @returns The created invitation
5166
5098
  */
5167
- inviteUserToOrganization({ userEmail, role, teamId, resend, applicationId }: InviteUserToOrganizationOptions): Promise<NonNullable<{
5099
+ inviteUserToOrganization({ userEmail, role, teamId, resend }: InviteUserToOrganizationOptions): Promise<NonNullable<{
5168
5100
  id: string;
5169
5101
  organizationId: string;
5170
5102
  email: string;
@@ -5653,5 +5585,5 @@ declare function validateToken(token: string, apiUrl: string): Promise<boolean>;
5653
5585
  */
5654
5586
  declare function extractTokenPayload(token: string): JWTPayload;
5655
5587
 
5656
- export { ApplicationError, AuthClient, AuthorizationFlowError, DeviceAccessDeniedError, DeviceAuthorizationPendingError, DeviceAuthorizationSlowDownError, DeviceCodeExpiredError, DeviceTransientServerError, EmailRequired, InvalidCallbackURL, InvalidSocialProvider, JWTPayload, JWTPayloadUser, JWTPayloadWorkspace, RefreshTokenExpiredError, Roles, UserNotLoggedInError, ac, createAPIClient, extractTokenPayload, invitationAdditionalFields, isTokenExpired, memberAdditionalFields, organizationAdditionalFields, rolesAccessControl, userAdditionalFields, validateToken };
5657
- export type { APIClient, ApiKey, ApiKeyMetadata, ApiKeyWithoutSecret, Application, ApplicationAuthContextResponse, ApplicationInvitationResponse, BaseOrganization, CompleteAuthorizationFlowResponse, CreateApiKeyPayload, CreateApplicationInvitationResponse, CreateTeamPayload, DeviceAuthorizationActionResponse, DeviceAuthorizationContextResponse, DeviceAuthorizationResponse, DeviceContextApplication, FullOrganization, Invitation, InviteUserToApplicationOptions, InviteUserToOrganizationOptions, ListCandidateOrganizationsResponse, ListMembersOptions, Member, ExtendedOrganization as Organization, OrganizationSettings, RemoveUserFromOrganizationOptions, Role, Session, SignInWithEmailAndPasswordOptions, SignInWithSamlOptions, SocialSignInOptions, StartAuthorizationFlowResponse, Strict, Team, TeamMember, UpdateApiKeyPayload, UpdateMemberRoleOptions, UpdateOrganizationPayload, UpdateTeamPayload, User, WhoAmIInclude, WhoAmIOptions, WhoAmIOrganization, WhoAmIResponse };
5588
+ export { ApiKeyMetadata, ApplicationError, AuthClient, AuthorizationFlowError, DeviceAccessDeniedError, DeviceAuthorizationPendingError, DeviceAuthorizationSlowDownError, DeviceCodeExpiredError, DeviceTransientServerError, EmailRequired, InvalidCallbackURL, InvalidSocialProvider, JWTPayload, JWTPayloadUser, JWTPayloadWorkspace, RefreshTokenExpiredError, Roles, UserNotLoggedInError, ac, createAPIClient, extractTokenPayload, invitationAdditionalFields, isTokenExpired, memberAdditionalFields, organizationAdditionalFields, rolesAccessControl, userAdditionalFields, validateToken };
5589
+ export type { APIClient, ApiKey, ApiKeyWithoutSecret, Application, ApplicationAuthContextResponse, BaseOrganization, CompleteAuthorizationFlowResponse, CreateApiKeyPayload, CreateTeamPayload, DeviceAuthorizationActionResponse, DeviceAuthorizationContextResponse, DeviceAuthorizationResponse, DeviceContextApplication, FullOrganization, Invitation, InviteUserToOrganizationOptions, ListCandidateOrganizationsResponse, ListMembersOptions, Member, ExtendedOrganization as Organization, OrganizationSettings, RemoveUserFromOrganizationOptions, Role, Session, SignInWithEmailAndPasswordOptions, SignInWithSamlOptions, SocialSignInOptions, StartAuthorizationFlowResponse, Strict, Team, TeamMember, UpdateApiKeyPayload, UpdateMemberRoleOptions, UpdateOrganizationPayload, UpdateTeamPayload, User, WhoAmIInclude, WhoAmIOptions, WhoAmIOrganization, WhoAmIResponse };
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ import * as better_auth_plugins from 'better-auth/plugins';
2
2
  import * as better_auth from 'better-auth';
3
3
  import { JWTPayload as JWTPayload$1 } from 'better-auth';
4
4
  export { APIError } from 'better-auth';
5
- import { z } from 'zod';
5
+ import z$1, { z } from 'zod';
6
6
  import * as better_auth_client from 'better-auth/client';
7
7
  import { BetterFetchOption } from 'better-auth/client';
8
8
  import * as jose from 'jose';
@@ -261,21 +261,24 @@ declare const JWTPayload: z.ZodObject<{
261
261
  }, z.core.$strip>;
262
262
  type JWTPayload = JWTPayload$1 & z.infer<typeof JWTPayload>;
263
263
 
264
+ declare const ApiKeyMetadata: z$1.ZodObject<{
265
+ user: z$1.ZodObject<{
266
+ id: z$1.ZodString;
267
+ email: z$1.ZodString;
268
+ }, z$1.core.$strip>;
269
+ workspace: z$1.ZodObject<{
270
+ id: z$1.ZodString;
271
+ title: z$1.ZodString;
272
+ }, z$1.core.$strip>;
273
+ application: z$1.ZodNullable<z$1.ZodOptional<z$1.ZodObject<{
274
+ id: z$1.ZodString;
275
+ name: z$1.ZodString;
276
+ }, z$1.core.$strip>>>;
277
+ }, z$1.core.$strip>;
264
278
  /**
265
279
  * Metadata attached to an API key, identifying the owning user and workspace.
266
280
  */
267
- type ApiKeyMetadata = {
268
- /** The user who owns this API key. */
269
- user: {
270
- id: string;
271
- email: string;
272
- };
273
- /** The workspace this API key belongs to. */
274
- workspace: {
275
- id: string;
276
- title: string;
277
- };
278
- } & Record<string, unknown>;
281
+ type ApiKeyMetadata = z$1.infer<typeof ApiKeyMetadata> & Record<string, unknown>;
279
282
  /**
280
283
  * A full API key including the secret key value.
281
284
  *
@@ -3390,32 +3393,8 @@ declare function createAPIClient(apiUrl: string, fetchOptions?: BetterFetchOptio
3390
3393
  };
3391
3394
  }>;
3392
3395
  listCandidateOrganizations: (applicationId: string) => Promise<{
3393
- data: {
3394
- organizations: FullOrganization[];
3395
- application?: Application | undefined;
3396
- };
3397
- error: {
3398
- message?: string | undefined;
3399
- status: number;
3400
- statusText: string;
3401
- };
3402
- } | {
3403
- data: {
3404
- organizations: FullOrganization[];
3405
- application?: Application | undefined;
3406
- };
3407
- error: null;
3408
- }>;
3409
- inviteUserToApplication: (options: InviteUserToApplicationOptions) => Promise<{
3410
- data: null;
3411
- error: {
3412
- message?: string | undefined;
3413
- status: number;
3414
- statusText: string;
3415
- };
3416
- } | {
3417
- data: CreateApplicationInvitationResponse;
3418
- error: null;
3396
+ data: ListCandidateOrganizationsResponse;
3397
+ error?: unknown;
3419
3398
  }>;
3420
3399
  startAuthorizationFlow: (applicationId: string, redirectUri: string, codeChallenge: string, organizationId: string) => Promise<{
3421
3400
  data: null;
@@ -4505,8 +4484,7 @@ type ExtendedOrganization = BaseOrganization & {
4505
4484
  /**
4506
4485
  * A complete organization object including its members, invitations, and teams.
4507
4486
  */
4508
- type FullOrganization = Omit<ExtendedOrganization, 'slug'> & {
4509
- slug: string | null;
4487
+ type FullOrganization = ExtendedOrganization & {
4510
4488
  members: Member[];
4511
4489
  invitations: Invitation[];
4512
4490
  teams: Team[];
@@ -4556,12 +4534,7 @@ type Application = {
4556
4534
  /**
4557
4535
  * Response returned when listing candidate organizations for an application.
4558
4536
  */
4559
- type ListCandidateOrganizationsResponse = {
4560
- /** The application being queried. */
4561
- application: Application;
4562
- /** Organizations where the user is a member and the application is entitled. */
4563
- organizations: FullOrganization[];
4564
- };
4537
+ type ListCandidateOrganizationsResponse = FullOrganization[];
4565
4538
  /**
4566
4539
  * Public application context used to preserve continuity during auth redirects.
4567
4540
  */
@@ -4612,30 +4585,6 @@ type WhoAmIOptions = {
4612
4585
  */
4613
4586
  include?: WhoAmIInclude[];
4614
4587
  };
4615
- type InviteUserToApplicationOptions = {
4616
- organizationId: string;
4617
- applicationId: string;
4618
- email: string;
4619
- role: Role;
4620
- teamId?: string;
4621
- resend?: boolean;
4622
- sendEmail?: boolean;
4623
- };
4624
- type ApplicationInvitationResponse = {
4625
- id: string;
4626
- organizationId: string;
4627
- email: string;
4628
- role: string | null;
4629
- teamId: string | null;
4630
- applicationId: string | null;
4631
- status: string;
4632
- expiresAt: Date | string;
4633
- inviterId: string;
4634
- createdAt: Date | string;
4635
- };
4636
- type CreateApplicationInvitationResponse = {
4637
- data?: ApplicationInvitationResponse;
4638
- };
4639
4588
  /**
4640
4589
  * Response returned when starting a device authorization flow (RFC 8628).
4641
4590
  */
@@ -4810,22 +4759,9 @@ declare class ApplicationService {
4810
4759
  * the application has been enabled with appropriate entitlement rules.
4811
4760
  *
4812
4761
  * @param applicationId - The application ID to get candidate organizations for
4813
- * @returns The application details and list of candidate organizations
4762
+ * @returns The list of candidate organizations
4814
4763
  */
4815
- listCandidateOrganizations(applicationId: string): Promise<{
4816
- organizations: FullOrganization[];
4817
- application?: Application | undefined;
4818
- } | {
4819
- organizations: FullOrganization[];
4820
- application?: Application | undefined;
4821
- }>;
4822
- /**
4823
- * Invites a user to an application through an organization entitlement.
4824
- *
4825
- * @param options - Invitation details including organization, application, email, and role
4826
- * @returns The created invitation
4827
- */
4828
- inviteUserToApplication(options: InviteUserToApplicationOptions): Promise<CreateApplicationInvitationResponse>;
4764
+ listCandidateOrganizations(applicationId: string): Promise<ListCandidateOrganizationsResponse>;
4829
4765
  /**
4830
4766
  * Starts an authorization flow for a specific application.
4831
4767
  *
@@ -4952,6 +4888,10 @@ type ListMembersOptions = {
4952
4888
  };
4953
4889
  /**
4954
4890
  * Options for inviting a user to the active organization.
4891
+ *
4892
+ * When the SDK is authenticated with an application-scoped session, the invitation
4893
+ * is automatically scoped to that application. First-party callers receive a
4894
+ * plain organization invitation.
4955
4895
  */
4956
4896
  type InviteUserToOrganizationOptions = {
4957
4897
  /** Email address of the user to invite. */
@@ -4962,16 +4902,6 @@ type InviteUserToOrganizationOptions = {
4962
4902
  teamId?: string;
4963
4903
  /** Whether to resend the invitation if one already exists for this email. */
4964
4904
  resend?: boolean;
4965
- /**
4966
- * Application scope for legacy callers that still pass this option through
4967
- * the organization invitation path.
4968
- *
4969
- * New app-scoped invitations should use
4970
- * `applications.inviteUserToApplication`, which calls
4971
- * `POST /api/auth/applications/invitations`. The server rejects legacy
4972
- * organization invitation creation when this field is present.
4973
- */
4974
- applicationId?: string;
4975
4905
  };
4976
4906
  /**
4977
4907
  * Options for removing a user from the active organization.
@@ -5156,15 +5086,17 @@ declare class OrganizationService {
5156
5086
  /**
5157
5087
  * Invites a user to join the active organization.
5158
5088
  *
5089
+ * When the SDK runs with an application-scoped session, the server
5090
+ * automatically scopes the resulting invitation to that application.
5091
+ *
5159
5092
  * @param options - Invitation configuration
5160
5093
  * @param options.userEmail - Email address of the user to invite
5161
5094
  * @param options.role - Role to assign to the invited user
5162
5095
  * @param options.teamId - Team ID to add the user to
5163
- * @param options.applicationId - Legacy application scope; prefer applications.inviteUserToApplication for new app-scoped invites
5164
5096
  * @param options.resend - Whether to resend if invitation already exists
5165
5097
  * @returns The created invitation
5166
5098
  */
5167
- inviteUserToOrganization({ userEmail, role, teamId, resend, applicationId }: InviteUserToOrganizationOptions): Promise<NonNullable<{
5099
+ inviteUserToOrganization({ userEmail, role, teamId, resend }: InviteUserToOrganizationOptions): Promise<NonNullable<{
5168
5100
  id: string;
5169
5101
  organizationId: string;
5170
5102
  email: string;
@@ -5653,5 +5585,5 @@ declare function validateToken(token: string, apiUrl: string): Promise<boolean>;
5653
5585
  */
5654
5586
  declare function extractTokenPayload(token: string): JWTPayload;
5655
5587
 
5656
- export { ApplicationError, AuthClient, AuthorizationFlowError, DeviceAccessDeniedError, DeviceAuthorizationPendingError, DeviceAuthorizationSlowDownError, DeviceCodeExpiredError, DeviceTransientServerError, EmailRequired, InvalidCallbackURL, InvalidSocialProvider, JWTPayload, JWTPayloadUser, JWTPayloadWorkspace, RefreshTokenExpiredError, Roles, UserNotLoggedInError, ac, createAPIClient, extractTokenPayload, invitationAdditionalFields, isTokenExpired, memberAdditionalFields, organizationAdditionalFields, rolesAccessControl, userAdditionalFields, validateToken };
5657
- export type { APIClient, ApiKey, ApiKeyMetadata, ApiKeyWithoutSecret, Application, ApplicationAuthContextResponse, ApplicationInvitationResponse, BaseOrganization, CompleteAuthorizationFlowResponse, CreateApiKeyPayload, CreateApplicationInvitationResponse, CreateTeamPayload, DeviceAuthorizationActionResponse, DeviceAuthorizationContextResponse, DeviceAuthorizationResponse, DeviceContextApplication, FullOrganization, Invitation, InviteUserToApplicationOptions, InviteUserToOrganizationOptions, ListCandidateOrganizationsResponse, ListMembersOptions, Member, ExtendedOrganization as Organization, OrganizationSettings, RemoveUserFromOrganizationOptions, Role, Session, SignInWithEmailAndPasswordOptions, SignInWithSamlOptions, SocialSignInOptions, StartAuthorizationFlowResponse, Strict, Team, TeamMember, UpdateApiKeyPayload, UpdateMemberRoleOptions, UpdateOrganizationPayload, UpdateTeamPayload, User, WhoAmIInclude, WhoAmIOptions, WhoAmIOrganization, WhoAmIResponse };
5588
+ export { ApiKeyMetadata, ApplicationError, AuthClient, AuthorizationFlowError, DeviceAccessDeniedError, DeviceAuthorizationPendingError, DeviceAuthorizationSlowDownError, DeviceCodeExpiredError, DeviceTransientServerError, EmailRequired, InvalidCallbackURL, InvalidSocialProvider, JWTPayload, JWTPayloadUser, JWTPayloadWorkspace, RefreshTokenExpiredError, Roles, UserNotLoggedInError, ac, createAPIClient, extractTokenPayload, invitationAdditionalFields, isTokenExpired, memberAdditionalFields, organizationAdditionalFields, rolesAccessControl, userAdditionalFields, validateToken };
5589
+ export type { APIClient, ApiKey, ApiKeyWithoutSecret, Application, ApplicationAuthContextResponse, BaseOrganization, CompleteAuthorizationFlowResponse, CreateApiKeyPayload, CreateTeamPayload, DeviceAuthorizationActionResponse, DeviceAuthorizationContextResponse, DeviceAuthorizationResponse, DeviceContextApplication, FullOrganization, Invitation, InviteUserToOrganizationOptions, ListCandidateOrganizationsResponse, ListMembersOptions, Member, ExtendedOrganization as Organization, OrganizationSettings, RemoveUserFromOrganizationOptions, Role, Session, SignInWithEmailAndPasswordOptions, SignInWithSamlOptions, SocialSignInOptions, StartAuthorizationFlowResponse, Strict, Team, TeamMember, UpdateApiKeyPayload, UpdateMemberRoleOptions, UpdateOrganizationPayload, UpdateTeamPayload, User, WhoAmIInclude, WhoAmIOptions, WhoAmIOrganization, WhoAmIResponse };
package/dist/index.mjs CHANGED
@@ -5,10 +5,10 @@ import { createAuthClient } from 'better-auth/client';
5
5
  import { organizationClient, inferOrgAdditionalFields, twoFactorClient, jwtClient, adminClient, inferAdditionalFields } from 'better-auth/client/plugins';
6
6
  import { createAccessControl } from 'better-auth/plugins/access';
7
7
  import { defaultStatements } from 'better-auth/plugins/organization/access';
8
- import { z } from 'zod';
8
+ import z$1, { z } from 'zod';
9
9
  export { APIError } from 'better-auth';
10
10
 
11
- const version = "1.18.0";
11
+ const version = "1.20.0";
12
12
 
13
13
  const statements = {
14
14
  ...defaultStatements,
@@ -86,6 +86,17 @@ const JWTPayload = z.object({
86
86
  });
87
87
 
88
88
  const DEVICE_CODE_GRANT = "urn:ietf:params:oauth:grant-type:device_code";
89
+ function normalizeOrganizationsResponse(response) {
90
+ if (Array.isArray(response)) {
91
+ return {
92
+ data: response
93
+ };
94
+ }
95
+ return {
96
+ ...response,
97
+ data: Array.isArray(response.data) ? response.data : []
98
+ };
99
+ }
89
100
  function applicationsPluginClient() {
90
101
  return {
91
102
  id: "applications",
@@ -100,25 +111,12 @@ function applicationsPluginClient() {
100
111
  });
101
112
  },
102
113
  listCandidateOrganizations: async (applicationId) => {
103
- const response = await $fetch("/applications/candidate-organizations", {
114
+ const response = await $fetch("/organization/list", {
104
115
  query: {
105
116
  applicationId
106
117
  }
107
118
  });
108
- const organizations = response.data?.organizations ?? [];
109
- return {
110
- ...response,
111
- data: {
112
- ...response.data,
113
- organizations
114
- }
115
- };
116
- },
117
- inviteUserToApplication: async (options) => {
118
- return await $fetch("/applications/invitations", {
119
- method: "POST",
120
- body: options
121
- });
119
+ return normalizeOrganizationsResponse(response);
122
120
  },
123
121
  startAuthorizationFlow: async (applicationId, redirectUri, codeChallenge, organizationId) => {
124
122
  return await $fetch("/applications/authorize", {
@@ -409,7 +407,7 @@ class ApplicationService {
409
407
  * the application has been enabled with appropriate entitlement rules.
410
408
  *
411
409
  * @param applicationId - The application ID to get candidate organizations for
412
- * @returns The application details and list of candidate organizations
410
+ * @returns The list of candidate organizations
413
411
  */
414
412
  async listCandidateOrganizations(applicationId) {
415
413
  const response = await this.client.applications.listCandidateOrganizations(applicationId);
@@ -418,20 +416,6 @@ class ApplicationService {
418
416
  }
419
417
  return response.data;
420
418
  }
421
- /**
422
- * Invites a user to an application through an organization entitlement.
423
- *
424
- * @param options - Invitation details including organization, application, email, and role
425
- * @returns The created invitation
426
- */
427
- async inviteUserToApplication(options) {
428
- const response = await this.client.applications.inviteUserToApplication(options);
429
- const invitation = response.data;
430
- if (!invitation) {
431
- throw new Error("No invitation returned from application invitation endpoint");
432
- }
433
- return invitation;
434
- }
435
419
  /**
436
420
  * Starts an authorization flow for a specific application.
437
421
  *
@@ -707,23 +691,23 @@ class OrganizationService {
707
691
  /**
708
692
  * Invites a user to join the active organization.
709
693
  *
694
+ * When the SDK runs with an application-scoped session, the server
695
+ * automatically scopes the resulting invitation to that application.
696
+ *
710
697
  * @param options - Invitation configuration
711
698
  * @param options.userEmail - Email address of the user to invite
712
699
  * @param options.role - Role to assign to the invited user
713
700
  * @param options.teamId - Team ID to add the user to
714
- * @param options.applicationId - Legacy application scope; prefer applications.inviteUserToApplication for new app-scoped invites
715
701
  * @param options.resend - Whether to resend if invitation already exists
716
702
  * @returns The created invitation
717
703
  */
718
- async inviteUserToOrganization({ userEmail, role, teamId, resend, applicationId }) {
719
- const invitation = {
704
+ async inviteUserToOrganization({ userEmail, role, teamId, resend }) {
705
+ return await this.client.organization.inviteMember({
720
706
  email: userEmail,
721
707
  role,
722
708
  teamId,
723
- resend: resend ?? false,
724
- applicationId
725
- };
726
- return await this.client.organization.inviteMember(invitation);
709
+ resend: resend ?? false
710
+ });
727
711
  }
728
712
  /**
729
713
  * Cancels a pending organization invitation.
@@ -1113,6 +1097,21 @@ class ApiKeyService {
1113
1097
  }
1114
1098
  }
1115
1099
 
1100
+ const ApiKeyMetadata = z$1.object({
1101
+ user: z$1.object({
1102
+ id: z$1.string(),
1103
+ email: z$1.string()
1104
+ }),
1105
+ workspace: z$1.object({
1106
+ id: z$1.string(),
1107
+ title: z$1.string()
1108
+ }),
1109
+ application: z$1.object({
1110
+ id: z$1.string(),
1111
+ name: z$1.string()
1112
+ }).optional().nullable()
1113
+ });
1114
+
1116
1115
  class AuthClient {
1117
1116
  client;
1118
1117
  /**
@@ -1179,4 +1178,4 @@ function extractTokenPayload(token) {
1179
1178
  return payload;
1180
1179
  }
1181
1180
 
1182
- export { ApplicationError, AuthClient, AuthorizationFlowError, DeviceAccessDeniedError, DeviceAuthorizationPendingError, DeviceAuthorizationSlowDownError, DeviceCodeExpiredError, DeviceTransientServerError, EmailRequired, InvalidCallbackURL, InvalidSocialProvider, JWTPayload, JWTPayloadUser, JWTPayloadWorkspace, RefreshTokenExpiredError, Roles, UserNotLoggedInError, ac, extractTokenPayload, invitationAdditionalFields, isTokenExpired, memberAdditionalFields, organizationAdditionalFields, rolesAccessControl, userAdditionalFields, validateToken };
1181
+ export { ApiKeyMetadata, ApplicationError, AuthClient, AuthorizationFlowError, DeviceAccessDeniedError, DeviceAuthorizationPendingError, DeviceAuthorizationSlowDownError, DeviceCodeExpiredError, DeviceTransientServerError, EmailRequired, InvalidCallbackURL, InvalidSocialProvider, JWTPayload, JWTPayloadUser, JWTPayloadWorkspace, RefreshTokenExpiredError, Roles, UserNotLoggedInError, ac, extractTokenPayload, invitationAdditionalFields, isTokenExpired, memberAdditionalFields, organizationAdditionalFields, rolesAccessControl, userAdditionalFields, validateToken };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meistrari/auth-core",
3
- "version": "1.18.0",
3
+ "version": "1.20.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {