@evervault/react-native 2.4.0 → 2.5.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.
- 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 +138 -80
- package/build/index.cjs.js.map +1 -1
- package/build/index.esm.js +138 -80
- package/package.json +2 -2
- 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
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ThreeDSecureSession } from "./types";
|
|
2
|
+
export type ThreeDSecureEventType = "requestChallenge";
|
|
3
|
+
export declare class ThreeDSecureEvent {
|
|
4
|
+
readonly type: ThreeDSecureEventType;
|
|
5
|
+
readonly session: ThreeDSecureSession;
|
|
6
|
+
private _defaultPrevented;
|
|
7
|
+
constructor(type: ThreeDSecureEventType, session: ThreeDSecureSession, _defaultPrevented?: boolean);
|
|
8
|
+
preventDefault(): void;
|
|
9
|
+
get defaultPrevented(): boolean;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=event.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../src/ThreeDSecure/event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAE9C,MAAM,MAAM,qBAAqB,GAAG,kBAAkB,CAAC;AAEvD,qBAAa,iBAAiB;aAEV,IAAI,EAAE,qBAAqB;aAC3B,OAAO,EAAE,mBAAmB;IAC5C,OAAO,CAAC,iBAAiB;gBAFT,IAAI,EAAE,qBAAqB,EAC3B,OAAO,EAAE,mBAAmB,EACpC,iBAAiB,GAAE,OAAe;IAGrC,cAAc;IAIrB,IAAW,gBAAgB,YAE1B;CACF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ThreeDSecureSessionsParams, ThreeDSecureSession, ThreeDSecureOptions } from "./types";
|
|
2
2
|
export declare function stopPolling(intervalRef: React.MutableRefObject<NodeJS.Timeout | null>, setIsVisible: (show: boolean) => void): void;
|
|
3
|
-
export declare function startSession(session: ThreeDSecureSession,
|
|
4
|
-
export declare function pollSession(session: ThreeDSecureSession,
|
|
5
|
-
export declare function threeDSecureSession({ sessionId, appId,
|
|
3
|
+
export declare function startSession(session: ThreeDSecureSession, options: ThreeDSecureOptions | undefined, intervalRef: React.MutableRefObject<NodeJS.Timeout | null>, setIsVisible: (show: boolean) => void): Promise<void>;
|
|
4
|
+
export declare function pollSession(session: ThreeDSecureSession, options: ThreeDSecureOptions | undefined, intervalRef: React.MutableRefObject<NodeJS.Timeout | null>, setIsVisible: (show: boolean) => void, interval?: number): void;
|
|
5
|
+
export declare function threeDSecureSession({ sessionId, appId, options, intervalRef, setIsVisible, }: ThreeDSecureSessionsParams): ThreeDSecureSession;
|
|
6
6
|
//# sourceMappingURL=session.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/ThreeDSecure/session.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/ThreeDSecure/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,0BAA0B,EAC1B,mBAAmB,EAEnB,mBAAmB,EACpB,MAAM,SAAS,CAAC;AAIjB,wBAAgB,WAAW,CACzB,WAAW,EAAE,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,EAC1D,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,QAQtC;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,mBAAmB,EAC5B,OAAO,EAAE,mBAAmB,GAAG,SAAS,EACxC,WAAW,EAAE,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,EAC1D,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,iBA+CtC;AAED,wBAAgB,WAAW,CACzB,OAAO,EAAE,mBAAmB,EAC5B,OAAO,EAAE,mBAAmB,GAAG,SAAS,EACxC,WAAW,EAAE,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,EAC1D,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,EACrC,QAAQ,SAAO,QAgDhB;AAED,wBAAgB,mBAAmB,CAAC,EAClC,SAAS,EACT,KAAK,EACL,OAAO,EACP,WAAW,EACX,YAAY,GACb,EAAE,0BAA0B,GAAG,mBAAmB,CA+ClD"}
|
|
@@ -1,8 +1,14 @@
|
|
|
1
|
+
import { ThreeDSecureEvent } from "./event";
|
|
1
2
|
export interface ThreeDSecureCallbacks {
|
|
2
3
|
/**
|
|
3
4
|
* The error event will be fired if the component fails to load.
|
|
4
5
|
*/
|
|
5
6
|
onError?(error: Error): void;
|
|
7
|
+
/**
|
|
8
|
+
* The 'requestChallenge' event will be fired if the 3DS authentication process requires a challenge.
|
|
9
|
+
* If you'd like to fail the authentication, you should call `preventDefault` on the passed event.
|
|
10
|
+
*/
|
|
11
|
+
onRequestChallenge?(event: ThreeDSecureEvent): void;
|
|
6
12
|
/**
|
|
7
13
|
* The 'failure' event will be fired if the 3DS authentication process fails. You should use this event to handle the failure and inform the user and prompt them to try again.
|
|
8
14
|
* If the user cancels the 3DS authentication process this event will be fired.
|
|
@@ -15,6 +21,12 @@ export interface ThreeDSecureCallbacks {
|
|
|
15
21
|
*/
|
|
16
22
|
onSuccess?(): void;
|
|
17
23
|
}
|
|
24
|
+
export interface ThreeDSecureOptions extends ThreeDSecureCallbacks {
|
|
25
|
+
/**
|
|
26
|
+
* If set to `true` (or a function that returns `true`), the authentication will fail if a challenge is required.
|
|
27
|
+
*/
|
|
28
|
+
failOnChallenge?: boolean | (() => Promise<boolean>);
|
|
29
|
+
}
|
|
18
30
|
export interface ThreeDSecureInitialState {
|
|
19
31
|
session: ThreeDSecureSession | null;
|
|
20
32
|
isVisible: boolean;
|
|
@@ -35,7 +47,7 @@ export interface ThreeDSecureSessionResponse {
|
|
|
35
47
|
}
|
|
36
48
|
export interface ThreeDSecureSessionsParams {
|
|
37
49
|
appId: string;
|
|
38
|
-
|
|
50
|
+
options?: ThreeDSecureOptions;
|
|
39
51
|
intervalRef: React.MutableRefObject<NodeJS.Timeout | null>;
|
|
40
52
|
sessionId: string;
|
|
41
53
|
setIsVisible: (show: boolean) => void;
|
|
@@ -50,8 +62,8 @@ export interface ThreeDSecureState extends ThreeDSecureInitialState {
|
|
|
50
62
|
* The `start()` function is used to kick off the 3DS authentication process.
|
|
51
63
|
*
|
|
52
64
|
* @param sessionId The 3DS session ID. A 3DS session can be created using the [Evervault API](https://docs.evervault.com/api-reference#createThreeDSSession).
|
|
53
|
-
* @param
|
|
65
|
+
* @param options The options to be used for the 3DS authentication process.
|
|
54
66
|
*/
|
|
55
|
-
start(sessionId: string,
|
|
67
|
+
start(sessionId: string, options?: ThreeDSecureOptions): void;
|
|
56
68
|
}
|
|
57
69
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/ThreeDSecure/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/ThreeDSecure/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAE5C,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAE7B;;;OAGG;IACH,kBAAkB,CAAC,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAEpD;;;OAGG;IACH,SAAS,CAAC,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAE/B;;;;OAIG;IACH,SAAS,CAAC,IAAI,IAAI,CAAC;CACpB;AAED,MAAM,WAAW,mBAAoB,SAAQ,qBAAqB;IAChE;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;CACtD;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACpC,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,GAAG,IAAI,OAAO,CAAC,2BAA2B,CAAC,CAAC;IAC5C,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,aAAa,GAAG,iBAAiB,GAAG,SAAS,GAAG,SAAS,CAAC;AAEtE,MAAM,WAAW,2BAA2B;IAC1C,UAAU,EAAE;QACV,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IACF,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,WAAW,EAAE,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,iBAAkB,SAAQ,wBAAwB;IACjE;;;OAGG;IACH,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAExB;;;;;OAKG;IACH,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAC;CAC/D"}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import { ThreeDSecureState } from "./types";
|
|
2
|
-
export
|
|
2
|
+
export interface UseThreeDSecureOptions {
|
|
3
|
+
failOnChallenge?: boolean | (() => Promise<boolean>);
|
|
4
|
+
}
|
|
5
|
+
export declare function useThreeDSecure(options?: UseThreeDSecureOptions): ThreeDSecureState;
|
|
3
6
|
//# sourceMappingURL=useThreeDSecure.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useThreeDSecure.d.ts","sourceRoot":"","sources":["../../src/ThreeDSecure/useThreeDSecure.ts"],"names":[],"mappings":"AAGA,OAAO,
|
|
1
|
+
{"version":3,"file":"useThreeDSecure.d.ts","sourceRoot":"","sources":["../../src/ThreeDSecure/useThreeDSecure.ts"],"names":[],"mappings":"AAGA,OAAO,EAGL,iBAAiB,EAClB,MAAM,SAAS,CAAC;AAGjB,MAAM,WAAW,sBAAsB;IACrC,eAAe,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;CACtD;AAED,wBAAgB,eAAe,CAC7B,OAAO,CAAC,EAAE,sBAAsB,GAC/B,iBAAiB,CA+CnB"}
|
package/build/index.cjs.js
CHANGED
|
@@ -6702,11 +6702,11 @@ var z = /*#__PURE__*/Object.freeze({
|
|
|
6702
6702
|
ZodError: ZodError
|
|
6703
6703
|
});
|
|
6704
6704
|
|
|
6705
|
-
function
|
|
6706
|
-
let
|
|
6705
|
+
function g(e) {
|
|
6706
|
+
let n = 0, t = false, s = e.length - 1, l;
|
|
6707
6707
|
for (; s >= 0; )
|
|
6708
|
-
l = parseInt(
|
|
6709
|
-
return
|
|
6708
|
+
l = parseInt(e.charAt(s), 10), t && (l *= 2, l > 9 && (l = l % 10 + 1)), t = !t, n += l, s--;
|
|
6709
|
+
return n % 10 === 0;
|
|
6710
6710
|
}
|
|
6711
6711
|
const h = [
|
|
6712
6712
|
{
|
|
@@ -6964,19 +6964,19 @@ const h = [
|
|
|
6964
6964
|
}
|
|
6965
6965
|
}
|
|
6966
6966
|
];
|
|
6967
|
-
function
|
|
6968
|
-
const s = String(
|
|
6969
|
-
return l.length < s ? false : (
|
|
6967
|
+
function m(e, n, t) {
|
|
6968
|
+
const s = String(n).length, l = e.substring(0, s), a = parseInt(l, 10);
|
|
6969
|
+
return l.length < s ? false : (n = parseInt(String(n).substring(0, l.length), 10), t = parseInt(String(t).substring(0, l.length), 10), a >= n && a <= t);
|
|
6970
6970
|
}
|
|
6971
|
-
function
|
|
6972
|
-
return
|
|
6971
|
+
function V(e, n) {
|
|
6972
|
+
return e.startsWith(String(n));
|
|
6973
6973
|
}
|
|
6974
|
-
function
|
|
6975
|
-
return
|
|
6974
|
+
function f(e) {
|
|
6975
|
+
return e.length < 16 ? e.substring(0, 6) : e.substring(0, 8);
|
|
6976
6976
|
}
|
|
6977
|
-
function
|
|
6978
|
-
const
|
|
6979
|
-
if (!/^\d*$/.test(
|
|
6977
|
+
function C(e) {
|
|
6978
|
+
const n = String(e).replace(/\s/g, "");
|
|
6979
|
+
if (!/^\d*$/.test(n))
|
|
6980
6980
|
return {
|
|
6981
6981
|
brand: null,
|
|
6982
6982
|
localBrands: [],
|
|
@@ -6984,37 +6984,37 @@ function f(n) {
|
|
|
6984
6984
|
lastFour: null,
|
|
6985
6985
|
isValid: false
|
|
6986
6986
|
};
|
|
6987
|
-
const t = h.filter((
|
|
6987
|
+
const t = h.filter((i) => i.numberValidationRules.ranges.some((r) => {
|
|
6988
6988
|
if (Array.isArray(r)) {
|
|
6989
6989
|
if (r[0] && r[1])
|
|
6990
|
-
return
|
|
6990
|
+
return m(n, r[0], r[1]);
|
|
6991
6991
|
} else
|
|
6992
|
-
return
|
|
6992
|
+
return V(n, r);
|
|
6993
6993
|
return false;
|
|
6994
|
-
})), s = t.filter((
|
|
6995
|
-
const { lengths: r, luhnCheck:
|
|
6996
|
-
return
|
|
6997
|
-
});
|
|
6994
|
+
})), s = t.filter((i) => !i.isLocal), l = t.filter((i) => i.isLocal), a = t.length > 0 && t.every((i) => {
|
|
6995
|
+
const { lengths: r, luhnCheck: o } = i.numberValidationRules, c = r.includes(n.length), d = !o || g(n);
|
|
6996
|
+
return c && d;
|
|
6997
|
+
}), u = e.length > 5;
|
|
6998
6998
|
return {
|
|
6999
6999
|
brand: s.length > 0 ? s[0].name : null,
|
|
7000
|
-
localBrands: l.map((
|
|
7001
|
-
bin:
|
|
7002
|
-
lastFour:
|
|
7003
|
-
isValid:
|
|
7000
|
+
localBrands: l.map((i) => i.name),
|
|
7001
|
+
bin: u ? f(e) : null,
|
|
7002
|
+
lastFour: a ? n.substring(n.length - 4) : null,
|
|
7003
|
+
isValid: a
|
|
7004
7004
|
};
|
|
7005
7005
|
}
|
|
7006
|
-
function
|
|
7007
|
-
if (!/^\d{3,4}$/.test(
|
|
7006
|
+
function R(e, n) {
|
|
7007
|
+
if (!/^\d{3,4}$/.test(e))
|
|
7008
7008
|
return {
|
|
7009
7009
|
cvc: null,
|
|
7010
7010
|
isValid: false
|
|
7011
7011
|
};
|
|
7012
|
-
if (!
|
|
7012
|
+
if (!n)
|
|
7013
7013
|
return {
|
|
7014
|
-
cvc:
|
|
7014
|
+
cvc: e,
|
|
7015
7015
|
isValid: true
|
|
7016
7016
|
};
|
|
7017
|
-
const t =
|
|
7017
|
+
const t = C(n);
|
|
7018
7018
|
if (!t.isValid)
|
|
7019
7019
|
return {
|
|
7020
7020
|
cvc: null,
|
|
@@ -7022,20 +7022,20 @@ function C(n, e) {
|
|
|
7022
7022
|
};
|
|
7023
7023
|
const s = [];
|
|
7024
7024
|
t.brand && s.push(t.brand), t.localBrands && s.push(...t.localBrands);
|
|
7025
|
-
const l = h.filter((
|
|
7025
|
+
const l = h.filter((a) => s.includes(a.name)).some((a) => a.securityCodeValidationRules.lengths.includes(e.length));
|
|
7026
7026
|
return {
|
|
7027
|
-
cvc: l ?
|
|
7027
|
+
cvc: l ? e : null,
|
|
7028
7028
|
isValid: l
|
|
7029
7029
|
};
|
|
7030
7030
|
}
|
|
7031
|
-
function
|
|
7032
|
-
var
|
|
7033
|
-
const
|
|
7031
|
+
function b(e) {
|
|
7032
|
+
var i;
|
|
7033
|
+
const n = /^(0[1-9]|1[[0-2]).*$/, t = e.match(n), s = t ? parseInt(t[1].toString(), 10) : null, l = /^(0[1-9]|1[[0-2])(\d{2})$/, a = e.match(l), u = a ? parseInt(a[2].toString(), 10) : null;
|
|
7034
7034
|
if (s) {
|
|
7035
|
-
const
|
|
7035
|
+
const r = (/* @__PURE__ */ new Date()).getFullYear() % 100, o = (/* @__PURE__ */ new Date()).getMonth() + 1, c = !u || u < r || u === r && s < o;
|
|
7036
7036
|
return {
|
|
7037
7037
|
month: s.toString().padStart(2, "0"),
|
|
7038
|
-
year: ((
|
|
7038
|
+
year: ((i = u == null ? void 0 : u.toString()) == null ? void 0 : i.padStart(2, "0")) ?? null,
|
|
7039
7039
|
isValid: !c
|
|
7040
7040
|
};
|
|
7041
7041
|
}
|
|
@@ -7048,13 +7048,13 @@ function R(n) {
|
|
|
7048
7048
|
|
|
7049
7049
|
async function formatPayload(values, context) {
|
|
7050
7050
|
const number = values.number?.replace(/\s/g, "") || "";
|
|
7051
|
-
const { brand, localBrands, bin, lastFour, isValid: isNumberValid, } =
|
|
7051
|
+
const { brand, localBrands, bin, lastFour, isValid: isNumberValid, } = C(number);
|
|
7052
7052
|
if (number.length > 0 &&
|
|
7053
7053
|
brand !== "american-express" &&
|
|
7054
7054
|
values.cvc?.length === 4) {
|
|
7055
7055
|
context.form.setValue("cvc", values.cvc?.slice(0, 3));
|
|
7056
7056
|
}
|
|
7057
|
-
const { cvc, isValid: isCvcValid } =
|
|
7057
|
+
const { cvc, isValid: isCvcValid } = R(values.cvc ?? "", number);
|
|
7058
7058
|
const formErrors = context.form.formState.errors;
|
|
7059
7059
|
const isValid = !Object.keys(formErrors).length;
|
|
7060
7060
|
const isComplete = areValuesComplete(values);
|
|
@@ -7091,14 +7091,14 @@ function areValuesComplete(values) {
|
|
|
7091
7091
|
if ("name" in values && !values.name?.length) {
|
|
7092
7092
|
return false;
|
|
7093
7093
|
}
|
|
7094
|
-
if ("number" in values && !
|
|
7094
|
+
if ("number" in values && !C(values.number ?? "").isValid) {
|
|
7095
7095
|
return false;
|
|
7096
7096
|
}
|
|
7097
|
-
if ("expiry" in values && !
|
|
7097
|
+
if ("expiry" in values && !b(values.expiry ?? "").isValid) {
|
|
7098
7098
|
return false;
|
|
7099
7099
|
}
|
|
7100
7100
|
if ("cvc" in values &&
|
|
7101
|
-
!
|
|
7101
|
+
!R(values.cvc ?? "", values.number).isValid) {
|
|
7102
7102
|
return false;
|
|
7103
7103
|
}
|
|
7104
7104
|
return true;
|
|
@@ -7115,7 +7115,7 @@ function isAcceptedBrand(acceptedBrands, cardNumberValidationResult) {
|
|
|
7115
7115
|
return isBrandAccepted || isLocalBrandAccepted;
|
|
7116
7116
|
}
|
|
7117
7117
|
function formatExpiry(expiry) {
|
|
7118
|
-
const parsedExpiry =
|
|
7118
|
+
const parsedExpiry = b(expiry);
|
|
7119
7119
|
if (!parsedExpiry.isValid) {
|
|
7120
7120
|
return null;
|
|
7121
7121
|
}
|
|
@@ -7131,20 +7131,20 @@ function getCardFormSchema(acceptedBrands) {
|
|
|
7131
7131
|
number: z
|
|
7132
7132
|
.string()
|
|
7133
7133
|
.min(1, "Required")
|
|
7134
|
-
.refine((value) =>
|
|
7134
|
+
.refine((value) => C(value).isValid, {
|
|
7135
7135
|
message: "Invalid card number",
|
|
7136
7136
|
})
|
|
7137
|
-
.refine((value) => isAcceptedBrand(acceptedBrands,
|
|
7137
|
+
.refine((value) => isAcceptedBrand(acceptedBrands, C(value)), { message: "Brand not accepted" }),
|
|
7138
7138
|
expiry: z
|
|
7139
7139
|
.string()
|
|
7140
7140
|
.min(1, "Required")
|
|
7141
|
-
.refine((value) =>
|
|
7141
|
+
.refine((value) => b(value).isValid, {
|
|
7142
7142
|
message: "Invalid expiry",
|
|
7143
7143
|
}),
|
|
7144
7144
|
cvc: z
|
|
7145
7145
|
.string()
|
|
7146
7146
|
.min(1, "Required")
|
|
7147
|
-
.refine((value) =>
|
|
7147
|
+
.refine((value) => R(value).isValid, {
|
|
7148
7148
|
message: "Invalid CVC",
|
|
7149
7149
|
}),
|
|
7150
7150
|
});
|
|
@@ -7530,7 +7530,7 @@ const CardCvc = React.forwardRef(function CardCvc(props, ref) {
|
|
|
7530
7530
|
if (!number) {
|
|
7531
7531
|
return DEFAULT_CARD_CVC_MASK;
|
|
7532
7532
|
}
|
|
7533
|
-
const brand =
|
|
7533
|
+
const brand = C(number).brand;
|
|
7534
7534
|
if (brand && CARD_CVC_MASKS[brand]) {
|
|
7535
7535
|
return CARD_CVC_MASKS[brand];
|
|
7536
7536
|
}
|
|
@@ -7549,7 +7549,7 @@ const CardNumber = React.forwardRef(function CardNumber(props, ref) {
|
|
|
7549
7549
|
if (!text) {
|
|
7550
7550
|
return DEFAULT_CARD_NUMBER_MASK;
|
|
7551
7551
|
}
|
|
7552
|
-
const brand =
|
|
7552
|
+
const brand = C(text).brand;
|
|
7553
7553
|
if (brand && CARD_NUMBER_MASKS[brand]) {
|
|
7554
7554
|
return CARD_NUMBER_MASKS[brand];
|
|
7555
7555
|
}
|
|
@@ -7603,6 +7603,23 @@ const defaultStyles = reactNative.StyleSheet.create({
|
|
|
7603
7603
|
},
|
|
7604
7604
|
});
|
|
7605
7605
|
|
|
7606
|
+
class ThreeDSecureEvent {
|
|
7607
|
+
type;
|
|
7608
|
+
session;
|
|
7609
|
+
_defaultPrevented;
|
|
7610
|
+
constructor(type, session, _defaultPrevented = false) {
|
|
7611
|
+
this.type = type;
|
|
7612
|
+
this.session = session;
|
|
7613
|
+
this._defaultPrevented = _defaultPrevented;
|
|
7614
|
+
}
|
|
7615
|
+
preventDefault() {
|
|
7616
|
+
this._defaultPrevented = true;
|
|
7617
|
+
}
|
|
7618
|
+
get defaultPrevented() {
|
|
7619
|
+
return this._defaultPrevented;
|
|
7620
|
+
}
|
|
7621
|
+
}
|
|
7622
|
+
|
|
7606
7623
|
function stopPolling(intervalRef, setIsVisible) {
|
|
7607
7624
|
setIsVisible(false);
|
|
7608
7625
|
if (intervalRef.current) {
|
|
@@ -7610,55 +7627,91 @@ function stopPolling(intervalRef, setIsVisible) {
|
|
|
7610
7627
|
intervalRef.current = null;
|
|
7611
7628
|
}
|
|
7612
7629
|
}
|
|
7613
|
-
async function startSession(session,
|
|
7630
|
+
async function startSession(session, options, intervalRef, setIsVisible) {
|
|
7614
7631
|
try {
|
|
7615
7632
|
const sessionState = await session.get();
|
|
7633
|
+
function fail() {
|
|
7634
|
+
stopPolling(intervalRef, setIsVisible);
|
|
7635
|
+
options?.onFailure?.(new Error("3DS session failed"));
|
|
7636
|
+
}
|
|
7616
7637
|
switch (sessionState.status) {
|
|
7617
|
-
case "success":
|
|
7638
|
+
case "success": {
|
|
7618
7639
|
stopPolling(intervalRef, setIsVisible);
|
|
7619
|
-
|
|
7640
|
+
options?.onSuccess?.();
|
|
7620
7641
|
break;
|
|
7621
|
-
|
|
7622
|
-
|
|
7623
|
-
|
|
7642
|
+
}
|
|
7643
|
+
case "failure": {
|
|
7644
|
+
fail();
|
|
7624
7645
|
break;
|
|
7625
|
-
|
|
7646
|
+
}
|
|
7647
|
+
case "action-required": {
|
|
7648
|
+
const failOnChallenge = typeof options?.failOnChallenge === "function"
|
|
7649
|
+
? await options.failOnChallenge()
|
|
7650
|
+
: options?.failOnChallenge ?? false;
|
|
7651
|
+
if (failOnChallenge) {
|
|
7652
|
+
fail();
|
|
7653
|
+
break;
|
|
7654
|
+
}
|
|
7655
|
+
const event = new ThreeDSecureEvent("requestChallenge", session);
|
|
7656
|
+
options?.onRequestChallenge?.(event);
|
|
7657
|
+
if (event.defaultPrevented) {
|
|
7658
|
+
fail();
|
|
7659
|
+
break;
|
|
7660
|
+
}
|
|
7626
7661
|
setIsVisible(true);
|
|
7627
|
-
pollSession(session,
|
|
7628
|
-
|
|
7629
|
-
default:
|
|
7630
|
-
break;
|
|
7662
|
+
pollSession(session, options, intervalRef, setIsVisible);
|
|
7663
|
+
}
|
|
7631
7664
|
}
|
|
7632
7665
|
}
|
|
7633
7666
|
catch (error) {
|
|
7634
7667
|
console.error("Error checking session state", error);
|
|
7635
|
-
|
|
7668
|
+
options?.onError?.(new Error("Failed to check 3DS session state"));
|
|
7636
7669
|
}
|
|
7637
7670
|
}
|
|
7638
|
-
function pollSession(session,
|
|
7671
|
+
function pollSession(session, options, intervalRef, setIsVisible, interval = 3000) {
|
|
7672
|
+
function fail() {
|
|
7673
|
+
stopPolling(intervalRef, setIsVisible);
|
|
7674
|
+
options?.onFailure?.(new Error("3DS session failed"));
|
|
7675
|
+
}
|
|
7639
7676
|
intervalRef.current = setInterval(async () => {
|
|
7640
7677
|
try {
|
|
7641
7678
|
const pollResponse = await session.get();
|
|
7642
|
-
|
|
7643
|
-
|
|
7644
|
-
|
|
7645
|
-
|
|
7646
|
-
|
|
7647
|
-
|
|
7648
|
-
|
|
7649
|
-
|
|
7650
|
-
|
|
7651
|
-
|
|
7679
|
+
switch (pollResponse.status) {
|
|
7680
|
+
case "success": {
|
|
7681
|
+
stopPolling(intervalRef, setIsVisible);
|
|
7682
|
+
options?.onSuccess?.();
|
|
7683
|
+
break;
|
|
7684
|
+
}
|
|
7685
|
+
case "failure": {
|
|
7686
|
+
fail();
|
|
7687
|
+
break;
|
|
7688
|
+
}
|
|
7689
|
+
case "action-required": {
|
|
7690
|
+
const failOnChallenge = typeof options?.failOnChallenge === "function"
|
|
7691
|
+
? await options.failOnChallenge()
|
|
7692
|
+
: options?.failOnChallenge ?? false;
|
|
7693
|
+
if (failOnChallenge) {
|
|
7694
|
+
fail();
|
|
7695
|
+
break;
|
|
7696
|
+
}
|
|
7697
|
+
const event = new ThreeDSecureEvent("requestChallenge", session);
|
|
7698
|
+
options?.onRequestChallenge?.(event);
|
|
7699
|
+
if (event.defaultPrevented) {
|
|
7700
|
+
fail();
|
|
7701
|
+
break;
|
|
7702
|
+
}
|
|
7703
|
+
setIsVisible(true);
|
|
7704
|
+
}
|
|
7652
7705
|
}
|
|
7653
7706
|
}
|
|
7654
7707
|
catch (error) {
|
|
7655
7708
|
stopPolling(intervalRef, setIsVisible);
|
|
7656
7709
|
console.error("Error polling session", error);
|
|
7657
|
-
|
|
7710
|
+
options?.onError?.(new Error("Error polling 3DS session"));
|
|
7658
7711
|
}
|
|
7659
7712
|
}, interval);
|
|
7660
7713
|
}
|
|
7661
|
-
function threeDSecureSession({ sessionId, appId,
|
|
7714
|
+
function threeDSecureSession({ sessionId, appId, options, intervalRef, setIsVisible, }) {
|
|
7662
7715
|
async function get() {
|
|
7663
7716
|
try {
|
|
7664
7717
|
const response = await fetch(`https://${EV_API_DOMAIN}/frontend/3ds/browser-sessions/${sessionId}`, {
|
|
@@ -7684,7 +7737,7 @@ function threeDSecureSession({ sessionId, appId, callbacks, intervalRef, setIsVi
|
|
|
7684
7737
|
},
|
|
7685
7738
|
body: JSON.stringify({ outcome: "cancelled" }),
|
|
7686
7739
|
});
|
|
7687
|
-
|
|
7740
|
+
options?.onFailure?.(new Error("3DS session cancelled by user"));
|
|
7688
7741
|
stopPolling(intervalRef, setIsVisible);
|
|
7689
7742
|
}
|
|
7690
7743
|
catch (error) {
|
|
@@ -7699,22 +7752,27 @@ function threeDSecureSession({ sessionId, appId, callbacks, intervalRef, setIsVi
|
|
|
7699
7752
|
};
|
|
7700
7753
|
}
|
|
7701
7754
|
|
|
7702
|
-
function useThreeDSecure() {
|
|
7755
|
+
function useThreeDSecure(options) {
|
|
7703
7756
|
const { appId } = useEvervault();
|
|
7704
7757
|
const intervalRef = React.useRef(null);
|
|
7705
7758
|
const [session, setSession] = React.useState(null);
|
|
7706
7759
|
const [isVisible, setIsVisible] = React.useState(false);
|
|
7707
|
-
const
|
|
7760
|
+
const failOnChallenge = options?.failOnChallenge ?? false;
|
|
7761
|
+
const start = React.useCallback((sessionId, options) => {
|
|
7762
|
+
const startOptions = {
|
|
7763
|
+
...options,
|
|
7764
|
+
failOnChallenge: options?.failOnChallenge ?? failOnChallenge,
|
|
7765
|
+
};
|
|
7708
7766
|
const session = threeDSecureSession({
|
|
7709
7767
|
sessionId,
|
|
7710
7768
|
appId,
|
|
7711
|
-
|
|
7769
|
+
options: startOptions,
|
|
7712
7770
|
intervalRef,
|
|
7713
7771
|
setIsVisible,
|
|
7714
7772
|
});
|
|
7715
7773
|
setSession(session);
|
|
7716
|
-
startSession(session,
|
|
7717
|
-
}, [appId]);
|
|
7774
|
+
startSession(session, startOptions, intervalRef, setIsVisible);
|
|
7775
|
+
}, [appId, failOnChallenge]);
|
|
7718
7776
|
const cancel = React.useCallback(async () => {
|
|
7719
7777
|
if (session) {
|
|
7720
7778
|
await session.cancel();
|