@solidstarters/solid-core 1.2.163 → 1.2.166

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 (189) hide show
  1. package/dist/controllers/test-queue.controller.d.ts +1 -1
  2. package/dist/controllers/test-queue.controller.d.ts.map +1 -1
  3. package/dist/controllers/test-queue.controller.js +6 -4
  4. package/dist/controllers/test-queue.controller.js.map +1 -1
  5. package/dist/decorators/error-codes-provider.decorator.d.ts +4 -0
  6. package/dist/decorators/error-codes-provider.decorator.d.ts.map +1 -0
  7. package/dist/decorators/error-codes-provider.decorator.js +12 -0
  8. package/dist/decorators/error-codes-provider.decorator.js.map +1 -0
  9. package/dist/entities/security-rule.entity.js +0 -1
  10. package/dist/entities/security-rule.entity.js.map +1 -1
  11. package/dist/filters/http-exception.filter.d.ts +3 -2
  12. package/dist/filters/http-exception.filter.d.ts.map +1 -1
  13. package/dist/filters/http-exception.filter.js +23 -16
  14. package/dist/filters/http-exception.filter.js.map +1 -1
  15. package/dist/helpers/error-mapper.service.d.ts +12 -2
  16. package/dist/helpers/error-mapper.service.d.ts.map +1 -1
  17. package/dist/helpers/error-mapper.service.js +85 -72
  18. package/dist/helpers/error-mapper.service.js.map +1 -1
  19. package/dist/helpers/solid-core-error-codes-provider.service.d.ts +7 -0
  20. package/dist/helpers/solid-core-error-codes-provider.service.d.ts.map +1 -0
  21. package/dist/helpers/solid-core-error-codes-provider.service.js +67 -0
  22. package/dist/helpers/solid-core-error-codes-provider.service.js.map +1 -0
  23. package/dist/helpers/solid-registry.d.ts +5 -1
  24. package/dist/helpers/solid-registry.d.ts.map +1 -1
  25. package/dist/helpers/solid-registry.js +16 -0
  26. package/dist/helpers/solid-registry.js.map +1 -1
  27. package/dist/index.d.ts +1 -0
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +1 -0
  30. package/dist/index.js.map +1 -1
  31. package/dist/interfaces.d.ts +16 -0
  32. package/dist/interfaces.d.ts.map +1 -1
  33. package/dist/interfaces.js.map +1 -1
  34. package/dist/jobs/chatter-queue-options.d.ts +8 -0
  35. package/dist/jobs/chatter-queue-options.d.ts.map +1 -0
  36. package/dist/jobs/chatter-queue-options.js +10 -0
  37. package/dist/jobs/chatter-queue-options.js.map +1 -0
  38. package/dist/jobs/chatter-queue-publisher.service.d.ts +22 -0
  39. package/dist/jobs/chatter-queue-publisher.service.d.ts.map +1 -0
  40. package/dist/jobs/chatter-queue-publisher.service.js +39 -0
  41. package/dist/jobs/chatter-queue-publisher.service.js.map +1 -0
  42. package/dist/jobs/chatter-queue-subscriber.service.d.ts +17 -0
  43. package/dist/jobs/chatter-queue-subscriber.service.d.ts.map +1 -0
  44. package/dist/jobs/chatter-queue-subscriber.service.js +59 -0
  45. package/dist/jobs/chatter-queue-subscriber.service.js.map +1 -0
  46. package/dist/jobs/{database/computed-field-evaluation-publisher.service.d.ts → computed-field-evaluation-publisher.service.d.ts} +2 -2
  47. package/dist/jobs/computed-field-evaluation-publisher.service.d.ts.map +1 -0
  48. package/dist/jobs/{database/computed-field-evaluation-publisher.service.js → computed-field-evaluation-publisher.service.js} +8 -8
  49. package/dist/jobs/computed-field-evaluation-publisher.service.js.map +1 -0
  50. package/dist/jobs/{database/computed-field-evaluation-queue-options.d.ts → computed-field-evaluation-queue-options.d.ts} +1 -1
  51. package/dist/jobs/computed-field-evaluation-queue-options.d.ts.map +1 -0
  52. package/dist/jobs/{database/computed-field-evaluation-queue-options.js → computed-field-evaluation-queue-options.js} +2 -2
  53. package/dist/jobs/computed-field-evaluation-queue-options.js.map +1 -0
  54. package/dist/jobs/{database/computed-field-evaluation-subscriber.service.d.ts → computed-field-evaluation-subscriber.service.d.ts} +3 -3
  55. package/dist/jobs/computed-field-evaluation-subscriber.service.d.ts.map +1 -0
  56. package/dist/jobs/computed-field-evaluation-subscriber.service.js +51 -0
  57. package/dist/jobs/computed-field-evaluation-subscriber.service.js.map +1 -0
  58. package/dist/jobs/database/computed-field-evaluation-publisher-database.service.d.ts +12 -0
  59. package/dist/jobs/database/computed-field-evaluation-publisher-database.service.d.ts.map +1 -0
  60. package/dist/jobs/database/computed-field-evaluation-publisher-database.service.js +39 -0
  61. package/dist/jobs/database/computed-field-evaluation-publisher-database.service.js.map +1 -0
  62. package/dist/jobs/database/computed-field-evaluation-queue-options-database.d.ts +8 -0
  63. package/dist/jobs/database/computed-field-evaluation-queue-options-database.d.ts.map +1 -0
  64. package/dist/jobs/database/computed-field-evaluation-queue-options-database.js +10 -0
  65. package/dist/jobs/database/computed-field-evaluation-queue-options-database.js.map +1 -0
  66. package/dist/jobs/database/computed-field-evaluation-subscriber-database.service.d.ts +18 -0
  67. package/dist/jobs/database/computed-field-evaluation-subscriber-database.service.d.ts.map +1 -0
  68. package/dist/jobs/database/{computed-field-evaluation-subscriber.service.js → computed-field-evaluation-subscriber-database.service.js} +8 -8
  69. package/dist/jobs/database/computed-field-evaluation-subscriber-database.service.js.map +1 -0
  70. package/dist/jobs/database/generate-code-queue-options-database.js +2 -2
  71. package/dist/jobs/database/generate-code-queue-options-database.js.map +1 -1
  72. package/dist/jobs/database/test-queue-subscriber-database.service.d.ts.map +1 -1
  73. package/dist/jobs/database/test-queue-subscriber-database.service.js +7 -1
  74. package/dist/jobs/database/test-queue-subscriber-database.service.js.map +1 -1
  75. package/dist/jobs/generate-code-publisher.service.d.ts +11 -0
  76. package/dist/jobs/generate-code-publisher.service.d.ts.map +1 -0
  77. package/dist/jobs/generate-code-publisher.service.js +39 -0
  78. package/dist/jobs/generate-code-publisher.service.js.map +1 -0
  79. package/dist/jobs/generate-code-queue-options.d.ts +8 -0
  80. package/dist/jobs/generate-code-queue-options.d.ts.map +1 -0
  81. package/dist/jobs/generate-code-queue-options.js +10 -0
  82. package/dist/jobs/generate-code-queue-options.js.map +1 -0
  83. package/dist/jobs/generate-code-subscriber.service.d.ts +18 -0
  84. package/dist/jobs/generate-code-subscriber.service.d.ts.map +1 -0
  85. package/dist/jobs/generate-code-subscriber.service.js +70 -0
  86. package/dist/jobs/generate-code-subscriber.service.js.map +1 -0
  87. package/dist/jobs/test-queue-subscriber.service.d.ts +1 -1
  88. package/dist/jobs/test-queue-subscriber.service.d.ts.map +1 -1
  89. package/dist/jobs/test-queue-subscriber.service.js +9 -6
  90. package/dist/jobs/test-queue-subscriber.service.js.map +1 -1
  91. package/dist/jobs/trigger-mcp-client-publisher.service.d.ts +11 -0
  92. package/dist/jobs/trigger-mcp-client-publisher.service.d.ts.map +1 -0
  93. package/dist/jobs/trigger-mcp-client-publisher.service.js +39 -0
  94. package/dist/jobs/trigger-mcp-client-publisher.service.js.map +1 -0
  95. package/dist/jobs/trigger-mcp-client-queue-options.d.ts +8 -0
  96. package/dist/jobs/trigger-mcp-client-queue-options.d.ts.map +1 -0
  97. package/dist/jobs/trigger-mcp-client-queue-options.js +10 -0
  98. package/dist/jobs/trigger-mcp-client-queue-options.js.map +1 -0
  99. package/dist/jobs/trigger-mcp-client-subscriber.service.d.ts +18 -0
  100. package/dist/jobs/trigger-mcp-client-subscriber.service.d.ts.map +1 -0
  101. package/dist/jobs/trigger-mcp-client-subscriber.service.js +103 -0
  102. package/dist/jobs/trigger-mcp-client-subscriber.service.js.map +1 -0
  103. package/dist/jobs/twilio-sms-publisher.service.d.ts +11 -0
  104. package/dist/jobs/twilio-sms-publisher.service.d.ts.map +1 -0
  105. package/dist/jobs/twilio-sms-publisher.service.js +39 -0
  106. package/dist/jobs/twilio-sms-publisher.service.js.map +1 -0
  107. package/dist/jobs/twilio-sms-queue-options.d.ts +8 -0
  108. package/dist/jobs/twilio-sms-queue-options.d.ts.map +1 -0
  109. package/dist/jobs/twilio-sms-queue-options.js +10 -0
  110. package/dist/jobs/twilio-sms-queue-options.js.map +1 -0
  111. package/dist/jobs/twilio-sms-subscriber.service.d.ts +17 -0
  112. package/dist/jobs/twilio-sms-subscriber.service.d.ts.map +1 -0
  113. package/dist/jobs/twilio-sms-subscriber.service.js +48 -0
  114. package/dist/jobs/twilio-sms-subscriber.service.js.map +1 -0
  115. package/dist/repository/security-rule.repository.js +2 -2
  116. package/dist/repository/security-rule.repository.js.map +1 -1
  117. package/dist/seeders/seed-data/solid-core-metadata.json +2 -2
  118. package/dist/services/authentication.service.js +3 -3
  119. package/dist/services/authentication.service.js.map +1 -1
  120. package/dist/services/queues/database-publisher.service.js +2 -2
  121. package/dist/services/queues/database-publisher.service.js.map +1 -1
  122. package/dist/services/queues/database-subscriber.service.d.ts.map +1 -1
  123. package/dist/services/queues/database-subscriber.service.js +2 -1
  124. package/dist/services/queues/database-subscriber.service.js.map +1 -1
  125. package/dist/services/queues/publisher-factory.service.js +1 -1
  126. package/dist/services/queues/publisher-factory.service.js.map +1 -1
  127. package/dist/services/solid-introspect.service.d.ts +1 -0
  128. package/dist/services/solid-introspect.service.d.ts.map +1 -1
  129. package/dist/services/solid-introspect.service.js +14 -0
  130. package/dist/services/solid-introspect.service.js.map +1 -1
  131. package/dist/solid-core.module.d.ts.map +1 -1
  132. package/dist/solid-core.module.js +23 -4
  133. package/dist/solid-core.module.js.map +1 -1
  134. package/dist/subscribers/audit.subscriber.d.ts +8 -0
  135. package/dist/subscribers/audit.subscriber.d.ts.map +1 -1
  136. package/dist/subscribers/audit.subscriber.js +52 -3
  137. package/dist/subscribers/audit.subscriber.js.map +1 -1
  138. package/dist/subscribers/computed-entity-field.subscriber.d.ts +3 -3
  139. package/dist/subscribers/computed-entity-field.subscriber.d.ts.map +1 -1
  140. package/dist/subscribers/computed-entity-field.subscriber.js +5 -7
  141. package/dist/subscribers/computed-entity-field.subscriber.js.map +1 -1
  142. package/dist/tsconfig.tsbuildinfo +1 -1
  143. package/package.json +1 -1
  144. package/src/controllers/test-queue.controller.ts +4 -3
  145. package/src/decorators/error-codes-provider.decorator.ts +9 -0
  146. package/src/entities/security-rule.entity.ts +1 -1
  147. package/src/filters/http-exception.filter.ts +48 -23
  148. package/src/helpers/error-mapper.service.ts +117 -176
  149. package/src/helpers/solid-core-error-codes-provider.service.ts +63 -0
  150. package/src/helpers/solid-registry.ts +20 -1
  151. package/src/index.ts +1 -0
  152. package/src/interfaces.ts +36 -0
  153. package/src/jobs/chatter-queue-options.ts +9 -0
  154. package/src/jobs/chatter-queue-publisher.service.ts +37 -0
  155. package/src/jobs/chatter-queue-subscriber.service.ts +46 -0
  156. package/src/jobs/computed-field-evaluation-publisher.service.ts +23 -0
  157. package/src/jobs/{database/computed-field-evaluation-queue-options.ts → computed-field-evaluation-queue-options.ts} +2 -2
  158. package/src/jobs/computed-field-evaluation-subscriber.service.ts +38 -0
  159. package/src/jobs/database/{computed-field-evaluation-publisher.service.ts → computed-field-evaluation-publisher-database.service.ts} +2 -2
  160. package/src/jobs/database/computed-field-evaluation-queue-options-database.ts +9 -0
  161. package/src/jobs/database/{computed-field-evaluation-subscriber.service.ts → computed-field-evaluation-subscriber-database.service.ts} +2 -2
  162. package/src/jobs/database/generate-code-queue-options-database.ts +2 -2
  163. package/src/jobs/database/test-queue-subscriber-database.service.ts +10 -2
  164. package/src/jobs/generate-code-publisher.service.ts +23 -0
  165. package/src/jobs/generate-code-queue-options.ts +9 -0
  166. package/src/jobs/generate-code-subscriber.service.ts +59 -0
  167. package/src/jobs/test-queue-subscriber.service.ts +15 -7
  168. package/src/jobs/trigger-mcp-client-publisher.service.ts +22 -0
  169. package/src/jobs/trigger-mcp-client-queue-options.ts +9 -0
  170. package/src/jobs/trigger-mcp-client-subscriber.service.ts +104 -0
  171. package/src/jobs/twilio-sms-publisher.service.ts +23 -0
  172. package/src/jobs/twilio-sms-queue-options.ts +9 -0
  173. package/src/jobs/twilio-sms-subscriber.service.ts +32 -0
  174. package/src/repository/security-rule.repository.ts +2 -2
  175. package/src/seeders/seed-data/solid-core-metadata.json +2 -2
  176. package/src/services/authentication.service.ts +4 -4
  177. package/src/services/queues/database-publisher.service.ts +2 -2
  178. package/src/services/queues/database-subscriber.service.ts +2 -1
  179. package/src/services/queues/publisher-factory.service.ts +1 -1
  180. package/src/services/solid-introspect.service.ts +22 -0
  181. package/src/solid-core.module.ts +35 -8
  182. package/src/subscribers/audit.subscriber.ts +235 -5
  183. package/src/subscribers/computed-entity-field.subscriber.ts +7 -5
  184. package/dist/jobs/database/computed-field-evaluation-publisher.service.d.ts.map +0 -1
  185. package/dist/jobs/database/computed-field-evaluation-publisher.service.js.map +0 -1
  186. package/dist/jobs/database/computed-field-evaluation-queue-options.d.ts.map +0 -1
  187. package/dist/jobs/database/computed-field-evaluation-queue-options.js.map +0 -1
  188. package/dist/jobs/database/computed-field-evaluation-subscriber.service.d.ts.map +0 -1
  189. package/dist/jobs/database/computed-field-evaluation-subscriber.service.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"security-rule.repository.js","sourceRoot":"","sources":["../../src/repository/security-rule.repository.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,2CAAoD;AAKpD,6EAAmE;AACnE,2EAAiE;AACjE,2EAAiE;AACjE,8DAA2D;AAE3D,yEAAuF;AACvF,qCAA+E;AAGxE,IAAM,sBAAsB,8BAA5B,MAAM,sBAAuB,SAAQ,oBAAwB;IAEhE,YACY,UAAsB,EACb,aAA4B,EAC5B,iBAAoC;QAErD,KAAK,CAAC,mCAAY,EAAE,UAAU,CAAC,mBAAmB,EAAE,CAAC,CAAC;QAJ9C,eAAU,GAAV,UAAU,CAAY;QACb,kBAAa,GAAb,aAAa,CAAe;QAC5B,sBAAiB,GAAjB,iBAAiB,CAAmB;QAJxC,WAAM,GAAG,IAAI,eAAM,CAAC,wBAAsB,CAAC,IAAI,CAAC,CAAC;IAOlE,CAAC;IAED,kBAAkB,CAAyB,EAAyB,EAAE,iBAAyB,EAAE,UAA0B,EAAE,oBAA4B,EAAE,CAAC,KAAK;QAE7J,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,iBAAiB,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;QAG/F,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;YACxB,OAAO,EAAE,CAAC;QACd,CAAC;QAGD,EAAE,CAAC,QAAQ,CAAC,IAAI,kBAAQ,CAAC,CAAC,OAAO,EAAE,EAAE;YACjC,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;gBAC/B,IAAI,CAAC;oBACD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CACzB,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,kBAAkB,EAAE,UAAU,CAAC,CAChD,CAAC;oBAE5B,IAAI,UAAU,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;wBAC/B,OAAO,CAAC,OAAO,CACX,IAAI,kBAAQ,CAAC,CAAC,OAAO,EAAE,EAAE;4BACtB,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,EAAE,iBAAiB,EAAE,EAAE,CAAC,CAAC;wBAC3F,CAAC,CAAC,CACL,CAAC;oBACN,CAAC;gBACL,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACb,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gCAAgC,IAAI,CAAC,kBAAkB,EAAE,EAAE,KAAK,CAAC,CAAC;gBACvF,CAAC;YACL,CAAC;QACL,CAAC,CAAC,CAAC,CAAC;QAEJ,OAAO,EAAE,CAAC;IACd,CAAC;IAGO,yBAAyB,CAAC,YAAoB,EAAE,UAA0B;QAC9E,OAAO,YAAY,CAAC,OAAO,CAAC,eAAe,EAAE,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,YAA0B;QAElC,IAAI,qBAAqB,GAAiB,YAAY,CAAC;QAEvD,IAAI,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC;YACpD,qBAAqB,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC;gBACvC,KAAK,EAAE;oBACH,EAAE,EAAE,YAAY,CAAC,EAAE;iBACtB;gBACD,SAAS,EAAE;oBACP,IAAI,EAAE,IAAI;oBACV,aAAa,EAAE,IAAI;iBACtB;aACJ,CAAC,CAAC;QACP,CAAC;QAED,OAAO;YACH,EAAE,EAAE,qBAAqB,CAAC,EAAE;YAC5B,IAAI,EAAE,qBAAqB,CAAC,IAAI;YAChC,WAAW,EAAE,qBAAqB,CAAC,WAAW;YAC9C,MAAM,EAAE,qBAAqB,CAAC,IAAI,CAAC,EAAE;YACrC,WAAW,EAAE,qBAAqB,CAAC,IAAI,CAAC,IAAI;YAC5C,eAAe,EAAE,qBAAqB,CAAC,aAAa,CAAC,EAAE;YACvD,oBAAoB,EAAE,qBAAqB,CAAC,aAAa,CAAC,YAAY;YACtE,kBAAkB,EAAE,qBAAqB,CAAC,kBAAkB;SAC/D,CAAC;IACN,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,SAAgC;QAEhD,MAAM,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,mCAAY,CAAC,CAAC;QACnE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;YACpB,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC;gBACtC,KAAK,EAAE;oBACH,EAAE,EAAE,SAAS,CAAC,MAAM;iBACvB;aACJ,CAAC,CAAC;YACH,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;QAC7B,CAAC;QAED,IAAI,SAAS,CAAC,WAAW,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC;gBACtC,KAAK,EAAE;oBACH,IAAI,EAAE,SAAS,CAAC,WAAW;iBAC9B;aACJ,CAAC,CAAC;YACH,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;QAC7B,CAAC;QAGD,MAAM,uBAAuB,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,qCAAa,CAAC,CAAC;QAC7E,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE,CAAC;YAC7B,MAAM,aAAa,GAAG,MAAM,uBAAuB,CAAC,OAAO,CAAC;gBACxD,KAAK,EAAE;oBACH,EAAE,EAAE,SAAS,CAAC,eAAe;iBAChC;aACJ,CAAC,CAAC;YACH,SAAS,CAAC,eAAe,CAAC,GAAG,aAAa,CAAC;QAC/C,CAAC;QACD,IAAI,SAAS,CAAC,oBAAoB,EAAE,CAAC;YACjC,MAAM,aAAa,GAAG,MAAM,uBAAuB,CAAC,OAAO,CAAC;gBACxD,KAAK,EAAE;oBACH,YAAY,EAAE,SAAS,CAAC,oBAAoB;iBAC/C;aACJ,CAAC,CAAC;YACH,SAAS,CAAC,eAAe,CAAC,GAAG,aAAa,CAAC;QAC/C,CAAC;QAGD,MAAM,oBAAoB,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC;YAC5C,KAAK,EAAE;gBACH,IAAI,EAAE,SAAS,CAAC,IAAI;aACvB;SACJ,CAAC,CAAC;QAEH,IAAI,oBAAoB,EAAE,CAAC;YACvB,MAAM,mBAAmB,GAAG,IAAI,CAAC,KAAK,CAAC,oBAAoB,EAAE,SAAS,CAAC,CAAC;YACxE,OAAO,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAC1C,CAAC;aACI,CAAC;YACF,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAC5C,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACnC,CAAC;IACL,CAAC;CAEJ,CAAA;AArIY,wDAAsB;iCAAtB,sBAAsB;IADlC,IAAA,mBAAU,GAAE;qCAIe,oBAAU;QACE,8BAAa;QACT,uCAAiB;GALhD,sBAAsB,CAqIlC","sourcesContent":["import { Injectable, Logger } from '@nestjs/common';\nimport { CreateSecurityRuleDto } from 'src/dtos/create-security-rule.dto';\nimport { SecurityRuleConfig } from 'src/dtos/security-rule-config.dto';\nimport { UpdateSecurityRuleDto } from 'src/dtos/update-security-rule.dto';\nimport { CommonEntity } from 'src/entities/common.entity';\nimport { ModelMetadata } from 'src/entities/model-metadata.entity';\nimport { RoleMetadata } from 'src/entities/role-metadata.entity';\nimport { SecurityRule } from 'src/entities/security-rule.entity';\nimport { SolidRegistry } from 'src/helpers/solid-registry';\nimport { ActiveUserData } from 'src/interfaces/active-user-data.interface';\nimport { CrudHelperService, FilterCombinator } from 'src/services/crud-helper.service';\nimport { Brackets, DataSource, Repository, SelectQueryBuilder } from 'typeorm';\n\n@Injectable()\nexport class SecurityRuleRepository extends Repository<SecurityRule> {\n private readonly logger = new Logger(SecurityRuleRepository.name);\n constructor(\n private dataSource: DataSource,\n private readonly solidRegistry: SolidRegistry,\n private readonly crudHelperService: CrudHelperService,\n ) {\n super(SecurityRule, dataSource.createEntityManager());\n }\n\n applySecurityRules<T extends CommonEntity>(qb: SelectQueryBuilder<T>, modelSingularName: string, activeUser: ActiveUserData, securityRuleAlias: string = qb.alias): SelectQueryBuilder<T> {\n // Fetch the security rules for the model and roles\n const securityRules = this.solidRegistry.getSecurityRules(modelSingularName, activeUser.roles);\n\n // If no security rules, return the original query builder\n if (!securityRules.length) {\n return qb;\n }\n\n // Apply each security rule to the query builder. The rules are combined with OR logic at the top level.\n qb.andWhere(new Brackets((outerQb) => {\n for (const rule of securityRules) {\n try {\n const parsedRule = JSON.parse(\n this.resolveSecurityRuleConfig(rule.securityRuleConfig, activeUser)\n ) as SecurityRuleConfig;\n\n if (parsedRule && parsedRule.filters) {\n outerQb.orWhere( // combine each rule-group with OR at the outer level\n new Brackets((innerQb) => {\n this.crudHelperService.applyFilters(innerQb, parsedRule.filters, securityRuleAlias, qb); // AND within a rule\n })\n );\n }\n } catch (error) {\n this.logger.warn(`Error parsing security rule: ${rule.securityRuleConfig}`, error);\n }\n }\n }));\n\n return qb;\n }\n\n\n private resolveSecurityRuleConfig(configString: string, activeUser: ActiveUserData) {\n return configString.replace('$activeUserId', activeUser.sub.toString());\n }\n\n async toDto(securityRule: SecurityRule): Promise<UpdateSecurityRuleDto> {\n // load the role and model relations for the security rule\n let populatedSecurityRule: SecurityRule = securityRule;\n // If the security rule does not have the role and model relations loaded, load them\n if (!securityRule.role || !securityRule.modelMetadata) {\n populatedSecurityRule = await this.findOne({\n where: {\n id: securityRule.id,\n },\n relations: {\n role: true,\n modelMetadata: true,\n },\n });\n }\n\n return {\n id: populatedSecurityRule.id,\n name: populatedSecurityRule.name,\n description: populatedSecurityRule.description,\n roleId: populatedSecurityRule.role.id,\n roleUserKey: populatedSecurityRule.role.name,\n modelMetadataId: populatedSecurityRule.modelMetadata.id,\n modelMetadataUserKey: populatedSecurityRule.modelMetadata.singularName,\n securityRuleConfig: populatedSecurityRule.securityRuleConfig,\n };\n }\n\n async upsertWithDto(createDto: CreateSecurityRuleDto) {\n // Populate the role from roleId or roleUserKey\n const roleRepository = this.dataSource.getRepository(RoleMetadata);\n if (!createDto.roleId) {\n const role = await roleRepository.findOne({\n where: {\n id: createDto.roleId,\n },\n });\n createDto['role'] = role;\n }\n\n if (createDto.roleUserKey) {\n const role = await roleRepository.findOne({\n where: {\n name: createDto.roleUserKey,\n },\n });\n createDto['role'] = role;\n }\n\n // Populate the model from modelMetadataId or modelMetadataUserKey\n const modelMetadataRepository = this.dataSource.getRepository(ModelMetadata);\n if (!createDto.modelMetadataId) {\n const modelMetadata = await modelMetadataRepository.findOne({\n where: {\n id: createDto.modelMetadataId,\n },\n });\n createDto['modelMetadata'] = modelMetadata;\n }\n if (createDto.modelMetadataUserKey) {\n const modelMetadata = await modelMetadataRepository.findOne({\n where: {\n singularName: createDto.modelMetadataUserKey,\n },\n });\n createDto['modelMetadata'] = modelMetadata;\n }\n\n // First check if module already exists using name\n const existingSecurityRule = await this.findOne({\n where: {\n name: createDto.name,\n },\n });\n\n if (existingSecurityRule) {\n const updatedSecurityRule = this.merge(existingSecurityRule, createDto);\n return this.save(updatedSecurityRule);\n }\n else {\n const securityRule = this.create(createDto);\n return this.save(securityRule);\n }\n }\n\n}"]}
