@neofaceid/web-sdk 1.15.0 → 1.17.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,
|
|
@@ -1652,110 +1653,6 @@ const loginWithBiometric = async (image, applicationToken) => {
|
|
|
1652
1653
|
throw new NeoFaceError("Unknown error occurred", ErrorType.NETWORK_ERROR);
|
|
1653
1654
|
}
|
|
1654
1655
|
};
|
|
1655
|
-
const loginWithBiometricSSE = async (image, applicationToken) => {
|
|
1656
|
-
var _a;
|
|
1657
|
-
ensureSecureContext();
|
|
1658
|
-
const compressedImage = await compressImage(image);
|
|
1659
|
-
const arrayBuffer = await compressedImage.arrayBuffer();
|
|
1660
|
-
const base64Image = btoa(
|
|
1661
|
-
new Uint8Array(arrayBuffer).reduce((data, byte) => data + String.fromCharCode(byte), "")
|
|
1662
|
-
);
|
|
1663
|
-
const controller = createTimeoutController();
|
|
1664
|
-
let response;
|
|
1665
|
-
try {
|
|
1666
|
-
response = await fetch(`${getApiBaseUrl()}/api/v1/auth/recognition/face/external/`, {
|
|
1667
|
-
method: "POST",
|
|
1668
|
-
headers: {
|
|
1669
|
-
"Content-Type": "application/json",
|
|
1670
|
-
"X-App-Token": applicationToken
|
|
1671
|
-
},
|
|
1672
|
-
body: JSON.stringify({ image: base64Image, purpose: "LOGIN" }),
|
|
1673
|
-
signal: controller.signal
|
|
1674
|
-
});
|
|
1675
|
-
} catch (error) {
|
|
1676
|
-
if (error instanceof Error) {
|
|
1677
|
-
if (error.name === "AbortError") {
|
|
1678
|
-
throw new NeoFaceError("Request timed out", ErrorType.NETWORK);
|
|
1679
|
-
}
|
|
1680
|
-
if (error instanceof NeoFaceError) throw error;
|
|
1681
|
-
throw new NeoFaceError(error.message, ErrorType.NETWORK);
|
|
1682
|
-
}
|
|
1683
|
-
throw new NeoFaceError("Unknown error occurred", ErrorType.NETWORK_ERROR);
|
|
1684
|
-
}
|
|
1685
|
-
if (!response.ok) {
|
|
1686
|
-
if (response.status === 401 || response.status === 403) {
|
|
1687
|
-
throw new NeoFaceError("Invalid application token", ErrorType.INVALID_TOKEN);
|
|
1688
|
-
}
|
|
1689
|
-
throw new NeoFaceError(`API Error ${response.status}`, ErrorType.API_ERROR);
|
|
1690
|
-
}
|
|
1691
|
-
const initData = await response.json();
|
|
1692
|
-
if (!initData.success || !((_a = initData.data) == null ? void 0 : _a.task_id)) {
|
|
1693
|
-
throw new NeoFaceError(initData.message || "Failed to start login", ErrorType.LOGIN_FAILED);
|
|
1694
|
-
}
|
|
1695
|
-
const taskId = initData.data.task_id;
|
|
1696
|
-
return new Promise((resolve, reject) => {
|
|
1697
|
-
const sseUrl = `${getApiBaseUrl()}/api/v1/auth/recognition/face/external/login/events/${taskId}/`;
|
|
1698
|
-
const eventSource = new EventSource(sseUrl);
|
|
1699
|
-
const timeoutId = setTimeout(() => {
|
|
1700
|
-
eventSource.close();
|
|
1701
|
-
reject(new NeoFaceError("Login timeout", ErrorType.NETWORK));
|
|
1702
|
-
}, 31e4);
|
|
1703
|
-
const cleanup = () => {
|
|
1704
|
-
clearTimeout(timeoutId);
|
|
1705
|
-
eventSource.close();
|
|
1706
|
-
};
|
|
1707
|
-
eventSource.addEventListener("success", (event) => {
|
|
1708
|
-
var _a2, _b, _c, _d, _e, _f;
|
|
1709
|
-
cleanup();
|
|
1710
|
-
try {
|
|
1711
|
-
const data = JSON.parse(event.data);
|
|
1712
|
-
resolve({
|
|
1713
|
-
success: true,
|
|
1714
|
-
accessToken: data.token || data.access_token || "",
|
|
1715
|
-
alias: ((_a2 = data.user) == null ? void 0 : _a2.alias) || data.alias || "",
|
|
1716
|
-
user: {
|
|
1717
|
-
id: ((_b = data.user) == null ? void 0 : _b.id) || "",
|
|
1718
|
-
email: ((_c = data.user) == null ? void 0 : _c.email) || "",
|
|
1719
|
-
role: ((_d = data.user) == null ? void 0 : _d.role) || "",
|
|
1720
|
-
validated: ((_e = data.user) == null ? void 0 : _e.validated) ?? false,
|
|
1721
|
-
active: ((_f = data.user) == null ? void 0 : _f.active) ?? false
|
|
1722
|
-
},
|
|
1723
|
-
person: data.person ? { name: data.person.name || "", birth_date: data.person.birth_date || "" } : void 0,
|
|
1724
|
-
confidence_score: data.confidence_score,
|
|
1725
|
-
recognition_id: data.recognition_id ?? data.history_id
|
|
1726
|
-
});
|
|
1727
|
-
} catch {
|
|
1728
|
-
reject(new NeoFaceError("Erro ao processar resposta de login", ErrorType.API_ERROR));
|
|
1729
|
-
}
|
|
1730
|
-
});
|
|
1731
|
-
eventSource.addEventListener("failed", (event) => {
|
|
1732
|
-
cleanup();
|
|
1733
|
-
try {
|
|
1734
|
-
const data = JSON.parse(event.data);
|
|
1735
|
-
reject(new NeoFaceError(data.message || "Login failed", ErrorType.LOGIN_FAILED));
|
|
1736
|
-
} catch {
|
|
1737
|
-
reject(new NeoFaceError("Login failed", ErrorType.LOGIN_FAILED));
|
|
1738
|
-
}
|
|
1739
|
-
});
|
|
1740
|
-
eventSource.addEventListener("error", (event) => {
|
|
1741
|
-
cleanup();
|
|
1742
|
-
try {
|
|
1743
|
-
const data = JSON.parse(event.data || "{}");
|
|
1744
|
-
reject(new NeoFaceError(data.message || "Processing error", ErrorType.API_ERROR));
|
|
1745
|
-
} catch {
|
|
1746
|
-
reject(new NeoFaceError("Processing error", ErrorType.API_ERROR));
|
|
1747
|
-
}
|
|
1748
|
-
});
|
|
1749
|
-
eventSource.addEventListener("timeout", () => {
|
|
1750
|
-
cleanup();
|
|
1751
|
-
reject(new NeoFaceError("Login timeout", ErrorType.NETWORK));
|
|
1752
|
-
});
|
|
1753
|
-
eventSource.onerror = () => {
|
|
1754
|
-
cleanup();
|
|
1755
|
-
reject(new NeoFaceError("SSE connection error", ErrorType.NETWORK));
|
|
1756
|
-
};
|
|
1757
|
-
});
|
|
1758
|
-
};
|
|
1759
1656
|
const recognizeBiometric = async (image, applicationToken, livenessCheck = true, confidenceThreshold = 0.8) => {
|
|
1760
1657
|
ensureSecureContext();
|
|
1761
1658
|
const controller = createTimeoutController();
|
|
@@ -1942,7 +1839,8 @@ const registerPersonWithoutFace = async (personData, applicationToken, options)
|
|
|
1942
1839
|
cpf: personData.cpf,
|
|
1943
1840
|
email: personData.email,
|
|
1944
1841
|
password: personData.password,
|
|
1945
|
-
password_confirm: personData.password
|
|
1842
|
+
password_confirm: personData.password,
|
|
1843
|
+
is_pep: personData.is_pep ?? false
|
|
1946
1844
|
};
|
|
1947
1845
|
if (documentFrontBase64) {
|
|
1948
1846
|
body.document_images = [
|
|
@@ -1983,6 +1881,43 @@ const registerPersonWithoutFace = async (personData, applicationToken, options)
|
|
|
1983
1881
|
throw new NeoFaceError("Unknown error occurred", ErrorType.NETWORK);
|
|
1984
1882
|
}
|
|
1985
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
|
+
};
|
|
1986
1921
|
const registerPersonWithBiometric = async (personData, facePhotos, applicationToken, options) => {
|
|
1987
1922
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
1988
1923
|
ensureSecureContext();
|
|
@@ -2038,7 +1973,8 @@ const registerPersonWithBiometric = async (personData, facePhotos, applicationTo
|
|
|
2038
1973
|
email: personData.email,
|
|
2039
1974
|
password: personData.password,
|
|
2040
1975
|
password_confirm: personData.password,
|
|
2041
|
-
face_photos: facePhotosBase64
|
|
1976
|
+
face_photos: facePhotosBase64,
|
|
1977
|
+
is_pep: personData.is_pep ?? false
|
|
2042
1978
|
};
|
|
2043
1979
|
if (documentFrontBase64) {
|
|
2044
1980
|
body.document_images = [
|
|
@@ -2132,7 +2068,6 @@ const registerPersonWithBiometric = async (personData, facePhotos, applicationTo
|
|
|
2132
2068
|
}
|
|
2133
2069
|
};
|
|
2134
2070
|
const loginWithEmail = async (email, password, applicationToken) => {
|
|
2135
|
-
ensureSecureContext();
|
|
2136
2071
|
const controller = createTimeoutController();
|
|
2137
2072
|
try {
|
|
2138
2073
|
const response = await fetch(`${getApiBaseUrl()}/api/v1/auth/login/`, {
|
|
@@ -2178,10 +2113,10 @@ const loginWithEmail = async (email, password, applicationToken) => {
|
|
|
2178
2113
|
}
|
|
2179
2114
|
};
|
|
2180
2115
|
const identifyPerson = async (image, applicationToken) => {
|
|
2181
|
-
var _a, _b;
|
|
2116
|
+
var _a, _b, _c, _d;
|
|
2182
2117
|
ensureSecureContext();
|
|
2183
2118
|
const controller = createTimeoutController();
|
|
2184
|
-
const compressedImage = await
|
|
2119
|
+
const compressedImage = await compressDocumentImage(image);
|
|
2185
2120
|
const base64Image = await new Promise((resolve, reject) => {
|
|
2186
2121
|
const reader = new FileReader();
|
|
2187
2122
|
reader.onload = () => {
|
|
@@ -2192,7 +2127,7 @@ const identifyPerson = async (image, applicationToken) => {
|
|
|
2192
2127
|
reader.readAsDataURL(compressedImage);
|
|
2193
2128
|
});
|
|
2194
2129
|
try {
|
|
2195
|
-
const response = await fetch(`${getApiBaseUrl()}/api/v1/
|
|
2130
|
+
const response = await fetch(`${getApiBaseUrl()}/api/v1/auth/recognition/face/external/`, {
|
|
2196
2131
|
method: "POST",
|
|
2197
2132
|
headers: {
|
|
2198
2133
|
"Content-Type": "application/json",
|
|
@@ -2211,30 +2146,26 @@ const identifyPerson = async (image, applicationToken) => {
|
|
|
2211
2146
|
throw new NeoFaceError(`Server returned status ${response.status}`, ErrorType.NETWORK);
|
|
2212
2147
|
}
|
|
2213
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
|
+
}
|
|
2214
2157
|
if (!data.success) {
|
|
2215
2158
|
throw new NeoFaceError(
|
|
2216
2159
|
data.message || "Person identification failed",
|
|
2217
2160
|
ErrorType.RECOGNITION_FAILED
|
|
2218
2161
|
);
|
|
2219
2162
|
}
|
|
2220
|
-
const personName = ((_a = data.person) == null ? void 0 : _a.name) || "";
|
|
2221
|
-
const birthDateStr = (_b = data.person) == null ? void 0 : _b.birth_date;
|
|
2222
|
-
if (!personName) {
|
|
2223
|
-
throw new NeoFaceError("Person name not found in response", ErrorType.PERSON_NOT_FOUND);
|
|
2224
|
-
}
|
|
2225
|
-
if (!birthDateStr) {
|
|
2226
|
-
throw new NeoFaceError("Birth date not found in response", ErrorType.PERSON_NOT_FOUND);
|
|
2227
|
-
}
|
|
2228
|
-
const birthDate = new Date(birthDateStr);
|
|
2229
|
-
const today = /* @__PURE__ */ new Date();
|
|
2230
|
-
let age = today.getFullYear() - birthDate.getFullYear();
|
|
2231
|
-
const monthDiff = today.getMonth() - birthDate.getMonth();
|
|
2232
|
-
if (monthDiff < 0 || monthDiff === 0 && today.getDate() < birthDate.getDate()) {
|
|
2233
|
-
age--;
|
|
2234
|
-
}
|
|
2235
2163
|
return {
|
|
2236
|
-
|
|
2237
|
-
|
|
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
|
+
}
|
|
2238
2169
|
};
|
|
2239
2170
|
} catch (error) {
|
|
2240
2171
|
if (error instanceof Error) {
|
|
@@ -2668,6 +2599,135 @@ const registerDocumentByImage = async (personId, jwtToken, images) => {
|
|
|
2668
2599
|
throw new NeoFaceError("Unknown error occurred", ErrorType.NETWORK_ERROR);
|
|
2669
2600
|
}
|
|
2670
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" }));
|
|
2671
2731
|
const modalReducer$1 = (state, action) => {
|
|
2672
2732
|
switch (action.type) {
|
|
2673
2733
|
case "PERMISSION_GRANTED":
|
|
@@ -2961,6 +3021,336 @@ function FaceCaptureModal({ accessToken, onClose, onSuccess }) {
|
|
|
2961
3021
|
] })
|
|
2962
3022
|
] });
|
|
2963
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
|
+
}
|
|
2964
3354
|
const modalReducer = (state, action) => {
|
|
2965
3355
|
switch (action.type) {
|
|
2966
3356
|
case "START_LIVENESS":
|
|
@@ -2995,10 +3385,10 @@ const modalReducer = (state, action) => {
|
|
|
2995
3385
|
return state;
|
|
2996
3386
|
case "CAMERA_LOADING":
|
|
2997
3387
|
return { status: "camera-loading" };
|
|
2998
|
-
case "START_PROCESSING":
|
|
2999
|
-
return { status: "processing" };
|
|
3000
3388
|
case "SUCCESS":
|
|
3001
3389
|
return { status: "success" };
|
|
3390
|
+
case "DUPLICATE":
|
|
3391
|
+
return { status: "duplicate", personName: action.personName };
|
|
3002
3392
|
case "ERROR":
|
|
3003
3393
|
return { status: "error", message: action.message, retryable: action.retryable ?? true };
|
|
3004
3394
|
case "RESET":
|
|
@@ -3468,7 +3858,24 @@ function BiometricRegistrationModal({
|
|
|
3468
3858
|
);
|
|
3469
3859
|
};
|
|
3470
3860
|
const processRegistration = async (photos) => {
|
|
3861
|
+
var _a;
|
|
3471
3862
|
try {
|
|
3863
|
+
dispatch({ type: "START_PROCESSING" });
|
|
3864
|
+
if (applicationToken && photos.length > 0) {
|
|
3865
|
+
try {
|
|
3866
|
+
const { identifyPersonAsync: identifyPersonAsync2 } = await Promise.resolve().then(() => api);
|
|
3867
|
+
const result2 = await identifyPersonAsync2(photos[0], applicationToken);
|
|
3868
|
+
if (result2.personFound) {
|
|
3869
|
+
dispatch({
|
|
3870
|
+
type: "DUPLICATE",
|
|
3871
|
+
personName: ((_a = result2.person) == null ? void 0 : _a.name) || "Pessoa identificada"
|
|
3872
|
+
});
|
|
3873
|
+
return;
|
|
3874
|
+
}
|
|
3875
|
+
} catch (idError) {
|
|
3876
|
+
console.warn("Erro silencioso na identificação preventiva:", idError);
|
|
3877
|
+
}
|
|
3878
|
+
}
|
|
3472
3879
|
if (onPhotosCaptured) {
|
|
3473
3880
|
dispatch({ type: "SUCCESS" });
|
|
3474
3881
|
onPhotosCaptured(photos);
|
|
@@ -3624,6 +4031,75 @@ function BiometricRegistrationModal({
|
|
|
3624
4031
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: onPhotosCaptured ? "Suas capturas faciais foram realizadas" : "Sua biometria foi registrada com sucesso" }),
|
|
3625
4032
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "primary-button", onClick: onClose, children: "Continuar" })
|
|
3626
4033
|
] });
|
|
4034
|
+
const renderDuplicate = () => {
|
|
4035
|
+
if (state.status !== "duplicate") return null;
|
|
4036
|
+
const greeting = state.personName && state.personName !== "Pessoa identificada" ? `Olá, ${state.personName.split(" ")[0]}!` : "Olá!";
|
|
4037
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "result-container duplicate scale-in", children: [
|
|
4038
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { style: { marginTop: "0px" }, children: greeting }),
|
|
4039
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: { marginBottom: "32px", fontSize: "15px" }, children: "Identificamos seu cadastro biométrico em nossa rede. Você já faz parte da NeoFaceId!" }),
|
|
4040
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "button-group-vertical", children: [
|
|
4041
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4042
|
+
"button",
|
|
4043
|
+
{
|
|
4044
|
+
className: "primary-button",
|
|
4045
|
+
onClick: () => {
|
|
4046
|
+
onClose();
|
|
4047
|
+
window.location.href = "/";
|
|
4048
|
+
},
|
|
4049
|
+
children: "Ir para o Login"
|
|
4050
|
+
}
|
|
4051
|
+
),
|
|
4052
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4053
|
+
"button",
|
|
4054
|
+
{
|
|
4055
|
+
className: "secondary-button",
|
|
4056
|
+
style: { marginTop: "12px" },
|
|
4057
|
+
onClick: () => {
|
|
4058
|
+
onClose();
|
|
4059
|
+
new ForgotPasswordModal(applicationToken ?? "").open();
|
|
4060
|
+
},
|
|
4061
|
+
children: "Esqueci minha senha"
|
|
4062
|
+
}
|
|
4063
|
+
),
|
|
4064
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "support-section", children: [
|
|
4065
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "Não reconhece esta conta?" }),
|
|
4066
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4067
|
+
"button",
|
|
4068
|
+
{
|
|
4069
|
+
className: "ghost-button",
|
|
4070
|
+
onClick: () => window.open("https://support.neofaceid.com", "_blank"),
|
|
4071
|
+
children: "Falar com Suporte"
|
|
4072
|
+
}
|
|
4073
|
+
)
|
|
4074
|
+
] })
|
|
4075
|
+
] }),
|
|
4076
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
4077
|
+
"div",
|
|
4078
|
+
{
|
|
4079
|
+
className: "branding",
|
|
4080
|
+
style: {
|
|
4081
|
+
marginTop: "32px",
|
|
4082
|
+
paddingTop: "20px",
|
|
4083
|
+
borderTop: "1px solid rgba(255, 255, 255, 0.08)",
|
|
4084
|
+
width: "100%"
|
|
4085
|
+
},
|
|
4086
|
+
children: [
|
|
4087
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4088
|
+
"img",
|
|
4089
|
+
{
|
|
4090
|
+
src: "/logo-icone.png",
|
|
4091
|
+
alt: "NeoFaceId",
|
|
4092
|
+
className: "brand-logo",
|
|
4093
|
+
style: { height: "18px" }
|
|
4094
|
+
}
|
|
4095
|
+
),
|
|
4096
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "NeoFaceId by" }),
|
|
4097
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "brand-name", children: "OCTA" })
|
|
4098
|
+
]
|
|
4099
|
+
}
|
|
4100
|
+
)
|
|
4101
|
+
] });
|
|
4102
|
+
};
|
|
3627
4103
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
3628
4104
|
/* @__PURE__ */ jsxRuntimeExports.jsx("style", { children: `
|
|
3629
4105
|
@keyframes fadeIn {
|
|
@@ -4153,6 +4629,61 @@ function BiometricRegistrationModal({
|
|
|
4153
4629
|
background: rgba(255, 255, 255, 0.05);
|
|
4154
4630
|
}
|
|
4155
4631
|
|
|
4632
|
+
/* Duplicate Screen Styles */
|
|
4633
|
+
.profile-icon-wrapper {
|
|
4634
|
+
position: relative;
|
|
4635
|
+
display: inline-block;
|
|
4636
|
+
margin-bottom: 24px;
|
|
4637
|
+
}
|
|
4638
|
+
|
|
4639
|
+
.profile-main-icon {
|
|
4640
|
+
background: rgba(124, 58, 237, 0.1);
|
|
4641
|
+
color: #7c3aed;
|
|
4642
|
+
padding: 20px;
|
|
4643
|
+
border-radius: 50%;
|
|
4644
|
+
border: 2px solid rgba(124, 58, 237, 0.2);
|
|
4645
|
+
box-shadow: 0 0 30px rgba(124, 58, 237, 0.2);
|
|
4646
|
+
}
|
|
4647
|
+
|
|
4648
|
+
.profile-main-icon svg {
|
|
4649
|
+
width: 48px;
|
|
4650
|
+
height: 48px;
|
|
4651
|
+
}
|
|
4652
|
+
|
|
4653
|
+
.verified-badge {
|
|
4654
|
+
position: absolute;
|
|
4655
|
+
bottom: -4px;
|
|
4656
|
+
right: -4px;
|
|
4657
|
+
background: #10b981;
|
|
4658
|
+
border-radius: 50%;
|
|
4659
|
+
padding: 4px;
|
|
4660
|
+
border: 3px solid #16213e;
|
|
4661
|
+
width: 24px;
|
|
4662
|
+
height: 24px;
|
|
4663
|
+
display: flex;
|
|
4664
|
+
align-items: center;
|
|
4665
|
+
justify-content: center;
|
|
4666
|
+
}
|
|
4667
|
+
|
|
4668
|
+
.button-group-vertical {
|
|
4669
|
+
display: flex;
|
|
4670
|
+
flex-direction: column;
|
|
4671
|
+
width: 100%;
|
|
4672
|
+
gap: 8px;
|
|
4673
|
+
}
|
|
4674
|
+
|
|
4675
|
+
.support-section {
|
|
4676
|
+
margin-top: 24px;
|
|
4677
|
+
padding-top: 16px;
|
|
4678
|
+
border-top: 1px solid rgba(255, 255, 255, 0.05);
|
|
4679
|
+
}
|
|
4680
|
+
|
|
4681
|
+
.support-section p {
|
|
4682
|
+
font-size: 13px;
|
|
4683
|
+
color: rgba(255, 255, 255, 0.4);
|
|
4684
|
+
margin-bottom: 8px;
|
|
4685
|
+
}
|
|
4686
|
+
|
|
4156
4687
|
/* Canvas */
|
|
4157
4688
|
canvas {
|
|
4158
4689
|
display: none;
|
|
@@ -4190,7 +4721,8 @@ function BiometricRegistrationModal({
|
|
|
4190
4721
|
state.status === "camera-loading" && renderCameraLoading(),
|
|
4191
4722
|
state.status === "processing" && renderProcessing(),
|
|
4192
4723
|
state.status === "error" && renderError(),
|
|
4193
|
-
state.status === "success" && renderSuccess()
|
|
4724
|
+
state.status === "success" && renderSuccess(),
|
|
4725
|
+
state.status === "duplicate" && renderDuplicate()
|
|
4194
4726
|
] }) }),
|
|
4195
4727
|
/* @__PURE__ */ jsxRuntimeExports.jsx("canvas", { ref: canvasRef })
|
|
4196
4728
|
] });
|
|
@@ -4778,6 +5310,7 @@ class BiometricStatusOverlay {
|
|
|
4778
5310
|
/* Cores por estado */
|
|
4779
5311
|
.neofaceid-state-preparing .neofaceid-logo { filter: drop-shadow(0 0 15px rgba(124, 58, 237, 0.4)); }
|
|
4780
5312
|
.neofaceid-state-detecting .neofaceid-logo { filter: hue-rotate(180deg) drop-shadow(0 0 15px rgba(59, 130, 246, 0.6)); }
|
|
5313
|
+
.neofaceid-state-waiting-for-face .neofaceid-logo { filter: hue-rotate(30deg) drop-shadow(0 0 15px rgba(251, 146, 60, 0.6)); }
|
|
4781
5314
|
.neofaceid-state-capturing .neofaceid-logo { filter: hue-rotate(45deg) drop-shadow(0 0 15px rgba(245, 158, 11, 0.6)); }
|
|
4782
5315
|
.neofaceid-state-verifying .neofaceid-logo { filter: hue-rotate(90deg) drop-shadow(0 0 15px rgba(34, 197, 94, 0.6)); }
|
|
4783
5316
|
|
|
@@ -4851,6 +5384,8 @@ class BiometricStatusOverlay {
|
|
|
4851
5384
|
return "Iniciando câmera";
|
|
4852
5385
|
case "detecting":
|
|
4853
5386
|
return "Posicione seu rosto";
|
|
5387
|
+
case "waiting-for-face":
|
|
5388
|
+
return "Aguardando rosto";
|
|
4854
5389
|
case "capturing":
|
|
4855
5390
|
return "Capturando";
|
|
4856
5391
|
case "verifying":
|
|
@@ -4864,12 +5399,18 @@ class BiometricStatusOverlay {
|
|
|
4864
5399
|
}
|
|
4865
5400
|
}
|
|
4866
5401
|
renderContent() {
|
|
4867
|
-
const isPulsing = ["detecting", "verifying"].includes(this.currentStatus);
|
|
5402
|
+
const isPulsing = ["detecting", "waiting-for-face", "verifying"].includes(this.currentStatus);
|
|
4868
5403
|
const showLogo = !["success", "error"].includes(this.currentStatus);
|
|
4869
5404
|
const showSuccess = this.currentStatus === "success";
|
|
4870
5405
|
const showError = this.currentStatus === "error";
|
|
4871
5406
|
const statusText = this.getStatusText();
|
|
4872
|
-
const showDots = [
|
|
5407
|
+
const showDots = [
|
|
5408
|
+
"preparing",
|
|
5409
|
+
"detecting",
|
|
5410
|
+
"waiting-for-face",
|
|
5411
|
+
"capturing",
|
|
5412
|
+
"verifying"
|
|
5413
|
+
].includes(this.currentStatus);
|
|
4873
5414
|
return `
|
|
4874
5415
|
<style>${this.getStyles()}</style>
|
|
4875
5416
|
<div class="neofaceid-overlay-container neofaceid-state-${this.currentStatus}">
|
|
@@ -4954,8 +5495,13 @@ function FallbackPromptComponent({
|
|
|
4954
5495
|
error,
|
|
4955
5496
|
onRetry,
|
|
4956
5497
|
onCredentials,
|
|
4957
|
-
onCancel
|
|
5498
|
+
onCancel,
|
|
5499
|
+
applicationToken
|
|
4958
5500
|
}) {
|
|
5501
|
+
const handleForgotPassword = () => {
|
|
5502
|
+
const modal = new ForgotPasswordModal(applicationToken);
|
|
5503
|
+
modal.open();
|
|
5504
|
+
};
|
|
4959
5505
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4960
5506
|
/* @__PURE__ */ jsxRuntimeExports.jsx("style", { children: `
|
|
4961
5507
|
@keyframes slideUp {
|
|
@@ -5133,6 +5679,15 @@ function FallbackPromptComponent({
|
|
|
5133
5679
|
children: "Entrar com Email e Senha"
|
|
5134
5680
|
}
|
|
5135
5681
|
),
|
|
5682
|
+
applicationToken && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5683
|
+
"button",
|
|
5684
|
+
{
|
|
5685
|
+
type: "button",
|
|
5686
|
+
className: "neofaceid-fallback-button neofaceid-fallback-button-ghost",
|
|
5687
|
+
onClick: handleForgotPassword,
|
|
5688
|
+
children: "Esqueceu sua senha?"
|
|
5689
|
+
}
|
|
5690
|
+
),
|
|
5136
5691
|
onCancel && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5137
5692
|
"button",
|
|
5138
5693
|
{
|
|
@@ -5154,7 +5709,7 @@ class FallbackPrompt {
|
|
|
5154
5709
|
/**
|
|
5155
5710
|
* Exibe o prompt de fallback
|
|
5156
5711
|
*/
|
|
5157
|
-
show(error, onRetry, onCredentials, onCancel) {
|
|
5712
|
+
show(error, onRetry, onCredentials, onCancel, applicationToken) {
|
|
5158
5713
|
if (this.container) {
|
|
5159
5714
|
return;
|
|
5160
5715
|
}
|
|
@@ -5162,7 +5717,7 @@ class FallbackPrompt {
|
|
|
5162
5717
|
this.container.id = "neofaceid-fallback-prompt";
|
|
5163
5718
|
document.body.appendChild(this.container);
|
|
5164
5719
|
this.root = clientExports.createRoot(this.container);
|
|
5165
|
-
this.render(error, onRetry, onCredentials, onCancel);
|
|
5720
|
+
this.render(error, onRetry, onCredentials, onCancel, applicationToken);
|
|
5166
5721
|
}
|
|
5167
5722
|
/**
|
|
5168
5723
|
* Fecha o prompt
|
|
@@ -5180,7 +5735,7 @@ class FallbackPrompt {
|
|
|
5180
5735
|
/**
|
|
5181
5736
|
* Renderiza o componente
|
|
5182
5737
|
*/
|
|
5183
|
-
render(error, onRetry, onCredentials, onCancel) {
|
|
5738
|
+
render(error, onRetry, onCredentials, onCancel, applicationToken) {
|
|
5184
5739
|
if (!this.root || !this.container) return;
|
|
5185
5740
|
this.root.render(
|
|
5186
5741
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -5195,6 +5750,7 @@ class FallbackPrompt {
|
|
|
5195
5750
|
this.close();
|
|
5196
5751
|
onCredentials();
|
|
5197
5752
|
},
|
|
5753
|
+
applicationToken: applicationToken ?? "",
|
|
5198
5754
|
onCancel: () => {
|
|
5199
5755
|
this.close();
|
|
5200
5756
|
onCancel == null ? void 0 : onCancel();
|
|
@@ -5669,12 +6225,14 @@ async function captureFaceSilently() {
|
|
|
5669
6225
|
});
|
|
5670
6226
|
});
|
|
5671
6227
|
}
|
|
5672
|
-
async function detectFaceQuickly(video, maxTime = FACE_DETECTION_TIME, interval = DETECTION_INTERVAL) {
|
|
6228
|
+
async function detectFaceQuickly(video, maxTime = FACE_DETECTION_TIME, interval = DETECTION_INTERVAL, overlay) {
|
|
5673
6229
|
return new Promise((resolve) => {
|
|
5674
6230
|
let attempts = 0;
|
|
5675
6231
|
const maxAttempts = Math.ceil(maxTime / interval);
|
|
5676
6232
|
let timeoutId = null;
|
|
5677
6233
|
let isResolved = false;
|
|
6234
|
+
let overlayShowingWaiting = false;
|
|
6235
|
+
const ATTEMPTS_BEFORE_WAITING = Math.ceil(3e3 / interval);
|
|
5678
6236
|
const finish = (success) => {
|
|
5679
6237
|
if (isResolved) return;
|
|
5680
6238
|
isResolved = true;
|
|
@@ -5685,7 +6243,16 @@ async function detectFaceQuickly(video, maxTime = FACE_DETECTION_TIME, interval
|
|
|
5685
6243
|
if (isResolved) return;
|
|
5686
6244
|
attempts++;
|
|
5687
6245
|
if (!modelsLoaded) {
|
|
5688
|
-
|
|
6246
|
+
if (overlay && !overlayShowingWaiting && attempts >= ATTEMPTS_BEFORE_WAITING) {
|
|
6247
|
+
overlay.updateStatus("waiting-for-face");
|
|
6248
|
+
overlayShowingWaiting = true;
|
|
6249
|
+
console.log("⏳ Models not loaded - waiting for face...");
|
|
6250
|
+
}
|
|
6251
|
+
if (attempts >= maxAttempts) {
|
|
6252
|
+
finish(false);
|
|
6253
|
+
return;
|
|
6254
|
+
}
|
|
6255
|
+
timeoutId = window.setTimeout(checkFace, interval);
|
|
5689
6256
|
return;
|
|
5690
6257
|
}
|
|
5691
6258
|
try {
|
|
@@ -5694,21 +6261,43 @@ async function detectFaceQuickly(video, maxTime = FACE_DETECTION_TIME, interval
|
|
|
5694
6261
|
new faceapi.TinyFaceDetectorOptions({ inputSize: 160, scoreThreshold: 0.3 })
|
|
5695
6262
|
);
|
|
5696
6263
|
if (detection) {
|
|
6264
|
+
if (overlay && overlayShowingWaiting) {
|
|
6265
|
+
overlay.updateStatus("detecting");
|
|
6266
|
+
overlayShowingWaiting = false;
|
|
6267
|
+
console.log("👤 Face appeared");
|
|
6268
|
+
}
|
|
6269
|
+
console.log("✅ Face detected!");
|
|
5697
6270
|
finish(true);
|
|
5698
6271
|
return;
|
|
5699
6272
|
}
|
|
6273
|
+
if (overlay && !overlayShowingWaiting && attempts >= ATTEMPTS_BEFORE_WAITING) {
|
|
6274
|
+
overlay.updateStatus("waiting-for-face");
|
|
6275
|
+
overlayShowingWaiting = true;
|
|
6276
|
+
console.log("⏳ Waiting for face...");
|
|
6277
|
+
}
|
|
5700
6278
|
if (attempts >= maxAttempts) {
|
|
6279
|
+
console.warn("⏱️ Face detection timeout - no face found");
|
|
5701
6280
|
finish(false);
|
|
5702
6281
|
return;
|
|
5703
6282
|
}
|
|
5704
6283
|
timeoutId = window.setTimeout(checkFace, interval);
|
|
5705
6284
|
} catch (error) {
|
|
5706
|
-
|
|
6285
|
+
console.error("❌ Face detection error:", error);
|
|
6286
|
+
if (overlay && !overlayShowingWaiting && attempts >= ATTEMPTS_BEFORE_WAITING) {
|
|
6287
|
+
overlay.updateStatus("waiting-for-face");
|
|
6288
|
+
overlayShowingWaiting = true;
|
|
6289
|
+
}
|
|
6290
|
+
if (attempts >= maxAttempts) {
|
|
6291
|
+
finish(false);
|
|
6292
|
+
return;
|
|
6293
|
+
}
|
|
6294
|
+
timeoutId = window.setTimeout(checkFace, interval);
|
|
5707
6295
|
}
|
|
5708
6296
|
};
|
|
5709
6297
|
window.setTimeout(() => {
|
|
5710
6298
|
if (!isResolved) {
|
|
5711
|
-
|
|
6299
|
+
console.warn("⏱️ Face detection safety timeout reached");
|
|
6300
|
+
finish(false);
|
|
5712
6301
|
}
|
|
5713
6302
|
}, maxTime + 500);
|
|
5714
6303
|
checkFace();
|
|
@@ -5782,7 +6371,12 @@ async function attemptLogin(applicationToken, overlay, fastMode = false, isRetry
|
|
|
5782
6371
|
await new Promise((resolve) => setTimeout(resolve, CAMERA_STABILITY_DELAY));
|
|
5783
6372
|
let faceDetected = true;
|
|
5784
6373
|
if (!fastMode) {
|
|
5785
|
-
faceDetected = await detectFaceQuickly(
|
|
6374
|
+
faceDetected = await detectFaceQuickly(
|
|
6375
|
+
video,
|
|
6376
|
+
FACE_DETECTION_TIME,
|
|
6377
|
+
DETECTION_INTERVAL,
|
|
6378
|
+
overlay
|
|
6379
|
+
);
|
|
5786
6380
|
}
|
|
5787
6381
|
if (!faceDetected) {
|
|
5788
6382
|
if (stream) {
|
|
@@ -5792,7 +6386,7 @@ async function attemptLogin(applicationToken, overlay, fastMode = false, isRetry
|
|
|
5792
6386
|
video.parentElement.removeChild(video);
|
|
5793
6387
|
}
|
|
5794
6388
|
throw new NeoFaceError(
|
|
5795
|
-
"
|
|
6389
|
+
"Nenhum rosto detectado. Por favor, posicione seu rosto na frente da câmera e tente novamente.",
|
|
5796
6390
|
ErrorType.VALIDATION_ERROR
|
|
5797
6391
|
);
|
|
5798
6392
|
}
|
|
@@ -5832,7 +6426,7 @@ async function attemptLogin(applicationToken, overlay, fastMode = false, isRetry
|
|
|
5832
6426
|
);
|
|
5833
6427
|
});
|
|
5834
6428
|
overlay.updateStatus("verifying");
|
|
5835
|
-
const result = await
|
|
6429
|
+
const result = await loginWithBiometric(imageBlob, applicationToken);
|
|
5836
6430
|
if (!result.success) {
|
|
5837
6431
|
throw new NeoFaceError("Login falhou", ErrorType.LOGIN_FAILED);
|
|
5838
6432
|
}
|
|
@@ -5912,7 +6506,8 @@ async function executeBiometricLoginFlow(options) {
|
|
|
5912
6506
|
);
|
|
5913
6507
|
}
|
|
5914
6508
|
},
|
|
5915
|
-
onCancel
|
|
6509
|
+
onCancel,
|
|
6510
|
+
applicationToken
|
|
5916
6511
|
);
|
|
5917
6512
|
}, 500);
|
|
5918
6513
|
}
|
|
@@ -5930,11 +6525,6 @@ const biometricLoginFlow = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.
|
|
|
5930
6525
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
5931
6526
|
async function startFaceLogin(options) {
|
|
5932
6527
|
try {
|
|
5933
|
-
const isValidToken = await validateToken(options.applicationToken);
|
|
5934
|
-
if (!isValidToken) {
|
|
5935
|
-
options.onError(new NeoFaceError("Token de aplicação inválido", ErrorType.INVALID_TOKEN));
|
|
5936
|
-
return;
|
|
5937
|
-
}
|
|
5938
6528
|
await executeBiometricLoginFlow({
|
|
5939
6529
|
applicationToken: options.applicationToken,
|
|
5940
6530
|
onSuccess: options.onSuccess,
|
|
@@ -5963,11 +6553,6 @@ async function startFaceLogin(options) {
|
|
|
5963
6553
|
}
|
|
5964
6554
|
async function startHandLogin(options) {
|
|
5965
6555
|
try {
|
|
5966
|
-
const isValidToken = await validateToken(options.applicationToken);
|
|
5967
|
-
if (!isValidToken) {
|
|
5968
|
-
options.onError(new NeoFaceError("Token de aplicação inválido", ErrorType.INVALID_TOKEN));
|
|
5969
|
-
return;
|
|
5970
|
-
}
|
|
5971
6556
|
const captureOptions = {
|
|
5972
6557
|
mode: "hand",
|
|
5973
6558
|
onSuccess: async (imageData, _detectedType) => {
|
|
@@ -5998,11 +6583,6 @@ async function startHandLogin(options) {
|
|
|
5998
6583
|
}
|
|
5999
6584
|
async function startAutoLogin(options) {
|
|
6000
6585
|
try {
|
|
6001
|
-
const isValidToken = await validateToken(options.applicationToken);
|
|
6002
|
-
if (!isValidToken) {
|
|
6003
|
-
options.onError(new NeoFaceError("Token de aplicação inválido", ErrorType.INVALID_TOKEN));
|
|
6004
|
-
return;
|
|
6005
|
-
}
|
|
6006
6586
|
const captureOptions = {
|
|
6007
6587
|
mode: "auto",
|
|
6008
6588
|
onSuccess: async (imageData, _detectedType) => {
|
|
@@ -6255,8 +6835,8 @@ const biometricDetection = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.
|
|
|
6255
6835
|
initializeBiometricDetection,
|
|
6256
6836
|
isAdvancedDetectionAvailable
|
|
6257
6837
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
6258
|
-
const VERSION = "1.
|
|
6259
|
-
const RELEASE_DATE = "2026-03-
|
|
6838
|
+
const VERSION = "1.17.0";
|
|
6839
|
+
const RELEASE_DATE = "2026-03-13";
|
|
6260
6840
|
class OnboardingCaptureModal {
|
|
6261
6841
|
constructor(options) {
|
|
6262
6842
|
__publicField(this, "overlay", null);
|
|
@@ -6941,11 +7521,11 @@ const authorizeOperation = async (applicationToken, cpf, options) => {
|
|
|
6941
7521
|
};
|
|
6942
7522
|
const DOCUMENT_INFO = {
|
|
6943
7523
|
RG: {
|
|
6944
|
-
name: "RG /
|
|
7524
|
+
name: "Documento de Identidade (RG / CIN / CPF)",
|
|
6945
7525
|
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>',
|
|
6946
7526
|
hasBack: true,
|
|
6947
|
-
frontLabel: "Frente do
|
|
6948
|
-
backLabel: "Verso do
|
|
7527
|
+
frontLabel: "Frente do Documento",
|
|
7528
|
+
backLabel: "Verso do Documento"
|
|
6949
7529
|
},
|
|
6950
7530
|
CNH: {
|
|
6951
7531
|
name: "CNH / Carteira de Motorista",
|
|
@@ -6955,7 +7535,7 @@ const DOCUMENT_INFO = {
|
|
|
6955
7535
|
backLabel: "Verso da CNH"
|
|
6956
7536
|
},
|
|
6957
7537
|
CPF: {
|
|
6958
|
-
name: "CPF",
|
|
7538
|
+
name: "Cartão CPF (Apenas Frente)",
|
|
6959
7539
|
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>',
|
|
6960
7540
|
hasBack: false,
|
|
6961
7541
|
frontLabel: "Cartão CPF"
|
|
@@ -7049,7 +7629,7 @@ class DocumentCaptureModal {
|
|
|
7049
7629
|
|
|
7050
7630
|
<div class="neoface-doc-body">
|
|
7051
7631
|
<div class="neoface-doc-select-grid">
|
|
7052
|
-
${Object.entries(DOCUMENT_INFO).map(([type, info]) => `
|
|
7632
|
+
${Object.entries(DOCUMENT_INFO).filter(([type]) => type !== "CPF").map(([type, info]) => `
|
|
7053
7633
|
<button class="neoface-doc-select-option" data-type="${type}">
|
|
7054
7634
|
<span class="neoface-doc-select-icon">${info.icon}</span>
|
|
7055
7635
|
<span class="neoface-doc-select-name">${info.name}</span>
|
|
@@ -8055,6 +8635,7 @@ export {
|
|
|
8055
8635
|
ErrorType,
|
|
8056
8636
|
FaceCaptureModal,
|
|
8057
8637
|
FallbackPrompt,
|
|
8638
|
+
ForgotPasswordModal,
|
|
8058
8639
|
NeoFaceError,
|
|
8059
8640
|
NeoFaceID,
|
|
8060
8641
|
RELEASE_DATE,
|
|
@@ -8062,14 +8643,17 @@ export {
|
|
|
8062
8643
|
authorizeOperation,
|
|
8063
8644
|
biometricLogin,
|
|
8064
8645
|
biometricLoginWithFallback,
|
|
8646
|
+
checkUserExistence,
|
|
8065
8647
|
completeOnboarding,
|
|
8066
8648
|
completeOnboardingWithData,
|
|
8649
|
+
confirmPasswordReset,
|
|
8067
8650
|
detectBiometricType,
|
|
8068
8651
|
getApplicationToken,
|
|
8069
8652
|
getBaseUrl,
|
|
8070
8653
|
getConfig,
|
|
8071
8654
|
getEnvironment,
|
|
8072
8655
|
identifyPerson,
|
|
8656
|
+
identifyPersonAsync,
|
|
8073
8657
|
init,
|
|
8074
8658
|
initializeBiometricDetection,
|
|
8075
8659
|
isAdvancedDetectionAvailable,
|
|
@@ -8083,6 +8667,7 @@ export {
|
|
|
8083
8667
|
registerBiometric,
|
|
8084
8668
|
registerPersonWithBiometric,
|
|
8085
8669
|
registerPersonWithoutFace,
|
|
8670
|
+
requestPasswordReset,
|
|
8086
8671
|
simpleIdentification,
|
|
8087
8672
|
start,
|
|
8088
8673
|
startAutoLogin,
|