postex-auth-sdk-stage 1.4.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -364,6 +364,7 @@ DPoP provides enhanced security by binding tokens to cryptographic keys. The SDK
364
364
  #### getRequestAuthHeaders()
365
365
 
366
366
  Get authentication headers (Authorization + DPoP) for a request. Use this to attach auth to your own HTTP client.
367
+ If DPoP proof generation fails, this method throws and does not return bearer-only headers.
367
368
 
368
369
  ```typescript
369
370
  async getRequestAuthHeaders(
@@ -475,33 +476,6 @@ async function clearPasskeyMobileNumber(): Promise<void>
475
476
 
476
477
  ---
477
478
 
478
- ### DPoP Utility Functions
479
-
480
- Low-level DPoP functions. Most developers won't need these as they're handled automatically by the SDK.
481
-
482
- ```typescript
483
- // Generate DPoP key pair
484
- async function generateDPoPKeyPair(): Promise<{
485
- publicKey: MinimalECPublicKeyJWK;
486
- thumbprint: string;
487
- }>
488
-
489
- // Generate DPoP proof JWT
490
- async function generateDPoPProof(
491
- httpMethod: string,
492
- httpUri: string,
493
- accessToken?: string
494
- ): Promise<string | null>
495
-
496
- // Check if DPoP is enabled
497
- async function isDPoPEnabled(): Promise<boolean>
498
-
499
- // Clear DPoP keys
500
- async function clearDPoPKey(): Promise<void>
501
- ```
502
-
503
- ---
504
-
505
479
  ## Complete Examples
506
480
 
507
481
  ### Passkey Registration Flow
@@ -620,14 +594,18 @@ const response2 = await fetch('https://api.example.com/data', {
620
594
 
621
595
  ## Error Handling
622
596
 
623
- The SDK throws `AuthSDKFetchError` for HTTP errors. This error includes the status code and response data.
597
+ The SDK throws `AuthSDKFetchError` for HTTP errors and `SDKValidationError` for client-side input validation failures before any network request is sent.
624
598
 
625
599
  ```javascript
626
- import { AuthSDK, AuthSDKFetchError } from 'postex-auth-sdk-stage';
600
+ import { AuthSDK, AuthSDKFetchError, SDKValidationError } from 'postex-auth-sdk-stage';
627
601
 
