@futdevpro/fsm-dynamo 1.10.37 → 1.10.39
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/.github/workflows/main.yml +11 -51
- package/build/_collections/constants/error-defaults.const.d.ts +8 -0
- package/build/_collections/constants/error-defaults.const.d.ts.map +1 -1
- package/build/_collections/constants/error-defaults.const.js +8 -0
- package/build/_collections/constants/error-defaults.const.js.map +1 -1
- package/build/_collections/constants/global-settings.const.d.ts +8 -0
- package/build/_collections/constants/global-settings.const.d.ts.map +1 -1
- package/build/_collections/constants/global-settings.const.js +9 -0
- package/build/_collections/constants/global-settings.const.js.map +1 -1
- package/build/_collections/constants/numbers.const.d.ts +32 -0
- package/build/_collections/constants/numbers.const.d.ts.map +1 -1
- package/build/_collections/constants/numbers.const.js +32 -0
- package/build/_collections/constants/numbers.const.js.map +1 -1
- package/build/_collections/constants/times.const.d.ts +31 -0
- package/build/_collections/constants/times.const.d.ts.map +1 -1
- package/build/_collections/constants/times.const.js +31 -0
- package/build/_collections/constants/times.const.js.map +1 -1
- package/build/_collections/utils/array.util.d.ts +136 -7
- package/build/_collections/utils/array.util.d.ts.map +1 -1
- package/build/_collections/utils/array.util.js +132 -2
- package/build/_collections/utils/array.util.js.map +1 -1
- package/build/_collections/utils/array.util.spec.js.map +1 -1
- package/build/_collections/utils/log.util.d.ts +123 -0
- package/build/_collections/utils/log.util.d.ts.map +1 -1
- package/build/_collections/utils/log.util.js +123 -0
- package/build/_collections/utils/log.util.js.map +1 -1
- package/build/_collections/utils/math/box-bounds.spec.js +2 -5
- package/build/_collections/utils/math/box-bounds.spec.js.map +1 -1
- package/build/_collections/utils/math/box-bounds.util.d.ts +52 -6
- package/build/_collections/utils/math/box-bounds.util.d.ts.map +1 -1
- package/build/_collections/utils/math/box-bounds.util.js +57 -5
- package/build/_collections/utils/math/box-bounds.util.js.map +1 -1
- package/build/_collections/utils/math/box-bounds.util.spec.js +1 -1
- package/build/_collections/utils/math/box-bounds.util.spec.js.map +1 -1
- package/build/_collections/utils/math/math.util.d.ts +30 -0
- package/build/_collections/utils/math/math.util.d.ts.map +1 -1
- package/build/_collections/utils/math/math.util.js +30 -0
- package/build/_collections/utils/math/math.util.js.map +1 -1
- package/build/_collections/utils/math/random.util.d.ts +19 -2
- package/build/_collections/utils/math/random.util.d.ts.map +1 -1
- package/build/_collections/utils/math/random.util.js +22 -0
- package/build/_collections/utils/math/random.util.js.map +1 -1
- package/build/_collections/utils/math/random.util.spec.js.map +1 -1
- package/build/_collections/utils/math/vector2.util.d.ts +142 -20
- package/build/_collections/utils/math/vector2.util.d.ts.map +1 -1
- package/build/_collections/utils/math/vector2.util.js +126 -0
- package/build/_collections/utils/math/vector2.util.js.map +1 -1
- package/build/_collections/utils/round-list.util.d.ts +36 -1
- package/build/_collections/utils/round-list.util.d.ts.map +1 -1
- package/build/_collections/utils/round-list.util.js +35 -0
- package/build/_collections/utils/round-list.util.js.map +1 -1
- package/build/_collections/utils/shared.util.js.map +1 -1
- package/build/_collections/utils/stack.util.js +3 -3
- package/build/_collections/utils/stack.util.js.map +1 -1
- package/build/_collections/utils/string.util.d.ts +8 -1
- package/build/_collections/utils/string.util.d.ts.map +1 -1
- package/build/_collections/utils/string.util.js +8 -1
- package/build/_collections/utils/string.util.js.map +1 -1
- package/build/_collections/utils/time.util.d.ts +29 -0
- package/build/_collections/utils/time.util.d.ts.map +1 -1
- package/build/_collections/utils/time.util.js +29 -0
- package/build/_collections/utils/time.util.js.map +1 -1
- package/build/_collections/utils/type-cloning-facility.util.d.ts +29 -3
- package/build/_collections/utils/type-cloning-facility.util.d.ts.map +1 -1
- package/build/_collections/utils/type-cloning-facility.util.js +53 -3
- package/build/_collections/utils/type-cloning-facility.util.js.map +1 -1
- package/build/_collections/utils/utilities.util.d.ts +49 -2
- package/build/_collections/utils/utilities.util.d.ts.map +1 -1
- package/build/_collections/utils/utilities.util.js +53 -1
- package/build/_collections/utils/utilities.util.js.map +1 -1
- package/build/_collections/utils/utilities.util.spec.js.map +1 -1
- package/build/_collections/utils/uuid.util.d.ts +5 -0
- package/build/_collections/utils/uuid.util.d.ts.map +1 -1
- package/build/_collections/utils/uuid.util.js +5 -0
- package/build/_collections/utils/uuid.util.js.map +1 -1
- package/build/_enums/basic-property-type.enum.d.ts +8 -0
- package/build/_enums/basic-property-type.enum.d.ts.map +1 -1
- package/build/_enums/basic-property-type.enum.js +8 -0
- package/build/_enums/basic-property-type.enum.js.map +1 -1
- package/build/_enums/data-model-type.enum.d.ts +8 -4
- package/build/_enums/data-model-type.enum.d.ts.map +1 -1
- package/build/_enums/data-model-type.enum.js +8 -4
- package/build/_enums/data-model-type.enum.js.map +1 -1
- package/build/_enums/environment-flag.enum.d.ts +18 -0
- package/build/_enums/environment-flag.enum.d.ts.map +1 -1
- package/build/_enums/environment-flag.enum.js +18 -0
- package/build/_enums/environment-flag.enum.js.map +1 -1
- package/build/_enums/error-level.enum.d.ts +10 -0
- package/build/_enums/error-level.enum.d.ts.map +1 -1
- package/build/_enums/error-level.enum.js +10 -0
- package/build/_enums/error-level.enum.js.map +1 -1
- package/build/_enums/http-call-type.enum.d.ts +6 -2
- package/build/_enums/http-call-type.enum.d.ts.map +1 -1
- package/build/_enums/http-call-type.enum.js +6 -2
- package/build/_enums/http-call-type.enum.js.map +1 -1
- package/build/_enums/http-response-type.enum.d.ts +8 -0
- package/build/_enums/http-response-type.enum.d.ts.map +1 -1
- package/build/_enums/http-response-type.enum.js +8 -0
- package/build/_enums/http-response-type.enum.js.map +1 -1
- package/build/_enums/log-style.enum.d.ts +8 -0
- package/build/_enums/log-style.enum.d.ts.map +1 -1
- package/build/_enums/log-style.enum.js +8 -0
- package/build/_enums/log-style.enum.js.map +1 -1
- package/build/_enums/time/day-of-week.enum.d.ts +13 -1
- package/build/_enums/time/day-of-week.enum.d.ts.map +1 -1
- package/build/_enums/time/day-of-week.enum.js +13 -1
- package/build/_enums/time/day-of-week.enum.js.map +1 -1
- package/build/_enums/time/month.enum.d.ts +8 -0
- package/build/_enums/time/month.enum.d.ts.map +1 -1
- package/build/_enums/time/month.enum.js +8 -0
- package/build/_enums/time/month.enum.js.map +1 -1
- package/build/_enums/time/relative-date.enum.d.ts +10 -0
- package/build/_enums/time/relative-date.enum.d.ts.map +1 -1
- package/build/_enums/time/relative-date.enum.js +10 -0
- package/build/_enums/time/relative-date.enum.js.map +1 -1
- package/build/_models/control-models/data-model-params.control-model.d.ts +4 -4
- package/build/_models/control-models/data-model-params.control-model.d.ts.map +1 -1
- package/build/_models/control-models/data-model-params.control-model.js.map +1 -1
- package/build/_models/control-models/data-property-params.control-model.d.ts.map +1 -1
- package/build/_models/control-models/data-property-params.control-model.js.map +1 -1
- package/build/_models/control-models/error.control-model.spec.js.map +1 -1
- package/build/_models/interfaces/box-bounds.interface.d.ts +8 -0
- package/build/_models/interfaces/box-bounds.interface.d.ts.map +1 -0
- package/build/_models/interfaces/box-bounds.interface.js +3 -0
- package/build/_models/interfaces/box-bounds.interface.js.map +1 -0
- package/build/_models/interfaces/environment/global-settings.interface.d.ts +1 -0
- package/build/_models/interfaces/environment/global-settings.interface.d.ts.map +1 -1
- package/build/_models/interfaces/route-settings.interface.d.ts +6 -1
- package/build/_models/interfaces/route-settings.interface.d.ts.map +1 -1
- package/build/_modules/crypto/_collections/crypto.util.d.ts +11 -17
- package/build/_modules/crypto/_collections/crypto.util.d.ts.map +1 -1
- package/build/_modules/crypto/_collections/crypto.util.js +74 -58
- package/build/_modules/crypto/_collections/crypto.util.js.map +1 -1
- package/build/_modules/crypto/_collections/crypto.util.spec.js +390 -0
- package/build/_modules/crypto/_collections/crypto.util.spec.js.map +1 -1
- package/build/_modules/custom-data/_collections/cud-module-settings.const.d.ts +6 -0
- package/build/_modules/custom-data/_collections/cud-module-settings.const.d.ts.map +1 -1
- package/build/_modules/custom-data/_collections/cud-module-settings.const.js +6 -0
- package/build/_modules/custom-data/_collections/cud-module-settings.const.js.map +1 -1
- package/build/_modules/custom-data/_models/cud.data-model.d.ts +3 -0
- package/build/_modules/custom-data/_models/cud.data-model.d.ts.map +1 -1
- package/build/_modules/custom-data/_models/cud.data-model.js +3 -0
- package/build/_modules/custom-data/_models/cud.data-model.js.map +1 -1
- package/build/_modules/location/_collections/loc-country-divisions.const.d.ts +1 -0
- package/build/_modules/location/_collections/loc-country-divisions.const.d.ts.map +1 -1
- package/build/_modules/location/_collections/loc-country-divisions.const.js +1 -0
- package/build/_modules/location/_collections/loc-country-divisions.const.js.map +1 -1
- package/build/_modules/location/_collections/loc-regions.util.d.ts +4 -0
- package/build/_modules/location/_collections/loc-regions.util.d.ts.map +1 -1
- package/build/_modules/location/_collections/loc-regions.util.js +4 -0
- package/build/_modules/location/_collections/loc-regions.util.js.map +1 -1
- package/build/_modules/location/_collections/loc.util.d.ts +9 -0
- package/build/_modules/location/_collections/loc.util.d.ts.map +1 -1
- package/build/_modules/location/_collections/loc.util.js +9 -0
- package/build/_modules/location/_collections/loc.util.js.map +1 -1
- package/build/_modules/location/_enums/loc-region.enum.d.ts +3 -0
- package/build/_modules/location/_enums/loc-region.enum.d.ts.map +1 -1
- package/build/_modules/location/_enums/loc-region.enum.js +3 -0
- package/build/_modules/location/_enums/loc-region.enum.js.map +1 -1
- package/build/_modules/location/_enums/loc-sub-region.enum.d.ts +3 -0
- package/build/_modules/location/_enums/loc-sub-region.enum.d.ts.map +1 -1
- package/build/_modules/location/_enums/loc-sub-region.enum.js +3 -0
- package/build/_modules/location/_enums/loc-sub-region.enum.js.map +1 -1
- package/build/_modules/location/_enums/loc-subdivision-region-type.enum.d.ts +37 -34
- package/build/_modules/location/_enums/loc-subdivision-region-type.enum.d.ts.map +1 -1
- package/build/_modules/location/_enums/loc-subdivision-region-type.enum.js +3 -0
- package/build/_modules/location/_enums/loc-subdivision-region-type.enum.js.map +1 -1
- package/build/_modules/location/_models/loc-coordinates.interface.d.ts +1 -0
- package/build/_modules/location/_models/loc-coordinates.interface.d.ts.map +1 -1
- package/build/_modules/open-ai/_enums/open-ai-model.enum.d.ts +10 -7
- package/build/_modules/open-ai/_enums/open-ai-model.enum.d.ts.map +1 -1
- package/build/_modules/open-ai/_enums/open-ai-model.enum.js +3 -0
- package/build/_modules/open-ai/_enums/open-ai-model.enum.js.map +1 -1
- package/build/_modules/pipe/_enums/pip-range-pipe-setting.enum.d.ts +3 -0
- package/build/_modules/pipe/_enums/pip-range-pipe-setting.enum.d.ts.map +1 -1
- package/build/_modules/pipe/_enums/pip-range-pipe-setting.enum.js +3 -0
- package/build/_modules/pipe/_enums/pip-range-pipe-setting.enum.js.map +1 -1
- package/build/_modules/pipe/_enums/pip.enum.d.ts +14 -0
- package/build/_modules/pipe/_enums/pip.enum.d.ts.map +1 -1
- package/build/_modules/pipe/_enums/pip.enum.js +11 -0
- package/build/_modules/pipe/_enums/pip.enum.js.map +1 -1
- package/build/_modules/socket/_enums/sck-event-key.enum.d.ts +3 -0
- package/build/_modules/socket/_enums/sck-event-key.enum.d.ts.map +1 -1
- package/build/_modules/socket/_enums/sck-event-key.enum.js +3 -0
- package/build/_modules/socket/_enums/sck-event-key.enum.js.map +1 -1
- package/build/_modules/socket/_models/sck-client-params.control-model.d.ts +12 -0
- package/build/_modules/socket/_models/sck-client-params.control-model.d.ts.map +1 -1
- package/build/_modules/socket/_models/sck-client-params.control-model.js +12 -0
- package/build/_modules/socket/_models/sck-client-params.control-model.js.map +1 -1
- package/build/_modules/socket/_models/sck-socket-event.control-model.d.ts +12 -1
- package/build/_modules/socket/_models/sck-socket-event.control-model.d.ts.map +1 -1
- package/build/_modules/socket/_models/sck-socket-event.control-model.js +12 -1
- package/build/_modules/socket/_models/sck-socket-event.control-model.js.map +1 -1
- package/build/_modules/socket/_services/sck-client.service-base.d.ts +4 -0
- package/build/_modules/socket/_services/sck-client.service-base.d.ts.map +1 -1
- package/build/_modules/socket/_services/sck-client.service-base.js +4 -0
- package/build/_modules/socket/_services/sck-client.service-base.js.map +1 -1
- package/build/_modules/test/_collections/tst-module-settings.const.d.ts +9 -0
- package/build/_modules/test/_collections/tst-module-settings.const.d.ts.map +1 -1
- package/build/_modules/test/_collections/tst-module-settings.const.js +9 -0
- package/build/_modules/test/_collections/tst-module-settings.const.js.map +1 -1
- package/build/_modules/usage/_models/usg-action.control-model.d.ts +13 -0
- package/build/_modules/usage/_models/usg-action.control-model.d.ts.map +1 -1
- package/build/_modules/usage/_models/usg-action.control-model.js +13 -0
- package/build/_modules/usage/_models/usg-action.control-model.js.map +1 -1
- package/build/_modules/usage/_models/usg-daily-usage-data.control-model.d.ts +14 -0
- package/build/_modules/usage/_models/usg-daily-usage-data.control-model.d.ts.map +1 -1
- package/build/_modules/usage/_models/usg-daily-usage-data.control-model.js +14 -0
- package/build/_modules/usage/_models/usg-daily-usage-data.control-model.js.map +1 -1
- package/build/_modules/usage/_models/usg-data.control-model.d.ts +16 -0
- package/build/_modules/usage/_models/usg-data.control-model.d.ts.map +1 -1
- package/build/_modules/usage/_models/usg-data.control-model.js +16 -0
- package/build/_modules/usage/_models/usg-data.control-model.js.map +1 -1
- package/build/_modules/usage/_models/usg-session.data-model.d.ts +17 -0
- package/build/_modules/usage/_models/usg-session.data-model.d.ts.map +1 -1
- package/build/_modules/usage/_models/usg-session.data-model.js +17 -0
- package/build/_modules/usage/_models/usg-session.data-model.js.map +1 -1
- package/build/_modules/usage/_models/usg-session.data-model.spec.js.map +1 -1
- package/build/index.d.ts +1 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -0
- package/build/index.js.map +1 -1
- package/futdevpro-fsm-dynamo-01.10.39.tgz +0 -0
- package/package.json +9 -5
- package/src/_collections/constants/error-defaults.const.ts +8 -0
- package/src/_collections/constants/global-settings.const.ts +12 -2
- package/src/_collections/constants/numbers.const.ts +32 -0
- package/src/_collections/constants/times.const.ts +37 -0
- package/src/_collections/utils/array.util.spec.ts +36 -38
- package/src/_collections/utils/array.util.ts +146 -12
- package/src/_collections/utils/log.util.ts +126 -2
- package/src/_collections/utils/math/box-bounds.spec.ts +8 -13
- package/src/_collections/utils/math/box-bounds.util.spec.ts +3 -3
- package/src/_collections/utils/math/box-bounds.util.ts +65 -12
- package/src/_collections/utils/math/math.util.ts +30 -6
- package/src/_collections/utils/math/random.util.spec.ts +7 -7
- package/src/_collections/utils/math/random.util.ts +27 -4
- package/src/_collections/utils/math/vector2.util.ts +148 -21
- package/src/_collections/utils/round-list.util.ts +36 -3
- package/src/_collections/utils/shared.util.ts +17 -17
- package/src/_collections/utils/stack.util.ts +6 -6
- package/src/_collections/utils/string.util.ts +8 -1
- package/src/_collections/utils/time.util.ts +37 -2
- package/src/_collections/utils/type-cloning-facility.util.ts +57 -8
- package/src/_collections/utils/utilities.util.spec.ts +2 -2
- package/src/_collections/utils/utilities.util.ts +61 -8
- package/src/_collections/utils/uuid.util.ts +5 -0
- package/src/_enums/basic-property-type.enum.ts +8 -0
- package/src/_enums/data-model-type.enum.ts +11 -6
- package/src/_enums/environment-flag.enum.ts +18 -0
- package/src/_enums/error-level.enum.ts +10 -0
- package/src/_enums/http-call-type.enum.ts +6 -2
- package/src/_enums/http-response-type.enum.ts +8 -0
- package/src/_enums/log-style.enum.ts +8 -0
- package/src/_enums/time/day-of-week.enum.ts +13 -1
- package/src/_enums/time/month.enum.ts +8 -0
- package/src/_enums/time/relative-date.enum.ts +10 -0
- package/src/_models/control-models/data-model-params.control-model.ts +6 -6
- package/src/_models/control-models/data-property-params.control-model.ts +1 -1
- package/src/_models/control-models/error.control-model.spec.ts +2 -2
- package/src/_models/interfaces/box-bounds.interface.ts +8 -0
- package/src/_models/interfaces/environment/global-settings.interface.ts +2 -0
- package/src/_models/interfaces/route-settings.interface.ts +6 -1
- package/src/_modules/crypto/_collections/crypto.util.spec.ts +428 -0
- package/src/_modules/crypto/_collections/crypto.util.ts +88 -52
- package/src/_modules/custom-data/_collections/cud-module-settings.const.ts +6 -0
- package/src/_modules/custom-data/_models/cud.data-model.ts +3 -0
- package/src/_modules/location/_collections/loc-country-divisions.const.ts +2 -1
- package/src/_modules/location/_collections/loc-regions.util.ts +4 -0
- package/src/_modules/location/_collections/loc.util.ts +13 -5
- package/src/_modules/location/_enums/loc-region.enum.ts +3 -0
- package/src/_modules/location/_enums/loc-sub-region.enum.ts +3 -0
- package/src/_modules/location/_enums/loc-subdivision-region-type.enum.ts +37 -34
- package/src/_modules/location/_models/loc-coordinates.interface.ts +1 -0
- package/src/_modules/open-ai/_enums/open-ai-model.enum.ts +11 -8
- package/src/_modules/pipe/_enums/pip-range-pipe-setting.enum.ts +3 -0
- package/src/_modules/pipe/_enums/pip.enum.ts +17 -3
- package/src/_modules/socket/_enums/sck-event-key.enum.ts +3 -0
- package/src/_modules/socket/_models/sck-client-params.control-model.ts +12 -0
- package/src/_modules/socket/_models/sck-socket-event.control-model.ts +12 -1
- package/src/_modules/socket/_services/sck-client.service-base.ts +4 -0
- package/src/_modules/test/_collections/tst-module-settings.const.ts +9 -0
- package/src/_modules/usage/_models/usg-action.control-model.ts +13 -0
- package/src/_modules/usage/_models/usg-daily-usage-data.control-model.ts +14 -0
- package/src/_modules/usage/_models/usg-data.control-model.ts +16 -0
- package/src/_modules/usage/_models/usg-session.data-model.spec.ts +2 -1
- package/src/_modules/usage/_models/usg-session.data-model.ts +17 -0
- package/src/index.ts +1 -0
- package/tsconfig.json +1 -0
- package/futdevpro-fsm-dynamo-01.10.37.tgz +0 -0
|
@@ -44,6 +44,39 @@ describe('| DyFM_Crypto', () => {
|
|
|
44
44
|
expect(decrypted).toEqual(complexData);
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
+
it('| should get the same result with the same input', () => {
|
|
48
|
+
const complexData = {
|
|
49
|
+
id: 2,
|
|
50
|
+
name: 'test',
|
|
51
|
+
nested: {
|
|
52
|
+
value: 'nested-value',
|
|
53
|
+
array: [1, 2, 3]
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
const expectedResult = JSON.stringify(complexData);
|
|
57
|
+
|
|
58
|
+
const encrypted = DyFM_Crypto.encrypt(complexData, testKey);
|
|
59
|
+
const decrypted = DyFM_Crypto.decrypt(encrypted, testKey);
|
|
60
|
+
|
|
61
|
+
const result = JSON.stringify(decrypted);
|
|
62
|
+
expect(result).toBe(expectedResult);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('| should not effect the original object', () => {
|
|
66
|
+
const complexData = {
|
|
67
|
+
id: 1,
|
|
68
|
+
name: 'test',
|
|
69
|
+
nested: { value: 'nested-value', array: [1, 2, 3] }
|
|
70
|
+
};
|
|
71
|
+
const originalData = JSON.stringify(complexData);
|
|
72
|
+
|
|
73
|
+
const encrypted = DyFM_Crypto.encrypt(complexData, testKey);
|
|
74
|
+
const decrypted = DyFM_Crypto.decrypt(encrypted, testKey);
|
|
75
|
+
|
|
76
|
+
const result = JSON.stringify(decrypted);
|
|
77
|
+
expect(result).toBe(originalData);
|
|
78
|
+
});
|
|
79
|
+
|
|
47
80
|
it('| should handle arrays', () => {
|
|
48
81
|
const arrayData = [1, 'test', { nested: true }];
|
|
49
82
|
const encrypted = DyFM_Crypto.encrypt(arrayData, testKey);
|
|
@@ -191,5 +224,400 @@ describe('| DyFM_Crypto', () => {
|
|
|
191
224
|
expect(() => DyFM_Crypto.decrypt(modified, testKey)).toThrow();
|
|
192
225
|
});
|
|
193
226
|
});
|
|
227
|
+
|
|
228
|
+
describe('| JSON handling edge cases', () => {
|
|
229
|
+
it('| should handle double-stringified JSON data correctly', () => {
|
|
230
|
+
const testData = {
|
|
231
|
+
username: 'Itharen',
|
|
232
|
+
password: 'asdasd',
|
|
233
|
+
roles: [],
|
|
234
|
+
permissions: [],
|
|
235
|
+
activeSubscriptions: [],
|
|
236
|
+
clientUserIds: {},
|
|
237
|
+
oauth2Data: {}
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
// Simulate double stringification
|
|
241
|
+
const doubleStringified = JSON.stringify(JSON.stringify(testData));
|
|
242
|
+
|
|
243
|
+
const encrypted = DyFM_Crypto.encrypt(doubleStringified, testKey);
|
|
244
|
+
const decrypted = DyFM_Crypto.decrypt(encrypted, testKey);
|
|
245
|
+
|
|
246
|
+
// Should be able to parse the decrypted data back to the original object
|
|
247
|
+
const parsed = JSON.parse(decrypted as string);
|
|
248
|
+
expect(parsed).toEqual(testData);
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
it('| should handle character-by-character JSON data correctly', () => {
|
|
252
|
+
// Create a character-by-character object like in the example
|
|
253
|
+
const charByCharData = {
|
|
254
|
+
'0': '{',
|
|
255
|
+
'1': '"',
|
|
256
|
+
'2': '_',
|
|
257
|
+
'3': '_',
|
|
258
|
+
'4': 'c',
|
|
259
|
+
'5': 'r',
|
|
260
|
+
'6': 'e',
|
|
261
|
+
'7': 'a',
|
|
262
|
+
'8': 't',
|
|
263
|
+
'9': 'e',
|
|
264
|
+
'10': 'd',
|
|
265
|
+
'11': '"',
|
|
266
|
+
'12': ':',
|
|
267
|
+
'13': '"',
|
|
268
|
+
'14': '2',
|
|
269
|
+
'15': '0',
|
|
270
|
+
'16': '2',
|
|
271
|
+
'17': '5',
|
|
272
|
+
'18': '-',
|
|
273
|
+
'19': '0',
|
|
274
|
+
'20': '5',
|
|
275
|
+
'21': '-',
|
|
276
|
+
'22': '1',
|
|
277
|
+
'23': '3',
|
|
278
|
+
'24': 'T',
|
|
279
|
+
'25': '1',
|
|
280
|
+
'26': '0',
|
|
281
|
+
'27': ':',
|
|
282
|
+
'28': '4',
|
|
283
|
+
'29': '0',
|
|
284
|
+
'30': ':',
|
|
285
|
+
'31': '4',
|
|
286
|
+
'32': '4',
|
|
287
|
+
'33': '.',
|
|
288
|
+
'34': '7',
|
|
289
|
+
'35': '6',
|
|
290
|
+
'36': '0',
|
|
291
|
+
'37': 'Z',
|
|
292
|
+
'38': '"',
|
|
293
|
+
'39': ',',
|
|
294
|
+
'40': '"',
|
|
295
|
+
'41': '_',
|
|
296
|
+
'42': '_',
|
|
297
|
+
'43': 'l',
|
|
298
|
+
'44': 'a',
|
|
299
|
+
'45': 's',
|
|
300
|
+
'46': 't',
|
|
301
|
+
'47': 'M',
|
|
302
|
+
'48': 'o',
|
|
303
|
+
'49': 'd',
|
|
304
|
+
'50': 'i',
|
|
305
|
+
'51': 'f',
|
|
306
|
+
'52': 'i',
|
|
307
|
+
'53': 'e',
|
|
308
|
+
'54': 'd',
|
|
309
|
+
'55': '"',
|
|
310
|
+
'56': ':',
|
|
311
|
+
'57': '"',
|
|
312
|
+
'58': '2',
|
|
313
|
+
'59': '0',
|
|
314
|
+
'60': '2',
|
|
315
|
+
'61': '5',
|
|
316
|
+
'62': '-',
|
|
317
|
+
'63': '0',
|
|
318
|
+
'64': '5',
|
|
319
|
+
'65': '-',
|
|
320
|
+
'66': '1',
|
|
321
|
+
'67': '3',
|
|
322
|
+
'68': 'T',
|
|
323
|
+
'69': '1',
|
|
324
|
+
'70': '0',
|
|
325
|
+
'71': ':',
|
|
326
|
+
'72': '4',
|
|
327
|
+
'73': '0',
|
|
328
|
+
'74': ':',
|
|
329
|
+
'75': '4',
|
|
330
|
+
'76': '4',
|
|
331
|
+
'77': '.',
|
|
332
|
+
'78': '7',
|
|
333
|
+
'79': '6',
|
|
334
|
+
'80': '0',
|
|
335
|
+
'81': 'Z',
|
|
336
|
+
'82': '"',
|
|
337
|
+
'83': ',',
|
|
338
|
+
'84': '"',
|
|
339
|
+
'85': '_',
|
|
340
|
+
'86': '_',
|
|
341
|
+
'87': 'v',
|
|
342
|
+
'88': '"',
|
|
343
|
+
'89': ':',
|
|
344
|
+
'90': '0',
|
|
345
|
+
'91': ',',
|
|
346
|
+
'92': '"',
|
|
347
|
+
'93': 'u',
|
|
348
|
+
'94': 's',
|
|
349
|
+
'95': 'e',
|
|
350
|
+
'96': 'r',
|
|
351
|
+
'97': 'n',
|
|
352
|
+
'98': 'a',
|
|
353
|
+
'99': 'm',
|
|
354
|
+
'100': 'e',
|
|
355
|
+
'101': '"',
|
|
356
|
+
'102': ':',
|
|
357
|
+
'103': '"',
|
|
358
|
+
'104': 'I',
|
|
359
|
+
'105': 't',
|
|
360
|
+
'106': 'h',
|
|
361
|
+
'107': 'a',
|
|
362
|
+
'108': 'r',
|
|
363
|
+
'109': 'e',
|
|
364
|
+
'110': 'n',
|
|
365
|
+
'111': '"',
|
|
366
|
+
'112': ',',
|
|
367
|
+
'113': '"',
|
|
368
|
+
'114': 'p',
|
|
369
|
+
'115': 'r',
|
|
370
|
+
'116': 'e',
|
|
371
|
+
'117': 'v',
|
|
372
|
+
'118': 'i',
|
|
373
|
+
'119': 'o',
|
|
374
|
+
'120': 'u',
|
|
375
|
+
'121': 's',
|
|
376
|
+
'122': 'E',
|
|
377
|
+
'123': 'm',
|
|
378
|
+
'124': 'a',
|
|
379
|
+
'125': 'i',
|
|
380
|
+
'126': 'l',
|
|
381
|
+
'127': 's',
|
|
382
|
+
'128': '"',
|
|
383
|
+
'129': ':',
|
|
384
|
+
'130': '[',
|
|
385
|
+
'131': ']',
|
|
386
|
+
'132': ',',
|
|
387
|
+
'133': '"',
|
|
388
|
+
'134': 'p',
|
|
389
|
+
'135': 'a',
|
|
390
|
+
'136': 's',
|
|
391
|
+
'137': 's',
|
|
392
|
+
'138': 'w',
|
|
393
|
+
'139': 'o',
|
|
394
|
+
'140': 'r',
|
|
395
|
+
'141': 'd',
|
|
396
|
+
'142': '"',
|
|
397
|
+
'143': ':',
|
|
398
|
+
'144': '"',
|
|
399
|
+
'145': 'a',
|
|
400
|
+
'146': 's',
|
|
401
|
+
'147': 'd',
|
|
402
|
+
'148': 'a',
|
|
403
|
+
'149': 's',
|
|
404
|
+
'150': 'd',
|
|
405
|
+
'151': '"',
|
|
406
|
+
'152': ',',
|
|
407
|
+
'153': '"',
|
|
408
|
+
'154': 'r',
|
|
409
|
+
'155': 'o',
|
|
410
|
+
'156': 'l',
|
|
411
|
+
'157': 'e',
|
|
412
|
+
'158': 's',
|
|
413
|
+
'159': '"',
|
|
414
|
+
'160': ':',
|
|
415
|
+
'161': '[',
|
|
416
|
+
'162': ']',
|
|
417
|
+
'163': ',',
|
|
418
|
+
'164': '"',
|
|
419
|
+
'165': 'p',
|
|
420
|
+
'166': 'e',
|
|
421
|
+
'167': 'r',
|
|
422
|
+
'168': 'm',
|
|
423
|
+
'169': 'i',
|
|
424
|
+
'170': 's',
|
|
425
|
+
'171': 's',
|
|
426
|
+
'172': 'i',
|
|
427
|
+
'173': 'o',
|
|
428
|
+
'174': 'n',
|
|
429
|
+
'175': 's',
|
|
430
|
+
'176': '"',
|
|
431
|
+
'177': ':',
|
|
432
|
+
'178': '[',
|
|
433
|
+
'179': ']',
|
|
434
|
+
'180': ',',
|
|
435
|
+
'181': '"',
|
|
436
|
+
'182': 'a',
|
|
437
|
+
'183': 'c',
|
|
438
|
+
'184': 't',
|
|
439
|
+
'185': 'i',
|
|
440
|
+
'186': 'v',
|
|
441
|
+
'187': 'e',
|
|
442
|
+
'188': 'S',
|
|
443
|
+
'189': 'u',
|
|
444
|
+
'190': 'b',
|
|
445
|
+
'191': 's',
|
|
446
|
+
'192': 'c',
|
|
447
|
+
'193': 'r',
|
|
448
|
+
'194': 'i',
|
|
449
|
+
'195': 'p',
|
|
450
|
+
'196': 't',
|
|
451
|
+
'197': 'i',
|
|
452
|
+
'198': 'o',
|
|
453
|
+
'199': 'n',
|
|
454
|
+
'200': 's',
|
|
455
|
+
'201': '"',
|
|
456
|
+
'202': ':',
|
|
457
|
+
'203': '[',
|
|
458
|
+
'204': ']',
|
|
459
|
+
'205': ',',
|
|
460
|
+
'206': '"',
|
|
461
|
+
'207': 'c',
|
|
462
|
+
'208': 'l',
|
|
463
|
+
'209': 'i',
|
|
464
|
+
'210': 'e',
|
|
465
|
+
'211': 'n',
|
|
466
|
+
'212': 't',
|
|
467
|
+
'213': 'U',
|
|
468
|
+
'214': 's',
|
|
469
|
+
'215': 'e',
|
|
470
|
+
'216': 'r',
|
|
471
|
+
'217': 'I',
|
|
472
|
+
'218': 'd',
|
|
473
|
+
'219': 's',
|
|
474
|
+
'220': '"',
|
|
475
|
+
'221': ':',
|
|
476
|
+
'222': '{',
|
|
477
|
+
'223': '}',
|
|
478
|
+
'224': ',',
|
|
479
|
+
'225': '"',
|
|
480
|
+
'226': 'o',
|
|
481
|
+
'227': 'a',
|
|
482
|
+
'228': 'u',
|
|
483
|
+
'229': 't',
|
|
484
|
+
'230': 'h',
|
|
485
|
+
'231': '2',
|
|
486
|
+
'232': 'D',
|
|
487
|
+
'233': 'a',
|
|
488
|
+
'234': 't',
|
|
489
|
+
'235': 'a',
|
|
490
|
+
'236': '"',
|
|
491
|
+
'237': ':',
|
|
492
|
+
'238': '{',
|
|
493
|
+
'239': '}',
|
|
494
|
+
'240': '}'
|
|
495
|
+
};
|
|
496
|
+
|
|
497
|
+
const encrypted = DyFM_Crypto.encrypt(charByCharData, testKey);
|
|
498
|
+
const decrypted = DyFM_Crypto.decrypt(encrypted, testKey);
|
|
499
|
+
|
|
500
|
+
// Should be able to parse the decrypted data back to the original object
|
|
501
|
+
expect(decrypted).toEqual(charByCharData);
|
|
502
|
+
});
|
|
503
|
+
});
|
|
504
|
+
|
|
505
|
+
describe('| cross-environment consistency', () => {
|
|
506
|
+
it('| should produce same encrypted output for same input across different environments', () => {
|
|
507
|
+
const testData = {
|
|
508
|
+
id: 1,
|
|
509
|
+
name: 'test',
|
|
510
|
+
timestamp: '2024-03-20T10:00:00Z'
|
|
511
|
+
};
|
|
512
|
+
const key = 'test-secret-key-123';
|
|
513
|
+
|
|
514
|
+
// Simulate different environments by creating new instances
|
|
515
|
+
const encrypted1 = DyFM_Crypto.encrypt(testData, key);
|
|
516
|
+
const encrypted2 = DyFM_Crypto.encrypt(testData, key);
|
|
517
|
+
|
|
518
|
+
expect(encrypted1).toBe(encrypted2);
|
|
519
|
+
expect(DyFM_Crypto.decrypt(encrypted1, key)).toEqual(testData);
|
|
520
|
+
expect(DyFM_Crypto.decrypt(encrypted2, key)).toEqual(testData);
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
it('| should maintain encryption consistency with different data types', () => {
|
|
524
|
+
const testCases = [
|
|
525
|
+
{ data: { id: 1 }, key: 'key1' },
|
|
526
|
+
{ data: 'string data', key: 'key2' },
|
|
527
|
+
{ data: [1, 2, 3], key: 'key3' },
|
|
528
|
+
{ data: { nested: { value: true } }, key: 'key4' }
|
|
529
|
+
];
|
|
530
|
+
|
|
531
|
+
testCases.forEach(({ data, key }) => {
|
|
532
|
+
const encrypted1 = DyFM_Crypto.encrypt(data, key);
|
|
533
|
+
const encrypted2 = DyFM_Crypto.encrypt(data, key);
|
|
534
|
+
expect(encrypted1).toBe(encrypted2);
|
|
535
|
+
});
|
|
536
|
+
});
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
describe('| database persistence', () => {
|
|
540
|
+
interface UserData {
|
|
541
|
+
id: number;
|
|
542
|
+
name: string;
|
|
543
|
+
lastLogin: string;
|
|
544
|
+
preferences: {
|
|
545
|
+
language: string;
|
|
546
|
+
timezone: string;
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
it('| should successfully encrypt and decrypt data after database storage simulation', () => {
|
|
551
|
+
const originalData = {
|
|
552
|
+
id: 1,
|
|
553
|
+
name: 'test user',
|
|
554
|
+
email: 'test@example.com',
|
|
555
|
+
settings: {
|
|
556
|
+
theme: 'dark',
|
|
557
|
+
notifications: true
|
|
558
|
+
}
|
|
559
|
+
};
|
|
560
|
+
const key = 'db-storage-key';
|
|
561
|
+
|
|
562
|
+
// Simulate database storage and retrieval
|
|
563
|
+
const encrypted = DyFM_Crypto.encrypt(originalData, key);
|
|
564
|
+
const storedData = encrypted; // Simulating database storage
|
|
565
|
+
const retrievedData = storedData; // Simulating database retrieval
|
|
566
|
+
const decrypted = DyFM_Crypto.decrypt(retrievedData, key);
|
|
567
|
+
|
|
568
|
+
expect(decrypted).toEqual(originalData);
|
|
569
|
+
});
|
|
570
|
+
|
|
571
|
+
it('| should handle multiple encryption/decryption cycles for database operations', () => {
|
|
572
|
+
const userData: UserData = {
|
|
573
|
+
id: 1,
|
|
574
|
+
name: 'test user',
|
|
575
|
+
lastLogin: new Date().toISOString(),
|
|
576
|
+
preferences: {
|
|
577
|
+
language: 'en',
|
|
578
|
+
timezone: 'UTC'
|
|
579
|
+
}
|
|
580
|
+
};
|
|
581
|
+
const key = 'persistent-key';
|
|
582
|
+
|
|
583
|
+
// Simulate multiple database operations
|
|
584
|
+
const encrypted1 = DyFM_Crypto.encrypt(userData, key);
|
|
585
|
+
const decrypted1 = DyFM_Crypto.decrypt(encrypted1, key) as UserData;
|
|
586
|
+
|
|
587
|
+
// Simulate data update
|
|
588
|
+
const updatedData: UserData = {
|
|
589
|
+
...decrypted1,
|
|
590
|
+
lastLogin: new Date().toISOString()
|
|
591
|
+
};
|
|
592
|
+
const encrypted2 = DyFM_Crypto.encrypt(updatedData, key);
|
|
593
|
+
const decrypted2 = DyFM_Crypto.decrypt(encrypted2, key) as UserData;
|
|
594
|
+
|
|
595
|
+
expect(decrypted1).toEqual(userData);
|
|
596
|
+
expect(decrypted2).toEqual(updatedData);
|
|
597
|
+
expect(decrypted2.lastLogin).not.toBe(userData.lastLogin);
|
|
598
|
+
});
|
|
599
|
+
|
|
600
|
+
it('| should maintain data integrity through multiple database operations', () => {
|
|
601
|
+
const sensitiveData = {
|
|
602
|
+
id: 1,
|
|
603
|
+
password: 'hashed-password-123',
|
|
604
|
+
securityQuestions: [
|
|
605
|
+
{ question: 'What is your pet name?', answer: 'Fluffy' },
|
|
606
|
+
{ question: 'Where were you born?', answer: 'New York' }
|
|
607
|
+
]
|
|
608
|
+
};
|
|
609
|
+
const key = 'sensitive-data-key';
|
|
610
|
+
|
|
611
|
+
// Simulate multiple database operations with the same data
|
|
612
|
+
const encrypted1 = DyFM_Crypto.encrypt(sensitiveData, key);
|
|
613
|
+
const decrypted1 = DyFM_Crypto.decrypt(encrypted1, key);
|
|
614
|
+
const encrypted2 = DyFM_Crypto.encrypt(decrypted1, key);
|
|
615
|
+
const decrypted2 = DyFM_Crypto.decrypt(encrypted2, key);
|
|
616
|
+
|
|
617
|
+
expect(decrypted1).toEqual(sensitiveData);
|
|
618
|
+
expect(decrypted2).toEqual(sensitiveData);
|
|
619
|
+
expect(encrypted1).toBe(encrypted2); // Different encryption instances
|
|
620
|
+
});
|
|
621
|
+
});
|
|
194
622
|
});
|
|
195
623
|
});
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import * as CryptoJS from 'crypto-js';
|
|
2
|
+
import {
|
|
3
|
+
DyFM_Error,
|
|
4
|
+
DyFM_Error_Settings
|
|
5
|
+
} from '../../../_models/control-models/error.control-model';
|
|
2
6
|
|
|
3
|
-
import { DyFM_Error } from '../../../_models/control-models/error.control-model';
|
|
4
7
|
|
|
5
8
|
/**
|
|
6
9
|
* Error codes for crypto operations
|
|
7
10
|
*/
|
|
8
|
-
export enum CryptoErrorCode {
|
|
11
|
+
/* export enum CryptoErrorCode {
|
|
9
12
|
INVALID_INPUT = 'DyFM-CRY-EA0',
|
|
10
|
-
DECRYPTION_FAILED = '
|
|
13
|
+
DECRYPTION_FAILED = '',
|
|
11
14
|
ENCRYPTION_FAILED = 'DyFM-CRY-ENF',
|
|
12
15
|
INVALID_KEY = 'DyFM-CRY-IKY',
|
|
13
16
|
INVALID_DATA = 'DyFM-CRY-IDT'
|
|
14
|
-
}
|
|
17
|
+
} */
|
|
15
18
|
|
|
16
19
|
/**
|
|
17
20
|
* Configuration options for encryption/decryption
|
|
@@ -29,11 +32,14 @@ export interface CryptoConfig {
|
|
|
29
32
|
*/
|
|
30
33
|
export class DyFM_Crypto {
|
|
31
34
|
private static readonly DEFAULT_CONFIG: Required<CryptoConfig> = {
|
|
32
|
-
ivLength: 16,
|
|
33
|
-
saltLength: 16,
|
|
35
|
+
ivLength: 16, // 128 bits
|
|
36
|
+
saltLength: 16, // 128 bits
|
|
34
37
|
keyIterations: 10000,
|
|
35
|
-
keySize: 256
|
|
38
|
+
keySize: 8 // 256 bits (8 * 32)
|
|
36
39
|
};
|
|
40
|
+
private static readonly defaultErrorUserMsg =
|
|
41
|
+
`We encountered an unhandled Authentication Error, ` +
|
|
42
|
+
`\nplease contact the responsible development team.`;
|
|
37
43
|
|
|
38
44
|
// Tömör: kb. 60–80 karakteres token, nem 200+
|
|
39
45
|
// Nem szabványos: nehéz visszafejteni
|
|
@@ -43,37 +49,42 @@ export class DyFM_Crypto {
|
|
|
43
49
|
* Validates the input data and key
|
|
44
50
|
* @throws {DyFM_Error} if validation fails
|
|
45
51
|
*/
|
|
46
|
-
private static validateInput
|
|
47
|
-
if (
|
|
52
|
+
private static validateInput(data: any, key: string): void {
|
|
53
|
+
if (!key || typeof key !== 'string' || key.trim().length === 0) {
|
|
48
54
|
throw new DyFM_Error({
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
55
|
+
...this.getDefaultErrorSettings('validateInput'),
|
|
56
|
+
errorCode: 'DyFM-CRY-IKY',
|
|
57
|
+
message: 'Invalid encryption key'
|
|
52
58
|
});
|
|
53
59
|
}
|
|
54
60
|
|
|
55
|
-
if (
|
|
61
|
+
if (data === undefined || data === null) {
|
|
56
62
|
throw new DyFM_Error({
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
63
|
+
...this.getDefaultErrorSettings('validateInput'),
|
|
64
|
+
errorCode: 'DyFM-CRY-IDT',
|
|
65
|
+
message: 'Invalid data to encrypt/decrypt'
|
|
60
66
|
});
|
|
61
67
|
}
|
|
62
68
|
}
|
|
63
69
|
|
|
64
70
|
/**
|
|
65
|
-
* Generates a
|
|
66
|
-
* @param length Length of the padding in bytes
|
|
71
|
+
* Generates a deterministic IV based on the input data and key
|
|
67
72
|
*/
|
|
68
|
-
private static
|
|
69
|
-
|
|
73
|
+
private static generateIV(data: string, key: string, config: Required<CryptoConfig>): CryptoJS.lib.WordArray {
|
|
74
|
+
const hash = CryptoJS.SHA256(data + key);
|
|
75
|
+
return CryptoJS.lib.WordArray.create(hash.words.slice(0, config.ivLength / 4));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Generates a deterministic salt based on the input data and key
|
|
80
|
+
*/
|
|
81
|
+
private static generateSalt(data: string, key: string, config: Required<CryptoConfig>): CryptoJS.lib.WordArray {
|
|
82
|
+
const hash = CryptoJS.SHA256(key + data);
|
|
83
|
+
return CryptoJS.lib.WordArray.create(hash.words.slice(0, config.saltLength / 4));
|
|
70
84
|
}
|
|
71
85
|
|
|
72
86
|
/**
|
|
73
87
|
* Derives a key using PBKDF2
|
|
74
|
-
* @param key The input key
|
|
75
|
-
* @param salt The salt to use
|
|
76
|
-
* @param config Configuration options
|
|
77
88
|
*/
|
|
78
89
|
private static deriveKey(key: string, salt: CryptoJS.lib.WordArray, config: Required<CryptoConfig>): CryptoJS.lib.WordArray {
|
|
79
90
|
return CryptoJS.PBKDF2(key, salt, {
|
|
@@ -84,38 +95,62 @@ export class DyFM_Crypto {
|
|
|
84
95
|
|
|
85
96
|
/**
|
|
86
97
|
* Safely serializes data to JSON
|
|
87
|
-
* @param data The data to serialize
|
|
88
|
-
* @returns Serialized data as string
|
|
89
98
|
*/
|
|
90
99
|
private static safeSerialize<T>(data: T): string {
|
|
91
100
|
try {
|
|
92
101
|
return JSON.stringify(data);
|
|
93
102
|
} catch (error) {
|
|
94
103
|
throw new DyFM_Error({
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
104
|
+
...this.getDefaultErrorSettings('safeSerialize', error),
|
|
105
|
+
errorCode: 'DyFM-CRY-SER',
|
|
106
|
+
message: 'Failed to serialize data'
|
|
98
107
|
});
|
|
99
108
|
}
|
|
100
109
|
}
|
|
101
110
|
|
|
102
111
|
/**
|
|
103
112
|
* Safely deserializes JSON data
|
|
104
|
-
* @param data The JSON string to deserialize
|
|
105
|
-
* @returns Deserialized data
|
|
106
113
|
*/
|
|
107
114
|
private static safeDeserialize<T>(data: string): T {
|
|
108
115
|
try {
|
|
109
|
-
|
|
116
|
+
let parsed = JSON.parse(data);
|
|
117
|
+
|
|
118
|
+
// Handle double-stringified JSON
|
|
119
|
+
if (typeof parsed === 'string') {
|
|
120
|
+
try {
|
|
121
|
+
parsed = JSON.parse(parsed);
|
|
122
|
+
} catch {
|
|
123
|
+
// If second parse fails, return the string as is
|
|
124
|
+
return parsed as T;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Handle primitive values
|
|
129
|
+
if (typeof parsed === 'string' || typeof parsed === 'number' || typeof parsed === 'boolean') {
|
|
130
|
+
return parsed as T;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return parsed as T;
|
|
110
134
|
} catch (error) {
|
|
111
135
|
throw new DyFM_Error({
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
136
|
+
...this.getDefaultErrorSettings('safeDeserialize', error),
|
|
137
|
+
errorCode: 'DyFM-CRY-DES',
|
|
138
|
+
message: 'Failed to deserialize data'
|
|
115
139
|
});
|
|
116
140
|
}
|
|
117
141
|
}
|
|
118
142
|
|
|
143
|
+
/**
|
|
144
|
+
* Gets default error settings
|
|
145
|
+
*/
|
|
146
|
+
private static getDefaultErrorSettings(operation: string, error?: any): DyFM_Error_Settings {
|
|
147
|
+
return {
|
|
148
|
+
message: `Crypto operation '${operation}' failed`,
|
|
149
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
150
|
+
errorCode: 'DyFM-CRY-ERR'
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
119
154
|
/**
|
|
120
155
|
* Encrypts data using AES-256-CBC
|
|
121
156
|
* @param data The data to encrypt
|
|
@@ -129,20 +164,18 @@ export class DyFM_Crypto {
|
|
|
129
164
|
this.validateInput(data, key);
|
|
130
165
|
const finalConfig = { ...this.DEFAULT_CONFIG, ...config };
|
|
131
166
|
|
|
132
|
-
//
|
|
133
|
-
const
|
|
134
|
-
|
|
167
|
+
// Convert data to string
|
|
168
|
+
const dataStr = this.safeSerialize(data);
|
|
169
|
+
|
|
170
|
+
// Generate deterministic IV and salt based on data and key
|
|
171
|
+
const iv = this.generateIV(dataStr, key, finalConfig);
|
|
172
|
+
const salt = this.generateSalt(dataStr, key, finalConfig);
|
|
135
173
|
|
|
136
174
|
// Derive key using PBKDF2
|
|
137
175
|
const derivedKey = this.deriveKey(key, salt, finalConfig);
|
|
138
176
|
|
|
139
|
-
// Convert data to string and add random padding
|
|
140
|
-
const dataStr = this.safeSerialize(data);
|
|
141
|
-
const padding = this.generatePadding(16);
|
|
142
|
-
const paddedData = padding + dataStr;
|
|
143
|
-
|
|
144
177
|
// Encrypt the data
|
|
145
|
-
const encrypted = CryptoJS.AES.encrypt(
|
|
178
|
+
const encrypted = CryptoJS.AES.encrypt(dataStr, derivedKey, {
|
|
146
179
|
iv: iv,
|
|
147
180
|
mode: CryptoJS.mode.CBC,
|
|
148
181
|
padding: CryptoJS.pad.Pkcs7
|
|
@@ -158,9 +191,8 @@ export class DyFM_Crypto {
|
|
|
158
191
|
.replace(/=+$/, '');
|
|
159
192
|
} catch (error) {
|
|
160
193
|
throw new DyFM_Error({
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
errorCode: CryptoErrorCode.ENCRYPTION_FAILED
|
|
194
|
+
...this.getDefaultErrorSettings('encrypt', error),
|
|
195
|
+
errorCode: 'DyFM-CRY-ENC',
|
|
164
196
|
});
|
|
165
197
|
}
|
|
166
198
|
}
|
|
@@ -186,6 +218,12 @@ export class DyFM_Crypto {
|
|
|
186
218
|
// Parse the combined data
|
|
187
219
|
const combined = CryptoJS.enc.Base64.parse(base64);
|
|
188
220
|
|
|
221
|
+
// Validate minimum length (IV + Salt + minimum ciphertext)
|
|
222
|
+
const minLength = (finalConfig.ivLength + finalConfig.saltLength + 16) / 4; // 16 bytes minimum for ciphertext
|
|
223
|
+
if (combined.words.length < minLength) {
|
|
224
|
+
throw new Error('Invalid encrypted data length');
|
|
225
|
+
}
|
|
226
|
+
|
|
189
227
|
// Extract IV, salt, and ciphertext
|
|
190
228
|
const iv = CryptoJS.lib.WordArray.create(combined.words.slice(0, finalConfig.ivLength / 4));
|
|
191
229
|
const salt = CryptoJS.lib.WordArray.create(
|
|
@@ -212,15 +250,13 @@ export class DyFM_Crypto {
|
|
|
212
250
|
}
|
|
213
251
|
);
|
|
214
252
|
|
|
215
|
-
//
|
|
253
|
+
// Parse JSON
|
|
216
254
|
const decryptedStr = decrypted.toString(CryptoJS.enc.Utf8);
|
|
217
|
-
|
|
218
|
-
return this.safeDeserialize<T>(jsonStr);
|
|
255
|
+
return this.safeDeserialize<T>(decryptedStr);
|
|
219
256
|
} catch (error) {
|
|
220
257
|
throw new DyFM_Error({
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
errorCode: CryptoErrorCode.DECRYPTION_FAILED
|
|
258
|
+
...this.getDefaultErrorSettings('decrypt', error),
|
|
259
|
+
errorCode: 'DyFM-CRY-DRY',
|
|
224
260
|
});
|
|
225
261
|
}
|
|
226
262
|
}
|