altcha 1.4.2 → 2.0.0-beta.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/README.md +144 -156
- package/dist/altcha.d.ts +6 -0
- package/dist/altcha.js +1683 -1383
- package/dist/altcha.umd.cjs +10 -7
- package/dist_external/altcha.css +127 -13
- package/dist_external/altcha.d.ts +6 -0
- package/dist_external/altcha.js +1667 -1367
- package/dist_external/altcha.umd.cjs +9 -6
- package/dist_i18n/all.js +810 -0
- package/dist_i18n/all.umd.cjs +1 -0
- package/dist_i18n/americas.js +54 -0
- package/dist_i18n/americas.umd.cjs +1 -0
- package/dist_i18n/ar.js +21 -0
- package/dist_i18n/ar.umd.cjs +1 -0
- package/dist_i18n/asia.js +288 -0
- package/dist_i18n/asia.umd.cjs +1 -0
- package/dist_i18n/bg.js +21 -0
- package/dist_i18n/bg.umd.cjs +1 -0
- package/dist_i18n/bn.js +21 -0
- package/dist_i18n/bn.umd.cjs +1 -0
- package/dist_i18n/cs.js +21 -0
- package/dist_i18n/cs.umd.cjs +1 -0
- package/dist_i18n/da.js +21 -0
- package/dist_i18n/da.umd.cjs +1 -0
- package/dist_i18n/de.js +21 -0
- package/dist_i18n/de.umd.cjs +1 -0
- package/dist_i18n/el.js +21 -0
- package/dist_i18n/el.umd.cjs +1 -0
- package/dist_i18n/en.js +21 -0
- package/dist_i18n/en.umd.cjs +1 -0
- package/dist_i18n/es-419.js +21 -0
- package/dist_i18n/es-419.umd.cjs +1 -0
- package/dist_i18n/es-es.js +21 -0
- package/dist_i18n/es-es.umd.cjs +1 -0
- package/dist_i18n/et.js +21 -0
- package/dist_i18n/et.umd.cjs +1 -0
- package/dist_i18n/eu.js +21 -0
- package/dist_i18n/eu.umd.cjs +1 -0
- package/dist_i18n/europe.js +468 -0
- package/dist_i18n/europe.umd.cjs +1 -0
- package/dist_i18n/fi.js +21 -0
- package/dist_i18n/fi.umd.cjs +1 -0
- package/dist_i18n/fr-ca.js +21 -0
- package/dist_i18n/fr-ca.umd.cjs +1 -0
- package/dist_i18n/fr-fr.js +21 -0
- package/dist_i18n/fr-fr.umd.cjs +1 -0
- package/dist_i18n/ga.js +21 -0
- package/dist_i18n/ga.umd.cjs +1 -0
- package/dist_i18n/he.js +21 -0
- package/dist_i18n/he.umd.cjs +1 -0
- package/dist_i18n/hi.js +21 -0
- package/dist_i18n/hi.umd.cjs +1 -0
- package/dist_i18n/hr.js +21 -0
- package/dist_i18n/hr.umd.cjs +1 -0
- package/dist_i18n/hu.js +21 -0
- package/dist_i18n/hu.umd.cjs +1 -0
- package/dist_i18n/id.js +21 -0
- package/dist_i18n/id.umd.cjs +1 -0
- package/dist_i18n/it.js +21 -0
- package/dist_i18n/it.umd.cjs +1 -0
- package/dist_i18n/ja.js +21 -0
- package/dist_i18n/ja.umd.cjs +1 -0
- package/dist_i18n/ko.js +21 -0
- package/dist_i18n/ko.umd.cjs +1 -0
- package/dist_i18n/lt.js +21 -0
- package/dist_i18n/lt.umd.cjs +1 -0
- package/dist_i18n/lv.js +21 -0
- package/dist_i18n/lv.umd.cjs +1 -0
- package/dist_i18n/mr.js +21 -0
- package/dist_i18n/mr.umd.cjs +1 -0
- package/dist_i18n/mt.js +21 -0
- package/dist_i18n/mt.umd.cjs +1 -0
- package/dist_i18n/nl.js +21 -0
- package/dist_i18n/nl.umd.cjs +1 -0
- package/dist_i18n/pl.js +21 -0
- package/dist_i18n/pl.umd.cjs +1 -0
- package/dist_i18n/pt-br.js +21 -0
- package/dist_i18n/pt-br.umd.cjs +1 -0
- package/dist_i18n/pt-pt.js +21 -0
- package/dist_i18n/pt-pt.umd.cjs +1 -0
- package/dist_i18n/ro.js +21 -0
- package/dist_i18n/ro.umd.cjs +1 -0
- package/dist_i18n/ru.js +21 -0
- package/dist_i18n/ru.umd.cjs +1 -0
- package/dist_i18n/sk.js +21 -0
- package/dist_i18n/sk.umd.cjs +1 -0
- package/dist_i18n/sl.js +21 -0
- package/dist_i18n/sl.umd.cjs +1 -0
- package/dist_i18n/sv.js +21 -0
- package/dist_i18n/sv.umd.cjs +1 -0
- package/dist_i18n/ta.js +21 -0
- package/dist_i18n/ta.umd.cjs +1 -0
- package/dist_i18n/te.js +21 -0
- package/dist_i18n/te.umd.cjs +1 -0
- package/dist_i18n/th.js +21 -0
- package/dist_i18n/th.umd.cjs +1 -0
- package/dist_i18n/tr.js +21 -0
- package/dist_i18n/tr.umd.cjs +1 -0
- package/dist_i18n/uk.js +21 -0
- package/dist_i18n/uk.umd.cjs +1 -0
- package/dist_i18n/ur.js +21 -0
- package/dist_i18n/ur.umd.cjs +1 -0
- package/dist_i18n/vi.js +21 -0
- package/dist_i18n/vi.umd.cjs +1 -0
- package/dist_i18n/zh-cn.js +21 -0
- package/dist_i18n/zh-cn.umd.cjs +1 -0
- package/dist_i18n/zh-tw.js +21 -0
- package/dist_i18n/zh-tw.umd.cjs +1 -0
- package/dist_plugins/obfuscation.js +10 -10
- package/dist_plugins/obfuscation.umd.cjs +1 -1
- package/dist_plugins/upload.js +145 -133
- package/dist_plugins/upload.umd.cjs +4 -4
- package/package.json +12 -8
- package/postinstall.js +0 -10
package/dist_plugins/upload.js
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
1
|
+
var J = Object.defineProperty;
|
|
2
|
+
var v = (t) => {
|
|
3
3
|
throw TypeError(t);
|
|
4
4
|
};
|
|
5
|
-
var
|
|
6
|
-
var p = (t, n, e) =>
|
|
7
|
-
var
|
|
8
|
-
var u = (t, n, e) => (
|
|
9
|
-
const
|
|
10
|
-
generateKey:
|
|
11
|
-
exportKey:
|
|
12
|
-
importKey:
|
|
13
|
-
decrypt:
|
|
14
|
-
encrypt:
|
|
5
|
+
var X = (t, n, e) => n in t ? J(t, n, { enumerable: !0, configurable: !0, writable: !0, value: e }) : t[n] = e;
|
|
6
|
+
var p = (t, n, e) => X(t, typeof n != "symbol" ? n + "" : n, e), S = (t, n, e) => n.has(t) || v("Cannot " + e);
|
|
7
|
+
var f = (t, n, e) => (S(t, n, "read from private field"), e ? e.call(t) : n.get(t)), w = (t, n, e) => n.has(t) ? v("Cannot add the same private member more than once") : n instanceof WeakSet ? n.add(t) : n.set(t, e);
|
|
8
|
+
var u = (t, n, e) => (S(t, n, "access private method"), e);
|
|
9
|
+
const E = {
|
|
10
|
+
generateKey: Q,
|
|
11
|
+
exportKey: W,
|
|
12
|
+
importKey: Z,
|
|
13
|
+
decrypt: te,
|
|
14
|
+
encrypt: ee
|
|
15
15
|
};
|
|
16
|
-
async function
|
|
16
|
+
async function Q(t = 256) {
|
|
17
17
|
return crypto.subtle.generateKey({
|
|
18
18
|
name: "AES-GCM",
|
|
19
19
|
length: t
|
|
20
20
|
}, !0, ["encrypt", "decrypt"]);
|
|
21
21
|
}
|
|
22
|
-
async function
|
|
22
|
+
async function W(t) {
|
|
23
23
|
return new Uint8Array(await crypto.subtle.exportKey("raw", t));
|
|
24
24
|
}
|
|
25
|
-
async function
|
|
25
|
+
async function Z(t) {
|
|
26
26
|
return crypto.subtle.importKey("raw", t, {
|
|
27
27
|
name: "AES-GCM"
|
|
28
28
|
}, !0, ["encrypt", "decrypt"]);
|
|
29
29
|
}
|
|
30
|
-
async function
|
|
30
|
+
async function ee(t, n, e = 16) {
|
|
31
31
|
const i = crypto.getRandomValues(new Uint8Array(e));
|
|
32
32
|
return {
|
|
33
33
|
encrypted: new Uint8Array(await crypto.subtle.encrypt({
|
|
@@ -37,115 +37,115 @@ async function Z(t, n, e = 16) {
|
|
|
37
37
|
iv: i
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
|
-
async function
|
|
40
|
+
async function te(t, n, e) {
|
|
41
41
|
return new Uint8Array(await crypto.subtle.decrypt({
|
|
42
42
|
name: "AES-GCM",
|
|
43
43
|
iv: e
|
|
44
44
|
}, t, n));
|
|
45
45
|
}
|
|
46
|
-
function
|
|
46
|
+
function ne(t, n = !1) {
|
|
47
47
|
return n && (t = t.replace(/_/g, "/").replace(/-/g, "+") + "=".repeat(3 - (3 + t.length) % 4)), Uint8Array.from(atob(t), (e) => e.charCodeAt(0));
|
|
48
48
|
}
|
|
49
|
-
function
|
|
49
|
+
function x(t, n = !1) {
|
|
50
50
|
const e = btoa(String.fromCharCode(...t));
|
|
51
51
|
return n ? e.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "") : e;
|
|
52
52
|
}
|
|
53
|
-
function
|
|
53
|
+
function L(t, n = 80) {
|
|
54
54
|
let e = "";
|
|
55
55
|
for (; t.length > 0; )
|
|
56
56
|
e += t.slice(0, n) + `
|
|
57
57
|
`, t = t.slice(n);
|
|
58
58
|
return e;
|
|
59
59
|
}
|
|
60
|
-
function
|
|
61
|
-
return
|
|
60
|
+
function C(t) {
|
|
61
|
+
return ne(t.split(/\r?\n/).filter((n) => !n.startsWith("-----")).join(""));
|
|
62
62
|
}
|
|
63
|
-
const
|
|
64
|
-
generateKeyPair:
|
|
65
|
-
encrypt:
|
|
66
|
-
decrypt:
|
|
67
|
-
exportPrivateKey:
|
|
68
|
-
exportPrivateKeyPem:
|
|
69
|
-
exportPublicKey:
|
|
70
|
-
exportPublicKeyPem:
|
|
71
|
-
exportPublicKeyFromPrivateKey:
|
|
72
|
-
importPrivateKey:
|
|
73
|
-
importPrivateKeyPem:
|
|
74
|
-
importPublicKey:
|
|
75
|
-
importPublicKeyPem:
|
|
63
|
+
const h = "RSA-OAEP", b = "SHA-256", re = 2048, ie = new Uint8Array([1, 0, 1]), se = {
|
|
64
|
+
generateKeyPair: oe,
|
|
65
|
+
encrypt: ae,
|
|
66
|
+
decrypt: ce,
|
|
67
|
+
exportPrivateKey: I,
|
|
68
|
+
exportPrivateKeyPem: pe,
|
|
69
|
+
exportPublicKey: F,
|
|
70
|
+
exportPublicKeyPem: le,
|
|
71
|
+
exportPublicKeyFromPrivateKey: de,
|
|
72
|
+
importPrivateKey: T,
|
|
73
|
+
importPrivateKeyPem: ue,
|
|
74
|
+
importPublicKey: N,
|
|
75
|
+
importPublicKeyPem: z
|
|
76
76
|
};
|
|
77
|
-
async function
|
|
77
|
+
async function oe() {
|
|
78
78
|
return crypto.subtle.generateKey({
|
|
79
|
-
name:
|
|
80
|
-
modulusLength:
|
|
81
|
-
publicExponent:
|
|
82
|
-
hash:
|
|
79
|
+
name: h,
|
|
80
|
+
modulusLength: re,
|
|
81
|
+
publicExponent: ie,
|
|
82
|
+
hash: b
|
|
83
83
|
}, !0, ["encrypt", "decrypt"]);
|
|
84
84
|
}
|
|
85
|
-
async function
|
|
85
|
+
async function ae(t, n) {
|
|
86
86
|
return new Uint8Array(await crypto.subtle.encrypt({
|
|
87
|
-
name:
|
|
87
|
+
name: h
|
|
88
88
|
}, t, n));
|
|
89
89
|
}
|
|
90
|
-
async function
|
|
90
|
+
async function ce(t, n) {
|
|
91
91
|
return new Uint8Array(await crypto.subtle.decrypt({
|
|
92
|
-
name:
|
|
92
|
+
name: h
|
|
93
93
|
}, t, n));
|
|
94
94
|
}
|
|
95
|
-
async function
|
|
95
|
+
async function F(t) {
|
|
96
96
|
return new Uint8Array(await crypto.subtle.exportKey("spki", t));
|
|
97
97
|
}
|
|
98
|
-
async function
|
|
98
|
+
async function I(t) {
|
|
99
99
|
return new Uint8Array(await crypto.subtle.exportKey("pkcs8", t));
|
|
100
100
|
}
|
|
101
|
-
async function
|
|
101
|
+
async function le(t) {
|
|
102
102
|
return `-----BEGIN PUBLIC KEY-----
|
|
103
|
-
` + x(
|
|
103
|
+
` + L(x(await F(t)), 64) + "-----END PUBLIC KEY-----";
|
|
104
104
|
}
|
|
105
|
-
async function
|
|
105
|
+
async function pe(t) {
|
|
106
106
|
return `-----BEGIN PRIVATE KEY-----
|
|
107
|
-
` + x(
|
|
107
|
+
` + L(x(await I(t)), 64) + "-----END PRIVATE KEY-----";
|
|
108
108
|
}
|
|
109
|
-
async function
|
|
109
|
+
async function N(t) {
|
|
110
110
|
return crypto.subtle.importKey("spki", t, {
|
|
111
|
-
name:
|
|
112
|
-
hash:
|
|
111
|
+
name: h,
|
|
112
|
+
hash: b
|
|
113
113
|
}, !0, ["encrypt"]);
|
|
114
114
|
}
|
|
115
|
-
async function N(t) {
|
|
116
|
-
return I(L(t));
|
|
117
|
-
}
|
|
118
115
|
async function z(t) {
|
|
116
|
+
return N(C(t));
|
|
117
|
+
}
|
|
118
|
+
async function T(t) {
|
|
119
119
|
return crypto.subtle.importKey("pkcs8", t, {
|
|
120
|
-
name:
|
|
121
|
-
hash:
|
|
120
|
+
name: h,
|
|
121
|
+
hash: b
|
|
122
122
|
}, !0, ["decrypt"]);
|
|
123
123
|
}
|
|
124
|
-
async function pe(t) {
|
|
125
|
-
return z(L(t));
|
|
126
|
-
}
|
|
127
124
|
async function ue(t) {
|
|
125
|
+
return T(C(t));
|
|
126
|
+
}
|
|
127
|
+
async function de(t) {
|
|
128
128
|
const n = await crypto.subtle.exportKey("jwk", t);
|
|
129
129
|
delete n.d, delete n.dp, delete n.dq, delete n.q, delete n.qi, n.key_ops = ["encrypt"];
|
|
130
130
|
const e = await crypto.subtle.importKey("jwk", n, {
|
|
131
|
-
name:
|
|
132
|
-
hash:
|
|
131
|
+
name: h,
|
|
132
|
+
hash: b
|
|
133
133
|
}, !0, ["encrypt"]);
|
|
134
|
-
return
|
|
134
|
+
return F(e);
|
|
135
135
|
}
|
|
136
|
-
const ye = new Uint8Array([1, 0, 1]),
|
|
137
|
-
async function
|
|
138
|
-
const { aesIVLength: i =
|
|
136
|
+
const ye = new Uint8Array([1, 0, 1]), he = 256, fe = 16;
|
|
137
|
+
async function me(t, n, e = {}) {
|
|
138
|
+
const { aesIVLength: i = fe, aesKeyLength: r = he } = e, o = await E.generateKey(r), { encrypted: a, iv: s } = await E.encrypt(o, n, i), l = await se.encrypt(t, await E.exportKey(o));
|
|
139
139
|
return new Uint8Array([
|
|
140
140
|
...ye,
|
|
141
141
|
...new Uint8Array([l.length]),
|
|
142
142
|
...new Uint8Array([s.length]),
|
|
143
143
|
...l,
|
|
144
144
|
...s,
|
|
145
|
-
...
|
|
145
|
+
...a
|
|
146
146
|
]);
|
|
147
147
|
}
|
|
148
|
-
class
|
|
148
|
+
class P {
|
|
149
149
|
/**
|
|
150
150
|
* Constructs a new instance of the Plugin.
|
|
151
151
|
*
|
|
@@ -189,9 +189,9 @@ class A {
|
|
|
189
189
|
/**
|
|
190
190
|
* A distinct name of the plugin. Every plugin must have it's own name.
|
|
191
191
|
*/
|
|
192
|
-
p(
|
|
193
|
-
var
|
|
194
|
-
class
|
|
192
|
+
p(P, "pluginName");
|
|
193
|
+
var m, g, c, R, j, k, U, H, q, O, A, $, B, G;
|
|
194
|
+
class _ extends P {
|
|
195
195
|
/**
|
|
196
196
|
* Constructor initializes the plugin, setting up event listeners on the form.
|
|
197
197
|
*
|
|
@@ -199,13 +199,13 @@ class T extends A {
|
|
|
199
199
|
*/
|
|
200
200
|
constructor(e) {
|
|
201
201
|
super(e);
|
|
202
|
-
|
|
202
|
+
w(this, c);
|
|
203
203
|
p(this, "pendingFiles", []);
|
|
204
204
|
p(this, "uploadHandles", []);
|
|
205
205
|
p(this, "elForm");
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
this.elForm = this.context.el.closest("form"), this.elForm && (this.elForm.addEventListener("change",
|
|
206
|
+
w(this, m, u(this, c, q).bind(this));
|
|
207
|
+
w(this, g, u(this, c, O).bind(this));
|
|
208
|
+
this.elForm = this.context.el.closest("form"), this.elForm && (this.elForm.addEventListener("change", f(this, m)), this.elForm.addEventListener("submit", f(this, g), {
|
|
209
209
|
capture: !0
|
|
210
210
|
}));
|
|
211
211
|
}
|
|
@@ -222,7 +222,7 @@ class T extends A {
|
|
|
222
222
|
* Cleans up event listeners and other resources when the plugin is destroyed.
|
|
223
223
|
*/
|
|
224
224
|
destroy() {
|
|
225
|
-
this.elForm && (this.elForm.removeEventListener("change",
|
|
225
|
+
this.elForm && (this.elForm.removeEventListener("change", f(this, m)), this.elForm.removeEventListener("submit", f(this, g)));
|
|
226
226
|
}
|
|
227
227
|
/**
|
|
228
228
|
* Uploads all pending files in the list.
|
|
@@ -231,24 +231,31 @@ class T extends A {
|
|
|
231
231
|
var i;
|
|
232
232
|
const e = async () => {
|
|
233
233
|
const r = this.pendingFiles[0];
|
|
234
|
-
if (r && await u(this,
|
|
234
|
+
if (r && await u(this, c, A).call(this, u(this, c, j).call(this, r)), this.pendingFiles.length)
|
|
235
235
|
return e();
|
|
236
236
|
};
|
|
237
|
-
|
|
237
|
+
try {
|
|
238
|
+
await e();
|
|
239
|
+
} catch (r) {
|
|
240
|
+
return this.context.log("upload failed", r), this.context.dispatch("uploaderror", {
|
|
241
|
+
error: r
|
|
242
|
+
}), !1;
|
|
243
|
+
}
|
|
244
|
+
this.pendingFiles.length === 0 && (u(this, c, R).call(this), (i = this.elForm) == null || i.requestSubmit());
|
|
238
245
|
}
|
|
239
246
|
}
|
|
240
|
-
|
|
247
|
+
m = new WeakMap(), g = new WeakMap(), c = new WeakSet(), /**
|
|
241
248
|
* Adds hidden input fields to the form containing the file IDs of uploaded files.
|
|
242
249
|
*/
|
|
243
|
-
|
|
250
|
+
R = function() {
|
|
244
251
|
var i, r, o;
|
|
245
252
|
const e = this.uploadHandles.reduce(
|
|
246
|
-
(
|
|
253
|
+
(a, s) => (a[s.fieldName] || (a[s.fieldName] = []), s.fileId && a[s.fieldName].push(s.fileId), a),
|
|
247
254
|
{}
|
|
248
255
|
);
|
|
249
|
-
for (const
|
|
256
|
+
for (const a in e) {
|
|
250
257
|
const s = document.createElement("input");
|
|
251
|
-
s.name =
|
|
258
|
+
s.name = a, s.type = "hidden", s.value = e[a].join(","), (r = (i = this.elForm) == null ? void 0 : i.querySelector(`[name="${a}"]`)) == null || r.setAttribute("disabled", "disabled"), (o = this.elForm) == null || o.appendChild(s);
|
|
252
259
|
}
|
|
253
260
|
}, /**
|
|
254
261
|
* Creates an upload handle for the specified pending file.
|
|
@@ -259,12 +266,12 @@ _ = function() {
|
|
|
259
266
|
*/
|
|
260
267
|
j = function(e) {
|
|
261
268
|
const i = this.pendingFiles.findIndex(
|
|
262
|
-
([o,
|
|
269
|
+
([o, a]) => o === e[0] && a === e[1]
|
|
263
270
|
);
|
|
264
271
|
if (i < 0)
|
|
265
272
|
throw new Error("Cannot create upload handle.");
|
|
266
|
-
const r = new
|
|
267
|
-
return this.uploadHandles.push(r), this.pendingFiles.splice(i, 1), u(this,
|
|
273
|
+
const r = new ge(e[0], e[1]);
|
|
274
|
+
return this.uploadHandles.push(r), this.pendingFiles.splice(i, 1), u(this, c, k).call(this, r), u(this, c, U).call(this), r;
|
|
268
275
|
}, /**
|
|
269
276
|
* Dispatches a custom event when a file upload starts.
|
|
270
277
|
*
|
|
@@ -275,8 +282,8 @@ k = function(e) {
|
|
|
275
282
|
}, /**
|
|
276
283
|
* Dispatches a custom event to track the progress of ongoing file uploads.
|
|
277
284
|
*/
|
|
278
|
-
|
|
279
|
-
const e = this.pendingFiles.reduce((r, [o,
|
|
285
|
+
U = function() {
|
|
286
|
+
const e = this.pendingFiles.reduce((r, [o, a]) => r + a.size, 0) + this.uploadHandles.reduce((r, { uploadSize: o }) => r + o, 0), i = this.uploadHandles.reduce(
|
|
280
287
|
(r, { loaded: o }) => r + o,
|
|
281
288
|
0
|
|
282
289
|
);
|
|
@@ -293,8 +300,11 @@ E = function() {
|
|
|
293
300
|
*/
|
|
294
301
|
H = function() {
|
|
295
302
|
if (this.elForm) {
|
|
296
|
-
const e = this.elForm.getAttribute("action");
|
|
297
|
-
|
|
303
|
+
const e = this.elForm.getAttribute("action"), i = this.elForm.getAttribute("data-upload-url");
|
|
304
|
+
if (i)
|
|
305
|
+
return i;
|
|
306
|
+
const r = new URL(e || location.origin);
|
|
307
|
+
return r.pathname = r.pathname + "/file", r.toString();
|
|
298
308
|
}
|
|
299
309
|
return null;
|
|
300
310
|
}, /**
|
|
@@ -302,7 +312,7 @@ H = function() {
|
|
|
302
312
|
*
|
|
303
313
|
* @param {Event} ev - The change event.
|
|
304
314
|
*/
|
|
305
|
-
|
|
315
|
+
q = function(e) {
|
|
306
316
|
const i = e.target;
|
|
307
317
|
if (i && i.type === "file") {
|
|
308
318
|
const r = i.files;
|
|
@@ -315,17 +325,18 @@ R = function(e) {
|
|
|
315
325
|
*
|
|
316
326
|
* @param {SubmitEvent} ev - The submit event.
|
|
317
327
|
*/
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
328
|
+
O = function(e) {
|
|
329
|
+
const i = e.target;
|
|
330
|
+
i != null && i.hasAttribute("data-code-challenge-form") || this.pendingFiles.length && (e.preventDefault(), e.stopPropagation(), this.uploadPendingFiles());
|
|
331
|
+
}, A = async function(e, i) {
|
|
332
|
+
const r = u(this, c, H).call(this);
|
|
322
333
|
if (!r)
|
|
323
334
|
throw new Error("Upload url not specified.");
|
|
324
335
|
const o = {
|
|
325
336
|
"content-type": "application/json"
|
|
326
337
|
};
|
|
327
338
|
i && (o.authorization = "Altcha payload=" + i);
|
|
328
|
-
const
|
|
339
|
+
const a = await fetch(r, {
|
|
329
340
|
body: JSON.stringify({
|
|
330
341
|
name: e.file.name || "file",
|
|
331
342
|
size: e.file.size,
|
|
@@ -335,48 +346,48 @@ q = function(e) {
|
|
|
335
346
|
headers: o,
|
|
336
347
|
method: "POST"
|
|
337
348
|
});
|
|
338
|
-
if (
|
|
339
|
-
return u(this,
|
|
340
|
-
if (
|
|
341
|
-
throw new Error(`Unexpected server response ${
|
|
342
|
-
const s = await
|
|
349
|
+
if (a.status === 401)
|
|
350
|
+
return u(this, c, $).call(this, a, e);
|
|
351
|
+
if (a.status !== 200)
|
|
352
|
+
throw new Error(`Unexpected server response ${a.status}.`);
|
|
353
|
+
const s = await a.json();
|
|
343
354
|
let l = e.file;
|
|
344
355
|
if (s.encrypted && s.encryptionPublicKey) {
|
|
345
|
-
const
|
|
356
|
+
const d = await z(s.encryptionPublicKey), M = await new Response(
|
|
346
357
|
new ReadableStream({
|
|
347
|
-
async start(
|
|
348
|
-
const
|
|
358
|
+
async start(K) {
|
|
359
|
+
const Y = e.file.stream().getReader();
|
|
349
360
|
for (; ; ) {
|
|
350
|
-
const { done:
|
|
351
|
-
if (
|
|
361
|
+
const { done: D, value: V } = await Y.read();
|
|
362
|
+
if (D)
|
|
352
363
|
break;
|
|
353
|
-
|
|
364
|
+
K.enqueue(V);
|
|
354
365
|
}
|
|
355
|
-
|
|
366
|
+
K.close();
|
|
356
367
|
}
|
|
357
368
|
})
|
|
358
369
|
).arrayBuffer();
|
|
359
|
-
l = await
|
|
370
|
+
l = await me(d, new Uint8Array(M));
|
|
360
371
|
}
|
|
361
|
-
return e.uploadSize = l instanceof Uint8Array ? l.byteLength : e.file.size, await u(this,
|
|
372
|
+
return e.uploadSize = l instanceof Uint8Array ? l.byteLength : e.file.size, await u(this, c, G).call(this, s.uploadUrl, e, l, {
|
|
362
373
|
"content-type": e.file.type || "application/octet-stream"
|
|
363
|
-
}), s.finalizeUrl && await u(this,
|
|
374
|
+
}), s.finalizeUrl && await u(this, c, B).call(this, s.finalizeUrl, e.uploadSize), e.fileId = s.fileId, e.resolve({
|
|
364
375
|
encrypted: s.encrypted,
|
|
365
376
|
fileId: s.fileId
|
|
366
377
|
}), e.promise;
|
|
367
|
-
},
|
|
378
|
+
}, $ = async function(e, i) {
|
|
368
379
|
var r;
|
|
369
380
|
try {
|
|
370
|
-
const o = e.headers.get("www-authenticate"),
|
|
371
|
-
if (!
|
|
381
|
+
const o = e.headers.get("www-authenticate"), a = (r = o == null ? void 0 : o.match(/challenge=(.*),/)) == null ? void 0 : r[1];
|
|
382
|
+
if (!a)
|
|
372
383
|
throw new Error(
|
|
373
384
|
"Unable to retrieve altcha challenge from www-authenticate header."
|
|
374
385
|
);
|
|
375
|
-
const s = JSON.parse(
|
|
386
|
+
const s = JSON.parse(a);
|
|
376
387
|
if (s && "challenge" in s) {
|
|
377
388
|
const { solution: l } = await this.context.solve(s);
|
|
378
389
|
if (l && "number" in l)
|
|
379
|
-
return u(this,
|
|
390
|
+
return u(this, c, A).call(this, i, btoa(
|
|
380
391
|
JSON.stringify({
|
|
381
392
|
...s,
|
|
382
393
|
number: l.number
|
|
@@ -401,23 +412,24 @@ q = function(e) {
|
|
|
401
412
|
throw new Error(`Unexpected server response ${r.status}.`);
|
|
402
413
|
return !0;
|
|
403
414
|
}, G = async function(e, i, r, o = {}) {
|
|
404
|
-
|
|
405
|
-
|
|
415
|
+
var a;
|
|
416
|
+
return e = new URL(e, ((a = this.elForm) == null ? void 0 : a.getAttribute("action")) || location.origin).toString(), new Promise((s, l) => {
|
|
417
|
+
const d = new XMLHttpRequest();
|
|
406
418
|
i.controller.signal.addEventListener("abort", () => {
|
|
407
|
-
|
|
408
|
-
}),
|
|
409
|
-
i.setProgress(y.loaded), u(this,
|
|
410
|
-
}),
|
|
411
|
-
|
|
412
|
-
}),
|
|
413
|
-
|
|
414
|
-
}),
|
|
419
|
+
d.abort();
|
|
420
|
+
}), d.upload.addEventListener("progress", (y) => {
|
|
421
|
+
i.setProgress(y.loaded), u(this, c, U).call(this);
|
|
422
|
+
}), d.addEventListener("error", (y) => {
|
|
423
|
+
l(new Error("Upload failed."));
|
|
424
|
+
}), d.addEventListener("load", () => {
|
|
425
|
+
d.status >= 400 ? l(new Error(`Server responded with ${d.status}`)) : s(void 0);
|
|
426
|
+
}), d.open("PUT", e);
|
|
415
427
|
for (const y in o)
|
|
416
|
-
|
|
417
|
-
|
|
428
|
+
d.setRequestHeader(y, o[y]);
|
|
429
|
+
d.send(r);
|
|
418
430
|
});
|
|
419
|
-
}, p(
|
|
420
|
-
class
|
|
431
|
+
}, p(_, "pluginName", "upload");
|
|
432
|
+
class ge {
|
|
421
433
|
/**
|
|
422
434
|
* Creates an instance of UploadHandle.
|
|
423
435
|
*
|
|
@@ -452,7 +464,7 @@ class me {
|
|
|
452
464
|
this.loaded = n, this.progress = this.file.size && n ? Math.min(1, n / this.file.size) : 0;
|
|
453
465
|
}
|
|
454
466
|
}
|
|
455
|
-
|
|
467
|
+
P.register(_);
|
|
456
468
|
export {
|
|
457
|
-
|
|
469
|
+
_ as PluginUpload
|
|
458
470
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(c,a){typeof exports=="object"&&typeof module<"u"?a(exports):typeof define=="function"&&define.amd?define(["exports"],a):(c=typeof globalThis<"u"?globalThis:c||self,a(c["[name]"]={}))})(this,function(c){"use strict";var
|
|
2
|
-
`,t=t.slice(
|
|
3
|
-
`+x(
|
|
4
|
-
`+x(
|
|
1
|
+
(function(c,a){typeof exports=="object"&&typeof module<"u"?a(exports):typeof define=="function"&&define.amd?define(["exports"],a):(c=typeof globalThis<"u"?globalThis:c||self,a(c["[name]"]={}))})(this,function(c){"use strict";var ge=Object.defineProperty;var _=c=>{throw TypeError(c)};var we=(c,a,u)=>a in c?ge(c,a,{enumerable:!0,configurable:!0,writable:!0,value:u}):c[a]=u;var y=(c,a,u)=>we(c,typeof a!="symbol"?a+"":a,u),R=(c,a,u)=>a.has(c)||_("Cannot "+u);var E=(c,a,u)=>(R(c,a,"read from private field"),u?u.call(c):a.get(c)),P=(c,a,u)=>a.has(c)?_("Cannot add the same private member more than once"):a instanceof WeakSet?a.add(c):a.set(c,u);var h=(c,a,u)=>(R(c,a,"access private method"),u);var w,b,l,k,H,O,v,q,M,$,S,B,G,Y;const a={generateKey:u,exportKey:D,importKey:V,decrypt:X,encrypt:J};async function u(t=256){return crypto.subtle.generateKey({name:"AES-GCM",length:t},!0,["encrypt","decrypt"])}async function D(t){return new Uint8Array(await crypto.subtle.exportKey("raw",t))}async function V(t){return crypto.subtle.importKey("raw",t,{name:"AES-GCM"},!0,["encrypt","decrypt"])}async function J(t,i,e=16){const r=crypto.getRandomValues(new Uint8Array(e));return{encrypted:new Uint8Array(await crypto.subtle.encrypt({name:"AES-GCM",iv:r},t,i)),iv:r}}async function X(t,i,e){return new Uint8Array(await crypto.subtle.decrypt({name:"AES-GCM",iv:e},t,i))}function Q(t,i=!1){return i&&(t=t.replace(/_/g,"/").replace(/-/g,"+")+"=".repeat(3-(3+t.length)%4)),Uint8Array.from(atob(t),e=>e.charCodeAt(0))}function x(t,i=!1){const e=btoa(String.fromCharCode(...t));return i?e.replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,""):e}function L(t,i=80){let e="";for(;t.length>0;)e+=t.slice(0,i)+`
|
|
2
|
+
`,t=t.slice(i);return e}function C(t){return Q(t.split(/\r?\n/).filter(i=>!i.startsWith("-----")).join(""))}const m="RSA-OAEP",U="SHA-256",W=2048,Z=new Uint8Array([1,0,1]),ee={generateKeyPair:te,encrypt:ne,decrypt:re,exportPrivateKey:I,exportPrivateKeyPem:se,exportPublicKey:A,exportPublicKeyPem:ie,exportPublicKeyFromPrivateKey:ae,importPrivateKey:z,importPrivateKeyPem:oe,importPublicKey:T,importPublicKeyPem:N};async function te(){return crypto.subtle.generateKey({name:m,modulusLength:W,publicExponent:Z,hash:U},!0,["encrypt","decrypt"])}async function ne(t,i){return new Uint8Array(await crypto.subtle.encrypt({name:m},t,i))}async function re(t,i){return new Uint8Array(await crypto.subtle.decrypt({name:m},t,i))}async function A(t){return new Uint8Array(await crypto.subtle.exportKey("spki",t))}async function I(t){return new Uint8Array(await crypto.subtle.exportKey("pkcs8",t))}async function ie(t){return`-----BEGIN PUBLIC KEY-----
|
|
3
|
+
`+L(x(await A(t)),64)+"-----END PUBLIC KEY-----"}async function se(t){return`-----BEGIN PRIVATE KEY-----
|
|
4
|
+
`+L(x(await I(t)),64)+"-----END PRIVATE KEY-----"}async function T(t){return crypto.subtle.importKey("spki",t,{name:m,hash:U},!0,["encrypt"])}async function N(t){return T(C(t))}async function z(t){return crypto.subtle.importKey("pkcs8",t,{name:m,hash:U},!0,["decrypt"])}async function oe(t){return z(C(t))}async function ae(t){const i=await crypto.subtle.exportKey("jwk",t);delete i.d,delete i.dp,delete i.dq,delete i.q,delete i.qi,i.key_ops=["encrypt"];const e=await crypto.subtle.importKey("jwk",i,{name:m,hash:U},!0,["encrypt"]);return A(e)}const ce=new Uint8Array([1,0,1]),le=256,pe=16;async function ue(t,i,e={}){const{aesIVLength:r=pe,aesKeyLength:n=le}=e,o=await a.generateKey(n),{encrypted:p,iv:s}=await a.encrypt(o,i,r),d=await ee.encrypt(t,await a.exportKey(o));return new Uint8Array([...ce,...new Uint8Array([d.length]),...new Uint8Array([s.length]),...d,...s,...p])}class F{constructor(i){this.context=i}static register(i){typeof globalThis.altchaPlugins!="object"&&(globalThis.altchaPlugins=[]),globalThis.altchaPlugins.includes(i)||globalThis.altchaPlugins.push(i)}destroy(){}onErrorChange(i){}onStateChange(i){}}y(F,"pluginName");class K extends F{constructor(e){super(e);P(this,l);y(this,"pendingFiles",[]);y(this,"uploadHandles",[]);y(this,"elForm");P(this,w,h(this,l,M).bind(this));P(this,b,h(this,l,$).bind(this));this.elForm=this.context.el.closest("form"),this.elForm&&(this.elForm.addEventListener("change",E(this,w)),this.elForm.addEventListener("submit",E(this,b),{capture:!0}))}addFile(e,r){this.pendingFiles.find(([n,o])=>n===e&&o===r)||this.pendingFiles.push([e,r])}destroy(){this.elForm&&(this.elForm.removeEventListener("change",E(this,w)),this.elForm.removeEventListener("submit",E(this,b)))}async uploadPendingFiles(){var r;const e=async()=>{const n=this.pendingFiles[0];if(n&&await h(this,l,S).call(this,h(this,l,H).call(this,n)),this.pendingFiles.length)return e()};try{await e()}catch(n){return this.context.log("upload failed",n),this.context.dispatch("uploaderror",{error:n}),!1}this.pendingFiles.length===0&&(h(this,l,k).call(this),(r=this.elForm)==null||r.requestSubmit())}}w=new WeakMap,b=new WeakMap,l=new WeakSet,k=function(){var r,n,o;const e=this.uploadHandles.reduce((p,s)=>(p[s.fieldName]||(p[s.fieldName]=[]),s.fileId&&p[s.fieldName].push(s.fileId),p),{});for(const p in e){const s=document.createElement("input");s.name=p,s.type="hidden",s.value=e[p].join(","),(n=(r=this.elForm)==null?void 0:r.querySelector(`[name="${p}"]`))==null||n.setAttribute("disabled","disabled"),(o=this.elForm)==null||o.appendChild(s)}},H=function(e){const r=this.pendingFiles.findIndex(([o,p])=>o===e[0]&&p===e[1]);if(r<0)throw new Error("Cannot create upload handle.");const n=new de(e[0],e[1]);return this.uploadHandles.push(n),this.pendingFiles.splice(r,1),h(this,l,O).call(this,n),h(this,l,v).call(this),n},O=function(e){this.context.dispatch("upload",{handle:e})},v=function(){const e=this.pendingFiles.reduce((n,[o,p])=>n+p.size,0)+this.uploadHandles.reduce((n,{uploadSize:o})=>n+o,0),r=this.uploadHandles.reduce((n,{loaded:o})=>n+o,0);this.context.dispatch("uploadprogress",{bytesLoaded:r,bytesTotal:e,pendingFiles:this.pendingFiles,uploadHandles:this.uploadHandles})},q=function(){if(this.elForm){const e=this.elForm.getAttribute("action"),r=this.elForm.getAttribute("data-upload-url");if(r)return r;const n=new URL(e||location.origin);return n.pathname=n.pathname+"/file",n.toString()}return null},M=function(e){const r=e.target;if(r&&r.type==="file"){const n=r.files;if(n!=null&&n.length)for(const o of n)this.addFile(r.name,o)}},$=function(e){const r=e.target;r!=null&&r.hasAttribute("data-code-challenge-form")||this.pendingFiles.length&&(e.preventDefault(),e.stopPropagation(),this.uploadPendingFiles())},S=async function(e,r){const n=h(this,l,q).call(this);if(!n)throw new Error("Upload url not specified.");const o={"content-type":"application/json"};r&&(o.authorization="Altcha payload="+r);const p=await fetch(n,{body:JSON.stringify({name:e.file.name||"file",size:e.file.size,type:e.file.type||"application/octet-stream"}),credentials:"include",headers:o,method:"POST"});if(p.status===401)return h(this,l,B).call(this,p,e);if(p.status!==200)throw new Error(`Unexpected server response ${p.status}.`);const s=await p.json();let d=e.file;if(s.encrypted&&s.encryptionPublicKey){const f=await N(s.encryptionPublicKey),ye=await new Response(new ReadableStream({async start(j){const he=e.file.stream().getReader();for(;;){const{done:fe,value:me}=await he.read();if(fe)break;j.enqueue(me)}j.close()}})).arrayBuffer();d=await ue(f,new Uint8Array(ye))}return e.uploadSize=d instanceof Uint8Array?d.byteLength:e.file.size,await h(this,l,Y).call(this,s.uploadUrl,e,d,{"content-type":e.file.type||"application/octet-stream"}),s.finalizeUrl&&await h(this,l,G).call(this,s.finalizeUrl,e.uploadSize),e.fileId=s.fileId,e.resolve({encrypted:s.encrypted,fileId:s.fileId}),e.promise},B=async function(e,r){var n;try{const o=e.headers.get("www-authenticate"),p=(n=o==null?void 0:o.match(/challenge=(.*),/))==null?void 0:n[1];if(!p)throw new Error("Unable to retrieve altcha challenge from www-authenticate header.");const s=JSON.parse(p);if(s&&"challenge"in s){const{solution:d}=await this.context.solve(s);if(d&&"number"in d)return h(this,l,S).call(this,r,btoa(JSON.stringify({...s,number:d.number})));throw new Error("Invalid challenge solution.")}}catch(o){throw this.context.log(o),new Error("Unable to solve altcha challenge for upload.")}},G=async function(e,r){const n=await fetch(e,{body:JSON.stringify({uploadedBytes:r}),headers:{"content-type":"application/json"},method:"POST"});if(n.status>204)throw new Error(`Unexpected server response ${n.status}.`);return!0},Y=async function(e,r,n,o={}){var p;return e=new URL(e,((p=this.elForm)==null?void 0:p.getAttribute("action"))||location.origin).toString(),new Promise((s,d)=>{const f=new XMLHttpRequest;r.controller.signal.addEventListener("abort",()=>{f.abort()}),f.upload.addEventListener("progress",g=>{r.setProgress(g.loaded),h(this,l,v).call(this)}),f.addEventListener("error",g=>{d(new Error("Upload failed."))}),f.addEventListener("load",()=>{f.status>=400?d(new Error(`Server responded with ${f.status}`)):s(void 0)}),f.open("PUT",e);for(const g in o)f.setRequestHeader(g,o[g]);f.send(n)})},y(K,"pluginName","upload");class de{constructor(i,e){y(this,"controller",new AbortController);y(this,"promise");y(this,"fileId");y(this,"loaded",0);y(this,"progress",0);y(this,"uploadSize",0);y(this,"resolve");y(this,"reject");this.fieldName=i,this.file=e,this.uploadSize=this.file.size,this.promise=new Promise((r,n)=>{this.resolve=r,this.reject=n})}abort(){this.controller.abort()}setProgress(i){this.loaded=i,this.progress=this.file.size&&i?Math.min(1,i/this.file.size):0}}F.register(K),c.PluginUpload=K,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "altcha",
|
|
3
3
|
"description": "GDPR compliant, self-hosted CAPTCHA alternative.",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "2.0.0-beta.2",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Daniel Regeci",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"homepage": "https://altcha.org",
|
|
11
11
|
"repository": {
|
|
12
12
|
"type": "git",
|
|
13
|
-
"url": "https://github.com/altcha-org/altcha"
|
|
13
|
+
"url": "git+https://github.com/altcha-org/altcha.git"
|
|
14
14
|
},
|
|
15
15
|
"type": "module",
|
|
16
16
|
"keywords": [
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"dist",
|
|
31
31
|
"dist_external",
|
|
32
32
|
"dist_plugins",
|
|
33
|
-
"
|
|
33
|
+
"dist_i18n"
|
|
34
34
|
],
|
|
35
35
|
"main": "./dist/altcha.umd.cjs",
|
|
36
36
|
"module": "./dist/altcha.js",
|
|
@@ -63,24 +63,27 @@
|
|
|
63
63
|
"./worker": {
|
|
64
64
|
"import": "./dist_external/worker.js",
|
|
65
65
|
"require": "./dist_external/worker.js"
|
|
66
|
+
},
|
|
67
|
+
"./i18n/*": {
|
|
68
|
+
"import": "./dist_i18n/*.js",
|
|
69
|
+
"require": "./dist_i18n/*.umd.js"
|
|
66
70
|
}
|
|
67
71
|
},
|
|
68
72
|
"scripts": {
|
|
69
73
|
"dev": "vite",
|
|
70
|
-
"build": "npm run build:bundle && npm run build:external && npm run build:plugins",
|
|
74
|
+
"build": "npm run build:bundle && npm run build:external && npm run build:plugins && npm run build:i18n",
|
|
71
75
|
"build:bundle": "rimraf dist && vite build && cp src/declarations.d.ts dist/altcha.d.ts",
|
|
72
76
|
"build:external": "rimraf dist_external && vite build -c vite.external.config.ts && cp src/declarations.d.ts dist_external/altcha.d.ts",
|
|
73
77
|
"build:plugins": "rimraf dist_plugins && find src/plugins -type f -name '*.ts' | xargs -I {} vite build -c vite.plugins.config.ts -- {}",
|
|
78
|
+
"build:i18n": "rimraf dist_i18n && find src/i18n -type f -name '*.ts' | xargs -I {} vite build -c vite.i18n.config.ts -- {}",
|
|
74
79
|
"preview": "vite preview",
|
|
75
80
|
"check": "svelte-check --tsconfig ./tsconfig.json",
|
|
76
81
|
"format": "prettier --write ./src/**/*",
|
|
77
82
|
"test": "vitest run tests/helpers.test.ts",
|
|
78
|
-
"test:e2e": "
|
|
79
|
-
"prepare": "husky"
|
|
80
|
-
"postinstall": "node postinstall.js"
|
|
83
|
+
"test:e2e": "testcafe chrome,firefox e2e/altcha.fixture.ts --hostname localhost",
|
|
84
|
+
"prepare": "husky"
|
|
81
85
|
},
|
|
82
86
|
"devDependencies": {
|
|
83
|
-
"@playwright/test": "^1.49.1",
|
|
84
87
|
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
|
85
88
|
"@tsconfig/svelte": "^5.0.4",
|
|
86
89
|
"@types/node": "^20.16.3",
|
|
@@ -93,6 +96,7 @@
|
|
|
93
96
|
"sass": "^1.77.8",
|
|
94
97
|
"svelte": "^5.22.6",
|
|
95
98
|
"svelte-check": "^4.0.0",
|
|
99
|
+
"testcafe": "^3.7.2",
|
|
96
100
|
"tslib": "^2.7.0",
|
|
97
101
|
"typescript": "^5.5.4",
|
|
98
102
|
"vite": "^6.2.1",
|
package/postinstall.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import { execSync } from 'node:child_process';
|
|
3
|
-
|
|
4
|
-
const srcDir = 'node_modules/@ovx/svelte';
|
|
5
|
-
const destDir = 'node_modules/svelte';
|
|
6
|
-
|
|
7
|
-
if (fs.existsSync(srcDir)) {
|
|
8
|
-
execSync(`rm -rf ${destDir}`);
|
|
9
|
-
execSync(`cp -R ${srcDir} ${destDir}`);
|
|
10
|
-
}
|