@glideidentity/web-client-sdk 4.4.8-beta.1

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.
Files changed (136) hide show
  1. package/README.md +938 -0
  2. package/dist/adapters/angular/client.service.d.ts +7 -0
  3. package/dist/adapters/angular/client.service.js +30 -0
  4. package/dist/adapters/angular/index.d.ts +3 -0
  5. package/dist/adapters/angular/index.js +18 -0
  6. package/dist/adapters/angular/phone-auth.service.d.ts +38 -0
  7. package/dist/adapters/angular/phone-auth.service.js +130 -0
  8. package/dist/adapters/react/index.d.ts +9 -0
  9. package/dist/adapters/react/index.js +28 -0
  10. package/dist/adapters/react/useClient.d.ts +26 -0
  11. package/dist/adapters/react/useClient.js +121 -0
  12. package/dist/adapters/react/usePhoneAuth.d.ts +23 -0
  13. package/dist/adapters/react/usePhoneAuth.js +95 -0
  14. package/dist/adapters/vanilla/client.d.ts +8 -0
  15. package/dist/adapters/vanilla/client.js +33 -0
  16. package/dist/adapters/vanilla/index.d.ts +3 -0
  17. package/dist/adapters/vanilla/index.js +18 -0
  18. package/dist/adapters/vanilla/phone-auth.d.ts +46 -0
  19. package/dist/adapters/vanilla/phone-auth.js +138 -0
  20. package/dist/adapters/vue/index.d.ts +10 -0
  21. package/dist/adapters/vue/index.js +36 -0
  22. package/dist/adapters/vue/useClient.d.ts +115 -0
  23. package/dist/adapters/vue/useClient.js +131 -0
  24. package/dist/adapters/vue/usePhoneAuth.d.ts +94 -0
  25. package/dist/adapters/vue/usePhoneAuth.js +103 -0
  26. package/dist/browser/web-client-sdk.min.js +2 -0
  27. package/dist/browser/web-client-sdk.min.js.LICENSE.txt +1 -0
  28. package/dist/browser.d.ts +7 -0
  29. package/dist/browser.js +31 -0
  30. package/dist/core/client.d.ts +22 -0
  31. package/dist/core/client.js +77 -0
  32. package/dist/core/logger.d.ts +130 -0
  33. package/dist/core/logger.js +370 -0
  34. package/dist/core/phone-auth/api-types.d.ts +525 -0
  35. package/dist/core/phone-auth/api-types.js +215 -0
  36. package/dist/core/phone-auth/client.d.ts +187 -0
  37. package/dist/core/phone-auth/client.js +1353 -0
  38. package/dist/core/phone-auth/error-utils.d.ts +110 -0
  39. package/dist/core/phone-auth/error-utils.js +350 -0
  40. package/dist/core/phone-auth/index.d.ts +7 -0
  41. package/dist/core/phone-auth/index.js +47 -0
  42. package/dist/core/phone-auth/status-types.d.ts +107 -0
  43. package/dist/core/phone-auth/status-types.js +31 -0
  44. package/dist/core/phone-auth/strategies/desktop.d.ts +113 -0
  45. package/dist/core/phone-auth/strategies/desktop.js +502 -0
  46. package/dist/core/phone-auth/strategies/index.d.ts +11 -0
  47. package/dist/core/phone-auth/strategies/index.js +15 -0
  48. package/dist/core/phone-auth/strategies/link.d.ts +81 -0
  49. package/dist/core/phone-auth/strategies/link.js +265 -0
  50. package/dist/core/phone-auth/strategies/ts43.d.ts +32 -0
  51. package/dist/core/phone-auth/strategies/ts43.js +146 -0
  52. package/dist/core/phone-auth/strategies/types.d.ts +18 -0
  53. package/dist/core/phone-auth/strategies/types.js +6 -0
  54. package/dist/core/phone-auth/type-guards.d.ts +125 -0
  55. package/dist/core/phone-auth/type-guards.js +160 -0
  56. package/dist/core/phone-auth/types.d.ts +232 -0
  57. package/dist/core/phone-auth/types.js +93 -0
  58. package/dist/core/phone-auth/ui/mobile-debug-console.d.ts +25 -0
  59. package/dist/core/phone-auth/ui/mobile-debug-console.js +288 -0
  60. package/dist/core/phone-auth/ui/modal.d.ts +84 -0
  61. package/dist/core/phone-auth/ui/modal.js +574 -0
  62. package/dist/core/phone-auth/validation-utils.d.ts +66 -0
  63. package/dist/core/phone-auth/validation-utils.js +182 -0
  64. package/dist/core/types.d.ts +62 -0
  65. package/dist/core/types.js +2 -0
  66. package/dist/core/version.d.ts +1 -0
  67. package/dist/core/version.js +5 -0
  68. package/dist/esm/adapters/angular/client.service.d.ts +7 -0
  69. package/dist/esm/adapters/angular/client.service.js +27 -0
  70. package/dist/esm/adapters/angular/index.d.ts +3 -0
  71. package/dist/esm/adapters/angular/index.js +4 -0
  72. package/dist/esm/adapters/angular/phone-auth.service.d.ts +38 -0
  73. package/dist/esm/adapters/angular/phone-auth.service.js +127 -0
  74. package/dist/esm/adapters/react/index.d.ts +9 -0
  75. package/dist/esm/adapters/react/index.js +8 -0
  76. package/dist/esm/adapters/react/useClient.d.ts +26 -0
  77. package/dist/esm/adapters/react/useClient.js +116 -0
  78. package/dist/esm/adapters/react/usePhoneAuth.d.ts +23 -0
  79. package/dist/esm/adapters/react/usePhoneAuth.js +92 -0
  80. package/dist/esm/adapters/vanilla/client.d.ts +8 -0
  81. package/dist/esm/adapters/vanilla/client.js +29 -0
  82. package/dist/esm/adapters/vanilla/index.d.ts +3 -0
  83. package/dist/esm/adapters/vanilla/index.js +4 -0
  84. package/dist/esm/adapters/vanilla/phone-auth.d.ts +46 -0
  85. package/dist/esm/adapters/vanilla/phone-auth.js +134 -0
  86. package/dist/esm/adapters/vue/index.d.ts +10 -0
  87. package/dist/esm/adapters/vue/index.js +11 -0
  88. package/dist/esm/adapters/vue/useClient.d.ts +115 -0
  89. package/dist/esm/adapters/vue/useClient.js +127 -0
  90. package/dist/esm/adapters/vue/usePhoneAuth.d.ts +94 -0
  91. package/dist/esm/adapters/vue/usePhoneAuth.js +100 -0
  92. package/dist/esm/browser.d.ts +7 -0
  93. package/dist/esm/browser.js +11 -0
  94. package/dist/esm/core/client.d.ts +22 -0
  95. package/dist/esm/core/client.js +70 -0
  96. package/dist/esm/core/logger.d.ts +130 -0
  97. package/dist/esm/core/logger.js +359 -0
  98. package/dist/esm/core/phone-auth/api-types.d.ts +525 -0
  99. package/dist/esm/core/phone-auth/api-types.js +203 -0
  100. package/dist/esm/core/phone-auth/client.d.ts +187 -0
  101. package/dist/esm/core/phone-auth/client.js +1316 -0
  102. package/dist/esm/core/phone-auth/error-utils.d.ts +110 -0
  103. package/dist/esm/core/phone-auth/error-utils.js +338 -0
  104. package/dist/esm/core/phone-auth/index.d.ts +7 -0
  105. package/dist/esm/core/phone-auth/index.js +6 -0
  106. package/dist/esm/core/phone-auth/status-types.d.ts +107 -0
  107. package/dist/esm/core/phone-auth/status-types.js +26 -0
  108. package/dist/esm/core/phone-auth/strategies/desktop.d.ts +113 -0
  109. package/dist/esm/core/phone-auth/strategies/desktop.js +496 -0
  110. package/dist/esm/core/phone-auth/strategies/index.d.ts +11 -0
  111. package/dist/esm/core/phone-auth/strategies/index.js +7 -0
  112. package/dist/esm/core/phone-auth/strategies/link.d.ts +81 -0
  113. package/dist/esm/core/phone-auth/strategies/link.js +261 -0
  114. package/dist/esm/core/phone-auth/strategies/ts43.d.ts +32 -0
  115. package/dist/esm/core/phone-auth/strategies/ts43.js +142 -0
  116. package/dist/esm/core/phone-auth/strategies/types.d.ts +18 -0
  117. package/dist/esm/core/phone-auth/strategies/types.js +5 -0
  118. package/dist/esm/core/phone-auth/type-guards.d.ts +125 -0
  119. package/dist/esm/core/phone-auth/type-guards.js +150 -0
  120. package/dist/esm/core/phone-auth/types.d.ts +232 -0
  121. package/dist/esm/core/phone-auth/types.js +76 -0
  122. package/dist/esm/core/phone-auth/ui/mobile-debug-console.d.ts +25 -0
  123. package/dist/esm/core/phone-auth/ui/mobile-debug-console.js +284 -0
  124. package/dist/esm/core/phone-auth/ui/modal.d.ts +84 -0
  125. package/dist/esm/core/phone-auth/ui/modal.js +570 -0
  126. package/dist/esm/core/phone-auth/validation-utils.d.ts +66 -0
  127. package/dist/esm/core/phone-auth/validation-utils.js +174 -0
  128. package/dist/esm/core/types.d.ts +62 -0
  129. package/dist/esm/core/types.js +1 -0
  130. package/dist/esm/core/version.d.ts +1 -0
  131. package/dist/esm/core/version.js +2 -0
  132. package/dist/esm/index.d.ts +12 -0
  133. package/dist/esm/index.js +15 -0
  134. package/dist/index.d.ts +12 -0
  135. package/dist/index.js +52 -0
  136. package/package.json +92 -0
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Link Strategy Handler
3
+ * Handles authentication via app links (iOS and Android)
4
+ * Opens authentication app while keeping user on current page
5
+ */
6
+ import type { StrategyHandler } from './types';
7
+ import type { PrepareResponse } from '../types';
8
+ export interface LinkAuthOptions {
9
+ /** Fixed polling interval in milliseconds (default: 2000) */
10
+ pollingInterval?: number;
11
+ /** Maximum polling attempts before timeout (default: 150 = 5 minutes with 2s interval) */
12
+ maxPollingAttempts?: number;
13
+ /** Custom polling endpoint (overrides backend-provided or configured endpoint) */
14
+ pollingEndpoint?: string;
15
+ /** Callback when link is opened */
16
+ onLinkOpened?: () => void;
17
+ /** Callback for polling status updates */
18
+ onStatusUpdate?: (status: PollingStatus) => void;
19
+ /** Callback when authentication times out */
20
+ onTimeout?: () => void;
21
+ /** Callback when authentication is cancelled by user */
22
+ onCancel?: () => void;
23
+ }
24
+ export interface PollingStatus {
25
+ /** Current status of the authentication */
26
+ status: 'pending' | 'authenticated' | 'expired' | 'cancelled' | 'error';
27
+ /** Optional message */
28
+ message?: string;
29
+ /** Authentication result data if status is 'authenticated' */
30
+ data?: any;
31
+ }
32
+ export interface LinkAuthResult {
33
+ /** Whether authentication was successful */
34
+ authenticated: boolean;
35
+ /** Authentication credential if successful */
36
+ credential?: string;
37
+ /** Session info for subsequent requests */
38
+ session?: any;
39
+ /** Error message if authentication failed */
40
+ error?: string;
41
+ }
42
+ export declare class LinkHandler implements StrategyHandler {
43
+ private pollingInterval?;
44
+ private isPolling;
45
+ private isCancelled;
46
+ private onCancel?;
47
+ /**
48
+ * Invoke link-based authentication
49
+ * Opens authentication app while keeping user on current page
50
+ */
51
+ invoke(data: PrepareResponse, options?: LinkAuthOptions): Promise<LinkAuthResult>;
52
+ /**
53
+ * Open authentication link without navigating away
54
+ */
55
+ private openAuthenticationLink;
56
+ /**
57
+ * Start polling for authentication status with constant interval
58
+ */
59
+ private startPolling;
60
+ /**
61
+ * Stop polling
62
+ */
63
+ private stopPolling;
64
+ /**
65
+ * Format response for backend processing
66
+ */
67
+ formatResponse(response: LinkAuthResult): any;
68
+ /**
69
+ * Check if link strategy is supported
70
+ * Returns true for mobile devices (iOS and Android)
71
+ */
72
+ isSupported(): boolean;
73
+ /**
74
+ * Clean up resources (stop polling if active)
75
+ */
76
+ cleanup(): void;
77
+ /**
78
+ * Cancel the ongoing authentication
79
+ */
80
+ cancel(): void;
81
+ }
@@ -0,0 +1,265 @@
1
+ "use strict";
2
+ /**
3
+ * Link Strategy Handler
4
+ * Handles authentication via app links (iOS and Android)
5
+ * Opens authentication app while keeping user on current page
6
+ */
7
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
8
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
9
+ return new (P || (P = Promise))(function (resolve, reject) {
10
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
11
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
12
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
13
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
14
+ });
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.LinkHandler = void 0;
18
+ class LinkHandler {
19
+ constructor() {
20
+ this.isPolling = false;
21
+ this.isCancelled = false;
22
+ }
23
+ /**
24
+ * Invoke link-based authentication
25
+ * Opens authentication app while keeping user on current page
26
+ */
27
+ invoke(data, options) {
28
+ return __awaiter(this, void 0, void 0, function* () {
29
+ // Extract link data from prepare response
30
+ const linkData = data.data;
31
+ if (!linkData || !linkData.url) {
32
+ throw new Error('Invalid link data: missing URL');
33
+ }
34
+ const sessionKey = data.session.session_key;
35
+ // Open authentication app without navigating away from current page
36
+ this.openAuthenticationLink(linkData.url);
37
+ // Notify that link was opened
38
+ if (options === null || options === void 0 ? void 0 : options.onLinkOpened) {
39
+ options.onLinkOpened();
40
+ }
41
+ // Start polling for authentication status
42
+ // Use constant interval (no exponential backoff)
43
+ return this.startPolling(sessionKey, linkData, options);
44
+ });
45
+ }
46
+ /**
47
+ * Open authentication link without navigating away
48
+ */
49
+ openAuthenticationLink(url) {
50
+ // Always use window.open - Works best for App Clips and Android deep links
51
+ // Must be called in direct response to user action to avoid popup blocker
52
+ const newWindow = window.open(url, '_blank');
53
+ if (!newWindow || newWindow.closed || typeof newWindow.closed === 'undefined') {
54
+ // Popup was blocked - this can happen if not called from user gesture
55
+ console.warn('[LinkHandler] Failed to open app link - popup may have been blocked');
56
+ }
57
+ }
58
+ /**
59
+ * Start polling for authentication status with constant interval
60
+ */
61
+ startPolling(sessionKey, linkData, options) {
62
+ return __awaiter(this, void 0, void 0, function* () {
63
+ const interval = (options === null || options === void 0 ? void 0 : options.pollingInterval) || 2000; // Fixed 2 second interval
64
+ const maxAttempts = (options === null || options === void 0 ? void 0 : options.maxPollingAttempts) || 150; // 5 minutes with 2s interval
65
+ let attempts = 0;
66
+ return new Promise((resolve, reject) => {
67
+ this.isPolling = true;
68
+ const poll = () => __awaiter(this, void 0, void 0, function* () {
69
+ if (!this.isPolling) {
70
+ return; // Polling was stopped
71
+ }
72
+ try {
73
+ attempts++;
74
+ // Check max attempts
75
+ if (attempts >= maxAttempts) {
76
+ this.stopPolling();
77
+ if (options === null || options === void 0 ? void 0 : options.onTimeout) {
78
+ options.onTimeout();
79
+ }
80
+ if (options === null || options === void 0 ? void 0 : options.onStatusUpdate) {
81
+ options.onStatusUpdate({
82
+ status: 'expired',
83
+ message: 'Authentication timeout'
84
+ });
85
+ }
86
+ reject(new Error('Authentication timeout after 5 minutes'));
87
+ return;
88
+ }
89
+ // Build public status endpoint URL
90
+ let statusUrl;
91
+ // First priority: use status_url from link data if provided
92
+ if (linkData.status_url) {
93
+ statusUrl = linkData.status_url;
94
+ console.log('[Link Auth] Using status URL from link data:', statusUrl);
95
+ }
96
+ else {
97
+ statusUrl = `https://api.glideidentity.app/public/public/status/${sessionKey}`;
98
+ }
99
+ // Poll public status endpoint - no authentication required
100
+ const response = yield fetch(statusUrl, {
101
+ method: 'GET',
102
+ headers: {
103
+ 'Accept': 'application/json'
104
+ // No Authorization header needed for public endpoint
105
+ }
106
+ });
107
+ // Handle based on HTTP status code
108
+ if (response.status === 200) {
109
+ // Session is active (pending or completed)
110
+ const result = yield response.json();
111
+ if (result.status === 'completed') {
112
+ // Authentication completed successfully
113
+ this.stopPolling();
114
+ // Authentication completed successfully
115
+ if (options === null || options === void 0 ? void 0 : options.onStatusUpdate) {
116
+ options.onStatusUpdate({
117
+ status: 'authenticated',
118
+ message: 'Authentication successful',
119
+ data: result
120
+ });
121
+ }
122
+ // Return the authentication result
123
+ resolve({
124
+ authenticated: true,
125
+ credential: result.credential || sessionKey,
126
+ session: result.session || {
127
+ session_key: sessionKey,
128
+ status: result.status,
129
+ protocol: result.protocol || 'link',
130
+ created_at: result.created_at,
131
+ last_updated: result.last_updated
132
+ }
133
+ });
134
+ }
135
+ else if (result.status === 'pending') {
136
+ // Continue polling
137
+ if (options === null || options === void 0 ? void 0 : options.onStatusUpdate) {
138
+ options.onStatusUpdate({
139
+ status: 'pending',
140
+ message: 'Waiting for app authentication...'
141
+ });
142
+ }
143
+ }
144
+ }
145
+ else if (response.status === 410) {
146
+ // Session expired
147
+ this.stopPolling();
148
+ const errorData = yield response.json().catch(() => ({ message: 'Session expired' }));
149
+ if (options === null || options === void 0 ? void 0 : options.onTimeout) {
150
+ options.onTimeout();
151
+ }
152
+ if (options === null || options === void 0 ? void 0 : options.onStatusUpdate) {
153
+ options.onStatusUpdate({
154
+ status: 'expired',
155
+ message: errorData.message || 'Session expired'
156
+ });
157
+ }
158
+ reject(new Error(errorData.message || 'Session expired'));
159
+ }
160
+ else if (response.status === 422) {
161
+ // Authentication failed
162
+ this.stopPolling();
163
+ const errorData = yield response.json().catch(() => ({ message: 'Authentication failed' }));
164
+ const isUserCancelled = errorData.code === 'USER_CANCELLED';
165
+ const errorMsg = isUserCancelled
166
+ ? 'User cancelled authentication'
167
+ : (errorData.message || 'Verification failed');
168
+ // Authentication failed
169
+ if (options === null || options === void 0 ? void 0 : options.onStatusUpdate) {
170
+ options.onStatusUpdate({
171
+ status: 'error',
172
+ message: errorMsg
173
+ });
174
+ }
175
+ reject(new Error(errorMsg));
176
+ }
177
+ else if (response.status === 404) {
178
+ // Session not found
179
+ this.stopPolling();
180
+ if (options === null || options === void 0 ? void 0 : options.onStatusUpdate) {
181
+ options.onStatusUpdate({
182
+ status: 'error',
183
+ message: 'Session not found'
184
+ });
185
+ }
186
+ reject(new Error('Session not found'));
187
+ }
188
+ else if (response.status === 400) {
189
+ // Invalid session key
190
+ this.stopPolling();
191
+ const errorData = yield response.json().catch(() => ({ message: 'Invalid session key' }));
192
+ reject(new Error(errorData.message || 'Invalid session key'));
193
+ }
194
+ else {
195
+ // Unexpected status - continue polling
196
+ }
197
+ }
198
+ catch (error) {
199
+ // Network or other error - continue polling
200
+ if (options === null || options === void 0 ? void 0 : options.onStatusUpdate) {
201
+ options.onStatusUpdate({
202
+ status: 'pending',
203
+ message: `Connection issue, retrying... (${attempts}/${maxAttempts})`
204
+ });
205
+ }
206
+ }
207
+ });
208
+ // Start initial poll immediately
209
+ poll();
210
+ // Set up constant interval polling (no backoff)
211
+ this.pollingInterval = setInterval(poll, interval);
212
+ });
213
+ });
214
+ }
215
+ /**
216
+ * Stop polling
217
+ */
218
+ stopPolling() {
219
+ this.isPolling = false;
220
+ if (this.pollingInterval) {
221
+ clearInterval(this.pollingInterval);
222
+ this.pollingInterval = undefined;
223
+ }
224
+ }
225
+ /**
226
+ * Format response for backend processing
227
+ */
228
+ formatResponse(response) {
229
+ if (!response.authenticated || !response.credential) {
230
+ throw new Error('Authentication not completed');
231
+ }
232
+ return {
233
+ credential: response.credential,
234
+ session: response.session,
235
+ type: 'link'
236
+ };
237
+ }
238
+ /**
239
+ * Check if link strategy is supported
240
+ * Returns true for mobile devices (iOS and Android)
241
+ */
242
+ isSupported() {
243
+ // Link strategy is supported on mobile devices
244
+ const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
245
+ return isMobile;
246
+ }
247
+ /**
248
+ * Clean up resources (stop polling if active)
249
+ */
250
+ cleanup() {
251
+ this.stopPolling();
252
+ this.isCancelled = false;
253
+ this.onCancel = undefined;
254
+ }
255
+ /**
256
+ * Cancel the ongoing authentication
257
+ */
258
+ cancel() {
259
+ var _a;
260
+ this.isCancelled = true;
261
+ this.stopPolling();
262
+ (_a = this.onCancel) === null || _a === void 0 ? void 0 : _a.call(this);
263
+ }
264
+ }
265
+ exports.LinkHandler = LinkHandler;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * TS-43 Strategy Handler
3
+ * Handles Digital Credentials API authentication for Android/Chromium
4
+ * Properly manages session objects with session_key, nonce, and enc_key
5
+ */
6
+ import type { StrategyHandler } from './types';
7
+ import type { PrepareResponse } from '../types';
8
+ export declare class TS43Handler implements StrategyHandler {
9
+ /**
10
+ * Invoke TS-43 authentication using Digital Credentials API
11
+ * The data structure from backend is already in the correct format for navigator.credentials.get
12
+ */
13
+ invoke(data: PrepareResponse): Promise<any>;
14
+ /**
15
+ * Format the credential response for backend processing
16
+ * Include the session key so backend can retrieve the full session
17
+ */
18
+ formatResponse(response: any): any;
19
+ /**
20
+ * Check if Digital Credentials API is supported
21
+ */
22
+ isSupported(): boolean;
23
+ /**
24
+ * Get browser support information
25
+ */
26
+ getBrowserSupportInfo(): {
27
+ supported: boolean;
28
+ browser: string;
29
+ message?: string;
30
+ helpUrl?: string;
31
+ };
32
+ }
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+ /**
3
+ * TS-43 Strategy Handler
4
+ * Handles Digital Credentials API authentication for Android/Chromium
5
+ * Properly manages session objects with session_key, nonce, and enc_key
6
+ */
7
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
8
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
9
+ return new (P || (P = Promise))(function (resolve, reject) {
10
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
11
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
12
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
13
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
14
+ });
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.TS43Handler = void 0;
18
+ class TS43Handler {
19
+ /**
20
+ * Invoke TS-43 authentication using Digital Credentials API
21
+ * The data structure from backend is already in the correct format for navigator.credentials.get
22
+ */
23
+ invoke(data) {
24
+ return __awaiter(this, void 0, void 0, function* () {
25
+ // Validate session structure - only session_key is actually required
26
+ if (!data.session || !data.session.session_key) {
27
+ throw new Error('Invalid TS43 session: missing required session_key');
28
+ }
29
+ // Check if Digital Credentials API is available
30
+ if (!this.isSupported()) {
31
+ throw new Error('Digital Credentials API not supported in this browser');
32
+ }
33
+ // Extract TS43 data from the prepare response
34
+ const ts43Data = data.data;
35
+ // The data is already in the correct format from backend
36
+ // Just pass it through to navigator.credentials.get
37
+ const credentialRequest = {
38
+ digital: {
39
+ requests: [{
40
+ protocol: ts43Data.protocol, // e.g., "openid4vp-v1-unsigned"
41
+ data: ts43Data.data // Pass the entire data object as-is
42
+ }]
43
+ }
44
+ };
45
+ try {
46
+ // @ts-ignore - Digital Credentials API types not yet in TypeScript
47
+ const credential = yield navigator.credentials.get(credentialRequest);
48
+ if (!credential) {
49
+ throw new Error('No credential received from Digital Credentials API');
50
+ }
51
+ // @ts-ignore - credential.data is not typed yet
52
+ return credential;
53
+ }
54
+ catch (error) {
55
+ // Handle browser-specific errors
56
+ if (error instanceof Error) {
57
+ if (error.name === 'NotAllowedError') {
58
+ throw new Error('User denied the authentication request');
59
+ }
60
+ if (error.name === 'NotSupportedError') {
61
+ throw new Error('Digital Credentials API not supported');
62
+ }
63
+ if (error.name === 'AbortError') {
64
+ throw new Error('Authentication was aborted');
65
+ }
66
+ }
67
+ throw error;
68
+ }
69
+ });
70
+ }
71
+ /**
72
+ * Format the credential response for backend processing
73
+ * Include the session key so backend can retrieve the full session
74
+ */
75
+ formatResponse(response) {
76
+ var _a;
77
+ // Extract vp_token from the response
78
+ const vpToken = (_a = response.data) === null || _a === void 0 ? void 0 : _a.vp_token;
79
+ if (!vpToken) {
80
+ throw new Error('Invalid TS43 response: missing vp_token');
81
+ }
82
+ return {
83
+ vp_token: vpToken,
84
+ type: 'ts43'
85
+ };
86
+ }
87
+ /**
88
+ * Check if Digital Credentials API is supported
89
+ */
90
+ isSupported() {
91
+ if (typeof window === 'undefined') {
92
+ return false;
93
+ }
94
+ // Check for DigitalCredential constructor
95
+ // @ts-ignore - DigitalCredential not yet in TypeScript
96
+ return 'DigitalCredential' in window;
97
+ }
98
+ /**
99
+ * Get browser support information
100
+ */
101
+ getBrowserSupportInfo() {
102
+ if (typeof window === 'undefined') {
103
+ return {
104
+ supported: false,
105
+ browser: 'unknown',
106
+ message: 'Not running in a browser environment'
107
+ };
108
+ }
109
+ const userAgent = navigator.userAgent;
110
+ const isChrome = /Chrome/.test(userAgent) && /Google Inc/.test(navigator.vendor);
111
+ const isEdge = /Edg\//.test(userAgent);
112
+ const isAndroid = /Android/.test(userAgent);
113
+ const isSupported = this.isSupported();
114
+ if (isSupported) {
115
+ return {
116
+ supported: true,
117
+ browser: isChrome ? 'Chrome' : isEdge ? 'Edge' : 'Chromium'
118
+ };
119
+ }
120
+ // Provide specific guidance based on browser
121
+ if ((isChrome || isEdge) && isAndroid) {
122
+ return {
123
+ supported: false,
124
+ browser: isChrome ? 'Chrome' : 'Edge',
125
+ message: 'Digital Credentials API requires Chrome 128+ on Android. Please update your browser.',
126
+ helpUrl: 'https://play.google.com/store/apps/details?id=com.android.chrome'
127
+ };
128
+ }
129
+ if (isChrome || isEdge) {
130
+ return {
131
+ supported: false,
132
+ browser: isChrome ? 'Chrome' : 'Edge',
133
+ message: 'Digital Credentials API is not enabled. Please enable the #web-identity-digital-credentials flag.',
134
+ helpUrl: isChrome
135
+ ? 'chrome://flags/#web-identity-digital-credentials'
136
+ : 'edge://flags/#web-identity-digital-credentials'
137
+ };
138
+ }
139
+ return {
140
+ supported: false,
141
+ browser: 'unsupported',
142
+ message: 'Your browser does not support Digital Credentials API'
143
+ };
144
+ }
145
+ }
146
+ exports.TS43Handler = TS43Handler;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Strategy Handler Interface
3
+ * Defines the contract for authentication strategy implementations
4
+ */
5
+ export interface StrategyHandler {
6
+ /**
7
+ * Invoke authentication using strategy-specific data
8
+ */
9
+ invoke(data: any): Promise<any>;
10
+ /**
11
+ * Format response for backend processing
12
+ */
13
+ formatResponse(response: any): any;
14
+ /**
15
+ * Check if this strategy is supported in the current environment
16
+ */
17
+ isSupported(): boolean;
18
+ }
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ /**
3
+ * Strategy Handler Interface
4
+ * Defines the contract for authentication strategy implementations
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Type Guards and Helper Functions for Phone Authentication
3
+ *
4
+ * These utilities help developers work with the SDK responses in a type-safe way
5
+ * without having to write their own type checking logic.
6
+ */
7
+ import type { HeadlessResult } from './api-types';
8
+ /**
9
+ * Type guard to check if the result is a HeadlessResult (headless mode)
10
+ * or a Credential (UI mode).
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const result = await invokeSecurePrompt(sdkRequest);
15
+ *
16
+ * if (isHeadlessResult(result)) {
17
+ * // TypeScript knows this is HeadlessResult
18
+ * console.log(result.strategy);
19
+ * await result.trigger();
20
+ * } else {
21
+ * // TypeScript knows this is a Credential
22
+ * const processedResult = await verifyPhoneNumberCredential(result, session);
23
+ * }
24
+ * ```
25
+ */
26
+ export declare function isHeadlessResult(result: any): result is HeadlessResult;
27
+ /**
28
+ * Type guard to check if the result is a Credential (UI mode response).
29
+ * A credential is either a string token or an object without HeadlessResult properties.
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * if (isCredential(result)) {
34
+ * // Process the credential directly
35
+ * const verified = await verifyPhoneNumberCredential(result, session);
36
+ * }
37
+ * ```
38
+ */
39
+ export declare function isCredential(result: any): result is string | {
40
+ [aggregator_id: string]: string | string[];
41
+ };
42
+ /**
43
+ * Type guard to check if a HeadlessResult is using the Link strategy.
44
+ * Link strategy involves opening an app link (App Clip on iOS, app on Android).
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * if (isHeadlessResult(result) && isLinkStrategy(result)) {
49
+ * // Show custom button for opening app
50
+ * myButton.onclick = () => result.trigger();
51
+ * await result.pollingPromise;
52
+ * }
53
+ * ```
54
+ */
55
+ export declare function isLinkStrategy(result: HeadlessResult): result is HeadlessResult & {
56
+ strategy: 'link';
57
+ };
58
+ /**
59
+ * Type guard to check if a HeadlessResult is using the TS43 strategy.
60
+ * TS43 strategy uses the browser's Digital Credentials API.
61
+ *
62
+ * @example
63
+ * ```typescript
64
+ * if (isHeadlessResult(result) && isTS43Strategy(result)) {
65
+ * // Invoke credential API immediately or on button click
66
+ * const credential = await result.trigger();
67
+ * }
68
+ * ```
69
+ */
70
+ export declare function isTS43Strategy(result: HeadlessResult): result is HeadlessResult & {
71
+ strategy: 'ts43';
72
+ };
73
+ /**
74
+ * Type guard to check if a HeadlessResult is using the Desktop strategy.
75
+ * Desktop strategy involves QR codes for cross-device authentication.
76
+ *
77
+ * @example
78
+ * ```typescript
79
+ * if (isHeadlessResult(result) && isDesktopStrategy(result)) {
80
+ * // Show custom QR code UI
81
+ * displayQRCode(result.qrCodeUrl);
82
+ * await result.pollingPromise;
83
+ * }
84
+ * ```
85
+ */
86
+ export declare function isDesktopStrategy(result: HeadlessResult): result is HeadlessResult & {
87
+ strategy: 'desktop';
88
+ };
89
+ /**
90
+ * Helper function to safely get the authentication strategy from any result.
91
+ * Returns undefined if the result is not a HeadlessResult.
92
+ *
93
+ * @example
94
+ * ```typescript
95
+ * const strategy = getStrategy(result);
96
+ * if (strategy === 'link') {
97
+ * // Handle link strategy
98
+ * }
99
+ * ```
100
+ */
101
+ export declare function getStrategy(result: any): 'link' | 'ts43' | 'desktop' | undefined;
102
+ /**
103
+ * Helper function to determine if a result requires polling.
104
+ * Link and Desktop strategies require polling, TS43 does not.
105
+ *
106
+ * @example
107
+ * ```typescript
108
+ * if (requiresPolling(result)) {
109
+ * await result.pollingPromise;
110
+ * }
111
+ * ```
112
+ */
113
+ export declare function requiresPolling(result: any): boolean;
114
+ /**
115
+ * Helper function to determine if a result requires user interaction.
116
+ * All headless strategies require some form of user interaction.
117
+ *
118
+ * @example
119
+ * ```typescript
120
+ * if (requiresUserAction(result)) {
121
+ * showActionButton();
122
+ * }
123
+ * ```
124
+ */
125
+ export declare function requiresUserAction(result: any): boolean;