emilsoftware-utilities 2.0.0-dev.21 → 2.0.0-dev.23

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 (379) hide show
  1. package/dist/DailyFileTransport.d.ts +15 -0
  2. package/dist/DailyFileTransport.js +67 -0
  3. package/dist/DailyFileTransport.js.map +1 -0
  4. package/dist/DatabaseUpdater.js +0 -2
  5. package/dist/DatabaseUpdater.js.map +1 -1
  6. package/dist/ExecutionTimeLogger.js +2 -2
  7. package/dist/ExecutionTimeLogger.js.map +1 -1
  8. package/dist/Logger.d.ts +0 -2
  9. package/dist/Logger.js +6 -70
  10. package/dist/Logger.js.map +1 -1
  11. package/dist/Utilities.d.ts +8 -3
  12. package/dist/Utilities.js +61 -16
  13. package/dist/Utilities.js.map +1 -1
  14. package/dist/accessi-module/AccessiModule.d.ts +60 -0
  15. package/dist/accessi-module/AccessiModule.js +21 -5
  16. package/dist/accessi-module/AccessiModule.js.map +1 -1
  17. package/dist/accessi-module/Console/accessiFetch.d.ts +7 -0
  18. package/dist/accessi-module/Console/accessiFetch.js +59 -0
  19. package/dist/accessi-module/Console/accessiFetch.js.map +1 -0
  20. package/dist/accessi-module/Console/console.css +370 -0
  21. package/dist/accessi-module/Console/console.d.ts +1 -0
  22. package/dist/accessi-module/Console/console.js +1105 -0
  23. package/dist/accessi-module/Console/console.js.map +1 -0
  24. package/dist/accessi-module/Console/generated/accessiApi.d.ts +376 -0
  25. package/dist/accessi-module/Console/generated/accessiApi.js +363 -0
  26. package/dist/accessi-module/Console/generated/accessiApi.js.map +1 -0
  27. package/dist/accessi-module/Console/generated/model/abilitazioneMenu.d.ts +27 -0
  28. package/dist/accessi-module/Console/generated/model/abilitazioneMenu.js +3 -0
  29. package/dist/accessi-module/Console/generated/model/abilitazioneMenu.js.map +1 -0
  30. package/dist/accessi-module/Console/generated/model/abilitazioneMenuTipoAbilitazione.d.ts +16 -0
  31. package/dist/accessi-module/Console/generated/model/abilitazioneMenuTipoAbilitazione.js +17 -0
  32. package/dist/accessi-module/Console/generated/model/abilitazioneMenuTipoAbilitazione.js.map +1 -0
  33. package/dist/accessi-module/Console/generated/model/actionResponse.d.ts +12 -0
  34. package/dist/accessi-module/Console/generated/model/actionResponse.js +9 -0
  35. package/dist/accessi-module/Console/generated/model/actionResponse.js.map +1 -0
  36. package/dist/accessi-module/Console/generated/model/assignPermissionsToUserRequest.d.ts +11 -0
  37. package/dist/accessi-module/Console/generated/model/assignPermissionsToUserRequest.js +3 -0
  38. package/dist/accessi-module/Console/generated/model/assignPermissionsToUserRequest.js.map +1 -0
  39. package/dist/accessi-module/Console/generated/model/assignRolesToUserRequest.d.ts +10 -0
  40. package/dist/accessi-module/Console/generated/model/assignRolesToUserRequest.js +9 -0
  41. package/dist/accessi-module/Console/generated/model/assignRolesToUserRequest.js.map +1 -0
  42. package/dist/accessi-module/Console/generated/model/authenticatedTokenPayloadDto.d.ts +10 -0
  43. package/dist/accessi-module/Console/generated/model/authenticatedTokenPayloadDto.js +3 -0
  44. package/dist/accessi-module/Console/generated/model/authenticatedTokenPayloadDto.js.map +1 -0
  45. package/dist/accessi-module/Console/generated/model/authenticatedUserPayloadDto.d.ts +19 -0
  46. package/dist/accessi-module/Console/generated/model/authenticatedUserPayloadDto.js +9 -0
  47. package/dist/accessi-module/Console/generated/model/authenticatedUserPayloadDto.js.map +1 -0
  48. package/dist/accessi-module/Console/generated/model/confirmResetPasswordRequest.d.ts +14 -0
  49. package/dist/accessi-module/Console/generated/model/confirmResetPasswordRequest.js +9 -0
  50. package/dist/accessi-module/Console/generated/model/confirmResetPasswordRequest.js.map +1 -0
  51. package/dist/accessi-module/Console/generated/model/createFederatedIdentityRequest.d.ts +13 -0
  52. package/dist/accessi-module/Console/generated/model/createFederatedIdentityRequest.js +9 -0
  53. package/dist/accessi-module/Console/generated/model/createFederatedIdentityRequest.js.map +1 -0
  54. package/dist/accessi-module/Console/generated/model/createFederatedProviderRequest.d.ts +13 -0
  55. package/dist/accessi-module/Console/generated/model/createFederatedProviderRequest.js +9 -0
  56. package/dist/accessi-module/Console/generated/model/createFederatedProviderRequest.js.map +1 -0
  57. package/dist/accessi-module/Console/generated/model/createFederatedUserRequest.d.ts +18 -0
  58. package/dist/accessi-module/Console/generated/model/createFederatedUserRequest.js +3 -0
  59. package/dist/accessi-module/Console/generated/model/createFederatedUserRequest.js.map +1 -0
  60. package/dist/accessi-module/Console/generated/model/errorResponse.d.ts +18 -0
  61. package/dist/accessi-module/Console/generated/model/errorResponse.js +9 -0
  62. package/dist/accessi-module/Console/generated/model/errorResponse.js.map +1 -0
  63. package/dist/accessi-module/Console/generated/model/federatedIdentityListResponse.d.ts +14 -0
  64. package/dist/accessi-module/Console/generated/model/federatedIdentityListResponse.js +3 -0
  65. package/dist/accessi-module/Console/generated/model/federatedIdentityListResponse.js.map +1 -0
  66. package/dist/accessi-module/Console/generated/model/federatedIdentityResponse.d.ts +14 -0
  67. package/dist/accessi-module/Console/generated/model/federatedIdentityResponse.js +3 -0
  68. package/dist/accessi-module/Console/generated/model/federatedIdentityResponse.js.map +1 -0
  69. package/dist/accessi-module/Console/generated/model/federatedIdentityResponseDto.d.ts +23 -0
  70. package/dist/accessi-module/Console/generated/model/federatedIdentityResponseDto.js +9 -0
  71. package/dist/accessi-module/Console/generated/model/federatedIdentityResponseDto.js.map +1 -0
  72. package/dist/accessi-module/Console/generated/model/federatedProviderListResponse.d.ts +14 -0
  73. package/dist/accessi-module/Console/generated/model/federatedProviderListResponse.js +3 -0
  74. package/dist/accessi-module/Console/generated/model/federatedProviderListResponse.js.map +1 -0
  75. package/dist/accessi-module/Console/generated/model/federatedProviderResponse.d.ts +14 -0
  76. package/dist/accessi-module/Console/generated/model/federatedProviderResponse.js +3 -0
  77. package/dist/accessi-module/Console/generated/model/federatedProviderResponse.js.map +1 -0
  78. package/dist/accessi-module/Console/generated/model/federatedProviderResponseDto.d.ts +13 -0
  79. package/dist/accessi-module/Console/generated/model/federatedProviderResponseDto.js +9 -0
  80. package/dist/accessi-module/Console/generated/model/federatedProviderResponseDto.js.map +1 -0
  81. package/dist/accessi-module/Console/generated/model/filtriUtente.d.ts +32 -0
  82. package/dist/accessi-module/Console/generated/model/filtriUtente.js +9 -0
  83. package/dist/accessi-module/Console/generated/model/filtriUtente.js.map +1 -0
  84. package/dist/accessi-module/Console/generated/model/getFiltriResponse.d.ts +14 -0
  85. package/dist/accessi-module/Console/generated/model/getFiltriResponse.js +3 -0
  86. package/dist/accessi-module/Console/generated/model/getFiltriResponse.js.map +1 -0
  87. package/dist/accessi-module/Console/generated/model/getFiltriUtenteParams.d.ts +12 -0
  88. package/dist/accessi-module/Console/generated/model/getFiltriUtenteParams.js +9 -0
  89. package/dist/accessi-module/Console/generated/model/getFiltriUtenteParams.js.map +1 -0
  90. package/dist/accessi-module/Console/generated/model/getFiltriUtenteResponse.d.ts +14 -0
  91. package/dist/accessi-module/Console/generated/model/getFiltriUtenteResponse.js +3 -0
  92. package/dist/accessi-module/Console/generated/model/getFiltriUtenteResponse.js.map +1 -0
  93. package/dist/accessi-module/Console/generated/model/getGroupsWithMenusParams.d.ts +12 -0
  94. package/dist/accessi-module/Console/generated/model/getGroupsWithMenusParams.js +9 -0
  95. package/dist/accessi-module/Console/generated/model/getGroupsWithMenusParams.js.map +1 -0
  96. package/dist/accessi-module/Console/generated/model/getGroupsWithMenusResponse.d.ts +14 -0
  97. package/dist/accessi-module/Console/generated/model/getGroupsWithMenusResponse.js +3 -0
  98. package/dist/accessi-module/Console/generated/model/getGroupsWithMenusResponse.js.map +1 -0
  99. package/dist/accessi-module/Console/generated/model/getMenusResponse.d.ts +14 -0
  100. package/dist/accessi-module/Console/generated/model/getMenusResponse.js +3 -0
  101. package/dist/accessi-module/Console/generated/model/getMenusResponse.js.map +1 -0
  102. package/dist/accessi-module/Console/generated/model/getRolesResponse.d.ts +14 -0
  103. package/dist/accessi-module/Console/generated/model/getRolesResponse.js +3 -0
  104. package/dist/accessi-module/Console/generated/model/getRolesResponse.js.map +1 -0
  105. package/dist/accessi-module/Console/generated/model/getUserByTokenRequest.d.ts +10 -0
  106. package/dist/accessi-module/Console/generated/model/getUserByTokenRequest.js +9 -0
  107. package/dist/accessi-module/Console/generated/model/getUserByTokenRequest.js.map +1 -0
  108. package/dist/accessi-module/Console/generated/model/getUserByTokenResponse.d.ts +14 -0
  109. package/dist/accessi-module/Console/generated/model/getUserByTokenResponse.js +3 -0
  110. package/dist/accessi-module/Console/generated/model/getUserByTokenResponse.js.map +1 -0
  111. package/dist/accessi-module/Console/generated/model/getUsersParams.d.ts +24 -0
  112. package/dist/accessi-module/Console/generated/model/getUsersParams.js +9 -0
  113. package/dist/accessi-module/Console/generated/model/getUsersParams.js.map +1 -0
  114. package/dist/accessi-module/Console/generated/model/getUsersResponse.d.ts +14 -0
  115. package/dist/accessi-module/Console/generated/model/getUsersResponse.js +3 -0
  116. package/dist/accessi-module/Console/generated/model/getUsersResponse.js.map +1 -0
  117. package/dist/accessi-module/Console/generated/model/getUsersResult.d.ts +17 -0
  118. package/dist/accessi-module/Console/generated/model/getUsersResult.js +3 -0
  119. package/dist/accessi-module/Console/generated/model/getUsersResult.js.map +1 -0
  120. package/dist/accessi-module/Console/generated/model/getUsersResultExtensionFields.d.ts +12 -0
  121. package/dist/accessi-module/Console/generated/model/getUsersResultExtensionFields.js +9 -0
  122. package/dist/accessi-module/Console/generated/model/getUsersResultExtensionFields.js.map +1 -0
  123. package/dist/accessi-module/Console/generated/model/groupWithMenusEntity.d.ts +19 -0
  124. package/dist/accessi-module/Console/generated/model/groupWithMenusEntity.js +3 -0
  125. package/dist/accessi-module/Console/generated/model/groupWithMenusEntity.js.map +1 -0
  126. package/dist/accessi-module/Console/generated/model/index.d.ts +75 -0
  127. package/dist/accessi-module/Console/generated/model/index.js +92 -0
  128. package/dist/accessi-module/Console/generated/model/index.js.map +1 -0
  129. package/dist/accessi-module/Console/generated/model/loginRequest.d.ts +12 -0
  130. package/dist/accessi-module/Console/generated/model/loginRequest.js +9 -0
  131. package/dist/accessi-module/Console/generated/model/loginRequest.js.map +1 -0
  132. package/dist/accessi-module/Console/generated/model/loginResponse.d.ts +14 -0
  133. package/dist/accessi-module/Console/generated/model/loginResponse.js +3 -0
  134. package/dist/accessi-module/Console/generated/model/loginResponse.js.map +1 -0
  135. package/dist/accessi-module/Console/generated/model/loginResult.d.ts +32 -0
  136. package/dist/accessi-module/Console/generated/model/loginResult.js +3 -0
  137. package/dist/accessi-module/Console/generated/model/loginResult.js.map +1 -0
  138. package/dist/accessi-module/Console/generated/model/loginResultExtensionFields.d.ts +12 -0
  139. package/dist/accessi-module/Console/generated/model/loginResultExtensionFields.js +9 -0
  140. package/dist/accessi-module/Console/generated/model/loginResultExtensionFields.js.map +1 -0
  141. package/dist/accessi-module/Console/generated/model/loginResultPasswordRequired.d.ts +13 -0
  142. package/dist/accessi-module/Console/generated/model/loginResultPasswordRequired.js +14 -0
  143. package/dist/accessi-module/Console/generated/model/loginResultPasswordRequired.js.map +1 -0
  144. package/dist/accessi-module/Console/generated/model/menuEntity.d.ts +32 -0
  145. package/dist/accessi-module/Console/generated/model/menuEntity.js +9 -0
  146. package/dist/accessi-module/Console/generated/model/menuEntity.js.map +1 -0
  147. package/dist/accessi-module/Console/generated/model/passwordExpiredResponse.d.ts +12 -0
  148. package/dist/accessi-module/Console/generated/model/passwordExpiredResponse.js +9 -0
  149. package/dist/accessi-module/Console/generated/model/passwordExpiredResponse.js.map +1 -0
  150. package/dist/accessi-module/Console/generated/model/permission.d.ts +12 -0
  151. package/dist/accessi-module/Console/generated/model/permission.js +9 -0
  152. package/dist/accessi-module/Console/generated/model/permission.js.map +1 -0
  153. package/dist/accessi-module/Console/generated/model/publicRegisterRequest.d.ts +51 -0
  154. package/dist/accessi-module/Console/generated/model/publicRegisterRequest.js +9 -0
  155. package/dist/accessi-module/Console/generated/model/publicRegisterRequest.js.map +1 -0
  156. package/dist/accessi-module/Console/generated/model/registerRequest.d.ts +62 -0
  157. package/dist/accessi-module/Console/generated/model/registerRequest.js +3 -0
  158. package/dist/accessi-module/Console/generated/model/registerRequest.js.map +1 -0
  159. package/dist/accessi-module/Console/generated/model/registerResponse.d.ts +14 -0
  160. package/dist/accessi-module/Console/generated/model/registerResponse.js +3 -0
  161. package/dist/accessi-module/Console/generated/model/registerResponse.js.map +1 -0
  162. package/dist/accessi-module/Console/generated/model/resendTwoFactorRequest.d.ts +13 -0
  163. package/dist/accessi-module/Console/generated/model/resendTwoFactorRequest.js +9 -0
  164. package/dist/accessi-module/Console/generated/model/resendTwoFactorRequest.js.map +1 -0
  165. package/dist/accessi-module/Console/generated/model/role.d.ts +15 -0
  166. package/dist/accessi-module/Console/generated/model/role.js +3 -0
  167. package/dist/accessi-module/Console/generated/model/role.js.map +1 -0
  168. package/dist/accessi-module/Console/generated/model/ruoliMenu.d.ts +15 -0
  169. package/dist/accessi-module/Console/generated/model/ruoliMenu.js +3 -0
  170. package/dist/accessi-module/Console/generated/model/ruoliMenu.js.map +1 -0
  171. package/dist/accessi-module/Console/generated/model/ruoliMenuTipoAbilitazione.d.ts +16 -0
  172. package/dist/accessi-module/Console/generated/model/ruoliMenuTipoAbilitazione.js +17 -0
  173. package/dist/accessi-module/Console/generated/model/ruoliMenuTipoAbilitazione.js.map +1 -0
  174. package/dist/accessi-module/Console/generated/model/sendResetPasswordEmailRequest.d.ts +12 -0
  175. package/dist/accessi-module/Console/generated/model/sendResetPasswordEmailRequest.js +9 -0
  176. package/dist/accessi-module/Console/generated/model/sendResetPasswordEmailRequest.js.map +1 -0
  177. package/dist/accessi-module/Console/generated/model/serveResetPasswordPageParams.d.ts +12 -0
  178. package/dist/accessi-module/Console/generated/model/serveResetPasswordPageParams.js +9 -0
  179. package/dist/accessi-module/Console/generated/model/serveResetPasswordPageParams.js.map +1 -0
  180. package/dist/accessi-module/Console/generated/model/setPasswordLoginPolicyRequest.d.ts +10 -0
  181. package/dist/accessi-module/Console/generated/model/setPasswordLoginPolicyRequest.js +9 -0
  182. package/dist/accessi-module/Console/generated/model/setPasswordLoginPolicyRequest.js.map +1 -0
  183. package/dist/accessi-module/Console/generated/model/setStatoRegistrazioneDto.d.ts +13 -0
  184. package/dist/accessi-module/Console/generated/model/setStatoRegistrazioneDto.js +3 -0
  185. package/dist/accessi-module/Console/generated/model/setStatoRegistrazioneDto.js.map +1 -0
  186. package/dist/accessi-module/Console/generated/model/setStatoRegistrazioneDtoStatoRegistrazione.d.ts +18 -0
  187. package/dist/accessi-module/Console/generated/model/setStatoRegistrazioneDtoStatoRegistrazione.js +19 -0
  188. package/dist/accessi-module/Console/generated/model/setStatoRegistrazioneDtoStatoRegistrazione.js.map +1 -0
  189. package/dist/accessi-module/Console/generated/model/status.d.ts +12 -0
  190. package/dist/accessi-module/Console/generated/model/status.js +9 -0
  191. package/dist/accessi-module/Console/generated/model/status.js.map +1 -0
  192. package/dist/accessi-module/Console/generated/model/tipoFiltro.d.ts +23 -0
  193. package/dist/accessi-module/Console/generated/model/tipoFiltro.js +3 -0
  194. package/dist/accessi-module/Console/generated/model/tipoFiltro.js.map +1 -0
  195. package/dist/accessi-module/Console/generated/model/tipoFiltroFlgEnabled.d.ts +14 -0
  196. package/dist/accessi-module/Console/generated/model/tipoFiltroFlgEnabled.js +15 -0
  197. package/dist/accessi-module/Console/generated/model/tipoFiltroFlgEnabled.js.map +1 -0
  198. package/dist/accessi-module/Console/generated/model/tokenResult.d.ts +15 -0
  199. package/dist/accessi-module/Console/generated/model/tokenResult.js +3 -0
  200. package/dist/accessi-module/Console/generated/model/tokenResult.js.map +1 -0
  201. package/dist/accessi-module/Console/generated/model/tokenResultType.d.ts +14 -0
  202. package/dist/accessi-module/Console/generated/model/tokenResultType.js +15 -0
  203. package/dist/accessi-module/Console/generated/model/tokenResultType.js.map +1 -0
  204. package/dist/accessi-module/Console/generated/model/twoFactorChallengeDto.d.ts +18 -0
  205. package/dist/accessi-module/Console/generated/model/twoFactorChallengeDto.js +3 -0
  206. package/dist/accessi-module/Console/generated/model/twoFactorChallengeDto.js.map +1 -0
  207. package/dist/accessi-module/Console/generated/model/twoFactorChallengeDtoMethod.d.ts +10 -0
  208. package/dist/accessi-module/Console/generated/model/twoFactorChallengeDtoMethod.js +14 -0
  209. package/dist/accessi-module/Console/generated/model/twoFactorChallengeDtoMethod.js.map +1 -0
  210. package/dist/accessi-module/Console/generated/model/twoFactorChallengeDtoTwoFactorRequired.d.ts +13 -0
  211. package/dist/accessi-module/Console/generated/model/twoFactorChallengeDtoTwoFactorRequired.js +14 -0
  212. package/dist/accessi-module/Console/generated/model/twoFactorChallengeDtoTwoFactorRequired.js.map +1 -0
  213. package/dist/accessi-module/Console/generated/model/updateEnabledStatusRequest.d.ts +10 -0
  214. package/dist/accessi-module/Console/generated/model/updateEnabledStatusRequest.js +9 -0
  215. package/dist/accessi-module/Console/generated/model/updateEnabledStatusRequest.js.map +1 -0
  216. package/dist/accessi-module/Console/generated/model/updateFederatedIdentityRequest.d.ts +11 -0
  217. package/dist/accessi-module/Console/generated/model/updateFederatedIdentityRequest.js +9 -0
  218. package/dist/accessi-module/Console/generated/model/updateFederatedIdentityRequest.js.map +1 -0
  219. package/dist/accessi-module/Console/generated/model/updateFederatedProviderRequest.d.ts +12 -0
  220. package/dist/accessi-module/Console/generated/model/updateFederatedProviderRequest.js +9 -0
  221. package/dist/accessi-module/Console/generated/model/updateFederatedProviderRequest.js.map +1 -0
  222. package/dist/accessi-module/Console/generated/model/userDto.d.ts +88 -0
  223. package/dist/accessi-module/Console/generated/model/userDto.js +3 -0
  224. package/dist/accessi-module/Console/generated/model/userDto.js.map +1 -0
  225. package/dist/accessi-module/Console/generated/model/userDtoStatoRegistrazione.d.ts +18 -0
  226. package/dist/accessi-module/Console/generated/model/userDtoStatoRegistrazione.js +19 -0
  227. package/dist/accessi-module/Console/generated/model/userDtoStatoRegistrazione.js.map +1 -0
  228. package/dist/accessi-module/Console/generated/model/userGrantsDto.d.ts +16 -0
  229. package/dist/accessi-module/Console/generated/model/userGrantsDto.js +3 -0
  230. package/dist/accessi-module/Console/generated/model/userGrantsDto.js.map +1 -0
  231. package/dist/accessi-module/Console/generated/model/userGrantsResponse.d.ts +14 -0
  232. package/dist/accessi-module/Console/generated/model/userGrantsResponse.js +3 -0
  233. package/dist/accessi-module/Console/generated/model/userGrantsResponse.js.map +1 -0
  234. package/dist/accessi-module/Console/generated/model/verifyTwoFactorRequest.d.ts +18 -0
  235. package/dist/accessi-module/Console/generated/model/verifyTwoFactorRequest.js +9 -0
  236. package/dist/accessi-module/Console/generated/model/verifyTwoFactorRequest.js.map +1 -0
  237. package/dist/accessi-module/Console/index.html +59 -0
  238. package/dist/accessi-module/Controllers/AccessiConsoleController.d.ts +11 -0
  239. package/dist/accessi-module/Controllers/AccessiConsoleController.js +74 -0
  240. package/dist/accessi-module/Controllers/AccessiConsoleController.js.map +1 -0
  241. package/dist/accessi-module/Controllers/AuthController.d.ts +4 -1
  242. package/dist/accessi-module/Controllers/AuthController.js +86 -47
  243. package/dist/accessi-module/Controllers/AuthController.js.map +1 -1
  244. package/dist/accessi-module/Controllers/ConfiguratorController.d.ts +1 -1
  245. package/dist/accessi-module/Controllers/ConfiguratorController.js +3 -1
  246. package/dist/accessi-module/Controllers/ConfiguratorController.js.map +1 -1
  247. package/dist/accessi-module/Controllers/EmailController.d.ts +1 -1
  248. package/dist/accessi-module/Controllers/EmailController.js +3 -1
  249. package/dist/accessi-module/Controllers/EmailController.js.map +1 -1
  250. package/dist/accessi-module/Controllers/FiltriController.d.ts +1 -1
  251. package/dist/accessi-module/Controllers/FiltriController.js +3 -1
  252. package/dist/accessi-module/Controllers/FiltriController.js.map +1 -1
  253. package/dist/accessi-module/Controllers/PermissionController.d.ts +1 -1
  254. package/dist/accessi-module/Controllers/PermissionController.js +9 -5
  255. package/dist/accessi-module/Controllers/PermissionController.js.map +1 -1
  256. package/dist/accessi-module/Controllers/UserController.d.ts +3 -1
  257. package/dist/accessi-module/Controllers/UserController.js +40 -2
  258. package/dist/accessi-module/Controllers/UserController.js.map +1 -1
  259. package/dist/accessi-module/Dtos/AssignRolesToUserRequest.js +1 -1
  260. package/dist/accessi-module/Dtos/AssignRolesToUserRequest.js.map +1 -1
  261. package/dist/accessi-module/Dtos/AuthenticatedUserPayloadDto.d.ts +3 -0
  262. package/dist/accessi-module/Dtos/AuthenticatedUserPayloadDto.js +18 -0
  263. package/dist/accessi-module/Dtos/AuthenticatedUserPayloadDto.js.map +1 -1
  264. package/dist/accessi-module/Dtos/BaseResponse.d.ts +2 -0
  265. package/dist/accessi-module/Dtos/BaseResponse.js +21 -2
  266. package/dist/accessi-module/Dtos/BaseResponse.js.map +1 -1
  267. package/dist/accessi-module/Dtos/FederatedIdentityDtos.d.ts +69 -0
  268. package/dist/accessi-module/Dtos/FederatedIdentityDtos.js +236 -0
  269. package/dist/accessi-module/Dtos/FederatedIdentityDtos.js.map +1 -0
  270. package/dist/accessi-module/Dtos/FiltriUtente.js +4 -1
  271. package/dist/accessi-module/Dtos/FiltriUtente.js.map +1 -1
  272. package/dist/accessi-module/Dtos/LoginRequest.d.ts +1 -1
  273. package/dist/accessi-module/Dtos/LoginRequest.js +3 -2
  274. package/dist/accessi-module/Dtos/LoginRequest.js.map +1 -1
  275. package/dist/accessi-module/Dtos/LoginResponse.d.ts +5 -1
  276. package/dist/accessi-module/Dtos/LoginResponse.js +19 -6
  277. package/dist/accessi-module/Dtos/LoginResponse.js.map +1 -1
  278. package/dist/accessi-module/Dtos/Permission.d.ts +1 -0
  279. package/dist/accessi-module/Dtos/Permission.js +1 -0
  280. package/dist/accessi-module/Dtos/Permission.js.map +1 -1
  281. package/dist/accessi-module/Dtos/PublicRegisterRequest.d.ts +1 -1
  282. package/dist/accessi-module/Dtos/PublicRegisterRequest.js +1 -0
  283. package/dist/accessi-module/Dtos/PublicRegisterRequest.js.map +1 -1
  284. package/dist/accessi-module/Dtos/RegisterRequest.js +1 -0
  285. package/dist/accessi-module/Dtos/RegisterRequest.js.map +1 -1
  286. package/dist/accessi-module/Dtos/Role.d.ts +4 -0
  287. package/dist/accessi-module/Dtos/Role.js +4 -0
  288. package/dist/accessi-module/Dtos/Role.js.map +1 -1
  289. package/dist/accessi-module/Dtos/TipoAbilitazione.d.ts +4 -0
  290. package/dist/accessi-module/Dtos/TipoAbilitazione.js +4 -0
  291. package/dist/accessi-module/Dtos/TipoAbilitazione.js.map +1 -1
  292. package/dist/accessi-module/Dtos/TwoFactorDtos.d.ts +13 -0
  293. package/dist/accessi-module/Dtos/TwoFactorDtos.js +60 -0
  294. package/dist/accessi-module/Dtos/TwoFactorDtos.js.map +1 -0
  295. package/dist/accessi-module/Dtos/UserDto.d.ts +7 -0
  296. package/dist/accessi-module/Dtos/UserDto.js +22 -0
  297. package/dist/accessi-module/Dtos/UserDto.js.map +1 -1
  298. package/dist/accessi-module/Dtos/index.d.ts +2 -0
  299. package/dist/accessi-module/Dtos/index.js +2 -0
  300. package/dist/accessi-module/Dtos/index.js.map +1 -1
  301. package/dist/accessi-module/Services/AuthService/AuthService.d.ts +39 -4
  302. package/dist/accessi-module/Services/AuthService/AuthService.js +184 -32
  303. package/dist/accessi-module/Services/AuthService/AuthService.js.map +1 -1
  304. package/dist/accessi-module/Services/ConfiguratorService/ConfiguratorService.d.ts +3 -1
  305. package/dist/accessi-module/Services/ConfiguratorService/ConfiguratorService.js +5 -1
  306. package/dist/accessi-module/Services/ConfiguratorService/ConfiguratorService.js.map +1 -1
  307. package/dist/accessi-module/Services/EmailService/EmailService.d.ts +7 -1
  308. package/dist/accessi-module/Services/EmailService/EmailService.js +23 -5
  309. package/dist/accessi-module/Services/EmailService/EmailService.js.map +1 -1
  310. package/dist/accessi-module/Services/FiltriService/FiltriService.d.ts +9 -1
  311. package/dist/accessi-module/Services/FiltriService/FiltriService.js +29 -4
  312. package/dist/accessi-module/Services/FiltriService/FiltriService.js.map +1 -1
  313. package/dist/accessi-module/Services/PermissionService/PermissionService.d.ts +29 -1
  314. package/dist/accessi-module/Services/PermissionService/PermissionService.js +38 -7
  315. package/dist/accessi-module/Services/PermissionService/PermissionService.js.map +1 -1
  316. package/dist/accessi-module/Services/TwoFactorService/TwoFactorService.d.ts +27 -0
  317. package/dist/accessi-module/Services/TwoFactorService/TwoFactorService.js +179 -0
  318. package/dist/accessi-module/Services/TwoFactorService/TwoFactorService.js.map +1 -0
  319. package/dist/accessi-module/Services/UserService/UserService.d.ts +26 -2
  320. package/dist/accessi-module/Services/UserService/UserService.js +124 -30
  321. package/dist/accessi-module/Services/UserService/UserService.js.map +1 -1
  322. package/dist/accessi-module/database-updates/AccessiDatabaseUpdater.d.ts +38 -10
  323. package/dist/accessi-module/database-updates/AccessiDatabaseUpdater.js +368 -184
  324. package/dist/accessi-module/database-updates/AccessiDatabaseUpdater.js.map +1 -1
  325. package/dist/accessi-module/database-updates/accessiSchema.d.ts +45 -0
  326. package/dist/accessi-module/database-updates/accessiSchema.js +79 -0
  327. package/dist/accessi-module/database-updates/accessiSchema.js.map +1 -0
  328. package/dist/accessi-module/database-updates/optionalColumns.d.ts +5 -0
  329. package/dist/accessi-module/database-updates/optionalColumns.js +26 -0
  330. package/dist/accessi-module/database-updates/optionalColumns.js.map +1 -0
  331. package/dist/accessi-module/database-updates/runAccessiDbUpdate.js +11 -6
  332. package/dist/accessi-module/database-updates/runAccessiDbUpdate.js.map +1 -1
  333. package/dist/accessi-module/federated-auth/FederatedAuthController.d.ts +23 -0
  334. package/dist/accessi-module/federated-auth/FederatedAuthController.js +307 -0
  335. package/dist/accessi-module/federated-auth/FederatedAuthController.js.map +1 -0
  336. package/dist/accessi-module/federated-auth/FederatedAuthService.d.ts +94 -0
  337. package/dist/accessi-module/federated-auth/FederatedAuthService.js +424 -0
  338. package/dist/accessi-module/federated-auth/FederatedAuthService.js.map +1 -0
  339. package/dist/accessi-module/federated-auth/FederatedAuthTypes.d.ts +53 -0
  340. package/dist/accessi-module/federated-auth/FederatedAuthTypes.js +3 -0
  341. package/dist/accessi-module/federated-auth/FederatedAuthTypes.js.map +1 -0
  342. package/dist/accessi-module/index.d.ts +14 -0
  343. package/dist/accessi-module/index.js +18 -10
  344. package/dist/accessi-module/index.js.map +1 -1
  345. package/dist/accessi-module/jwt/jwt.strategy.d.ts +1 -1
  346. package/dist/accessi-module/jwt/jwt.strategy.js +10 -4
  347. package/dist/accessi-module/jwt/jwt.strategy.js.map +1 -1
  348. package/dist/accessi-module/middleware/accessiRequirements.d.ts +22 -0
  349. package/dist/accessi-module/middleware/accessiRequirements.js +7 -0
  350. package/dist/accessi-module/middleware/accessiRequirements.js.map +1 -1
  351. package/dist/accessi-module/middleware/authenticateGen.d.ts +16 -1
  352. package/dist/accessi-module/middleware/authenticateGen.js +54 -20
  353. package/dist/accessi-module/middleware/authenticateGen.js.map +1 -1
  354. package/dist/accessi-module/security/AccessiHttpExceptionFilter.d.ts +12 -0
  355. package/dist/accessi-module/security/AccessiHttpExceptionFilter.js +74 -0
  356. package/dist/accessi-module/security/AccessiHttpExceptionFilter.js.map +1 -0
  357. package/dist/accessi-module/security/accessControl.d.ts +11 -0
  358. package/dist/accessi-module/security/accessControl.js +11 -1
  359. package/dist/accessi-module/security/accessControl.js.map +1 -1
  360. package/dist/accessi-module/security/accessiValidation.d.ts +9 -0
  361. package/dist/accessi-module/security/accessiValidation.js +41 -0
  362. package/dist/accessi-module/security/accessiValidation.js.map +1 -0
  363. package/dist/accessi-module/security/authenticatedToken.d.ts +14 -0
  364. package/dist/accessi-module/security/authenticatedToken.js +30 -4
  365. package/dist/accessi-module/security/authenticatedToken.js.map +1 -1
  366. package/dist/accessi-module/security/passwordResetToken.d.ts +5 -1
  367. package/dist/accessi-module/security/passwordResetToken.js +5 -1
  368. package/dist/accessi-module/security/passwordResetToken.js.map +1 -1
  369. package/dist/accessi-module/security/publicAuthRateLimit.d.ts +2 -2
  370. package/dist/accessi-module/security/publicAuthRateLimit.js +2 -0
  371. package/dist/accessi-module/security/publicAuthRateLimit.js.map +1 -1
  372. package/dist/emilsoftware-utilities-2.0.0-dev.23.tgz +0 -0
  373. package/dist/initEmilsoftwareModule.js +7 -0
  374. package/dist/initEmilsoftwareModule.js.map +1 -1
  375. package/dist/scripts/generateAccessiOpenApi.d.ts +1 -0
  376. package/dist/scripts/generateAccessiOpenApi.js +57 -0
  377. package/dist/scripts/generateAccessiOpenApi.js.map +1 -0
  378. package/package.json +13 -4
  379. package/dist/emilsoftware-utilities-2.0.0-dev.21.tgz +0 -0
