@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.
Files changed (290) hide show
  1. package/.github/workflows/main.yml +11 -51
  2. package/build/_collections/constants/error-defaults.const.d.ts +8 -0
  3. package/build/_collections/constants/error-defaults.const.d.ts.map +1 -1
  4. package/build/_collections/constants/error-defaults.const.js +8 -0
  5. package/build/_collections/constants/error-defaults.const.js.map +1 -1
  6. package/build/_collections/constants/global-settings.const.d.ts +8 -0
  7. package/build/_collections/constants/global-settings.const.d.ts.map +1 -1
  8. package/build/_collections/constants/global-settings.const.js +9 -0
  9. package/build/_collections/constants/global-settings.const.js.map +1 -1
  10. package/build/_collections/constants/numbers.const.d.ts +32 -0
  11. package/build/_collections/constants/numbers.const.d.ts.map +1 -1
  12. package/build/_collections/constants/numbers.const.js +32 -0
  13. package/build/_collections/constants/numbers.const.js.map +1 -1
  14. package/build/_collections/constants/times.const.d.ts +31 -0
  15. package/build/_collections/constants/times.const.d.ts.map +1 -1
  16. package/build/_collections/constants/times.const.js +31 -0
  17. package/build/_collections/constants/times.const.js.map +1 -1
  18. package/build/_collections/utils/array.util.d.ts +136 -7
  19. package/build/_collections/utils/array.util.d.ts.map +1 -1
  20. package/build/_collections/utils/array.util.js +132 -2
  21. package/build/_collections/utils/array.util.js.map +1 -1
  22. package/build/_collections/utils/array.util.spec.js.map +1 -1
  23. package/build/_collections/utils/log.util.d.ts +123 -0
  24. package/build/_collections/utils/log.util.d.ts.map +1 -1
  25. package/build/_collections/utils/log.util.js +123 -0
  26. package/build/_collections/utils/log.util.js.map +1 -1
  27. package/build/_collections/utils/math/box-bounds.spec.js +2 -5
  28. package/build/_collections/utils/math/box-bounds.spec.js.map +1 -1
  29. package/build/_collections/utils/math/box-bounds.util.d.ts +52 -6
  30. package/build/_collections/utils/math/box-bounds.util.d.ts.map +1 -1
  31. package/build/_collections/utils/math/box-bounds.util.js +57 -5
  32. package/build/_collections/utils/math/box-bounds.util.js.map +1 -1
  33. package/build/_collections/utils/math/box-bounds.util.spec.js +1 -1
  34. package/build/_collections/utils/math/box-bounds.util.spec.js.map +1 -1
  35. package/build/_collections/utils/math/math.util.d.ts +30 -0
  36. package/build/_collections/utils/math/math.util.d.ts.map +1 -1
  37. package/build/_collections/utils/math/math.util.js +30 -0
  38. package/build/_collections/utils/math/math.util.js.map +1 -1
  39. package/build/_collections/utils/math/random.util.d.ts +19 -2
  40. package/build/_collections/utils/math/random.util.d.ts.map +1 -1
  41. package/build/_collections/utils/math/random.util.js +22 -0
  42. package/build/_collections/utils/math/random.util.js.map +1 -1
  43. package/build/_collections/utils/math/random.util.spec.js.map +1 -1
  44. package/build/_collections/utils/math/vector2.util.d.ts +142 -20
  45. package/build/_collections/utils/math/vector2.util.d.ts.map +1 -1
  46. package/build/_collections/utils/math/vector2.util.js +126 -0
  47. package/build/_collections/utils/math/vector2.util.js.map +1 -1
  48. package/build/_collections/utils/round-list.util.d.ts +36 -1
  49. package/build/_collections/utils/round-list.util.d.ts.map +1 -1
  50. package/build/_collections/utils/round-list.util.js +35 -0
  51. package/build/_collections/utils/round-list.util.js.map +1 -1
  52. package/build/_collections/utils/shared.util.js.map +1 -1
  53. package/build/_collections/utils/stack.util.js +3 -3
  54. package/build/_collections/utils/stack.util.js.map +1 -1
  55. package/build/_collections/utils/string.util.d.ts +8 -1
  56. package/build/_collections/utils/string.util.d.ts.map +1 -1
  57. package/build/_collections/utils/string.util.js +8 -1
  58. package/build/_collections/utils/string.util.js.map +1 -1
  59. package/build/_collections/utils/time.util.d.ts +29 -0
  60. package/build/_collections/utils/time.util.d.ts.map +1 -1
  61. package/build/_collections/utils/time.util.js +29 -0
  62. package/build/_collections/utils/time.util.js.map +1 -1
  63. package/build/_collections/utils/type-cloning-facility.util.d.ts +29 -3
  64. package/build/_collections/utils/type-cloning-facility.util.d.ts.map +1 -1
  65. package/build/_collections/utils/type-cloning-facility.util.js +53 -3
  66. package/build/_collections/utils/type-cloning-facility.util.js.map +1 -1
  67. package/build/_collections/utils/utilities.util.d.ts +49 -2
  68. package/build/_collections/utils/utilities.util.d.ts.map +1 -1
  69. package/build/_collections/utils/utilities.util.js +53 -1
  70. package/build/_collections/utils/utilities.util.js.map +1 -1
  71. package/build/_collections/utils/utilities.util.spec.js.map +1 -1
  72. package/build/_collections/utils/uuid.util.d.ts +5 -0
  73. package/build/_collections/utils/uuid.util.d.ts.map +1 -1
  74. package/build/_collections/utils/uuid.util.js +5 -0
  75. package/build/_collections/utils/uuid.util.js.map +1 -1
  76. package/build/_enums/basic-property-type.enum.d.ts +8 -0
  77. package/build/_enums/basic-property-type.enum.d.ts.map +1 -1
  78. package/build/_enums/basic-property-type.enum.js +8 -0
  79. package/build/_enums/basic-property-type.enum.js.map +1 -1
  80. package/build/_enums/data-model-type.enum.d.ts +8 -4
  81. package/build/_enums/data-model-type.enum.d.ts.map +1 -1
  82. package/build/_enums/data-model-type.enum.js +8 -4
  83. package/build/_enums/data-model-type.enum.js.map +1 -1
  84. package/build/_enums/environment-flag.enum.d.ts +18 -0
  85. package/build/_enums/environment-flag.enum.d.ts.map +1 -1
  86. package/build/_enums/environment-flag.enum.js +18 -0
  87. package/build/_enums/environment-flag.enum.js.map +1 -1
  88. package/build/_enums/error-level.enum.d.ts +10 -0
  89. package/build/_enums/error-level.enum.d.ts.map +1 -1
  90. package/build/_enums/error-level.enum.js +10 -0
  91. package/build/_enums/error-level.enum.js.map +1 -1
  92. package/build/_enums/http-call-type.enum.d.ts +6 -2
  93. package/build/_enums/http-call-type.enum.d.ts.map +1 -1
  94. package/build/_enums/http-call-type.enum.js +6 -2
  95. package/build/_enums/http-call-type.enum.js.map +1 -1
  96. package/build/_enums/http-response-type.enum.d.ts +8 -0
  97. package/build/_enums/http-response-type.enum.d.ts.map +1 -1
  98. package/build/_enums/http-response-type.enum.js +8 -0
  99. package/build/_enums/http-response-type.enum.js.map +1 -1
  100. package/build/_enums/log-style.enum.d.ts +8 -0
  101. package/build/_enums/log-style.enum.d.ts.map +1 -1
  102. package/build/_enums/log-style.enum.js +8 -0
  103. package/build/_enums/log-style.enum.js.map +1 -1
  104. package/build/_enums/time/day-of-week.enum.d.ts +13 -1
  105. package/build/_enums/time/day-of-week.enum.d.ts.map +1 -1
  106. package/build/_enums/time/day-of-week.enum.js +13 -1
  107. package/build/_enums/time/day-of-week.enum.js.map +1 -1
  108. package/build/_enums/time/month.enum.d.ts +8 -0
  109. package/build/_enums/time/month.enum.d.ts.map +1 -1
  110. package/build/_enums/time/month.enum.js +8 -0
  111. package/build/_enums/time/month.enum.js.map +1 -1
  112. package/build/_enums/time/relative-date.enum.d.ts +10 -0
  113. package/build/_enums/time/relative-date.enum.d.ts.map +1 -1
  114. package/build/_enums/time/relative-date.enum.js +10 -0
  115. package/build/_enums/time/relative-date.enum.js.map +1 -1
  116. package/build/_models/control-models/data-model-params.control-model.d.ts +4 -4
  117. package/build/_models/control-models/data-model-params.control-model.d.ts.map +1 -1
  118. package/build/_models/control-models/data-model-params.control-model.js.map +1 -1
  119. package/build/_models/control-models/data-property-params.control-model.d.ts.map +1 -1
  120. package/build/_models/control-models/data-property-params.control-model.js.map +1 -1
  121. package/build/_models/control-models/error.control-model.spec.js.map +1 -1
  122. package/build/_models/interfaces/box-bounds.interface.d.ts +8 -0
  123. package/build/_models/interfaces/box-bounds.interface.d.ts.map +1 -0
  124. package/build/_models/interfaces/box-bounds.interface.js +3 -0
  125. package/build/_models/interfaces/box-bounds.interface.js.map +1 -0
  126. package/build/_models/interfaces/environment/global-settings.interface.d.ts +1 -0
  127. package/build/_models/interfaces/environment/global-settings.interface.d.ts.map +1 -1
  128. package/build/_models/interfaces/route-settings.interface.d.ts +6 -1
  129. package/build/_models/interfaces/route-settings.interface.d.ts.map +1 -1
  130. package/build/_modules/crypto/_collections/crypto.util.d.ts +11 -17
  131. package/build/_modules/crypto/_collections/crypto.util.d.ts.map +1 -1
  132. package/build/_modules/crypto/_collections/crypto.util.js +74 -58
  133. package/build/_modules/crypto/_collections/crypto.util.js.map +1 -1
  134. package/build/_modules/crypto/_collections/crypto.util.spec.js +390 -0
  135. package/build/_modules/crypto/_collections/crypto.util.spec.js.map +1 -1
  136. package/build/_modules/custom-data/_collections/cud-module-settings.const.d.ts +6 -0
  137. package/build/_modules/custom-data/_collections/cud-module-settings.const.d.ts.map +1 -1
  138. package/build/_modules/custom-data/_collections/cud-module-settings.const.js +6 -0
  139. package/build/_modules/custom-data/_collections/cud-module-settings.const.js.map +1 -1
  140. package/build/_modules/custom-data/_models/cud.data-model.d.ts +3 -0
  141. package/build/_modules/custom-data/_models/cud.data-model.d.ts.map +1 -1
  142. package/build/_modules/custom-data/_models/cud.data-model.js +3 -0
  143. package/build/_modules/custom-data/_models/cud.data-model.js.map +1 -1
  144. package/build/_modules/location/_collections/loc-country-divisions.const.d.ts +1 -0
  145. package/build/_modules/location/_collections/loc-country-divisions.const.d.ts.map +1 -1
  146. package/build/_modules/location/_collections/loc-country-divisions.const.js +1 -0
  147. package/build/_modules/location/_collections/loc-country-divisions.const.js.map +1 -1
  148. package/build/_modules/location/_collections/loc-regions.util.d.ts +4 -0
  149. package/build/_modules/location/_collections/loc-regions.util.d.ts.map +1 -1
  150. package/build/_modules/location/_collections/loc-regions.util.js +4 -0
  151. package/build/_modules/location/_collections/loc-regions.util.js.map +1 -1
  152. package/build/_modules/location/_collections/loc.util.d.ts +9 -0
  153. package/build/_modules/location/_collections/loc.util.d.ts.map +1 -1
  154. package/build/_modules/location/_collections/loc.util.js +9 -0
  155. package/build/_modules/location/_collections/loc.util.js.map +1 -1
  156. package/build/_modules/location/_enums/loc-region.enum.d.ts +3 -0
  157. package/build/_modules/location/_enums/loc-region.enum.d.ts.map +1 -1
  158. package/build/_modules/location/_enums/loc-region.enum.js +3 -0
  159. package/build/_modules/location/_enums/loc-region.enum.js.map +1 -1
  160. package/build/_modules/location/_enums/loc-sub-region.enum.d.ts +3 -0
  161. package/build/_modules/location/_enums/loc-sub-region.enum.d.ts.map +1 -1
  162. package/build/_modules/location/_enums/loc-sub-region.enum.js +3 -0
  163. package/build/_modules/location/_enums/loc-sub-region.enum.js.map +1 -1
  164. package/build/_modules/location/_enums/loc-subdivision-region-type.enum.d.ts +37 -34
  165. package/build/_modules/location/_enums/loc-subdivision-region-type.enum.d.ts.map +1 -1
  166. package/build/_modules/location/_enums/loc-subdivision-region-type.enum.js +3 -0
  167. package/build/_modules/location/_enums/loc-subdivision-region-type.enum.js.map +1 -1
  168. package/build/_modules/location/_models/loc-coordinates.interface.d.ts +1 -0
  169. package/build/_modules/location/_models/loc-coordinates.interface.d.ts.map +1 -1
  170. package/build/_modules/open-ai/_enums/open-ai-model.enum.d.ts +10 -7
  171. package/build/_modules/open-ai/_enums/open-ai-model.enum.d.ts.map +1 -1
  172. package/build/_modules/open-ai/_enums/open-ai-model.enum.js +3 -0
  173. package/build/_modules/open-ai/_enums/open-ai-model.enum.js.map +1 -1
  174. package/build/_modules/pipe/_enums/pip-range-pipe-setting.enum.d.ts +3 -0
  175. package/build/_modules/pipe/_enums/pip-range-pipe-setting.enum.d.ts.map +1 -1
  176. package/build/_modules/pipe/_enums/pip-range-pipe-setting.enum.js +3 -0
  177. package/build/_modules/pipe/_enums/pip-range-pipe-setting.enum.js.map +1 -1
  178. package/build/_modules/pipe/_enums/pip.enum.d.ts +14 -0
  179. package/build/_modules/pipe/_enums/pip.enum.d.ts.map +1 -1
  180. package/build/_modules/pipe/_enums/pip.enum.js +11 -0
  181. package/build/_modules/pipe/_enums/pip.enum.js.map +1 -1
  182. package/build/_modules/socket/_enums/sck-event-key.enum.d.ts +3 -0
  183. package/build/_modules/socket/_enums/sck-event-key.enum.d.ts.map +1 -1
  184. package/build/_modules/socket/_enums/sck-event-key.enum.js +3 -0
  185. package/build/_modules/socket/_enums/sck-event-key.enum.js.map +1 -1
  186. package/build/_modules/socket/_models/sck-client-params.control-model.d.ts +12 -0
  187. package/build/_modules/socket/_models/sck-client-params.control-model.d.ts.map +1 -1
  188. package/build/_modules/socket/_models/sck-client-params.control-model.js +12 -0
  189. package/build/_modules/socket/_models/sck-client-params.control-model.js.map +1 -1
  190. package/build/_modules/socket/_models/sck-socket-event.control-model.d.ts +12 -1
  191. package/build/_modules/socket/_models/sck-socket-event.control-model.d.ts.map +1 -1
  192. package/build/_modules/socket/_models/sck-socket-event.control-model.js +12 -1
  193. package/build/_modules/socket/_models/sck-socket-event.control-model.js.map +1 -1
  194. package/build/_modules/socket/_services/sck-client.service-base.d.ts +4 -0
  195. package/build/_modules/socket/_services/sck-client.service-base.d.ts.map +1 -1
  196. package/build/_modules/socket/_services/sck-client.service-base.js +4 -0
  197. package/build/_modules/socket/_services/sck-client.service-base.js.map +1 -1
  198. package/build/_modules/test/_collections/tst-module-settings.const.d.ts +9 -0
  199. package/build/_modules/test/_collections/tst-module-settings.const.d.ts.map +1 -1
  200. package/build/_modules/test/_collections/tst-module-settings.const.js +9 -0
  201. package/build/_modules/test/_collections/tst-module-settings.const.js.map +1 -1
  202. package/build/_modules/usage/_models/usg-action.control-model.d.ts +13 -0
  203. package/build/_modules/usage/_models/usg-action.control-model.d.ts.map +1 -1
  204. package/build/_modules/usage/_models/usg-action.control-model.js +13 -0
  205. package/build/_modules/usage/_models/usg-action.control-model.js.map +1 -1
  206. package/build/_modules/usage/_models/usg-daily-usage-data.control-model.d.ts +14 -0
  207. package/build/_modules/usage/_models/usg-daily-usage-data.control-model.d.ts.map +1 -1
  208. package/build/_modules/usage/_models/usg-daily-usage-data.control-model.js +14 -0
  209. package/build/_modules/usage/_models/usg-daily-usage-data.control-model.js.map +1 -1
  210. package/build/_modules/usage/_models/usg-data.control-model.d.ts +16 -0
  211. package/build/_modules/usage/_models/usg-data.control-model.d.ts.map +1 -1
  212. package/build/_modules/usage/_models/usg-data.control-model.js +16 -0
  213. package/build/_modules/usage/_models/usg-data.control-model.js.map +1 -1
  214. package/build/_modules/usage/_models/usg-session.data-model.d.ts +17 -0
  215. package/build/_modules/usage/_models/usg-session.data-model.d.ts.map +1 -1
  216. package/build/_modules/usage/_models/usg-session.data-model.js +17 -0
  217. package/build/_modules/usage/_models/usg-session.data-model.js.map +1 -1
  218. package/build/_modules/usage/_models/usg-session.data-model.spec.js.map +1 -1
  219. package/build/index.d.ts +1 -0
  220. package/build/index.d.ts.map +1 -1
  221. package/build/index.js +1 -0
  222. package/build/index.js.map +1 -1
  223. package/futdevpro-fsm-dynamo-01.10.39.tgz +0 -0
  224. package/package.json +9 -5
  225. package/src/_collections/constants/error-defaults.const.ts +8 -0
  226. package/src/_collections/constants/global-settings.const.ts +12 -2
  227. package/src/_collections/constants/numbers.const.ts +32 -0
  228. package/src/_collections/constants/times.const.ts +37 -0
  229. package/src/_collections/utils/array.util.spec.ts +36 -38
  230. package/src/_collections/utils/array.util.ts +146 -12
  231. package/src/_collections/utils/log.util.ts +126 -2
  232. package/src/_collections/utils/math/box-bounds.spec.ts +8 -13
  233. package/src/_collections/utils/math/box-bounds.util.spec.ts +3 -3
  234. package/src/_collections/utils/math/box-bounds.util.ts +65 -12
  235. package/src/_collections/utils/math/math.util.ts +30 -6
  236. package/src/_collections/utils/math/random.util.spec.ts +7 -7
  237. package/src/_collections/utils/math/random.util.ts +27 -4
  238. package/src/_collections/utils/math/vector2.util.ts +148 -21
  239. package/src/_collections/utils/round-list.util.ts +36 -3
  240. package/src/_collections/utils/shared.util.ts +17 -17
  241. package/src/_collections/utils/stack.util.ts +6 -6
  242. package/src/_collections/utils/string.util.ts +8 -1
  243. package/src/_collections/utils/time.util.ts +37 -2
  244. package/src/_collections/utils/type-cloning-facility.util.ts +57 -8
  245. package/src/_collections/utils/utilities.util.spec.ts +2 -2
  246. package/src/_collections/utils/utilities.util.ts +61 -8
  247. package/src/_collections/utils/uuid.util.ts +5 -0
  248. package/src/_enums/basic-property-type.enum.ts +8 -0
  249. package/src/_enums/data-model-type.enum.ts +11 -6
  250. package/src/_enums/environment-flag.enum.ts +18 -0
  251. package/src/_enums/error-level.enum.ts +10 -0
  252. package/src/_enums/http-call-type.enum.ts +6 -2
  253. package/src/_enums/http-response-type.enum.ts +8 -0
  254. package/src/_enums/log-style.enum.ts +8 -0
  255. package/src/_enums/time/day-of-week.enum.ts +13 -1
  256. package/src/_enums/time/month.enum.ts +8 -0
  257. package/src/_enums/time/relative-date.enum.ts +10 -0
  258. package/src/_models/control-models/data-model-params.control-model.ts +6 -6
  259. package/src/_models/control-models/data-property-params.control-model.ts +1 -1
  260. package/src/_models/control-models/error.control-model.spec.ts +2 -2
  261. package/src/_models/interfaces/box-bounds.interface.ts +8 -0
  262. package/src/_models/interfaces/environment/global-settings.interface.ts +2 -0
  263. package/src/_models/interfaces/route-settings.interface.ts +6 -1
  264. package/src/_modules/crypto/_collections/crypto.util.spec.ts +428 -0
  265. package/src/_modules/crypto/_collections/crypto.util.ts +88 -52
  266. package/src/_modules/custom-data/_collections/cud-module-settings.const.ts +6 -0
  267. package/src/_modules/custom-data/_models/cud.data-model.ts +3 -0
  268. package/src/_modules/location/_collections/loc-country-divisions.const.ts +2 -1
  269. package/src/_modules/location/_collections/loc-regions.util.ts +4 -0
  270. package/src/_modules/location/_collections/loc.util.ts +13 -5
  271. package/src/_modules/location/_enums/loc-region.enum.ts +3 -0
  272. package/src/_modules/location/_enums/loc-sub-region.enum.ts +3 -0
  273. package/src/_modules/location/_enums/loc-subdivision-region-type.enum.ts +37 -34
  274. package/src/_modules/location/_models/loc-coordinates.interface.ts +1 -0
  275. package/src/_modules/open-ai/_enums/open-ai-model.enum.ts +11 -8
  276. package/src/_modules/pipe/_enums/pip-range-pipe-setting.enum.ts +3 -0
  277. package/src/_modules/pipe/_enums/pip.enum.ts +17 -3
  278. package/src/_modules/socket/_enums/sck-event-key.enum.ts +3 -0
  279. package/src/_modules/socket/_models/sck-client-params.control-model.ts +12 -0
  280. package/src/_modules/socket/_models/sck-socket-event.control-model.ts +12 -1
  281. package/src/_modules/socket/_services/sck-client.service-base.ts +4 -0
  282. package/src/_modules/test/_collections/tst-module-settings.const.ts +9 -0
  283. package/src/_modules/usage/_models/usg-action.control-model.ts +13 -0
  284. package/src/_modules/usage/_models/usg-daily-usage-data.control-model.ts +14 -0
  285. package/src/_modules/usage/_models/usg-data.control-model.ts +16 -0
  286. package/src/_modules/usage/_models/usg-session.data-model.spec.ts +2 -1
  287. package/src/_modules/usage/_models/usg-session.data-model.ts +17 -0
  288. package/src/index.ts +1 -0
  289. package/tsconfig.json +1 -0
  290. 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 = 'DyFM-CRY-DRY',
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 / 32
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<T>(data: T, key: string): void {
47
- if (data === undefined || data === null) {
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
- message: 'Data is required',
50
- error: new Error('Data is required'),
51
- errorCode: CryptoErrorCode.INVALID_DATA
55
+ ...this.getDefaultErrorSettings('validateInput'),
56
+ errorCode: 'DyFM-CRY-IKY',
57
+ message: 'Invalid encryption key'
52
58
  });
53
59
  }
54
60
 
55
- if (!key || typeof key !== 'string' || key.trim().length === 0) {
61
+ if (data === undefined || data === null) {
56
62
  throw new DyFM_Error({
57
- message: 'Valid key is required',
58
- error: new Error('Key must be a non-empty string'),
59
- errorCode: CryptoErrorCode.INVALID_KEY
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 secure random padding
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 generatePadding(length: number): string {
69
- return CryptoJS.lib.WordArray.random(length).toString();
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
- message: 'Failed to serialize data',
96
- error: error instanceof Error ? error : new Error(String(error)),
97
- errorCode: CryptoErrorCode.INVALID_DATA
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
- return JSON.parse(data);
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
- message: 'Failed to deserialize data',
113
- error: error instanceof Error ? error : new Error(String(error)),
114
- errorCode: CryptoErrorCode.DECRYPTION_FAILED
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
- // Generate random IV and salt
133
- const iv = CryptoJS.lib.WordArray.random(finalConfig.ivLength);
134
- const salt = CryptoJS.lib.WordArray.random(finalConfig.saltLength);
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(paddedData, derivedKey, {
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
- message: 'Error encrypting data',
162
- error: error instanceof Error ? error : new Error(String(error)),
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
- // Remove padding and parse JSON
253
+ // Parse JSON
216
254
  const decryptedStr = decrypted.toString(CryptoJS.enc.Utf8);
217
- const jsonStr = decryptedStr.slice(32); // Remove 16-byte padding
218
- return this.safeDeserialize<T>(jsonStr);
255
+ return this.safeDeserialize<T>(decryptedStr);
219
256
  } catch (error) {
220
257
  throw new DyFM_Error({
221
- message: 'Error decrypting data',
222
- error: error instanceof Error ? error : new Error(String(error)),
223
- errorCode: CryptoErrorCode.DECRYPTION_FAILED
258
+ ...this.getDefaultErrorSettings('decrypt', error),
259
+ errorCode: 'DyFM-CRY-DRY',
224
260
  });
225
261
  }
226
262
  }