@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.
- package/example/src/chevre/confirmationNumber/testRandomness.ts +49 -0
- package/example/src/chevre/settings/addSettings.ts +35 -30
- package/lib/chevre/repo/confirmationNumber.d.ts +1 -0
- package/lib/chevre/repo/confirmationNumber.js +32 -25
- package/lib/chevre/repo/setting.d.ts +1 -1
- package/lib/chevre/repo/setting.js +2 -2
- package/package.json +3 -3
|
@@ -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 {
|
|
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
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
-
|
|
44
|
+
);
|
|
45
|
+
console.log('transactionNumber updated.');
|
|
46
|
+
}
|
|
42
47
|
}
|
|
43
48
|
|
|
44
49
|
main()
|
|
@@ -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
|
-
|
|
13
|
+
// import * as cdigit from 'cdigit';
|
|
14
|
+
const crypto_1 = require("crypto");
|
|
14
15
|
const moment = require("moment-timezone");
|
|
15
|
-
|
|
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
|
-
|
|
59
|
-
//
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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": "
|
|
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": ">=
|
|
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.
|
|
120
|
+
"version": "23.2.0-alpha.45"
|
|
121
121
|
}
|