@authrim/core 0.1.2 → 0.1.4

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.cts CHANGED
@@ -51,6 +51,14 @@ interface HttpClient {
51
51
  */
52
52
  fetch<T = unknown>(url: string, options?: HttpOptions): Promise<HttpResponse<T>>;
53
53
  }
54
+ /**
55
+ * HTTP error response body (OAuth 2.0 / OIDC standard)
56
+ */
57
+ interface OAuthErrorResponse {
58
+ error: string;
59
+ error_description?: string;
60
+ error_uri?: string;
61
+ }
54
62
 
55
63
  /**
56
64
  * Crypto Provider Interface
@@ -386,6 +394,32 @@ interface OIDCDiscoveryDocument {
386
394
  introspection_endpoint_auth_signing_alg_values_supported?: string[];
387
395
  /** Code challenge methods supported (OPTIONAL) */
388
396
  code_challenge_methods_supported?: string[];
397
+ /** Pushed Authorization Request endpoint (OPTIONAL) */
398
+ pushed_authorization_request_endpoint?: string;
399
+ /** Whether PAR is required (OPTIONAL) */
400
+ require_pushed_authorization_requests?: boolean;
401
+ /** Device Authorization endpoint (OPTIONAL) */
402
+ device_authorization_endpoint?: string;
403
+ /** DPoP signing algorithms supported (OPTIONAL) */
404
+ dpop_signing_alg_values_supported?: string[];
405
+ /** Whether signed request object is required (OPTIONAL) */
406
+ require_signed_request_object?: boolean;
407
+ /** Authorization response signing algorithms supported (OPTIONAL) */
408
+ authorization_signing_alg_values_supported?: string[];
409
+ /** Authorization response encryption algorithms supported (OPTIONAL) */
410
+ authorization_encryption_alg_values_supported?: string[];
411
+ /** Authorization response encryption enc values supported (OPTIONAL) */
412
+ authorization_encryption_enc_values_supported?: string[];
413
+ /** Check session iframe URL (OPTIONAL) */
414
+ check_session_iframe?: string;
415
+ /** Whether front-channel logout is supported (OPTIONAL) */
416
+ frontchannel_logout_supported?: boolean;
417
+ /** Whether session ID is required in front-channel logout (OPTIONAL) */
418
+ frontchannel_logout_session_supported?: boolean;
419
+ /** Whether back-channel logout is supported (OPTIONAL) */
420
+ backchannel_logout_supported?: boolean;
421
+ /** Whether session ID is required in back-channel logout (OPTIONAL) */
422
+ backchannel_logout_session_supported?: boolean;
389
423
  /** Flow Engine support indicator (OPTIONAL, Authrim-specific) */
390
424
  flow_engine_supported?: boolean;
391
425
  [key: string]: unknown;