@@ -55,24 +55,26 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
55
55
  };
56
56
  var AuthService_1;
57
57
  Object.defineProperty(exports, "__esModule", { value: true });
58
- exports.AuthService = void 0;
58
+ exports.AuthService = exports.PASSWORD_LOGIN_DISABLED = void 0;
59
59
  const common_1 = require("@nestjs/common");
60
+ const TwoFactorService_1 = require("../TwoFactorService/TwoFactorService");
60
61
  const jwt = __importStar(require("jsonwebtoken"));
61
62
  const Orm_1 = require("../../../Orm");
62
63
  const Utilities_1 = require("../../../Utilities");
63
64
  const StatoRegistrazione_1 = require("../../Dtos/StatoRegistrazione");
64
65
  const UserService_1 = require("../UserService/UserService");
65
- const PermissionService_1 = require("../PermissionService/PermissionService");
66
66
  const FiltriService_1 = require("../FiltriService/FiltriService");
67
67
  const authenticatedToken_1 = require("../../security/authenticatedToken");
68
68
  const passwordResetToken_1 = require("../../security/passwordResetToken");
69
69
  const Logger_1 = require("../../../Logger");
70
+ /** Error code deliberately returned when a user is configured as SSO-only. */
71
+ exports.PASSWORD_LOGIN_DISABLED = 'PASSWORD_LOGIN_DISABLED';
70
72
  let AuthService = AuthService_1 = class AuthService {
71
- constructor(userService, permissionService, filtriService, accessiOptions) {
73
+ constructor(userService, filtriService, accessiOptions, twoFactorService) {
72
74
  this.userService = userService;
73
- this.permissionService = permissionService;
74
75
  this.filtriService = filtriService;
75
76
  this.accessiOptions = accessiOptions;
77
+ this.twoFactorService = twoFactorService;
76
78
  this.logger = new Logger_1.Logger(AuthService_1.name);
77
79
  }
78
80
  refreshPasswordExpiration(codiceUtente) {
@@ -96,6 +98,58 @@ let AuthService = AuthService_1 = class AuthService {
96
98
  const nodeEnv = ((_a = process.env.NODE_ENV) !== null && _a !== void 0 ? _a : "production").toLowerCase();
97
99
  return nodeEnv !== "production" || process.env.ACCESSI_ALLOW_MOCK_DEMO_USER === "true";
98
100
  }
101
+ /** Creates the normal internal JWT consumed by all existing Accessi guards. */
102
+ createAccessiToken(utente, methods = []) {
103
+ if (!(utente === null || utente === void 0 ? void 0 : utente.codiceUtente)) {
104
+ throw new Error('Impossibile creare un token senza un utente Accessi valido.');
105
+ }
106
+ if ((utente.flagDueFattori === true || Number(utente.flagDueFattori) === 1) && !methods.includes('otp')) {
107
+ throw new common_1.UnauthorizedException('Verifica del codice di accesso richiesta.');
108
+ }
109
+ return {
110
+ expiresIn: this.accessiOptions.jwtOptions.expiresIn,
111
+ value: jwt.sign({ utente, typ: 'access', amr: methods }, (0, passwordResetToken_1.getAccessiJwtSecret)(this.accessiOptions), {
112
+ expiresIn: this.accessiOptions.jwtOptions.expiresIn,
113
+ }),
114
+ type: 'Bearer',
115
+ };
116
+ }
117
+ /** Builds the standard login response for a user authenticated by any supported method. */
118
+ getLoginResultForUser(codiceUtente) {
119
+ return __awaiter(this, void 0, void 0, function* () {
120
+ const users = yield this.userService.getUsers({ codiceUtente }, { includeExtensionFields: true, includeGrants: true });
121
+ const result = users[0];
122
+ if (!(result === null || result === void 0 ? void 0 : result.utente)) {
123
+ throw new Error('Utente Accessi non trovato.');
124
+ }
125
+ const current = yield this.userService.getAuthenticatedUserSnapshot(codiceUtente);
126
+ if (!(0, authenticatedToken_1.isAuthenticatedUserEnabledForJwt)(current))
127
+ throw new common_1.UnauthorizedException('Utente non abilitato.');
128
+ result.utente = Object.assign(Object.assign({}, result.utente), current);
129
+ return {
130
+ utente: result.utente,
131
+ filtri: yield this.filtriService.getFiltriUser(codiceUtente),
132
+ userGrants: result.userGrants,
133
+ extensionFields: result.extensionFields,
134
+ };
135
+ });
136
+ }
137
+ /** Users without a row retain the historic password-login enabled default. */
138
+ isPasswordLoginEnabled(codiceUtente) {
139
+ return __awaiter(this, void 0, void 0, function* () {
140
+ var _a;
141
+ if (((_a = this.accessiOptions.federatedAuthentication) === null || _a === void 0 ? void 0 : _a.enabled) !== true)
142
+ return true;
143
+ const rows = yield Orm_1.Orm.query(this.accessiOptions.databaseOptions, 'SELECT COALESCE(FLGPASSWORD, 1) AS password_login_enabled FROM UTENTI_CONFIG WHERE CODUTE = ?', [codiceUtente]);
144
+ const policy = rows.map(Utilities_1.RestUtilities.convertKeysToCamelCase)[0];
145
+ return (policy === null || policy === void 0 ? void 0 : policy.passwordLoginEnabled) !== false && (policy === null || policy === void 0 ? void 0 : policy.passwordLoginEnabled) !== 0 && (policy === null || policy === void 0 ? void 0 : policy.passwordLoginEnabled) !== '0';
146
+ });
147
+ }
148
+ /**
149
+ * Autentica con credenziali locali e restituisce profilo, filtri e grant effettivi.
150
+ * Non crea il JWT: il controller o il flusso SSO deve chiamare `createAccessiToken` sul risultato.
151
+ * Per utenti SSO-only genera `PASSWORD_LOGIN_DISABLED`, da trattare come istruzione a usare l'SSO.
152
+ */
99
153
  login(request) {
100
154
  return __awaiter(this, void 0, void 0, function* () {
101
155
  const mockDemoUserEnabled = this.isMockDemoUserEnabled();
@@ -107,9 +161,19 @@ let AuthService = AuthService_1 = class AuthService {
107
161
  request.email.toLowerCase() === "admin") {
108
162
  return this.getAdminUser();
109
163
  }
110
- const utente = yield this.userService.getUserByEmail(request.email.toLowerCase());
111
- if (!utente)
164
+ const utente = yield this.userService.getUserByEmail(request.email.trim().toLowerCase());
165
+ if (!utente) {
166
+ if (!request.password)
167
+ return { passwordRequired: true };
112
168
  throw new Error("Nome utente o password errata!");
169
+ }
170
+ const currentUser = yield this.userService.getAuthenticatedUserSnapshot(utente.codiceUtente);
171
+ if ((0, authenticatedToken_1.isAuthenticatedUserEnabledForJwt)(currentUser) && currentUser.flagDueFattori && currentUser.passwordlessLoginEnabled) {
172
+ return { challenge: yield this.twoFactorService.issue({ codiceUtente: utente.codiceUtente, email: currentUser.email.trim(), mode: 'passwordless' }) };
173
+ }
174
+ // The email-only step has the same response for unknown and ordinary local accounts.
175
+ if (!request.password)
176
+ return { passwordRequired: true };
113
177
  switch (utente.statoRegistrazione) {
114
178
  case undefined:
115
179
  throw new Error("Struttura dati compromessa: Stato Registrazione inesistente.");
@@ -122,32 +186,40 @@ let AuthService = AuthService_1 = class AuthService {
122
186
  if (utente.statoRegistrazione !== StatoRegistrazione_1.StatoRegistrazione.CONF) {
123
187
  throw new Error(`Errore generico. Stato di registrazione non valido: ${utente.statoRegistrazione}.`);
124
188
  }
189
+ if (!(0, authenticatedToken_1.isAuthenticatedUserEnabledForJwt)(currentUser))
190
+ throw new Error('Utente non abilitato');
191
+ if (!(yield this.isPasswordLoginEnabled(utente.codiceUtente))) {
192
+ throw new Error(exports.PASSWORD_LOGIN_DISABLED);
193
+ }
194
+ if (typeof request.password !== 'string' || request.password.length === 0) {
195
+ throw new Error('Nome utente o password errata!');
196
+ }
125
197
  const isPasswordValid = yield this.verifyPassword(utente.codiceUtente, request.password);
126
198
  if (!isPasswordValid)
127
199
  throw new Error("Nome utente o password errata!");
128
200
  if (this.accessiOptions.passwordExpiration &&
129
201
  this.accessiOptions.passwordExpiration == true) {
130
202
  const today = new Date();
131
- const targetDate = new Date(utente.dataScadenzaPassword);
132
- if (today >= targetDate) {
203
+ const targetDate = utente.dataScadenzaPassword
204
+ ? new Date(utente.dataScadenzaPassword)
205
+ : undefined;
206
+ // Legacy users may not have an expiration date. Preserve the former non-expiring behaviour for them.
207
+ if (targetDate && !Number.isNaN(targetDate.getTime()) && today >= targetDate) {
133
208
  throw new Error("PASSWORD_EXPIRED");
134
209
  }
135
210
  }
136
- const userGrants = yield this.permissionService.getUserRolesAndGrants(utente.codiceUtente);
137
- const filtri = yield this.filtriService.getFiltriUser(utente.codiceUtente);
211
+ if (currentUser.flagDueFattori) {
212
+ return { challenge: yield this.twoFactorService.issue({ codiceUtente: utente.codiceUtente, email: currentUser.email, mode: 'password' }) };
213
+ }
138
214
  const updateLastAccessDateQuery = "UPDATE UTENTI SET DATLASTLOGIN = CURRENT_TIMESTAMP WHERE CODUTE = ?";
139
215
  yield Orm_1.Orm.query(this.accessiOptions.databaseOptions, updateLastAccessDateQuery, [utente.codiceUtente]);
140
- const extensionFields = {};
141
- if (this.accessiOptions.extensionFieldsOptions &&
142
- this.accessiOptions.extensionFieldsOptions.length > 0) {
143
- for (const ext of this.accessiOptions.extensionFieldsOptions) {
144
- const values = (yield Orm_1.Orm.query(ext.databaseOptions, `SELECT ${ext.tableFields.join(",")} FROM ${ext.tableName} WHERE ${ext.tableJoinFieldName} = ?`, [utente.codiceUtente])).map(Utilities_1.RestUtilities.convertKeysToCamelCase);
145
- extensionFields[ext.objectKey] = values;
146
- }
147
- }
148
- return { utente, filtri, userGrants, extensionFields };
216
+ return this.getLoginResultForUser(utente.codiceUtente);
149
217
  });
150
218
  }
219
+ /**
220
+ * Verifica un JWT Accessi e ricostruisce il profilo corrente dal database.
221
+ * Questo evita che privilegi, stato utente o flag amministrativi presenti in un token vecchio restino validi.
222
+ */
151
223
  getAuthenticatedTokenPayload(token) {
152
224
  return __awaiter(this, void 0, void 0, function* () {
153
225
  if (typeof token !== "string" || token.trim() === "") {
@@ -160,12 +232,61 @@ let AuthService = AuthService_1 = class AuthService {
160
232
  throw new Error("Token non valido.");
161
233
  }
162
234
  const currentUser = yield this.userService.getAuthenticatedUserSnapshot(codiceUtente);
163
- if (!(0, authenticatedToken_1.isAuthenticatedUserEnabledForJwt)(currentUser)) {
235
+ if (!currentUser || !(0, authenticatedToken_1.isAuthenticatedUserEnabledForJwt)(currentUser) || !(0, authenticatedToken_1.isAccessiTokenAllowedForUser)(decoded, currentUser)) {
164
236
  throw new Error("Token non valido o utente non autorizzato.");
165
237
  }
166
238
  return (0, authenticatedToken_1.buildAuthenticatedTokenPayload)(decoded, currentUser);
167
239
  });
168
240
  }
241
+ /** Starts a second-factor challenge after the hosting backend has verified an SSO identity. */
242
+ beginFederatedTwoFactor(codiceUtente, identityKey) {
243
+ return __awaiter(this, void 0, void 0, function* () {
244
+ const user = yield this.userService.getAuthenticatedUserSnapshot(codiceUtente);
245
+ if (!(0, authenticatedToken_1.isAuthenticatedUserEnabledForJwt)(user) || !user.flagDueFattori)
246
+ throw new common_1.UnauthorizedException();
247
+ return { challenge: yield this.twoFactorService.issue({ codiceUtente, email: user.email, mode: 'federated', identityKey }) };
248
+ });
249
+ }
250
+ validateTwoFactorProof(proof) {
251
+ return __awaiter(this, void 0, void 0, function* () {
252
+ var _a, _b;
253
+ const user = yield this.userService.getAuthenticatedUserSnapshot(proof.codiceUtente);
254
+ if (!(0, authenticatedToken_1.isAuthenticatedUserEnabledForJwt)(user) || !user.flagDueFattori || ((_a = user.email) === null || _a === void 0 ? void 0 : _a.trim().toLowerCase()) !== proof.email.trim().toLowerCase()) {
255
+ throw new common_1.UnauthorizedException('Profilo modificato o utente non abilitato. Ripeti l accesso.');
256
+ }
257
+ if (proof.mode === 'passwordless' && !user.passwordlessLoginEnabled)
258
+ throw new common_1.UnauthorizedException('Accesso senza password disabilitato.');
259
+ if (proof.mode === 'password' && !(yield this.isPasswordLoginEnabled(proof.codiceUtente)))
260
+ throw new common_1.UnauthorizedException('Login locale disabilitato.');
261
+ if (proof.mode === 'federated') {
262
+ if (!((_b = this.accessiOptions.federatedAuthentication) === null || _b === void 0 ? void 0 : _b.enabled))
263
+ throw new common_1.UnauthorizedException();
264
+ const rows = yield Orm_1.Orm.query(this.accessiOptions.databaseOptions, 'SELECT I.IDNKEY FROM UTENTI_IDENTITA_EXT I INNER JOIN SSO_PROVIDER P ON P.PROVIDER = I.PROVIDER WHERE I.IDNKEY = ? AND I.CODUTE = ? AND I.FLGATTIVO = 1 AND P.FLGATTIVO = 1', [proof.identityKey, proof.codiceUtente], false);
265
+ if (!rows.length)
266
+ throw new common_1.UnauthorizedException('Identita SSO non piu abilitata.');
267
+ }
268
+ });
269
+ }
270
+ verifyTwoFactor(challengeId, code) {
271
+ return __awaiter(this, void 0, void 0, function* () {
272
+ const proof = yield this.twoFactorService.consume(challengeId, code);
273
+ yield this.validateTwoFactorProof(proof);
274
+ const result = yield this.getLoginResultForUser(proof.codiceUtente);
275
+ result.token = this.createAccessiToken(result.utente, [proof.mode, 'otp']);
276
+ yield Orm_1.Orm.execute(this.accessiOptions.databaseOptions, 'UPDATE UTENTI SET DATLASTLOGIN = CURRENT_TIMESTAMP WHERE CODUTE = ?', [proof.codiceUtente]);
277
+ if (proof.mode === 'federated') {
278
+ yield Orm_1.Orm.execute(this.accessiOptions.databaseOptions, 'UPDATE UTENTI_IDENTITA_EXT SET DATLASTLOGIN = CURRENT_TIMESTAMP WHERE IDNKEY = ?', [proof.identityKey]);
279
+ }
280
+ return result;
281
+ });
282
+ }
283
+ resendTwoFactor(challengeId) {
284
+ return __awaiter(this, void 0, void 0, function* () {
285
+ yield this.validateTwoFactorProof(yield this.twoFactorService.describe(challengeId));
286
+ return { challenge: yield this.twoFactorService.resend(challengeId) };
287
+ });
288
+ }
289
+ /** Persiste una password hashata e aggiorna la scadenza, se la policy password e attiva. Non invia email. */
169
290
  setPassword(codiceUtente, nuovaPassword) {
170
291
  return __awaiter(this, void 0, void 0, function* () {
171
292
  try {
@@ -183,6 +304,10 @@ let AuthService = AuthService_1 = class AuthService {
183
304
  }
184
305
  });
185
306
  }
307
+ /**
308
+ * Converte le password legacy cifrate nel formato hash compatibile, senza conoscere le password in chiaro.
309
+ * E idempotente: hash moderni e gia migrati vengono ignorati.
310
+ */
186
311
  migrateLegacyEncryptedPasswords() {
187
312
  return __awaiter(this, void 0, void 0, function* () {
188
313
  const startedAt = performance.now();
@@ -208,6 +333,7 @@ let AuthService = AuthService_1 = class AuthService {
208
333
  this.logger.info(`Migrazione password legacy accessi completata. Letti=${rows.length}, migrati=${migratedCount}, ignorati=${skippedCount}, durataMs=${(performance.now() - startedAt).toFixed(2)}`);
209
334
  });
210
335
  }
336
+ /** Verifica una password locale e migra automaticamente il formato legacy dopo una verifica positiva. */
211
337
  verifyPassword(codiceUtente, plainPassword) {
212
338
  return __awaiter(this, void 0, void 0, function* () {
213
339
  const query = `SELECT PWD AS password FROM UTENTI_PWD WHERE CODUTE = ?`;
@@ -234,6 +360,7 @@ let AuthService = AuthService_1 = class AuthService {
234
360
  return isLegacyPasswordValid;
235
361
  });
236
362
  }
363
+ /** Restituisce l'utente fittizio amministratore; usabile solo con `mockDemoUser` esplicitamente abilitato. */
237
364
  getAdminUser() {
238
365
  return __awaiter(this, void 0, void 0, function* () {
239
366
  return {
@@ -262,6 +389,7 @@ let AuthService = AuthService_1 = class AuthService {
262
389
  };
263
390
  });
264
391
  }
392
+ /** Restituisce l'utente demo fittizio; non contiene dati o grant reali. */
265
393
  getDemoUser() {
266
394
  return {
267
395
  utente: {
@@ -288,8 +416,13 @@ let AuthService = AuthService_1 = class AuthService {
288
416
  },
289
417
  };
290
418
  }
419
+ /**
420
+ * Consuma un token monouso di reset, riporta l'utente allo stato confermato e salva la nuova password.
421
+ * Il nonce in `UTENTI.KEYREG` viene annullato prima di impostare la password, impedendo il riuso del token.
422
+ */
291
423
  confirmResetPassword(token, newPassword) {
292
424
  return __awaiter(this, void 0, void 0, function* () {
425
+ var _a;
293
426
  try {
294
427
  if (typeof token !== "string" || token.trim() === "") {
295
428
  throw new Error("Token non valido.");
@@ -301,17 +434,37 @@ let AuthService = AuthService_1 = class AuthService {
301
434
  }
302
435
  const secret = (0, passwordResetToken_1.getAccessiJwtSecret)(this.accessiOptions);
303
436
  const { codiceUtente, nonce } = (0, passwordResetToken_1.verifyPasswordResetToken)(token.trim(), secret);
304
- const result = (yield Orm_1.Orm.query(this.accessiOptions.databaseOptions, "SELECT CODUTE AS codice_utente, STAREG AS stato_registrazione FROM UTENTI WHERE CODUTE = ? AND KEYREG = ?", [codiceUtente, nonce]).then((rows) => rows.map(Utilities_1.RestUtilities.convertKeysToCamelCase)));
305
- if (result.length === 0) {
306
- throw new Error("Token non valido o gia usato.");
437
+ const hashedPassword = Utilities_1.PasswordUtilities.hashPassword(newPassword);
438
+ const db = yield Orm_1.Orm.connect(this.accessiOptions.databaseOptions);
439
+ let transaction;
440
+ try {
441
+ transaction = yield Orm_1.Orm.startTransaction(db);
442
+ const query = (sql, params) => new Promise((resolve, reject) => {
443
+ transaction.query(sql, params, (error, result) => error ? reject(error) : resolve(result));
444
+ });
445
+ // A conditional write claims the nonce under the database row lock. A second
446
+ // concurrent reset cannot also consume it; failures roll the whole reset back.
447
+ const claimed = yield query('UPDATE UTENTI SET KEYREG = NULL, STAREG = ? WHERE CODUTE = ? AND KEYREG = ? AND STAREG IN (?, ?) RETURNING CODUTE', [StatoRegistrazione_1.StatoRegistrazione.CONF, codiceUtente, nonce, StatoRegistrazione_1.StatoRegistrazione.CONF, StatoRegistrazione_1.StatoRegistrazione.INVIO]);
448
+ const row = Array.isArray(claimed) ? claimed[0] : claimed;
449
+ if (Number((_a = row === null || row === void 0 ? void 0 : row.CODUTE) !== null && _a !== void 0 ? _a : row === null || row === void 0 ? void 0 : row.codute) !== codiceUtente) {
450
+ throw new Error('Token non valido, gia usato o utente non autorizzato.');
451
+ }
452
+ yield query('UPDATE OR INSERT INTO UTENTI_PWD (CODUTE, PWD) VALUES (?, ?) MATCHING (CODUTE)', [codiceUtente, hashedPassword]);
453
+ if (this.accessiOptions.passwordExpiration) {
454
+ const days = Number(this.accessiOptions.passwordExpirationDays);
455
+ const expirationDays = Number.isFinite(days) && days > 0 ? Math.trunc(days) : 90;
456
+ yield query(`UPDATE UTENTI SET DATSCAPWD = DATEADD(${expirationDays} DAY TO CURRENT_TIMESTAMP) WHERE CODUTE = ?`, [codiceUtente]);
457
+ }
458
+ yield Orm_1.Orm.commitTransaction(transaction);
459
+ }
460
+ catch (error) {
461
+ if (transaction)
462
+ yield Orm_1.Orm.rollbackTransaction(transaction).catch(() => undefined);
463
+ throw error;
307
464
  }
308
- const currentState = Number(result[0].statoRegistrazione);
309
- if (currentState === StatoRegistrazione_1.StatoRegistrazione.BLOCC ||
310
- currentState === StatoRegistrazione_1.StatoRegistrazione.DELETE) {
311
- throw new Error("Utente non autorizzato a completare il reset password.");
465
+ finally {
466
+ yield new Promise((resolve) => db.detach(() => resolve()));
312
467
  }
313
- yield Orm_1.Orm.query(this.accessiOptions.databaseOptions, "UPDATE UTENTI SET KEYREG = NULL, STAREG = ? WHERE CODUTE = ?", [StatoRegistrazione_1.StatoRegistrazione.CONF, codiceUtente]);
314
- yield this.setPassword(codiceUtente, newPassword);
315
468
  }
316
469
  catch (error) {
317
470
  throw error;
@@ -322,9 +475,8 @@ let AuthService = AuthService_1 = class AuthService {
322
475
  exports.AuthService = AuthService;
323
476
  exports.AuthService = AuthService = AuthService_1 = __decorate([
324
477
  (0, common_1.Injectable)(),
325
- __param(3, (0, common_1.Inject)("ACCESSI_OPTIONS")),
478
+ __param(2, (0, common_1.Inject)("ACCESSI_OPTIONS")),
326
479
  __metadata("design:paramtypes", [UserService_1.UserService,
327
- PermissionService_1.PermissionService,
328
- FiltriService_1.FiltriService, Object])
480
+ FiltriService_1.FiltriService, Object, TwoFactorService_1.TwoFactorService])
329
481
  ], AuthService);
330
482
  //# sourceMappingURL=AuthService.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AuthService.js","sourceRoot":"","sources":["../../../../src/accessi-module/Services/AuthService/AuthService.ts"],"names":[],"mappings":"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","sourcesContent":["import { Inject, Injectable } from \"@nestjs/common\";\nimport * as jwt from \"jsonwebtoken\";\nimport { Orm } from \"../../../Orm\";\nimport { CryptUtilities, PasswordUtilities, RestUtilities } from \"../../../Utilities\";\nimport { AccessiOptions } from \"../../AccessiModule\";\nimport { LoginRequest } from \"../../Dtos/LoginRequest\";\nimport { LoginResult } from \"../../Dtos/LoginResponse\";\nimport { StatoRegistrazione } from \"../../Dtos/StatoRegistrazione\";\nimport { UserService } from \"../UserService/UserService\";\nimport { PermissionService } from \"../PermissionService/PermissionService\";\nimport { FiltriService } from \"../FiltriService/FiltriService\";\nimport {\n buildAuthenticatedTokenPayload,\n isAuthenticatedUserEnabledForJwt,\n resolveCodiceUtenteFromTokenPayload,\n} from \"../../security/authenticatedToken\";\nimport {\n getAccessiJwtSecret,\n verifyPasswordResetToken,\n} from \"../../security/passwordResetToken\";\nimport { Logger } from \"../../../Logger\";\n\n@Injectable()\nexport class AuthService {\n private readonly logger = new Logger(AuthService.name);\n\n constructor(\n private userService: UserService,\n private permissionService: PermissionService,\n private filtriService: FiltriService,\n @Inject(\"ACCESSI_OPTIONS\") private readonly accessiOptions: AccessiOptions\n ) {}\n\n private async refreshPasswordExpiration(codiceUtente: number): Promise<void> {\n if (!this.accessiOptions.passwordExpiration) {\n return;\n }\n\n const configuredDays = Number(this.accessiOptions.passwordExpirationDays);\n const expirationDays =\n Number.isFinite(configuredDays) && configuredDays > 0\n ? Math.trunc(configuredDays)\n : 90;\n\n const query = `UPDATE UTENTI SET DATSCAPWD = DATEADD(${expirationDays} DAY TO CURRENT_TIMESTAMP) WHERE CODUTE = ?`;\n await Orm.execute(this.accessiOptions.databaseOptions, query, [codiceUtente]);\n }\n\n private isMockDemoUserEnabled(): boolean {\n if (!this.accessiOptions.mockDemoUser) {\n return false;\n }\n\n const nodeEnv = (process.env.NODE_ENV ?? \"production\").toLowerCase();\n return nodeEnv !== \"production\" || process.env.ACCESSI_ALLOW_MOCK_DEMO_USER === \"true\";\n }\n\n async login(request: LoginRequest): Promise<LoginResult> {\n const mockDemoUserEnabled = this.isMockDemoUserEnabled();\n\n if (\n mockDemoUserEnabled &&\n request.email.toLowerCase() === \"demo\"\n ) {\n return this.getDemoUser();\n }\n\n if (\n mockDemoUserEnabled &&\n request.email.toLowerCase() === \"admin\"\n ) {\n return this.getAdminUser();\n }\n\n const utente = await this.userService.getUserByEmail(\n request.email.toLowerCase()\n );\n if (!utente) throw new Error(\"Nome utente o password errata!\");\n\n switch (utente.statoRegistrazione) {\n case undefined:\n throw new Error(\n \"Struttura dati compromessa: Stato Registrazione inesistente.\"\n );\n case StatoRegistrazione.BLOCC:\n case StatoRegistrazione.DELETE:\n throw new Error(\"Utente non abilitato\");\n case StatoRegistrazione.INVIO:\n throw new Error(\"Rinnovo password necessario.\");\n }\n\n if (utente.statoRegistrazione !== StatoRegistrazione.CONF) {\n throw new Error(\n `Errore generico. Stato di registrazione non valido: ${utente.statoRegistrazione}.`\n );\n }\n\n const isPasswordValid = await this.verifyPassword(\n utente.codiceUtente,\n request.password\n );\n if (!isPasswordValid) throw new Error(\"Nome utente o password errata!\");\n\n if (\n this.accessiOptions.passwordExpiration &&\n this.accessiOptions.passwordExpiration == true\n ) {\n const today = new Date();\n const targetDate = new Date(utente.dataScadenzaPassword);\n\n if (today >= targetDate) {\n throw new Error(\"PASSWORD_EXPIRED\");\n }\n }\n\n const userGrants = await this.permissionService.getUserRolesAndGrants(\n utente.codiceUtente\n );\n\n const filtri = await this.filtriService.getFiltriUser(utente.codiceUtente);\n\n const updateLastAccessDateQuery =\n \"UPDATE UTENTI SET DATLASTLOGIN = CURRENT_TIMESTAMP WHERE CODUTE = ?\";\n await Orm.query(\n this.accessiOptions.databaseOptions,\n updateLastAccessDateQuery,\n [utente.codiceUtente]\n );\n\n const extensionFields = {};\n\n if (\n this.accessiOptions.extensionFieldsOptions &&\n this.accessiOptions.extensionFieldsOptions.length > 0\n ) {\n for (const ext of this.accessiOptions.extensionFieldsOptions) {\n const values = (\n await Orm.query(\n ext.databaseOptions,\n `SELECT ${ext.tableFields.join(\",\")} FROM ${ext.tableName} WHERE ${\n ext.tableJoinFieldName\n } = ?`,\n [utente.codiceUtente]\n )\n ).map(RestUtilities.convertKeysToCamelCase);\n\n extensionFields[ext.objectKey] = values;\n }\n }\n\n return { utente, filtri, userGrants, extensionFields };\n }\n\n public async getAuthenticatedTokenPayload(token: string): Promise<Record<string, unknown>> {\n if (typeof token !== \"string\" || token.trim() === \"\") {\n throw new Error(\"Token non fornito.\");\n }\n\n const secret = getAccessiJwtSecret(this.accessiOptions);\n const decoded = jwt.verify(token.trim(), secret);\n const codiceUtente = resolveCodiceUtenteFromTokenPayload(decoded);\n\n if (!codiceUtente) {\n throw new Error(\"Token non valido.\");\n }\n\n const currentUser = await this.userService.getAuthenticatedUserSnapshot(codiceUtente);\n if (!isAuthenticatedUserEnabledForJwt(currentUser)) {\n throw new Error(\"Token non valido o utente non autorizzato.\");\n }\n\n return buildAuthenticatedTokenPayload(decoded, currentUser);\n }\n\n public async setPassword(codiceUtente: number, nuovaPassword: string) {\n try {\n const query = `UPDATE OR INSERT INTO UTENTI_PWD (CODUTE, PWD) VALUES (?, ?)`;\n const hashedPassword = PasswordUtilities.hashPassword(nuovaPassword);\n\n const result = await Orm.execute(this.accessiOptions.databaseOptions, query, [\n codiceUtente,\n hashedPassword,\n ]);\n await this.refreshPasswordExpiration(codiceUtente);\n return result;\n } catch (error) {\n throw error;\n }\n }\n\n public async migrateLegacyEncryptedPasswords(): Promise<void> {\n const startedAt = performance.now();\n this.logger.info(\"Avvio migrazione password legacy accessi.\");\n const results = await Orm.query(\n this.accessiOptions.databaseOptions,\n \"SELECT CODUTE AS codice_utente, PWD AS password FROM UTENTI_PWD WHERE PWD IS NOT NULL\",\n []\n );\n\n const rows = results.map(RestUtilities.convertKeysToCamelCase) as {\n codiceUtente?: number;\n password?: string;\n }[];\n let migratedCount = 0;\n let skippedCount = 0;\n\n for (const row of rows) {\n const codiceUtente = Number(row.codiceUtente);\n const storedPassword = typeof row.password === \"string\" ? row.password : null;\n\n if (\n !codiceUtente ||\n !storedPassword ||\n PasswordUtilities.isPasswordHash(storedPassword) ||\n PasswordUtilities.isLegacyPasswordHash(storedPassword)\n ) {\n skippedCount += 1;\n continue;\n }\n\n const protectedLegacyPassword =\n PasswordUtilities.hashLegacyEncryptedPassword(storedPassword);\n\n await Orm.execute(\n this.accessiOptions.databaseOptions,\n \"UPDATE UTENTI_PWD SET PWD = ? WHERE CODUTE = ? AND PWD = ?\",\n [protectedLegacyPassword, codiceUtente, storedPassword]\n );\n migratedCount += 1;\n }\n\n this.logger.info(\n `Migrazione password legacy accessi completata. Letti=${rows.length}, migrati=${migratedCount}, ignorati=${skippedCount}, durataMs=${(performance.now() - startedAt).toFixed(2)}`\n );\n }\n\n async verifyPassword(\n codiceUtente: number,\n plainPassword: string\n ): Promise<boolean> {\n const query = `SELECT PWD AS password FROM UTENTI_PWD WHERE CODUTE = ?`;\n const result = (await Orm.query(\n this.accessiOptions.databaseOptions,\n query,\n [codiceUtente]\n ).then((results) => results.map(RestUtilities.convertKeysToCamelCase))) as {\n password: string;\n }[];\n\n if (result.length === 0 || typeof result[0].password !== \"string\") {\n return false;\n }\n\n const storedPassword = result[0].password;\n\n if (PasswordUtilities.isPasswordHash(storedPassword)) {\n return PasswordUtilities.verifyPassword(plainPassword, storedPassword);\n }\n\n const legacyEncryptedPassword = CryptUtilities.encrypt(\n plainPassword,\n this.accessiOptions.encryptionKey\n );\n\n if (PasswordUtilities.isLegacyPasswordHash(storedPassword)) {\n const isMigratedLegacyPasswordValid =\n PasswordUtilities.verifyLegacyEncryptedPassword(\n legacyEncryptedPassword,\n storedPassword\n );\n\n if (isMigratedLegacyPasswordValid) {\n await this.setPassword(codiceUtente, plainPassword);\n }\n\n return isMigratedLegacyPasswordValid;\n }\n\n const isLegacyPasswordValid = storedPassword === legacyEncryptedPassword;\n\n if (isLegacyPasswordValid) {\n await this.setPassword(codiceUtente, plainPassword);\n }\n\n return isLegacyPasswordValid;\n }\n\n async getAdminUser(): Promise<LoginResult> {\n return {\n utente: {\n codiceUtente: 6789,\n email: \"admin\",\n statoRegistrazione: StatoRegistrazione.CONF,\n cognome: \"Admin\",\n nome: \"Admin\",\n flagGdpr: true,\n avatar: \"/path/to/avatar.jpg\",\n flagDueFattori: false,\n codiceLingua: \"IT\",\n cellulare: \"+391234567890\",\n flagSuper: true,\n paginaDefault: \"/home\",\n roles: [],\n permissions: [],\n },\n filtri: null,\n userGrants: {\n abilitazioni: [],\n grants: [],\n ruoli: [],\n },\n };\n }\n\n getDemoUser(): LoginResult {\n return {\n utente: {\n codiceUtente: 12345,\n email: \"jdoe\",\n statoRegistrazione: StatoRegistrazione.CONF,\n cognome: \"Doe\",\n nome: \"John\",\n flagGdpr: true,\n avatar: \"/path/to/avatar.jpg\",\n flagDueFattori: false,\n codiceLingua: \"IT\",\n cellulare: \"+391234567890\",\n flagSuper: false,\n paginaDefault: \"/home\",\n roles: [],\n permissions: [],\n },\n filtri: null,\n userGrants: {\n abilitazioni: [],\n grants: [],\n ruoli: [],\n },\n };\n }\n\n public async confirmResetPassword(\n token: string,\n newPassword: string\n ): Promise<void> {\n try {\n if (typeof token !== \"string\" || token.trim() === \"\") {\n throw new Error(\"Token non valido.\");\n }\n\n if (\n typeof newPassword !== \"string\" ||\n newPassword.length < 8 ||\n newPassword.length > 100\n ) {\n throw new Error(\"La nuova password deve essere compresa tra 8 e 100 caratteri.\");\n }\n\n const secret = getAccessiJwtSecret(this.accessiOptions);\n const { codiceUtente, nonce } = verifyPasswordResetToken(token.trim(), secret);\n\n const result = (await Orm.query(\n this.accessiOptions.databaseOptions,\n \"SELECT CODUTE AS codice_utente, STAREG AS stato_registrazione FROM UTENTI WHERE CODUTE = ? AND KEYREG = ?\",\n [codiceUtente, nonce]\n ).then((rows) => rows.map(RestUtilities.convertKeysToCamelCase))) as {\n codiceUtente?: number;\n statoRegistrazione?: StatoRegistrazione | number;\n }[];\n\n if (result.length === 0) {\n throw new Error(\"Token non valido o gia usato.\");\n }\n\n const currentState = Number(result[0].statoRegistrazione);\n if (\n currentState === StatoRegistrazione.BLOCC ||\n currentState === StatoRegistrazione.DELETE\n ) {\n throw new Error(\"Utente non autorizzato a completare il reset password.\");\n }\n\n await Orm.query(\n this.accessiOptions.databaseOptions,\n \"UPDATE UTENTI SET KEYREG = NULL, STAREG = ? WHERE CODUTE = ?\",\n [StatoRegistrazione.CONF, codiceUtente]\n );\n\n await this.setPassword(codiceUtente, newPassword);\n } catch (error) {\n throw error;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"AuthService.js","sourceRoot":"","sources":["../../../../src/accessi-module/Services/AuthService/AuthService.ts"],"names":[],"mappings":"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","sourcesContent":["import { Inject, Injectable, UnauthorizedException } from \"@nestjs/common\";\nimport { TwoFactorService, TwoFactorProof } from '../TwoFactorService/TwoFactorService';\nimport * as jwt from \"jsonwebtoken\";\nimport { Orm } from \"../../../Orm\";\nimport { CryptUtilities, PasswordUtilities, RestUtilities } from \"../../../Utilities\";\nimport type { AccessiOptions } from \"../../AccessiModule\";\nimport { LoginRequest } from \"../../Dtos/LoginRequest\";\nimport { LoginResult } from \"../../Dtos/LoginResponse\";\nimport { StatoRegistrazione } from \"../../Dtos/StatoRegistrazione\";\nimport { UserService } from \"../UserService/UserService\";\nimport { FiltriService } from \"../FiltriService/FiltriService\";\nimport {\n buildAuthenticatedTokenPayload,\n isAuthenticatedUserEnabledForJwt,\n isAccessiTokenAllowedForUser,\n resolveCodiceUtenteFromTokenPayload,\n} from \"../../security/authenticatedToken\";\nimport {\n getAccessiJwtSecret,\n verifyPasswordResetToken,\n} from \"../../security/passwordResetToken\";\nimport { Logger } from \"../../../Logger\";\nimport { TokenResult } from '../../Dtos/TokenResult';\n\n/** Error code deliberately returned when a user is configured as SSO-only. */\nexport const PASSWORD_LOGIN_DISABLED = 'PASSWORD_LOGIN_DISABLED';\n\n@Injectable()\nexport class AuthService {\n private readonly logger = new Logger(AuthService.name);\n\n constructor(\n private userService: UserService,\n private filtriService: FiltriService,\n @Inject(\"ACCESSI_OPTIONS\") private readonly accessiOptions: AccessiOptions,\n private readonly twoFactorService: TwoFactorService,\n ) {}\n\n private async refreshPasswordExpiration(codiceUtente: number): Promise<void> {\n if (!this.accessiOptions.passwordExpiration) {\n return;\n }\n\n const configuredDays = Number(this.accessiOptions.passwordExpirationDays);\n const expirationDays =\n Number.isFinite(configuredDays) && configuredDays > 0\n ? Math.trunc(configuredDays)\n : 90;\n\n const query = `UPDATE UTENTI SET DATSCAPWD = DATEADD(${expirationDays} DAY TO CURRENT_TIMESTAMP) WHERE CODUTE = ?`;\n await Orm.execute(this.accessiOptions.databaseOptions, query, [codiceUtente]);\n }\n\n private isMockDemoUserEnabled(): boolean {\n if (!this.accessiOptions.mockDemoUser) {\n return false;\n }\n\n const nodeEnv = (process.env.NODE_ENV ?? \"production\").toLowerCase();\n return nodeEnv !== \"production\" || process.env.ACCESSI_ALLOW_MOCK_DEMO_USER === \"true\";\n }\n\n /** Creates the normal internal JWT consumed by all existing Accessi guards. */\n public createAccessiToken(utente: LoginResult['utente'], methods: string[] = []): TokenResult {\n if (!utente?.codiceUtente) {\n throw new Error('Impossibile creare un token senza un utente Accessi valido.');\n }\n if ((utente.flagDueFattori === true || Number(utente.flagDueFattori) === 1) && !methods.includes('otp')) {\n throw new UnauthorizedException('Verifica del codice di accesso richiesta.');\n }\n\n return {\n expiresIn: this.accessiOptions.jwtOptions.expiresIn,\n value: jwt.sign({ utente, typ: 'access', amr: methods }, getAccessiJwtSecret(this.accessiOptions), {\n expiresIn: this.accessiOptions.jwtOptions.expiresIn as any,\n }),\n type: 'Bearer',\n };\n }\n\n /** Builds the standard login response for a user authenticated by any supported method. */\n public async getLoginResultForUser(codiceUtente: number): Promise<LoginResult> {\n const users = await this.userService.getUsers(\n { codiceUtente },\n { includeExtensionFields: true, includeGrants: true },\n );\n const result = users[0];\n if (!result?.utente) {\n throw new Error('Utente Accessi non trovato.');\n }\n const current = await this.userService.getAuthenticatedUserSnapshot(codiceUtente);\n if (!isAuthenticatedUserEnabledForJwt(current)) throw new UnauthorizedException('Utente non abilitato.');\n result.utente = { ...result.utente, ...current };\n\n return {\n utente: result.utente,\n filtri: await this.filtriService.getFiltriUser(codiceUtente),\n userGrants: result.userGrants,\n extensionFields: result.extensionFields,\n };\n }\n\n /** Users without a row retain the historic password-login enabled default. */\n private async isPasswordLoginEnabled(codiceUtente: number): Promise<boolean> {\n if (this.accessiOptions.federatedAuthentication?.enabled !== true) return true;\n\n const rows = await Orm.query(\n this.accessiOptions.databaseOptions,\n 'SELECT COALESCE(FLGPASSWORD, 1) AS password_login_enabled FROM UTENTI_CONFIG WHERE CODUTE = ?',\n [codiceUtente],\n );\n const policy = rows.map(RestUtilities.convertKeysToCamelCase)[0] as { passwordLoginEnabled?: unknown } | undefined;\n return policy?.passwordLoginEnabled !== false && policy?.passwordLoginEnabled !== 0 && policy?.passwordLoginEnabled !== '0';\n }\n\n /**\n * Autentica con credenziali locali e restituisce profilo, filtri e grant effettivi.\n * Non crea il JWT: il controller o il flusso SSO deve chiamare `createAccessiToken` sul risultato.\n * Per utenti SSO-only genera `PASSWORD_LOGIN_DISABLED`, da trattare come istruzione a usare l'SSO.\n */\n async login(request: LoginRequest): Promise<LoginResult> {\n const mockDemoUserEnabled = this.isMockDemoUserEnabled();\n\n if (\n mockDemoUserEnabled &&\n request.email.toLowerCase() === \"demo\"\n ) {\n return this.getDemoUser();\n }\n\n if (\n mockDemoUserEnabled &&\n request.email.toLowerCase() === \"admin\"\n ) {\n return this.getAdminUser();\n }\n\n const utente = await this.userService.getUserByEmail(\n request.email.trim().toLowerCase()\n );\n if (!utente) {\n if (!request.password) return { passwordRequired: true };\n throw new Error(\"Nome utente o password errata!\");\n }\n\n const currentUser = await this.userService.getAuthenticatedUserSnapshot(utente.codiceUtente);\n if (isAuthenticatedUserEnabledForJwt(currentUser) && currentUser.flagDueFattori && currentUser.passwordlessLoginEnabled) {\n return { challenge: await this.twoFactorService.issue({ codiceUtente: utente.codiceUtente, email: currentUser.email.trim(), mode: 'passwordless' }) };\n }\n // The email-only step has the same response for unknown and ordinary local accounts.\n if (!request.password) return { passwordRequired: true };\n\n switch (utente.statoRegistrazione) {\n case undefined:\n throw new Error(\n \"Struttura dati compromessa: Stato Registrazione inesistente.\"\n );\n case StatoRegistrazione.BLOCC:\n case StatoRegistrazione.DELETE:\n throw new Error(\"Utente non abilitato\");\n case StatoRegistrazione.INVIO:\n throw new Error(\"Rinnovo password necessario.\");\n }\n\n if (utente.statoRegistrazione !== StatoRegistrazione.CONF) {\n throw new Error(\n `Errore generico. Stato di registrazione non valido: ${utente.statoRegistrazione}.`\n );\n }\n\n if (!isAuthenticatedUserEnabledForJwt(currentUser)) throw new Error('Utente non abilitato');\n if (!(await this.isPasswordLoginEnabled(utente.codiceUtente))) {\n throw new Error(PASSWORD_LOGIN_DISABLED);\n }\n\n if (typeof request.password !== 'string' || request.password.length === 0) {\n throw new Error('Nome utente o password errata!');\n }\n\n const isPasswordValid = await this.verifyPassword(\n utente.codiceUtente,\n request.password\n );\n if (!isPasswordValid) throw new Error(\"Nome utente o password errata!\");\n\n if (\n this.accessiOptions.passwordExpiration &&\n this.accessiOptions.passwordExpiration == true\n ) {\n const today = new Date();\n const targetDate = utente.dataScadenzaPassword\n ? new Date(utente.dataScadenzaPassword)\n : undefined;\n\n // Legacy users may not have an expiration date. Preserve the former non-expiring behaviour for them.\n if (targetDate && !Number.isNaN(targetDate.getTime()) && today >= targetDate) {\n throw new Error(\"PASSWORD_EXPIRED\");\n }\n }\n\n if (currentUser.flagDueFattori) {\n return { challenge: await this.twoFactorService.issue({ codiceUtente: utente.codiceUtente, email: currentUser.email, mode: 'password' }) };\n }\n\n const updateLastAccessDateQuery =\n \"UPDATE UTENTI SET DATLASTLOGIN = CURRENT_TIMESTAMP WHERE CODUTE = ?\";\n await Orm.query(\n this.accessiOptions.databaseOptions,\n updateLastAccessDateQuery,\n [utente.codiceUtente]\n );\n\n return this.getLoginResultForUser(utente.codiceUtente);\n }\n\n /**\n * Verifica un JWT Accessi e ricostruisce il profilo corrente dal database.\n * Questo evita che privilegi, stato utente o flag amministrativi presenti in un token vecchio restino validi.\n */\n public async getAuthenticatedTokenPayload(token: string): Promise<Record<string, unknown>> {\n if (typeof token !== \"string\" || token.trim() === \"\") {\n throw new Error(\"Token non fornito.\");\n }\n\n const secret = getAccessiJwtSecret(this.accessiOptions);\n const decoded = jwt.verify(token.trim(), secret);\n const codiceUtente = resolveCodiceUtenteFromTokenPayload(decoded);\n\n if (!codiceUtente) {\n throw new Error(\"Token non valido.\");\n }\n\n const currentUser = await this.userService.getAuthenticatedUserSnapshot(codiceUtente);\n if (!currentUser || !isAuthenticatedUserEnabledForJwt(currentUser) || !isAccessiTokenAllowedForUser(decoded, currentUser)) {\n throw new Error(\"Token non valido o utente non autorizzato.\");\n }\n\n return buildAuthenticatedTokenPayload(decoded, currentUser);\n }\n\n /** Starts a second-factor challenge after the hosting backend has verified an SSO identity. */\n public async beginFederatedTwoFactor(codiceUtente: number, identityKey: string): Promise<LoginResult> {\n const user = await this.userService.getAuthenticatedUserSnapshot(codiceUtente);\n if (!isAuthenticatedUserEnabledForJwt(user) || !user.flagDueFattori) throw new UnauthorizedException();\n return { challenge: await this.twoFactorService.issue({ codiceUtente, email: user.email, mode: 'federated', identityKey }) };\n }\n\n private async validateTwoFactorProof(proof: TwoFactorProof): Promise<void> {\n const user = await this.userService.getAuthenticatedUserSnapshot(proof.codiceUtente);\n if (!isAuthenticatedUserEnabledForJwt(user) || !user.flagDueFattori || user.email?.trim().toLowerCase() !== proof.email.trim().toLowerCase()) {\n throw new UnauthorizedException('Profilo modificato o utente non abilitato. Ripeti l accesso.');\n }\n if (proof.mode === 'passwordless' && !user.passwordlessLoginEnabled) throw new UnauthorizedException('Accesso senza password disabilitato.');\n if (proof.mode === 'password' && !(await this.isPasswordLoginEnabled(proof.codiceUtente))) throw new UnauthorizedException('Login locale disabilitato.');\n if (proof.mode === 'federated') {\n if (!this.accessiOptions.federatedAuthentication?.enabled) throw new UnauthorizedException();\n const rows = await Orm.query(this.accessiOptions.databaseOptions,\n 'SELECT I.IDNKEY FROM UTENTI_IDENTITA_EXT I INNER JOIN SSO_PROVIDER P ON P.PROVIDER = I.PROVIDER WHERE I.IDNKEY = ? AND I.CODUTE = ? AND I.FLGATTIVO = 1 AND P.FLGATTIVO = 1',\n [proof.identityKey, proof.codiceUtente], false);\n if (!rows.length) throw new UnauthorizedException('Identita SSO non piu abilitata.');\n }\n }\n\n public async verifyTwoFactor(challengeId: string, code: string): Promise<LoginResult> {\n const proof = await this.twoFactorService.consume(challengeId, code);\n await this.validateTwoFactorProof(proof);\n const result = await this.getLoginResultForUser(proof.codiceUtente);\n result.token = this.createAccessiToken(result.utente, [proof.mode, 'otp']);\n await Orm.execute(this.accessiOptions.databaseOptions, 'UPDATE UTENTI SET DATLASTLOGIN = CURRENT_TIMESTAMP WHERE CODUTE = ?', [proof.codiceUtente]);\n if (proof.mode === 'federated') {\n await Orm.execute(this.accessiOptions.databaseOptions, 'UPDATE UTENTI_IDENTITA_EXT SET DATLASTLOGIN = CURRENT_TIMESTAMP WHERE IDNKEY = ?', [proof.identityKey]);\n }\n return result;\n }\n\n public async resendTwoFactor(challengeId: string): Promise<LoginResult> {\n await this.validateTwoFactorProof(await this.twoFactorService.describe(challengeId));\n return { challenge: await this.twoFactorService.resend(challengeId) };\n }\n\n /** Persiste una password hashata e aggiorna la scadenza, se la policy password e attiva. Non invia email. */\n public async setPassword(codiceUtente: number, nuovaPassword: string) {\n try {\n const query = `UPDATE OR INSERT INTO UTENTI_PWD (CODUTE, PWD) VALUES (?, ?)`;\n const hashedPassword = PasswordUtilities.hashPassword(nuovaPassword);\n\n const result = await Orm.execute(this.accessiOptions.databaseOptions, query, [\n codiceUtente,\n hashedPassword,\n ]);\n await this.refreshPasswordExpiration(codiceUtente);\n return result;\n } catch (error) {\n throw error;\n }\n }\n\n /**\n * Converte le password legacy cifrate nel formato hash compatibile, senza conoscere le password in chiaro.\n * E idempotente: hash moderni e gia migrati vengono ignorati.\n */\n public async migrateLegacyEncryptedPasswords(): Promise<void> {\n const startedAt = performance.now();\n this.logger.info(\"Avvio migrazione password legacy accessi.\");\n const results = await Orm.query(\n this.accessiOptions.databaseOptions,\n \"SELECT CODUTE AS codice_utente, PWD AS password FROM UTENTI_PWD WHERE PWD IS NOT NULL\",\n []\n );\n\n const rows = results.map(RestUtilities.convertKeysToCamelCase) as {\n codiceUtente?: number;\n password?: string;\n }[];\n let migratedCount = 0;\n let skippedCount = 0;\n\n for (const row of rows) {\n const codiceUtente = Number(row.codiceUtente);\n const storedPassword = typeof row.password === \"string\" ? row.password : null;\n\n if (\n !codiceUtente ||\n !storedPassword ||\n PasswordUtilities.isPasswordHash(storedPassword) ||\n PasswordUtilities.isLegacyPasswordHash(storedPassword)\n ) {\n skippedCount += 1;\n continue;\n }\n\n const protectedLegacyPassword =\n PasswordUtilities.hashLegacyEncryptedPassword(storedPassword);\n\n await Orm.execute(\n this.accessiOptions.databaseOptions,\n \"UPDATE UTENTI_PWD SET PWD = ? WHERE CODUTE = ? AND PWD = ?\",\n [protectedLegacyPassword, codiceUtente, storedPassword]\n );\n migratedCount += 1;\n }\n\n this.logger.info(\n `Migrazione password legacy accessi completata. Letti=${rows.length}, migrati=${migratedCount}, ignorati=${skippedCount}, durataMs=${(performance.now() - startedAt).toFixed(2)}`\n );\n }\n\n /** Verifica una password locale e migra automaticamente il formato legacy dopo una verifica positiva. */\n async verifyPassword(\n codiceUtente: number,\n plainPassword: string\n ): Promise<boolean> {\n const query = `SELECT PWD AS password FROM UTENTI_PWD WHERE CODUTE = ?`;\n const result = (await Orm.query(\n this.accessiOptions.databaseOptions,\n query,\n [codiceUtente]\n ).then((results) => results.map(RestUtilities.convertKeysToCamelCase))) as {\n password: string;\n }[];\n\n if (result.length === 0 || typeof result[0].password !== \"string\") {\n return false;\n }\n\n const storedPassword = result[0].password;\n\n if (PasswordUtilities.isPasswordHash(storedPassword)) {\n return PasswordUtilities.verifyPassword(plainPassword, storedPassword);\n }\n\n const legacyEncryptedPassword = CryptUtilities.encrypt(\n plainPassword,\n this.accessiOptions.encryptionKey\n );\n\n if (PasswordUtilities.isLegacyPasswordHash(storedPassword)) {\n const isMigratedLegacyPasswordValid =\n PasswordUtilities.verifyLegacyEncryptedPassword(\n legacyEncryptedPassword,\n storedPassword\n );\n\n if (isMigratedLegacyPasswordValid) {\n await this.setPassword(codiceUtente, plainPassword);\n }\n\n return isMigratedLegacyPasswordValid;\n }\n\n const isLegacyPasswordValid = storedPassword === legacyEncryptedPassword;\n\n if (isLegacyPasswordValid) {\n await this.setPassword(codiceUtente, plainPassword);\n }\n\n return isLegacyPasswordValid;\n }\n\n /** Restituisce l'utente fittizio amministratore; usabile solo con `mockDemoUser` esplicitamente abilitato. */\n async getAdminUser(): Promise<LoginResult> {\n return {\n utente: {\n codiceUtente: 6789,\n email: \"admin\",\n statoRegistrazione: StatoRegistrazione.CONF,\n cognome: \"Admin\",\n nome: \"Admin\",\n flagGdpr: true,\n avatar: \"/path/to/avatar.jpg\",\n flagDueFattori: false,\n codiceLingua: \"IT\",\n cellulare: \"+391234567890\",\n flagSuper: true,\n paginaDefault: \"/home\",\n roles: [],\n permissions: [],\n },\n filtri: null,\n userGrants: {\n abilitazioni: [],\n grants: [],\n ruoli: [],\n },\n };\n }\n\n /** Restituisce l'utente demo fittizio; non contiene dati o grant reali. */\n getDemoUser(): LoginResult {\n return {\n utente: {\n codiceUtente: 12345,\n email: \"jdoe\",\n statoRegistrazione: StatoRegistrazione.CONF,\n cognome: \"Doe\",\n nome: \"John\",\n flagGdpr: true,\n avatar: \"/path/to/avatar.jpg\",\n flagDueFattori: false,\n codiceLingua: \"IT\",\n cellulare: \"+391234567890\",\n flagSuper: false,\n paginaDefault: \"/home\",\n roles: [],\n permissions: [],\n },\n filtri: null,\n userGrants: {\n abilitazioni: [],\n grants: [],\n ruoli: [],\n },\n };\n }\n\n /**\n * Consuma un token monouso di reset, riporta l'utente allo stato confermato e salva la nuova password.\n * Il nonce in `UTENTI.KEYREG` viene annullato prima di impostare la password, impedendo il riuso del token.\n */\n public async confirmResetPassword(\n token: string,\n newPassword: string\n ): Promise<void> {\n try {\n if (typeof token !== \"string\" || token.trim() === \"\") {\n throw new Error(\"Token non valido.\");\n }\n\n if (\n typeof newPassword !== \"string\" ||\n newPassword.length < 8 ||\n newPassword.length > 100\n ) {\n throw new Error(\"La nuova password deve essere compresa tra 8 e 100 caratteri.\");\n }\n\n const secret = getAccessiJwtSecret(this.accessiOptions);\n const { codiceUtente, nonce } = verifyPasswordResetToken(token.trim(), secret);\n\n const hashedPassword = PasswordUtilities.hashPassword(newPassword);\n const db = await Orm.connect(this.accessiOptions.databaseOptions);\n let transaction: Awaited<ReturnType<typeof Orm.startTransaction>> | undefined;\n try {\n transaction = await Orm.startTransaction(db);\n const query = (sql: string, params: unknown[]) => new Promise<any>((resolve, reject) => {\n transaction!.query(sql, params, (error, result) => error ? reject(error) : resolve(result));\n });\n // A conditional write claims the nonce under the database row lock. A second\n // concurrent reset cannot also consume it; failures roll the whole reset back.\n const claimed = await query(\n 'UPDATE UTENTI SET KEYREG = NULL, STAREG = ? WHERE CODUTE = ? AND KEYREG = ? AND STAREG IN (?, ?) RETURNING CODUTE',\n [StatoRegistrazione.CONF, codiceUtente, nonce, StatoRegistrazione.CONF, StatoRegistrazione.INVIO],\n );\n const row = Array.isArray(claimed) ? claimed[0] : claimed;\n if (Number(row?.CODUTE ?? row?.codute) !== codiceUtente) {\n throw new Error('Token non valido, gia usato o utente non autorizzato.');\n }\n await query('UPDATE OR INSERT INTO UTENTI_PWD (CODUTE, PWD) VALUES (?, ?) MATCHING (CODUTE)', [codiceUtente, hashedPassword]);\n if (this.accessiOptions.passwordExpiration) {\n const days = Number(this.accessiOptions.passwordExpirationDays);\n const expirationDays = Number.isFinite(days) && days > 0 ? Math.trunc(days) : 90;\n await query(`UPDATE UTENTI SET DATSCAPWD = DATEADD(${expirationDays} DAY TO CURRENT_TIMESTAMP) WHERE CODUTE = ?`, [codiceUtente]);\n }\n await Orm.commitTransaction(transaction);\n } catch (error) {\n if (transaction) await Orm.rollbackTransaction(transaction).catch(() => undefined);\n throw error;\n } finally {\n await new Promise<void>((resolve) => db.detach(() => resolve()));\n }\n } catch (error) {\n throw error;\n }\n }\n}\n"]}
@@ -1,7 +1,9 @@
1
- import { AccessiOptions } from '../../AccessiModule';
1
+ import type { AccessiOptions } from '../../AccessiModule';
2
2
  export declare class ConfiguratorService {
3
3
  private readonly accessiOptions;
4
4
  constructor(accessiOptions: AccessiOptions);
5
+ /** Enables or disables one menu in the runtime catalog. Disabled menus are excluded from normal grant resolution. */
5
6
  setMenuEnabled(codiceMenu: string, enabled: boolean): Promise<void>;
7
+ /** Enables or disables a whole group. Existing menus and role mappings are preserved for future reactivation. */
6
8
  setGroupEnabled(codiceGruppo: string, enabled: boolean): Promise<void>;
7
9
  }
@@ -29,6 +29,7 @@ let ConfiguratorService = class ConfiguratorService {
29
29
  constructor(accessiOptions) {
30
30
  this.accessiOptions = accessiOptions;
31
31
  }
32
+ /** Enables or disables one menu in the runtime catalog. Disabled menus are excluded from normal grant resolution. */
32
33
  setMenuEnabled(codiceMenu, enabled) {
33
34
  return __awaiter(this, void 0, void 0, function* () {
34
35
  const query = `UPDATE MENU SET FLGENABLED = ? WHERE CODMNU = ?`;
@@ -36,6 +37,7 @@ let ConfiguratorService = class ConfiguratorService {
36
37
  yield Orm_1.Orm.execute(this.accessiOptions.databaseOptions, query, [enabledValue, codiceMenu]);
37
38
  });
38
39
  }
40
+ /** Enables or disables a whole group. Existing menus and role mappings are preserved for future reactivation. */
39
41
  setGroupEnabled(codiceGruppo, enabled) {
40
42
  return __awaiter(this, void 0, void 0, function* () {
41
43
  const query = `UPDATE MENU_GRP SET FLGENABLED = ? WHERE CODGRP = ?`;
@@ -47,7 +49,9 @@ let ConfiguratorService = class ConfiguratorService {
47
49
  exports.ConfiguratorService = ConfiguratorService;
48
50
  exports.ConfiguratorService = ConfiguratorService = __decorate([
49
51
  autobind_1.autobind,
50
- (0, common_1.Injectable)(),
52
+ (0, common_1.Injectable)()
53
+ /** Administrative catalog service. Disabling a menu or group does not delete grants already stored for it. */
54
+ ,
51
55
  __param(0, (0, common_1.Inject)('ACCESSI_OPTIONS')),
52
56
  __metadata("design:paramtypes", [Object])
53
57
  ], ConfiguratorService);
@@ -1 +1 @@
1
- {"version":3,"file":"ConfiguratorService.js","sourceRoot":"","sources":["../../../../src/accessi-module/Services/ConfiguratorService/ConfiguratorService.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAAoD;AACpD,gDAA6C;AAE7C,sCAAmC;AAI5B,IAAM,mBAAmB,GAAzB,MAAM,mBAAmB;IAC9B,YAC8C,cAA8B;QAA9B,mBAAc,GAAd,cAAc,CAAgB;IAEzE,CAAC;IAES,cAAc,CAAC,UAAkB,EAAE,OAAgB;;YAC9D,MAAM,KAAK,GAAG,iDAAiD,CAAC;YAChE,MAAM,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YACpC,MAAM,SAAG,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,eAAe,EAAE,KAAK,EAAE,CAAC,YAAY,EAAC,UAAU,CAAC,CAAC,CAAA;QAC1F,CAAC;KAAA;IAEY,eAAe,CAAC,YAAoB,EAAE,OAAgB;;YACjE,MAAM,KAAK,GAAG,qDAAqD,CAAA;YACnE,MAAM,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YACpC,MAAM,SAAG,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,eAAe,EAAE,KAAK,EAAE,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,CAAA;QAC7F,CAAC;KAAA;CAKF,CAAA;AArBY,kDAAmB;8BAAnB,mBAAmB;IAF/B,mBAAQ;IACR,IAAA,mBAAU,GAAE;IAGR,WAAA,IAAA,eAAM,EAAC,iBAAiB,CAAC,CAAA;;GAFjB,mBAAmB,CAqB/B","sourcesContent":["import { Inject, Injectable } from '@nestjs/common';\nimport { autobind } from '../../../autobind';\nimport { AccessiOptions } from '../../AccessiModule';\nimport { Orm } from '../../../Orm';\n\n@autobind\n@Injectable()\nexport class ConfiguratorService {\n constructor(\n @Inject('ACCESSI_OPTIONS') private readonly accessiOptions: AccessiOptions,\n\n ) {}\n\n public async setMenuEnabled(codiceMenu: string, enabled: boolean): Promise<void> {\n const query = `UPDATE MENU SET FLGENABLED = ? WHERE CODMNU = ?`;\n const enabledValue = enabled ? 1 : 0\n await Orm.execute(this.accessiOptions.databaseOptions, query, [enabledValue,codiceMenu])\n }\n\n public async setGroupEnabled(codiceGruppo: string, enabled: boolean): Promise<void> {\n const query = `UPDATE MENU_GRP SET FLGENABLED = ? WHERE CODGRP = ?`\n const enabledValue = enabled ? 1 : 0\n await Orm.execute(this.accessiOptions.databaseOptions, query, [enabledValue, codiceGruppo])\n }\n\n\n\n\n}\n"]}
1
+ {"version":3,"file":"ConfiguratorService.js","sourceRoot":"","sources":["../../../../src/accessi-module/Services/ConfiguratorService/ConfiguratorService.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAAoD;AACpD,gDAA6C;AAE7C,sCAAmC;AAK5B,IAAM,mBAAmB,GAAzB,MAAM,mBAAmB;IAC9B,YAC8C,cAA8B;QAA9B,mBAAc,GAAd,cAAc,CAAgB;IAEzE,CAAC;IAEJ,qHAAqH;IACxG,cAAc,CAAC,UAAkB,EAAE,OAAgB;;YAC9D,MAAM,KAAK,GAAG,iDAAiD,CAAC;YAChE,MAAM,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YACpC,MAAM,SAAG,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,eAAe,EAAE,KAAK,EAAE,CAAC,YAAY,EAAC,UAAU,CAAC,CAAC,CAAA;QAC1F,CAAC;KAAA;IAED,iHAAiH;IACpG,eAAe,CAAC,YAAoB,EAAE,OAAgB;;YACjE,MAAM,KAAK,GAAG,qDAAqD,CAAA;YACnE,MAAM,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YACpC,MAAM,SAAG,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,eAAe,EAAE,KAAK,EAAE,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,CAAA;QAC7F,CAAC;KAAA;CAKF,CAAA;AAvBY,kDAAmB;8BAAnB,mBAAmB;IAH/B,mBAAQ;IACR,IAAA,mBAAU,GAAE;IACb,8GAA8G;;IAGzG,WAAA,IAAA,eAAM,EAAC,iBAAiB,CAAC,CAAA;;GAFjB,mBAAmB,CAuB/B","sourcesContent":["import { Inject, Injectable } from '@nestjs/common';\nimport { autobind } from '../../../autobind';\nimport type { AccessiOptions } from '../../AccessiModule';\nimport { Orm } from '../../../Orm';\n\n@autobind\n@Injectable()\n/** Administrative catalog service. Disabling a menu or group does not delete grants already stored for it. */\nexport class ConfiguratorService {\n constructor(\n @Inject('ACCESSI_OPTIONS') private readonly accessiOptions: AccessiOptions,\n\n ) {}\n\n /** Enables or disables one menu in the runtime catalog. Disabled menus are excluded from normal grant resolution. */\n public async setMenuEnabled(codiceMenu: string, enabled: boolean): Promise<void> {\n const query = `UPDATE MENU SET FLGENABLED = ? WHERE CODMNU = ?`;\n const enabledValue = enabled ? 1 : 0\n await Orm.execute(this.accessiOptions.databaseOptions, query, [enabledValue,codiceMenu])\n }\n\n /** Enables or disables a whole group. Existing menus and role mappings are preserved for future reactivation. */\n public async setGroupEnabled(codiceGruppo: string, enabled: boolean): Promise<void> {\n const query = `UPDATE MENU_GRP SET FLGENABLED = ? WHERE CODGRP = ?`\n const enabledValue = enabled ? 1 : 0\n await Orm.execute(this.accessiOptions.databaseOptions, query, [enabledValue, codiceGruppo])\n }\n\n\n\n\n}\n"]}
@@ -1,9 +1,15 @@
1
- import { AccessiOptions } from '../../AccessiModule';
1
+ import type { AccessiOptions } from '../../AccessiModule';
2
2
  export declare class EmailService {
3
3
  private readonly accessiOptions;
4
4
  constructor(accessiOptions: AccessiOptions);
5
5
  sendAccountUpdateEmail(email: string, message: string): Promise<void>;
6
6
  private transporter;
7
+ /** Sends the one-time login code without including it in application logs. */
8
+ sendTwoFactorCode(email: string, code: string, validityMinutes: number): Promise<void>;
9
+ /**
10
+ * Creates a short-lived, one-use reset token and sends it by email. Invalid, missing, blocked or deleted users
11
+ * return without error to prevent account enumeration. On delivery failure the stored reset nonce is cleared.
12
+ */
7
13
  sendPasswordResetEmail(email: string, htmlMail?: string): Promise<void>;
8
14
  private GetHtmlMail;
9
15
  }
@@ -39,11 +39,27 @@ let EmailService = class EmailService {
39
39
  sendAccountUpdateEmail(email, message) {
40
40
  throw new Error('Method not implemented.');
41
41
  }
42
+ /** Sends the one-time login code without including it in application logs. */
43
+ sendTwoFactorCode(email, code, validityMinutes) {
44
+ return __awaiter(this, void 0, void 0, function* () {
45
+ yield this.transporter.sendMail({
46
+ from: this.accessiOptions.emailOptions.from,
47
+ to: email,
48
+ subject: 'Codice di accesso',
49
+ text: `Il tuo codice di accesso e: ${code}\n\nScade entro ${validityMinutes} minuti e puo essere usato una sola volta. Se non hai richiesto l accesso, ignora questa email.`,
50
+ });
51
+ });
52
+ }
53
+ /**
54
+ * Creates a short-lived, one-use reset token and sends it by email. Invalid, missing, blocked or deleted users
55
+ * return without error to prevent account enumeration. On delivery failure the stored reset nonce is cleared.
56
+ */
42
57
  sendPasswordResetEmail(email, htmlMail) {
43
58
  return __awaiter(this, void 0, void 0, function* () {
44
59
  var _a;
45
60
  let codiceUtente = null;
46
61
  let resetToken = null;
62
+ let nonce = null;
47
63
  try {
48
64
  if (typeof email !== 'string' || email.trim() === '') {
49
65
  return;
@@ -63,10 +79,10 @@ let EmailService = class EmailService {
63
79
  return;
64
80
  }
65
81
  codiceUtente = user.codiceUtente;
66
- const nonce = (0, uuid_1.v4)();
82
+ nonce = (0, uuid_1.v4)();
67
83
  const secret = (0, passwordResetToken_1.getAccessiJwtSecret)(this.accessiOptions);
68
84
  resetToken = (0, passwordResetToken_1.createPasswordResetToken)(codiceUtente, nonce, secret);
69
- yield Orm_1.Orm.execute(this.accessiOptions.databaseOptions, 'UPDATE UTENTI SET KEYREG = ? WHERE CODUTE = ? ', [nonce, codiceUtente]);
85
+ yield Orm_1.Orm.execute(this.accessiOptions.databaseOptions, 'UPDATE UTENTI SET KEYREG = ? WHERE CODUTE = ? ', [nonce, codiceUtente], false);
70
86
  //costruizione dei queryparams
71
87
  const returnUrlQueryParams = '?returnUrl=' +
72
88
  encodeURIComponent(this.accessiOptions.confirmationEmailReturnUrl) +
@@ -108,8 +124,8 @@ let EmailService = class EmailService {
108
124
  yield this.transporter.sendMail(mailOptions);
109
125
  }
110
126
  catch (error) {
111
- if (codiceUtente) {
112
- yield Orm_1.Orm.execute(this.accessiOptions.databaseOptions, 'UPDATE UTENTI SET KEYREG = NULL WHERE CODUTE = ?', [codiceUtente]).catch(() => undefined);
127
+ if (codiceUtente && nonce) {
128
+ yield Orm_1.Orm.execute(this.accessiOptions.databaseOptions, 'UPDATE UTENTI SET KEYREG = NULL WHERE CODUTE = ? AND KEYREG = ?', [codiceUtente, nonce], false).catch(() => undefined);
113
129
  }
114
130
  console.error("Errore nell'invio dell'email di reset password:", error);
115
131
  throw new Error("Errore durante l'invio dell'email di reset password.");
@@ -407,7 +423,9 @@ let EmailService = class EmailService {
407
423
  };
408
424
  exports.EmailService = EmailService;
409
425
  exports.EmailService = EmailService = __decorate([
410
- (0, common_1.Injectable)(),
426
+ (0, common_1.Injectable)()
427
+ /** Sends password lifecycle email. It deliberately does not expose whether an email exists to public callers. */
428
+ ,
411
429
  __param(0, (0, common_1.Inject)('ACCESSI_OPTIONS')),
412
430
  __metadata("design:paramtypes", [Object])
413
431
  ], EmailService);