altcha 3.0.3 → 3.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 +68 -0
- package/dist/external/altcha.js +42 -15
- package/dist/external/altcha.min.js +1 -1
- package/dist/external/altcha.umd.cjs +42 -15
- package/dist/external/altcha.umd.min.cjs +1 -1
- package/dist/main/altcha.i18n.js +42 -15
- package/dist/main/altcha.i18n.min.js +1 -1
- package/dist/main/altcha.i18n.umd.cjs +42 -15
- package/dist/main/altcha.i18n.umd.min.cjs +1 -1
- package/dist/main/altcha.js +42 -15
- package/dist/main/altcha.min.js +1 -1
- package/dist/main/altcha.umd.cjs +42 -15
- package/dist/main/altcha.umd.min.cjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -228,6 +228,74 @@ For simple implementations, the widget supports a subset of configuration option
|
|
|
228
228
|
- **`timeout`**: Verification timeout in milliseconds (Default: `90_000`).
|
|
229
229
|
- **`verifyFunction`**: A custom verification handler that overrides default network verification.
|
|
230
230
|
|
|
231
|
+
## Algorithms
|
|
232
|
+
|
|
233
|
+
ALTCHA supports multiple proof-of-work algorithms. `PBKDF2/*` and `SHA-*` are bundled with the main widget by default. `Argon2` and `Scrypt` are memory-bound algorithms that resist hardware acceleration (ASICs/GPUs) but require importing their workers separately.
|
|
234
|
+
|
|
235
|
+
**Supported algorithms:**
|
|
236
|
+
|
|
237
|
+
- `PBKDF2/SHA-256` (default, bundled)
|
|
238
|
+
- `PBKDF2/SHA-384` (bundled)
|
|
239
|
+
- `PBKDF2/SHA-512` (bundled)
|
|
240
|
+
- `SHA-256` (bundled)
|
|
241
|
+
- `SHA-384` (bundled)
|
|
242
|
+
- `SHA-512` (bundled)
|
|
243
|
+
- `ARGON2ID` (requires separate worker import)
|
|
244
|
+
- `SCRYPT` (requires separate worker import)
|
|
245
|
+
|
|
246
|
+
If you use `Argon2` or `Scrypt`, import their workers and register them via the `$altcha.algorithms` global before the widget initializes.
|
|
247
|
+
|
|
248
|
+
### Adding Argon2 / Scrypt Workers (Vite)
|
|
249
|
+
|
|
250
|
+
Works with both `altcha` and `altcha/external`:
|
|
251
|
+
|
|
252
|
+
```ts
|
|
253
|
+
import 'altcha'; // or 'altcha/external'
|
|
254
|
+
import Argon2idWorker from 'altcha/workers/argon2id?worker';
|
|
255
|
+
import ScryptWorker from 'altcha/workers/scrypt?worker';
|
|
256
|
+
|
|
257
|
+
$altcha.algorithms.set('ARGON2ID', () => new Argon2idWorker());
|
|
258
|
+
$altcha.algorithms.set('SCRYPT', () => new ScryptWorker());
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Without Bundler Worker Import Support
|
|
262
|
+
|
|
263
|
+
If your environment does not support `?worker` imports, load the prebuilt worker files directly:
|
|
264
|
+
|
|
265
|
+
```ts
|
|
266
|
+
import 'altcha';
|
|
267
|
+
|
|
268
|
+
$altcha.algorithms.set(
|
|
269
|
+
'ARGON2ID',
|
|
270
|
+
() => new Worker('/path/to/node_modules/altcha/dist/workers/argon2id.js')
|
|
271
|
+
);
|
|
272
|
+
$altcha.algorithms.set(
|
|
273
|
+
'SCRYPT',
|
|
274
|
+
() => new Worker('/path/to/node_modules/altcha/dist/workers/scrypt.js')
|
|
275
|
+
);
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Using `altcha/external`
|
|
279
|
+
|
|
280
|
+
`altcha/external` excludes all bundled workers, requiring you to register every algorithm explicitly. Use this for full control over which workers are loaded:
|
|
281
|
+
|
|
282
|
+
```ts
|
|
283
|
+
import 'altcha/external';
|
|
284
|
+
import Argon2idWorker from 'altcha/workers/argon2id?worker';
|
|
285
|
+
import Pbkdf2Worker from 'altcha/workers/pbkdf2?worker';
|
|
286
|
+
import ScryptWorker from 'altcha/workers/scrypt?worker';
|
|
287
|
+
import ShaWorker from 'altcha/workers/sha?worker';
|
|
288
|
+
|
|
289
|
+
$altcha.algorithms.set('PBKDF2/SHA-256', () => new Pbkdf2Worker());
|
|
290
|
+
$altcha.algorithms.set('PBKDF2/SHA-384', () => new Pbkdf2Worker());
|
|
291
|
+
$altcha.algorithms.set('PBKDF2/SHA-512', () => new Pbkdf2Worker());
|
|
292
|
+
$altcha.algorithms.set('SHA-256', () => new ShaWorker());
|
|
293
|
+
$altcha.algorithms.set('SHA-384', () => new ShaWorker());
|
|
294
|
+
$altcha.algorithms.set('SHA-512', () => new ShaWorker());
|
|
295
|
+
$altcha.algorithms.set('ARGON2ID', () => new Argon2idWorker());
|
|
296
|
+
$altcha.algorithms.set('SCRYPT', () => new ScryptWorker());
|
|
297
|
+
```
|
|
298
|
+
|
|
231
299
|
## Cookies
|
|
232
300
|
|
|
233
301
|
By default, the widget sends the ALTCHA payload as a form field by creating a hidden input. It can also be configured to send the payload via a cookie.
|
package/dist/external/altcha.js
CHANGED
|
@@ -5363,7 +5363,7 @@ function Code($$anchor, $$props) {
|
|
|
5363
5363
|
button.disabled = get(audioState) === AudioState.LOADING || get(audioState) === AudioState.ERROR;
|
|
5364
5364
|
set_attribute(button, "aria-label", get(audioState) === AudioState.LOADING ? strings().loading : strings().getAudioChallenge);
|
|
5365
5365
|
});
|
|
5366
|
-
|
|
5366
|
+
event("click", button, () => onPlayAudio(), true);
|
|
5367
5367
|
append($$anchor2, button);
|
|
5368
5368
|
};
|
|
5369
5369
|
if_block(node_1, ($$render) => {
|
|
@@ -5418,12 +5418,12 @@ function Code($$anchor, $$props) {
|
|
|
5418
5418
|
event("submit", form, onSubmitCapture, true);
|
|
5419
5419
|
delegated("keydown", input, onInputKeyDown);
|
|
5420
5420
|
bind_value(input, () => get(code), ($$value) => set(code, $$value));
|
|
5421
|
-
|
|
5422
|
-
|
|
5421
|
+
event("click", button_1, () => onReload()?.(), true);
|
|
5422
|
+
event("click", button_3, () => onCancel()?.(), true);
|
|
5423
5423
|
append($$anchor, div);
|
|
5424
5424
|
return pop($$exports);
|
|
5425
5425
|
}
|
|
5426
|
-
delegate(["keydown"
|
|
5426
|
+
delegate(["keydown"]);
|
|
5427
5427
|
create_custom_element(
|
|
5428
5428
|
Code,
|
|
5429
5429
|
{
|
|
@@ -5446,7 +5446,7 @@ var root_3$1 = /* @__PURE__ */ from_html(`<div role="button" class="altcha-popov
|
|
|
5446
5446
|
var root$1 = /* @__PURE__ */ from_html(`<!> <div><!> <!> <div class="altcha-popover-content"><!></div></div>`, 1);
|
|
5447
5447
|
function Popover($$anchor, $$props) {
|
|
5448
5448
|
push($$props, true);
|
|
5449
|
-
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, [
|
|
5449
|
+
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"), updateUISignal = prop($$props, "updateUISignal"), variant = prop($$props, "variant", 7, "neutral"), rest = /* @__PURE__ */ rest_props($$props, [
|
|
5450
5450
|
"$$slots",
|
|
5451
5451
|
"$$events",
|
|
5452
5452
|
"$$legacy",
|
|
@@ -5459,6 +5459,7 @@ function Popover($$anchor, $$props) {
|
|
|
5459
5459
|
"onClickOutsideDelay",
|
|
5460
5460
|
"onClose",
|
|
5461
5461
|
"placement",
|
|
5462
|
+
"updateUISignal",
|
|
5462
5463
|
"variant"
|
|
5463
5464
|
]);
|
|
5464
5465
|
let el = /* @__PURE__ */ state(void 0);
|
|
@@ -5470,6 +5471,11 @@ function Popover($$anchor, $$props) {
|
|
|
5470
5471
|
set(top, placement() === "top");
|
|
5471
5472
|
}
|
|
5472
5473
|
});
|
|
5474
|
+
user_effect(() => {
|
|
5475
|
+
if (updateUISignal()) {
|
|
5476
|
+
reposition();
|
|
5477
|
+
}
|
|
5478
|
+
});
|
|
5473
5479
|
onMount(() => {
|
|
5474
5480
|
const moveToBody = display() === "bottomsheet" || display() === "overlay";
|
|
5475
5481
|
if (moveToBody) {
|
|
@@ -5492,7 +5498,7 @@ function Popover($$anchor, $$props) {
|
|
|
5492
5498
|
}
|
|
5493
5499
|
function onWindowClick(ev) {
|
|
5494
5500
|
const target = ev.target;
|
|
5495
|
-
if (!get(el)?.contains(target) &&
|
|
5501
|
+
if (!get(el)?.contains(target) && (!onClickOutsideDelay() || get(mountedAt) + onClickOutsideDelay() < Date.now())) {
|
|
5496
5502
|
onClickOutside()?.();
|
|
5497
5503
|
}
|
|
5498
5504
|
}
|
|
@@ -5569,6 +5575,13 @@ function Popover($$anchor, $$props) {
|
|
|
5569
5575
|
placement($$value);
|
|
5570
5576
|
flushSync();
|
|
5571
5577
|
},
|
|
5578
|
+
get updateUISignal() {
|
|
5579
|
+
return updateUISignal();
|
|
5580
|
+
},
|
|
5581
|
+
set updateUISignal($$value) {
|
|
5582
|
+
updateUISignal($$value);
|
|
5583
|
+
flushSync();
|
|
5584
|
+
},
|
|
5572
5585
|
get variant() {
|
|
5573
5586
|
return variant();
|
|
5574
5587
|
},
|
|
@@ -5578,7 +5591,7 @@ function Popover($$anchor, $$props) {
|
|
|
5578
5591
|
}
|
|
5579
5592
|
};
|
|
5580
5593
|
var fragment = root$1();
|
|
5581
|
-
event("click", $window, onWindowClick);
|
|
5594
|
+
event("click", $window, onWindowClick, true);
|
|
5582
5595
|
event("resize", $window, onWindowResize);
|
|
5583
5596
|
event("scroll", $window, onWindowScroll);
|
|
5584
5597
|
var node = first_child(fragment);
|
|
@@ -5615,7 +5628,7 @@ function Popover($$anchor, $$props) {
|
|
|
5615
5628
|
{
|
|
5616
5629
|
var consequent_2 = ($$anchor2) => {
|
|
5617
5630
|
var div_3 = root_3$1();
|
|
5618
|
-
|
|
5631
|
+
event("click", div_3, onCloseClick, true);
|
|
5619
5632
|
append($$anchor2, div_3);
|
|
5620
5633
|
};
|
|
5621
5634
|
if_block(node_2, ($$render) => {
|
|
@@ -5631,7 +5644,6 @@ function Popover($$anchor, $$props) {
|
|
|
5631
5644
|
append($$anchor, fragment);
|
|
5632
5645
|
return pop($$exports);
|
|
5633
5646
|
}
|
|
5634
|
-
delegate(["click"]);
|
|
5635
5647
|
create_custom_element(
|
|
5636
5648
|
Popover,
|
|
5637
5649
|
{
|
|
@@ -5643,6 +5655,7 @@ create_custom_element(
|
|
|
5643
5655
|
onClickOutsideDelay: {},
|
|
5644
5656
|
onClose: {},
|
|
5645
5657
|
placement: {},
|
|
5658
|
+
updateUISignal: {},
|
|
5646
5659
|
variant: {}
|
|
5647
5660
|
},
|
|
5648
5661
|
[],
|
|
@@ -5909,6 +5922,7 @@ function Widget($$anchor, $$props) {
|
|
|
5909
5922
|
let checked = /* @__PURE__ */ state(false);
|
|
5910
5923
|
let codeChallenge = /* @__PURE__ */ state(null);
|
|
5911
5924
|
let currentController = /* @__PURE__ */ state(null);
|
|
5925
|
+
let currentDisplay = /* @__PURE__ */ state(null);
|
|
5912
5926
|
let currentState = /* @__PURE__ */ state(proxy(State.UNVERIFIED));
|
|
5913
5927
|
let elAnchorArrow = /* @__PURE__ */ state(void 0);
|
|
5914
5928
|
let elFloatingAnchor = /* @__PURE__ */ state(void 0);
|
|
@@ -5919,6 +5933,7 @@ function Widget($$anchor, $$props) {
|
|
|
5919
5933
|
let expirationTimeout = /* @__PURE__ */ state(null);
|
|
5920
5934
|
let payload = /* @__PURE__ */ state(null);
|
|
5921
5935
|
let plugins = /* @__PURE__ */ state(proxy([]));
|
|
5936
|
+
let updateUISignal = /* @__PURE__ */ state(0);
|
|
5922
5937
|
let userConfig = /* @__PURE__ */ state(proxy({}));
|
|
5923
5938
|
let visible = /* @__PURE__ */ state(true);
|
|
5924
5939
|
const config = /* @__PURE__ */ user_derived(() => ({
|
|
@@ -5998,7 +6013,9 @@ function Widget($$anchor, $$props) {
|
|
|
5998
6013
|
}
|
|
5999
6014
|
});
|
|
6000
6015
|
user_effect(() => {
|
|
6001
|
-
|
|
6016
|
+
if (get(currentDisplay) !== get(config).display) {
|
|
6017
|
+
setDisplay(get(config).display);
|
|
6018
|
+
}
|
|
6002
6019
|
});
|
|
6003
6020
|
user_effect(() => {
|
|
6004
6021
|
if (get(checked) && get(currentState) === State.VERIFYING) {
|
|
@@ -6049,7 +6066,7 @@ function Widget($$anchor, $$props) {
|
|
|
6049
6066
|
}
|
|
6050
6067
|
});
|
|
6051
6068
|
onMount(() => {
|
|
6052
|
-
log("mounted", "3.0.
|
|
6069
|
+
log("mounted", "3.0.5");
|
|
6053
6070
|
if (instance) {
|
|
6054
6071
|
globalThis.$altcha.instances.add(instance);
|
|
6055
6072
|
}
|
|
@@ -6343,6 +6360,7 @@ function Widget($$anchor, $$props) {
|
|
|
6343
6360
|
}
|
|
6344
6361
|
}
|
|
6345
6362
|
function onWindowPageshow() {
|
|
6363
|
+
setDisplay(get(config).display);
|
|
6346
6364
|
reset$1();
|
|
6347
6365
|
}
|
|
6348
6366
|
function onWindowResize() {
|
|
@@ -6463,6 +6481,9 @@ function Widget($$anchor, $$props) {
|
|
|
6463
6481
|
case "standard":
|
|
6464
6482
|
show();
|
|
6465
6483
|
}
|
|
6484
|
+
if (get(currentDisplay) !== value) {
|
|
6485
|
+
set(currentDisplay, value, true);
|
|
6486
|
+
}
|
|
6466
6487
|
}
|
|
6467
6488
|
function setChallengeExpiration(expiresAt) {
|
|
6468
6489
|
if (get(expirationTimeout)) {
|
|
@@ -6583,6 +6604,7 @@ function Widget($$anchor, $$props) {
|
|
|
6583
6604
|
case "floating":
|
|
6584
6605
|
return repositionFloating();
|
|
6585
6606
|
}
|
|
6607
|
+
set(updateUISignal, get(updateUISignal) + 1);
|
|
6586
6608
|
}
|
|
6587
6609
|
async function verify(options = {}) {
|
|
6588
6610
|
const {
|
|
@@ -6613,7 +6635,7 @@ function Widget($$anchor, $$props) {
|
|
|
6613
6635
|
set(payload, btoa(JSON.stringify({ challenge: null, solution: null, test: true })), true);
|
|
6614
6636
|
log("verified");
|
|
6615
6637
|
setState(State.VERIFIED);
|
|
6616
|
-
dispatch("
|
|
6638
|
+
dispatch("verified", { payload: get(payload) });
|
|
6617
6639
|
return { payload: get(payload) };
|
|
6618
6640
|
}
|
|
6619
6641
|
challenge = await fetchChallenge();
|
|
@@ -6684,7 +6706,7 @@ function Widget($$anchor, $$props) {
|
|
|
6684
6706
|
} else {
|
|
6685
6707
|
log("verified");
|
|
6686
6708
|
setState(State.VERIFIED);
|
|
6687
|
-
dispatch("
|
|
6709
|
+
dispatch("verified", { payload: get(payload) });
|
|
6688
6710
|
}
|
|
6689
6711
|
} catch (err) {
|
|
6690
6712
|
log("verification failed", err);
|
|
@@ -6740,7 +6762,7 @@ function Widget($$anchor, $$props) {
|
|
|
6740
6762
|
if (get(config).overlayContent) $$render(consequent_1);
|
|
6741
6763
|
});
|
|
6742
6764
|
}
|
|
6743
|
-
|
|
6765
|
+
event("click", div_2, onCloseClick, true);
|
|
6744
6766
|
append($$anchor2, fragment_1);
|
|
6745
6767
|
};
|
|
6746
6768
|
if_block(node_1, ($$render) => {
|
|
@@ -6885,6 +6907,9 @@ function Widget($$anchor, $$props) {
|
|
|
6885
6907
|
get dir() {
|
|
6886
6908
|
return get(dir);
|
|
6887
6909
|
},
|
|
6910
|
+
get updateUISignal() {
|
|
6911
|
+
return get(updateUISignal);
|
|
6912
|
+
},
|
|
6888
6913
|
children: ($$anchor3, $$slotProps) => {
|
|
6889
6914
|
var fragment_9 = comment();
|
|
6890
6915
|
var node_10 = first_child(fragment_9);
|
|
@@ -6950,6 +6975,9 @@ function Widget($$anchor, $$props) {
|
|
|
6950
6975
|
get dir() {
|
|
6951
6976
|
return get(dir);
|
|
6952
6977
|
},
|
|
6978
|
+
get updateUISignal() {
|
|
6979
|
+
return get(updateUISignal);
|
|
6980
|
+
},
|
|
6953
6981
|
children: ($$anchor4, $$slotProps) => {
|
|
6954
6982
|
var fragment_12 = root_19();
|
|
6955
6983
|
var node_12 = first_child(fragment_12);
|
|
@@ -7021,7 +7049,6 @@ function Widget($$anchor, $$props) {
|
|
|
7021
7049
|
$$cleanup();
|
|
7022
7050
|
return $$pop;
|
|
7023
7051
|
}
|
|
7024
|
-
delegate(["click"]);
|
|
7025
7052
|
if (typeof window !== "undefined" && window.customElements) customElements.define("altcha-widget", create_custom_element(
|
|
7026
7053
|
Widget,
|
|
7027
7054
|
{
|