@meistrari/auth-core 1.5.2 → 1.6.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
@@ -2665,6 +2665,70 @@ declare function createAPIClient(apiUrl: string, fetchOptions?: BetterFetchOptio
2665
2665
  code?: string | undefined;
2666
2666
  message?: string | undefined;
2667
2667
  }, FetchOptions["throw"] extends true ? true : true>>;
2668
+ } & {
2669
+ applications: {
2670
+ listCandidateOrganizations: (applicationId: string) => Promise<{
2671
+ data: {
2672
+ organizations: ExtendedOrganization[];
2673
+ application?: Application | undefined;
2674
+ };
2675
+ error: null;
2676
+ } | {
2677
+ data: {
2678
+ organizations: ExtendedOrganization[];
2679
+ application?: Application | undefined;
2680
+ };
2681
+ error: {
2682
+ message?: string | undefined;
2683
+ status: number;
2684
+ statusText: string;
2685
+ };
2686
+ }>;
2687
+ startAuthorizationFlow: (applicationId: string, redirectUri: string, codeChallenge: string, organizationId: string) => Promise<{
2688
+ data: null;
2689
+ error: {
2690
+ message?: string | undefined;
2691
+ status: number;
2692
+ statusText: string;
2693
+ };
2694
+ } | {
2695
+ data: StartAuthorizationFlowResponse;
2696
+ error: null;
2697
+ }>;
2698
+ completeAuthorizationFlow: (code: string, codeVerifier: string) => Promise<{
2699
+ data: null;
2700
+ error: {
2701
+ message?: string | undefined;
2702
+ status: number;
2703
+ statusText: string;
2704
+ };
2705
+ } | {
2706
+ data: CompleteAuthorizationFlowResponse;
2707
+ error: null;
2708
+ }>;
2709
+ refreshAccessToken: (refreshToken?: string) => Promise<{
2710
+ data: null;
2711
+ error: {
2712
+ message?: string | undefined;
2713
+ status: number;
2714
+ statusText: string;
2715
+ };
2716
+ } | {
2717
+ data: CompleteAuthorizationFlowResponse;
2718
+ error: null;
2719
+ }>;
2720
+ whoAmI: (accessToken?: string) => Promise<{
2721
+ data: null;
2722
+ error: {
2723
+ message?: string | undefined;
2724
+ status: number;
2725
+ statusText: string;
2726
+ };
2727
+ } | {
2728
+ data: WhoAmIResponse;
2729
+ error: null;
2730
+ }>;
2731
+ };
2668
2732
  } & {
2669
2733
  $Infer: {
2670
2734
  ActiveOrganization: {
@@ -5553,6 +5617,70 @@ declare const stub: {
5553
5617
  code?: string | undefined;
5554
5618
  message?: string | undefined;
5555
5619
  }, FetchOptions["throw"] extends true ? true : true>>;
5620
+ } & {
5621
+ applications: {
5622
+ listCandidateOrganizations: (applicationId: string) => Promise<{
5623
+ data: {
5624
+ organizations: ExtendedOrganization[];
5625
+ application?: Application | undefined;
5626
+ };
5627
+ error: null;
5628
+ } | {
5629
+ data: {
5630
+ organizations: ExtendedOrganization[];
5631
+ application?: Application | undefined;
5632
+ };
5633
+ error: {
5634
+ message?: string | undefined;
5635
+ status: number;
5636
+ statusText: string;
5637
+ };
5638
+ }>;
5639
+ startAuthorizationFlow: (applicationId: string, redirectUri: string, codeChallenge: string, organizationId: string) => Promise<{
5640
+ data: null;
5641
+ error: {
5642
+ message?: string | undefined;
5643
+ status: number;
5644
+ statusText: string;
5645
+ };
5646
+ } | {
5647
+ data: StartAuthorizationFlowResponse;
5648
+ error: null;
5649
+ }>;
5650
+ completeAuthorizationFlow: (code: string, codeVerifier: string) => Promise<{
5651
+ data: null;
5652
+ error: {
5653
+ message?: string | undefined;
5654
+ status: number;
5655
+ statusText: string;
5656
+ };
5657
+ } | {
5658
+ data: CompleteAuthorizationFlowResponse;
5659
+ error: null;
5660
+ }>;
5661
+ refreshAccessToken: (refreshToken?: string) => Promise<{
5662
+ data: null;
5663
+ error: {
5664
+ message?: string | undefined;
5665
+ status: number;
5666
+ statusText: string;
5667
+ };
5668
+ } | {
5669
+ data: CompleteAuthorizationFlowResponse;
5670
+ error: null;
5671
+ }>;
5672
+ whoAmI: (accessToken?: string) => Promise<{
5673
+ data: null;
5674
+ error: {
5675
+ message?: string | undefined;
5676
+ status: number;
5677
+ statusText: string;
5678
+ };
5679
+ } | {
5680
+ data: WhoAmIResponse;
5681
+ error: null;
5682
+ }>;
5683
+ };
5556
5684
  } & {
5557
5685
  $Infer: {
5558
5686
  ActiveOrganization: {
@@ -5996,6 +6124,117 @@ type TeamMember = {
5996
6124
  createdAt: Date;
5997
6125
  };
5998
6126
 
6127
+ type InternalOrganization = {
6128
+ id: string;
6129
+ title: string;
6130
+ slug: string | null;
6131
+ avatarUrl: string | null;
6132
+ createdAt: Date;
6133
+ metadata: string | null;
6134
+ settings: unknown;
6135
+ };
6136
+ type Application = {
6137
+ id: string;
6138
+ name: string;
6139
+ description: string;
6140
+ redirectUris: string[];
6141
+ };
6142
+ type ListCandidateOrganizationsResponse = {
6143
+ application: Application;
6144
+ organizations: InternalOrganization[];
6145
+ };
6146
+ type StartAuthorizationFlowResponse = {
6147
+ code: string;
6148
+ };
6149
+ type CompleteAuthorizationFlowResponse = {
6150
+ accessToken: string;
6151
+ refreshToken: string;
6152
+ user: User;
6153
+ organization: InternalOrganization;
6154
+ };
6155
+ type WhoAmIResponse = {
6156
+ user: User;
6157
+ organization: InternalOrganization;
6158
+ };
6159
+
6160
+ declare class BaseError extends Error {
6161
+ code: string;
6162
+ constructor(code: string, message: string, options?: ErrorOptions);
6163
+ }
6164
+
6165
+ declare class ApplicationError extends BaseError {
6166
+ constructor(message: string, options?: ErrorOptions);
6167
+ }
6168
+ declare class RefreshTokenExpiredError extends ApplicationError {
6169
+ constructor(options?: ErrorOptions);
6170
+ }
6171
+ declare class AuthorizationFlowError extends ApplicationError {
6172
+ constructor(message: string, options?: ErrorOptions);
6173
+ }
6174
+
6175
+ /**
6176
+ * Service for managing applications and their candidate organizations.
6177
+ *
6178
+ * Provides functionality for:
6179
+ * - Listing candidate organizations for an application
6180
+ */
6181
+ declare class ApplicationService {
6182
+ private client;
6183
+ /**
6184
+ * Creates a new ApplicationService instance.
6185
+ *
6186
+ * @param client - The API client for making application requests
6187
+ */
6188
+ constructor(client: APIClient);
6189
+ /**
6190
+ * Lists candidate organizations for a specific application.
6191
+ *
6192
+ * Returns organizations where the authenticated user is a member and
6193
+ * the application has been enabled with appropriate entitlement rules.
6194
+ *
6195
+ * @param applicationId - The application ID to get candidate organizations for
6196
+ * @returns The application details and list of candidate organizations
6197
+ */
6198
+ listCandidateOrganizations(applicationId: string): Promise<{
6199
+ organizations: ExtendedOrganization[];
6200
+ application?: Application | undefined;
6201
+ } | {
6202
+ organizations: ExtendedOrganization[];
6203
+ application?: Application | undefined;
6204
+ }>;
6205
+ /**
6206
+ * Starts an authorization flow for a specific application.
6207
+ *
6208
+ * @param applicationId - The application ID to start the authorization flow for
6209
+ * @param redirectUri - The redirect URI to use for the authorization flow
6210
+ * @param codeChallenge - The code challenge to use for the authorization flow
6211
+ * @param organizationId - The organization ID to start the authorization flow for
6212
+ */
6213
+ startAuthorizationFlow(applicationId: string, redirectUri: string, codeChallenge: string, organizationId: string): Promise<StartAuthorizationFlowResponse>;
6214
+ /**
6215
+ * Completes an authorization flow for a specific application.
6216
+ *
6217
+ * @param code - The code to use for the authorization flow
6218
+ * @param codeVerifier - The code verifier to use for the authorization flow
6219
+ */
6220
+ completeAuthorizationFlow(code: string, codeVerifier: string): Promise<CompleteAuthorizationFlowResponse>;
6221
+ /**
6222
+ * Refreshes an authentication token for a specific application.
6223
+ *
6224
+ * @param refreshToken - The refresh token to use for the authentication token refresh
6225
+ * @throws {RefreshTokenExpiredError} When the refresh token has expired or is invalid
6226
+ * @throws {ApplicationError} For other API errors
6227
+ */
6228
+ refreshAccessToken(): Promise<CompleteAuthorizationFlowResponse>;
6229
+ /**
6230
+ * Gets the current user and organization for a specific application.
6231
+ *
6232
+ * @param accessToken - The access token to use for the who am I request
6233
+ * @returns The current user and organization
6234
+ */
6235
+ whoAmI(accessToken?: string): Promise<WhoAmIResponse>;
6236
+ }
6237
+
5999
6238
  type UpdateOrganizationPayload = Partial<Pick<ExtendedOrganization, 'name' | 'logo' | 'settings'>>;
6000
6239
  type ListMembersOptions = {
6001
6240
  limit?: number;
@@ -6567,11 +6806,6 @@ declare class ApiKeyService {
6567
6806
  }>;
6568
6807
  }
6569
6808
 
6570
- declare class BaseError extends Error {
6571
- code: string;
6572
- constructor(code: string, message: string, options?: ErrorOptions);
6573
- }
6574
-
6575
6809
  /**
6576
6810
  * Error thrown when an invalid social provider is specified.
6577
6811
  */
@@ -6624,6 +6858,10 @@ declare class AuthClient {
6624
6858
  * Organization management service for multi-tenant operations
6625
6859
  */
6626
6860
  organization: OrganizationService;
6861
+ /**
6862
+ * Application management service for application operations
6863
+ */
6864
+ application: ApplicationService;
6627
6865
  /**
6628
6866
  * API key management service for API key operations
6629
6867
  */
@@ -6638,20 +6876,28 @@ declare class AuthClient {
6638
6876
  }
6639
6877
 
6640
6878
  /**
6641
- * Checks if a JWT token has expired based on the `exp` claim.
6879
+ * Checks if a JWT token has expired or will expire within a specified time window.
6642
6880
  *
6643
6881
  * @param token - The JWT token string to check
6644
- * @returns `true` if the token is expired, `false` otherwise
6882
+ * @param expiresInMs - Optional time window in milliseconds. If provided, returns `true` if the token will expire within this time window
6883
+ * @returns `true` if the token is expired (or will expire within the specified window), `false` otherwise
6645
6884
  *
6646
6885
  * @example
6647
6886
  * ```typescript
6648
6887
  * const token = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...'
6888
+ *
6889
+ * // Check if token is already expired
6649
6890
  * if (isTokenExpired(token)) {
6650
6891
  * console.log('Token has expired')
6651
6892
  * }
6893
+ *
6894
+ * // Check if token will expire in the next 5 minutes
6895
+ * if (isTokenExpired(token, 5 * 60 * 1000)) {
6896
+ * console.log('Token will expire in the next 5 minutes')
6897
+ * }
6652
6898
  * ```
6653
6899
  */
6654
- declare function isTokenExpired(token: string): any;
6900
+ declare function isTokenExpired(token: string, expiresInMs?: number): boolean;
6655
6901
  /**
6656
6902
  * Validates a JWT token by checking its expiration and verifying its signature
6657
6903
  * against the JWKS endpoint.
@@ -6690,5 +6936,5 @@ declare function validateToken(token: string, apiUrl: string): Promise<boolean>;
6690
6936
  */
6691
6937
  declare function extractTokenPayload(token: string): JWTTokenPayload;
6692
6938
 
6693
- export { AuthClient, EmailRequired, InvalidCallbackURL, InvalidSocialProvider, Roles, ac, createAPIClient, extractTokenPayload, isTokenExpired, organizationAdditionalFields, rolesAccessControl, userAdditionalFields, validateToken };
6694
- export type { APIClient, ApiKeyMetadata, CreateApiKeyPayload, CreateTeamPayload, FullOrganization, Invitation, InviteUserToOrganizationOptions, JWTTokenPayload, ListMembersOptions, ExtendedMember as Member, ExtendedOrganization as Organization, RemoveUserFromOrganizationOptions, Role, Session, SignInWithEmailAndPasswordOptions, SignInWithSamlOptions, SocialSignInOptions, Team, TeamMember, UpdateApiKeyPayload, UpdateMemberRoleOptions, UpdateOrganizationPayload, UpdateTeamPayload, User };
6939
+ export { ApplicationError, AuthClient, AuthorizationFlowError, EmailRequired, InvalidCallbackURL, InvalidSocialProvider, RefreshTokenExpiredError, Roles, ac, createAPIClient, extractTokenPayload, isTokenExpired, organizationAdditionalFields, rolesAccessControl, userAdditionalFields, validateToken };
6940
+ export type { APIClient, ApiKeyMetadata, Application, CompleteAuthorizationFlowResponse, CreateApiKeyPayload, CreateTeamPayload, FullOrganization, Invitation, InviteUserToOrganizationOptions, JWTTokenPayload, ListCandidateOrganizationsResponse, ListMembersOptions, ExtendedMember as Member, ExtendedOrganization as Organization, RemoveUserFromOrganizationOptions, Role, Session, SignInWithEmailAndPasswordOptions, SignInWithSamlOptions, SocialSignInOptions, StartAuthorizationFlowResponse, Team, TeamMember, UpdateApiKeyPayload, UpdateMemberRoleOptions, UpdateOrganizationPayload, UpdateTeamPayload, User, WhoAmIResponse };
package/dist/index.d.ts CHANGED
@@ -2665,6 +2665,70 @@ declare function createAPIClient(apiUrl: string, fetchOptions?: BetterFetchOptio
2665
2665
  code?: string | undefined;
2666
2666
  message?: string | undefined;
2667
2667
  }, FetchOptions["throw"] extends true ? true : true>>;
2668
+ } & {
2669
+ applications: {
2670
+ listCandidateOrganizations: (applicationId: string) => Promise<{
2671
+ data: {
2672
+ organizations: ExtendedOrganization[];
2673
+ application?: Application | undefined;
2674
+ };
2675
+ error: null;
2676
+ } | {
2677
+ data: {
2678
+ organizations: ExtendedOrganization[];
2679
+ application?: Application | undefined;
2680
+ };
2681
+ error: {
2682
+ message?: string | undefined;
2683
+ status: number;
2684
+ statusText: string;
2685
+ };
2686
+ }>;
2687
+ startAuthorizationFlow: (applicationId: string, redirectUri: string, codeChallenge: string, organizationId: string) => Promise<{
2688
+ data: null;
2689
+ error: {
2690
+ message?: string | undefined;
2691
+ status: number;
2692
+ statusText: string;
2693
+ };
2694
+ } | {
2695
+ data: StartAuthorizationFlowResponse;
2696
+ error: null;
2697
+ }>;
2698
+ completeAuthorizationFlow: (code: string, codeVerifier: string) => Promise<{
2699
+ data: null;
2700
+ error: {
2701
+ message?: string | undefined;
2702
+ status: number;
2703
+ statusText: string;
2704
+ };
2705
+ } | {
2706
+ data: CompleteAuthorizationFlowResponse;
2707
+ error: null;
2708
+ }>;
2709
+ refreshAccessToken: (refreshToken?: string) => Promise<{
2710
+ data: null;
2711
+ error: {
2712
+ message?: string | undefined;
2713
+ status: number;
2714
+ statusText: string;
2715
+ };
2716
+ } | {
2717
+ data: CompleteAuthorizationFlowResponse;
2718
+ error: null;
2719
+ }>;
2720
+ whoAmI: (accessToken?: string) => Promise<{
2721
+ data: null;
2722
+ error: {
2723
+ message?: string | undefined;
2724
+ status: number;
2725
+ statusText: string;
2726
+ };
2727
+ } | {
2728
+ data: WhoAmIResponse;
2729
+ error: null;
2730
+ }>;
2731
+ };
2668
2732
  } & {
2669
2733
  $Infer: {
2670
2734
  ActiveOrganization: {
@@ -5553,6 +5617,70 @@ declare const stub: {
5553
5617
  code?: string | undefined;
5554
5618
  message?: string | undefined;
5555
5619
  }, FetchOptions["throw"] extends true ? true : true>>;
5620
+ } & {
5621
+ applications: {
5622
+ listCandidateOrganizations: (applicationId: string) => Promise<{
5623
+ data: {
5624
+ organizations: ExtendedOrganization[];
5625
+ application?: Application | undefined;
5626
+ };
5627
+ error: null;
5628
+ } | {
5629
+ data: {
5630
+ organizations: ExtendedOrganization[];
5631
+ application?: Application | undefined;
5632
+ };
5633
+ error: {
5634
+ message?: string | undefined;
5635
+ status: number;
5636
+ statusText: string;
5637
+ };
5638
+ }>;
5639
+ startAuthorizationFlow: (applicationId: string, redirectUri: string, codeChallenge: string, organizationId: string) => Promise<{
5640
+ data: null;
5641
+ error: {
5642
+ message?: string | undefined;
5643
+ status: number;
5644
+ statusText: string;
5645
+ };
5646
+ } | {
5647
+ data: StartAuthorizationFlowResponse;
5648
+ error: null;
5649
+ }>;
5650
+ completeAuthorizationFlow: (code: string, codeVerifier: string) => Promise<{
5651
+ data: null;
5652
+ error: {
5653
+ message?: string | undefined;
5654
+ status: number;
5655
+ statusText: string;
5656
+ };
5657
+ } | {
5658
+ data: CompleteAuthorizationFlowResponse;
5659
+ error: null;
5660
+ }>;
5661
+ refreshAccessToken: (refreshToken?: string) => Promise<{
5662
+ data: null;
5663
+ error: {
5664
+ message?: string | undefined;
5665
+ status: number;
5666
+ statusText: string;
5667
+ };
5668
+ } | {
5669
+ data: CompleteAuthorizationFlowResponse;
5670
+ error: null;
5671
+ }>;
5672
+ whoAmI: (accessToken?: string) => Promise<{
5673
+ data: null;
5674
+ error: {
5675
+ message?: string | undefined;
5676
+ status: number;
5677
+ statusText: string;
5678
+ };
5679
+ } | {
5680
+ data: WhoAmIResponse;
5681
+ error: null;
5682
+ }>;
5683
+ };
5556
5684
  } & {
5557
5685
  $Infer: {
5558
5686
  ActiveOrganization: {
@@ -5996,6 +6124,117 @@ type TeamMember = {
5996
6124
  createdAt: Date;
5997
6125
  };
5998
6126
 
6127
+ type InternalOrganization = {
6128
+ id: string;
6129
+ title: string;
6130
+ slug: string | null;
6131
+ avatarUrl: string | null;
6132
+ createdAt: Date;
6133
+ metadata: string | null;
6134
+ settings: unknown;
6135
+ };
6136
+ type Application = {
6137
+ id: string;
6138
+ name: string;
6139
+ description: string;
6140
+ redirectUris: string[];
6141
+ };
6142
+ type ListCandidateOrganizationsResponse = {
6143
+ application: Application;
6144
+ organizations: InternalOrganization[];
6145
+ };
6146
+ type StartAuthorizationFlowResponse = {
6147
+ code: string;
6148
+ };
6149
+ type CompleteAuthorizationFlowResponse = {
6150
+ accessToken: string;
6151
+ refreshToken: string;
6152
+ user: User;
6153
+ organization: InternalOrganization;
6154
+ };
6155
+ type WhoAmIResponse = {
6156
+ user: User;
6157
+ organization: InternalOrganization;
6158
+ };
6159
+
6160
+ declare class BaseError extends Error {
6161
+ code: string;
6162
+ constructor(code: string, message: string, options?: ErrorOptions);
6163
+ }
6164
+
6165
+ declare class ApplicationError extends BaseError {
6166
+ constructor(message: string, options?: ErrorOptions);
6167
+ }
6168
+ declare class RefreshTokenExpiredError extends ApplicationError {
6169
+ constructor(options?: ErrorOptions);
6170
+ }
6171
+ declare class AuthorizationFlowError extends ApplicationError {
6172
+ constructor(message: string, options?: ErrorOptions);
6173
+ }
6174
+
6175
+ /**
6176
+ * Service for managing applications and their candidate organizations.
6177
+ *
6178
+ * Provides functionality for:
6179
+ * - Listing candidate organizations for an application
6180
+ */
6181
+ declare class ApplicationService {
6182
+ private client;
6183
+ /**
6184
+ * Creates a new ApplicationService instance.
6185
+ *
6186
+ * @param client - The API client for making application requests
6187
+ */
6188
+ constructor(client: APIClient);
6189
+ /**
6190
+ * Lists candidate organizations for a specific application.
6191
+ *
6192
+ * Returns organizations where the authenticated user is a member and
6193
+ * the application has been enabled with appropriate entitlement rules.
6194
+ *
6195
+ * @param applicationId - The application ID to get candidate organizations for
6196
+ * @returns The application details and list of candidate organizations
6197
+ */
6198
+ listCandidateOrganizations(applicationId: string): Promise<{
6199
+ organizations: ExtendedOrganization[];
6200
+ application?: Application | undefined;
6201
+ } | {
6202
+ organizations: ExtendedOrganization[];
6203
+ application?: Application | undefined;
6204
+ }>;
6205
+ /**
6206
+ * Starts an authorization flow for a specific application.
6207
+ *
6208
+ * @param applicationId - The application ID to start the authorization flow for
6209
+ * @param redirectUri - The redirect URI to use for the authorization flow
6210
+ * @param codeChallenge - The code challenge to use for the authorization flow
6211
+ * @param organizationId - The organization ID to start the authorization flow for
6212
+ */
6213
+ startAuthorizationFlow(applicationId: string, redirectUri: string, codeChallenge: string, organizationId: string): Promise<StartAuthorizationFlowResponse>;
6214
+ /**
6215
+ * Completes an authorization flow for a specific application.
6216
+ *
6217
+ * @param code - The code to use for the authorization flow
6218
+ * @param codeVerifier - The code verifier to use for the authorization flow
6219
+ */
6220
+ completeAuthorizationFlow(code: string, codeVerifier: string): Promise<CompleteAuthorizationFlowResponse>;
6221
+ /**
6222
+ * Refreshes an authentication token for a specific application.
6223
+ *
6224
+ * @param refreshToken - The refresh token to use for the authentication token refresh
6225
+ * @throws {RefreshTokenExpiredError} When the refresh token has expired or is invalid
6226
+ * @throws {ApplicationError} For other API errors
6227
+ */
6228
+ refreshAccessToken(): Promise<CompleteAuthorizationFlowResponse>;
6229
+ /**
6230
+ * Gets the current user and organization for a specific application.
6231
+ *
6232
+ * @param accessToken - The access token to use for the who am I request
6233
+ * @returns The current user and organization
6234
+ */
6235
+ whoAmI(accessToken?: string): Promise<WhoAmIResponse>;
6236
+ }
6237
+
5999
6238
  type UpdateOrganizationPayload = Partial<Pick<ExtendedOrganization, 'name' | 'logo' | 'settings'>>;
6000
6239
  type ListMembersOptions = {
6001
6240
  limit?: number;
@@ -6567,11 +6806,6 @@ declare class ApiKeyService {
6567
6806
  }>;
6568
6807
  }
6569
6808
 
6570
- declare class BaseError extends Error {
6571
- code: string;
6572
- constructor(code: string, message: string, options?: ErrorOptions);
6573
- }
6574
-
6575
6809
  /**
6576
6810
  * Error thrown when an invalid social provider is specified.
6577
6811
  */
@@ -6624,6 +6858,10 @@ declare class AuthClient {
6624
6858
  * Organization management service for multi-tenant operations
6625
6859
  */
6626
6860
  organization: OrganizationService;
6861
+ /**
6862
+ * Application management service for application operations
6863
+ */
6864
+ application: ApplicationService;
6627
6865
  /**
6628
6866
  * API key management service for API key operations
6629
6867
  */
@@ -6638,20 +6876,28 @@ declare class AuthClient {
6638
6876
  }
6639
6877
 
6640
6878
  /**
6641
- * Checks if a JWT token has expired based on the `exp` claim.
6879
+ * Checks if a JWT token has expired or will expire within a specified time window.
6642
6880
  *
6643
6881
  * @param token - The JWT token string to check
6644
- * @returns `true` if the token is expired, `false` otherwise
6882
+ * @param expiresInMs - Optional time window in milliseconds. If provided, returns `true` if the token will expire within this time window
6883
+ * @returns `true` if the token is expired (or will expire within the specified window), `false` otherwise
6645
6884
  *
6646
6885
  * @example
6647
6886
  * ```typescript
6648
6887
  * const token = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...'
6888
+ *
6889
+ * // Check if token is already expired
6649
6890
  * if (isTokenExpired(token)) {
6650
6891
  * console.log('Token has expired')
6651
6892
  * }
6893
+ *
6894
+ * // Check if token will expire in the next 5 minutes
6895
+ * if (isTokenExpired(token, 5 * 60 * 1000)) {
6896
+ * console.log('Token will expire in the next 5 minutes')
6897
+ * }
6652
6898
  * ```
6653
6899
  */
6654
- declare function isTokenExpired(token: string): any;
6900
+ declare function isTokenExpired(token: string, expiresInMs?: number): boolean;
6655
6901
  /**
6656
6902
  * Validates a JWT token by checking its expiration and verifying its signature
6657
6903
  * against the JWKS endpoint.
@@ -6690,5 +6936,5 @@ declare function validateToken(token: string, apiUrl: string): Promise<boolean>;
6690
6936
  */
6691
6937
  declare function extractTokenPayload(token: string): JWTTokenPayload;
6692
6938
 
6693
- export { AuthClient, EmailRequired, InvalidCallbackURL, InvalidSocialProvider, Roles, ac, createAPIClient, extractTokenPayload, isTokenExpired, organizationAdditionalFields, rolesAccessControl, userAdditionalFields, validateToken };
6694
- export type { APIClient, ApiKeyMetadata, CreateApiKeyPayload, CreateTeamPayload, FullOrganization, Invitation, InviteUserToOrganizationOptions, JWTTokenPayload, ListMembersOptions, ExtendedMember as Member, ExtendedOrganization as Organization, RemoveUserFromOrganizationOptions, Role, Session, SignInWithEmailAndPasswordOptions, SignInWithSamlOptions, SocialSignInOptions, Team, TeamMember, UpdateApiKeyPayload, UpdateMemberRoleOptions, UpdateOrganizationPayload, UpdateTeamPayload, User };
6939
+ export { ApplicationError, AuthClient, AuthorizationFlowError, EmailRequired, InvalidCallbackURL, InvalidSocialProvider, RefreshTokenExpiredError, Roles, ac, createAPIClient, extractTokenPayload, isTokenExpired, organizationAdditionalFields, rolesAccessControl, userAdditionalFields, validateToken };
6940
+ export type { APIClient, ApiKeyMetadata, Application, CompleteAuthorizationFlowResponse, CreateApiKeyPayload, CreateTeamPayload, FullOrganization, Invitation, InviteUserToOrganizationOptions, JWTTokenPayload, ListCandidateOrganizationsResponse, ListMembersOptions, ExtendedMember as Member, ExtendedOrganization as Organization, RemoveUserFromOrganizationOptions, Role, Session, SignInWithEmailAndPasswordOptions, SignInWithSamlOptions, SocialSignInOptions, StartAuthorizationFlowResponse, Team, TeamMember, UpdateApiKeyPayload, UpdateMemberRoleOptions, UpdateOrganizationPayload, UpdateTeamPayload, User, WhoAmIResponse };
package/dist/index.mjs CHANGED
@@ -6,7 +6,7 @@ import { createAccessControl } from 'better-auth/plugins/access';
6
6
  import { defaultStatements } from 'better-auth/plugins/organization/access';
7
7
  export { BetterFetchError as APIError } from '@better-fetch/fetch';
8
8
 
9
- const version = "1.5.2";
9
+ const version = "1.6.0";
10
10
 
11
11
  const statements = {
12
12
  ...defaultStatements,
@@ -48,6 +48,80 @@ const organizationAdditionalFields = {
48
48
  }
49
49
  };
50
50
 
51
+ function applicationsPluginClient() {
52
+ return {
53
+ id: "applications",
54
+ getActions: ($fetch) => {
55
+ return {
56
+ applications: {
57
+ listCandidateOrganizations: async (applicationId) => {
58
+ const response = await $fetch("/applications/candidate-organizations", {
59
+ query: {
60
+ applicationId
61
+ }
62
+ });
63
+ const organizations = response.data?.organizations.map((organization) => ({
64
+ id: organization.id,
65
+ name: organization.title,
66
+ slug: organization.slug ?? "",
67
+ createdAt: organization.createdAt,
68
+ logo: organization.avatarUrl,
69
+ metadata: organization.metadata
70
+ })) ?? [];
71
+ return {
72
+ ...response,
73
+ data: {
74
+ ...response.data,
75
+ organizations
76
+ }
77
+ };
78
+ },
79
+ startAuthorizationFlow: async (applicationId, redirectUri, codeChallenge, organizationId) => {
80
+ return await $fetch("/applications/authorize", {
81
+ method: "POST",
82
+ body: {
83
+ applicationId,
84
+ redirectUri,
85
+ codeChallenge,
86
+ organizationId
87
+ }
88
+ });
89
+ },
90
+ completeAuthorizationFlow: async (code, codeVerifier) => {
91
+ return await $fetch("/applications/token", {
92
+ method: "POST",
93
+ body: {
94
+ code,
95
+ codeVerifier
96
+ }
97
+ });
98
+ },
99
+ refreshAccessToken: async (refreshToken) => {
100
+ const headers = new Headers();
101
+ if (refreshToken) {
102
+ headers.set("Cookie", `tela-refresh-token=${refreshToken}`);
103
+ }
104
+ return await $fetch("/applications/token/refresh", {
105
+ method: "POST",
106
+ headers
107
+ });
108
+ },
109
+ whoAmI: async (accessToken) => {
110
+ const headers = new Headers();
111
+ if (accessToken) {
112
+ headers.set("Cookie", `tela-access-token=${accessToken}`);
113
+ }
114
+ return await $fetch("/applications/whoami", {
115
+ method: "GET",
116
+ headers
117
+ });
118
+ }
119
+ }
120
+ };
121
+ }
122
+ };
123
+ }
124
+
51
125
  function customEndpointsPluginClient() {
52
126
  return {
53
127
  id: "custom-endpoints",
@@ -94,7 +168,8 @@ function createAPIClient(apiUrl, fetchOptions = {}) {
94
168
  adminClient(),
95
169
  inferAdditionalFields({
96
170
  user: userAdditionalFields
97
- })
171
+ }),
172
+ applicationsPluginClient()
98
173
  ],
99
174
  fetchOptions: {
100
175
  ...fetchOptions,
@@ -109,6 +184,119 @@ function createAPIClient(apiUrl, fetchOptions = {}) {
109
184
  }
110
185
  createAPIClient("");
111
186
 
187
+ class BaseError extends Error {
188
+ code;
189
+ constructor(code, message, options) {
190
+ super(message, options);
191
+ this.code = code;
192
+ }
193
+ }
194
+
195
+ class ApplicationError extends BaseError {
196
+ constructor(message, options) {
197
+ super("APPLICATION_ERROR", message, options);
198
+ }
199
+ }
200
+ class RefreshTokenExpiredError extends ApplicationError {
201
+ constructor(options) {
202
+ super("Refresh token has expired or is invalid", options);
203
+ this.code = "REFRESH_TOKEN_EXPIRED";
204
+ }
205
+ }
206
+ class AuthorizationFlowError extends ApplicationError {
207
+ constructor(message, options) {
208
+ super(message, options);
209
+ this.code = "AUTHORIZATION_FLOW_ERROR";
210
+ }
211
+ }
212
+
213
+ class ApplicationService {
214
+ /**
215
+ * Creates a new ApplicationService instance.
216
+ *
217
+ * @param client - The API client for making application requests
218
+ */
219
+ constructor(client) {
220
+ this.client = client;
221
+ }
222
+ /**
223
+ * Lists candidate organizations for a specific application.
224
+ *
225
+ * Returns organizations where the authenticated user is a member and
226
+ * the application has been enabled with appropriate entitlement rules.
227
+ *
228
+ * @param applicationId - The application ID to get candidate organizations for
229
+ * @returns The application details and list of candidate organizations
230
+ */
231
+ async listCandidateOrganizations(applicationId) {
232
+ const response = await this.client.applications.listCandidateOrganizations(applicationId);
233
+ if (!response.data) {
234
+ throw new Error("No data returned from the API", { cause: response.error });
235
+ }
236
+ return response.data;
237
+ }
238
+ /**
239
+ * Starts an authorization flow for a specific application.
240
+ *
241
+ * @param applicationId - The application ID to start the authorization flow for
242
+ * @param redirectUri - The redirect URI to use for the authorization flow
243
+ * @param codeChallenge - The code challenge to use for the authorization flow
244
+ * @param organizationId - The organization ID to start the authorization flow for
245
+ */
246
+ async startAuthorizationFlow(applicationId, redirectUri, codeChallenge, organizationId) {
247
+ const response = await this.client.applications.startAuthorizationFlow(applicationId, redirectUri, codeChallenge, organizationId);
248
+ if (!response.data) {
249
+ throw new Error("No data returned from the API", { cause: response.error });
250
+ }
251
+ return response.data;
252
+ }
253
+ /**
254
+ * Completes an authorization flow for a specific application.
255
+ *
256
+ * @param code - The code to use for the authorization flow
257
+ * @param codeVerifier - The code verifier to use for the authorization flow
258
+ */
259
+ async completeAuthorizationFlow(code, codeVerifier) {
260
+ const response = await this.client.applications.completeAuthorizationFlow(code, codeVerifier);
261
+ if (!response.data) {
262
+ throw new Error("No data returned from the API", { cause: response.error });
263
+ }
264
+ return response.data;
265
+ }
266
+ /**
267
+ * Refreshes an authentication token for a specific application.
268
+ *
269
+ * @param refreshToken - The refresh token to use for the authentication token refresh
270
+ * @throws {RefreshTokenExpiredError} When the refresh token has expired or is invalid
271
+ * @throws {ApplicationError} For other API errors
272
+ */
273
+ async refreshAccessToken() {
274
+ const response = await this.client.applications.refreshAccessToken();
275
+ if (!response.data) {
276
+ const error = response.error;
277
+ const status = error?.status;
278
+ if (status === 404) {
279
+ throw new RefreshTokenExpiredError({ cause: error });
280
+ }
281
+ throw new ApplicationError(error?.message || "Failed to refresh access token", { cause: error });
282
+ }
283
+ return response.data;
284
+ }
285
+ /**
286
+ * Gets the current user and organization for a specific application.
287
+ *
288
+ * @param accessToken - The access token to use for the who am I request
289
+ * @returns The current user and organization
290
+ */
291
+ async whoAmI(accessToken) {
292
+ const response = await this.client.applications.whoAmI(accessToken);
293
+ if (!response.data) {
294
+ throw new Error("No data returned from the API", { cause: response.error });
295
+ }
296
+ return response.data;
297
+ }
298
+ }
299
+
112
300
  class OrganizationService {
113
301
  /**
114
302
  * Creates a new OrganizationService instance.
@@ -337,14 +525,6 @@ class OrganizationService {
337
525
  }
338
526
  }
339
527
 
340
- class BaseError extends Error {
341
- code;
342
- constructor(code, message, options) {
343
- super(message, options);
344
- this.code = code;
345
- }
346
- }
347
-
348
528
  class InvalidSocialProvider extends BaseError {
349
529
  constructor(message) {
350
530
  super("INVALID_SOCIAL_PROVIDER", message);
@@ -583,6 +763,10 @@ class AuthClient {
583
763
  * Organization management service for multi-tenant operations
584
764
  */
585
765
  organization;
766
+ /**
767
+ * Application management service for application operations
768
+ */
769
+ application;
586
770
  /**
587
771
  * API key management service for API key operations
588
772
  */
@@ -597,13 +781,21 @@ class AuthClient {
597
781
  this.client = createAPIClient(apiUrl, fetchOptions);
598
782
  this.session = new SessionService(this.client, apiUrl);
599
783
  this.organization = new OrganizationService(this.client);
784
+ this.application = new ApplicationService(this.client);
600
785
  this.apiKey = new ApiKeyService(this.client);
601
786
  }
602
787
  }
603
788
 
604
- function isTokenExpired(token) {
789
+ function isTokenExpired(token, expiresInMs) {
605
790
  const payload = JSON.parse(atob(token.split(".")[1] ?? ""));
606
- return payload.exp && Date.now() / 1e3 > payload.exp;
791
+ if (!payload.exp) return false;
792
+ const nowInSeconds = Date.now() / 1e3;
793
+ const expirationTime = payload.exp;
794
+ if (expiresInMs !== void 0) {
795
+ const futureTimeInSeconds = nowInSeconds + expiresInMs / 1e3;
796
+ return futureTimeInSeconds >= expirationTime;
797
+ }
798
+ return nowInSeconds > expirationTime;
607
799
  }
608
800
  async function validateToken(token, apiUrl) {
609
801
  if (isTokenExpired(token)) {
@@ -626,4 +818,4 @@ function extractTokenPayload(token) {
626
818
  return payload;
627
819
  }
628
820
 
629
- export { AuthClient, EmailRequired, InvalidCallbackURL, InvalidSocialProvider, Roles, ac, extractTokenPayload, isTokenExpired, organizationAdditionalFields, rolesAccessControl, userAdditionalFields, validateToken };
821
+ export { ApplicationError, AuthClient, AuthorizationFlowError, EmailRequired, InvalidCallbackURL, InvalidSocialProvider, RefreshTokenExpiredError, Roles, ac, extractTokenPayload, isTokenExpired, organizationAdditionalFields, rolesAccessControl, userAdditionalFields, validateToken };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meistrari/auth-core",
3
- "version": "1.5.2",
3
+ "version": "1.6.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {