@safepassage/sdk 3.4.8 → 3.4.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # SafePassage SDK v3.4.8
1
+ # SafePassage SDK v3.4.9
2
2
 
3
3
  A lightweight SDK for integrating SafePassage age verification into your website or application.
4
4
 
@@ -12,6 +12,11 @@ A lightweight SDK for integrating SafePassage age verification into your website
12
12
  - **Secure**: HMAC-signed state parameters, automatic session management
13
13
  - **Compliant**: Enforces minimum age of 25
14
14
 
15
+ ## Changelog
16
+
17
+ ### 3.4.9
18
+ - Prevents `onCancel` from firing after a successful new-tab verification when the popup closes.
19
+
15
20
  ## Installation
16
21
 
17
22
  ```bash
@@ -62,12 +67,13 @@ That's it! The SDK handles session creation automatically.
62
67
  |--------|------|----------|-------------|
63
68
  | apiKey | string | Yes | Your public API key (`pk_...`) |
64
69
  | returnUrl | string | Yes | URL to redirect after verification |
70
+ | cancelUrl | string | No | URL to redirect to if user closes the verification window (new-tab mode) |
65
71
  | environment | string | No | `'production'` or `'staging'` (auto-detected) |
66
72
  | mode | string | No | `'redirect'` (default) or `'new-tab'` |
67
73
  | defaultChallengeAge | number | No | Default minimum age (25 or higher) |
68
74
  | defaultVerificationMode | string | No | `'L1'` or `'L2'` |
69
75
  | onComplete | function | No | Callback for new-tab mode |
70
- | onCancel | function | No | Called when user closes popup (new-tab mode) |
76
+ | onCancel | function | No | Called when user closes popup (new-tab mode). Return `false` to suppress automatic `cancelUrl` redirect. |
71
77
  | onError | function | No | Error handler |
72
78
 
73
79
  ## Verification Options
@@ -114,6 +120,7 @@ Verification opens in a popup window:
114
120
  const sp = new SafePassage({
115
121
  apiKey: 'pk_...',
116
122
  returnUrl: '/age-verified',
123
+ cancelUrl: '/age-cancelled',
117
124
  mode: 'new-tab',
118
125
  onComplete: (result) => {
119
126
  console.log('Verification complete:', result.sessionId, result.status);
@@ -121,6 +128,8 @@ const sp = new SafePassage({
121
128
  },
122
129
  onCancel: () => {
123
130
  console.log('User closed the verification window');
131
+ // Return false if you want to handle navigation manually
132
+ // return false;
124
133
  },
125
134
  onError: (error) => {
126
135
  console.error('Verification error:', error.message);
@@ -130,6 +139,10 @@ const sp = new SafePassage({
130
139
  await sp.verify();
131
140
  ```
132
141
 
142
+ If `cancelUrl` is provided, the SDK will redirect the opener to `cancelUrl` with
143
+ `status=cancelled` and `sessionId` when the user closes the verification window.
144
+ Return `false` from `onCancel` to suppress the automatic redirect.
145
+
133
146
  ## Server-Side Validation (Required!)
134
147
 
135
148
  After verification completes, **always validate the result on your server** before granting access:
