efront 4.4.14 → 4.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/#/345/233/275/351/231/205/345/214/226.yml +83 -5
  2. package/apps/pivot/api.yml +4 -0
  3. package/apps/pivot/cert/edit.js +1 -0
  4. package/apps/pivot/cert/list.js +9 -0
  5. package/apps/pivot/cert/main.xht +188 -0
  6. package/apps/pivot/cert/orders.xht +232 -0
  7. package/apps/pivot/cert/update.xht +7 -0
  8. package/apps/pivot/menu.yml +1 -0
  9. package/coms/basic/assert.js +40 -16
  10. package/coms/basic/cross_.js +22 -4
  11. package/coms/basic/renderTags.js +23 -0
  12. package/coms/basic/shallowClone.js +8 -0
  13. package/coms/basic/shallowEqual.js +13 -4
  14. package/coms/basic/valid.js +19 -4
  15. package/coms/compile/Javascript.js +25 -12
  16. package/coms/compile//347/264/240/351/246/250.js +2 -1
  17. package/coms/docs/codetext.xht +3 -3
  18. package/coms/frame/chat.js +1 -1
  19. package/coms/frame/edit.html +1 -0
  20. package/coms/frame/edit.js +3 -2
  21. package/coms/kugou/bindScroll.js +1 -1
  22. package/coms/kugou/krc.js +2 -2
  23. package/coms/layer/leftCenter.js +5 -5
  24. package/coms/pivot/acme2.js +290 -0
  25. package/coms/pivot/pedit.js +13 -5
  26. package/coms/pivot/plist.js +12 -5
  27. package/coms/reptile/colored_console.js +5 -17
  28. package/coms/zimoli/appendChild.js +3 -2
  29. package/coms/zimoli/autofocus.js +2 -2
  30. package/coms/zimoli/button.less +5 -3
  31. package/coms/zimoli/checker.js +34 -15
  32. package/coms/zimoli/checker.less +2 -3
  33. package/coms/zimoli/container.js +26 -15
  34. package/coms/zimoli/data.js +124 -169
  35. package/coms/zimoli/field.js +3 -3
  36. package/coms/zimoli/field.less +8 -2
  37. package/coms/zimoli/filterTime.js +39 -8
  38. package/coms/zimoli/fromBase64.js +2 -0
  39. package/coms/zimoli/grid.js +2 -2
  40. package/coms/zimoli/isMounted.js +3 -3
  41. package/coms/zimoli/list.js +5 -5
  42. package/coms/zimoli/maps.js +1 -1
  43. package/coms/zimoli/menuList.js +1 -1
  44. package/coms/zimoli/model.js +61 -8
  45. package/coms/zimoli/on.js +4 -4
  46. package/coms/zimoli/remove.js +3 -3
  47. package/coms/zimoli/render.js +25 -33
  48. package/coms/zimoli/scrollbar.js +54 -19
  49. package/coms/zimoli/scrollbar.less +14 -2
  50. package/coms/zimoli/scrollbar_test.less +1 -0
  51. package/coms/zimoli/select.js +3 -3
  52. package/coms/zimoli/table.js +1 -1
  53. package/coms/zimoli/toBase64.js +16 -6
  54. package/coms/zimoli/view.js +24 -14
  55. package/coms/zimoli/view.less +6 -4
  56. package/coms/zimoli/watch.js +1 -1
  57. package/docs/loader.js +1 -1
  58. package/docs//347/273/204/344/273/266.xht +0 -1
  59. package/package.json +1 -1
  60. package/public/efront.js +1 -1
@@ -20,7 +20,7 @@ var setHost = function (host) {
20
20
  base = host;
21
21
  encrypt = null;
22
22
  };
23
- var HeadersKeys = ["Content-Type"];
23
+ var RealHeadersKeys = { "content-type": "Content-Type" };
24
24
  var cors_hosts = [];
