@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.
@@ -6682,11 +6682,11 @@ var z = /*#__PURE__*/Object.freeze({
6682
6682
  ZodError: ZodError
6683
6683
  });
6684
6684
 
6685
- function d(n) {
6686
- let e = 0, t = false, s = n.length - 1, l;
6685
+ function g(e) {
6686
+ let n = 0, t = false, s = e.length - 1, l;
6687
6687
  for (; s >= 0; )
6688
- l = parseInt(n.charAt(s), 10), t && (l *= 2, l > 9 && (l = l % 10 + 1)), t = !t, e += l, s--;
6689
- return e % 10 === 0;
6688
+ l = parseInt(e.charAt(s), 10), t && (l *= 2, l > 9 && (l = l % 10 + 1)), t = !t, n += l, s--;
6689
+ return n % 10 === 0;
6690
6690
  }
6691
6691
  const h = [
6692
6692
  {
@@ -6944,19 +6944,19 @@ const h = [
6944
6944
  }
6945
6945
  }
6946
6946
  ];
6947
- function g(n, e, t) {
6948
- const s = String(e).length, l = n.substring(0, s), i = parseInt(l, 10);
6949
- return l.length < s ? false : (e = parseInt(String(e).substring(0, l.length), 10), t = parseInt(String(t).substring(0, l.length), 10), i >= e && i <= t);
6947
+ function m(e, n, t) {
6948
+ const s = String(n).length, l = e.substring(0, s), a = parseInt(l, 10);
6949
+ 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);
6950
6950
  }
6951
- function m(n, e) {
6952
- return n.startsWith(String(e));
6951
+ function V(e, n) {
6952
+ return e.startsWith(String(n));
6953
6953
  }
6954
- function V(n) {
6955
- return n.length < 16 ? n.substring(0, 6) : n.substring(0, 8);
6954
+ function f(e) {
6955
+ return e.length < 16 ? e.substring(0, 6) : e.substring(0, 8);
6956
6956
  }
6957
- function f(n) {
6958
- const e = String(n).replace(/\s/g, "");
6959
- if (!/^\d*$/.test(e))
6957
+ function C(e) {
6958
+ const n = String(e).replace(/\s/g, "");
6959
+ if (!/^\d*$/.test(n))
6960
6960
  return {
6961
6961
  brand: null,
6962
6962
  localBrands: [],
@@ -6964,37 +6964,37 @@ function f(n) {
6964
6964
  lastFour: null,
6965
6965
  isValid: false
6966
6966
  };
6967
- const t = h.filter((a) => a.numberValidationRules.ranges.some((r) => {
6967
+ const t = h.filter((i) => i.numberValidationRules.ranges.some((r) => {
6968
6968
  if (Array.isArray(r)) {
6969
6969
  if (r[0] && r[1])
6970
- return g(e, r[0], r[1]);
6970
+ return m(n, r[0], r[1]);
6971
6971
  } else
6972
- return m(e, r);
6972
+ return V(n, r);
6973
6973
  return false;
6974
- })), s = t.filter((a) => !a.isLocal), l = t.filter((a) => a.isLocal), i = t.length > 0 && t.every((a) => {
6975
- const { lengths: r, luhnCheck: u } = a.numberValidationRules, o = r.includes(e.length), c = !u || d(e);
6976
- return o && c;
6977
- });
6974
+ })), s = t.filter((i) => !i.isLocal), l = t.filter((i) => i.isLocal), a = t.length > 0 && t.every((i) => {
6975
+ const { lengths: r, luhnCheck: o } = i.numberValidationRules, c = r.includes(n.length), d = !o || g(n);
6976
+ return c && d;
6977
+ }), u = e.length > 5;
6978
6978
  return {
6979
6979
  brand: s.length > 0 ? s[0].name : null,
6980
- localBrands: l.map((a) => a.name),
6981
- bin: i ? V(n) : null,
6982
- lastFour: i ? e.substring(e.length - 4) : null,
6983
- isValid: i
6980
+ localBrands: l.map((i) => i.name),
6981
+ bin: u ? f(e) : null,
6982
+ lastFour: a ? n.substring(n.length - 4) : null,
6983
+ isValid: a
6984
6984
  };
6985
6985
  }
6986
- function C(n, e) {
6987
- if (!/^\d{3,4}$/.test(n))
6986
+ function R(e, n) {
6987
+ if (!/^\d{3,4}$/.test(e))
6988
6988
  return {
6989
6989
  cvc: null,
6990
6990
  isValid: false
6991
6991
  };
6992
- if (!e)
6992
+ if (!n)
6993
6993
  return {
6994
- cvc: n,
6994
+ cvc: e,
6995
6995
  isValid: true
6996
6996
  };
6997
- const t = f(e);
6997
+ const t = C(n);
6998
6998
  if (!t.isValid)
6999
6999
  return {
7000
7000
  cvc: null,
@@ -7002,20 +7002,20 @@ function C(n, e) {
7002
7002
  };
7003
7003
  const s = [];
7004
7004
  t.brand && s.push(t.brand), t.localBrands && s.push(...t.localBrands);
7005
- const l = h.filter((i) => s.includes(i.name)).some((i) => i.securityCodeValidationRules.lengths.includes(n.length));
7005
+ const l = h.filter((a) => s.includes(a.name)).some((a) => a.securityCodeValidationRules.lengths.includes(e.length));
7006
7006
  return {
7007
- cvc: l ? n : null,
7007
+ cvc: l ? e : null,
7008
7008
  isValid: l
7009
7009
  };
7010
7010
  }
7011
- function R(n) {
7012
- var r;
7013
- const e = /^(0[1-9]|1[[0-2]).*$/, t = n.match(e), s = t ? parseInt(t[1].toString(), 10) : null, l = /^(0[1-9]|1[[0-2])(\d{2})$/, i = n.match(l), a = i ? parseInt(i[2].toString(), 10) : null;
7011
+ function b(e) {
7012
+ var i;
7013
+ 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;
7014
7014
  if (s) {
7015
- const u = (/* @__PURE__ */ new Date()).getFullYear() % 100, o = (/* @__PURE__ */ new Date()).getMonth() + 1, c = !a || a < u || a === u && s < o;
7015
+ const r = (/* @__PURE__ */ new Date()).getFullYear() % 100, o = (/* @__PURE__ */ new Date()).getMonth() + 1, c = !u || u < r || u === r && s < o;
7016
7016
  return {
7017
7017
  month: s.toString().padStart(2, "0"),
7018
- year: ((r = a == null ? void 0 : a.toString()) == null ? void 0 : r.padStart(2, "0")) ?? null,
7018
+ year: ((i = u == null ? void 0 : u.toString()) == null ? void 0 : i.padStart(2, "0")) ?? null,
7019
7019
  isValid: !c
7020
7020
  };
7021
7021
  }
@@ -7028,13 +7028,13 @@ function R(n) {
7028
7028
 
7029
7029
  async function formatPayload(values, context) {
7030
7030
  const number = values.number?.replace(/\s/g, "") || "";
7031
- const { brand, localBrands, bin, lastFour, isValid: isNumberValid, } = f(number);
7031
+ const { brand, localBrands, bin, lastFour, isValid: isNumberValid, } = C(number);
7032
7032
  if (number.length > 0 &&
7033
7033
  brand !== "american-express" &&
7034
7034
  values.cvc?.length === 4) {
7035
7035
  context.form.setValue("cvc", values.cvc?.slice(0, 3));
7036
7036
  }
7037
- const { cvc, isValid: isCvcValid } = C(values.cvc ?? "", number);
7037
+ const { cvc, isValid: isCvcValid } = R(values.cvc ?? "", number);
7038
7038
  const formErrors = context.form.formState.errors;
7039
7039
  const isValid = !Object.keys(formErrors).length;
7040
7040
  const isComplete = areValuesComplete(values);
@@ -7071,14 +7071,14 @@ function areValuesComplete(values) {
7071
7071
  if ("name" in values && !values.name?.length) {
7072
7072
  return false;
7073
7073
  }
7074
- if ("number" in values && !f(values.number ?? "").isValid) {
7074
+ if ("number" in values && !C(values.number ?? "").isValid) {
7075
7075
  return false;
7076
7076
  }
7077
- if ("expiry" in values && !R(values.expiry ?? "").isValid) {
7077
+ if ("expiry" in values && !b(values.expiry ?? "").isValid) {
7078
7078
  return false;
7079
7079
  }
7080
7080
  if ("cvc" in values &&
7081
- !C(values.cvc ?? "", values.number).isValid) {
7081
+ !R(values.cvc ?? "", values.number).isValid) {
7082
7082
  return false;
7083
7083
  }
7084
7084
  return true;
@@ -7095,7 +7095,7 @@ function isAcceptedBrand(acceptedBrands, cardNumberValidationResult) {
7095
7095
  return isBrandAccepted || isLocalBrandAccepted;
7096
7096
  }
7097
7097
  function formatExpiry(expiry) {
7098
- const parsedExpiry = R(expiry);
7098
+ const parsedExpiry = b(expiry);
7099
7099
  if (!parsedExpiry.isValid) {
7100
7100
  return null;
7101
7101
  }
@@ -7111,20 +7111,20 @@ function getCardFormSchema(acceptedBrands) {
7111
7111
  number: z
7112
7112
  .string()
7113
7113
  .min(1, "Required")
7114
- .refine((value) => f(value).isValid, {
7114
+ .refine((value) => C(value).isValid, {
7115
7115
  message: "Invalid card number",
7116
7116
  })
7117
- .refine((value) => isAcceptedBrand(acceptedBrands, f(value)), { message: "Brand not accepted" }),
7117
+ .refine((value) => isAcceptedBrand(acceptedBrands, C(value)), { message: "Brand not accepted" }),
7118
7118
  expiry: z
7119
7119
  .string()
7120
7120
  .min(1, "Required")
7121
- .refine((value) => R(value).isValid, {
7121
+ .refine((value) => b(value).isValid, {
7122
7122
  message: "Invalid expiry",
7123
7123
  }),
7124
7124
  cvc: z
7125
7125
  .string()
7126
7126
  .min(1, "Required")
7127
- .refine((value) => C(value).isValid, {
7127
+ .refine((value) => R(value).isValid, {
7128
7128
  message: "Invalid CVC",
7129
7129
  }),
7130
7130
  });
@@ -7510,7 +7510,7 @@ const CardCvc = forwardRef(function CardCvc(props, ref) {
7510
7510
  if (!number) {
7511
7511
  return DEFAULT_CARD_CVC_MASK;
7512
7512
  }
7513
- const brand = f(number).brand;
7513
+ const brand = C(number).brand;
7514
7514
  if (brand && CARD_CVC_MASKS[brand]) {
7515
7515
  return CARD_CVC_MASKS[brand];
7516
7516
  }
@@ -7529,7 +7529,7 @@ const CardNumber = forwardRef(function CardNumber(props, ref) {
7529
7529
  if (!text) {
7530
7530
  return DEFAULT_CARD_NUMBER_MASK;
7531
7531
  }
7532
- const brand = f(text).brand;
7532
+ const brand = C(text).brand;
7533
7533
  if (brand && CARD_NUMBER_MASKS[brand]) {
7534
7534
  return CARD_NUMBER_MASKS[brand];
7535
7535
  }
@@ -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, callbacks, intervalRef, setIsVisible) {
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
- callbacks?.onSuccess?.();
7620
+ options?.onSuccess?.();
7600
7621
  break;
7601
- case "failure":
7602
- stopPolling(intervalRef, setIsVisible);
7603
- callbacks?.onFailure?.(new Error("3DS session failed"));
7622
+ }
7623
+ case "failure": {
7624
+ fail();
7604
7625
  break;
7605
- case "action-required":
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, callbacks, intervalRef, setIsVisible);
7608
- break;
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
- callbacks?.onError?.(new Error("Failed to check 3DS session state"));
7648
+ options?.onError?.(new Error("Failed to check 3DS session state"));
7616
7649
  }
7617
7650
  }
7618
- function pollSession(session, callbacks, intervalRef, setIsVisible, interval = 3000) {
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
- if (pollResponse.status === "success") {
7623
- stopPolling(intervalRef, setIsVisible);
7624
- callbacks?.onSuccess?.();
7625
- }
7626
- else if (pollResponse.status === "failure") {
7627
- stopPolling(intervalRef, setIsVisible);
7628
- callbacks?.onFailure?.(new Error("3DS session failed"));
7629
- }
7630
- else {
7631
- setIsVisible(true);
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
- callbacks?.onError?.(new Error("Error polling 3DS session"));
7690
+ options?.onError?.(new Error("Error polling 3DS session"));
7638
7691
  }
7639
7692
  }, interval);
7640
7693
  }
7641
- function threeDSecureSession({ sessionId, appId, callbacks, intervalRef, setIsVisible, }) {
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
- callbacks?.onFailure?.(new Error("3DS session cancelled by user"));
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 start = useCallback((sessionId, callbacks) => {
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
- callbacks,
7749
+ options: startOptions,
7692
7750
  intervalRef,
7693
7751
  setIsVisible,
7694
7752
  });
7695
7753
  setSession(session);
7696
- startSession(session, callbacks, intervalRef, setIsVisible);
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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@evervault/react-native",
3
3
  "description": "Evervault SDK for React Native",
4
- "version": "2.4.0",
4
+ "version": "2.5.1",
5
5
  "source": "./src/index.ts",
6
6
  "main": "./build/index.cjs.js",
7
7
  "module": "./build/index.esm.js",
@@ -73,7 +73,7 @@
73
73
  "react-hook-form": "^7.54.2",
74
74
  "react-native-mask-input": "^1.2.3",
75
75
  "zod": "^3.24.2",
76
- "@evervault/card-validator": "1.4.0"
76
+ "@evervault/card-validator": "1.5.0"
77
77
  },
78
78
  "scripts": {
79
79
  "prebuild": "pnpm codegen",
@@ -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
+ }