@edge-markets/connect-link 1.3.0 → 1.4.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/dist/index.d.mts +79 -3
- package/dist/index.d.ts +79 -3
- package/dist/index.js +51 -2
- package/dist/index.mjs +56 -19
- package/package.json +4 -2
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { EdgeLinkConfigBase, EdgeScope, EdgeLinkSuccess, EdgeLinkExit, PKCEPair } from '@edge-markets/connect';
|
|
2
|
-
export { ALL_EDGE_SCOPES, EDGE_SCOPES, EdgeEnvironment, EdgeError, EdgeLinkEvent, EdgeLinkEventName, EdgeLinkExit, EdgeLinkSuccess, EdgePopupBlockedError, EdgeScope, EdgeStateMismatchError, PKCEPair, isEdgeError } from '@edge-markets/connect';
|
|
1
|
+
import { EdgeLinkConfigBase, EdgeScope, EdgeLinkSuccess, EdgeLinkExit, SdkGeolocation, PKCEPair } from '@edge-markets/connect';
|
|
2
|
+
export { ALL_EDGE_SCOPES, EDGE_SCOPES, EdgeEnvironment, EdgeError, EdgeLinkEvent, EdgeLinkEventName, EdgeLinkExit, EdgeLinkSuccess, EdgePopupBlockedError, EdgeScope, EdgeStateMismatchError, PKCEPair, SdkGeolocation, isEdgeError } from '@edge-markets/connect';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* EdgeLink - Popup Authentication for EDGE Connect
|
|
@@ -99,6 +99,7 @@ declare class EdgeLink {
|
|
|
99
99
|
private state;
|
|
100
100
|
private messageHandler;
|
|
101
101
|
private isDestroyed;
|
|
102
|
+
private isInitializing;
|
|
102
103
|
/**
|
|
103
104
|
* Creates a new EdgeLink instance.
|
|
104
105
|
*
|
|
@@ -253,6 +254,7 @@ declare function useEdgeLink(config: UseEdgeLinkConfig): UseEdgeLinkReturn;
|
|
|
253
254
|
* verify.destroy()
|
|
254
255
|
* ```
|
|
255
256
|
*/
|
|
257
|
+
|
|
256
258
|
/**
|
|
257
259
|
* Event types emitted during the transfer verification flow.
|
|
258
260
|
*
|
|
@@ -418,6 +420,25 @@ interface EdgeTransferVerifyConfig {
|
|
|
418
420
|
* ```
|
|
419
421
|
*/
|
|
420
422
|
onEvent?: (event: TransferVerifyEvent) => void;
|
|
423
|
+
/**
|
|
424
|
+
* SDK-reported geolocation to forward to the verification page.
|
|
425
|
+
*
|
|
426
|
+
* Collect this using `collectGeolocation()` before opening the verification UI.
|
|
427
|
+
* The server cross-references it against IP-based geolocation for stronger
|
|
428
|
+
* state-level enforcement.
|
|
429
|
+
*
|
|
430
|
+
* @example
|
|
431
|
+
* ```typescript
|
|
432
|
+
* import { collectGeolocation } from '@edge-markets/connect-link'
|
|
433
|
+
*
|
|
434
|
+
* const geo = await collectGeolocation()
|
|
435
|
+
* const verify = new EdgeTransferVerify({
|
|
436
|
+
* // ...
|
|
437
|
+
* geolocation: geo ?? undefined,
|
|
438
|
+
* })
|
|
439
|
+
* ```
|
|
440
|
+
*/
|
|
441
|
+
geolocation?: SdkGeolocation;
|
|
421
442
|
}
|
|
422
443
|
/**
|
|
423
444
|
* EdgeTransferVerify - Transfer verification launcher for EDGE Connect.
|
|
@@ -600,6 +621,8 @@ declare class EdgeTransferVerify {
|
|
|
600
621
|
* Handles the loaded event from the verification page.
|
|
601
622
|
*
|
|
602
623
|
* The verification UI is ready for user interaction.
|
|
624
|
+
* If geolocation data was provided, forwards it to the verification page
|
|
625
|
+
* via postMessage for server-side cross-referencing.
|
|
603
626
|
*/
|
|
604
627
|
private handleLoaded;
|
|
605
628
|
/**
|
|
@@ -718,6 +741,59 @@ declare class IframeManager {
|
|
|
718
741
|
private hideLoadingState;
|
|
719
742
|
}
|
|
720
743
|
|
|
744
|
+
/**
|
|
745
|
+
* Browser Geolocation Collector for EDGE Connect
|
|
746
|
+
*
|
|
747
|
+
* Collects the user's geolocation from the Browser Geolocation API.
|
|
748
|
+
* The result can be passed to {@link EdgeTransferVerify} for cross-referencing
|
|
749
|
+
* against server-side IP-based geolocation.
|
|
750
|
+
*
|
|
751
|
+
* This function **never throws** — it returns `null` on permission denial,
|
|
752
|
+
* timeout, or API unavailability.
|
|
753
|
+
*
|
|
754
|
+
* @module @edge-markets/connect-link
|
|
755
|
+
*/
|
|
756
|
+
|
|
757
|
+
/**
|
|
758
|
+
* Options for geolocation collection.
|
|
759
|
+
*/
|
|
760
|
+
interface GeolocationOptions {
|
|
761
|
+
/** Timeout in milliseconds (default: 10000) */
|
|
762
|
+
timeout?: number;
|
|
763
|
+
/** Maximum age of a cached position in milliseconds (default: 60000) */
|
|
764
|
+
maximumAge?: number;
|
|
765
|
+
/** Whether to request high-accuracy positioning (default: false) */
|
|
766
|
+
enableHighAccuracy?: boolean;
|
|
767
|
+
}
|
|
768
|
+
/**
|
|
769
|
+
* Collects the user's geolocation from the Browser Geolocation API.
|
|
770
|
+
*
|
|
771
|
+
* Returns `null` silently if:
|
|
772
|
+
* - The Geolocation API is not available
|
|
773
|
+
* - The user denies permission
|
|
774
|
+
* - The request times out
|
|
775
|
+
* - Any other error occurs
|
|
776
|
+
*
|
|
777
|
+
* @param options - Optional configuration for the geolocation request
|
|
778
|
+
* @returns The user's geolocation, or `null` if unavailable
|
|
779
|
+
*
|
|
780
|
+
* @example
|
|
781
|
+
* ```typescript
|
|
782
|
+
* import { collectGeolocation, EdgeTransferVerify } from '@edge-markets/connect-link'
|
|
783
|
+
*
|
|
784
|
+
* const geo = await collectGeolocation()
|
|
785
|
+
*
|
|
786
|
+
* const verify = new EdgeTransferVerify({
|
|
787
|
+
* verificationUrl: session.verificationUrl,
|
|
788
|
+
* sessionId: session.sessionId,
|
|
789
|
+
* container: document.getElementById('verify-container')!,
|
|
790
|
+
* geolocation: geo ?? undefined,
|
|
791
|
+
* onSuccess: (event) => console.log('Verified!'),
|
|
792
|
+
* })
|
|
793
|
+
* ```
|
|
794
|
+
*/
|
|
795
|
+
declare function collectGeolocation(options?: GeolocationOptions): Promise<SdkGeolocation | null>;
|
|
796
|
+
|
|
721
797
|
/**
|
|
722
798
|
* PKCE (Proof Key for Code Exchange) Utilities
|
|
723
799
|
*
|
|
@@ -802,4 +878,4 @@ declare function generateState(): string;
|
|
|
802
878
|
*/
|
|
803
879
|
declare function assertCryptoAvailable(): void;
|
|
804
880
|
|
|
805
|
-
export { EdgeLink, type EdgeLinkConfig, type EdgeLinkOpenOptions, EdgeTransferVerify, type EdgeTransferVerifyConfig, type IframeCallbacks, type IframeConfig, IframeManager, type TransferVerifyEvent, type TransferVerifyEventType, type TransferVerifyMode, type UseEdgeLinkConfig, type UseEdgeLinkReturn, assertCryptoAvailable, generatePKCE, generateState, useEdgeLink };
|
|
881
|
+
export { EdgeLink, type EdgeLinkConfig, type EdgeLinkOpenOptions, EdgeTransferVerify, type EdgeTransferVerifyConfig, type GeolocationOptions, type IframeCallbacks, type IframeConfig, IframeManager, type TransferVerifyEvent, type TransferVerifyEventType, type TransferVerifyMode, type UseEdgeLinkConfig, type UseEdgeLinkReturn, assertCryptoAvailable, collectGeolocation, generatePKCE, generateState, useEdgeLink };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { EdgeLinkConfigBase, EdgeScope, EdgeLinkSuccess, EdgeLinkExit, PKCEPair } from '@edge-markets/connect';
|
|
2
|
-
export { ALL_EDGE_SCOPES, EDGE_SCOPES, EdgeEnvironment, EdgeError, EdgeLinkEvent, EdgeLinkEventName, EdgeLinkExit, EdgeLinkSuccess, EdgePopupBlockedError, EdgeScope, EdgeStateMismatchError, PKCEPair, isEdgeError } from '@edge-markets/connect';
|
|
1
|
+
import { EdgeLinkConfigBase, EdgeScope, EdgeLinkSuccess, EdgeLinkExit, SdkGeolocation, PKCEPair } from '@edge-markets/connect';
|
|
2
|
+
export { ALL_EDGE_SCOPES, EDGE_SCOPES, EdgeEnvironment, EdgeError, EdgeLinkEvent, EdgeLinkEventName, EdgeLinkExit, EdgeLinkSuccess, EdgePopupBlockedError, EdgeScope, EdgeStateMismatchError, PKCEPair, SdkGeolocation, isEdgeError } from '@edge-markets/connect';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* EdgeLink - Popup Authentication for EDGE Connect
|
|
@@ -99,6 +99,7 @@ declare class EdgeLink {
|
|
|
99
99
|
private state;
|
|
100
100
|
private messageHandler;
|
|
101
101
|
private isDestroyed;
|
|
102
|
+
private isInitializing;
|
|
102
103
|
/**
|
|
103
104
|
* Creates a new EdgeLink instance.
|
|
104
105
|
*
|
|
@@ -253,6 +254,7 @@ declare function useEdgeLink(config: UseEdgeLinkConfig): UseEdgeLinkReturn;
|
|
|
253
254
|
* verify.destroy()
|
|
254
255
|
* ```
|
|
255
256
|
*/
|
|
257
|
+
|
|
256
258
|
/**
|
|
257
259
|
* Event types emitted during the transfer verification flow.
|
|
258
260
|
*
|
|
@@ -418,6 +420,25 @@ interface EdgeTransferVerifyConfig {
|
|
|
418
420
|
* ```
|
|
419
421
|
*/
|
|
420
422
|
onEvent?: (event: TransferVerifyEvent) => void;
|
|
423
|
+
/**
|
|
424
|
+
* SDK-reported geolocation to forward to the verification page.
|
|
425
|
+
*
|
|
426
|
+
* Collect this using `collectGeolocation()` before opening the verification UI.
|
|
427
|
+
* The server cross-references it against IP-based geolocation for stronger
|
|
428
|
+
* state-level enforcement.
|
|
429
|
+
*
|
|
430
|
+
* @example
|
|
431
|
+
* ```typescript
|
|
432
|
+
* import { collectGeolocation } from '@edge-markets/connect-link'
|
|
433
|
+
*
|
|
434
|
+
* const geo = await collectGeolocation()
|
|
435
|
+
* const verify = new EdgeTransferVerify({
|
|
436
|
+
* // ...
|
|
437
|
+
* geolocation: geo ?? undefined,
|
|
438
|
+
* })
|
|
439
|
+
* ```
|
|
440
|
+
*/
|
|
441
|
+
geolocation?: SdkGeolocation;
|
|
421
442
|
}
|
|
422
443
|
/**
|
|
423
444
|
* EdgeTransferVerify - Transfer verification launcher for EDGE Connect.
|
|
@@ -600,6 +621,8 @@ declare class EdgeTransferVerify {
|
|
|
600
621
|
* Handles the loaded event from the verification page.
|
|
601
622
|
*
|
|
602
623
|
* The verification UI is ready for user interaction.
|
|
624
|
+
* If geolocation data was provided, forwards it to the verification page
|
|
625
|
+
* via postMessage for server-side cross-referencing.
|
|
603
626
|
*/
|
|
604
627
|
private handleLoaded;
|
|
605
628
|
/**
|
|
@@ -718,6 +741,59 @@ declare class IframeManager {
|
|
|
718
741
|
private hideLoadingState;
|
|
719
742
|
}
|
|
720
743
|
|
|
744
|
+
/**
|
|
745
|
+
* Browser Geolocation Collector for EDGE Connect
|
|
746
|
+
*
|
|
747
|
+
* Collects the user's geolocation from the Browser Geolocation API.
|
|
748
|
+
* The result can be passed to {@link EdgeTransferVerify} for cross-referencing
|
|
749
|
+
* against server-side IP-based geolocation.
|
|
750
|
+
*
|
|
751
|
+
* This function **never throws** — it returns `null` on permission denial,
|
|
752
|
+
* timeout, or API unavailability.
|
|
753
|
+
*
|
|
754
|
+
* @module @edge-markets/connect-link
|
|
755
|
+
*/
|
|
756
|
+
|
|
757
|
+
/**
|
|
758
|
+
* Options for geolocation collection.
|
|
759
|
+
*/
|
|
760
|
+
interface GeolocationOptions {
|
|
761
|
+
/** Timeout in milliseconds (default: 10000) */
|
|
762
|
+
timeout?: number;
|
|
763
|
+
/** Maximum age of a cached position in milliseconds (default: 60000) */
|
|
764
|
+
maximumAge?: number;
|
|
765
|
+
/** Whether to request high-accuracy positioning (default: false) */
|
|
766
|
+
enableHighAccuracy?: boolean;
|
|
767
|
+
}
|
|
768
|
+
/**
|
|
769
|
+
* Collects the user's geolocation from the Browser Geolocation API.
|
|
770
|
+
*
|
|
771
|
+
* Returns `null` silently if:
|
|
772
|
+
* - The Geolocation API is not available
|
|
773
|
+
* - The user denies permission
|
|
774
|
+
* - The request times out
|
|
775
|
+
* - Any other error occurs
|
|
776
|
+
*
|
|
777
|
+
* @param options - Optional configuration for the geolocation request
|
|
778
|
+
* @returns The user's geolocation, or `null` if unavailable
|
|
779
|
+
*
|
|
780
|
+
* @example
|
|
781
|
+
* ```typescript
|
|
782
|
+
* import { collectGeolocation, EdgeTransferVerify } from '@edge-markets/connect-link'
|
|
783
|
+
*
|
|
784
|
+
* const geo = await collectGeolocation()
|
|
785
|
+
*
|
|
786
|
+
* const verify = new EdgeTransferVerify({
|
|
787
|
+
* verificationUrl: session.verificationUrl,
|
|
788
|
+
* sessionId: session.sessionId,
|
|
789
|
+
* container: document.getElementById('verify-container')!,
|
|
790
|
+
* geolocation: geo ?? undefined,
|
|
791
|
+
* onSuccess: (event) => console.log('Verified!'),
|
|
792
|
+
* })
|
|
793
|
+
* ```
|
|
794
|
+
*/
|
|
795
|
+
declare function collectGeolocation(options?: GeolocationOptions): Promise<SdkGeolocation | null>;
|
|
796
|
+
|
|
721
797
|
/**
|
|
722
798
|
* PKCE (Proof Key for Code Exchange) Utilities
|
|
723
799
|
*
|
|
@@ -802,4 +878,4 @@ declare function generateState(): string;
|
|
|
802
878
|
*/
|
|
803
879
|
declare function assertCryptoAvailable(): void;
|
|
804
880
|
|
|
805
|
-
export { EdgeLink, type EdgeLinkConfig, type EdgeLinkOpenOptions, EdgeTransferVerify, type EdgeTransferVerifyConfig, type IframeCallbacks, type IframeConfig, IframeManager, type TransferVerifyEvent, type TransferVerifyEventType, type TransferVerifyMode, type UseEdgeLinkConfig, type UseEdgeLinkReturn, assertCryptoAvailable, generatePKCE, generateState, useEdgeLink };
|
|
881
|
+
export { EdgeLink, type EdgeLinkConfig, type EdgeLinkOpenOptions, EdgeTransferVerify, type EdgeTransferVerifyConfig, type GeolocationOptions, type IframeCallbacks, type IframeConfig, IframeManager, type TransferVerifyEvent, type TransferVerifyEventType, type TransferVerifyMode, type UseEdgeLinkConfig, type UseEdgeLinkReturn, assertCryptoAvailable, collectGeolocation, generatePKCE, generateState, useEdgeLink };
|
package/dist/index.js
CHANGED
|
@@ -29,6 +29,7 @@ __export(index_exports, {
|
|
|
29
29
|
EdgeTransferVerify: () => EdgeTransferVerify,
|
|
30
30
|
IframeManager: () => IframeManager,
|
|
31
31
|
assertCryptoAvailable: () => assertCryptoAvailable,
|
|
32
|
+
collectGeolocation: () => collectGeolocation,
|
|
32
33
|
generatePKCE: () => generatePKCE,
|
|
33
34
|
generateState: () => generateState,
|
|
34
35
|
isEdgeError: () => import_connect3.isEdgeError,
|
|
@@ -332,6 +333,7 @@ var EdgeLink = class {
|
|
|
332
333
|
this.state = null;
|
|
333
334
|
this.messageHandler = null;
|
|
334
335
|
this.isDestroyed = false;
|
|
336
|
+
this.isInitializing = false;
|
|
335
337
|
if (!config.clientId) {
|
|
336
338
|
throw new Error("EdgeLink: clientId is required");
|
|
337
339
|
}
|
|
@@ -376,7 +378,7 @@ var EdgeLink = class {
|
|
|
376
378
|
if (this.isDestroyed) {
|
|
377
379
|
throw new Error("EdgeLink: Cannot open - instance has been destroyed");
|
|
378
380
|
}
|
|
379
|
-
if (this.popup.isOpen()) {
|
|
381
|
+
if (this.popup.isOpen() || this.isInitializing) {
|
|
380
382
|
this.popup.focus();
|
|
381
383
|
return;
|
|
382
384
|
}
|
|
@@ -439,6 +441,7 @@ var EdgeLink = class {
|
|
|
439
441
|
* Initializes PKCE and navigates popup to auth URL.
|
|
440
442
|
*/
|
|
441
443
|
async initializeAuth(scopes) {
|
|
444
|
+
this.isInitializing = true;
|
|
442
445
|
try {
|
|
443
446
|
this.pkce = await generatePKCE();
|
|
444
447
|
this.state = generateState();
|
|
@@ -455,6 +458,8 @@ var EdgeLink = class {
|
|
|
455
458
|
message: error instanceof Error ? error.message : "Failed to initialize"
|
|
456
459
|
}
|
|
457
460
|
});
|
|
461
|
+
} finally {
|
|
462
|
+
this.isInitializing = false;
|
|
458
463
|
}
|
|
459
464
|
}
|
|
460
465
|
/**
|
|
@@ -486,6 +491,7 @@ var EdgeLink = class {
|
|
|
486
491
|
*/
|
|
487
492
|
setupMessageListener() {
|
|
488
493
|
this.messageHandler = (event) => {
|
|
494
|
+
if (this.isDestroyed) return;
|
|
489
495
|
if (event.origin !== this.expectedOrigin) {
|
|
490
496
|
return;
|
|
491
497
|
}
|
|
@@ -530,7 +536,7 @@ var EdgeLink = class {
|
|
|
530
536
|
}
|
|
531
537
|
});
|
|
532
538
|
this.close();
|
|
533
|
-
|
|
539
|
+
return;
|
|
534
540
|
}
|
|
535
541
|
if (!this.pkce?.verifier) {
|
|
536
542
|
this.config.onExit?.({
|
|
@@ -1160,9 +1166,27 @@ var EdgeTransferVerify = class {
|
|
|
1160
1166
|
* Handles the loaded event from the verification page.
|
|
1161
1167
|
*
|
|
1162
1168
|
* The verification UI is ready for user interaction.
|
|
1169
|
+
* If geolocation data was provided, forwards it to the verification page
|
|
1170
|
+
* via postMessage for server-side cross-referencing.
|
|
1163
1171
|
*/
|
|
1164
1172
|
handleLoaded(event) {
|
|
1165
1173
|
this.config.onLoaded?.(event);
|
|
1174
|
+
if (this.config.geolocation) {
|
|
1175
|
+
const target = this.mode === "popup" ? this.popupManager?.getWindow?.() : this.iframeManager?.getContentWindow?.();
|
|
1176
|
+
if (target) {
|
|
1177
|
+
target.postMessage(
|
|
1178
|
+
{
|
|
1179
|
+
type: "edge:transfer-verify:geo",
|
|
1180
|
+
nonce: this.nonce,
|
|
1181
|
+
latitude: this.config.geolocation.latitude,
|
|
1182
|
+
longitude: this.config.geolocation.longitude,
|
|
1183
|
+
accuracy: this.config.geolocation.accuracy,
|
|
1184
|
+
timestamp: this.config.geolocation.timestamp
|
|
1185
|
+
},
|
|
1186
|
+
this.expectedOrigin
|
|
1187
|
+
);
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1166
1190
|
}
|
|
1167
1191
|
/**
|
|
1168
1192
|
* Handles user closing the popup manually (popup mode only).
|
|
@@ -1184,6 +1208,30 @@ var EdgeTransferVerify = class {
|
|
|
1184
1208
|
}
|
|
1185
1209
|
};
|
|
1186
1210
|
|
|
1211
|
+
// src/geolocation.ts
|
|
1212
|
+
async function collectGeolocation(options) {
|
|
1213
|
+
if (typeof navigator === "undefined" || !navigator.geolocation) {
|
|
1214
|
+
return null;
|
|
1215
|
+
}
|
|
1216
|
+
try {
|
|
1217
|
+
const position = await new Promise((resolve, reject) => {
|
|
1218
|
+
navigator.geolocation.getCurrentPosition(resolve, reject, {
|
|
1219
|
+
timeout: options?.timeout ?? 1e4,
|
|
1220
|
+
maximumAge: options?.maximumAge ?? 6e4,
|
|
1221
|
+
enableHighAccuracy: options?.enableHighAccuracy ?? false
|
|
1222
|
+
});
|
|
1223
|
+
});
|
|
1224
|
+
return {
|
|
1225
|
+
latitude: position.coords.latitude,
|
|
1226
|
+
longitude: position.coords.longitude,
|
|
1227
|
+
accuracy: position.coords.accuracy,
|
|
1228
|
+
timestamp: new Date(position.timestamp).toISOString()
|
|
1229
|
+
};
|
|
1230
|
+
} catch {
|
|
1231
|
+
return null;
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1187
1235
|
// src/index.ts
|
|
1188
1236
|
var import_connect3 = require("@edge-markets/connect");
|
|
1189
1237
|
var import_connect4 = require("@edge-markets/connect");
|
|
@@ -1198,6 +1246,7 @@ var import_connect4 = require("@edge-markets/connect");
|
|
|
1198
1246
|
EdgeTransferVerify,
|
|
1199
1247
|
IframeManager,
|
|
1200
1248
|
assertCryptoAvailable,
|
|
1249
|
+
collectGeolocation,
|
|
1201
1250
|
generatePKCE,
|
|
1202
1251
|
generateState,
|
|
1203
1252
|
isEdgeError,
|
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
// src/edge-link.ts
|
|
2
2
|
import {
|
|
3
|
-
getEnvironmentConfig,
|
|
4
3
|
ALL_EDGE_SCOPES,
|
|
5
|
-
formatScopesForEnvironment,
|
|
6
4
|
EdgePopupBlockedError,
|
|
7
|
-
|
|
5
|
+
formatScopesForEnvironment,
|
|
6
|
+
getEnvironmentConfig
|
|
8
7
|
} from "@edge-markets/connect";
|
|
9
8
|
|
|
10
9
|
// src/pkce.ts
|
|
@@ -300,6 +299,7 @@ var EdgeLink = class {
|
|
|
300
299
|
this.state = null;
|
|
301
300
|
this.messageHandler = null;
|
|
302
301
|
this.isDestroyed = false;
|
|
302
|
+
this.isInitializing = false;
|
|
303
303
|
if (!config.clientId) {
|
|
304
304
|
throw new Error("EdgeLink: clientId is required");
|
|
305
305
|
}
|
|
@@ -344,7 +344,7 @@ var EdgeLink = class {
|
|
|
344
344
|
if (this.isDestroyed) {
|
|
345
345
|
throw new Error("EdgeLink: Cannot open - instance has been destroyed");
|
|
346
346
|
}
|
|
347
|
-
if (this.popup.isOpen()) {
|
|
347
|
+
if (this.popup.isOpen() || this.isInitializing) {
|
|
348
348
|
this.popup.focus();
|
|
349
349
|
return;
|
|
350
350
|
}
|
|
@@ -407,6 +407,7 @@ var EdgeLink = class {
|
|
|
407
407
|
* Initializes PKCE and navigates popup to auth URL.
|
|
408
408
|
*/
|
|
409
409
|
async initializeAuth(scopes) {
|
|
410
|
+
this.isInitializing = true;
|
|
410
411
|
try {
|
|
411
412
|
this.pkce = await generatePKCE();
|
|
412
413
|
this.state = generateState();
|
|
@@ -423,6 +424,8 @@ var EdgeLink = class {
|
|
|
423
424
|
message: error instanceof Error ? error.message : "Failed to initialize"
|
|
424
425
|
}
|
|
425
426
|
});
|
|
427
|
+
} finally {
|
|
428
|
+
this.isInitializing = false;
|
|
426
429
|
}
|
|
427
430
|
}
|
|
428
431
|
/**
|
|
@@ -454,6 +457,7 @@ var EdgeLink = class {
|
|
|
454
457
|
*/
|
|
455
458
|
setupMessageListener() {
|
|
456
459
|
this.messageHandler = (event) => {
|
|
460
|
+
if (this.isDestroyed) return;
|
|
457
461
|
if (event.origin !== this.expectedOrigin) {
|
|
458
462
|
return;
|
|
459
463
|
}
|
|
@@ -498,7 +502,7 @@ var EdgeLink = class {
|
|
|
498
502
|
}
|
|
499
503
|
});
|
|
500
504
|
this.close();
|
|
501
|
-
|
|
505
|
+
return;
|
|
502
506
|
}
|
|
503
507
|
if (!this.pkce?.verifier) {
|
|
504
508
|
this.config.onExit?.({
|
|
@@ -616,9 +620,7 @@ function useEdgeLink(config) {
|
|
|
616
620
|
}
|
|
617
621
|
|
|
618
622
|
// src/edge-transfer-verify.ts
|
|
619
|
-
import {
|
|
620
|
-
EdgePopupBlockedError as EdgePopupBlockedError2
|
|
621
|
-
} from "@edge-markets/connect";
|
|
623
|
+
import { EdgePopupBlockedError as EdgePopupBlockedError2 } from "@edge-markets/connect";
|
|
622
624
|
|
|
623
625
|
// src/iframe-manager.ts
|
|
624
626
|
var DEFAULT_TITLE = "EDGE Connect Transfer Verification";
|
|
@@ -1130,9 +1132,27 @@ var EdgeTransferVerify = class {
|
|
|
1130
1132
|
* Handles the loaded event from the verification page.
|
|
1131
1133
|
*
|
|
1132
1134
|
* The verification UI is ready for user interaction.
|
|
1135
|
+
* If geolocation data was provided, forwards it to the verification page
|
|
1136
|
+
* via postMessage for server-side cross-referencing.
|
|
1133
1137
|
*/
|
|
1134
1138
|
handleLoaded(event) {
|
|
1135
1139
|
this.config.onLoaded?.(event);
|
|
1140
|
+
if (this.config.geolocation) {
|
|
1141
|
+
const target = this.mode === "popup" ? this.popupManager?.getWindow?.() : this.iframeManager?.getContentWindow?.();
|
|
1142
|
+
if (target) {
|
|
1143
|
+
target.postMessage(
|
|
1144
|
+
{
|
|
1145
|
+
type: "edge:transfer-verify:geo",
|
|
1146
|
+
nonce: this.nonce,
|
|
1147
|
+
latitude: this.config.geolocation.latitude,
|
|
1148
|
+
longitude: this.config.geolocation.longitude,
|
|
1149
|
+
accuracy: this.config.geolocation.accuracy,
|
|
1150
|
+
timestamp: this.config.geolocation.timestamp
|
|
1151
|
+
},
|
|
1152
|
+
this.expectedOrigin
|
|
1153
|
+
);
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1136
1156
|
}
|
|
1137
1157
|
/**
|
|
1138
1158
|
* Handles user closing the popup manually (popup mode only).
|
|
@@ -1154,27 +1174,44 @@ var EdgeTransferVerify = class {
|
|
|
1154
1174
|
}
|
|
1155
1175
|
};
|
|
1156
1176
|
|
|
1177
|
+
// src/geolocation.ts
|
|
1178
|
+
async function collectGeolocation(options) {
|
|
1179
|
+
if (typeof navigator === "undefined" || !navigator.geolocation) {
|
|
1180
|
+
return null;
|
|
1181
|
+
}
|
|
1182
|
+
try {
|
|
1183
|
+
const position = await new Promise((resolve, reject) => {
|
|
1184
|
+
navigator.geolocation.getCurrentPosition(resolve, reject, {
|
|
1185
|
+
timeout: options?.timeout ?? 1e4,
|
|
1186
|
+
maximumAge: options?.maximumAge ?? 6e4,
|
|
1187
|
+
enableHighAccuracy: options?.enableHighAccuracy ?? false
|
|
1188
|
+
});
|
|
1189
|
+
});
|
|
1190
|
+
return {
|
|
1191
|
+
latitude: position.coords.latitude,
|
|
1192
|
+
longitude: position.coords.longitude,
|
|
1193
|
+
accuracy: position.coords.accuracy,
|
|
1194
|
+
timestamp: new Date(position.timestamp).toISOString()
|
|
1195
|
+
};
|
|
1196
|
+
} catch {
|
|
1197
|
+
return null;
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1157
1201
|
// src/index.ts
|
|
1158
|
-
import {
|
|
1159
|
-
|
|
1160
|
-
EdgeStateMismatchError as EdgeStateMismatchError2,
|
|
1161
|
-
EdgeError,
|
|
1162
|
-
isEdgeError
|
|
1163
|
-
} from "@edge-markets/connect";
|
|
1164
|
-
import {
|
|
1165
|
-
EDGE_SCOPES,
|
|
1166
|
-
ALL_EDGE_SCOPES as ALL_EDGE_SCOPES2
|
|
1167
|
-
} from "@edge-markets/connect";
|
|
1202
|
+
import { EdgeError, EdgePopupBlockedError as EdgePopupBlockedError3, EdgeStateMismatchError, isEdgeError } from "@edge-markets/connect";
|
|
1203
|
+
import { ALL_EDGE_SCOPES as ALL_EDGE_SCOPES2, EDGE_SCOPES } from "@edge-markets/connect";
|
|
1168
1204
|
export {
|
|
1169
1205
|
ALL_EDGE_SCOPES2 as ALL_EDGE_SCOPES,
|
|
1170
1206
|
EDGE_SCOPES,
|
|
1171
1207
|
EdgeError,
|
|
1172
1208
|
EdgeLink,
|
|
1173
1209
|
EdgePopupBlockedError3 as EdgePopupBlockedError,
|
|
1174
|
-
|
|
1210
|
+
EdgeStateMismatchError,
|
|
1175
1211
|
EdgeTransferVerify,
|
|
1176
1212
|
IframeManager,
|
|
1177
1213
|
assertCryptoAvailable,
|
|
1214
|
+
collectGeolocation,
|
|
1178
1215
|
generatePKCE,
|
|
1179
1216
|
generateState,
|
|
1180
1217
|
isEdgeError,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@edge-markets/connect-link",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Browser SDK for EDGE Connect popup authentication",
|
|
5
5
|
"author": "EdgeBoost",
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@edge-markets/connect": "1.
|
|
24
|
+
"@edge-markets/connect": "1.5.0"
|
|
25
25
|
},
|
|
26
26
|
"peerDependencies": {
|
|
27
27
|
"react": ">=17.0.0"
|
|
@@ -32,7 +32,9 @@
|
|
|
32
32
|
}
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
+
"@types/jsdom": "^28.0.1",
|
|
35
36
|
"@types/react": "^18.2.0",
|
|
37
|
+
"jsdom": "^29.0.2",
|
|
36
38
|
"tsup": "^8.0.0",
|
|
37
39
|
"typescript": "^5.3.0",
|
|
38
40
|
"vitest": "^1.0.0"
|