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.
- package/#/345/233/275/351/231/205/345/214/226.yml +83 -5
- package/apps/pivot/api.yml +4 -0
- package/apps/pivot/cert/edit.js +1 -0
- package/apps/pivot/cert/list.js +9 -0
- package/apps/pivot/cert/main.xht +188 -0
- package/apps/pivot/cert/orders.xht +232 -0
- package/apps/pivot/cert/update.xht +7 -0
- package/apps/pivot/menu.yml +1 -0
- package/coms/basic/assert.js +40 -16
- package/coms/basic/cross_.js +22 -4
- package/coms/basic/renderTags.js +23 -0
- package/coms/basic/shallowClone.js +8 -0
- package/coms/basic/shallowEqual.js +13 -4
- package/coms/basic/valid.js +19 -4
- package/coms/compile/Javascript.js +25 -12
- package/coms/compile//347/264/240/351/246/250.js +2 -1
- package/coms/docs/codetext.xht +3 -3
- package/coms/frame/chat.js +1 -1
- package/coms/frame/edit.html +1 -0
- package/coms/frame/edit.js +3 -2
- package/coms/kugou/bindScroll.js +1 -1
- package/coms/kugou/krc.js +2 -2
- package/coms/layer/leftCenter.js +5 -5
- package/coms/pivot/acme2.js +290 -0
- package/coms/pivot/pedit.js +13 -5
- package/coms/pivot/plist.js +12 -5
- package/coms/reptile/colored_console.js +5 -17
- package/coms/zimoli/appendChild.js +3 -2
- package/coms/zimoli/autofocus.js +2 -2
- package/coms/zimoli/button.less +5 -3
- package/coms/zimoli/checker.js +34 -15
- package/coms/zimoli/checker.less +2 -3
- package/coms/zimoli/container.js +26 -15
- package/coms/zimoli/data.js +124 -169
- package/coms/zimoli/field.js +3 -3
- package/coms/zimoli/field.less +8 -2
- package/coms/zimoli/filterTime.js +39 -8
- package/coms/zimoli/fromBase64.js +2 -0
- package/coms/zimoli/grid.js +2 -2
- package/coms/zimoli/isMounted.js +3 -3
- package/coms/zimoli/list.js +5 -5
- package/coms/zimoli/maps.js +1 -1
- package/coms/zimoli/menuList.js +1 -1
- package/coms/zimoli/model.js +61 -8
- package/coms/zimoli/on.js +4 -4
- package/coms/zimoli/remove.js +3 -3
- package/coms/zimoli/render.js +25 -33
- package/coms/zimoli/scrollbar.js +54 -19
- package/coms/zimoli/scrollbar.less +14 -2
- package/coms/zimoli/scrollbar_test.less +1 -0
- package/coms/zimoli/select.js +3 -3
- package/coms/zimoli/table.js +1 -1
- package/coms/zimoli/toBase64.js +16 -6
- package/coms/zimoli/view.js +24 -14
- package/coms/zimoli/view.less +6 -4
- package/coms/zimoli/watch.js +1 -1
- package/docs/loader.js +1 -1
- package/docs//347/273/204/344/273/266.xht +0 -1
- package/package.json +1 -1
- package/public/efront.js +1 -1
package/coms/basic/cross_.js
CHANGED
|
@@ -20,7 +20,7 @@ var setHost = function (host) {
|
|
|
20
20
|
base = host;
|
|
21
21
|
encrypt = null;
|
|
22
22
|
};
|
|
23
|
-
var
|
|
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
|
|
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 (
|
|
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
|
-
|
|
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 (
|
|
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
|
-
|
|
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
|
|
26
|
+
return false;
|
|
18
27
|
}
|
package/coms/basic/valid.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
36
|
-
|
|
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 (
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
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
|
-
|
|
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];
|
package/coms/docs/codetext.xht
CHANGED
|
@@ -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(' ')).replace(/\s/g, ' ')}</code
|
|
302
|
+
return `<code type=${type}>${codes.join("<br/>").replace(/\t/g, Array(5).join(' ')).replace(/\s/g, ' ')}</code>`;
|
|
303
303
|
}
|
|
304
304
|
codetext.encode = encode;
|
|
305
305
|
</script>
|
package/coms/frame/chat.js
CHANGED
package/coms/frame/edit.html
CHANGED
package/coms/frame/edit.js
CHANGED
|
@@ -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("
|
|
35
|
+
on("mounted")(page, lazy(function () {
|
|
35
36
|
page.querySelector("input").focus();
|
|
36
37
|
}));
|
|
37
38
|
return page;
|
package/coms/kugou/bindScroll.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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) {
|
package/coms/layer/leftCenter.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
63
|
+
} else if (!leftPage.$mounted) {
|
|
64
64
|
appendChild(leftLayer, leftPage);
|
|
65
65
|
}
|
|
66
66
|
} else {
|
|
67
|
-
if (!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
|
+
}
|