628
602
  try {
629
603
  await auth.verifyOTP(otpCode);
630
604
  } catch (error) {
605
+ if (error instanceof SDKValidationError) {
606
+ console.error('Invalid field:', error.field);
607
+ console.error('Validation message:', error.message);
608
+ }
631
609
  if (error instanceof AuthSDKFetchError) {
632
610
  console.error('Status:', error.response.status);
633
611
  console.error('Data:', error.response.data);
@@ -656,7 +634,8 @@ The SDK automatically implements DPoP (RFC 9449) to bind tokens to cryptographic
656
634
  - Generated using ECDSA P-256 (ES256)
657
635
  - Stored securely in IndexedDB
658
636
  - Non-extractable (private key cannot be exported)
659
- - Automatically included in all authenticated requests
637
+ - Checked during SDK initialization and regenerated once if missing or incomplete
638
+ - Required for authenticated requests; the SDK fails closed instead of sending bearer-only requests
660
639
 
661
640
  ---
662
641
 
@@ -732,7 +711,8 @@ import {
732
711
  PasskeyRegisterResponse,
733
712
  PasskeyStatusResponse,
734
713
  RefreshTokenResponse,
735
- AuthSDKFetchError
714
+ AuthSDKFetchError,
715
+ SDKValidationError
736
716
  } from 'postex-auth-sdk-stage';
737
717
  ```
738
718
 
@@ -750,8 +730,9 @@ import {
750
730
  ## API overview
751
731
 
752
732
  - **AuthSDK** – Main client: `getStatus`, `initiateAuth`, `initiateOTP`, `verifyOTP`, `resendOTP`, `verifySignupOTP`, `resendSignupOTP`, `verifyMagicLink`, `completeMagicLink`, `authenticateWithPasskey`, `registerPasskey`, `getPasskeyStatus`, `removePasskey`, `getRequestAuthHeaders`, `authenticatedFetch`, `refreshToken`, `logout`, `getAccessToken`, `storeTokens`, `clearTokens`
753
- - **WebAuthn** – Helpers: `isWebAuthnSupported`, `isConditionalUISupported`, base64/ArrayBuffer conversion, DPoP key and proof helpers, passkey email/mobile storage (`getPasskeyEmail`, `setPasskeyEmail`, `clearPasskeyEmail`, `getPasskeyMobileNumber`, `setPasskeyMobileNumber`, `clearPasskeyMobileNumber`)
733
+ - **WebAuthn** – Helpers: `isWebAuthnSupported`, `isConditionalUISupported`, base64/ArrayBuffer conversion, and passkey email/mobile storage (`getPasskeyEmail`, `setPasskeyEmail`, `clearPasskeyEmail`, `getPasskeyMobileNumber`, `setPasskeyMobileNumber`, `clearPasskeyMobileNumber`)
754
734
  - **AuthSDKFetchError** – Error class with `response.status` and `response.data`
735
+ - **SDKValidationError** – Error class with `field`, `code`, and a validation message for invalid client input
755
736
 
756
737
  ## Versioning
757
738
 
package/dist/auth.d.ts CHANGED
@@ -1,4 +1,12 @@
1
1
  type AuthEntity = "xstak" | "postex" | "callcourier" | "postexglobal" | "postexsa";
2
+ type AuthIdentifierInput = string | {
3
+ email?: string;
4
+ mobileNumber?: string;
5
+ realm?: string;
6
+ };
7
+ interface RealmOptions {
8
+ realm?: string;
9
+ }
2
10
  interface AuthSDKConfig {
3
11
  apiKey?: string;
4
12
  appId?: AuthEntity;
@@ -101,11 +109,33 @@ export declare class AuthSDKFetchError extends Error {
101
109
  };
102
110
  constructor(status: number, data?: any, message?: string);
103
111
  }
112
+ export declare class SDKValidationError extends Error {
113
+ field: string;
114
+ code: string;
115
+ constructor(field: string, message: string, code?: string);
116
+ }
104
117
  export declare class AuthSDK {
105
118
  private config;
119
+ private dpopInitializationPromise;
106
120
  constructor(config: AuthSDKConfig);
107
121
  private getBaseUrl;
122
+ private initializeDPoPState;
123
+ private ensureDPoPInitialized;
124
+ private createDPoPInitializationPromise;
125
+ private resetDPoPInitialization;
126
+ private getRequiredDPoPProof;
127
+ private containsControlChars;
128
+ private hasMixedLatinAndCyrillic;
129
+ private assertNoControlChars;
130
+ private validateEmail;
131
+ private validateMobileNumber;
132
+ private validateOTP;
133
+ private validateMagicLinkToken;
134
+ private validateRealm;
135
+ private normalizeAndValidateIdentifier;
108
136
  private normalizeAuthIdentifier;
137
+ private extractRealm;
138
+ private buildAuthRequestBody;
109
139
  private buildUrl;
110
140
  private request;
111
141
  /**
@@ -119,26 +149,17 @@ export declare class AuthSDK {
119
149
  * GET /auth/status - Check if client has trusted device session and what auth method is available.
120
150
  * Returns no_session | session_found | webauthn_ready per PostEx Auth BFF spec.
121
151
  */
122
- getStatus(identifier: string | {
123
- email?: string;
124
- mobileNumber?: string;
125
- }): Promise<AuthStatusResponse>;
152
+ getStatus(identifier: AuthIdentifierInput, options?: RealmOptions): Promise<AuthStatusResponse>;
126
153
  /**
127
154
  * POST /auth/initiate - Unified entry: returns webauthn_challenge or otp_sent.
128
155
  * Sets auth_session cookie when otp_sent.
129
156
  */
130
- initiateAuth(identifier: string | {
131
- email?: string;
132
- mobileNumber?: string;
133
- }): Promise<InitiateAuthResponse>;
157
+ initiateAuth(identifier: AuthIdentifierInput, options?: RealmOptions): Promise<InitiateAuthResponse>;
134
158
  /**
135
159
  * POST /otp/initiate - Direct OTP initiation using email or mobile number.
136
160
  * Requires at least one identifier: email or mobileNumber.
137
161
  */
138
- initiateOTP(identifier: string | {
139
- email?: string;
140
- mobileNumber?: string;
141
- }): Promise<OTPInitiateResponse>;
162
+ initiateOTP(identifier: AuthIdentifierInput, options?: RealmOptions): Promise<OTPInitiateResponse>;
142
163
  /**
143
164
  * POST /otp/verify - Verifies the OTP code entered by the user.
144
165
  * Stores tokens from the response.
@@ -174,7 +195,7 @@ export declare class AuthSDK {
174
195
  * GET /magic-link - Verify a magic link token.
175
196
  * Sets auth_session cookie on success.
176
197
  */
177
- verifyMagicLink(token: string, email: string): Promise<void>;
198
+ verifyMagicLink(token: string): Promise<void>;
178
199
  /**
179
200
  * POST /magic-link/complete - Complete magic link authentication.
180
201
  * Requires auth_session cookie set by verifyMagicLink.
@@ -229,7 +250,7 @@ export declare class AuthSDK {
229
250
  * Requires trusted device cookie (td). Refresh token is stored server-side.
230
251
  * Rate limit: 10 requests per minute.
231
252
  */
232
- refreshToken(): Promise<RefreshTokenResponse>;
253
+ refreshToken(options?: RealmOptions): Promise<RefreshTokenResponse>;
233
254
  /**
234
255
  * POST /auth/logout - Logout from the current device.
235
256
  * Revokes the current token and trusted device, then clears local tokens.
package/dist/main.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export * from "./auth";
2
- export * from "./webauthn";
2
+ export { isWebAuthnSupported, isConditionalUISupported, arrayBufferToBase64, base64ToArrayBuffer, arrayBufferToBase64url, base64urlToArrayBuffer, stringToArrayBuffer, uint8ArrayToString, getPasskeyEmail, setPasskeyEmail, clearPasskeyEmail, getPasskeyMobileNumber, setPasskeyMobileNumber, clearPasskeyMobileNumber, } from "./webauthn";