1
+ {"version":3,"file":"security-rule.repository.js","sourceRoot":"","sources":["../../src/repository/security-rule.repository.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, Logger } from '@nestjs/common';\nimport { CreateSecurityRuleDto } from 'src/dtos/create-security-rule.dto';\nimport { SecurityRuleConfig } from 'src/dtos/security-rule-config.dto';\nimport { UpdateSecurityRuleDto } from 'src/dtos/update-security-rule.dto';\nimport { CommonEntity } from 'src/entities/common.entity';\nimport { ModelMetadata } from 'src/entities/model-metadata.entity';\nimport { RoleMetadata } from 'src/entities/role-metadata.entity';\nimport { SecurityRule } from 'src/entities/security-rule.entity';\nimport { SolidRegistry } from 'src/helpers/solid-registry';\nimport { ActiveUserData } from 'src/interfaces/active-user-data.interface';\nimport { CrudHelperService, FilterCombinator } from 'src/services/crud-helper.service';\nimport { Brackets, DataSource, Repository, SelectQueryBuilder } from 'typeorm';\n\n@Injectable()\nexport class SecurityRuleRepository extends Repository<SecurityRule> {\n private readonly logger = new Logger(SecurityRuleRepository.name);\n constructor(\n private dataSource: DataSource,\n private readonly solidRegistry: SolidRegistry,\n private readonly crudHelperService: CrudHelperService,\n ) {\n super(SecurityRule, dataSource.createEntityManager());\n }\n\n applySecurityRules<T extends CommonEntity>(qb: SelectQueryBuilder<T>, modelSingularName: string, activeUser: ActiveUserData, securityRuleAlias: string = qb.alias): SelectQueryBuilder<T> {\n // Fetch the security rules for the model and roles\n const securityRules = this.solidRegistry.getSecurityRules(modelSingularName, activeUser.roles);\n\n // If no security rules, return the original query builder\n if (!securityRules.length) {\n return qb;\n }\n\n // Apply each security rule to the query builder. The rules are combined with OR logic at the top level.\n qb.andWhere(new Brackets((outerQb) => {\n for (const rule of securityRules) {\n try {\n const parsedRule = JSON.parse(\n this.resolveSecurityRuleConfig(rule.securityRuleConfig, activeUser)\n ) as SecurityRuleConfig;\n\n if (parsedRule && parsedRule.filters) {\n outerQb.orWhere( // combine each rule-group with OR at the outer level\n new Brackets((innerQb) => {\n this.crudHelperService.applyFilters(innerQb, parsedRule.filters, securityRuleAlias, qb); // AND within a rule\n })\n );\n }\n } catch (error) {\n this.logger.warn(`Error parsing security rule: ${rule.securityRuleConfig}`, error);\n }\n }\n }));\n\n return qb;\n }\n\n\n private resolveSecurityRuleConfig(configString: string, activeUser: ActiveUserData) {\n return configString.replace('$activeUserId', activeUser.sub.toString());\n }\n\n async toDto(securityRule: SecurityRule): Promise<UpdateSecurityRuleDto> {\n // load the role and model relations for the security rule\n let populatedSecurityRule: SecurityRule = securityRule;\n // If the security rule does not have the role and model relations loaded, load them\n if (!securityRule.role || !securityRule.modelMetadata) {\n populatedSecurityRule = await this.findOne({\n where: {\n id: securityRule.id,\n },\n relations: {\n role: true,\n modelMetadata: true,\n },\n });\n }\n\n return {\n id: populatedSecurityRule.id,\n name: populatedSecurityRule.name,\n description: populatedSecurityRule.description,\n roleId: populatedSecurityRule.role.id,\n roleUserKey: populatedSecurityRule.role.name,\n modelMetadataId: populatedSecurityRule.modelMetadata.id,\n modelMetadataUserKey: populatedSecurityRule.modelMetadata.singularName,\n securityRuleConfig: populatedSecurityRule.securityRuleConfig,\n };\n }\n\n async upsertWithDto(createDto: CreateSecurityRuleDto) {\n // Populate the role from roleId or roleUserKey\n const roleRepository = this.dataSource.getRepository(RoleMetadata);\n if (createDto.roleId) {\n const role = await roleRepository.findOne({\n where: {\n id: createDto.roleId,\n },\n });\n createDto['role'] = role;\n }\n\n if (createDto.roleUserKey) {\n const role = await roleRepository.findOne({\n where: {\n name: createDto.roleUserKey,\n },\n });\n createDto['role'] = role;\n }\n\n // Populate the model from modelMetadataId or modelMetadataUserKey\n const modelMetadataRepository = this.dataSource.getRepository(ModelMetadata);\n if (createDto.modelMetadataId) {\n const modelMetadata = await modelMetadataRepository.findOne({\n where: {\n id: createDto.modelMetadataId,\n },\n });\n createDto['modelMetadata'] = modelMetadata;\n }\n if (createDto.modelMetadataUserKey) {\n const modelMetadata = await modelMetadataRepository.findOne({\n where: {\n singularName: createDto.modelMetadataUserKey,\n },\n });\n createDto['modelMetadata'] = modelMetadata;\n }\n\n // First check if module already exists using name\n const existingSecurityRule = await this.findOne({\n where: {\n name: createDto.name,\n },\n });\n\n if (existingSecurityRule) {\n const updatedSecurityRule = this.merge(existingSecurityRule, createDto);\n return this.save(updatedSecurityRule);\n }\n else {\n const securityRule = this.create(createDto);\n return this.save(securityRule);\n }\n }\n\n}"]}
@@ -3058,8 +3058,8 @@
3058
3058
  "ormType": "varchar",
3059
3059
  "length": 128,
3060
3060
  "required": true,
3061
- "unique": true,
3062
- "index": true,
3061
+ "unique": false,
3062
+ "index": false,
3063
3063
  "private": false,
3064
3064
  "encrypt": false,
3065
3065
  "isSystem": true
@@ -604,10 +604,10 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
604
604
  if (!user) {
605
605
  isValidUser = false;
606
606
  }
