@evervault/react-native 2.4.0 → 2.5.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/build/ThreeDSecure/event.d.ts +11 -0
- package/build/ThreeDSecure/event.d.ts.map +1 -0
- package/build/ThreeDSecure/session.d.ts +4 -4
- package/build/ThreeDSecure/session.d.ts.map +1 -1
- package/build/ThreeDSecure/types.d.ts +15 -3
- package/build/ThreeDSecure/types.d.ts.map +1 -1
- package/build/ThreeDSecure/useThreeDSecure.d.ts +4 -1
- package/build/ThreeDSecure/useThreeDSecure.d.ts.map +1 -1
- package/build/index.cjs.js +89 -31
- package/build/index.cjs.js.map +1 -1
- package/build/index.esm.js +89 -31
- package/package.json +1 -1
- package/src/ThreeDSecure/event.ts +19 -0
- package/src/ThreeDSecure/session.test.ts +219 -24
- package/src/ThreeDSecure/session.ts +76 -24
- package/src/ThreeDSecure/types.ts +17 -4
- package/src/ThreeDSecure/useThreeDSecure.test.tsx +112 -1
- package/src/ThreeDSecure/useThreeDSecure.ts +23 -6
package/build/index.esm.js
CHANGED
|
@@ -7583,6 +7583,23 @@ const defaultStyles = StyleSheet.create({
|
|
|
7583
7583
|
},
|
|
7584
7584
|
});
|
|
7585
7585
|
|
|
7586
|
+
class ThreeDSecureEvent {
|
|
7587
|
+
type;
|
|
7588
|
+
session;
|
|
7589
|
+
_defaultPrevented;
|
|
7590
|
+
constructor(type, session, _defaultPrevented = false) {
|
|
7591
|
+
this.type = type;
|
|
7592
|
+
this.session = session;
|
|
7593
|
+
this._defaultPrevented = _defaultPrevented;
|
|
7594
|
+
}
|
|
7595
|
+
preventDefault() {
|
|
7596
|
+
this._defaultPrevented = true;
|
|
7597
|
+
}
|
|
7598
|
+
get defaultPrevented() {
|
|
7599
|
+
return this._defaultPrevented;
|
|
7600
|
+
}
|
|
7601
|
+
}
|
|
7602
|
+
|
|
7586
7603
|
function stopPolling(intervalRef, setIsVisible) {
|
|
7587
7604
|
setIsVisible(false);
|
|
7588
7605
|
if (intervalRef.current) {
|
|
@@ -7590,55 +7607,91 @@ function stopPolling(intervalRef, setIsVisible) {
|
|
|
7590
7607
|
intervalRef.current = null;
|
|
7591
7608
|
}
|
|
7592
7609
|
}
|
|
7593
|
-
async function startSession(session,
|
|
7610
|
+
async function startSession(session, options, intervalRef, setIsVisible) {
|
|
7594
7611
|
try {
|
|
7595
7612
|
const sessionState = await session.get();
|
|
7613
|
+
function fail() {
|
|
7614
|
+
stopPolling(intervalRef, setIsVisible);
|
|
7615
|
+
options?.onFailure?.(new Error("3DS session failed"));
|
|
7616
|
+
}
|
|
7596
7617
|
switch (sessionState.status) {
|
|
7597
|
-
case "success":
|
|
7618
|
+
case "success": {
|
|
7598
7619
|
stopPolling(intervalRef, setIsVisible);
|
|
7599
|
-
|
|
7620
|
+
options?.onSuccess?.();
|
|
7600
7621
|
break;
|
|
7601
|
-
|
|
7602
|
-
|
|
7603
|
-
|
|
7622
|
+
}
|
|
7623
|
+
case "failure": {
|
|
7624
|
+
fail();
|
|
7604
7625
|
break;
|
|
7605
|
-
|
|
7626
|
+
}
|
|
7627
|
+
case "action-required": {
|
|
7628
|
+
const failOnChallenge = typeof options?.failOnChallenge === "function"
|
|
7629
|
+
? await options.failOnChallenge()
|
|
7630
|
+
: options?.failOnChallenge ?? false;
|
|
7631
|
+
if (failOnChallenge) {
|
|
7632
|
+
fail();
|
|
7633
|
+
break;
|
|
7634
|
+
}
|
|
7635
|
+
const event = new ThreeDSecureEvent("requestChallenge", session);
|
|
7636
|
+
options?.onRequestChallenge?.(event);
|
|
7637
|
+
if (event.defaultPrevented) {
|
|
7638
|
+
fail();
|
|
7639
|
+
break;
|
|
7640
|
+
}
|
|
7606
7641
|
setIsVisible(true);
|
|
7607
|
-
pollSession(session,
|
|
7608
|
-
|
|
7609
|
-
default:
|
|
7610
|
-
break;
|
|
7642
|
+
pollSession(session, options, intervalRef, setIsVisible);
|
|
7643
|
+
}
|
|
7611
7644
|
}
|
|
7612
7645
|
}
|
|
7613
7646
|
catch (error) {
|
|
7614
7647
|
console.error("Error checking session state", error);
|
|
7615
|
-
|
|
7648
|
+
options?.onError?.(new Error("Failed to check 3DS session state"));
|
|
7616
7649
|
}
|
|
7617
7650
|
}
|
|
7618
|
-
function pollSession(session,
|
|
7651
|
+
function pollSession(session, options, intervalRef, setIsVisible, interval = 3000) {
|
|
7652
|
+
function fail() {
|
|
7653
|
+
stopPolling(intervalRef, setIsVisible);
|
|
7654
|
+
options?.onFailure?.(new Error("3DS session failed"));
|
|
7655
|
+
}
|
|
7619
7656
|
intervalRef.current = setInterval(async () => {
|
|
7620
7657
|
try {
|
|
7621
7658
|
const pollResponse = await session.get();
|
|
7622
|
-
|
|
7623
|
-
|
|
7624
|
-
|
|
7625
|
-
|
|
7626
|
-
|
|
7627
|
-
|
|
7628
|
-
|
|
7629
|
-
|
|
7630
|
-
|
|
7631
|
-
|
|
7659
|
+
switch (pollResponse.status) {
|
|
7660
|
+
case "success": {
|
|
7661
|
+
stopPolling(intervalRef, setIsVisible);
|
|
7662
|
+
options?.onSuccess?.();
|
|
7663
|
+
break;
|
|
7664
|
+
}
|
|
7665
|
+
case "failure": {
|
|
7666
|
+
fail();
|
|
7667
|
+
break;
|
|
7668
|
+
}
|
|
7669
|
+
case "action-required": {
|
|
7670
|
+
const failOnChallenge = typeof options?.failOnChallenge === "function"
|
|
7671
|
+
? await options.failOnChallenge()
|
|
7672
|
+
: options?.failOnChallenge ?? false;
|
|
7673
|
+
if (failOnChallenge) {
|
|
7674
|
+
fail();
|
|
7675
|
+
break;
|
|
7676
|
+
}
|
|
7677
|
+
const event = new ThreeDSecureEvent("requestChallenge", session);
|
|
7678
|
+
options?.onRequestChallenge?.(event);
|
|
7679
|
+
if (event.defaultPrevented) {
|
|
7680
|
+
fail();
|
|
7681
|
+
break;
|
|
7682
|
+
}
|
|
7683
|
+
setIsVisible(true);
|
|
7684
|
+
}
|
|
7632
7685
|
}
|
|
7633
7686
|
}
|
|
7634
7687
|
catch (error) {
|
|
7635
7688
|
stopPolling(intervalRef, setIsVisible);
|
|
7636
7689
|
console.error("Error polling session", error);
|
|
7637
|
-
|
|
7690
|
+
options?.onError?.(new Error("Error polling 3DS session"));
|
|
7638
7691
|
}
|
|
7639
7692
|
}, interval);
|
|
7640
7693
|
}
|
|
7641
|
-
function threeDSecureSession({ sessionId, appId,
|
|
7694
|
+
function threeDSecureSession({ sessionId, appId, options, intervalRef, setIsVisible, }) {
|
|
7642
7695
|
async function get() {
|
|
7643
7696
|
try {
|
|
7644
7697
|
const response = await fetch(`https://${EV_API_DOMAIN}/frontend/3ds/browser-sessions/${sessionId}`, {
|
|
@@ -7664,7 +7717,7 @@ function threeDSecureSession({ sessionId, appId, callbacks, intervalRef, setIsVi
|
|
|
7664
7717
|
},
|
|
7665
7718
|
body: JSON.stringify({ outcome: "cancelled" }),
|
|
7666
7719
|
});
|
|
7667
|
-
|
|
7720
|
+
options?.onFailure?.(new Error("3DS session cancelled by user"));
|
|
7668
7721
|
stopPolling(intervalRef, setIsVisible);
|
|
7669
7722
|
}
|
|
7670
7723
|
catch (error) {
|
|
@@ -7679,22 +7732,27 @@ function threeDSecureSession({ sessionId, appId, callbacks, intervalRef, setIsVi
|
|
|
7679
7732
|
};
|
|
7680
7733
|
}
|
|
7681
7734
|
|
|
7682
|
-
function useThreeDSecure() {
|
|
7735
|
+
function useThreeDSecure(options) {
|
|
7683
7736
|
const { appId } = useEvervault();
|
|
7684
7737
|
const intervalRef = useRef(null);
|
|
7685
7738
|
const [session, setSession] = useState(null);
|
|
7686
7739
|
const [isVisible, setIsVisible] = useState(false);
|
|
7687
|
-
const
|
|
7740
|
+
const failOnChallenge = options?.failOnChallenge ?? false;
|
|
7741
|
+
const start = useCallback((sessionId, options) => {
|
|
7742
|
+
const startOptions = {
|
|
7743
|
+
...options,
|
|
7744
|
+
failOnChallenge: options?.failOnChallenge ?? failOnChallenge,
|
|
7745
|
+
};
|
|
7688
7746
|
const session = threeDSecureSession({
|
|
7689
7747
|
sessionId,
|
|
7690
7748
|
appId,
|
|
7691
|
-
|
|
7749
|
+
options: startOptions,
|
|
7692
7750
|
intervalRef,
|
|
7693
7751
|
setIsVisible,
|
|
7694
7752
|
});
|
|
7695
7753
|
setSession(session);
|
|
7696
|
-
startSession(session,
|
|
7697
|
-
}, [appId]);
|
|
7754
|
+
startSession(session, startOptions, intervalRef, setIsVisible);
|
|
7755
|
+
}, [appId, failOnChallenge]);
|
|
7698
7756
|
const cancel = useCallback(async () => {
|
|
7699
7757
|
if (session) {
|
|
7700
7758
|
await session.cancel();
|
package/package.json
CHANGED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ThreeDSecureSession } from "./types";
|
|
2
|
+
|
|
3
|
+
export type ThreeDSecureEventType = "requestChallenge";
|
|
4
|
+
|
|
5
|
+
export class ThreeDSecureEvent {
|
|
6
|
+
constructor(
|
|
7
|
+
public readonly type: ThreeDSecureEventType,
|
|
8
|
+
public readonly session: ThreeDSecureSession,
|
|
9
|
+
private _defaultPrevented: boolean = false
|
|
10
|
+
) {}
|
|
11
|
+
|
|
12
|
+
public preventDefault() {
|
|
13
|
+
this._defaultPrevented = true;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
public get defaultPrevented() {
|
|
17
|
+
return this._defaultPrevented;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { EV_API_DOMAIN } from "./config";
|
|
2
|
+
import { ThreeDSecureEvent } from "./event";
|
|
2
3
|
import {
|
|
3
4
|
pollSession,
|
|
4
5
|
startSession,
|
|
@@ -24,7 +25,7 @@ describe("stopPolling", () => {
|
|
|
24
25
|
});
|
|
25
26
|
|
|
26
27
|
describe("startSession", () => {
|
|
27
|
-
const
|
|
28
|
+
const options = {
|
|
28
29
|
onSuccess: vi.fn(),
|
|
29
30
|
onFailure: vi.fn(),
|
|
30
31
|
onError: vi.fn(),
|
|
@@ -32,6 +33,10 @@ describe("startSession", () => {
|
|
|
32
33
|
const intervalRef = { current: null };
|
|
33
34
|
const setIsVisible = vi.fn();
|
|
34
35
|
|
|
36
|
+
beforeEach(() => {
|
|
37
|
+
vi.clearAllMocks();
|
|
38
|
+
});
|
|
39
|
+
|
|
35
40
|
it("should start a successful session", async () => {
|
|
36
41
|
const session: ThreeDSecureSession = {
|
|
37
42
|
cancel: vi.fn(),
|
|
@@ -39,10 +44,10 @@ describe("startSession", () => {
|
|
|
39
44
|
sessionId: "123",
|
|
40
45
|
};
|
|
41
46
|
|
|
42
|
-
await startSession(session,
|
|
47
|
+
await startSession(session, options, intervalRef, setIsVisible);
|
|
43
48
|
|
|
44
49
|
expect(session.get).toHaveBeenCalled();
|
|
45
|
-
expect(
|
|
50
|
+
expect(options.onSuccess).toHaveBeenCalled();
|
|
46
51
|
});
|
|
47
52
|
|
|
48
53
|
it("should start a failed session", async () => {
|
|
@@ -52,10 +57,10 @@ describe("startSession", () => {
|
|
|
52
57
|
sessionId: "123",
|
|
53
58
|
};
|
|
54
59
|
|
|
55
|
-
await startSession(session,
|
|
60
|
+
await startSession(session, options, intervalRef, setIsVisible);
|
|
56
61
|
|
|
57
62
|
expect(session.get).toHaveBeenCalled();
|
|
58
|
-
expect(
|
|
63
|
+
expect(options.onFailure).toHaveBeenCalledWith(
|
|
59
64
|
new Error("3DS session failed")
|
|
60
65
|
);
|
|
61
66
|
});
|
|
@@ -67,12 +72,98 @@ describe("startSession", () => {
|
|
|
67
72
|
sessionId: "123",
|
|
68
73
|
};
|
|
69
74
|
|
|
70
|
-
await startSession(session,
|
|
75
|
+
await startSession(session, options, intervalRef, setIsVisible);
|
|
71
76
|
|
|
72
77
|
expect(session.get).toHaveBeenCalled();
|
|
73
78
|
expect(setIsVisible).toHaveBeenCalledWith(true);
|
|
74
79
|
});
|
|
75
80
|
|
|
81
|
+
it("should fail the session when failOnChallenge is true and a challenge is required", async () => {
|
|
82
|
+
const session: ThreeDSecureSession = {
|
|
83
|
+
cancel: vi.fn(),
|
|
84
|
+
get: vi.fn(() => Promise.resolve({ status: "action-required" }) as any),
|
|
85
|
+
sessionId: "123",
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
await startSession(
|
|
89
|
+
session,
|
|
90
|
+
{ ...options, failOnChallenge: true },
|
|
91
|
+
intervalRef,
|
|
92
|
+
setIsVisible
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
expect(session.get).toHaveBeenCalled();
|
|
96
|
+
expect(options.onFailure).toHaveBeenCalledWith(
|
|
97
|
+
new Error("3DS session failed")
|
|
98
|
+
);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it("should fail the session when failOnChallenge is a function that returns true and a challenge is required", async () => {
|
|
102
|
+
const session: ThreeDSecureSession = {
|
|
103
|
+
cancel: vi.fn(),
|
|
104
|
+
get: vi.fn(() => Promise.resolve({ status: "action-required" }) as any),
|
|
105
|
+
sessionId: "123",
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
await startSession(
|
|
109
|
+
session,
|
|
110
|
+
{ ...options, failOnChallenge: () => Promise.resolve(true) },
|
|
111
|
+
intervalRef,
|
|
112
|
+
setIsVisible
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
expect(session.get).toHaveBeenCalled();
|
|
116
|
+
expect(options.onFailure).toHaveBeenCalledWith(
|
|
117
|
+
new Error("3DS session failed")
|
|
118
|
+
);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it("should call onRequestChallenge when a challenge is required", async () => {
|
|
122
|
+
const session: ThreeDSecureSession = {
|
|
123
|
+
cancel: vi.fn(),
|
|
124
|
+
get: vi.fn(() => Promise.resolve({ status: "action-required" }) as any),
|
|
125
|
+
sessionId: "123",
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const onRequestChallenge = vi.fn();
|
|
129
|
+
|
|
130
|
+
await startSession(
|
|
131
|
+
session,
|
|
132
|
+
{ ...options, onRequestChallenge },
|
|
133
|
+
intervalRef,
|
|
134
|
+
setIsVisible
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
expect(session.get).toHaveBeenCalled();
|
|
138
|
+
expect(onRequestChallenge).toHaveBeenCalled();
|
|
139
|
+
expect(options.onFailure).not.toHaveBeenCalled();
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it("should fail the session when onRequestChallenge is called and default is prevented", async () => {
|
|
143
|
+
const session: ThreeDSecureSession = {
|
|
144
|
+
cancel: vi.fn(),
|
|
145
|
+
get: vi.fn(() => Promise.resolve({ status: "action-required" }) as any),
|
|
146
|
+
sessionId: "123",
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const onRequestChallenge = vi.fn((event: ThreeDSecureEvent) => {
|
|
150
|
+
event.preventDefault();
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
await startSession(
|
|
154
|
+
session,
|
|
155
|
+
{ ...options, onRequestChallenge },
|
|
156
|
+
intervalRef,
|
|
157
|
+
setIsVisible
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
expect(session.get).toHaveBeenCalled();
|
|
161
|
+
expect(onRequestChallenge).toHaveBeenCalled();
|
|
162
|
+
expect(options.onFailure).toHaveBeenCalledWith(
|
|
163
|
+
new Error("3DS session failed")
|
|
164
|
+
);
|
|
165
|
+
});
|
|
166
|
+
|
|
76
167
|
it("should call onError if the session fails to start", async () => {
|
|
77
168
|
const session: ThreeDSecureSession = {
|
|
78
169
|
cancel: vi.fn(),
|
|
@@ -84,21 +175,21 @@ describe("startSession", () => {
|
|
|
84
175
|
.spyOn(console, "error")
|
|
85
176
|
.mockImplementation(() => {});
|
|
86
177
|
|
|
87
|
-
await startSession(session,
|
|
178
|
+
await startSession(session, options, intervalRef, setIsVisible);
|
|
88
179
|
|
|
89
180
|
expect(session.get).toHaveBeenCalled();
|
|
90
181
|
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
91
182
|
"Error checking session state",
|
|
92
183
|
new Error("Failed to start session")
|
|
93
184
|
);
|
|
94
|
-
expect(
|
|
185
|
+
expect(options.onError).toHaveBeenCalledWith(
|
|
95
186
|
new Error("Failed to check 3DS session state")
|
|
96
187
|
);
|
|
97
188
|
});
|
|
98
189
|
});
|
|
99
190
|
|
|
100
191
|
describe("pollSession", () => {
|
|
101
|
-
const
|
|
192
|
+
const options = {
|
|
102
193
|
onSuccess: vi.fn(),
|
|
103
194
|
onFailure: vi.fn(),
|
|
104
195
|
onError: vi.fn(),
|
|
@@ -106,6 +197,10 @@ describe("pollSession", () => {
|
|
|
106
197
|
const intervalRef = { current: null };
|
|
107
198
|
const setIsVisible = vi.fn();
|
|
108
199
|
|
|
200
|
+
beforeEach(() => {
|
|
201
|
+
vi.clearAllMocks();
|
|
202
|
+
});
|
|
203
|
+
|
|
109
204
|
it("should start an interval", () => {
|
|
110
205
|
const session: ThreeDSecureSession = {
|
|
111
206
|
cancel: vi.fn(),
|
|
@@ -114,7 +209,7 @@ describe("pollSession", () => {
|
|
|
114
209
|
};
|
|
115
210
|
|
|
116
211
|
const intervalSpy = vi.spyOn(global, "setInterval");
|
|
117
|
-
pollSession(session,
|
|
212
|
+
pollSession(session, options, intervalRef, setIsVisible);
|
|
118
213
|
|
|
119
214
|
expect(intervalSpy).toHaveBeenCalledWith(expect.any(Function), 3000);
|
|
120
215
|
});
|
|
@@ -127,11 +222,11 @@ describe("pollSession", () => {
|
|
|
127
222
|
};
|
|
128
223
|
|
|
129
224
|
const intervalSpy = vi.spyOn(global, "setInterval");
|
|
130
|
-
pollSession(session,
|
|
225
|
+
pollSession(session, options, intervalRef, setIsVisible);
|
|
131
226
|
await intervalSpy.mock.calls[0][0]();
|
|
132
227
|
|
|
133
228
|
expect(session.get).toHaveBeenCalled();
|
|
134
|
-
expect(
|
|
229
|
+
expect(options.onSuccess).toHaveBeenCalled();
|
|
135
230
|
});
|
|
136
231
|
|
|
137
232
|
it("should poll failed session", async () => {
|
|
@@ -142,11 +237,11 @@ describe("pollSession", () => {
|
|
|
142
237
|
};
|
|
143
238
|
|
|
144
239
|
const intervalSpy = vi.spyOn(global, "setInterval");
|
|
145
|
-
pollSession(session,
|
|
240
|
+
pollSession(session, options, intervalRef, setIsVisible);
|
|
146
241
|
await intervalSpy.mock.calls[0][0]();
|
|
147
242
|
|
|
148
243
|
expect(session.get).toHaveBeenCalled();
|
|
149
|
-
expect(
|
|
244
|
+
expect(options.onFailure).toHaveBeenCalledWith(
|
|
150
245
|
new Error("3DS session failed")
|
|
151
246
|
);
|
|
152
247
|
});
|
|
@@ -159,13 +254,113 @@ describe("pollSession", () => {
|
|
|
159
254
|
};
|
|
160
255
|
|
|
161
256
|
const intervalSpy = vi.spyOn(global, "setInterval");
|
|
162
|
-
pollSession(session,
|
|
257
|
+
pollSession(session, options, intervalRef, setIsVisible);
|
|
163
258
|
await intervalSpy.mock.calls[0][0]();
|
|
164
259
|
|
|
165
260
|
expect(session.get).toHaveBeenCalled();
|
|
166
261
|
expect(setIsVisible).toHaveBeenCalledWith(true);
|
|
167
262
|
});
|
|
168
263
|
|
|
264
|
+
it("should fail the session when failOnChallenge is true and a challenge is required", async () => {
|
|
265
|
+
const session: ThreeDSecureSession = {
|
|
266
|
+
cancel: vi.fn(),
|
|
267
|
+
get: vi.fn(() => Promise.resolve({ status: "action-required" }) as any),
|
|
268
|
+
sessionId: "123",
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
const intervalSpy = vi.spyOn(global, "setInterval");
|
|
272
|
+
const onRequestChallenge = vi.fn();
|
|
273
|
+
pollSession(
|
|
274
|
+
session,
|
|
275
|
+
{ ...options, failOnChallenge: true, onRequestChallenge },
|
|
276
|
+
intervalRef,
|
|
277
|
+
setIsVisible
|
|
278
|
+
);
|
|
279
|
+
await intervalSpy.mock.calls[0][0]();
|
|
280
|
+
|
|
281
|
+
expect(session.get).toHaveBeenCalled();
|
|
282
|
+
expect(onRequestChallenge).not.toHaveBeenCalled();
|
|
283
|
+
expect(options.onFailure).toHaveBeenCalledWith(
|
|
284
|
+
new Error("3DS session failed")
|
|
285
|
+
);
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
it("should fail the session when failOnChallenge is a function that returns true and a challenge is required", async () => {
|
|
289
|
+
const session: ThreeDSecureSession = {
|
|
290
|
+
cancel: vi.fn(),
|
|
291
|
+
get: vi.fn(() => Promise.resolve({ status: "action-required" }) as any),
|
|
292
|
+
sessionId: "123",
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
const intervalSpy = vi.spyOn(global, "setInterval");
|
|
296
|
+
const onRequestChallenge = vi.fn();
|
|
297
|
+
pollSession(
|
|
298
|
+
session,
|
|
299
|
+
{
|
|
300
|
+
...options,
|
|
301
|
+
onRequestChallenge,
|
|
302
|
+
failOnChallenge: () => Promise.resolve(true),
|
|
303
|
+
},
|
|
304
|
+
intervalRef,
|
|
305
|
+
setIsVisible
|
|
306
|
+
);
|
|
307
|
+
await intervalSpy.mock.calls[0][0]();
|
|
308
|
+
|
|
309
|
+
expect(session.get).toHaveBeenCalled();
|
|
310
|
+
expect(onRequestChallenge).not.toHaveBeenCalled();
|
|
311
|
+
expect(options.onFailure).toHaveBeenCalledWith(
|
|
312
|
+
new Error("3DS session failed")
|
|
313
|
+
);
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
it("should call onRequestChallenge when a challenge is required", async () => {
|
|
317
|
+
const session: ThreeDSecureSession = {
|
|
318
|
+
cancel: vi.fn(),
|
|
319
|
+
get: vi.fn(() => Promise.resolve({ status: "action-required" }) as any),
|
|
320
|
+
sessionId: "123",
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
const intervalSpy = vi.spyOn(global, "setInterval");
|
|
324
|
+
const onRequestChallenge = vi.fn();
|
|
325
|
+
pollSession(
|
|
326
|
+
session,
|
|
327
|
+
{ ...options, onRequestChallenge },
|
|
328
|
+
intervalRef,
|
|
329
|
+
setIsVisible
|
|
330
|
+
);
|
|
331
|
+
await intervalSpy.mock.calls[0][0]();
|
|
332
|
+
|
|
333
|
+
expect(session.get).toHaveBeenCalled();
|
|
334
|
+
expect(onRequestChallenge).toHaveBeenCalled();
|
|
335
|
+
expect(options.onFailure).not.toHaveBeenCalled();
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
it("should fail the session when onRequestChallenge is called and default is prevented", async () => {
|
|
339
|
+
const session: ThreeDSecureSession = {
|
|
340
|
+
cancel: vi.fn(),
|
|
341
|
+
get: vi.fn(() => Promise.resolve({ status: "action-required" }) as any),
|
|
342
|
+
sessionId: "123",
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
const intervalSpy = vi.spyOn(global, "setInterval");
|
|
346
|
+
const onRequestChallenge = vi.fn((event: ThreeDSecureEvent) => {
|
|
347
|
+
event.preventDefault();
|
|
348
|
+
});
|
|
349
|
+
pollSession(
|
|
350
|
+
session,
|
|
351
|
+
{ ...options, onRequestChallenge },
|
|
352
|
+
intervalRef,
|
|
353
|
+
setIsVisible
|
|
354
|
+
);
|
|
355
|
+
await intervalSpy.mock.calls[0][0]();
|
|
356
|
+
|
|
357
|
+
expect(session.get).toHaveBeenCalled();
|
|
358
|
+
expect(onRequestChallenge).toHaveBeenCalled();
|
|
359
|
+
expect(options.onFailure).toHaveBeenCalledWith(
|
|
360
|
+
new Error("3DS session failed")
|
|
361
|
+
);
|
|
362
|
+
});
|
|
363
|
+
|
|
169
364
|
it("should call onError if the session fails to poll", async () => {
|
|
170
365
|
const session: ThreeDSecureSession = {
|
|
171
366
|
cancel: vi.fn(),
|
|
@@ -178,7 +373,7 @@ describe("pollSession", () => {
|
|
|
178
373
|
.mockImplementation(() => {});
|
|
179
374
|
|
|
180
375
|
const intervalSpy = vi.spyOn(global, "setInterval");
|
|
181
|
-
pollSession(session,
|
|
376
|
+
pollSession(session, options, intervalRef, setIsVisible);
|
|
182
377
|
await intervalSpy.mock.calls[0][0]();
|
|
183
378
|
|
|
184
379
|
expect(session.get).toHaveBeenCalled();
|
|
@@ -186,14 +381,14 @@ describe("pollSession", () => {
|
|
|
186
381
|
"Error polling session",
|
|
187
382
|
new Error("Failed to poll session")
|
|
188
383
|
);
|
|
189
|
-
expect(
|
|
384
|
+
expect(options.onError).toHaveBeenCalledWith(
|
|
190
385
|
new Error("Error polling 3DS session")
|
|
191
386
|
);
|
|
192
387
|
});
|
|
193
388
|
});
|
|
194
389
|
|
|
195
390
|
describe("threeDSecureSession", () => {
|
|
196
|
-
const
|
|
391
|
+
const options = {
|
|
197
392
|
onSuccess: vi.fn(),
|
|
198
393
|
onFailure: vi.fn(),
|
|
199
394
|
onError: vi.fn(),
|
|
@@ -205,7 +400,7 @@ describe("threeDSecureSession", () => {
|
|
|
205
400
|
const session = threeDSecureSession({
|
|
206
401
|
sessionId: "123",
|
|
207
402
|
appId: "app_123",
|
|
208
|
-
|
|
403
|
+
options,
|
|
209
404
|
intervalRef,
|
|
210
405
|
setIsVisible,
|
|
211
406
|
});
|
|
@@ -220,7 +415,7 @@ describe("threeDSecureSession", () => {
|
|
|
220
415
|
const session = threeDSecureSession({
|
|
221
416
|
sessionId: "123",
|
|
222
417
|
appId: "app_123",
|
|
223
|
-
|
|
418
|
+
options,
|
|
224
419
|
intervalRef,
|
|
225
420
|
setIsVisible,
|
|
226
421
|
});
|
|
@@ -250,7 +445,7 @@ describe("threeDSecureSession", () => {
|
|
|
250
445
|
const session = threeDSecureSession({
|
|
251
446
|
sessionId: "123",
|
|
252
447
|
appId: "app_123",
|
|
253
|
-
|
|
448
|
+
options,
|
|
254
449
|
intervalRef,
|
|
255
450
|
setIsVisible,
|
|
256
451
|
});
|
|
@@ -275,7 +470,7 @@ describe("threeDSecureSession", () => {
|
|
|
275
470
|
const session = threeDSecureSession({
|
|
276
471
|
sessionId: "123",
|
|
277
472
|
appId: "app_123",
|
|
278
|
-
|
|
473
|
+
options,
|
|
279
474
|
intervalRef,
|
|
280
475
|
setIsVisible,
|
|
281
476
|
});
|
|
@@ -297,7 +492,7 @@ describe("threeDSecureSession", () => {
|
|
|
297
492
|
}
|
|
298
493
|
);
|
|
299
494
|
|
|
300
|
-
expect(
|
|
495
|
+
expect(options.onFailure).toHaveBeenCalledWith(
|
|
301
496
|
new Error("3DS session cancelled by user")
|
|
302
497
|
);
|
|
303
498
|
});
|
|
@@ -306,7 +501,7 @@ describe("threeDSecureSession", () => {
|
|
|
306
501
|
const session = threeDSecureSession({
|
|
307
502
|
sessionId: "123",
|
|
308
503
|
appId: "app_123",
|
|
309
|
-
|
|
504
|
+
options,
|
|
310
505
|
intervalRef,
|
|
311
506
|
setIsVisible,
|
|
312
507
|
});
|