@chevre/domain 23.2.0-alpha.43 → 23.2.0-alpha.45

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.
@@ -0,0 +1,49 @@
1
+ // tslint:disable:object-literal-key-quotes no-console
2
+ import * as mongoose from 'mongoose';
3
+
4
+ import { chevre } from '../../../../lib/index';
5
+
6
+ async function testGeneration() {
7
+ await mongoose.connect(<string>process.env.MONGOLAB_URI, { autoIndex: false });
8
+
9
+ const confirmationNumberRepo = await chevre.repository.ConfirmationNumber.createInstance({
10
+ connection: mongoose.connection
11
+ });
12
+
13
+ const ts = new Date(); // 同一ミリ秒固定
14
+ const results: Record<string, string>[] = [];
15
+
16
+ console.log(`--- 同一ミリ秒(${ts})内での連続生成テスト ---`);
17
+
18
+ // tslint:disable-next-line:no-magic-numbers
19
+ for (let i = 0; i < 100; i += 1) {
20
+ // 同一ミリ秒内でシーケンス(00-99)だけが変わる状況を再現
21
+ const confirmationNumber = await confirmationNumberRepo.publish({
22
+ orderDate: ts
23
+
24
+ });
25
+
26
+ // 復号して元のデータに戻るかチェック
27
+ const decoded = await confirmationNumberRepo.decrypt(confirmationNumber);
28
+ const decodedShouldBe = `${i.toString()
29
+ // tslint:disable-next-line:no-magic-numbers
30
+ .padStart(4, '0')}`;
31
+ const isSuccess = decoded === decodedShouldBe;
32
+
33
+ results.push({
34
+ timestamp: ts.valueOf()
35
+ .toString(),
36
+ 'シーケンス': i.toString(),
37
+ '生成された番号': confirmationNumber,
38
+ // tslint:disable-next-line:no-magic-numbers
39
+ 'ソルト': confirmationNumber[0],
40
+ '復号結果': decoded,
41
+ '復号結果(should be)': decodedShouldBe,
42
+ '復号確認': isSuccess ? '✅OK' : '❌NG'
43
+ });
44
+ }
45
+
46
+ console.table(results);
47
+ }
48
+
49
+ testGeneration();
@@ -3,42 +3,47 @@ import * as mongoose from 'mongoose';
3
3
 
4
4
  import { chevre } from '../../../../lib/index';
5
5
 
6
- const { INFORM_TASK_AGG_URL } = process.env;
7
- if (typeof INFORM_TASK_AGG_URL !== 'string') {
8
- throw new Error('INFORM_TASK_AGG_URL required');
9
- }
6
+ const { FPE_SECRET } = process.env;
10
7
 
