oak-backend-base 4.1.8 → 4.1.9

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.
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
+ const crypto_1 = require("crypto");
4
5
  const types_1 = require("oak-domain/lib/types");
5
6
  const relationPath_1 = require("oak-domain/lib/utils/relationPath");
6
7
  const assert_1 = tslib_1.__importDefault(require("assert"));
@@ -11,6 +12,31 @@ const uuid_1 = require("oak-domain/lib/utils/uuid");
11
12
  const lodash_2 = require("lodash");
12
13
  const OAK_SYNC_HEADER_ENTITY = 'oak-sync-entity';
13
14
  const OAK_SYNC_HEADER_ENTITY_ID = 'oak-sync-entity-id';
15
+ const OAK_SYNC_HEADER_TIMESTAMP = 'oak-sync-timestamp';
16
+ const OAK_SYNC_HEADER_NONCE = 'oak-sync-nonce';
17
+ const OAK_SYNC_HEADER_SIGN = 'oak-sync-sign';
18
+ function generateSignStr(body, ts, nonce) {
19
+ return `${body}\n${ts}\n${nonce}`;
20
+ }
21
+ async function sign(privateKey, body) {
22
+ const ts = Date.now();
23
+ const nonce = await (0, uuid_1.generateNewIdAsync)();
24
+ const sign2 = (0, crypto_1.createSign)('SHA256');
25
+ sign2.update(generateSignStr(body, `${ts}`, nonce));
26
+ sign2.end();
27
+ const signature = sign2.sign(privateKey).toString('hex');
28
+ return {
29
+ ts,
30
+ nonce,
31
+ signature,
32
+ };
33
+ }
34
+ function verify(publicKey, body, ts, nonce, signature) {
35
+ const verify2 = (0, crypto_1.createVerify)('SHA256');
36
+ verify2.update(generateSignStr(body, ts, nonce));
37
+ verify2.end();
38
+ return verify2.verify(publicKey, signature, 'hex');
39
+ }
14
40
  class Synchronizer {
15
41
  config;
16
42
  schema;
@@ -31,14 +57,19 @@ class Synchronizer {
31
57
  const finalApi = (0, path_1.join)(api, selfEncryptInfo.id);
32
58
  channel.queue = [];
33
59
  try {
60
+ const body = JSON.stringify(opers);
61
+ const { ts, nonce, signature } = await sign(selfEncryptInfo.privateKey, body);
34
62
  const res = await fetch(finalApi, {
35
63
  method: 'post',
36
64
  headers: {
37
65
  'Content-Type': 'application/json',
38
66
  [OAK_SYNC_HEADER_ENTITY]: entity,
39
67
  [OAK_SYNC_HEADER_ENTITY_ID]: entityId,
68
+ [OAK_SYNC_HEADER_TIMESTAMP]: `${ts}`,
69
+ [OAK_SYNC_HEADER_NONCE]: nonce,
70
+ [OAK_SYNC_HEADER_SIGN]: signature,
40
71
  },
41
- body: JSON.stringify(opers),
72
+ body,
42
73
  });
43
74
  if (res.status !== 200) {
44
75
  throw new Error(`sync数据时,访问api「${finalApi}」的结果不是200。「${res.status}」`);
@@ -462,7 +493,7 @@ class Synchronizer {
462
493
  fn: async (context, params, headers, req, body) => {
463
494
  // body中是传过来的oper数组信息
464
495
  const { entity, entityId } = params;
465
- const { [OAK_SYNC_HEADER_ENTITY]: meEntity, [OAK_SYNC_HEADER_ENTITY_ID]: meEntityId } = headers;
496
+ const { [OAK_SYNC_HEADER_ENTITY]: meEntity, [OAK_SYNC_HEADER_ENTITY_ID]: meEntityId, [OAK_SYNC_HEADER_NONCE]: syncNonce, [OAK_SYNC_HEADER_TIMESTAMP]: syncTs, [OAK_SYNC_HEADER_SIGN]: syncSign } = headers;
466
497
  if (process.env.NODE_ENV === 'development') {
467
498
  console.log('接收到来自远端的sync数据', entity, JSON.stringify(body));
468
499
  }
@@ -493,7 +524,13 @@ class Synchronizer {
493
524
  if (cxtInfo) {
494
525
  await context.initialize(cxtInfo);
495
526
  }
496
- // todo 解密
527
+ const syncTimestamp = parseInt(syncTs, 10);
528
+ if (!(Date.now() - syncTimestamp < 10000)) {
529
+ throw new Error('同步时钟漂移过长');
530
+ }
531
+ if (!verify(publicKey, JSON.stringify(body), syncTs, syncNonce, syncSign)) {
532
+ throw new Error('sync验签失败');
533
+ }
497
534
  const opers = body;
498
535
  const ids = opers.map(ele => ele.id);
499
536
  const existsIds = (await context.select('oper', {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oak-backend-base",
3
- "version": "4.1.8",
3
+ "version": "4.1.9",
4
4
  "description": "oak-backend-base",
5
5
  "main": "lib/index",
6
6
  "author": {