607
- if (!user.active) {
607
+ if (isValidUser && !user?.active) {
608
608
  isValidUser = false;
609
609
  }
610
- if (user.lastLoginProvider !== 'local') {
610
+ if (isValidUser && user?.lastLoginProvider !== 'local') {
611
611
  isValidUser = false;
612
612
  }
613
613
  if (isValidUser) {
@@ -624,7 +624,7 @@ let AuthenticationService = AuthenticationService_1 = class AuthenticationServic
624
624
  errorCode: '',
625
625
  data: {
626
626
  user: {
627
- email: user.email,
627
+ email: user?.email,
628
628
  },
629
629
  }
630
630
  };
@@ -1 +1 @@
1
- {"version":3,"file":"authentication.service.js","sourceRoot":"","sources":["../../src/services/authentication.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { HttpService } from '@nestjs/axios';\nimport {\n BadRequestException,\n ConflictException,\n Inject,\n Injectable,\n InternalServerErrorException,\n Logger,\n NotFoundException,\n UnauthorizedException,\n} from '@nestjs/common';\nimport { ConfigType } from '@nestjs/config';\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport { JwtService } from '@nestjs/jwt';\nimport { InjectDataSource, InjectRepository } from '@nestjs/typeorm';\nimport { isEmpty, isNotEmpty } from 'class-validator';\nimport { randomInt, randomUUID } from 'crypto';\nimport { SMTPEMailService } from 'src/services/mail/smtp-email.service';\nimport { Msg91OTPService } from 'src/services/sms/Msg91OTPService';\nimport { DataSource, Repository } from 'typeorm';\nimport { iamConfig, jwtConfig } from '../config/iam.config';\nimport { ChangePasswordDto } from \"../dtos/change-password.dto\";\nimport { ConfirmForgotPasswordDto } from '../dtos/confirm-forgot-password.dto';\nimport { InitiateForgotPasswordDto } from '../dtos/initiate-forgot-password.dto';\nimport { OTPConfirmOTPDto } from '../dtos/otp-confirm-otp.dto';\nimport { OTPSignInDto } from '../dtos/otp-sign-in.dto';\nimport { OTPSignUpDto } from '../dtos/otp-sign-up.dto';\nimport { RefreshTokenDto } from '../dtos/refresh-token.dto';\nimport { SignInDto } from '../dtos/sign-in.dto';\nimport { SignUpDto } from '../dtos/sign-up.dto';\nimport { UserPasswordHistory } from '../entities/user-password-history.entity';\nimport { User } from '../entities/user.entity';\nimport { ActiveUserData } from '../interfaces/active-user-data.interface';\nimport { HashingService } from './hashing.service';\nimport { InvalidatedRefreshTokenError, RefreshTokenIdsStorageService } from './refresh-token-ids-storage.service';\nimport { UserService } from './user.service';\nimport { EventDetails, EventType, IMail } from \"../interfaces\";\nimport {\n ForgotPasswordSendVerificationTokenOn,\n RegistrationValidationSource,\n TransactionalRegistrationValidationSource\n} from \"../constants\";\nimport { SettingService } from './setting.service';\nimport { CreateUserDto } from 'src/dtos/create-user.dto';\nimport { RoleMetadataService } from './role-metadata.service';\nimport commonConfig from 'src/config/common.config';\nimport { UserActivityHistoryService } from './user-activity-history.service';\nimport { RequestContextService } from './request-context.service';\nimport { ERROR_MESSAGES } from 'src/constants/error-messages';\nimport { SUCCESS_MESSAGES } from 'src/constants/success-messages';\nimport { MailFactory } from 'src/factories/mail.factory';\nimport { v4 as uuidv4 } from 'uuid';\n\nenum LoginProvider {\n LOCAL = 'local',\n GOOGLE = 'google',\n OTP = 'otp',\n}\n\ninterface otp {\n token: string;\n expiresAt: Date;\n}\n\n@Injectable()\nexport class AuthenticationService {\n private readonly logger = new Logger(AuthenticationService.name);\n // private readonly mailService: IMail;\n constructor(\n private readonly userService: UserService,\n @InjectRepository(User) private readonly userRepository: Repository<User>,\n @InjectRepository(UserPasswordHistory) private readonly userPasswordHistoryRepository: Repository<UserPasswordHistory>,\n private readonly hashingService: HashingService,\n private readonly jwtService: JwtService,\n @Inject(jwtConfig.KEY)\n private readonly jwtConfiguration: ConfigType<typeof jwtConfig>,\n @Inject(iamConfig.KEY)\n private readonly iamConfiguration: ConfigType<typeof iamConfig>,\n private readonly refreshTokenIdsStorage: RefreshTokenIdsStorageService,\n private readonly httpService: HttpService,\n // private readonly mailService: SMTPEMailService,\n private readonly mailServiceFactory: MailFactory,\n private readonly smsService: Msg91OTPService,\n private readonly eventEmitter: EventEmitter2,\n private readonly settingService: SettingService,\n private readonly roleMetadataService: RoleMetadataService,\n @Inject(commonConfig.KEY)\n private readonly commonConfiguration: ConfigType<typeof commonConfig>,\n private readonly userActivityHistoryService: UserActivityHistoryService,\n private readonly requestContextService: RequestContextService,\n @InjectDataSource()\n private readonly dataSource: DataSource,\n ) {\n // this.mailService = this.mailServiceFactory.getMailService();\n }\n\n private async getConfig(key: string): Promise<any> {\n return this.settingService.getConfigValue(key);\n }\n\n private async getCompanyLogo(): Promise<string> {\n return await this.settingService.getConfigValue('companylogo');\n }\n\n async resolveUser(username: string, email: string) {\n return await this.userRepository.findOne({\n where: [\n { username: username },\n { email: email },\n ],\n relations: {\n roles: true\n }\n });\n }\n\n async resolveUserByVerificationToken(token: string) {\n return await this.userRepository.findOne({\n where: { verificationTokenOnForgotPassword: token },\n relations: { roles: true }\n });\n }\n\n async validateUser(signInDto: SignInDto) {\n\n const user = await this.resolveUser(signInDto.username, signInDto.email);\n\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n }\n if (!user.active) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_ACTIVE);\n }\n const isEqual = await this.hashingService.compare(\n signInDto.password,\n user.password,\n );\n if (!isEqual) {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n }\n\n return user;\n }\n\n async signUp(signUpDto: SignUpDto, activeUser: ActiveUserData = null): Promise<User> {\n // If public registrations are disabled and no activeUser is present when invoking signUp then we throw an exception.\n if (!(await this.settingService.getConfigValue('allowPublicRegistration')) && !activeUser) {\n throw new BadRequestException(ERROR_MESSAGES.PUBLIC_REGISTRATION_DISABLED);\n }\n\n try {\n const onForcePasswordChange = await this.getConfig('forceChangePasswordOnFirstLogin');\n var { user, pwd, autoGeneratedPwd } = await this.populateForSignup(new User(), signUpDto, this.iamConfiguration.activateUserOnRegistration, onForcePasswordChange);\n const savedUser = await this.userRepository.save(user);\n // Also assign a default role to the newly created user. \n const userRoles = signUpDto.roles ?? [];\n if (this.iamConfiguration.defaultRole) {\n userRoles.push(this.iamConfiguration.defaultRole);\n }\n await this.handlePostSignup(savedUser, userRoles, pwd, autoGeneratedPwd);\n\n // TODO: make provision to trigger a welcome email also.\n\n return savedUser;\n } catch (err) {\n const pgUniqueViolationErrorCode = '23505';\n if (err.code === pgUniqueViolationErrorCode) {\n throw new ConflictException(ERROR_MESSAGES.USER_ALREADY_EXISTS);\n }\n throw err;\n }\n }\n\n async signupForExtensionUser<T extends User, U extends CreateUserDto>(signUpDto: SignUpDto, extensionUserDto: U, extensionUserRepo: Repository<T>): Promise<T> {\n try {\n const onForcePasswordChange = await this.getConfig('forceChangePasswordOnFirstLogin');\n // Merge the extended signUpDto attributes into the user entity \n //@ts-ignore \n const extensionUser = extensionUserRepo.merge(extensionUserRepo.create() as T, extensionUserDto);\n var { user, pwd, autoGeneratedPwd } = await this.populateForSignup<T>(extensionUser, signUpDto, true, onForcePasswordChange);\n const savedUser = await extensionUserRepo.save(user);\n\n await this.handlePostSignup(savedUser, signUpDto.roles, pwd, autoGeneratedPwd);\n\n return savedUser;\n }\n catch (err) {\n const pgUniqueViolationErrorCode = '23505';\n if (err.code === pgUniqueViolationErrorCode) {\n throw new ConflictException(parseUniqueConstraintError(err.detail || ERROR_MESSAGES.UNIQUE_CONSTRAINT_VIOLATION));\n }\n throw err;\n }\n }\n\n\n private async populateForSignup<T extends User>(user: T, signUpDto: SignUpDto, isUserActive: boolean = true, onForcePasswordChange?: boolean) {\n // const user = new User();\n\n if (signUpDto.roles && signUpDto.roles.length > 0) {\n for (let i = 0; i < signUpDto.roles.length; i++) {\n const roleName = signUpDto.roles[i];\n await this.roleMetadataService.findRoleByName(roleName);\n }\n }\n user.username = signUpDto.username;\n user.email = signUpDto.email;\n user.fullName = signUpDto.fullName;\n user.forcePasswordChange = onForcePasswordChange;\n if (signUpDto.mobile) {\n user.mobile = signUpDto.mobile;\n }\n this.logger.debug(\"user\", user);\n // If password has been specified by the user, then we simply create & activate the user based on the configuration parameter \"activateUserOnRegistration\".\n let pwd = '';\n let autoGeneratedPwd = '';\n if (signUpDto.password) {\n pwd = await this.hashingService.hash(signUpDto.password);\n }\n else {\n // TODO: If password is not specified then auto-generate a random password, trigger this password over an email to the user.\n // TODO: Also track if the user has to force reset / change their password, and then activate the user. \n autoGeneratedPwd = this.generatePassword();\n pwd = await this.hashingService.hash(autoGeneratedPwd);\n user.forcePasswordChange = true;\n }\n user.password = pwd;\n // user.active = this.iamConfiguration.activateUserOnRegistration;\n user.active = isUserActive;\n return { user, pwd, autoGeneratedPwd };\n }\n\n\n private async handlePostSignup(user: User, roles: string[] = [], pwd: string, autoGeneratedPwd: string) {\n await this.userService.initializeRolesForNewUser(roles, user);\n // Tanay: Adding user password to history table\n const userPasswordHistory = new UserPasswordHistory();\n userPasswordHistory.passwordHash = pwd;\n userPasswordHistory.user = user;\n await this.userPasswordHistoryRepository.save(userPasswordHistory);\n\n // if forcePasswordChange is true, then we trigger an email to the user to change the password, this needs to be done using a queue. \n // Create a new method like notifyUserOnForcePasswordChange, create a new email template we can call it on-force-password-change this template to include the random password\n if (user.forcePasswordChange && autoGeneratedPwd) {\n this.notifyUserOnForcePasswordChange(user, autoGeneratedPwd);\n }\n }\n\n\n generatePassword(length: number = 8): string {\n const upperCase = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n const lowerCase = \"abcdefghijklmnopqrstuvwxyz\";\n const numbers = \"0123456789\";\n const specialChars = \"@$#\";\n const allChars = upperCase + lowerCase + numbers + specialChars;\n\n let password = \"\";\n\n for (let i = 0; i < length; i++) {\n const randomIndex = Math.floor(Math.random() * allChars.length);\n password += allChars[randomIndex];\n }\n\n return password;\n }\n\n private async notifyUserOnForcePasswordChange(user: User, autoGeneratedPwd: string) {\n const companyLogo = await this.getCompanyLogo();\n const mailService = this.mailServiceFactory.getMailService();\n mailService.sendEmailUsingTemplate(\n user.email,\n 'on-force-password-change',\n {\n solidAppName: process.env.SOLID_APP_NAME,\n solidAppWebsiteUrl: process.env.SOLID_APP_WEBSITE_URL,\n frontendLoginPageUrl: process.env.IAM_FRONTEND_APP_LOGIN_PAGE_URL,\n email: user.email,\n fullName: user.fullName,\n userName: user.username,\n password: autoGeneratedPwd,\n companyLogoUrl: companyLogo\n },\n this.commonConfiguration.shouldQueueEmails,\n null,\n null,\n 'user',\n user.id\n );\n\n }\n\n async otpInitiateRegistration(signUpDto: OTPSignUpDto) {\n try {\n if (!this.isPasswordlessRegistrationEnabled()) {\n throw new BadRequestException(ERROR_MESSAGES.PASSWORDLESS_REGISTRATION_DISABLED);\n }\n // Validate if either mobile or email is present.\n if (isEmpty(signUpDto.mobile) && isEmpty(signUpDto.email)) {\n throw new BadRequestException(ERROR_MESSAGES.REGISTRATION_REQUIRES_CONTACT);\n }\n if (signUpDto.validationSources.includes(TransactionalRegistrationValidationSource.EMAIL) && isEmpty(signUpDto.email)) {\n throw new BadRequestException(ERROR_MESSAGES.EMAIL_REQUIRED_FOR_VALIDATION);\n }\n if (signUpDto.validationSources.includes(TransactionalRegistrationValidationSource.MOBILE) && isEmpty(signUpDto.mobile)) {\n throw new BadRequestException(ERROR_MESSAGES.MOBILE_REQUIRED_FOR_VALIDATION);\n }\n\n // Validate if user already exists.\n const existingUser = await this.userRepository.findOne({ //TODO Perhaps we should use the user service instead of the repository directly.\n where: [\n { email: signUpDto.email, },\n { mobile: signUpDto.mobile, },\n { username: signUpDto.username, }\n ]\n });\n if (isNotEmpty(existingUser) && existingUser.active) {\n throw new ConflictException(ERROR_MESSAGES.USER_ALREADY_EXISTS);\n }\n const finalRegistrationVerificationSources = this.calculateVerificationSources(this.iamConfiguration.passwordlessRegistrationValidateWhat, signUpDto);\n let user = existingUser\n if (isEmpty(user)) {\n user = this.createUser(signUpDto);\n this.populateVerificationTokens(finalRegistrationVerificationSources, user);\n await this.userRepository.save(user);\n await this.userService.addRoleToUser(user.username, await this.settingService.getConfigValue('defaultRole'));\n }\n else {\n this.populateVerificationTokens(finalRegistrationVerificationSources, user);\n await this.userRepository.save(user);\n }\n\n // Send OTP to the user through email or SMS, depending on the configuration.\n this.notifyUserOnOtpInitiateRegistration(user, finalRegistrationVerificationSources);\n return { message: SUCCESS_MESSAGES.OTP_SENT_SUCCESS_REGISTRATION }\n } catch (err) {\n const pgUniqueViolationErrorCode = '23505';\n if (err.code === pgUniqueViolationErrorCode) {\n throw new ConflictException(ERROR_MESSAGES.USER_ALREADY_EXISTS);\n }\n throw err;\n }\n }\n\n // Create a new user entity.\n private createUser(signUpDto: OTPSignUpDto) {\n const user = new User();\n user.username = signUpDto.username;\n user.email = signUpDto.email;\n user.mobile = signUpDto.mobile;\n user.customPayload = signUpDto.customPayload;\n user.lastLoginProvider = LoginProvider.OTP;\n return user;\n }\n\n private calculateVerificationSources(configuredRegistrationValidationSources: string[], signUpDto: OTPSignUpDto): string[] {\n const finalRegistrationValidationSources = configuredRegistrationValidationSources.filter((source) => source !== RegistrationValidationSource.TRANSACTIONAL);\n if (configuredRegistrationValidationSources.includes(RegistrationValidationSource.TRANSACTIONAL)) {\n finalRegistrationValidationSources.push(...signUpDto.validationSources); // Add the validation sources provided by the user.\n }\n return finalRegistrationValidationSources;\n }\n\n // Generate the validation tokens for the user i.e (system configured + user provided)\n private populateVerificationTokens(finalRegistrationValidationSources: string[], user: User) {\n if (finalRegistrationValidationSources.length === 0) {\n throw new BadRequestException(ERROR_MESSAGES.VALIDATION_SOURCE_REQUIRED);\n }\n if (finalRegistrationValidationSources.includes(TransactionalRegistrationValidationSource.EMAIL)) {\n const { token, expiresAt } = this.otp();\n user.emailVerificationTokenOnRegistration = token;\n user.emailVerificationTokenOnRegistrationExpiresAt = expiresAt;\n if (this.iamConfiguration.autoLoginUserOnRegistration) {\n user.emailVerificationTokenOnLogin = token;\n user.emailVerificationTokenOnLoginExpiresAt = expiresAt;\n }\n }\n if (finalRegistrationValidationSources.includes(TransactionalRegistrationValidationSource.MOBILE)) {\n const { token, expiresAt } = this.otp();\n user.mobileVerificationTokenOnRegistration = token;\n user.mobileVerificationTokenOnRegistrationExpiresAt = expiresAt;\n if (this.iamConfiguration.autoLoginUserOnRegistration) {\n user.mobileVerificationTokenOnLogin = token;\n user.mobileVerificationTokenOnLoginExpiresAt = expiresAt;\n }\n }\n }\n\n private async notifyUserOnOtpInitiateRegistration(user: User, registrationValidationSources: string[]) {\n const companyLogo = await this.getCompanyLogo();\n if (this.iamConfiguration.dummyOtp)\n return; // Do nothing if dummy otp is configured.\n if (registrationValidationSources.includes(RegistrationValidationSource.EMAIL)) {\n const mailService = this.mailServiceFactory.getMailService();\n mailService.sendEmailUsingTemplate(\n user.email,\n 'otp-on-register',\n {\n solidAppName: process.env.SOLID_APP_NAME,\n solidAppWebsiteUrl: process.env.SOLID_APP_WEBSITE_URL,\n firstName: user.username,\n fullName: user.fullName ? user.fullName : user.username,\n emailVerificationTokenOnRegistration: user.emailVerificationTokenOnRegistration,\n companyLogoUrl: companyLogo\n },\n this.commonConfiguration.shouldQueueEmails,\n null,\n null,\n 'user',\n user.id\n );\n }\n if (registrationValidationSources.includes(RegistrationValidationSource.MOBILE)) {\n this.smsService.sendSMSUsingTemplate(\n user.mobile,\n 'otp-on-register',\n {\n solidAppName: process.env.SOLID_APP_NAME,\n otp: user.mobileVerificationTokenOnRegistration,\n mobileVerificationTokenOnRegistration: user.mobileVerificationTokenOnRegistration,\n firstName: user.username,\n fullName: user.fullName ? user.fullName : user.username,\n companyLogoUrl: companyLogo\n }\n );\n }\n }\n\n async otpConfirmRegistration(confirmSignUpDto: OTPConfirmOTPDto) {\n if (!this.isPasswordlessRegistrationEnabled()) {\n throw new BadRequestException(ERROR_MESSAGES.PASSWORDLESS_REGISTRATION_DISABLED);\n }\n\n // Based on the identifier, validate by query the user table.\n if (confirmSignUpDto.type === RegistrationValidationSource.EMAIL) {\n const user = await this.userRepository.findOne({\n where: {\n email: confirmSignUpDto.identifier,\n }\n });\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n if (user.emailVerificationTokenOnRegistration !== confirmSignUpDto.otp) {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);\n }\n if (user.emailVerificationTokenOnRegistrationExpiresAt < new Date()) {\n throw new UnauthorizedException(ERROR_MESSAGES.OTP_EXPIRED);\n }\n user.emailVerifiedOnRegistrationAt = new Date();\n user.emailVerificationTokenOnRegistration = null;\n user.emailVerificationTokenOnRegistrationExpiresAt = null;\n user.active = await this.settingService.getConfigValue('activateUserOnRegistration') && this.areRegistrationValidationSourcesVerified(user);\n const savedUser: User = await this.userRepository.save(user);\n this.triggerRegistrationEvent(savedUser);\n return { active: savedUser.active, message: `User registration verified for ${confirmSignUpDto.type}` }\n } else if (confirmSignUpDto.type === RegistrationValidationSource.MOBILE) {\n const user = await this.userRepository.findOne({\n where: {\n mobile: confirmSignUpDto.identifier,\n }\n });\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n if (user.mobileVerificationTokenOnRegistration !== confirmSignUpDto.otp) {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);\n }\n if (user.mobileVerificationTokenOnRegistrationExpiresAt < new Date()) {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);\n }\n user.mobileVerifiedOnRegistrationAt = new Date();\n user.mobileVerificationTokenOnRegistration = null;\n user.mobileVerificationTokenOnRegistrationExpiresAt = null;\n user.active = await this.settingService.getConfigValue('activateUserOnRegistration') && this.areRegistrationValidationSourcesVerified(user);\n const savedUser: User = await this.userRepository.save(user);\n this.triggerRegistrationEvent(savedUser);\n return { active: savedUser.active, message: `User registration verified for ${confirmSignUpDto.type}` }\n }\n throw new BadRequestException(ERROR_MESSAGES.INVALID_VERIFICATION_TYPE);\n }\n\n private triggerRegistrationEvent(savedUser: User) {\n // Trigger events for user registration.\n const event = new EventDetails<User>(EventType.USER_REGISTERED, savedUser);\n this.eventEmitter.emit(EventType.USER_REGISTERED, event);\n }\n\n areRegistrationValidationSourcesVerified(user: User): boolean {\n const registrationValidationSources = this.iamConfiguration.passwordlessRegistrationValidateWhat;\n if (registrationValidationSources.includes(RegistrationValidationSource.EMAIL)) {\n if (!user.emailVerifiedOnRegistrationAt) {\n return false;\n }\n }\n if (registrationValidationSources.includes(RegistrationValidationSource.MOBILE)) {\n if (!user.mobileVerifiedOnRegistrationAt) {\n return false;\n }\n }\n return true;\n }\n\n private otp(): otp {\n const now = new Date();\n now.setMinutes(now.getMinutes() + this.iamConfiguration.otpExpiry);\n return {\n token: this.iamConfiguration.dummyOtp ? this.iamConfiguration.dummyOtp : randomInt(100000, 999999).toString(),\n expiresAt: now,\n };\n }\n\n async signIn(signInDto: SignInDto) {\n const user = await this.validateUser(signInDto);\n\n // TODO: Unset the password etc...\n const tokens = await this.generateTokens(user);\n\n await this.userActivityHistoryService.logEvent('login', user);\n\n return {\n user: {\n email: user.email,\n mobile: user.mobile,\n username: user.username,\n forcePasswordChange: user.forcePasswordChange,\n id: user.id,\n roles: user.roles.map((role, idx, roles) => role.name)\n },\n ...tokens\n }\n }\n\n async otpInitiateLogin(signInDto: OTPSignInDto) {\n if (!this.isPasswordlessRegistrationEnabled()) {\n throw new BadRequestException(ERROR_MESSAGES.PASSWORDLESS_REGISTRATION_DISABLED);\n }\n\n // Validate & generate otp token for the user based on the identifier type.\n if (signInDto.type === RegistrationValidationSource.EMAIL) {\n const user = await this.userRepository.findOne({\n where: {\n email: signInDto.identifier,\n }\n });\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n if (!user.active) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_INACTIVE);\n }\n const { token, expiresAt } = this.otp();\n user.emailVerificationTokenOnLogin = token;\n user.emailVerificationTokenOnLoginExpiresAt = expiresAt;\n await this.userRepository.save(user);\n this.notifyUserOnOtpInititateLogin(user, RegistrationValidationSource.EMAIL);\n } else if (signInDto.type === RegistrationValidationSource.MOBILE) {\n const user = await this.userRepository.findOne({\n where: {\n mobile: signInDto.identifier,\n }\n });\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n\n const { token, expiresAt } = this.otp();\n user.mobileVerificationTokenOnLogin = token;\n user.mobileVerificationTokenOnLoginExpiresAt = expiresAt;\n await this.userRepository.save(user);\n this.notifyUserOnOtpInititateLogin(user, RegistrationValidationSource.MOBILE);\n }\n else {\n throw new BadRequestException(ERROR_MESSAGES.INVALID_VERIFICATION_TYPE);\n }\n return { message: SUCCESS_MESSAGES.OTP_SENT_SUCCESS_LOGIN };\n }\n\n private async notifyUserOnOtpInititateLogin(user: User, loginType: RegistrationValidationSource) {\n const companyLogo = await this.getCompanyLogo();\n\n if (this.iamConfiguration.dummyOtp)\n return; // Do nothing if dummy otp is configured.\n if (loginType === RegistrationValidationSource.EMAIL) {\n const mailService = this.mailServiceFactory.getMailService();\n mailService.sendEmailUsingTemplate(\n user.email,\n 'otp-on-login',\n {\n solidAppName: process.env.SOLID_APP_NAME,\n solidAppWebsiteUrl: process.env.SOLID_APP_WEBSITE_URL,\n firstName: user.username,\n emailVerificationTokenOnLogin: user.emailVerificationTokenOnLogin,\n fullName: user.fullName ? user.fullName : user.username,\n companyLogoUrl: companyLogo\n },\n this.commonConfiguration.shouldQueueEmails,\n null,\n null,\n 'user',\n user.id\n );\n }\n if (loginType === RegistrationValidationSource.MOBILE) {\n this.smsService.sendSMSUsingTemplate(\n user.mobile,\n 'otp-on-login',\n {\n solidAppName: process.env.SOLID_APP_NAME,\n otp: user.mobileVerificationTokenOnLogin,\n mobileVerificationTokenOnLogin: user.mobileVerificationTokenOnLogin,\n firstName: user.username,\n fullName: user.fullName ? user.fullName : user.username,\n companyLogoUrl: companyLogo\n }\n );\n }\n }\n\n async otpConfirmLogin(confirmSignInDto: OTPConfirmOTPDto) {\n if (!this.isPasswordlessRegistrationEnabled()) {\n throw new BadRequestException(ERROR_MESSAGES.PASSWORDLESS_REGISTRATION_DISABLED);\n }\n if (confirmSignInDto.type === RegistrationValidationSource.EMAIL) {\n const user = await this.userRepository.findOne({\n where: {\n email: confirmSignInDto.identifier,\n },\n relations: ['roles']\n });\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n if (!user.active) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_INACTIVE);\n }\n if (user.emailVerificationTokenOnLogin !== confirmSignInDto.otp) {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);\n }\n if (user.emailVerificationTokenOnLoginExpiresAt < new Date()) {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);\n }\n user.emailVerifiedOnLoginAt = new Date();\n user.emailVerificationTokenOnLogin = null;\n user.emailVerificationTokenOnLoginExpiresAt = null;\n await this.userRepository.save(user);\n const { accessToken, refreshToken } = await this.generateTokens(user);\n const { id, username, email, mobile, lastLoginProvider } = user;\n const roles = user.roles.map((role) => role.name);\n return { accessToken, refreshToken, user: { id, username, email, mobile, lastLoginProvider, roles } };\n } else if (confirmSignInDto.type === RegistrationValidationSource.MOBILE) {\n const user = await this.userRepository.findOne({\n where: {\n mobile: confirmSignInDto.identifier,\n },\n relations: ['roles']\n });\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_ACTIVE);\n }\n if (!user.active) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_INACTIVE);\n }\n if (user.mobileVerificationTokenOnLogin !== confirmSignInDto.otp) {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);\n }\n if (user.mobileVerificationTokenOnLoginExpiresAt < new Date()) {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);\n }\n user.mobileVerifiedOnLoginAt = new Date();\n user.mobileVerificationTokenOnLogin = null;\n user.mobileVerificationTokenOnLoginExpiresAt = null;\n await this.userRepository.save(user);\n const { accessToken, refreshToken } = await this.generateTokens(user);\n const { id, username, email, mobile, lastLoginProvider } = user;\n const roles = user.roles.map((role) => role.name);\n return { accessToken, refreshToken, user: { id, username, email, mobile, lastLoginProvider, roles } };\n\n }\n throw new BadRequestException(ERROR_MESSAGES.INVALID_VERIFICATION_TYPE);\n }\n\n async changePassword(changePasswordDto: ChangePasswordDto, activeUser: ActiveUserData) {\n const user = await this.userRepository.findOne({\n where: { id: changePasswordDto.id }\n });\n if (!user) {\n throw new NotFoundException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n\n if (!user.active) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_INACTIVE);\n }\n\n // 2. Validate if user has used a provider which is \"local\", only then it makes sense for us to initiate the forgot password routine.\n if (user.lastLoginProvider !== 'local') {\n throw new BadRequestException(ERROR_MESSAGES.NON_LOCAL_PROVIDER);\n }\n\n // Check if ID's match\n if (!(user.id === activeUser.sub)) {\n throw new BadRequestException(ERROR_MESSAGES.USER_ID_MISMATCH);\n }\n\n // Check if username's match\n if (!(user.username === activeUser.username)) {\n throw new BadRequestException(ERROR_MESSAGES.USERNAME_MISMATCH);\n }\n\n // Check if old password is matching.\n const isEqual = await this.hashingService.compare(\n changePasswordDto.currentPassword,\n user.password,\n );\n if (!isEqual) {\n throw new UnauthorizedException(ERROR_MESSAGES.INCORRECT_CURRENT_PASSWORD);\n }\n\n // Update Password\n const newPwd = await this.hashingService.hash(changePasswordDto.newPassword);\n user.password = changePasswordDto.newPassword;\n\n // Everytime the user changes the password we reset the forcePasswordChange flag back to false. \n user.forcePasswordChange = false;\n\n if (await this.isPasswordDuplicate(user)) {\n throw new BadRequestException(ERROR_MESSAGES.PASSWORD_REUSED);\n }\n await this.deleteOldPasswords(user);\n\n user.password = newPwd;\n const userPasswordHistory = new UserPasswordHistory();\n userPasswordHistory.passwordHash = newPwd;\n userPasswordHistory.user = user;\n\n await this.userRepository.save(user);\n await this.userPasswordHistoryRepository.save(userPasswordHistory);\n\n return true;\n }\n\n // generate uuid token for forgot password\n private generateForgotPasswordToken() {\n const expiryTime = new Date();\n expiryTime.setMinutes(expiryTime.getMinutes() + this.iamConfiguration.forgotPasswordVerificationTokenExpiry);\n\n return {\n token: this.iamConfiguration.dummyOtp\n ? this.iamConfiguration.dummyOtp\n : uuidv4(), // UUID instead of numeric OTP\n expiresAt: expiryTime,\n };\n }\n\n async initiateForgotPassword(initiateForgotPasswordDto: InitiateForgotPasswordDto) {\n // Steps / Algorithm: \n // 1. Identify the user using the specified \"username\", if not found exit.\n // const user = await this.userRepository.findOne({\n // where: { username: initiateForgotPasswordDto.username, }\n // });\n const user = await this.resolveUser(initiateForgotPasswordDto.username, initiateForgotPasswordDto.email);\n\n let isValidUser = true // Instead of throwing exceptions we will simply return success message, this is to avoid user enumeration attacks.\n if (!user) {\n isValidUser = false \n // throw new NotFoundException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n }\n if (!user.active) {\n isValidUser = false\n // throw new UnauthorizedException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n }\n\n // 2. Validate if user has used a provider which is \"local\", only then it makes sense for us to initiate the forgot password routine. \n if (user.lastLoginProvider !== 'local') {\n isValidUser = false\n // throw new BadRequestException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n }\n\n // 3. Generate a 6 digit validation token, we send this token to the user over their email & mobile number (controlled using configuration).\n // 4. Save this validation token in new fields on the user record. \n if (isValidUser) {\n const { token, expiresAt } = this.generateForgotPasswordToken();\n user.verificationTokenOnForgotPassword = token;\n user.verificationTokenOnForgotPasswordExpiresAt = expiresAt;\n await this.userRepository.save(user);\n this.notifyUserOnForgotPassword(user);\n }\n\n // 5. Return. \n return {\n status: 'success',\n message: SUCCESS_MESSAGES.FORGOT_PASSWORD_TOKEN_SENT,\n error: '',\n errorCode: '',\n data: {\n user: {\n email: user.email,\n // mobile: user.mobile,\n // username: user.username,\n },\n }\n }\n }\n\n private async notifyUserOnForgotPassword(user: User) {\n const companyLogo = await this.getCompanyLogo();\n\n const forgotPasswordSendVerificationTokenOn = this.iamConfiguration.forgotPasswordSendVerificationTokenOn;\n\n if (forgotPasswordSendVerificationTokenOn == ForgotPasswordSendVerificationTokenOn.EMAIL) {\n const mailService = this.mailServiceFactory.getMailService();\n mailService.sendEmailUsingTemplate(\n user.email,\n 'forgot-password',\n {\n solidAppName: process.env.SOLID_APP_NAME,\n solidAppWebsiteUrl: process.env.SOLID_APP_WEBSITE_URL,\n firstName: user.username,\n fullName: user.fullName,\n // TODO: Need to prefix this with the page url where the forgot password page will open up.\n passwordResetLink: `${process.env.IAM_FRONTEND_APP_FORGOT_PASSWORD_PAGE_URL}?token=${user.verificationTokenOnForgotPassword}`,\n companyLogoUrl: companyLogo\n },\n this.commonConfiguration.shouldQueueEmails,\n null,\n null,\n 'user',\n user.id\n );\n }\n // Assuming all users do not have mobile as mandatory.\n if (forgotPasswordSendVerificationTokenOn == ForgotPasswordSendVerificationTokenOn.MOBILE && user.mobile) {\n this.smsService.sendSMSUsingTemplate(\n user.mobile,\n 'forgot-password',\n {\n solidAppName: process.env.SOLID_APP_NAME,\n otp: user.verificationTokenOnForgotPassword,\n verificationTokenOnForgotPassword: user.verificationTokenOnForgotPassword,\n firstName: user.username,\n companyLogoUrl: companyLogo\n }\n );\n }\n }\n\n async confirmForgotPassword(confirmForgotPasswordDto: ConfirmForgotPasswordDto) {\n return this.dataSource.transaction(async (m) => {\n // Resolve the user id first (by username/email), but DON'T check the token in JS.\n const user = await this.resolveUserByVerificationToken(confirmForgotPasswordDto.verificationToken);\n if (!user) throw new UnauthorizedException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n if (user.lastLoginProvider !== 'local') throw new UnauthorizedException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n if (!user.active) throw new UnauthorizedException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n\n // 1) Atomically consume the token (only one request can succeed)\n const { affected } = await m\n .createQueryBuilder()\n .update(User)\n .set({\n forgotPasswordConfirmedAt: () => 'NOW()',\n verificationTokenOnForgotPassword: () => 'NULL',\n verificationTokenOnForgotPasswordExpiresAt: () => 'NULL',\n })\n .where('id = :id', { id: user.id })\n .andWhere('verificationTokenOnForgotPassword = :token', { token: confirmForgotPasswordDto.verificationToken })\n .andWhere('verificationTokenOnForgotPasswordExpiresAt > NOW()')\n .execute();\n\n if (affected !== 1) {\n // Token invalid/expired/already used (or a parallel call already consumed it)\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n }\n\n // 2) Now update the password & history (still inside the same transaction)\n const pwdHash = await this.hashingService.hash(confirmForgotPasswordDto.password);\n\n // Avoid ever assigning plaintext:\n // user.password = dto.password <-- remove this line in your original code\n\n // Check reuse with your existing method (ensure it looks at hashes).\n const tempUser = { ...user, password: pwdHash } as User; // if your helper expects it\n if (await this.isPasswordDuplicate(tempUser)) {\n throw new BadRequestException(ERROR_MESSAGES.PASSWORD_REUSED);\n }\n\n await this.deleteOldPasswords(user);\n\n await m.getRepository(User).update({ id: user.id }, { password: pwdHash });\n\n const history = m.getRepository(UserPasswordHistory).create({\n user: { id: user.id } as any,\n passwordHash: pwdHash,\n });\n await m.getRepository(UserPasswordHistory).save(history);\n this.notifyUserOnPasswordChanged(user);\n\n return {\n status: 'success',\n message: SUCCESS_MESSAGES.FORGOT_PASSWORD_CONFIRMED,\n error: '',\n errorCode: '',\n data: {},\n };\n });\n }\n\n private async notifyUserOnPasswordChanged(user: User) {\n const companyLogo = await this.getCompanyLogo();\n\n const forgotPasswordSendVerificationTokenOn = this.iamConfiguration.forgotPasswordSendVerificationTokenOn;\n\n if (forgotPasswordSendVerificationTokenOn == ForgotPasswordSendVerificationTokenOn.EMAIL) {\n const mailService = this.mailServiceFactory.getMailService();\n mailService.sendEmailUsingTemplate(\n user.email,\n 'password-changed',\n {\n solidAppName: process.env.SOLID_APP_NAME,\n solidAppWebsiteUrl: process.env.SOLID_APP_WEBSITE_URL,\n email: user.email,\n firstName: user.username,\n fullName: user.fullName,\n // TODO: Need to prefix this with the page url where the forgot password page will open up.\n passwordResetLink: `${process.env.IAM_FRONTEND_APP_FORGOT_PASSWORD_PAGE_URL}?token=${user.verificationTokenOnForgotPassword}`,\n companyLogoUrl: companyLogo\n },\n this.commonConfiguration.shouldQueueEmails,\n null,\n null,\n 'user',\n user.id\n );\n }\n // Assuming all users do not have mobile as mandatory.\n if (forgotPasswordSendVerificationTokenOn == ForgotPasswordSendVerificationTokenOn.MOBILE && user.mobile) {\n this.smsService.sendSMSUsingTemplate(\n user.mobile,\n 'forgot-password',\n {\n solidAppName: process.env.SOLID_APP_NAME,\n otp: user.verificationTokenOnForgotPassword,\n verificationTokenOnForgotPassword: user.verificationTokenOnForgotPassword,\n firstName: user.username,\n companyLogoUrl: companyLogo\n }\n );\n }\n }\n\n // async confirmForgotPassword(confirmForgotPasswordDto: ConfirmForgotPasswordDto) {\n // // Steps / Algorithm: \n // // 1. Identify the user using the specified \"username\", if not found exit.\n // // const user = await this.userRepository.findOne({\n // // where: { username: confirmForgotPasswordDto.username, }\n // // });\n // const user = await this.resolveUserByVerificationToken(confirmForgotPasswordDto.verificationToken);\n\n // if (!user) {\n // throw new NotFoundException(ERROR_MESSAGES.USER_NOT_FOUND);\n // }\n\n // // 2. Validate if user has used a provider which is \"local\", only then it makes sense for us to initiate the forgot password routine. \n // if (user.lastLoginProvider !== 'local') {\n // throw new BadRequestException(ERROR_MESSAGES.NON_LOCAL_PROVIDER);\n // }\n // if (!user.active) {\n // throw new UnauthorizedException(ERROR_MESSAGES.USER_INACTIVE);\n // }\n\n // // 3. Validate the verification token is proper & update the user record. \n // if (user.verificationTokenOnForgotPassword !== confirmForgotPasswordDto.verificationToken) {\n // throw new UnauthorizedException(ERROR_MESSAGES.INVALID_VERIFICATION_TOKEN);\n // }\n // if (user.verificationTokenOnForgotPasswordExpiresAt < new Date()) {\n // throw new UnauthorizedException(ERROR_MESSAGES.INVALID_VERIFICATION_TOKEN);\n // }\n // user.forgotPasswordConfirmedAt = new Date();\n // user.verificationTokenOnForgotPassword = null;\n // user.verificationTokenOnForgotPasswordExpiresAt = null;\n\n // // 4. Update the users password while encrypting it.\n // const pwd = await this.hashingService.hash(confirmForgotPasswordDto.password);\n // user.password = confirmForgotPasswordDto.password\n\n // if (await this.isPasswordDuplicate(user)) {\n // throw new BadRequestException(ERROR_MESSAGES.PASSWORD_REUSED);\n // }\n // await this.deleteOldPasswords(user);\n\n // user.password = pwd;\n // const userPasswordHistory = new UserPasswordHistory();\n // userPasswordHistory.passwordHash = pwd;\n // userPasswordHistory.user = user;\n\n // await this.userRepository.save(user);\n // //FIXME: Do this check conditionally, basis a configuration parameter i.e if IAM_ALLOW_PREVIOUS_PASSWORDS=false, default true\n // await this.userPasswordHistoryRepository.save(userPasswordHistory);\n\n // return {\n // status: 'success',\n // message: SUCCESS_MESSAGES.FORGOT_PASSWORD_CONFIRMED,\n // error: '',\n // errorCode: '',\n // data: {}\n // }\n // }\n\n //FIXME: Do this check conditionally, basis a configuration parameter i.e if IAM_ALLOW_PREVIOUS_PASSWORDS=true, return immediately without processing, i.e false.\n private async isPasswordDuplicate(user: User) {\n const userPwdHistoryEntityArray = await this.userPasswordHistoryRepository.findBy(\n { user: { id: user.id } }\n )\n let userPwdHistoryArray = [];\n // O(n)\n for (const entity of userPwdHistoryEntityArray) {\n userPwdHistoryArray.push(entity.passwordHash);\n }\n // O(n)\n for (const pwdHash of userPwdHistoryArray) {\n const isEqual = await this.hashingService.compare(user.password, pwdHash);\n if (isEqual) {\n return true;\n }\n }\n return false;\n }\n\n //FIXME: Do this check conditionally, basis a configuration parameter i.e if IAM_ALLOW_PREVIOUS_PASSWORDS=true, return immediately without processing\n private async deleteOldPasswords(user: User) {\n const userPwdHistoryArray = await this.userPasswordHistoryRepository.findBy(\n { user: { id: user.id } }\n )\n const pwdLimit = 2; //FIXME: Should this be moved into the env? IAM_PREVIOUS_PASSWORDS_LIMIT\n\n // TODO: Check what slice() or splice() does.\n //FIXME - Delete passwords which are older than the latest n passwords. n is configurable\n if (userPwdHistoryArray.length >= pwdLimit) {\n const numToDelete = pwdLimit + 1 - userPwdHistoryArray.length;\n for (let i = 0; i < numToDelete; i++) {\n await this.userPasswordHistoryRepository.remove(userPwdHistoryArray[i]);\n }\n }\n }\n\n async generateTokens(user: User) {\n\n const [accessToken, refreshToken] = await Promise.all([\n this.generateAccessToken(user),\n this.generateRefreshToken(user),\n ]);\n\n return {\n accessToken,\n refreshToken,\n };\n }\n\n async generateAccessToken(user: User) {\n\n // const userRoleNames = user.roles.map((role) => role.name).join(';')\n const userRoleNames = user.roles.map((role) => role.name);\n\n const accessToken = await this.signToken<Partial<ActiveUserData>>(\n user.id,\n this.jwtConfiguration.accessTokenTtl,\n { username: user.username, email: user.email, roles: userRoleNames },\n );\n\n return accessToken;\n }\n\n async generateRefreshToken(user: User) {\n const refreshTokenId = randomUUID();\n\n const refreshToken = await this.signToken(user.id, this.jwtConfiguration.refreshTokenTtl, {\n refreshTokenId,\n })\n\n // store the refresh token id in the redis storage.\n await this.refreshTokenIdsStorage.insert(user.id, refreshToken);\n\n return refreshToken;\n }\n\n async refreshTokens(refreshTokenDto: RefreshTokenDto) {\n try {\n const { sub, refreshTokenId } = await this.jwtService.verifyAsync<Pick<ActiveUserData, 'sub'> & { refreshTokenId: string }>(refreshTokenDto.refreshToken, {\n secret: this.jwtConfiguration.secret,\n audience: this.jwtConfiguration.audience,\n issuer: this.jwtConfiguration.issuer,\n });\n // const user = await this.userRepository.findOneByOrFail({ id: sub });\n const user = await this.userRepository.findOne({\n where: {\n id: sub,\n },\n relations: {\n roles: true\n }\n });\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.SESSION_INVALID);\n }\n\n // TODO: Replace the if else condition below with a call to validateAndRotate - Done\n // const isValid = await this.refreshTokenIdsStorage.validate(user.id, refreshTokenId);\n // if (isValid) {\n // // Refresh token rotation.\n // await this.refreshTokenIdsStorage.invalidate(user.id);\n // } else {\n // throw new Error('Refresh token is invalid');\n // }\n\n const currentRefreshToken = await this.refreshTokenIdsStorage.validateAndRotate(user, refreshTokenDto.refreshToken);\n\n await this.userActivityHistoryService.logEvent('tokenRefreshed', user);\n\n return {\n accessToken: await this.generateAccessToken(user),\n refreshToken: currentRefreshToken,\n };\n } catch (err) {\n if (err instanceof InvalidatedRefreshTokenError) {\n // Take action: notify user that his refresh token might have been stolen?\n throw new UnauthorizedException(ERROR_MESSAGES.ACCESS_DENIED);\n }\n\n throw new UnauthorizedException(ERROR_MESSAGES.SESSION_EXPIRED);\n }\n }\n\n private async signToken<T>(userId: number, expiresIn: number, payload?: T) {\n return await this.jwtService.signAsync(\n {\n sub: userId,\n ...payload,\n },\n {\n audience: this.jwtConfiguration.audience,\n issuer: this.jwtConfiguration.issuer,\n secret: this.jwtConfiguration.secret,\n expiresIn,\n },\n );\n }\n\n // PROVIDER SPECIFIC CODE\n async validateUserUsingGoogle(user: User) {\n try {\n // Make API call to Google OAuth service to fetch user profile\n const response = await this.httpService.axiosRef.get(`https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token=${user.googleAccessToken}`);\n const userProfile = response.data;\n\n // Ensure the fetched profile email & provider Id match the ones we have stored in the database earlier. \n if (userProfile.email === user.email && userProfile.id === user.googleId) {\n // TODO: remove the access code both from the database.\n return userProfile;\n } else {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_USER_PROFILE);\n }\n } catch (error) {\n throw new UnauthorizedException(ERROR_MESSAGES.GOOGLE_OAUTH_PROFILE_FETCH_FAILED);\n }\n }\n\n async signInUsingGoogle(accessCode: string) {\n const user = await this.userRepository.findOne({\n where: {\n accessCode: accessCode\n },\n relations: {\n roles: true\n }\n });\n\n // Validate the user against the Google oauth provider. \n // If the below call finishes without raising an exception then we have validated the user properly.\n await this.validateUserUsingGoogle(user);\n\n // finally we simply generate the tokens. \n const tokens = await this.generateTokens(user);\n return {\n user: {\n email: user.email,\n mobile: user.mobile,\n username: user.username,\n // forcePasswordChange: user.forcePasswordChange,\n id: user.id,\n roles: user.roles.map((role, idx, roles) => role.name)\n },\n ...tokens\n }\n\n }\n\n private async isPasswordlessRegistrationEnabled() {\n return this.settingService.getConfigValue('passwordlessRegistration');\n }\n\n //FIXME - Pending implementation\n // async logout() {\n // // const user = this.request.user; //TODO: // Access the user from the execution context\n\n // // Invalidate the refresh token\n // // await this.refreshTokenIdsStorage.invalidate(user.id);\n // }\n async logout() {\n try {\n const activeUser = this.requestContextService.getActiveUser();\n const userId = activeUser?.sub;\n const user = await this.userRepository.findOne({\n where: {\n id: userId,\n }\n })\n // Invalidate refresh token if you store them\n await this.refreshTokenIdsStorage.invalidate(userId); // ← Your existing logic\n\n // Log logout event\n await this.userActivityHistoryService.logEvent('logout', user);\n\n\n return { message: SUCCESS_MESSAGES.LOGOUT_SUCCESS };\n } catch (err) {\n throw err instanceof UnauthorizedException || err instanceof InternalServerErrorException\n ? err\n : new InternalServerErrorException(ERROR_MESSAGES.LOGOUT_FAILED);\n }\n }\n\n\n async activateUser(userId: number) {\n const user = await this.userService.findOne(userId, {});\n if (!user) {\n throw new NotFoundException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n user.active = true;\n await this.userRepository.save(user);\n }\n\n async me(activeUser: ActiveUserData) {\n const user = await this.userRepository.findOne({\n where: {\n id: activeUser.sub,\n },\n relations: {\n roles: true\n }\n });\n const tokens = await this.generateTokens(user);\n\n const response = {\n user: {\n email: user.email,\n mobile: user.mobile,\n username: user.username,\n // forcePasswordChange: user.forcePasswordChange,\n id: user.id,\n roles: user.roles.map((role, idx, roles) => role.name)\n },\n ...tokens\n }\n return response;\n }\n\n}\n\nfunction parseUniqueConstraintError(detail: string): string {\n const match = detail.match(/Key \\(([^)]+)\\)=\\(([^)]+)\\) already exists\\./);\n if (match) {\n const field = match[1];\n const value = match[2];\n const fieldMap: Record<string, string> = {\n username: 'username',\n email: 'email address',\n full_name_user_key: 'full name',\n };\n const friendlyField = fieldMap[field] || field;\n return `A user with ${friendlyField} \"${value}\" already exists.`;\n }\n return detail;\n}\n"]}
1
+ {"version":3,"file":"authentication.service.js","sourceRoot":"","sources":["../../src/services/authentication.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { HttpService } from '@nestjs/axios';\nimport {\n BadRequestException,\n ConflictException,\n Inject,\n Injectable,\n InternalServerErrorException,\n Logger,\n NotFoundException,\n UnauthorizedException,\n} from '@nestjs/common';\nimport { ConfigType } from '@nestjs/config';\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport { JwtService } from '@nestjs/jwt';\nimport { InjectDataSource, InjectRepository } from '@nestjs/typeorm';\nimport { isEmpty, isNotEmpty } from 'class-validator';\nimport { randomInt, randomUUID } from 'crypto';\nimport { SMTPEMailService } from 'src/services/mail/smtp-email.service';\nimport { Msg91OTPService } from 'src/services/sms/Msg91OTPService';\nimport { DataSource, Repository } from 'typeorm';\nimport { iamConfig, jwtConfig } from '../config/iam.config';\nimport { ChangePasswordDto } from \"../dtos/change-password.dto\";\nimport { ConfirmForgotPasswordDto } from '../dtos/confirm-forgot-password.dto';\nimport { InitiateForgotPasswordDto } from '../dtos/initiate-forgot-password.dto';\nimport { OTPConfirmOTPDto } from '../dtos/otp-confirm-otp.dto';\nimport { OTPSignInDto } from '../dtos/otp-sign-in.dto';\nimport { OTPSignUpDto } from '../dtos/otp-sign-up.dto';\nimport { RefreshTokenDto } from '../dtos/refresh-token.dto';\nimport { SignInDto } from '../dtos/sign-in.dto';\nimport { SignUpDto } from '../dtos/sign-up.dto';\nimport { UserPasswordHistory } from '../entities/user-password-history.entity';\nimport { User } from '../entities/user.entity';\nimport { ActiveUserData } from '../interfaces/active-user-data.interface';\nimport { HashingService } from './hashing.service';\nimport { InvalidatedRefreshTokenError, RefreshTokenIdsStorageService } from './refresh-token-ids-storage.service';\nimport { UserService } from './user.service';\nimport { EventDetails, EventType, IMail } from \"../interfaces\";\nimport {\n ForgotPasswordSendVerificationTokenOn,\n RegistrationValidationSource,\n TransactionalRegistrationValidationSource\n} from \"../constants\";\nimport { SettingService } from './setting.service';\nimport { CreateUserDto } from 'src/dtos/create-user.dto';\nimport { RoleMetadataService } from './role-metadata.service';\nimport commonConfig from 'src/config/common.config';\nimport { UserActivityHistoryService } from './user-activity-history.service';\nimport { RequestContextService } from './request-context.service';\nimport { ERROR_MESSAGES } from 'src/constants/error-messages';\nimport { SUCCESS_MESSAGES } from 'src/constants/success-messages';\nimport { MailFactory } from 'src/factories/mail.factory';\nimport { v4 as uuidv4 } from 'uuid';\n\nenum LoginProvider {\n LOCAL = 'local',\n GOOGLE = 'google',\n OTP = 'otp',\n}\n\ninterface otp {\n token: string;\n expiresAt: Date;\n}\n\n@Injectable()\nexport class AuthenticationService {\n private readonly logger = new Logger(AuthenticationService.name);\n // private readonly mailService: IMail;\n constructor(\n private readonly userService: UserService,\n @InjectRepository(User) private readonly userRepository: Repository<User>,\n @InjectRepository(UserPasswordHistory) private readonly userPasswordHistoryRepository: Repository<UserPasswordHistory>,\n private readonly hashingService: HashingService,\n private readonly jwtService: JwtService,\n @Inject(jwtConfig.KEY)\n private readonly jwtConfiguration: ConfigType<typeof jwtConfig>,\n @Inject(iamConfig.KEY)\n private readonly iamConfiguration: ConfigType<typeof iamConfig>,\n private readonly refreshTokenIdsStorage: RefreshTokenIdsStorageService,\n private readonly httpService: HttpService,\n // private readonly mailService: SMTPEMailService,\n private readonly mailServiceFactory: MailFactory,\n private readonly smsService: Msg91OTPService,\n private readonly eventEmitter: EventEmitter2,\n private readonly settingService: SettingService,\n private readonly roleMetadataService: RoleMetadataService,\n @Inject(commonConfig.KEY)\n private readonly commonConfiguration: ConfigType<typeof commonConfig>,\n private readonly userActivityHistoryService: UserActivityHistoryService,\n private readonly requestContextService: RequestContextService,\n @InjectDataSource()\n private readonly dataSource: DataSource,\n ) {\n // this.mailService = this.mailServiceFactory.getMailService();\n }\n\n private async getConfig(key: string): Promise<any> {\n return this.settingService.getConfigValue(key);\n }\n\n private async getCompanyLogo(): Promise<string> {\n return await this.settingService.getConfigValue('companylogo');\n }\n\n async resolveUser(username: string, email: string) {\n return await this.userRepository.findOne({\n where: [\n { username: username },\n { email: email },\n ],\n relations: {\n roles: true\n }\n });\n }\n\n async resolveUserByVerificationToken(token: string) {\n return await this.userRepository.findOne({\n where: { verificationTokenOnForgotPassword: token },\n relations: { roles: true }\n });\n }\n\n async validateUser(signInDto: SignInDto) {\n\n const user = await this.resolveUser(signInDto.username, signInDto.email);\n\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n }\n if (!user.active) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_ACTIVE);\n }\n const isEqual = await this.hashingService.compare(\n signInDto.password,\n user.password,\n );\n if (!isEqual) {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n }\n\n return user;\n }\n\n async signUp(signUpDto: SignUpDto, activeUser: ActiveUserData = null): Promise<User> {\n // If public registrations are disabled and no activeUser is present when invoking signUp then we throw an exception.\n if (!(await this.settingService.getConfigValue('allowPublicRegistration')) && !activeUser) {\n throw new BadRequestException(ERROR_MESSAGES.PUBLIC_REGISTRATION_DISABLED);\n }\n\n try {\n const onForcePasswordChange = await this.getConfig('forceChangePasswordOnFirstLogin');\n var { user, pwd, autoGeneratedPwd } = await this.populateForSignup(new User(), signUpDto, this.iamConfiguration.activateUserOnRegistration, onForcePasswordChange);\n const savedUser = await this.userRepository.save(user);\n // Also assign a default role to the newly created user. \n const userRoles = signUpDto.roles ?? [];\n if (this.iamConfiguration.defaultRole) {\n userRoles.push(this.iamConfiguration.defaultRole);\n }\n await this.handlePostSignup(savedUser, userRoles, pwd, autoGeneratedPwd);\n\n // TODO: make provision to trigger a welcome email also.\n\n return savedUser;\n } catch (err) {\n const pgUniqueViolationErrorCode = '23505';\n if (err.code === pgUniqueViolationErrorCode) {\n throw new ConflictException(ERROR_MESSAGES.USER_ALREADY_EXISTS);\n }\n throw err;\n }\n }\n\n async signupForExtensionUser<T extends User, U extends CreateUserDto>(signUpDto: SignUpDto, extensionUserDto: U, extensionUserRepo: Repository<T>): Promise<T> {\n try {\n const onForcePasswordChange = await this.getConfig('forceChangePasswordOnFirstLogin');\n // Merge the extended signUpDto attributes into the user entity \n //@ts-ignore \n const extensionUser = extensionUserRepo.merge(extensionUserRepo.create() as T, extensionUserDto);\n var { user, pwd, autoGeneratedPwd } = await this.populateForSignup<T>(extensionUser, signUpDto, true, onForcePasswordChange);\n const savedUser = await extensionUserRepo.save(user);\n\n await this.handlePostSignup(savedUser, signUpDto.roles, pwd, autoGeneratedPwd);\n\n return savedUser;\n }\n catch (err) {\n const pgUniqueViolationErrorCode = '23505';\n if (err.code === pgUniqueViolationErrorCode) {\n throw new ConflictException(parseUniqueConstraintError(err.detail || ERROR_MESSAGES.UNIQUE_CONSTRAINT_VIOLATION));\n }\n throw err;\n }\n }\n\n\n private async populateForSignup<T extends User>(user: T, signUpDto: SignUpDto, isUserActive: boolean = true, onForcePasswordChange?: boolean) {\n // const user = new User();\n\n if (signUpDto.roles && signUpDto.roles.length > 0) {\n for (let i = 0; i < signUpDto.roles.length; i++) {\n const roleName = signUpDto.roles[i];\n await this.roleMetadataService.findRoleByName(roleName);\n }\n }\n user.username = signUpDto.username;\n user.email = signUpDto.email;\n user.fullName = signUpDto.fullName;\n user.forcePasswordChange = onForcePasswordChange;\n if (signUpDto.mobile) {\n user.mobile = signUpDto.mobile;\n }\n this.logger.debug(\"user\", user);\n // If password has been specified by the user, then we simply create & activate the user based on the configuration parameter \"activateUserOnRegistration\".\n let pwd = '';\n let autoGeneratedPwd = '';\n if (signUpDto.password) {\n pwd = await this.hashingService.hash(signUpDto.password);\n }\n else {\n // TODO: If password is not specified then auto-generate a random password, trigger this password over an email to the user.\n // TODO: Also track if the user has to force reset / change their password, and then activate the user. \n autoGeneratedPwd = this.generatePassword();\n pwd = await this.hashingService.hash(autoGeneratedPwd);\n user.forcePasswordChange = true;\n }\n user.password = pwd;\n // user.active = this.iamConfiguration.activateUserOnRegistration;\n user.active = isUserActive;\n return { user, pwd, autoGeneratedPwd };\n }\n\n\n private async handlePostSignup(user: User, roles: string[] = [], pwd: string, autoGeneratedPwd: string) {\n await this.userService.initializeRolesForNewUser(roles, user);\n // Tanay: Adding user password to history table\n const userPasswordHistory = new UserPasswordHistory();\n userPasswordHistory.passwordHash = pwd;\n userPasswordHistory.user = user;\n await this.userPasswordHistoryRepository.save(userPasswordHistory);\n\n // if forcePasswordChange is true, then we trigger an email to the user to change the password, this needs to be done using a queue. \n // Create a new method like notifyUserOnForcePasswordChange, create a new email template we can call it on-force-password-change this template to include the random password\n if (user.forcePasswordChange && autoGeneratedPwd) {\n this.notifyUserOnForcePasswordChange(user, autoGeneratedPwd);\n }\n }\n\n\n generatePassword(length: number = 8): string {\n const upperCase = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n const lowerCase = \"abcdefghijklmnopqrstuvwxyz\";\n const numbers = \"0123456789\";\n const specialChars = \"@$#\";\n const allChars = upperCase + lowerCase + numbers + specialChars;\n\n let password = \"\";\n\n for (let i = 0; i < length; i++) {\n const randomIndex = Math.floor(Math.random() * allChars.length);\n password += allChars[randomIndex];\n }\n\n return password;\n }\n\n private async notifyUserOnForcePasswordChange(user: User, autoGeneratedPwd: string) {\n const companyLogo = await this.getCompanyLogo();\n const mailService = this.mailServiceFactory.getMailService();\n mailService.sendEmailUsingTemplate(\n user.email,\n 'on-force-password-change',\n {\n solidAppName: process.env.SOLID_APP_NAME,\n solidAppWebsiteUrl: process.env.SOLID_APP_WEBSITE_URL,\n frontendLoginPageUrl: process.env.IAM_FRONTEND_APP_LOGIN_PAGE_URL,\n email: user.email,\n fullName: user.fullName,\n userName: user.username,\n password: autoGeneratedPwd,\n companyLogoUrl: companyLogo\n },\n this.commonConfiguration.shouldQueueEmails,\n null,\n null,\n 'user',\n user.id\n );\n\n }\n\n async otpInitiateRegistration(signUpDto: OTPSignUpDto) {\n try {\n if (!this.isPasswordlessRegistrationEnabled()) {\n throw new BadRequestException(ERROR_MESSAGES.PASSWORDLESS_REGISTRATION_DISABLED);\n }\n // Validate if either mobile or email is present.\n if (isEmpty(signUpDto.mobile) && isEmpty(signUpDto.email)) {\n throw new BadRequestException(ERROR_MESSAGES.REGISTRATION_REQUIRES_CONTACT);\n }\n if (signUpDto.validationSources.includes(TransactionalRegistrationValidationSource.EMAIL) && isEmpty(signUpDto.email)) {\n throw new BadRequestException(ERROR_MESSAGES.EMAIL_REQUIRED_FOR_VALIDATION);\n }\n if (signUpDto.validationSources.includes(TransactionalRegistrationValidationSource.MOBILE) && isEmpty(signUpDto.mobile)) {\n throw new BadRequestException(ERROR_MESSAGES.MOBILE_REQUIRED_FOR_VALIDATION);\n }\n\n // Validate if user already exists.\n const existingUser = await this.userRepository.findOne({ //TODO Perhaps we should use the user service instead of the repository directly.\n where: [\n { email: signUpDto.email, },\n { mobile: signUpDto.mobile, },\n { username: signUpDto.username, }\n ]\n });\n if (isNotEmpty(existingUser) && existingUser.active) {\n throw new ConflictException(ERROR_MESSAGES.USER_ALREADY_EXISTS);\n }\n const finalRegistrationVerificationSources = this.calculateVerificationSources(this.iamConfiguration.passwordlessRegistrationValidateWhat, signUpDto);\n let user = existingUser\n if (isEmpty(user)) {\n user = this.createUser(signUpDto);\n this.populateVerificationTokens(finalRegistrationVerificationSources, user);\n await this.userRepository.save(user);\n await this.userService.addRoleToUser(user.username, await this.settingService.getConfigValue('defaultRole'));\n }\n else {\n this.populateVerificationTokens(finalRegistrationVerificationSources, user);\n await this.userRepository.save(user);\n }\n\n // Send OTP to the user through email or SMS, depending on the configuration.\n this.notifyUserOnOtpInitiateRegistration(user, finalRegistrationVerificationSources);\n return { message: SUCCESS_MESSAGES.OTP_SENT_SUCCESS_REGISTRATION }\n } catch (err) {\n const pgUniqueViolationErrorCode = '23505';\n if (err.code === pgUniqueViolationErrorCode) {\n throw new ConflictException(ERROR_MESSAGES.USER_ALREADY_EXISTS);\n }\n throw err;\n }\n }\n\n // Create a new user entity.\n private createUser(signUpDto: OTPSignUpDto) {\n const user = new User();\n user.username = signUpDto.username;\n user.email = signUpDto.email;\n user.mobile = signUpDto.mobile;\n user.customPayload = signUpDto.customPayload;\n user.lastLoginProvider = LoginProvider.OTP;\n return user;\n }\n\n private calculateVerificationSources(configuredRegistrationValidationSources: string[], signUpDto: OTPSignUpDto): string[] {\n const finalRegistrationValidationSources = configuredRegistrationValidationSources.filter((source) => source !== RegistrationValidationSource.TRANSACTIONAL);\n if (configuredRegistrationValidationSources.includes(RegistrationValidationSource.TRANSACTIONAL)) {\n finalRegistrationValidationSources.push(...signUpDto.validationSources); // Add the validation sources provided by the user.\n }\n return finalRegistrationValidationSources;\n }\n\n // Generate the validation tokens for the user i.e (system configured + user provided)\n private populateVerificationTokens(finalRegistrationValidationSources: string[], user: User) {\n if (finalRegistrationValidationSources.length === 0) {\n throw new BadRequestException(ERROR_MESSAGES.VALIDATION_SOURCE_REQUIRED);\n }\n if (finalRegistrationValidationSources.includes(TransactionalRegistrationValidationSource.EMAIL)) {\n const { token, expiresAt } = this.otp();\n user.emailVerificationTokenOnRegistration = token;\n user.emailVerificationTokenOnRegistrationExpiresAt = expiresAt;\n if (this.iamConfiguration.autoLoginUserOnRegistration) {\n user.emailVerificationTokenOnLogin = token;\n user.emailVerificationTokenOnLoginExpiresAt = expiresAt;\n }\n }\n if (finalRegistrationValidationSources.includes(TransactionalRegistrationValidationSource.MOBILE)) {\n const { token, expiresAt } = this.otp();\n user.mobileVerificationTokenOnRegistration = token;\n user.mobileVerificationTokenOnRegistrationExpiresAt = expiresAt;\n if (this.iamConfiguration.autoLoginUserOnRegistration) {\n user.mobileVerificationTokenOnLogin = token;\n user.mobileVerificationTokenOnLoginExpiresAt = expiresAt;\n }\n }\n }\n\n private async notifyUserOnOtpInitiateRegistration(user: User, registrationValidationSources: string[]) {\n const companyLogo = await this.getCompanyLogo();\n if (this.iamConfiguration.dummyOtp)\n return; // Do nothing if dummy otp is configured.\n if (registrationValidationSources.includes(RegistrationValidationSource.EMAIL)) {\n const mailService = this.mailServiceFactory.getMailService();\n mailService.sendEmailUsingTemplate(\n user.email,\n 'otp-on-register',\n {\n solidAppName: process.env.SOLID_APP_NAME,\n solidAppWebsiteUrl: process.env.SOLID_APP_WEBSITE_URL,\n firstName: user.username,\n fullName: user.fullName ? user.fullName : user.username,\n emailVerificationTokenOnRegistration: user.emailVerificationTokenOnRegistration,\n companyLogoUrl: companyLogo\n },\n this.commonConfiguration.shouldQueueEmails,\n null,\n null,\n 'user',\n user.id\n );\n }\n if (registrationValidationSources.includes(RegistrationValidationSource.MOBILE)) {\n this.smsService.sendSMSUsingTemplate(\n user.mobile,\n 'otp-on-register',\n {\n solidAppName: process.env.SOLID_APP_NAME,\n otp: user.mobileVerificationTokenOnRegistration,\n mobileVerificationTokenOnRegistration: user.mobileVerificationTokenOnRegistration,\n firstName: user.username,\n fullName: user.fullName ? user.fullName : user.username,\n companyLogoUrl: companyLogo\n }\n );\n }\n }\n\n async otpConfirmRegistration(confirmSignUpDto: OTPConfirmOTPDto) {\n if (!this.isPasswordlessRegistrationEnabled()) {\n throw new BadRequestException(ERROR_MESSAGES.PASSWORDLESS_REGISTRATION_DISABLED);\n }\n\n // Based on the identifier, validate by query the user table.\n if (confirmSignUpDto.type === RegistrationValidationSource.EMAIL) {\n const user = await this.userRepository.findOne({\n where: {\n email: confirmSignUpDto.identifier,\n }\n });\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n if (user.emailVerificationTokenOnRegistration !== confirmSignUpDto.otp) {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);\n }\n if (user.emailVerificationTokenOnRegistrationExpiresAt < new Date()) {\n throw new UnauthorizedException(ERROR_MESSAGES.OTP_EXPIRED);\n }\n user.emailVerifiedOnRegistrationAt = new Date();\n user.emailVerificationTokenOnRegistration = null;\n user.emailVerificationTokenOnRegistrationExpiresAt = null;\n user.active = await this.settingService.getConfigValue('activateUserOnRegistration') && this.areRegistrationValidationSourcesVerified(user);\n const savedUser: User = await this.userRepository.save(user);\n this.triggerRegistrationEvent(savedUser);\n return { active: savedUser.active, message: `User registration verified for ${confirmSignUpDto.type}` }\n } else if (confirmSignUpDto.type === RegistrationValidationSource.MOBILE) {\n const user = await this.userRepository.findOne({\n where: {\n mobile: confirmSignUpDto.identifier,\n }\n });\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n if (user.mobileVerificationTokenOnRegistration !== confirmSignUpDto.otp) {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);\n }\n if (user.mobileVerificationTokenOnRegistrationExpiresAt < new Date()) {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);\n }\n user.mobileVerifiedOnRegistrationAt = new Date();\n user.mobileVerificationTokenOnRegistration = null;\n user.mobileVerificationTokenOnRegistrationExpiresAt = null;\n user.active = await this.settingService.getConfigValue('activateUserOnRegistration') && this.areRegistrationValidationSourcesVerified(user);\n const savedUser: User = await this.userRepository.save(user);\n this.triggerRegistrationEvent(savedUser);\n return { active: savedUser.active, message: `User registration verified for ${confirmSignUpDto.type}` }\n }\n throw new BadRequestException(ERROR_MESSAGES.INVALID_VERIFICATION_TYPE);\n }\n\n private triggerRegistrationEvent(savedUser: User) {\n // Trigger events for user registration.\n const event = new EventDetails<User>(EventType.USER_REGISTERED, savedUser);\n this.eventEmitter.emit(EventType.USER_REGISTERED, event);\n }\n\n areRegistrationValidationSourcesVerified(user: User): boolean {\n const registrationValidationSources = this.iamConfiguration.passwordlessRegistrationValidateWhat;\n if (registrationValidationSources.includes(RegistrationValidationSource.EMAIL)) {\n if (!user.emailVerifiedOnRegistrationAt) {\n return false;\n }\n }\n if (registrationValidationSources.includes(RegistrationValidationSource.MOBILE)) {\n if (!user.mobileVerifiedOnRegistrationAt) {\n return false;\n }\n }\n return true;\n }\n\n private otp(): otp {\n const now = new Date();\n now.setMinutes(now.getMinutes() + this.iamConfiguration.otpExpiry);\n return {\n token: this.iamConfiguration.dummyOtp ? this.iamConfiguration.dummyOtp : randomInt(100000, 999999).toString(),\n expiresAt: now,\n };\n }\n\n async signIn(signInDto: SignInDto) {\n const user = await this.validateUser(signInDto);\n\n // TODO: Unset the password etc...\n const tokens = await this.generateTokens(user);\n\n await this.userActivityHistoryService.logEvent('login', user);\n\n return {\n user: {\n email: user.email,\n mobile: user.mobile,\n username: user.username,\n forcePasswordChange: user.forcePasswordChange,\n id: user.id,\n roles: user.roles.map((role, idx, roles) => role.name)\n },\n ...tokens\n }\n }\n\n async otpInitiateLogin(signInDto: OTPSignInDto) {\n if (!this.isPasswordlessRegistrationEnabled()) {\n throw new BadRequestException(ERROR_MESSAGES.PASSWORDLESS_REGISTRATION_DISABLED);\n }\n\n // Validate & generate otp token for the user based on the identifier type.\n if (signInDto.type === RegistrationValidationSource.EMAIL) {\n const user = await this.userRepository.findOne({\n where: {\n email: signInDto.identifier,\n }\n });\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n if (!user.active) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_INACTIVE);\n }\n const { token, expiresAt } = this.otp();\n user.emailVerificationTokenOnLogin = token;\n user.emailVerificationTokenOnLoginExpiresAt = expiresAt;\n await this.userRepository.save(user);\n this.notifyUserOnOtpInititateLogin(user, RegistrationValidationSource.EMAIL);\n } else if (signInDto.type === RegistrationValidationSource.MOBILE) {\n const user = await this.userRepository.findOne({\n where: {\n mobile: signInDto.identifier,\n }\n });\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n\n const { token, expiresAt } = this.otp();\n user.mobileVerificationTokenOnLogin = token;\n user.mobileVerificationTokenOnLoginExpiresAt = expiresAt;\n await this.userRepository.save(user);\n this.notifyUserOnOtpInititateLogin(user, RegistrationValidationSource.MOBILE);\n }\n else {\n throw new BadRequestException(ERROR_MESSAGES.INVALID_VERIFICATION_TYPE);\n }\n return { message: SUCCESS_MESSAGES.OTP_SENT_SUCCESS_LOGIN };\n }\n\n private async notifyUserOnOtpInititateLogin(user: User, loginType: RegistrationValidationSource) {\n const companyLogo = await this.getCompanyLogo();\n\n if (this.iamConfiguration.dummyOtp)\n return; // Do nothing if dummy otp is configured.\n if (loginType === RegistrationValidationSource.EMAIL) {\n const mailService = this.mailServiceFactory.getMailService();\n mailService.sendEmailUsingTemplate(\n user.email,\n 'otp-on-login',\n {\n solidAppName: process.env.SOLID_APP_NAME,\n solidAppWebsiteUrl: process.env.SOLID_APP_WEBSITE_URL,\n firstName: user.username,\n emailVerificationTokenOnLogin: user.emailVerificationTokenOnLogin,\n fullName: user.fullName ? user.fullName : user.username,\n companyLogoUrl: companyLogo\n },\n this.commonConfiguration.shouldQueueEmails,\n null,\n null,\n 'user',\n user.id\n );\n }\n if (loginType === RegistrationValidationSource.MOBILE) {\n this.smsService.sendSMSUsingTemplate(\n user.mobile,\n 'otp-on-login',\n {\n solidAppName: process.env.SOLID_APP_NAME,\n otp: user.mobileVerificationTokenOnLogin,\n mobileVerificationTokenOnLogin: user.mobileVerificationTokenOnLogin,\n firstName: user.username,\n fullName: user.fullName ? user.fullName : user.username,\n companyLogoUrl: companyLogo\n }\n );\n }\n }\n\n async otpConfirmLogin(confirmSignInDto: OTPConfirmOTPDto) {\n if (!this.isPasswordlessRegistrationEnabled()) {\n throw new BadRequestException(ERROR_MESSAGES.PASSWORDLESS_REGISTRATION_DISABLED);\n }\n if (confirmSignInDto.type === RegistrationValidationSource.EMAIL) {\n const user = await this.userRepository.findOne({\n where: {\n email: confirmSignInDto.identifier,\n },\n relations: ['roles']\n });\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n if (!user.active) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_INACTIVE);\n }\n if (user.emailVerificationTokenOnLogin !== confirmSignInDto.otp) {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);\n }\n if (user.emailVerificationTokenOnLoginExpiresAt < new Date()) {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);\n }\n user.emailVerifiedOnLoginAt = new Date();\n user.emailVerificationTokenOnLogin = null;\n user.emailVerificationTokenOnLoginExpiresAt = null;\n await this.userRepository.save(user);\n const { accessToken, refreshToken } = await this.generateTokens(user);\n const { id, username, email, mobile, lastLoginProvider } = user;\n const roles = user.roles.map((role) => role.name);\n return { accessToken, refreshToken, user: { id, username, email, mobile, lastLoginProvider, roles } };\n } else if (confirmSignInDto.type === RegistrationValidationSource.MOBILE) {\n const user = await this.userRepository.findOne({\n where: {\n mobile: confirmSignInDto.identifier,\n },\n relations: ['roles']\n });\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_ACTIVE);\n }\n if (!user.active) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_INACTIVE);\n }\n if (user.mobileVerificationTokenOnLogin !== confirmSignInDto.otp) {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);\n }\n if (user.mobileVerificationTokenOnLoginExpiresAt < new Date()) {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_OTP);\n }\n user.mobileVerifiedOnLoginAt = new Date();\n user.mobileVerificationTokenOnLogin = null;\n user.mobileVerificationTokenOnLoginExpiresAt = null;\n await this.userRepository.save(user);\n const { accessToken, refreshToken } = await this.generateTokens(user);\n const { id, username, email, mobile, lastLoginProvider } = user;\n const roles = user.roles.map((role) => role.name);\n return { accessToken, refreshToken, user: { id, username, email, mobile, lastLoginProvider, roles } };\n\n }\n throw new BadRequestException(ERROR_MESSAGES.INVALID_VERIFICATION_TYPE);\n }\n\n async changePassword(changePasswordDto: ChangePasswordDto, activeUser: ActiveUserData) {\n const user = await this.userRepository.findOne({\n where: { id: changePasswordDto.id }\n });\n if (!user) {\n throw new NotFoundException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n\n if (!user.active) {\n throw new UnauthorizedException(ERROR_MESSAGES.USER_INACTIVE);\n }\n\n // 2. Validate if user has used a provider which is \"local\", only then it makes sense for us to initiate the forgot password routine.\n if (user.lastLoginProvider !== 'local') {\n throw new BadRequestException(ERROR_MESSAGES.NON_LOCAL_PROVIDER);\n }\n\n // Check if ID's match\n if (!(user.id === activeUser.sub)) {\n throw new BadRequestException(ERROR_MESSAGES.USER_ID_MISMATCH);\n }\n\n // Check if username's match\n if (!(user.username === activeUser.username)) {\n throw new BadRequestException(ERROR_MESSAGES.USERNAME_MISMATCH);\n }\n\n // Check if old password is matching.\n const isEqual = await this.hashingService.compare(\n changePasswordDto.currentPassword,\n user.password,\n );\n if (!isEqual) {\n throw new UnauthorizedException(ERROR_MESSAGES.INCORRECT_CURRENT_PASSWORD);\n }\n\n // Update Password\n const newPwd = await this.hashingService.hash(changePasswordDto.newPassword);\n user.password = changePasswordDto.newPassword;\n\n // Everytime the user changes the password we reset the forcePasswordChange flag back to false. \n user.forcePasswordChange = false;\n\n if (await this.isPasswordDuplicate(user)) {\n throw new BadRequestException(ERROR_MESSAGES.PASSWORD_REUSED);\n }\n await this.deleteOldPasswords(user);\n\n user.password = newPwd;\n const userPasswordHistory = new UserPasswordHistory();\n userPasswordHistory.passwordHash = newPwd;\n userPasswordHistory.user = user;\n\n await this.userRepository.save(user);\n await this.userPasswordHistoryRepository.save(userPasswordHistory);\n\n return true;\n }\n\n // generate uuid token for forgot password\n private generateForgotPasswordToken() {\n const expiryTime = new Date();\n expiryTime.setMinutes(expiryTime.getMinutes() + this.iamConfiguration.forgotPasswordVerificationTokenExpiry);\n\n return {\n token: this.iamConfiguration.dummyOtp\n ? this.iamConfiguration.dummyOtp\n : uuidv4(), // UUID instead of numeric OTP\n expiresAt: expiryTime,\n };\n }\n\n async initiateForgotPassword(initiateForgotPasswordDto: InitiateForgotPasswordDto) {\n // Steps / Algorithm: \n // 1. Identify the user using the specified \"username\", if not found exit.\n // const user = await this.userRepository.findOne({\n // where: { username: initiateForgotPasswordDto.username, }\n // });\n const user = await this.resolveUser(initiateForgotPasswordDto.username, initiateForgotPasswordDto.email);\n\n let isValidUser = true // Instead of throwing exceptions we will simply return success message, this is to avoid user enumeration attacks.\n if (!user) {\n isValidUser = false \n // throw new NotFoundException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n }\n if (isValidUser && !user?.active) {\n isValidUser = false\n // throw new UnauthorizedException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n }\n\n // 2. Validate if user has used a provider which is \"local\", only then it makes sense for us to initiate the forgot password routine. \n if (isValidUser && user?.lastLoginProvider !== 'local') {\n isValidUser = false\n // throw new BadRequestException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n }\n\n // 3. Generate a 6 digit validation token, we send this token to the user over their email & mobile number (controlled using configuration).\n // 4. Save this validation token in new fields on the user record. \n if (isValidUser) {\n const { token, expiresAt } = this.generateForgotPasswordToken();\n user.verificationTokenOnForgotPassword = token;\n user.verificationTokenOnForgotPasswordExpiresAt = expiresAt;\n await this.userRepository.save(user);\n this.notifyUserOnForgotPassword(user);\n }\n\n // 5. Return. \n return {\n status: 'success',\n message: SUCCESS_MESSAGES.FORGOT_PASSWORD_TOKEN_SENT,\n error: '',\n errorCode: '',\n data: {\n user: {\n email: user?.email,\n // mobile: user.mobile,\n // username: user.username,\n },\n }\n }\n }\n\n private async notifyUserOnForgotPassword(user: User) {\n const companyLogo = await this.getCompanyLogo();\n\n const forgotPasswordSendVerificationTokenOn = this.iamConfiguration.forgotPasswordSendVerificationTokenOn;\n\n if (forgotPasswordSendVerificationTokenOn == ForgotPasswordSendVerificationTokenOn.EMAIL) {\n const mailService = this.mailServiceFactory.getMailService();\n mailService.sendEmailUsingTemplate(\n user.email,\n 'forgot-password',\n {\n solidAppName: process.env.SOLID_APP_NAME,\n solidAppWebsiteUrl: process.env.SOLID_APP_WEBSITE_URL,\n firstName: user.username,\n fullName: user.fullName,\n // TODO: Need to prefix this with the page url where the forgot password page will open up.\n passwordResetLink: `${process.env.IAM_FRONTEND_APP_FORGOT_PASSWORD_PAGE_URL}?token=${user.verificationTokenOnForgotPassword}`,\n companyLogoUrl: companyLogo\n },\n this.commonConfiguration.shouldQueueEmails,\n null,\n null,\n 'user',\n user.id\n );\n }\n // Assuming all users do not have mobile as mandatory.\n if (forgotPasswordSendVerificationTokenOn == ForgotPasswordSendVerificationTokenOn.MOBILE && user.mobile) {\n this.smsService.sendSMSUsingTemplate(\n user.mobile,\n 'forgot-password',\n {\n solidAppName: process.env.SOLID_APP_NAME,\n otp: user.verificationTokenOnForgotPassword,\n verificationTokenOnForgotPassword: user.verificationTokenOnForgotPassword,\n firstName: user.username,\n companyLogoUrl: companyLogo\n }\n );\n }\n }\n\n async confirmForgotPassword(confirmForgotPasswordDto: ConfirmForgotPasswordDto) {\n return this.dataSource.transaction(async (m) => {\n // Resolve the user id first (by username/email), but DON'T check the token in JS.\n const user = await this.resolveUserByVerificationToken(confirmForgotPasswordDto.verificationToken);\n if (!user) throw new UnauthorizedException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n if (user.lastLoginProvider !== 'local') throw new UnauthorizedException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n if (!user.active) throw new UnauthorizedException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n\n // 1) Atomically consume the token (only one request can succeed)\n const { affected } = await m\n .createQueryBuilder()\n .update(User)\n .set({\n forgotPasswordConfirmedAt: () => 'NOW()',\n verificationTokenOnForgotPassword: () => 'NULL',\n verificationTokenOnForgotPasswordExpiresAt: () => 'NULL',\n })\n .where('id = :id', { id: user.id })\n .andWhere('verificationTokenOnForgotPassword = :token', { token: confirmForgotPasswordDto.verificationToken })\n .andWhere('verificationTokenOnForgotPasswordExpiresAt > NOW()')\n .execute();\n\n if (affected !== 1) {\n // Token invalid/expired/already used (or a parallel call already consumed it)\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_CREDENTIALS);\n }\n\n // 2) Now update the password & history (still inside the same transaction)\n const pwdHash = await this.hashingService.hash(confirmForgotPasswordDto.password);\n\n // Avoid ever assigning plaintext:\n // user.password = dto.password <-- remove this line in your original code\n\n // Check reuse with your existing method (ensure it looks at hashes).\n const tempUser = { ...user, password: pwdHash } as User; // if your helper expects it\n if (await this.isPasswordDuplicate(tempUser)) {\n throw new BadRequestException(ERROR_MESSAGES.PASSWORD_REUSED);\n }\n\n await this.deleteOldPasswords(user);\n\n await m.getRepository(User).update({ id: user.id }, { password: pwdHash });\n\n const history = m.getRepository(UserPasswordHistory).create({\n user: { id: user.id } as any,\n passwordHash: pwdHash,\n });\n await m.getRepository(UserPasswordHistory).save(history);\n this.notifyUserOnPasswordChanged(user);\n\n return {\n status: 'success',\n message: SUCCESS_MESSAGES.FORGOT_PASSWORD_CONFIRMED,\n error: '',\n errorCode: '',\n data: {},\n };\n });\n }\n\n private async notifyUserOnPasswordChanged(user: User) {\n const companyLogo = await this.getCompanyLogo();\n\n const forgotPasswordSendVerificationTokenOn = this.iamConfiguration.forgotPasswordSendVerificationTokenOn;\n\n if (forgotPasswordSendVerificationTokenOn == ForgotPasswordSendVerificationTokenOn.EMAIL) {\n const mailService = this.mailServiceFactory.getMailService();\n mailService.sendEmailUsingTemplate(\n user.email,\n 'password-changed',\n {\n solidAppName: process.env.SOLID_APP_NAME,\n solidAppWebsiteUrl: process.env.SOLID_APP_WEBSITE_URL,\n email: user.email,\n firstName: user.username,\n fullName: user.fullName,\n // TODO: Need to prefix this with the page url where the forgot password page will open up.\n passwordResetLink: `${process.env.IAM_FRONTEND_APP_FORGOT_PASSWORD_PAGE_URL}?token=${user.verificationTokenOnForgotPassword}`,\n companyLogoUrl: companyLogo\n },\n this.commonConfiguration.shouldQueueEmails,\n null,\n null,\n 'user',\n user.id\n );\n }\n // Assuming all users do not have mobile as mandatory.\n if (forgotPasswordSendVerificationTokenOn == ForgotPasswordSendVerificationTokenOn.MOBILE && user.mobile) {\n this.smsService.sendSMSUsingTemplate(\n user.mobile,\n 'forgot-password',\n {\n solidAppName: process.env.SOLID_APP_NAME,\n otp: user.verificationTokenOnForgotPassword,\n verificationTokenOnForgotPassword: user.verificationTokenOnForgotPassword,\n firstName: user.username,\n companyLogoUrl: companyLogo\n }\n );\n }\n }\n\n // async confirmForgotPassword(confirmForgotPasswordDto: ConfirmForgotPasswordDto) {\n // // Steps / Algorithm: \n // // 1. Identify the user using the specified \"username\", if not found exit.\n // // const user = await this.userRepository.findOne({\n // // where: { username: confirmForgotPasswordDto.username, }\n // // });\n // const user = await this.resolveUserByVerificationToken(confirmForgotPasswordDto.verificationToken);\n\n // if (!user) {\n // throw new NotFoundException(ERROR_MESSAGES.USER_NOT_FOUND);\n // }\n\n // // 2. Validate if user has used a provider which is \"local\", only then it makes sense for us to initiate the forgot password routine. \n // if (user.lastLoginProvider !== 'local') {\n // throw new BadRequestException(ERROR_MESSAGES.NON_LOCAL_PROVIDER);\n // }\n // if (!user.active) {\n // throw new UnauthorizedException(ERROR_MESSAGES.USER_INACTIVE);\n // }\n\n // // 3. Validate the verification token is proper & update the user record. \n // if (user.verificationTokenOnForgotPassword !== confirmForgotPasswordDto.verificationToken) {\n // throw new UnauthorizedException(ERROR_MESSAGES.INVALID_VERIFICATION_TOKEN);\n // }\n // if (user.verificationTokenOnForgotPasswordExpiresAt < new Date()) {\n // throw new UnauthorizedException(ERROR_MESSAGES.INVALID_VERIFICATION_TOKEN);\n // }\n // user.forgotPasswordConfirmedAt = new Date();\n // user.verificationTokenOnForgotPassword = null;\n // user.verificationTokenOnForgotPasswordExpiresAt = null;\n\n // // 4. Update the users password while encrypting it.\n // const pwd = await this.hashingService.hash(confirmForgotPasswordDto.password);\n // user.password = confirmForgotPasswordDto.password\n\n // if (await this.isPasswordDuplicate(user)) {\n // throw new BadRequestException(ERROR_MESSAGES.PASSWORD_REUSED);\n // }\n // await this.deleteOldPasswords(user);\n\n // user.password = pwd;\n // const userPasswordHistory = new UserPasswordHistory();\n // userPasswordHistory.passwordHash = pwd;\n // userPasswordHistory.user = user;\n\n // await this.userRepository.save(user);\n // //FIXME: Do this check conditionally, basis a configuration parameter i.e if IAM_ALLOW_PREVIOUS_PASSWORDS=false, default true\n // await this.userPasswordHistoryRepository.save(userPasswordHistory);\n\n // return {\n // status: 'success',\n // message: SUCCESS_MESSAGES.FORGOT_PASSWORD_CONFIRMED,\n // error: '',\n // errorCode: '',\n // data: {}\n // }\n // }\n\n //FIXME: Do this check conditionally, basis a configuration parameter i.e if IAM_ALLOW_PREVIOUS_PASSWORDS=true, return immediately without processing, i.e false.\n private async isPasswordDuplicate(user: User) {\n const userPwdHistoryEntityArray = await this.userPasswordHistoryRepository.findBy(\n { user: { id: user.id } }\n )\n let userPwdHistoryArray = [];\n // O(n)\n for (const entity of userPwdHistoryEntityArray) {\n userPwdHistoryArray.push(entity.passwordHash);\n }\n // O(n)\n for (const pwdHash of userPwdHistoryArray) {\n const isEqual = await this.hashingService.compare(user.password, pwdHash);\n if (isEqual) {\n return true;\n }\n }\n return false;\n }\n\n //FIXME: Do this check conditionally, basis a configuration parameter i.e if IAM_ALLOW_PREVIOUS_PASSWORDS=true, return immediately without processing\n private async deleteOldPasswords(user: User) {\n const userPwdHistoryArray = await this.userPasswordHistoryRepository.findBy(\n { user: { id: user.id } }\n )\n const pwdLimit = 2; //FIXME: Should this be moved into the env? IAM_PREVIOUS_PASSWORDS_LIMIT\n\n // TODO: Check what slice() or splice() does.\n //FIXME - Delete passwords which are older than the latest n passwords. n is configurable\n if (userPwdHistoryArray.length >= pwdLimit) {\n const numToDelete = pwdLimit + 1 - userPwdHistoryArray.length;\n for (let i = 0; i < numToDelete; i++) {\n await this.userPasswordHistoryRepository.remove(userPwdHistoryArray[i]);\n }\n }\n }\n\n async generateTokens(user: User) {\n\n const [accessToken, refreshToken] = await Promise.all([\n this.generateAccessToken(user),\n this.generateRefreshToken(user),\n ]);\n\n return {\n accessToken,\n refreshToken,\n };\n }\n\n async generateAccessToken(user: User) {\n\n // const userRoleNames = user.roles.map((role) => role.name).join(';')\n const userRoleNames = user.roles.map((role) => role.name);\n\n const accessToken = await this.signToken<Partial<ActiveUserData>>(\n user.id,\n this.jwtConfiguration.accessTokenTtl,\n { username: user.username, email: user.email, roles: userRoleNames },\n );\n\n return accessToken;\n }\n\n async generateRefreshToken(user: User) {\n const refreshTokenId = randomUUID();\n\n const refreshToken = await this.signToken(user.id, this.jwtConfiguration.refreshTokenTtl, {\n refreshTokenId,\n })\n\n // store the refresh token id in the redis storage.\n await this.refreshTokenIdsStorage.insert(user.id, refreshToken);\n\n return refreshToken;\n }\n\n async refreshTokens(refreshTokenDto: RefreshTokenDto) {\n try {\n const { sub, refreshTokenId } = await this.jwtService.verifyAsync<Pick<ActiveUserData, 'sub'> & { refreshTokenId: string }>(refreshTokenDto.refreshToken, {\n secret: this.jwtConfiguration.secret,\n audience: this.jwtConfiguration.audience,\n issuer: this.jwtConfiguration.issuer,\n });\n // const user = await this.userRepository.findOneByOrFail({ id: sub });\n const user = await this.userRepository.findOne({\n where: {\n id: sub,\n },\n relations: {\n roles: true\n }\n });\n if (!user) {\n throw new UnauthorizedException(ERROR_MESSAGES.SESSION_INVALID);\n }\n\n // TODO: Replace the if else condition below with a call to validateAndRotate - Done\n // const isValid = await this.refreshTokenIdsStorage.validate(user.id, refreshTokenId);\n // if (isValid) {\n // // Refresh token rotation.\n // await this.refreshTokenIdsStorage.invalidate(user.id);\n // } else {\n // throw new Error('Refresh token is invalid');\n // }\n\n const currentRefreshToken = await this.refreshTokenIdsStorage.validateAndRotate(user, refreshTokenDto.refreshToken);\n\n await this.userActivityHistoryService.logEvent('tokenRefreshed', user);\n\n return {\n accessToken: await this.generateAccessToken(user),\n refreshToken: currentRefreshToken,\n };\n } catch (err) {\n if (err instanceof InvalidatedRefreshTokenError) {\n // Take action: notify user that his refresh token might have been stolen?\n throw new UnauthorizedException(ERROR_MESSAGES.ACCESS_DENIED);\n }\n\n throw new UnauthorizedException(ERROR_MESSAGES.SESSION_EXPIRED);\n }\n }\n\n private async signToken<T>(userId: number, expiresIn: number, payload?: T) {\n return await this.jwtService.signAsync(\n {\n sub: userId,\n ...payload,\n },\n {\n audience: this.jwtConfiguration.audience,\n issuer: this.jwtConfiguration.issuer,\n secret: this.jwtConfiguration.secret,\n expiresIn,\n },\n );\n }\n\n // PROVIDER SPECIFIC CODE\n async validateUserUsingGoogle(user: User) {\n try {\n // Make API call to Google OAuth service to fetch user profile\n const response = await this.httpService.axiosRef.get(`https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token=${user.googleAccessToken}`);\n const userProfile = response.data;\n\n // Ensure the fetched profile email & provider Id match the ones we have stored in the database earlier. \n if (userProfile.email === user.email && userProfile.id === user.googleId) {\n // TODO: remove the access code both from the database.\n return userProfile;\n } else {\n throw new UnauthorizedException(ERROR_MESSAGES.INVALID_USER_PROFILE);\n }\n } catch (error) {\n throw new UnauthorizedException(ERROR_MESSAGES.GOOGLE_OAUTH_PROFILE_FETCH_FAILED);\n }\n }\n\n async signInUsingGoogle(accessCode: string) {\n const user = await this.userRepository.findOne({\n where: {\n accessCode: accessCode\n },\n relations: {\n roles: true\n }\n });\n\n // Validate the user against the Google oauth provider. \n // If the below call finishes without raising an exception then we have validated the user properly.\n await this.validateUserUsingGoogle(user);\n\n // finally we simply generate the tokens. \n const tokens = await this.generateTokens(user);\n return {\n user: {\n email: user.email,\n mobile: user.mobile,\n username: user.username,\n // forcePasswordChange: user.forcePasswordChange,\n id: user.id,\n roles: user.roles.map((role, idx, roles) => role.name)\n },\n ...tokens\n }\n\n }\n\n private async isPasswordlessRegistrationEnabled() {\n return this.settingService.getConfigValue('passwordlessRegistration');\n }\n\n //FIXME - Pending implementation\n // async logout() {\n // // const user = this.request.user; //TODO: // Access the user from the execution context\n\n // // Invalidate the refresh token\n // // await this.refreshTokenIdsStorage.invalidate(user.id);\n // }\n async logout() {\n try {\n const activeUser = this.requestContextService.getActiveUser();\n const userId = activeUser?.sub;\n const user = await this.userRepository.findOne({\n where: {\n id: userId,\n }\n })\n // Invalidate refresh token if you store them\n await this.refreshTokenIdsStorage.invalidate(userId); // ← Your existing logic\n\n // Log logout event\n await this.userActivityHistoryService.logEvent('logout', user);\n\n\n return { message: SUCCESS_MESSAGES.LOGOUT_SUCCESS };\n } catch (err) {\n throw err instanceof UnauthorizedException || err instanceof InternalServerErrorException\n ? err\n : new InternalServerErrorException(ERROR_MESSAGES.LOGOUT_FAILED);\n }\n }\n\n\n async activateUser(userId: number) {\n const user = await this.userService.findOne(userId, {});\n if (!user) {\n throw new NotFoundException(ERROR_MESSAGES.USER_NOT_FOUND);\n }\n user.active = true;\n await this.userRepository.save(user);\n }\n\n async me(activeUser: ActiveUserData) {\n const user = await this.userRepository.findOne({\n where: {\n id: activeUser.sub,\n },\n relations: {\n roles: true\n }\n });\n const tokens = await this.generateTokens(user);\n\n const response = {\n user: {\n email: user.email,\n mobile: user.mobile,\n username: user.username,\n // forcePasswordChange: user.forcePasswordChange,\n id: user.id,\n roles: user.roles.map((role, idx, roles) => role.name)\n },\n ...tokens\n }\n return response;\n }\n\n}\n\nfunction parseUniqueConstraintError(detail: string): string {\n const match = detail.match(/Key \\(([^)]+)\\)=\\(([^)]+)\\) already exists\\./);\n if (match) {\n const field = match[1];\n const value = match[2];\n const fieldMap: Record<string, string> = {\n username: 'username',\n email: 'email address',\n full_name_user_key: 'full name',\n };\n const friendlyField = fieldMap[field] || field;\n return `A user with ${friendlyField} \"${value}\" already exists.`;\n }\n return detail;\n}\n"]}
@@ -12,7 +12,7 @@ class DatabasePublisher {
12
12
  if (!this.serviceRole) {
13
13
  this.logger.debug('Queue service Role is not defined in the environment variables');
14
14
  }
15
- this.logger.debug(`DatabasePublisher instance created with options: ${JSON.stringify(this.options())} and url: ${this.url}`);
15
+ this.logger.debug(`DatabasePublisher instance created with options: ${JSON.stringify(this.options())}`);
16
16
  }
17
17
  async publish(message) {
18
18
  if (!this.serviceRole) {
@@ -23,7 +23,7 @@ class DatabasePublisher {
23
23
  this.logger.error('Queue service Role is subscriber, cannot publish messages');
24
24
  throw new Error('Queue service Role is subscriber, cannot publish messages');
25
25
  }
26
- this.logger.debug(`DatabasePublisher publishing with options: ${JSON.stringify(this.options())} and url: ${this.url}`);
26
+ this.logger.debug(`DatabasePublisher publishing with options: ${JSON.stringify(this.options())}`);
27
27
  const options = this.options();
28
28
  const queueName = options.queueName;
29
29
  if (!message.retryCount)
@@ -1 +1 @@
1
- {"version":3,"file":"database-publisher.service.js","sourceRoot":"","sources":["../../../src/services/queues/database-publisher.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Logger } from '@nestjs/common';\nimport { v4 as uuidv4 } from 'uuid';\nimport { QueuesModuleOptions } from \"../../interfaces\";\nimport { QueueMessage, QueuePublisher } from '../../interfaces/mq';\nimport { MqMessageQueueService } from '../mq-message-queue.service';\nimport { MqMessageService } from '../mq-message.service';\n\nexport abstract class DatabasePublisher<T> implements QueuePublisher<T> {\n private readonly logger = new Logger(DatabasePublisher.name);\n private readonly url: string;\n private readonly serviceRole: string;\n\n constructor(\n protected readonly mqMessageService: MqMessageService,\n protected readonly mqMessageQueueService: MqMessageQueueService,\n ) {\n this.serviceRole = process.env.QUEUES_SERVICE_ROLE;\n if (!this.serviceRole) {\n this.logger.debug('Queue service Role is not defined in the environment variables');\n }\n this.logger.debug(`DatabasePublisher instance created with options: ${JSON.stringify(this.options())} and url: ${this.url}`);\n }\n\n abstract options(): QueuesModuleOptions;\n\n async publish(message: QueueMessage<T>): Promise<string> {\n if (!this.serviceRole) {\n this.logger.error('Queue service Role is not defined in the environment variables');\n throw new Error('Queue service Role is not defined in the environment variables');\n }\n if (this.serviceRole === 'subscriber') {\n this.logger.error('Queue service Role is subscriber, cannot publish messages');\n throw new Error('Queue service Role is subscriber, cannot publish messages');\n }\n\n this.logger.debug(`DatabasePublisher publishing with options: ${JSON.stringify(this.options())} and url: ${this.url}`);\n\n const options = this.options();\n\n const queueName = options.queueName;\n if (!message.retryCount) message.retryCount = 0;\n if (!message.retryInterval) message.retryInterval = 1000;\n\n // generate a new message id \n message.messageId = uuidv4();\n\n // Save the message to the DB so that we can then change its status in the subscriber...\n await this.persistToDatabase(queueName, message);\n\n // return the newly created message id.\n return message.messageId;\n }\n\n private async persistToDatabase(queueName: string, message: QueueMessage<T>) {\n // make an entry in the relevant database table, generate a unique id earlier.\n try {\n // 1. resolve the queue first\n const mqMessageQueue = await this.mqMessageQueueService.resolveQueue(queueName);\n\n // 2. Next create an entry in the mqMessage table. \n await this.mqMessageService.create({\n messageBroker: this.options().type,\n messageId: message.messageId,\n retryCount: message.retryCount,\n retryInterval: message.retryInterval,\n stage: 'pending',\n startedAt: new Date(),\n input: JSON.stringify(message, null, 2),\n parentEntityId: message.parentEntityId,\n parentEntity: message.parentEntity,\n mqMessageQueueId: mqMessageQueue.id,\n });\n }\n catch (error) {\n this.logger.error(error.message, error.stack);\n }\n\n }\n}\n"]}
1
+ {"version":3,"file":"database-publisher.service.js","sourceRoot":"","sources":["../../../src/services/queues/database-publisher.service.ts"],"names":[],"mappings":";;;AAAA,2CAAwC;AACxC,+BAAoC;AAMpC,MAAsB,iBAAiB;IAKnC,YACuB,gBAAkC,EAClC,qBAA4C;QAD5C,qBAAgB,GAAhB,gBAAgB,CAAkB;QAClC,0BAAqB,GAArB,qBAAqB,CAAuB;QANlD,WAAM,GAAG,IAAI,eAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAQzD,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;QACnD,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACpB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gEAAgE,CAAC,CAAC;QACxF,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oDAAoD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5G,CAAC;IAID,KAAK,CAAC,OAAO,CAAC,OAAwB;QAClC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACpB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gEAAgE,CAAC,CAAC;YACpF,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;QACtF,CAAC;QACD,IAAI,IAAI,CAAC,WAAW,KAAK,YAAY,EAAE,CAAC;YACpC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,2DAA2D,CAAC,CAAC;YAC/E,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;QACjF,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,8CAA8C,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;QAElG,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAE/B,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACpC,IAAI,CAAC,OAAO,CAAC,UAAU;YAAE,OAAO,CAAC,UAAU,GAAG,CAAC,CAAC;QAChD,IAAI,CAAC,OAAO,CAAC,aAAa;YAAE,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;QAGzD,OAAO,CAAC,SAAS,GAAG,IAAA,SAAM,GAAE,CAAC;QAG7B,MAAM,IAAI,CAAC,iBAAiB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAGjD,OAAO,OAAO,CAAC,SAAS,CAAC;IAC7B,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,SAAiB,EAAE,OAAwB;QAEvE,IAAI,CAAC;YAED,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;YAGhF,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC;gBAC/B,aAAa,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI;gBAClC,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,aAAa,EAAE,OAAO,CAAC,aAAa;gBACpC,KAAK,EAAE,SAAS;gBAChB,SAAS,EAAE,IAAI,IAAI,EAAE;gBACrB,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;gBACvC,cAAc,EAAE,OAAO,CAAC,cAAc;gBACtC,YAAY,EAAE,OAAO,CAAC,YAAY;gBAClC,gBAAgB,EAAE,cAAc,CAAC,EAAE;aACtC,CAAC,CAAC;QACP,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QAClD,CAAC;IAEL,CAAC;CACJ;AAvED,8CAuEC","sourcesContent":["import { Logger } from '@nestjs/common';\nimport { v4 as uuidv4 } from 'uuid';\nimport { QueuesModuleOptions } from \"../../interfaces\";\nimport { QueueMessage, QueuePublisher } from '../../interfaces/mq';\nimport { MqMessageQueueService } from '../mq-message-queue.service';\nimport { MqMessageService } from '../mq-message.service';\n\nexport abstract class DatabasePublisher<T> implements QueuePublisher<T> {\n private readonly logger = new Logger(DatabasePublisher.name);\n private readonly url: string;\n private readonly serviceRole: string;\n\n constructor(\n protected readonly mqMessageService: MqMessageService,\n protected readonly mqMessageQueueService: MqMessageQueueService,\n ) {\n this.serviceRole = process.env.QUEUES_SERVICE_ROLE;\n if (!this.serviceRole) {\n this.logger.debug('Queue service Role is not defined in the environment variables');\n }\n this.logger.debug(`DatabasePublisher instance created with options: ${JSON.stringify(this.options())}`);\n }\n\n abstract options(): QueuesModuleOptions;\n\n async publish(message: QueueMessage<T>): Promise<string> {\n if (!this.serviceRole) {\n this.logger.error('Queue service Role is not defined in the environment variables');\n throw new Error('Queue service Role is not defined in the environment variables');\n }\n if (this.serviceRole === 'subscriber') {\n this.logger.error('Queue service Role is subscriber, cannot publish messages');\n throw new Error('Queue service Role is subscriber, cannot publish messages');\n }\n\n this.logger.debug(`DatabasePublisher publishing with options: ${JSON.stringify(this.options())}`);\n\n const options = this.options();\n\n const queueName = options.queueName;\n if (!message.retryCount) message.retryCount = 0;\n if (!message.retryInterval) message.retryInterval = 1000;\n\n // generate a new message id \n message.messageId = uuidv4();\n\n // Save the message to the DB so that we can then change its status in the subscriber...\n await this.persistToDatabase(queueName, message);\n\n // return the newly created message id.\n return message.messageId;\n }\n\n private async persistToDatabase(queueName: string, message: QueueMessage<T>) {\n // make an entry in the relevant database table, generate a unique id earlier.\n try {\n // 1. resolve the queue first\n const mqMessageQueue = await this.mqMessageQueueService.resolveQueue(queueName);\n\n // 2. Next create an entry in the mqMessage table. \n await this.mqMessageService.create({\n messageBroker: this.options().type,\n messageId: message.messageId,\n retryCount: message.retryCount,\n retryInterval: message.retryInterval,\n stage: 'pending',\n startedAt: new Date(),\n input: JSON.stringify(message, null, 2),\n parentEntityId: message.parentEntityId,\n parentEntity: message.parentEntity,\n mqMessageQueueId: mqMessageQueue.id,\n });\n }\n catch (error) {\n this.logger.error(error.message, error.stack);\n }\n\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"database-subscriber.service.d.ts","sourceRoot":"","sources":["../../../src/services/queues/database-subscriber.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGlD,8BAAsB,kBAAkB,CAAC,CAAC,CAAE,YAAW,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC;IAM/E,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB;IACrD,SAAS,CAAC,QAAQ,CAAC,qBAAqB,EAAE,qBAAqB;IAC/D,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,aAAa;IAP5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;IAC9D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAGd,gBAAgB,EAAE,gBAAgB,EAClC,qBAAqB,EAAE,qBAAqB,EAC5C,MAAM,EAAE,aAAa;IAS5C,QAAQ,CAAC,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;IAE3C,QAAQ,CAAC,OAAO,IAAI,mBAAmB;YAEzB,WAAW;IAsEnB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAmBnC,eAAe;cASC,cAAc,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;YAazD,YAAY;YAsBZ,sBAAsB;CAoCvC"}
1
+ {"version":3,"file":"database-subscriber.service.d.ts","sourceRoot":"","sources":["../../../src/services/queues/database-subscriber.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGlD,8BAAsB,kBAAkB,CAAC,CAAC,CAAE,YAAW,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC;IAM/E,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB;IACrD,SAAS,CAAC,QAAQ,CAAC,qBAAqB,EAAE,qBAAqB;IAC/D,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,aAAa;IAP5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;IAC9D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAGd,gBAAgB,EAAE,gBAAgB,EAClC,qBAAqB,EAAE,qBAAqB,EAC5C,MAAM,EAAE,aAAa;IAS5C,QAAQ,CAAC,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;IAE3C,QAAQ,CAAC,OAAO,IAAI,mBAAmB;YAEzB,WAAW;IAsEnB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBnC,eAAe;cASC,cAAc,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;YAazD,YAAY;YAsBZ,sBAAsB;CAoCvC"}
@@ -50,7 +50,8 @@ class DatabaseSubscriber {
50
50
  }
51
51
  }
52
52
  async onModuleInit() {
53
- if (['both', 'subscriber'].includes(this.serviceRole)) {
53
+ const defaultBroker = process.env.QUEUES_DEFAULT_BROKER || 'database';
54
+ if (['both', 'subscriber'].includes(this.serviceRole) && defaultBroker === 'database') {
54
55
  const options = this.options();
55
56
  const queueName = options.queueName;
56
57
  this.poller.start(queueName, (q) => this.processNext(q), {