11
8
  async function main() {
9
+ if (typeof FPE_SECRET !== 'string') {
10
+ throw new Error('FPE_SECRET required');
11
+ }
12
+
12
13
  await mongoose.connect(<string>process.env.MONGOLAB_URI, { autoIndex: false });
13
14
 
14
15
  const settingRepo = await chevre.repository.Setting.createInstance(mongoose.connection);
15
- // const setting = await settingRepo.findOne({ project: { id: { $eq: '*' } } }, ['onTaskStatusChanged']);
16
- // update
17
- await settingRepo.updateByProject(
18
- { project: { id: { $eq: '*' } } },
19
- {
20
- onTaskStatusChanged: {
21
- informTask: [{
22
- recipient: {
23
- name: 'Aggregation Service',
24
- url: INFORM_TASK_AGG_URL
25
- }
26
- }],
27
- informTaskNames: [
28
- chevre.factory.taskName.Pay,
29
- chevre.factory.taskName.InvalidatePaymentUrl,
30
- chevre.factory.taskName.Refund,
31
- chevre.factory.taskName.VoidPayment
32
- // chevre.factory.taskName.ConfirmReserveTransaction
33
- ],
34
- informTaskStatuses: [
35
- chevre.factory.taskStatus.Aborted
36
- // chevre.factory.taskStatus.Running
37
- ]
16
+
17
+ const setting = await settingRepo.findOne({ project: { id: { $eq: '*' } } }, ['orderNumber', 'transactionNumber']);
18
+ console.log(setting);
19
+
20
+ if (typeof setting?.orderNumber?.version !== 'string') {
21
+ console.log('updating orderNumber...');
22
+ await settingRepo.updateByProject(
23
+ { project: { id: { $eq: '*' } } },
24
+ {
25
+ orderNumber: {
26
+ fpeSecret: FPE_SECRET,
27
+ version: 'A'
28
+ }
29
+ }
30
+ );
31
+ console.log('orderNumber updated.');
32
+ }
33
+
34
+ if (typeof setting?.transactionNumber?.version !== 'string') {
35
+ console.log('updating orderNumber...');
36
+ await settingRepo.updateByProject(
37
+ { project: { id: { $eq: '*' } } },
38
+ {
39
+ transactionNumber: {
40
+ fpeSecret: FPE_SECRET,
41
+ version: '1'
42
+ }
38
43
  }
39
- }
40
- );
41
- console.log('updated.');
44
+ );
45
+ console.log('transactionNumber updated.');
46
+ }
42
47
  }
43
48
 
44
49
  main()
@@ -16,4 +16,5 @@ export declare class ConfirmationNumberRepo {
16
16
  publish(params: {
17
17
  orderDate: Date;
18
18
  }): Promise<string>;
19
+ decrypt(id: string): Promise<string>;
19
20
  }
@@ -10,12 +10,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.ConfirmationNumberRepo = void 0;
13
- const cdigit = require("cdigit");
13
+ // import * as cdigit from 'cdigit';
14
+ const crypto_1 = require("crypto");
14
15
  const moment = require("moment-timezone");
15
- // import { RedisClientType } from 'redis';
16
+ const fpe2Module = require("node-fpe-v2");
17
+ // 型定義が新しいtypescriptに適合しないので、強制的に型変更
18
+ const fpe2 = fpe2Module;
16
19
  // tslint:disable-next-line:no-require-imports no-var-requires
17
- const fpe = require('node-fpe-v1');
18
- // import { createSchema as createSettingSchema, modelName as settingModelName } from './mongoose/schemas/setting';
20
+ // const fpe = require('node-fpe-v1');
19
21
  const transactionNumber_1 = require("./mongoose/schemas/transactionNumber");
20
22
  const transactionNumberCounter_1 = require("./transactionNumberCounter");
21
23
  const CONFIRMATION_NUMBER_MIN_LENGH = 4;
@@ -25,8 +27,6 @@ const TIMEZONE = 'Asia/Tokyo';
25
27
  */
26
28
  class ConfirmationNumberRepo {
27
29
  constructor(params) {
28
- // const { connection } = params;
29
- // this.settingModel = connection.model(settingModelName, createSettingSchema());
30
30
  this.counterRepo = new transactionNumberCounter_1.TransactionNumberCounterRepo(params);
31
31
  }
32
32
  static alignDigits(params) {
@@ -37,32 +37,32 @@ class ConfirmationNumberRepo {
37
37
  }
38
38
  return aligndNumber;
39
39
  }
40
- // private static createKey(params: {
41
- // orderDate: Date;
42
- // }): string {
43
- // return util.format(
44
- // '%s:%s',
45
- // ConfirmationNumberRepo.REDIS_KEY_PREFIX_NEW,
46
- // moment(params.orderDate)
47
- // .tz(TIMEZONE)
48
- // .format('YYMM')
49
- // );
50
- // }
51
40
  static createDataFeedIdentifier(params) {
52
41
  return moment(params.orderDate)
53
42
  .tz(TIMEZONE)
54
43
  .format('YYMM');
55
44
  }
45
+ // private static count2confirmationNumberUsingFPE1(params: { count: number }): string {
46
+ // // 桁数調整
47
+ // let confirmationNumber: string = ConfirmationNumberRepo.alignDigits(params.count);
48
+ // // checkdigit
49
+ // const cd = cdigit.luhn.compute(confirmationNumber);
50
+ // // debug('check digit:', cd);
51
+ // confirmationNumber = fpe({ password: cd })
52
+ // .encrypt(confirmationNumber);
53
+ // confirmationNumber = `${cd}${confirmationNumber}`;
54
+ // return confirmationNumber;
55
+ // }
56
+ // reimplement using fpe2(2026-02-02~)
56
57
  static count2confirmationNumber(params) {
57
58
  // 桁数調整
58
- let confirmationNumber = ConfirmationNumberRepo.alignDigits(params.count);
59
- // checkdigit
60
- const cd = cdigit.luhn.compute(confirmationNumber);
61
- // debug('check digit:', cd);
62
- confirmationNumber = fpe({ password: cd })
63
- .encrypt(confirmationNumber);
64
- confirmationNumber = `${cd}${confirmationNumber}`;
65
- return confirmationNumber;
59
+ const rawBody = ConfirmationNumberRepo.alignDigits(params.count);
60
+ // tslint:disable-next-line:no-magic-numbers
61
+ const saltDigit = (0, crypto_1.randomInt)(0, 10);
62
+ const saltStr = saltDigit.toString();
63
+ const cipher = fpe2({ secret: `${saltStr}` });
64
+ const encryptedBody = cipher.encrypt(rawBody);
65
+ return `${saltStr}${encryptedBody}`;
66
66
  }
67
67
  /**
68
68
  * 発行する
@@ -87,5 +87,12 @@ class ConfirmationNumberRepo {
87
87
  return ConfirmationNumberRepo.count2confirmationNumber({ count: incrReply });
88
88
  });
89
89
  }
90
+ // tslint:disable-next-line:prefer-function-over-method
91
+ decrypt(id) {
92
+ return __awaiter(this, void 0, void 0, function* () {
93
+ const cipher = fpe2({ secret: id[0] });
94
+ return cipher.decrypt(id.slice(1));
95
+ });
96
+ }
90
97
  }
91
98
  exports.ConfirmationNumberRepo = ConfirmationNumberRepo;
@@ -22,7 +22,7 @@ export declare class SettingRepo {
22
22
  $eq: string;
23
23
  };
24
24
  };
25
- }, update: Pick<ISetting, 'onEventChanged' | 'onReservationStatusChanged' | 'onTaskStatusChanged' | 'onResourceUpdated' | 'defaultSenderEmail' | 'useInformResourceTypes' | 'userPoolIdNew' | 'userPoolIdOld' | 'storage' | 'quota' | 'triggerWebhook' | 'waiter'>): Promise<import("mongoose").UpdateWriteOpResult>;
25
+ }, update: Pick<ISetting, 'onEventChanged' | 'onReservationStatusChanged' | 'onTaskStatusChanged' | 'onResourceUpdated' | 'defaultSenderEmail' | 'useInformResourceTypes' | 'userPoolIdNew' | 'userPoolIdOld' | 'storage' | 'quota' | 'triggerWebhook' | 'waiter' | 'orderNumber' | 'transactionNumber'>): Promise<import("mongoose").UpdateWriteOpResult>;
26
26
  unsetUnnecessaryFields(params: {
27
27
  filter: FilterQuery<ISetting>;
28
28
  $unset: any;
@@ -49,9 +49,9 @@ class SettingRepo {
49
49
  }
50
50
  updateByProject(filter, update) {
51
51
  return __awaiter(this, void 0, void 0, function* () {
52
- const { onEventChanged, onReservationStatusChanged, onTaskStatusChanged, onResourceUpdated, defaultSenderEmail, useInformResourceTypes, userPoolIdNew, userPoolIdOld, storage, quota, triggerWebhook, waiter } = update;
52
+ const { onEventChanged, onReservationStatusChanged, onTaskStatusChanged, onResourceUpdated, defaultSenderEmail, useInformResourceTypes, userPoolIdNew, userPoolIdOld, storage, quota, triggerWebhook, waiter, orderNumber, transactionNumber } = update;
53
53
  return this.settingModel.updateOne({ 'project.id': { $eq: filter.project.id.$eq } }, {
54
- $set: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (onEventChanged !== undefined) ? { onEventChanged } : undefined), (onReservationStatusChanged !== undefined) ? { onReservationStatusChanged } : undefined), (onTaskStatusChanged !== undefined) ? { onTaskStatusChanged } : undefined), (onResourceUpdated !== undefined) ? { onResourceUpdated } : undefined), (defaultSenderEmail !== undefined) ? { defaultSenderEmail } : undefined), (useInformResourceTypes !== undefined) ? { useInformResourceTypes } : undefined), (userPoolIdNew !== undefined) ? { userPoolIdNew } : undefined), (userPoolIdOld !== undefined) ? { userPoolIdOld } : undefined), (storage !== undefined) ? { storage } : undefined), (quota !== undefined) ? { quota } : undefined), (triggerWebhook !== undefined) ? { triggerWebhook } : undefined), (waiter !== undefined) ? { waiter } : undefined)
54
+ $set: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (onEventChanged !== undefined) ? { onEventChanged } : undefined), (onReservationStatusChanged !== undefined) ? { onReservationStatusChanged } : undefined), (onTaskStatusChanged !== undefined) ? { onTaskStatusChanged } : undefined), (onResourceUpdated !== undefined) ? { onResourceUpdated } : undefined), (defaultSenderEmail !== undefined) ? { defaultSenderEmail } : undefined), (useInformResourceTypes !== undefined) ? { useInformResourceTypes } : undefined), (userPoolIdNew !== undefined) ? { userPoolIdNew } : undefined), (userPoolIdOld !== undefined) ? { userPoolIdOld } : undefined), (storage !== undefined) ? { storage } : undefined), (quota !== undefined) ? { quota } : undefined), (triggerWebhook !== undefined) ? { triggerWebhook } : undefined), (waiter !== undefined) ? { waiter } : undefined), (orderNumber !== undefined) ? { orderNumber } : undefined), (transactionNumber !== undefined) ? { transactionNumber } : undefined)
55
55
  })
56
56
  .exec();
57
57
  });
package/package.json CHANGED
@@ -44,7 +44,7 @@
44
44
  "@types/lodash.difference": "^4.5.6",
45
45
  "@types/mocha": "10.0.7",
46
46
  "@types/moment-timezone": "^0.5.30",
47
- "@types/node": "18.19.2",
47
+ "@types/node": "22.19.7",
48
48
  "@types/power-assert": "^1.5.3",
49
49
  "@types/pug": "^2.0.4",
50
50
  "@types/sinon": "^4.3.3",
@@ -78,7 +78,7 @@
78
78
  },
79
79
  "engines": {
80
80
  "node": ">=18.0.0",
81
- "npm": ">=6.0.0"
81
+ "npm": ">=10.0.0"
82
82
  },
83
83
  "keywords": [],
84
84
  "license": "UNLICENSED",
@@ -117,5 +117,5 @@
117
117
  "postversion": "git push origin --tags",
118
118
  "prepublishOnly": "npm run clean && npm run build && npm test && npm run doc"
119
119
  },
120
- "version": "23.2.0-alpha.43"
120
+ "version": "23.2.0-alpha.45"
121
121
  }