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.
Files changed (114) hide show
  1. package/README.md +144 -156
  2. package/dist/altcha.d.ts +6 -0
  3. package/dist/altcha.js +1683 -1383
  4. package/dist/altcha.umd.cjs +10 -7
  5. package/dist_external/altcha.css +127 -13
  6. package/dist_external/altcha.d.ts +6 -0
  7. package/dist_external/altcha.js +1667 -1367
  8. package/dist_external/altcha.umd.cjs +9 -6
  9. package/dist_i18n/all.js +810 -0
  10. package/dist_i18n/all.umd.cjs +1 -0
  11. package/dist_i18n/americas.js +54 -0
  12. package/dist_i18n/americas.umd.cjs +1 -0
  13. package/dist_i18n/ar.js +21 -0
  14. package/dist_i18n/ar.umd.cjs +1 -0
  15. package/dist_i18n/asia.js +288 -0
  16. package/dist_i18n/asia.umd.cjs +1 -0
  17. package/dist_i18n/bg.js +21 -0
  18. package/dist_i18n/bg.umd.cjs +1 -0
  19. package/dist_i18n/bn.js +21 -0
  20. package/dist_i18n/bn.umd.cjs +1 -0
  21. package/dist_i18n/cs.js +21 -0
  22. package/dist_i18n/cs.umd.cjs +1 -0
  23. package/dist_i18n/da.js +21 -0
  24. package/dist_i18n/da.umd.cjs +1 -0
  25. package/dist_i18n/de.js +21 -0
  26. package/dist_i18n/de.umd.cjs +1 -0
  27. package/dist_i18n/el.js +21 -0
  28. package/dist_i18n/el.umd.cjs +1 -0
  29. package/dist_i18n/en.js +21 -0
  30. package/dist_i18n/en.umd.cjs +1 -0
  31. package/dist_i18n/es-419.js +21 -0
  32. package/dist_i18n/es-419.umd.cjs +1 -0
  33. package/dist_i18n/es-es.js +21 -0
  34. package/dist_i18n/es-es.umd.cjs +1 -0
  35. package/dist_i18n/et.js +21 -0
  36. package/dist_i18n/et.umd.cjs +1 -0
  37. package/dist_i18n/eu.js +21 -0
  38. package/dist_i18n/eu.umd.cjs +1 -0
  39. package/dist_i18n/europe.js +468 -0
  40. package/dist_i18n/europe.umd.cjs +1 -0
  41. package/dist_i18n/fi.js +21 -0
  42. package/dist_i18n/fi.umd.cjs +1 -0
  43. package/dist_i18n/fr-ca.js +21 -0
  44. package/dist_i18n/fr-ca.umd.cjs +1 -0
  45. package/dist_i18n/fr-fr.js +21 -0
  46. package/dist_i18n/fr-fr.umd.cjs +1 -0
  47. package/dist_i18n/ga.js +21 -0
  48. package/dist_i18n/ga.umd.cjs +1 -0
  49. package/dist_i18n/he.js +21 -0
  50. package/dist_i18n/he.umd.cjs +1 -0
  51. package/dist_i18n/hi.js +21 -0
  52. package/dist_i18n/hi.umd.cjs +1 -0
  53. package/dist_i18n/hr.js +21 -0
  54. package/dist_i18n/hr.umd.cjs +1 -0
  55. package/dist_i18n/hu.js +21 -0
  56. package/dist_i18n/hu.umd.cjs +1 -0
  57. package/dist_i18n/id.js +21 -0
  58. package/dist_i18n/id.umd.cjs +1 -0
  59. package/dist_i18n/it.js +21 -0
  60. package/dist_i18n/it.umd.cjs +1 -0
  61. package/dist_i18n/ja.js +21 -0
  62. package/dist_i18n/ja.umd.cjs +1 -0
  63. package/dist_i18n/ko.js +21 -0
  64. package/dist_i18n/ko.umd.cjs +1 -0
  65. package/dist_i18n/lt.js +21 -0
  66. package/dist_i18n/lt.umd.cjs +1 -0
  67. package/dist_i18n/lv.js +21 -0
  68. package/dist_i18n/lv.umd.cjs +1 -0
  69. package/dist_i18n/mr.js +21 -0
  70. package/dist_i18n/mr.umd.cjs +1 -0
  71. package/dist_i18n/mt.js +21 -0
  72. package/dist_i18n/mt.umd.cjs +1 -0
  73. package/dist_i18n/nl.js +21 -0
  74. package/dist_i18n/nl.umd.cjs +1 -0
  75. package/dist_i18n/pl.js +21 -0
  76. package/dist_i18n/pl.umd.cjs +1 -0
  77. package/dist_i18n/pt-br.js +21 -0
  78. package/dist_i18n/pt-br.umd.cjs +1 -0
  79. package/dist_i18n/pt-pt.js +21 -0
  80. package/dist_i18n/pt-pt.umd.cjs +1 -0
  81. package/dist_i18n/ro.js +21 -0
  82. package/dist_i18n/ro.umd.cjs +1 -0
  83. package/dist_i18n/ru.js +21 -0
  84. package/dist_i18n/ru.umd.cjs +1 -0
  85. package/dist_i18n/sk.js +21 -0
  86. package/dist_i18n/sk.umd.cjs +1 -0
  87. package/dist_i18n/sl.js +21 -0
  88. package/dist_i18n/sl.umd.cjs +1 -0
  89. package/dist_i18n/sv.js +21 -0
  90. package/dist_i18n/sv.umd.cjs +1 -0
  91. package/dist_i18n/ta.js +21 -0
  92. package/dist_i18n/ta.umd.cjs +1 -0
  93. package/dist_i18n/te.js +21 -0
  94. package/dist_i18n/te.umd.cjs +1 -0
  95. package/dist_i18n/th.js +21 -0
  96. package/dist_i18n/th.umd.cjs +1 -0
  97. package/dist_i18n/tr.js +21 -0
  98. package/dist_i18n/tr.umd.cjs +1 -0
  99. package/dist_i18n/uk.js +21 -0
  100. package/dist_i18n/uk.umd.cjs +1 -0
  101. package/dist_i18n/ur.js +21 -0
  102. package/dist_i18n/ur.umd.cjs +1 -0
  103. package/dist_i18n/vi.js +21 -0
  104. package/dist_i18n/vi.umd.cjs +1 -0
  105. package/dist_i18n/zh-cn.js +21 -0
  106. package/dist_i18n/zh-cn.umd.cjs +1 -0
  107. package/dist_i18n/zh-tw.js +21 -0
  108. package/dist_i18n/zh-tw.umd.cjs +1 -0
  109. package/dist_plugins/obfuscation.js +10 -10
  110. package/dist_plugins/obfuscation.umd.cjs +1 -1
  111. package/dist_plugins/upload.js +145 -133
  112. package/dist_plugins/upload.umd.cjs +4 -4
  113. package/package.json +12 -8
  114. package/postinstall.js +0 -10
