@nice2dev/ui-security 1.2.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +142 -0
- package/dist/components/NiceMfaSelector.d.ts +1 -1
- package/dist/components/NiceSecurityAuditLog.d.ts +1 -1
- package/dist/components/NiceSessionManager.d.ts +1 -1
- package/dist/core/biometricEngine.d.ts +10 -0
- package/dist/core/i18n.d.ts +1 -0
- package/dist/index.cjs +10 -10
- package/dist/index.mjs +1331 -1293
- package/dist/ui-security.css +1 -1
- package/package.json +5 -1
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { jsx as c, jsxs as P, Fragment as Pe } from "react/jsx-runtime";
|
|
2
|
-
import { useContext as Ee, createContext as Fe, useRef as
|
|
3
|
-
|
|
2
|
+
import { useContext as Ee, createContext as Fe, useRef as V, useState as j, useCallback as K, useEffect as ne, useMemo as ae } from "react";
|
|
3
|
+
import { useNiceTranslation as ze } from "@nice2dev/ui-core";
|
|
4
|
+
import { NtdBackspace as Ne, NtdArrowLeft as Le, NtdArrowRight as $e } from "@nice2dev/icons";
|
|
5
|
+
const je = {
|
|
4
6
|
low: 0.7,
|
|
5
7
|
medium: 0.8,
|
|
6
8
|
high: 0.85,
|
|
7
9
|
critical: 0.95
|
|
8
|
-
},
|
|
10
|
+
}, _e = {
|
|
9
11
|
matchThreshold: 0.85,
|
|
10
12
|
timeout: 3e4,
|
|
11
13
|
maxRetries: 3,
|
|
@@ -19,8 +21,8 @@ const ze = {
|
|
|
19
21
|
antiSpoofing: !0
|
|
20
22
|
};
|
|
21
23
|
function fe(e) {
|
|
22
|
-
const t = { ...
|
|
23
|
-
return e != null && e.matchThreshold || (t.matchThreshold =
|
|
24
|
+
const t = { ..._e, ...e };
|
|
25
|
+
return e != null && e.matchThreshold || (t.matchThreshold = je[t.securityLevel]), t;
|
|
24
26
|
}
|
|
25
27
|
async function ue(e) {
|
|
26
28
|
const t = new TextEncoder().encode(e), r = await crypto.subtle.digest("SHA-256", t);
|
|
@@ -30,11 +32,11 @@ function ye(e = 8) {
|
|
|
30
32
|
const t = new Uint8Array(e);
|
|
31
33
|
return crypto.getRandomValues(t), Array.from(t).map((r) => r.toString(36).padStart(2, "0")).join("").slice(0, e);
|
|
32
34
|
}
|
|
33
|
-
function
|
|
35
|
+
function Be(e) {
|
|
34
36
|
const t = new Uint32Array(1);
|
|
35
37
|
return crypto.getRandomValues(t), t[0] % e;
|
|
36
38
|
}
|
|
37
|
-
function
|
|
39
|
+
function We(e, t) {
|
|
38
40
|
return Math.sqrt((e.x - t.x) ** 2 + (e.y - t.y) ** 2);
|
|
39
41
|
}
|
|
40
42
|
async function pe(e = "user") {
|
|
@@ -44,143 +46,143 @@ async function pe(e = "user") {
|
|
|
44
46
|
});
|
|
45
47
|
}
|
|
46
48
|
function le(e, t, r) {
|
|
47
|
-
const n = t ?? e.videoWidth,
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
const
|
|
52
|
-
return { canvas:
|
|
49
|
+
const n = t ?? e.videoWidth, o = r ?? e.videoHeight, s = document.createElement("canvas");
|
|
50
|
+
s.width = n, s.height = o;
|
|
51
|
+
const a = s.getContext("2d");
|
|
52
|
+
a.drawImage(e, 0, 0, n, o);
|
|
53
|
+
const i = a.getImageData(0, 0, n, o);
|
|
54
|
+
return { canvas: s, ctx: a, imageData: i };
|
|
53
55
|
}
|
|
54
56
|
function ce(e) {
|
|
55
57
|
const t = new Uint8Array(e.width * e.height), r = e.data;
|
|
56
58
|
for (let n = 0; n < t.length; n++) {
|
|
57
|
-
const
|
|
58
|
-
t[n] = Math.round(0.299 * r[
|
|
59
|
+
const o = n * 4;
|
|
60
|
+
t[n] = Math.round(0.299 * r[o] + 0.587 * r[o + 1] + 0.114 * r[o + 2]);
|
|
59
61
|
}
|
|
60
62
|
return t;
|
|
61
63
|
}
|
|
62
64
|
function Ae(e, t, r) {
|
|
63
|
-
const n = new Uint8Array(t * r),
|
|
64
|
-
for (let
|
|
65
|
-
for (let
|
|
66
|
-
let
|
|
65
|
+
const n = new Uint8Array(t * r), o = [1, 2, 1, 2, 4, 2, 1, 2, 1], s = 16;
|
|
66
|
+
for (let a = 1; a < r - 1; a++)
|
|
67
|
+
for (let i = 1; i < t - 1; i++) {
|
|
68
|
+
let y = 0, b = 0;
|
|
67
69
|
for (let f = -1; f <= 1; f++)
|
|
68
|
-
for (let
|
|
69
|
-
|
|
70
|
-
n[
|
|
70
|
+
for (let x = -1; x <= 1; x++)
|
|
71
|
+
y += e[(a + f) * t + (i + x)] * o[b++];
|
|
72
|
+
n[a * t + i] = Math.round(y / s);
|
|
71
73
|
}
|
|
72
74
|
return n;
|
|
73
75
|
}
|
|
74
|
-
function
|
|
76
|
+
function He(e, t, r) {
|
|
75
77
|
const n = new Uint8Array(t * r);
|
|
76
|
-
for (let
|
|
77
|
-
for (let
|
|
78
|
-
const
|
|
79
|
-
n[
|
|
78
|
+
for (let o = 1; o < r - 1; o++)
|
|
79
|
+
for (let s = 1; s < t - 1; s++) {
|
|
80
|
+
const a = -e[(o - 1) * t + (s - 1)] + e[(o - 1) * t + (s + 1)] + -2 * e[o * t + (s - 1)] + 2 * e[o * t + (s + 1)] + -e[(o + 1) * t + (s - 1)] + e[(o + 1) * t + (s + 1)], i = -e[(o - 1) * t + (s - 1)] - 2 * e[(o - 1) * t + s] - e[(o - 1) * t + (s + 1)] + e[(o + 1) * t + (s - 1)] + 2 * e[(o + 1) * t + s] + e[(o + 1) * t + (s + 1)];
|
|
81
|
+
n[o * t + s] = Math.min(255, Math.round(Math.sqrt(a * a + i * i)));
|
|
80
82
|
}
|
|
81
83
|
return n;
|
|
82
84
|
}
|
|
83
|
-
function
|
|
85
|
+
function Oe(e) {
|
|
84
86
|
const t = new Array(256).fill(0);
|
|
85
|
-
for (const
|
|
86
|
-
t[
|
|
87
|
+
for (const b of e)
|
|
88
|
+
t[b]++;
|
|
87
89
|
const r = e.length;
|
|
88
90
|
let n = 0;
|
|
89
|
-
for (let
|
|
90
|
-
n +=
|
|
91
|
-
let
|
|
92
|
-
for (let
|
|
93
|
-
if (
|
|
91
|
+
for (let b = 0; b < 256; b++)
|
|
92
|
+
n += b * t[b];
|
|
93
|
+
let o = 0, s = 0, a = 0, i = 0;
|
|
94
|
+
for (let b = 0; b < 256; b++) {
|
|
95
|
+
if (s += t[b], s === 0)
|
|
94
96
|
continue;
|
|
95
|
-
const f = r -
|
|
97
|
+
const f = r - s;
|
|
96
98
|
if (f === 0)
|
|
97
99
|
break;
|
|
98
|
-
|
|
99
|
-
const
|
|
100
|
-
|
|
100
|
+
o += b * t[b];
|
|
101
|
+
const x = o / s, A = (n - o) / f, g = s * f * (x - A) ** 2;
|
|
102
|
+
g > a && (a = g, i = b);
|
|
101
103
|
}
|
|
102
|
-
const
|
|
103
|
-
for (let
|
|
104
|
-
|
|
105
|
-
return { threshold:
|
|
106
|
-
}
|
|
107
|
-
function
|
|
108
|
-
var
|
|
109
|
-
const r = e.width, n = e.height,
|
|
110
|
-
for (let
|
|
111
|
-
for (let
|
|
112
|
-
if (
|
|
104
|
+
const y = new Uint8Array(e.length);
|
|
105
|
+
for (let b = 0; b < e.length; b++)
|
|
106
|
+
y[b] = e[b] > i ? 255 : 0;
|
|
107
|
+
return { threshold: i, binary: y };
|
|
108
|
+
}
|
|
109
|
+
function Ue(e, t = 0.3) {
|
|
110
|
+
var S;
|
|
111
|
+
const r = e.width, n = e.height, o = ce(e), s = Ae(o, r, n), a = He(s, r, n), { binary: i } = Oe(a), y = [], b = [], f = [];
|
|
112
|
+
for (let v = 2; v < n - 2; v++)
|
|
113
|
+
for (let l = 2; l < r - 2; l++) {
|
|
114
|
+
if (i[v * r + l] === 0)
|
|
113
115
|
continue;
|
|
114
116
|
const w = [
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
117
|
+
i[(v - 1) * r + l],
|
|
118
|
+
i[(v - 1) * r + (l + 1)],
|
|
119
|
+
i[v * r + (l + 1)],
|
|
120
|
+
i[(v + 1) * r + (l + 1)],
|
|
121
|
+
i[(v + 1) * r + l],
|
|
122
|
+
i[(v + 1) * r + (l - 1)],
|
|
123
|
+
i[v * r + (l - 1)],
|
|
124
|
+
i[(v - 1) * r + (l - 1)]
|
|
123
125
|
];
|
|
124
|
-
let
|
|
125
|
-
for (let
|
|
126
|
-
const
|
|
127
|
-
|
|
126
|
+
let u = 0;
|
|
127
|
+
for (let W = 0; W < 8; W++) {
|
|
128
|
+
const O = w[W] > 0 ? 1 : 0, Y = w[(W + 1) % 8] > 0 ? 1 : 0;
|
|
129
|
+
u += Math.abs(O - Y);
|
|
128
130
|
}
|
|
129
|
-
|
|
130
|
-
let h = 0,
|
|
131
|
-
for (let
|
|
132
|
-
for (let
|
|
133
|
-
h +=
|
|
134
|
-
const
|
|
135
|
-
if (
|
|
131
|
+
u /= 2;
|
|
132
|
+
let h = 0, R = 0;
|
|
133
|
+
for (let W = -2; W <= 2; W++)
|
|
134
|
+
for (let O = -2; O <= 2; O++)
|
|
135
|
+
h += a[(v + W) * r + (l + O)], R++;
|
|
136
|
+
const G = h / R / 255;
|
|
137
|
+
if (G < t)
|
|
136
138
|
continue;
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
139
|
+
const J = Math.atan2(
|
|
140
|
+
o[(v + 1) * r + l] - o[(v - 1) * r + l],
|
|
141
|
+
o[v * r + (l + 1)] - o[v * r + (l - 1)]
|
|
140
142
|
);
|
|
141
|
-
|
|
143
|
+
u === 1 ? y.push({ x: l / r, y: v / n, angle: J, type: "ending", quality: G }) : u === 3 && y.push({ x: l / r, y: v / n, angle: J, type: "bifurcation", quality: G });
|
|
142
144
|
}
|
|
143
|
-
|
|
144
|
-
const
|
|
145
|
-
if (
|
|
146
|
-
const
|
|
147
|
-
|
|
145
|
+
y.sort((v, l) => l.quality - v.quality);
|
|
146
|
+
const x = y.slice(0, 120);
|
|
147
|
+
if (x.length > 5) {
|
|
148
|
+
const v = x.reduce((w, u) => w + u.x, 0) / x.length, l = x.reduce((w, u) => w + u.y, 0) / x.length;
|
|
149
|
+
b.push({ x: v, y: l });
|
|
148
150
|
}
|
|
149
|
-
const
|
|
150
|
-
let
|
|
151
|
-
|
|
152
|
-
const
|
|
151
|
+
const A = x.length, g = x.filter((v) => v.type === "ending").length, L = x.filter((v) => v.type === "bifurcation").length / (g + 1);
|
|
152
|
+
let p = "loop-right";
|
|
153
|
+
L > 1.5 ? p = "whorl" : L < 0.5 ? p = "arch" : ((S = b[0]) == null ? void 0 : S.x) < 0.45 && (p = "loop-left");
|
|
154
|
+
const C = x.length > 20 ? x.reduce((v, l) => v + l.quality, 0) / x.length : 0;
|
|
153
155
|
return {
|
|
154
|
-
minutiae:
|
|
155
|
-
corePoints:
|
|
156
|
+
minutiae: x,
|
|
157
|
+
corePoints: b,
|
|
156
158
|
deltaPoints: f,
|
|
157
|
-
ridgeCount:
|
|
158
|
-
patternType:
|
|
159
|
-
quality:
|
|
159
|
+
ridgeCount: A,
|
|
160
|
+
patternType: p,
|
|
161
|
+
quality: C
|
|
160
162
|
};
|
|
161
163
|
}
|
|
162
|
-
function
|
|
164
|
+
function qe(e, t) {
|
|
163
165
|
if (e.minutiae.length < 5 || t.minutiae.length < 5)
|
|
164
166
|
return 0;
|
|
165
167
|
let r = 0;
|
|
166
|
-
const n = 0.05,
|
|
167
|
-
for (const
|
|
168
|
-
let
|
|
168
|
+
const n = 0.05, o = 0.5, s = /* @__PURE__ */ new Set();
|
|
169
|
+
for (const i of e.minutiae) {
|
|
170
|
+
let y = 1 / 0, b = -1;
|
|
169
171
|
for (let f = 0; f < t.minutiae.length; f++) {
|
|
170
|
-
if (
|
|
172
|
+
if (s.has(f))
|
|
171
173
|
continue;
|
|
172
|
-
const
|
|
173
|
-
if (
|
|
174
|
+
const x = t.minutiae[f];
|
|
175
|
+
if (i.type !== x.type)
|
|
174
176
|
continue;
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
+
const A = We(i, x), g = Math.abs(i.angle - x.angle);
|
|
178
|
+
A < n && g < o && A < y && (y = A, b = f);
|
|
177
179
|
}
|
|
178
|
-
|
|
180
|
+
b >= 0 && (r++, s.add(b));
|
|
179
181
|
}
|
|
180
|
-
const
|
|
181
|
-
return
|
|
182
|
+
const a = Math.min(e.minutiae.length, t.minutiae.length);
|
|
183
|
+
return a > 0 ? r / a : 0;
|
|
182
184
|
}
|
|
183
|
-
async function
|
|
185
|
+
async function Ke(e, t) {
|
|
184
186
|
const r = JSON.stringify(e), n = await ue(r);
|
|
185
187
|
return {
|
|
186
188
|
id: `fp_${Date.now()}_${ye()}`,
|
|
@@ -191,65 +193,65 @@ async function Ue(e, t) {
|
|
|
191
193
|
hash: n
|
|
192
194
|
};
|
|
193
195
|
}
|
|
194
|
-
function
|
|
196
|
+
function Ge(e) {
|
|
195
197
|
return JSON.parse(atob(e.templateData));
|
|
196
198
|
}
|
|
197
|
-
function
|
|
198
|
-
const r = e.width, n = e.height,
|
|
199
|
-
let
|
|
200
|
-
for (let
|
|
201
|
-
for (let
|
|
202
|
-
for (let
|
|
203
|
-
let
|
|
204
|
-
for (let
|
|
205
|
-
const h = Math.round(
|
|
206
|
-
h >= 0 && h < r &&
|
|
199
|
+
function Je(e, t = "left") {
|
|
200
|
+
const r = e.width, n = e.height, o = ce(e), s = Ae(o, r, n);
|
|
201
|
+
let a = { cx: r / 2, cy: n / 2, r: Math.min(r, n) * 0.08, score: 1 / 0 };
|
|
202
|
+
for (let I = Math.round(n * 0.3); I < Math.round(n * 0.7); I += 2)
|
|
203
|
+
for (let L = Math.round(r * 0.3); L < Math.round(r * 0.7); L += 2)
|
|
204
|
+
for (let p = Math.round(Math.min(r, n) * 0.04); p < Math.round(Math.min(r, n) * 0.15); p += 2) {
|
|
205
|
+
let C = 0, S = 0;
|
|
206
|
+
for (let u = 0; u < Math.PI * 2; u += 0.3) {
|
|
207
|
+
const h = Math.round(L + p * Math.cos(u)), R = Math.round(I + p * Math.sin(u));
|
|
208
|
+
h >= 0 && h < r && R >= 0 && R < n && (C += s[R * r + h], S++);
|
|
207
209
|
}
|
|
208
|
-
const
|
|
209
|
-
w <
|
|
210
|
+
const v = S > 0 ? C / S : 255, l = s[I * r + L], w = v * 0.5 + l * 0.5;
|
|
211
|
+
w < a.score && (a = { cx: L, cy: I, r: p, score: w });
|
|
210
212
|
}
|
|
211
|
-
const
|
|
212
|
-
cx:
|
|
213
|
-
cy:
|
|
214
|
-
r: Math.min(
|
|
215
|
-
},
|
|
216
|
-
for (let
|
|
217
|
-
const
|
|
218
|
-
if (
|
|
219
|
-
const
|
|
220
|
-
f.push(w >
|
|
213
|
+
const i = a.r * 3, y = {
|
|
214
|
+
cx: a.cx,
|
|
215
|
+
cy: a.cy,
|
|
216
|
+
r: Math.min(i, Math.min(r, n) * 0.4)
|
|
217
|
+
}, b = 256, f = [];
|
|
218
|
+
for (let I = 0; I < b; I++) {
|
|
219
|
+
const L = I / b * Math.PI * 2, p = a.r + (y.r - a.r) * 0.5, C = Math.round(a.cx + p * Math.cos(L)), S = Math.round(a.cy + p * Math.sin(L));
|
|
220
|
+
if (C >= 0 && C < r && S >= 0 && S < n) {
|
|
221
|
+
const v = Math.round(a.cx + p * Math.cos(L + 0.1)), l = Math.round(a.cy + p * Math.sin(L + 0.1)), w = s[S * r + C], u = v >= 0 && v < r && l >= 0 && l < n ? s[l * r + v] : w;
|
|
222
|
+
f.push(w > u ? 1 : 0);
|
|
221
223
|
} else
|
|
222
224
|
f.push(0);
|
|
223
225
|
}
|
|
224
|
-
const
|
|
226
|
+
const x = f.join(""), A = Math.PI * a.r ** 2, g = Math.min(1, Math.max(0, A / (r * n) * 100));
|
|
225
227
|
return {
|
|
226
|
-
irisCode:
|
|
227
|
-
pupil:
|
|
228
|
-
iris:
|
|
229
|
-
quality:
|
|
228
|
+
irisCode: x,
|
|
229
|
+
pupil: a,
|
|
230
|
+
iris: y,
|
|
231
|
+
quality: g,
|
|
230
232
|
eye: t
|
|
231
233
|
};
|
|
232
234
|
}
|
|
233
|
-
function
|
|
235
|
+
function Ye(e, t) {
|
|
234
236
|
if (!e.irisCode || !t.irisCode)
|
|
235
237
|
return 0;
|
|
236
238
|
const r = Math.min(e.irisCode.length, t.irisCode.length);
|
|
237
239
|
if (r === 0)
|
|
238
240
|
return 0;
|
|
239
|
-
let n = 0,
|
|
240
|
-
for (let
|
|
241
|
-
let
|
|
242
|
-
for (let
|
|
243
|
-
const
|
|
244
|
-
e.irisCode[
|
|
241
|
+
let n = 0, o = r;
|
|
242
|
+
for (let a = -8; a <= 8; a++) {
|
|
243
|
+
let i = 0;
|
|
244
|
+
for (let y = 0; y < r; y++) {
|
|
245
|
+
const b = (y + a + r) % r;
|
|
246
|
+
e.irisCode[y] !== t.irisCode[b] && i++;
|
|
245
247
|
}
|
|
246
|
-
|
|
248
|
+
i < o && (o = i);
|
|
247
249
|
}
|
|
248
|
-
n =
|
|
249
|
-
const
|
|
250
|
-
return Math.max(0, 1 -
|
|
250
|
+
n = o;
|
|
251
|
+
const s = n / r;
|
|
252
|
+
return Math.max(0, 1 - s * 2.5);
|
|
251
253
|
}
|
|
252
|
-
async function
|
|
254
|
+
async function Ze(e, t) {
|
|
253
255
|
const r = JSON.stringify(e), n = await ue(r);
|
|
254
256
|
return {
|
|
255
257
|
id: `iris_${Date.now()}_${ye()}`,
|
|
@@ -260,59 +262,59 @@ async function Ke(e, t) {
|
|
|
260
262
|
hash: n
|
|
261
263
|
};
|
|
262
264
|
}
|
|
263
|
-
function
|
|
265
|
+
function Xe(e) {
|
|
264
266
|
return JSON.parse(atob(e.templateData));
|
|
265
267
|
}
|
|
266
268
|
function he(e) {
|
|
267
|
-
const t = e.width, r = e.height, n = e.data,
|
|
268
|
-
for (let
|
|
269
|
-
const w =
|
|
270
|
-
|
|
269
|
+
const t = e.width, r = e.height, n = e.data, o = new Uint8Array(t * r);
|
|
270
|
+
for (let l = 0; l < t * r; l++) {
|
|
271
|
+
const w = l * 4, u = n[w], h = n[w + 1], R = n[w + 2], G = 0.299 * u + 0.587 * h + 0.114 * R, J = 128 - 0.169 * u - 0.331 * h + 0.5 * R, W = 128 + 0.5 * u - 0.419 * h - 0.081 * R;
|
|
272
|
+
J >= 77 && J <= 127 && W >= 133 && W <= 173 && G > 80 && (o[l] = 1);
|
|
271
273
|
}
|
|
272
|
-
let
|
|
273
|
-
for (let
|
|
274
|
+
let s = t, a = r, i = 0, y = 0, b = 0;
|
|
275
|
+
for (let l = 0; l < r; l++)
|
|
274
276
|
for (let w = 0; w < t; w++)
|
|
275
|
-
|
|
276
|
-
const f =
|
|
277
|
-
if (f < t * 0.1 ||
|
|
277
|
+
o[l * t + w] && (b++, w < s && (s = w), w > i && (i = w), l < a && (a = l), l > y && (y = l));
|
|
278
|
+
const f = i - s, x = y - a;
|
|
279
|
+
if (f < t * 0.1 || x < r * 0.1)
|
|
278
280
|
return null;
|
|
279
|
-
const
|
|
280
|
-
for (let
|
|
281
|
+
const A = { x: s, y: a, width: f, height: x }, g = [], I = ce(e), L = Math.max(1, Math.floor(f / 8)), p = Math.max(1, Math.floor(x / 16));
|
|
282
|
+
for (let l = 0; l < 16; l++)
|
|
281
283
|
for (let w = 0; w < 8; w++) {
|
|
282
|
-
const
|
|
283
|
-
|
|
284
|
+
const u = s + w * L + Math.floor(L / 2), h = a + l * p + Math.floor(p / 2);
|
|
285
|
+
u < t && h < r ? g.push(I[h * t + u] / 255) : g.push(0);
|
|
284
286
|
}
|
|
285
|
-
const
|
|
286
|
-
for (let
|
|
287
|
-
const w =
|
|
288
|
-
|
|
289
|
-
x: (
|
|
290
|
-
y: (
|
|
287
|
+
const C = [], S = { x: s + f / 2, y: a + x / 2 };
|
|
288
|
+
for (let l = 0; l < 68; l++) {
|
|
289
|
+
const w = l / 68 * Math.PI * 2, u = f * 0.4 * Math.cos(w), h = x * 0.45 * Math.sin(w);
|
|
290
|
+
C.push({
|
|
291
|
+
x: (S.x + u) / t,
|
|
292
|
+
y: (S.y + h) / r
|
|
291
293
|
});
|
|
292
294
|
}
|
|
293
|
-
const
|
|
295
|
+
const v = Math.min(1, b / (f * x) * 2);
|
|
294
296
|
return {
|
|
295
|
-
embedding:
|
|
296
|
-
boundingBox:
|
|
297
|
-
landmarks:
|
|
297
|
+
embedding: g,
|
|
298
|
+
boundingBox: A,
|
|
299
|
+
landmarks: C,
|
|
298
300
|
headPose: { yaw: 0, pitch: 0, roll: 0 },
|
|
299
|
-
quality:
|
|
301
|
+
quality: v
|
|
300
302
|
};
|
|
301
303
|
}
|
|
302
304
|
function Te(e, t) {
|
|
303
305
|
if (e.embedding.length !== t.embedding.length)
|
|
304
306
|
return 0;
|
|
305
|
-
let r = 0, n = 0,
|
|
306
|
-
for (let
|
|
307
|
-
r += e.embedding[
|
|
308
|
-
const
|
|
309
|
-
return
|
|
307
|
+
let r = 0, n = 0, o = 0;
|
|
308
|
+
for (let a = 0; a < e.embedding.length; a++)
|
|
309
|
+
r += e.embedding[a] * t.embedding[a], n += e.embedding[a] ** 2, o += t.embedding[a] ** 2;
|
|
310
|
+
const s = Math.sqrt(n) * Math.sqrt(o);
|
|
311
|
+
return s > 0 ? (r / s + 1) / 2 : 0;
|
|
310
312
|
}
|
|
311
|
-
function
|
|
313
|
+
function Qe(e, t) {
|
|
312
314
|
const r = he(e), n = he(t);
|
|
313
315
|
return !r || !n ? { similarity: 0, cameraFeatures: r, refFeatures: n } : { similarity: Te(r, n), cameraFeatures: r, refFeatures: n };
|
|
314
316
|
}
|
|
315
|
-
async function
|
|
317
|
+
async function Ve(e, t) {
|
|
316
318
|
const r = JSON.stringify(e), n = await ue(r);
|
|
317
319
|
return {
|
|
318
320
|
id: `face_${Date.now()}_${ye()}`,
|
|
@@ -323,10 +325,10 @@ async function Ze(e, t) {
|
|
|
323
325
|
hash: n
|
|
324
326
|
};
|
|
325
327
|
}
|
|
326
|
-
function
|
|
328
|
+
function et(e) {
|
|
327
329
|
return JSON.parse(atob(e.templateData));
|
|
328
330
|
}
|
|
329
|
-
function
|
|
331
|
+
function zt() {
|
|
330
332
|
const e = [
|
|
331
333
|
"blink",
|
|
332
334
|
"smile",
|
|
@@ -334,7 +336,7 @@ function It() {
|
|
|
334
336
|
"turn-right",
|
|
335
337
|
"nod",
|
|
336
338
|
"raise-eyebrows"
|
|
337
|
-
], t = e[
|
|
339
|
+
], t = e[Be(e.length)];
|
|
338
340
|
return { type: t, instruction: {
|
|
339
341
|
blink: "Please blink your eyes",
|
|
340
342
|
smile: "Please smile",
|
|
@@ -348,17 +350,17 @@ function Ie(e, t = 0.02) {
|
|
|
348
350
|
if (e.length < 2)
|
|
349
351
|
return { isLive: !1, confidence: 0, motionScore: 0 };
|
|
350
352
|
let r = 0;
|
|
351
|
-
for (let
|
|
352
|
-
const
|
|
353
|
-
let
|
|
354
|
-
for (let f = 0; f <
|
|
355
|
-
|
|
356
|
-
r +=
|
|
353
|
+
for (let a = 1; a < e.length; a++) {
|
|
354
|
+
const i = ce(e[a - 1]), y = ce(e[a]);
|
|
355
|
+
let b = 0;
|
|
356
|
+
for (let f = 0; f < i.length; f++)
|
|
357
|
+
b += Math.abs(i[f] - y[f]);
|
|
358
|
+
r += b / (i.length * 255);
|
|
357
359
|
}
|
|
358
|
-
const n = r / (e.length - 1),
|
|
359
|
-
return { isLive:
|
|
360
|
+
const n = r / (e.length - 1), o = n > t, s = Math.min(1, n / (t * 3));
|
|
361
|
+
return { isLive: o, confidence: s, motionScore: n };
|
|
360
362
|
}
|
|
361
|
-
function
|
|
363
|
+
function Ce() {
|
|
362
364
|
return {
|
|
363
365
|
userAgent: navigator.userAgent,
|
|
364
366
|
platform: navigator.platform,
|
|
@@ -370,14 +372,14 @@ function De() {
|
|
|
370
372
|
};
|
|
371
373
|
}
|
|
372
374
|
async function de() {
|
|
373
|
-
const e =
|
|
375
|
+
const e = Ce(), t = JSON.stringify(e);
|
|
374
376
|
return ue(t);
|
|
375
377
|
}
|
|
376
|
-
function
|
|
378
|
+
function De() {
|
|
377
379
|
return typeof window < "u" && !!window.PublicKeyCredential;
|
|
378
380
|
}
|
|
379
|
-
async function
|
|
380
|
-
if (!
|
|
381
|
+
async function tt() {
|
|
382
|
+
if (!De())
|
|
381
383
|
return !1;
|
|
382
384
|
try {
|
|
383
385
|
return await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable();
|
|
@@ -385,7 +387,7 @@ async function Xe() {
|
|
|
385
387
|
return !1;
|
|
386
388
|
}
|
|
387
389
|
}
|
|
388
|
-
async function
|
|
390
|
+
async function rt(e) {
|
|
389
391
|
const t = {
|
|
390
392
|
rp: { name: e.rpName, id: e.rpId },
|
|
391
393
|
user: {
|
|
@@ -401,21 +403,21 @@ async function Qe(e) {
|
|
|
401
403
|
// RS256
|
|
402
404
|
],
|
|
403
405
|
authenticatorSelection: {
|
|
404
|
-
authenticatorAttachment: "platform",
|
|
405
|
-
userVerification: "required",
|
|
406
|
-
residentKey: "preferred"
|
|
406
|
+
authenticatorAttachment: e.authenticatorAttachment ?? "platform",
|
|
407
|
+
userVerification: e.userVerification ?? "required",
|
|
408
|
+
residentKey: e.residentKey ?? "preferred"
|
|
407
409
|
},
|
|
408
410
|
timeout: e.timeout ?? 6e4,
|
|
409
|
-
attestation: "none"
|
|
411
|
+
attestation: e.attestation ?? "none"
|
|
410
412
|
};
|
|
411
413
|
return await navigator.credentials.create({ publicKey: t });
|
|
412
414
|
}
|
|
413
|
-
async function
|
|
415
|
+
async function nt(e) {
|
|
414
416
|
const t = {
|
|
415
417
|
rpId: e.rpId,
|
|
416
418
|
challenge: e.challenge,
|
|
417
419
|
allowCredentials: e.allowCredentials,
|
|
418
|
-
userVerification: "required",
|
|
420
|
+
userVerification: e.userVerification ?? "required",
|
|
419
421
|
timeout: e.timeout ?? 6e4
|
|
420
422
|
};
|
|
421
423
|
return await navigator.credentials.get({ publicKey: t });
|
|
@@ -423,140 +425,141 @@ async function Ve(e) {
|
|
|
423
425
|
async function ge(e, t, r) {
|
|
424
426
|
const n = { "Content-Type": "application/json" };
|
|
425
427
|
r && (n.Authorization = `Bearer ${r}`);
|
|
426
|
-
const
|
|
428
|
+
const o = await fetch(e, {
|
|
427
429
|
method: "POST",
|
|
428
430
|
headers: n,
|
|
429
431
|
body: JSON.stringify(t)
|
|
430
432
|
});
|
|
431
|
-
return
|
|
433
|
+
return o.ok ? o.json() : { verified: !1, message: `Server error: ${o.status}` };
|
|
432
434
|
}
|
|
433
435
|
function re(e, t) {
|
|
434
|
-
var
|
|
436
|
+
var a;
|
|
435
437
|
const r = e.trim().match(/^var\(\s*([^,\s)]+)\s*(?:,\s*(.+))?\)$/);
|
|
436
438
|
if (!r)
|
|
437
439
|
return e;
|
|
438
|
-
const n = (
|
|
440
|
+
const n = (a = r[2]) == null ? void 0 : a.trim();
|
|
439
441
|
if (typeof document > "u" || typeof getComputedStyle > "u")
|
|
440
442
|
return n ? re(n) : e;
|
|
441
|
-
const
|
|
442
|
-
return
|
|
443
|
+
const o = typeof Element < "u" && t instanceof Element && t.isConnected ? t : document.documentElement, s = getComputedStyle(o).getPropertyValue(r[1]).trim();
|
|
444
|
+
return s || (n ? re(n, t) : e);
|
|
443
445
|
}
|
|
444
|
-
const
|
|
446
|
+
const Re = /* @__PURE__ */ Fe(null), Nt = ({ t: e, children: t }) => /* @__PURE__ */ c(Re.Provider, { value: e, children: t });
|
|
445
447
|
function te() {
|
|
446
|
-
|
|
448
|
+
const e = Ee(Re), { t } = ze();
|
|
449
|
+
return { t: e ?? t };
|
|
447
450
|
}
|
|
448
|
-
const
|
|
451
|
+
const it = { sm: 200, md: 280, lg: 380 }, Lt = (e) => {
|
|
449
452
|
const {
|
|
450
453
|
mode: t,
|
|
451
454
|
enrolledTemplates: r = [],
|
|
452
455
|
fingerPosition: n = "right-index",
|
|
453
|
-
onEnroll:
|
|
454
|
-
onVerify:
|
|
455
|
-
onStatusChange:
|
|
456
|
-
onError:
|
|
457
|
-
className:
|
|
458
|
-
size:
|
|
456
|
+
onEnroll: o,
|
|
457
|
+
onVerify: s,
|
|
458
|
+
onStatusChange: a,
|
|
459
|
+
onError: i,
|
|
460
|
+
className: y,
|
|
461
|
+
size: b = "md",
|
|
459
462
|
label: f,
|
|
460
|
-
showQuality:
|
|
461
|
-
showMinutiae:
|
|
462
|
-
instructionText:
|
|
463
|
-
cameraFacing:
|
|
464
|
-
...
|
|
465
|
-
} = e, { t:
|
|
463
|
+
showQuality: x = !0,
|
|
464
|
+
showMinutiae: A = !1,
|
|
465
|
+
instructionText: g,
|
|
466
|
+
cameraFacing: I = "environment",
|
|
467
|
+
...L
|
|
468
|
+
} = e, { t: p } = te(), C = fe(L), S = it[b], v = V(null), l = V(null), w = V(null), [u, h] = j("idle"), [R, G] = j(0), [J, W] = j(null), [O, Y] = j(0), [_, $] = j(""), B = K(
|
|
466
469
|
(E) => {
|
|
467
|
-
h(E),
|
|
470
|
+
h(E), a == null || a(E);
|
|
468
471
|
},
|
|
469
|
-
[
|
|
470
|
-
), F =
|
|
472
|
+
[a]
|
|
473
|
+
), F = K(async () => {
|
|
471
474
|
try {
|
|
472
|
-
const E = await pe(
|
|
473
|
-
w.current = E,
|
|
475
|
+
const E = await pe(I);
|
|
476
|
+
w.current = E, v.current && (v.current.srcObject = E, await v.current.play()), B("idle"), $(p("security.fingerprint.placeFingerPrompt", "Place your finger on the scanner"));
|
|
474
477
|
} catch (E) {
|
|
475
|
-
|
|
478
|
+
i == null || i(E instanceof Error ? E : new Error(String(E))), $(p("security.fingerprint.cameraError", "Camera access denied")), B("error");
|
|
476
479
|
}
|
|
477
|
-
}, [
|
|
480
|
+
}, [I, p, B, i]), q = K(() => {
|
|
478
481
|
var E;
|
|
479
|
-
(E = w.current) == null || E.getTracks().forEach((
|
|
482
|
+
(E = w.current) == null || E.getTracks().forEach((z) => z.stop()), w.current = null;
|
|
480
483
|
}, []);
|
|
481
|
-
ne(() => (F(),
|
|
482
|
-
const
|
|
483
|
-
if (!(!
|
|
484
|
-
B("scanning"), $(
|
|
484
|
+
ne(() => (F(), q), [F, q]);
|
|
485
|
+
const H = K(async () => {
|
|
486
|
+
if (!(!v.current || u === "processing" || u === "success")) {
|
|
487
|
+
B("scanning"), $(p("security.fingerprint.scanning", "Scanning…"));
|
|
485
488
|
try {
|
|
486
|
-
const { imageData: E } = le(
|
|
487
|
-
B("processing"), $(
|
|
488
|
-
const
|
|
489
|
-
if (
|
|
490
|
-
$(
|
|
489
|
+
const { imageData: E } = le(v.current);
|
|
490
|
+
B("processing"), $(p("security.fingerprint.processing", "Processing fingerprint…"));
|
|
491
|
+
const z = Ue(E);
|
|
492
|
+
if (W(z), G(z.quality), z.quality < 0.2) {
|
|
493
|
+
$(p("security.fingerprint.lowQuality", "Low quality — try again")), B("idle");
|
|
491
494
|
return;
|
|
492
495
|
}
|
|
493
496
|
if (t === "enroll") {
|
|
494
|
-
const
|
|
495
|
-
|
|
497
|
+
const D = await Ke(z, f ?? n);
|
|
498
|
+
o == null || o(D, z), $(p("security.fingerprint.enrolled", "Fingerprint enrolled successfully")), B("success");
|
|
496
499
|
} else {
|
|
497
|
-
let
|
|
500
|
+
let D = 0;
|
|
498
501
|
for (const d of r) {
|
|
499
|
-
const
|
|
500
|
-
N >
|
|
502
|
+
const k = Ge(d), N = qe(z, k);
|
|
503
|
+
N > D && (D = N);
|
|
501
504
|
}
|
|
502
|
-
const
|
|
503
|
-
success:
|
|
504
|
-
confidence:
|
|
505
|
+
const T = D >= C.matchThreshold, m = {
|
|
506
|
+
success: T,
|
|
507
|
+
confidence: D,
|
|
505
508
|
method: "fingerprint",
|
|
506
509
|
timestamp: Date.now(),
|
|
507
510
|
duration: 0,
|
|
508
|
-
payload: btoa(JSON.stringify(
|
|
511
|
+
payload: btoa(JSON.stringify(z))
|
|
509
512
|
};
|
|
510
|
-
if (
|
|
511
|
-
const d = await de(),
|
|
512
|
-
|
|
513
|
+
if (T && C.verifyEndpoint) {
|
|
514
|
+
const d = await de(), k = await ge(
|
|
515
|
+
C.verifyEndpoint,
|
|
513
516
|
{
|
|
514
517
|
method: "fingerprint",
|
|
515
|
-
templateData:
|
|
516
|
-
matchScore:
|
|
518
|
+
templateData: m.payload,
|
|
519
|
+
matchScore: D,
|
|
517
520
|
deviceFingerprint: d
|
|
518
521
|
},
|
|
519
|
-
|
|
522
|
+
C.authToken
|
|
520
523
|
);
|
|
521
|
-
|
|
524
|
+
m.success = k.verified;
|
|
522
525
|
}
|
|
523
|
-
|
|
526
|
+
m.success ? ($(p("security.fingerprint.verified", "Fingerprint verified")), B("success")) : (Y((d) => d + 1), O + 1 >= C.maxRetries ? ($(p("security.fingerprint.maxAttempts", "Maximum attempts reached")), B("failure")) : ($(p("security.fingerprint.noMatch", "No match — try again")), B("idle"))), s == null || s(m);
|
|
524
527
|
}
|
|
525
528
|
} catch (E) {
|
|
526
|
-
|
|
529
|
+
i == null || i(E instanceof Error ? E : new Error(String(E))), $(p("security.fingerprint.error", "Scan error — try again")), B("error");
|
|
527
530
|
}
|
|
528
531
|
}
|
|
529
532
|
}, [
|
|
530
|
-
|
|
533
|
+
u,
|
|
531
534
|
t,
|
|
532
535
|
r,
|
|
533
|
-
|
|
534
|
-
|
|
536
|
+
C,
|
|
537
|
+
p,
|
|
535
538
|
B,
|
|
539
|
+
o,
|
|
536
540
|
s,
|
|
537
541
|
i,
|
|
538
|
-
a,
|
|
539
542
|
f,
|
|
540
543
|
n,
|
|
541
|
-
|
|
544
|
+
O
|
|
542
545
|
]);
|
|
543
546
|
ne(() => {
|
|
544
|
-
if (!
|
|
547
|
+
if (!A || !J || !l.current)
|
|
545
548
|
return;
|
|
546
|
-
const E =
|
|
549
|
+
const E = l.current.getContext("2d");
|
|
547
550
|
if (!E)
|
|
548
551
|
return;
|
|
549
|
-
E.clearRect(0, 0,
|
|
550
|
-
const
|
|
551
|
-
|
|
552
|
-
E.beginPath(), E.arc(
|
|
552
|
+
E.clearRect(0, 0, S, S);
|
|
553
|
+
const z = re("var(--nice-success, #10b981)", E.canvas), D = re("var(--nice-warning, #f59e0b)", E.canvas);
|
|
554
|
+
J.minutiae.forEach((T) => {
|
|
555
|
+
E.beginPath(), E.arc(T.x * S, T.y * S, 2, 0, Math.PI * 2), E.fillStyle = T.type === "ending" ? z : D, E.fill(), E.beginPath(), E.moveTo(T.x * S, T.y * S), E.lineTo(T.x * S + Math.cos(T.angle) * 8, T.y * S + Math.sin(T.angle) * 8), E.strokeStyle = E.fillStyle, E.lineWidth = 1, E.stroke();
|
|
553
556
|
});
|
|
554
|
-
}, [
|
|
555
|
-
const Q =
|
|
557
|
+
}, [J, A, S]);
|
|
558
|
+
const Q = u === "success" ? "var(--security-success)" : u === "failure" || u === "error" ? "var(--security-error)" : u === "scanning" || u === "processing" ? "var(--security-biometric)" : "var(--security-border)";
|
|
556
559
|
return /* @__PURE__ */ P(
|
|
557
560
|
"div",
|
|
558
561
|
{
|
|
559
|
-
className:
|
|
562
|
+
className: y,
|
|
560
563
|
style: { display: "inline-flex", flexDirection: "column", alignItems: "center", gap: 12 },
|
|
561
564
|
children: [
|
|
562
565
|
f && /* @__PURE__ */ c("div", { style: { fontSize: 14, fontWeight: 600, color: "var(--security-text)" }, children: f }),
|
|
@@ -564,31 +567,31 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
564
567
|
"div",
|
|
565
568
|
{
|
|
566
569
|
style: {
|
|
567
|
-
width:
|
|
568
|
-
height:
|
|
570
|
+
width: S,
|
|
571
|
+
height: S,
|
|
569
572
|
position: "relative",
|
|
570
573
|
borderRadius: "var(--security-radius-lg)",
|
|
571
574
|
overflow: "hidden",
|
|
572
575
|
border: `3px solid ${Q}`,
|
|
573
|
-
boxShadow:
|
|
576
|
+
boxShadow: u === "scanning" ? `0 0 20px ${Q}` : "var(--security-shadow)",
|
|
574
577
|
transition: "border-color 0.3s, box-shadow 0.3s"
|
|
575
578
|
},
|
|
576
579
|
children: [
|
|
577
580
|
/* @__PURE__ */ c(
|
|
578
581
|
"video",
|
|
579
582
|
{
|
|
580
|
-
ref:
|
|
583
|
+
ref: v,
|
|
581
584
|
style: { width: "100%", height: "100%", objectFit: "cover" },
|
|
582
585
|
playsInline: !0,
|
|
583
586
|
muted: !0
|
|
584
587
|
}
|
|
585
588
|
),
|
|
586
|
-
|
|
589
|
+
A && /* @__PURE__ */ c(
|
|
587
590
|
"canvas",
|
|
588
591
|
{
|
|
589
|
-
ref:
|
|
590
|
-
width:
|
|
591
|
-
height:
|
|
592
|
+
ref: l,
|
|
593
|
+
width: S,
|
|
594
|
+
height: S,
|
|
592
595
|
style: { position: "absolute", inset: 0, pointerEvents: "none" }
|
|
593
596
|
}
|
|
594
597
|
),
|
|
@@ -634,7 +637,7 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
634
637
|
]
|
|
635
638
|
}
|
|
636
639
|
),
|
|
637
|
-
(
|
|
640
|
+
(u === "scanning" || u === "processing") && /* @__PURE__ */ c(
|
|
638
641
|
"div",
|
|
639
642
|
{
|
|
640
643
|
style: {
|
|
@@ -663,11 +666,11 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
663
666
|
]
|
|
664
667
|
}
|
|
665
668
|
),
|
|
666
|
-
|
|
669
|
+
x && R > 0 && /* @__PURE__ */ c(
|
|
667
670
|
"div",
|
|
668
671
|
{
|
|
669
672
|
style: {
|
|
670
|
-
width:
|
|
673
|
+
width: S,
|
|
671
674
|
height: 4,
|
|
672
675
|
background: "var(--security-bg-panel)",
|
|
673
676
|
borderRadius: 2,
|
|
@@ -677,9 +680,9 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
677
680
|
"div",
|
|
678
681
|
{
|
|
679
682
|
style: {
|
|
680
|
-
width: `${
|
|
683
|
+
width: `${R * 100}%`,
|
|
681
684
|
height: "100%",
|
|
682
|
-
background:
|
|
685
|
+
background: R > 0.6 ? "var(--security-success)" : R > 0.3 ? "var(--security-warning)" : "var(--security-error)",
|
|
683
686
|
transition: "width 0.3s"
|
|
684
687
|
}
|
|
685
688
|
}
|
|
@@ -695,14 +698,14 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
695
698
|
textAlign: "center",
|
|
696
699
|
minHeight: 20
|
|
697
700
|
},
|
|
698
|
-
children:
|
|
701
|
+
children: g ?? _
|
|
699
702
|
}
|
|
700
703
|
),
|
|
701
|
-
|
|
704
|
+
u !== "success" && u !== "failure" && /* @__PURE__ */ c(
|
|
702
705
|
"button",
|
|
703
706
|
{
|
|
704
|
-
onClick:
|
|
705
|
-
disabled:
|
|
707
|
+
onClick: H,
|
|
708
|
+
disabled: u === "scanning" || u === "processing",
|
|
706
709
|
style: {
|
|
707
710
|
padding: "10px 24px",
|
|
708
711
|
fontSize: 14,
|
|
@@ -712,16 +715,16 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
712
715
|
border: "none",
|
|
713
716
|
borderRadius: "var(--security-radius)",
|
|
714
717
|
cursor: "pointer",
|
|
715
|
-
opacity:
|
|
718
|
+
opacity: u === "scanning" || u === "processing" ? 0.6 : 1
|
|
716
719
|
},
|
|
717
|
-
children: t === "enroll" ?
|
|
720
|
+
children: t === "enroll" ? p("security.fingerprint.captureBtn", "Capture Fingerprint") : p("security.fingerprint.verifyBtn", "Verify Fingerprint")
|
|
718
721
|
}
|
|
719
722
|
),
|
|
720
|
-
(
|
|
723
|
+
(u === "failure" || u === "error") && /* @__PURE__ */ c(
|
|
721
724
|
"button",
|
|
722
725
|
{
|
|
723
726
|
onClick: () => {
|
|
724
|
-
|
|
727
|
+
Y(0), B("idle"), $("");
|
|
725
728
|
},
|
|
726
729
|
style: {
|
|
727
730
|
padding: "8px 20px",
|
|
@@ -732,149 +735,149 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
732
735
|
borderRadius: "var(--security-radius)",
|
|
733
736
|
cursor: "pointer"
|
|
734
737
|
},
|
|
735
|
-
children:
|
|
738
|
+
children: p("security.common.retry", "Try Again")
|
|
736
739
|
}
|
|
737
740
|
),
|
|
738
741
|
/* @__PURE__ */ c("style", { children: "@keyframes spin { to { transform: rotate(360deg); } }" })
|
|
739
742
|
]
|
|
740
743
|
}
|
|
741
744
|
);
|
|
742
|
-
},
|
|
745
|
+
}, st = { sm: 220, md: 300, lg: 400 }, $t = (e) => {
|
|
743
746
|
const {
|
|
744
747
|
mode: t,
|
|
745
748
|
enrolledTemplates: r = [],
|
|
746
749
|
eye: n = "right",
|
|
747
|
-
onEnroll:
|
|
748
|
-
onVerify:
|
|
749
|
-
onStatusChange:
|
|
750
|
-
onError:
|
|
751
|
-
className:
|
|
752
|
-
size:
|
|
750
|
+
onEnroll: o,
|
|
751
|
+
onVerify: s,
|
|
752
|
+
onStatusChange: a,
|
|
753
|
+
onError: i,
|
|
754
|
+
className: y,
|
|
755
|
+
size: b = "md",
|
|
753
756
|
label: f,
|
|
754
|
-
showQuality:
|
|
755
|
-
showSegmentation:
|
|
756
|
-
showGuide:
|
|
757
|
-
instructionText:
|
|
758
|
-
...
|
|
759
|
-
} = e, { t:
|
|
760
|
-
(
|
|
761
|
-
|
|
757
|
+
showQuality: x = !0,
|
|
758
|
+
showSegmentation: A = !0,
|
|
759
|
+
showGuide: g = !0,
|
|
760
|
+
instructionText: I,
|
|
761
|
+
...L
|
|
762
|
+
} = e, { t: p } = te(), C = fe(L), S = st[b], v = V(null), l = V(null), w = V(null), u = V([]), [h, R] = j("idle"), [G, J] = j(0), [W, O] = j(null), [Y, _] = j(0), [$, B] = j(""), F = K(
|
|
763
|
+
(z) => {
|
|
764
|
+
R(z), a == null || a(z);
|
|
762
765
|
},
|
|
763
|
-
[
|
|
764
|
-
),
|
|
766
|
+
[a]
|
|
767
|
+
), q = K(async () => {
|
|
765
768
|
try {
|
|
766
|
-
const
|
|
767
|
-
w.current =
|
|
768
|
-
} catch (
|
|
769
|
-
|
|
769
|
+
const z = await pe("user");
|
|
770
|
+
w.current = z, v.current && (v.current.srcObject = z, await v.current.play()), F("idle"), B(p("security.iris.alignEyePrompt", "Align your eye with the circle"));
|
|
771
|
+
} catch (z) {
|
|
772
|
+
i == null || i(z instanceof Error ? z : new Error(String(z))), B(p("security.iris.cameraError", "Camera access denied")), F("error");
|
|
770
773
|
}
|
|
771
|
-
}, [
|
|
772
|
-
var
|
|
773
|
-
(
|
|
774
|
+
}, [p, F, i]), H = K(() => {
|
|
775
|
+
var z;
|
|
776
|
+
(z = w.current) == null || z.getTracks().forEach((D) => D.stop()), w.current = null;
|
|
774
777
|
}, []);
|
|
775
|
-
ne(() => (
|
|
776
|
-
const Q =
|
|
777
|
-
if (!(!
|
|
778
|
-
F("scanning"), B(
|
|
778
|
+
ne(() => (q(), H), [q, H]);
|
|
779
|
+
const Q = K(async () => {
|
|
780
|
+
if (!(!v.current || h === "processing" || h === "success")) {
|
|
781
|
+
F("scanning"), B(p("security.iris.scanning", "Scanning iris…"));
|
|
779
782
|
try {
|
|
780
|
-
const
|
|
781
|
-
for (let
|
|
782
|
-
const { imageData: d } = le(
|
|
783
|
-
|
|
783
|
+
const z = [];
|
|
784
|
+
for (let m = 0; m < 5; m++) {
|
|
785
|
+
const { imageData: d } = le(v.current);
|
|
786
|
+
z.push(d), await new Promise((k) => setTimeout(k, 200));
|
|
784
787
|
}
|
|
785
|
-
if (
|
|
788
|
+
if (u.current = z, C.livenessDetection && !Ie(z).isLive) {
|
|
786
789
|
B(
|
|
787
|
-
|
|
790
|
+
p("security.iris.notLive", "Liveness check failed — please blink or move slightly")
|
|
788
791
|
), F("idle");
|
|
789
792
|
return;
|
|
790
793
|
}
|
|
791
|
-
F("processing"), B(
|
|
792
|
-
const
|
|
793
|
-
if (!
|
|
794
|
-
B(
|
|
794
|
+
F("processing"), B(p("security.iris.processing", "Processing iris pattern…"));
|
|
795
|
+
const D = z[z.length - 1], T = Je(D, n === "both" ? "left" : n);
|
|
796
|
+
if (!T) {
|
|
797
|
+
B(p("security.iris.noIrisDetected", "No iris detected — adjust position")), F("idle");
|
|
795
798
|
return;
|
|
796
799
|
}
|
|
797
|
-
if (
|
|
798
|
-
B(
|
|
800
|
+
if (O(T), J(T.quality), T.quality < 0.1) {
|
|
801
|
+
B(p("security.iris.lowQuality", "Low quality — move closer")), F("idle");
|
|
799
802
|
return;
|
|
800
803
|
}
|
|
801
|
-
if (
|
|
802
|
-
const
|
|
803
|
-
if (
|
|
804
|
-
|
|
805
|
-
const d =
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
804
|
+
if (A && l.current) {
|
|
805
|
+
const m = l.current.getContext("2d");
|
|
806
|
+
if (m) {
|
|
807
|
+
m.clearRect(0, 0, S, S);
|
|
808
|
+
const d = S / D.width, k = S / D.height;
|
|
809
|
+
m.beginPath(), m.arc(
|
|
810
|
+
T.pupil.cx * d,
|
|
811
|
+
T.pupil.cy * k,
|
|
812
|
+
T.pupil.r * d,
|
|
810
813
|
0,
|
|
811
814
|
Math.PI * 2
|
|
812
|
-
),
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
815
|
+
), m.strokeStyle = re("var(--nice-danger, #ef4444)", m.canvas), m.lineWidth = 2, m.stroke(), m.beginPath(), m.arc(
|
|
816
|
+
T.iris.cx * d,
|
|
817
|
+
T.iris.cy * k,
|
|
818
|
+
T.iris.r * d,
|
|
816
819
|
0,
|
|
817
820
|
Math.PI * 2
|
|
818
|
-
),
|
|
821
|
+
), m.strokeStyle = re("var(--nice-primary, #3b82f6)", m.canvas), m.lineWidth = 2, m.stroke();
|
|
819
822
|
}
|
|
820
823
|
}
|
|
821
824
|
if (t === "enroll") {
|
|
822
|
-
const
|
|
823
|
-
|
|
825
|
+
const m = await Ze(T, f ?? `${n} eye`);
|
|
826
|
+
o == null || o(m, T), B(p("security.iris.enrolled", "Iris enrolled successfully")), F("success");
|
|
824
827
|
} else {
|
|
825
|
-
let
|
|
828
|
+
let m = 0;
|
|
826
829
|
for (const N of r) {
|
|
827
|
-
const M =
|
|
828
|
-
|
|
830
|
+
const M = Xe(N), U = Ye(T, M);
|
|
831
|
+
U > m && (m = U);
|
|
829
832
|
}
|
|
830
|
-
const d =
|
|
833
|
+
const d = m >= C.matchThreshold, k = {
|
|
831
834
|
success: d,
|
|
832
|
-
confidence:
|
|
835
|
+
confidence: m,
|
|
833
836
|
method: "iris",
|
|
834
837
|
timestamp: Date.now(),
|
|
835
838
|
duration: 0,
|
|
836
|
-
livenessPassed:
|
|
837
|
-
payload: btoa(JSON.stringify(
|
|
839
|
+
livenessPassed: C.livenessDetection ? !0 : void 0,
|
|
840
|
+
payload: btoa(JSON.stringify(T))
|
|
838
841
|
};
|
|
839
|
-
if (d &&
|
|
842
|
+
if (d && C.verifyEndpoint) {
|
|
840
843
|
const N = await de(), M = await ge(
|
|
841
|
-
|
|
844
|
+
C.verifyEndpoint,
|
|
842
845
|
{
|
|
843
846
|
method: "iris",
|
|
844
|
-
templateData:
|
|
845
|
-
matchScore:
|
|
847
|
+
templateData: k.payload,
|
|
848
|
+
matchScore: m,
|
|
846
849
|
deviceFingerprint: N
|
|
847
850
|
},
|
|
848
|
-
|
|
851
|
+
C.authToken
|
|
849
852
|
);
|
|
850
|
-
|
|
853
|
+
k.success = M.verified;
|
|
851
854
|
}
|
|
852
|
-
|
|
855
|
+
k.success ? (B(p("security.iris.verified", "Iris verified")), F("success")) : (_((N) => N + 1), Y + 1 >= C.maxRetries ? (B(p("security.iris.maxAttempts", "Maximum attempts reached")), F("failure")) : (B(p("security.iris.noMatch", "No match — try again")), F("idle"))), s == null || s(k);
|
|
853
856
|
}
|
|
854
|
-
} catch (
|
|
855
|
-
|
|
857
|
+
} catch (z) {
|
|
858
|
+
i == null || i(z instanceof Error ? z : new Error(String(z))), B(p("security.iris.error", "Scan error")), F("error");
|
|
856
859
|
}
|
|
857
860
|
}
|
|
858
861
|
}, [
|
|
859
862
|
h,
|
|
860
863
|
t,
|
|
861
864
|
r,
|
|
862
|
-
|
|
863
|
-
|
|
865
|
+
C,
|
|
866
|
+
p,
|
|
864
867
|
F,
|
|
868
|
+
o,
|
|
865
869
|
s,
|
|
866
870
|
i,
|
|
867
|
-
a,
|
|
868
871
|
f,
|
|
869
872
|
n,
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
+
Y,
|
|
874
|
+
A,
|
|
875
|
+
S
|
|
873
876
|
]), E = h === "success" ? "var(--security-success)" : h === "failure" || h === "error" ? "var(--security-error)" : h === "scanning" || h === "processing" ? "var(--security-biometric)" : "var(--security-border)";
|
|
874
877
|
return /* @__PURE__ */ P(
|
|
875
878
|
"div",
|
|
876
879
|
{
|
|
877
|
-
className:
|
|
880
|
+
className: y,
|
|
878
881
|
style: { display: "inline-flex", flexDirection: "column", alignItems: "center", gap: 12 },
|
|
879
882
|
children: [
|
|
880
883
|
f && /* @__PURE__ */ c("div", { style: { fontSize: 14, fontWeight: 600, color: "var(--security-text)" }, children: f }),
|
|
@@ -882,8 +885,8 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
882
885
|
"div",
|
|
883
886
|
{
|
|
884
887
|
style: {
|
|
885
|
-
width:
|
|
886
|
-
height:
|
|
888
|
+
width: S,
|
|
889
|
+
height: S,
|
|
887
890
|
position: "relative",
|
|
888
891
|
borderRadius: "50%",
|
|
889
892
|
overflow: "hidden",
|
|
@@ -895,22 +898,22 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
895
898
|
/* @__PURE__ */ c(
|
|
896
899
|
"video",
|
|
897
900
|
{
|
|
898
|
-
ref:
|
|
901
|
+
ref: v,
|
|
899
902
|
style: { width: "100%", height: "100%", objectFit: "cover" },
|
|
900
903
|
playsInline: !0,
|
|
901
904
|
muted: !0
|
|
902
905
|
}
|
|
903
906
|
),
|
|
904
|
-
|
|
907
|
+
A && /* @__PURE__ */ c(
|
|
905
908
|
"canvas",
|
|
906
909
|
{
|
|
907
|
-
ref:
|
|
908
|
-
width:
|
|
909
|
-
height:
|
|
910
|
+
ref: l,
|
|
911
|
+
width: S,
|
|
912
|
+
height: S,
|
|
910
913
|
style: { position: "absolute", inset: 0, pointerEvents: "none" }
|
|
911
914
|
}
|
|
912
915
|
),
|
|
913
|
-
|
|
916
|
+
g && h === "idle" && /* @__PURE__ */ P(
|
|
914
917
|
"svg",
|
|
915
918
|
{
|
|
916
919
|
viewBox: "0 0 100 100",
|
|
@@ -969,7 +972,7 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
969
972
|
"div",
|
|
970
973
|
{
|
|
971
974
|
style: {
|
|
972
|
-
width:
|
|
975
|
+
width: S * 0.7,
|
|
973
976
|
height: 3,
|
|
974
977
|
background: E,
|
|
975
978
|
animation: "irisLineAnim 1.5s ease-in-out infinite",
|
|
@@ -992,14 +995,14 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
992
995
|
textTransform: "uppercase",
|
|
993
996
|
letterSpacing: 1
|
|
994
997
|
},
|
|
995
|
-
children: n === "both" ?
|
|
998
|
+
children: n === "both" ? p("security.iris.bothEyes", "Both eyes") : n === "left" ? p("security.iris.leftEye", "Left eye") : p("security.iris.rightEye", "Right eye")
|
|
996
999
|
}
|
|
997
1000
|
),
|
|
998
|
-
|
|
1001
|
+
x && G > 0 && /* @__PURE__ */ c(
|
|
999
1002
|
"div",
|
|
1000
1003
|
{
|
|
1001
1004
|
style: {
|
|
1002
|
-
width:
|
|
1005
|
+
width: S * 0.6,
|
|
1003
1006
|
height: 4,
|
|
1004
1007
|
background: "var(--security-bg-panel)",
|
|
1005
1008
|
borderRadius: 2,
|
|
@@ -1009,9 +1012,9 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
1009
1012
|
"div",
|
|
1010
1013
|
{
|
|
1011
1014
|
style: {
|
|
1012
|
-
width: `${Math.min(100,
|
|
1015
|
+
width: `${Math.min(100, G * 300)}%`,
|
|
1013
1016
|
height: "100%",
|
|
1014
|
-
background:
|
|
1017
|
+
background: G > 0.3 ? "var(--security-success)" : G > 0.1 ? "var(--security-warning)" : "var(--security-error)",
|
|
1015
1018
|
transition: "width 0.3s"
|
|
1016
1019
|
}
|
|
1017
1020
|
}
|
|
@@ -1027,7 +1030,7 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
1027
1030
|
textAlign: "center",
|
|
1028
1031
|
minHeight: 20
|
|
1029
1032
|
},
|
|
1030
|
-
children:
|
|
1033
|
+
children: I ?? $
|
|
1031
1034
|
}
|
|
1032
1035
|
),
|
|
1033
1036
|
h !== "success" && h !== "failure" && /* @__PURE__ */ c(
|
|
@@ -1046,14 +1049,14 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
1046
1049
|
cursor: "pointer",
|
|
1047
1050
|
opacity: h === "scanning" || h === "processing" ? 0.6 : 1
|
|
1048
1051
|
},
|
|
1049
|
-
children: t === "enroll" ?
|
|
1052
|
+
children: t === "enroll" ? p("security.iris.captureBtn", "Capture Iris") : p("security.iris.verifyBtn", "Verify Iris")
|
|
1050
1053
|
}
|
|
1051
1054
|
),
|
|
1052
1055
|
(h === "failure" || h === "error") && /* @__PURE__ */ c(
|
|
1053
1056
|
"button",
|
|
1054
1057
|
{
|
|
1055
1058
|
onClick: () => {
|
|
1056
|
-
|
|
1059
|
+
_(0), F("idle"), B("");
|
|
1057
1060
|
},
|
|
1058
1061
|
style: {
|
|
1059
1062
|
padding: "8px 20px",
|
|
@@ -1064,151 +1067,156 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
1064
1067
|
borderRadius: "var(--security-radius)",
|
|
1065
1068
|
cursor: "pointer"
|
|
1066
1069
|
},
|
|
1067
|
-
children:
|
|
1070
|
+
children: p("security.common.retry", "Try Again")
|
|
1068
1071
|
}
|
|
1069
1072
|
),
|
|
1070
1073
|
/* @__PURE__ */ c("style", { children: `
|
|
1071
1074
|
@keyframes irisLineAnim {
|
|
1072
|
-
0%, 100% { transform: translateY(-${
|
|
1073
|
-
50% { transform: translateY(${
|
|
1075
|
+
0%, 100% { transform: translateY(-${S * 0.3}px); opacity: 0.3; }
|
|
1076
|
+
50% { transform: translateY(${S * 0.3}px); opacity: 0.8; }
|
|
1074
1077
|
}
|
|
1075
1078
|
` })
|
|
1076
1079
|
]
|
|
1077
1080
|
}
|
|
1078
1081
|
);
|
|
1079
|
-
},
|
|
1082
|
+
}, ot = { sm: 240, md: 320, lg: 440 }, jt = (e) => {
|
|
1080
1083
|
const {
|
|
1081
1084
|
mode: t,
|
|
1082
1085
|
enrolledTemplates: r = [],
|
|
1083
1086
|
referencePhoto: n,
|
|
1084
|
-
onEnroll:
|
|
1085
|
-
onVerify:
|
|
1086
|
-
onStatusChange:
|
|
1087
|
-
onError:
|
|
1088
|
-
className:
|
|
1089
|
-
size:
|
|
1087
|
+
onEnroll: o,
|
|
1088
|
+
onVerify: s,
|
|
1089
|
+
onStatusChange: a,
|
|
1090
|
+
onError: i,
|
|
1091
|
+
className: y,
|
|
1092
|
+
size: b = "md",
|
|
1090
1093
|
label: f,
|
|
1091
|
-
showQuality:
|
|
1092
|
-
showBoundingBox:
|
|
1093
|
-
livenessSteps:
|
|
1094
|
-
showReference:
|
|
1095
|
-
instructionText:
|
|
1096
|
-
...
|
|
1097
|
-
} = e, { t:
|
|
1098
|
-
(
|
|
1099
|
-
|
|
1094
|
+
showQuality: x = !0,
|
|
1095
|
+
showBoundingBox: A = !0,
|
|
1096
|
+
livenessSteps: g = 1,
|
|
1097
|
+
showReference: I = !0,
|
|
1098
|
+
instructionText: L,
|
|
1099
|
+
...p
|
|
1100
|
+
} = e, { t: C } = te(), S = fe(p), v = ot[b], l = V(null), w = V(null), u = V(null), [h, R] = j("idle"), [G, J] = j(0), [W, O] = j(0), [Y, _] = j(""), [$, B] = j(null), [F, q] = j(0), H = K(
|
|
1101
|
+
(m) => {
|
|
1102
|
+
R(m), a == null || a(m);
|
|
1100
1103
|
},
|
|
1101
|
-
[
|
|
1102
|
-
), Q =
|
|
1104
|
+
[a]
|
|
1105
|
+
), Q = K(async () => {
|
|
1103
1106
|
try {
|
|
1104
|
-
const
|
|
1105
|
-
|
|
1106
|
-
} catch (
|
|
1107
|
-
|
|
1107
|
+
const m = await pe("user");
|
|
1108
|
+
u.current = m, l.current && (l.current.srcObject = m, await l.current.play()), H("idle"), _(C("security.face.lookAtCamera", "Look at the camera"));
|
|
1109
|
+
} catch (m) {
|
|
1110
|
+
i == null || i(m instanceof Error ? m : new Error(String(m))), _(C("security.face.cameraError", "Camera access denied")), H("error");
|
|
1108
1111
|
}
|
|
1109
|
-
}, [
|
|
1110
|
-
var
|
|
1111
|
-
(
|
|
1112
|
+
}, [C, H, i]), E = K(() => {
|
|
1113
|
+
var m;
|
|
1114
|
+
(m = u.current) == null || m.getTracks().forEach((d) => d.stop()), u.current = null;
|
|
1112
1115
|
}, []);
|
|
1113
1116
|
ne(() => (Q(), E), [Q, E]);
|
|
1114
|
-
const
|
|
1115
|
-
(
|
|
1117
|
+
const z = K(
|
|
1118
|
+
(m) => {
|
|
1116
1119
|
var ie, ve, be;
|
|
1117
1120
|
const d = (ie = w.current) == null ? void 0 : ie.getContext("2d");
|
|
1118
1121
|
if (!d)
|
|
1119
1122
|
return;
|
|
1120
|
-
const
|
|
1121
|
-
if (d.clearRect(0, 0,
|
|
1123
|
+
const k = w.current.width, N = w.current.height;
|
|
1124
|
+
if (d.clearRect(0, 0, k, N), !m || !A)
|
|
1122
1125
|
return;
|
|
1123
|
-
const M =
|
|
1126
|
+
const M = m.boundingBox, U = k / (((ve = l.current) == null ? void 0 : ve.videoWidth) ?? k), Z = N / (((be = l.current) == null ? void 0 : be.videoHeight) ?? N);
|
|
1124
1127
|
d.strokeStyle = re(
|
|
1125
1128
|
h === "success" ? "var(--nice-success, #10b981)" : "var(--nice-primary, #3b82f6)",
|
|
1126
1129
|
d.canvas
|
|
1127
|
-
), d.lineWidth = 2, d.setLineDash([6, 4]), d.strokeRect(M.x *
|
|
1128
|
-
const
|
|
1129
|
-
[M.x *
|
|
1130
|
-
[(M.x + M.width) *
|
|
1131
|
-
[M.x *
|
|
1132
|
-
[(M.x + M.width) *
|
|
1130
|
+
), d.lineWidth = 2, d.setLineDash([6, 4]), d.strokeRect(M.x * U, M.y * Z, M.width * U, M.height * Z), d.setLineDash([]);
|
|
1131
|
+
const ee = [
|
|
1132
|
+
[M.x * U, M.y * Z],
|
|
1133
|
+
[(M.x + M.width) * U, M.y * Z],
|
|
1134
|
+
[M.x * U, (M.y + M.height) * Z],
|
|
1135
|
+
[(M.x + M.width) * U, (M.y + M.height) * Z]
|
|
1133
1136
|
], X = 12;
|
|
1134
1137
|
d.lineWidth = 3;
|
|
1135
|
-
for (const [se, oe] of
|
|
1136
|
-
d.beginPath(), d.moveTo(se === M.x *
|
|
1138
|
+
for (const [se, oe] of ee)
|
|
1139
|
+
d.beginPath(), d.moveTo(se === M.x * U ? se : se - X, oe), d.lineTo(se, oe), d.lineTo(se, oe === M.y * Z ? oe + X : oe - X), d.stroke();
|
|
1137
1140
|
},
|
|
1138
|
-
[
|
|
1139
|
-
),
|
|
1140
|
-
if (!(!
|
|
1141
|
-
|
|
1141
|
+
[A, h]
|
|
1142
|
+
), D = K(async () => {
|
|
1143
|
+
if (!(!l.current || h === "processing" || h === "success")) {
|
|
1144
|
+
H("scanning"), _(C("security.face.scanning", "Scanning face…"));
|
|
1142
1145
|
try {
|
|
1143
|
-
if (
|
|
1144
|
-
const
|
|
1146
|
+
if (S.livenessDetection) {
|
|
1147
|
+
const k = [];
|
|
1145
1148
|
for (let M = 0; M < 8; M++)
|
|
1146
|
-
|
|
1147
|
-
if (!Ie(
|
|
1148
|
-
|
|
1149
|
+
k.push(le(l.current).imageData), await new Promise((U) => setTimeout(U, 200));
|
|
1150
|
+
if (!Ie(k).isLive) {
|
|
1151
|
+
_(C("security.face.notLive", "Liveness check failed — move naturally")), H("idle");
|
|
1149
1152
|
return;
|
|
1150
1153
|
}
|
|
1151
1154
|
}
|
|
1152
|
-
|
|
1153
|
-
const { imageData:
|
|
1155
|
+
H("processing"), _(C("security.face.processing", "Analysing face…"));
|
|
1156
|
+
const { imageData: m } = le(l.current);
|
|
1154
1157
|
if (t === "compare" && n) {
|
|
1155
|
-
const
|
|
1158
|
+
const k = typeof n == "string" ? await at(n) : ct(n), {
|
|
1156
1159
|
similarity: N,
|
|
1157
1160
|
cameraFeatures: M,
|
|
1158
|
-
refFeatures:
|
|
1159
|
-
} =
|
|
1160
|
-
|
|
1161
|
-
const
|
|
1162
|
-
success: N >=
|
|
1161
|
+
refFeatures: U
|
|
1162
|
+
} = Qe(m, k);
|
|
1163
|
+
q(N), J((M == null ? void 0 : M.quality) ?? 0), z(M);
|
|
1164
|
+
const ee = {
|
|
1165
|
+
success: N >= S.matchThreshold,
|
|
1163
1166
|
confidence: N,
|
|
1164
1167
|
method: "face",
|
|
1165
1168
|
timestamp: Date.now(),
|
|
1166
1169
|
duration: 0,
|
|
1167
|
-
livenessPassed:
|
|
1170
|
+
livenessPassed: S.livenessDetection
|
|
1168
1171
|
};
|
|
1169
|
-
|
|
1172
|
+
ee.success ? (_(
|
|
1173
|
+
C("security.face.matchFound", "Match: {percent}%").replace(
|
|
1174
|
+
"{percent}",
|
|
1175
|
+
(N * 100).toFixed(0)
|
|
1176
|
+
)
|
|
1177
|
+
), H("success")) : (O((X) => X + 1), W + 1 >= S.maxRetries ? (_(C("security.face.maxAttempts", "Maximum attempts reached")), H("failure")) : (_(C("security.face.noMatch", "No match — try again")), H("idle"))), s == null || s(ee);
|
|
1170
1178
|
return;
|
|
1171
1179
|
}
|
|
1172
|
-
const d = he(
|
|
1180
|
+
const d = he(m);
|
|
1173
1181
|
if (!d) {
|
|
1174
|
-
|
|
1182
|
+
_(C("security.face.noFaceDetected", "No face detected")), H("idle");
|
|
1175
1183
|
return;
|
|
1176
1184
|
}
|
|
1177
|
-
if (
|
|
1178
|
-
const
|
|
1179
|
-
|
|
1185
|
+
if (J(d.quality), z(d), t === "enroll") {
|
|
1186
|
+
const k = await Ve(d, f ?? "face");
|
|
1187
|
+
o == null || o(k, d), _(C("security.face.enrolled", "Face enrolled successfully")), H("success");
|
|
1180
1188
|
} else {
|
|
1181
|
-
let
|
|
1182
|
-
for (const
|
|
1183
|
-
const
|
|
1184
|
-
|
|
1189
|
+
let k = 0;
|
|
1190
|
+
for (const U of r) {
|
|
1191
|
+
const Z = et(U), ee = Te(d, Z);
|
|
1192
|
+
ee > k && (k = ee);
|
|
1185
1193
|
}
|
|
1186
|
-
|
|
1187
|
-
const N =
|
|
1194
|
+
q(k);
|
|
1195
|
+
const N = k >= S.matchThreshold, M = {
|
|
1188
1196
|
success: N,
|
|
1189
|
-
confidence:
|
|
1197
|
+
confidence: k,
|
|
1190
1198
|
method: "face",
|
|
1191
1199
|
timestamp: Date.now(),
|
|
1192
1200
|
duration: 0,
|
|
1193
|
-
livenessPassed:
|
|
1201
|
+
livenessPassed: S.livenessDetection
|
|
1194
1202
|
};
|
|
1195
|
-
if (N &&
|
|
1196
|
-
const
|
|
1197
|
-
|
|
1203
|
+
if (N && S.verifyEndpoint) {
|
|
1204
|
+
const U = await de(), Z = await ge(
|
|
1205
|
+
S.verifyEndpoint,
|
|
1198
1206
|
{
|
|
1199
1207
|
method: "face",
|
|
1200
1208
|
templateData: btoa(JSON.stringify(d)),
|
|
1201
|
-
matchScore:
|
|
1202
|
-
deviceFingerprint:
|
|
1209
|
+
matchScore: k,
|
|
1210
|
+
deviceFingerprint: U
|
|
1203
1211
|
},
|
|
1204
|
-
|
|
1212
|
+
S.authToken
|
|
1205
1213
|
);
|
|
1206
|
-
M.success =
|
|
1214
|
+
M.success = Z.verified;
|
|
1207
1215
|
}
|
|
1208
|
-
M.success ? (
|
|
1216
|
+
M.success ? (_(C("security.face.verified", "Face verified")), H("success")) : (O((U) => U + 1), W + 1 >= S.maxRetries ? (_(C("security.face.maxAttempts", "Maximum attempts reached")), H("failure")) : (_(C("security.face.noMatch", "No match — try again")), H("idle"))), s == null || s(M);
|
|
1209
1217
|
}
|
|
1210
|
-
} catch (
|
|
1211
|
-
|
|
1218
|
+
} catch (m) {
|
|
1219
|
+
i == null || i(m instanceof Error ? m : new Error(String(m))), _(C("security.face.error", "Error — try again")), H("error");
|
|
1212
1220
|
}
|
|
1213
1221
|
}
|
|
1214
1222
|
}, [
|
|
@@ -1216,20 +1224,20 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
1216
1224
|
t,
|
|
1217
1225
|
r,
|
|
1218
1226
|
n,
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1227
|
+
S,
|
|
1228
|
+
C,
|
|
1229
|
+
H,
|
|
1230
|
+
o,
|
|
1222
1231
|
s,
|
|
1223
1232
|
i,
|
|
1224
|
-
a,
|
|
1225
1233
|
f,
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
]),
|
|
1234
|
+
W,
|
|
1235
|
+
z
|
|
1236
|
+
]), T = h === "success" ? "var(--security-success)" : h === "failure" || h === "error" ? "var(--security-error)" : h === "scanning" || h === "processing" ? "var(--security-biometric)" : "var(--security-border)";
|
|
1229
1237
|
return /* @__PURE__ */ P(
|
|
1230
1238
|
"div",
|
|
1231
1239
|
{
|
|
1232
|
-
className:
|
|
1240
|
+
className: y,
|
|
1233
1241
|
style: {
|
|
1234
1242
|
display: "inline-flex",
|
|
1235
1243
|
flexDirection: "column",
|
|
@@ -1243,20 +1251,20 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
1243
1251
|
"div",
|
|
1244
1252
|
{
|
|
1245
1253
|
style: {
|
|
1246
|
-
width:
|
|
1247
|
-
height:
|
|
1254
|
+
width: v,
|
|
1255
|
+
height: v * 0.75,
|
|
1248
1256
|
position: "relative",
|
|
1249
1257
|
borderRadius: "var(--security-radius-lg)",
|
|
1250
1258
|
overflow: "hidden",
|
|
1251
|
-
border: `3px solid ${
|
|
1252
|
-
boxShadow: h === "scanning" ? `0 0 20px ${
|
|
1259
|
+
border: `3px solid ${T}`,
|
|
1260
|
+
boxShadow: h === "scanning" ? `0 0 20px ${T}` : "var(--security-shadow)",
|
|
1253
1261
|
transition: "border-color 0.3s, box-shadow 0.3s"
|
|
1254
1262
|
},
|
|
1255
1263
|
children: [
|
|
1256
1264
|
/* @__PURE__ */ c(
|
|
1257
1265
|
"video",
|
|
1258
1266
|
{
|
|
1259
|
-
ref:
|
|
1267
|
+
ref: l,
|
|
1260
1268
|
style: { width: "100%", height: "100%", objectFit: "cover", transform: "scaleX(-1)" },
|
|
1261
1269
|
playsInline: !0,
|
|
1262
1270
|
muted: !0
|
|
@@ -1266,8 +1274,8 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
1266
1274
|
"canvas",
|
|
1267
1275
|
{
|
|
1268
1276
|
ref: w,
|
|
1269
|
-
width:
|
|
1270
|
-
height:
|
|
1277
|
+
width: v,
|
|
1278
|
+
height: v * 0.75,
|
|
1271
1279
|
style: {
|
|
1272
1280
|
position: "absolute",
|
|
1273
1281
|
inset: 0,
|
|
@@ -1322,7 +1330,7 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
1322
1330
|
height: 50,
|
|
1323
1331
|
borderRadius: "50%",
|
|
1324
1332
|
border: "3px solid transparent",
|
|
1325
|
-
borderTopColor:
|
|
1333
|
+
borderTopColor: T,
|
|
1326
1334
|
animation: "spin 0.8s linear infinite"
|
|
1327
1335
|
}
|
|
1328
1336
|
}
|
|
@@ -1332,12 +1340,12 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
1332
1340
|
]
|
|
1333
1341
|
}
|
|
1334
1342
|
),
|
|
1335
|
-
t === "compare" &&
|
|
1343
|
+
t === "compare" && I && n && /* @__PURE__ */ P(
|
|
1336
1344
|
"div",
|
|
1337
1345
|
{
|
|
1338
1346
|
style: {
|
|
1339
|
-
width:
|
|
1340
|
-
height:
|
|
1347
|
+
width: v * 0.4,
|
|
1348
|
+
height: v * 0.5,
|
|
1341
1349
|
borderRadius: "var(--security-radius)",
|
|
1342
1350
|
overflow: "hidden",
|
|
1343
1351
|
border: "2px solid var(--security-border)"
|
|
@@ -1347,7 +1355,7 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
1347
1355
|
"img",
|
|
1348
1356
|
{
|
|
1349
1357
|
src: typeof n == "string" ? n : void 0,
|
|
1350
|
-
alt:
|
|
1358
|
+
alt: C("security.face.referenceAlt", "Reference"),
|
|
1351
1359
|
style: { width: "100%", height: "100%", objectFit: "cover" }
|
|
1352
1360
|
}
|
|
1353
1361
|
),
|
|
@@ -1361,7 +1369,7 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
1361
1369
|
color: "var(--security-text-muted)",
|
|
1362
1370
|
background: "var(--security-bg-panel)"
|
|
1363
1371
|
},
|
|
1364
|
-
children:
|
|
1372
|
+
children: C("security.face.reference", "Reference")
|
|
1365
1373
|
}
|
|
1366
1374
|
)
|
|
1367
1375
|
]
|
|
@@ -1370,7 +1378,7 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
1370
1378
|
] }),
|
|
1371
1379
|
F > 0 && /* @__PURE__ */ P("div", { style: { display: "flex", alignItems: "center", gap: 8, fontSize: 13 }, children: [
|
|
1372
1380
|
/* @__PURE__ */ P("span", { style: { color: "var(--security-text-secondary)" }, children: [
|
|
1373
|
-
|
|
1381
|
+
C("security.face.confidence", "Confidence"),
|
|
1374
1382
|
":"
|
|
1375
1383
|
] }),
|
|
1376
1384
|
/* @__PURE__ */ c(
|
|
@@ -1389,7 +1397,7 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
1389
1397
|
style: {
|
|
1390
1398
|
width: `${F * 100}%`,
|
|
1391
1399
|
height: "100%",
|
|
1392
|
-
background: F >=
|
|
1400
|
+
background: F >= S.matchThreshold ? "var(--security-success)" : "var(--security-warning)"
|
|
1393
1401
|
}
|
|
1394
1402
|
}
|
|
1395
1403
|
)
|
|
@@ -1400,7 +1408,7 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
1400
1408
|
{
|
|
1401
1409
|
style: {
|
|
1402
1410
|
fontWeight: 600,
|
|
1403
|
-
color: F >=
|
|
1411
|
+
color: F >= S.matchThreshold ? "var(--security-success)" : "var(--security-warning)"
|
|
1404
1412
|
},
|
|
1405
1413
|
children: [
|
|
1406
1414
|
(F * 100).toFixed(0),
|
|
@@ -1418,13 +1426,13 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
1418
1426
|
textAlign: "center",
|
|
1419
1427
|
minHeight: 20
|
|
1420
1428
|
},
|
|
1421
|
-
children:
|
|
1429
|
+
children: L ?? Y
|
|
1422
1430
|
}
|
|
1423
1431
|
),
|
|
1424
1432
|
h !== "success" && h !== "failure" && /* @__PURE__ */ c(
|
|
1425
1433
|
"button",
|
|
1426
1434
|
{
|
|
1427
|
-
onClick:
|
|
1435
|
+
onClick: D,
|
|
1428
1436
|
disabled: h === "scanning" || h === "processing",
|
|
1429
1437
|
style: {
|
|
1430
1438
|
padding: "10px 24px",
|
|
@@ -1437,14 +1445,14 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
1437
1445
|
cursor: "pointer",
|
|
1438
1446
|
opacity: h === "scanning" || h === "processing" ? 0.6 : 1
|
|
1439
1447
|
},
|
|
1440
|
-
children: t === "enroll" ?
|
|
1448
|
+
children: t === "enroll" ? C("security.face.captureBtn", "Capture Face") : t === "compare" ? C("security.face.compareBtn", "Compare") : C("security.face.verifyBtn", "Verify Face")
|
|
1441
1449
|
}
|
|
1442
1450
|
),
|
|
1443
1451
|
(h === "failure" || h === "error") && /* @__PURE__ */ c(
|
|
1444
1452
|
"button",
|
|
1445
1453
|
{
|
|
1446
1454
|
onClick: () => {
|
|
1447
|
-
|
|
1455
|
+
O(0), q(0), H("idle"), _("");
|
|
1448
1456
|
},
|
|
1449
1457
|
style: {
|
|
1450
1458
|
padding: "8px 20px",
|
|
@@ -1455,7 +1463,7 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
1455
1463
|
borderRadius: "var(--security-radius)",
|
|
1456
1464
|
cursor: "pointer"
|
|
1457
1465
|
},
|
|
1458
|
-
children:
|
|
1466
|
+
children: C("security.common.retry", "Try Again")
|
|
1459
1467
|
}
|
|
1460
1468
|
),
|
|
1461
1469
|
/* @__PURE__ */ c("style", { children: "@keyframes spin { to { transform: rotate(360deg); } }" })
|
|
@@ -1463,137 +1471,137 @@ const tt = { sm: 200, md: 280, lg: 380 }, Ct = (e) => {
|
|
|
1463
1471
|
}
|
|
1464
1472
|
);
|
|
1465
1473
|
};
|
|
1466
|
-
async function
|
|
1474
|
+
async function at(e) {
|
|
1467
1475
|
return new Promise((t, r) => {
|
|
1468
1476
|
const n = new Image();
|
|
1469
1477
|
n.crossOrigin = "anonymous", n.onload = () => {
|
|
1470
|
-
const
|
|
1471
|
-
|
|
1472
|
-
const
|
|
1473
|
-
|
|
1478
|
+
const o = document.createElement("canvas");
|
|
1479
|
+
o.width = n.naturalWidth, o.height = n.naturalHeight;
|
|
1480
|
+
const s = o.getContext("2d");
|
|
1481
|
+
s.drawImage(n, 0, 0), t(s.getImageData(0, 0, o.width, o.height));
|
|
1474
1482
|
}, n.onerror = () => r(new Error("Failed to load reference image")), n.src = e;
|
|
1475
1483
|
});
|
|
1476
1484
|
}
|
|
1477
|
-
function
|
|
1485
|
+
function ct(e) {
|
|
1478
1486
|
const t = document.createElement("canvas");
|
|
1479
1487
|
t.width = e.naturalWidth || e.width, t.height = e.naturalHeight || e.height;
|
|
1480
1488
|
const r = t.getContext("2d");
|
|
1481
1489
|
return r.drawImage(e, 0, 0), r.getImageData(0, 0, t.width, t.height);
|
|
1482
1490
|
}
|
|
1483
|
-
const
|
|
1491
|
+
const lt = 4, ut = 5, dt = 3e4, _t = (e) => {
|
|
1484
1492
|
const {
|
|
1485
|
-
length: t =
|
|
1493
|
+
length: t = lt,
|
|
1486
1494
|
scramble: r = !1,
|
|
1487
1495
|
showDigits: n = !1,
|
|
1488
|
-
maxAttempts:
|
|
1489
|
-
lockoutDuration:
|
|
1490
|
-
keySize:
|
|
1491
|
-
haptic:
|
|
1492
|
-
keyLabels:
|
|
1493
|
-
expectedHash:
|
|
1496
|
+
maxAttempts: o = ut,
|
|
1497
|
+
lockoutDuration: s = dt,
|
|
1498
|
+
keySize: a = 64,
|
|
1499
|
+
haptic: i = !0,
|
|
1500
|
+
keyLabels: y,
|
|
1501
|
+
expectedHash: b,
|
|
1494
1502
|
expectedPin: f,
|
|
1495
|
-
mode:
|
|
1496
|
-
onComplete:
|
|
1497
|
-
onVerify:
|
|
1498
|
-
onStatusChange:
|
|
1499
|
-
onError:
|
|
1500
|
-
showBiometricFallback:
|
|
1501
|
-
onBiometricFallback:
|
|
1502
|
-
label:
|
|
1503
|
-
className:
|
|
1504
|
-
} = e, { t:
|
|
1505
|
-
const
|
|
1503
|
+
mode: x = "verify",
|
|
1504
|
+
onComplete: A,
|
|
1505
|
+
onVerify: g,
|
|
1506
|
+
onStatusChange: I,
|
|
1507
|
+
onError: L,
|
|
1508
|
+
showBiometricFallback: p = !1,
|
|
1509
|
+
onBiometricFallback: C,
|
|
1510
|
+
label: S,
|
|
1511
|
+
className: v
|
|
1512
|
+
} = e, { t: l } = te(), [w, u] = j([]), [h, R] = j("idle"), [G, J] = j(0), [W, O] = j(0), [Y, _] = j(null), $ = V(void 0), B = ae(() => {
|
|
1513
|
+
const D = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "", "0", "back"];
|
|
1506
1514
|
if (!r)
|
|
1507
|
-
return
|
|
1508
|
-
const
|
|
1509
|
-
for (let
|
|
1515
|
+
return D;
|
|
1516
|
+
const T = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
|
|
1517
|
+
for (let m = T.length - 1; m > 0; m--) {
|
|
1510
1518
|
const d = new Uint32Array(1);
|
|
1511
1519
|
crypto.getRandomValues(d);
|
|
1512
|
-
const
|
|
1513
|
-
[
|
|
1520
|
+
const k = d[0] % (m + 1);
|
|
1521
|
+
[T[m], T[k]] = [T[k], T[m]];
|
|
1514
1522
|
}
|
|
1515
1523
|
return [
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1524
|
+
T[0],
|
|
1525
|
+
T[1],
|
|
1526
|
+
T[2],
|
|
1527
|
+
T[3],
|
|
1528
|
+
T[4],
|
|
1529
|
+
T[5],
|
|
1530
|
+
T[6],
|
|
1531
|
+
T[7],
|
|
1532
|
+
T[8],
|
|
1525
1533
|
"",
|
|
1526
|
-
|
|
1534
|
+
T[9],
|
|
1527
1535
|
"back"
|
|
1528
1536
|
];
|
|
1529
|
-
}, [r, h]), F =
|
|
1530
|
-
(
|
|
1531
|
-
|
|
1537
|
+
}, [r, h]), F = K(
|
|
1538
|
+
(D) => {
|
|
1539
|
+
R(D), I == null || I(D);
|
|
1532
1540
|
},
|
|
1533
|
-
[
|
|
1541
|
+
[I]
|
|
1534
1542
|
);
|
|
1535
1543
|
ne(() => {
|
|
1536
|
-
if (!(
|
|
1544
|
+
if (!(W <= Date.now()))
|
|
1537
1545
|
return $.current = setInterval(() => {
|
|
1538
|
-
Date.now() >=
|
|
1546
|
+
Date.now() >= W && (clearInterval($.current), F("idle"), J(0), u([]));
|
|
1539
1547
|
}, 500), () => clearInterval($.current);
|
|
1540
|
-
}, [
|
|
1541
|
-
const
|
|
1542
|
-
|
|
1543
|
-
}, [
|
|
1544
|
-
async (
|
|
1545
|
-
if (
|
|
1548
|
+
}, [W, F]);
|
|
1549
|
+
const q = W > Date.now(), H = K(() => {
|
|
1550
|
+
i && navigator.vibrate && navigator.vibrate(20);
|
|
1551
|
+
}, [i]), Q = K(
|
|
1552
|
+
async (D) => {
|
|
1553
|
+
if (q || h === "success")
|
|
1546
1554
|
return;
|
|
1547
|
-
if (
|
|
1548
|
-
|
|
1555
|
+
if (H(), D === "back") {
|
|
1556
|
+
u((k) => k.slice(0, -1));
|
|
1549
1557
|
return;
|
|
1550
1558
|
}
|
|
1551
|
-
if (
|
|
1559
|
+
if (D === "")
|
|
1552
1560
|
return;
|
|
1553
|
-
const
|
|
1554
|
-
if (
|
|
1561
|
+
const T = [...w, D];
|
|
1562
|
+
if (u(T), T.length < t)
|
|
1555
1563
|
return;
|
|
1556
|
-
const
|
|
1557
|
-
if (F("processing"),
|
|
1558
|
-
if (
|
|
1559
|
-
|
|
1564
|
+
const m = T.join("");
|
|
1565
|
+
if (F("processing"), x === "set") {
|
|
1566
|
+
if (Y === null) {
|
|
1567
|
+
_(m), u([]), F("idle");
|
|
1560
1568
|
return;
|
|
1561
1569
|
}
|
|
1562
|
-
if (
|
|
1563
|
-
|
|
1570
|
+
if (Y !== m) {
|
|
1571
|
+
_(null), u([]), F("failure"), setTimeout(() => F("idle"), 1200);
|
|
1564
1572
|
return;
|
|
1565
1573
|
}
|
|
1566
|
-
|
|
1574
|
+
A == null || A(m), F("success");
|
|
1567
1575
|
return;
|
|
1568
1576
|
}
|
|
1569
1577
|
let d = !1;
|
|
1570
|
-
if (
|
|
1571
|
-
const
|
|
1572
|
-
d = Array.from(new Uint8Array(N)).map((
|
|
1578
|
+
if (b) {
|
|
1579
|
+
const k = new TextEncoder(), N = await crypto.subtle.digest("SHA-256", k.encode(m));
|
|
1580
|
+
d = Array.from(new Uint8Array(N)).map((U) => U.toString(16).padStart(2, "0")).join("") === b;
|
|
1573
1581
|
} else if (f)
|
|
1574
|
-
d =
|
|
1582
|
+
d = m === f;
|
|
1575
1583
|
else {
|
|
1576
|
-
|
|
1584
|
+
A == null || A(m), F("success");
|
|
1577
1585
|
return;
|
|
1578
1586
|
}
|
|
1579
1587
|
if (d)
|
|
1580
|
-
F("success"),
|
|
1588
|
+
F("success"), g == null || g({
|
|
1581
1589
|
success: !0,
|
|
1582
1590
|
confidence: 1,
|
|
1583
1591
|
method: "pin",
|
|
1584
1592
|
timestamp: Date.now(),
|
|
1585
1593
|
duration: 0
|
|
1586
|
-
}),
|
|
1594
|
+
}), A == null || A(m);
|
|
1587
1595
|
else {
|
|
1588
|
-
const
|
|
1589
|
-
if (
|
|
1590
|
-
const N = Date.now() +
|
|
1591
|
-
|
|
1596
|
+
const k = G + 1;
|
|
1597
|
+
if (J(k), k >= o) {
|
|
1598
|
+
const N = Date.now() + s;
|
|
1599
|
+
O(N), F("failure"), L == null || L(new Error("Too many failed PIN attempts"));
|
|
1592
1600
|
} else
|
|
1593
1601
|
F("failure"), setTimeout(() => {
|
|
1594
|
-
F("idle"),
|
|
1602
|
+
F("idle"), u([]);
|
|
1595
1603
|
}, 800);
|
|
1596
|
-
|
|
1604
|
+
g == null || g({
|
|
1597
1605
|
success: !1,
|
|
1598
1606
|
confidence: 0,
|
|
1599
1607
|
method: "pin",
|
|
@@ -1605,26 +1613,26 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
1605
1613
|
[
|
|
1606
1614
|
w,
|
|
1607
1615
|
t,
|
|
1608
|
-
|
|
1616
|
+
q,
|
|
1609
1617
|
h,
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1618
|
+
x,
|
|
1619
|
+
Y,
|
|
1620
|
+
b,
|
|
1613
1621
|
f,
|
|
1614
|
-
|
|
1622
|
+
G,
|
|
1623
|
+
o,
|
|
1615
1624
|
s,
|
|
1616
|
-
|
|
1617
|
-
U,
|
|
1625
|
+
H,
|
|
1618
1626
|
F,
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1627
|
+
A,
|
|
1628
|
+
g,
|
|
1629
|
+
L
|
|
1622
1630
|
]
|
|
1623
|
-
), E = Math.max(0, Math.ceil((
|
|
1631
|
+
), E = Math.max(0, Math.ceil((W - Date.now()) / 1e3)), z = h === "success" ? "var(--security-success)" : h === "failure" ? "var(--security-error)" : "var(--security-border)";
|
|
1624
1632
|
return /* @__PURE__ */ P(
|
|
1625
1633
|
"div",
|
|
1626
1634
|
{
|
|
1627
|
-
className:
|
|
1635
|
+
className: v,
|
|
1628
1636
|
style: {
|
|
1629
1637
|
display: "inline-flex",
|
|
1630
1638
|
flexDirection: "column",
|
|
@@ -1634,7 +1642,7 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
1634
1642
|
color: "var(--security-text)"
|
|
1635
1643
|
},
|
|
1636
1644
|
children: [
|
|
1637
|
-
|
|
1645
|
+
S && /* @__PURE__ */ c("div", { style: { fontSize: 14, fontWeight: 600 }, children: S }),
|
|
1638
1646
|
/* @__PURE__ */ c(
|
|
1639
1647
|
"div",
|
|
1640
1648
|
{
|
|
@@ -1644,51 +1652,54 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
1644
1652
|
minHeight: 18,
|
|
1645
1653
|
textAlign: "center"
|
|
1646
1654
|
},
|
|
1647
|
-
children:
|
|
1655
|
+
children: q ? l("security.pin.locked", "Locked — try again in {seconds}s").replace(
|
|
1656
|
+
"{seconds}",
|
|
1657
|
+
String(E)
|
|
1658
|
+
) : x === "set" && Y !== null ? l("security.pin.confirm", "Confirm your PIN") : x === "set" ? l("security.pin.setNew", "Enter a new PIN") : l("security.pin.enter", "Enter your PIN")
|
|
1648
1659
|
}
|
|
1649
1660
|
),
|
|
1650
|
-
/* @__PURE__ */ c("div", { style: { display: "flex", gap: 12 }, children: Array.from({ length: t }, (
|
|
1661
|
+
/* @__PURE__ */ c("div", { style: { display: "flex", gap: 12 }, children: Array.from({ length: t }, (D, T) => /* @__PURE__ */ c(
|
|
1651
1662
|
"div",
|
|
1652
1663
|
{
|
|
1653
1664
|
style: {
|
|
1654
1665
|
width: 16,
|
|
1655
1666
|
height: 16,
|
|
1656
1667
|
borderRadius: "50%",
|
|
1657
|
-
border: `2px solid ${
|
|
1658
|
-
background:
|
|
1668
|
+
border: `2px solid ${z}`,
|
|
1669
|
+
background: T < w.length ? z : "transparent",
|
|
1659
1670
|
transition: "background 0.15s, border-color 0.15s"
|
|
1660
1671
|
}
|
|
1661
1672
|
},
|
|
1662
|
-
|
|
1673
|
+
T
|
|
1663
1674
|
)) }),
|
|
1664
1675
|
/* @__PURE__ */ c(
|
|
1665
1676
|
"div",
|
|
1666
1677
|
{
|
|
1667
1678
|
style: {
|
|
1668
1679
|
display: "grid",
|
|
1669
|
-
gridTemplateColumns: `repeat(3, ${
|
|
1680
|
+
gridTemplateColumns: `repeat(3, ${a}px)`,
|
|
1670
1681
|
gap: 10,
|
|
1671
|
-
opacity:
|
|
1672
|
-
pointerEvents:
|
|
1682
|
+
opacity: q ? 0.4 : 1,
|
|
1683
|
+
pointerEvents: q ? "none" : "auto"
|
|
1673
1684
|
},
|
|
1674
|
-
children: B.map((
|
|
1675
|
-
if (
|
|
1676
|
-
return /* @__PURE__ */ c("div", {},
|
|
1677
|
-
const
|
|
1685
|
+
children: B.map((D, T) => {
|
|
1686
|
+
if (D === "")
|
|
1687
|
+
return /* @__PURE__ */ c("div", {}, T);
|
|
1688
|
+
const m = D === "back";
|
|
1678
1689
|
return /* @__PURE__ */ c(
|
|
1679
1690
|
"button",
|
|
1680
1691
|
{
|
|
1681
|
-
onClick: () => Q(
|
|
1682
|
-
disabled:
|
|
1683
|
-
"aria-label":
|
|
1692
|
+
onClick: () => Q(D),
|
|
1693
|
+
disabled: q || h === "success",
|
|
1694
|
+
"aria-label": m ? l("security.pin.backspace", "Backspace") : D,
|
|
1684
1695
|
style: {
|
|
1685
|
-
width:
|
|
1686
|
-
height:
|
|
1696
|
+
width: a,
|
|
1697
|
+
height: a,
|
|
1687
1698
|
borderRadius: "var(--security-key-border-radius, 50%)",
|
|
1688
1699
|
border: "1px solid var(--security-key-border, var(--security-border))",
|
|
1689
1700
|
background: "var(--security-key-bg, var(--security-bg-panel))",
|
|
1690
1701
|
color: "var(--security-key-text, var(--security-text))",
|
|
1691
|
-
fontSize:
|
|
1702
|
+
fontSize: m ? 20 : 22,
|
|
1692
1703
|
fontWeight: 600,
|
|
1693
1704
|
cursor: "pointer",
|
|
1694
1705
|
display: "flex",
|
|
@@ -1706,9 +1717,9 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
1706
1717
|
onMouseLeave: (d) => {
|
|
1707
1718
|
d.currentTarget.style.transform = "";
|
|
1708
1719
|
},
|
|
1709
|
-
children:
|
|
1720
|
+
children: m ? /* @__PURE__ */ c(Ne, { size: 22 }) : (y == null ? void 0 : y[D]) ?? D
|
|
1710
1721
|
},
|
|
1711
|
-
|
|
1722
|
+
T
|
|
1712
1723
|
);
|
|
1713
1724
|
})
|
|
1714
1725
|
}
|
|
@@ -1716,7 +1727,7 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
1716
1727
|
w.length > 0 && h !== "success" && /* @__PURE__ */ c(
|
|
1717
1728
|
"button",
|
|
1718
1729
|
{
|
|
1719
|
-
onClick: () =>
|
|
1730
|
+
onClick: () => u([]),
|
|
1720
1731
|
style: {
|
|
1721
1732
|
fontSize: 12,
|
|
1722
1733
|
background: "none",
|
|
@@ -1725,13 +1736,13 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
1725
1736
|
cursor: "pointer",
|
|
1726
1737
|
textDecoration: "underline"
|
|
1727
1738
|
},
|
|
1728
|
-
children:
|
|
1739
|
+
children: l("security.pin.clear", "Clear")
|
|
1729
1740
|
}
|
|
1730
1741
|
),
|
|
1731
|
-
|
|
1742
|
+
p && /* @__PURE__ */ c(
|
|
1732
1743
|
"button",
|
|
1733
1744
|
{
|
|
1734
|
-
onClick:
|
|
1745
|
+
onClick: C,
|
|
1735
1746
|
style: {
|
|
1736
1747
|
fontSize: 13,
|
|
1737
1748
|
padding: "8px 16px",
|
|
@@ -1741,158 +1752,158 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
1741
1752
|
color: "var(--security-biometric)",
|
|
1742
1753
|
cursor: "pointer"
|
|
1743
1754
|
},
|
|
1744
|
-
children:
|
|
1755
|
+
children: l("security.pin.biometricFallback", "Use biometrics instead")
|
|
1745
1756
|
}
|
|
1746
1757
|
),
|
|
1747
|
-
|
|
1758
|
+
G > 0 && h !== "success" && !q && /* @__PURE__ */ c("div", { style: { fontSize: 11, color: "var(--security-warning)" }, children: l("security.pin.attempts", "{attempts}/{max} attempts").replace("{attempts}", String(G)).replace("{max}", String(o)) })
|
|
1748
1759
|
]
|
|
1749
1760
|
}
|
|
1750
1761
|
);
|
|
1751
|
-
},
|
|
1762
|
+
}, ht = 3, ft = 4, yt = 5, pt = 14, Bt = (e) => {
|
|
1752
1763
|
const {
|
|
1753
|
-
gridSize: t =
|
|
1754
|
-
minLength: r =
|
|
1764
|
+
gridSize: t = ht,
|
|
1765
|
+
minLength: r = ft,
|
|
1755
1766
|
showTrail: n = !0,
|
|
1756
|
-
showError:
|
|
1757
|
-
maxAttempts:
|
|
1758
|
-
dotSize:
|
|
1759
|
-
trailColor:
|
|
1760
|
-
mode:
|
|
1761
|
-
expectedHash:
|
|
1767
|
+
showError: o = !0,
|
|
1768
|
+
maxAttempts: s = yt,
|
|
1769
|
+
dotSize: a = pt,
|
|
1770
|
+
trailColor: i,
|
|
1771
|
+
mode: y = "verify",
|
|
1772
|
+
expectedHash: b,
|
|
1762
1773
|
expectedPattern: f,
|
|
1763
|
-
onComplete:
|
|
1764
|
-
onVerify:
|
|
1765
|
-
onStatusChange:
|
|
1766
|
-
onError:
|
|
1767
|
-
label:
|
|
1768
|
-
className:
|
|
1769
|
-
canvasSize:
|
|
1770
|
-
} = e, { t:
|
|
1774
|
+
onComplete: x,
|
|
1775
|
+
onVerify: A,
|
|
1776
|
+
onStatusChange: g,
|
|
1777
|
+
onError: I,
|
|
1778
|
+
label: L,
|
|
1779
|
+
className: p,
|
|
1780
|
+
canvasSize: C
|
|
1781
|
+
} = e, { t: S } = te(), v = V(null), [l, w] = j([]), [u, h] = j(!1), [R, G] = j("idle"), [J, W] = j(0), [O, Y] = j(null), [_, $] = j(null), B = C ?? t * 80, F = B / t, q = K(
|
|
1771
1782
|
(d) => {
|
|
1772
|
-
|
|
1783
|
+
G(d), g == null || g(d);
|
|
1773
1784
|
},
|
|
1774
|
-
[
|
|
1775
|
-
),
|
|
1785
|
+
[g]
|
|
1786
|
+
), H = K(() => {
|
|
1776
1787
|
const d = [];
|
|
1777
|
-
for (let
|
|
1788
|
+
for (let k = 0; k < t; k++)
|
|
1778
1789
|
for (let N = 0; N < t; N++)
|
|
1779
|
-
d.push({ x: N * F + F / 2, y:
|
|
1790
|
+
d.push({ x: N * F + F / 2, y: k * F + F / 2 });
|
|
1780
1791
|
return d;
|
|
1781
|
-
}, [t, F]), Q =
|
|
1782
|
-
const
|
|
1783
|
-
return { x: N -
|
|
1784
|
-
}, []), E =
|
|
1785
|
-
(d,
|
|
1786
|
-
const N =
|
|
1787
|
-
for (let
|
|
1788
|
-
const
|
|
1789
|
-
if (
|
|
1790
|
-
return
|
|
1792
|
+
}, [t, F]), Q = K((d) => {
|
|
1793
|
+
const k = v.current.getBoundingClientRect(), N = "touches" in d ? d.touches[0].clientX : d.clientX, M = "touches" in d ? d.touches[0].clientY : d.clientY;
|
|
1794
|
+
return { x: N - k.left, y: M - k.top };
|
|
1795
|
+
}, []), E = K(
|
|
1796
|
+
(d, k) => {
|
|
1797
|
+
const N = H(), M = F * 0.38;
|
|
1798
|
+
for (let U = 0; U < N.length; U++) {
|
|
1799
|
+
const Z = N[U].x - d, ee = N[U].y - k;
|
|
1800
|
+
if (Z * Z + ee * ee < M * M)
|
|
1801
|
+
return U;
|
|
1791
1802
|
}
|
|
1792
1803
|
return -1;
|
|
1793
1804
|
},
|
|
1794
|
-
[
|
|
1795
|
-
),
|
|
1796
|
-
var
|
|
1797
|
-
const d = (
|
|
1805
|
+
[H, F]
|
|
1806
|
+
), z = K(() => {
|
|
1807
|
+
var ee;
|
|
1808
|
+
const d = (ee = v.current) == null ? void 0 : ee.getContext("2d");
|
|
1798
1809
|
if (!d)
|
|
1799
1810
|
return;
|
|
1800
1811
|
d.clearRect(0, 0, B, B);
|
|
1801
|
-
const
|
|
1802
|
-
N &&
|
|
1812
|
+
const k = H(), N = R === "failure", M = d.canvas, U = re(
|
|
1813
|
+
N && o ? "var(--security-error)" : i ?? "var(--security-biometric)",
|
|
1803
1814
|
M
|
|
1804
|
-
),
|
|
1805
|
-
for (let X = 0; X <
|
|
1806
|
-
const ie =
|
|
1807
|
-
d.beginPath(), d.arc(
|
|
1815
|
+
), Z = re("var(--security-border)", M);
|
|
1816
|
+
for (let X = 0; X < k.length; X++) {
|
|
1817
|
+
const ie = l.includes(X);
|
|
1818
|
+
d.beginPath(), d.arc(k[X].x, k[X].y, ie ? a * 0.75 : a * 0.5, 0, Math.PI * 2), d.fillStyle = ie ? U : Z, d.fill(), ie && (d.beginPath(), d.arc(k[X].x, k[X].y, a * 1.2, 0, Math.PI * 2), d.strokeStyle = U, d.lineWidth = 1.5, d.globalAlpha = 0.3, d.stroke(), d.globalAlpha = 1);
|
|
1808
1819
|
}
|
|
1809
|
-
if (n &&
|
|
1810
|
-
d.beginPath(), d.moveTo(
|
|
1811
|
-
for (let X = 1; X <
|
|
1812
|
-
d.lineTo(
|
|
1813
|
-
|
|
1814
|
-
} else n &&
|
|
1820
|
+
if (n && l.length > 1) {
|
|
1821
|
+
d.beginPath(), d.moveTo(k[l[0]].x, k[l[0]].y);
|
|
1822
|
+
for (let X = 1; X < l.length; X++)
|
|
1823
|
+
d.lineTo(k[l[X]].x, k[l[X]].y);
|
|
1824
|
+
u && _ && d.lineTo(_.x, _.y), d.strokeStyle = U, d.lineWidth = 3, d.lineCap = "round", d.lineJoin = "round", d.globalAlpha = 0.5, d.stroke(), d.globalAlpha = 1;
|
|
1825
|
+
} else n && l.length === 1 && u && _ && (d.beginPath(), d.moveTo(k[l[0]].x, k[l[0]].y), d.lineTo(_.x, _.y), d.strokeStyle = re(i ?? "var(--security-biometric)", M), d.lineWidth = 3, d.globalAlpha = 0.4, d.stroke(), d.globalAlpha = 1);
|
|
1815
1826
|
}, [
|
|
1816
1827
|
B,
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
u,
|
|
1828
|
+
H,
|
|
1829
|
+
a,
|
|
1820
1830
|
l,
|
|
1821
|
-
|
|
1822
|
-
|
|
1831
|
+
u,
|
|
1832
|
+
_,
|
|
1833
|
+
R,
|
|
1823
1834
|
n,
|
|
1824
|
-
|
|
1825
|
-
|
|
1835
|
+
o,
|
|
1836
|
+
i
|
|
1826
1837
|
]);
|
|
1827
1838
|
ne(() => {
|
|
1828
|
-
|
|
1829
|
-
}, [
|
|
1830
|
-
const
|
|
1839
|
+
z();
|
|
1840
|
+
}, [z]);
|
|
1841
|
+
const D = K(
|
|
1831
1842
|
(d) => {
|
|
1832
|
-
if (
|
|
1843
|
+
if (R === "success" || R === "failure")
|
|
1833
1844
|
return;
|
|
1834
1845
|
d.preventDefault();
|
|
1835
|
-
const { x:
|
|
1836
|
-
M >= 0 && (h(!0), w([M]), $({ x:
|
|
1846
|
+
const { x: k, y: N } = Q(d), M = E(k, N);
|
|
1847
|
+
M >= 0 && (h(!0), w([M]), $({ x: k, y: N }));
|
|
1837
1848
|
},
|
|
1838
|
-
[
|
|
1839
|
-
),
|
|
1849
|
+
[R, Q, E]
|
|
1850
|
+
), T = K(
|
|
1840
1851
|
(d) => {
|
|
1841
|
-
if (!
|
|
1852
|
+
if (!u)
|
|
1842
1853
|
return;
|
|
1843
1854
|
d.preventDefault();
|
|
1844
|
-
const { x:
|
|
1845
|
-
$({ x:
|
|
1846
|
-
const M = E(
|
|
1847
|
-
M >= 0 && !
|
|
1855
|
+
const { x: k, y: N } = Q(d);
|
|
1856
|
+
$({ x: k, y: N });
|
|
1857
|
+
const M = E(k, N);
|
|
1858
|
+
M >= 0 && !l.includes(M) && w((U) => [...U, M]);
|
|
1848
1859
|
},
|
|
1849
|
-
[
|
|
1850
|
-
),
|
|
1851
|
-
if (!
|
|
1860
|
+
[u, Q, E, l]
|
|
1861
|
+
), m = K(async () => {
|
|
1862
|
+
if (!u)
|
|
1852
1863
|
return;
|
|
1853
|
-
if (h(!1), $(null),
|
|
1864
|
+
if (h(!1), $(null), l.length < r) {
|
|
1854
1865
|
w([]);
|
|
1855
1866
|
return;
|
|
1856
1867
|
}
|
|
1857
|
-
const d =
|
|
1858
|
-
if (
|
|
1859
|
-
if (
|
|
1860
|
-
|
|
1868
|
+
const d = l.join(",");
|
|
1869
|
+
if (y === "set") {
|
|
1870
|
+
if (O === null) {
|
|
1871
|
+
Y([...l]), w([]);
|
|
1861
1872
|
return;
|
|
1862
1873
|
}
|
|
1863
|
-
if (
|
|
1864
|
-
|
|
1865
|
-
|
|
1874
|
+
if (O.join(",") !== d) {
|
|
1875
|
+
Y(null), q("failure"), setTimeout(() => {
|
|
1876
|
+
q("idle"), w([]);
|
|
1866
1877
|
}, 800);
|
|
1867
1878
|
return;
|
|
1868
1879
|
}
|
|
1869
|
-
|
|
1880
|
+
x == null || x([...l]), q("success");
|
|
1870
1881
|
return;
|
|
1871
1882
|
}
|
|
1872
|
-
|
|
1873
|
-
let
|
|
1874
|
-
if (
|
|
1883
|
+
q("processing");
|
|
1884
|
+
let k = !1;
|
|
1885
|
+
if (b) {
|
|
1875
1886
|
const N = new TextEncoder(), M = await crypto.subtle.digest("SHA-256", N.encode(d));
|
|
1876
|
-
|
|
1887
|
+
k = Array.from(new Uint8Array(M)).map((Z) => Z.toString(16).padStart(2, "0")).join("") === b;
|
|
1877
1888
|
} else if (f)
|
|
1878
|
-
|
|
1889
|
+
k = d === f;
|
|
1879
1890
|
else {
|
|
1880
|
-
|
|
1891
|
+
x == null || x([...l]), q("success");
|
|
1881
1892
|
return;
|
|
1882
1893
|
}
|
|
1883
|
-
if (
|
|
1884
|
-
|
|
1894
|
+
if (k)
|
|
1895
|
+
q("success"), A == null || A({
|
|
1885
1896
|
success: !0,
|
|
1886
1897
|
confidence: 1,
|
|
1887
1898
|
method: "pattern",
|
|
1888
1899
|
timestamp: Date.now(),
|
|
1889
1900
|
duration: 0
|
|
1890
|
-
}),
|
|
1901
|
+
}), x == null || x([...l]);
|
|
1891
1902
|
else {
|
|
1892
|
-
const N =
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
}, 900),
|
|
1903
|
+
const N = J + 1;
|
|
1904
|
+
W(N), q("failure"), N >= s && (I == null || I(new Error("Too many failed pattern attempts"))), setTimeout(() => {
|
|
1905
|
+
q("idle"), w([]);
|
|
1906
|
+
}, 900), A == null || A({
|
|
1896
1907
|
success: !1,
|
|
1897
1908
|
confidence: 0,
|
|
1898
1909
|
method: "pattern",
|
|
@@ -1901,24 +1912,24 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
1901
1912
|
});
|
|
1902
1913
|
}
|
|
1903
1914
|
}, [
|
|
1904
|
-
l,
|
|
1905
1915
|
u,
|
|
1916
|
+
l,
|
|
1906
1917
|
r,
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1918
|
+
y,
|
|
1919
|
+
O,
|
|
1920
|
+
b,
|
|
1910
1921
|
f,
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1922
|
+
J,
|
|
1923
|
+
s,
|
|
1924
|
+
q,
|
|
1925
|
+
x,
|
|
1926
|
+
A,
|
|
1927
|
+
I
|
|
1917
1928
|
]);
|
|
1918
1929
|
return /* @__PURE__ */ P(
|
|
1919
1930
|
"div",
|
|
1920
1931
|
{
|
|
1921
|
-
className:
|
|
1932
|
+
className: p,
|
|
1922
1933
|
style: {
|
|
1923
1934
|
display: "inline-flex",
|
|
1924
1935
|
flexDirection: "column",
|
|
@@ -1928,7 +1939,7 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
1928
1939
|
color: "var(--security-text)"
|
|
1929
1940
|
},
|
|
1930
1941
|
children: [
|
|
1931
|
-
|
|
1942
|
+
L && /* @__PURE__ */ c("div", { style: { fontSize: 14, fontWeight: 600 }, children: L }),
|
|
1932
1943
|
/* @__PURE__ */ c(
|
|
1933
1944
|
"div",
|
|
1934
1945
|
{
|
|
@@ -1938,37 +1949,37 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
1938
1949
|
minHeight: 18,
|
|
1939
1950
|
textAlign: "center"
|
|
1940
1951
|
},
|
|
1941
|
-
children:
|
|
1952
|
+
children: R === "success" ? S("security.pattern.success", "Pattern accepted") : R === "failure" ? S("security.pattern.wrong", "Wrong pattern") : y === "set" && O !== null ? S("security.pattern.confirm", "Draw pattern again to confirm") : y === "set" ? S("security.pattern.setNew", "Draw a new pattern") : S("security.pattern.draw", "Draw your pattern")
|
|
1942
1953
|
}
|
|
1943
1954
|
),
|
|
1944
1955
|
/* @__PURE__ */ c(
|
|
1945
1956
|
"canvas",
|
|
1946
1957
|
{
|
|
1947
|
-
ref:
|
|
1958
|
+
ref: v,
|
|
1948
1959
|
width: B,
|
|
1949
1960
|
height: B,
|
|
1950
1961
|
style: {
|
|
1951
1962
|
touchAction: "none",
|
|
1952
1963
|
borderRadius: "var(--security-radius-lg)",
|
|
1953
1964
|
background: "var(--security-bg-panel)",
|
|
1954
|
-
border: `1px solid ${
|
|
1965
|
+
border: `1px solid ${R === "failure" ? "var(--security-error)" : "var(--security-border)"}`,
|
|
1955
1966
|
cursor: "pointer",
|
|
1956
1967
|
transition: "border-color 0.3s"
|
|
1957
1968
|
},
|
|
1958
|
-
onMouseDown:
|
|
1959
|
-
onMouseMove:
|
|
1960
|
-
onMouseUp:
|
|
1961
|
-
onMouseLeave:
|
|
1962
|
-
onTouchStart:
|
|
1963
|
-
onTouchMove:
|
|
1964
|
-
onTouchEnd:
|
|
1969
|
+
onMouseDown: D,
|
|
1970
|
+
onMouseMove: T,
|
|
1971
|
+
onMouseUp: m,
|
|
1972
|
+
onMouseLeave: m,
|
|
1973
|
+
onTouchStart: D,
|
|
1974
|
+
onTouchMove: T,
|
|
1975
|
+
onTouchEnd: m
|
|
1965
1976
|
}
|
|
1966
1977
|
),
|
|
1967
|
-
(
|
|
1978
|
+
(R === "failure" || R === "success") && /* @__PURE__ */ c(
|
|
1968
1979
|
"button",
|
|
1969
1980
|
{
|
|
1970
1981
|
onClick: () => {
|
|
1971
|
-
w([]),
|
|
1982
|
+
w([]), W(0), Y(null), q("idle");
|
|
1972
1983
|
},
|
|
1973
1984
|
style: {
|
|
1974
1985
|
fontSize: 13,
|
|
@@ -1979,70 +1990,79 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
1979
1990
|
color: "var(--security-text)",
|
|
1980
1991
|
cursor: "pointer"
|
|
1981
1992
|
},
|
|
1982
|
-
children:
|
|
1993
|
+
children: S("security.common.retry", "Try Again")
|
|
1983
1994
|
}
|
|
1984
1995
|
),
|
|
1985
|
-
|
|
1996
|
+
J > 0 && R !== "success" && /* @__PURE__ */ c("div", { style: { fontSize: 11, color: "var(--security-warning)" }, children: S("security.pattern.attempts", "{attempts}/{max} attempts").replace("{attempts}", String(J)).replace("{max}", String(s)) })
|
|
1986
1997
|
]
|
|
1987
1998
|
}
|
|
1988
1999
|
);
|
|
1989
|
-
},
|
|
2000
|
+
}, gt = { sm: "8px 16px", md: "12px 24px", lg: "14px 32px" }, mt = { sm: 13, md: 14, lg: 16 }, Wt = (e) => {
|
|
1990
2001
|
const {
|
|
1991
2002
|
mode: t,
|
|
1992
2003
|
credentialIds: r = [],
|
|
1993
2004
|
challenge: n,
|
|
1994
|
-
rpName:
|
|
1995
|
-
rpId:
|
|
1996
|
-
user:
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2005
|
+
rpName: o = window.location.hostname,
|
|
2006
|
+
rpId: s = window.location.hostname,
|
|
2007
|
+
user: a,
|
|
2008
|
+
// no defaults here: the engine applies the documented ones (WebAuthnConfig). Until 1.2.2
|
|
2009
|
+
// these four were read and never passed on — the registration always used the engine's
|
|
2010
|
+
// fixed values, whatever the props said.
|
|
2011
|
+
attestation: i,
|
|
2012
|
+
authenticatorAttachment: y,
|
|
2013
|
+
residentKey: b,
|
|
2014
|
+
userVerification: f,
|
|
2015
|
+
timeout: x,
|
|
2016
|
+
onRegister: A,
|
|
2017
|
+
onAuthenticate: g,
|
|
2018
|
+
onVerify: I,
|
|
2019
|
+
onStatusChange: L,
|
|
2020
|
+
onError: p,
|
|
2021
|
+
label: C,
|
|
2022
|
+
className: S,
|
|
2023
|
+
variant: v = "primary",
|
|
2024
|
+
size: l = "md",
|
|
2025
|
+
fullWidth: w = !1,
|
|
2026
|
+
icon: u
|
|
2027
|
+
} = e, { t: h } = te(), [R, G] = j("idle"), [J, W] = j(!0), [O, Y] = j(!1), _ = K(
|
|
2028
|
+
(D) => {
|
|
2029
|
+
G(D), L == null || L(D);
|
|
2015
2030
|
},
|
|
2016
|
-
[
|
|
2031
|
+
[L]
|
|
2017
2032
|
);
|
|
2018
2033
|
ne(() => {
|
|
2019
|
-
|
|
2034
|
+
W(De()), tt().then(Y);
|
|
2020
2035
|
}, []);
|
|
2021
|
-
const
|
|
2036
|
+
const $ = K(() => {
|
|
2022
2037
|
if (n) {
|
|
2023
|
-
const
|
|
2024
|
-
for (let
|
|
2025
|
-
|
|
2026
|
-
return
|
|
2038
|
+
const D = atob(n.replace(/-/g, "+").replace(/_/g, "/")), T = new Uint8Array(D.length);
|
|
2039
|
+
for (let m = 0; m < D.length; m++)
|
|
2040
|
+
T[m] = D.charCodeAt(m);
|
|
2041
|
+
return T.buffer;
|
|
2027
2042
|
}
|
|
2028
2043
|
return crypto.getRandomValues(new Uint8Array(32)).buffer;
|
|
2029
|
-
}, [n]),
|
|
2030
|
-
if (!
|
|
2031
|
-
|
|
2044
|
+
}, [n]), B = K(async () => {
|
|
2045
|
+
if (!J) {
|
|
2046
|
+
p == null || p(new Error("WebAuthn not available"));
|
|
2032
2047
|
return;
|
|
2033
2048
|
}
|
|
2034
|
-
|
|
2049
|
+
_("processing");
|
|
2035
2050
|
try {
|
|
2036
2051
|
if (t === "register") {
|
|
2037
|
-
const
|
|
2038
|
-
rpName:
|
|
2039
|
-
rpId:
|
|
2040
|
-
userId: typeof
|
|
2041
|
-
userName:
|
|
2042
|
-
userDisplayName:
|
|
2043
|
-
challenge:
|
|
2052
|
+
const D = (a == null ? void 0 : a.id) ?? crypto.getRandomValues(new Uint8Array(16)), T = (a == null ? void 0 : a.name) ?? "user", m = (a == null ? void 0 : a.displayName) ?? T, d = $(), k = await rt({
|
|
2053
|
+
rpName: o,
|
|
2054
|
+
rpId: s,
|
|
2055
|
+
userId: typeof D == "string" ? D : Array.from(D).join(""),
|
|
2056
|
+
userName: T,
|
|
2057
|
+
userDisplayName: m,
|
|
2058
|
+
challenge: d,
|
|
2059
|
+
timeout: x,
|
|
2060
|
+
attestation: i,
|
|
2061
|
+
authenticatorAttachment: y,
|
|
2062
|
+
residentKey: b,
|
|
2063
|
+
userVerification: f
|
|
2044
2064
|
});
|
|
2045
|
-
|
|
2065
|
+
_("success"), k && (A == null || A(k)), I == null || I({
|
|
2046
2066
|
success: !0,
|
|
2047
2067
|
confidence: 1,
|
|
2048
2068
|
method: "webauthn",
|
|
@@ -2050,15 +2070,17 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2050
2070
|
duration: 0
|
|
2051
2071
|
});
|
|
2052
2072
|
} else {
|
|
2053
|
-
const
|
|
2054
|
-
rpId:
|
|
2055
|
-
challenge:
|
|
2056
|
-
allowCredentials: r == null ? void 0 : r.map((
|
|
2057
|
-
id: new TextEncoder().encode(
|
|
2073
|
+
const D = await nt({
|
|
2074
|
+
rpId: s,
|
|
2075
|
+
challenge: $(),
|
|
2076
|
+
allowCredentials: r == null ? void 0 : r.map((T) => ({
|
|
2077
|
+
id: new TextEncoder().encode(T),
|
|
2058
2078
|
type: "public-key"
|
|
2059
|
-
}))
|
|
2079
|
+
})),
|
|
2080
|
+
timeout: x,
|
|
2081
|
+
userVerification: f
|
|
2060
2082
|
});
|
|
2061
|
-
|
|
2083
|
+
_("success"), D && (g == null || g(D)), I == null || I({
|
|
2062
2084
|
success: !0,
|
|
2063
2085
|
confidence: 1,
|
|
2064
2086
|
method: "webauthn",
|
|
@@ -2066,9 +2088,9 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2066
2088
|
duration: 0
|
|
2067
2089
|
});
|
|
2068
2090
|
}
|
|
2069
|
-
} catch (
|
|
2070
|
-
const
|
|
2071
|
-
|
|
2091
|
+
} catch (D) {
|
|
2092
|
+
const T = D instanceof Error ? D : new Error(String(D));
|
|
2093
|
+
T.name === "NotAllowedError" ? _("idle") : (_("error"), p == null || p(T), I == null || I({
|
|
2072
2094
|
success: !1,
|
|
2073
2095
|
confidence: 0,
|
|
2074
2096
|
method: "webauthn",
|
|
@@ -2077,59 +2099,60 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2077
2099
|
}));
|
|
2078
2100
|
}
|
|
2079
2101
|
}, [
|
|
2080
|
-
|
|
2102
|
+
J,
|
|
2081
2103
|
t,
|
|
2082
2104
|
r,
|
|
2105
|
+
a,
|
|
2083
2106
|
o,
|
|
2084
2107
|
s,
|
|
2085
2108
|
i,
|
|
2086
|
-
a,
|
|
2087
|
-
g,
|
|
2088
|
-
v,
|
|
2089
|
-
f,
|
|
2090
|
-
W,
|
|
2091
|
-
J,
|
|
2092
|
-
m,
|
|
2093
|
-
k,
|
|
2094
2109
|
y,
|
|
2095
|
-
|
|
2096
|
-
|
|
2110
|
+
b,
|
|
2111
|
+
f,
|
|
2112
|
+
x,
|
|
2113
|
+
$,
|
|
2114
|
+
_,
|
|
2115
|
+
A,
|
|
2116
|
+
g,
|
|
2117
|
+
I,
|
|
2118
|
+
p
|
|
2119
|
+
]), F = t === "register" ? O ? h("security.webauthn.registerPasskey", "Register Passkey") : h("security.webauthn.register", "Register Security Key") : O ? h("security.webauthn.signInPasskey", "Sign in with Passkey") : h("security.webauthn.signIn", "Sign in with Security Key"), q = C ?? F, H = {
|
|
2097
2120
|
primary: "var(--security-biometric)",
|
|
2098
2121
|
outline: "transparent",
|
|
2099
2122
|
ghost: "transparent"
|
|
2100
|
-
},
|
|
2123
|
+
}, Q = {
|
|
2101
2124
|
primary: "none",
|
|
2102
2125
|
outline: "2px solid var(--security-biometric)",
|
|
2103
2126
|
ghost: "none"
|
|
2104
|
-
},
|
|
2127
|
+
}, E = {
|
|
2105
2128
|
// Label on the brand-coloured button: the on-primary text token, not a surface token.
|
|
2106
2129
|
primary: "var(--nice-color-white, #fff)",
|
|
2107
2130
|
outline: "var(--security-biometric)",
|
|
2108
2131
|
ghost: "var(--security-biometric)"
|
|
2109
|
-
},
|
|
2132
|
+
}, z = !J || R === "processing" || R === "success";
|
|
2110
2133
|
return /* @__PURE__ */ P(
|
|
2111
2134
|
"div",
|
|
2112
2135
|
{
|
|
2113
|
-
className:
|
|
2114
|
-
style: { display:
|
|
2136
|
+
className: S,
|
|
2137
|
+
style: { display: w ? "block" : "inline-block", textAlign: "center" },
|
|
2115
2138
|
children: [
|
|
2116
2139
|
/* @__PURE__ */ P(
|
|
2117
2140
|
"button",
|
|
2118
2141
|
{
|
|
2119
|
-
onClick:
|
|
2120
|
-
disabled:
|
|
2142
|
+
onClick: B,
|
|
2143
|
+
disabled: z,
|
|
2121
2144
|
style: {
|
|
2122
|
-
width:
|
|
2123
|
-
padding:
|
|
2124
|
-
fontSize:
|
|
2145
|
+
width: w ? "100%" : "auto",
|
|
2146
|
+
padding: gt[l],
|
|
2147
|
+
fontSize: mt[l],
|
|
2125
2148
|
fontWeight: 600,
|
|
2126
2149
|
fontFamily: "var(--security-font)",
|
|
2127
|
-
background:
|
|
2128
|
-
color:
|
|
2129
|
-
border:
|
|
2150
|
+
background: H[v],
|
|
2151
|
+
color: E[v],
|
|
2152
|
+
border: Q[v],
|
|
2130
2153
|
borderRadius: "var(--security-radius)",
|
|
2131
|
-
cursor:
|
|
2132
|
-
opacity:
|
|
2154
|
+
cursor: z ? "not-allowed" : "pointer",
|
|
2155
|
+
opacity: z ? 0.6 : 1,
|
|
2133
2156
|
display: "inline-flex",
|
|
2134
2157
|
alignItems: "center",
|
|
2135
2158
|
justifyContent: "center",
|
|
@@ -2137,7 +2160,7 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2137
2160
|
transition: "opacity 0.2s, transform 0.1s"
|
|
2138
2161
|
},
|
|
2139
2162
|
children: [
|
|
2140
|
-
|
|
2163
|
+
R === "processing" && /* @__PURE__ */ c(
|
|
2141
2164
|
"span",
|
|
2142
2165
|
{
|
|
2143
2166
|
style: {
|
|
@@ -2151,7 +2174,7 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2151
2174
|
}
|
|
2152
2175
|
}
|
|
2153
2176
|
),
|
|
2154
|
-
|
|
2177
|
+
R === "success" && /* @__PURE__ */ c(
|
|
2155
2178
|
"span",
|
|
2156
2179
|
{
|
|
2157
2180
|
"aria-hidden": "true",
|
|
@@ -2166,33 +2189,33 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2166
2189
|
}
|
|
2167
2190
|
}
|
|
2168
2191
|
),
|
|
2169
|
-
|
|
2170
|
-
|
|
2192
|
+
u && R !== "processing" && R !== "success" && u,
|
|
2193
|
+
q
|
|
2171
2194
|
]
|
|
2172
2195
|
}
|
|
2173
2196
|
),
|
|
2174
|
-
!
|
|
2175
|
-
|
|
2197
|
+
!J && /* @__PURE__ */ c("div", { style: { fontSize: 11, marginTop: 6, color: "var(--security-warning)" }, children: h("security.webauthn.notAvailable", "WebAuthn is not supported in this browser") }),
|
|
2198
|
+
R === "error" && /* @__PURE__ */ c("div", { style: { fontSize: 11, marginTop: 6, color: "var(--security-error)" }, children: h("security.webauthn.error", "Authentication failed — try again") }),
|
|
2176
2199
|
/* @__PURE__ */ c("style", { children: "@keyframes spin { to { transform: rotate(360deg); } }" })
|
|
2177
2200
|
]
|
|
2178
2201
|
}
|
|
2179
2202
|
);
|
|
2180
|
-
},
|
|
2181
|
-
entries: e,
|
|
2203
|
+
}, vt = [], bt = (e) => e >= 80 ? "var(--security-error)" : e >= 50 ? "var(--security-warning)" : "var(--security-success)", Ht = ({
|
|
2204
|
+
entries: e = vt,
|
|
2182
2205
|
pageSize: t = 20,
|
|
2183
2206
|
showExport: r = !0,
|
|
2184
2207
|
filterMethods: n,
|
|
2185
|
-
onEntryClick:
|
|
2186
|
-
className:
|
|
2187
|
-
label:
|
|
2208
|
+
onEntryClick: o,
|
|
2209
|
+
className: s,
|
|
2210
|
+
label: a
|
|
2188
2211
|
}) => {
|
|
2189
|
-
const { t:
|
|
2190
|
-
let
|
|
2191
|
-
return
|
|
2192
|
-
}, [e,
|
|
2193
|
-
const
|
|
2194
|
-
|
|
2195
|
-
}, [
|
|
2212
|
+
const { t: i } = te(), [y, b] = j("all"), [f, x] = j("all"), [A, g] = j(0), I = ae(() => {
|
|
2213
|
+
let u = [...e];
|
|
2214
|
+
return y !== "all" && (u = u.filter((h) => h.method === y)), f !== "all" && (u = u.filter((h) => h.status === f)), u.sort((h, R) => R.timestamp - h.timestamp), u;
|
|
2215
|
+
}, [e, y, f]), L = Math.max(1, Math.ceil(I.length / t)), p = I.slice(A * t, (A + 1) * t), C = ae(() => n || Array.from(new Set(e.map((u) => u.method))), [e, n]), S = ae(() => Array.from(new Set(e.map((u) => u.status))), [e]), v = K(() => {
|
|
2216
|
+
const u = new Blob([JSON.stringify(I, null, 2)], { type: "application/json" }), h = URL.createObjectURL(u), R = document.createElement("a");
|
|
2217
|
+
R.href = h, R.download = `security-audit-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}.json`, R.click(), URL.revokeObjectURL(h);
|
|
2218
|
+
}, [I]), l = (u) => new Date(u).toLocaleString(), w = {
|
|
2196
2219
|
padding: "8px 12px",
|
|
2197
2220
|
borderBottom: "1px solid var(--security-border)",
|
|
2198
2221
|
fontSize: 13,
|
|
@@ -2201,7 +2224,7 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2201
2224
|
return /* @__PURE__ */ P(
|
|
2202
2225
|
"div",
|
|
2203
2226
|
{
|
|
2204
|
-
className:
|
|
2227
|
+
className: s,
|
|
2205
2228
|
style: {
|
|
2206
2229
|
fontFamily: "var(--security-font)",
|
|
2207
2230
|
color: "var(--security-text)",
|
|
@@ -2223,19 +2246,19 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2223
2246
|
borderBottom: "1px solid var(--security-border)"
|
|
2224
2247
|
},
|
|
2225
2248
|
children: [
|
|
2226
|
-
/* @__PURE__ */ c("div", { style: { fontWeight: 600, fontSize: 15 }, children:
|
|
2249
|
+
/* @__PURE__ */ c("div", { style: { fontWeight: 600, fontSize: 15 }, children: a ?? i("security.audit.title", "Security Audit Log") }),
|
|
2227
2250
|
/* @__PURE__ */ P("div", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
|
|
2228
2251
|
/* @__PURE__ */ P(
|
|
2229
2252
|
"select",
|
|
2230
2253
|
{
|
|
2231
|
-
value:
|
|
2232
|
-
onChange: (
|
|
2233
|
-
|
|
2254
|
+
value: y,
|
|
2255
|
+
onChange: (u) => {
|
|
2256
|
+
b(u.target.value), g(0);
|
|
2234
2257
|
},
|
|
2235
2258
|
style: xe,
|
|
2236
2259
|
children: [
|
|
2237
|
-
/* @__PURE__ */ c("option", { value: "all", children:
|
|
2238
|
-
|
|
2260
|
+
/* @__PURE__ */ c("option", { value: "all", children: i("security.audit.allMethods", "All methods") }),
|
|
2261
|
+
C.map((u) => /* @__PURE__ */ c("option", { value: u, children: u }, u))
|
|
2239
2262
|
]
|
|
2240
2263
|
}
|
|
2241
2264
|
),
|
|
@@ -2243,23 +2266,23 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2243
2266
|
"select",
|
|
2244
2267
|
{
|
|
2245
2268
|
value: f,
|
|
2246
|
-
onChange: (
|
|
2247
|
-
|
|
2269
|
+
onChange: (u) => {
|
|
2270
|
+
x(u.target.value), g(0);
|
|
2248
2271
|
},
|
|
2249
2272
|
style: xe,
|
|
2250
2273
|
children: [
|
|
2251
|
-
/* @__PURE__ */ c("option", { value: "all", children:
|
|
2252
|
-
|
|
2274
|
+
/* @__PURE__ */ c("option", { value: "all", children: i("security.audit.allStatuses", "All statuses") }),
|
|
2275
|
+
S.map((u) => /* @__PURE__ */ c("option", { value: u, children: u }, u))
|
|
2253
2276
|
]
|
|
2254
2277
|
}
|
|
2255
2278
|
),
|
|
2256
2279
|
r && /* @__PURE__ */ c(
|
|
2257
2280
|
"button",
|
|
2258
2281
|
{
|
|
2259
|
-
onClick:
|
|
2260
|
-
style:
|
|
2261
|
-
title:
|
|
2262
|
-
children: "JSON"
|
|
2282
|
+
onClick: v,
|
|
2283
|
+
style: xt,
|
|
2284
|
+
title: i("security.audit.exportJson", "Export JSON"),
|
|
2285
|
+
children: i("security.json", "JSON")
|
|
2263
2286
|
}
|
|
2264
2287
|
)
|
|
2265
2288
|
] })
|
|
@@ -2278,17 +2301,17 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2278
2301
|
letterSpacing: 0.5
|
|
2279
2302
|
},
|
|
2280
2303
|
children: [
|
|
2281
|
-
/* @__PURE__ */ c("th", { style: { ...w, textAlign: "left" }, children:
|
|
2282
|
-
/* @__PURE__ */ c("th", { style: { ...w, textAlign: "left" }, children:
|
|
2283
|
-
/* @__PURE__ */ c("th", { style: { ...w, textAlign: "center" }, children:
|
|
2284
|
-
/* @__PURE__ */ c("th", { style: { ...w, textAlign: "center" }, children:
|
|
2285
|
-
/* @__PURE__ */ c("th", { style: { ...w, textAlign: "center" }, children:
|
|
2286
|
-
/* @__PURE__ */ c("th", { style: { ...w, textAlign: "left" }, children:
|
|
2304
|
+
/* @__PURE__ */ c("th", { style: { ...w, textAlign: "left" }, children: i("security.audit.time", "Time") }),
|
|
2305
|
+
/* @__PURE__ */ c("th", { style: { ...w, textAlign: "left" }, children: i("security.audit.action", "Action") }),
|
|
2306
|
+
/* @__PURE__ */ c("th", { style: { ...w, textAlign: "center" }, children: i("security.audit.method", "Method") }),
|
|
2307
|
+
/* @__PURE__ */ c("th", { style: { ...w, textAlign: "center" }, children: i("security.audit.status", "Status") }),
|
|
2308
|
+
/* @__PURE__ */ c("th", { style: { ...w, textAlign: "center" }, children: i("security.audit.risk", "Risk") }),
|
|
2309
|
+
/* @__PURE__ */ c("th", { style: { ...w, textAlign: "left" }, children: i("security.audit.device", "Device") })
|
|
2287
2310
|
]
|
|
2288
2311
|
}
|
|
2289
2312
|
) }),
|
|
2290
2313
|
/* @__PURE__ */ P("tbody", { children: [
|
|
2291
|
-
|
|
2314
|
+
p.length === 0 && /* @__PURE__ */ c("tr", { children: /* @__PURE__ */ c(
|
|
2292
2315
|
"td",
|
|
2293
2316
|
{
|
|
2294
2317
|
colSpan: 6,
|
|
@@ -2298,14 +2321,14 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2298
2321
|
color: "var(--security-text-muted)",
|
|
2299
2322
|
padding: 24
|
|
2300
2323
|
},
|
|
2301
|
-
children:
|
|
2324
|
+
children: i("security.audit.noEntries", "No entries to show")
|
|
2302
2325
|
}
|
|
2303
2326
|
) }),
|
|
2304
|
-
|
|
2327
|
+
p.map((u) => /* @__PURE__ */ P(
|
|
2305
2328
|
"tr",
|
|
2306
2329
|
{
|
|
2307
|
-
onClick: () =>
|
|
2308
|
-
style: { cursor:
|
|
2330
|
+
onClick: () => o == null ? void 0 : o(u),
|
|
2331
|
+
style: { cursor: o ? "pointer" : "default" },
|
|
2309
2332
|
onMouseEnter: (h) => {
|
|
2310
2333
|
h.currentTarget.style.background = "var(--security-bg-panel)";
|
|
2311
2334
|
},
|
|
@@ -2313,8 +2336,8 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2313
2336
|
h.currentTarget.style.background = "";
|
|
2314
2337
|
},
|
|
2315
2338
|
children: [
|
|
2316
|
-
/* @__PURE__ */ c("td", { style: w, children: u
|
|
2317
|
-
/* @__PURE__ */ c("td", { style: w, children:
|
|
2339
|
+
/* @__PURE__ */ c("td", { style: w, children: l(u.timestamp) }),
|
|
2340
|
+
/* @__PURE__ */ c("td", { style: w, children: u.action }),
|
|
2318
2341
|
/* @__PURE__ */ c("td", { style: { ...w, textAlign: "center" }, children: /* @__PURE__ */ c(
|
|
2319
2342
|
"span",
|
|
2320
2343
|
{
|
|
@@ -2326,11 +2349,11 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2326
2349
|
background: "var(--security-bg-panel)",
|
|
2327
2350
|
border: "1px solid var(--security-border)"
|
|
2328
2351
|
},
|
|
2329
|
-
children:
|
|
2352
|
+
children: u.method
|
|
2330
2353
|
}
|
|
2331
2354
|
) }),
|
|
2332
|
-
/* @__PURE__ */ c("td", { style: { ...w, textAlign: "center" }, children:
|
|
2333
|
-
/* @__PURE__ */ c("td", { style: { ...w, textAlign: "center" }, children:
|
|
2355
|
+
/* @__PURE__ */ c("td", { style: { ...w, textAlign: "center" }, children: u.status }),
|
|
2356
|
+
/* @__PURE__ */ c("td", { style: { ...w, textAlign: "center" }, children: u.riskScore != null && /* @__PURE__ */ c("span", { style: { color: bt(u.riskScore), fontWeight: 600 }, children: u.riskScore }) }),
|
|
2334
2357
|
/* @__PURE__ */ c(
|
|
2335
2358
|
"td",
|
|
2336
2359
|
{
|
|
@@ -2340,16 +2363,16 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2340
2363
|
overflow: "hidden",
|
|
2341
2364
|
textOverflow: "ellipsis"
|
|
2342
2365
|
},
|
|
2343
|
-
children:
|
|
2366
|
+
children: u.device ?? "—"
|
|
2344
2367
|
}
|
|
2345
2368
|
)
|
|
2346
2369
|
]
|
|
2347
2370
|
},
|
|
2348
|
-
|
|
2371
|
+
u.id
|
|
2349
2372
|
))
|
|
2350
2373
|
] })
|
|
2351
2374
|
] }) }),
|
|
2352
|
-
|
|
2375
|
+
L > 1 && /* @__PURE__ */ P(
|
|
2353
2376
|
"div",
|
|
2354
2377
|
{
|
|
2355
2378
|
style: {
|
|
@@ -2363,24 +2386,26 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2363
2386
|
borderTop: "1px solid var(--security-border)"
|
|
2364
2387
|
},
|
|
2365
2388
|
children: [
|
|
2366
|
-
/* @__PURE__ */ P("button", { disabled:
|
|
2367
|
-
"
|
|
2368
|
-
|
|
2389
|
+
/* @__PURE__ */ P("button", { disabled: A === 0, onClick: () => g(A - 1), style: we, children: [
|
|
2390
|
+
/* @__PURE__ */ c(Le, { size: 14, style: { verticalAlign: "-2px" } }),
|
|
2391
|
+
" ",
|
|
2392
|
+
i("security.audit.prev", "Prev")
|
|
2369
2393
|
] }),
|
|
2370
2394
|
/* @__PURE__ */ P("span", { children: [
|
|
2371
|
-
|
|
2395
|
+
A + 1,
|
|
2372
2396
|
" / ",
|
|
2373
|
-
|
|
2397
|
+
L
|
|
2374
2398
|
] }),
|
|
2375
2399
|
/* @__PURE__ */ P(
|
|
2376
2400
|
"button",
|
|
2377
2401
|
{
|
|
2378
|
-
disabled:
|
|
2379
|
-
onClick: () =>
|
|
2402
|
+
disabled: A >= L - 1,
|
|
2403
|
+
onClick: () => g(A + 1),
|
|
2380
2404
|
style: we,
|
|
2381
2405
|
children: [
|
|
2382
|
-
|
|
2383
|
-
"
|
|
2406
|
+
i("security.audit.next", "Next"),
|
|
2407
|
+
" ",
|
|
2408
|
+
/* @__PURE__ */ c($e, { size: 14, style: { verticalAlign: "-2px" } })
|
|
2384
2409
|
]
|
|
2385
2410
|
}
|
|
2386
2411
|
)
|
|
@@ -2396,7 +2421,10 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2396
2421
|
color: "var(--security-text-muted)",
|
|
2397
2422
|
textAlign: "right"
|
|
2398
2423
|
},
|
|
2399
|
-
children:
|
|
2424
|
+
children: i("security.audit.total", "{count} entries").replace(
|
|
2425
|
+
"{count}",
|
|
2426
|
+
String(I.length)
|
|
2427
|
+
)
|
|
2400
2428
|
}
|
|
2401
2429
|
)
|
|
2402
2430
|
]
|
|
@@ -2409,7 +2437,7 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2409
2437
|
color: "var(--security-text)",
|
|
2410
2438
|
border: "1px solid var(--security-border)",
|
|
2411
2439
|
borderRadius: "var(--security-radius)"
|
|
2412
|
-
},
|
|
2440
|
+
}, xt = {
|
|
2413
2441
|
background: "none",
|
|
2414
2442
|
border: "1px solid var(--security-border)",
|
|
2415
2443
|
borderRadius: "var(--security-radius)",
|
|
@@ -2423,7 +2451,7 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2423
2451
|
color: "var(--security-biometric)",
|
|
2424
2452
|
fontWeight: 600,
|
|
2425
2453
|
fontSize: 13
|
|
2426
|
-
}, Se = {
|
|
2454
|
+
}, wt = [], Se = {
|
|
2427
2455
|
display: "inline-block",
|
|
2428
2456
|
width: "0.3em",
|
|
2429
2457
|
height: "0.6em",
|
|
@@ -2431,20 +2459,20 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2431
2459
|
borderRight: "0.12em solid currentColor",
|
|
2432
2460
|
borderBottom: "0.12em solid currentColor",
|
|
2433
2461
|
transform: "rotate(45deg)"
|
|
2434
|
-
},
|
|
2435
|
-
options: e,
|
|
2462
|
+
}, Ot = ({
|
|
2463
|
+
options: e = wt,
|
|
2436
2464
|
requiredCount: t = 1,
|
|
2437
2465
|
onSelect: r,
|
|
2438
2466
|
onComplete: n,
|
|
2439
|
-
className:
|
|
2440
|
-
label:
|
|
2441
|
-
layout:
|
|
2467
|
+
className: o,
|
|
2468
|
+
label: s,
|
|
2469
|
+
layout: a = "grid"
|
|
2442
2470
|
}) => {
|
|
2443
|
-
const { t:
|
|
2471
|
+
const { t: i } = te(), y = e.filter((f) => f.verified).length, b = y >= t;
|
|
2444
2472
|
return /* @__PURE__ */ P(
|
|
2445
2473
|
"div",
|
|
2446
2474
|
{
|
|
2447
|
-
className:
|
|
2475
|
+
className: o,
|
|
2448
2476
|
style: {
|
|
2449
2477
|
fontFamily: "var(--security-font)",
|
|
2450
2478
|
color: "var(--security-text)",
|
|
@@ -2453,40 +2481,40 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2453
2481
|
gap: 16
|
|
2454
2482
|
},
|
|
2455
2483
|
children: [
|
|
2456
|
-
|
|
2457
|
-
t > 1 && /* @__PURE__ */ c("div", { style: { fontSize: 13, color: "var(--security-text-secondary)" }, children:
|
|
2484
|
+
s && /* @__PURE__ */ c("div", { style: { fontSize: 15, fontWeight: 600 }, children: s }),
|
|
2485
|
+
t > 1 && /* @__PURE__ */ c("div", { style: { fontSize: 13, color: "var(--security-text-secondary)" }, children: i("security.mfa.progress", "Verified {verified} of {required} required").replace("{verified}", String(y)).replace("{required}", String(t)) }),
|
|
2458
2486
|
/* @__PURE__ */ c(
|
|
2459
2487
|
"div",
|
|
2460
2488
|
{
|
|
2461
2489
|
style: {
|
|
2462
|
-
display:
|
|
2463
|
-
gridTemplateColumns:
|
|
2464
|
-
flexDirection:
|
|
2490
|
+
display: a === "grid" ? "grid" : "flex",
|
|
2491
|
+
gridTemplateColumns: a === "grid" ? "repeat(auto-fill, minmax(140px, 1fr))" : void 0,
|
|
2492
|
+
flexDirection: a === "list" ? "column" : void 0,
|
|
2465
2493
|
gap: 12
|
|
2466
2494
|
},
|
|
2467
2495
|
children: e.map((f) => {
|
|
2468
|
-
const
|
|
2496
|
+
const x = f.verified ?? !1, A = f.disabled || b;
|
|
2469
2497
|
return /* @__PURE__ */ P(
|
|
2470
2498
|
"button",
|
|
2471
2499
|
{
|
|
2472
|
-
onClick: () => !
|
|
2473
|
-
disabled:
|
|
2500
|
+
onClick: () => !A && !x && (r == null ? void 0 : r(f.method)),
|
|
2501
|
+
disabled: A || x,
|
|
2474
2502
|
style: {
|
|
2475
2503
|
display: "flex",
|
|
2476
|
-
flexDirection:
|
|
2504
|
+
flexDirection: a === "grid" ? "column" : "row",
|
|
2477
2505
|
alignItems: "center",
|
|
2478
|
-
gap:
|
|
2479
|
-
padding:
|
|
2480
|
-
background:
|
|
2481
|
-
border: `2px solid ${
|
|
2506
|
+
gap: a === "grid" ? 8 : 12,
|
|
2507
|
+
padding: a === "grid" ? "20px 16px" : "12px 16px",
|
|
2508
|
+
background: x ? "color-mix(in srgb, var(--nice-color-success, #10b981) 8%, transparent)" : "var(--security-bg-panel)",
|
|
2509
|
+
border: `2px solid ${x ? "var(--security-success)" : "var(--security-border)"}`,
|
|
2482
2510
|
borderRadius: "var(--security-radius-lg)",
|
|
2483
|
-
cursor:
|
|
2484
|
-
opacity:
|
|
2511
|
+
cursor: A || x ? "default" : "pointer",
|
|
2512
|
+
opacity: A && !x ? 0.5 : 1,
|
|
2485
2513
|
transition: "border-color 0.2s, background 0.2s",
|
|
2486
|
-
textAlign:
|
|
2514
|
+
textAlign: a === "grid" ? "center" : "left"
|
|
2487
2515
|
},
|
|
2488
2516
|
children: [
|
|
2489
|
-
/* @__PURE__ */ c("span", { style: { fontSize: 28 }, children:
|
|
2517
|
+
/* @__PURE__ */ c("span", { style: { fontSize: 28 }, children: x ? /* @__PURE__ */ c(
|
|
2490
2518
|
"span",
|
|
2491
2519
|
{
|
|
2492
2520
|
"aria-label": "verified",
|
|
@@ -2504,7 +2532,7 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2504
2532
|
})
|
|
2505
2533
|
}
|
|
2506
2534
|
),
|
|
2507
|
-
|
|
2535
|
+
b && /* @__PURE__ */ P(
|
|
2508
2536
|
"div",
|
|
2509
2537
|
{
|
|
2510
2538
|
style: {
|
|
@@ -2516,37 +2544,37 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2516
2544
|
},
|
|
2517
2545
|
children: [
|
|
2518
2546
|
/* @__PURE__ */ c("span", { "aria-hidden": "true", style: Se }),
|
|
2519
|
-
|
|
2547
|
+
i("security.mfa.complete", "All factors verified")
|
|
2520
2548
|
]
|
|
2521
2549
|
}
|
|
2522
2550
|
)
|
|
2523
2551
|
]
|
|
2524
2552
|
}
|
|
2525
2553
|
);
|
|
2526
|
-
},
|
|
2527
|
-
sessions: e,
|
|
2554
|
+
}, St = [], Ut = ({
|
|
2555
|
+
sessions: e = St,
|
|
2528
2556
|
onRevoke: t,
|
|
2529
2557
|
onRevokeAll: r,
|
|
2530
2558
|
onTrust: n,
|
|
2531
|
-
className:
|
|
2532
|
-
label:
|
|
2533
|
-
showRevokeAll:
|
|
2559
|
+
className: o,
|
|
2560
|
+
label: s,
|
|
2561
|
+
showRevokeAll: a = !0
|
|
2534
2562
|
}) => {
|
|
2535
|
-
const { t:
|
|
2563
|
+
const { t: i } = te(), [y, b] = j(/* @__PURE__ */ new Set()), f = ae(
|
|
2536
2564
|
() => [...e].sort(
|
|
2537
|
-
(
|
|
2565
|
+
(g, I) => (I.current ? 1 : 0) - (g.current ? 1 : 0) || I.lastActive - g.lastActive
|
|
2538
2566
|
),
|
|
2539
2567
|
[e]
|
|
2540
|
-
),
|
|
2541
|
-
const
|
|
2542
|
-
return
|
|
2543
|
-
},
|
|
2544
|
-
|
|
2568
|
+
), x = (g) => {
|
|
2569
|
+
const I = new Date(g), p = Date.now() - g;
|
|
2570
|
+
return p < 6e4 ? i("security.session.justNow", "Just now") : p < 36e5 ? `${Math.floor(p / 6e4)}m ago` : p < 864e5 ? `${Math.floor(p / 36e5)}h ago` : I.toLocaleDateString();
|
|
2571
|
+
}, A = (g) => {
|
|
2572
|
+
b((I) => new Set(I).add(g)), t == null || t(g);
|
|
2545
2573
|
};
|
|
2546
2574
|
return /* @__PURE__ */ P(
|
|
2547
2575
|
"div",
|
|
2548
2576
|
{
|
|
2549
|
-
className:
|
|
2577
|
+
className: o,
|
|
2550
2578
|
style: {
|
|
2551
2579
|
fontFamily: "var(--security-font)",
|
|
2552
2580
|
color: "var(--security-text)",
|
|
@@ -2568,8 +2596,8 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2568
2596
|
borderBottom: "1px solid var(--security-border)"
|
|
2569
2597
|
},
|
|
2570
2598
|
children: [
|
|
2571
|
-
/* @__PURE__ */ c("div", { style: { fontSize: 15, fontWeight: 600 }, children:
|
|
2572
|
-
|
|
2599
|
+
/* @__PURE__ */ c("div", { style: { fontSize: 15, fontWeight: 600 }, children: s ?? i("security.session.title", "Active Sessions") }),
|
|
2600
|
+
a && e.length > 1 && /* @__PURE__ */ c(
|
|
2573
2601
|
"button",
|
|
2574
2602
|
{
|
|
2575
2603
|
onClick: r,
|
|
@@ -2582,14 +2610,14 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2582
2610
|
color: "var(--security-error)",
|
|
2583
2611
|
cursor: "pointer"
|
|
2584
2612
|
},
|
|
2585
|
-
children:
|
|
2613
|
+
children: i("security.session.revokeAll", "Revoke all others")
|
|
2586
2614
|
}
|
|
2587
2615
|
)
|
|
2588
2616
|
]
|
|
2589
2617
|
}
|
|
2590
2618
|
),
|
|
2591
2619
|
/* @__PURE__ */ P("div", { children: [
|
|
2592
|
-
f.map((
|
|
2620
|
+
f.map((g) => /* @__PURE__ */ P(
|
|
2593
2621
|
"div",
|
|
2594
2622
|
{
|
|
2595
2623
|
style: {
|
|
@@ -2598,8 +2626,8 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2598
2626
|
justifyContent: "space-between",
|
|
2599
2627
|
padding: "12px 16px",
|
|
2600
2628
|
borderBottom: "1px solid var(--security-border)",
|
|
2601
|
-
opacity:
|
|
2602
|
-
background:
|
|
2629
|
+
opacity: y.has(g.id) ? 0.5 : 1,
|
|
2630
|
+
background: g.current ? "color-mix(in srgb, var(--nice-color-primary, #3b82f6) 4%, transparent)" : void 0
|
|
2603
2631
|
},
|
|
2604
2632
|
children: [
|
|
2605
2633
|
/* @__PURE__ */ P("div", { style: { display: "flex", gap: 12, alignItems: "center" }, children: [
|
|
@@ -2613,13 +2641,13 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2613
2641
|
color: "var(--security-text-muted)",
|
|
2614
2642
|
minWidth: 48
|
|
2615
2643
|
},
|
|
2616
|
-
children:
|
|
2644
|
+
children: g.device.toLowerCase().includes("mobile") ? i("security.session.mobile", "Mobile") : i("security.session.desktop", "Desktop")
|
|
2617
2645
|
}
|
|
2618
2646
|
),
|
|
2619
2647
|
/* @__PURE__ */ P("div", { children: [
|
|
2620
2648
|
/* @__PURE__ */ P("div", { style: { fontSize: 14, fontWeight: 500 }, children: [
|
|
2621
|
-
|
|
2622
|
-
|
|
2649
|
+
g.device,
|
|
2650
|
+
g.current && /* @__PURE__ */ c(
|
|
2623
2651
|
"span",
|
|
2624
2652
|
{
|
|
2625
2653
|
style: {
|
|
@@ -2630,10 +2658,10 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2630
2658
|
color: "var(--nice-color-white, #fff)",
|
|
2631
2659
|
borderRadius: 8
|
|
2632
2660
|
},
|
|
2633
|
-
children:
|
|
2661
|
+
children: i("security.session.current", "Current")
|
|
2634
2662
|
}
|
|
2635
2663
|
),
|
|
2636
|
-
|
|
2664
|
+
g.trusted && /* @__PURE__ */ c(
|
|
2637
2665
|
"span",
|
|
2638
2666
|
{
|
|
2639
2667
|
style: {
|
|
@@ -2647,24 +2675,24 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2647
2675
|
color: "var(--nice-success-text, #065f46)",
|
|
2648
2676
|
borderRadius: 8
|
|
2649
2677
|
},
|
|
2650
|
-
children:
|
|
2678
|
+
children: i("security.session.trusted", "Trusted")
|
|
2651
2679
|
}
|
|
2652
2680
|
)
|
|
2653
2681
|
] }),
|
|
2654
|
-
/* @__PURE__ */ c("div", { style: { fontSize: 12, color: "var(--security-text-muted)", marginTop: 2 }, children: [
|
|
2682
|
+
/* @__PURE__ */ c("div", { style: { fontSize: 12, color: "var(--security-text-muted)", marginTop: 2 }, children: [g.browser, g.os, g.location].filter(Boolean).join(" · ") }),
|
|
2655
2683
|
/* @__PURE__ */ P("div", { style: { fontSize: 11, color: "var(--security-text-muted)", marginTop: 1 }, children: [
|
|
2656
|
-
|
|
2684
|
+
i("security.session.lastActive", "Last active"),
|
|
2657
2685
|
":",
|
|
2658
2686
|
" ",
|
|
2659
|
-
|
|
2687
|
+
x(g.lastActive)
|
|
2660
2688
|
] })
|
|
2661
2689
|
] })
|
|
2662
2690
|
] }),
|
|
2663
2691
|
/* @__PURE__ */ P("div", { style: { display: "flex", gap: 6 }, children: [
|
|
2664
|
-
n && !
|
|
2692
|
+
n && !g.current && /* @__PURE__ */ c(
|
|
2665
2693
|
"button",
|
|
2666
2694
|
{
|
|
2667
|
-
onClick: () => n(
|
|
2695
|
+
onClick: () => n(g.id, !g.trusted),
|
|
2668
2696
|
style: {
|
|
2669
2697
|
fontSize: 11,
|
|
2670
2698
|
padding: "4px 8px",
|
|
@@ -2674,14 +2702,14 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2674
2702
|
cursor: "pointer",
|
|
2675
2703
|
color: "var(--security-text-secondary)"
|
|
2676
2704
|
},
|
|
2677
|
-
children:
|
|
2705
|
+
children: g.trusted ? i("security.session.untrust", "Untrust") : i("security.session.trust", "Trust")
|
|
2678
2706
|
}
|
|
2679
2707
|
),
|
|
2680
|
-
!
|
|
2708
|
+
!g.current && /* @__PURE__ */ c(
|
|
2681
2709
|
"button",
|
|
2682
2710
|
{
|
|
2683
|
-
onClick: () =>
|
|
2684
|
-
disabled:
|
|
2711
|
+
onClick: () => A(g.id),
|
|
2712
|
+
disabled: y.has(g.id),
|
|
2685
2713
|
style: {
|
|
2686
2714
|
fontSize: 11,
|
|
2687
2715
|
padding: "4px 10px",
|
|
@@ -2691,13 +2719,13 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2691
2719
|
cursor: "pointer",
|
|
2692
2720
|
color: "var(--security-error)"
|
|
2693
2721
|
},
|
|
2694
|
-
children:
|
|
2722
|
+
children: i("security.session.revoke", "Revoke")
|
|
2695
2723
|
}
|
|
2696
2724
|
)
|
|
2697
2725
|
] })
|
|
2698
2726
|
]
|
|
2699
2727
|
},
|
|
2700
|
-
|
|
2728
|
+
g.id
|
|
2701
2729
|
)),
|
|
2702
2730
|
e.length === 0 && /* @__PURE__ */ c(
|
|
2703
2731
|
"div",
|
|
@@ -2708,98 +2736,103 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2708
2736
|
color: "var(--security-text-muted)",
|
|
2709
2737
|
fontSize: 13
|
|
2710
2738
|
},
|
|
2711
|
-
children:
|
|
2739
|
+
children: i("security.session.noSessions", "No active sessions")
|
|
2712
2740
|
}
|
|
2713
2741
|
)
|
|
2714
2742
|
] })
|
|
2715
2743
|
]
|
|
2716
2744
|
}
|
|
2717
2745
|
);
|
|
2718
|
-
},
|
|
2746
|
+
}, qt = ({
|
|
2719
2747
|
trustScore: e,
|
|
2720
2748
|
onScoreComputed: t,
|
|
2721
2749
|
trustThreshold: r = 60,
|
|
2722
2750
|
showFactors: n = !0,
|
|
2723
|
-
showFingerprint:
|
|
2724
|
-
className:
|
|
2725
|
-
label:
|
|
2751
|
+
showFingerprint: o = !1,
|
|
2752
|
+
className: s,
|
|
2753
|
+
label: a
|
|
2726
2754
|
}) => {
|
|
2727
|
-
const { t:
|
|
2728
|
-
|
|
2729
|
-
|
|
2755
|
+
const { t: i } = te(), [y, b] = j(e ?? null), [f, x] = j(!e), A = V(t);
|
|
2756
|
+
A.current = t;
|
|
2757
|
+
const g = K(async () => {
|
|
2758
|
+
var L, p;
|
|
2759
|
+
x(!0);
|
|
2730
2760
|
try {
|
|
2731
|
-
const
|
|
2732
|
-
let
|
|
2733
|
-
|
|
2734
|
-
name: "Known platform",
|
|
2761
|
+
const C = Ce(), S = await de(), v = [];
|
|
2762
|
+
let l = 50;
|
|
2763
|
+
C.platform && !C.platform.includes("Linux") && (v.push({
|
|
2764
|
+
name: i("security.trust.knownPlatform", "Known platform"),
|
|
2735
2765
|
score: 5,
|
|
2736
|
-
description: "Running on a recognized platform",
|
|
2766
|
+
description: i("security.trust.knownPlatformHint", "Running on a recognized platform"),
|
|
2737
2767
|
weight: 0.05
|
|
2738
|
-
}),
|
|
2739
|
-
name: "Cookies enabled",
|
|
2768
|
+
}), l += 5), navigator.cookieEnabled && (v.push({
|
|
2769
|
+
name: i("security.trust.cookiesEnabled", "Cookies enabled"),
|
|
2740
2770
|
score: 5,
|
|
2741
|
-
description: "Browser cookies are enabled",
|
|
2771
|
+
description: i("security.trust.cookiesEnabledHint", "Browser cookies are enabled"),
|
|
2742
2772
|
weight: 0.05
|
|
2743
|
-
}),
|
|
2744
|
-
name: "Standard resolution",
|
|
2773
|
+
}), l += 5), C.screenResolution[0] >= 360 && C.screenResolution[1] >= 640 && (v.push({
|
|
2774
|
+
name: i("security.trust.standardResolution", "Standard resolution"),
|
|
2745
2775
|
score: 5,
|
|
2746
|
-
description:
|
|
2776
|
+
description: i(
|
|
2777
|
+
"security.trust.standardResolutionHint",
|
|
2778
|
+
"Screen resolution within normal range"
|
|
2779
|
+
),
|
|
2747
2780
|
weight: 0.05
|
|
2748
|
-
}),
|
|
2749
|
-
name: "Secure context",
|
|
2781
|
+
}), l += 5), typeof window < "u" && window.isSecureContext && (v.push({
|
|
2782
|
+
name: i("security.trust.secureContext", "Secure context"),
|
|
2750
2783
|
score: 10,
|
|
2751
|
-
description: "Running in HTTPS secure context",
|
|
2784
|
+
description: i("security.trust.secureContextHint", "Running in HTTPS secure context"),
|
|
2752
2785
|
weight: 0.1
|
|
2753
|
-
}),
|
|
2754
|
-
name: "Language configured",
|
|
2786
|
+
}), l += 10), ((L = navigator.languages) == null ? void 0 : L.length) > 0 && (v.push({
|
|
2787
|
+
name: i("security.trust.languageConfigured", "Language configured"),
|
|
2755
2788
|
score: 5,
|
|
2756
|
-
description: "Browser language is set",
|
|
2789
|
+
description: i("security.trust.languageConfiguredHint", "Browser language is set"),
|
|
2757
2790
|
weight: 0.05
|
|
2758
|
-
}),
|
|
2759
|
-
name: "Touch device",
|
|
2791
|
+
}), l += 5), C.touchSupport && (v.push({
|
|
2792
|
+
name: i("security.trust.touchDevice", "Touch device"),
|
|
2760
2793
|
score: 5,
|
|
2761
|
-
description: "Touch input is supported",
|
|
2794
|
+
description: i("security.trust.touchDeviceHint", "Touch input is supported"),
|
|
2762
2795
|
weight: 0.05
|
|
2763
|
-
}),
|
|
2796
|
+
}), l += 5);
|
|
2764
2797
|
try {
|
|
2765
|
-
const
|
|
2766
|
-
|
|
2767
|
-
name: "Hardware GPU",
|
|
2798
|
+
const R = document.createElement("canvas").getContext("webgl");
|
|
2799
|
+
R && R.getExtension("WEBGL_debug_renderer_info") && (v.push({
|
|
2800
|
+
name: i("security.trust.hardwareGpu", "Hardware GPU"),
|
|
2768
2801
|
score: 10,
|
|
2769
|
-
description: "Hardware GPU detected",
|
|
2802
|
+
description: i("security.trust.hardwareGpuHint", "Hardware GPU detected"),
|
|
2770
2803
|
weight: 0.1
|
|
2771
|
-
}),
|
|
2804
|
+
}), l += 10);
|
|
2772
2805
|
} catch {
|
|
2773
2806
|
}
|
|
2774
|
-
navigator.credentials && (
|
|
2775
|
-
name: "Credential API",
|
|
2807
|
+
navigator.credentials && (v.push({
|
|
2808
|
+
name: i("security.trust.credentialApi", "Credential API"),
|
|
2776
2809
|
score: 5,
|
|
2777
|
-
description: "Credential Management API available",
|
|
2810
|
+
description: i("security.trust.credentialApiHint", "Credential Management API available"),
|
|
2778
2811
|
weight: 0.05
|
|
2779
|
-
}),
|
|
2780
|
-
const
|
|
2781
|
-
score:
|
|
2782
|
-
factors:
|
|
2783
|
-
trusted:
|
|
2784
|
-
firstSeen:
|
|
2785
|
-
lastSeen:
|
|
2786
|
-
fingerprint:
|
|
2812
|
+
}), l += 5), l = Math.min(100, Math.max(0, l));
|
|
2813
|
+
const w = Date.now(), u = {
|
|
2814
|
+
score: l,
|
|
2815
|
+
factors: v,
|
|
2816
|
+
trusted: l >= r,
|
|
2817
|
+
firstSeen: w,
|
|
2818
|
+
lastSeen: w,
|
|
2819
|
+
fingerprint: S
|
|
2787
2820
|
};
|
|
2788
|
-
|
|
2821
|
+
b(u), (p = A.current) == null || p.call(A, u);
|
|
2789
2822
|
} finally {
|
|
2790
|
-
|
|
2823
|
+
x(!1);
|
|
2791
2824
|
}
|
|
2792
|
-
}, [r,
|
|
2825
|
+
}, [r, i]);
|
|
2793
2826
|
ne(() => {
|
|
2794
|
-
e ||
|
|
2795
|
-
}, [e,
|
|
2796
|
-
e &&
|
|
2827
|
+
e || g();
|
|
2828
|
+
}, [e, g]), ne(() => {
|
|
2829
|
+
e && b(e);
|
|
2797
2830
|
}, [e]);
|
|
2798
|
-
const
|
|
2831
|
+
const I = y ? y.score >= 80 ? "var(--security-success)" : y.score >= 50 ? "var(--security-warning)" : "var(--security-error)" : "var(--security-text-muted)";
|
|
2799
2832
|
return /* @__PURE__ */ P(
|
|
2800
2833
|
"div",
|
|
2801
2834
|
{
|
|
2802
|
-
className:
|
|
2835
|
+
className: s,
|
|
2803
2836
|
style: {
|
|
2804
2837
|
fontFamily: "var(--security-font)",
|
|
2805
2838
|
color: "var(--security-text)",
|
|
@@ -2813,8 +2846,8 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2813
2846
|
alignItems: "center"
|
|
2814
2847
|
},
|
|
2815
2848
|
children: [
|
|
2816
|
-
/* @__PURE__ */ c("div", { style: { fontSize: 15, fontWeight: 600 }, children:
|
|
2817
|
-
f ? /* @__PURE__ */ c("div", { style: { fontSize: 13, color: "var(--security-text-muted)" }, children:
|
|
2849
|
+
/* @__PURE__ */ c("div", { style: { fontSize: 15, fontWeight: 600 }, children: a ?? i("security.trust.title", "Device Trust") }),
|
|
2850
|
+
f ? /* @__PURE__ */ c("div", { style: { fontSize: 13, color: "var(--security-text-muted)" }, children: i("security.trust.computing", "Analysing device…") }) : y ? /* @__PURE__ */ P(Pe, { children: [
|
|
2818
2851
|
/* @__PURE__ */ P("div", { style: { position: "relative", width: 100, height: 100 }, children: [
|
|
2819
2852
|
/* @__PURE__ */ P(
|
|
2820
2853
|
"svg",
|
|
@@ -2840,9 +2873,9 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2840
2873
|
cy: "18",
|
|
2841
2874
|
r: "15.9",
|
|
2842
2875
|
fill: "none",
|
|
2843
|
-
stroke:
|
|
2876
|
+
stroke: I,
|
|
2844
2877
|
strokeWidth: "2.5",
|
|
2845
|
-
strokeDasharray: `${
|
|
2878
|
+
strokeDasharray: `${y.score}, 100`,
|
|
2846
2879
|
strokeLinecap: "round"
|
|
2847
2880
|
}
|
|
2848
2881
|
)
|
|
@@ -2861,7 +2894,7 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2861
2894
|
justifyContent: "center"
|
|
2862
2895
|
},
|
|
2863
2896
|
children: [
|
|
2864
|
-
/* @__PURE__ */ c("span", { style: { fontSize: 24, fontWeight: 700, color:
|
|
2897
|
+
/* @__PURE__ */ c("span", { style: { fontSize: 24, fontWeight: 700, color: I }, children: y.score }),
|
|
2865
2898
|
/* @__PURE__ */ c("span", { style: { fontSize: 10, color: "var(--security-text-muted)" }, children: "/100" })
|
|
2866
2899
|
]
|
|
2867
2900
|
}
|
|
@@ -2873,12 +2906,12 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2873
2906
|
style: {
|
|
2874
2907
|
fontSize: 14,
|
|
2875
2908
|
fontWeight: 600,
|
|
2876
|
-
color:
|
|
2909
|
+
color: y.trusted ? "var(--security-success)" : "var(--security-warning)"
|
|
2877
2910
|
},
|
|
2878
|
-
children:
|
|
2911
|
+
children: y.trusted ? i("security.trust.trusted", "Device Trusted") : i("security.trust.untrusted", "Low Trust Score")
|
|
2879
2912
|
}
|
|
2880
2913
|
),
|
|
2881
|
-
n &&
|
|
2914
|
+
n && y.factors.length > 0 && /* @__PURE__ */ P("div", { style: { width: "100%", fontSize: 12 }, children: [
|
|
2882
2915
|
/* @__PURE__ */ P(
|
|
2883
2916
|
"div",
|
|
2884
2917
|
{
|
|
@@ -2888,14 +2921,14 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2888
2921
|
color: "var(--security-text-secondary)"
|
|
2889
2922
|
},
|
|
2890
2923
|
children: [
|
|
2891
|
-
|
|
2924
|
+
i("security.trust.factors", "Contributing factors"),
|
|
2892
2925
|
":"
|
|
2893
2926
|
]
|
|
2894
2927
|
}
|
|
2895
2928
|
),
|
|
2896
|
-
/* @__PURE__ */ c("ul", { style: { margin: 0, paddingLeft: 18, color: "var(--security-text-muted)" }, children:
|
|
2929
|
+
/* @__PURE__ */ c("ul", { style: { margin: 0, paddingLeft: 18, color: "var(--security-text-muted)" }, children: y.factors.map((L, p) => /* @__PURE__ */ c("li", { style: { marginBottom: 2 }, children: L.name }, p)) })
|
|
2897
2930
|
] }),
|
|
2898
|
-
|
|
2931
|
+
o && y.fingerprint && /* @__PURE__ */ c(
|
|
2899
2932
|
"div",
|
|
2900
2933
|
{
|
|
2901
2934
|
style: {
|
|
@@ -2906,7 +2939,7 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2906
2939
|
maxWidth: 280,
|
|
2907
2940
|
fontFamily: "monospace"
|
|
2908
2941
|
},
|
|
2909
|
-
children:
|
|
2942
|
+
children: y.fingerprint
|
|
2910
2943
|
}
|
|
2911
2944
|
)
|
|
2912
2945
|
] }) : null
|
|
@@ -2914,68 +2947,73 @@ const ot = 4, at = 5, ct = 3e4, Pt = (e) => {
|
|
|
2914
2947
|
}
|
|
2915
2948
|
);
|
|
2916
2949
|
};
|
|
2917
|
-
function
|
|
2950
|
+
function kt(e) {
|
|
2918
2951
|
if (!e)
|
|
2919
2952
|
return 0;
|
|
2920
2953
|
let t = 0;
|
|
2921
2954
|
return e.length >= 8 && t++, e.length >= 12 && t++, /[a-z]/.test(e) && /[A-Z]/.test(e) && t++, /\d/.test(e) && t++, /[^a-zA-Z0-9]/.test(e) && t++, /(.)\1{3,}/.test(e) && t--, Math.max(0, Math.min(4, t));
|
|
2922
2955
|
}
|
|
2923
|
-
const
|
|
2956
|
+
const At = ["Very weak", "Weak", "Fair", "Strong", "Very strong"], ke = [
|
|
2924
2957
|
"var(--nice-danger, #ef4444)",
|
|
2925
2958
|
"var(--nice-warning, #f97316)",
|
|
2926
2959
|
"var(--nice-warning, #eab308)",
|
|
2927
2960
|
"var(--nice-success, #22c55e)",
|
|
2928
2961
|
"var(--nice-success, #10b981)"
|
|
2929
|
-
],
|
|
2962
|
+
], Kt = ({
|
|
2930
2963
|
mode: e = "verify",
|
|
2931
2964
|
expectedHash: t,
|
|
2932
2965
|
minStrength: r = 2,
|
|
2933
2966
|
minLength: n = 8,
|
|
2934
|
-
onComplete:
|
|
2935
|
-
onVerify:
|
|
2936
|
-
onStatusChange:
|
|
2937
|
-
onError:
|
|
2938
|
-
label:
|
|
2939
|
-
placeholder:
|
|
2967
|
+
onComplete: o,
|
|
2968
|
+
onVerify: s,
|
|
2969
|
+
onStatusChange: a,
|
|
2970
|
+
onError: i,
|
|
2971
|
+
label: y,
|
|
2972
|
+
placeholder: b,
|
|
2940
2973
|
className: f,
|
|
2941
|
-
showStrength:
|
|
2942
|
-
maxAttempts:
|
|
2974
|
+
showStrength: x = !0,
|
|
2975
|
+
maxAttempts: A = 5
|
|
2943
2976
|
}) => {
|
|
2944
|
-
const { t:
|
|
2977
|
+
const { t: g } = te(), [I, L] = j(""), [p, C] = j(""), [S, v] = j(!1), [l, w] = j("idle"), [u, h] = j(0), [R, G] = j(""), J = V(null), W = kt(I), O = K(
|
|
2945
2978
|
($) => {
|
|
2946
|
-
w($),
|
|
2979
|
+
w($), a == null || a($);
|
|
2947
2980
|
},
|
|
2948
|
-
[
|
|
2949
|
-
),
|
|
2950
|
-
if (
|
|
2951
|
-
if (
|
|
2952
|
-
|
|
2981
|
+
[a]
|
|
2982
|
+
), Y = K(async () => {
|
|
2983
|
+
if (G(""), O("processing"), e === "set") {
|
|
2984
|
+
if (I.length < n) {
|
|
2985
|
+
G(
|
|
2986
|
+
g("security.passphrase.tooShort", "Minimum {min} characters").replace(
|
|
2987
|
+
"{min}",
|
|
2988
|
+
String(n)
|
|
2989
|
+
)
|
|
2990
|
+
), O("idle");
|
|
2953
2991
|
return;
|
|
2954
2992
|
}
|
|
2955
|
-
if (
|
|
2956
|
-
|
|
2993
|
+
if (W < r) {
|
|
2994
|
+
G(g("security.passphrase.tooWeak", "Passphrase is too weak")), O("idle");
|
|
2957
2995
|
return;
|
|
2958
2996
|
}
|
|
2959
|
-
if (
|
|
2960
|
-
|
|
2997
|
+
if (I !== p) {
|
|
2998
|
+
G(g("security.passphrase.noMatch", "Passphrases do not match")), O("failure"), setTimeout(() => O("idle"), 1e3);
|
|
2961
2999
|
return;
|
|
2962
3000
|
}
|
|
2963
|
-
|
|
3001
|
+
o == null || o(I), O("success");
|
|
2964
3002
|
return;
|
|
2965
3003
|
}
|
|
2966
3004
|
if (t) {
|
|
2967
|
-
const $ = new TextEncoder(), B = await crypto.subtle.digest("SHA-256", $.encode(
|
|
2968
|
-
if (Array.from(new Uint8Array(B)).map((
|
|
2969
|
-
|
|
3005
|
+
const $ = new TextEncoder(), B = await crypto.subtle.digest("SHA-256", $.encode(I));
|
|
3006
|
+
if (Array.from(new Uint8Array(B)).map((H) => H.toString(16).padStart(2, "0")).join("") === t)
|
|
3007
|
+
O("success"), s == null || s({
|
|
2970
3008
|
success: !0,
|
|
2971
3009
|
confidence: 1,
|
|
2972
3010
|
method: "passphrase",
|
|
2973
3011
|
timestamp: Date.now(),
|
|
2974
3012
|
duration: 0
|
|
2975
|
-
}),
|
|
3013
|
+
}), o == null || o(I);
|
|
2976
3014
|
else {
|
|
2977
|
-
const
|
|
2978
|
-
h(
|
|
3015
|
+
const H = u + 1;
|
|
3016
|
+
h(H), H >= A ? (O("failure"), i == null || i(new Error("Too many failed attempts"))) : (G(g("security.passphrase.incorrect", "Incorrect passphrase")), O("idle")), s == null || s({
|
|
2979
3017
|
success: !1,
|
|
2980
3018
|
confidence: 0,
|
|
2981
3019
|
method: "passphrase",
|
|
@@ -2984,29 +3022,29 @@ const vt = ["Very weak", "Weak", "Fair", "Strong", "Very strong"], ke = [
|
|
|
2984
3022
|
});
|
|
2985
3023
|
}
|
|
2986
3024
|
} else
|
|
2987
|
-
|
|
3025
|
+
o == null || o(I), O("success");
|
|
2988
3026
|
}, [
|
|
2989
|
-
|
|
2990
|
-
|
|
3027
|
+
I,
|
|
3028
|
+
p,
|
|
2991
3029
|
e,
|
|
2992
3030
|
t,
|
|
2993
|
-
|
|
3031
|
+
W,
|
|
2994
3032
|
r,
|
|
2995
3033
|
n,
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3034
|
+
u,
|
|
3035
|
+
A,
|
|
3036
|
+
g,
|
|
3037
|
+
O,
|
|
3038
|
+
o,
|
|
3000
3039
|
s,
|
|
3001
|
-
i
|
|
3002
|
-
|
|
3003
|
-
]), W = {
|
|
3040
|
+
i
|
|
3041
|
+
]), _ = {
|
|
3004
3042
|
width: "100%",
|
|
3005
3043
|
padding: "10px 14px",
|
|
3006
3044
|
fontSize: 14,
|
|
3007
3045
|
background: "var(--security-bg)",
|
|
3008
3046
|
color: "var(--security-text)",
|
|
3009
|
-
border: `1px solid ${
|
|
3047
|
+
border: `1px solid ${l === "failure" ? "var(--security-error)" : "var(--security-border)"}`,
|
|
3010
3048
|
borderRadius: "var(--security-radius)",
|
|
3011
3049
|
boxSizing: "border-box",
|
|
3012
3050
|
fontFamily: "var(--security-font)"
|
|
@@ -3024,26 +3062,26 @@ const vt = ["Very weak", "Weak", "Fair", "Strong", "Very strong"], ke = [
|
|
|
3024
3062
|
color: "var(--security-text)"
|
|
3025
3063
|
},
|
|
3026
3064
|
children: [
|
|
3027
|
-
|
|
3065
|
+
y && /* @__PURE__ */ c("label", { style: { fontSize: 14, fontWeight: 600 }, children: y }),
|
|
3028
3066
|
/* @__PURE__ */ P("div", { style: { position: "relative" }, children: [
|
|
3029
3067
|
/* @__PURE__ */ c(
|
|
3030
3068
|
"input",
|
|
3031
3069
|
{
|
|
3032
|
-
ref:
|
|
3033
|
-
type:
|
|
3034
|
-
value:
|
|
3035
|
-
onChange: ($) =>
|
|
3036
|
-
placeholder:
|
|
3037
|
-
style:
|
|
3038
|
-
disabled:
|
|
3039
|
-
onKeyDown: ($) => $.key === "Enter" &&
|
|
3070
|
+
ref: J,
|
|
3071
|
+
type: S ? "text" : "password",
|
|
3072
|
+
value: I,
|
|
3073
|
+
onChange: ($) => L($.target.value),
|
|
3074
|
+
placeholder: b ?? g("security.passphrase.placeholder", "Enter passphrase"),
|
|
3075
|
+
style: _,
|
|
3076
|
+
disabled: l === "success",
|
|
3077
|
+
onKeyDown: ($) => $.key === "Enter" && Y()
|
|
3040
3078
|
}
|
|
3041
3079
|
),
|
|
3042
3080
|
/* @__PURE__ */ c(
|
|
3043
3081
|
"button",
|
|
3044
3082
|
{
|
|
3045
3083
|
type: "button",
|
|
3046
|
-
onClick: () =>
|
|
3084
|
+
onClick: () => v(!S),
|
|
3047
3085
|
style: {
|
|
3048
3086
|
position: "absolute",
|
|
3049
3087
|
right: 8,
|
|
@@ -3056,64 +3094,64 @@ const vt = ["Very weak", "Weak", "Fair", "Strong", "Very strong"], ke = [
|
|
|
3056
3094
|
color: "var(--security-text-muted)"
|
|
3057
3095
|
},
|
|
3058
3096
|
tabIndex: -1,
|
|
3059
|
-
children:
|
|
3097
|
+
children: S ? g("security.passphrase.hide", "Hide") : g("security.passphrase.show", "Show")
|
|
3060
3098
|
}
|
|
3061
3099
|
)
|
|
3062
3100
|
] }),
|
|
3063
|
-
e === "set" &&
|
|
3101
|
+
e === "set" && x && I.length > 0 && /* @__PURE__ */ P("div", { children: [
|
|
3064
3102
|
/* @__PURE__ */ c("div", { style: { display: "flex", gap: 3, height: 4 }, children: [0, 1, 2, 3].map(($) => /* @__PURE__ */ c(
|
|
3065
3103
|
"div",
|
|
3066
3104
|
{
|
|
3067
3105
|
style: {
|
|
3068
3106
|
flex: 1,
|
|
3069
3107
|
borderRadius: 2,
|
|
3070
|
-
background: $ <
|
|
3108
|
+
background: $ < W ? ke[W] : "var(--security-border)",
|
|
3071
3109
|
transition: "background 0.2s"
|
|
3072
3110
|
}
|
|
3073
3111
|
},
|
|
3074
3112
|
$
|
|
3075
3113
|
)) }),
|
|
3076
|
-
/* @__PURE__ */ c("div", { style: { fontSize: 11, marginTop: 4, color: ke[
|
|
3114
|
+
/* @__PURE__ */ c("div", { style: { fontSize: 11, marginTop: 4, color: ke[W] }, children: g(`security.passphrase.strength${W}`, At[W]) })
|
|
3077
3115
|
] }),
|
|
3078
3116
|
e === "set" && /* @__PURE__ */ c(
|
|
3079
3117
|
"input",
|
|
3080
3118
|
{
|
|
3081
|
-
type:
|
|
3082
|
-
value:
|
|
3083
|
-
onChange: ($) =>
|
|
3084
|
-
placeholder:
|
|
3085
|
-
style:
|
|
3086
|
-
disabled:
|
|
3087
|
-
onKeyDown: ($) => $.key === "Enter" &&
|
|
3119
|
+
type: S ? "text" : "password",
|
|
3120
|
+
value: p,
|
|
3121
|
+
onChange: ($) => C($.target.value),
|
|
3122
|
+
placeholder: g("security.passphrase.confirmPlaceholder", "Confirm passphrase"),
|
|
3123
|
+
style: _,
|
|
3124
|
+
disabled: l === "success",
|
|
3125
|
+
onKeyDown: ($) => $.key === "Enter" && Y(),
|
|
3088
3126
|
onPaste: ($) => $.preventDefault()
|
|
3089
3127
|
}
|
|
3090
3128
|
),
|
|
3091
|
-
|
|
3129
|
+
R && /* @__PURE__ */ c("div", { style: { fontSize: 12, color: "var(--security-error)" }, children: R }),
|
|
3092
3130
|
/* @__PURE__ */ c(
|
|
3093
3131
|
"button",
|
|
3094
3132
|
{
|
|
3095
|
-
onClick:
|
|
3096
|
-
disabled: !
|
|
3133
|
+
onClick: Y,
|
|
3134
|
+
disabled: !I || l === "processing" || l === "success",
|
|
3097
3135
|
style: {
|
|
3098
3136
|
padding: "10px 20px",
|
|
3099
3137
|
fontSize: 14,
|
|
3100
3138
|
fontWeight: 600,
|
|
3101
|
-
background:
|
|
3139
|
+
background: l === "success" ? "var(--security-success)" : "var(--security-biometric)",
|
|
3102
3140
|
color: "var(--nice-color-white, #fff)",
|
|
3103
3141
|
border: "none",
|
|
3104
3142
|
borderRadius: "var(--security-radius)",
|
|
3105
|
-
cursor:
|
|
3106
|
-
opacity: !
|
|
3143
|
+
cursor: l === "success" ? "default" : "pointer",
|
|
3144
|
+
opacity: !I || l === "processing" ? 0.6 : 1
|
|
3107
3145
|
},
|
|
3108
|
-
children:
|
|
3146
|
+
children: l === "success" ? g("security.passphrase.accepted", "Accepted") : e === "set" ? g("security.passphrase.setBtn", "Set Passphrase") : g("security.passphrase.verifyBtn", "Verify")
|
|
3109
3147
|
}
|
|
3110
3148
|
),
|
|
3111
|
-
|
|
3149
|
+
u > 0 && l !== "success" && /* @__PURE__ */ c("div", { style: { fontSize: 11, color: "var(--security-warning)" }, children: g("security.passphrase.attempts", "{attempts}/{max} attempts").replace("{attempts}", String(u)).replace("{max}", String(A)) })
|
|
3112
3150
|
]
|
|
3113
3151
|
}
|
|
3114
3152
|
);
|
|
3115
3153
|
};
|
|
3116
|
-
function
|
|
3154
|
+
function Gt(e) {
|
|
3117
3155
|
const t = [], r = {
|
|
3118
3156
|
defaultSrc: "default-src",
|
|
3119
3157
|
scriptSrc: "script-src",
|
|
@@ -3134,21 +3172,21 @@ function Bt(e) {
|
|
|
3134
3172
|
upgradeInsecureRequests: "upgrade-insecure-requests",
|
|
3135
3173
|
blockAllMixedContent: "block-all-mixed-content"
|
|
3136
3174
|
};
|
|
3137
|
-
return Object.entries(e.directives).forEach(([n,
|
|
3138
|
-
const
|
|
3139
|
-
if (
|
|
3140
|
-
if (typeof
|
|
3141
|
-
|
|
3142
|
-
else if (typeof
|
|
3143
|
-
t.push(`${
|
|
3144
|
-
else if (Array.isArray(
|
|
3145
|
-
let
|
|
3146
|
-
e.nonce && (n === "scriptSrc" || n === "styleSrc") && (
|
|
3175
|
+
return Object.entries(e.directives).forEach(([n, o]) => {
|
|
3176
|
+
const s = r[n];
|
|
3177
|
+
if (s) {
|
|
3178
|
+
if (typeof o == "boolean")
|
|
3179
|
+
o && t.push(s);
|
|
3180
|
+
else if (typeof o == "string")
|
|
3181
|
+
t.push(`${s} ${o}`);
|
|
3182
|
+
else if (Array.isArray(o)) {
|
|
3183
|
+
let a = o;
|
|
3184
|
+
e.nonce && (n === "scriptSrc" || n === "styleSrc") && (a = [...a, `'nonce-${e.nonce}'`]), t.push(`${s} ${a.join(" ")}`);
|
|
3147
3185
|
}
|
|
3148
3186
|
}
|
|
3149
3187
|
}), t.join("; ");
|
|
3150
3188
|
}
|
|
3151
|
-
function
|
|
3189
|
+
function Jt(e) {
|
|
3152
3190
|
const t = "'self'";
|
|
3153
3191
|
return {
|
|
3154
3192
|
defaultSrc: [t],
|
|
@@ -3167,10 +3205,10 @@ function _t(e) {
|
|
|
3167
3205
|
reportUri: e == null ? void 0 : e.reportUri
|
|
3168
3206
|
};
|
|
3169
3207
|
}
|
|
3170
|
-
function
|
|
3208
|
+
function Yt() {
|
|
3171
3209
|
return typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID().replace(/-/g, "") : Math.random().toString(36).substring(2) + Date.now().toString(36);
|
|
3172
3210
|
}
|
|
3173
|
-
const
|
|
3211
|
+
const Tt = {
|
|
3174
3212
|
"&": "&",
|
|
3175
3213
|
"<": "<",
|
|
3176
3214
|
">": ">",
|
|
@@ -3180,14 +3218,14 @@ const bt = {
|
|
|
3180
3218
|
"`": "`",
|
|
3181
3219
|
"=": "="
|
|
3182
3220
|
};
|
|
3183
|
-
function
|
|
3184
|
-
return e.replace(/[&<>"'`=/]/g, (t) =>
|
|
3221
|
+
function It(e) {
|
|
3222
|
+
return e.replace(/[&<>"'`=/]/g, (t) => Tt[t] || t);
|
|
3185
3223
|
}
|
|
3186
|
-
function
|
|
3187
|
-
let r =
|
|
3224
|
+
function Zt(e, t) {
|
|
3225
|
+
let r = It(e);
|
|
3188
3226
|
return t != null && t.maxLength && r.length > t.maxLength && (r = r.substring(0, t.maxLength)), r;
|
|
3189
3227
|
}
|
|
3190
|
-
function
|
|
3228
|
+
function Xt(e) {
|
|
3191
3229
|
if (!e)
|
|
3192
3230
|
return null;
|
|
3193
3231
|
try {
|
|
@@ -3197,25 +3235,25 @@ function Ht(e) {
|
|
|
3197
3235
|
return null;
|
|
3198
3236
|
}
|
|
3199
3237
|
}
|
|
3200
|
-
function
|
|
3238
|
+
function Qt(e) {
|
|
3201
3239
|
const t = ["script", "iframe", "object", "embed", "form"];
|
|
3202
3240
|
let r = e;
|
|
3203
|
-
t.forEach((
|
|
3204
|
-
const
|
|
3205
|
-
r = r.replace(o, "");
|
|
3206
|
-
const a = new RegExp(`<${i}[^>]*/>`, "gi");
|
|
3241
|
+
t.forEach((s) => {
|
|
3242
|
+
const a = new RegExp(`<${s}[^>]*>.*?</${s}>`, "gi");
|
|
3207
3243
|
r = r.replace(a, "");
|
|
3244
|
+
const i = new RegExp(`<${s}[^>]*/>`, "gi");
|
|
3245
|
+
r = r.replace(i, "");
|
|
3208
3246
|
});
|
|
3209
3247
|
const n = /\s+on\w+\s*=/gi;
|
|
3210
3248
|
r = r.replace(n, " data-removed=");
|
|
3211
|
-
const
|
|
3212
|
-
return r = r.replace(
|
|
3249
|
+
const o = /javascript:/gi;
|
|
3250
|
+
return r = r.replace(o, ""), r;
|
|
3213
3251
|
}
|
|
3214
|
-
function
|
|
3252
|
+
function Vt(e, t) {
|
|
3215
3253
|
let r = e;
|
|
3216
3254
|
if (t != null && t.allowedTags) {
|
|
3217
3255
|
const n = /<\/?([a-z][a-z0-9]*)[^>]*>/gi;
|
|
3218
|
-
r = r.replace(n, (
|
|
3256
|
+
r = r.replace(n, (o, s) => t.allowedTags.includes(s.toLowerCase()) ? o : "");
|
|
3219
3257
|
}
|
|
3220
3258
|
return r = r.replace(/\s+on\w+\s*=/gi, " data-removed="), r = r.replace(/javascript:/gi, ""), { __html: r };
|
|
3221
3259
|
}
|
|
@@ -3224,7 +3262,7 @@ const me = {
|
|
|
3224
3262
|
cookieName: "XSRF-TOKEN",
|
|
3225
3263
|
fieldName: "_csrf"
|
|
3226
3264
|
};
|
|
3227
|
-
function
|
|
3265
|
+
function er() {
|
|
3228
3266
|
if (typeof crypto < "u") {
|
|
3229
3267
|
const e = new Uint8Array(32);
|
|
3230
3268
|
return crypto.getRandomValues(e), Array.from(e, (t) => t.toString(16).padStart(2, "0")).join("");
|
|
@@ -3237,15 +3275,15 @@ function Me(e = me.cookieName) {
|
|
|
3237
3275
|
const t = document.cookie.match(new RegExp(`(^| )${e}=([^;]+)`));
|
|
3238
3276
|
return t ? decodeURIComponent(t[2]) : null;
|
|
3239
3277
|
}
|
|
3240
|
-
function
|
|
3278
|
+
function tr(e = me) {
|
|
3241
3279
|
return async function(r, n = {}) {
|
|
3242
|
-
const
|
|
3243
|
-
|
|
3244
|
-
const
|
|
3245
|
-
return
|
|
3280
|
+
const o = Me(e.cookieName);
|
|
3281
|
+
o || console.warn("CSRF token not found");
|
|
3282
|
+
const s = new Headers(n.headers);
|
|
3283
|
+
return o && e.headerName && s.set(e.headerName, o), fetch(r, { ...n, headers: s });
|
|
3246
3284
|
};
|
|
3247
3285
|
}
|
|
3248
|
-
function
|
|
3286
|
+
function rr(e = me) {
|
|
3249
3287
|
const t = Me(e.cookieName);
|
|
3250
3288
|
return {
|
|
3251
3289
|
token: t,
|
|
@@ -3257,46 +3295,46 @@ function Jt(e = me) {
|
|
|
3257
3295
|
headerName: e.headerName
|
|
3258
3296
|
};
|
|
3259
3297
|
}
|
|
3260
|
-
function
|
|
3261
|
-
const t = /* @__PURE__ */ new Map(), r = e.keyGenerator || ((
|
|
3262
|
-
function n(
|
|
3263
|
-
const
|
|
3264
|
-
let
|
|
3265
|
-
(!
|
|
3298
|
+
function Ct(e) {
|
|
3299
|
+
const t = /* @__PURE__ */ new Map(), r = e.keyGenerator || ((s) => s.url);
|
|
3300
|
+
function n(s) {
|
|
3301
|
+
const a = r(s), i = Date.now();
|
|
3302
|
+
let y = t.get(a);
|
|
3303
|
+
(!y || i > y.resetAt) && (y = {
|
|
3266
3304
|
count: 0,
|
|
3267
|
-
resetAt:
|
|
3268
|
-
}),
|
|
3269
|
-
const
|
|
3270
|
-
return { allowed:
|
|
3305
|
+
resetAt: i + e.windowMs
|
|
3306
|
+
}), y.count++, t.set(a, y);
|
|
3307
|
+
const b = y.count <= e.maxRequests, f = Math.max(0, e.maxRequests - y.count);
|
|
3308
|
+
return { allowed: b, remaining: f, resetAt: y.resetAt };
|
|
3271
3309
|
}
|
|
3272
|
-
function s
|
|
3273
|
-
|
|
3310
|
+
function o(s) {
|
|
3311
|
+
s ? t.delete(s) : t.clear();
|
|
3274
3312
|
}
|
|
3275
|
-
return { checkLimit: n, reset:
|
|
3276
|
-
}
|
|
3277
|
-
function
|
|
3278
|
-
const t =
|
|
3279
|
-
return { checkAndFetch: async (n,
|
|
3280
|
-
const
|
|
3281
|
-
if (!
|
|
3282
|
-
const
|
|
3283
|
-
throw new Error(`Rate limit exceeded. Retry after ${
|
|
3313
|
+
return { checkLimit: n, reset: o };
|
|
3314
|
+
}
|
|
3315
|
+
function nr(e) {
|
|
3316
|
+
const t = Ct(e);
|
|
3317
|
+
return { checkAndFetch: async (n, o) => {
|
|
3318
|
+
const s = t.checkLimit({ url: n, method: o == null ? void 0 : o.method });
|
|
3319
|
+
if (!s.allowed) {
|
|
3320
|
+
const a = Math.ceil((s.resetAt - Date.now()) / 1e3);
|
|
3321
|
+
throw new Error(`Rate limit exceeded. Retry after ${a} seconds.`);
|
|
3284
3322
|
}
|
|
3285
|
-
return fetch(n,
|
|
3323
|
+
return fetch(n, o);
|
|
3286
3324
|
}, checkLimit: t.checkLimit, reset: t.reset };
|
|
3287
3325
|
}
|
|
3288
|
-
function
|
|
3326
|
+
function Dt(e, t) {
|
|
3289
3327
|
const r = [];
|
|
3290
3328
|
if (t.allowedTypes && t.allowedTypes.length > 0 && (t.allowedTypes.includes(e.type) || r.push(
|
|
3291
3329
|
`File type '${e.type}' is not allowed. Allowed types: ${t.allowedTypes.join(", ")}`
|
|
3292
3330
|
)), t.maxSize && e.size > t.maxSize) {
|
|
3293
|
-
const
|
|
3294
|
-
r.push(`File size (${
|
|
3331
|
+
const s = (t.maxSize / 1048576).toFixed(2), a = (e.size / (1024 * 1024)).toFixed(2);
|
|
3332
|
+
r.push(`File size (${a}MB) exceeds maximum allowed size (${s}MB)`);
|
|
3295
3333
|
}
|
|
3296
|
-
const n = [".exe", ".bat", ".cmd", ".sh", ".ps1", ".vbs", ".js", ".jar"],
|
|
3297
|
-
for (const
|
|
3298
|
-
if (
|
|
3299
|
-
r.push(`File extension '${
|
|
3334
|
+
const n = [".exe", ".bat", ".cmd", ".sh", ".ps1", ".vbs", ".js", ".jar"], o = e.name.toLowerCase();
|
|
3335
|
+
for (const s of n)
|
|
3336
|
+
if (o.includes(s + ".") || o.endsWith(s)) {
|
|
3337
|
+
r.push(`File extension '${s}' is not allowed`);
|
|
3300
3338
|
break;
|
|
3301
3339
|
}
|
|
3302
3340
|
return {
|
|
@@ -3305,25 +3343,25 @@ function St(e, t) {
|
|
|
3305
3343
|
file: r.length === 0 ? e : void 0
|
|
3306
3344
|
};
|
|
3307
3345
|
}
|
|
3308
|
-
function
|
|
3309
|
-
const r = [], n = [],
|
|
3346
|
+
function ir(e, t) {
|
|
3347
|
+
const r = [], n = [], o = [];
|
|
3310
3348
|
t.maxFiles && e.length > t.maxFiles && r.push(`Too many files. Maximum allowed: ${t.maxFiles}`);
|
|
3311
|
-
const
|
|
3312
|
-
if (t.maxTotalSize &&
|
|
3313
|
-
const
|
|
3314
|
-
r.push(`Total file size (${
|
|
3349
|
+
const s = e.reduce((a, i) => a + i.size, 0);
|
|
3350
|
+
if (t.maxTotalSize && s > t.maxTotalSize) {
|
|
3351
|
+
const a = (t.maxTotalSize / 1048576).toFixed(2), i = (s / (1024 * 1024)).toFixed(2);
|
|
3352
|
+
r.push(`Total file size (${i}MB) exceeds maximum (${a}MB)`);
|
|
3315
3353
|
}
|
|
3316
|
-
return e.forEach((
|
|
3317
|
-
const
|
|
3318
|
-
|
|
3354
|
+
return e.forEach((a) => {
|
|
3355
|
+
const i = Dt(a, t);
|
|
3356
|
+
i.valid ? n.push(a) : o.push({ file: a, errors: i.errors });
|
|
3319
3357
|
}), {
|
|
3320
|
-
valid: r.length === 0 &&
|
|
3321
|
-
errors: [...r, ...
|
|
3358
|
+
valid: r.length === 0 && o.length === 0,
|
|
3359
|
+
errors: [...r, ...o.flatMap((a) => a.errors)],
|
|
3322
3360
|
validFiles: n,
|
|
3323
|
-
invalidFiles:
|
|
3361
|
+
invalidFiles: o
|
|
3324
3362
|
};
|
|
3325
3363
|
}
|
|
3326
|
-
async function
|
|
3364
|
+
async function sr(e, t) {
|
|
3327
3365
|
const r = new FormData();
|
|
3328
3366
|
r.append("file", e);
|
|
3329
3367
|
try {
|
|
@@ -3338,7 +3376,7 @@ async function Xt(e, t) {
|
|
|
3338
3376
|
return console.error("Virus scan error:", n), { clean: !1, threat: "Scan failed" };
|
|
3339
3377
|
}
|
|
3340
3378
|
}
|
|
3341
|
-
function
|
|
3379
|
+
function Rt() {
|
|
3342
3380
|
if (typeof localStorage > "u")
|
|
3343
3381
|
return null;
|
|
3344
3382
|
const e = localStorage.getItem("nice2dev_consent");
|
|
@@ -3350,7 +3388,7 @@ function kt() {
|
|
|
3350
3388
|
return null;
|
|
3351
3389
|
}
|
|
3352
3390
|
}
|
|
3353
|
-
function
|
|
3391
|
+
function or(e) {
|
|
3354
3392
|
typeof localStorage > "u" || localStorage.setItem(
|
|
3355
3393
|
"nice2dev_consent",
|
|
3356
3394
|
JSON.stringify({
|
|
@@ -3361,11 +3399,11 @@ function Qt(e) {
|
|
|
3361
3399
|
})
|
|
3362
3400
|
);
|
|
3363
3401
|
}
|
|
3364
|
-
function
|
|
3365
|
-
const t =
|
|
3402
|
+
function ar(e) {
|
|
3403
|
+
const t = Rt();
|
|
3366
3404
|
return t ? t[e] === !0 : !1;
|
|
3367
3405
|
}
|
|
3368
|
-
function
|
|
3406
|
+
function cr(e) {
|
|
3369
3407
|
if (typeof document > "u")
|
|
3370
3408
|
return;
|
|
3371
3409
|
document.cookie.split(";").forEach((r) => {
|
|
@@ -3373,23 +3411,23 @@ function er(e) {
|
|
|
3373
3411
|
e.includes(n) || (document.cookie = `${n}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`);
|
|
3374
3412
|
});
|
|
3375
3413
|
}
|
|
3376
|
-
async function
|
|
3414
|
+
async function lr(e, t, r = fetch) {
|
|
3377
3415
|
const n = {
|
|
3378
3416
|
exportDate: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3379
3417
|
userId: e
|
|
3380
3418
|
};
|
|
3381
3419
|
return await Promise.all(
|
|
3382
|
-
Object.entries(t).map(async ([
|
|
3420
|
+
Object.entries(t).map(async ([o, s]) => {
|
|
3383
3421
|
try {
|
|
3384
|
-
const
|
|
3385
|
-
|
|
3386
|
-
} catch (
|
|
3387
|
-
console.error(`Failed to fetch ${
|
|
3422
|
+
const a = await r(s);
|
|
3423
|
+
a.ok && (n[o] = await a.json());
|
|
3424
|
+
} catch (a) {
|
|
3425
|
+
console.error(`Failed to fetch ${o} data:`, a), n[o] = { error: "Failed to retrieve data" };
|
|
3388
3426
|
}
|
|
3389
3427
|
})
|
|
3390
3428
|
), n;
|
|
3391
3429
|
}
|
|
3392
|
-
async function
|
|
3430
|
+
async function ur(e, t, r = fetch) {
|
|
3393
3431
|
try {
|
|
3394
3432
|
const n = await r(t, {
|
|
3395
3433
|
method: "DELETE",
|
|
@@ -3401,7 +3439,7 @@ async function rr(e, t, r = fetch) {
|
|
|
3401
3439
|
return { success: !1, error: String(n) };
|
|
3402
3440
|
}
|
|
3403
3441
|
}
|
|
3404
|
-
function
|
|
3442
|
+
function dr(e, t) {
|
|
3405
3443
|
var n;
|
|
3406
3444
|
const r = {
|
|
3407
3445
|
...e,
|
|
@@ -3414,119 +3452,119 @@ function nr(e, t) {
|
|
|
3414
3452
|
body: JSON.stringify(r)
|
|
3415
3453
|
}).catch(console.error), process.env.NODE_ENV === "development" && console.warn("[HIPAA] PHI Access:", r), r;
|
|
3416
3454
|
}
|
|
3417
|
-
function
|
|
3455
|
+
function hr(e) {
|
|
3418
3456
|
let t = null, r = null, n = Date.now();
|
|
3419
|
-
const
|
|
3420
|
-
function
|
|
3457
|
+
const o = e.timeoutMinutes * 60 * 1e3, s = e.warningBeforeMs || 6e4;
|
|
3458
|
+
function a() {
|
|
3421
3459
|
n = Date.now(), t && clearTimeout(t), r && clearTimeout(r), e.onWarning && (r = setTimeout(() => {
|
|
3422
3460
|
var f;
|
|
3423
|
-
const
|
|
3424
|
-
(f = e.onWarning) == null || f.call(e,
|
|
3425
|
-
},
|
|
3461
|
+
const b = o - (Date.now() - n);
|
|
3462
|
+
(f = e.onWarning) == null || f.call(e, b);
|
|
3463
|
+
}, o - s)), t = setTimeout(e.onTimeout, o);
|
|
3426
3464
|
}
|
|
3427
|
-
function
|
|
3465
|
+
function i() {
|
|
3428
3466
|
t && clearTimeout(t), r && clearTimeout(r);
|
|
3429
3467
|
}
|
|
3430
|
-
function
|
|
3431
|
-
return Math.max(0,
|
|
3468
|
+
function y() {
|
|
3469
|
+
return Math.max(0, o - (Date.now() - n));
|
|
3432
3470
|
}
|
|
3433
|
-
return
|
|
3434
|
-
window.addEventListener(f,
|
|
3435
|
-
}), { resetTimer:
|
|
3436
|
-
}
|
|
3437
|
-
function
|
|
3438
|
-
const r = (
|
|
3439
|
-
const
|
|
3440
|
-
return 0.2126 *
|
|
3441
|
-
}, n = r(e),
|
|
3471
|
+
return a(), typeof window < "u" && ["mousedown", "keypress", "touchstart", "scroll"].forEach((f) => {
|
|
3472
|
+
window.addEventListener(f, a, { passive: !0 });
|
|
3473
|
+
}), { resetTimer: a, destroy: i, getTimeRemaining: y };
|
|
3474
|
+
}
|
|
3475
|
+
function fr(e, t) {
|
|
3476
|
+
const r = (a) => {
|
|
3477
|
+
const i = a.replace("#", ""), y = parseInt(i.substr(0, 2), 16) / 255, b = parseInt(i.substr(2, 2), 16) / 255, f = parseInt(i.substr(4, 2), 16) / 255, x = (A) => A <= 0.03928 ? A / 12.92 : Math.pow((A + 0.055) / 1.055, 2.4);
|
|
3478
|
+
return 0.2126 * x(y) + 0.7152 * x(b) + 0.0722 * x(f);
|
|
3479
|
+
}, n = r(e), o = r(t), s = (Math.max(n, o) + 0.05) / (Math.min(n, o) + 0.05);
|
|
3442
3480
|
return {
|
|
3443
|
-
ratio: Math.round(
|
|
3444
|
-
passesAA:
|
|
3481
|
+
ratio: Math.round(s * 100) / 100,
|
|
3482
|
+
passesAA: s >= 4.5,
|
|
3445
3483
|
// Normal text
|
|
3446
|
-
passesAAA:
|
|
3484
|
+
passesAAA: s >= 7,
|
|
3447
3485
|
// Normal text enhanced
|
|
3448
|
-
passesAALarge:
|
|
3486
|
+
passesAALarge: s >= 3,
|
|
3449
3487
|
// Large text (18pt+ or 14pt bold)
|
|
3450
|
-
passesAAALarge:
|
|
3488
|
+
passesAAALarge: s >= 4.5
|
|
3451
3489
|
// Large text enhanced
|
|
3452
3490
|
};
|
|
3453
3491
|
}
|
|
3454
|
-
function
|
|
3455
|
-
var r, n,
|
|
3492
|
+
function yr(e) {
|
|
3493
|
+
var r, n, o;
|
|
3456
3494
|
if (e.getAttribute("aria-label"))
|
|
3457
3495
|
return !0;
|
|
3458
3496
|
const t = e.getAttribute("aria-labelledby");
|
|
3459
3497
|
if (t) {
|
|
3460
|
-
const
|
|
3461
|
-
if ((r =
|
|
3498
|
+
const s = document.getElementById(t);
|
|
3499
|
+
if ((r = s == null ? void 0 : s.textContent) != null && r.trim())
|
|
3462
3500
|
return !0;
|
|
3463
3501
|
}
|
|
3464
3502
|
if (e.id) {
|
|
3465
|
-
const
|
|
3466
|
-
if ((n =
|
|
3503
|
+
const s = document.querySelector(`label[for="${e.id}"]`);
|
|
3504
|
+
if ((n = s == null ? void 0 : s.textContent) != null && n.trim())
|
|
3467
3505
|
return !0;
|
|
3468
3506
|
}
|
|
3469
|
-
return !!((
|
|
3507
|
+
return !!((o = e.textContent) != null && o.trim() || e.getAttribute("title") || e.placeholder);
|
|
3470
3508
|
}
|
|
3471
|
-
function
|
|
3509
|
+
function pr(e) {
|
|
3472
3510
|
const r = (e || document.body).querySelectorAll("h1, h2, h3, h4, h5, h6"), n = [];
|
|
3473
|
-
let
|
|
3474
|
-
return r.forEach((
|
|
3475
|
-
const
|
|
3476
|
-
|
|
3477
|
-
level:
|
|
3478
|
-
element:
|
|
3511
|
+
let o = 0, s = !1;
|
|
3512
|
+
return r.forEach((a) => {
|
|
3513
|
+
const i = parseInt(a.tagName[1]);
|
|
3514
|
+
i === 1 && (s && n.push({
|
|
3515
|
+
level: i,
|
|
3516
|
+
element: a,
|
|
3479
3517
|
issue: "Multiple H1 elements found"
|
|
3480
|
-
}),
|
|
3481
|
-
level:
|
|
3482
|
-
element:
|
|
3483
|
-
issue: `Skipped heading level: H${
|
|
3484
|
-
}),
|
|
3485
|
-
}), !
|
|
3518
|
+
}), s = !0), i > o + 1 && o !== 0 && n.push({
|
|
3519
|
+
level: i,
|
|
3520
|
+
element: a,
|
|
3521
|
+
issue: `Skipped heading level: H${o} to H${i}`
|
|
3522
|
+
}), o = i;
|
|
3523
|
+
}), !s && r.length > 0 && n.push({
|
|
3486
3524
|
level: 0,
|
|
3487
3525
|
element: r[0],
|
|
3488
3526
|
issue: "Missing H1 element"
|
|
3489
3527
|
}), { valid: n.length === 0, issues: n };
|
|
3490
3528
|
}
|
|
3491
|
-
function
|
|
3529
|
+
function gr(e) {
|
|
3492
3530
|
const t = [];
|
|
3493
3531
|
let r = null;
|
|
3494
|
-
const n = e.batchSize || 10,
|
|
3495
|
-
async function
|
|
3532
|
+
const n = e.batchSize || 10, o = e.flushInterval || 5e3;
|
|
3533
|
+
async function s() {
|
|
3496
3534
|
if (t.length === 0)
|
|
3497
3535
|
return;
|
|
3498
|
-
const
|
|
3536
|
+
const b = t.splice(0, n);
|
|
3499
3537
|
try {
|
|
3500
3538
|
await fetch(e.endpoint, {
|
|
3501
3539
|
method: "POST",
|
|
3502
3540
|
headers: { "Content-Type": "application/json" },
|
|
3503
|
-
body: JSON.stringify({ entries:
|
|
3541
|
+
body: JSON.stringify({ entries: b })
|
|
3504
3542
|
});
|
|
3505
3543
|
} catch (f) {
|
|
3506
|
-
console.error("Failed to send audit logs:", f), t.unshift(...
|
|
3544
|
+
console.error("Failed to send audit logs:", f), t.unshift(...b);
|
|
3507
3545
|
}
|
|
3508
3546
|
}
|
|
3509
|
-
function
|
|
3547
|
+
function a() {
|
|
3510
3548
|
r || (r = setTimeout(() => {
|
|
3511
|
-
r = null,
|
|
3512
|
-
},
|
|
3549
|
+
r = null, s();
|
|
3550
|
+
}, o));
|
|
3513
3551
|
}
|
|
3514
|
-
function
|
|
3515
|
-
var
|
|
3552
|
+
function i(b) {
|
|
3553
|
+
var x;
|
|
3516
3554
|
const f = {
|
|
3517
|
-
...
|
|
3518
|
-
id: ((
|
|
3555
|
+
...b,
|
|
3556
|
+
id: ((x = crypto.randomUUID) == null ? void 0 : x.call(crypto)) || Math.random().toString(36),
|
|
3519
3557
|
timestamp: /* @__PURE__ */ new Date(),
|
|
3520
3558
|
userAgent: e.includeUserAgent && typeof navigator < "u" ? navigator.userAgent : void 0
|
|
3521
3559
|
};
|
|
3522
|
-
t.push(f), t.length >= n ?
|
|
3560
|
+
t.push(f), t.length >= n ? s() : a();
|
|
3523
3561
|
}
|
|
3524
|
-
function
|
|
3525
|
-
r && clearTimeout(r),
|
|
3562
|
+
function y() {
|
|
3563
|
+
r && clearTimeout(r), s();
|
|
3526
3564
|
}
|
|
3527
|
-
return { log:
|
|
3565
|
+
return { log: i, flush: s, destroy: y };
|
|
3528
3566
|
}
|
|
3529
|
-
function
|
|
3567
|
+
function mr() {
|
|
3530
3568
|
return [
|
|
3531
3569
|
// Security
|
|
3532
3570
|
{
|
|
@@ -3604,7 +3642,7 @@ function lr() {
|
|
|
3604
3642
|
}
|
|
3605
3643
|
];
|
|
3606
3644
|
}
|
|
3607
|
-
const
|
|
3645
|
+
const vr = {
|
|
3608
3646
|
// Hardcoded secrets
|
|
3609
3647
|
hardcodedSecrets: [
|
|
3610
3648
|
{ pattern: /password\s*[:=]\s*["'][^"']+["']/gi, name: "Hardcoded password" },
|
|
@@ -3641,7 +3679,7 @@ const ur = {
|
|
|
3641
3679
|
{ pattern: /TODO.*password/gi, name: "TODO mentioning password" }
|
|
3642
3680
|
]
|
|
3643
3681
|
};
|
|
3644
|
-
function
|
|
3682
|
+
function br() {
|
|
3645
3683
|
return `# .github/workflows/sast.yml
|
|
3646
3684
|
name: Security Scan (SAST)
|
|
3647
3685
|
|
|
@@ -3692,7 +3730,7 @@ jobs:
|
|
|
3692
3730
|
uses: github/codeql-action/analyze@v3
|
|
3693
3731
|
`;
|
|
3694
3732
|
}
|
|
3695
|
-
function
|
|
3733
|
+
function xr() {
|
|
3696
3734
|
return `# .github/workflows/sca.yml
|
|
3697
3735
|
name: Dependency Security (SCA)
|
|
3698
3736
|
|
|
@@ -3758,7 +3796,7 @@ jobs:
|
|
|
3758
3796
|
args: --severity-threshold=high
|
|
3759
3797
|
`;
|
|
3760
3798
|
}
|
|
3761
|
-
const
|
|
3799
|
+
const wr = [
|
|
3762
3800
|
// API Keys
|
|
3763
3801
|
{ name: "AWS Access Key ID", pattern: /AKIA[0-9A-Z]{16}/g, severity: "critical" },
|
|
3764
3802
|
{ name: "AWS Secret Access Key", pattern: /[A-Za-z0-9/+=]{40}/g, severity: "critical" },
|
|
@@ -3789,7 +3827,7 @@ const fr = [
|
|
|
3789
3827
|
{ name: "Bearer Token", pattern: /bearer [a-zA-Z0-9_\-.=]+/gi, severity: "high" },
|
|
3790
3828
|
{ name: "Connection String", pattern: /[a-z]+:\/\/[^:]+:[^@]+@[^/]+/gi, severity: "critical" }
|
|
3791
3829
|
];
|
|
3792
|
-
function
|
|
3830
|
+
function Sr() {
|
|
3793
3831
|
return `#!/bin/sh
|
|
3794
3832
|
# .git/hooks/pre-commit
|
|
3795
3833
|
|
|
@@ -3820,7 +3858,7 @@ echo "No secrets detected."
|
|
|
3820
3858
|
exit 0
|
|
3821
3859
|
`;
|
|
3822
3860
|
}
|
|
3823
|
-
function
|
|
3861
|
+
function kr() {
|
|
3824
3862
|
return `# .github/workflows/secret-scanning.yml
|
|
3825
3863
|
name: Secret Scanning
|
|
3826
3864
|
|
|
@@ -3858,7 +3896,7 @@ jobs:
|
|
|
3858
3896
|
head: HEAD
|
|
3859
3897
|
`;
|
|
3860
3898
|
}
|
|
3861
|
-
function
|
|
3899
|
+
function Ar(e) {
|
|
3862
3900
|
return `# Security Advisory
|
|
3863
3901
|
|
|
3864
3902
|
## ${e.cves.join(", ")} - ${e.description}
|
|
@@ -3906,7 +3944,7 @@ ${e.cves.map((t) => `- [${t}](https://www.cve.org/CVERecord?id=${t})`).join(`
|
|
|
3906
3944
|
`)}
|
|
3907
3945
|
`;
|
|
3908
3946
|
}
|
|
3909
|
-
function
|
|
3947
|
+
function Tr() {
|
|
3910
3948
|
return `# Security Policy
|
|
3911
3949
|
|
|
3912
3950
|
## Supported Versions
|
|
@@ -3977,80 +4015,80 @@ We will not pursue legal action against researchers who:
|
|
|
3977
4015
|
`;
|
|
3978
4016
|
}
|
|
3979
4017
|
export {
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
4018
|
+
qt as NiceDeviceTrust,
|
|
4019
|
+
jt as NiceFaceRecognition,
|
|
4020
|
+
Lt as NiceFingerprintScanner,
|
|
4021
|
+
Nt as NiceI18nProvider,
|
|
4022
|
+
$t as NiceIrisScanner,
|
|
4023
|
+
Ot as NiceMfaSelector,
|
|
4024
|
+
Kt as NicePassphraseInput,
|
|
4025
|
+
Bt as NicePatternLock,
|
|
4026
|
+
_t as NicePinKeypad,
|
|
4027
|
+
Ht as NiceSecurityAuditLog,
|
|
4028
|
+
Ut as NiceSessionManager,
|
|
4029
|
+
Wt as NiceWebAuthnButton,
|
|
4030
|
+
wr as SECRET_PATTERNS,
|
|
4031
|
+
vr as SECURITY_PATTERNS,
|
|
4032
|
+
nt as authenticateWebAuthn,
|
|
3995
4033
|
le as captureFrame,
|
|
3996
|
-
|
|
3997
|
-
|
|
4034
|
+
fr as checkColorContrast,
|
|
4035
|
+
pr as checkHeadingHierarchy,
|
|
3998
4036
|
Ie as checkLiveness,
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4037
|
+
cr as clearNonEssentialCookies,
|
|
4038
|
+
Ce as collectDeviceInfo,
|
|
4039
|
+
Qe as compareFaceToPhoto,
|
|
4040
|
+
gr as createAuditLogger,
|
|
4041
|
+
tr as createCSRFFetch,
|
|
4042
|
+
hr as createHIPAASession,
|
|
4043
|
+
Ct as createRateLimiter,
|
|
4044
|
+
Vt as createSafeHtml,
|
|
4045
|
+
Je as detectIris,
|
|
4046
|
+
It as escapeHtml,
|
|
4009
4047
|
he as extractFaceFeatures,
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4048
|
+
Ue as extractMinutiae,
|
|
4049
|
+
Ve as faceToTemplate,
|
|
4050
|
+
Ke as fingerprintToTemplate,
|
|
4051
|
+
Gt as generateCSPHeader,
|
|
4052
|
+
er as generateCSRFToken,
|
|
4053
|
+
lr as generateDataExport,
|
|
4016
4054
|
de as generateDeviceFingerprint,
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
-
|
|
4055
|
+
zt as generateLivenessChallenge,
|
|
4056
|
+
Yt as generateNonce,
|
|
4057
|
+
Sr as generatePreCommitHook,
|
|
4058
|
+
br as generateSASTConfig,
|
|
4059
|
+
xr as generateSCAConfig,
|
|
4060
|
+
kr as generateSecretScanningConfig,
|
|
4061
|
+
Ar as generateSecurityAdvisory,
|
|
4062
|
+
Tr as generateSecurityMd,
|
|
4025
4063
|
Me as getCSRFTokenFromCookie,
|
|
4026
4064
|
pe as getCameraStream,
|
|
4027
|
-
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4065
|
+
Rt as getConsentPreferences,
|
|
4066
|
+
Jt as getRecommendedCSP,
|
|
4067
|
+
mr as getSOC2Checklist,
|
|
4068
|
+
yr as hasAccessibleName,
|
|
4069
|
+
ar as hasConsent,
|
|
4070
|
+
Ze as irisToTemplate,
|
|
4071
|
+
tt as isPasskeyAvailable,
|
|
4072
|
+
De as isWebAuthnAvailable,
|
|
4073
|
+
dr as logPHIAccess,
|
|
4036
4074
|
Te as matchFaces,
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4075
|
+
qe as matchFingerprints,
|
|
4076
|
+
Ye as matchIris,
|
|
4077
|
+
rt as registerWebAuthn,
|
|
4078
|
+
ur as requestDataDeletion,
|
|
4041
4079
|
fe as resolveConfig,
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4080
|
+
Zt as sanitizeInput,
|
|
4081
|
+
Qt as sanitizeSvg,
|
|
4082
|
+
Xt as sanitizeUrl,
|
|
4083
|
+
or as saveConsentPreferences,
|
|
4084
|
+
sr as scanFileForViruses,
|
|
4085
|
+
et as templateToFace,
|
|
4086
|
+
Ge as templateToFingerprint,
|
|
4087
|
+
Xe as templateToIris,
|
|
4088
|
+
rr as useCSRFToken,
|
|
4051
4089
|
te as useNiceTranslation,
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4090
|
+
nr as useRateLimiter,
|
|
4091
|
+
Dt as validateFile,
|
|
4092
|
+
ir as validateFiles,
|
|
4055
4093
|
ge as verifyWithBackend
|
|
4056
4094
|
};
|