@evervault/react-native 2.5.1 → 2.6.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/README.md +0 -2
- package/build/cjs/Card/Cvc.js +29 -0
- package/build/cjs/Card/Expiry.js +12 -0
- package/build/cjs/Card/Holder.js +15 -0
- package/build/cjs/Card/Number.js +27 -0
- package/build/cjs/Card/Root.js +70 -0
- package/build/cjs/Card/index.js +20 -0
- package/build/cjs/Card/schema.js +32 -0
- package/build/cjs/Card/types.js +21 -0
- package/build/cjs/Card/utils.js +87 -0
- package/build/cjs/EvervaultProvider.js +17 -0
- package/build/cjs/Input.js +107 -0
- package/build/cjs/ThreeDSecure/Frame.js +37 -0
- package/build/cjs/ThreeDSecure/Root.js +14 -0
- package/build/cjs/ThreeDSecure/config.js +7 -0
- package/build/cjs/ThreeDSecure/context.js +7 -0
- package/build/cjs/ThreeDSecure/event.js +20 -0
- package/build/cjs/ThreeDSecure/index.js +12 -0
- package/build/cjs/ThreeDSecure/session.js +141 -0
- package/build/cjs/ThreeDSecure/types.js +2 -0
- package/build/cjs/ThreeDSecure/useThreeDSecure.js +44 -0
- package/build/cjs/__mocks__/NativeEvervault.js +14 -0
- package/build/cjs/__mocks__/react-native-webview.js +10 -0
- package/build/cjs/context.js +7 -0
- package/build/cjs/index.js +25 -0
- package/build/cjs/node_modules/@hookform/resolvers/dist/resolvers.js +8 -0
- package/build/cjs/node_modules/@hookform/resolvers/zod/dist/zod.js +8 -0
- package/build/cjs/node_modules/react-hook-form/dist/index.esm.js +2221 -0
- package/build/cjs/node_modules/react-native-mask-input/lib/module/MaskInput.js +60 -0
- package/build/cjs/node_modules/react-native-mask-input/lib/module/formatWithMask.js +92 -0
- package/build/cjs/node_modules/react-native-mask-input/lib/module/index.js +10 -0
- package/build/cjs/node_modules/react-native-mask-input/lib/module/useMaskedInputProps.js +93 -0
- package/build/{index.cjs.js → cjs/node_modules/zod/lib/index.js} +193 -3490
- package/build/cjs/packages/card-validator/dist/evervault-card-validator.main.js +349 -0
- package/build/cjs/sdk.js +53 -0
- package/build/cjs/specs/NativeEvervault.js +7 -0
- package/build/cjs/useEvervault.js +14 -0
- package/build/cjs/utils.js +34 -0
- package/build/{Card → esm/Card}/Cvc.d.ts +0 -1
- package/build/esm/Card/Cvc.js +27 -0
- package/build/{Card → esm/Card}/Expiry.d.ts +0 -1
- package/build/esm/Card/Expiry.js +10 -0
- package/build/{Card → esm/Card}/Holder.d.ts +0 -1
- package/build/esm/Card/Holder.js +13 -0
- package/build/{Card → esm/Card}/Number.d.ts +0 -1
- package/build/esm/Card/Number.js +25 -0
- package/build/{Card → esm/Card}/Root.d.ts +0 -1
- package/build/esm/Card/Root.js +68 -0
- package/build/{Card → esm/Card}/index.d.ts +0 -1
- package/build/esm/Card/index.js +14 -0
- package/build/{Card → esm/Card}/schema.d.ts +0 -1
- package/build/esm/Card/schema.js +30 -0
- package/build/{Card → esm/Card}/types.d.ts +0 -1
- package/build/esm/Card/types.js +19 -0
- package/build/{Card → esm/Card}/utils.d.ts +0 -1
- package/build/esm/Card/utils.js +82 -0
- package/build/{EvervaultProvider.d.ts → esm/EvervaultProvider.d.ts} +0 -1
- package/build/esm/EvervaultProvider.js +15 -0
- package/build/{Input.d.ts → esm/Input.d.ts} +0 -1
- package/build/esm/Input.js +103 -0
- package/build/{ThreeDSecure → esm/ThreeDSecure}/Frame.d.ts +0 -1
- package/build/esm/ThreeDSecure/Frame.js +35 -0
- package/build/{ThreeDSecure → esm/ThreeDSecure}/Root.d.ts +0 -1
- package/build/esm/ThreeDSecure/Root.js +12 -0
- package/build/{ThreeDSecure → esm/ThreeDSecure}/config.d.ts +0 -1
- package/build/esm/ThreeDSecure/config.js +4 -0
- package/build/{ThreeDSecure → esm/ThreeDSecure}/context.d.ts +0 -1
- package/build/esm/ThreeDSecure/context.js +5 -0
- package/build/{ThreeDSecure → esm/ThreeDSecure}/event.d.ts +0 -1
- package/build/esm/ThreeDSecure/event.js +18 -0
- package/build/{ThreeDSecure → esm/ThreeDSecure}/index.d.ts +0 -1
- package/build/esm/ThreeDSecure/index.js +9 -0
- package/build/{ThreeDSecure → esm/ThreeDSecure}/session.d.ts +0 -1
- package/build/esm/ThreeDSecure/session.js +136 -0
- package/build/{ThreeDSecure → esm/ThreeDSecure}/types.d.ts +0 -1
- package/build/esm/ThreeDSecure/types.js +1 -0
- package/build/{ThreeDSecure → esm/ThreeDSecure}/useThreeDSecure.d.ts +0 -1
- package/build/esm/ThreeDSecure/useThreeDSecure.js +42 -0
- package/build/{__mocks__ → esm/__mocks__}/NativeEvervault.d.ts +0 -1
- package/build/esm/__mocks__/NativeEvervault.js +11 -0
- package/build/{__mocks__ → esm/__mocks__}/react-native-webview.d.ts +0 -1
- package/build/esm/__mocks__/react-native-webview.js +8 -0
- package/build/{context.d.ts → esm/context.d.ts} +0 -1
- package/build/esm/context.js +5 -0
- package/build/{index.d.ts → esm/index.d.ts} +0 -1
- package/build/esm/index.js +14 -0
- package/build/esm/node_modules/@hookform/resolvers/dist/resolvers.js +5 -0
- package/build/esm/node_modules/@hookform/resolvers/zod/dist/zod.js +6 -0
- package/build/esm/node_modules/react-hook-form/dist/index.esm.js +2211 -0
- package/build/esm/node_modules/react-native-mask-input/lib/module/MaskInput.js +37 -0
- package/build/esm/node_modules/react-native-mask-input/lib/module/formatWithMask.js +88 -0
- package/build/esm/node_modules/react-native-mask-input/lib/module/index.js +6 -0
- package/build/esm/node_modules/react-native-mask-input/lib/module/useMaskedInputProps.js +70 -0
- package/build/{index.esm.js → esm/node_modules/zod/lib/index.js} +1 -3377
- package/build/esm/packages/card-validator/dist/evervault-card-validator.main.js +345 -0
- package/build/{sdk.d.ts → esm/sdk.d.ts} +0 -1
- package/build/esm/sdk.js +51 -0
- package/build/{specs → esm/specs}/NativeEvervault.d.ts +0 -1
- package/build/esm/specs/NativeEvervault.js +5 -0
- package/build/{useEvervault.d.ts → esm/useEvervault.d.ts} +0 -1
- package/build/esm/useEvervault.js +12 -0
- package/build/{utils.d.ts → esm/utils.d.ts} +0 -1
- package/build/esm/utils.js +31 -0
- package/package.json +9 -21
- package/build/Card/Cvc.d.ts.map +0 -1
- package/build/Card/Cvc.test.d.ts +0 -2
- package/build/Card/Cvc.test.d.ts.map +0 -1
- package/build/Card/Expiry.d.ts.map +0 -1
- package/build/Card/Holder.d.ts.map +0 -1
- package/build/Card/Number.d.ts.map +0 -1
- package/build/Card/Number.test.d.ts +0 -2
- package/build/Card/Number.test.d.ts.map +0 -1
- package/build/Card/Root.d.ts.map +0 -1
- package/build/Card/Root.test.d.ts +0 -2
- package/build/Card/Root.test.d.ts.map +0 -1
- package/build/Card/index.d.ts.map +0 -1
- package/build/Card/schema.d.ts.map +0 -1
- package/build/Card/types.d.ts.map +0 -1
- package/build/Card/utils.d.ts.map +0 -1
- package/build/Card/utils.test.d.ts +0 -2
- package/build/Card/utils.test.d.ts.map +0 -1
- package/build/EvervaultProvider.d.ts.map +0 -1
- package/build/EvervaultProvider.test.d.ts +0 -2
- package/build/EvervaultProvider.test.d.ts.map +0 -1
- package/build/Input.d.ts.map +0 -1
- package/build/Input.test.d.ts +0 -2
- package/build/Input.test.d.ts.map +0 -1
- package/build/ThreeDSecure/Frame.d.ts.map +0 -1
- package/build/ThreeDSecure/Frame.test.d.ts +0 -2
- package/build/ThreeDSecure/Frame.test.d.ts.map +0 -1
- package/build/ThreeDSecure/Root.d.ts.map +0 -1
- package/build/ThreeDSecure/Root.test.d.ts +0 -2
- package/build/ThreeDSecure/Root.test.d.ts.map +0 -1
- package/build/ThreeDSecure/config.d.ts.map +0 -1
- package/build/ThreeDSecure/context.d.ts.map +0 -1
- package/build/ThreeDSecure/event.d.ts.map +0 -1
- package/build/ThreeDSecure/index.d.ts.map +0 -1
- package/build/ThreeDSecure/session.d.ts.map +0 -1
- package/build/ThreeDSecure/session.test.d.ts +0 -2
- package/build/ThreeDSecure/session.test.d.ts.map +0 -1
- package/build/ThreeDSecure/types.d.ts.map +0 -1
- package/build/ThreeDSecure/useThreeDSecure.d.ts.map +0 -1
- package/build/ThreeDSecure/useThreeDSecure.test.d.ts +0 -2
- package/build/ThreeDSecure/useThreeDSecure.test.d.ts.map +0 -1
- package/build/__mocks__/NativeEvervault.d.ts.map +0 -1
- package/build/__mocks__/react-native-webview.d.ts.map +0 -1
- package/build/context.d.ts.map +0 -1
- package/build/index.cjs.js.map +0 -1
- package/build/index.d.ts.map +0 -1
- package/build/sdk.d.ts.map +0 -1
- package/build/sdk.test.d.ts +0 -2
- package/build/sdk.test.d.ts.map +0 -1
- package/build/specs/NativeEvervault.d.ts.map +0 -1
- package/build/useEvervault.d.ts.map +0 -1
- package/build/useEvervault.test.d.ts +0 -2
- package/build/useEvervault.test.d.ts.map +0 -1
- package/build/utils.d.ts.map +0 -1
- package/src/Card/Cvc.test.tsx +0 -41
- package/src/Card/Cvc.tsx +0 -58
- package/src/Card/Expiry.tsx +0 -26
- package/src/Card/Holder.tsx +0 -27
- package/src/Card/Number.test.tsx +0 -76
- package/src/Card/Number.tsx +0 -54
- package/src/Card/Root.test.tsx +0 -341
- package/src/Card/Root.tsx +0 -150
- package/src/Card/index.ts +0 -28
- package/src/Card/schema.ts +0 -41
- package/src/Card/types.ts +0 -57
- package/src/Card/utils.test.ts +0 -271
- package/src/Card/utils.ts +0 -129
- package/src/EvervaultProvider.test.tsx +0 -24
- package/src/EvervaultProvider.tsx +0 -43
- package/src/Input.test.tsx +0 -420
- package/src/Input.tsx +0 -182
- package/src/ThreeDSecure/Frame.test.tsx +0 -87
- package/src/ThreeDSecure/Frame.tsx +0 -50
- package/src/ThreeDSecure/Root.test.tsx +0 -67
- package/src/ThreeDSecure/Root.tsx +0 -23
- package/src/ThreeDSecure/config.ts +0 -3
- package/src/ThreeDSecure/context.ts +0 -6
- package/src/ThreeDSecure/event.ts +0 -19
- package/src/ThreeDSecure/index.ts +0 -17
- package/src/ThreeDSecure/session.test.ts +0 -524
- package/src/ThreeDSecure/session.ts +0 -184
- package/src/ThreeDSecure/types.ts +0 -80
- package/src/ThreeDSecure/useThreeDSecure.test.tsx +0 -244
- package/src/ThreeDSecure/useThreeDSecure.ts +0 -64
- package/src/__mocks__/NativeEvervault.ts +0 -13
- package/src/__mocks__/react-native-webview.tsx +0 -6
- package/src/context.ts +0 -14
- package/src/index.ts +0 -21
- package/src/sdk.test.ts +0 -122
- package/src/sdk.ts +0 -71
- package/src/specs/NativeEvervault.ts +0 -67
- package/src/useEvervault.test.tsx +0 -31
- package/src/useEvervault.ts +0 -14
- package/src/utils.ts +0 -41
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import z from '../node_modules/zod/lib';
|
|
2
|
+
import { validateCVC as R, validateExpiry as b, validateNumber as C } from '../packages/card-validator/dist/evervault-card-validator.main.js';
|
|
3
|
+
import { isAcceptedBrand } from './utils.js';
|
|
4
|
+
|
|
5
|
+
function getCardFormSchema(acceptedBrands) {
|
|
6
|
+
return z.object({
|
|
7
|
+
name: z.string().min(1, "Missing name"),
|
|
8
|
+
number: z
|
|
9
|
+
.string()
|
|
10
|
+
.min(1, "Required")
|
|
11
|
+
.refine((value) => C(value).isValid, {
|
|
12
|
+
message: "Invalid card number",
|
|
13
|
+
})
|
|
14
|
+
.refine((value) => isAcceptedBrand(acceptedBrands, C(value)), { message: "Brand not accepted" }),
|
|
15
|
+
expiry: z
|
|
16
|
+
.string()
|
|
17
|
+
.min(1, "Required")
|
|
18
|
+
.refine((value) => b(value).isValid, {
|
|
19
|
+
message: "Invalid expiry",
|
|
20
|
+
}),
|
|
21
|
+
cvc: z
|
|
22
|
+
.string()
|
|
23
|
+
.min(1, "Required")
|
|
24
|
+
.refine((value) => R(value).isValid, {
|
|
25
|
+
message: "Invalid CVC",
|
|
26
|
+
}),
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { getCardFormSchema };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const CARD_BRAND_NAMES = [
|
|
2
|
+
"american-express",
|
|
3
|
+
"visa",
|
|
4
|
+
"mastercard",
|
|
5
|
+
"discover",
|
|
6
|
+
"jcb",
|
|
7
|
+
"diners-club",
|
|
8
|
+
"unionpay",
|
|
9
|
+
"maestro",
|
|
10
|
+
"mir",
|
|
11
|
+
"elo",
|
|
12
|
+
"hipercard",
|
|
13
|
+
"hiper",
|
|
14
|
+
"szep",
|
|
15
|
+
"uatp",
|
|
16
|
+
"rupay",
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
export { CARD_BRAND_NAMES };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { validateNumber as C, validateCVC as R, validateExpiry as b } from '../packages/card-validator/dist/evervault-card-validator.main.js';
|
|
2
|
+
|
|
3
|
+
async function formatPayload(values, context) {
|
|
4
|
+
const number = values.number?.replace(/\s/g, "") || "";
|
|
5
|
+
const { brand, localBrands, bin, lastFour, isValid: isNumberValid, } = C(number);
|
|
6
|
+
if (number.length > 0 &&
|
|
7
|
+
brand !== "american-express" &&
|
|
8
|
+
values.cvc?.length === 4) {
|
|
9
|
+
context.form.setValue("cvc", values.cvc?.slice(0, 3));
|
|
10
|
+
}
|
|
11
|
+
const { cvc, isValid: isCvcValid } = R(values.cvc ?? "", number);
|
|
12
|
+
const formErrors = context.form.formState.errors;
|
|
13
|
+
const isValid = !Object.keys(formErrors).length;
|
|
14
|
+
const isComplete = areValuesComplete(values);
|
|
15
|
+
const errors = {};
|
|
16
|
+
if (formErrors.name?.message) {
|
|
17
|
+
errors.name = formErrors.name.message;
|
|
18
|
+
}
|
|
19
|
+
if (formErrors.number?.message) {
|
|
20
|
+
errors.number = formErrors.number.message;
|
|
21
|
+
}
|
|
22
|
+
if (formErrors.expiry?.message) {
|
|
23
|
+
errors.expiry = formErrors.expiry.message;
|
|
24
|
+
}
|
|
25
|
+
if (formErrors.cvc?.message) {
|
|
26
|
+
errors.cvc = formErrors.cvc.message;
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
card: {
|
|
30
|
+
name: values.name ?? null,
|
|
31
|
+
brand,
|
|
32
|
+
localBrands,
|
|
33
|
+
bin,
|
|
34
|
+
lastFour,
|
|
35
|
+
expiry: formatExpiry(values.expiry ?? ""),
|
|
36
|
+
number: isNumberValid ? await context.encrypt(number) : null,
|
|
37
|
+
cvc: isCvcValid ? await context.encrypt(cvc ?? "") : null,
|
|
38
|
+
},
|
|
39
|
+
isComplete,
|
|
40
|
+
isValid: isValid && isComplete,
|
|
41
|
+
errors,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function areValuesComplete(values) {
|
|
45
|
+
if ("name" in values && !values.name?.length) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
if ("number" in values && !C(values.number ?? "").isValid) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
if ("expiry" in values && !b(values.expiry ?? "").isValid) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
if ("cvc" in values &&
|
|
55
|
+
!R(values.cvc ?? "", values.number).isValid) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
function isAcceptedBrand(acceptedBrands, cardNumberValidationResult) {
|
|
61
|
+
if (!acceptedBrands?.length)
|
|
62
|
+
return true;
|
|
63
|
+
if (!cardNumberValidationResult.isValid)
|
|
64
|
+
return false;
|
|
65
|
+
const { brand, localBrands } = cardNumberValidationResult;
|
|
66
|
+
const acceptedBrandsSet = new Set(acceptedBrands);
|
|
67
|
+
const isBrandAccepted = brand !== null && acceptedBrandsSet.has(brand);
|
|
68
|
+
const isLocalBrandAccepted = localBrands.some((localBrand) => acceptedBrandsSet.has(localBrand));
|
|
69
|
+
return isBrandAccepted || isLocalBrandAccepted;
|
|
70
|
+
}
|
|
71
|
+
function formatExpiry(expiry) {
|
|
72
|
+
const parsedExpiry = b(expiry);
|
|
73
|
+
if (!parsedExpiry.isValid) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
month: parsedExpiry.month,
|
|
78
|
+
year: parsedExpiry.year,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export { areValuesComplete, formatExpiry, formatPayload, isAcceptedBrand };
|
|
@@ -4,4 +4,3 @@ export interface EvervaultProviderProps extends PropsWithChildren {
|
|
|
4
4
|
appId: string;
|
|
5
5
|
}
|
|
6
6
|
export declare function EvervaultProvider({ teamId, appId, children, }: EvervaultProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
-
//# sourceMappingURL=EvervaultProvider.d.ts.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useMemo, useCallback } from 'react';
|
|
3
|
+
import { EvervaultContext } from './context.js';
|
|
4
|
+
import { sdk } from './sdk.js';
|
|
5
|
+
|
|
6
|
+
function EvervaultProvider({ teamId, appId, children, }) {
|
|
7
|
+
const instanceId = useMemo(() => sdk.initialize(teamId, appId), [teamId, appId]);
|
|
8
|
+
const encrypt = useCallback(function (data) {
|
|
9
|
+
return sdk.encrypt(instanceId, data);
|
|
10
|
+
}, [instanceId]);
|
|
11
|
+
const context = useMemo(() => ({ teamId, appId, encrypt }), [teamId, appId, encrypt]);
|
|
12
|
+
return (jsx(EvervaultContext.Provider, { value: context, children: children }));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { EvervaultProvider };
|
|
@@ -16,4 +16,3 @@ export interface EvervaultInputProps<Values extends Record<string, unknown>> ext
|
|
|
16
16
|
export declare const EvervaultInput: <Values extends Record<string, unknown>>(props: EvervaultInputProps<Values> & {
|
|
17
17
|
ref?: Ref<EvervaultInput>;
|
|
18
18
|
}) => ReactNode;
|
|
19
|
-
//# sourceMappingURL=Input.d.ts.map
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { createContext, forwardRef, useContext, useMemo, useRef, useImperativeHandle, useCallback } from 'react';
|
|
3
|
+
import { mergeRefs } from './utils.js';
|
|
4
|
+
import { useFormContext, useController } from './node_modules/react-hook-form/dist/index.esm.js';
|
|
5
|
+
import MaskInput from './node_modules/react-native-mask-input/lib/module/MaskInput.js';
|
|
6
|
+
|
|
7
|
+
const EvervaultInputContext = createContext({
|
|
8
|
+
validationMode: "all",
|
|
9
|
+
});
|
|
10
|
+
function useForwardedInputRef(ref) {
|
|
11
|
+
const inputRef = useRef(null);
|
|
12
|
+
useImperativeHandle(ref, useCallback(() => ({
|
|
13
|
+
isFocused() {
|
|
14
|
+
return inputRef.current?.isFocused() ?? false;
|
|
15
|
+
},
|
|
16
|
+
focus() {
|
|
17
|
+
inputRef.current?.focus();
|
|
18
|
+
},
|
|
19
|
+
blur() {
|
|
20
|
+
inputRef.current?.blur();
|
|
21
|
+
},
|
|
22
|
+
clear() {
|
|
23
|
+
inputRef.current?.clear();
|
|
24
|
+
},
|
|
25
|
+
measure(callback) {
|
|
26
|
+
inputRef.current?.measure(callback);
|
|
27
|
+
},
|
|
28
|
+
measureInWindow(callback) {
|
|
29
|
+
inputRef.current?.measureInWindow(callback);
|
|
30
|
+
},
|
|
31
|
+
measureLayout(relativeToNativeComponentRef, onSuccess, onFail) {
|
|
32
|
+
inputRef.current?.measureLayout(relativeToNativeComponentRef, onSuccess, onFail);
|
|
33
|
+
},
|
|
34
|
+
}), [inputRef]));
|
|
35
|
+
return inputRef;
|
|
36
|
+
}
|
|
37
|
+
function mask(format) {
|
|
38
|
+
const maskArray = [];
|
|
39
|
+
let isObfuscated = false;
|
|
40
|
+
format.split("").forEach((char) => {
|
|
41
|
+
if (char === "[") {
|
|
42
|
+
isObfuscated = true;
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
else if (char === "]") {
|
|
46
|
+
isObfuscated = false;
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
let value = char;
|
|
50
|
+
if (char === "9") {
|
|
51
|
+
value = isObfuscated ? [/\d/] : /\d/;
|
|
52
|
+
}
|
|
53
|
+
maskArray.push(value);
|
|
54
|
+
});
|
|
55
|
+
return maskArray;
|
|
56
|
+
}
|
|
57
|
+
const EvervaultInput = forwardRef(function EvervaultInput({ name, mask, obfuscateValue, ...props }, ref) {
|
|
58
|
+
const { validationMode } = useContext(EvervaultInputContext);
|
|
59
|
+
const inputRef = useForwardedInputRef(ref);
|
|
60
|
+
const methods = useFormContext();
|
|
61
|
+
const { field, fieldState } = useController({
|
|
62
|
+
control: methods.control,
|
|
63
|
+
name,
|
|
64
|
+
shouldUnregister: true,
|
|
65
|
+
});
|
|
66
|
+
const obfuscationCharacter = useMemo(() => {
|
|
67
|
+
if (typeof obfuscateValue === "string") {
|
|
68
|
+
return obfuscateValue;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
return "•";
|
|
72
|
+
}
|
|
73
|
+
}, [obfuscateValue]);
|
|
74
|
+
return (jsx(MaskInput
|
|
75
|
+
// Overridable props
|
|
76
|
+
, {
|
|
77
|
+
// Overridable props
|
|
78
|
+
id: field.name, ...props,
|
|
79
|
+
// Strict props
|
|
80
|
+
ref: mergeRefs(inputRef, field.ref), editable: !field.disabled && (props.editable ?? true), onBlur: (evt) => {
|
|
81
|
+
const shouldValidate = validationMode === "onBlur" ||
|
|
82
|
+
validationMode === "onTouched" ||
|
|
83
|
+
validationMode === "all";
|
|
84
|
+
methods.setValue(field.name, field.value, {
|
|
85
|
+
shouldDirty: true,
|
|
86
|
+
shouldTouch: true,
|
|
87
|
+
shouldValidate,
|
|
88
|
+
});
|
|
89
|
+
props.onBlur?.(evt);
|
|
90
|
+
}, mask: mask, maskAutoComplete: !!mask, obfuscationCharacter: obfuscationCharacter, showObfuscatedValue: !!obfuscateValue, value: field.value, onChangeText: (masked, unmasked) => {
|
|
91
|
+
const shouldValidate = (validationMode === "onTouched" && fieldState.isTouched) ||
|
|
92
|
+
((validationMode === "onChange" || validationMode === "all") &&
|
|
93
|
+
(!!fieldState.error || fieldState.isTouched));
|
|
94
|
+
methods.setValue(field.name, unmasked, {
|
|
95
|
+
shouldDirty: true,
|
|
96
|
+
shouldValidate,
|
|
97
|
+
});
|
|
98
|
+
},
|
|
99
|
+
// Remove unwanted props
|
|
100
|
+
defaultValue: undefined, onChange: undefined }));
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
export { EvervaultInput, EvervaultInputContext, mask };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useContext, useMemo } from 'react';
|
|
3
|
+
import { StyleSheet } from 'react-native';
|
|
4
|
+
import { useEvervault } from '../useEvervault.js';
|
|
5
|
+
import { WebView } from 'react-native-webview';
|
|
6
|
+
import { CHALLENGE_DOMAIN_3DS } from './config.js';
|
|
7
|
+
import { ThreeDSecureContext } from './context.js';
|
|
8
|
+
|
|
9
|
+
function ThreeDSecureFrame({ style }) {
|
|
10
|
+
const evervault = useEvervault();
|
|
11
|
+
const context = useContext(ThreeDSecureContext);
|
|
12
|
+
if (!context) {
|
|
13
|
+
throw new Error("`ThreeDSecure.Frame` must be used within a `ThreeDSecure` component.");
|
|
14
|
+
}
|
|
15
|
+
const uri = useMemo(() => {
|
|
16
|
+
if (!context.session)
|
|
17
|
+
return null;
|
|
18
|
+
const params = new URLSearchParams();
|
|
19
|
+
params.set("session", context.session.sessionId);
|
|
20
|
+
params.set("app", evervault.appId);
|
|
21
|
+
params.set("team", evervault.teamId);
|
|
22
|
+
return `https://${CHALLENGE_DOMAIN_3DS}/?${params.toString()}`;
|
|
23
|
+
}, [context.session, evervault.appId, evervault.teamId]);
|
|
24
|
+
if (!uri)
|
|
25
|
+
return null;
|
|
26
|
+
return (jsx(WebView, { containerStyle: [defaultStyles.webView, style], source: { uri }, hideKeyboardAccessoryView: true, overScrollMode: "content" }));
|
|
27
|
+
}
|
|
28
|
+
const defaultStyles = StyleSheet.create({
|
|
29
|
+
webView: {
|
|
30
|
+
flex: 1,
|
|
31
|
+
width: "100%",
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
export { ThreeDSecureFrame };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useEvervault } from '../useEvervault.js';
|
|
3
|
+
import { ThreeDSecureContext } from './context.js';
|
|
4
|
+
|
|
5
|
+
function ThreeDSecure({ state, children }) {
|
|
6
|
+
useEvervault();
|
|
7
|
+
if (!state.session)
|
|
8
|
+
return null;
|
|
9
|
+
return (jsx(ThreeDSecureContext.Provider, { value: state, children: state.isVisible && children }));
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export { ThreeDSecure };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
class ThreeDSecureEvent {
|
|
2
|
+
type;
|
|
3
|
+
session;
|
|
4
|
+
_defaultPrevented;
|
|
5
|
+
constructor(type, session, _defaultPrevented = false) {
|
|
6
|
+
this.type = type;
|
|
7
|
+
this.session = session;
|
|
8
|
+
this._defaultPrevented = _defaultPrevented;
|
|
9
|
+
}
|
|
10
|
+
preventDefault() {
|
|
11
|
+
this._defaultPrevented = true;
|
|
12
|
+
}
|
|
13
|
+
get defaultPrevented() {
|
|
14
|
+
return this._defaultPrevented;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { ThreeDSecureEvent };
|
|
@@ -7,4 +7,3 @@ export type { ThreeDSecureProps } from "./Root";
|
|
|
7
7
|
export type { ThreeDSecureFrameProps } from "./Frame";
|
|
8
8
|
export type { ThreeDSecureState, ThreeDSecureSession, ThreeDSecureCallbacks, } from "./types";
|
|
9
9
|
export { useThreeDSecure } from "./useThreeDSecure";
|
|
10
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ThreeDSecure as ThreeDSecure$1 } from './Root.js';
|
|
2
|
+
import { ThreeDSecureFrame } from './Frame.js';
|
|
3
|
+
export { useThreeDSecure } from './useThreeDSecure.js';
|
|
4
|
+
|
|
5
|
+
const ThreeDSecure = Object.assign(ThreeDSecure$1, {
|
|
6
|
+
Frame: ThreeDSecureFrame,
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
export { ThreeDSecure };
|
|
@@ -3,4 +3,3 @@ export declare function stopPolling(intervalRef: React.MutableRefObject<NodeJS.T
|
|
|
3
3
|
export declare function startSession(session: ThreeDSecureSession, options: ThreeDSecureOptions | undefined, intervalRef: React.MutableRefObject<NodeJS.Timeout | null>, setIsVisible: (show: boolean) => void): Promise<void>;
|
|
4
4
|
export declare function pollSession(session: ThreeDSecureSession, options: ThreeDSecureOptions | undefined, intervalRef: React.MutableRefObject<NodeJS.Timeout | null>, setIsVisible: (show: boolean) => void, interval?: number): void;
|
|
5
5
|
export declare function threeDSecureSession({ sessionId, appId, options, intervalRef, setIsVisible, }: ThreeDSecureSessionsParams): ThreeDSecureSession;
|
|
6
|
-
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { EV_API_DOMAIN } from './config.js';
|
|
2
|
+
import { ThreeDSecureEvent } from './event.js';
|
|
3
|
+
|
|
4
|
+
function stopPolling(intervalRef, setIsVisible) {
|
|
5
|
+
setIsVisible(false);
|
|
6
|
+
if (intervalRef.current) {
|
|
7
|
+
clearInterval(intervalRef.current);
|
|
8
|
+
intervalRef.current = null;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
async function startSession(session, options, intervalRef, setIsVisible) {
|
|
12
|
+
try {
|
|
13
|
+
const sessionState = await session.get();
|
|
14
|
+
function fail() {
|
|
15
|
+
stopPolling(intervalRef, setIsVisible);
|
|
16
|
+
options?.onFailure?.(new Error("3DS session failed"));
|
|
17
|
+
}
|
|
18
|
+
switch (sessionState.status) {
|
|
19
|
+
case "success": {
|
|
20
|
+
stopPolling(intervalRef, setIsVisible);
|
|
21
|
+
options?.onSuccess?.();
|
|
22
|
+
break;
|
|
23
|
+
}
|
|
24
|
+
case "failure": {
|
|
25
|
+
fail();
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
case "action-required": {
|
|
29
|
+
const failOnChallenge = typeof options?.failOnChallenge === "function"
|
|
30
|
+
? await options.failOnChallenge()
|
|
31
|
+
: options?.failOnChallenge ?? false;
|
|
32
|
+
if (failOnChallenge) {
|
|
33
|
+
fail();
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
const event = new ThreeDSecureEvent("requestChallenge", session);
|
|
37
|
+
options?.onRequestChallenge?.(event);
|
|
38
|
+
if (event.defaultPrevented) {
|
|
39
|
+
fail();
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
setIsVisible(true);
|
|
43
|
+
pollSession(session, options, intervalRef, setIsVisible);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
console.error("Error checking session state", error);
|
|
49
|
+
options?.onError?.(new Error("Failed to check 3DS session state"));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function pollSession(session, options, intervalRef, setIsVisible, interval = 3000) {
|
|
53
|
+
function fail() {
|
|
54
|
+
stopPolling(intervalRef, setIsVisible);
|
|
55
|
+
options?.onFailure?.(new Error("3DS session failed"));
|
|
56
|
+
}
|
|
57
|
+
intervalRef.current = setInterval(async () => {
|
|
58
|
+
try {
|
|
59
|
+
const pollResponse = await session.get();
|
|
60
|
+
switch (pollResponse.status) {
|
|
61
|
+
case "success": {
|
|
62
|
+
stopPolling(intervalRef, setIsVisible);
|
|
63
|
+
options?.onSuccess?.();
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
case "failure": {
|
|
67
|
+
fail();
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
case "action-required": {
|
|
71
|
+
const failOnChallenge = typeof options?.failOnChallenge === "function"
|
|
72
|
+
? await options.failOnChallenge()
|
|
73
|
+
: options?.failOnChallenge ?? false;
|
|
74
|
+
if (failOnChallenge) {
|
|
75
|
+
fail();
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
const event = new ThreeDSecureEvent("requestChallenge", session);
|
|
79
|
+
options?.onRequestChallenge?.(event);
|
|
80
|
+
if (event.defaultPrevented) {
|
|
81
|
+
fail();
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
setIsVisible(true);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
stopPolling(intervalRef, setIsVisible);
|
|
90
|
+
console.error("Error polling session", error);
|
|
91
|
+
options?.onError?.(new Error("Error polling 3DS session"));
|
|
92
|
+
}
|
|
93
|
+
}, interval);
|
|
94
|
+
}
|
|
95
|
+
function threeDSecureSession({ sessionId, appId, options, intervalRef, setIsVisible, }) {
|
|
96
|
+
async function get() {
|
|
97
|
+
try {
|
|
98
|
+
const response = await fetch(`https://${EV_API_DOMAIN}/frontend/3ds/browser-sessions/${sessionId}`, {
|
|
99
|
+
headers: {
|
|
100
|
+
"x-evervault-app-id": appId,
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
const result = (await response.json());
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
console.error("Error fetching 3DS session status", error);
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
async function cancel() {
|
|
112
|
+
try {
|
|
113
|
+
await fetch(`https://${EV_API_DOMAIN}/frontend/3ds/browser-sessions/${sessionId}`, {
|
|
114
|
+
method: "PATCH",
|
|
115
|
+
headers: {
|
|
116
|
+
"Content-Type": "application/json",
|
|
117
|
+
"x-evervault-app-id": appId,
|
|
118
|
+
},
|
|
119
|
+
body: JSON.stringify({ outcome: "cancelled" }),
|
|
120
|
+
});
|
|
121
|
+
options?.onFailure?.(new Error("3DS session cancelled by user"));
|
|
122
|
+
stopPolling(intervalRef, setIsVisible);
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
console.error("Error cancelling 3DS session", error);
|
|
126
|
+
throw error;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
sessionId,
|
|
131
|
+
get,
|
|
132
|
+
cancel,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export { pollSession, startSession, stopPolling, threeDSecureSession };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { useRef, useState, useCallback, useMemo } from 'react';
|
|
2
|
+
import { threeDSecureSession, startSession } from './session.js';
|
|
3
|
+
import { useEvervault } from '../useEvervault.js';
|
|
4
|
+
|
|
5
|
+
function useThreeDSecure(options) {
|
|
6
|
+
const { appId } = useEvervault();
|
|
7
|
+
const intervalRef = useRef(null);
|
|
8
|
+
const [session, setSession] = useState(null);
|
|
9
|
+
const [isVisible, setIsVisible] = useState(false);
|
|
10
|
+
const failOnChallenge = options?.failOnChallenge ?? false;
|
|
11
|
+
const start = useCallback((sessionId, options) => {
|
|
12
|
+
const startOptions = {
|
|
13
|
+
...options,
|
|
14
|
+
failOnChallenge: options?.failOnChallenge ?? failOnChallenge,
|
|
15
|
+
};
|
|
16
|
+
const session = threeDSecureSession({
|
|
17
|
+
sessionId,
|
|
18
|
+
appId,
|
|
19
|
+
options: startOptions,
|
|
20
|
+
intervalRef,
|
|
21
|
+
setIsVisible,
|
|
22
|
+
});
|
|
23
|
+
setSession(session);
|
|
24
|
+
startSession(session, startOptions, intervalRef, setIsVisible);
|
|
25
|
+
}, [appId, failOnChallenge]);
|
|
26
|
+
const cancel = useCallback(async () => {
|
|
27
|
+
if (session) {
|
|
28
|
+
await session.cancel();
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
console.warn("No 3DS session to cancel");
|
|
32
|
+
}
|
|
33
|
+
}, [session]);
|
|
34
|
+
return useMemo(() => ({
|
|
35
|
+
start,
|
|
36
|
+
cancel,
|
|
37
|
+
session,
|
|
38
|
+
isVisible,
|
|
39
|
+
}), [start, cancel, session, isVisible]);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export { useThreeDSecure };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const encryptedValue = "ev:W98t:uu98aas09udya863ty9372y7y23h97rg6gfs678987";
|
|
2
|
+
const NativeEvervault = {
|
|
3
|
+
initialize: vi.fn(),
|
|
4
|
+
encryptString: vi.fn(() => Promise.resolve(encryptedValue)),
|
|
5
|
+
encryptNumber: vi.fn(() => Promise.resolve(encryptedValue)),
|
|
6
|
+
encryptBoolean: vi.fn(() => Promise.resolve(encryptedValue)),
|
|
7
|
+
encryptObject: vi.fn(),
|
|
8
|
+
encryptArray: vi.fn(),
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export { NativeEvervault, encryptedValue };
|