@@ -1,33 +1,33 @@
1
- var V = Object.defineProperty;
2
- var K = (t) => {
1
+ var J = Object.defineProperty;
2
+ var v = (t) => {
3
3
  throw TypeError(t);
4
4
  };
5
- var J = (t, n, e) => n in t ? V(t, n, { enumerable: !0, configurable: !0, writable: !0, value: e }) : t[n] = e;
6
- var p = (t, n, e) => J(t, typeof n != "symbol" ? n + "" : n, e), v = (t, n, e) => n.has(t) || K("Cannot " + e);
7
- var h = (t, n, e) => (v(t, n, "read from private field"), e ? e.call(t) : n.get(t)), g = (t, n, e) => n.has(t) ? K("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) => (v(t, n, "access private method"), e);
9
- const b = {
10
- generateKey: X,
11
- exportKey: Q,
12
- importKey: W,
13
- decrypt: ee,
14
- encrypt: Z
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 X(t = 256) {
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 Q(t) {
22
+ async function W(t) {
23
23
  return new Uint8Array(await crypto.subtle.exportKey("raw", t));
24
24
  }
25
- async function W(t) {
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 Z(t, n, e = 16) {
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 ee(t, n, e) {
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 te(t, n = !1) {
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 S(t, n = !1) {
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 x(t, n = 80) {
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 L(t) {
61
- return te(t.split(/\r?\n/).filter((n) => !n.startsWith("-----")).join(""));
60
+ function C(t) {
61
+ return ne(t.split(/\r?\n/).filter((n) => !n.startsWith("-----")).join(""));
62
62
  }
63
- const d = "RSA-OAEP", w = "SHA-256", ne = 2048, re = new Uint8Array([1, 0, 1]), ie = {
64
- generateKeyPair: se,
65
- encrypt: oe,
66
- decrypt: ae,
67
- exportPrivateKey: C,
68
- exportPrivateKeyPem: le,
69
- exportPublicKey: U,
70
- exportPublicKeyPem: ce,
71
- exportPublicKeyFromPrivateKey: ue,
72
- importPrivateKey: z,
73
- importPrivateKeyPem: pe,
74
- importPublicKey: I,
75
- importPublicKeyPem: N
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 se() {
77
+ async function oe() {
78
78
  return crypto.subtle.generateKey({
79
- name: d,
80
- modulusLength: ne,
81
- publicExponent: re,
82
- hash: w
79
+ name: h,
80
+ modulusLength: re,
81
+ publicExponent: ie,
82
+ hash: b
83
83
  }, !0, ["encrypt", "decrypt"]);
84
84
  }
85
- async function oe(t, n) {
85
+ async function ae(t, n) {
86
86
  return new Uint8Array(await crypto.subtle.encrypt({
87
- name: d
87
+ name: h
88
88
  }, t, n));
89
89
  }
90
- async function ae(t, n) {
90
+ async function ce(t, n) {
91
91
  return new Uint8Array(await crypto.subtle.decrypt({
92
- name: d
92
+ name: h
93
93
  }, t, n));
94
94
  }
95
- async function U(t) {
95
+ async function F(t) {
96
96
  return new Uint8Array(await crypto.subtle.exportKey("spki", t));
97
97
  }
98
- async function C(t) {
98
+ async function I(t) {
99
99
  return new Uint8Array(await crypto.subtle.exportKey("pkcs8", t));
100
100
  }
101
- async function ce(t) {
101
+ async function le(t) {
102
102
  return `-----BEGIN PUBLIC KEY-----
103
- ` + x(S(await U(t)), 64) + "-----END PUBLIC KEY-----";
103
+ ` + L(x(await F(t)), 64) + "-----END PUBLIC KEY-----";
104
104
  }
105
- async function le(t) {
105
+ async function pe(t) {
106
106
  return `-----BEGIN PRIVATE KEY-----
107
- ` + x(S(await C(t)), 64) + "-----END PRIVATE KEY-----";
107
+ ` + L(x(await I(t)), 64) + "-----END PRIVATE KEY-----";
108
108
  }
109
- async function I(t) {
109
+ async function N(t) {
110
110
  return crypto.subtle.importKey("spki", t, {
111
- name: d,
112
- hash: w
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: d,
121
- hash: w
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: d,
132
- hash: w
131
+ name: h,
132
+ hash: b
133
133
  }, !0, ["encrypt"]);
134
- return U(e);
134
+ return F(e);
135
135
  }
136
- const ye = new Uint8Array([1, 0, 1]), de = 256, he = 16;
137
- async function fe(t, n, e = {}) {
138
- const { aesIVLength: i = he, aesKeyLength: r = de } = e, o = await b.generateKey(r), { encrypted: c, iv: s } = await b.encrypt(o, n, i), l = await ie.encrypt(t, await b.exportKey(o));
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
- ...c
145
+ ...a
146
146
  ]);
147
147
  }
148
- class A {
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(A, "pluginName");
193
- var f, m, a, _, j, k, E, H, R, q, P, O, B, G;
194
- class T extends A {
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
- g(this, a);
202
+ w(this, c);
203
203
  p(this, "pendingFiles", []);
204
204
  p(this, "uploadHandles", []);
205
205
  p(this, "elForm");
206
- g(this, f, u(this, a, R).bind(this));
207
- g(this, m, u(this, a, q).bind(this));
208
- this.elForm = this.context.el.closest("form"), this.elForm && (this.elForm.addEventListener("change", h(this, f)), this.elForm.addEventListener("submit", h(this, m), {
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", h(this, f)), this.elForm.removeEventListener("submit", h(this, m)));
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, a, P).call(this, u(this, a, j).call(this, r)), this.pendingFiles.length)
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
- await e(), this.pendingFiles.length === 0 && (u(this, a, _).call(this), (i = this.elForm) == null || i.requestSubmit());
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
- f = new WeakMap(), m = new WeakMap(), a = new WeakSet(), /**
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
- _ = function() {
250
+ R = function() {
244
251
  var i, r, o;
245
252
  const e = this.uploadHandles.reduce(
246
- (c, s) => (c[s.fieldName] || (c[s.fieldName] = []), s.fileId && c[s.fieldName].push(s.fileId), c),
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 c in e) {
256
+ for (const a in e) {
250
257
  const s = document.createElement("input");
251
- s.name = c, s.type = "hidden", s.value = e[c].join(","), (r = (i = this.elForm) == null ? void 0 : i.querySelector(`[name="${c}"]`)) == null || r.setAttribute("disabled", "disabled"), (o = this.elForm) == null || o.appendChild(s);
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, c]) => o === e[0] && c === e[1]
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 me(e[0], e[1]);
267
- return this.uploadHandles.push(r), this.pendingFiles.splice(i, 1), u(this, a, k).call(this, r), u(this, a, E).call(this), r;
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
- E = function() {
279
- const e = this.pendingFiles.reduce((r, [o, c]) => r + c.size, 0) + this.uploadHandles.reduce((r, { uploadSize: o }) => r + o, 0), i = this.uploadHandles.reduce(
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
- return this.elForm.getAttribute("data-upload-url") || e + "/file";
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
- R = function(e) {
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
- q = function(e) {
319
- this.pendingFiles.length && (e.preventDefault(), e.stopPropagation(), this.uploadPendingFiles());
320
- }, P = async function(e, i) {
321
- const r = u(this, a, H).call(this);
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 c = await fetch(r, {
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 (c.status === 401)
339
- return u(this, a, O).call(this, c, e);
340
- if (c.status !== 200)
341
- throw new Error(`Unexpected server response ${c.status}.`);
342
- const s = await c.json();
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 y = await N(s.encryptionPublicKey), M = await new Response(
356
+ const d = await z(s.encryptionPublicKey), M = await new Response(
346
357
  new ReadableStream({
347
- async start(F) {
348
- const $ = e.file.stream().getReader();
358
+ async start(K) {
359
+ const Y = e.file.stream().getReader();
349
360
  for (; ; ) {
350
- const { done: Y, value: D } = await $.read();
351
- if (Y)
361
+ const { done: D, value: V } = await Y.read();
362
+ if (D)
352
363
  break;
353
- F.enqueue(D);
364
+ K.enqueue(V);
354
365
  }
355
- F.close();
366
+ K.close();
356
367
  }
357
368
  })
358
369
  ).arrayBuffer();
359
- l = await fe(y, new Uint8Array(M));
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, a, G).call(this, s.uploadUrl, e, l, {
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, a, B).call(this, s.finalizeUrl, e.uploadSize), e.fileId = s.fileId, e.resolve({
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
- }, O = async function(e, i) {
378
+ }, $ = async function(e, i) {
368
379
  var r;
369
380
  try {
370
- const o = e.headers.get("www-authenticate"), c = (r = o == null ? void 0 : o.match(/challenge=(.*),/)) == null ? void 0 : r[1];
371
- if (!c)
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(c);
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, a, P).call(this, i, btoa(
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
- return new Promise((c, s) => {
405
- const l = new XMLHttpRequest();
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
- l.abort();
408
- }), l.upload.addEventListener("progress", (y) => {
409
- i.setProgress(y.loaded), u(this, a, E).call(this);
410
- }), l.addEventListener("error", (y) => {
411
- s(new Error("Upload failed."));
412
- }), l.addEventListener("load", () => {
413
- c(void 0);
414
- }), l.open("PUT", e);
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
- l.setRequestHeader(y, o[y]);
417
- l.send(r);
428
+ d.setRequestHeader(y, o[y]);
429
+ d.send(r);
418
430
  });
419
- }, p(T, "pluginName", "upload");
420
- class me {
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
- A.register(T);
467
+ P.register(_);
456
468
  export {
457
- T as PluginUpload
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 me=Object.defineProperty;var j=c=>{throw TypeError(c)};var ge=(c,a,d)=>a in c?me(c,a,{enumerable:!0,configurable:!0,writable:!0,value:d}):c[a]=d;var y=(c,a,d)=>ge(c,typeof a!="symbol"?a+"":a,d),_=(c,a,d)=>a.has(c)||j("Cannot "+d);var b=(c,a,d)=>(_(c,a,"read from private field"),d?d.call(c):a.get(c)),P=(c,a,d)=>a.has(c)?j("Cannot add the same private member more than once"):a instanceof WeakSet?a.add(c):a.set(c,d);var h=(c,a,d)=>(_(c,a,"access private method"),d);var g,w,l,k,H,R,K,O,q,M,v,B,G,$;const a={generateKey:d,exportKey:Y,importKey:D,decrypt:J,encrypt:V};async function d(t=256){return crypto.subtle.generateKey({name:"AES-GCM",length:t},!0,["encrypt","decrypt"])}async function Y(t){return new Uint8Array(await crypto.subtle.exportKey("raw",t))}async function D(t){return crypto.subtle.importKey("raw",t,{name:"AES-GCM"},!0,["encrypt","decrypt"])}async function V(t,n,e=16){const i=crypto.getRandomValues(new Uint8Array(e));return{encrypted:new Uint8Array(await crypto.subtle.encrypt({name:"AES-GCM",iv:i},t,n)),iv:i}}async function J(t,n,e){return new Uint8Array(await crypto.subtle.decrypt({name:"AES-GCM",iv:e},t,n))}function X(t,n=!1){return n&&(t=t.replace(/_/g,"/").replace(/-/g,"+")+"=".repeat(3-(3+t.length)%4)),Uint8Array.from(atob(t),e=>e.charCodeAt(0))}function S(t,n=!1){const e=btoa(String.fromCharCode(...t));return n?e.replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,""):e}function x(t,n=80){let e="";for(;t.length>0;)e+=t.slice(0,n)+`
2
- `,t=t.slice(n);return e}function L(t){return X(t.split(/\r?\n/).filter(n=>!n.startsWith("-----")).join(""))}const m="RSA-OAEP",E="SHA-256",Q=2048,W=new Uint8Array([1,0,1]),Z={generateKeyPair:ee,encrypt:te,decrypt:ne,exportPrivateKey:C,exportPrivateKeyPem:ie,exportPublicKey:U,exportPublicKeyPem:re,exportPublicKeyFromPrivateKey:oe,importPrivateKey:N,importPrivateKeyPem:se,importPublicKey:I,importPublicKeyPem:T};async function ee(){return crypto.subtle.generateKey({name:m,modulusLength:Q,publicExponent:W,hash:E},!0,["encrypt","decrypt"])}async function te(t,n){return new Uint8Array(await crypto.subtle.encrypt({name:m},t,n))}async function ne(t,n){return new Uint8Array(await crypto.subtle.decrypt({name:m},t,n))}async function U(t){return new Uint8Array(await crypto.subtle.exportKey("spki",t))}async function C(t){return new Uint8Array(await crypto.subtle.exportKey("pkcs8",t))}async function re(t){return`-----BEGIN PUBLIC KEY-----
3
- `+x(S(await U(t)),64)+"-----END PUBLIC KEY-----"}async function ie(t){return`-----BEGIN PRIVATE KEY-----
4
- `+x(S(await C(t)),64)+"-----END PRIVATE KEY-----"}async function I(t){return crypto.subtle.importKey("spki",t,{name:m,hash:E},!0,["encrypt"])}async function T(t){return I(L(t))}async function N(t){return crypto.subtle.importKey("pkcs8",t,{name:m,hash:E},!0,["decrypt"])}async function se(t){return N(L(t))}async function oe(t){const n=await crypto.subtle.exportKey("jwk",t);delete n.d,delete n.dp,delete n.dq,delete n.q,delete n.qi,n.key_ops=["encrypt"];const e=await crypto.subtle.importKey("jwk",n,{name:m,hash:E},!0,["encrypt"]);return U(e)}const ae=new Uint8Array([1,0,1]),ce=256,le=16;async function pe(t,n,e={}){const{aesIVLength:i=le,aesKeyLength:r=ce}=e,o=await a.generateKey(r),{encrypted:p,iv:s}=await a.encrypt(o,n,i),u=await Z.encrypt(t,await a.exportKey(o));return new Uint8Array([...ae,...new Uint8Array([u.length]),...new Uint8Array([s.length]),...u,...s,...p])}class A{constructor(n){this.context=n}static register(n){typeof globalThis.altchaPlugins!="object"&&(globalThis.altchaPlugins=[]),globalThis.altchaPlugins.includes(n)||globalThis.altchaPlugins.push(n)}destroy(){}onErrorChange(n){}onStateChange(n){}}y(A,"pluginName");class F extends A{constructor(e){super(e);P(this,l);y(this,"pendingFiles",[]);y(this,"uploadHandles",[]);y(this,"elForm");P(this,g,h(this,l,q).bind(this));P(this,w,h(this,l,M).bind(this));this.elForm=this.context.el.closest("form"),this.elForm&&(this.elForm.addEventListener("change",b(this,g)),this.elForm.addEventListener("submit",b(this,w),{capture:!0}))}addFile(e,i){this.pendingFiles.find(([r,o])=>r===e&&o===i)||this.pendingFiles.push([e,i])}destroy(){this.elForm&&(this.elForm.removeEventListener("change",b(this,g)),this.elForm.removeEventListener("submit",b(this,w)))}async uploadPendingFiles(){var i;const e=async()=>{const r=this.pendingFiles[0];if(r&&await h(this,l,v).call(this,h(this,l,H).call(this,r)),this.pendingFiles.length)return e()};await e(),this.pendingFiles.length===0&&(h(this,l,k).call(this),(i=this.elForm)==null||i.requestSubmit())}}g=new WeakMap,w=new WeakMap,l=new WeakSet,k=function(){var i,r,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(","),(r=(i=this.elForm)==null?void 0:i.querySelector(`[name="${p}"]`))==null||r.setAttribute("disabled","disabled"),(o=this.elForm)==null||o.appendChild(s)}},H=function(e){const i=this.pendingFiles.findIndex(([o,p])=>o===e[0]&&p===e[1]);if(i<0)throw new Error("Cannot create upload handle.");const r=new ue(e[0],e[1]);return this.uploadHandles.push(r),this.pendingFiles.splice(i,1),h(this,l,R).call(this,r),h(this,l,K).call(this),r},R=function(e){this.context.dispatch("upload",{handle:e})},K=function(){const e=this.pendingFiles.reduce((r,[o,p])=>r+p.size,0)+this.uploadHandles.reduce((r,{uploadSize:o})=>r+o,0),i=this.uploadHandles.reduce((r,{loaded:o})=>r+o,0);this.context.dispatch("uploadprogress",{bytesLoaded:i,bytesTotal:e,pendingFiles:this.pendingFiles,uploadHandles:this.uploadHandles})},O=function(){if(this.elForm){const e=this.elForm.getAttribute("action");return this.elForm.getAttribute("data-upload-url")||e+"/file"}return null},q=function(e){const i=e.target;if(i&&i.type==="file"){const r=i.files;if(r!=null&&r.length)for(const o of r)this.addFile(i.name,o)}},M=function(e){this.pendingFiles.length&&(e.preventDefault(),e.stopPropagation(),this.uploadPendingFiles())},v=async function(e,i){const r=h(this,l,O).call(this);if(!r)throw new Error("Upload url not specified.");const o={"content-type":"application/json"};i&&(o.authorization="Altcha payload="+i);const p=await fetch(r,{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 u=e.file;if(s.encrypted&&s.encryptionPublicKey){const f=await T(s.encryptionPublicKey),de=await new Response(new ReadableStream({async start(z){const ye=e.file.stream().getReader();for(;;){const{done:he,value:fe}=await ye.read();if(he)break;z.enqueue(fe)}z.close()}})).arrayBuffer();u=await pe(f,new Uint8Array(de))}return e.uploadSize=u instanceof Uint8Array?u.byteLength:e.file.size,await h(this,l,$).call(this,s.uploadUrl,e,u,{"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,i){var r;try{const o=e.headers.get("www-authenticate"),p=(r=o==null?void 0:o.match(/challenge=(.*),/))==null?void 0:r[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:u}=await this.context.solve(s);if(u&&"number"in u)return h(this,l,v).call(this,i,btoa(JSON.stringify({...s,number:u.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,i){const r=await fetch(e,{body:JSON.stringify({uploadedBytes:i}),headers:{"content-type":"application/json"},method:"POST"});if(r.status>204)throw new Error(`Unexpected server response ${r.status}.`);return!0},$=async function(e,i,r,o={}){return new Promise((p,s)=>{const u=new XMLHttpRequest;i.controller.signal.addEventListener("abort",()=>{u.abort()}),u.upload.addEventListener("progress",f=>{i.setProgress(f.loaded),h(this,l,K).call(this)}),u.addEventListener("error",f=>{s(new Error("Upload failed."))}),u.addEventListener("load",()=>{p(void 0)}),u.open("PUT",e);for(const f in o)u.setRequestHeader(f,o[f]);u.send(r)})},y(F,"pluginName","upload");class ue{constructor(n,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=n,this.file=e,this.uploadSize=this.file.size,this.promise=new Promise((i,r)=>{this.resolve=i,this.reject=r})}abort(){this.controller.abort()}setProgress(n){this.loaded=n,this.progress=this.file.size&&n?Math.min(1,n/this.file.size):0}}A.register(F),c.PluginUpload=F,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})});
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": "1.4.2",
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
- "postinstall.js"
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": "playwright test",
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
- }