@@ -591,9 +625,16 @@ interface TokenExchangeResult {
591
625
  */
592
626
  type AuthrimErrorUserAction = 'retry' | 'reauthenticate' | 'contact_support' | 'check_network' | 'none';
593
627
  /**
594
- * Error severity level
628
+ * Error severity level (legacy - 3 levels)
595
629
  */
596
630
  type AuthrimErrorSeverity = 'fatal' | 'error' | 'warning';
631
+ /**
632
+ * Error remediation action
633
+ *
634
+ * Specifies what action should be taken to recover from an error.
635
+ * Separated from severity for clearer decision making.
636
+ */
637
+ type AuthrimErrorRemediation = 'retry' | 'reauthenticate' | 'switch_flow' | 'contact_support' | 'none';
597
638
  /**
598
639
  * Error metadata for recovery information
599
640
  */
@@ -614,7 +655,7 @@ interface AuthrimErrorMeta {
614
655
  /**
615
656
  * Error codes used by the SDK
616
657
  */
617
- type AuthrimErrorCode = 'invalid_request' | 'unauthorized_client' | 'access_denied' | 'unsupported_response_type' | 'invalid_scope' | 'server_error' | 'temporarily_unavailable' | 'invalid_grant' | 'invalid_token' | 'invalid_state' | 'expired_state' | 'invalid_nonce' | 'nonce_mismatch' | 'session_expired' | 'session_check_failed' | 'network_error' | 'timeout_error' | 'discovery_error' | 'discovery_mismatch' | 'configuration_error' | 'storage_error' | 'flow_engine_error' | 'no_tokens' | 'token_expired' | 'token_error' | 'refresh_error' | 'token_exchange_error' | 'oauth_error' | 'missing_code' | 'missing_state' | 'not_initialized' | 'no_discovery' | 'no_userinfo_endpoint' | 'userinfo_error' | 'introspection_error' | 'revocation_error' | 'no_introspection_endpoint' | 'no_revocation_endpoint' | 'login_required' | 'interaction_required' | 'consent_required' | 'account_selection_required' | 'dom_not_ready' | 'state_mismatch' | 'popup_blocked' | 'popup_closed' | 'invalid_response';
658
+ type AuthrimErrorCode = 'invalid_request' | 'unauthorized_client' | 'access_denied' | 'unsupported_response_type' | 'invalid_scope' | 'server_error' | 'temporarily_unavailable' | 'invalid_grant' | 'invalid_token' | 'invalid_state' | 'expired_state' | 'invalid_nonce' | 'nonce_mismatch' | 'missing_nonce' | 'missing_id_token' | 'session_expired' | 'session_check_failed' | 'network_error' | 'timeout_error' | 'discovery_error' | 'discovery_mismatch' | 'configuration_error' | 'storage_error' | 'flow_engine_error' | 'no_tokens' | 'token_expired' | 'token_error' | 'refresh_error' | 'token_exchange_error' | 'oauth_error' | 'missing_code' | 'missing_state' | 'not_initialized' | 'no_discovery' | 'no_userinfo_endpoint' | 'userinfo_error' | 'introspection_error' | 'revocation_error' | 'no_introspection_endpoint' | 'no_revocation_endpoint' | 'login_required' | 'interaction_required' | 'consent_required' | 'account_selection_required' | 'dom_not_ready' | 'state_mismatch' | 'popup_blocked' | 'popup_closed' | 'invalid_response' | 'invalid_callback' | 'passkey_not_found' | 'passkey_verification_failed' | 'passkey_not_supported' | 'passkey_cancelled' | 'passkey_invalid_credential' | 'email_code_invalid' | 'email_code_expired' | 'email_code_too_many_attempts' | 'challenge_expired' | 'challenge_invalid' | 'auth_code_invalid' | 'auth_code_expired' | 'pkce_mismatch' | 'origin_not_allowed' | 'mfa_required' | 'email_verification_required' | 'consent_required_direct' | 'rate_limited' | 'event_handler_error' | 'par_required' | 'no_par_endpoint' | 'par_error' | 'par_request_uri_expired' | 'no_device_authorization_endpoint' | 'device_authorization_error' | 'device_authorization_pending' | 'device_slow_down' | 'device_authorization_expired' | 'device_access_denied' | 'client_credentials_error' | 'invalid_client_authentication' | 'insecure_client_auth' | 'dpop_key_generation_error' | 'dpop_proof_generation_error' | 'dpop_nonce_required' | 'jar_signing_error' | 'jar_required' | 'jarm_validation_error' | 'jarm_signature_invalid' | 'operation_cancelled' | 'invalid_return_to';
618
659
  /**
619
660
  * Options for creating an AuthrimError
620
661
  */
@@ -657,81 +698,456 @@ declare class AuthrimError extends Error {
657
698
  * Get error metadata for a given error code
658
699
  */
659
700
  declare function getErrorMeta(code: AuthrimErrorCode): AuthrimErrorMeta;
701
+ /**
702
+ * Error classification result
703
+ */
704
+ interface ErrorClassification {
705
+ /** Severity: recoverable or fatal */
706
+ severity: 'recoverable' | 'fatal';
707
+ /** Recommended remediation action */
708
+ remediation: AuthrimErrorRemediation;
709
+ }
710
+ /**
711
+ * Classify an error by severity and remediation
712
+ *
713
+ * This provides a simplified 2-axis classification for UI decision making:
714
+ * - severity: Is this recoverable or fatal?
715
+ * - remediation: What action should be taken?
716
+ */
717
+ declare function classifyError(error: AuthrimError): ErrorClassification;
718
+ /**
719
+ * Check if an error is retryable based on classification
720
+ */
721
+ declare function isRetryableError(error: AuthrimError): boolean;
722
+ /**
723
+ * Event emitter interface for error emission
724
+ *
725
+ * Minimal interface required by emitClassifiedError
726
+ */
727
+ interface ErrorEventEmitter {
728
+ emit(event: 'error', payload: {
729
+ error: AuthrimError;
730
+ severity: 'recoverable' | 'fatal';
731
+ remediation: AuthrimErrorRemediation;
732
+ context: string;
733
+ timestamp: number;
734
+ source: 'core' | 'web';
735
+ operationId?: string;
736
+ }): void;
737
+ emit(event: 'error:recoverable', payload: {
738
+ error: AuthrimError;
739
+ severity: 'recoverable';
740
+ remediation: AuthrimErrorRemediation;
741
+ context: string;
742
+ timestamp: number;
743
+ source: 'core' | 'web';
744
+ operationId?: string;
745
+ }): void;
746
+ emit(event: 'error:fatal', payload: {
747
+ error: AuthrimError;
748
+ severity: 'fatal';
749
+ remediation: AuthrimErrorRemediation;
750
+ context: string;
751
+ timestamp: number;
752
+ source: 'core' | 'web';
753
+ operationId?: string;
754
+ }): void;
755
+ }
756
+ /**
757
+ * Options for emitting classified errors
758
+ */
759
+ interface EmitClassifiedErrorOptions {
760
+ /** Operation context where the error occurred */
761
+ context: string;
762
+ /** Operation tracking ID */
763
+ operationId?: string;
764
+ /** Event source (defaults to 'core') */
765
+ source?: 'core' | 'web';
766
+ }
767
+ /**
768
+ * Emit error events with proper classification
769
+ *
770
+ * Emits three events:
771
+ * 1. 'error' - Legacy event for backward compatibility
772
+ * 2. 'error:recoverable' - If severity is recoverable
773
+ * 3. 'error:fatal' - If severity is fatal
774
+ *
775
+ * @param emitter - Event emitter instance
776
+ * @param error - The error to emit
777
+ * @param options - Emission options (context, operationId, source)
778
+ */
779
+ declare function emitClassifiedError(emitter: ErrorEventEmitter, error: AuthrimError, options: EmitClassifiedErrorOptions): void;
660
780
 
661
781
  /**
662
782
  * Event Types
783
+ *
784
+ * Unified event system for SDK observability.
785
+ * All events follow the namespace convention: auth:*, token:*, session:*, state:*, error:*, warning:*, debug:*
663
786
  */
664
787
 
665
788
  /**
666
- * Token refresh event data
789
+ * Base event payload - all events include these fields
667
790
  */
668
- interface TokenRefreshedEvent {
669
- tokens: TokenSet;
791
+ interface BaseEventPayload {
792
+ /** Event timestamp (Date.now()) */
793
+ timestamp: number;
794
+ /** Event source */
795
+ source: 'core' | 'web';
796
+ /** Operation tracking ID (maintained from redirect start to callback complete) */
797
+ operationId?: string;
670
798
  }
671
799
  /**
672
- * Token expired event data
800
+ * SDK initialization complete
673
801
  */
674
- interface TokenExpiredEvent {
675
- accessToken: string;
802
+ interface AuthInitEvent extends BaseEventPayload {
803
+ /** Client ID */
804
+ clientId: string;
805
+ /** Issuer URL */
806
+ issuer: string;
807
+ }
808
+ /**
809
+ * Auth redirecting event data
810
+ */
811
+ interface AuthRedirectingEvent extends BaseEventPayload {
812
+ /** Authorization URL */
813
+ url: string;
814
+ }
815
+ /**
816
+ * Auth callback received
817
+ */
818
+ interface AuthCallbackEvent extends BaseEventPayload {
819
+ /** Authorization code */
820
+ code: string;
821
+ /** State parameter */
822
+ state: string;
823
+ }
824
+ /**
825
+ * Callback processing started
826
+ */
827
+ interface AuthCallbackProcessingEvent extends BaseEventPayload {
828
+ /** State parameter being processed */
829
+ state: string;
830
+ }
831
+ /**
832
+ * Callback processing complete
833
+ */
834
+ interface AuthCallbackCompleteEvent extends BaseEventPayload {
835
+ /** Whether authentication was successful */
836
+ success: boolean;
837
+ }
838
+ /**
839
+ * Login complete
840
+ */
841
+ interface AuthLoginCompleteEvent extends BaseEventPayload {
842
+ /** Authentication method used */
843
+ method: 'redirect' | 'popup' | 'silent' | 'passkey' | 'email_code' | 'social';
844
+ /** User info (if available) */
845
+ user?: UserInfo;
846
+ }
847
+ /**
848
+ * Logout complete
849
+ */
850
+ interface AuthLogoutCompleteEvent extends BaseEventPayload {
851
+ /** Logout method */
852
+ method: 'local' | 'redirect' | 'front_channel' | 'back_channel';
853
+ }
854
+ /**
855
+ * Re-authentication required
856
+ */
857
+ interface AuthRequiredEvent extends BaseEventPayload {
858
+ /** Reason for re-authentication */
859
+ reason: 'refresh_failed' | 'session_expired' | 'token_revoked' | 'user_action';
676
860
  }
677
861
  /**
678
- * Token error event data
862
+ * Popup blocked by browser (Web SDK only)
679
863
  */
680
- interface TokenErrorEvent {
864
+ interface AuthPopupBlockedEvent extends BaseEventPayload {
865
+ /** Intended popup URL */
866
+ url?: string;
867
+ }
868
+ /**
869
+ * Flow fallback occurred (e.g., popup → redirect)
870
+ */
871
+ interface AuthFallbackEvent extends BaseEventPayload {
872
+ /** Original flow */
873
+ from: 'popup' | 'silent' | 'iframe';
874
+ /** Fallback flow */
875
+ to: 'redirect';
876
+ /** Reason for fallback */
877
+ reason: 'popup_blocked' | 'iframe_timeout' | 'silent_failed';
878
+ }
879
+ /**
880
+ * Token refresh starting
881
+ */
882
+ interface TokenRefreshingEvent extends BaseEventPayload {
883
+ /** Reason for refresh */
884
+ reason: 'expiring' | 'manual' | 'on_demand' | 'background';
885
+ }
886
+ /**
887
+ * Token refresh succeeded
888
+ */
889
+ interface TokenRefreshedEvent extends BaseEventPayload {
890
+ /** Whether access token is present */
891
+ hasAccessToken: boolean;
892
+ /** Whether refresh token is present */
893
+ hasRefreshToken: boolean;
894
+ /** Whether ID token is present */
895
+ hasIdToken: boolean;
896
+ /** Token expiration timestamp (epoch seconds) */
897
+ expiresAt: number;
898
+ }
899
+ /**
900
+ * Token refresh failed
901
+ */
902
+ interface TokenRefreshFailedEvent extends BaseEventPayload {
903
+ /** Error that caused the failure */
681
904
  error: AuthrimError;
905
+ /** Whether retry is possible */
906
+ willRetry: boolean;
907
+ /** Retry attempt number (0 = first attempt) */
908
+ attempt: number;
682
909
  }
683
910
  /**
684
- * Token exchanged event data (RFC 8693)
911
+ * Token expiring soon (warning)
685
912
  */
686
- interface TokenExchangedEvent {
687
- tokens: TokenSet;
688
- issuedTokenType: string;
913
+ interface TokenExpiringEvent extends BaseEventPayload {
914
+ /** Token expiration timestamp (epoch seconds) */
915
+ expiresAt: number;
916
+ /** Remaining time in seconds */
917
+ expiresIn: number;
918
+ }
919
+ /**
920
+ * Token expired
921
+ */
922
+ interface TokenExpiredEvent extends BaseEventPayload {
923
+ /** Token expiration timestamp (epoch seconds) */
924
+ expiredAt: number;
925
+ /** Whether refresh token is available */
926
+ hasRefreshToken: boolean;
927
+ }
928
+ /**
929
+ * Token error
930
+ */
931
+ interface TokenErrorEvent extends BaseEventPayload {
932
+ /** Error details */
933
+ error: AuthrimError;
934
+ /** Operation context */
935
+ context: 'refresh' | 'exchange' | 'validation' | 'storage';
936
+ }
937
+ /**
938
+ * Token exchanged (RFC 8693)
939
+ */
940
+ interface TokenExchangedEvent extends BaseEventPayload {
941
+ /** Whether new access token is present */
942
+ hasAccessToken: boolean;
943
+ /** Whether new refresh token is present */
944
+ hasRefreshToken: boolean;
945
+ /** Issued token type URI */
946
+ issuedTokenType: TokenTypeUri | string;
689
947
  }
690
948
  /**
691
- * Session started event data
949
+ * Session started
692
950
  */
693
- interface SessionStartedEvent {
951
+ interface SessionStartedEvent extends BaseEventPayload {
952
+ /** User info */
694
953
  user: UserInfo;
695
954
  }
696
955
  /**
697
- * Session ended event data
956
+ * Session ended
698
957
  */
699
- interface SessionEndedEvent {
958
+ interface SessionEndedEvent extends BaseEventPayload {
959
+ /** Reason for session end */
700
960
  reason: 'logout' | 'expired' | 'revoked';
701
961
  }
702
962
  /**
703
- * Auth redirecting event data
963
+ * Session changed (general)
704
964
  */
705
- interface AuthRedirectingEvent {
706
- url: string;
965
+ interface SessionChangedEvent extends BaseEventPayload {
966
+ /** Whether user is authenticated */
967
+ isAuthenticated: boolean;
968
+ /** User info (if authenticated) */
969
+ user?: UserInfo;
707
970
  }
708
971
  /**
709
- * Auth callback event data
972
+ * Tab synchronization event (Web SDK only)
710
973
  */
711
- interface AuthCallbackEvent {
712
- code: string;
713
- state: string;
974
+ interface SessionSyncEvent extends BaseEventPayload {
975
+ /** Sync action */
976
+ action: 'login' | 'logout' | 'refresh' | 'leader_change';
977
+ /** Source tab ID */
978
+ sourceTabId?: string;
714
979
  }
715
980
  /**
716
- * Error event data
981
+ * Logout broadcast from another tab (Web SDK only)
982
+ */
983
+ interface SessionLogoutBroadcastEvent extends BaseEventPayload {
984
+ /** Source tab ID */
985
+ sourceTabId?: string;
986
+ }
987
+ /**
988
+ * Auth state type
989
+ */
990
+ type AuthState$1 = 'idle' | 'initializing' | 'authenticated' | 'unauthenticated' | 'authenticating' | 'refreshing' | 'logging_out' | 'error';
991
+ /**
992
+ * Auth state snapshot
993
+ */
994
+ interface AuthStateSnapshot {
995
+ /** Current state */
996
+ state: AuthState$1;
997
+ /** Previous state */
998
+ previousState: AuthState$1 | null;
999
+ /** Snapshot timestamp */
1000
+ timestamp: number;
1001
+ /** Current operation ID */
1002
+ operationId: string | null;
1003
+ /** State context */
1004
+ context: {
1005
+ /** Whether user is authenticated */
1006
+ isAuthenticated: boolean;
1007
+ /** Token expiration timestamp (epoch seconds) */
1008
+ tokenExpiresAt: number | null;
1009
+ /** Last error */
1010
+ lastError: AuthrimError | null;
1011
+ /** Pending operation description */
1012
+ pendingOperation: string | null;
1013
+ };
1014
+ }
1015
+ /**
1016
+ * State change event
1017
+ */
1018
+ interface StateChangeEvent extends BaseEventPayload {
1019
+ /** Previous state */
1020
+ from: AuthState$1;
1021
+ /** New state */
1022
+ to: AuthState$1;
1023
+ /** Full state snapshot */
1024
+ snapshot: AuthStateSnapshot;
1025
+ }
1026
+ /**
1027
+ * Error severity for event classification
1028
+ */
1029
+ type ErrorSeverity = 'recoverable' | 'fatal';
1030
+ /**
1031
+ * Error event payload (extended)
1032
+ */
1033
+ interface ErrorEventPayload extends BaseEventPayload {
1034
+ /** Error instance */
1035
+ error: AuthrimError;
1036
+ /** Error severity */
1037
+ severity: ErrorSeverity;
1038
+ /** Recommended remediation */
1039
+ remediation: AuthrimErrorRemediation;
1040
+ /** Operation context where error occurred */
1041
+ context: string;
1042
+ }
1043
+ /**
1044
+ * Legacy error event (backward compatibility)
717
1045
  */
718
1046
  interface ErrorEvent {
719
1047
  error: AuthrimError;
720
1048
  context: string;
721
1049
  }
1050
+ /**
1051
+ * Recoverable error event
1052
+ */
1053
+ interface ErrorRecoverableEvent extends ErrorEventPayload {
1054
+ severity: 'recoverable';
1055
+ }
1056
+ /**
1057
+ * Fatal error event
1058
+ */
1059
+ interface ErrorFatalEvent extends ErrorEventPayload {
1060
+ severity: 'fatal';
1061
+ }
1062
+ /**
1063
+ * ITP environment detected warning (Web SDK only)
1064
+ */
1065
+ interface WarningITPEvent extends BaseEventPayload {
1066
+ /** Warning message */
1067
+ message: string;
1068
+ /** Detected browser */
1069
+ browser: 'safari' | 'webkit' | 'unknown';
1070
+ /** Recommended action */
1071
+ recommendation: 'use_redirect' | 'use_popup' | 'normal';
1072
+ }
1073
+ /**
1074
+ * Storage fallback warning
1075
+ *
1076
+ * Fired when:
1077
+ * - localStorage → sessionStorage fallback
1078
+ * - sessionStorage → memory fallback
1079
+ */
1080
+ interface WarningStorageFallbackEvent extends BaseEventPayload {
1081
+ /** Original storage type */
1082
+ from: 'localStorage' | 'sessionStorage';
1083
+ /** Fallback storage type */
1084
+ to: 'sessionStorage' | 'memory';
1085
+ /** Reason for fallback */
1086
+ reason: 'not_available' | 'quota_exceeded' | 'private_mode' | 'security_error';
1087
+ }
1088
+ /**
1089
+ * Private browsing mode detected warning (Web SDK only)
1090
+ */
1091
+ interface WarningPrivateModeEvent extends BaseEventPayload {
1092
+ /** Detected browser */
1093
+ browser: 'safari' | 'firefox' | 'chrome' | 'edge' | 'unknown';
1094
+ /** Storage limitations */
1095
+ limitations: string[];
1096
+ }
1097
+ /**
1098
+ * Timeline event entry
1099
+ */
1100
+ interface TimelineEntry {
1101
+ /** Event type */
1102
+ type: string;
1103
+ /** Event timestamp */
1104
+ timestamp: number;
1105
+ /** Operation ID */
1106
+ operationId?: string;
1107
+ /** Redacted event data */
1108
+ data?: Record<string, unknown>;
1109
+ }
1110
+ /**
1111
+ * Debug timeline event
1112
+ */
1113
+ interface DebugTimelineEvent extends BaseEventPayload {
1114
+ /** Timeline entry */
1115
+ entry: TimelineEntry;
1116
+ }
722
1117
  /**
723
1118
  * All Authrim events
724
1119
  */
725
1120
  interface AuthrimEvents {
1121
+ 'auth:init': AuthInitEvent;
1122
+ 'auth:redirecting': AuthRedirectingEvent;
1123
+ 'auth:callback': AuthCallbackEvent;
1124
+ 'auth:callback:processing': AuthCallbackProcessingEvent;
1125
+ 'auth:callback:complete': AuthCallbackCompleteEvent;
1126
+ 'auth:login:complete': AuthLoginCompleteEvent;
1127
+ 'auth:logout:complete': AuthLogoutCompleteEvent;
1128
+ 'auth:required': AuthRequiredEvent;
1129
+ 'auth:popup_blocked': AuthPopupBlockedEvent;
1130
+ 'auth:fallback': AuthFallbackEvent;
1131
+ 'token:refreshing': TokenRefreshingEvent;
726
1132
  'token:refreshed': TokenRefreshedEvent;
1133
+ 'token:refresh:failed': TokenRefreshFailedEvent;
1134
+ 'token:expiring': TokenExpiringEvent;
727
1135
  'token:expired': TokenExpiredEvent;
728
1136
  'token:error': TokenErrorEvent;
729
1137
  'token:exchanged': TokenExchangedEvent;
730
1138
  'session:started': SessionStartedEvent;
731
1139
  'session:ended': SessionEndedEvent;
732
- 'auth:redirecting': AuthRedirectingEvent;
733
- 'auth:callback': AuthCallbackEvent;
734
- error: ErrorEvent;
1140
+ 'session:changed': SessionChangedEvent;
1141
+ 'session:sync': SessionSyncEvent;
1142
+ 'session:logout:broadcast': SessionLogoutBroadcastEvent;
1143
+ 'state:change': StateChangeEvent;
1144
+ 'error': ErrorEvent;
1145
+ 'error:recoverable': ErrorRecoverableEvent;
1146
+ 'error:fatal': ErrorFatalEvent;
1147
+ 'warning:itp': WarningITPEvent;
1148
+ 'warning:storage_fallback': WarningStorageFallbackEvent;
1149
+ 'warning:private_mode': WarningPrivateModeEvent;
1150
+ 'debug:timeline': DebugTimelineEvent;
735
1151
  }
736
1152
  /**
737
1153
  * Event names
@@ -741,129 +1157,429 @@ type AuthrimEventName = keyof AuthrimEvents;
741
1157
  * Event handler type
742
1158
  */
743
1159
  type AuthrimEventHandler<T extends AuthrimEventName> = (event: AuthrimEvents[T]) => void;
744
-
745
1160
  /**
746
- * State/Nonce Manager
747
- *
748
- * Manages CSRF protection (state) and replay attack prevention (nonce)
749
- * for Authorization Code Flow.
1161
+ * Events emitted by Core SDK
1162
+ */
1163
+ type CoreEventName = 'auth:init' | 'auth:redirecting' | 'auth:callback' | 'auth:callback:processing' | 'auth:callback:complete' | 'auth:login:complete' | 'auth:logout:complete' | 'auth:required' | 'token:refreshing' | 'token:refreshed' | 'token:refresh:failed' | 'token:expiring' | 'token:expired' | 'token:error' | 'token:exchanged' | 'session:started' | 'session:ended' | 'session:changed' | 'state:change' | 'error' | 'error:recoverable' | 'error:fatal' | 'debug:timeline';
1164
+ /**
1165
+ * Events emitted by Web SDK only
750
1166
  */
1167
+ type WebOnlyEventName = 'auth:popup_blocked' | 'auth:fallback' | 'session:sync' | 'session:logout:broadcast' | 'warning:itp' | 'warning:storage_fallback' | 'warning:private_mode';
751
1168
 
752
1169
  /**
753
- * Auth state stored in storage
1170
+ * Device Authorization Flow Types
1171
+ * RFC 8628: OAuth 2.0 Device Authorization Grant
1172
+ *
1173
+ * Used for devices with limited input capabilities (TVs, CLI tools, IoT devices).
754
1174
  */
755
- interface AuthState {
756
- /** State parameter (CSRF protection) */
757
- state: string;
758
- /** Nonce parameter (replay attack prevention) */
759
- nonce: string;
760
- /** PKCE code verifier */
761
- codeVerifier: string;
762
- /** Redirect URI used for this auth request */
763
- redirectUri: string;
764
- /** Timestamp when state was created */
765
- createdAt: number;
766
- /** Timestamp when state expires */
767
- expiresAt: number;
768
- }
769
1175
  /**
770
- * Options for generating auth state
1176
+ * Device authorization response from the server (RFC 8628 §3.2)
771
1177
  */
772
- interface GenerateAuthStateOptions {
773
- /** Redirect URI for this auth request */
774
- redirectUri: string;
775
- /** Code verifier for PKCE */
776
- codeVerifier: string;
777
- /** TTL in seconds (default: 600 = 10 minutes) */
778
- ttlSeconds?: number;
1178
+ interface DeviceAuthorizationResponse {
1179
+ /** Device verification code (for token requests) */
1180
+ device_code: string;
1181
+ /** User-facing code to enter at verification_uri */
1182
+ user_code: string;
1183
+ /** URI where the user should go to enter the code */
1184
+ verification_uri: string;
1185
+ /** Complete URI with user_code embedded (optional) */
1186
+ verification_uri_complete?: string;
1187
+ /** Lifetime of device_code and user_code in seconds */
1188
+ expires_in: number;
1189
+ /** Minimum polling interval in seconds (default: 5) */
1190
+ interval?: number;
779
1191
  }
780
1192
  /**
781
- * Storage keys factory
1193
+ * Device flow state maintained by the client
782
1194
  */
783
- declare const STORAGE_KEYS: {
784
- /**
785
- * Auth state key (state-specific)
786
- */
787
- readonly authState: (issuerHash: string, clientIdHash: string, state: string) => string;
788
- /**
789
- * Token storage key
790
- */
791
- readonly tokens: (issuerHash: string, clientIdHash: string) => string;
792
- /**
793
- * ID token storage key
794
- */
795
- readonly idToken: (issuerHash: string, clientIdHash: string) => string;
1195
+ interface DeviceFlowState {
1196
+ /** Device code (used for polling) */
1197
+ deviceCode: string;
1198
+ /** User code (displayed to user) */
1199
+ userCode: string;
1200
+ /** Verification URI (user goes here) */
1201
+ verificationUri: string;
1202
+ /** Complete verification URI with code (if provided) */
1203
+ verificationUriComplete?: string;
1204
+ /** Absolute expiration time (epoch seconds) */
1205
+ expiresAt: number;
796
1206
  /**
797
- * Auth state prefix for cleanup
1207
+ * Polling interval in seconds (RFC 8628)
1208
+ *
1209
+ * IMPORTANT: This value is in SECONDS, not milliseconds.
1210
+ * When using with setTimeout, multiply by 1000.
798
1211
  */
799
- readonly authStatePrefix: (issuerHash: string, clientIdHash: string) => string;
800
- };
1212
+ interval: number;
1213
+ }
801
1214
  /**
802
- * State Manager
1215
+ * Poll result from Device Flow
1216
+ *
1217
+ * Core SDK returns "facts" only - UX events are the responsibility
1218
+ * of upper-layer SDKs (web/react/svelte).
803
1219
  */
804
- declare class StateManager {
805
- private readonly crypto;
806
- private readonly storage;
807
- private readonly issuerHash;
808
- private readonly clientIdHash;
809
- /** Default TTL: 10 minutes */
810
- private static readonly DEFAULT_TTL_SECONDS;
811
- constructor(crypto: CryptoProvider, storage: AuthrimStorage, issuerHash: string, clientIdHash: string);
812
- /**
813
- * Generate and store auth state
814
- *
815
- * Creates state, nonce, stores them with the code verifier.
816
- *
817
- * @param options - Generation options
818
- * @returns Generated state string
819
- */
820
- generateAuthState(options: GenerateAuthStateOptions): Promise<AuthState>;
1220
+ type DeviceFlowPollResult = DeviceFlowPendingResult | DeviceFlowCompletedResult | DeviceFlowSlowDownResult | DeviceFlowExpiredResult | DeviceFlowAccessDeniedResult;
1221
+ /**
1222
+ * Authorization pending - user hasn't completed auth yet
1223
+ */
1224
+ interface DeviceFlowPendingResult {
1225
+ status: 'pending';
821
1226
  /**
822
- * Validate and consume state
823
- *
824
- * Retrieves, validates, and ALWAYS deletes the state (success or failure).
825
- * This ensures replay attack prevention and GC.
1227
+ * Seconds until next poll attempt (RFC 8628)
826
1228
  *
827
- * @param state - State parameter from callback
828
- * @returns Auth state if valid
829
- * @throws AuthrimError if state is invalid or expired
1229
+ * IMPORTANT: This value is in SECONDS.
1230
+ * Use `retryAfter * 1000` for setTimeout in JavaScript.
830
1231
  */
831
- validateAndConsumeState(state: string): Promise<AuthState>;
1232
+ retryAfter: number;
1233
+ }
1234
+ /**
1235
+ * Authorization completed - tokens received
1236
+ */
1237
+ interface DeviceFlowCompletedResult {
1238
+ status: 'completed';
1239
+ /** Received tokens */
1240
+ tokens: TokenSet;
1241
+ }
1242
+ /**
1243
+ * Slow down - polling too fast
1244
+ */
1245
+ interface DeviceFlowSlowDownResult {
1246
+ status: 'slow_down';
832
1247
  /**
833
- * Clean up expired states
834
- *
835
- * This is a best-effort cleanup. Only works if storage.getAll() is available.
836
- * The primary GC mechanism is validateAndConsumeState()'s finally delete.
1248
+ * New interval in seconds (server-specified)
837
1249
  *
838
- * Safe to call at startup or periodically.
1250
+ * IMPORTANT: This value is in SECONDS.
1251
+ * The polling interval should be increased to this value.
839
1252
  */
840
- cleanupExpiredStates(): Promise<void>;
1253
+ retryAfter: number;
841
1254
  }
842
-
843
1255
  /**
844
- * PKCE (Proof Key for Code Exchange) Helper
845
- *
846
- * Implements RFC 7636 for Authorization Code Flow security.
847
- * https://tools.ietf.org/html/rfc7636
1256
+ * Device code expired - user needs to start over
848
1257
  */
849
-
1258
+ interface DeviceFlowExpiredResult {
1259
+ status: 'expired';
1260
+ }
850
1261
  /**
851
- * PKCE challenge method
1262
+ * Access denied - user denied the authorization request
852
1263
  */
853
- type CodeChallengeMethod = 'S256' | 'plain';
1264
+ interface DeviceFlowAccessDeniedResult {
1265
+ status: 'access_denied';
1266
+ }
854
1267
  /**
855
- * PKCE pair (verifier and challenge)
1268
+ * Options for starting device authorization
856
1269
  */
857
- interface PKCEPair {
858
- /** Code verifier (high-entropy random string) */
859
- codeVerifier: string;
860
- /** Code challenge (derived from verifier) */
861
- codeChallenge: string;
862
- /** Challenge method used */
863
- codeChallengeMethod: CodeChallengeMethod;
1270
+ interface DeviceFlowStartOptions {
1271
+ /** Scopes to request */
1272
+ scope?: string;
1273
+ /** Additional parameters */
1274
+ extraParams?: Record<string, string>;
864
1275
  }
1276
+
865
1277
  /**
866
- * PKCE Helper class
1278
+ * PAR (Pushed Authorization Request) Types
1279
+ * RFC 9126: OAuth 2.0 Pushed Authorization Requests
1280
+ */
1281
+ /**
1282
+ * PAR request parameters
1283
+ */
1284
+ interface PARRequest {
1285
+ /** Redirect URI (required) */
1286
+ redirectUri: string;
1287
+ /** Scopes to request (default: 'openid profile') */
1288
+ scope?: string;
1289
+ /**
1290
+ * Response type (default: 'code')
1291
+ *
1292
+ * Use 'none' for session check without token issuance
1293
+ * (OAuth 2.0 Multiple Response Types 1.0 §5)
1294
+ */
1295
+ responseType?: 'code' | 'none';
1296
+ /** State parameter for CSRF protection */
1297
+ state: string;
1298
+ /** Nonce for replay attack prevention */
1299
+ nonce: string;
1300
+ /** PKCE code challenge */
1301
+ codeChallenge: string;
1302
+ /** PKCE code challenge method (always S256) */
1303
+ codeChallengeMethod: 'S256';
1304
+ /** Prompt behavior */
1305
+ prompt?: 'none' | 'login' | 'consent' | 'select_account';
1306
+ /** Hint about the login identifier */
1307
+ loginHint?: string;
1308
+ /** Requested Authentication Context Class Reference values */
1309
+ acrValues?: string;
1310
+ /** Additional custom parameters */
1311
+ extraParams?: Record<string, string>;
1312
+ }
1313
+ /**
1314
+ * PAR response from the server (RFC 9126 §2.2)
1315
+ */
1316
+ interface PARResponse {
1317
+ /** The request URI to use in authorization request */
1318
+ request_uri: string;
1319
+ /** Lifetime of the request URI in seconds */
1320
+ expires_in: number;
1321
+ }
1322
+ /**
1323
+ * PAR result returned by PARClient
1324
+ */
1325
+ interface PARResult {
1326
+ /** The request URI to use in authorization request */
1327
+ requestUri: string;
1328
+ /** Absolute expiration time (epoch seconds) */
1329
+ expiresAt: number;
1330
+ }
1331
+ /**
1332
+ * Options for PAR client
1333
+ */
1334
+ interface PARClientOptions {
1335
+ /** Additional headers to include in PAR request */
1336
+ headers?: Record<string, string>;
1337
+ }
1338
+
1339
+ /**
1340
+ * Event Emitter
1341
+ *
1342
+ * Simple typed event emitter for SDK events.
1343
+ */
1344
+
1345
+ /**
1346
+ * Typed Event Emitter
1347
+ */
1348
+ declare class EventEmitter {
1349
+ private listeners;
1350
+ /**
1351
+ * Subscribe to an event
1352
+ *
1353
+ * @param event - Event name
1354
+ * @param handler - Event handler
1355
+ * @returns Unsubscribe function
1356
+ */
1357
+ on<T extends AuthrimEventName>(event: T, handler: AuthrimEventHandler<T>): () => void;
1358
+ /**
1359
+ * Subscribe to an event (one-time)
1360
+ *
1361
+ * @param event - Event name
1362
+ * @param handler - Event handler
1363
+ * @returns Unsubscribe function
1364
+ */
1365
+ once<T extends AuthrimEventName>(event: T, handler: AuthrimEventHandler<T>): () => void;
1366
+ /**
1367
+ * Unsubscribe from an event
1368
+ *
1369
+ * @param event - Event name
1370
+ * @param handler - Event handler to remove
1371
+ */
1372
+ off<T extends AuthrimEventName>(event: T, handler: AuthrimEventHandler<T>): void;
1373
+ /**
1374
+ * Emit an event
1375
+ *
1376
+ * @param event - Event name
1377
+ * @param data - Event data
1378
+ */
1379
+ emit<T extends AuthrimEventName>(event: T, data: AuthrimEvents[T]): void;
1380
+ /**
1381
+ * Remove all listeners for an event (or all events)
1382
+ *
1383
+ * @param event - Event name (optional, removes all if not specified)
1384
+ */
1385
+ removeAllListeners(event?: AuthrimEventName): void;
1386
+ /**
1387
+ * Get the number of listeners for an event
1388
+ *
1389
+ * @param event - Event name
1390
+ * @returns Number of listeners
1391
+ */
1392
+ listenerCount(event: AuthrimEventName): number;
1393
+ }
1394
+
1395
+ /**
1396
+ * State/Nonce Manager
1397
+ *
1398
+ * Manages CSRF protection (state) and replay attack prevention (nonce)
1399
+ * for Authorization Code Flow.
1400
+ */
1401
+
1402
+ /**
1403
+ * Auth state stored in storage
1404
+ */
1405
+ interface AuthState {
1406
+ /** State parameter (CSRF protection) */
1407
+ state: string;
1408
+ /** Nonce parameter (replay attack prevention) */
1409
+ nonce: string;
1410
+ /** PKCE code verifier */
1411
+ codeVerifier: string;
1412
+ /** Redirect URI used for this auth request */
1413
+ redirectUri: string;
1414
+ /** Requested scope (for validation) */
1415
+ scope: string;
1416
+ /** Timestamp when state was created */
1417
+ createdAt: number;
1418
+ /** Timestamp when state expires */
1419
+ expiresAt: number;
1420
+ /** Return URL after authentication (validated) */
1421
+ returnTo?: string;
1422
+ /** Operation tracking ID (for event correlation) */
1423
+ operationId: string;
1424
+ }
1425
+ /**
1426
+ * ReturnTo URL policy
1427
+ *
1428
+ * Controls which returnTo URLs are accepted to prevent open redirect attacks.
1429
+ */
1430
+ type ReturnToPolicy = 'relative_only' | 'same_origin' | 'allowlist';
1431
+ /**
1432
+ * ReturnTo URL options
1433
+ */
1434
+ interface ReturnToOptions {
1435
+ /** Validation policy */
1436
+ policy: ReturnToPolicy;
1437
+ /** Allowed origins (required when policy is 'allowlist') */
1438
+ allowedOrigins?: string[];
1439
+ /** Current origin for same_origin check (required in non-browser environments) */
1440
+ currentOrigin?: string;
1441
+ }
1442
+ /**
1443
+ * Options for generating auth state
1444
+ */
1445
+ interface GenerateAuthStateOptions {
1446
+ /** Redirect URI for this auth request */
1447
+ redirectUri: string;
1448
+ /** Code verifier for PKCE */
1449
+ codeVerifier: string;
1450
+ /** Requested scope (for validation) */
1451
+ scope: string;
1452
+ /** TTL in seconds (default: 600 = 10 minutes) */
1453
+ ttlSeconds?: number;
1454
+ /** Return URL after authentication */
1455
+ returnTo?: string;
1456
+ /** ReturnTo URL validation options */
1457
+ returnToOptions?: ReturnToOptions;
1458
+ }
1459
+ /**
1460
+ * Storage keys factory
1461
+ */
1462
+ declare const STORAGE_KEYS: {
1463
+ /**
1464
+ * Auth state key (state-specific)
1465
+ */
1466
+ readonly authState: (issuerHash: string, clientIdHash: string, state: string) => string;
1467
+ /**
1468
+ * Token storage key
1469
+ */
1470
+ readonly tokens: (issuerHash: string, clientIdHash: string) => string;
1471
+ /**
1472
+ * ID token storage key
1473
+ */
1474
+ readonly idToken: (issuerHash: string, clientIdHash: string) => string;
1475
+ /**
1476
+ * Auth state prefix for cleanup
1477
+ */
1478
+ readonly authStatePrefix: (issuerHash: string, clientIdHash: string) => string;
1479
+ };
1480
+ /**
1481
+ * State Manager
1482
+ */
1483
+ declare class StateManager {
1484
+ private readonly crypto;
1485
+ private readonly storage;
1486
+ private readonly issuerHash;
1487
+ private readonly clientIdHash;
1488
+ /** Default TTL: 10 minutes */
1489
+ private static readonly DEFAULT_TTL_SECONDS;
1490
+ /** Entropy bytes for state/nonce generation (256 bits = 32 bytes) */
1491
+ private static readonly ENTROPY_BYTES;
1492
+ /** Entropy bytes for operationId (128 bits = 16 bytes, enough for tracking) */
1493
+ private static readonly OPERATION_ID_BYTES;
1494
+ /** Auto cleanup interval (5 minutes) */
1495
+ private static readonly DEFAULT_CLEANUP_INTERVAL_MS;
1496
+ /** Cleanup interval handle */
1497
+ private cleanupInterval;
1498
+ constructor(crypto: CryptoProvider, storage: AuthrimStorage, issuerHash: string, clientIdHash: string);
1499
+ /**
1500
+ * Generate and store auth state
1501
+ *
1502
+ * Creates state, nonce, stores them with the code verifier.
1503
+ *
1504
+ * @param options - Generation options
1505
+ * @returns Generated state string
1506
+ */
1507
+ generateAuthState(options: GenerateAuthStateOptions): Promise<AuthState>;
1508
+ /**
1509
+ * Validate returnTo URL against policy (Open Redirect Protection)
1510
+ *
1511
+ * @param returnTo - URL to validate
1512
+ * @param options - Validation options
1513
+ * @returns Validated URL
1514
+ * @throws AuthrimError if URL is invalid
1515
+ */
1516
+ private validateReturnTo;
1517
+ /**
1518
+ * Validate and consume state
1519
+ *
1520
+ * Retrieves, validates, and ALWAYS deletes the state (success or failure).
1521
+ * This ensures replay attack prevention and GC.
1522
+ *
1523
+ * @param state - State parameter from callback
1524
+ * @returns Auth state if valid
1525
+ * @throws AuthrimError if state is invalid or expired
1526
+ */
1527
+ validateAndConsumeState(state: string): Promise<AuthState>;
1528
+ /**
1529
+ * Clean up expired states
1530
+ *
1531
+ * This is a best-effort cleanup. Only works if storage.getAll() is available.
1532
+ * The primary GC mechanism is validateAndConsumeState()'s finally delete.
1533
+ *
1534
+ * Safe to call at startup or periodically.
1535
+ */
1536
+ cleanupExpiredStates(): Promise<void>;
1537
+ /**
1538
+ * Start automatic cleanup of expired states
1539
+ *
1540
+ * Runs cleanup every 5 minutes by default.
1541
+ *
1542
+ * @param intervalMs - Cleanup interval in milliseconds (default: 300000 = 5 minutes)
1543
+ */
1544
+ startAutoCleanup(intervalMs?: number): void;
1545
+ /**
1546
+ * Stop automatic cleanup
1547
+ */
1548
+ stopAutoCleanup(): void;
1549
+ /**
1550
+ * Get the number of stored auth states
1551
+ *
1552
+ * Only works if storage.getAll() is available.
1553
+ *
1554
+ * @returns Number of stored states, or -1 if not supported
1555
+ */
1556
+ getStoredStateCount(): Promise<number>;
1557
+ }
1558
+
1559
+ /**
1560
+ * PKCE (Proof Key for Code Exchange) Helper
1561
+ *
1562
+ * Implements RFC 7636 for Authorization Code Flow security.
1563
+ * https://tools.ietf.org/html/rfc7636
1564
+ */
1565
+
1566
+ /**
1567
+ * PKCE challenge method
1568
+ */
1569
+ type CodeChallengeMethod = 'S256' | 'plain';
1570
+ /**
1571
+ * PKCE pair (verifier and challenge)
1572
+ */
1573
+ interface PKCEPair {
1574
+ /** Code verifier (high-entropy random string) */
1575
+ codeVerifier: string;
1576
+ /** Code challenge (derived from verifier) */
1577
+ codeChallenge: string;
1578
+ /** Challenge method used */
1579
+ codeChallengeMethod: CodeChallengeMethod;
1580
+ }
1581
+ /**
1582
+ * PKCE Helper class
867
1583
  */
868
1584
  declare class PKCEHelper {
869
1585
  private readonly crypto;
@@ -906,6 +1622,13 @@ interface BuildAuthorizationUrlOptions {
906
1622
  redirectUri: string;
907
1623
  /** Scopes to request (default: 'openid profile') */
908
1624
  scope?: string;
1625
+ /**
1626
+ * Response type (default: 'code')
1627
+ *
1628
+ * Use 'none' for session check without token issuance
1629
+ * (OAuth 2.0 Multiple Response Types 1.0 §5)
1630
+ */
1631
+ responseType?: 'code' | 'none';
909
1632
  /** Prompt behavior */
910
1633
  prompt?: 'none' | 'login' | 'consent' | 'select_account';
911
1634
  /** Hint about the login identifier */
@@ -922,6 +1645,23 @@ interface BuildAuthorizationUrlOptions {
922
1645
  * (e.g., cookie, server-side session)
923
1646
  */
924
1647
  exposeState?: boolean;
1648
+ /**
1649
+ * Use PAR (Pushed Authorization Request - RFC 9126)
1650
+ *
1651
+ * When true, authorization parameters are first pushed to the PAR endpoint,
1652
+ * and the resulting request_uri is used in the authorization URL.
1653
+ *
1654
+ * Required when server sets require_pushed_authorization_requests=true.
1655
+ */
1656
+ usePar?: boolean;
1657
+ /**
1658
+ * Use JAR (JWT Secured Authorization Request - RFC 9101)
1659
+ *
1660
+ * When true, authorization parameters are encoded in a signed JWT.
1661
+ *
1662
+ * Required when server sets require_signed_request_object=true.
1663
+ */
1664
+ useJar?: boolean;
925
1665
  }
926
1666
  /**
927
1667
  * Result of buildAuthorizationUrl
@@ -957,6 +1697,8 @@ interface ExchangeCodeOptions {
957
1697
  codeVerifier: string;
958
1698
  /** Nonce to validate in ID token */
959
1699
  nonce: string;
1700
+ /** Requested scope (for validation) */
1701
+ scope: string;
960
1702
  }
961
1703
  /**
962
1704
  * Authorization Code Flow helper
@@ -973,6 +1715,7 @@ declare class AuthorizationCodeFlow {
973
1715
  * @param pkce - PKCE pair
974
1716
  * @param options - Authorization options
975
1717
  * @returns Authorization URL result
1718
+ * @throws AuthrimError with code 'par_required' if server requires PAR but usePar is not enabled
976
1719
  */
977
1720
  buildAuthorizationUrl(discovery: OIDCDiscoveryDocument, authState: AuthState, pkce: PKCEPair, options: BuildAuthorizationUrlOptions): AuthorizationUrlResult;
978
1721
  /**
@@ -980,7 +1723,9 @@ declare class AuthorizationCodeFlow {
980
1723
  *
981
1724
  * @param callbackUrl - Callback URL or query string
982
1725
  * @returns Parsed code and state
983
- * @throws AuthrimError if code or state is missing, or if error is present
1726
+ * @throws AuthrimError with code 'oauth_error' if OAuth error response is present
1727
+ * @throws AuthrimError with code 'missing_code' if authorization code is not found
1728
+ * @throws AuthrimError with code 'missing_state' if state parameter is not found
984
1729
  */
985
1730
  parseCallback(callbackUrl: string): {
986
1731
  code: string;
@@ -992,7 +1737,9 @@ declare class AuthorizationCodeFlow {
992
1737
  * @param discovery - OIDC discovery document
993
1738
  * @param options - Exchange options
994
1739
  * @returns Token set
995
- * @throws AuthrimError if exchange fails or nonce validation fails
1740
+ * @throws AuthrimError with code 'network_error' if token request fails
1741
+ * @throws AuthrimError with code 'token_error' if token exchange fails
1742
+ * @throws AuthrimError with code 'nonce_mismatch' if ID token nonce validation fails
996
1743
  */
997
1744
  exchangeCode(discovery: OIDCDiscoveryDocument, options: ExchangeCodeOptions): Promise<TokenSet>;
998
1745
  }
@@ -1166,70 +1913,14 @@ declare class TokenRevoker {
1166
1913
  }
1167
1914
 
1168
1915
  /**
1169
- * Event Emitter
1916
+ * Logout Handler
1170
1917
  *
1171
- * Simple typed event emitter for SDK events.
1918
+ * Implements RP-Initiated Logout (OpenID Connect RP-Initiated Logout 1.0)
1919
+ * https://openid.net/specs/openid-connect-rpinitiated-1_0.html
1172
1920
  */
1173
1921
 
1174
1922
  /**
1175
- * Typed Event Emitter
1176
- */
1177
- declare class EventEmitter {
1178
- private listeners;
1179
- /**
1180
- * Subscribe to an event
1181
- *
1182
- * @param event - Event name
1183
- * @param handler - Event handler
1184
- * @returns Unsubscribe function
1185
- */
1186
- on<T extends AuthrimEventName>(event: T, handler: AuthrimEventHandler<T>): () => void;
1187
- /**
1188
- * Subscribe to an event (one-time)
1189
- *
1190
- * @param event - Event name
1191
- * @param handler - Event handler
1192
- * @returns Unsubscribe function
1193
- */
1194
- once<T extends AuthrimEventName>(event: T, handler: AuthrimEventHandler<T>): () => void;
1195
- /**
1196
- * Unsubscribe from an event
1197
- *
1198
- * @param event - Event name
1199
- * @param handler - Event handler to remove
1200
- */
1201
- off<T extends AuthrimEventName>(event: T, handler: AuthrimEventHandler<T>): void;
1202
- /**
1203
- * Emit an event
1204
- *
1205
- * @param event - Event name
1206
- * @param data - Event data
1207
- */
1208
- emit<T extends AuthrimEventName>(event: T, data: AuthrimEvents[T]): void;
1209
- /**
1210
- * Remove all listeners for an event (or all events)
1211
- *
1212
- * @param event - Event name (optional, removes all if not specified)
1213
- */
1214
- removeAllListeners(event?: AuthrimEventName): void;
1215
- /**
1216
- * Get the number of listeners for an event
1217
- *
1218
- * @param event - Event name
1219
- * @returns Number of listeners
1220
- */
1221
- listenerCount(event: AuthrimEventName): number;
1222
- }
1223
-
1224
- /**
1225
- * Logout Handler
1226
- *
1227
- * Implements RP-Initiated Logout (OpenID Connect RP-Initiated Logout 1.0)
1228
- * https://openid.net/specs/openid-connect-rpinitiated-1_0.html
1229
- */
1230
-
1231
- /**
1232
- * Logout options
1923
+ * Logout options
1233
1924
  */
1234
1925
  interface LogoutOptions {
1235
1926
  /** URI to redirect to after logout */
@@ -1345,6 +2036,12 @@ declare class AuthrimClient {
1345
2036
  private stateManager;
1346
2037
  /** Authorization code flow helper */
1347
2038
  private readonly authCodeFlow;
2039
+ /** PAR client */
2040
+ private readonly parClient;
2041
+ /** Device Flow client */
2042
+ private readonly deviceFlowClient;
2043
+ /** DPoP manager (lazily initialized) */
2044
+ private dpopManager;
1348
2045
  /** Token manager (initialized in initialize()) */
1349
2046
  private tokenManager;
1350
2047
  /** Logout handler (initialized in initialize()) */
@@ -1363,6 +2060,10 @@ declare class AuthrimClient {
1363
2060
  private readonly normalizedIssuer;
1364
2061
  /** Whether the client has been initialized */
1365
2062
  private initialized;
2063
+ /**
2064
+ * Get the event emitter for subscribing to SDK events
2065
+ */
2066
+ get eventEmitter(): EventEmitter;
1366
2067
  /**
1367
2068
  * Create a new Authrim client
1368
2069
  *
@@ -1405,6 +2106,144 @@ declare class AuthrimClient {
1405
2106
  * @returns Token set
1406
2107
  */
1407
2108
  handleCallback(callbackUrl: string): Promise<TokenSet>;
2109
+ /**
2110
+ * PAR API accessor
2111
+ *
2112
+ * Provides access to Pushed Authorization Request functionality.
2113
+ * PAR allows pushing authorization request parameters to a dedicated endpoint,
2114
+ * receiving a request_uri to use in the authorization URL.
2115
+ */
2116
+ get par(): {
2117
+ /**
2118
+ * Push authorization request and get request_uri
2119
+ *
2120
+ * @param options - Authorization options
2121
+ * @returns PAR result with request_uri and expiration
2122
+ */
2123
+ push: (options: BuildAuthorizationUrlOptions) => Promise<PARResult>;
2124
+ /**
2125
+ * Build authorization URL using request_uri from PAR
2126
+ *
2127
+ * @param requestUri - Request URI from PAR response
2128
+ * @returns Authorization URL
2129
+ */
2130
+ buildAuthorizationUrl: (requestUri: string) => Promise<string>;
2131
+ /**
2132
+ * Check if PAR is available
2133
+ *
2134
+ * @returns True if PAR endpoint is available
2135
+ */
2136
+ isAvailable: () => Promise<boolean>;
2137
+ /**
2138
+ * Check if PAR is required by the server
2139
+ *
2140
+ * @returns True if server requires PAR
2141
+ */
2142
+ isRequired: () => Promise<boolean>;
2143
+ };
2144
+ /**
2145
+ * Device Flow API accessor
2146
+ *
2147
+ * Provides access to Device Authorization Grant functionality.
2148
+ * Used for devices with limited input capabilities (TVs, CLIs, IoT).
2149
+ */
2150
+ get deviceFlow(): {
2151
+ /**
2152
+ * Start device authorization
2153
+ *
2154
+ * @param options - Start options (scope, etc.)
2155
+ * @returns Device flow state with codes and URIs
2156
+ */
2157
+ start: (options?: DeviceFlowStartOptions) => Promise<DeviceFlowState>;
2158
+ /**
2159
+ * Poll once for token
2160
+ *
2161
+ * @param state - Device flow state
2162
+ * @returns Poll result
2163
+ */
2164
+ pollOnce: (state: DeviceFlowState) => Promise<DeviceFlowPollResult>;
2165
+ /**
2166
+ * Poll until complete or expired
2167
+ *
2168
+ * @param state - Device flow state
2169
+ * @param options - Polling options (signal for abort)
2170
+ * @returns Token set on success
2171
+ */
2172
+ pollUntilComplete: (state: DeviceFlowState, options?: {
2173
+ signal?: AbortSignal;
2174
+ }) => Promise<TokenSet>;
2175
+ /**
2176
+ * Check if Device Flow is available
2177
+ *
2178
+ * @returns True if device authorization endpoint is available
2179
+ */
2180
+ isAvailable: () => Promise<boolean>;
2181
+ };
2182
+ /**
2183
+ * DPoP API accessor
2184
+ *
2185
+ * Provides access to DPoP (Demonstrating Proof of Possession) functionality.
2186
+ * DPoP binds access tokens to a cryptographic key held by the client,
2187
+ * preventing token theft and replay attacks.
2188
+ *
2189
+ * NOTE: The CryptoProvider must implement DPoPCryptoProvider interface
2190
+ * for DPoP to be available.
2191
+ *
2192
+ * @returns DPoP API accessor, or undefined if not supported
2193
+ */
2194
+ get dpop(): {
2195
+ /**
2196
+ * Initialize DPoP (generates or retrieves key pair)
2197
+ */
2198
+ initialize: () => Promise<void>;
2199
+ /**
2200
+ * Check if DPoP is initialized
2201
+ */
2202
+ isInitialized: () => boolean;
2203
+ /**
2204
+ * Generate a DPoP proof for a request
2205
+ *
2206
+ * @param method - HTTP method (GET, POST, etc.)
2207
+ * @param uri - Full request URI
2208
+ * @param options - Additional options (access token hash, nonce)
2209
+ * @returns Signed DPoP proof JWT
2210
+ */
2211
+ generateProof: (method: string, uri: string, options?: {
2212
+ accessTokenHash?: string;
2213
+ nonce?: string;
2214
+ }) => Promise<string>;
2215
+ /**
2216
+ * Handle DPoP-Nonce response from server
2217
+ *
2218
+ * @param nonce - Server-provided nonce
2219
+ */
2220
+ handleNonceResponse: (nonce: string) => void;
2221
+ /**
2222
+ * Calculate access token hash for ath claim
2223
+ *
2224
+ * @param accessToken - Access token to hash
2225
+ * @returns Base64url-encoded SHA-256 hash
2226
+ */
2227
+ calculateAccessTokenHash: (accessToken: string) => Promise<string>;
2228
+ /**
2229
+ * Get the public key JWK
2230
+ */
2231
+ getPublicKeyJwk: () => JWK | null;
2232
+ /**
2233
+ * Get the JWK thumbprint
2234
+ */
2235
+ getThumbprint: () => string | null;
2236
+ /**
2237
+ * Clear DPoP key pair (call on logout)
2238
+ */
2239
+ clear: () => Promise<void>;
2240
+ /**
2241
+ * Check if DPoP is supported by the server
2242
+ *
2243
+ * @returns True if server advertises DPoP support
2244
+ */
2245
+ isServerSupported: () => Promise<boolean>;
2246
+ } | undefined;
1408
2247
  /**
1409
2248
  * Token API accessor
1410
2249
  */
@@ -1608,6 +2447,13 @@ interface SilentAuthOptions {
1608
2447
  redirectUri: string;
1609
2448
  /** Scopes to request (default: 'openid') */
1610
2449
  scope?: string;
2450
+ /**
2451
+ * Response type (default: 'code')
2452
+ *
2453
+ * Use 'none' for session check without token issuance
2454
+ * (OAuth 2.0 Multiple Response Types 1.0 §5)
2455
+ */
2456
+ responseType?: 'code' | 'none';
1611
2457
  /** Hint about the login identifier */
1612
2458
  loginHint?: string;
1613
2459
  /** ID token hint (helps IdP identify the user) */
@@ -1699,298 +2545,1472 @@ declare class SilentAuthHandler {
1699
2545
  }
1700
2546
 
1701
2547
  /**
1702
- * Token Manager
2548
+ * PAR (Pushed Authorization Request) Client
2549
+ * RFC 9126: OAuth 2.0 Pushed Authorization Requests
1703
2550
  *
1704
- * Manages token storage, retrieval, and automatic refresh.
1705
- * Implements in-flight request coalescing for concurrent refresh requests.
2551
+ * PAR allows the client to push the authorization request payload
2552
+ * to the authorization server via a direct POST request, receiving
2553
+ * a request_uri to use in the authorization URL.
2554
+ *
2555
+ * Benefits:
2556
+ * - Integrity protection of authorization request
2557
+ * - Confidentiality of authorization request parameters
2558
+ * - Support for large request parameters
2559
+ * - Required for FAPI 2.0 compliance
1706
2560
  */
1707
2561
 
1708
2562
  /**
1709
- * Token manager options
2563
+ * PAR Client
2564
+ *
2565
+ * Handles Pushed Authorization Requests per RFC 9126.
1710
2566
  */
1711
- interface TokenManagerOptions {
2567
+ declare class PARClient {
2568
+ private readonly http;
2569
+ private readonly clientId;
2570
+ private readonly options?;
2571
+ constructor(http: HttpClient, clientId: string, options?: PARClientOptions | undefined);
2572
+ /**
2573
+ * Push authorization request to the server
2574
+ *
2575
+ * @param discovery - OIDC discovery document
2576
+ * @param request - PAR request parameters
2577
+ * @returns PAR result with request_uri and expiration
2578
+ * @throws AuthrimError with code 'no_par_endpoint' if PAR endpoint not available
2579
+ * @throws AuthrimError with code 'par_error' if PAR request fails
2580
+ */
2581
+ pushAuthorizationRequest(discovery: OIDCDiscoveryDocument, request: PARRequest): Promise<PARResult>;
2582
+ /**
2583
+ * Build authorization URL using request_uri from PAR
2584
+ *
2585
+ * @param discovery - OIDC discovery document
2586
+ * @param requestUri - Request URI from PAR response
2587
+ * @returns Authorization URL
2588
+ */
2589
+ buildAuthorizationUrlWithPar(discovery: OIDCDiscoveryDocument, requestUri: string): string;
2590
+ }
2591
+
2592
+ /**
2593
+ * Client Authentication Types
2594
+ * RFC 6749 §2.3, RFC 7521, RFC 7523
2595
+ */
2596
+ /**
2597
+ * Client authentication methods
2598
+ */
2599
+ type ClientAuthMethod = 'client_secret_basic' | 'client_secret_post' | 'private_key_jwt' | 'none';
2600
+ /**
2601
+ * Client secret credentials (Basic or POST)
2602
+ */
2603
+ interface ClientSecretCredentials {
2604
+ /** Authentication method */
2605
+ method: 'client_secret_basic' | 'client_secret_post';
2606
+ /** Client secret */
2607
+ clientSecret: string;
2608
+ }
2609
+ /**
2610
+ * Private key JWT credentials (RFC 7523)
2611
+ */
2612
+ interface PrivateKeyJwtCredentials {
2613
+ /** Authentication method */
2614
+ method: 'private_key_jwt';
2615
+ /**
2616
+ * Function to sign JWT assertions
2617
+ *
2618
+ * @param claims - JWT claims to sign
2619
+ * @returns Signed JWT string
2620
+ */
2621
+ signJwt: (claims: Record<string, unknown>) => Promise<string>;
2622
+ /** Key ID to include in JWT header */
2623
+ keyId?: string;
2624
+ }
2625
+ /**
2626
+ * No client authentication (public client)
2627
+ *
2628
+ * SECURITY: method='none' requires explicit opt-in via dangerouslyAllowInsecure
2629
+ * to ensure developers consciously choose to use public client authentication.
2630
+ */
2631
+ interface NoClientCredentials {
2632
+ /** Authentication method */
2633
+ method: 'none';
2634
+ /**
2635
+ * Required flag to acknowledge insecure client authentication
2636
+ *
2637
+ * Setting this to true acknowledges that:
2638
+ * - The client cannot be authenticated securely
2639
+ * - This should only be used for public clients (browser apps, native apps)
2640
+ * - Tokens may be exposed to the user
2641
+ */
2642
+ dangerouslyAllowInsecure: true;
2643
+ }
2644
+ /**
2645
+ * Union type for all client credentials
2646
+ */
2647
+ type ClientCredentials = ClientSecretCredentials | PrivateKeyJwtCredentials | NoClientCredentials;
2648
+ /**
2649
+ * JWT assertion claims for client authentication
2650
+ */
2651
+ interface ClientAssertionClaims extends Record<string, unknown> {
2652
+ /** Issuer (client_id) */
2653
+ iss: string;
2654
+ /** Subject (client_id) */
2655
+ sub: string;
2656
+ /** Audience (token endpoint URL) */
2657
+ aud: string;
2658
+ /** JWT ID (unique identifier) */
2659
+ jti: string;
2660
+ /** Expiration time (epoch seconds) */
2661
+ exp: number;
2662
+ /** Issued at time (epoch seconds) */
2663
+ iat: number;
2664
+ }
2665
+
2666
+ /**
2667
+ * Client Authentication Utilities
2668
+ * RFC 6749 §2.3, RFC 7521, RFC 7523
2669
+ *
2670
+ * Provides utilities for building client authentication headers and body parameters
2671
+ * for various authentication methods.
2672
+ */
2673
+
2674
+ /**
2675
+ * Client authentication result
2676
+ */
2677
+ interface ClientAuthResult {
2678
+ /** Headers to include in the request */
2679
+ headers: Record<string, string>;
2680
+ /** Body parameters to include in the request */
2681
+ bodyParams: Record<string, string>;
2682
+ }
2683
+ /**
2684
+ * Build client authentication headers and body parameters
2685
+ *
2686
+ * @param credentials - Client credentials configuration
2687
+ * @param clientId - Client ID
2688
+ * @param tokenEndpoint - Token endpoint URL (used as audience for private_key_jwt)
2689
+ * @returns Headers and body parameters for authentication
2690
+ * @throws AuthrimError with code 'insecure_client_auth' if method='none' without dangerouslyAllowInsecure
2691
+ * @throws AuthrimError with code 'invalid_client_authentication' for invalid credentials
2692
+ */
2693
+ declare function buildClientAuthentication(credentials: ClientCredentials, clientId: string, tokenEndpoint: string): Promise<ClientAuthResult>;
2694
+
2695
+ /**
2696
+ * Client Credentials Flow
2697
+ * RFC 6749 §4.4
2698
+ *
2699
+ * The client credentials grant is used for machine-to-machine (M2M) authentication
2700
+ * where no user is involved. The client authenticates directly with the authorization
2701
+ * server using its own credentials.
2702
+ *
2703
+ * IMPORTANT: This flow should only be used in secure environments (server-side)
2704
+ * where client credentials can be kept confidential.
2705
+ */
2706
+
2707
+ /**
2708
+ * Options for ClientCredentialsClient constructor
2709
+ */
2710
+ interface ClientCredentialsClientOptions {
1712
2711
  /** HTTP client */
1713
2712
  http: HttpClient;
1714
- /** Storage provider */
1715
- storage: AuthrimStorage;
1716
2713
  /** Client ID */
1717
2714
  clientId: string;
1718
- /** Issuer hash for storage keys */
1719
- issuerHash: string;
1720
- /** Client ID hash for storage keys */
1721
- clientIdHash: string;
1722
- /** Refresh skew in seconds (default: 30) */
1723
- refreshSkewSeconds?: number;
1724
- /** Event emitter for token events */
1725
- eventEmitter?: EventEmitter;
2715
+ /** Client credentials */
2716
+ credentials: ClientCredentials;
1726
2717
  }
1727
2718
  /**
1728
- * Token Manager
2719
+ * Options for getting a token
2720
+ */
2721
+ interface ClientCredentialsTokenOptions {
2722
+ /** Scopes to request */
2723
+ scope?: string;
2724
+ /** Target audience (resource server identifier) */
2725
+ audience?: string;
2726
+ /** Additional parameters */
2727
+ extraParams?: Record<string, string>;
2728
+ }
2729
+ /**
2730
+ * Client Credentials Flow Client
1729
2731
  *
1730
- * Handles token storage, retrieval, and automatic refresh with
1731
- * concurrent request coalescing.
2732
+ * Handles machine-to-machine authentication using the client credentials grant.
1732
2733
  */
1733
- declare class TokenManager {
2734
+ declare class ClientCredentialsClient {
1734
2735
  private readonly http;
1735
- private readonly storage;
1736
2736
  private readonly clientId;
1737
- private readonly issuerHash;
1738
- private readonly clientIdHash;
1739
- private readonly refreshSkewSeconds;
1740
- private readonly eventEmitter?;
1741
- /** In-flight refresh promise for request coalescing */
1742
- private refreshPromise;
1743
- /** Discovery document (set externally) */
1744
- private discovery;
1745
- /** Default refresh skew: 30 seconds */
1746
- private static readonly DEFAULT_REFRESH_SKEW_SECONDS;
1747
- constructor(options: TokenManagerOptions);
1748
- /**
1749
- * Set discovery document
1750
- */
1751
- setDiscovery(discovery: OIDCDiscoveryDocument): void;
2737
+ private readonly credentials;
2738
+ constructor(options: ClientCredentialsClientOptions);
1752
2739
  /**
1753
- * Get storage key for tokens
2740
+ * Get an access token using client credentials
2741
+ *
2742
+ * @param discovery - OIDC discovery document
2743
+ * @param options - Token request options
2744
+ * @returns Token set
2745
+ * @throws AuthrimError with code 'client_credentials_error' if token request fails
1754
2746
  */
1755
- private get tokenKey();
2747
+ getToken(discovery: OIDCDiscoveryDocument, options?: ClientCredentialsTokenOptions): Promise<TokenSet>;
2748
+ }
2749
+
2750
+ /**
2751
+ * Device Authorization Flow
2752
+ * RFC 8628: OAuth 2.0 Device Authorization Grant
2753
+ *
2754
+ * Used for devices with limited input capabilities where the user
2755
+ * authenticates on a separate device (phone, computer).
2756
+ *
2757
+ * Flow:
2758
+ * 1. Client requests device code from authorization server
2759
+ * 2. User goes to verification URI and enters user code
2760
+ * 3. Client polls token endpoint until user completes auth
2761
+ *
2762
+ * NOTE: This core SDK returns "facts" only - UX events like
2763
+ * 'device:started' or 'device:pending' are the responsibility
2764
+ * of upper-layer SDKs (web/react/svelte).
2765
+ */
2766
+
2767
+ /**
2768
+ * Device Flow Client
2769
+ *
2770
+ * Handles the OAuth 2.0 Device Authorization Grant (RFC 8628).
2771
+ */
2772
+ declare class DeviceFlowClient {
2773
+ private readonly http;
2774
+ private readonly clientId;
2775
+ constructor(http: HttpClient, clientId: string);
1756
2776
  /**
1757
- * Get storage key for ID token
2777
+ * Start device authorization
2778
+ *
2779
+ * Requests a device code and user code from the authorization server.
2780
+ *
2781
+ * @param discovery - OIDC discovery document
2782
+ * @param options - Start options (scope, etc.)
2783
+ * @returns Device flow state with codes and URIs
2784
+ * @throws AuthrimError with code 'no_device_authorization_endpoint' if endpoint not available
2785
+ * @throws AuthrimError with code 'device_authorization_error' if request fails
1758
2786
  */
1759
- private get idTokenKey();
2787
+ startDeviceAuthorization(discovery: OIDCDiscoveryDocument, options?: DeviceFlowStartOptions): Promise<DeviceFlowState>;
1760
2788
  /**
1761
- * Get current tokens from storage
2789
+ * Poll the token endpoint once
1762
2790
  *
1763
- * @returns Token set or null if not found
2791
+ * Returns the current state of the authorization:
2792
+ * - 'pending': User hasn't completed auth yet
2793
+ * - 'completed': Auth complete, tokens received
2794
+ * - 'slow_down': Polling too fast, increase interval
2795
+ * - 'expired': Device code expired
2796
+ * - 'access_denied': User denied the request
2797
+ *
2798
+ * @param discovery - OIDC discovery document
2799
+ * @param state - Device flow state from startDeviceAuthorization
2800
+ * @returns Poll result
1764
2801
  */
1765
- getTokens(): Promise<TokenSet | null>;
2802
+ pollOnce(discovery: OIDCDiscoveryDocument, state: DeviceFlowState): Promise<DeviceFlowPollResult>;
1766
2803
  /**
1767
- * Save tokens to storage
2804
+ * Poll until authorization is complete or expires
1768
2805
  *
1769
- * @param tokens - Token set to save
2806
+ * Automatically handles polling interval and retries.
2807
+ *
2808
+ * @param discovery - OIDC discovery document
2809
+ * @param state - Device flow state from startDeviceAuthorization
2810
+ * @param options - Polling options
2811
+ * @returns Token set on success
2812
+ * @throws AuthrimError with code 'device_authorization_expired' if device code expires
2813
+ * @throws AuthrimError with code 'device_access_denied' if user denies authorization
1770
2814
  */
1771
- saveTokens(tokens: TokenSet): Promise<void>;
2815
+ pollUntilComplete(discovery: OIDCDiscoveryDocument, state: DeviceFlowState, options?: {
2816
+ signal?: AbortSignal;
2817
+ }): Promise<TokenSet>;
1772
2818
  /**
1773
- * Clear all tokens from storage
2819
+ * Sleep for a given number of milliseconds
2820
+ * @param ms - Milliseconds to sleep
2821
+ * @param signal - Optional abort signal
1774
2822
  */
1775
- clearTokens(): Promise<void>;
1776
- /**
1777
- * Get access token, refreshing if necessary
2823
+ private sleep;
2824
+ }
2825
+
2826
+ /**
2827
+ * DPoP (Demonstrating Proof of Possession) Types
2828
+ * RFC 9449: OAuth 2.0 Demonstrating Proof of Possession (DPoP)
2829
+ *
2830
+ * DPoP provides a mechanism for sender-constraining access tokens
2831
+ * to a particular client by binding tokens to a cryptographic key.
2832
+ */
2833
+ /**
2834
+ * JSON Web Key (JWK) format
2835
+ *
2836
+ * Subset of the Web Crypto API JWK interface.
2837
+ * Defined here for platform-agnostic support.
2838
+ */
2839
+ interface JWK {
2840
+ /** Key type (e.g., 'EC', 'RSA') */
2841
+ kty?: string;
2842
+ /** Key ID */
2843
+ kid?: string;
2844
+ /** Algorithm */
2845
+ alg?: string;
2846
+ /** Public key use */
2847
+ use?: string;
2848
+ /** Key operations */
2849
+ key_ops?: string[];
2850
+ /** Extractable flag */
2851
+ ext?: boolean;
2852
+ /** Curve name */
2853
+ crv?: string;
2854
+ /** X coordinate (base64url) */
2855
+ x?: string;
2856
+ /** Y coordinate (base64url) */
2857
+ y?: string;
2858
+ /** Private key value (base64url) - should not be exported */
2859
+ d?: string;
2860
+ /** Modulus (base64url) */
2861
+ n?: string;
2862
+ /** Public exponent (base64url) */
2863
+ e?: string;
2864
+ [key: string]: unknown;
2865
+ }
2866
+ /**
2867
+ * DPoP key pair interface
2868
+ *
2869
+ * Represents an asymmetric key pair used for DPoP proofs.
2870
+ */
2871
+ interface DPoPKeyPair {
2872
+ /** Algorithm identifier (e.g., 'ES256', 'RS256') */
2873
+ algorithm: string;
2874
+ /** JWK thumbprint of the public key (base64url encoded) */
2875
+ thumbprint: string;
2876
+ /** Public key in JWK format */
2877
+ publicKeyJwk: JWK;
2878
+ /**
2879
+ * Sign data with the private key
1778
2880
  *
1779
- * This method coalesces concurrent refresh requests - if multiple
1780
- * calls are made while a refresh is in-flight, they all share the
1781
- * same refresh operation.
2881
+ * @param data - Data to sign
2882
+ * @returns Signature
2883
+ */
2884
+ sign(data: Uint8Array): Promise<Uint8Array>;
2885
+ }
2886
+ /**
2887
+ * DPoP proof JWT header
2888
+ */
2889
+ interface DPoPProofHeader {
2890
+ /** Type (always 'dpop+jwt') */
2891
+ typ: 'dpop+jwt';
2892
+ /** Algorithm */
2893
+ alg: string;
2894
+ /** Public key in JWK format */
2895
+ jwk: JWK;
2896
+ }
2897
+ /**
2898
+ * DPoP proof JWT claims
2899
+ */
2900
+ interface DPoPProofClaims {
2901
+ /** Unique identifier for the proof */
2902
+ jti: string;
2903
+ /** HTTP method of the request */
2904
+ htm: string;
2905
+ /** HTTP URI of the request (without query and fragment) */
2906
+ htu: string;
2907
+ /** Issued at time (epoch seconds) */
2908
+ iat: number;
2909
+ /** Access token hash (when binding to access token) */
2910
+ ath?: string;
2911
+ /** Server-provided nonce (when server requires it) */
2912
+ nonce?: string;
2913
+ }
2914
+ /**
2915
+ * Options for generating a DPoP proof
2916
+ */
2917
+ interface DPoPProofOptions {
2918
+ /** Hash of the access token (base64url(SHA-256(access_token))) */
2919
+ accessTokenHash?: string;
2920
+ /** Server-provided nonce */
2921
+ nonce?: string;
2922
+ }
2923
+ /**
2924
+ * DPoP Manager configuration
2925
+ */
2926
+ interface DPoPManagerConfig {
2927
+ /** Preferred algorithm (default: 'ES256') */
2928
+ algorithm?: string;
2929
+ }
2930
+ /**
2931
+ * Extended CryptoProvider interface with DPoP support
2932
+ *
2933
+ * This extends the base CryptoProvider with optional DPoP methods.
2934
+ * Implementations that support DPoP should implement these methods.
2935
+ */
2936
+ interface DPoPCryptoProvider {
2937
+ /**
2938
+ * Generate a new DPoP key pair
1782
2939
  *
1783
- * @returns Access token
1784
- * @throws AuthrimError if no tokens available or refresh fails
2940
+ * @param algorithm - Preferred algorithm (default: 'ES256')
2941
+ * @returns Generated key pair
1785
2942
  */
1786
- getAccessToken(): Promise<string>;
2943
+ generateDPoPKeyPair?(algorithm?: string): Promise<DPoPKeyPair>;
1787
2944
  /**
1788
- * Get ID token
2945
+ * Get the current DPoP key pair
1789
2946
  *
1790
- * @returns ID token or null
2947
+ * Returns null if no key pair has been generated.
2948
+ *
2949
+ * @returns Current key pair or null
1791
2950
  */
1792
- getIdToken(): Promise<string | null>;
2951
+ getDPoPKeyPair?(): Promise<DPoPKeyPair | null>;
1793
2952
  /**
1794
- * Check if token needs refresh
2953
+ * Clear the DPoP key pair
1795
2954
  *
1796
- * @param tokens - Token set to check
1797
- * @returns True if token should be refreshed
2955
+ * Should be called on logout to clean up key material.
1798
2956
  */
1799
- private shouldRefresh;
2957
+ clearDPoPKeyPair?(): Promise<void>;
2958
+ }
2959
+
2960
+ /**
2961
+ * DPoP Manager
2962
+ * RFC 9449: OAuth 2.0 Demonstrating Proof of Possession (DPoP)
2963
+ *
2964
+ * DPoP provides sender-constrained access tokens by binding them
2965
+ * to a cryptographic key held by the client. This prevents token theft
2966
+ * and replay attacks.
2967
+ *
2968
+ * NOTE: DPoP proofs are required for:
2969
+ * - Token requests (authorization code exchange, refresh)
2970
+ * - PAR requests
2971
+ * - UserInfo requests
2972
+ * - Any protected resource request
2973
+ *
2974
+ * Future consideration: HttpClient-level middleware for automatic DPoP proof attachment.
2975
+ */
2976
+
2977
+ /**
2978
+ * DPoP Manager
2979
+ *
2980
+ * Manages DPoP key pairs and generates DPoP proofs for requests.
2981
+ */
2982
+ declare class DPoPManager {
2983
+ private readonly crypto;
2984
+ private readonly config;
2985
+ private keyPair;
2986
+ private serverNonce;
2987
+ constructor(crypto: CryptoProvider & DPoPCryptoProvider, config?: DPoPManagerConfig);
1800
2988
  /**
1801
- * Refresh token with in-flight request coalescing
2989
+ * Initialize the DPoP manager
1802
2990
  *
1803
- * If a refresh is already in progress, wait for it instead of
1804
- * starting a new one.
2991
+ * Generates or retrieves a DPoP key pair.
1805
2992
  *
1806
- * @param refreshToken - Refresh token to use
1807
- * @returns Access token from new token set
2993
+ * @throws AuthrimError with code 'dpop_key_generation_error' if key generation fails
1808
2994
  */
1809
- private refreshWithLock;
2995
+ initialize(): Promise<void>;
2996
+ /**
2997
+ * Check if DPoP is initialized
2998
+ */
2999
+ isInitialized(): boolean;
1810
3000
  /**
1811
- * Perform refresh with single retry for network errors
3001
+ * Generate a DPoP proof
1812
3002
  *
1813
- * @param refreshToken - Refresh token to use
1814
- * @param attemptedRetry - Whether retry has been attempted (stack-local)
1815
- * @returns New token set
3003
+ * Creates a signed JWT proof for the specified HTTP method and URI.
3004
+ *
3005
+ * @param method - HTTP method (GET, POST, etc.)
3006
+ * @param uri - Full request URI (https://example.com/path)
3007
+ * @param options - Additional options (access token hash, nonce)
3008
+ * @returns Signed DPoP proof JWT
3009
+ * @throws AuthrimError with code 'dpop_proof_generation_error' if proof generation fails
1816
3010
  */
1817
- private doRefreshWithRetry;
3011
+ generateProof(method: string, uri: string, options?: DPoPProofOptions): Promise<string>;
1818
3012
  /**
1819
- * Perform the actual token refresh
3013
+ * Handle a DPoP-Nonce response from the server
1820
3014
  *
1821
- * @param refreshToken - Refresh token to use
1822
- * @returns New token set
3015
+ * When the server returns a use_dpop_nonce error or includes
3016
+ * a DPoP-Nonce header, this method stores the nonce for future proofs.
3017
+ *
3018
+ * @param nonce - Server-provided nonce value
1823
3019
  */
1824
- private doRefresh;
3020
+ handleNonceResponse(nonce: string): void;
1825
3021
  /**
1826
- * Check if error is retryable (network errors only)
3022
+ * Get the current server nonce
1827
3023
  */
1828
- private isRetryableError;
3024
+ getServerNonce(): string | null;
1829
3025
  /**
1830
- * Check if user is authenticated
3026
+ * Clear the server nonce
3027
+ */
3028
+ clearServerNonce(): void;
3029
+ /**
3030
+ * Get the public key JWK
1831
3031
  *
1832
- * @returns True if valid tokens exist
3032
+ * @returns Public key in JWK format, or null if not initialized
1833
3033
  */
1834
- isAuthenticated(): Promise<boolean>;
3034
+ getPublicKeyJwk(): JWK | null;
1835
3035
  /**
1836
- * Exchange a token using RFC 8693 Token Exchange
3036
+ * Get the JWK thumbprint
1837
3037
  *
1838
- * This allows exchanging tokens for different audiences or scopes,
1839
- * delegation scenarios, and cross-service token acquisition.
3038
+ * @returns Base64url-encoded thumbprint, or null if not initialized
3039
+ */
3040
+ getThumbprint(): string | null;
3041
+ /**
3042
+ * Calculate access token hash for ath claim
1840
3043
  *
1841
- * @param request - Token exchange request parameters
1842
- * @returns Token exchange result with new tokens and issued token type
1843
- * @throws AuthrimError if exchange fails
3044
+ * @param accessToken - Access token to hash
3045
+ * @returns Base64url-encoded SHA-256 hash
1844
3046
  */
1845
- exchangeToken(request: TokenExchangeRequest): Promise<TokenExchangeResult>;
3047
+ calculateAccessTokenHash(accessToken: string): Promise<string>;
1846
3048
  /**
1847
- * Map short token type to URI (RFC 8693)
3049
+ * Clear the DPoP key pair
3050
+ *
3051
+ * Should be called on logout to clean up key material.
1848
3052
  */
1849
- private mapTokenTypeToUri;
3053
+ clear(): Promise<void>;
3054
+ /**
3055
+ * Generate a unique JWT ID (jti)
3056
+ */
3057
+ private generateJti;
1850
3058
  }
1851
3059
 
1852
3060
  /**
1853
- * Token API Client
3061
+ * JAR (JWT Secured Authorization Request) Types
3062
+ * RFC 9101: The OAuth 2.0 Authorization Framework: JWT-Secured Authorization Request (JAR)
1854
3063
  *
1855
- * Provides session verification against the authorization server.
1856
- * Uses the UserInfo endpoint or custom session check endpoint.
3064
+ * JAR allows authorization request parameters to be encoded in a
3065
+ * signed JWT, providing integrity protection and non-repudiation.
1857
3066
  */
1858
-
1859
3067
  /**
1860
- * Session check result
3068
+ * JAR request object claims
1861
3069
  */
1862
- interface SessionCheckResult {
1863
- /** Whether session is valid */
1864
- valid: boolean;
1865
- /** User info if session is valid */
1866
- user?: UserInfo;
1867
- /** Error if session is invalid */
1868
- error?: AuthrimError;
3070
+ interface JARRequestObjectClaims {
3071
+ /** Issuer (client_id) */
3072
+ iss: string;
3073
+ /** Audience (authorization server issuer) */
3074
+ aud: string;
3075
+ /** Response type */
3076
+ response_type: string;
3077
+ /** Client ID */
3078
+ client_id: string;
3079
+ /** Redirect URI */
3080
+ redirect_uri: string;
3081
+ /** Scope */
3082
+ scope: string;
3083
+ /** State */
3084
+ state: string;
3085
+ /** Nonce */
3086
+ nonce: string;
3087
+ /** PKCE code challenge */
3088
+ code_challenge: string;
3089
+ /** PKCE code challenge method */
3090
+ code_challenge_method: string;
3091
+ /** Issued at time (epoch seconds) */
3092
+ iat: number;
3093
+ /** Expiration time (epoch seconds) */
3094
+ exp: number;
3095
+ /** JWT ID (optional but recommended) */
3096
+ jti?: string;
3097
+ /** Not before time (optional) */
3098
+ nbf?: number;
3099
+ /** Prompt */
3100
+ prompt?: string;
3101
+ /** Login hint */
3102
+ login_hint?: string;
3103
+ /** ACR values */
3104
+ acr_values?: string;
3105
+ [key: string]: unknown;
1869
3106
  }
1870
3107
  /**
1871
- * Token API client options
3108
+ * JAR Builder configuration
1872
3109
  */
1873
- interface TokenApiClientOptions {
1874
- /** HTTP client */
1875
- http: HttpClient;
3110
+ interface JARBuilderConfig {
3111
+ /**
3112
+ * Function to sign JWT
3113
+ *
3114
+ * @param header - JWT header object
3115
+ * @param claims - JWT claims object
3116
+ * @returns Signed JWT string
3117
+ */
3118
+ signJwt: (header: object, claims: object) => Promise<string>;
3119
+ /** Key ID to include in JWT header */
3120
+ keyId?: string;
3121
+ /** Lifetime of the request object in seconds (default: 300) */
3122
+ lifetime?: number;
3123
+ /** Algorithm for signing (e.g., 'RS256', 'ES256') */
3124
+ algorithm?: string;
1876
3125
  }
1877
3126
  /**
1878
- * Token API Client
3127
+ * Options for building a request object
3128
+ */
3129
+ interface JARRequestOptions {
3130
+ /** Client ID */
3131
+ clientId: string;
3132
+ /** Authorization server issuer */
3133
+ issuer: string;
3134
+ /** Response type (default: 'code') */
3135
+ responseType?: string;
3136
+ /** Redirect URI */
3137
+ redirectUri: string;
3138
+ /** Scope */
3139
+ scope: string;
3140
+ /** State */
3141
+ state: string;
3142
+ /** Nonce */
3143
+ nonce: string;
3144
+ /** PKCE code challenge */
3145
+ codeChallenge: string;
3146
+ /** PKCE code challenge method */
3147
+ codeChallengeMethod: string;
3148
+ /** Prompt */
3149
+ prompt?: string;
3150
+ /** Login hint */
3151
+ loginHint?: string;
3152
+ /** ACR values */
3153
+ acrValues?: string;
3154
+ /** Additional claims */
3155
+ extraClaims?: Record<string, unknown>;
3156
+ }
3157
+
3158
+ /**
3159
+ * JAR Builder
3160
+ * RFC 9101: JWT-Secured Authorization Request (JAR)
1879
3161
  *
1880
- * Verifies session status with the authorization server.
3162
+ * JAR provides a way to send authorization request parameters
3163
+ * in a signed (and optionally encrypted) JWT, ensuring:
3164
+ * - Integrity protection of parameters
3165
+ * - Non-repudiation
3166
+ * - Confidentiality (when encrypted)
3167
+ *
3168
+ * The signed JWT is sent as the 'request' parameter in the authorization URL,
3169
+ * or can be passed by reference using the 'request_uri' parameter (with PAR).
1881
3170
  */
1882
- declare class TokenApiClient {
1883
- private readonly http;
1884
- constructor(options: TokenApiClientOptions);
3171
+
3172
+ /**
3173
+ * JAR Builder
3174
+ *
3175
+ * Builds signed JWT request objects for authorization requests.
3176
+ */
3177
+ declare class JARBuilder {
3178
+ private readonly config;
3179
+ constructor(config: JARBuilderConfig);
1885
3180
  /**
1886
- * Check session validity by calling UserInfo endpoint
3181
+ * Build a signed request object
1887
3182
  *
1888
- * @param discovery - OIDC discovery document
1889
- * @param accessToken - Access token to verify
1890
- * @returns Session check result
3183
+ * @param options - Request options
3184
+ * @returns Signed JWT request object
3185
+ * @throws AuthrimError with code 'jar_signing_error' if signing fails
1891
3186
  */
1892
- checkSession(discovery: OIDCDiscoveryDocument, accessToken: string): Promise<SessionCheckResult>;
3187
+ buildRequestObject(options: JARRequestOptions): Promise<string>;
1893
3188
  /**
1894
- * Get user info from the authorization server
1895
- *
1896
- * @param discovery - OIDC discovery document
1897
- * @param accessToken - Access token
1898
- * @returns User info
1899
- * @throws AuthrimError if request fails
3189
+ * Generate a unique JWT ID (jti)
1900
3190
  */
1901
- getUserInfo(discovery: OIDCDiscoveryDocument, accessToken: string): Promise<UserInfo>;
3191
+ private generateJti;
1902
3192
  }
1903
-
1904
3193
  /**
1905
- * Session Manager
3194
+ * Check if JAR is required by the authorization server
1906
3195
  *
1907
- * Coordinates session-related operations including checking
1908
- * session status and retrieving user information.
3196
+ * @param discovery - OIDC discovery document
3197
+ * @returns True if require_signed_request_object is true
1909
3198
  */
3199
+ declare function isJarRequired(discovery: {
3200
+ require_signed_request_object?: boolean;
3201
+ }): boolean;
1910
3202
 
1911
3203
  /**
1912
- * Session manager options
3204
+ * JARM (JWT Secured Authorization Response Mode) Types
3205
+ * Financial-grade API (FAPI) / OpenID Connect
3206
+ *
3207
+ * JARM provides a way for authorization servers to return authorization
3208
+ * response parameters in a signed (and optionally encrypted) JWT.
3209
+ * This provides integrity protection and authenticity verification.
1913
3210
  */
1914
- interface SessionManagerOptions {
1915
- /** Token manager */
1916
- tokenManager: TokenManager;
1917
- /** Token API client */
1918
- tokenApiClient: TokenApiClient;
3211
+ /**
3212
+ * JARM response JWT claims
3213
+ */
3214
+ interface JARMResponseClaims {
3215
+ /** Issuer (authorization server) */
3216
+ iss: string;
3217
+ /** Audience (client_id) */
3218
+ aud: string;
3219
+ /** Expiration time (epoch seconds) */
3220
+ exp: number;
3221
+ /** Issued at time (optional) */
3222
+ iat?: number;
3223
+ /** Authorization code */
3224
+ code?: string;
3225
+ /** State parameter */
3226
+ state?: string;
3227
+ /** Error code */
3228
+ error?: string;
3229
+ /** Error description */
3230
+ error_description?: string;
3231
+ /** Error URI */
3232
+ error_uri?: string;
3233
+ [key: string]: unknown;
1919
3234
  }
1920
3235
  /**
1921
- * Session Manager
3236
+ * JARM validation options
1922
3237
  */
1923
- declare class SessionManager {
1924
- private readonly tokenManager;
1925
- private readonly tokenApiClient;
1926
- /** Discovery document */
1927
- private discovery;
1928
- constructor(options: SessionManagerOptions);
1929
- /**
1930
- * Set discovery document
1931
- */
1932
- setDiscovery(discovery: OIDCDiscoveryDocument): void;
3238
+ interface JARMValidationOptions {
3239
+ /** Expected state value */
3240
+ expectedState: string;
3241
+ /** Client ID (audience) */
3242
+ clientId: string;
3243
+ /** Clock skew tolerance in seconds (default: 60) */
3244
+ clockSkewSeconds?: number;
3245
+ }
3246
+ /**
3247
+ * JARM validation result
3248
+ */
3249
+ interface JARMValidationResult {
3250
+ /** Authorization code (if present) */
3251
+ code: string;
3252
+ /** State parameter */
3253
+ state: string;
3254
+ }
3255
+ /**
3256
+ * JARM Validator configuration
3257
+ */
3258
+ interface JARMValidatorConfig {
1933
3259
  /**
1934
- * Check if user is authenticated locally
3260
+ * Function to verify JWT signature
1935
3261
  *
1936
- * This checks if valid tokens exist in storage.
1937
- * Does not verify with the authorization server.
3262
+ * Should verify the signature using the authorization server's public keys
3263
+ * (typically from JWKS endpoint) and return the decoded claims.
1938
3264
  *
1939
- * @returns True if tokens exist
3265
+ * @param jwt - The JWT string to verify
3266
+ * @param issuer - Expected issuer
3267
+ * @returns Decoded and verified claims
3268
+ * @throws Error if signature verification fails
1940
3269
  */
1941
- isAuthenticated(): Promise<boolean>;
3270
+ verifyJwt: (jwt: string, issuer: string) => Promise<JARMResponseClaims>;
3271
+ }
3272
+
3273
+ /**
3274
+ * JARM Validator
3275
+ * JWT Secured Authorization Response Mode (JARM)
3276
+ *
3277
+ * JARM allows authorization servers to return authorization response
3278
+ * parameters in a signed JWT, providing:
3279
+ * - Response integrity protection
3280
+ * - Response authenticity verification
3281
+ * - Confidentiality (when encrypted)
3282
+ *
3283
+ * The response JWT is returned in the 'response' parameter of the
3284
+ * authorization callback.
3285
+ */
3286
+
3287
+ /**
3288
+ * JARM Validator
3289
+ *
3290
+ * Validates JWT-secured authorization responses.
3291
+ */
3292
+ declare class JARMValidator {
3293
+ private readonly config;
3294
+ constructor(config: JARMValidatorConfig);
1942
3295
  /**
1943
- * Check session validity with authorization server
1944
- *
1945
- * Calls the UserInfo endpoint to verify the session is still valid.
3296
+ * Validate a JARM response
1946
3297
  *
1947
- * @returns Session check result
3298
+ * @param discovery - OIDC discovery document
3299
+ * @param response - The JWT response string from the 'response' parameter
3300
+ * @param options - Validation options
3301
+ * @returns Validated authorization code and state
3302
+ * @throws AuthrimError with code 'jarm_validation_error' if validation fails
3303
+ * @throws AuthrimError with code 'jarm_signature_invalid' if signature verification fails
1948
3304
  */
1949
- checkSession(): Promise<SessionCheckResult>;
3305
+ validateResponse(discovery: OIDCDiscoveryDocument, response: string, options: JARMValidationOptions): Promise<JARMValidationResult>;
1950
3306
  /**
1951
- * Get user information
3307
+ * Parse a JARM response from callback URL
1952
3308
  *
1953
- * Fetches user info from the UserInfo endpoint.
3309
+ * Extracts the 'response' parameter from the callback URL.
1954
3310
  *
1955
- * @returns User info
1956
- * @throws AuthrimError if not authenticated or request fails
3311
+ * @param callbackUrl - Full callback URL or query string
3312
+ * @returns The response JWT, or null if not present
1957
3313
  */
1958
- getUser(): Promise<UserInfo>;
3314
+ static extractResponseFromCallback(callbackUrl: string): string | null;
1959
3315
  }
1960
3316
 
1961
3317
  /**
1962
- * Base64URL Encoding/Decoding Utilities
3318
+ * Session Management Types
3319
+ * OpenID Connect Session Management 1.0
1963
3320
  *
1964
- * Implements RFC 4648 Section 5 (Base64 URL and Filename Safe Alphabet)
3321
+ * These types support session management via check_session_iframe
3322
+ * and related specifications.
3323
+ *
3324
+ * NOTE: Actual implementation of session management (postMessage communication,
3325
+ * iframe handling) is the responsibility of the web SDK (@authrim/web).
3326
+ * Core SDK only provides type definitions.
1965
3327
  */
1966
3328
  /**
1967
- * Encode a Uint8Array to base64url string
1968
- *
1969
- * @param data - Bytes to encode
1970
- * @returns Base64URL encoded string (no padding)
3329
+ * Session state from check_session_iframe
1971
3330
  */
1972
- declare function base64urlEncode(data: Uint8Array): string;
3331
+ type SessionState = string;
1973
3332
  /**
1974
- * Decode a base64url string to Uint8Array
3333
+ * Check session iframe message
1975
3334
  *
1976
- * @param str - Base64URL encoded string
1977
- * @returns Decoded bytes
3335
+ * Format: "client_id session_state"
1978
3336
  */
1979
- declare function base64urlDecode(str: string): Uint8Array;
3337
+ interface CheckSessionMessage {
3338
+ /** Client ID */
3339
+ clientId: string;
3340
+ /** Session state from authentication response */
3341
+ sessionState: SessionState;
3342
+ }
1980
3343
  /**
1981
- * Encode a string to base64url
1982
- *
1983
- * @param str - String to encode (UTF-8)
1984
- * @returns Base64URL encoded string
3344
+ * Check session iframe response
1985
3345
  */
1986
- declare function stringToBase64url(str: string): string;
3346
+ type CheckSessionResponse = 'changed' | 'unchanged' | 'error';
1987
3347
  /**
1988
- * Decode a base64url string to string
3348
+ * Session management configuration
3349
+ */
3350
+ interface SessionManagementConfig {
3351
+ /** check_session_iframe URL from discovery */
3352
+ checkSessionIframe?: string;
3353
+ /** Polling interval in milliseconds (default: 2000) */
3354
+ pollIntervalMs?: number;
3355
+ /** Whether session management is enabled */
3356
+ enabled: boolean;
3357
+ }
3358
+ /**
3359
+ * Session change event
3360
+ */
3361
+ interface SessionChangeEvent {
3362
+ /** Previous session state */
3363
+ previousState: SessionState | null;
3364
+ /** Current session state */
3365
+ currentState: SessionState | null;
3366
+ /** Whether the session is still valid */
3367
+ isValid: boolean;
3368
+ }
3369
+ /**
3370
+ * Front-Channel Logout Types
3371
+ * OpenID Connect Front-Channel Logout 1.0
3372
+ *
3373
+ * Front-channel logout allows the OP to notify RPs of logout events
3374
+ * via browser redirects.
3375
+ *
3376
+ * NOTE: Actual implementation of front-channel logout (iframe handling)
3377
+ * is the responsibility of the web SDK (@authrim/web).
3378
+ * Core SDK only provides type definitions.
3379
+ */
3380
+ /**
3381
+ * Front-channel logout request parameters
3382
+ */
3383
+ interface FrontChannelLogoutParams {
3384
+ /** Issuer identifier */
3385
+ iss?: string;
3386
+ /** Session ID */
3387
+ sid?: string;
3388
+ }
3389
+ /**
3390
+ * Front-channel logout URL builder options
3391
+ */
3392
+ interface FrontChannelLogoutUrlOptions {
3393
+ /** Base logout URI registered with the OP */
3394
+ logoutUri: string;
3395
+ /** Whether to include issuer parameter */
3396
+ includeIssuer?: boolean;
3397
+ /** Whether to include session ID parameter */
3398
+ includeSessionId?: boolean;
3399
+ }
3400
+ /**
3401
+ * Back-Channel Logout Types
3402
+ * OpenID Connect Back-Channel Logout 1.0
3403
+ *
3404
+ * Back-channel logout allows the OP to notify RPs of logout events
3405
+ * via direct HTTP calls (server-to-server).
3406
+ *
3407
+ * NOTE: This is typically handled server-side, not in the browser.
3408
+ * Included here for completeness of type definitions.
3409
+ */
3410
+ /**
3411
+ * Logout token claims (for back-channel logout)
3412
+ */
3413
+ interface LogoutTokenClaims {
3414
+ /** Issuer */
3415
+ iss: string;
3416
+ /** Subject */
3417
+ sub?: string;
3418
+ /** Audience */
3419
+ aud: string | string[];
3420
+ /** Issued at time */
3421
+ iat: number;
3422
+ /** JWT ID */
3423
+ jti: string;
3424
+ /** Events claim (must contain logout event) */
3425
+ events: {
3426
+ 'http://schemas.openid.net/event/backchannel-logout': Record<string, never>;
3427
+ };
3428
+ /** Session ID (if back-channel logout session is supported) */
3429
+ sid?: string;
3430
+ }
3431
+
3432
+ /**
3433
+ * Token Manager
3434
+ *
3435
+ * Manages token storage, retrieval, and automatic refresh.
3436
+ * Implements in-flight request coalescing for concurrent refresh requests.
3437
+ */
3438
+
3439
+ /**
3440
+ * Token manager options
3441
+ */
3442
+ interface TokenManagerOptions {
3443
+ /** HTTP client */
3444
+ http: HttpClient;
3445
+ /** Storage provider */
3446
+ storage: AuthrimStorage;
3447
+ /** Client ID */
3448
+ clientId: string;
3449
+ /** Issuer hash for storage keys */
3450
+ issuerHash: string;
3451
+ /** Client ID hash for storage keys */
3452
+ clientIdHash: string;
3453
+ /** Refresh skew in seconds (default: 30) */
3454
+ refreshSkewSeconds?: number;
3455
+ /** Event emitter for token events */
3456
+ eventEmitter?: EventEmitter;
3457
+ /** Token expiring warning threshold in seconds (default: 300 = 5 minutes) */
3458
+ expiringThresholdSeconds?: number;
3459
+ /** Jitter for expiring event in milliseconds (default: 30000 = ±30 seconds) */
3460
+ expiringJitterMs?: number;
3461
+ }
3462
+ /**
3463
+ * Token Manager
3464
+ *
3465
+ * Handles token storage, retrieval, and automatic refresh with
3466
+ * concurrent request coalescing.
3467
+ */
3468
+ declare class TokenManager {
3469
+ private readonly http;
3470
+ private readonly storage;
3471
+ private readonly clientId;
3472
+ private readonly issuerHash;
3473
+ private readonly clientIdHash;
3474
+ private readonly refreshSkewSeconds;
3475
+ private readonly eventEmitter?;
3476
+ private readonly expiringThresholdMs;
3477
+ private readonly expiringJitterMs;
3478
+ /** In-flight refresh promise for request coalescing */
3479
+ private refreshPromise;
3480
+ /** Discovery document (set externally) */
3481
+ private discovery;
3482
+ /** Timer for token expiring event */
3483
+ private expiringTimeout;
3484
+ /** Whether this tab is the leader for refresh scheduling */
3485
+ private isLeaderTab;
3486
+ /** Current operation ID for event tracking */
3487
+ private currentOperationId;
3488
+ /** Default refresh skew: 30 seconds */
3489
+ private static readonly DEFAULT_REFRESH_SKEW_SECONDS;
3490
+ /** Default expiring threshold: 5 minutes */
3491
+ private static readonly DEFAULT_EXPIRING_THRESHOLD_SECONDS;
3492
+ /** Default expiring jitter: ±30 seconds */
3493
+ private static readonly DEFAULT_EXPIRING_JITTER_MS;
3494
+ constructor(options: TokenManagerOptions);
3495
+ /**
3496
+ * Set discovery document
3497
+ */
3498
+ setDiscovery(discovery: OIDCDiscoveryDocument): void;
3499
+ /**
3500
+ * Get storage key for tokens
3501
+ */
3502
+ private get tokenKey();
3503
+ /**
3504
+ * Get storage key for ID token
3505
+ */
3506
+ private get idTokenKey();
3507
+ /**
3508
+ * Get current tokens from storage
3509
+ *
3510
+ * @returns Token set or null if not found
3511
+ */
3512
+ getTokens(): Promise<TokenSet | null>;
3513
+ /**
3514
+ * Save tokens to storage
3515
+ *
3516
+ * @param tokens - Token set to save
3517
+ */
3518
+ saveTokens(tokens: TokenSet): Promise<void>;
3519
+ /**
3520
+ * Schedule token:expiring event with jitter
3521
+ *
3522
+ * @param expiresAt - Token expiration timestamp (epoch seconds)
3523
+ */
3524
+ private scheduleExpiringEvent;
3525
+ /**
3526
+ * Set leader tab status
3527
+ *
3528
+ * When not the leader, expiring event scheduling is disabled
3529
+ * to prevent multiple tabs from triggering simultaneous refreshes.
3530
+ *
3531
+ * @param isLeader - Whether this tab is the leader
3532
+ */
3533
+ setLeaderTab(isLeader: boolean): void;
3534
+ /**
3535
+ * Set current operation ID for event tracking
3536
+ */
3537
+ setOperationId(operationId: string | null): void;
3538
+ /**
3539
+ * Get current operation ID
3540
+ */
3541
+ getOperationId(): string | null;
3542
+ /**
3543
+ * Clear all tokens from storage
3544
+ */
3545
+ clearTokens(): Promise<void>;
3546
+ /**
3547
+ * Get access token, refreshing if necessary
3548
+ *
3549
+ * This method coalesces concurrent refresh requests - if multiple
3550
+ * calls are made while a refresh is in-flight, they all share the
3551
+ * same refresh operation.
3552
+ *
3553
+ * @returns Access token
3554
+ * @throws AuthrimError if no tokens available or refresh fails
3555
+ */
3556
+ getAccessToken(): Promise<string>;
3557
+ /**
3558
+ * Get ID token
3559
+ *
3560
+ * @returns ID token or null
3561
+ */
3562
+ getIdToken(): Promise<string | null>;
3563
+ /**
3564
+ * Check if token needs refresh
3565
+ *
3566
+ * @param tokens - Token set to check
3567
+ * @returns True if token should be refreshed
3568
+ */
3569
+ private shouldRefresh;
3570
+ /**
3571
+ * Refresh token with in-flight request coalescing
3572
+ *
3573
+ * If a refresh is already in progress, wait for it instead of
3574
+ * starting a new one.
3575
+ *
3576
+ * @param refreshToken - Refresh token to use
3577
+ * @param reason - Reason for refresh
3578
+ * @returns Access token from new token set
3579
+ */
3580
+ private refreshWithLock;
3581
+ /**
3582
+ * Manually refresh tokens
3583
+ *
3584
+ * @returns New token set
3585
+ * @throws AuthrimError if refresh fails
3586
+ */
3587
+ refresh(): Promise<TokenSet>;
3588
+ /**
3589
+ * Perform refresh with retry for network errors
3590
+ *
3591
+ * @param refreshToken - Refresh token to use
3592
+ * @param reason - Reason for refresh
3593
+ * @param attempt - Current retry attempt (0-indexed)
3594
+ * @returns New token set
3595
+ */
3596
+ private doRefreshWithRetry;
3597
+ /**
3598
+ * Perform the actual token refresh
3599
+ *
3600
+ * @param refreshToken - Refresh token to use
3601
+ * @returns New token set
3602
+ */
3603
+ private doRefresh;
3604
+ /**
3605
+ * Check if user is authenticated
3606
+ *
3607
+ * @returns True if valid tokens exist
3608
+ */
3609
+ isAuthenticated(): Promise<boolean>;
3610
+ /**
3611
+ * Exchange a token using RFC 8693 Token Exchange
3612
+ *
3613
+ * This allows exchanging tokens for different audiences or scopes,
3614
+ * delegation scenarios, and cross-service token acquisition.
3615
+ *
3616
+ * @param request - Token exchange request parameters
3617
+ * @returns Token exchange result with new tokens and issued token type
3618
+ * @throws AuthrimError if exchange fails
3619
+ */
3620
+ exchangeToken(request: TokenExchangeRequest): Promise<TokenExchangeResult>;
3621
+ /**
3622
+ * Map short token type to URI (RFC 8693)
3623
+ */
3624
+ private mapTokenTypeToUri;
3625
+ /**
3626
+ * Clean up resources
3627
+ */
3628
+ destroy(): void;
3629
+ }
3630
+
3631
+ /**
3632
+ * Auto Refresh Scheduler
3633
+ *
3634
+ * Automatically refreshes tokens before they expire.
3635
+ * Supports cancellation via AbortController.
3636
+ */
3637
+
3638
+ /**
3639
+ * Auto refresh options
3640
+ */
3641
+ interface AutoRefreshOptions {
3642
+ /** Refresh threshold in seconds before expiry (default: 60) */
3643
+ thresholdSeconds?: number;
3644
+ /** Check interval in milliseconds (default: 30000 = 30 seconds) */
3645
+ checkIntervalMs?: number;
3646
+ /** Event emitter for logging/debugging */
3647
+ eventEmitter?: EventEmitter;
3648
+ }
3649
+ /**
3650
+ * Auto Refresh Scheduler
3651
+ *
3652
+ * Schedules automatic token refresh before expiration.
3653
+ * Can be stopped and started as needed.
3654
+ */
3655
+ declare class AutoRefreshScheduler {
3656
+ private tokenManager;
3657
+ private options;
3658
+ private checkInterval;
3659
+ private abortController;
3660
+ private isRunning;
3661
+ /** Default refresh threshold: 60 seconds */
3662
+ private static readonly DEFAULT_THRESHOLD_SECONDS;
3663
+ /** Default check interval: 30 seconds */
3664
+ private static readonly DEFAULT_CHECK_INTERVAL_MS;
3665
+ constructor(options?: AutoRefreshOptions);
3666
+ /**
3667
+ * Start auto-refresh scheduling
3668
+ *
3669
+ * @param tokenManager - Token manager instance
3670
+ */
3671
+ start(tokenManager: TokenManager): void;
3672
+ /**
3673
+ * Stop auto-refresh scheduling
3674
+ */
3675
+ stop(): void;
3676
+ /**
3677
+ * Check if scheduler is running
3678
+ */
3679
+ get running(): boolean;
3680
+ /**
3681
+ * Get the abort signal for external cancellation support
3682
+ */
3683
+ get signal(): AbortSignal | null;
3684
+ /**
3685
+ * Check if token needs refresh and perform if needed
3686
+ */
3687
+ private checkAndRefresh;
3688
+ /**
3689
+ * Force an immediate refresh check
3690
+ */
3691
+ forceCheck(): Promise<void>;
3692
+ }
3693
+
3694
+ /**
3695
+ * Token API Client
3696
+ *
3697
+ * Provides session verification against the authorization server.
3698
+ * Uses the UserInfo endpoint or custom session check endpoint.
3699
+ */
3700
+
3701
+ /**
3702
+ * Session check result
3703
+ */
3704
+ interface SessionCheckResult {
3705
+ /** Whether session is valid */
3706
+ valid: boolean;
3707
+ /** User info if session is valid */
3708
+ user?: UserInfo;
3709
+ /** Error if session is invalid */
3710
+ error?: AuthrimError;
3711
+ }
3712
+ /**
3713
+ * Token API client options
3714
+ */
3715
+ interface TokenApiClientOptions {
3716
+ /** HTTP client */
3717
+ http: HttpClient;
3718
+ }
3719
+ /**
3720
+ * Token API Client
3721
+ *
3722
+ * Verifies session status with the authorization server.
3723
+ */
3724
+ declare class TokenApiClient {
3725
+ private readonly http;
3726
+ constructor(options: TokenApiClientOptions);
3727
+ /**
3728
+ * Check session validity by calling UserInfo endpoint
3729
+ *
3730
+ * @param discovery - OIDC discovery document
3731
+ * @param accessToken - Access token to verify
3732
+ * @returns Session check result
3733
+ */
3734
+ checkSession(discovery: OIDCDiscoveryDocument, accessToken: string): Promise<SessionCheckResult>;
3735
+ /**
3736
+ * Get user info from the authorization server
3737
+ *
3738
+ * @param discovery - OIDC discovery document
3739
+ * @param accessToken - Access token
3740
+ * @returns User info
3741
+ * @throws AuthrimError if request fails
3742
+ */
3743
+ getUserInfo(discovery: OIDCDiscoveryDocument, accessToken: string): Promise<UserInfo>;
3744
+ }
3745
+
3746
+ /**
3747
+ * Session Manager
3748
+ *
3749
+ * Coordinates session-related operations including checking
3750
+ * session status and retrieving user information.
3751
+ */
3752
+
3753
+ /**
3754
+ * Session manager options
3755
+ */
3756
+ interface SessionManagerOptions {
3757
+ /** Token manager */
3758
+ tokenManager: TokenManager;
3759
+ /** Token API client */
3760
+ tokenApiClient: TokenApiClient;
3761
+ }
3762
+ /**
3763
+ * Session Manager
3764
+ */
3765
+ declare class SessionManager {
3766
+ private readonly tokenManager;
3767
+ private readonly tokenApiClient;
3768
+ /** Discovery document */
3769
+ private discovery;
3770
+ constructor(options: SessionManagerOptions);
3771
+ /**
3772
+ * Set discovery document
3773
+ */
3774
+ setDiscovery(discovery: OIDCDiscoveryDocument): void;
3775
+ /**
3776
+ * Check if user is authenticated locally
3777
+ *
3778
+ * This checks if valid tokens exist in storage.
3779
+ * Does not verify with the authorization server.
3780
+ *
3781
+ * @returns True if tokens exist
3782
+ */
3783
+ isAuthenticated(): Promise<boolean>;
3784
+ /**
3785
+ * Check session validity with authorization server
3786
+ *
3787
+ * Calls the UserInfo endpoint to verify the session is still valid.
3788
+ *
3789
+ * @returns Session check result
3790
+ */
3791
+ checkSession(): Promise<SessionCheckResult>;
3792
+ /**
3793
+ * Get user information
3794
+ *
3795
+ * Fetches user info from the UserInfo endpoint.
3796
+ *
3797
+ * @returns User info
3798
+ * @throws AuthrimError if not authenticated or request fails
3799
+ */
3800
+ getUser(): Promise<UserInfo>;
3801
+ }
3802
+
3803
+ /**
3804
+ * Session State Calculator
1989
3805
  *
1990
- * @param base64url - Base64URL encoded string
1991
- * @returns Decoded string (UTF-8)
3806
+ * Implements OIDC Session Management 1.0 specification
3807
+ * https://openid.net/specs/openid-connect-session-1_0.html
3808
+ *
3809
+ * session_state = hash(client_id + " " + origin + " " + browser_state + salt) + "." + salt
1992
3810
  */
1993
- declare function base64urlToString(base64url: string): string;
3811
+
3812
+ /**
3813
+ * Parameters for calculating session_state
3814
+ */
3815
+ interface SessionStateParams {
3816
+ /** OAuth client_id */
3817
+ clientId: string;
3818
+ /** RP origin (e.g., "https://example.com") */
3819
+ origin: string;
3820
+ /**
3821
+ * OP-managed browser state (opaque value)
3822
+ *
3823
+ * Per OIDC Session Management 1.0 spec, this is called "browser_state" but is actually
3824
+ * an opaque value managed by the OP to identify the session at the OP.
3825
+ * It is NOT a value managed by the RP's browser.
3826
+ */
3827
+ opBrowserState: string;
3828
+ /** Optional salt (generated if not provided) */
3829
+ salt?: string;
3830
+ }
3831
+ /**
3832
+ * Result of session_state calculation
3833
+ */
3834
+ interface SessionStateResult {
3835
+ /** Full session_state value (hash.salt) */
3836
+ sessionState: string;
3837
+ /** Hash portion of session_state */
3838
+ hash: string;
3839
+ /** Salt used in calculation */
3840
+ salt: string;
3841
+ }
3842
+ /**
3843
+ * Options for SessionStateCalculator
3844
+ */
3845
+ interface SessionStateCalculatorOptions {
3846
+ /** Crypto provider for hashing */
3847
+ crypto: CryptoProvider;
3848
+ }
3849
+ /**
3850
+ * Session State Calculator
3851
+ *
3852
+ * Calculates and validates session_state values per OIDC Session Management 1.0.
3853
+ *
3854
+ * Usage (OP side - calculating session_state to include in auth response):
3855
+ * ```typescript
3856
+ * const calculator = new SessionStateCalculator({ crypto });
3857
+ * const result = await calculator.calculate({
3858
+ * clientId: 'my-client',
3859
+ * origin: 'https://rp.example.com',
3860
+ * opBrowserState: 'op-session-id-xyz'
3861
+ * });
3862
+ * // result.sessionState -> include in auth response
3863
+ * ```
3864
+ *
3865
+ * Usage (RP check_session_iframe - validating session state):
3866
+ * ```typescript
3867
+ * const isValid = await calculator.validate(sessionState, {
3868
+ * clientId: 'my-client',
3869
+ * origin: 'https://rp.example.com',
3870
+ * opBrowserState: 'op-session-id-xyz'
3871
+ * });
3872
+ * ```
3873
+ */
3874
+ declare class SessionStateCalculator {
3875
+ private readonly crypto;
3876
+ constructor(options: SessionStateCalculatorOptions);
3877
+ /**
3878
+ * Calculate session_state
3879
+ *
3880
+ * Per OIDC Session Management 1.0:
3881
+ * session_state = hash(client_id + " " + origin + " " + browser_state + salt) + "." + salt
3882
+ *
3883
+ * @param params - Parameters for calculation
3884
+ * @returns Session state result
3885
+ */
3886
+ calculate(params: SessionStateParams): Promise<SessionStateResult>;
3887
+ /**
3888
+ * Validate session_state
3889
+ *
3890
+ * Uses constant-time comparison to prevent timing attacks.
3891
+ *
3892
+ * @param sessionState - session_state value to validate
3893
+ * @param params - Parameters that should match (without salt, extracted from sessionState)
3894
+ * @returns true if valid
3895
+ */
3896
+ validate(sessionState: string, params: Omit<SessionStateParams, 'salt'>): Promise<boolean>;
3897
+ /**
3898
+ * Parse session_state into hash and salt components
3899
+ *
3900
+ * @param sessionState - session_state value to parse
3901
+ * @returns Parsed components or null if invalid format
3902
+ */
3903
+ parse(sessionState: string): {
3904
+ hash: string;
3905
+ salt: string;
3906
+ } | null;
3907
+ }
3908
+
3909
+ /**
3910
+ * Front-Channel Logout URL Builder
3911
+ *
3912
+ * Implements OpenID Connect Front-Channel Logout 1.0
3913
+ * https://openid.net/specs/openid-connect-frontchannel-1_0.html
3914
+ *
3915
+ * Front-channel logout allows the OP to notify RPs of logout events
3916
+ * via browser redirects (iframes loaded by the OP's logout page).
3917
+ */
3918
+
3919
+ /**
3920
+ * Result of building a front-channel logout URL
3921
+ */
3922
+ interface FrontChannelLogoutUrlResult {
3923
+ /** Complete logout URL with query parameters */
3924
+ url: string;
3925
+ /** Parameters included in the URL */
3926
+ params: FrontChannelLogoutParams;
3927
+ }
3928
+ /**
3929
+ * Parameters for building a front-channel logout URL
3930
+ */
3931
+ interface FrontChannelLogoutBuildParams {
3932
+ /** Issuer identifier to include (optional) */
3933
+ iss?: string;
3934
+ /** Session ID to include (optional) */
3935
+ sid?: string;
3936
+ }
3937
+ /**
3938
+ * Validation options for front-channel logout requests
3939
+ */
3940
+ interface FrontChannelLogoutValidationOptions {
3941
+ /** Expected issuer (for validation) */
3942
+ issuer?: string;
3943
+ /** Expected session ID (for validation) */
3944
+ sessionId?: string;
3945
+ /** Require issuer parameter */
3946
+ requireIss?: boolean;
3947
+ /** Require session ID parameter */
3948
+ requireSid?: boolean;
3949
+ }
3950
+ /**
3951
+ * Result of front-channel logout request validation
3952
+ */
3953
+ interface FrontChannelLogoutValidationResult {
3954
+ /** Whether the request is valid */
3955
+ valid: boolean;
3956
+ /** Parsed parameters (if valid) */
3957
+ params?: FrontChannelLogoutParams;
3958
+ /** Error message (if invalid) */
3959
+ error?: string;
3960
+ }
3961
+ /**
3962
+ * Front-Channel Logout URL Builder
3963
+ *
3964
+ * Builds and validates front-channel logout URLs per OIDC Front-Channel Logout 1.0.
3965
+ *
3966
+ * Usage (OP side - building logout URL to load in iframe):
3967
+ * ```typescript
3968
+ * const builder = new FrontChannelLogoutUrlBuilder();
3969
+ * const result = builder.build(
3970
+ * { logoutUri: 'https://rp.example.com/logout', includeIssuer: true, includeSessionId: true },
3971
+ * { iss: 'https://op.example.com', sid: 'session-123' }
3972
+ * );
3973
+ * // result.url -> load in iframe
3974
+ * ```
3975
+ *
3976
+ * Usage (RP side - validating incoming logout request):
3977
+ * ```typescript
3978
+ * const result = builder.validateRequest(window.location.href, {
3979
+ * issuer: 'https://op.example.com',
3980
+ * requireIss: true
3981
+ * });
3982
+ * if (result.valid) {
3983
+ * // Perform local logout
3984
+ * }
3985
+ * ```
3986
+ */
3987
+ declare class FrontChannelLogoutUrlBuilder {
3988
+ /**
3989
+ * Build a front-channel logout URL
3990
+ *
3991
+ * @param options - URL configuration options
3992
+ * @param params - Parameters to include in the URL
3993
+ * @returns Built URL and included parameters
3994
+ */
3995
+ build(options: FrontChannelLogoutUrlOptions, params: FrontChannelLogoutBuildParams): FrontChannelLogoutUrlResult;
3996
+ /**
3997
+ * Parse parameters from a front-channel logout URL
3998
+ *
3999
+ * @param url - URL or URL string to parse
4000
+ * @returns Parsed parameters
4001
+ */
4002
+ parseParams(url: string | URL): FrontChannelLogoutParams;
4003
+ /**
4004
+ * Validate a front-channel logout request
4005
+ *
4006
+ * Uses constant-time comparison for security-sensitive values to prevent timing attacks.
4007
+ *
4008
+ * @param url - URL to validate
4009
+ * @param expected - Expected values and requirements
4010
+ * @returns Validation result
4011
+ */
4012
+ validateRequest(url: string | URL, expected?: FrontChannelLogoutValidationOptions): FrontChannelLogoutValidationResult;
4013
+ }
1994
4014
 
1995
4015
  /**
1996
4016
  * JWT Utilities
@@ -2050,12 +4070,375 @@ declare function isJwtExpired(payload: {
2050
4070
  exp?: number;
2051
4071
  }, skewSeconds?: number): boolean;
2052
4072
  /**
2053
- * Get the nonce claim from an ID token
4073
+ * Get the nonce claim from an ID token
4074
+ *
4075
+ * @param idToken - ID token string
4076
+ * @returns nonce value or undefined
4077
+ */
4078
+ declare function getIdTokenNonce(idToken: string): string | undefined;
4079
+
4080
+ /**
4081
+ * Back-Channel Logout Validator
4082
+ *
4083
+ * Implements OpenID Connect Back-Channel Logout 1.0
4084
+ * https://openid.net/specs/openid-connect-backchannel-1_0.html
4085
+ *
4086
+ * Back-channel logout allows the OP to notify RPs of logout events
4087
+ * via direct HTTP calls (server-to-server).
4088
+ *
4089
+ * NOTE: This validator performs claims validation only.
4090
+ * JWT signature verification MUST be performed separately using JWKS.
4091
+ */
4092
+
4093
+ /**
4094
+ * Back-channel logout event URI
4095
+ */
4096
+ declare const BACKCHANNEL_LOGOUT_EVENT = "http://schemas.openid.net/event/backchannel-logout";
4097
+ /**
4098
+ * Back-channel logout validation error codes
4099
+ */
4100
+ type BackChannelLogoutErrorCode = 'invalid_format' | 'invalid_issuer' | 'invalid_audience' | 'invalid_events' | 'expired' | 'not_yet_valid' | 'missing_sub_and_sid' | 'sub_mismatch' | 'sid_mismatch' | 'missing_jti' | 'nonce_present';
4101
+ /**
4102
+ * Options for validating a logout token
4103
+ */
4104
+ interface BackChannelLogoutValidationOptions {
4105
+ /** Expected issuer */
4106
+ issuer: string;
4107
+ /** Expected audience (client_id) */
4108
+ audience: string;
4109
+ /** Maximum age in seconds (default: 60) */
4110
+ maxAge?: number;
4111
+ /** Clock skew tolerance in seconds (default: 30) */
4112
+ clockSkew?: number;
4113
+ /** Expected session ID (optional) */
4114
+ expectedSid?: string;
4115
+ /** Expected subject (optional) */
4116
+ expectedSub?: string;
4117
+ }
4118
+ /**
4119
+ * Result of back-channel logout token validation
4120
+ */
4121
+ interface BackChannelLogoutValidationResult {
4122
+ /** Whether the token is valid */
4123
+ valid: boolean;
4124
+ /** Validated claims (if valid) */
4125
+ claims?: LogoutTokenClaims;
4126
+ /** JWT header (if valid) */
4127
+ header?: JwtHeader;
4128
+ /** Error message (if invalid) */
4129
+ error?: string;
4130
+ /** Error code (if invalid) */
4131
+ errorCode?: BackChannelLogoutErrorCode;
4132
+ }
4133
+ /**
4134
+ * Back-Channel Logout Validator
4135
+ *
4136
+ * Validates logout_token JWTs per OIDC Back-Channel Logout 1.0.
4137
+ *
4138
+ * ## Security Notes
4139
+ *
4140
+ * 1. **JWT Signature Verification**: This class performs claims validation only.
4141
+ * JWT signature verification MUST be performed separately using JWKS
4142
+ * before calling validate().
4143
+ *
4144
+ * 2. **JTI Replay Protection**: This validator checks for jti presence only.
4145
+ * The application MUST implement jti replay protection by:
4146
+ * - Storing used jti values (at least until token expiry + clock skew)
4147
+ * - Rejecting tokens with previously-used jti values
4148
+ *
4149
+ * Usage (Node.js server receiving back-channel logout request):
4150
+ * ```typescript
4151
+ * // 1. Receive logout_token from POST body
4152
+ * const logoutToken = req.body.logout_token;
4153
+ *
4154
+ * // 2. Verify JWT signature using JWKS (not shown - use jose or similar)
4155
+ * await verifyJwtSignature(logoutToken, jwks);
4156
+ *
4157
+ * // 3. Validate claims
4158
+ * const validator = new BackChannelLogoutValidator();
4159
+ * const result = validator.validate(logoutToken, {
4160
+ * issuer: 'https://op.example.com',
4161
+ * audience: 'my-client-id'
4162
+ * });
4163
+ *
4164
+ * if (!result.valid) {
4165
+ * return res.status(400).send('Invalid logout token');
4166
+ * }
4167
+ *
4168
+ * // 4. Check for jti replay (application responsibility)
4169
+ * if (await jtiStore.has(result.claims.jti)) {
4170
+ * return res.status(400).send('Token replay detected');
4171
+ * }
4172
+ * await jtiStore.set(result.claims.jti, true, maxAge + clockSkew);
4173
+ *
4174
+ * // 5. Perform logout for sub and/or sid
4175
+ * await logoutUser(result.claims.sub, result.claims.sid);
4176
+ * ```
4177
+ */
4178
+ declare class BackChannelLogoutValidator {
4179
+ /**
4180
+ * Validate a logout_token
4181
+ *
4182
+ * Per OIDC Back-Channel Logout 1.0, the logout_token MUST:
4183
+ * - Be a valid JWT
4184
+ * - Contain iss, aud, iat, jti claims
4185
+ * - Contain events claim with back-channel logout event
4186
+ * - Contain either sub or sid (or both)
4187
+ * - NOT contain a nonce claim
4188
+ *
4189
+ * @param logoutToken - JWT logout token to validate
4190
+ * @param options - Validation options
4191
+ * @returns Validation result
4192
+ */
4193
+ validate(logoutToken: string, options: BackChannelLogoutValidationOptions): BackChannelLogoutValidationResult;
4194
+ /**
4195
+ * Extract claims from a logout token without validation
4196
+ *
4197
+ * Useful for inspecting the token before/during validation.
4198
+ *
4199
+ * @param logoutToken - JWT logout token
4200
+ * @returns Claims or null if invalid format
4201
+ */
4202
+ extractClaims(logoutToken: string): LogoutTokenClaims | null;
4203
+ /**
4204
+ * Extract header from a logout token without validation
4205
+ *
4206
+ * Useful for getting kid to select the correct JWKS key.
4207
+ *
4208
+ * @param logoutToken - JWT logout token
4209
+ * @returns Header or null if invalid format
4210
+ */
4211
+ extractHeader(logoutToken: string): JwtHeader | null;
4212
+ }
4213
+
4214
+ /**
4215
+ * Debug Module Types
4216
+ *
4217
+ * Types for debugging and observability features.
4218
+ */
4219
+ /**
4220
+ * Debug options for SDK initialization
4221
+ */
4222
+ interface DebugOptions {
4223
+ /** Enable debug mode */
4224
+ enabled: boolean;
4225
+ /** Enable verbose logging */
4226
+ verbose?: boolean;
4227
+ /** Include timestamps in logs */
4228
+ logTimestamps?: boolean;
4229
+ /** Custom logger implementation */
4230
+ logger?: DebugLogger;
4231
+ /** Maximum events to keep in timeline (default: 100) */
4232
+ maxTimelineEvents?: number;
4233
+ /** Redaction level for sensitive data */
4234
+ redactLevel?: RedactLevel;
4235
+ }
4236
+ /**
4237
+ * Debug logger interface
4238
+ */
4239
+ interface DebugLogger {
4240
+ /** Log a message with optional data */
4241
+ log(level: DebugLogLevel, message: string, data?: unknown): void;
4242
+ }
4243
+ /**
4244
+ * Debug log levels
4245
+ */
4246
+ type DebugLogLevel = 'debug' | 'info' | 'warn' | 'error';
4247
+ /**
4248
+ * Redaction level for sensitive data
4249
+ *
4250
+ * - 'default': Mask token values, keep structure
4251
+ * - 'none': No redaction (only for development)
4252
+ * - 'aggressive': Mask tokens and URL parameters
4253
+ */
4254
+ type RedactLevel = 'default' | 'none' | 'aggressive';
4255
+
4256
+ /**
4257
+ * Event Timeline
4258
+ *
4259
+ * Records SDK events for debugging and observability.
4260
+ * All sensitive data is automatically redacted.
4261
+ */
4262
+
4263
+ /**
4264
+ * Event Timeline for debugging
4265
+ *
4266
+ * Records events with automatic redaction of sensitive data.
4267
+ * Safe to use in production - no sensitive data is stored.
4268
+ */
4269
+ declare class EventTimeline {
4270
+ private entries;
4271
+ private maxEvents;
4272
+ private redactLevel;
4273
+ constructor(options?: {
4274
+ maxEvents?: number;
4275
+ redactLevel?: RedactLevel;
4276
+ });
4277
+ /**
4278
+ * Record an event to the timeline
4279
+ *
4280
+ * Data is automatically redacted based on redact level.
4281
+ *
4282
+ * @param type - Event type
4283
+ * @param data - Event data (will be redacted)
4284
+ * @param options - Recording options
4285
+ */
4286
+ record(type: string, data?: unknown, options?: {
4287
+ operationId?: string;
4288
+ redact?: RedactLevel;
4289
+ }): void;
4290
+ /**
4291
+ * Get recent entries
4292
+ *
4293
+ * @param count - Number of entries to return (default: all)
4294
+ * @returns Recent timeline entries
4295
+ */
4296
+ getRecent(count?: number): TimelineEntry[];
4297
+ /**
4298
+ * Get entries for a specific operation
4299
+ *
4300
+ * @param operationId - Operation ID to filter by
4301
+ * @returns Entries for the operation
4302
+ */
4303
+ getByOperationId(operationId: string): TimelineEntry[];
4304
+ /**
4305
+ * Get entries by event type
4306
+ *
4307
+ * @param type - Event type to filter by
4308
+ * @returns Entries matching the type
4309
+ */
4310
+ getByType(type: string): TimelineEntry[];
4311
+ /**
4312
+ * Clear all entries
4313
+ */
4314
+ clear(): void;
4315
+ /**
4316
+ * Get entry count
4317
+ */
4318
+ get length(): number;
4319
+ /**
4320
+ * Convert timeline to JSON string (for export/logging)
4321
+ */
4322
+ toJSON(): string;
4323
+ /**
4324
+ * Set redaction level
4325
+ */
4326
+ setRedactLevel(level: RedactLevel): void;
4327
+ /**
4328
+ * Redact sensitive data from event payload
4329
+ */
4330
+ private redactData;
4331
+ /**
4332
+ * Deep redact an object
4333
+ */
4334
+ private deepRedact;
4335
+ /**
4336
+ * Check if a key is sensitive
4337
+ */
4338
+ private isSensitiveKey;
4339
+ /**
4340
+ * Redact sensitive URL parameters
4341
+ */
4342
+ private redactUrl;
4343
+ }
4344
+
4345
+ /**
4346
+ * Debug Logger
4347
+ *
4348
+ * Platform-agnostic logging infrastructure for SDK debugging.
4349
+ */
4350
+
4351
+ /**
4352
+ * Create a console-based debug logger
4353
+ *
4354
+ * This logger writes to console with Authrim-prefixed messages.
4355
+ * Safe to use with any console implementation.
4356
+ */
4357
+ declare function createConsoleLogger(options?: {
4358
+ timestamps?: boolean;
4359
+ }): DebugLogger;
4360
+ /**
4361
+ * No-op logger for when debug mode is disabled
4362
+ */
4363
+ declare const noopLogger: DebugLogger;
4364
+ /**
4365
+ * Create a debug logger based on options
4366
+ */
4367
+ declare function createDebugLogger(options: DebugOptions): DebugLogger;
4368
+ /**
4369
+ * Debug context for tracking operations
4370
+ */
4371
+ declare class DebugContext {
4372
+ private logger;
4373
+ private verbose;
4374
+ private operationId;
4375
+ constructor(logger: DebugLogger, options?: {
4376
+ verbose?: boolean;
4377
+ });
4378
+ /**
4379
+ * Set current operation ID for log correlation
4380
+ */
4381
+ setOperationId(id: string | null): void;
4382
+ /**
4383
+ * Get current operation ID
4384
+ */
4385
+ getOperationId(): string | null;
4386
+ /**
4387
+ * Log a debug message (verbose mode only)
4388
+ */
4389
+ debug(message: string, data?: unknown): void;
4390
+ /**
4391
+ * Log an info message
4392
+ */
4393
+ info(message: string, data?: unknown): void;
4394
+ /**
4395
+ * Log a warning message
4396
+ */
4397
+ warn(message: string, data?: unknown): void;
4398
+ /**
4399
+ * Log an error message
4400
+ */
4401
+ error(message: string, data?: unknown): void;
4402
+ /**
4403
+ * Format message with operation ID if available
4404
+ */
4405
+ private formatMessage;
4406
+ }
4407
+
4408
+ /**
4409
+ * Base64URL Encoding/Decoding Utilities
4410
+ *
4411
+ * Implements RFC 4648 Section 5 (Base64 URL and Filename Safe Alphabet)
4412
+ */
4413
+ /**
4414
+ * Encode a Uint8Array to base64url string
4415
+ *
4416
+ * @param data - Bytes to encode
4417
+ * @returns Base64URL encoded string (no padding)
4418
+ */
4419
+ declare function base64urlEncode(data: Uint8Array): string;
4420
+ /**
4421
+ * Decode a base64url string to Uint8Array
4422
+ *
4423
+ * @param str - Base64URL encoded string
4424
+ * @returns Decoded bytes
4425
+ * @throws Error if the input contains invalid characters
4426
+ */
4427
+ declare function base64urlDecode(str: string): Uint8Array;
4428
+ /**
4429
+ * Encode a string to base64url
4430
+ *
4431
+ * @param str - String to encode (UTF-8)
4432
+ * @returns Base64URL encoded string
4433
+ */
4434
+ declare function stringToBase64url(str: string): string;
4435
+ /**
4436
+ * Decode a base64url string to string
2054
4437
  *
2055
- * @param idToken - ID token string
2056
- * @returns nonce value or undefined
4438
+ * @param base64url - Base64URL encoded string
4439
+ * @returns Decoded string (UTF-8)
2057
4440
  */
2058
- declare function getIdTokenNonce(idToken: string): string | undefined;
4441
+ declare function base64urlToString(base64url: string): string;
2059
4442
 
2060
4443
  /**
2061
4444
  * Hash Utilities
@@ -2087,4 +4470,691 @@ declare function getIdTokenNonce(idToken: string): string | undefined;
2087
4470
  */
2088
4471
  declare function calculateDsHash(deviceSecret: string, crypto: CryptoProvider): Promise<string>;
2089
4472
 
2090
- export { type AddressClaim, type AuthCallbackEvent, type AuthRedirectingEvent, type AuthState, AuthorizationCodeFlow, type AuthorizationContext, type AuthorizationUrlResult, AuthrimClient, type AuthrimClientConfig, AuthrimError, type AuthrimErrorCode, type AuthrimErrorMeta, type AuthrimErrorOptions, type AuthrimErrorSeverity, type AuthrimErrorUserAction, type AuthrimEventHandler, type AuthrimEventName, type AuthrimEvents, type AuthrimStorage, type BuildAuthorizationUrlOptions, type CodeChallengeMethod, type CryptoProvider, type DecodedJwt, DiscoveryClient, type EndpointOverrides, type ErrorEvent, EventEmitter, type ExchangeCodeOptions, type GenerateAuthStateOptions, type HashOptions, type HttpClient, type HttpOptions, type HttpResponse, type IntrospectTokenOptions, type IntrospectionResponse, type IntrospectionTokenTypeHint, type JwtHeader, LogoutHandler, type LogoutHandlerOptions, type LogoutOptions, type LogoutResult, type OIDCDiscoveryDocument, PKCEHelper, type PKCEPair, type ResolvedConfig, type RevokeTokenOptions, STORAGE_KEYS, type SessionCheckResult, type SessionEndedEvent, SessionManager, type SessionManagerOptions, type SessionStartedEvent, SilentAuthHandler, type SilentAuthOptions, type SilentAuthResult, type SilentAuthUrlResult, type StandardClaims, StateManager, TOKEN_TYPE_URIS, TokenApiClient, type TokenApiClientOptions, type TokenErrorEvent, type TokenExchangeRequest, type TokenExchangeResponse, type TokenExchangeResult, type TokenExchangedEvent, type TokenExpiredEvent, TokenIntrospector, type TokenIntrospectorOptions, TokenManager, type TokenManagerOptions, type TokenRefreshedEvent, type TokenResponse, TokenRevoker, type TokenRevokerOptions, type TokenSet, type TokenTypeHint, type TokenTypeUri, type UserInfo, base64urlDecode, base64urlEncode, base64urlToString, calculateDsHash, createAuthrimClient, decodeIdToken, decodeJwt, getErrorMeta, getIdTokenNonce, isJwtExpired, normalizeIssuer, resolveConfig, stringToBase64url };
4473
+ /**
4474
+ * Timing-Safe Comparison Utilities
4475
+ *
4476
+ * Provides constant-time string comparison to prevent timing attacks.
4477
+ * Used for comparing security-sensitive values like nonces and states.
4478
+ */
4479
+ /**
4480
+ * Compare two strings in constant time
4481
+ *
4482
+ * This function always takes the same amount of time regardless of
4483
+ * where the strings differ, preventing timing attacks.
4484
+ *
4485
+ * @param a - First string
4486
+ * @param b - Second string
4487
+ * @returns true if strings are equal, false otherwise
4488
+ */
4489
+ declare function timingSafeEqual(a: string, b: string): boolean;
4490
+
4491
+ /**
4492
+ * Cancellation Utilities
4493
+ *
4494
+ * Provides AbortController-based cancellation for async operations.
4495
+ */
4496
+ /**
4497
+ * Wrap a promise with AbortSignal support
4498
+ *
4499
+ * If the signal is aborted, the promise will reject with an
4500
+ * 'operation_cancelled' error which is recoverable and retryable.
4501
+ *
4502
+ * @param promise - Promise to wrap
4503
+ * @param signal - AbortSignal to use for cancellation
4504
+ * @returns Promise that can be cancelled
4505
+ */
4506
+ declare function withAbortSignal<T>(promise: Promise<T>, signal: AbortSignal): Promise<T>;
4507
+ /**
4508
+ * Create a cancellable operation wrapper
4509
+ *
4510
+ * Returns an object with the promise and a cancel function.
4511
+ * Useful for creating operations that can be externally cancelled.
4512
+ *
4513
+ * @param fn - Async function to execute
4514
+ * @returns Object with promise and cancel function
4515
+ */
4516
+ declare function createCancellableOperation<T>(fn: (signal: AbortSignal) => Promise<T>): {
4517
+ promise: Promise<T>;
4518
+ cancel: () => void;
4519
+ signal: AbortSignal;
4520
+ };
4521
+ /**
4522
+ * Check if an error is a cancellation error
4523
+ */
4524
+ declare function isCancellationError(error: unknown): boolean;
4525
+ /**
4526
+ * Race multiple promises with cancellation support
4527
+ *
4528
+ * When one promise resolves, other operations are cancelled.
4529
+ *
4530
+ * @param operations - Array of operations with their signals
4531
+ * @returns Result of the first successful operation
4532
+ */
4533
+ declare function raceWithCancellation<T>(operations: Array<{
4534
+ promise: Promise<T>;
4535
+ cancel: () => void;
4536
+ }>): Promise<T>;
4537
+
4538
+ /**
4539
+ * Retry Utilities
4540
+ *
4541
+ * Provides exponential backoff retry logic with jitter.
4542
+ */
4543
+ /**
4544
+ * Retry options
4545
+ */
4546
+ interface RetryOptions {
4547
+ /** Maximum number of retry attempts (default: 3) */
4548
+ maxRetries?: number;
4549
+ /** Base delay in milliseconds (default: 1000) */
4550
+ baseDelayMs?: number;
4551
+ /** Maximum delay in milliseconds (default: 30000) */
4552
+ maxDelayMs?: number;
4553
+ /** Enable jitter for delay randomization (default: true) */
4554
+ jitter?: boolean;
4555
+ /** AbortSignal for cancellation */
4556
+ signal?: AbortSignal;
4557
+ /** Custom retry condition (default: check isRetryableError) */
4558
+ shouldRetry?: (error: unknown, attempt: number) => boolean;
4559
+ /** Callback for each retry attempt */
4560
+ onRetry?: (error: unknown, attempt: number, delayMs: number) => void;
4561
+ }
4562
+ /**
4563
+ * Calculate delay with exponential backoff and optional jitter
4564
+ *
4565
+ * @param attempt - Current attempt number (0-indexed)
4566
+ * @param baseDelayMs - Base delay in milliseconds
4567
+ * @param maxDelayMs - Maximum delay in milliseconds
4568
+ * @param jitter - Whether to add jitter
4569
+ * @returns Delay in milliseconds
4570
+ */
4571
+ declare function calculateBackoffDelay(attempt: number, baseDelayMs: number, maxDelayMs: number, jitter: boolean): number;
4572
+ /**
4573
+ * Sleep for a specified duration
4574
+ *
4575
+ * @param ms - Duration in milliseconds
4576
+ * @param signal - Optional AbortSignal for cancellation
4577
+ */
4578
+ declare function sleep(ms: number, signal?: AbortSignal): Promise<void>;
4579
+ /**
4580
+ * Execute a function with exponential backoff retry
4581
+ *
4582
+ * @param fn - Function to execute
4583
+ * @param options - Retry options
4584
+ * @returns Result of the function
4585
+ */
4586
+ declare function withRetry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
4587
+ /**
4588
+ * Create a retry function with preset options
4589
+ *
4590
+ * Useful for creating specialized retry functions for specific use cases.
4591
+ *
4592
+ * @param defaultOptions - Default options for all retries
4593
+ * @returns Retry function with preset options
4594
+ */
4595
+ declare function createRetryFunction(defaultOptions: RetryOptions): <T>(fn: () => Promise<T>, options?: RetryOptions) => Promise<T>;
4596
+ /**
4597
+ * Extract Retry-After header value
4598
+ *
4599
+ * Supports both HTTP-date and delay-seconds formats.
4600
+ *
4601
+ * @param headers - Response headers
4602
+ * @returns Delay in milliseconds, or null if not found
4603
+ */
4604
+ declare function parseRetryAfterHeader(headers: Headers | Record<string, string>): number | null;
4605
+
4606
+ /**
4607
+ * Direct Authentication API Types
4608
+ *
4609
+ * Simple and intuitive BetterAuth-style API type definitions
4610
+ * for calling Authrim API directly from custom login pages.
4611
+ */
4612
+ /**
4613
+ * Authenticator transport type
4614
+ */
4615
+ type AuthenticatorTransportType = 'usb' | 'nfc' | 'ble' | 'internal' | 'hybrid';
4616
+ /**
4617
+ * User verification requirement
4618
+ */
4619
+ type UserVerificationRequirementType = 'required' | 'preferred' | 'discouraged';
4620
+ /**
4621
+ * Authenticator attachment
4622
+ */
4623
+ type AuthenticatorAttachmentType = 'platform' | 'cross-platform';
4624
+ /**
4625
+ * Resident key requirement
4626
+ */
4627
+ type ResidentKeyRequirementType = 'required' | 'preferred' | 'discouraged';
4628
+ /**
4629
+ * Attestation conveyance preference
4630
+ */
4631
+ type AttestationConveyancePreferenceType = 'none' | 'indirect' | 'direct' | 'enterprise';
4632
+ /**
4633
+ * Public key credential type
4634
+ */
4635
+ type PublicKeyCredentialType = 'public-key';
4636
+ /**
4637
+ * COSE algorithm identifier
4638
+ */
4639
+ type COSEAlgorithmIdentifier = -7 | -257 | -8 | -35 | -36 | -37 | -38 | -39 | number;
4640
+ /**
4641
+ * Public key credential parameters
4642
+ */
4643
+ interface PublicKeyCredentialParametersType {
4644
+ type: PublicKeyCredentialType;
4645
+ alg: COSEAlgorithmIdentifier;
4646
+ }
4647
+ /**
4648
+ * Relying party entity
4649
+ */
4650
+ interface PublicKeyCredentialRpEntityType {
4651
+ id?: string;
4652
+ name: string;
4653
+ }
4654
+ /**
4655
+ * Authenticator selection criteria
4656
+ */
4657
+ interface AuthenticatorSelectionCriteriaType {
4658
+ authenticatorAttachment?: AuthenticatorAttachmentType;
4659
+ residentKey?: ResidentKeyRequirementType;
4660
+ requireResidentKey?: boolean;
4661
+ userVerification?: UserVerificationRequirementType;
4662
+ }
4663
+ /**
4664
+ * Authentication extensions client inputs
4665
+ */
4666
+ interface AuthenticationExtensionsClientInputsType {
4667
+ credProps?: boolean;
4668
+ appid?: string;
4669
+ [key: string]: unknown;
4670
+ }
4671
+ /**
4672
+ * Social login provider
4673
+ */
4674
+ type SocialProvider = 'google' | 'github' | 'apple' | 'microsoft' | 'facebook';
4675
+ /**
4676
+ * MFA method
4677
+ */
4678
+ type MfaMethod = 'totp' | 'sms' | 'email' | 'passkey';
4679
+ /**
4680
+ * User information
4681
+ */
4682
+ interface User {
4683
+ /** User ID */
4684
+ id: string;
4685
+ /** Email address */
4686
+ email?: string;
4687
+ /** Whether email is verified */
4688
+ emailVerified?: boolean;
4689
+ /** Display name */
4690
+ name?: string;
4691
+ /** Profile picture URL */
4692
+ picture?: string;
4693
+ /** Username */
4694
+ username?: string;
4695
+ /** Additional claims */
4696
+ [key: string]: unknown;
4697
+ }
4698
+ /**
4699
+ * Session information
4700
+ */
4701
+ interface Session {
4702
+ /** Session ID */
4703
+ id: string;
4704
+ /** User ID */
4705
+ userId: string;
4706
+ /** Session creation time (ISO 8601) */
4707
+ createdAt: string;
4708
+ /** Session expiration time (ISO 8601) */
4709
+ expiresAt: string;
4710
+ /** Last activity time (ISO 8601) */
4711
+ lastActiveAt?: string;
4712
+ /** User agent that created the session */
4713
+ userAgent?: string;
4714
+ /** IP address (for display purposes only, not for security) */
4715
+ ipAddress?: string;
4716
+ }
4717
+ /**
4718
+ * Next action required after authentication
4719
+ */
4720
+ type NextAction = {
4721
+ type: 'mfa_required';
4722
+ methods: MfaMethod[];
4723
+ } | {
4724
+ type: 'consent_required';
4725
+ scopes: string[];
4726
+ } | {
4727
+ type: 'email_verification_required';
4728
+ };
4729
+ /**
4730
+ * Authentication result (tokens are not returned directly for security)
4731
+ */
4732
+ interface AuthResult {
4733
+ /** Authentication success flag */
4734
+ success: boolean;
4735
+ /** Session information (on success) */
4736
+ session?: Session;
4737
+ /** User information (on success) */
4738
+ user?: User;
4739
+ /** Error information (on failure) */
4740
+ error?: DirectAuthError;
4741
+ /** Additional action required */
4742
+ nextAction?: NextAction;
4743
+ }
4744
+ /**
4745
+ * Direct Auth error structure (OAuth 2.0 extension)
4746
+ */
4747
+ interface DirectAuthError {
4748
+ /** OAuth 2.0 error code */
4749
+ error: string;
4750
+ /** Human-readable error description */
4751
+ error_description?: string;
4752
+ /** URI with more information about the error */
4753
+ error_uri?: string;
4754
+ /** Authrim error code (AR000001 format) */
4755
+ code: string;
4756
+ /** Error metadata */
4757
+ meta: {
4758
+ /** Whether the error can be retried */
4759
+ retryable: boolean;
4760
+ /** Whether the error is transient */
4761
+ transient?: boolean;
4762
+ /** Suggested user action */
4763
+ user_action?: 'login' | 'reauth' | 'retry' | 'contact_admin';
4764
+ /** Error severity */
4765
+ severity: 'info' | 'warn' | 'error' | 'critical';
4766
+ /** Retry after (seconds) */
4767
+ retry_after?: number;
4768
+ };
4769
+ }
4770
+ /**
4771
+ * Passkey login options
4772
+ */
4773
+ interface PasskeyLoginOptions {
4774
+ /** Use conditional UI (autofill) */
4775
+ conditional?: boolean;
4776
+ /** Mediation preference */
4777
+ mediation?: 'conditional' | 'optional' | 'required' | 'silent';
4778
+ /** Abort signal for cancellation */
4779
+ signal?: AbortSignal;
4780
+ }
4781
+ /**
4782
+ * Passkey sign-up options
4783
+ */
4784
+ interface PasskeySignUpOptions {
4785
+ /** User email */
4786
+ email: string;
4787
+ /** User display name */
4788
+ displayName?: string;
4789
+ /** Preferred authenticator type */
4790
+ authenticatorType?: 'platform' | 'cross-platform' | 'any';
4791
+ /** Resident key requirement */
4792
+ residentKey?: 'required' | 'preferred' | 'discouraged';
4793
+ /** User verification requirement */
4794
+ userVerification?: 'required' | 'preferred' | 'discouraged';
4795
+ /** Abort signal for cancellation */
4796
+ signal?: AbortSignal;
4797
+ }
4798
+ /**
4799
+ * Passkey register options (for adding to existing account)
4800
+ */
4801
+ interface PasskeyRegisterOptions {
4802
+ /** Passkey display name */
4803
+ displayName?: string;
4804
+ /** Preferred authenticator type */
4805
+ authenticatorType?: 'platform' | 'cross-platform' | 'any';
4806
+ /** Resident key requirement */
4807
+ residentKey?: 'required' | 'preferred' | 'discouraged';
4808
+ /** User verification requirement */
4809
+ userVerification?: 'required' | 'preferred' | 'discouraged';
4810
+ /** Abort signal for cancellation */
4811
+ signal?: AbortSignal;
4812
+ }
4813
+ /**
4814
+ * Passkey credential (returned after registration)
4815
+ */
4816
+ interface PasskeyCredential {
4817
+ /** Credential ID (base64url) */
4818
+ credentialId: string;
4819
+ /** Public key (COSE format, base64url) */
4820
+ publicKey: string;
4821
+ /** Authenticator type */
4822
+ authenticatorType: 'platform' | 'cross-platform';
4823
+ /** Transports (usb, nfc, ble, internal, etc.) */
4824
+ transports?: AuthenticatorTransportType[];
4825
+ /** When the credential was created */
4826
+ createdAt: string;
4827
+ /** User-friendly name */
4828
+ displayName?: string;
4829
+ }
4830
+ /**
4831
+ * Email code send options
4832
+ */
4833
+ interface EmailCodeSendOptions {
4834
+ /** Email locale for the message */
4835
+ locale?: string;
4836
+ /** Code length (default: 6) */
4837
+ codeLength?: 6 | 8;
4838
+ }
4839
+ /**
4840
+ * Email code send result
4841
+ */
4842
+ interface EmailCodeSendResult {
4843
+ /** Attempt ID for verification */
4844
+ attemptId: string;
4845
+ /** Code expiration time (seconds) */
4846
+ expiresIn: number;
4847
+ /** Masked email for display */
4848
+ maskedEmail: string;
4849
+ /** Whether this is a new user */
4850
+ isNewUser?: boolean;
4851
+ }
4852
+ /**
4853
+ * Email code verify options
4854
+ */
4855
+ interface EmailCodeVerifyOptions {
4856
+ /** Create account if user doesn't exist */
4857
+ createAccountIfNotExists?: boolean;
4858
+ }
4859
+ /**
4860
+ * Social login options
4861
+ */
4862
+ interface SocialLoginOptions {
4863
+ /** Redirect URI after authentication */
4864
+ redirectUri?: string;
4865
+ /** Additional OAuth scopes */
4866
+ scopes?: string[];
4867
+ /** Custom state parameter */
4868
+ state?: string;
4869
+ /** Login hint (e.g., email address) */
4870
+ loginHint?: string;
4871
+ /** Popup window features */
4872
+ popupFeatures?: {
4873
+ width?: number;
4874
+ height?: number;
4875
+ };
4876
+ }
4877
+ /**
4878
+ * Logout options
4879
+ */
4880
+ interface DirectAuthLogoutOptions {
4881
+ /** Revoke refresh tokens */
4882
+ revokeTokens?: boolean;
4883
+ /** Post-logout redirect URI */
4884
+ redirectUri?: string;
4885
+ }
4886
+ /**
4887
+ * Passkey login start request
4888
+ */
4889
+ interface PasskeyLoginStartRequest {
4890
+ client_id: string;
4891
+ code_challenge: string;
4892
+ code_challenge_method: 'S256';
4893
+ }
4894
+ /**
4895
+ * Passkey login start response
4896
+ */
4897
+ interface PasskeyLoginStartResponse {
4898
+ /** Challenge ID (5 min TTL) */
4899
+ challenge_id: string;
4900
+ /** WebAuthn options */
4901
+ options: PublicKeyCredentialRequestOptionsJSON;
4902
+ }
4903
+ /**
4904
+ * Passkey login finish request
4905
+ */
4906
+ interface PasskeyLoginFinishRequest {
4907
+ challenge_id: string;
4908
+ credential: AuthenticatorAssertionResponseJSON;
4909
+ code_verifier: string;
4910
+ }
4911
+ /**
4912
+ * Passkey login finish response
4913
+ */
4914
+ interface PasskeyLoginFinishResponse {
4915
+ /** Authorization code (60s TTL, single-use) */
4916
+ auth_code: string;
4917
+ }
4918
+ /**
4919
+ * Passkey signup start request
4920
+ */
4921
+ interface PasskeySignupStartRequest {
4922
+ client_id: string;
4923
+ email: string;
4924
+ display_name?: string;
4925
+ code_challenge: string;
4926
+ code_challenge_method: 'S256';
4927
+ authenticator_type?: 'platform' | 'cross-platform' | 'any';
4928
+ resident_key?: 'required' | 'preferred' | 'discouraged';
4929
+ user_verification?: 'required' | 'preferred' | 'discouraged';
4930
+ }
4931
+ /**
4932
+ * Passkey signup start response
4933
+ */
4934
+ interface PasskeySignupStartResponse {
4935
+ /** Challenge ID (5 min TTL) */
4936
+ challenge_id: string;
4937
+ /** WebAuthn creation options */
4938
+ options: PublicKeyCredentialCreationOptionsJSON;
4939
+ }
4940
+ /**
4941
+ * Passkey signup finish request
4942
+ */
4943
+ interface PasskeySignupFinishRequest {
4944
+ challenge_id: string;
4945
+ credential: AuthenticatorAttestationResponseJSON;
4946
+ code_verifier: string;
4947
+ }
4948
+ /**
4949
+ * Passkey signup finish response
4950
+ */
4951
+ interface PasskeySignupFinishResponse {
4952
+ /** Authorization code (60s TTL, single-use) */
4953
+ auth_code: string;
4954
+ /** Whether the user was newly created */
4955
+ is_new_user: boolean;
4956
+ }
4957
+ /**
4958
+ * Email code send request
4959
+ */
4960
+ interface EmailCodeSendRequest {
4961
+ client_id: string;
4962
+ email: string;
4963
+ code_challenge: string;
4964
+ code_challenge_method: 'S256';
4965
+ locale?: string;
4966
+ }
4967
+ /**
4968
+ * Email code send response
4969
+ */
4970
+ interface EmailCodeSendResponse {
4971
+ /** Attempt ID (5 min TTL) */
4972
+ attempt_id: string;
4973
+ /** Code expiration (seconds) */
4974
+ expires_in: number;
4975
+ /** Masked email */
4976
+ masked_email: string;
4977
+ }
4978
+ /**
4979
+ * Email code verify request
4980
+ */
4981
+ interface EmailCodeVerifyRequest {
4982
+ attempt_id: string;
4983
+ code: string;
4984
+ code_verifier: string;
4985
+ }
4986
+ /**
4987
+ * Email code verify response
4988
+ */
4989
+ interface EmailCodeVerifyResponse {
4990
+ /** Authorization code (60s TTL, single-use) */
4991
+ auth_code: string;
4992
+ /** Whether the user was newly created */
4993
+ is_new_user: boolean;
4994
+ }
4995
+ /**
4996
+ * Token exchange request (Direct Auth)
4997
+ */
4998
+ interface DirectAuthTokenRequest {
4999
+ grant_type: 'authorization_code';
5000
+ code: string;
5001
+ client_id: string;
5002
+ code_verifier: string;
5003
+ /** Whether to request refresh token (for SPA opt-in) */
5004
+ request_refresh_token?: boolean;
5005
+ }
5006
+ /**
5007
+ * Token exchange response (OAuth 2.0 extension)
5008
+ *
5009
+ * Unified structure for Web/Mobile, differentiated by flags.
5010
+ */
5011
+ interface DirectAuthTokenResponse {
5012
+ /** Token type (always 'Bearer') */
5013
+ token_type: 'Bearer';
5014
+ /** Access token */
5015
+ access_token: string;
5016
+ /** Token expiration (seconds) */
5017
+ expires_in: number;
5018
+ /** Refresh token (Mobile, or SPA with opt-in) */
5019
+ refresh_token?: string;
5020
+ /** ID token */
5021
+ id_token?: string;
5022
+ /** Granted scopes */
5023
+ scope?: string;
5024
+ /** Whether session is established via Cookie (Web) */
5025
+ session_established: boolean;
5026
+ /** Session information */
5027
+ session?: Session;
5028
+ /** User information */
5029
+ user?: User;
5030
+ }
5031
+ /**
5032
+ * PublicKeyCredentialRequestOptions as JSON
5033
+ */
5034
+ interface PublicKeyCredentialRequestOptionsJSON {
5035
+ challenge: string;
5036
+ timeout?: number;
5037
+ rpId?: string;
5038
+ allowCredentials?: PublicKeyCredentialDescriptorJSON[];
5039
+ userVerification?: UserVerificationRequirementType;
5040
+ extensions?: AuthenticationExtensionsClientInputsType;
5041
+ }
5042
+ /**
5043
+ * PublicKeyCredentialCreationOptions as JSON
5044
+ */
5045
+ interface PublicKeyCredentialCreationOptionsJSON {
5046
+ rp: PublicKeyCredentialRpEntityType;
5047
+ user: PublicKeyCredentialUserEntityJSON;
5048
+ challenge: string;
5049
+ pubKeyCredParams: PublicKeyCredentialParametersType[];
5050
+ timeout?: number;
5051
+ excludeCredentials?: PublicKeyCredentialDescriptorJSON[];
5052
+ authenticatorSelection?: AuthenticatorSelectionCriteriaType;
5053
+ attestation?: AttestationConveyancePreferenceType;
5054
+ extensions?: AuthenticationExtensionsClientInputsType;
5055
+ }
5056
+ /**
5057
+ * PublicKeyCredentialDescriptor as JSON
5058
+ */
5059
+ interface PublicKeyCredentialDescriptorJSON {
5060
+ type: PublicKeyCredentialType;
5061
+ id: string;
5062
+ transports?: AuthenticatorTransportType[];
5063
+ }
5064
+ /**
5065
+ * PublicKeyCredentialUserEntity as JSON
5066
+ */
5067
+ interface PublicKeyCredentialUserEntityJSON {
5068
+ id: string;
5069
+ name: string;
5070
+ displayName: string;
5071
+ }
5072
+ /**
5073
+ * AuthenticatorAssertionResponse as JSON
5074
+ */
5075
+ interface AuthenticatorAssertionResponseJSON {
5076
+ clientDataJSON: string;
5077
+ authenticatorData: string;
5078
+ signature: string;
5079
+ userHandle?: string;
5080
+ }
5081
+ /**
5082
+ * AuthenticatorAttestationResponse as JSON
5083
+ */
5084
+ interface AuthenticatorAttestationResponseJSON {
5085
+ clientDataJSON: string;
5086
+ attestationObject: string;
5087
+ transports?: AuthenticatorTransportType[];
5088
+ }
5089
+ /**
5090
+ * Direct Auth client configuration
5091
+ */
5092
+ interface DirectAuthClientConfig {
5093
+ /** Authrim IdP URL */
5094
+ issuer: string;
5095
+ /** OAuth client ID */
5096
+ clientId: string;
5097
+ /** Default redirect URI */
5098
+ redirectUri?: string;
5099
+ }
5100
+ /**
5101
+ * Passkey authentication interface
5102
+ */
5103
+ interface PasskeyAuth {
5104
+ /** Login with Passkey */
5105
+ login(options?: PasskeyLoginOptions): Promise<AuthResult>;
5106
+ /** Sign up with Passkey (create account + register Passkey) */
5107
+ signUp(options: PasskeySignUpOptions): Promise<AuthResult>;
5108
+ /** Register a Passkey to existing account (requires authentication) */
5109
+ register(options?: PasskeyRegisterOptions): Promise<PasskeyCredential>;
5110
+ /** Check if WebAuthn is supported */
5111
+ isSupported(): boolean;
5112
+ /** Check if conditional UI (autofill) is available */
5113
+ isConditionalUIAvailable(): Promise<boolean>;
5114
+ }
5115
+ /**
5116
+ * Email code authentication interface
5117
+ */
5118
+ interface EmailCodeAuth {
5119
+ /** Send verification code to email */
5120
+ send(email: string, options?: EmailCodeSendOptions): Promise<EmailCodeSendResult>;
5121
+ /** Verify code and authenticate */
5122
+ verify(email: string, code: string, options?: EmailCodeVerifyOptions): Promise<AuthResult>;
5123
+ }
5124
+ /**
5125
+ * Social login interface
5126
+ */
5127
+ interface SocialAuth {
5128
+ /** Login with social provider (popup) */
5129
+ loginWithPopup(provider: SocialProvider, options?: SocialLoginOptions): Promise<AuthResult>;
5130
+ /** Login with social provider (redirect) */
5131
+ loginWithRedirect(provider: SocialProvider, options?: SocialLoginOptions): Promise<void>;
5132
+ /** Handle callback from social provider (redirect) */
5133
+ handleCallback(): Promise<AuthResult>;
5134
+ }
5135
+ /**
5136
+ * Session management interface
5137
+ */
5138
+ interface SessionAuth {
5139
+ /** Get current session */
5140
+ get(): Promise<Session | null>;
5141
+ /** Validate session */
5142
+ validate(): Promise<boolean>;
5143
+ /** Logout */
5144
+ logout(options?: DirectAuthLogoutOptions): Promise<void>;
5145
+ }
5146
+ /**
5147
+ * Direct Auth client interface (BetterAuth style)
5148
+ */
5149
+ interface DirectAuthClient {
5150
+ /** Passkey authentication */
5151
+ passkey: PasskeyAuth;
5152
+ /** Email code authentication */
5153
+ emailCode: EmailCodeAuth;
5154
+ /** Social login */
5155
+ social: SocialAuth;
5156
+ /** Session management */
5157
+ session: SessionAuth;
5158
+ }
5159
+
5160
+ export { type AddressClaim, type AttestationConveyancePreferenceType, type AuthCallbackCompleteEvent, type AuthCallbackEvent, type AuthCallbackProcessingEvent, type AuthFallbackEvent, type AuthInitEvent, type AuthLoginCompleteEvent, type AuthLogoutCompleteEvent, type AuthPopupBlockedEvent, type AuthRedirectingEvent, type AuthRequiredEvent, type AuthResult, type AuthState, type AuthStateSnapshot, type AuthState$1 as AuthStateType, type AuthenticationExtensionsClientInputsType, type AuthenticatorAssertionResponseJSON, type AuthenticatorAttachmentType, type AuthenticatorAttestationResponseJSON, type AuthenticatorSelectionCriteriaType, type AuthenticatorTransportType, AuthorizationCodeFlow, type AuthorizationContext, type AuthorizationUrlResult, AuthrimClient, type AuthrimClientConfig, AuthrimError, type AuthrimErrorCode, type AuthrimErrorMeta, type AuthrimErrorOptions, type AuthrimErrorRemediation, type AuthrimErrorSeverity, type AuthrimErrorUserAction, type AuthrimEventHandler, type AuthrimEventName, type AuthrimEvents, type AuthrimStorage, type AutoRefreshOptions, AutoRefreshScheduler, BACKCHANNEL_LOGOUT_EVENT, type BackChannelLogoutErrorCode, type BackChannelLogoutValidationOptions, type BackChannelLogoutValidationResult, BackChannelLogoutValidator, type BaseEventPayload, type BuildAuthorizationUrlOptions, type COSEAlgorithmIdentifier, type CheckSessionMessage, type CheckSessionResponse, type ClientAssertionClaims, type ClientAuthMethod, type ClientAuthResult, type ClientCredentials, ClientCredentialsClient, type ClientCredentialsClientOptions, type ClientCredentialsTokenOptions, type ClientSecretCredentials, type CodeChallengeMethod, type CoreEventName, type CryptoProvider, type DPoPCryptoProvider, type DPoPKeyPair, DPoPManager, type DPoPManagerConfig, type DPoPProofClaims, type DPoPProofHeader, type DPoPProofOptions, DebugContext, type DebugLogLevel, type DebugLogger, type DebugOptions, type DebugTimelineEvent, type DecodedJwt, type DeviceAuthorizationResponse, type DeviceFlowAccessDeniedResult, DeviceFlowClient, type DeviceFlowCompletedResult, type DeviceFlowExpiredResult, type DeviceFlowPendingResult, type DeviceFlowPollResult, type DeviceFlowSlowDownResult, type DeviceFlowStartOptions, type DeviceFlowState, type DirectAuthClient, type DirectAuthClientConfig, type DirectAuthError, type DirectAuthLogoutOptions, type DirectAuthTokenRequest, type DirectAuthTokenResponse, DiscoveryClient, type EmailCodeAuth, type EmailCodeSendOptions, type EmailCodeSendRequest, type EmailCodeSendResponse, type EmailCodeSendResult, type EmailCodeVerifyOptions, type EmailCodeVerifyRequest, type EmailCodeVerifyResponse, type EmitClassifiedErrorOptions, type EndpointOverrides, type ErrorClassification, type ErrorEvent, type ErrorEventEmitter, type ErrorEventPayload, type ErrorFatalEvent, type ErrorRecoverableEvent, type ErrorSeverity, EventEmitter, EventTimeline, type ExchangeCodeOptions, type FrontChannelLogoutBuildParams, type FrontChannelLogoutParams, FrontChannelLogoutUrlBuilder, type FrontChannelLogoutUrlOptions, type FrontChannelLogoutUrlResult, type FrontChannelLogoutValidationOptions, type FrontChannelLogoutValidationResult, type GenerateAuthStateOptions, type HashOptions, type HttpClient, type HttpOptions, type HttpResponse, type IntrospectTokenOptions, type IntrospectionResponse, type IntrospectionTokenTypeHint, JARBuilder, type JARBuilderConfig, type JARMResponseClaims, type JARMValidationOptions, type JARMValidationResult, JARMValidator, type JARMValidatorConfig, type JARRequestObjectClaims, type JARRequestOptions, type JWK, type JwtHeader, LogoutHandler, type LogoutHandlerOptions, type LogoutOptions, type LogoutResult, type LogoutTokenClaims, type MfaMethod, type NextAction, type NoClientCredentials, type OAuthErrorResponse, type OIDCDiscoveryDocument, PARClient, type PARClientOptions, type PARRequest, type PARResponse, type PARResult, PKCEHelper, type PKCEPair, type PasskeyAuth, type PasskeyCredential, type PasskeyLoginFinishRequest, type PasskeyLoginFinishResponse, type PasskeyLoginOptions, type PasskeyLoginStartRequest, type PasskeyLoginStartResponse, type PasskeyRegisterOptions, type PasskeySignUpOptions, type PasskeySignupFinishRequest, type PasskeySignupFinishResponse, type PasskeySignupStartRequest, type PasskeySignupStartResponse, type PrivateKeyJwtCredentials, type PublicKeyCredentialCreationOptionsJSON, type PublicKeyCredentialDescriptorJSON, type PublicKeyCredentialParametersType, type PublicKeyCredentialRequestOptionsJSON, type PublicKeyCredentialRpEntityType, type PublicKeyCredentialType, type PublicKeyCredentialUserEntityJSON, type RedactLevel, type ResidentKeyRequirementType, type ResolvedConfig, type RetryOptions, type RevokeTokenOptions, STORAGE_KEYS, type Session, type SessionAuth, type SessionChangeEvent, type SessionChangedEvent, type SessionCheckResult, type SessionEndedEvent, type SessionLogoutBroadcastEvent, type SessionManagementConfig, SessionManager, type SessionManagerOptions, type SessionStartedEvent, type SessionState, SessionStateCalculator, type SessionStateCalculatorOptions, type SessionStateParams, type SessionStateResult, type SessionSyncEvent, SilentAuthHandler, type SilentAuthOptions, type SilentAuthResult, type SilentAuthUrlResult, type SocialAuth, type SocialLoginOptions, type SocialProvider, type StandardClaims, type StateChangeEvent, StateManager, TOKEN_TYPE_URIS, type TimelineEntry, TokenApiClient, type TokenApiClientOptions, type TokenErrorEvent, type TokenExchangeRequest, type TokenExchangeResponse, type TokenExchangeResult, type TokenExchangedEvent, type TokenExpiredEvent, type TokenExpiringEvent, TokenIntrospector, type TokenIntrospectorOptions, TokenManager, type TokenManagerOptions, type TokenRefreshFailedEvent, type TokenRefreshedEvent, type TokenRefreshingEvent, type TokenResponse, TokenRevoker, type TokenRevokerOptions, type TokenSet, type TokenTypeHint, type TokenTypeUri, type User, type UserInfo, type UserVerificationRequirementType, type WarningITPEvent, type WarningPrivateModeEvent, type WarningStorageFallbackEvent, type WebOnlyEventName, base64urlDecode, base64urlEncode, base64urlToString, buildClientAuthentication, calculateBackoffDelay, calculateDsHash, classifyError, createAuthrimClient, createCancellableOperation, createConsoleLogger, createDebugLogger, createRetryFunction, decodeIdToken, decodeJwt, emitClassifiedError, getErrorMeta, getIdTokenNonce, isCancellationError, isJarRequired, isJwtExpired, isRetryableError, noopLogger, normalizeIssuer, parseRetryAfterHeader, raceWithCancellation, resolveConfig, sleep, stringToBase64url, timingSafeEqual, withAbortSignal, withRetry };