@@ -141,7 +154,7 @@ app.get('/age-verified', async (req, res) => {
141
154
 
142
155
  // Validate with your SECRET key (sk_...)
143
156
  const response = await fetch(
144
- `https://api.safepassageapp.com/api/v1/sessions/${sessionId}`,
157
+ `https://api.safepassage.live/api/v1/sessions/${sessionId}`,
145
158
  {
146
159
  headers: {
147
160
  'Authorization': `Bearer ${process.env.SAFEPASSAGE_SECRET_KEY}`
@@ -178,8 +191,6 @@ For reliable verification tracking, configure webhooks in your dashboard:
178
191
  }
179
192
  ```
180
193
 
181
- Webhook `timestamp` values are ISO 8601 strings. SDK `onComplete` results use milliseconds since epoch.
182
-
183
194
  ## Complete Example
184
195
 
185
196
  ### HTML + CDN
@@ -248,8 +259,6 @@ import { SafePassage, SafePassageConfig, VerificationResult } from '@safepassage
248
259
  const config: SafePassageConfig = {
249
260
  apiKey: process.env.NEXT_PUBLIC_SAFEPASSAGE_KEY!,
250
261
  returnUrl: '/verified',
251
- // Optional: used as a fallback redirect for Emblem login failures
252
- cancelUrl: '/verify-cancelled',
253
262
  mode: 'new-tab',
254
263
  onComplete: (result: VerificationResult) => {
255
264
  console.log(`Session ${result.sessionId}: ${result.status}`);
@@ -301,7 +310,7 @@ SafePassage uses two types of API keys:
301
310
  | Public Key | `pk_` | Client-side SDK (this package) |
302
311
  | Secret Key | `sk_` | Server-side validation only |
303
312
 
304
- > **Important**: This SDK only works with public keys (`pk_`). For server-side integrations using secret keys, use the [Direct API](https://docs.safepassageapp.com/api) instead.
313
+ > **Important**: This SDK only works with public keys (`pk_`). For server-side integrations using secret keys, use the [Direct API](https://docs.safepassage.live/api) instead.
305
314
 
306
315
  ## Browser Support
307
316
 
@@ -343,6 +352,6 @@ The SDK now creates sessions automatically via the API when using public keys.
343
352
 
344
353
  ## Support
345
354
 
346
- - [Documentation](https://docs.safepassageapp.com)
347
- - [API Reference](https://docs.safepassageapp.com/api)
348
- - [Dashboard](https://portal.safepassageapp.com)
355
+ - [Documentation](https://docs.safepassage.live)
356
+ - [API Reference](https://docs.safepassage.live/api)
357
+ - [Dashboard](https://portal.safepassage.live)
@@ -0,0 +1,12 @@
1
+ /**
2
+ * SafePassage SDK - Redirect-based age verification
3
+ */
4
+ import { VerificationSDK } from '../../core/VerificationSDK';
5
+ import type { SDKConfig, VerificationOptions, VerificationResult, SessionValidationResponse, SessionCreationResponse, CreateSessionRequest } from '../../types/base';
6
+ export type SafePassageConfig = SDKConfig;
7
+ export declare class SafePassage extends VerificationSDK {
8
+ constructor(config: SafePassageConfig);
9
+ }
10
+ export declare const VERSION = "3.4.9";
11
+ export type { SDKConfig, VerificationOptions, VerificationResult, SessionValidationResponse, SessionCreationResponse, CreateSessionRequest, };
12
+ export default SafePassage;
@@ -0,0 +1,3 @@
1
+ import type { BrandUrls, BrandConstants } from '../../core/VerificationSDK';
2
+ export declare const BRAND_URLS: BrandUrls;
3
+ export declare const BRAND_CONSTANTS: BrandConstants;
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Verification SDK - Redirect-based age verification
3
+ *
4
+ * Lightweight SDK for integrating age verification using redirect flow.
5
+ * Provides a secure, easy-to-implement solution with comprehensive
6
+ * security features and flexible integration options.
7
+ */
8
+ import type { SDKConfig, VerificationOptions } from '../types/base';
9
+ export interface UrlConfig {
10
+ apiUrl: string;
11
+ verifyUiUrl: string;
12
+ engineUrl: string;
13
+ wsUrl: string;
14
+ trustedOrigins: string[];
15
+ }
16
+ export interface BrandUrls {
17
+ production: UrlConfig;
18
+ staging: UrlConfig;
19
+ }
20
+ export interface BrandConstants {
21
+ name: string;
22
+ hmacSecretProd: string;
23
+ hmacSecretStaging: string;
24
+ messageType: string;
25
+ legacyMessageType?: string;
26
+ popupName: string;
27
+ docsUrl: string;
28
+ }
29
+ /**
30
+ * SDK Main Class
31
+ *
32
+ * Primary SDK class that manages verification sessions with comprehensive
33
+ * security and error handling. Supports both redirect and new-tab modes with
34
+ * automatic session management and PostMessage communication.
35
+ */
36
+ export declare class VerificationSDK {
37
+ private config;
38
+ private readonly brandUrls;
39
+ private readonly brandConstants;
40
+ private popupWindow;
41
+ private messageListener;
42
+ private popupMonitorInterval;
43
+ private unloadListener;
44
+ private isVerificationInProgress;
45
+ private currentSessionId;
46
+ private hasReceivedResult;
47
+ private lastVerifyUrl;
48
+ private lastSessionToken;
49
+ private lastExternalUserId;
50
+ private temporaryHandoffToken;
51
+ private static readonly LOCAL_HOSTNAMES;
52
+ /**
53
+ * Initialize SDK
54
+ *
55
+ * Validates configuration, sets up security measures, and prepares the SDK
56
+ * for verification operations. Performs comprehensive environment validation
57
+ * and security initialization.
58
+ */
59
+ constructor(config: SDKConfig, brandUrls: BrandUrls, brandConstants: BrandConstants);
60
+ /**
61
+ * Initiate verification with race condition protection
62
+ */
63
+ verify(options?: VerificationOptions): Promise<void>;
64
+ /**
65
+ * Build verification URL with HMAC-signed state
66
+ */
67
+ private buildVerificationUrl;
68
+ /**
69
+ * Redirect in same tab
70
+ */
71
+ private redirect;
72
+ /**
73
+ * Open in new tab with PostMessage communication and proper cleanup
74
+ */
75
+ private openNewTab;
76
+ /**
77
+ * Set up automatic cleanup on page unload to prevent memory leaks
78
+ */
79
+ private setupAutoCleanup;
80
+ /**
81
+ * Auto-detect environment based on current URL
82
+ */
83
+ private detectEnvironment;
84
+ /**
85
+ * Get the current environment
86
+ */
87
+ getEnvironment(): 'production' | 'staging';
88
+ /**
89
+ * Unlock verification process to allow new verifications
90
+ */
91
+ private unlockVerification;
92
+ /**
93
+ * Internal cleanup method to prevent memory leaks
94
+ */
95
+ private cleanup;
96
+ private handleCancellation;
97
+ private redirectToCancelUrl;
98
+ /**
99
+ * Remove auto-cleanup listeners
100
+ */
101
+ private removeAutoCleanupListeners;
102
+ /**
103
+ * Public cleanup method for manual resource management
104
+ */
105
+ destroy(): void;
106
+ /**
107
+ * Get Portal API URL based on environment and brand
108
+ */
109
+ private getPortalApiUrl;
110
+ /**
111
+ * Get Engine URL based on environment and brand
112
+ */
113
+ private getEngineUrl;
114
+ /**
115
+ * Get WebSocket URL based on environment and brand
116
+ */
117
+ private getWebSocketUrl;
118
+ /**
119
+ * Detect if this is a public key (pk_ prefix) vs private key (sk_ prefix)
120
+ */
121
+ private isPublicKey;
122
+ /**
123
+ * Create session internally for public keys
124
+ */
125
+ private createInternalSession;
126
+ private getUrlConfig;
127
+ private getTrustedOrigins;
128
+ private getAllowedCustomOrigins;
129
+ private getLocalOrigin;
130
+ private applyLocalVerifyOverride;
131
+ private getHmacSecret;
132
+ }
package/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './brands/safepassage';
2
+ export { default } from './brands/safepassage';