altcha 3.0.0-beta.2 → 3.0.0-beta.3
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 +5 -2
- package/dist/external/altcha.js +247 -36
- package/dist/external/altcha.min.js +1 -1
- package/dist/external/altcha.umd.cjs +247 -36
- package/dist/external/altcha.umd.min.cjs +1 -1
- package/dist/lib/index.d.ts +18 -6
- package/dist/lib/index.js +3 -1
- package/dist/lib/index.min.js +1 -1
- package/dist/lib/index.umd.cjs +3 -1
- package/dist/lib/index.umd.min.cjs +1 -1
- package/dist/main/altcha.i18n.js +253 -40
- package/dist/main/altcha.i18n.min.js +1 -1
- package/dist/main/altcha.i18n.umd.cjs +253 -40
- package/dist/main/altcha.i18n.umd.min.cjs +1 -1
- package/dist/main/altcha.js +253 -40
- package/dist/main/altcha.min.js +1 -1
- package/dist/main/altcha.umd.cjs +253 -40
- package/dist/main/altcha.umd.min.cjs +1 -1
- package/dist/plugins/obfuscation.plugin.js +55 -14
- package/dist/plugins/obfuscation.plugin.min.js +1 -1
- package/dist/plugins/obfuscation.plugin.umd.cjs +55 -14
- package/dist/plugins/obfuscation.plugin.umd.min.cjs +1 -1
- package/dist/types/generic.d.ts +4 -1
- package/dist/types/index.d.ts +18 -6
- package/dist/workers/argon2id.js +3 -2
- package/dist/workers/pbkdf2.js +3 -2
- package/dist/workers/scrypt.js +3 -2
- package/dist/workers/sha.js +3 -2
- package/package.json +2 -2
- package/dist/external/index.d.ts +0 -1
package/dist/main/altcha.js
CHANGED
|
@@ -5431,7 +5431,7 @@ var root_3$1 = /* @__PURE__ */ from_html(`<div role="button" class="altcha-popov
|
|
|
5431
5431
|
var root$1 = /* @__PURE__ */ from_html(`<!> <div><!> <!> <div class="altcha-popover-content"><!></div></div>`, 1);
|
|
5432
5432
|
function Popover($$anchor, $$props) {
|
|
5433
5433
|
push($$props, true);
|
|
5434
|
-
let anchor = prop($$props, "anchor"), children = prop($$props, "children"), display = prop($$props, "display", 7, "standard"), backdrop = prop($$props, "backdrop", 7, false), onClickOutside = prop($$props, "onClickOutside"), onClickOutsideDelay = prop($$props, "onClickOutsideDelay", 7, 600), onClose = prop($$props, "onClose"), variant = prop($$props, "variant", 7, "neutral"), rest = /* @__PURE__ */ rest_props($$props, [
|
|
5434
|
+
let anchor = prop($$props, "anchor"), children = prop($$props, "children"), display = prop($$props, "display", 7, "standard"), backdrop = prop($$props, "backdrop", 7, false), onClickOutside = prop($$props, "onClickOutside"), onClickOutsideDelay = prop($$props, "onClickOutsideDelay", 7, 600), onClose = prop($$props, "onClose"), placement = prop($$props, "placement", 7, "auto"), variant = prop($$props, "variant", 7, "neutral"), rest = /* @__PURE__ */ rest_props($$props, [
|
|
5435
5435
|
"$$slots",
|
|
5436
5436
|
"$$events",
|
|
5437
5437
|
"$$legacy",
|
|
@@ -5443,12 +5443,18 @@ function Popover($$anchor, $$props) {
|
|
|
5443
5443
|
"onClickOutside",
|
|
5444
5444
|
"onClickOutsideDelay",
|
|
5445
5445
|
"onClose",
|
|
5446
|
+
"placement",
|
|
5446
5447
|
"variant"
|
|
5447
5448
|
]);
|
|
5448
5449
|
let el = /* @__PURE__ */ state(void 0);
|
|
5449
5450
|
let elBackdrop = /* @__PURE__ */ state(void 0);
|
|
5450
5451
|
let top = /* @__PURE__ */ state(false);
|
|
5451
5452
|
let mountedAt = /* @__PURE__ */ state(0);
|
|
5453
|
+
user_effect(() => {
|
|
5454
|
+
if (placement() !== "auto") {
|
|
5455
|
+
set(top, placement() === "top");
|
|
5456
|
+
}
|
|
5457
|
+
});
|
|
5452
5458
|
onMount(() => {
|
|
5453
5459
|
const moveToBody = display() === "bottomsheet" || display() === "overlay";
|
|
5454
5460
|
if (moveToBody) {
|
|
@@ -5482,7 +5488,7 @@ function Popover($$anchor, $$props) {
|
|
|
5482
5488
|
reposition();
|
|
5483
5489
|
}
|
|
5484
5490
|
function reposition() {
|
|
5485
|
-
if (anchor() && get(el)) {
|
|
5491
|
+
if (anchor() && placement() === "auto" && get(el)) {
|
|
5486
5492
|
const boundary2 = anchor().getBoundingClientRect();
|
|
5487
5493
|
const bottomGap = document.documentElement.clientHeight - (boundary2.top + boundary2.height);
|
|
5488
5494
|
const newTop = bottomGap < get(el).clientHeight;
|
|
@@ -5541,6 +5547,13 @@ function Popover($$anchor, $$props) {
|
|
|
5541
5547
|
onClose($$value);
|
|
5542
5548
|
flushSync();
|
|
5543
5549
|
},
|
|
5550
|
+
get placement() {
|
|
5551
|
+
return placement();
|
|
5552
|
+
},
|
|
5553
|
+
set placement($$value = "auto") {
|
|
5554
|
+
placement($$value);
|
|
5555
|
+
flushSync();
|
|
5556
|
+
},
|
|
5544
5557
|
get variant() {
|
|
5545
5558
|
return variant();
|
|
5546
5559
|
},
|
|
@@ -5614,6 +5627,7 @@ create_custom_element(
|
|
|
5614
5627
|
onClickOutside: {},
|
|
5615
5628
|
onClickOutsideDelay: {},
|
|
5616
5629
|
onClose: {},
|
|
5630
|
+
placement: {},
|
|
5617
5631
|
variant: {}
|
|
5618
5632
|
},
|
|
5619
5633
|
[],
|
|
@@ -5638,7 +5652,8 @@ async function solveChallengeWorkers(options) {
|
|
|
5638
5652
|
controller = new AbortController(),
|
|
5639
5653
|
createWorker,
|
|
5640
5654
|
onOutOfMemory = (c) => c > 1 ? Math.floor(c / 2) : 0,
|
|
5641
|
-
counterMode
|
|
5655
|
+
counterMode,
|
|
5656
|
+
timeout = 9e4
|
|
5642
5657
|
} = options;
|
|
5643
5658
|
const workersConcurrency = Math.min(16, Math.max(1, concurrency));
|
|
5644
5659
|
const workersInstances = [];
|
|
@@ -5679,6 +5694,7 @@ async function solveChallengeWorkers(options) {
|
|
|
5679
5694
|
counterMode,
|
|
5680
5695
|
counterStart: i,
|
|
5681
5696
|
counterStep: workersConcurrency,
|
|
5697
|
+
timeout,
|
|
5682
5698
|
type: "work"
|
|
5683
5699
|
});
|
|
5684
5700
|
});
|
|
@@ -5710,6 +5726,147 @@ async function solveChallengeWorkers(options) {
|
|
|
5710
5726
|
}
|
|
5711
5727
|
return solution || null;
|
|
5712
5728
|
}
|
|
5729
|
+
class Collector {
|
|
5730
|
+
TAG_CODES = {
|
|
5731
|
+
INPUT: 1,
|
|
5732
|
+
TEXTAREA: 2,
|
|
5733
|
+
SELECT: 3,
|
|
5734
|
+
BUTTON: 4,
|
|
5735
|
+
A: 5,
|
|
5736
|
+
DETAILS: 6,
|
|
5737
|
+
SUMMARY: 7,
|
|
5738
|
+
IFRAME: 8,
|
|
5739
|
+
VIDEO: 9,
|
|
5740
|
+
AUDIO: 10
|
|
5741
|
+
};
|
|
5742
|
+
maxSamples;
|
|
5743
|
+
sampleInterval;
|
|
5744
|
+
target;
|
|
5745
|
+
focusStartTime = 0;
|
|
5746
|
+
focusInteraction = 0;
|
|
5747
|
+
focusInteractionTimer = null;
|
|
5748
|
+
lastPointerSample = 0;
|
|
5749
|
+
lastTouchSample = 0;
|
|
5750
|
+
lastScrollSample = 0;
|
|
5751
|
+
pendingPointer = null;
|
|
5752
|
+
pendingTouch = null;
|
|
5753
|
+
focus = [];
|
|
5754
|
+
pointer = [];
|
|
5755
|
+
scroll = [];
|
|
5756
|
+
touch = [];
|
|
5757
|
+
constructor(options = {}) {
|
|
5758
|
+
const { maxSamples = 60, sampleInterval = 50, target = window } = options;
|
|
5759
|
+
this.maxSamples = maxSamples;
|
|
5760
|
+
this.sampleInterval = sampleInterval;
|
|
5761
|
+
this.target = target;
|
|
5762
|
+
this.attach();
|
|
5763
|
+
}
|
|
5764
|
+
destroy() {
|
|
5765
|
+
const o = { capture: true };
|
|
5766
|
+
this.target.removeEventListener("focusin", this.onFocus, o);
|
|
5767
|
+
this.target.removeEventListener("keydown", this.onInteraction, o);
|
|
5768
|
+
this.target.removeEventListener("pointerdown", this.onInteraction, o);
|
|
5769
|
+
this.target.removeEventListener("pointermove", this.onPointer, o);
|
|
5770
|
+
this.target.removeEventListener("scroll", this.onScroll, o);
|
|
5771
|
+
this.target.removeEventListener("touchmove", this.onTouchMove, o);
|
|
5772
|
+
}
|
|
5773
|
+
export() {
|
|
5774
|
+
return {
|
|
5775
|
+
focus: this.focus,
|
|
5776
|
+
maxTouchPoints: navigator.maxTouchPoints || 0,
|
|
5777
|
+
pointer: this.pointer,
|
|
5778
|
+
scroll: this.scroll,
|
|
5779
|
+
time: Date.now(),
|
|
5780
|
+
touch: this.touch
|
|
5781
|
+
};
|
|
5782
|
+
}
|
|
5783
|
+
attach() {
|
|
5784
|
+
const o = { passive: true, capture: true };
|
|
5785
|
+
this.target.addEventListener("focusin", this.onFocus, o);
|
|
5786
|
+
this.target.addEventListener("keydown", this.onInteraction, o);
|
|
5787
|
+
this.target.addEventListener("pointerdown", this.onInteraction, o);
|
|
5788
|
+
this.target.addEventListener("pointermove", this.onPointer, o);
|
|
5789
|
+
this.target.addEventListener("scroll", this.onScroll, o);
|
|
5790
|
+
this.target.addEventListener("touchmove", this.onTouchMove, o);
|
|
5791
|
+
}
|
|
5792
|
+
evict(buffer) {
|
|
5793
|
+
if (buffer.length > this.maxSamples) {
|
|
5794
|
+
buffer.splice(0, buffer.length - this.maxSamples);
|
|
5795
|
+
}
|
|
5796
|
+
}
|
|
5797
|
+
onFocus = (e) => {
|
|
5798
|
+
if (this.focusInteraction === 2) {
|
|
5799
|
+
return;
|
|
5800
|
+
}
|
|
5801
|
+
const el = e.target;
|
|
5802
|
+
if (!(el instanceof Element)) {
|
|
5803
|
+
return;
|
|
5804
|
+
}
|
|
5805
|
+
const now = performance.now();
|
|
5806
|
+
if (this.focusStartTime === 0) {
|
|
5807
|
+
this.focusStartTime = now;
|
|
5808
|
+
}
|
|
5809
|
+
this.focus.push([
|
|
5810
|
+
Math.round(now - this.focusStartTime),
|
|
5811
|
+
el.tabIndex,
|
|
5812
|
+
this.TAG_CODES[el.tagName] ?? 0,
|
|
5813
|
+
this.focusInteraction ? 1 : 0
|
|
5814
|
+
]);
|
|
5815
|
+
this.evict(this.focus);
|
|
5816
|
+
};
|
|
5817
|
+
onInteraction = (e) => {
|
|
5818
|
+
this.focusInteraction = "keyCode" in e ? 1 : 2;
|
|
5819
|
+
if (this.focusInteractionTimer) {
|
|
5820
|
+
clearTimeout(this.focusInteractionTimer);
|
|
5821
|
+
}
|
|
5822
|
+
this.focusInteractionTimer = setTimeout(() => {
|
|
5823
|
+
this.focusInteraction = 0;
|
|
5824
|
+
}, 100);
|
|
5825
|
+
};
|
|
5826
|
+
onPointer = (e) => {
|
|
5827
|
+
if (e.pointerType === "touch") {
|
|
5828
|
+
return;
|
|
5829
|
+
}
|
|
5830
|
+
const now = e.timeStamp || performance.now();
|
|
5831
|
+
this.pendingPointer = [Math.round(e.clientX), Math.round(e.clientY), Math.round(now)];
|
|
5832
|
+
if (now - this.lastPointerSample >= this.sampleInterval) {
|
|
5833
|
+
this.pointer.push(this.pendingPointer);
|
|
5834
|
+
this.lastPointerSample = now;
|
|
5835
|
+
this.pendingPointer = null;
|
|
5836
|
+
this.evict(this.pointer);
|
|
5837
|
+
}
|
|
5838
|
+
};
|
|
5839
|
+
onScroll = () => {
|
|
5840
|
+
const now = performance.now();
|
|
5841
|
+
if (now - this.lastScrollSample < this.sampleInterval) {
|
|
5842
|
+
return;
|
|
5843
|
+
}
|
|
5844
|
+
this.scroll.push([Math.round(window.scrollY), Math.round(now)]);
|
|
5845
|
+
this.lastScrollSample = now;
|
|
5846
|
+
this.evict(this.scroll);
|
|
5847
|
+
};
|
|
5848
|
+
onTouchMove = (e) => {
|
|
5849
|
+
const now = e.timeStamp || performance.now();
|
|
5850
|
+
const t = e.touches[0];
|
|
5851
|
+
if (!t) {
|
|
5852
|
+
return;
|
|
5853
|
+
}
|
|
5854
|
+
this.pendingTouch = [
|
|
5855
|
+
Math.round(t.clientX),
|
|
5856
|
+
Math.round(t.clientY),
|
|
5857
|
+
Math.round(now),
|
|
5858
|
+
Math.round(t.force * 1e3) / 1e3,
|
|
5859
|
+
Math.round(t.radiusX || 0),
|
|
5860
|
+
Math.round(t.radiusY || 0)
|
|
5861
|
+
];
|
|
5862
|
+
if (now - this.lastTouchSample >= this.sampleInterval) {
|
|
5863
|
+
this.touch.push(this.pendingTouch);
|
|
5864
|
+
this.lastTouchSample = now;
|
|
5865
|
+
this.pendingTouch = null;
|
|
5866
|
+
this.evict(this.touch);
|
|
5867
|
+
}
|
|
5868
|
+
};
|
|
5869
|
+
}
|
|
5713
5870
|
var root_1 = /* @__PURE__ */ from_html(`<div class="altcha-overlay-backdrop" data-backdrop=""></div>`);
|
|
5714
5871
|
var root_3 = /* @__PURE__ */ from_html(`<div class="altcha-overlay-content"></div>`);
|
|
5715
5872
|
var root_2 = /* @__PURE__ */ from_html(`<div role="button" class="altcha-overlay-close">×</div> <!>`, 1);
|
|
@@ -5740,6 +5897,7 @@ function Widget($$anchor, $$props) {
|
|
|
5740
5897
|
instance?.dispatchEvent(new CustomEvent(event2, { detail }));
|
|
5741
5898
|
});
|
|
5742
5899
|
};
|
|
5900
|
+
let hisCollector = null;
|
|
5743
5901
|
let baseUrl = /* @__PURE__ */ state(proxy(new URL(location.origin)));
|
|
5744
5902
|
let checked = /* @__PURE__ */ state(false);
|
|
5745
5903
|
let codeChallenge = /* @__PURE__ */ state(null);
|
|
@@ -5774,16 +5932,19 @@ function Widget($$anchor, $$props) {
|
|
|
5774
5932
|
floatingPlacement: "auto",
|
|
5775
5933
|
hideFooter: false,
|
|
5776
5934
|
hideLogo: false,
|
|
5935
|
+
humanInteractionSignature: true,
|
|
5777
5936
|
language: "",
|
|
5778
5937
|
mockError: false,
|
|
5779
5938
|
minDuration: 500,
|
|
5780
5939
|
overlayContent: "",
|
|
5781
5940
|
name: "altcha",
|
|
5941
|
+
popoverPlacement: "auto",
|
|
5782
5942
|
retryOnOutOfMemoryError: true,
|
|
5783
5943
|
setCookie: null,
|
|
5784
5944
|
serverVerificationFields: false,
|
|
5785
5945
|
serverVerificationTimeZone: false,
|
|
5786
5946
|
test: false,
|
|
5947
|
+
timeout: 9e4,
|
|
5787
5948
|
type: "checkbox",
|
|
5788
5949
|
validationMessage: "",
|
|
5789
5950
|
verifyFunction: null,
|
|
@@ -5794,6 +5955,7 @@ function Widget($$anchor, $$props) {
|
|
|
5794
5955
|
}));
|
|
5795
5956
|
const checkboxId = /* @__PURE__ */ user_derived(() => `altcha-checkbox-${$$props.id || Math.floor(Math.random() * 1e12).toString(16)}`);
|
|
5796
5957
|
const CheckboxComponent = /* @__PURE__ */ user_derived(() => getCheckboxComponent(get(config).type));
|
|
5958
|
+
const auto = /* @__PURE__ */ user_derived(() => get(config).auto);
|
|
5797
5959
|
const loading = /* @__PURE__ */ user_derived(() => get(currentState) === State.VERIFYING);
|
|
5798
5960
|
const showFooter = /* @__PURE__ */ user_derived(() => !get(config).hideFooter);
|
|
5799
5961
|
const showLogo = /* @__PURE__ */ user_derived(() => !get(config).hideLogo && get(config).display !== "bar");
|
|
@@ -5855,7 +6017,7 @@ function Widget($$anchor, $$props) {
|
|
|
5855
6017
|
}
|
|
5856
6018
|
});
|
|
5857
6019
|
user_effect(() => {
|
|
5858
|
-
if (get(
|
|
6020
|
+
if (get(auto) === "onload") {
|
|
5859
6021
|
const tm = setTimeout(
|
|
5860
6022
|
() => {
|
|
5861
6023
|
verify();
|
|
@@ -5880,15 +6042,19 @@ function Widget($$anchor, $$props) {
|
|
|
5880
6042
|
}
|
|
5881
6043
|
});
|
|
5882
6044
|
onMount(() => {
|
|
5883
|
-
log("mounted", "3.0.0-beta.
|
|
6045
|
+
log("mounted", "3.0.0-beta.3");
|
|
5884
6046
|
if (instance) {
|
|
5885
6047
|
globalThis.$altcha.instances.add(instance);
|
|
5886
6048
|
}
|
|
5887
6049
|
set(elForm, get(elRoot)?.closest("form"), true);
|
|
5888
6050
|
get(elForm)?.addEventListener("reset", onFormReset);
|
|
5889
|
-
get(elForm)?.addEventListener("submit", onFormSubmit);
|
|
6051
|
+
get(elForm)?.addEventListener("submit", onFormSubmit, { capture: true });
|
|
5890
6052
|
get(elForm)?.addEventListener("focusin", onFormFocusIn);
|
|
5891
6053
|
activatePlugins();
|
|
6054
|
+
if (get(config).humanInteractionSignature) {
|
|
6055
|
+
log("human interaction signature enabled");
|
|
6056
|
+
hisCollector = new Collector();
|
|
6057
|
+
}
|
|
5892
6058
|
dispatch("load");
|
|
5893
6059
|
if (!isSecureContext) {
|
|
5894
6060
|
log("secure context (HTTPS) required");
|
|
@@ -5902,8 +6068,9 @@ function Widget($$anchor, $$props) {
|
|
|
5902
6068
|
clearTimeout(get(expirationTimeout));
|
|
5903
6069
|
}
|
|
5904
6070
|
get(elForm)?.removeEventListener("reset", onFormReset);
|
|
5905
|
-
get(elForm)?.removeEventListener("submit", onFormSubmit);
|
|
6071
|
+
get(elForm)?.removeEventListener("submit", onFormSubmit, { capture: true });
|
|
5906
6072
|
get(elForm)?.removeEventListener("focusin", onFormFocusIn);
|
|
6073
|
+
hisCollector?.destroy();
|
|
5907
6074
|
};
|
|
5908
6075
|
});
|
|
5909
6076
|
function activatePlugins() {
|
|
@@ -5967,23 +6134,41 @@ function Widget($$anchor, $$props) {
|
|
|
5967
6134
|
async function delay(ms) {
|
|
5968
6135
|
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
5969
6136
|
}
|
|
5970
|
-
async function fetchChallenge(source2 = get(config).challenge) {
|
|
6137
|
+
async function fetchChallenge(source2 = get(config).challenge, requestOptions) {
|
|
5971
6138
|
const hook = await callHook("onFetchChallenge", source2);
|
|
6139
|
+
let challenge = null;
|
|
5972
6140
|
if (hook !== void 0) {
|
|
5973
6141
|
return hook;
|
|
5974
6142
|
}
|
|
5975
6143
|
if (typeof source2 === "string") {
|
|
5976
|
-
let challenge = null;
|
|
5977
6144
|
if (source2.match(/^(https?:)?\//)) {
|
|
5978
|
-
log("fetching challenge from", source2);
|
|
6145
|
+
log("fetching challenge from", requestOptions?.method || "GET", source2);
|
|
5979
6146
|
set(baseUrl, new URL(source2, location.origin), true);
|
|
5980
|
-
const resp = await get(config).fetch(source2, {
|
|
5981
|
-
|
|
6147
|
+
const resp = await get(config).fetch(source2, {
|
|
6148
|
+
credentials: get(config).credentials || void 0,
|
|
6149
|
+
...requestOptions
|
|
6150
|
+
});
|
|
6151
|
+
await validateResponse(resp);
|
|
5982
6152
|
const configHeader = resp.headers.get("x-altcha-config");
|
|
5983
6153
|
if (configHeader) {
|
|
5984
6154
|
processConfigHeader(configHeader);
|
|
5985
6155
|
}
|
|
5986
|
-
|
|
6156
|
+
const json = await resp.json();
|
|
6157
|
+
if (json && "his" in json && json.his) {
|
|
6158
|
+
log("requested HIS");
|
|
6159
|
+
if (!hisCollector) {
|
|
6160
|
+
throw new Error("Server requested HIS data but collector is disabled.");
|
|
6161
|
+
}
|
|
6162
|
+
return fetchChallenge(getUrl(json.his.url, get(baseUrl)), {
|
|
6163
|
+
body: JSON.stringify({ his: hisCollector.export() }),
|
|
6164
|
+
headers: { "content-type": "application/json" },
|
|
6165
|
+
method: "POST"
|
|
6166
|
+
});
|
|
6167
|
+
}
|
|
6168
|
+
if (json && "hisResult" in json && json.hisResult) {
|
|
6169
|
+
log("HIS result", json.hisResult);
|
|
6170
|
+
}
|
|
6171
|
+
challenge = json;
|
|
5987
6172
|
} else {
|
|
5988
6173
|
log("parsing JSON challenge");
|
|
5989
6174
|
try {
|
|
@@ -5992,20 +6177,26 @@ function Widget($$anchor, $$props) {
|
|
|
5992
6177
|
throw new Error(`Unable to parse JSON challenge.`);
|
|
5993
6178
|
}
|
|
5994
6179
|
}
|
|
5995
|
-
if (typeof challenge === "object" && "challenge" in challenge) {
|
|
5996
|
-
challenge = createChallengeFromV1(challenge);
|
|
5997
|
-
}
|
|
5998
|
-
if (!isChallengeValid(challenge)) {
|
|
5999
|
-
throw new Error(`Challenge validation failed.`);
|
|
6000
|
-
}
|
|
6001
|
-
return challenge;
|
|
6002
6180
|
} else if (source2 && typeof source2 === "object") {
|
|
6003
|
-
|
|
6181
|
+
try {
|
|
6182
|
+
challenge = JSON.parse(JSON.stringify(source2));
|
|
6183
|
+
} catch {
|
|
6184
|
+
throw new Error(`Unable to parse JSON challenge.`);
|
|
6185
|
+
}
|
|
6004
6186
|
}
|
|
6005
|
-
|
|
6187
|
+
if (isChallengeV1(challenge)) {
|
|
6188
|
+
challenge = createChallengeFromV1(challenge);
|
|
6189
|
+
}
|
|
6190
|
+
if (!isChallengeValid(challenge)) {
|
|
6191
|
+
throw new Error(`Challenge validation failed.`);
|
|
6192
|
+
}
|
|
6193
|
+
return challenge;
|
|
6194
|
+
}
|
|
6195
|
+
function isChallengeV1(challenge) {
|
|
6196
|
+
return typeof challenge === "object" && "challenge" in challenge;
|
|
6006
6197
|
}
|
|
6007
6198
|
function isChallengeValid(challenge) {
|
|
6008
|
-
return !!challenge && typeof challenge === "object" && "parameters" in challenge &&
|
|
6199
|
+
return !!challenge && typeof challenge === "object" && "parameters" in challenge && !!challenge.parameters && typeof challenge.parameters === "object" && "algorithm" in challenge.parameters && "nonce" in challenge.parameters && "salt" in challenge.parameters && "keyPrefix" in challenge.parameters;
|
|
6009
6200
|
}
|
|
6010
6201
|
function getCheckboxElement() {
|
|
6011
6202
|
return document.getElementById(get(checkboxId));
|
|
@@ -6118,7 +6309,7 @@ function Widget($$anchor, $$props) {
|
|
|
6118
6309
|
}
|
|
6119
6310
|
}
|
|
6120
6311
|
function onFormFocusIn(ev) {
|
|
6121
|
-
if (get(
|
|
6312
|
+
if (get(auto) === "onfocus" && get(currentState) === State.UNVERIFIED) {
|
|
6122
6313
|
verify();
|
|
6123
6314
|
}
|
|
6124
6315
|
}
|
|
@@ -6131,7 +6322,7 @@ function Widget($$anchor, $$props) {
|
|
|
6131
6322
|
}
|
|
6132
6323
|
function onFormSubmit(ev) {
|
|
6133
6324
|
set(elSubmitter, ev.submitter, true);
|
|
6134
|
-
if (get(
|
|
6325
|
+
if (get(auto) === "onsubmit" && get(currentState) === State.UNVERIFIED) {
|
|
6135
6326
|
ev.preventDefault();
|
|
6136
6327
|
ev.stopPropagation();
|
|
6137
6328
|
show();
|
|
@@ -6217,7 +6408,7 @@ function Widget($$anchor, $$props) {
|
|
|
6217
6408
|
headers: { "Content-Type": "application/json" },
|
|
6218
6409
|
method: "POST"
|
|
6219
6410
|
});
|
|
6220
|
-
validateResponse(resp);
|
|
6411
|
+
await validateResponse(resp);
|
|
6221
6412
|
const json = await resp.json();
|
|
6222
6413
|
if (json && typeof json === "object" && "payload" in json && !!json.payload) {
|
|
6223
6414
|
dispatch("serververification", json);
|
|
@@ -6258,7 +6449,7 @@ function Widget($$anchor, $$props) {
|
|
|
6258
6449
|
case "floating":
|
|
6259
6450
|
case "overlay":
|
|
6260
6451
|
hide();
|
|
6261
|
-
if (!get(
|
|
6452
|
+
if (!get(auto) || get(auto) === "off") {
|
|
6262
6453
|
get(userConfig).auto = "onsubmit";
|
|
6263
6454
|
}
|
|
6264
6455
|
break;
|
|
@@ -6286,8 +6477,18 @@ function Widget($$anchor, $$props) {
|
|
|
6286
6477
|
onExpired();
|
|
6287
6478
|
}
|
|
6288
6479
|
}
|
|
6289
|
-
function validateResponse(resp) {
|
|
6480
|
+
async function validateResponse(resp) {
|
|
6290
6481
|
if (resp.status >= 400) {
|
|
6482
|
+
if (resp.headers.get("content-type")?.includes("/json")) {
|
|
6483
|
+
let json;
|
|
6484
|
+
try {
|
|
6485
|
+
json = await resp.json();
|
|
6486
|
+
} catch {
|
|
6487
|
+
}
|
|
6488
|
+
if (json && "error" in json) {
|
|
6489
|
+
throw new Error(`Server responded with ${resp.status} - ${json.error}`);
|
|
6490
|
+
}
|
|
6491
|
+
}
|
|
6291
6492
|
throw new Error(`Server responded with ${resp.status}.`);
|
|
6292
6493
|
}
|
|
6293
6494
|
const contentType = resp.headers.get("content-type");
|
|
@@ -6318,7 +6519,7 @@ function Widget($$anchor, $$props) {
|
|
|
6318
6519
|
log("verified");
|
|
6319
6520
|
setState(State.VERIFIED);
|
|
6320
6521
|
dispatch("verified", { payload: get(payload) });
|
|
6321
|
-
if (get(
|
|
6522
|
+
if (get(auto) === "onsubmit") {
|
|
6322
6523
|
tick().then(() => {
|
|
6323
6524
|
requestSubmit(get(elSubmitter));
|
|
6324
6525
|
});
|
|
@@ -6385,7 +6586,7 @@ function Widget($$anchor, $$props) {
|
|
|
6385
6586
|
const start = performance.now();
|
|
6386
6587
|
let challenge = null;
|
|
6387
6588
|
let solution = null;
|
|
6388
|
-
let
|
|
6589
|
+
let isChallengeV12 = false;
|
|
6389
6590
|
const hook = await callHook("onVerify", options);
|
|
6390
6591
|
if (hook !== void 0) {
|
|
6391
6592
|
return hook;
|
|
@@ -6420,7 +6621,7 @@ function Widget($$anchor, $$props) {
|
|
|
6420
6621
|
if (challenge.parameters.expiresAt) {
|
|
6421
6622
|
setChallengeExpiration(challenge.parameters.expiresAt);
|
|
6422
6623
|
}
|
|
6423
|
-
|
|
6624
|
+
isChallengeV12 = "_version" in challenge && challenge._version === 1;
|
|
6424
6625
|
const createWorker = globalThis.$altcha.algorithms.get(challenge.parameters.algorithm);
|
|
6425
6626
|
if (!createWorker) {
|
|
6426
6627
|
throw new Error(`Unsupported algorithm ${challenge.parameters.algorithm}.`);
|
|
@@ -6430,7 +6631,7 @@ function Widget($$anchor, $$props) {
|
|
|
6430
6631
|
concurrency,
|
|
6431
6632
|
controller,
|
|
6432
6633
|
createWorker,
|
|
6433
|
-
counterMode:
|
|
6634
|
+
counterMode: isChallengeV12 ? "string" : "uint32",
|
|
6434
6635
|
onOutOfMemory: (c) => {
|
|
6435
6636
|
log("out of memory error received");
|
|
6436
6637
|
dispatch("outofmemory");
|
|
@@ -6439,7 +6640,8 @@ function Widget($$anchor, $$props) {
|
|
|
6439
6640
|
log(`retrying with ${retryConcurrency} workers...`);
|
|
6440
6641
|
return retryConcurrency;
|
|
6441
6642
|
}
|
|
6442
|
-
}
|
|
6643
|
+
},
|
|
6644
|
+
timeout: get(config).timeout
|
|
6443
6645
|
});
|
|
6444
6646
|
if (get(currentController)?.signal.aborted) {
|
|
6445
6647
|
reset$1();
|
|
@@ -6451,13 +6653,16 @@ function Widget($$anchor, $$props) {
|
|
|
6451
6653
|
log("solution", solution);
|
|
6452
6654
|
await delay(Math.max(0, minDuration - (performance.now() - start)));
|
|
6453
6655
|
set(codeChallenge, challenge.codeChallenge || get(config).codeChallenge || null, true);
|
|
6454
|
-
if (
|
|
6656
|
+
if (isChallengeV12) {
|
|
6455
6657
|
set(payload, btoa(JSON.stringify(createPayloadV1(challenge, solution))), true);
|
|
6456
6658
|
} else {
|
|
6457
6659
|
set(
|
|
6458
6660
|
payload,
|
|
6459
6661
|
btoa(JSON.stringify({
|
|
6460
|
-
challenge: {
|
|
6662
|
+
challenge: {
|
|
6663
|
+
parameters: challenge.parameters,
|
|
6664
|
+
signature: challenge.signature
|
|
6665
|
+
},
|
|
6461
6666
|
solution
|
|
6462
6667
|
})),
|
|
6463
6668
|
true
|
|
@@ -6540,7 +6745,7 @@ function Widget($$anchor, $$props) {
|
|
|
6540
6745
|
var div_6 = child(div_5);
|
|
6541
6746
|
var node_3 = child(div_6);
|
|
6542
6747
|
{
|
|
6543
|
-
let $0 = /* @__PURE__ */ user_derived(() => get(config).display === "standard" && get(
|
|
6748
|
+
let $0 = /* @__PURE__ */ user_derived(() => get(config).display === "standard" && get(auto) !== "onsubmit" || get(currentState) === State.VERIFYING);
|
|
6544
6749
|
component(node_3, () => get(CheckboxComponent), ($$anchor2, CheckboxComponent_1) => {
|
|
6545
6750
|
CheckboxComponent_1($$anchor2, {
|
|
6546
6751
|
get id() {
|
|
@@ -6665,6 +6870,9 @@ function Widget($$anchor, $$props) {
|
|
|
6665
6870
|
reset$1();
|
|
6666
6871
|
}
|
|
6667
6872
|
},
|
|
6873
|
+
get placement() {
|
|
6874
|
+
return get(config).popoverPlacement;
|
|
6875
|
+
},
|
|
6668
6876
|
role: "alert",
|
|
6669
6877
|
variant: "error",
|
|
6670
6878
|
get dir() {
|
|
@@ -6725,6 +6933,9 @@ function Widget($$anchor, $$props) {
|
|
|
6725
6933
|
onClose: () => {
|
|
6726
6934
|
reset$1();
|
|
6727
6935
|
},
|
|
6936
|
+
get placement() {
|
|
6937
|
+
return get(config).popoverPlacement;
|
|
6938
|
+
},
|
|
6728
6939
|
role: "dialog",
|
|
6729
6940
|
get "aria-label"() {
|
|
6730
6941
|
return get(strings).verificationRequired;
|
|
@@ -6945,7 +7156,7 @@ const jsContent$1 = `(function() {
|
|
|
6945
7156
|
const { deriveKey: deriveKey2 } = options;
|
|
6946
7157
|
let controller = void 0;
|
|
6947
7158
|
self.onmessage = async (message) => {
|
|
6948
|
-
const { challenge, counterMode, counterStart, counterStep, type } = message.data;
|
|
7159
|
+
const { challenge, counterMode, counterStart, counterStep, timeout, type } = message.data;
|
|
6949
7160
|
if (type === "abort") {
|
|
6950
7161
|
controller?.abort();
|
|
6951
7162
|
} else if (type === "work") {
|
|
@@ -6958,7 +7169,8 @@ const jsContent$1 = `(function() {
|
|
|
6958
7169
|
counterStart,
|
|
6959
7170
|
counterStep,
|
|
6960
7171
|
deriveKey: deriveKey2,
|
|
6961
|
-
counterMode
|
|
7172
|
+
counterMode,
|
|
7173
|
+
timeout
|
|
6962
7174
|
});
|
|
6963
7175
|
} catch (err) {
|
|
6964
7176
|
return self.postMessage({ error: err });
|
|
@@ -7144,7 +7356,7 @@ const jsContent = `(function() {
|
|
|
7144
7356
|
const { deriveKey: deriveKey2 } = options;
|
|
7145
7357
|
let controller = void 0;
|
|
7146
7358
|
self.onmessage = async (message) => {
|
|
7147
|
-
const { challenge, counterMode, counterStart, counterStep, type } = message.data;
|
|
7359
|
+
const { challenge, counterMode, counterStart, counterStep, timeout, type } = message.data;
|
|
7148
7360
|
if (type === "abort") {
|
|
7149
7361
|
controller?.abort();
|
|
7150
7362
|
} else if (type === "work") {
|
|
@@ -7157,7 +7369,8 @@ const jsContent = `(function() {
|
|
|
7157
7369
|
counterStart,
|
|
7158
7370
|
counterStep,
|
|
7159
7371
|
deriveKey: deriveKey2,
|
|
7160
|
-
counterMode
|
|
7372
|
+
counterMode,
|
|
7373
|
+
timeout
|
|
7161
7374
|
});
|
|
7162
7375
|
} catch (err) {
|
|
7163
7376
|
return self.postMessage({ error: err });
|