@neofaceid/web-sdk 1.15.2 → 1.19.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.
|
@@ -1623,7 +1623,7 @@ const loginWithBiometric = async (image, applicationToken) => {
|
|
|
1623
1623
|
}
|
|
1624
1624
|
return {
|
|
1625
1625
|
success: true,
|
|
1626
|
-
accessToken: data.accessToken,
|
|
1626
|
+
accessToken: data.accessToken || data.access_token || "",
|
|
1627
1627
|
alias: data.alias,
|
|
1628
1628
|
user: {
|
|
1629
1629
|
id: ((_a = data.user) == null ? void 0 : _a.id) || "",
|
|
@@ -1633,6 +1633,7 @@ const loginWithBiometric = async (image, applicationToken) => {
|
|
|
1633
1633
|
active: ((_e = data.user) == null ? void 0 : _e.active) || false
|
|
1634
1634
|
},
|
|
1635
1635
|
person: data.person ? {
|
|
1636
|
+
id: data.person.id || "",
|
|
1636
1637
|
name: data.person.name || "",
|
|
1637
1638
|
birth_date: data.person.birth_date || ""
|
|
1638
1639
|
} : void 0,
|
|
@@ -1838,7 +1839,8 @@ const registerPersonWithoutFace = async (personData, applicationToken, options)
|
|
|
1838
1839
|
cpf: personData.cpf,
|
|
1839
1840
|
email: personData.email,
|
|
1840
1841
|
password: personData.password,
|
|
1841
|
-
password_confirm: personData.password
|
|
1842
|
+
password_confirm: personData.password,
|
|
1843
|
+
is_pep: personData.is_pep ?? false
|
|
1842
1844
|
};
|
|
1843
1845
|
if (documentFrontBase64) {
|
|
1844
1846
|
body.document_images = [
|
|
@@ -1879,6 +1881,43 @@ const registerPersonWithoutFace = async (personData, applicationToken, options)
|
|
|
1879
1881
|
throw new NeoFaceError("Unknown error occurred", ErrorType.NETWORK);
|
|
1880
1882
|
}
|
|
1881
1883
|
};
|
|
1884
|
+
const checkUserExistence = async (params) => {
|
|
1885
|
+
const controller = createTimeoutController();
|
|
1886
|
+
const queryParams = new URLSearchParams();
|
|
1887
|
+
if (params.email) queryParams.append("email", params.email);
|
|
1888
|
+
if (params.cpf) queryParams.append("cpf", params.cpf);
|
|
1889
|
+
try {
|
|
1890
|
+
const response = await fetch(
|
|
1891
|
+
`${getApiBaseUrl()}/api/v1/verify/user/?${queryParams.toString()}`,
|
|
1892
|
+
{
|
|
1893
|
+
method: "GET",
|
|
1894
|
+
headers: {
|
|
1895
|
+
"Content-Type": "application/json"
|
|
1896
|
+
},
|
|
1897
|
+
signal: controller.signal
|
|
1898
|
+
}
|
|
1899
|
+
);
|
|
1900
|
+
if (!response.ok) {
|
|
1901
|
+
const errorData = await response.json().catch(() => ({}));
|
|
1902
|
+
throw new NeoFaceError(
|
|
1903
|
+
errorData.message || `Server returned status ${response.status}`,
|
|
1904
|
+
ErrorType.NETWORK
|
|
1905
|
+
);
|
|
1906
|
+
}
|
|
1907
|
+
return await response.json();
|
|
1908
|
+
} catch (error) {
|
|
1909
|
+
if (error instanceof Error) {
|
|
1910
|
+
if (error.name === "AbortError") {
|
|
1911
|
+
throw new NeoFaceError("Request timed out", ErrorType.NETWORK);
|
|
1912
|
+
}
|
|
1913
|
+
if (error instanceof NeoFaceError) {
|
|
1914
|
+
throw error;
|
|
1915
|
+
}
|
|
1916
|
+
throw new NeoFaceError(error.message, ErrorType.NETWORK);
|
|
1917
|
+
}
|
|
1918
|
+
throw new NeoFaceError("Unknown error occurred", ErrorType.NETWORK);
|
|
1919
|
+
}
|
|
1920
|
+
};
|
|
1882
1921
|
const registerPersonWithBiometric = async (personData, facePhotos, applicationToken, options) => {
|
|
1883
1922
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
1884
1923
|
ensureSecureContext();
|
|
@@ -1934,7 +1973,8 @@ const registerPersonWithBiometric = async (personData, facePhotos, applicationTo
|
|
|
1934
1973
|
email: personData.email,
|
|
1935
1974
|
password: personData.password,
|
|
1936
1975
|
password_confirm: personData.password,
|
|
1937
|
-
face_photos: facePhotosBase64
|
|
1976
|
+
face_photos: facePhotosBase64,
|
|
1977
|
+
is_pep: personData.is_pep ?? false
|
|
1938
1978
|
};
|
|
1939
1979
|
if (documentFrontBase64) {
|
|
1940
1980
|
body.document_images = [
|
|
@@ -2028,7 +2068,6 @@ const registerPersonWithBiometric = async (personData, facePhotos, applicationTo
|
|
|
2028
2068
|
}
|
|
2029
2069
|
};
|
|
2030
2070
|
const loginWithEmail = async (email, password, applicationToken) => {
|
|
2031
|
-
ensureSecureContext();
|
|
2032
2071
|
const controller = createTimeoutController();
|
|
2033
2072
|
try {
|
|
2034
2073
|
const response = await fetch(`${getApiBaseUrl()}/api/v1/auth/login/`, {
|
|
@@ -2074,10 +2113,10 @@ const loginWithEmail = async (email, password, applicationToken) => {
|
|
|
2074
2113
|
}
|
|
2075
2114
|
};
|
|
2076
2115
|
const identifyPerson = async (image, applicationToken) => {
|
|
2077
|
-
var _a, _b;
|
|
2116
|
+
var _a, _b, _c, _d;
|
|
2078
2117
|
ensureSecureContext();
|
|
2079
2118
|
const controller = createTimeoutController();
|
|
2080
|
-
const compressedImage = await
|
|
2119
|
+
const compressedImage = await compressDocumentImage(image);
|
|
2081
2120
|
const base64Image = await new Promise((resolve, reject) => {
|
|
2082
2121
|
const reader = new FileReader();
|
|
2083
2122
|
reader.onload = () => {
|
|
@@ -2088,7 +2127,7 @@ const identifyPerson = async (image, applicationToken) => {
|
|
|
2088
2127
|
reader.readAsDataURL(compressedImage);
|
|
2089
2128
|
});
|
|
2090
2129
|
try {
|
|
2091
|
-
const response = await fetch(`${getApiBaseUrl()}/api/v1/
|
|
2130
|
+
const response = await fetch(`${getApiBaseUrl()}/api/v1/auth/recognition/face/external/`, {
|
|
2092
2131
|
method: "POST",
|
|
2093
2132
|
headers: {
|
|
2094
2133
|
"Content-Type": "application/json",
|
|
@@ -2107,30 +2146,26 @@ const identifyPerson = async (image, applicationToken) => {
|
|
|
2107
2146
|
throw new NeoFaceError(`Server returned status ${response.status}`, ErrorType.NETWORK);
|
|
2108
2147
|
}
|
|
2109
2148
|
const data = await response.json();
|
|
2149
|
+
if (response.status === 202 || data.data && data.data.task_id) {
|
|
2150
|
+
return {
|
|
2151
|
+
success: true,
|
|
2152
|
+
taskId: ((_a = data.data) == null ? void 0 : _a.task_id) || data.task_id,
|
|
2153
|
+
status: ((_b = data.data) == null ? void 0 : _b.status) || "processing",
|
|
2154
|
+
message: data.message || "Identification scheduled"
|
|
2155
|
+
};
|
|
2156
|
+
}
|
|
2110
2157
|
if (!data.success) {
|
|
2111
2158
|
throw new NeoFaceError(
|
|
2112
2159
|
data.message || "Person identification failed",
|
|
2113
2160
|
ErrorType.RECOGNITION_FAILED
|
|
2114
2161
|
);
|
|
2115
2162
|
}
|
|
2116
|
-
const personName = ((_a = data.person) == null ? void 0 : _a.name) || "";
|
|
2117
|
-
const birthDateStr = (_b = data.person) == null ? void 0 : _b.birth_date;
|
|
2118
|
-
if (!personName) {
|
|
2119
|
-
throw new NeoFaceError("Person name not found in response", ErrorType.PERSON_NOT_FOUND);
|
|
2120
|
-
}
|
|
2121
|
-
if (!birthDateStr) {
|
|
2122
|
-
throw new NeoFaceError("Birth date not found in response", ErrorType.PERSON_NOT_FOUND);
|
|
2123
|
-
}
|
|
2124
|
-
const birthDate = new Date(birthDateStr);
|
|
2125
|
-
const today = /* @__PURE__ */ new Date();
|
|
2126
|
-
let age = today.getFullYear() - birthDate.getFullYear();
|
|
2127
|
-
const monthDiff = today.getMonth() - birthDate.getMonth();
|
|
2128
|
-
if (monthDiff < 0 || monthDiff === 0 && today.getDate() < birthDate.getDate()) {
|
|
2129
|
-
age--;
|
|
2130
|
-
}
|
|
2131
2163
|
return {
|
|
2132
|
-
|
|
2133
|
-
|
|
2164
|
+
success: true,
|
|
2165
|
+
person: {
|
|
2166
|
+
name: ((_c = data.person) == null ? void 0 : _c.name) || "",
|
|
2167
|
+
birth_date: ((_d = data.person) == null ? void 0 : _d.birth_date) || ""
|
|
2168
|
+
}
|
|
2134
2169
|
};
|
|
2135
2170
|
} catch (error) {
|
|
2136
2171
|
if (error instanceof Error) {
|
|
@@ -2564,6 +2599,135 @@ const registerDocumentByImage = async (personId, jwtToken, images) => {
|
|
|
2564
2599
|
throw new NeoFaceError("Unknown error occurred", ErrorType.NETWORK_ERROR);
|
|
2565
2600
|
}
|
|
2566
2601
|
};
|
|
2602
|
+
const getTaskStatus = async (taskId) => {
|
|
2603
|
+
const controller = createTimeoutController();
|
|
2604
|
+
try {
|
|
2605
|
+
const response = await fetch(`${getApiBaseUrl()}/api/v1/tasks/status/?task_id=${taskId}`, {
|
|
2606
|
+
method: "GET",
|
|
2607
|
+
headers: {
|
|
2608
|
+
"Content-Type": "application/json"
|
|
2609
|
+
},
|
|
2610
|
+
signal: controller.signal
|
|
2611
|
+
});
|
|
2612
|
+
const data = await response.json();
|
|
2613
|
+
if (!response.ok) {
|
|
2614
|
+
throw new NeoFaceError(
|
|
2615
|
+
(data == null ? void 0 : data.message) || `API Error ${response.status}`,
|
|
2616
|
+
ErrorType.NETWORK_ERROR
|
|
2617
|
+
);
|
|
2618
|
+
}
|
|
2619
|
+
return {
|
|
2620
|
+
success: data.success,
|
|
2621
|
+
status: data.data.status,
|
|
2622
|
+
result: data.data.result,
|
|
2623
|
+
error: data.data.error
|
|
2624
|
+
};
|
|
2625
|
+
} catch (error) {
|
|
2626
|
+
if (error instanceof NeoFaceError) throw error;
|
|
2627
|
+
throw new NeoFaceError("Failed to fetch task status", ErrorType.NETWORK_ERROR);
|
|
2628
|
+
}
|
|
2629
|
+
};
|
|
2630
|
+
const identifyPersonAsync = async (image, applicationToken, options = {}) => {
|
|
2631
|
+
var _a, _b;
|
|
2632
|
+
const { maxRetries = 30, interval = 2e3 } = options;
|
|
2633
|
+
const initialResponse = await identifyPerson(image, applicationToken);
|
|
2634
|
+
if (initialResponse.person) {
|
|
2635
|
+
return {
|
|
2636
|
+
personFound: true,
|
|
2637
|
+
person: initialResponse.person
|
|
2638
|
+
};
|
|
2639
|
+
}
|
|
2640
|
+
const taskId = initialResponse.taskId;
|
|
2641
|
+
if (!taskId) {
|
|
2642
|
+
return { personFound: false };
|
|
2643
|
+
}
|
|
2644
|
+
for (let i = 0; i < maxRetries; i++) {
|
|
2645
|
+
const status = await getTaskStatus(taskId);
|
|
2646
|
+
if (status.status === "success") {
|
|
2647
|
+
if (status.result && status.result.success) {
|
|
2648
|
+
return {
|
|
2649
|
+
personFound: true,
|
|
2650
|
+
person: {
|
|
2651
|
+
name: ((_a = status.result.person) == null ? void 0 : _a.name) || "Pessoa identificada",
|
|
2652
|
+
birth_date: ((_b = status.result.person) == null ? void 0 : _b.birth_date) || ""
|
|
2653
|
+
}
|
|
2654
|
+
};
|
|
2655
|
+
}
|
|
2656
|
+
return { personFound: false };
|
|
2657
|
+
}
|
|
2658
|
+
if (status.status === "failure") {
|
|
2659
|
+
return { personFound: false };
|
|
2660
|
+
}
|
|
2661
|
+
await new Promise((resolve) => setTimeout(resolve, interval));
|
|
2662
|
+
}
|
|
2663
|
+
throw new NeoFaceError("Timed out waiting for identification", ErrorType.NETWORK_ERROR);
|
|
2664
|
+
};
|
|
2665
|
+
async function requestPasswordReset(email, applicationToken) {
|
|
2666
|
+
const baseUrl = getBaseUrl();
|
|
2667
|
+
const response = await fetch(`${baseUrl}/api/v1/user/password/reset/request/`, {
|
|
2668
|
+
method: "POST",
|
|
2669
|
+
headers: {
|
|
2670
|
+
"Content-Type": "application/json",
|
|
2671
|
+
"X-App-Token": applicationToken
|
|
2672
|
+
},
|
|
2673
|
+
body: JSON.stringify({ email })
|
|
2674
|
+
});
|
|
2675
|
+
if (!response.ok) {
|
|
2676
|
+
const errorData = await response.json();
|
|
2677
|
+
throw new NeoFaceError(
|
|
2678
|
+
errorData.message || "Erro ao solicitar recuperação de senha",
|
|
2679
|
+
ErrorType.API_ERROR
|
|
2680
|
+
);
|
|
2681
|
+
}
|
|
2682
|
+
return response.json();
|
|
2683
|
+
}
|
|
2684
|
+
async function confirmPasswordReset(token, new_password) {
|
|
2685
|
+
const baseUrl = getBaseUrl();
|
|
2686
|
+
const response = await fetch(`${baseUrl}/api/v1/user/password/reset/confirm/`, {
|
|
2687
|
+
method: "POST",
|
|
2688
|
+
headers: {
|
|
2689
|
+
"Content-Type": "application/json"
|
|
2690
|
+
},
|
|
2691
|
+
body: JSON.stringify({ token, new_password })
|
|
2692
|
+
});
|
|
2693
|
+
if (!response.ok) {
|
|
2694
|
+
const errorData = await response.json();
|
|
2695
|
+
throw new NeoFaceError(
|
|
2696
|
+
errorData.error || errorData.message || "Erro ao redefinir senha",
|
|
2697
|
+
ErrorType.API_ERROR
|
|
2698
|
+
);
|
|
2699
|
+
}
|
|
2700
|
+
return response.json();
|
|
2701
|
+
}
|
|
2702
|
+
const api = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2703
|
+
__proto__: null,
|
|
2704
|
+
checkUserExistence,
|
|
2705
|
+
completeOnboarding,
|
|
2706
|
+
completeOnboardingWithData,
|
|
2707
|
+
confirmPasswordReset,
|
|
2708
|
+
getOnboardingDetails,
|
|
2709
|
+
getTaskStatus,
|
|
2710
|
+
identifyPerson,
|
|
2711
|
+
identifyPersonAsync,
|
|
2712
|
+
loginWithBiometric,
|
|
2713
|
+
loginWithEmail,
|
|
2714
|
+
pollTaskStatus,
|
|
2715
|
+
recognize,
|
|
2716
|
+
recognizeBiometric,
|
|
2717
|
+
recognizeByPurpose,
|
|
2718
|
+
recordFaceVideo,
|
|
2719
|
+
registerApplication,
|
|
2720
|
+
registerBiometric,
|
|
2721
|
+
registerDocumentByImage,
|
|
2722
|
+
registerPersonWithBiometric,
|
|
2723
|
+
registerPersonWithoutFace,
|
|
2724
|
+
requestPasswordReset,
|
|
2725
|
+
simpleIdentification,
|
|
2726
|
+
startProofOfLife,
|
|
2727
|
+
validateOnboardingToken,
|
|
2728
|
+
validateToken,
|
|
2729
|
+
videoToBase64
|
|
2730
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
2567
2731
|
const modalReducer$1 = (state, action) => {
|
|
2568
2732
|
switch (action.type) {
|
|
2569
2733
|
case "PERMISSION_GRANTED":
|
|
@@ -2857,6 +3021,336 @@ function FaceCaptureModal({ accessToken, onClose, onSuccess }) {
|
|
|
2857
3021
|
] })
|
|
2858
3022
|
] });
|
|
2859
3023
|
}
|
|
3024
|
+
class ForgotPasswordModal {
|
|
3025
|
+
constructor(applicationToken) {
|
|
3026
|
+
__publicField(this, "applicationToken");
|
|
3027
|
+
__publicField(this, "modalElement", null);
|
|
3028
|
+
this.applicationToken = applicationToken;
|
|
3029
|
+
}
|
|
3030
|
+
open() {
|
|
3031
|
+
if (this.modalElement) return;
|
|
3032
|
+
this.addStyles();
|
|
3033
|
+
this.modalElement = document.createElement("div");
|
|
3034
|
+
this.modalElement.className = "neoface-forgot-modal";
|
|
3035
|
+
this.renderEmailForm();
|
|
3036
|
+
document.body.appendChild(this.modalElement);
|
|
3037
|
+
}
|
|
3038
|
+
close() {
|
|
3039
|
+
if (this.modalElement && document.body.contains(this.modalElement)) {
|
|
3040
|
+
document.body.removeChild(this.modalElement);
|
|
3041
|
+
this.modalElement = null;
|
|
3042
|
+
}
|
|
3043
|
+
}
|
|
3044
|
+
renderEmailForm() {
|
|
3045
|
+
if (!this.modalElement) return;
|
|
3046
|
+
this.modalElement.innerHTML = `
|
|
3047
|
+
<div class="neoface-forgot-overlay">
|
|
3048
|
+
<div class="neoface-forgot-content">
|
|
3049
|
+
<div class="neoface-forgot-icon">
|
|
3050
|
+
<svg viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3051
|
+
<circle cx="32" cy="32" r="28" stroke="#7c3aed" stroke-width="3" fill="none"/>
|
|
3052
|
+
<rect x="22" y="28" width="20" height="16" rx="3" stroke="#7c3aed" stroke-width="2.5" fill="none"/>
|
|
3053
|
+
<path d="M26 28v-4a6 6 0 0 1 12 0v4" stroke="#7c3aed" stroke-width="2.5" stroke-linecap="round"/>
|
|
3054
|
+
<circle cx="32" cy="36" r="2" fill="#7c3aed"/>
|
|
3055
|
+
</svg>
|
|
3056
|
+
</div>
|
|
3057
|
+
|
|
3058
|
+
<h2 class="neoface-forgot-title">Recuperar senha</h2>
|
|
3059
|
+
<p class="neoface-forgot-subtitle">Informe seu email e enviaremos um link para redefinir sua senha.</p>
|
|
3060
|
+
|
|
3061
|
+
<div id="neoface-forgot-error" class="neoface-forgot-error" style="display:none"></div>
|
|
3062
|
+
|
|
3063
|
+
<form id="neoface-forgot-form">
|
|
3064
|
+
<input
|
|
3065
|
+
type="email"
|
|
3066
|
+
id="neoface-forgot-email"
|
|
3067
|
+
class="neoface-forgot-input"
|
|
3068
|
+
placeholder="seu@email.com"
|
|
3069
|
+
autocomplete="email"
|
|
3070
|
+
required
|
|
3071
|
+
/>
|
|
3072
|
+
<button type="submit" class="neoface-forgot-btn-primary">
|
|
3073
|
+
Enviar link
|
|
3074
|
+
</button>
|
|
3075
|
+
</form>
|
|
3076
|
+
|
|
3077
|
+
<button class="neoface-forgot-btn-ghost neoface-forgot-back">
|
|
3078
|
+
Voltar
|
|
3079
|
+
</button>
|
|
3080
|
+
|
|
3081
|
+
<div class="neoface-forgot-branding">
|
|
3082
|
+
<img src="/logo-icone-no-background.png" alt="NeoFaceId" class="neoface-forgot-brand-logo" onerror="this.style.display='none'" />
|
|
3083
|
+
<span>NeoFaceId by</span>
|
|
3084
|
+
<span class="neoface-forgot-brand-name">OCTA</span>
|
|
3085
|
+
</div>
|
|
3086
|
+
</div>
|
|
3087
|
+
</div>
|
|
3088
|
+
`;
|
|
3089
|
+
const form = this.modalElement.querySelector("#neoface-forgot-form");
|
|
3090
|
+
form.addEventListener("submit", this.handleSubmit.bind(this));
|
|
3091
|
+
const backBtn = this.modalElement.querySelector(".neoface-forgot-back");
|
|
3092
|
+
backBtn.addEventListener("click", this.close.bind(this));
|
|
3093
|
+
}
|
|
3094
|
+
renderSuccess() {
|
|
3095
|
+
if (!this.modalElement) return;
|
|
3096
|
+
const content = this.modalElement.querySelector(".neoface-forgot-content");
|
|
3097
|
+
content.innerHTML = `
|
|
3098
|
+
<div class="neoface-forgot-success-icon">
|
|
3099
|
+
<svg viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3100
|
+
<circle cx="32" cy="32" r="28" stroke="#10b981" stroke-width="3" fill="none"/>
|
|
3101
|
+
<path d="M20 32 L28 40 L44 24" stroke="#10b981" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
|
|
3102
|
+
</svg>
|
|
3103
|
+
</div>
|
|
3104
|
+
|
|
3105
|
+
<h2 class="neoface-forgot-title">Email enviado!</h2>
|
|
3106
|
+
<p class="neoface-forgot-subtitle">
|
|
3107
|
+
Verifique sua caixa de entrada e siga as instruções para redefinir sua senha.
|
|
3108
|
+
<br/><br/>
|
|
3109
|
+
<span style="color: rgba(255,255,255,0.5); font-size: 13px;">Não recebeu? Verifique também sua pasta de spam.</span>
|
|
3110
|
+
</p>
|
|
3111
|
+
|
|
3112
|
+
<button class="neoface-forgot-btn-primary neoface-forgot-close-success" style="margin-top: 8px;">
|
|
3113
|
+
Fechar
|
|
3114
|
+
</button>
|
|
3115
|
+
|
|
3116
|
+
<div class="neoface-forgot-branding">
|
|
3117
|
+
<img src="/logo-icone-no-background.png" alt="NeoFaceId" class="neoface-forgot-brand-logo" onerror="this.style.display='none'" />
|
|
3118
|
+
<span>NeoFaceId by</span>
|
|
3119
|
+
<span class="neoface-forgot-brand-name">OCTA</span>
|
|
3120
|
+
</div>
|
|
3121
|
+
`;
|
|
3122
|
+
const closeBtn = content.querySelector(".neoface-forgot-close-success");
|
|
3123
|
+
closeBtn.addEventListener("click", this.close.bind(this));
|
|
3124
|
+
}
|
|
3125
|
+
async handleSubmit(e) {
|
|
3126
|
+
var _a, _b, _c, _d;
|
|
3127
|
+
e.preventDefault();
|
|
3128
|
+
const emailInput = (_a = this.modalElement) == null ? void 0 : _a.querySelector(
|
|
3129
|
+
"#neoface-forgot-email"
|
|
3130
|
+
);
|
|
3131
|
+
const submitBtn = (_b = this.modalElement) == null ? void 0 : _b.querySelector(
|
|
3132
|
+
".neoface-forgot-btn-primary"
|
|
3133
|
+
);
|
|
3134
|
+
const errorEl = (_c = this.modalElement) == null ? void 0 : _c.querySelector("#neoface-forgot-error");
|
|
3135
|
+
const email = (_d = emailInput == null ? void 0 : emailInput.value) == null ? void 0 : _d.trim();
|
|
3136
|
+
if (!email) return;
|
|
3137
|
+
submitBtn.disabled = true;
|
|
3138
|
+
submitBtn.textContent = "Enviando...";
|
|
3139
|
+
errorEl.style.display = "none";
|
|
3140
|
+
try {
|
|
3141
|
+
await requestPasswordReset(email, this.applicationToken);
|
|
3142
|
+
this.renderSuccess();
|
|
3143
|
+
} catch (error) {
|
|
3144
|
+
submitBtn.disabled = false;
|
|
3145
|
+
submitBtn.textContent = "Enviar link";
|
|
3146
|
+
errorEl.style.display = "block";
|
|
3147
|
+
errorEl.textContent = error instanceof NeoFaceError ? error.message : "Erro ao enviar email. Tente novamente.";
|
|
3148
|
+
}
|
|
3149
|
+
}
|
|
3150
|
+
addStyles() {
|
|
3151
|
+
const styleId = "neoface-forgot-password-modal-styles";
|
|
3152
|
+
if (document.getElementById(styleId)) return;
|
|
3153
|
+
const style = document.createElement("style");
|
|
3154
|
+
style.id = styleId;
|
|
3155
|
+
style.textContent = `
|
|
3156
|
+
.neoface-forgot-modal {
|
|
3157
|
+
position: fixed;
|
|
3158
|
+
top: 0;
|
|
3159
|
+
left: 0;
|
|
3160
|
+
width: 100%;
|
|
3161
|
+
height: 100%;
|
|
3162
|
+
z-index: 10003;
|
|
3163
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
3164
|
+
}
|
|
3165
|
+
|
|
3166
|
+
.neoface-forgot-overlay {
|
|
3167
|
+
position: absolute;
|
|
3168
|
+
inset: 0;
|
|
3169
|
+
background: rgba(0, 0, 0, 0.65);
|
|
3170
|
+
backdrop-filter: blur(8px);
|
|
3171
|
+
display: flex;
|
|
3172
|
+
align-items: center;
|
|
3173
|
+
justify-content: center;
|
|
3174
|
+
padding: 20px;
|
|
3175
|
+
animation: neoface-forgot-fadeIn 0.3s ease-out;
|
|
3176
|
+
}
|
|
3177
|
+
|
|
3178
|
+
@keyframes neoface-forgot-fadeIn {
|
|
3179
|
+
from { opacity: 0; }
|
|
3180
|
+
to { opacity: 1; }
|
|
3181
|
+
}
|
|
3182
|
+
|
|
3183
|
+
@keyframes neoface-forgot-slideUp {
|
|
3184
|
+
from { opacity: 0; transform: translateY(20px); }
|
|
3185
|
+
to { opacity: 1; transform: translateY(0); }
|
|
3186
|
+
}
|
|
3187
|
+
|
|
3188
|
+
.neoface-forgot-content {
|
|
3189
|
+
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
|
|
3190
|
+
border-radius: 20px;
|
|
3191
|
+
padding: 32px;
|
|
3192
|
+
max-width: 400px;
|
|
3193
|
+
width: 100%;
|
|
3194
|
+
box-shadow: 0 24px 48px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.1);
|
|
3195
|
+
animation: neoface-forgot-slideUp 0.4s ease-out;
|
|
3196
|
+
text-align: center;
|
|
3197
|
+
}
|
|
3198
|
+
|
|
3199
|
+
.neoface-forgot-icon {
|
|
3200
|
+
width: 64px;
|
|
3201
|
+
height: 64px;
|
|
3202
|
+
margin: 0 auto 20px;
|
|
3203
|
+
}
|
|
3204
|
+
|
|
3205
|
+
.neoface-forgot-success-icon {
|
|
3206
|
+
width: 64px;
|
|
3207
|
+
height: 64px;
|
|
3208
|
+
margin: 0 auto 20px;
|
|
3209
|
+
animation: neoface-forgot-scaleIn 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
3210
|
+
}
|
|
3211
|
+
|
|
3212
|
+
@keyframes neoface-forgot-scaleIn {
|
|
3213
|
+
0% { transform: scale(0); opacity: 0; }
|
|
3214
|
+
50% { transform: scale(1.1); }
|
|
3215
|
+
100% { transform: scale(1); opacity: 1; }
|
|
3216
|
+
}
|
|
3217
|
+
|
|
3218
|
+
.neoface-forgot-title {
|
|
3219
|
+
font-size: 22px;
|
|
3220
|
+
font-weight: 700;
|
|
3221
|
+
color: white;
|
|
3222
|
+
margin: 0 0 10px 0;
|
|
3223
|
+
}
|
|
3224
|
+
|
|
3225
|
+
.neoface-forgot-subtitle {
|
|
3226
|
+
font-size: 15px;
|
|
3227
|
+
color: rgba(255, 255, 255, 0.7);
|
|
3228
|
+
margin: 0 0 24px 0;
|
|
3229
|
+
line-height: 1.5;
|
|
3230
|
+
}
|
|
3231
|
+
|
|
3232
|
+
.neoface-forgot-error {
|
|
3233
|
+
background: rgba(239, 68, 68, 0.15);
|
|
3234
|
+
border: 1px solid rgba(239, 68, 68, 0.4);
|
|
3235
|
+
color: #fca5a5;
|
|
3236
|
+
border-radius: 10px;
|
|
3237
|
+
padding: 10px 14px;
|
|
3238
|
+
font-size: 14px;
|
|
3239
|
+
margin-bottom: 16px;
|
|
3240
|
+
text-align: left;
|
|
3241
|
+
}
|
|
3242
|
+
|
|
3243
|
+
#neoface-forgot-form {
|
|
3244
|
+
display: flex;
|
|
3245
|
+
flex-direction: column;
|
|
3246
|
+
gap: 14px;
|
|
3247
|
+
margin-bottom: 12px;
|
|
3248
|
+
}
|
|
3249
|
+
|
|
3250
|
+
.neoface-forgot-input {
|
|
3251
|
+
width: 100%;
|
|
3252
|
+
padding: 14px 16px;
|
|
3253
|
+
border: 2px solid rgba(255, 255, 255, 0.2);
|
|
3254
|
+
border-radius: 12px;
|
|
3255
|
+
font-size: 15px;
|
|
3256
|
+
background: rgba(255, 255, 255, 0.08);
|
|
3257
|
+
color: white;
|
|
3258
|
+
font-family: inherit;
|
|
3259
|
+
transition: all 0.2s;
|
|
3260
|
+
box-sizing: border-box;
|
|
3261
|
+
}
|
|
3262
|
+
|
|
3263
|
+
.neoface-forgot-input::placeholder {
|
|
3264
|
+
color: rgba(255, 255, 255, 0.4);
|
|
3265
|
+
}
|
|
3266
|
+
|
|
3267
|
+
.neoface-forgot-input:focus {
|
|
3268
|
+
outline: none;
|
|
3269
|
+
border-color: #7c3aed;
|
|
3270
|
+
box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.2);
|
|
3271
|
+
background: rgba(255, 255, 255, 0.12);
|
|
3272
|
+
}
|
|
3273
|
+
|
|
3274
|
+
.neoface-forgot-btn-primary {
|
|
3275
|
+
width: 100%;
|
|
3276
|
+
padding: 14px 24px;
|
|
3277
|
+
border-radius: 12px;
|
|
3278
|
+
border: none;
|
|
3279
|
+
background: linear-gradient(135deg, #7c3aed 0%, #6d28d9 100%);
|
|
3280
|
+
color: white;
|
|
3281
|
+
font-size: 16px;
|
|
3282
|
+
font-weight: 600;
|
|
3283
|
+
cursor: pointer;
|
|
3284
|
+
transition: all 0.2s;
|
|
3285
|
+
box-shadow: 0 4px 16px rgba(124, 58, 237, 0.3);
|
|
3286
|
+
font-family: inherit;
|
|
3287
|
+
}
|
|
3288
|
+
|
|
3289
|
+
.neoface-forgot-btn-primary:hover:not(:disabled) {
|
|
3290
|
+
transform: translateY(-2px);
|
|
3291
|
+
box-shadow: 0 8px 24px rgba(124, 58, 237, 0.4);
|
|
3292
|
+
}
|
|
3293
|
+
|
|
3294
|
+
.neoface-forgot-btn-primary:disabled {
|
|
3295
|
+
opacity: 0.6;
|
|
3296
|
+
cursor: not-allowed;
|
|
3297
|
+
}
|
|
3298
|
+
|
|
3299
|
+
.neoface-forgot-btn-ghost {
|
|
3300
|
+
background: transparent;
|
|
3301
|
+
border: none;
|
|
3302
|
+
color: rgba(255, 255, 255, 0.5);
|
|
3303
|
+
font-size: 14px;
|
|
3304
|
+
font-weight: 500;
|
|
3305
|
+
cursor: pointer;
|
|
3306
|
+
padding: 10px 16px;
|
|
3307
|
+
border-radius: 8px;
|
|
3308
|
+
transition: all 0.2s;
|
|
3309
|
+
font-family: inherit;
|
|
3310
|
+
width: 100%;
|
|
3311
|
+
}
|
|
3312
|
+
|
|
3313
|
+
.neoface-forgot-btn-ghost:hover {
|
|
3314
|
+
color: white;
|
|
3315
|
+
background: rgba(255, 255, 255, 0.05);
|
|
3316
|
+
}
|
|
3317
|
+
|
|
3318
|
+
.neoface-forgot-branding {
|
|
3319
|
+
display: flex;
|
|
3320
|
+
align-items: center;
|
|
3321
|
+
justify-content: center;
|
|
3322
|
+
gap: 6px;
|
|
3323
|
+
margin-top: 20px;
|
|
3324
|
+
color: rgba(255, 255, 255, 0.3);
|
|
3325
|
+
font-size: 12px;
|
|
3326
|
+
}
|
|
3327
|
+
|
|
3328
|
+
.neoface-forgot-brand-logo {
|
|
3329
|
+
width: 18px;
|
|
3330
|
+
height: 18px;
|
|
3331
|
+
object-fit: contain;
|
|
3332
|
+
opacity: 0.5;
|
|
3333
|
+
}
|
|
3334
|
+
|
|
3335
|
+
.neoface-forgot-brand-name {
|
|
3336
|
+
font-weight: 700;
|
|
3337
|
+
letter-spacing: 0.05em;
|
|
3338
|
+
}
|
|
3339
|
+
|
|
3340
|
+
@media (max-width: 640px) {
|
|
3341
|
+
.neoface-forgot-content {
|
|
3342
|
+
padding: 24px;
|
|
3343
|
+
border-radius: 16px;
|
|
3344
|
+
}
|
|
3345
|
+
|
|
3346
|
+
.neoface-forgot-title {
|
|
3347
|
+
font-size: 20px;
|
|
3348
|
+
}
|
|
3349
|
+
}
|
|
3350
|
+
`;
|
|
3351
|
+
document.head.appendChild(style);
|
|
3352
|
+
}
|
|
3353
|
+
}
|
|
2860
3354
|
const modalReducer = (state, action) => {
|
|
2861
3355
|
switch (action.type) {
|
|
2862
3356
|
case "START_LIVENESS":
|
|
@@ -2891,10 +3385,10 @@ const modalReducer = (state, action) => {
|
|
|
2891
3385
|
return state;
|
|
2892
3386
|
case "CAMERA_LOADING":
|
|
2893
3387
|
return { status: "camera-loading" };
|
|
2894
|
-
case "START_PROCESSING":
|
|
2895
|
-
return { status: "processing" };
|
|
2896
3388
|
case "SUCCESS":
|
|
2897
3389
|
return { status: "success" };
|
|
3390
|
+
case "DUPLICATE":
|
|
3391
|
+
return { status: "duplicate", personName: action.personName };
|
|
2898
3392
|
case "ERROR":
|
|
2899
3393
|
return { status: "error", message: action.message, retryable: action.retryable ?? true };
|
|
2900
3394
|
case "RESET":
|
|
@@ -2934,7 +3428,16 @@ const CALIBRATION = {
|
|
|
2934
3428
|
YAW_LEFT_THRESHOLD: 15,
|
|
2935
3429
|
YAW_RIGHT_THRESHOLD: -15,
|
|
2936
3430
|
CAPTURE_HOLD_TIME: 1500,
|
|
2937
|
-
DETECTION_INTERVAL:
|
|
3431
|
+
DETECTION_INTERVAL: 150,
|
|
3432
|
+
// Um pouco mais rápido para melhor resposta
|
|
3433
|
+
MIN_FACE_WIDTH: 160,
|
|
3434
|
+
// Rosto deve ocupar boa parte do oval (era ~120 implícito)
|
|
3435
|
+
MAX_FACE_WIDTH: 280,
|
|
3436
|
+
// Evita rosto "colado" na câmera
|
|
3437
|
+
CENTER_X_THRESHOLD: 0.15,
|
|
3438
|
+
// Rosto deve estar centralizado (desvio max 15%)
|
|
3439
|
+
CENTER_Y_THRESHOLD: 0.2
|
|
3440
|
+
// Rosto deve estar centralizado verticalmente
|
|
2938
3441
|
};
|
|
2939
3442
|
function BiometricRegistrationModal({
|
|
2940
3443
|
personData,
|
|
@@ -2956,7 +3459,8 @@ function BiometricRegistrationModal({
|
|
|
2956
3459
|
const captureStateRef = useRef(null);
|
|
2957
3460
|
const [state, dispatch] = useReducer(modalReducer, initialState);
|
|
2958
3461
|
const [faceDetected, setFaceDetected] = useState(false);
|
|
2959
|
-
const [
|
|
3462
|
+
const [faceDistance, setFaceDistance] = useState("ok");
|
|
3463
|
+
const [cameraReady, setCameraReady] = useState(false);
|
|
2960
3464
|
useEffect(() => {
|
|
2961
3465
|
if (state.status === "liveness") {
|
|
2962
3466
|
const newStep = state.step;
|
|
@@ -3018,6 +3522,18 @@ function BiometricRegistrationModal({
|
|
|
3018
3522
|
return null;
|
|
3019
3523
|
}
|
|
3020
3524
|
};
|
|
3525
|
+
const checkFacePosition = (box, videoWidth, videoHeight) => {
|
|
3526
|
+
if (box.width < CALIBRATION.MIN_FACE_WIDTH) return "too-far";
|
|
3527
|
+
if (box.width > CALIBRATION.MAX_FACE_WIDTH) return "too-close";
|
|
3528
|
+
const faceCenterX = box.x + box.width / 2;
|
|
3529
|
+
const faceCenterY = box.y + box.height / 2;
|
|
3530
|
+
const deviationX = Math.abs(faceCenterX - videoWidth / 2) / videoWidth;
|
|
3531
|
+
const deviationY = Math.abs(faceCenterY - videoHeight / 2) / videoHeight;
|
|
3532
|
+
if (deviationX > CALIBRATION.CENTER_X_THRESHOLD || deviationY > CALIBRATION.CENTER_Y_THRESHOLD) {
|
|
3533
|
+
return "not-centered";
|
|
3534
|
+
}
|
|
3535
|
+
return "ok";
|
|
3536
|
+
};
|
|
3021
3537
|
const checkPositionMatch = (pitch, yaw, step) => {
|
|
3022
3538
|
switch (step) {
|
|
3023
3539
|
case "center":
|
|
@@ -3158,7 +3674,11 @@ function BiometricRegistrationModal({
|
|
|
3158
3674
|
}
|
|
3159
3675
|
video.srcObject = stream;
|
|
3160
3676
|
streamRef.current = stream;
|
|
3161
|
-
|
|
3677
|
+
video.onloadedmetadata = () => {
|
|
3678
|
+
video.play().then(() => {
|
|
3679
|
+
if (mounted) setCameraReady(true);
|
|
3680
|
+
});
|
|
3681
|
+
};
|
|
3162
3682
|
} catch (error) {
|
|
3163
3683
|
if (!mounted) return;
|
|
3164
3684
|
if (watchdogTimerRef.current) {
|
|
@@ -3228,14 +3748,17 @@ function BiometricRegistrationModal({
|
|
|
3228
3748
|
const hasFace = !!detection;
|
|
3229
3749
|
setFaceDetected(hasFace);
|
|
3230
3750
|
if (hasFace && detection.detection) {
|
|
3231
|
-
const
|
|
3232
|
-
const
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3751
|
+
const video2 = videoRef.current;
|
|
3752
|
+
const positionStatus = checkFacePosition(
|
|
3753
|
+
detection.detection.box,
|
|
3754
|
+
video2.videoWidth,
|
|
3755
|
+
video2.videoHeight
|
|
3756
|
+
);
|
|
3757
|
+
setFaceDistance(positionStatus);
|
|
3758
|
+
if (positionStatus !== "ok") {
|
|
3759
|
+
manageHoldAndCapture(false);
|
|
3760
|
+
requestAnimationFrame(detectFace2);
|
|
3761
|
+
return;
|
|
3239
3762
|
}
|
|
3240
3763
|
}
|
|
3241
3764
|
if (hasFace && detection.landmarks) {
|
|
@@ -3364,7 +3887,24 @@ function BiometricRegistrationModal({
|
|
|
3364
3887
|
);
|
|
3365
3888
|
};
|
|
3366
3889
|
const processRegistration = async (photos) => {
|
|
3890
|
+
var _a;
|
|
3367
3891
|
try {
|
|
3892
|
+
dispatch({ type: "START_PROCESSING" });
|
|
3893
|
+
if (applicationToken && photos.length > 0) {
|
|
3894
|
+
try {
|
|
3895
|
+
const { identifyPersonAsync: identifyPersonAsync2 } = await Promise.resolve().then(() => api);
|
|
3896
|
+
const result2 = await identifyPersonAsync2(photos[0], applicationToken);
|
|
3897
|
+
if (result2.personFound) {
|
|
3898
|
+
dispatch({
|
|
3899
|
+
type: "DUPLICATE",
|
|
3900
|
+
personName: ((_a = result2.person) == null ? void 0 : _a.name) || "Pessoa identificada"
|
|
3901
|
+
});
|
|
3902
|
+
return;
|
|
3903
|
+
}
|
|
3904
|
+
} catch (idError) {
|
|
3905
|
+
console.warn("Erro silencioso na identificação preventiva:", idError);
|
|
3906
|
+
}
|
|
3907
|
+
}
|
|
3368
3908
|
if (onPhotosCaptured) {
|
|
3369
3909
|
dispatch({ type: "SUCCESS" });
|
|
3370
3910
|
onPhotosCaptured(photos);
|
|
@@ -3400,12 +3940,26 @@ function BiometricRegistrationModal({
|
|
|
3400
3940
|
const stepProgress = state.stepProgress;
|
|
3401
3941
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "liveness-container", children: [
|
|
3402
3942
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "progress-indicator", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "progress-text", children: progress }) }),
|
|
3943
|
+
faceDetected && faceDistance !== "ok" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `face-badge ${faceDistance === "not-centered" ? "warning" : "error"}`, children: [
|
|
3944
|
+
faceDistance === "too-far" && "Aproxime-se mais",
|
|
3945
|
+
faceDistance === "too-close" && "Rosto muito perto",
|
|
3946
|
+
faceDistance === "not-centered" && "Centralize seu rosto"
|
|
3947
|
+
] }),
|
|
3403
3948
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "video-wrapper", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
3404
3949
|
"div",
|
|
3405
3950
|
{
|
|
3406
3951
|
className: `video-circle ${faceDetected ? "face-detected" : ""} ${stepProgress > 0 ? "capturing" : ""}`,
|
|
3407
3952
|
children: [
|
|
3408
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3953
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3954
|
+
"video",
|
|
3955
|
+
{
|
|
3956
|
+
ref: videoRef,
|
|
3957
|
+
className: `video-feed ${cameraReady ? "ready" : ""}`,
|
|
3958
|
+
autoPlay: true,
|
|
3959
|
+
muted: true,
|
|
3960
|
+
playsInline: true
|
|
3961
|
+
}
|
|
3962
|
+
),
|
|
3409
3963
|
faceDetected && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "face-badge", children: [
|
|
3410
3964
|
/* @__PURE__ */ jsxRuntimeExports.jsx("svg", { width: "16", height: "16", viewBox: "0 0 20 20", fill: "none", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3411
3965
|
"path",
|
|
@@ -3520,6 +4074,75 @@ function BiometricRegistrationModal({
|
|
|
3520
4074
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: onPhotosCaptured ? "Suas capturas faciais foram realizadas" : "Sua biometria foi registrada com sucesso" }),
|
|
3521
4075
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "primary-button", onClick: onClose, children: "Continuar" })
|
|
3522
4076
|
] });
|
|
4077
|
+
const renderDuplicate = () => {
|
|
4078
|
+
if (state.status !== "duplicate") return null;
|
|
4079
|
+
const greeting = state.personName && state.personName !== "Pessoa identificada" ? `Olá, ${state.personName.split(" ")[0]}!` : "Olá!";
|
|
4080
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "result-container duplicate scale-in", children: [
|
|
4081
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { style: { marginTop: "0px" }, children: greeting }),
|
|
4082
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: { marginBottom: "32px", fontSize: "15px" }, children: "Identificamos seu cadastro biométrico em nossa rede. Você já faz parte da NeoFaceId!" }),
|
|
4083
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "button-group-vertical", children: [
|
|
4084
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4085
|
+
"button",
|
|
4086
|
+
{
|
|
4087
|
+
className: "primary-button",
|
|
4088
|
+
onClick: () => {
|
|
4089
|
+
onClose();
|
|
4090
|
+
window.location.href = "/";
|
|
4091
|
+
},
|
|
4092
|
+
children: "Ir para o Login"
|
|
4093
|
+
}
|
|
4094
|
+
),
|
|
4095
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4096
|
+
"button",
|
|
4097
|
+
{
|
|
4098
|
+
className: "secondary-button",
|
|
4099
|
+
style: { marginTop: "12px" },
|
|
4100
|
+
onClick: () => {
|
|
4101
|
+
onClose();
|
|
4102
|
+
new ForgotPasswordModal(applicationToken ?? "").open();
|
|
4103
|
+
},
|
|
4104
|
+
children: "Esqueci minha senha"
|
|
4105
|
+
}
|
|
4106
|
+
),
|
|
4107
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "support-section", children: [
|
|
4108
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "Não reconhece esta conta?" }),
|
|
4109
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4110
|
+
"button",
|
|
4111
|
+
{
|
|
4112
|
+
className: "ghost-button",
|
|
4113
|
+
onClick: () => window.open("https://support.neofaceid.com", "_blank"),
|
|
4114
|
+
children: "Falar com Suporte"
|
|
4115
|
+
}
|
|
4116
|
+
)
|
|
4117
|
+
] })
|
|
4118
|
+
] }),
|
|
4119
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
4120
|
+
"div",
|
|
4121
|
+
{
|
|
4122
|
+
className: "branding",
|
|
4123
|
+
style: {
|
|
4124
|
+
marginTop: "32px",
|
|
4125
|
+
paddingTop: "20px",
|
|
4126
|
+
borderTop: "1px solid rgba(255, 255, 255, 0.08)",
|
|
4127
|
+
width: "100%"
|
|
4128
|
+
},
|
|
4129
|
+
children: [
|
|
4130
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4131
|
+
"img",
|
|
4132
|
+
{
|
|
4133
|
+
src: "/logo-icone.png",
|
|
4134
|
+
alt: "NeoFaceId",
|
|
4135
|
+
className: "brand-logo",
|
|
4136
|
+
style: { height: "18px" }
|
|
4137
|
+
}
|
|
4138
|
+
),
|
|
4139
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "NeoFaceId by" }),
|
|
4140
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "brand-name", children: "OCTA" })
|
|
4141
|
+
]
|
|
4142
|
+
}
|
|
4143
|
+
)
|
|
4144
|
+
] });
|
|
4145
|
+
};
|
|
3523
4146
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
3524
4147
|
/* @__PURE__ */ jsxRuntimeExports.jsx("style", { children: `
|
|
3525
4148
|
@keyframes fadeIn {
|
|
@@ -3807,8 +4430,9 @@ function BiometricRegistrationModal({
|
|
|
3807
4430
|
border-radius: 50%;
|
|
3808
4431
|
overflow: hidden;
|
|
3809
4432
|
position: relative;
|
|
3810
|
-
|
|
4433
|
+
/* Removida transição 'all' para evitar salto de zoom no início */
|
|
3811
4434
|
box-shadow: 0 0 0 4px rgba(124, 58, 237, 0.3);
|
|
4435
|
+
background: #000;
|
|
3812
4436
|
}
|
|
3813
4437
|
|
|
3814
4438
|
.video-circle.face-detected {
|
|
@@ -3825,6 +4449,12 @@ function BiometricRegistrationModal({
|
|
|
3825
4449
|
height: 100%;
|
|
3826
4450
|
object-fit: cover;
|
|
3827
4451
|
transform: scaleX(-1);
|
|
4452
|
+
opacity: 0;
|
|
4453
|
+
transition: opacity 0.4s ease;
|
|
4454
|
+
}
|
|
4455
|
+
|
|
4456
|
+
.video-feed.ready {
|
|
4457
|
+
opacity: 1;
|
|
3828
4458
|
}
|
|
3829
4459
|
|
|
3830
4460
|
.face-badge {
|
|
@@ -4049,6 +4679,61 @@ function BiometricRegistrationModal({
|
|
|
4049
4679
|
background: rgba(255, 255, 255, 0.05);
|
|
4050
4680
|
}
|
|
4051
4681
|
|
|
4682
|
+
/* Duplicate Screen Styles */
|
|
4683
|
+
.profile-icon-wrapper {
|
|
4684
|
+
position: relative;
|
|
4685
|
+
display: inline-block;
|
|
4686
|
+
margin-bottom: 24px;
|
|
4687
|
+
}
|
|
4688
|
+
|
|
4689
|
+
.profile-main-icon {
|
|
4690
|
+
background: rgba(124, 58, 237, 0.1);
|
|
4691
|
+
color: #7c3aed;
|
|
4692
|
+
padding: 20px;
|
|
4693
|
+
border-radius: 50%;
|
|
4694
|
+
border: 2px solid rgba(124, 58, 237, 0.2);
|
|
4695
|
+
box-shadow: 0 0 30px rgba(124, 58, 237, 0.2);
|
|
4696
|
+
}
|
|
4697
|
+
|
|
4698
|
+
.profile-main-icon svg {
|
|
4699
|
+
width: 48px;
|
|
4700
|
+
height: 48px;
|
|
4701
|
+
}
|
|
4702
|
+
|
|
4703
|
+
.verified-badge {
|
|
4704
|
+
position: absolute;
|
|
4705
|
+
bottom: -4px;
|
|
4706
|
+
right: -4px;
|
|
4707
|
+
background: #10b981;
|
|
4708
|
+
border-radius: 50%;
|
|
4709
|
+
padding: 4px;
|
|
4710
|
+
border: 3px solid #16213e;
|
|
4711
|
+
width: 24px;
|
|
4712
|
+
height: 24px;
|
|
4713
|
+
display: flex;
|
|
4714
|
+
align-items: center;
|
|
4715
|
+
justify-content: center;
|
|
4716
|
+
}
|
|
4717
|
+
|
|
4718
|
+
.button-group-vertical {
|
|
4719
|
+
display: flex;
|
|
4720
|
+
flex-direction: column;
|
|
4721
|
+
width: 100%;
|
|
4722
|
+
gap: 8px;
|
|
4723
|
+
}
|
|
4724
|
+
|
|
4725
|
+
.support-section {
|
|
4726
|
+
margin-top: 24px;
|
|
4727
|
+
padding-top: 16px;
|
|
4728
|
+
border-top: 1px solid rgba(255, 255, 255, 0.05);
|
|
4729
|
+
}
|
|
4730
|
+
|
|
4731
|
+
.support-section p {
|
|
4732
|
+
font-size: 13px;
|
|
4733
|
+
color: rgba(255, 255, 255, 0.4);
|
|
4734
|
+
margin-bottom: 8px;
|
|
4735
|
+
}
|
|
4736
|
+
|
|
4052
4737
|
/* Canvas */
|
|
4053
4738
|
canvas {
|
|
4054
4739
|
display: none;
|
|
@@ -4086,7 +4771,8 @@ function BiometricRegistrationModal({
|
|
|
4086
4771
|
state.status === "camera-loading" && renderCameraLoading(),
|
|
4087
4772
|
state.status === "processing" && renderProcessing(),
|
|
4088
4773
|
state.status === "error" && renderError(),
|
|
4089
|
-
state.status === "success" && renderSuccess()
|
|
4774
|
+
state.status === "success" && renderSuccess(),
|
|
4775
|
+
state.status === "duplicate" && renderDuplicate()
|
|
4090
4776
|
] }) }),
|
|
4091
4777
|
/* @__PURE__ */ jsxRuntimeExports.jsx("canvas", { ref: canvasRef })
|
|
4092
4778
|
] });
|
|
@@ -4674,6 +5360,7 @@ class BiometricStatusOverlay {
|
|
|
4674
5360
|
/* Cores por estado */
|
|
4675
5361
|
.neofaceid-state-preparing .neofaceid-logo { filter: drop-shadow(0 0 15px rgba(124, 58, 237, 0.4)); }
|
|
4676
5362
|
.neofaceid-state-detecting .neofaceid-logo { filter: hue-rotate(180deg) drop-shadow(0 0 15px rgba(59, 130, 246, 0.6)); }
|
|
5363
|
+
.neofaceid-state-waiting-for-face .neofaceid-logo { filter: hue-rotate(30deg) drop-shadow(0 0 15px rgba(251, 146, 60, 0.6)); }
|
|
4677
5364
|
.neofaceid-state-capturing .neofaceid-logo { filter: hue-rotate(45deg) drop-shadow(0 0 15px rgba(245, 158, 11, 0.6)); }
|
|
4678
5365
|
.neofaceid-state-verifying .neofaceid-logo { filter: hue-rotate(90deg) drop-shadow(0 0 15px rgba(34, 197, 94, 0.6)); }
|
|
4679
5366
|
|
|
@@ -4747,6 +5434,8 @@ class BiometricStatusOverlay {
|
|
|
4747
5434
|
return "Iniciando câmera";
|
|
4748
5435
|
case "detecting":
|
|
4749
5436
|
return "Posicione seu rosto";
|
|
5437
|
+
case "waiting-for-face":
|
|
5438
|
+
return "Aguardando rosto";
|
|
4750
5439
|
case "capturing":
|
|
4751
5440
|
return "Capturando";
|
|
4752
5441
|
case "verifying":
|
|
@@ -4760,12 +5449,18 @@ class BiometricStatusOverlay {
|
|
|
4760
5449
|
}
|
|
4761
5450
|
}
|
|
4762
5451
|
renderContent() {
|
|
4763
|
-
const isPulsing = ["detecting", "verifying"].includes(this.currentStatus);
|
|
5452
|
+
const isPulsing = ["detecting", "waiting-for-face", "verifying"].includes(this.currentStatus);
|
|
4764
5453
|
const showLogo = !["success", "error"].includes(this.currentStatus);
|
|
4765
5454
|
const showSuccess = this.currentStatus === "success";
|
|
4766
5455
|
const showError = this.currentStatus === "error";
|
|
4767
5456
|
const statusText = this.getStatusText();
|
|
4768
|
-
const showDots = [
|
|
5457
|
+
const showDots = [
|
|
5458
|
+
"preparing",
|
|
5459
|
+
"detecting",
|
|
5460
|
+
"waiting-for-face",
|
|
5461
|
+
"capturing",
|
|
5462
|
+
"verifying"
|
|
5463
|
+
].includes(this.currentStatus);
|
|
4769
5464
|
return `
|
|
4770
5465
|
<style>${this.getStyles()}</style>
|
|
4771
5466
|
<div class="neofaceid-overlay-container neofaceid-state-${this.currentStatus}">
|
|
@@ -4850,8 +5545,13 @@ function FallbackPromptComponent({
|
|
|
4850
5545
|
error,
|
|
4851
5546
|
onRetry,
|
|
4852
5547
|
onCredentials,
|
|
4853
|
-
onCancel
|
|
5548
|
+
onCancel,
|
|
5549
|
+
applicationToken
|
|
4854
5550
|
}) {
|
|
5551
|
+
const handleForgotPassword = () => {
|
|
5552
|
+
const modal = new ForgotPasswordModal(applicationToken);
|
|
5553
|
+
modal.open();
|
|
5554
|
+
};
|
|
4855
5555
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4856
5556
|
/* @__PURE__ */ jsxRuntimeExports.jsx("style", { children: `
|
|
4857
5557
|
@keyframes slideUp {
|
|
@@ -5029,6 +5729,15 @@ function FallbackPromptComponent({
|
|
|
5029
5729
|
children: "Entrar com Email e Senha"
|
|
5030
5730
|
}
|
|
5031
5731
|
),
|
|
5732
|
+
applicationToken && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5733
|
+
"button",
|
|
5734
|
+
{
|
|
5735
|
+
type: "button",
|
|
5736
|
+
className: "neofaceid-fallback-button neofaceid-fallback-button-ghost",
|
|
5737
|
+
onClick: handleForgotPassword,
|
|
5738
|
+
children: "Esqueceu sua senha?"
|
|
5739
|
+
}
|
|
5740
|
+
),
|
|
5032
5741
|
onCancel && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5033
5742
|
"button",
|
|
5034
5743
|
{
|
|
@@ -5050,7 +5759,7 @@ class FallbackPrompt {
|
|
|
5050
5759
|
/**
|
|
5051
5760
|
* Exibe o prompt de fallback
|
|
5052
5761
|
*/
|
|
5053
|
-
show(error, onRetry, onCredentials, onCancel) {
|
|
5762
|
+
show(error, onRetry, onCredentials, onCancel, applicationToken) {
|
|
5054
5763
|
if (this.container) {
|
|
5055
5764
|
return;
|
|
5056
5765
|
}
|
|
@@ -5058,7 +5767,7 @@ class FallbackPrompt {
|
|
|
5058
5767
|
this.container.id = "neofaceid-fallback-prompt";
|
|
5059
5768
|
document.body.appendChild(this.container);
|
|
5060
5769
|
this.root = clientExports.createRoot(this.container);
|
|
5061
|
-
this.render(error, onRetry, onCredentials, onCancel);
|
|
5770
|
+
this.render(error, onRetry, onCredentials, onCancel, applicationToken);
|
|
5062
5771
|
}
|
|
5063
5772
|
/**
|
|
5064
5773
|
* Fecha o prompt
|
|
@@ -5076,7 +5785,7 @@ class FallbackPrompt {
|
|
|
5076
5785
|
/**
|
|
5077
5786
|
* Renderiza o componente
|
|
5078
5787
|
*/
|
|
5079
|
-
render(error, onRetry, onCredentials, onCancel) {
|
|
5788
|
+
render(error, onRetry, onCredentials, onCancel, applicationToken) {
|
|
5080
5789
|
if (!this.root || !this.container) return;
|
|
5081
5790
|
this.root.render(
|
|
5082
5791
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -5091,6 +5800,7 @@ class FallbackPrompt {
|
|
|
5091
5800
|
this.close();
|
|
5092
5801
|
onCredentials();
|
|
5093
5802
|
},
|
|
5803
|
+
applicationToken: applicationToken ?? "",
|
|
5094
5804
|
onCancel: () => {
|
|
5095
5805
|
this.close();
|
|
5096
5806
|
onCancel == null ? void 0 : onCancel();
|
|
@@ -5565,12 +6275,14 @@ async function captureFaceSilently() {
|
|
|
5565
6275
|
});
|
|
5566
6276
|
});
|
|
5567
6277
|
}
|
|
5568
|
-
async function detectFaceQuickly(video, maxTime = FACE_DETECTION_TIME, interval = DETECTION_INTERVAL) {
|
|
6278
|
+
async function detectFaceQuickly(video, maxTime = FACE_DETECTION_TIME, interval = DETECTION_INTERVAL, overlay) {
|
|
5569
6279
|
return new Promise((resolve) => {
|
|
5570
6280
|
let attempts = 0;
|
|
5571
6281
|
const maxAttempts = Math.ceil(maxTime / interval);
|
|
5572
6282
|
let timeoutId = null;
|
|
5573
6283
|
let isResolved = false;
|
|
6284
|
+
let overlayShowingWaiting = false;
|
|
6285
|
+
const ATTEMPTS_BEFORE_WAITING = Math.ceil(3e3 / interval);
|
|
5574
6286
|
const finish = (success) => {
|
|
5575
6287
|
if (isResolved) return;
|
|
5576
6288
|
isResolved = true;
|
|
@@ -5581,7 +6293,16 @@ async function detectFaceQuickly(video, maxTime = FACE_DETECTION_TIME, interval
|
|
|
5581
6293
|
if (isResolved) return;
|
|
5582
6294
|
attempts++;
|
|
5583
6295
|
if (!modelsLoaded) {
|
|
5584
|
-
|
|
6296
|
+
if (overlay && !overlayShowingWaiting && attempts >= ATTEMPTS_BEFORE_WAITING) {
|
|
6297
|
+
overlay.updateStatus("waiting-for-face");
|
|
6298
|
+
overlayShowingWaiting = true;
|
|
6299
|
+
console.log("⏳ Models not loaded - waiting for face...");
|
|
6300
|
+
}
|
|
6301
|
+
if (attempts >= maxAttempts) {
|
|
6302
|
+
finish(false);
|
|
6303
|
+
return;
|
|
6304
|
+
}
|
|
6305
|
+
timeoutId = window.setTimeout(checkFace, interval);
|
|
5585
6306
|
return;
|
|
5586
6307
|
}
|
|
5587
6308
|
try {
|
|
@@ -5590,21 +6311,43 @@ async function detectFaceQuickly(video, maxTime = FACE_DETECTION_TIME, interval
|
|
|
5590
6311
|
new faceapi.TinyFaceDetectorOptions({ inputSize: 160, scoreThreshold: 0.3 })
|
|
5591
6312
|
);
|
|
5592
6313
|
if (detection) {
|
|
6314
|
+
if (overlay && overlayShowingWaiting) {
|
|
6315
|
+
overlay.updateStatus("detecting");
|
|
6316
|
+
overlayShowingWaiting = false;
|
|
6317
|
+
console.log("👤 Face appeared");
|
|
6318
|
+
}
|
|
6319
|
+
console.log("✅ Face detected!");
|
|
5593
6320
|
finish(true);
|
|
5594
6321
|
return;
|
|
5595
6322
|
}
|
|
6323
|
+
if (overlay && !overlayShowingWaiting && attempts >= ATTEMPTS_BEFORE_WAITING) {
|
|
6324
|
+
overlay.updateStatus("waiting-for-face");
|
|
6325
|
+
overlayShowingWaiting = true;
|
|
6326
|
+
console.log("⏳ Waiting for face...");
|
|
6327
|
+
}
|
|
5596
6328
|
if (attempts >= maxAttempts) {
|
|
6329
|
+
console.warn("⏱️ Face detection timeout - no face found");
|
|
5597
6330
|
finish(false);
|
|
5598
6331
|
return;
|
|
5599
6332
|
}
|
|
5600
6333
|
timeoutId = window.setTimeout(checkFace, interval);
|
|
5601
6334
|
} catch (error) {
|
|
5602
|
-
|
|
6335
|
+
console.error("❌ Face detection error:", error);
|
|
6336
|
+
if (overlay && !overlayShowingWaiting && attempts >= ATTEMPTS_BEFORE_WAITING) {
|
|
6337
|
+
overlay.updateStatus("waiting-for-face");
|
|
6338
|
+
overlayShowingWaiting = true;
|
|
6339
|
+
}
|
|
6340
|
+
if (attempts >= maxAttempts) {
|
|
6341
|
+
finish(false);
|
|
6342
|
+
return;
|
|
6343
|
+
}
|
|
6344
|
+
timeoutId = window.setTimeout(checkFace, interval);
|
|
5603
6345
|
}
|
|
5604
6346
|
};
|
|
5605
6347
|
window.setTimeout(() => {
|
|
5606
6348
|
if (!isResolved) {
|
|
5607
|
-
|
|
6349
|
+
console.warn("⏱️ Face detection safety timeout reached");
|
|
6350
|
+
finish(false);
|
|
5608
6351
|
}
|
|
5609
6352
|
}, maxTime + 500);
|
|
5610
6353
|
checkFace();
|
|
@@ -5678,7 +6421,12 @@ async function attemptLogin(applicationToken, overlay, fastMode = false, isRetry
|
|
|
5678
6421
|
await new Promise((resolve) => setTimeout(resolve, CAMERA_STABILITY_DELAY));
|
|
5679
6422
|
let faceDetected = true;
|
|
5680
6423
|
if (!fastMode) {
|
|
5681
|
-
faceDetected = await detectFaceQuickly(
|
|
6424
|
+
faceDetected = await detectFaceQuickly(
|
|
6425
|
+
video,
|
|
6426
|
+
FACE_DETECTION_TIME,
|
|
6427
|
+
DETECTION_INTERVAL,
|
|
6428
|
+
overlay
|
|
6429
|
+
);
|
|
5682
6430
|
}
|
|
5683
6431
|
if (!faceDetected) {
|
|
5684
6432
|
if (stream) {
|
|
@@ -5688,7 +6436,7 @@ async function attemptLogin(applicationToken, overlay, fastMode = false, isRetry
|
|
|
5688
6436
|
video.parentElement.removeChild(video);
|
|
5689
6437
|
}
|
|
5690
6438
|
throw new NeoFaceError(
|
|
5691
|
-
"
|
|
6439
|
+
"Nenhum rosto detectado. Por favor, posicione seu rosto na frente da câmera e tente novamente.",
|
|
5692
6440
|
ErrorType.VALIDATION_ERROR
|
|
5693
6441
|
);
|
|
5694
6442
|
}
|
|
@@ -5808,7 +6556,8 @@ async function executeBiometricLoginFlow(options) {
|
|
|
5808
6556
|
);
|
|
5809
6557
|
}
|
|
5810
6558
|
},
|
|
5811
|
-
onCancel
|
|
6559
|
+
onCancel,
|
|
6560
|
+
applicationToken
|
|
5812
6561
|
);
|
|
5813
6562
|
}, 500);
|
|
5814
6563
|
}
|
|
@@ -6136,8 +6885,8 @@ const biometricDetection = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.
|
|
|
6136
6885
|
initializeBiometricDetection,
|
|
6137
6886
|
isAdvancedDetectionAvailable
|
|
6138
6887
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
6139
|
-
const VERSION = "1.
|
|
6140
|
-
const RELEASE_DATE = "2026-03-
|
|
6888
|
+
const VERSION = "1.19.0";
|
|
6889
|
+
const RELEASE_DATE = "2026-03-13";
|
|
6141
6890
|
class OnboardingCaptureModal {
|
|
6142
6891
|
constructor(options) {
|
|
6143
6892
|
__publicField(this, "overlay", null);
|
|
@@ -6822,11 +7571,11 @@ const authorizeOperation = async (applicationToken, cpf, options) => {
|
|
|
6822
7571
|
};
|
|
6823
7572
|
const DOCUMENT_INFO = {
|
|
6824
7573
|
RG: {
|
|
6825
|
-
name: "RG /
|
|
7574
|
+
name: "Documento de Identidade (RG / CIN / CPF)",
|
|
6826
7575
|
icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="4" width="18" height="16" rx="2"/><circle cx="9" cy="10" r="2"/><path d="M15 8h2M15 12h2M7 16h10"/></svg>',
|
|
6827
7576
|
hasBack: true,
|
|
6828
|
-
frontLabel: "Frente do
|
|
6829
|
-
backLabel: "Verso do
|
|
7577
|
+
frontLabel: "Frente do Documento",
|
|
7578
|
+
backLabel: "Verso do Documento"
|
|
6830
7579
|
},
|
|
6831
7580
|
CNH: {
|
|
6832
7581
|
name: "CNH / Carteira de Motorista",
|
|
@@ -6836,7 +7585,7 @@ const DOCUMENT_INFO = {
|
|
|
6836
7585
|
backLabel: "Verso da CNH"
|
|
6837
7586
|
},
|
|
6838
7587
|
CPF: {
|
|
6839
|
-
name: "CPF",
|
|
7588
|
+
name: "Cartão CPF (Apenas Frente)",
|
|
6840
7589
|
icon: '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6M16 13H8M16 17H8M10 9H8"/></svg>',
|
|
6841
7590
|
hasBack: false,
|
|
6842
7591
|
frontLabel: "Cartão CPF"
|
|
@@ -6930,7 +7679,7 @@ class DocumentCaptureModal {
|
|
|
6930
7679
|
|
|
6931
7680
|
<div class="neoface-doc-body">
|
|
6932
7681
|
<div class="neoface-doc-select-grid">
|
|
6933
|
-
${Object.entries(DOCUMENT_INFO).map(([type, info]) => `
|
|
7682
|
+
${Object.entries(DOCUMENT_INFO).filter(([type]) => type !== "CPF").map(([type, info]) => `
|
|
6934
7683
|
<button class="neoface-doc-select-option" data-type="${type}">
|
|
6935
7684
|
<span class="neoface-doc-select-icon">${info.icon}</span>
|
|
6936
7685
|
<span class="neoface-doc-select-name">${info.name}</span>
|
|
@@ -7936,6 +8685,7 @@ export {
|
|
|
7936
8685
|
ErrorType,
|
|
7937
8686
|
FaceCaptureModal,
|
|
7938
8687
|
FallbackPrompt,
|
|
8688
|
+
ForgotPasswordModal,
|
|
7939
8689
|
NeoFaceError,
|
|
7940
8690
|
NeoFaceID,
|
|
7941
8691
|
RELEASE_DATE,
|
|
@@ -7943,14 +8693,17 @@ export {
|
|
|
7943
8693
|
authorizeOperation,
|
|
7944
8694
|
biometricLogin,
|
|
7945
8695
|
biometricLoginWithFallback,
|
|
8696
|
+
checkUserExistence,
|
|
7946
8697
|
completeOnboarding,
|
|
7947
8698
|
completeOnboardingWithData,
|
|
8699
|
+
confirmPasswordReset,
|
|
7948
8700
|
detectBiometricType,
|
|
7949
8701
|
getApplicationToken,
|
|
7950
8702
|
getBaseUrl,
|
|
7951
8703
|
getConfig,
|
|
7952
8704
|
getEnvironment,
|
|
7953
8705
|
identifyPerson,
|
|
8706
|
+
identifyPersonAsync,
|
|
7954
8707
|
init,
|
|
7955
8708
|
initializeBiometricDetection,
|
|
7956
8709
|
isAdvancedDetectionAvailable,
|
|
@@ -7964,6 +8717,7 @@ export {
|
|
|
7964
8717
|
registerBiometric,
|
|
7965
8718
|
registerPersonWithBiometric,
|
|
7966
8719
|
registerPersonWithoutFace,
|
|
8720
|
+
requestPasswordReset,
|
|
7967
8721
|
simpleIdentification,
|
|
7968
8722
|
start,
|
|
7969
8723
|
startAutoLogin,
|