25
25
  function getDomainPath(url) {
26
26
  return url.replace(domainReg, "$2/$3");
@@ -154,8 +154,9 @@ function cross_(jsonp, digest = noop, method, url, headers) {
154
154
  if (e.type === 'error') {
155
155
  e = createResponse("无法访问服务器!");
156
156
  }
157
+ headers = extend({}, _headers);
157
158
  for (var r of reforms) {
158
- var r = await reform.call(xhr, r, { method, url, status: xhr.status, headers: _headers }, fire, onerror1, e);
159
+ var r = await reform.call(xhr, r, { method, url, status: xhr.status, headers }, fire, onerror1, e);
159
160
  if (r === false) {
160
161
  return;
161
162
  }
@@ -330,7 +331,18 @@ function cross_(jsonp, digest = noop, method, url, headers) {
330
331
  }
331
332
  else if (cachedata.length && isEmpty(datas)) {
332
333
  var jsondata = mergedata(cachedata, parseKV);
333
- if (isform) {
334
+ if (realHeaders["Content-Type"]) {
335
+ if (/json$/i.test(realHeaders["Content-Type"])) {
336
+ datas = JSON.stringify(jsondata);
337
+ }
338
+ else {
339
+ if (hasFile(jsondata)) {
340
+ datas = kv2form(jsondata);
341
+ }
342
+ else datas = serialize(jsondata, '&', "=");
343
+ }
344
+ }
345
+ else if (isform) {
334
346
  var hasfile = hasFile(jsondata);
335
347
  if (hasfile) {
336
348
  datas = kv2form(jsondata);
@@ -383,7 +395,13 @@ function cross_(jsonp, digest = noop, method, url, headers) {
383
395
  }
384
396
  }
385
397
  else {
386
- _headers[k] = headers[k];
398
+ var k1 = RealHeadersKeys[k.toLowerCase()];
399
+ if (k1) {
400
+ realHeaders[k1] = headers[k];
401
+ }
402
+ else {
403
+ _headers[k] = headers[k];
404
+ }
387
405
  }
388
406
  }
389
407
  };
@@ -0,0 +1,23 @@
1
+ var tagReg = /<(\/?)([a-z][\w]*)\>/ig;
2
+ // 只应用一种效果,多种效果不能同时存在
3
+ function renderTags(str, getTag) {
4
+ var tagpath = [];
5
+ return String(str).replace(tagReg, function (_, e, c) {
6
+ if (!c || c.length < 3) return _;
7
+ var t = getTag(c, false);
8
+ if (!t) return _;
9
+ if (e) {
10
+ tagpath.pop();
11
+ c = tagpath[tagpath.length - 1];
12
+ }
13
+ else tagpath.push(c);
14
+ var res = [];
15
+ if (e) res.push(getTag());
16
+ if (c) res.push(getTag(c));
17
+ if (res.length) return res.join('');
18
+ return _;
19
+ });
20
+
21
+ }
22
+ renderTags.reg = tagReg;
23
+ module.exports = renderTags;
@@ -0,0 +1,8 @@
1
+ var shallowClone = function (origin, deep) {
2
+ if (--deep < 0) return origin;
3
+ if (!isObject(origin)) return origin;
4
+ var temp = origin instanceof Array ? [] : {};
5
+ if (deep > 0) for (var k in origin) temp[k] = shallowClone(origin[k], deep);
6
+ else for (var k in origin) temp[k] = origin[k];
7
+ return temp;
8
+ }
@@ -1,18 +1,27 @@
1
1
  var singleEqual = isSame;
2
- function shallowEqual(o1, o2) {
2
+ function shallowEqual(o1, o2, deep) {
3
3
  // 浅层比对,对内层对象不进行递归比对
4
- if (o1 === o2) return true;
4
+ if (--deep < 0) return singleEqual(o1, o2);
5
+ if (singleEqual(o1, o2)) return true;
5
6
  if (isObject(o1) && isObject(o2)) {
6
7
  var keys1 = Object.keys(o1), keys2 = Object.keys(o2);
7
8
  if (keys1.length !== keys2.length) return false;
8
9
  keys1.sort(), keys2.sort();
10
+ var rest = [];
9
11
  for (var cx = 0, dx = keys1.length; cx < dx; cx++) {
10
12
  var key1 = keys1[cx];
11
13
  var key2 = keys2[cx];
12
14
  if (key1 !== key2) return false;
13
- if (!singleEqual(o1[key1], o2[key2])) return false;
15
+ var v1 = o1[key1], v2 = o2[key2];
16
+ if (!singleEqual(v1, v2)) {
17
+ if (deep) rest.push(v1, v2);
18
+ else return false;
19
+ }
20
+ }
21
+ if (deep > 0) for (var cx = 0, dx = rest.length; cx < dx;) {
22
+ if (!shallowEqual(rest[cx++], rest[cx++], deep)) return false;
14
23
  }
15
24
  return true;
16
25
  }
17
- return singleEqual(o1, o2);
26
+ return false;
18
27
  }
@@ -1,3 +1,11 @@
1
+ var validators = {
2
+ email(text) {
3
+ var i = text.indexOf('@');
4
+ if (i < 0) return i18n`电子邮箱地址应包含符号“@”`;
5
+ if (i === 0) return i18n`@符号前应有内容`;
6
+ if (i === text.length - 1) return i18n`@符号后应有内容`;
7
+ }
8
+ }
1
9
  function valid(field, data) {
2
10
  var error;
3
11
  if (isEmpty(data[field.key])) {
@@ -6,8 +14,13 @@ function valid(field, data) {
6
14
  }
7
15
  return;
8
16
  }
9
- var tmp;
10
- if (tmp = /\:(\d+)(?:\.(\d+))?$/.exec(field.type)) {
17
+ var tmp = validators[field.type];
18
+ if (tmp) {
19
+ var value = data[field.key];
20
+ var error = tmp(String(value ?? ''));
21
+ if (error) return error;
22
+ }
23
+ else if (tmp = /\:(\d+)(?:\.(\d+))?$/.exec(field.type)) {
11
24
  var [, a, b] = tmp;
12
25
  var value = data[field.key];
13
26
  a = +a;
@@ -32,8 +45,10 @@ function valid(field, data) {
32
45
  if (e) return e;
33
46
  }
34
47
  if (field.options instanceof Function) {
35
- var e = field.options(data[field.key]);
36
- if (e) return e;
48
+ if (/^(input|text|html|password|raw)/.test(field.type)) {
49
+ var e = field.options(data[field.key]);
50
+ if (e) return e;
51
+ }
37
52
  }
38
53
  return error;
39
54
  }
@@ -514,6 +514,11 @@ Javascript.prototype.detour = function (o, ie) {
514
514
  context = null;
515
515
  return envs;
516
516
  }
517
+ var getfunc = function (o, k) {
518
+ var q = o.queue;
519
+ while (q && (!q.scoped || !q.scoped.used[k])) q = q.queue;
520
+ return q;
521
+ };
517
522
  var context = null, rootenvs = null;
518
523
  function detour(o, ie) {
519
524
  while (o) {
@@ -528,21 +533,29 @@ function detour(o, ie) {
528
533
  var m = /^[^\.\[\]]+/.exec(o.text);
529
534
  if (m) { context.avoidMap[m[0]] = true; }
530
535
  }
531
- if (/\?\./.test(text)) {
532
- if (/\?\.$/.test(text)) {
533
- o = snapExpressHead(o);
534
- var f = snapExpressFoot(o);
535
- var rest = [o];
536
- remove(o, f.prev);
537
- while (o !== f) {
538
- o = o.next;
539
- rest.push(o);
540
- }
541
- text = createString(rest);
536
+ if (/\?\.|\?\?/.test(text)) {
537
+ o = snapExpressHead(o);
538
+ var f = snapExpressFoot(o);
539
+ var rest = [o];
540
+ remove(o, f.prev);
541
+ while (o !== f) {
542
+ o = o.next;
543
+ rest.push(o);
542
544
  }
545
+ text = createString(rest);
543
546
  text = renderExpress(text, false);
544
547
  if (hasdot) text = "..." + text;
545
- o = replace(o, ...scan(text));
548
+ var o1 = scan(text);
549
+ var s1 = createScoped(o1);
550
+ if (s1.used.this) {
551
+ var s = getfunc(o, 'this').scoped;
552
+ s.used.this.push(...s1.used.this);
553
+ }
554
+ if (s1.used.arguments) {
555
+ var s = getfunc(o, 'arguments').scoped;
556
+ s.used.arguments.push(...s1.used.arguments);
557
+ };
558
+ o = replace(o, ...o1);
546
559
  continue;
547
560
  }
548
561
  text = text.replace(/\.([^\.\[\!\=\:]+)/g, (_, a) => ie === undefined || context.strap_reg.test(a) || /#/.test(a) ? `[${strings.recode(a)}]` : _);
@@ -401,7 +401,6 @@ var getFromScopeList = function (name, varsList, value = name) {
401
401
  };
402
402
  var removeSelectorSpace = a => a.trim().replace(/\s*([\+~\>])\s*/g, "$1");
403
403
  var fixBase = function (b, a) {
404
- var s = splitParams(a);
405
404
  return splitParams(a).map(a => {
406
405
  if (presets.test(a)) a = `@{${a}}`;
407
406
  var replaced = false;
@@ -426,9 +425,11 @@ function evalscoped(scoped, base = '') {
426
425
  base = removeSelectorSpace(base);
427
426
  var smaps = scoped.maps;
428
427
  var root = smaps[":root"], scope = smaps[":scope"];
428
+ var and = smaps["&"];
429
429
  var vars = extend(Object.create(null), scoped.vars);
430
430
  if (root) root.forEach(r => extend(vars, r.vars));
431
431
  if (scope) scope.forEach(s => extend(vars, s.vars));
432
+ if (and) and.forEach(a => extend(vars, a.vars));
432
433
  var vlist = [vars];
433
434
  var mlist = [macros];
434
435
  var clist = [smaps];
@@ -109,8 +109,8 @@
109
109
  case QUOTED:
110
110
  if (o.length || !o.text) {
111
111
  o.forEach(setcolor);
112
- o.entry = "<text>" + o.entry;
113
- o.leave = o.leave + "</text>";
112
+ o.entry = "<text>" + o.entry + "</text>";
113
+ o.leave = "<text>" + o.leave + "</text>";
114
114
  break;
115
115
  }
116
116
  case PIECE:
@@ -299,7 +299,7 @@
299
299
  }
300
300
  }
301
301
  if (minSpace > 0) codes = codes.map(c => /^\s+/.test(c) ? c.slice(minSpace) : c);
302
- return `<code type=${type}>${codes.join("<br/>").replace(/\t/g, Array(5).join('&ensp;')).replace(/\s/g, '&ensp;')}</code> `;
302
+ return `<code type=${type}>${codes.join("<br/>").replace(/\t/g, Array(5).join('&ensp;')).replace(/\s/g, '&ensp;')}</code>`;
303
303
  }
304
304
  codetext.encode = encode;
305
305
  </script>
@@ -168,7 +168,7 @@ function chat(title = '会话窗口') {
168
168
  }
169
169
  }
170
170
  };
171
- page.renders = [function () {
171
+ page.$renders = [function () {
172
172
  this.$scope.resize(this.$scope.body);
173
173
  }];
174
174
  page.localid = localid;
@@ -4,6 +4,7 @@
4
4
  <div body>
5
5
  <field v-if="!f.hidden" -repeat="f in fields" ng-src="[f,data]"></field>
6
6
  </div>
7
+ <scrollbar></scrollbar>
7
8
  <div foot>
8
9
  <btn @click="remove()" class="white">取消</btn>
9
10
  <button type="submit">保存</button>
@@ -11,6 +11,7 @@ function main(title, { submit }, { data: origin, fields, }) {
11
11
  fields,
12
12
  title,
13
13
  origin,
14
+ scrollbar,
14
15
  data: item,
15
16
  remove() {
16
17
  remove(page);
@@ -19,7 +20,7 @@ function main(title, { submit }, { data: origin, fields, }) {
19
20
  on('submit')(page, async function (e) {
20
21
  e.preventDefault();
21
22
  var res = await submit(item, fields, origin);
22
- if (typeof res === 'string') {
23
+ if (typeof res === 'string' && res) {
23
24
  return alert(res, 'error');
24
25
  }
25
26
  if (res === false) return;
@@ -31,7 +32,7 @@ function main(title, { submit }, { data: origin, fields, }) {
31
32
  await submit(item, fields, origin);
32
33
  dispatch(this, 'submited');
33
34
  });
34
- on("append")(page, lazy(function () {
35
+ on("mounted")(page, lazy(function () {
35
36
  page.querySelector("input").focus();
36
37
  }));
37
38
  return page;
@@ -53,6 +53,6 @@ function bindScroll(titlebar, page) {
53
53
  setOpacity(label, 1 - (titlebar.offsetHeight - topHeight) / (offsetHeight - topHeight));
54
54
  return {};
55
55
  };
56
- if (!page.renders) page.renders = [];
56
+ if (!page.$renders) page.$renders = [];
57
57
  page.onscroll = refresh;
58
58
  }
package/coms/kugou/krc.js CHANGED
@@ -72,7 +72,7 @@ function createLRC(lrc) {
72
72
  setClass(krcList, index);
73
73
  }
74
74
  }
75
- if (ele && firstChild && firstChild.isMounted) {
75
+ if (ele && firstChild && firstChild.$mounted) {
76
76
  var marginTop = (firstChild.parentNode.offsetHeight - ele.offsetHeight >> 1) - ele.offsetTop + firstChild.offsetTop;
77
77
  css(firstChild, `margin-top:${marginTop | 0}px;`);
78
78
  }
@@ -140,7 +140,7 @@ function createKRC(krc) {
140
140
  var current_row_word = current_words[current_row_index];
141
141
  var ele = krcList[index];
142
142
  var firstChild = krcList[0];
143
- if (ele && firstChild && firstChild.isMounted) {
143
+ if (ele && firstChild && firstChild.$mounted) {
144
144
  var marginTop = (firstChild.parentNode.offsetHeight - ele.offsetHeight >> 1) - ele.offsetTop + firstChild.offsetTop;
145
145
  if (index > 0) {
146
146
  if (markerLabel.parentNode !== ele) {
@@ -38,12 +38,12 @@ function setCurrentPage(page) {
38
38
  var currentLayer = getCurrentLayer();
39
39
  if (page !== leftPage) {
40
40
  if (currentLayer !== leftLayer) {
41
- if (!leftPage.isMounted) appendChild(leftLayer, leftPage);
41
+ if (!leftPage.$mounted) appendChild(leftLayer, leftPage);
42
42
  } else {
43
43
  remove(leftPage, false);
44
44
  }
45
45
  if (page.parentNode !== currentLayer) appendChild(currentLayer, page, false);
46
- } else if (!leftPage.isMounted) {
46
+ } else if (!leftPage.$mounted) {
47
47
  appendChild(leftLayer, leftPage, false);
48
48
  }
49
49
  }
@@ -54,16 +54,16 @@ function main(_leftPage) {
54
54
  layer.layer = function (child, old) {
55
55
  remove(old);
56
56
  if (child === leftPage) {
57
- if (!leftPage.isMounted) appendChild(leftLayer, child);
57
+ if (!leftPage.$mounted) appendChild(leftLayer, child);
58
58
  } else if (child) {
59
59
  var currentLayer = getCurrentLayer();
60
60
  appendChild(currentLayer, child);
61
61
  if (currentLayer === leftLayer) {
62
62
  if (arguments.length > 1) remove(leftPage);
63
- } else if (!leftPage.isMounted) {
63
+ } else if (!leftPage.$mounted) {
64
64
  appendChild(leftLayer, leftPage);
65
65
  }
66
66
  } else {
67
- if (!leftPage.isMounted) appendChild(leftLayer, leftPage);
67
+ if (!leftPage.$mounted) appendChild(leftLayer, leftPage);
68
68
  }
69
69
  };
@@ -0,0 +1,290 @@
1
+ var acmebase = `https://acme-v02.api.letsencrypt.org/`;
2
+ var data1 = data.enrich(parseYML(`
3
+ ${acmebase}:
4
+ directory: get directory
5
+ ${acmebase}acme/ Content-Type=application/jose+json:
6
+ key-change: get key-change
7
+ new-account: post:^efront-location new-acct
8
+ get-account: get acct/:aid
9
+ new-order: post:^efront-location new-order
10
+ get-order|: get order/:aid/:oid
11
+ new-nonce: head:^Replay-Nonce new-nonce
12
+ revert-cert: post:^efront-location revert-cert
13
+ `));
14
+ var publicKey, privateKey;
15
+ var private_key, public_key;
16
+ var RSASSA_PKCS1_v1_5 = "RSASSA-PKCS1-v1_5";
17
+ var base64url = function (params) {
18
+ var data = JSON.stringify(params);
19
+ return toBase64(encodeUTF8(data), true);
20
+ };
21
+ var accountApi = await data1.getApi('get-account');
22
+ var orderApi = await data1.getApi('get-order');
23
+ var wrapParams = async function (url, params, usejwk = false) {
24
+ var protected = {
25
+ url
26
+ };
27
+ var jwk = await subtle.exportKey("jwk", publicKey);
28
+ protected.alg = jwk.alg;
29
+ if (usejwk) {
30
+ protected.jwk = {
31
+ e: jwk.e,
32
+ kty: jwk.kty,
33
+ n: jwk.n
34
+ };
35
+ }
36
+ else {
37
+ protected.kid = acme2.kid;
38
+ }
39
+ protected.nonce = await data1.from("new-nonce");
40
+ protected = base64url(protected);
41
+ var payload = isHandled(params) ? base64url(params) : '';
42
+ var params = {
43
+ protected,
44
+ payload,
45
+ signature: toBase64(new Uint8Array(await subtle.sign({ name: RSASSA_PKCS1_v1_5, saltLength: 32 }, privateKey, new Uint8Array(encodeUTF8([protected, '.', payload].join(''))))), true)
46
+ };
47
+ return params;
48
+ }
49
+ var request = async function (id, params) {
50
+ var api = await data1.getApi(id);
51
+ if (/^(get|head)$/i.test(api.method)) return data1.from(id, params);
52
+ var [url, rest] = data.prepareURL(api.base + api.path, params);
53
+ var restparams = {};
54
+ rest.forEach(k => { restparams[k] = params[k]; delete params[k]; });
55
+ var params = await wrapParams(url, params, /new-account|revert-cert/i.test(id));
56
+ extend(params, restparams);
57
+ var account = await data1.from(id, params);
58
+ return account;
59
+ };
60
+ var ASN1 = function (type) {
61
+ var length = 0;
62
+ var bytesarr = [];
63
+ for (var cx = 1, dx = arguments.length; cx < dx; cx++) {
64
+ var bytes = arguments[cx];
65
+ if (bytes.constructor !== Array) {
66
+ bytes = Array.apply(null, bytes);
67
+ }
68
+ bytesarr.push(bytes);
69
+ length += bytes.length;
70
+ }
71
+ var asn1 = [type];
72
+ if (length === (2 << 8 | 36)) console.log(arguments)
73
+ if (length > 127) {
74
+ var nums = [];
75
+ while (length > 0) {
76
+ nums.unshift(length & 0xff);
77
+ length = length >>> 8;
78
+ }
79
+ asn1.push(0x80 | nums.length, ...nums);
80
+ }
81
+ else {
82
+ asn1.push(length);
83
+ }
84
+ asn1 = asn1.concat(...bytesarr);
85
+ return asn1;
86
+ };
87
+ var packUint = function (bytes) {
88
+ if (bytes[0] & 0x80) {
89
+ return ASN1(0x02, [0], bytes);
90
+ }
91
+ return ASN1(0x02, bytes);
92
+ };
93
+ var packBits = function (bytes) {
94
+ return ASN1(0x03, [0x00], bytes);
95
+ };
96
+ var packPublicKey = function (jwk) {
97
+ var n = packUint(fromBase64(jwk.n));
98
+ var e = packUint(fromBase64(jwk.e));
99
+ var p = ASN1(0x30, n, e);
100
+ return ASN1(0x30, ASN1(0x30,
101
+ ASN1(0x06, [0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01]),
102
+ ASN1(0x05),
103
+ ), packBits(p));
104
+ };
105
+ var packCSR = function (asn1pubkey, domains) {
106
+ return ASN1(0x30,
107
+ packUint([0x00]),
108
+ ASN1(0x30, ASN1(0x31, ASN1(0x30,
109
+ ASN1(0x06, [0x55, 0x04, 0x03]),
110
+ ASN1(0x0c, encodeUTF8(domains[0]))
111
+ ))),
112
+ asn1pubkey,
113
+ ASN1(0xa0, ASN1(0x30,
114
+ ASN1(0x06, [0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x0e]),
115
+ ASN1(0x31, ASN1(0x30, ASN1(0x30,
116
+ ASN1(0x06, [0x55, 0x1d, 0x11]),
117
+ ASN1(0x04, ASN1(0x30,
118
+ ...domains.map(d => ASN1(0x82, encodeUTF8(d)))
119
+ ))
120
+ )))
121
+ ))
122
+ )
123
+ }
124
+
125
+ var createCSR = async function (domains, private_key) {
126
+ var privateKey = await subtle.importKey("pkcs8", new Uint8Array(fromBase64(private_key)), {
127
+ name: RSASSA_PKCS1_v1_5,
128
+ hash: "SHA-256",
129
+ }, true, ["sign"]);
130
+ var jwk = await subtle.exportKey("jwk", privateKey);
131
+ var pubkey = packPublicKey(jwk);
132
+ var request = packCSR(pubkey, domains);
133
+ var sign = new Uint8Array(await subtle.sign({ name: RSASSA_PKCS1_v1_5, saltLength: 32 }, privateKey, new Uint8Array(request)));
134
+ var sty = ASN1(0x30,
135
+ ASN1(0x06, [0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b]),
136
+ ASN1(0x05)
137
+ );
138
+ return ASN1(0x30, request,
139
+ sty,
140
+ packBits(sign)
141
+ );
142
+ };
143
+ var makeKeyPair = async function (modulusLength = 2048) {
144
+ //https://www.w3.org/TR/WebCryptoAPI/ 第20章 只有RSASSA-PKCS1-v1_5的jwk的alg才是rs256
145
+ var k = await subtle.generateKey({
146
+ name: RSASSA_PKCS1_v1_5,
147
+ modulusLength,
148
+ publicExponent: new Uint8Array([1, 0, 1]),
149
+ hash: "SHA-256",
150
+ }, true, ["sign", "verify"]);
151
+ var { publicKey, privateKey } = k;
152
+ var private_key = await subtle.exportKey("pkcs8", privateKey);
153
+ var public_key = await subtle.exportKey("spki", publicKey);
154
+ private_key = toBase64(new Uint8Array(private_key));
155
+ public_key = toBase64(new Uint8Array(public_key));
156
+ return [private_key, public_key];
157
+ };
158
+ var subtle = this.crypto?.subtle;
159
+ var acme2 = new class {
160
+ email = '';
161
+ kid = '';
162
+ aid = '';
163
+ oid = '';
164
+ domain = '';
165
+ termsOfServiceAgreed = false;
166
+ orders = [];
167
+ public_key = '';
168
+ get enabled() {
169
+ return !!subtle;
170
+ }
171
+ async requestURL(url, params) {
172
+ params = await wrapParams(url, params);
173
+ var res = data.postURL(url, params);
174
+ if (res.loading) res.loading.setRequestHeader("Content-Type", "application/jose+json");
175
+ return res;
176
+ }
177
+ async initUnique() {
178
+ [private_key, public_key] = await makeKeyPair(4096);
179
+ var unique = [private_key, public_key].join(',');
180
+ await acme2.makeUnique(unique);
181
+ }
182
+ async makeUnique(unique) {
183
+ if (!unique) return;
184
+ var avme2 = this;
185
+ var extra;
186
+ [private_key, public_key, extra] = unique.split(',');
187
+ if (extra) {
188
+ extra = JSON.parse(decodeUTF8(fromBase64(extra)));
189
+ avme2.email = extra.email;
190
+ avme2.kid = extra.kid;
191
+ if (extra.kid) {
192
+ var account = data.getUrlParamsForApi(accountApi, extra.kid);
193
+ avme2.aid = account.aid;
194
+ }
195
+ avme2.domain = extra.domain;
196
+ avme2.termsOfServiceAgreed = extra.termsOfServiceAgreed;
197
+ avme2.orders = extra.orders;
198
+ }
199
+ try {
200
+ privateKey = await subtle.importKey("pkcs8", new Uint8Array(fromBase64(private_key)), {
201
+ name: RSASSA_PKCS1_v1_5,
202
+ hash: "SHA-256",
203
+ }, true, ["sign"]);
204
+ publicKey = await subtle.importKey("spki", new Uint8Array(fromBase64(public_key)), {
205
+ name: RSASSA_PKCS1_v1_5,
206
+ hash: "SHA-256",
207
+ }, true, ["verify"]);
208
+
209
+ avme2.public_key = public_key;
210
+ } catch (e) { alert("加载服务器公钥异常!", "error"); throw e }
211
+ }
212
+ pickUnique() {
213
+ var avme2 = this;
214
+ var extra = {
215
+ kid: avme2.kid,
216
+ email: avme2.email,
217
+ domain: avme2.domain,
218
+ orders: avme2.orders,
219
+ termsOfServiceAgreed: avme2.termsOfServiceAgreed
220
+ };
221
+ return [private_key, public_key, base64url(extra)].join(",");
222
+ }
223
+ async getTermsOfService() {
224
+ var data = await data1.from("directory");
225
+ var termsOfService = data?.meta?.termsOfService;
226
+ return termsOfService;
227
+ }
228
+ async newAccount(params) {
229
+ var account = await request("new-account", {
230
+ "contact": [
231
+ "mailto:" + params.email
232
+ ],
233
+ // onlyReturnExisting: false,// 可选
234
+ // externalAccountBinding: {},// 可选
235
+ "termsOfServiceAgreed": params.termsOfServiceAgreed
236
+ });
237
+ this.email = params.email;
238
+ this.termsOfServiceAgreed = params.termsOfServiceAgreed;
239
+ this.kid = account;
240
+ var a = data.getUrlParamsForApi(accountApi, account);
241
+ this.aid = a.aid;
242
+ alert('创建成功!', 'success');
243
+ return account;
244
+ }
245
+ async newOrder(params) {
246
+ if (!this.orders) this.orders = [];
247
+ if (this.orders.length > 20) return alert("请删除一些订单后再试!", "error");
248
+ var params = {
249
+ "identifiers": params.domain.trim().split(/[,;+,;\r\n\u2029\u2028\s]+/).map(n => {
250
+ if (/^\d+(\.\d+){3}$/.test(n)) return { type: "ipv4", value: n };
251
+ return { type: "dns", value: n };
252
+ })
253
+ };
254
+ var order = await request("new-order", params);
255
+ this.domain = params.domain;
256
+ var i = this.orders.indexOf(order);
257
+ if (i >= 0) this.orders.splice(i, 1);
258
+ this.orders = [order].concat(this.orders);
259
+ return order;
260
+ }
261
+ parseOrder(o) {
262
+ if (typeof o !== 'string') return o;
263
+ var order = data.getUrlParamsForApi(orderApi, o);
264
+ order.url = o;
265
+ order.name = order.oid;
266
+ return order;
267
+ }
268
+ async getOrder(o) {
269
+ var r = await data.fromURL(o.url);
270
+ if (r.expires) r.expires = new Date(r.expires);
271
+ return r;
272
+ }
273
+ async thumbprint() {
274
+ var jwk = await subtle.exportKey('jwk', publicKey);
275
+ jwk = `{"e":"${jwk.e}","kty":"${jwk.kty}","n":"${jwk.n}"}`;
276
+ var thumb = await subtle.digest("SHA-256", new Uint8Array(encodeUTF8(jwk)));
277
+ thumb = toBase64(new Uint8Array(thumb), true);
278
+ return thumb;
279
+ }
280
+ async createKeyPair() {
281
+ return makeKeyPair(2048);
282
+ }
283
+ async createCSR(domains, private_key) {
284
+ var csr = await createCSR(domains, private_key);
285
+ return toBase64(csr, true);
286
+ }
287
+ async audit(url) {
288
+ return data.fromURL(url);
289
+ }
290
+ }