@drmhse/sso-sdk 0.5.1 → 0.5.3

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
@@ -7,7 +7,7 @@ Core TypeScript SDK for AuthOS. It handles authentication flows, session persist
7
7
 
8
8
  Full documentation: [authos.dev/docs/sdk/](https://authos.dev/docs/sdk/)
9
9
 
10
- AI agent skills: [authos.dev/docs/ai-agent-skills/](https://authos.dev/docs/ai-agent-skills/) and [github.com/CkCreative/authos_skill](https://github.com/CkCreative/authos_skill)
10
+ AI agent skills: [authos.dev/docs/ai-agent-skills/](https://authos.dev/docs/ai-agent-skills/) and [github.com/drmhse/authos_skill](https://github.com/drmhse/authos_skill)
11
11
 
12
12
  ## Install
13
13
 
@@ -47,16 +47,30 @@ const sso = new SsoClient({ baseURL: 'https://sso.example.com' });
47
47
 
48
48
  ### Tenant application
49
49
 
50
- Pass organization and service context when you need hosted auth, BYOO, or service-scoped tokens:
50
+ Redirect users to AuthOS hosted login for the standard web flow. AuthOS handles provider selection, HRD, password, magic link, passkeys, MFA, and recovery before returning tokens to your callback:
51
51
 
52
52
  ```ts
53
- const loginUrl = sso.auth.getLoginUrl('github', {
53
+ const loginUrl = sso.auth.getAuthorizeUrl({
54
54
  org: 'acme-corp',
55
55
  service: 'main-app',
56
56
  redirect_uri: 'https://app.acme.com/callback',
57
57
  });
58
58
  ```
59
59
 
60
+ Use `getLoginUrl(provider, ...)` only when you are intentionally building a custom provider-selection flow.
61
+
62
+ ### Account security
63
+
64
+ Send users to the hosted account-security portal to manage MFA, passkeys, backup codes, and trusted devices on the AuthOS origin:
65
+
66
+ ```ts
67
+ const securityUrl = sso.auth.getAccountSecurityUrl({
68
+ org: 'acme-corp',
69
+ service: 'main-app',
70
+ return_to: 'https://app.acme.com/settings',
71
+ });
72
+ ```
73
+
60
74
  ### Hosted auth context
61
75
 
62
76
  ```ts
package/dist/index.d.mts CHANGED
@@ -254,6 +254,10 @@ interface LoginUrlParams {
254
254
  * Optional redirect URI (must be registered with the service)
255
255
  */
256
256
  redirect_uri?: string;
257
+ /**
258
+ * Optional caller state to return to the service callback.
259
+ */
260
+ state?: string;
257
261
  /**
258
262
  * Optional user code for device flow authorization
259
263
  */
@@ -265,6 +269,44 @@ interface LoginUrlParams {
265
269
  */
266
270
  connection_id?: string;
267
271
  }
272
+ /**
273
+ * Parameters for constructing the hosted AuthOS login URL.
274
+ */
275
+ interface AuthorizeUrlParams {
276
+ /**
277
+ * Organization slug
278
+ */
279
+ org: string;
280
+ /**
281
+ * Service slug
282
+ */
283
+ service: string;
284
+ /**
285
+ * Callback URI registered with the service
286
+ */
287
+ redirect_uri: string;
288
+ /**
289
+ * Optional caller state to return to the service callback.
290
+ */
291
+ state?: string;
292
+ }
293
+ /**
294
+ * Parameters for constructing the hosted account-security URL.
295
+ */
296
+ interface AccountSecurityUrlParams {
297
+ /**
298
+ * Optional organization slug for tenant-aware branding/context
299
+ */
300
+ org?: string;
301
+ /**
302
+ * Optional service slug for application context
303
+ */
304
+ service?: string;
305
+ /**
306
+ * Optional URL to return to after managing account security
307
+ */
308
+ return_to?: string;
309
+ }
268
310
  /**
269
311
  * Parameters for constructing admin login URL
270
312
  */
@@ -277,6 +319,10 @@ interface AdminLoginUrlParams {
277
319
  * Optional user code for device flow authorization
278
320
  */
279
321
  user_code?: string;
322
+ /**
323
+ * Optional internal Lite client path to return to after admin OAuth.
324
+ */
325
+ return_to?: string;
280
326
  }
281
327
  /**
282
328
  * Provider token response
@@ -327,6 +373,10 @@ interface RegisterRequest {
327
373
  * Optional service callback URI to preserve the original app return path in the verification link.
328
374
  */
329
375
  redirect_uri?: string;
376
+ /**
377
+ * Optional caller state to return to hosted service callbacks.
378
+ */
379
+ state?: string;
330
380
  }
331
381
  /**
332
382
  * Registration response
@@ -357,6 +407,10 @@ interface LoginRequest {
357
407
  * against the service before tokens are returned to the hosted UI.
358
408
  */
359
409
  redirect_uri?: string;
410
+ /**
411
+ * Optional caller state to return to hosted service callbacks.
412
+ */
413
+ state?: string;
360
414
  }
361
415
  /**
362
416
  * Forgot password request payload
@@ -366,6 +420,7 @@ interface ForgotPasswordRequest {
366
420
  org_slug?: string;
367
421
  service_slug?: string;
368
422
  redirect_uri?: string;
423
+ state?: string;
369
424
  }
370
425
  /**
371
426
  * Forgot password response
@@ -394,6 +449,7 @@ interface ResendVerificationRequest {
394
449
  org_slug?: string;
395
450
  service_slug?: string;
396
451
  redirect_uri?: string;
452
+ state?: string;
397
453
  }
398
454
  /**
399
455
  * Resend verification response
@@ -1156,6 +1212,7 @@ interface Service {
1156
1212
  google_scopes: string[];
1157
1213
  redirect_uris: string[];
1158
1214
  device_activation_uri?: string;
1215
+ resource_uris?: string[];
1159
1216
  saml_enabled: boolean;
1160
1217
  saml_entity_id?: string;
1161
1218
  saml_acs_url?: string;
@@ -1224,6 +1281,7 @@ interface CreateServicePayload {
1224
1281
  google_scopes?: string[];
1225
1282
  redirect_uris: string[];
1226
1283
  device_activation_uri?: string;
1284
+ resource_uris?: string[];
1227
1285
  }
1228
1286
  /**
1229
1287
  * Create service response
@@ -1252,6 +1310,7 @@ interface UpdateServicePayload {
1252
1310
  google_scopes?: string[];
1253
1311
  redirect_uris?: string[];
1254
1312
  device_activation_uri?: string;
1313
+ resource_uris?: string[];
1255
1314
  }
1256
1315
  /**
1257
1316
  * Service with aggregated details (for listing)
@@ -1774,6 +1833,7 @@ interface PasskeyAuthStartRequest {
1774
1833
  org_slug?: string;
1775
1834
  service_slug?: string;
1776
1835
  redirect_uri?: string;
1836
+ state?: string;
1777
1837
  }
1778
1838
  /**
1779
1839
  * Response from starting passkey authentication
@@ -2086,6 +2146,7 @@ interface UpdateUpstreamProviderPayload {
2086
2146
  interface SessionConfig {
2087
2147
  storageKeyPrefix?: string;
2088
2148
  autoRefresh?: boolean;
2149
+ minValiditySeconds?: number;
2089
2150
  }
2090
2151
  /**
2091
2152
  * Snapshot of the current authentication state.
@@ -2102,6 +2163,7 @@ declare class SessionManager {
2102
2163
  private accessToken;
2103
2164
  private refreshToken;
2104
2165
  private refreshPromise;
2166
+ private sessionVersion;
2105
2167
  private listeners;
2106
2168
  constructor(storage: TokenStorage, refreshHandler: (token: string) => Promise<RefreshTokenResponse>, config?: SessionConfig);
2107
2169
  /**
@@ -2303,6 +2365,32 @@ declare class AuthModule {
2303
2365
  private http;
2304
2366
  private session;
2305
2367
  constructor(http: HttpClient, session: SessionManager);
2368
+ /**
2369
+ * Constructs the hosted AuthOS login URL for an end-user application.
2370
+ * AuthOS owns provider selection, HRD, password, magic-link, passkey, MFA,
2371
+ * recovery, and callback token delivery for this flow.
2372
+ *
2373
+ * @param params Hosted authorize parameters (org, service, redirect_uri)
2374
+ * @returns The full URL to redirect the user to
2375
+ *
2376
+ * @example
2377
+ * ```typescript
2378
+ * window.location.href = sso.auth.getAuthorizeUrl({
2379
+ * org: 'acme-corp',
2380
+ * service: 'main-app',
2381
+ * redirect_uri: 'https://app.acme.com/callback'
2382
+ * });
2383
+ * ```
2384
+ */
2385
+ getAuthorizeUrl(params: AuthorizeUrlParams): string;
2386
+ /**
2387
+ * Constructs the hosted account-security URL for managing user factors.
2388
+ * Use this for AuthOS-owned MFA, passkeys, backup codes, and trusted devices.
2389
+ *
2390
+ * @param params Optional tenant/application context and return URL
2391
+ * @returns The full URL to open for account security management
2392
+ */
2393
+ getAccountSecurityUrl(params?: AccountSecurityUrlParams): string;
2306
2394
  /**
2307
2395
  * Constructs the OAuth login URL for end-users.
2308
2396
  * This does not perform the redirect; the consuming application
@@ -5649,6 +5737,7 @@ declare class PasskeysModule {
5649
5737
  org_slug?: string;
5650
5738
  service_slug?: string;
5651
5739
  redirect_uri?: string;
5740
+ state?: string;
5652
5741
  }): Promise<PasskeyAuthStartResponse>;
5653
5742
  /**
5654
5743
  * Finish the passkey authentication ceremony.
@@ -5663,6 +5752,7 @@ declare class PasskeysModule {
5663
5752
  org_slug?: string;
5664
5753
  service_slug?: string;
5665
5754
  redirect_uri?: string;
5755
+ state?: string;
5666
5756
  }): Promise<PasskeyAuthFinishResponse>;
5667
5757
  /**
5668
5758
  * Convert Base64URL string to Uint8Array
@@ -5687,6 +5777,8 @@ interface MagicLinkRequest {
5687
5777
  service_slug?: string;
5688
5778
  /** Optional service callback URI */
5689
5779
  redirect_uri?: string;
5780
+ /** Optional caller state to return to hosted service callbacks */
5781
+ state?: string;
5690
5782
  }
5691
5783
  /**
5692
5784
  * Magic link response
@@ -5717,7 +5809,7 @@ declare class MagicLinks {
5717
5809
  * @param redirectUri Optional where to redirect after success
5718
5810
  * @returns URL to redirect to for verification
5719
5811
  */
5720
- getVerificationUrl(token: string, redirectUri?: string): string;
5812
+ getVerificationUrl(token: string, redirectUri?: string, state?: string): string;
5721
5813
  /**
5722
5814
  * Verify a magic link token via API call
5723
5815
  * This is an alternative to redirect-based verification
@@ -5726,7 +5818,7 @@ declare class MagicLinks {
5726
5818
  * @param redirectUri Optional redirect URI
5727
5819
  * @returns Promise resolving to authentication response
5728
5820
  */
5729
- verify(token: string, redirectUri?: string): Promise<any>;
5821
+ verify(token: string, redirectUri?: string, state?: string): Promise<any>;
5730
5822
  /**
5731
5823
  * Construct the complete magic link URL that would be sent via email
5732
5824
  *
@@ -5734,7 +5826,7 @@ declare class MagicLinks {
5734
5826
  * @param redirectUri Optional redirect URI
5735
5827
  * @returns Complete magic link URL
5736
5828
  */
5737
- constructMagicLink(token: string, redirectUri?: string): string;
5829
+ constructMagicLink(token: string, redirectUri?: string, state?: string): string;
5738
5830
  }
5739
5831
 
5740
5832
  /**
@@ -5806,6 +5898,10 @@ interface SsoClientOptions {
5806
5898
  * Prefix for storage keys. Default: 'sso_'
5807
5899
  */
5808
5900
  storagePrefix?: string;
5901
+ /**
5902
+ * Refresh access tokens this many seconds before expiry. Default: 30.
5903
+ */
5904
+ tokenRefreshMinValiditySeconds?: number;
5809
5905
  }
5810
5906
  /**
5811
5907
  * Main SSO client class.
@@ -6087,4 +6183,4 @@ declare class SsoApiError extends Error {
6087
6183
  isNotFound(): boolean;
6088
6184
  }
6089
6185
 
6090
- export { type AcceptInvitationPayload, type AdminLoginUrlParams, type AnalyticsQuery, type ApiKey, type ApiKeyCreateResponse, type ApproveOrganizationPayload, type AuditLog, type AuditLogEntry, type AuditLogQueryParams, type AuditLogResponse, type AuthContextRequest, type AuthContextResponse, AuthErrorCodes, AuthModule, type AuthOrganizationContext, type AuthServiceContext, type AuthSnapshot, type AuthenticationResponseJSON, type BackupCodesResponse, type BrandingConfiguration, BrowserStorage, type ChangePasswordRequest, type ChangePasswordResponse, type CompleteProviderTokenRequestPayload, type CompleteProviderTokenRequestResponse, type ConfigureSamlPayload, type ConfigureSamlResponse, CookieStorage, type CreateApiKeyPayload, type CreateCheckoutPayload, type CreateCheckoutResponse, type CreateInvitationPayload, type CreateOrganizationPayload, type CreateOrganizationResponse, type CreatePlanPayload, type CreateRoleRequest, type CreateScimTokenRequest, type CreateServicePayload, type CreateServiceResponse, type CreateSiemConfigRequest, type CreateUpstreamProviderPayload, type CreateWebhookRequest, type DeclineInvitationPayload, type DeviceCodeRequest, type DeviceCodeResponse, type DeviceVerifyResponse, type DomainConfiguration, type DomainVerificationMethod, type DomainVerificationResponse, type DomainVerificationResult, type EndUser, type EndUserDetailResponse, type EndUserIdentity, type EndUserListResponse, type EndUserLoginEvent, type EndUserSession, type EndUserSubscription, type EventTypeInfo, type ExportUserDataResponse, type ForgetUserRequest, type ForgetUserResponse, type ForgotPasswordRequest, type ForgotPasswordResponse, type GeoLocation, type GetAuditLogParams, type GetRiskSettingsResponse, type GrantLinkedAccountRequest, type GrowthTrendPoint, type Identity, type ImpersonateRequest, type ImpersonateResponse, type ImpersonationUserInfo, type Invitation, type InvitationStatus, type InvitationWithOrg, InvitationsModule, type JwtClaims, type LinkedAccount, type LinkedAccountGrant, type LinkedAccountsResponse, type ListApiKeysResponse, type ListDevicesResponse, type ListEndUsersParams, type ListOrganizationsParams, type ListPlatformOrganizationsParams, type ListScimTokensResponse, type ListSiemConfigsResponse, type LoginActivityPoint, type LoginEventExport, type LoginRequest, type LoginTrendPoint, type LoginUrlParams, type LoginsByProvider, type LoginsByService, type LookupEmailRequest, type LookupEmailResponse, MagicLinks, type MemberListResponse, type MemberRole, type MemberServiceAccess, type Membership, type MembershipExport, MemoryStorage, type MfaEventExport, type MfaSetupResponse, type MfaStatusResponse, type MfaVerificationRequest, type MfaVerificationResponse, type MfaVerifyRequest, type MfaVerifyResponse, type OAuthCredentials, type OAuthIdentityExport, type OAuthProvider, type Organization, type OrganizationMember, type OrganizationResponse, type OrganizationStatus, type OrganizationStatusBreakdown, type OrganizationTier, OrganizationsModule, type PaginatedResponse, type PaginationInfo, type PaginationParams, type Passkey, type PasskeyActionResponse, type PasskeyAuthFinishRequest, type PasskeyAuthFinishResponse, type PasskeyAuthStartRequest, type PasskeyAuthStartResponse, type PasskeyExport, type PasskeyRegisterFinishRequest, type PasskeyRegisterFinishResponse, type PasskeyRegisterStartRequest, type PasskeyRegisterStartResponse, PasskeysModule, PermissionsModule, type Plan, type PlanResponse, type PlatformAnalyticsDateRangeParams, PlatformModule, type PlatformOrganizationResponse, type PlatformOrganizationsListResponse, type PlatformOverviewMetrics, type PlatformUser, type PlatformUserListResponse, type PromotePlatformOwnerPayload, type ProviderDefinition, type ProviderToken, type ProviderTokenRequestDetails, type RecentLogin, type RecentOrganization, type RefreshTokenRequest, type RefreshTokenResponse, type RegisterRequest, type RegisterResponse, type RegistrationResponseJSON, type RejectOrganizationPayload, type ResendVerificationRequest, type ResendVerificationResponse, type ResetPasswordRequest, type ResetPasswordResponse, type RevokeDeviceRequest, type RevokeDeviceResponse, type RevokeSessionsResponse, type RiskAction, type RiskAssessment, type RiskEventResponse, type RiskEventsQuery, type RoleResponse, type RotateServiceSecretResponse, type SamlCertificate, type SamlConfig, type ScimTokenResponse, type SelectOrganizationResponse, type Service, ServiceApiModule, type ServiceListResponse, type ServiceType, type ServiceWithDetails, ServicesModule, type SetCustomDomainRequest, type SetOAuthCredentialsPayload, type SetPasswordRequest, type SetPasswordResponse, type SetSmtpRequest, type SiemConfigResponse, type SiemProviderType, type SmtpConfigResponse, SsoApiError, SsoClient, type SsoClientOptions, type StartLinkResponse, type Subscription, type TestConnectionResponse, type TokenRequest, type TokenResponse, type TokenStorage, type TopOrganization, type TransferOwnershipPayload, type UpdateBrandingRequest, type UpdateMemberRolePayload, type UpdateMemberServiceAccessPayload, type UpdateOrganizationPayload, type UpdateOrganizationTierPayload, type UpdatePlanPayload, type UpdateRiskSettingsRequest, type UpdateRiskSettingsResponse, type UpdateRoleRequest, type UpdateServicePayload, type UpdateSiemConfigRequest, type UpdateUpstreamProviderPayload, type UpdateUserProfilePayload, type UpdateWebhookRequest, type UpstreamProvider, type UpstreamProviderType, type User, type UserDevice, UserModule, type UserPasskey, type UserProfile, type Webhook, type WebhookDelivery, type WebhookDeliveryListResponse, type WebhookDeliveryQueryParams, type WebhookListResponse, type WebhookResponse };
6186
+ export { type AcceptInvitationPayload, type AccountSecurityUrlParams, type AdminLoginUrlParams, type AnalyticsQuery, type ApiKey, type ApiKeyCreateResponse, type ApproveOrganizationPayload, type AuditLog, type AuditLogEntry, type AuditLogQueryParams, type AuditLogResponse, type AuthContextRequest, type AuthContextResponse, AuthErrorCodes, AuthModule, type AuthOrganizationContext, type AuthServiceContext, type AuthSnapshot, type AuthenticationResponseJSON, type AuthorizeUrlParams, type BackupCodesResponse, type BrandingConfiguration, BrowserStorage, type ChangePasswordRequest, type ChangePasswordResponse, type CompleteProviderTokenRequestPayload, type CompleteProviderTokenRequestResponse, type ConfigureSamlPayload, type ConfigureSamlResponse, CookieStorage, type CreateApiKeyPayload, type CreateCheckoutPayload, type CreateCheckoutResponse, type CreateInvitationPayload, type CreateOrganizationPayload, type CreateOrganizationResponse, type CreatePlanPayload, type CreateRoleRequest, type CreateScimTokenRequest, type CreateServicePayload, type CreateServiceResponse, type CreateSiemConfigRequest, type CreateUpstreamProviderPayload, type CreateWebhookRequest, type DeclineInvitationPayload, type DeviceCodeRequest, type DeviceCodeResponse, type DeviceVerifyResponse, type DomainConfiguration, type DomainVerificationMethod, type DomainVerificationResponse, type DomainVerificationResult, type EndUser, type EndUserDetailResponse, type EndUserIdentity, type EndUserListResponse, type EndUserLoginEvent, type EndUserSession, type EndUserSubscription, type EventTypeInfo, type ExportUserDataResponse, type ForgetUserRequest, type ForgetUserResponse, type ForgotPasswordRequest, type ForgotPasswordResponse, type GeoLocation, type GetAuditLogParams, type GetRiskSettingsResponse, type GrantLinkedAccountRequest, type GrowthTrendPoint, type Identity, type ImpersonateRequest, type ImpersonateResponse, type ImpersonationUserInfo, type Invitation, type InvitationStatus, type InvitationWithOrg, InvitationsModule, type JwtClaims, type LinkedAccount, type LinkedAccountGrant, type LinkedAccountsResponse, type ListApiKeysResponse, type ListDevicesResponse, type ListEndUsersParams, type ListOrganizationsParams, type ListPlatformOrganizationsParams, type ListScimTokensResponse, type ListSiemConfigsResponse, type LoginActivityPoint, type LoginEventExport, type LoginRequest, type LoginTrendPoint, type LoginUrlParams, type LoginsByProvider, type LoginsByService, type LookupEmailRequest, type LookupEmailResponse, MagicLinks, type MemberListResponse, type MemberRole, type MemberServiceAccess, type Membership, type MembershipExport, MemoryStorage, type MfaEventExport, type MfaSetupResponse, type MfaStatusResponse, type MfaVerificationRequest, type MfaVerificationResponse, type MfaVerifyRequest, type MfaVerifyResponse, type OAuthCredentials, type OAuthIdentityExport, type OAuthProvider, type Organization, type OrganizationMember, type OrganizationResponse, type OrganizationStatus, type OrganizationStatusBreakdown, type OrganizationTier, OrganizationsModule, type PaginatedResponse, type PaginationInfo, type PaginationParams, type Passkey, type PasskeyActionResponse, type PasskeyAuthFinishRequest, type PasskeyAuthFinishResponse, type PasskeyAuthStartRequest, type PasskeyAuthStartResponse, type PasskeyExport, type PasskeyRegisterFinishRequest, type PasskeyRegisterFinishResponse, type PasskeyRegisterStartRequest, type PasskeyRegisterStartResponse, PasskeysModule, PermissionsModule, type Plan, type PlanResponse, type PlatformAnalyticsDateRangeParams, PlatformModule, type PlatformOrganizationResponse, type PlatformOrganizationsListResponse, type PlatformOverviewMetrics, type PlatformUser, type PlatformUserListResponse, type PromotePlatformOwnerPayload, type ProviderDefinition, type ProviderToken, type ProviderTokenRequestDetails, type RecentLogin, type RecentOrganization, type RefreshTokenRequest, type RefreshTokenResponse, type RegisterRequest, type RegisterResponse, type RegistrationResponseJSON, type RejectOrganizationPayload, type ResendVerificationRequest, type ResendVerificationResponse, type ResetPasswordRequest, type ResetPasswordResponse, type RevokeDeviceRequest, type RevokeDeviceResponse, type RevokeSessionsResponse, type RiskAction, type RiskAssessment, type RiskEventResponse, type RiskEventsQuery, type RoleResponse, type RotateServiceSecretResponse, type SamlCertificate, type SamlConfig, type ScimTokenResponse, type SelectOrganizationResponse, type Service, ServiceApiModule, type ServiceListResponse, type ServiceType, type ServiceWithDetails, ServicesModule, SessionManager, type SetCustomDomainRequest, type SetOAuthCredentialsPayload, type SetPasswordRequest, type SetPasswordResponse, type SetSmtpRequest, type SiemConfigResponse, type SiemProviderType, type SmtpConfigResponse, SsoApiError, SsoClient, type SsoClientOptions, type StartLinkResponse, type Subscription, type TestConnectionResponse, type TokenRequest, type TokenResponse, type TokenStorage, type TopOrganization, type TransferOwnershipPayload, type UpdateBrandingRequest, type UpdateMemberRolePayload, type UpdateMemberServiceAccessPayload, type UpdateOrganizationPayload, type UpdateOrganizationTierPayload, type UpdatePlanPayload, type UpdateRiskSettingsRequest, type UpdateRiskSettingsResponse, type UpdateRoleRequest, type UpdateServicePayload, type UpdateSiemConfigRequest, type UpdateUpstreamProviderPayload, type UpdateUserProfilePayload, type UpdateWebhookRequest, type UpstreamProvider, type UpstreamProviderType, type User, type UserDevice, UserModule, type UserPasskey, type UserProfile, type Webhook, type WebhookDelivery, type WebhookDeliveryListResponse, type WebhookDeliveryQueryParams, type WebhookListResponse, type WebhookResponse };
package/dist/index.d.ts CHANGED
@@ -254,6 +254,10 @@ interface LoginUrlParams {
254
254
  * Optional redirect URI (must be registered with the service)
255
255
  */
256
256
  redirect_uri?: string;
257
+ /**
258
+ * Optional caller state to return to the service callback.
259
+ */
260
+ state?: string;
257
261
  /**
258
262
  * Optional user code for device flow authorization
259
263
  */
@@ -265,6 +269,44 @@ interface LoginUrlParams {
265
269
  */
266
270
  connection_id?: string;
267
271
  }
272
+ /**
273
+ * Parameters for constructing the hosted AuthOS login URL.
274
+ */
275
+ interface AuthorizeUrlParams {
276
+ /**
277
+ * Organization slug
278
+ */
279
+ org: string;
280
+ /**
281
+ * Service slug
282
+ */
283
+ service: string;
284
+ /**
285
+ * Callback URI registered with the service
286
+ */
287
+ redirect_uri: string;
288
+ /**
289
+ * Optional caller state to return to the service callback.
290
+ */
291
+ state?: string;
292
+ }
293
+ /**
294
+ * Parameters for constructing the hosted account-security URL.
295
+ */
296
+ interface AccountSecurityUrlParams {
297
+ /**
298
+ * Optional organization slug for tenant-aware branding/context
299
+ */
300
+ org?: string;
301
+ /**
302
+ * Optional service slug for application context
303
+ */
304
+ service?: string;
305
+ /**
306
+ * Optional URL to return to after managing account security
307
+ */
308
+ return_to?: string;
309
+ }
268
310
  /**
269
311
  * Parameters for constructing admin login URL
270
312
  */
@@ -277,6 +319,10 @@ interface AdminLoginUrlParams {
277
319
  * Optional user code for device flow authorization
278
320
  */
279
321
  user_code?: string;
322
+ /**
323
+ * Optional internal Lite client path to return to after admin OAuth.
324
+ */
325
+ return_to?: string;
280
326
  }
281
327
  /**
282
328
  * Provider token response
@@ -327,6 +373,10 @@ interface RegisterRequest {
327
373
  * Optional service callback URI to preserve the original app return path in the verification link.
328
374
  */
329
375
  redirect_uri?: string;
376
+ /**
377
+ * Optional caller state to return to hosted service callbacks.
378
+ */
379
+ state?: string;
330
380
  }
331
381
  /**
332
382
  * Registration response
@@ -357,6 +407,10 @@ interface LoginRequest {
357
407
  * against the service before tokens are returned to the hosted UI.
358
408
  */
359
409
  redirect_uri?: string;
410
+ /**
411
+ * Optional caller state to return to hosted service callbacks.
412
+ */
413
+ state?: string;
360
414
  }
361
415
  /**
362
416
  * Forgot password request payload
@@ -366,6 +420,7 @@ interface ForgotPasswordRequest {
366
420
  org_slug?: string;
367
421
  service_slug?: string;
368
422
  redirect_uri?: string;
423
+ state?: string;
369
424
  }
370
425
  /**
371
426
  * Forgot password response
@@ -394,6 +449,7 @@ interface ResendVerificationRequest {
394
449
  org_slug?: string;
395
450
  service_slug?: string;
396
451
  redirect_uri?: string;
452
+ state?: string;
397
453
  }
398
454
  /**
399
455
  * Resend verification response
@@ -1156,6 +1212,7 @@ interface Service {
1156
1212
  google_scopes: string[];
1157
1213
  redirect_uris: string[];
1158
1214
  device_activation_uri?: string;
1215
+ resource_uris?: string[];
1159
1216
  saml_enabled: boolean;
1160
1217
  saml_entity_id?: string;
1161
1218
  saml_acs_url?: string;
@@ -1224,6 +1281,7 @@ interface CreateServicePayload {
1224
1281
  google_scopes?: string[];
1225
1282
  redirect_uris: string[];
1226
1283
  device_activation_uri?: string;
1284
+ resource_uris?: string[];
1227
1285
  }
1228
1286
  /**
1229
1287
  * Create service response
@@ -1252,6 +1310,7 @@ interface UpdateServicePayload {
1252
1310
  google_scopes?: string[];
1253
1311
  redirect_uris?: string[];
1254
1312
  device_activation_uri?: string;
1313
+ resource_uris?: string[];
1255
1314
  }
1256
1315
  /**
1257
1316
  * Service with aggregated details (for listing)
@@ -1774,6 +1833,7 @@ interface PasskeyAuthStartRequest {
1774
1833
  org_slug?: string;
1775
1834
  service_slug?: string;
1776
1835
  redirect_uri?: string;
1836
+ state?: string;
1777
1837
  }
1778
1838
  /**
1779
1839
  * Response from starting passkey authentication
@@ -2086,6 +2146,7 @@ interface UpdateUpstreamProviderPayload {
2086
2146
  interface SessionConfig {
2087
2147
  storageKeyPrefix?: string;
2088
2148
  autoRefresh?: boolean;
2149
+ minValiditySeconds?: number;
2089
2150
  }
2090
2151
  /**
2091
2152
  * Snapshot of the current authentication state.
@@ -2102,6 +2163,7 @@ declare class SessionManager {
2102
2163
  private accessToken;
2103
2164
  private refreshToken;
2104
2165
  private refreshPromise;
2166
+ private sessionVersion;
2105
2167
  private listeners;
2106
2168
  constructor(storage: TokenStorage, refreshHandler: (token: string) => Promise<RefreshTokenResponse>, config?: SessionConfig);
2107
2169
  /**
@@ -2303,6 +2365,32 @@ declare class AuthModule {
2303
2365
  private http;
2304
2366
  private session;
2305
2367
  constructor(http: HttpClient, session: SessionManager);
2368
+ /**
2369
+ * Constructs the hosted AuthOS login URL for an end-user application.
2370
+ * AuthOS owns provider selection, HRD, password, magic-link, passkey, MFA,
2371
+ * recovery, and callback token delivery for this flow.
2372
+ *
2373
+ * @param params Hosted authorize parameters (org, service, redirect_uri)
2374
+ * @returns The full URL to redirect the user to
2375
+ *
2376
+ * @example
2377
+ * ```typescript
2378
+ * window.location.href = sso.auth.getAuthorizeUrl({
2379
+ * org: 'acme-corp',
2380
+ * service: 'main-app',
2381
+ * redirect_uri: 'https://app.acme.com/callback'
2382
+ * });
2383
+ * ```
2384
+ */
2385
+ getAuthorizeUrl(params: AuthorizeUrlParams): string;
2386
+ /**
2387
+ * Constructs the hosted account-security URL for managing user factors.
2388
+ * Use this for AuthOS-owned MFA, passkeys, backup codes, and trusted devices.
2389
+ *
2390
+ * @param params Optional tenant/application context and return URL
2391
+ * @returns The full URL to open for account security management
2392
+ */
2393
+ getAccountSecurityUrl(params?: AccountSecurityUrlParams): string;
2306
2394
  /**
2307
2395
  * Constructs the OAuth login URL for end-users.
2308
2396
  * This does not perform the redirect; the consuming application
@@ -5649,6 +5737,7 @@ declare class PasskeysModule {
5649
5737
  org_slug?: string;
5650
5738
  service_slug?: string;
5651
5739
  redirect_uri?: string;
5740
+ state?: string;
5652
5741
  }): Promise<PasskeyAuthStartResponse>;
5653
5742
  /**
5654
5743
  * Finish the passkey authentication ceremony.
@@ -5663,6 +5752,7 @@ declare class PasskeysModule {
5663
5752
  org_slug?: string;
5664
5753
  service_slug?: string;
5665
5754
  redirect_uri?: string;
5755
+ state?: string;
5666
5756
  }): Promise<PasskeyAuthFinishResponse>;
5667
5757
  /**
5668
5758
  * Convert Base64URL string to Uint8Array
@@ -5687,6 +5777,8 @@ interface MagicLinkRequest {
5687
5777
  service_slug?: string;
5688
5778
  /** Optional service callback URI */
5689
5779
  redirect_uri?: string;
5780
+ /** Optional caller state to return to hosted service callbacks */
5781
+ state?: string;
5690
5782
  }
5691
5783
  /**
5692
5784
  * Magic link response
@@ -5717,7 +5809,7 @@ declare class MagicLinks {
5717
5809
  * @param redirectUri Optional where to redirect after success
5718
5810
  * @returns URL to redirect to for verification
5719
5811
  */
5720
- getVerificationUrl(token: string, redirectUri?: string): string;
5812
+ getVerificationUrl(token: string, redirectUri?: string, state?: string): string;
5721
5813
  /**
5722
5814
  * Verify a magic link token via API call
5723
5815
  * This is an alternative to redirect-based verification
@@ -5726,7 +5818,7 @@ declare class MagicLinks {
5726
5818
  * @param redirectUri Optional redirect URI
5727
5819
  * @returns Promise resolving to authentication response
5728
5820
  */
5729
- verify(token: string, redirectUri?: string): Promise<any>;
5821
+ verify(token: string, redirectUri?: string, state?: string): Promise<any>;
5730
5822
  /**
5731
5823
  * Construct the complete magic link URL that would be sent via email
5732
5824
  *
@@ -5734,7 +5826,7 @@ declare class MagicLinks {
5734
5826
  * @param redirectUri Optional redirect URI
5735
5827
  * @returns Complete magic link URL
5736
5828
  */
5737
- constructMagicLink(token: string, redirectUri?: string): string;
5829
+ constructMagicLink(token: string, redirectUri?: string, state?: string): string;
5738
5830
  }
5739
5831
 
5740
5832
  /**
@@ -5806,6 +5898,10 @@ interface SsoClientOptions {
5806
5898
  * Prefix for storage keys. Default: 'sso_'
5807
5899
  */
5808
5900
  storagePrefix?: string;
5901
+ /**
5902
+ * Refresh access tokens this many seconds before expiry. Default: 30.
5903
+ */
5904
+ tokenRefreshMinValiditySeconds?: number;
5809
5905
  }
5810
5906
  /**
5811
5907
  * Main SSO client class.
@@ -6087,4 +6183,4 @@ declare class SsoApiError extends Error {
6087
6183
  isNotFound(): boolean;
6088
6184
  }
6089
6185
 
6090
- export { type AcceptInvitationPayload, type AdminLoginUrlParams, type AnalyticsQuery, type ApiKey, type ApiKeyCreateResponse, type ApproveOrganizationPayload, type AuditLog, type AuditLogEntry, type AuditLogQueryParams, type AuditLogResponse, type AuthContextRequest, type AuthContextResponse, AuthErrorCodes, AuthModule, type AuthOrganizationContext, type AuthServiceContext, type AuthSnapshot, type AuthenticationResponseJSON, type BackupCodesResponse, type BrandingConfiguration, BrowserStorage, type ChangePasswordRequest, type ChangePasswordResponse, type CompleteProviderTokenRequestPayload, type CompleteProviderTokenRequestResponse, type ConfigureSamlPayload, type ConfigureSamlResponse, CookieStorage, type CreateApiKeyPayload, type CreateCheckoutPayload, type CreateCheckoutResponse, type CreateInvitationPayload, type CreateOrganizationPayload, type CreateOrganizationResponse, type CreatePlanPayload, type CreateRoleRequest, type CreateScimTokenRequest, type CreateServicePayload, type CreateServiceResponse, type CreateSiemConfigRequest, type CreateUpstreamProviderPayload, type CreateWebhookRequest, type DeclineInvitationPayload, type DeviceCodeRequest, type DeviceCodeResponse, type DeviceVerifyResponse, type DomainConfiguration, type DomainVerificationMethod, type DomainVerificationResponse, type DomainVerificationResult, type EndUser, type EndUserDetailResponse, type EndUserIdentity, type EndUserListResponse, type EndUserLoginEvent, type EndUserSession, type EndUserSubscription, type EventTypeInfo, type ExportUserDataResponse, type ForgetUserRequest, type ForgetUserResponse, type ForgotPasswordRequest, type ForgotPasswordResponse, type GeoLocation, type GetAuditLogParams, type GetRiskSettingsResponse, type GrantLinkedAccountRequest, type GrowthTrendPoint, type Identity, type ImpersonateRequest, type ImpersonateResponse, type ImpersonationUserInfo, type Invitation, type InvitationStatus, type InvitationWithOrg, InvitationsModule, type JwtClaims, type LinkedAccount, type LinkedAccountGrant, type LinkedAccountsResponse, type ListApiKeysResponse, type ListDevicesResponse, type ListEndUsersParams, type ListOrganizationsParams, type ListPlatformOrganizationsParams, type ListScimTokensResponse, type ListSiemConfigsResponse, type LoginActivityPoint, type LoginEventExport, type LoginRequest, type LoginTrendPoint, type LoginUrlParams, type LoginsByProvider, type LoginsByService, type LookupEmailRequest, type LookupEmailResponse, MagicLinks, type MemberListResponse, type MemberRole, type MemberServiceAccess, type Membership, type MembershipExport, MemoryStorage, type MfaEventExport, type MfaSetupResponse, type MfaStatusResponse, type MfaVerificationRequest, type MfaVerificationResponse, type MfaVerifyRequest, type MfaVerifyResponse, type OAuthCredentials, type OAuthIdentityExport, type OAuthProvider, type Organization, type OrganizationMember, type OrganizationResponse, type OrganizationStatus, type OrganizationStatusBreakdown, type OrganizationTier, OrganizationsModule, type PaginatedResponse, type PaginationInfo, type PaginationParams, type Passkey, type PasskeyActionResponse, type PasskeyAuthFinishRequest, type PasskeyAuthFinishResponse, type PasskeyAuthStartRequest, type PasskeyAuthStartResponse, type PasskeyExport, type PasskeyRegisterFinishRequest, type PasskeyRegisterFinishResponse, type PasskeyRegisterStartRequest, type PasskeyRegisterStartResponse, PasskeysModule, PermissionsModule, type Plan, type PlanResponse, type PlatformAnalyticsDateRangeParams, PlatformModule, type PlatformOrganizationResponse, type PlatformOrganizationsListResponse, type PlatformOverviewMetrics, type PlatformUser, type PlatformUserListResponse, type PromotePlatformOwnerPayload, type ProviderDefinition, type ProviderToken, type ProviderTokenRequestDetails, type RecentLogin, type RecentOrganization, type RefreshTokenRequest, type RefreshTokenResponse, type RegisterRequest, type RegisterResponse, type RegistrationResponseJSON, type RejectOrganizationPayload, type ResendVerificationRequest, type ResendVerificationResponse, type ResetPasswordRequest, type ResetPasswordResponse, type RevokeDeviceRequest, type RevokeDeviceResponse, type RevokeSessionsResponse, type RiskAction, type RiskAssessment, type RiskEventResponse, type RiskEventsQuery, type RoleResponse, type RotateServiceSecretResponse, type SamlCertificate, type SamlConfig, type ScimTokenResponse, type SelectOrganizationResponse, type Service, ServiceApiModule, type ServiceListResponse, type ServiceType, type ServiceWithDetails, ServicesModule, type SetCustomDomainRequest, type SetOAuthCredentialsPayload, type SetPasswordRequest, type SetPasswordResponse, type SetSmtpRequest, type SiemConfigResponse, type SiemProviderType, type SmtpConfigResponse, SsoApiError, SsoClient, type SsoClientOptions, type StartLinkResponse, type Subscription, type TestConnectionResponse, type TokenRequest, type TokenResponse, type TokenStorage, type TopOrganization, type TransferOwnershipPayload, type UpdateBrandingRequest, type UpdateMemberRolePayload, type UpdateMemberServiceAccessPayload, type UpdateOrganizationPayload, type UpdateOrganizationTierPayload, type UpdatePlanPayload, type UpdateRiskSettingsRequest, type UpdateRiskSettingsResponse, type UpdateRoleRequest, type UpdateServicePayload, type UpdateSiemConfigRequest, type UpdateUpstreamProviderPayload, type UpdateUserProfilePayload, type UpdateWebhookRequest, type UpstreamProvider, type UpstreamProviderType, type User, type UserDevice, UserModule, type UserPasskey, type UserProfile, type Webhook, type WebhookDelivery, type WebhookDeliveryListResponse, type WebhookDeliveryQueryParams, type WebhookListResponse, type WebhookResponse };
6186
+ export { type AcceptInvitationPayload, type AccountSecurityUrlParams, type AdminLoginUrlParams, type AnalyticsQuery, type ApiKey, type ApiKeyCreateResponse, type ApproveOrganizationPayload, type AuditLog, type AuditLogEntry, type AuditLogQueryParams, type AuditLogResponse, type AuthContextRequest, type AuthContextResponse, AuthErrorCodes, AuthModule, type AuthOrganizationContext, type AuthServiceContext, type AuthSnapshot, type AuthenticationResponseJSON, type AuthorizeUrlParams, type BackupCodesResponse, type BrandingConfiguration, BrowserStorage, type ChangePasswordRequest, type ChangePasswordResponse, type CompleteProviderTokenRequestPayload, type CompleteProviderTokenRequestResponse, type ConfigureSamlPayload, type ConfigureSamlResponse, CookieStorage, type CreateApiKeyPayload, type CreateCheckoutPayload, type CreateCheckoutResponse, type CreateInvitationPayload, type CreateOrganizationPayload, type CreateOrganizationResponse, type CreatePlanPayload, type CreateRoleRequest, type CreateScimTokenRequest, type CreateServicePayload, type CreateServiceResponse, type CreateSiemConfigRequest, type CreateUpstreamProviderPayload, type CreateWebhookRequest, type DeclineInvitationPayload, type DeviceCodeRequest, type DeviceCodeResponse, type DeviceVerifyResponse, type DomainConfiguration, type DomainVerificationMethod, type DomainVerificationResponse, type DomainVerificationResult, type EndUser, type EndUserDetailResponse, type EndUserIdentity, type EndUserListResponse, type EndUserLoginEvent, type EndUserSession, type EndUserSubscription, type EventTypeInfo, type ExportUserDataResponse, type ForgetUserRequest, type ForgetUserResponse, type ForgotPasswordRequest, type ForgotPasswordResponse, type GeoLocation, type GetAuditLogParams, type GetRiskSettingsResponse, type GrantLinkedAccountRequest, type GrowthTrendPoint, type Identity, type ImpersonateRequest, type ImpersonateResponse, type ImpersonationUserInfo, type Invitation, type InvitationStatus, type InvitationWithOrg, InvitationsModule, type JwtClaims, type LinkedAccount, type LinkedAccountGrant, type LinkedAccountsResponse, type ListApiKeysResponse, type ListDevicesResponse, type ListEndUsersParams, type ListOrganizationsParams, type ListPlatformOrganizationsParams, type ListScimTokensResponse, type ListSiemConfigsResponse, type LoginActivityPoint, type LoginEventExport, type LoginRequest, type LoginTrendPoint, type LoginUrlParams, type LoginsByProvider, type LoginsByService, type LookupEmailRequest, type LookupEmailResponse, MagicLinks, type MemberListResponse, type MemberRole, type MemberServiceAccess, type Membership, type MembershipExport, MemoryStorage, type MfaEventExport, type MfaSetupResponse, type MfaStatusResponse, type MfaVerificationRequest, type MfaVerificationResponse, type MfaVerifyRequest, type MfaVerifyResponse, type OAuthCredentials, type OAuthIdentityExport, type OAuthProvider, type Organization, type OrganizationMember, type OrganizationResponse, type OrganizationStatus, type OrganizationStatusBreakdown, type OrganizationTier, OrganizationsModule, type PaginatedResponse, type PaginationInfo, type PaginationParams, type Passkey, type PasskeyActionResponse, type PasskeyAuthFinishRequest, type PasskeyAuthFinishResponse, type PasskeyAuthStartRequest, type PasskeyAuthStartResponse, type PasskeyExport, type PasskeyRegisterFinishRequest, type PasskeyRegisterFinishResponse, type PasskeyRegisterStartRequest, type PasskeyRegisterStartResponse, PasskeysModule, PermissionsModule, type Plan, type PlanResponse, type PlatformAnalyticsDateRangeParams, PlatformModule, type PlatformOrganizationResponse, type PlatformOrganizationsListResponse, type PlatformOverviewMetrics, type PlatformUser, type PlatformUserListResponse, type PromotePlatformOwnerPayload, type ProviderDefinition, type ProviderToken, type ProviderTokenRequestDetails, type RecentLogin, type RecentOrganization, type RefreshTokenRequest, type RefreshTokenResponse, type RegisterRequest, type RegisterResponse, type RegistrationResponseJSON, type RejectOrganizationPayload, type ResendVerificationRequest, type ResendVerificationResponse, type ResetPasswordRequest, type ResetPasswordResponse, type RevokeDeviceRequest, type RevokeDeviceResponse, type RevokeSessionsResponse, type RiskAction, type RiskAssessment, type RiskEventResponse, type RiskEventsQuery, type RoleResponse, type RotateServiceSecretResponse, type SamlCertificate, type SamlConfig, type ScimTokenResponse, type SelectOrganizationResponse, type Service, ServiceApiModule, type ServiceListResponse, type ServiceType, type ServiceWithDetails, ServicesModule, SessionManager, type SetCustomDomainRequest, type SetOAuthCredentialsPayload, type SetPasswordRequest, type SetPasswordResponse, type SetSmtpRequest, type SiemConfigResponse, type SiemProviderType, type SmtpConfigResponse, SsoApiError, SsoClient, type SsoClientOptions, type StartLinkResponse, type Subscription, type TestConnectionResponse, type TokenRequest, type TokenResponse, type TokenStorage, type TopOrganization, type TransferOwnershipPayload, type UpdateBrandingRequest, type UpdateMemberRolePayload, type UpdateMemberServiceAccessPayload, type UpdateOrganizationPayload, type UpdateOrganizationTierPayload, type UpdatePlanPayload, type UpdateRiskSettingsRequest, type UpdateRiskSettingsResponse, type UpdateRoleRequest, type UpdateServicePayload, type UpdateSiemConfigRequest, type UpdateUpstreamProviderPayload, type UpdateUserProfilePayload, type UpdateWebhookRequest, type UpstreamProvider, type UpstreamProviderType, type User, type UserDevice, UserModule, type UserPasskey, type UserProfile, type Webhook, type WebhookDelivery, type WebhookDeliveryListResponse, type WebhookDeliveryQueryParams, type WebhookListResponse, type WebhookResponse };
package/dist/index.js CHANGED
@@ -33,6 +33,7 @@ __export(index_exports, {
33
33
  PlatformModule: () => PlatformModule,
34
34
  ServiceApiModule: () => ServiceApiModule,
35
35
  ServicesModule: () => ServicesModule,
36
+ SessionManager: () => SessionManager,
36
37
  SsoApiError: () => SsoApiError,
37
38
  SsoClient: () => SsoClient,
38
39
  UserModule: () => UserModule
@@ -300,6 +301,22 @@ function createHttpAgent(baseURL) {
300
301
  }
301
302
 
302
303
  // src/session.ts
304
+ var DEFAULT_MIN_VALIDITY_SECONDS = 30;
305
+ function decodeJwtExpiration(token) {
306
+ const [, payload] = token.split(".");
307
+ if (!payload) {
308
+ return null;
309
+ }
310
+ try {
311
+ const normalized = payload.replace(/-/g, "+").replace(/_/g, "/");
312
+ const padded = normalized.padEnd(normalized.length + (4 - normalized.length % 4) % 4, "=");
313
+ const decoded = globalThis.atob(padded);
314
+ const parsed = JSON.parse(decoded);
315
+ return typeof parsed.exp === "number" && Number.isFinite(parsed.exp) ? parsed.exp : null;
316
+ } catch {
317
+ return null;
318
+ }
319
+ }
303
320
  var SessionManager = class {
304
321
  constructor(storage, refreshHandler, config = { storageKeyPrefix: "sso_" }) {
305
322
  this.storage = storage;
@@ -308,19 +325,27 @@ var SessionManager = class {
308
325
  this.accessToken = null;
309
326
  this.refreshToken = null;
310
327
  this.refreshPromise = null;
328
+ this.sessionVersion = 0;
311
329
  this.listeners = [];
312
330
  }
313
331
  /**
314
332
  * Initialize session from storage
315
333
  */
316
334
  async loadSession() {
317
- this.accessToken = await this.storage.getItem(`${this.config.storageKeyPrefix}access_token`);
318
- this.refreshToken = await this.storage.getItem(`${this.config.storageKeyPrefix}refresh_token`);
335
+ const version = this.sessionVersion;
336
+ const accessToken = await this.storage.getItem(`${this.config.storageKeyPrefix}access_token`);
337
+ const refreshToken = await this.storage.getItem(`${this.config.storageKeyPrefix}refresh_token`);
338
+ if (version !== this.sessionVersion) {
339
+ return;
340
+ }
341
+ this.accessToken = accessToken;
342
+ this.refreshToken = refreshToken;
319
343
  }
320
344
  /**
321
345
  * Set the session data (used after login/register)
322
346
  */
323
347
  async setSession(tokens) {
348
+ this.sessionVersion += 1;
324
349
  this.accessToken = tokens.access_token;
325
350
  await this.storage.setItem(`${this.config.storageKeyPrefix}access_token`, tokens.access_token);
326
351
  if (tokens.refresh_token) {
@@ -333,6 +358,7 @@ var SessionManager = class {
333
358
  * Clear session (logout)
334
359
  */
335
360
  async clearSession() {
361
+ this.sessionVersion += 1;
336
362
  this.accessToken = null;
337
363
  this.refreshToken = null;
338
364
  await this.storage.removeItem(`${this.config.storageKeyPrefix}access_token`);
@@ -343,6 +369,26 @@ var SessionManager = class {
343
369
  * Get the current access token, refreshing it if necessary/possible
344
370
  */
345
371
  async getToken() {
372
+ if (!this.accessToken) {
373
+ return null;
374
+ }
375
+ const expiresAt = decodeJwtExpiration(this.accessToken);
376
+ if (expiresAt === null) {
377
+ return this.accessToken;
378
+ }
379
+ const secondsUntilExpiry = expiresAt - Math.floor(Date.now() / 1e3);
380
+ const minValiditySeconds = this.config.minValiditySeconds ?? DEFAULT_MIN_VALIDITY_SECONDS;
381
+ if (secondsUntilExpiry <= 0 && !this.refreshToken) {
382
+ await this.clearSession();
383
+ return null;
384
+ }
385
+ if (secondsUntilExpiry <= minValiditySeconds && this.refreshToken) {
386
+ try {
387
+ return await this.refreshSession();
388
+ } catch {
389
+ return null;
390
+ }
391
+ }
346
392
  return this.accessToken;
347
393
  }
348
394
  /**
@@ -672,6 +718,49 @@ var AuthModule = class {
672
718
  }
673
719
  };
674
720
  }
721
+ /**
722
+ * Constructs the hosted AuthOS login URL for an end-user application.
723
+ * AuthOS owns provider selection, HRD, password, magic-link, passkey, MFA,
724
+ * recovery, and callback token delivery for this flow.
725
+ *
726
+ * @param params Hosted authorize parameters (org, service, redirect_uri)
727
+ * @returns The full URL to redirect the user to
728
+ *
729
+ * @example
730
+ * ```typescript
731
+ * window.location.href = sso.auth.getAuthorizeUrl({
732
+ * org: 'acme-corp',
733
+ * service: 'main-app',
734
+ * redirect_uri: 'https://app.acme.com/callback'
735
+ * });
736
+ * ```
737
+ */
738
+ getAuthorizeUrl(params) {
739
+ const baseURL = (this.http.defaults.baseURL || "").replace(/\/+$/, "");
740
+ const searchParams = new URLSearchParams({
741
+ org: params.org,
742
+ service: params.service,
743
+ redirect_uri: params.redirect_uri
744
+ });
745
+ if (params.state) searchParams.append("state", params.state);
746
+ return `${baseURL}/authorize?${searchParams.toString()}`;
747
+ }
748
+ /**
749
+ * Constructs the hosted account-security URL for managing user factors.
750
+ * Use this for AuthOS-owned MFA, passkeys, backup codes, and trusted devices.
751
+ *
752
+ * @param params Optional tenant/application context and return URL
753
+ * @returns The full URL to open for account security management
754
+ */
755
+ getAccountSecurityUrl(params = {}) {
756
+ const baseURL = (this.http.defaults.baseURL || "").replace(/\/+$/, "");
757
+ const searchParams = new URLSearchParams();
758
+ if (params.org) searchParams.append("org", params.org);
759
+ if (params.service) searchParams.append("service", params.service);
760
+ if (params.return_to) searchParams.append("return_to", params.return_to);
761
+ const query = searchParams.toString();
762
+ return `${baseURL}/app/account-security${query ? `?${query}` : ""}`;
763
+ }
675
764
  /**
676
765
  * Constructs the OAuth login URL for end-users.
677
766
  * This does not perform the redirect; the consuming application
@@ -712,6 +801,9 @@ var AuthModule = class {
712
801
  if (params.redirect_uri) {
713
802
  searchParams.append("redirect_uri", params.redirect_uri);
714
803
  }
804
+ if (params.state) {
805
+ searchParams.append("state", params.state);
806
+ }
715
807
  if (params.user_code) {
716
808
  searchParams.append("user_code", params.user_code);
717
809
  }
@@ -745,6 +837,9 @@ var AuthModule = class {
745
837
  if (params?.user_code) {
746
838
  searchParams.append("user_code", params.user_code);
747
839
  }
840
+ if (params?.return_to) {
841
+ searchParams.append("return_to", params.return_to);
842
+ }
748
843
  const queryString = searchParams.toString();
749
844
  return `${baseURL}/auth/admin/${provider}${queryString ? `?${queryString}` : ""}`;
750
845
  }
@@ -1680,11 +1775,11 @@ var WebhooksModule = class {
1680
1775
  /**
1681
1776
  * Trigger a test event for a specific webhook (owner/admin only).
1682
1777
  * Generates a "webhook.test.ping" event to verify connectivity.
1683
- *
1778
+ *
1684
1779
  * @param orgSlug Organization slug
1685
1780
  * @param webhookId Webhook ID
1686
1781
  * @returns Result including delivery ID
1687
- *
1782
+ *
1688
1783
  * @example
1689
1784
  * ```typescript
1690
1785
  * const result = await sso.organizations.webhooks.test('acme-corp', 'webhook-123');
@@ -1949,7 +2044,7 @@ var OrganizationsModule = class {
1949
2044
  * page: 1,
1950
2045
  * limit: 20
1951
2046
  * });
1952
- *
2047
+ *
1953
2048
  * // Filter by specific service
1954
2049
  * const serviceUsers = await sso.organizations.endUsers.list('acme-corp', {
1955
2050
  * service_slug: 'my-app',
@@ -2336,7 +2431,7 @@ var OrganizationsModule = class {
2336
2431
  /**
2337
2432
  * Get risk events for an organization.
2338
2433
  * Requires 'owner' or 'admin' role.
2339
- *
2434
+ *
2340
2435
  * @param orgSlug Organization slug
2341
2436
  * @param params Query parameters
2342
2437
  */
@@ -2536,7 +2631,7 @@ var OrganizationsModule = class {
2536
2631
  /**
2537
2632
  * Select/switch to a different organization context.
2538
2633
  * Issues a new JWT token with the organization context.
2539
- *
2634
+ *
2540
2635
  * This allows users to seamlessly switch between organizations
2541
2636
  * they are members of without re-authenticating.
2542
2637
  *
@@ -2547,7 +2642,7 @@ var OrganizationsModule = class {
2547
2642
  * ```typescript
2548
2643
  * // Switch to a different organization
2549
2644
  * const result = await sso.organizations.select('acme-corp');
2550
- *
2645
+ *
2551
2646
  * // The SDK automatically updates the session with new tokens
2552
2647
  * // API calls will now be made in the context of 'acme-corp'
2553
2648
  * ```
@@ -3734,10 +3829,10 @@ var PlatformModule = class {
3734
3829
  },
3735
3830
  /**
3736
3831
  * List all users on the platform with pagination.
3737
- *
3832
+ *
3738
3833
  * @param options Pagination options
3739
3834
  * @returns List of users and total count
3740
- *
3835
+ *
3741
3836
  * @example
3742
3837
  * ```typescript
3743
3838
  * const result = await sso.platform.users.list({ limit: 10, offset: 0 });
@@ -4767,11 +4862,14 @@ var MagicLinks = class {
4767
4862
  * @param redirectUri Optional where to redirect after success
4768
4863
  * @returns URL to redirect to for verification
4769
4864
  */
4770
- getVerificationUrl(token, redirectUri) {
4865
+ getVerificationUrl(token, redirectUri, state) {
4771
4866
  const params = new URLSearchParams({ token });
4772
4867
  if (redirectUri) {
4773
4868
  params.append("redirect_uri", redirectUri);
4774
4869
  }
4870
+ if (state) {
4871
+ params.append("state", state);
4872
+ }
4775
4873
  return `/api/auth/magic-link/verify?${params.toString()}`;
4776
4874
  }
4777
4875
  /**
@@ -4782,11 +4880,14 @@ var MagicLinks = class {
4782
4880
  * @param redirectUri Optional redirect URI
4783
4881
  * @returns Promise resolving to authentication response
4784
4882
  */
4785
- async verify(token, redirectUri) {
4883
+ async verify(token, redirectUri, state) {
4786
4884
  const params = new URLSearchParams({ token });
4787
4885
  if (redirectUri) {
4788
4886
  params.append("redirect_uri", redirectUri);
4789
4887
  }
4888
+ if (state) {
4889
+ params.append("state", state);
4890
+ }
4790
4891
  const response = await this.http.get(`/api/auth/magic-link/verify?${params.toString()}`);
4791
4892
  return response.data;
4792
4893
  }
@@ -4797,8 +4898,8 @@ var MagicLinks = class {
4797
4898
  * @param redirectUri Optional redirect URI
4798
4899
  * @returns Complete magic link URL
4799
4900
  */
4800
- constructMagicLink(token, redirectUri) {
4801
- return this.getVerificationUrl(token, redirectUri);
4901
+ constructMagicLink(token, redirectUri, state) {
4902
+ return this.getVerificationUrl(token, redirectUri, state);
4802
4903
  }
4803
4904
  };
4804
4905
 
@@ -4864,7 +4965,10 @@ var SsoClient = class {
4864
4965
  const res = await this.http.post("/api/auth/refresh", { refresh_token: refreshToken });
4865
4966
  return res.data;
4866
4967
  },
4867
- { storageKeyPrefix: options.storagePrefix || "sso_" }
4968
+ {
4969
+ storageKeyPrefix: options.storagePrefix || "sso_",
4970
+ minValiditySeconds: options.tokenRefreshMinValiditySeconds
4971
+ }
4868
4972
  );
4869
4973
  this.http.setSessionManager(this.session);
4870
4974
  this.analytics = new AnalyticsModule(this.http);
@@ -5028,6 +5132,7 @@ var SsoClient = class {
5028
5132
  PlatformModule,
5029
5133
  ServiceApiModule,
5030
5134
  ServicesModule,
5135
+ SessionManager,
5031
5136
  SsoApiError,
5032
5137
  SsoClient,
5033
5138
  UserModule
package/dist/index.mjs CHANGED
@@ -259,6 +259,22 @@ function createHttpAgent(baseURL) {
259
259
  }
260
260
 
261
261
  // src/session.ts
262
+ var DEFAULT_MIN_VALIDITY_SECONDS = 30;
263
+ function decodeJwtExpiration(token) {
264
+ const [, payload] = token.split(".");
265
+ if (!payload) {
266
+ return null;
267
+ }
268
+ try {
269
+ const normalized = payload.replace(/-/g, "+").replace(/_/g, "/");
270
+ const padded = normalized.padEnd(normalized.length + (4 - normalized.length % 4) % 4, "=");
271
+ const decoded = globalThis.atob(padded);
272
+ const parsed = JSON.parse(decoded);
273
+ return typeof parsed.exp === "number" && Number.isFinite(parsed.exp) ? parsed.exp : null;
274
+ } catch {
275
+ return null;
276
+ }
277
+ }
262
278
  var SessionManager = class {
263
279
  constructor(storage, refreshHandler, config = { storageKeyPrefix: "sso_" }) {
264
280
  this.storage = storage;
@@ -267,19 +283,27 @@ var SessionManager = class {
267
283
  this.accessToken = null;
268
284
  this.refreshToken = null;
269
285
  this.refreshPromise = null;
286
+ this.sessionVersion = 0;
270
287
  this.listeners = [];
271
288
  }
272
289
  /**
273
290
  * Initialize session from storage
274
291
  */
275
292
  async loadSession() {
276
- this.accessToken = await this.storage.getItem(`${this.config.storageKeyPrefix}access_token`);
277
- this.refreshToken = await this.storage.getItem(`${this.config.storageKeyPrefix}refresh_token`);
293
+ const version = this.sessionVersion;
294
+ const accessToken = await this.storage.getItem(`${this.config.storageKeyPrefix}access_token`);
295
+ const refreshToken = await this.storage.getItem(`${this.config.storageKeyPrefix}refresh_token`);
296
+ if (version !== this.sessionVersion) {
297
+ return;
298
+ }
299
+ this.accessToken = accessToken;
300
+ this.refreshToken = refreshToken;
278
301
  }
279
302
  /**
280
303
  * Set the session data (used after login/register)
281
304
  */
282
305
  async setSession(tokens) {
306
+ this.sessionVersion += 1;
283
307
  this.accessToken = tokens.access_token;
284
308
  await this.storage.setItem(`${this.config.storageKeyPrefix}access_token`, tokens.access_token);
285
309
  if (tokens.refresh_token) {
@@ -292,6 +316,7 @@ var SessionManager = class {
292
316
  * Clear session (logout)
293
317
  */
294
318
  async clearSession() {
319
+ this.sessionVersion += 1;
295
320
  this.accessToken = null;
296
321
  this.refreshToken = null;
297
322
  await this.storage.removeItem(`${this.config.storageKeyPrefix}access_token`);
@@ -302,6 +327,26 @@ var SessionManager = class {
302
327
  * Get the current access token, refreshing it if necessary/possible
303
328
  */
304
329
  async getToken() {
330
+ if (!this.accessToken) {
331
+ return null;
332
+ }
333
+ const expiresAt = decodeJwtExpiration(this.accessToken);
334
+ if (expiresAt === null) {
335
+ return this.accessToken;
336
+ }
337
+ const secondsUntilExpiry = expiresAt - Math.floor(Date.now() / 1e3);
338
+ const minValiditySeconds = this.config.minValiditySeconds ?? DEFAULT_MIN_VALIDITY_SECONDS;
339
+ if (secondsUntilExpiry <= 0 && !this.refreshToken) {
340
+ await this.clearSession();
341
+ return null;
342
+ }
343
+ if (secondsUntilExpiry <= minValiditySeconds && this.refreshToken) {
344
+ try {
345
+ return await this.refreshSession();
346
+ } catch {
347
+ return null;
348
+ }
349
+ }
305
350
  return this.accessToken;
306
351
  }
307
352
  /**
@@ -631,6 +676,49 @@ var AuthModule = class {
631
676
  }
632
677
  };
633
678
  }
679
+ /**
680
+ * Constructs the hosted AuthOS login URL for an end-user application.
681
+ * AuthOS owns provider selection, HRD, password, magic-link, passkey, MFA,
682
+ * recovery, and callback token delivery for this flow.
683
+ *
684
+ * @param params Hosted authorize parameters (org, service, redirect_uri)
685
+ * @returns The full URL to redirect the user to
686
+ *
687
+ * @example
688
+ * ```typescript
689
+ * window.location.href = sso.auth.getAuthorizeUrl({
690
+ * org: 'acme-corp',
691
+ * service: 'main-app',
692
+ * redirect_uri: 'https://app.acme.com/callback'
693
+ * });
694
+ * ```
695
+ */
696
+ getAuthorizeUrl(params) {
697
+ const baseURL = (this.http.defaults.baseURL || "").replace(/\/+$/, "");
698
+ const searchParams = new URLSearchParams({
699
+ org: params.org,
700
+ service: params.service,
701
+ redirect_uri: params.redirect_uri
702
+ });
703
+ if (params.state) searchParams.append("state", params.state);
704
+ return `${baseURL}/authorize?${searchParams.toString()}`;
705
+ }
706
+ /**
707
+ * Constructs the hosted account-security URL for managing user factors.
708
+ * Use this for AuthOS-owned MFA, passkeys, backup codes, and trusted devices.
709
+ *
710
+ * @param params Optional tenant/application context and return URL
711
+ * @returns The full URL to open for account security management
712
+ */
713
+ getAccountSecurityUrl(params = {}) {
714
+ const baseURL = (this.http.defaults.baseURL || "").replace(/\/+$/, "");
715
+ const searchParams = new URLSearchParams();
716
+ if (params.org) searchParams.append("org", params.org);
717
+ if (params.service) searchParams.append("service", params.service);
718
+ if (params.return_to) searchParams.append("return_to", params.return_to);
719
+ const query = searchParams.toString();
720
+ return `${baseURL}/app/account-security${query ? `?${query}` : ""}`;
721
+ }
634
722
  /**
635
723
  * Constructs the OAuth login URL for end-users.
636
724
  * This does not perform the redirect; the consuming application
@@ -671,6 +759,9 @@ var AuthModule = class {
671
759
  if (params.redirect_uri) {
672
760
  searchParams.append("redirect_uri", params.redirect_uri);
673
761
  }
762
+ if (params.state) {
763
+ searchParams.append("state", params.state);
764
+ }
674
765
  if (params.user_code) {
675
766
  searchParams.append("user_code", params.user_code);
676
767
  }
@@ -704,6 +795,9 @@ var AuthModule = class {
704
795
  if (params?.user_code) {
705
796
  searchParams.append("user_code", params.user_code);
706
797
  }
798
+ if (params?.return_to) {
799
+ searchParams.append("return_to", params.return_to);
800
+ }
707
801
  const queryString = searchParams.toString();
708
802
  return `${baseURL}/auth/admin/${provider}${queryString ? `?${queryString}` : ""}`;
709
803
  }
@@ -1639,11 +1733,11 @@ var WebhooksModule = class {
1639
1733
  /**
1640
1734
  * Trigger a test event for a specific webhook (owner/admin only).
1641
1735
  * Generates a "webhook.test.ping" event to verify connectivity.
1642
- *
1736
+ *
1643
1737
  * @param orgSlug Organization slug
1644
1738
  * @param webhookId Webhook ID
1645
1739
  * @returns Result including delivery ID
1646
- *
1740
+ *
1647
1741
  * @example
1648
1742
  * ```typescript
1649
1743
  * const result = await sso.organizations.webhooks.test('acme-corp', 'webhook-123');
@@ -1908,7 +2002,7 @@ var OrganizationsModule = class {
1908
2002
  * page: 1,
1909
2003
  * limit: 20
1910
2004
  * });
1911
- *
2005
+ *
1912
2006
  * // Filter by specific service
1913
2007
  * const serviceUsers = await sso.organizations.endUsers.list('acme-corp', {
1914
2008
  * service_slug: 'my-app',
@@ -2295,7 +2389,7 @@ var OrganizationsModule = class {
2295
2389
  /**
2296
2390
  * Get risk events for an organization.
2297
2391
  * Requires 'owner' or 'admin' role.
2298
- *
2392
+ *
2299
2393
  * @param orgSlug Organization slug
2300
2394
  * @param params Query parameters
2301
2395
  */
@@ -2495,7 +2589,7 @@ var OrganizationsModule = class {
2495
2589
  /**
2496
2590
  * Select/switch to a different organization context.
2497
2591
  * Issues a new JWT token with the organization context.
2498
- *
2592
+ *
2499
2593
  * This allows users to seamlessly switch between organizations
2500
2594
  * they are members of without re-authenticating.
2501
2595
  *
@@ -2506,7 +2600,7 @@ var OrganizationsModule = class {
2506
2600
  * ```typescript
2507
2601
  * // Switch to a different organization
2508
2602
  * const result = await sso.organizations.select('acme-corp');
2509
- *
2603
+ *
2510
2604
  * // The SDK automatically updates the session with new tokens
2511
2605
  * // API calls will now be made in the context of 'acme-corp'
2512
2606
  * ```
@@ -3693,10 +3787,10 @@ var PlatformModule = class {
3693
3787
  },
3694
3788
  /**
3695
3789
  * List all users on the platform with pagination.
3696
- *
3790
+ *
3697
3791
  * @param options Pagination options
3698
3792
  * @returns List of users and total count
3699
- *
3793
+ *
3700
3794
  * @example
3701
3795
  * ```typescript
3702
3796
  * const result = await sso.platform.users.list({ limit: 10, offset: 0 });
@@ -4726,11 +4820,14 @@ var MagicLinks = class {
4726
4820
  * @param redirectUri Optional where to redirect after success
4727
4821
  * @returns URL to redirect to for verification
4728
4822
  */
4729
- getVerificationUrl(token, redirectUri) {
4823
+ getVerificationUrl(token, redirectUri, state) {
4730
4824
  const params = new URLSearchParams({ token });
4731
4825
  if (redirectUri) {
4732
4826
  params.append("redirect_uri", redirectUri);
4733
4827
  }
4828
+ if (state) {
4829
+ params.append("state", state);
4830
+ }
4734
4831
  return `/api/auth/magic-link/verify?${params.toString()}`;
4735
4832
  }
4736
4833
  /**
@@ -4741,11 +4838,14 @@ var MagicLinks = class {
4741
4838
  * @param redirectUri Optional redirect URI
4742
4839
  * @returns Promise resolving to authentication response
4743
4840
  */
4744
- async verify(token, redirectUri) {
4841
+ async verify(token, redirectUri, state) {
4745
4842
  const params = new URLSearchParams({ token });
4746
4843
  if (redirectUri) {
4747
4844
  params.append("redirect_uri", redirectUri);
4748
4845
  }
4846
+ if (state) {
4847
+ params.append("state", state);
4848
+ }
4749
4849
  const response = await this.http.get(`/api/auth/magic-link/verify?${params.toString()}`);
4750
4850
  return response.data;
4751
4851
  }
@@ -4756,8 +4856,8 @@ var MagicLinks = class {
4756
4856
  * @param redirectUri Optional redirect URI
4757
4857
  * @returns Complete magic link URL
4758
4858
  */
4759
- constructMagicLink(token, redirectUri) {
4760
- return this.getVerificationUrl(token, redirectUri);
4859
+ constructMagicLink(token, redirectUri, state) {
4860
+ return this.getVerificationUrl(token, redirectUri, state);
4761
4861
  }
4762
4862
  };
4763
4863
 
@@ -4823,7 +4923,10 @@ var SsoClient = class {
4823
4923
  const res = await this.http.post("/api/auth/refresh", { refresh_token: refreshToken });
4824
4924
  return res.data;
4825
4925
  },
4826
- { storageKeyPrefix: options.storagePrefix || "sso_" }
4926
+ {
4927
+ storageKeyPrefix: options.storagePrefix || "sso_",
4928
+ minValiditySeconds: options.tokenRefreshMinValiditySeconds
4929
+ }
4827
4930
  );
4828
4931
  this.http.setSessionManager(this.session);
4829
4932
  this.analytics = new AnalyticsModule(this.http);
@@ -4986,6 +5089,7 @@ export {
4986
5089
  PlatformModule,
4987
5090
  ServiceApiModule,
4988
5091
  ServicesModule,
5092
+ SessionManager,
4989
5093
  SsoApiError,
4990
5094
  SsoClient,
4991
5095
  UserModule
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drmhse/sso-sdk",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
4
4
  "description": "Zero-dependency TypeScript SDK for AuthOS, the multi-tenant authentication platform",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -24,6 +24,7 @@
24
24
  "scripts": {
25
25
  "build": "tsup src/index.ts --format cjs,esm --dts --clean",
26
26
  "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
27
+ "test": "npm run build && node --test test/*.test.mjs",
27
28
  "typecheck": "tsc --noEmit",
28
29
  "lint": "eslint src --ext .ts",
29
30
  "prepublishOnly": "npm run build"