@tn3w/openage 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/openage.esm.js +135 -11
- package/dist/openage.esm.js.map +1 -1
- package/dist/openage.min.js +1 -1
- package/dist/openage.min.js.map +1 -1
- package/dist/openage.umd.js +135 -11
- package/dist/openage.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/challenge.js +61 -6
- package/src/constants.d.ts +1 -0
- package/src/constants.js +4 -3
- package/src/ui.d.ts +4 -0
- package/src/ui.js +57 -0
- package/src/widget.d.ts +1 -0
- package/src/widget.js +15 -2
package/dist/openage.umd.js
CHANGED
|
@@ -899,6 +899,52 @@
|
|
|
899
899
|
.oa-result-fail { color: var(--oa-danger); }
|
|
900
900
|
.oa-result-retry { color: var(--oa-warn); }
|
|
901
901
|
|
|
902
|
+
.oa-error-step {
|
|
903
|
+
display: flex;
|
|
904
|
+
flex-direction: column;
|
|
905
|
+
align-items: center;
|
|
906
|
+
gap: 0.7rem;
|
|
907
|
+
padding: 2rem 1.2rem;
|
|
908
|
+
background: var(--oa-surface);
|
|
909
|
+
border: 1px solid var(--oa-border);
|
|
910
|
+
border-radius: var(--oa-radius);
|
|
911
|
+
margin: 10px;
|
|
912
|
+
animation: oa-fade-in 0.4s ease;
|
|
913
|
+
text-align: center;
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
.oa-error-step-icon {
|
|
917
|
+
width: 3rem;
|
|
918
|
+
height: 3rem;
|
|
919
|
+
display: flex;
|
|
920
|
+
align-items: center;
|
|
921
|
+
justify-content: center;
|
|
922
|
+
border-radius: 999px;
|
|
923
|
+
background: rgba(239, 68, 68, 0.12);
|
|
924
|
+
color: var(--oa-danger);
|
|
925
|
+
font-size: 1.7rem;
|
|
926
|
+
line-height: 1;
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
.oa-error-step-title {
|
|
930
|
+
font-size: 1rem;
|
|
931
|
+
font-weight: 700;
|
|
932
|
+
color: var(--oa-text);
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
.oa-error-step-message {
|
|
936
|
+
font-size: 0.84rem;
|
|
937
|
+
line-height: 1.5;
|
|
938
|
+
color: var(--oa-text-muted);
|
|
939
|
+
max-width: 260px;
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
.oa-error-step-countdown {
|
|
943
|
+
font-size: 0.75rem;
|
|
944
|
+
font-weight: 600;
|
|
945
|
+
color: var(--oa-danger);
|
|
946
|
+
}
|
|
947
|
+
|
|
902
948
|
.oa-hidden { display: none !important; }
|
|
903
949
|
|
|
904
950
|
/* ── Animations ──────────────────────────────── */
|
|
@@ -1025,6 +1071,17 @@
|
|
|
1025
1071
|
`;
|
|
1026
1072
|
}
|
|
1027
1073
|
|
|
1074
|
+
function errorStepTemplate(message) {
|
|
1075
|
+
return `
|
|
1076
|
+
<div class="oa-error-step">
|
|
1077
|
+
<div class="oa-error-step-icon">✕</div>
|
|
1078
|
+
<div class="oa-error-step-title">Verification stopped</div>
|
|
1079
|
+
<div class="oa-error-step-message">${message}</div>
|
|
1080
|
+
<div class="oa-error-step-countdown"></div>
|
|
1081
|
+
</div>
|
|
1082
|
+
`;
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1028
1085
|
function resultTemplate(outcome, message) {
|
|
1029
1086
|
const icons = {
|
|
1030
1087
|
fail: '✕',
|
|
@@ -1046,7 +1103,7 @@
|
|
|
1046
1103
|
|
|
1047
1104
|
const VERSION = '1.0.0';
|
|
1048
1105
|
|
|
1049
|
-
const MEDIAPIPE_CDN = 'https://cdn.jsdelivr.net/npm
|
|
1106
|
+
const MEDIAPIPE_CDN = 'https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.17';
|
|
1050
1107
|
|
|
1051
1108
|
const MEDIAPIPE_WASM = `${MEDIAPIPE_CDN}/wasm`;
|
|
1052
1109
|
|
|
@@ -1058,12 +1115,13 @@
|
|
|
1058
1115
|
'face_landmarker.task';
|
|
1059
1116
|
|
|
1060
1117
|
const FACEAPI_CDN =
|
|
1061
|
-
'https://cdn.jsdelivr.net/npm/
|
|
1118
|
+
'https://cdn.jsdelivr.net/npm/face-api.js@0.22.2/dist/face-api.min.js';
|
|
1062
1119
|
|
|
1063
1120
|
const FACEAPI_MODEL_CDN =
|
|
1064
|
-
'https://cdn.jsdelivr.net/gh/
|
|
1121
|
+
'https://cdn.jsdelivr.net/gh/justadudewhohacks/face-api.js@master/weights';
|
|
1065
1122
|
|
|
1066
1123
|
const MAX_RETRIES = 3;
|
|
1124
|
+
const ERROR_STEP_SECONDS = 5;
|
|
1067
1125
|
const BURST_FRAMES = 5;
|
|
1068
1126
|
const BURST_INTERVAL_MS = 200;
|
|
1069
1127
|
const POSITION_CHECK_MS = 100;
|
|
@@ -1544,8 +1602,20 @@
|
|
|
1544
1602
|
}
|
|
1545
1603
|
}
|
|
1546
1604
|
|
|
1547
|
-
showError() {
|
|
1548
|
-
this.
|
|
1605
|
+
showError(message) {
|
|
1606
|
+
if (!this.popupElements?.body) return;
|
|
1607
|
+
|
|
1608
|
+
this.popupElements.body.innerHTML = errorStepTemplate(message);
|
|
1609
|
+
this.popupElements.errorCountdown =
|
|
1610
|
+
this.popupElements.body.querySelector('.oa-error-step-countdown');
|
|
1611
|
+
this.hideActions();
|
|
1612
|
+
}
|
|
1613
|
+
|
|
1614
|
+
setErrorCountdown(seconds) {
|
|
1615
|
+
if (!this.popupElements?.errorCountdown) return;
|
|
1616
|
+
|
|
1617
|
+
const unit = seconds === 1 ? 'second' : 'seconds';
|
|
1618
|
+
this.popupElements.errorCountdown.textContent = `Closing in ${seconds} ${unit}…`;
|
|
1549
1619
|
}
|
|
1550
1620
|
|
|
1551
1621
|
clearError() {
|
|
@@ -2723,6 +2793,64 @@
|
|
|
2723
2793
|
return new Promise((r) => setTimeout(r, ms));
|
|
2724
2794
|
}
|
|
2725
2795
|
|
|
2796
|
+
function resolveChallengeErrorMessage(error) {
|
|
2797
|
+
const name = typeof error?.name === 'string' ? error.name : '';
|
|
2798
|
+
const message = typeof error?.message === 'string' ? error.message : String(error || '');
|
|
2799
|
+
const normalized = `${name} ${message}`.toLowerCase();
|
|
2800
|
+
|
|
2801
|
+
if (
|
|
2802
|
+
name === 'NotFoundError' ||
|
|
2803
|
+
/request is not allowed by the user agent or the platform in the current context/.test(
|
|
2804
|
+
normalized
|
|
2805
|
+
) ||
|
|
2806
|
+
/requested device not found|device not found|no camera|could not start video source/.test(
|
|
2807
|
+
normalized
|
|
2808
|
+
)
|
|
2809
|
+
) {
|
|
2810
|
+
return 'No camera available. Plug in a camera and try again.';
|
|
2811
|
+
}
|
|
2812
|
+
|
|
2813
|
+
if (
|
|
2814
|
+
name === 'NotAllowedError' ||
|
|
2815
|
+
name === 'PermissionDeniedError' ||
|
|
2816
|
+
/permission|camera access|access denied/.test(normalized)
|
|
2817
|
+
) {
|
|
2818
|
+
return 'Camera access was blocked. Allow camera access and try again.';
|
|
2819
|
+
}
|
|
2820
|
+
|
|
2821
|
+
if (/positioning timeout/.test(normalized)) {
|
|
2822
|
+
return 'Face positioning timed out. Reopen the check and try again.';
|
|
2823
|
+
}
|
|
2824
|
+
|
|
2825
|
+
return 'Verification failed. Please try again.';
|
|
2826
|
+
}
|
|
2827
|
+
|
|
2828
|
+
async function showErrorStep(widget, error) {
|
|
2829
|
+
const message = resolveChallengeErrorMessage(error);
|
|
2830
|
+
|
|
2831
|
+
if (!widget.popup) {
|
|
2832
|
+
widget.openPopup?.();
|
|
2833
|
+
}
|
|
2834
|
+
|
|
2835
|
+
widget.showError?.(message);
|
|
2836
|
+
|
|
2837
|
+
for (let seconds = ERROR_STEP_SECONDS; seconds > 0; seconds--) {
|
|
2838
|
+
if (!widget.popup) break;
|
|
2839
|
+
widget.setErrorCountdown?.(seconds);
|
|
2840
|
+
await sleep(1000);
|
|
2841
|
+
}
|
|
2842
|
+
|
|
2843
|
+
widget.closePopup?.();
|
|
2844
|
+
widget.setState?.('retry');
|
|
2845
|
+
}
|
|
2846
|
+
|
|
2847
|
+
async function handleChallengeError(widget, emitter, error) {
|
|
2848
|
+
console.log('Error during challenge:', error);
|
|
2849
|
+
await showErrorStep(widget, error);
|
|
2850
|
+
emitter.emit('error', error, widget.id);
|
|
2851
|
+
widget.params.errorCallback?.(error);
|
|
2852
|
+
}
|
|
2853
|
+
|
|
2726
2854
|
async function runChallenge(widget, emitter) {
|
|
2727
2855
|
const mode = widget.params.mode || 'serverless';
|
|
2728
2856
|
|
|
@@ -2803,9 +2931,7 @@
|
|
|
2803
2931
|
emitResult(widget, emitter, result);
|
|
2804
2932
|
} catch (error) {
|
|
2805
2933
|
cleanupLocal();
|
|
2806
|
-
widget
|
|
2807
|
-
emitter.emit('error', error, widget.id);
|
|
2808
|
-
params.errorCallback?.(error);
|
|
2934
|
+
await handleChallengeError(widget, emitter, error);
|
|
2809
2935
|
}
|
|
2810
2936
|
}
|
|
2811
2937
|
|
|
@@ -2937,9 +3063,7 @@
|
|
|
2937
3063
|
cleanupVM(transport);
|
|
2938
3064
|
} catch (error) {
|
|
2939
3065
|
cleanupVM();
|
|
2940
|
-
widget
|
|
2941
|
-
emitter.emit('error', error, widget.id);
|
|
2942
|
-
params.errorCallback?.(error);
|
|
3066
|
+
await handleChallengeError(widget, emitter, error);
|
|
2943
3067
|
}
|
|
2944
3068
|
}
|
|
2945
3069
|
|