mongodb-dynamic-api 1.3.3 → 1.4.1

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 (295) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +476 -21
  3. package/package.json +11 -1
  4. package/src/builders/casl/casl-ability.builder.d.ts +5 -0
  5. package/src/builders/casl/casl-ability.builder.js +14 -0
  6. package/src/builders/index.d.ts +3 -1
  7. package/src/builders/index.js +3 -1
  8. package/src/builders/route-decorators/auth-decorators.builder.d.ts +7 -0
  9. package/src/builders/route-decorators/auth-decorators.builder.js +14 -0
  10. package/src/builders/route-decorators/route-decorators.builder.d.ts +23 -0
  11. package/src/builders/{route-decorators.builder.js → route-decorators/route-decorators.builder.js} +45 -23
  12. package/src/decorators/check-policies.decorator.d.ts +5 -0
  13. package/src/decorators/check-policies.decorator.js +8 -0
  14. package/src/decorators/index.d.ts +2 -0
  15. package/src/decorators/index.js +2 -0
  16. package/src/decorators/public.decorator.d.ts +3 -0
  17. package/src/decorators/public.decorator.js +8 -0
  18. package/src/dynamic-api.module.d.ts +5 -4
  19. package/src/dynamic-api.module.js +132 -87
  20. package/src/guards/base-policies.guard.d.ts +13 -0
  21. package/src/guards/base-policies.guard.js +32 -0
  22. package/src/guards/dynamic-api-jwt-auth.guard.d.ts +11 -0
  23. package/src/guards/dynamic-api-jwt-auth.guard.js +38 -0
  24. package/src/guards/index.d.ts +2 -0
  25. package/src/guards/index.js +18 -0
  26. package/src/helpers/controller-ability-predicates.helper.d.ts +4 -0
  27. package/src/helpers/controller-ability-predicates.helper.js +23 -0
  28. package/src/helpers/index.d.ts +1 -0
  29. package/src/helpers/index.js +1 -0
  30. package/src/helpers/route-decorators.helper.d.ts +2 -2
  31. package/src/helpers/schema.helper.d.ts +28 -0
  32. package/src/helpers/schema.helper.js +22 -0
  33. package/src/index.d.ts +3 -1
  34. package/src/index.js +3 -1
  35. package/src/interceptors/dynamic-api-cache.interceptor.d.ts +16 -0
  36. package/src/interceptors/dynamic-api-cache.interceptor.js +48 -0
  37. package/src/interceptors/index.d.ts +1 -0
  38. package/src/interceptors/index.js +17 -0
  39. package/src/interfaces/controller-options.interface.d.ts +5 -1
  40. package/src/interfaces/decorator-builder.interface.d.ts +5 -0
  41. package/src/interfaces/dynamic-api-cache-options.interface.d.ts +1 -0
  42. package/src/interfaces/dynamic-api-casl-ability.interface.d.ts +17 -0
  43. package/src/interfaces/dynamic-api-casl-ability.interface.js +11 -0
  44. package/src/interfaces/dynamic-api-global-state.interface.d.ts +16 -0
  45. package/src/interfaces/dynamic-api-options.interface.d.ts +5 -2
  46. package/src/interfaces/dynamic-api-options.interface.js +3 -0
  47. package/src/interfaces/dynamic-api-policy-handler.interface.d.ts +16 -0
  48. package/src/interfaces/dynamic-api-route-config.interface.d.ts +7 -9
  49. package/src/interfaces/dynamic-api-route-dtos-bundle.type.d.ts +8 -0
  50. package/src/interfaces/dynamic-api-route-module.type.d.ts +3 -0
  51. package/src/interfaces/dynamic-api-route-type.type.d.ts +2 -0
  52. package/src/interfaces/index.d.ts +11 -2
  53. package/src/interfaces/index.js +11 -2
  54. package/src/mixins/create-policies-guard.mixin.d.ts +5 -0
  55. package/src/mixins/create-policies-guard.mixin.js +37 -0
  56. package/src/mixins/index.d.ts +1 -0
  57. package/src/mixins/index.js +1 -0
  58. package/src/modules/auth/auth.helper.d.ts +10 -0
  59. package/src/modules/auth/auth.helper.js +103 -0
  60. package/src/modules/auth/auth.module.d.ts +12 -0
  61. package/src/modules/auth/auth.module.js +55 -0
  62. package/src/modules/auth/guards/index.d.ts +2 -0
  63. package/src/modules/auth/guards/index.js +18 -0
  64. package/src/modules/auth/guards/jwt-auth.guard.d.ts +4 -0
  65. package/src/modules/auth/guards/jwt-auth.guard.js +17 -0
  66. package/src/modules/auth/guards/local-auth.guard.d.ts +4 -0
  67. package/src/modules/auth/guards/local-auth.guard.js +17 -0
  68. package/src/modules/auth/index.d.ts +7 -0
  69. package/src/modules/auth/index.js +23 -0
  70. package/src/modules/auth/interfaces/auth-controller.interface.d.ts +9 -0
  71. package/src/modules/auth/interfaces/auth-options.interface.d.ts +22 -0
  72. package/src/modules/auth/interfaces/auth-service.interface.d.ts +12 -0
  73. package/src/modules/auth/interfaces/index.d.ts +3 -0
  74. package/src/modules/auth/interfaces/index.js +19 -0
  75. package/src/modules/auth/mixins/auth-controller.mixin.d.ts +6 -0
  76. package/src/modules/auth/mixins/auth-controller.mixin.js +101 -0
  77. package/src/modules/auth/mixins/auth-register-policies-guard.mixin.d.ts +6 -0
  78. package/src/modules/auth/mixins/auth-register-policies-guard.mixin.js +59 -0
  79. package/src/modules/auth/mixins/index.d.ts +2 -0
  80. package/src/modules/auth/mixins/index.js +18 -0
  81. package/src/modules/auth/services/base-auth.service.d.ts +51 -0
  82. package/src/modules/auth/services/base-auth.service.js +64 -0
  83. package/src/modules/auth/services/index.d.ts +1 -0
  84. package/src/modules/auth/services/index.js +17 -0
  85. package/src/modules/auth/strategies/index.d.ts +1 -0
  86. package/src/modules/auth/strategies/index.js +17 -0
  87. package/src/modules/auth/strategies/jwt.strategy.d.ts +8 -0
  88. package/src/modules/auth/strategies/jwt.strategy.js +35 -0
  89. package/src/modules/dynamic-api-config/dynamic-api-config.module.d.ts +5 -0
  90. package/src/modules/dynamic-api-config/dynamic-api-config.module.js +31 -0
  91. package/src/modules/dynamic-api-config/index.d.ts +1 -0
  92. package/src/modules/dynamic-api-config/index.js +17 -0
  93. package/src/modules/index.d.ts +2 -11
  94. package/src/modules/index.js +2 -11
  95. package/src/routes/create-many/create-many-controller.mixin.d.ts +6 -0
  96. package/src/{modules → routes}/create-many/create-many-controller.mixin.js +26 -4
  97. package/src/{modules → routes}/create-many/create-many.helper.d.ts +2 -2
  98. package/src/{modules → routes}/create-many/create-many.helper.js +6 -4
  99. package/src/{modules → routes}/create-many/create-many.module.d.ts +1 -1
  100. package/src/{modules → routes}/create-many/create-many.module.js +2 -2
  101. package/src/routes/create-one/create-one-controller.mixin.d.ts +6 -0
  102. package/src/{modules → routes}/create-one/create-one-controller.mixin.js +25 -3
  103. package/src/{modules → routes}/create-one/create-one.helper.d.ts +2 -2
  104. package/src/{modules → routes}/create-one/create-one.helper.js +6 -4
  105. package/src/routes/create-one/create-one.module.d.ts +6 -0
  106. package/src/{modules → routes}/create-one/create-one.module.js +3 -3
  107. package/src/routes/delete-many/delete-many-controller.mixin.d.ts +6 -0
  108. package/src/{modules → routes}/delete-many/delete-many-controller.mixin.js +26 -3
  109. package/src/{modules → routes}/delete-many/delete-many.helper.d.ts +2 -2
  110. package/src/{modules → routes}/delete-many/delete-many.helper.js +6 -4
  111. package/src/routes/delete-many/delete-many.module.d.ts +6 -0
  112. package/src/{modules → routes}/delete-many/delete-many.module.js +3 -3
  113. package/src/routes/delete-one/delete-one-controller.mixin.d.ts +6 -0
  114. package/src/{modules → routes}/delete-one/delete-one-controller.mixin.js +26 -3
  115. package/src/{modules → routes}/delete-one/delete-one.helper.d.ts +2 -2
  116. package/src/{modules → routes}/delete-one/delete-one.helper.js +6 -4
  117. package/src/routes/delete-one/delete-one.module.d.ts +6 -0
  118. package/src/{modules → routes}/delete-one/delete-one.module.js +3 -3
  119. package/src/routes/duplicate-many/duplicate-many-controller.mixin.d.ts +6 -0
  120. package/src/{modules → routes}/duplicate-many/duplicate-many-controller.mixin.js +25 -3
  121. package/src/{modules → routes}/duplicate-many/duplicate-many.helper.d.ts +2 -2
  122. package/src/{modules → routes}/duplicate-many/duplicate-many.helper.js +6 -4
  123. package/src/routes/duplicate-many/duplicate-many.module.d.ts +6 -0
  124. package/src/{modules → routes}/duplicate-many/duplicate-many.module.js +3 -3
  125. package/src/routes/duplicate-one/duplicate-one-controller.mixin.d.ts +6 -0
  126. package/src/{modules → routes}/duplicate-one/duplicate-one-controller.mixin.js +25 -3
  127. package/src/{modules → routes}/duplicate-one/duplicate-one.helper.d.ts +2 -2
  128. package/src/{modules → routes}/duplicate-one/duplicate-one.helper.js +6 -4
  129. package/src/routes/duplicate-one/duplicate-one.module.d.ts +6 -0
  130. package/src/{modules → routes}/duplicate-one/duplicate-one.module.js +3 -3
  131. package/src/routes/get-many/get-many-controller.mixin.d.ts +6 -0
  132. package/src/{modules → routes}/get-many/get-many-controller.mixin.js +28 -6
  133. package/src/routes/get-many/get-many-service.interface.js +2 -0
  134. package/src/{modules → routes}/get-many/get-many.helper.d.ts +2 -2
  135. package/src/{modules → routes}/get-many/get-many.helper.js +6 -4
  136. package/src/routes/get-many/get-many.module.d.ts +6 -0
  137. package/src/{modules → routes}/get-many/get-many.module.js +3 -3
  138. package/src/routes/get-one/get-one-controller.interface.js +2 -0
  139. package/src/routes/get-one/get-one-controller.mixin.d.ts +6 -0
  140. package/src/{modules → routes}/get-one/get-one-controller.mixin.js +25 -3
  141. package/src/routes/get-one/get-one-service.interface.js +2 -0
  142. package/src/{modules → routes}/get-one/get-one.helper.d.ts +2 -2
  143. package/src/{modules → routes}/get-one/get-one.helper.js +6 -4
  144. package/src/routes/get-one/get-one.module.d.ts +6 -0
  145. package/src/{modules → routes}/get-one/get-one.module.js +3 -3
  146. package/src/routes/index.d.ts +11 -0
  147. package/src/routes/index.js +27 -0
  148. package/src/routes/replace-one/replace-one-controller.interface.js +2 -0
  149. package/src/routes/replace-one/replace-one-controller.mixin.d.ts +6 -0
  150. package/src/{modules → routes}/replace-one/replace-one-controller.mixin.js +25 -3
  151. package/src/routes/replace-one/replace-one-service.interface.js +2 -0
  152. package/src/{modules → routes}/replace-one/replace-one.helper.d.ts +2 -2
  153. package/src/{modules → routes}/replace-one/replace-one.helper.js +6 -4
  154. package/src/routes/replace-one/replace-one.module.d.ts +6 -0
  155. package/src/{modules → routes}/replace-one/replace-one.module.js +3 -3
  156. package/src/routes/update-many/update-many-controller.interface.js +2 -0
  157. package/src/routes/update-many/update-many-controller.mixin.d.ts +6 -0
  158. package/src/{modules → routes}/update-many/update-many-controller.mixin.js +25 -3
  159. package/src/routes/update-many/update-many-service.interface.js +2 -0
  160. package/src/{modules → routes}/update-many/update-many.helper.d.ts +2 -2
  161. package/src/{modules → routes}/update-many/update-many.helper.js +6 -4
  162. package/src/routes/update-many/update-many.module.d.ts +6 -0
  163. package/src/{modules → routes}/update-many/update-many.module.js +3 -3
  164. package/src/routes/update-one/update-one-controller.interface.js +2 -0
  165. package/src/routes/update-one/update-one-controller.mixin.d.ts +6 -0
  166. package/src/{modules → routes}/update-one/update-one-controller.mixin.js +25 -3
  167. package/src/routes/update-one/update-one-service.interface.js +2 -0
  168. package/src/{modules → routes}/update-one/update-one.helper.d.ts +2 -2
  169. package/src/{modules → routes}/update-one/update-one.helper.js +6 -4
  170. package/src/routes/update-one/update-one.module.d.ts +6 -0
  171. package/src/{modules → routes}/update-one/update-one.module.js +3 -3
  172. package/src/services/{base.service.d.ts → base/base.service.d.ts} +1 -1
  173. package/src/services/{base.service.js → base/base.service.js} +2 -2
  174. package/src/services/bcrypt/bcrypt.service.d.ts +5 -0
  175. package/src/services/bcrypt/bcrypt.service.js +26 -0
  176. package/src/services/dynamic-api-global-state/dynamic-api-global-state.service.d.ts +11 -0
  177. package/src/services/dynamic-api-global-state/dynamic-api-global-state.service.js +36 -0
  178. package/src/services/index.d.ts +3 -1
  179. package/src/services/index.js +3 -1
  180. package/src/version.json +1 -1
  181. package/tsconfig.tsbuildinfo +1 -1
  182. package/src/builders/route-decorators.builder.d.ts +0 -20
  183. package/src/modules/create-many/create-many-controller.mixin.d.ts +0 -6
  184. package/src/modules/create-one/create-one-controller.mixin.d.ts +0 -6
  185. package/src/modules/create-one/create-one.module.d.ts +0 -6
  186. package/src/modules/delete-many/delete-many-controller.mixin.d.ts +0 -6
  187. package/src/modules/delete-many/delete-many.module.d.ts +0 -6
  188. package/src/modules/delete-one/delete-one-controller.mixin.d.ts +0 -6
  189. package/src/modules/delete-one/delete-one.module.d.ts +0 -6
  190. package/src/modules/duplicate-many/duplicate-many-controller.mixin.d.ts +0 -6
  191. package/src/modules/duplicate-many/duplicate-many.module.d.ts +0 -6
  192. package/src/modules/duplicate-one/duplicate-one-controller.mixin.d.ts +0 -6
  193. package/src/modules/duplicate-one/duplicate-one.module.d.ts +0 -6
  194. package/src/modules/get-many/get-many-controller.mixin.d.ts +0 -6
  195. package/src/modules/get-many/get-many.module.d.ts +0 -6
  196. package/src/modules/get-one/get-one-controller.mixin.d.ts +0 -6
  197. package/src/modules/get-one/get-one.module.d.ts +0 -6
  198. package/src/modules/replace-one/replace-one-controller.mixin.d.ts +0 -6
  199. package/src/modules/replace-one/replace-one.module.d.ts +0 -6
  200. package/src/modules/update-many/update-many-controller.mixin.d.ts +0 -6
  201. package/src/modules/update-many/update-many.module.d.ts +0 -6
  202. package/src/modules/update-one/update-one-controller.mixin.d.ts +0 -6
  203. package/src/modules/update-one/update-one.module.d.ts +0 -6
  204. /package/src/{modules/create-many/create-many-controller.interface.js → interfaces/decorator-builder.interface.js} +0 -0
  205. /package/src/{modules/create-many/create-many-service.interface.js → interfaces/dynamic-api-global-state.interface.js} +0 -0
  206. /package/src/{modules/create-one/create-one-controller.interface.js → interfaces/dynamic-api-policy-handler.interface.js} +0 -0
  207. /package/src/{modules/create-one/create-one-service.interface.js → interfaces/dynamic-api-route-dtos-bundle.type.js} +0 -0
  208. /package/src/{modules/delete-many/delete-many-controller.interface.js → interfaces/dynamic-api-route-module.type.js} +0 -0
  209. /package/src/{modules/delete-many/delete-many-service.interface.js → interfaces/dynamic-api-route-type.type.js} +0 -0
  210. /package/src/modules/{delete-one/delete-one-controller.interface.js → auth/interfaces/auth-controller.interface.js} +0 -0
  211. /package/src/modules/{delete-one/delete-one-service.interface.js → auth/interfaces/auth-options.interface.js} +0 -0
  212. /package/src/modules/{duplicate-many/duplicate-many-controller.interface.js → auth/interfaces/auth-service.interface.js} +0 -0
  213. /package/src/{modules → routes}/create-many/base-create-many.service.d.ts +0 -0
  214. /package/src/{modules → routes}/create-many/base-create-many.service.js +0 -0
  215. /package/src/{modules → routes}/create-many/create-many-controller.interface.d.ts +0 -0
  216. /package/src/{modules/duplicate-many/duplicate-many-service.interface.js → routes/create-many/create-many-controller.interface.js} +0 -0
  217. /package/src/{modules → routes}/create-many/create-many-service.interface.d.ts +0 -0
  218. /package/src/{modules/duplicate-one/duplicate-one-controller.interface.js → routes/create-many/create-many-service.interface.js} +0 -0
  219. /package/src/{modules → routes}/create-many/index.d.ts +0 -0
  220. /package/src/{modules → routes}/create-many/index.js +0 -0
  221. /package/src/{modules → routes}/create-one/base-create-one.service.d.ts +0 -0
  222. /package/src/{modules → routes}/create-one/base-create-one.service.js +0 -0
  223. /package/src/{modules → routes}/create-one/create-one-controller.interface.d.ts +0 -0
  224. /package/src/{modules/duplicate-one/duplicate-one-service.interface.js → routes/create-one/create-one-controller.interface.js} +0 -0
  225. /package/src/{modules → routes}/create-one/create-one-service.interface.d.ts +0 -0
  226. /package/src/{modules/get-many/get-many-controller.interface.js → routes/create-one/create-one-service.interface.js} +0 -0
  227. /package/src/{modules → routes}/create-one/index.d.ts +0 -0
  228. /package/src/{modules → routes}/create-one/index.js +0 -0
  229. /package/src/{modules → routes}/delete-many/base-delete-many.service.d.ts +0 -0
  230. /package/src/{modules → routes}/delete-many/base-delete-many.service.js +0 -0
  231. /package/src/{modules → routes}/delete-many/delete-many-controller.interface.d.ts +0 -0
  232. /package/src/{modules/get-many/get-many-service.interface.js → routes/delete-many/delete-many-controller.interface.js} +0 -0
  233. /package/src/{modules → routes}/delete-many/delete-many-service.interface.d.ts +0 -0
  234. /package/src/{modules/get-one/get-one-controller.interface.js → routes/delete-many/delete-many-service.interface.js} +0 -0
  235. /package/src/{modules → routes}/delete-many/delete-many.presenter.d.ts +0 -0
  236. /package/src/{modules → routes}/delete-many/delete-many.presenter.js +0 -0
  237. /package/src/{modules → routes}/delete-many/index.d.ts +0 -0
  238. /package/src/{modules → routes}/delete-many/index.js +0 -0
  239. /package/src/{modules → routes}/delete-one/base-delete-one.service.d.ts +0 -0
  240. /package/src/{modules → routes}/delete-one/base-delete-one.service.js +0 -0
  241. /package/src/{modules → routes}/delete-one/delete-one-controller.interface.d.ts +0 -0
  242. /package/src/{modules/get-one/get-one-service.interface.js → routes/delete-one/delete-one-controller.interface.js} +0 -0
  243. /package/src/{modules → routes}/delete-one/delete-one-service.interface.d.ts +0 -0
  244. /package/src/{modules/replace-one/replace-one-controller.interface.js → routes/delete-one/delete-one-service.interface.js} +0 -0
  245. /package/src/{modules → routes}/delete-one/delete-one.presenter.d.ts +0 -0
  246. /package/src/{modules → routes}/delete-one/delete-one.presenter.js +0 -0
  247. /package/src/{modules → routes}/delete-one/index.d.ts +0 -0
  248. /package/src/{modules → routes}/delete-one/index.js +0 -0
  249. /package/src/{modules → routes}/duplicate-many/base-duplicate-many.service.d.ts +0 -0
  250. /package/src/{modules → routes}/duplicate-many/base-duplicate-many.service.js +0 -0
  251. /package/src/{modules → routes}/duplicate-many/duplicate-many-controller.interface.d.ts +0 -0
  252. /package/src/{modules/replace-one/replace-one-service.interface.js → routes/duplicate-many/duplicate-many-controller.interface.js} +0 -0
  253. /package/src/{modules → routes}/duplicate-many/duplicate-many-service.interface.d.ts +0 -0
  254. /package/src/{modules/update-many/update-many-controller.interface.js → routes/duplicate-many/duplicate-many-service.interface.js} +0 -0
  255. /package/src/{modules → routes}/duplicate-many/index.d.ts +0 -0
  256. /package/src/{modules → routes}/duplicate-many/index.js +0 -0
  257. /package/src/{modules → routes}/duplicate-one/base-duplicate-one.service.d.ts +0 -0
  258. /package/src/{modules → routes}/duplicate-one/base-duplicate-one.service.js +0 -0
  259. /package/src/{modules → routes}/duplicate-one/duplicate-one-controller.interface.d.ts +0 -0
  260. /package/src/{modules/update-many/update-many-service.interface.js → routes/duplicate-one/duplicate-one-controller.interface.js} +0 -0
  261. /package/src/{modules → routes}/duplicate-one/duplicate-one-service.interface.d.ts +0 -0
  262. /package/src/{modules/update-one/update-one-controller.interface.js → routes/duplicate-one/duplicate-one-service.interface.js} +0 -0
  263. /package/src/{modules → routes}/duplicate-one/index.d.ts +0 -0
  264. /package/src/{modules → routes}/duplicate-one/index.js +0 -0
  265. /package/src/{modules → routes}/get-many/base-get-many.service.d.ts +0 -0
  266. /package/src/{modules → routes}/get-many/base-get-many.service.js +0 -0
  267. /package/src/{modules → routes}/get-many/get-many-controller.interface.d.ts +0 -0
  268. /package/src/{modules/update-one/update-one-service.interface.js → routes/get-many/get-many-controller.interface.js} +0 -0
  269. /package/src/{modules → routes}/get-many/get-many-service.interface.d.ts +0 -0
  270. /package/src/{modules → routes}/get-many/index.d.ts +0 -0
  271. /package/src/{modules → routes}/get-many/index.js +0 -0
  272. /package/src/{modules → routes}/get-one/base-get-one.service.d.ts +0 -0
  273. /package/src/{modules → routes}/get-one/base-get-one.service.js +0 -0
  274. /package/src/{modules → routes}/get-one/get-one-controller.interface.d.ts +0 -0
  275. /package/src/{modules → routes}/get-one/get-one-service.interface.d.ts +0 -0
  276. /package/src/{modules → routes}/get-one/index.d.ts +0 -0
  277. /package/src/{modules → routes}/get-one/index.js +0 -0
  278. /package/src/{modules → routes}/replace-one/base-replace-one.service.d.ts +0 -0
  279. /package/src/{modules → routes}/replace-one/base-replace-one.service.js +0 -0
  280. /package/src/{modules → routes}/replace-one/index.d.ts +0 -0
  281. /package/src/{modules → routes}/replace-one/index.js +0 -0
  282. /package/src/{modules → routes}/replace-one/replace-one-controller.interface.d.ts +0 -0
  283. /package/src/{modules → routes}/replace-one/replace-one-service.interface.d.ts +0 -0
  284. /package/src/{modules → routes}/update-many/base-update-many.service.d.ts +0 -0
  285. /package/src/{modules → routes}/update-many/base-update-many.service.js +0 -0
  286. /package/src/{modules → routes}/update-many/index.d.ts +0 -0
  287. /package/src/{modules → routes}/update-many/index.js +0 -0
  288. /package/src/{modules → routes}/update-many/update-many-controller.interface.d.ts +0 -0
  289. /package/src/{modules → routes}/update-many/update-many-service.interface.d.ts +0 -0
  290. /package/src/{modules → routes}/update-one/base-update-one.service.d.ts +0 -0
  291. /package/src/{modules → routes}/update-one/base-update-one.service.js +0 -0
  292. /package/src/{modules → routes}/update-one/index.d.ts +0 -0
  293. /package/src/{modules → routes}/update-one/index.js +0 -0
  294. /package/src/{modules → routes}/update-one/update-one-controller.interface.d.ts +0 -0
  295. /package/src/{modules → routes}/update-one/update-one-service.interface.d.ts +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  Changelog
2
2
 
3
+ ## [1.4.1](https://github.com/MikeDev75015/mongodb-dynamic-api/compare/v1.4.0...v1.4.1) (2024-03-12)
4
+
5
+ ## [1.4.0](https://github.com/MikeDev75015/mongodb-dynamic-api/compare/v1.3.3...v1.4.0) (2024-03-11)
6
+
7
+
8
+ ### authentication
9
+
10
+ * **authentication:** add register ability predicate ([811b085](https://github.com/MikeDev75015/mongodb-dynamic-api/commit/811b0853ed836ce33a7a56312c3e045b5f73f5ee))
11
+
12
+
13
+ ### api
14
+
15
+ * **api:** add authentication ([a692b7b](https://github.com/MikeDev75015/mongodb-dynamic-api/commit/a692b7b0fcd774dc5152b9f82ed22107c543110a))
16
+ * **api:** add casl ability to control route access ([6202a24](https://github.com/MikeDev75015/mongodb-dynamic-api/commit/6202a247d301a7a72ce47f596a288d66724999f1))
17
+
3
18
  ## [1.3.3](https://github.com/MikeDev75015/mongodb-dynamic-api/compare/v1.3.2...v1.3.3) (2024-03-06)
4
19
 
5
20
 
package/README.md CHANGED
@@ -67,6 +67,17 @@
67
67
  npm install --save mongodb-dynamic-api
68
68
  ```
69
69
 
70
+ ___
71
+
72
+ ### Table of Contents
73
+
74
+ [Introduction](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#how-to-enjoy-it)
75
+ - [Swagger UI](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#swagger-ui-optional-but-strongly-recommended)
76
+ - [Validation](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#validation-optional)
77
+ - [Versioning](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#versioning-optional)
78
+ - [Caching](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#caching-enabled-by-default)
79
+ - [Authentication](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#authentication-optional)
80
+ - [Casl](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#casl-only-with-authentication)
70
81
 
71
82
  ---
72
83
  ### HOW TO ENJOY IT
@@ -85,13 +96,13 @@ npm i -S mongodb-dynamic-api
85
96
  - Add `DynamicApiModule.forRoot` to your `app.module.ts` and pass your **MongoDB connection string** to the method.
86
97
 
87
98
  ```typescript
88
- // app.module.ts
99
+ // src/app.module.ts
89
100
  import { DynamicApiModule } from 'mongodb-dynamic-api';
90
101
 
91
102
  @Module({
92
103
  imports: [
93
104
  DynamicApiModule.forRoot(
94
- 'mongodb://127.0.0.1:27017/dynamic-api-db', // <- replace by your own connection string
105
+ 'mongodb-uri', // <- replace by your own MongoDB connection string
95
106
  ),
96
107
  // ...
97
108
  ],
@@ -103,19 +114,19 @@ export class AppModule {}
103
114
  **Basic Usage**
104
115
 
105
116
  - Ok, now let's add our first content with just 2 files. It will be a simple `User` with a `name` and an `email` field.
106
- - We use the `@Schema` and `@Prop` decorators from the `@nestjs/mongoose` package to define our MongoDB model. <br>*See <strong>nestjs</strong> <a href="https://docs.nestjs.com/techniques/mongodb#model-injection" target="_blank">documentation</a> for more details.*
117
+ - We use the `@Schema` and `@Prop` decorators from the <a href="https://docs.nestjs.com/techniques/mongodb#model-injection" target="_blank">@nestjs/mongoose</a> package to define our MongoDB model.
107
118
 
108
119
 
109
120
  - You must extend the `BaseEntity` (or `SoftDeletableEntity`) class from the `mongodb-dynamic-api` package **for all your collection models**.
110
121
  - Just create a new file `user.ts` and add the following code.
111
122
 
112
123
  ```typescript
113
- // users/user.ts
124
+ // src/users/user.ts
114
125
  import { Prop, Schema } from '@nestjs/mongoose';
115
126
  import { BaseEntity } from 'mongodb-dynamic-api';
116
127
 
117
128
  @Schema({ collection: 'users' })
118
- export class User extends BaseEntity {
129
+ export class User extends BaseEntity { // <- extends BaseEntity
119
130
  @Prop({ type: String, required: true })
120
131
  name: string;
121
132
 
@@ -124,12 +135,12 @@ export class User extends BaseEntity {
124
135
  }
125
136
  ```
126
137
 
127
- - Then we will use the `DynamicApiModule.forFeature` method to add the `User` content.
138
+ - Then we will use the `DynamicApiModule.forFeature` method to add the `User` API to our application.
128
139
  - We pass the `User` class to the `entity` property and specify the path `users` to the `controllerOptions` property.
129
140
  - Create a new file `users.module.ts` and add the following code.
130
141
 
131
142
  ```typescript
132
- // users/users.module.ts
143
+ // src/users/users.module.ts
133
144
  import { DynamicApiModule } from 'mongodb-dynamic-api';
134
145
  import { User } from './user';
135
146
 
@@ -149,7 +160,7 @@ export class UsersModule {}
149
160
  - Last step, add the `UsersModule` to the **imports** in the `app.module.ts` after the `DynamicApiModule.forRoot` method.
150
161
 
151
162
  ```typescript
152
- // app.module.ts
163
+ // src/app.module.ts
153
164
  import { DynamicApiModule } from 'mongodb-dynamic-api';
154
165
  import { UsersModule } from './users/users.module';
155
166
 
@@ -183,6 +194,15 @@ export class AppModule {}
183
194
  | **POST /users/duplicate** <br>*Duplicate many* | `{ name?: string; email?: string; }` | x | `ids: string[]` |
184
195
  | **POST /users/duplicate/:id**<br>*Duplicate one* | `{ name?: string; email?: string; }` | `id: string` | x |
185
196
 
197
+ ___
198
+
199
+ - TOC > [Validation](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#validation-optional)
200
+ / [Versioning](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#versioning-optional)
201
+ / [Caching](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#caching-enabled-by-default)
202
+ / [Authentication](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#authentication-optional)
203
+ / [Casl](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#casl-only-with-authentication)
204
+
205
+ ___
186
206
 
187
207
  ### [Swagger UI](https://docs.nestjs.com/openapi/introduction#document-options) (optional but strongly recommended)
188
208
  `function enableDynamicAPISwagger(app: INestApplication, options?: DynamicAPISwaggerOptions): void`
@@ -190,7 +210,7 @@ export class AppModule {}
190
210
  **Configuration**
191
211
 
192
212
  ```typescript
193
- // main.ts
213
+ // src/main.ts
194
214
  import { enableDynamicAPISwagger } from 'mongodb-dynamic-api';
195
215
 
196
216
  async function bootstrap() {
@@ -212,7 +232,7 @@ Add the `@ApiProperty` | `@ApiPropertyOptional` decorators to your class propert
212
232
  <br>Let's add an optional company field to the `User` class.
213
233
 
214
234
  ```typescript
215
- // user.ts
235
+ // src/users/user.ts
216
236
  import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
217
237
 
218
238
  @Schema({ collection: 'users' })
@@ -235,16 +255,25 @@ go to the swagger API path (default to `/dynamic-api`) and you will see the auto
235
255
 
236
256
  ![User API](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README/images/dynamic-api-user-full.Jpeg?raw=true "User API")
237
257
 
238
- <a href="https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README/swagger.md" target="_blank">See more User API screenshots</a>
258
+ <a href="https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README/swagger-user-api.md" target="_blank">See more User API screenshots</a>
259
+
260
+ ___
261
+
262
+ - TOC > [Introduction](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#how-to-enjoy-it)
263
+ / [Versioning](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#versioning-optional)
264
+ / [Caching](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#caching-enabled-by-default)
265
+ / [Authentication](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#authentication-optional)
266
+ / [Casl](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#casl-only-with-authentication)
239
267
 
240
268
  ___
269
+
241
270
  ### [Validation](https://docs.nestjs.com/techniques/validation#using-the-built-in-validationpipe) (optional)
242
- `function enableDynamicAPIValidation(app: INestApplication, options?: ValidationPipeOptions): void`
271
+ <br>`function enableDynamicAPIValidation(app: INestApplication, options?: ValidationPipeOptions): void`
243
272
 
244
273
  **Configuration**
245
274
 
246
275
  ```typescript
247
- // main.ts
276
+ // src/main.ts
248
277
  import { enableDynamicAPIValidation } from 'mongodb-dynamic-api';
249
278
 
250
279
  async function bootstrap() {
@@ -262,7 +291,7 @@ or in each route object defined in the routes property.
262
291
  <br>*If the options are specified in 2, the options specified in the route will have priority.*
263
292
 
264
293
  ```typescript
265
- // users.module.ts
294
+ // src/users/users.module.ts
266
295
  import { DynamicApiModule } from 'mongodb-dynamic-api';
267
296
  import { User } from './user';
268
297
 
@@ -296,7 +325,7 @@ Use the `Class validator` <a href="https://github.com/typestack/class-validator?
296
325
  <br>Let's add `IsEmail` decorator to the `email` field.
297
326
 
298
327
  ```typescript
299
- // user.ts
328
+ // src/users/user.ts
300
329
  import { IsEmail } from 'class-validator';
301
330
 
302
331
  @Schema({ collection: 'users' })
@@ -320,8 +349,16 @@ Ok, now if you try to create a new user with an invalid email, you will get a `4
320
349
 
321
350
  ![User API Validation](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README/images/dynamic-api-validation.Jpeg?raw=true "User API Validation")
322
351
 
352
+ ___
353
+
354
+ - TOC > [Introduction](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#how-to-enjoy-it)
355
+ / [Swagger UI](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#swagger-ui-optional-but-strongly-recommended)
356
+ / [Caching](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#caching-enabled-by-default)
357
+ / [Authentication](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#authentication-optional)
358
+ / [Casl](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#casl-only-with-authentication)
323
359
 
324
360
  ___
361
+
325
362
  ### [Versioning](https://docs.nestjs.com/techniques/versioning) (optional)
326
363
  `function enableDynamicAPIVersioning(app: INestApplication, options?: VersioningOptions): void`
327
364
 
@@ -333,7 +370,7 @@ The `enableDynamicAPIVersioning` function will automatically add versioning to t
333
370
  **Configuration**
334
371
 
335
372
  ```typescript
336
- // main.ts
373
+ // src/main.ts
337
374
  import { enableDynamicAPIVersioning } from 'mongodb-dynamic-api';
338
375
 
339
376
  async function bootstrap() {
@@ -353,7 +390,7 @@ Pass the `version` property to the `controllerOptions` object or to the `route`
353
390
  Let's add a new version to the `User` content.
354
391
 
355
392
  ```typescript
356
- // create-one-user-v2.dto.ts
393
+ // src/users/create-one-user-v2.dto.ts
357
394
  import { ApiProperty, ApiPropertyOptional, PickType } from '@nestjs/swagger';
358
395
  import { IsOptional, IsString } from 'class-validator';
359
396
  import { User } from './user';
@@ -375,7 +412,7 @@ export class CreateOneUserV2Dto extends PickType(User, ['email']) {
375
412
  ```
376
413
 
377
414
  ```typescript
378
- // user-v2.presenter.ts
415
+ // src/users/user-v2.presenter.ts
379
416
  import { ApiProperty, ApiPropertyOptional, PickType } from '@nestjs/swagger';
380
417
  import { User } from './user';
381
418
 
@@ -392,7 +429,7 @@ export class UserV2Presenter extends PickType(User, ['email']) {
392
429
  ```
393
430
 
394
431
  ```typescript
395
- // users.module.ts
432
+ // src/users/users.module.ts
396
433
  import { DynamicApiModule } from 'mongodb-dynamic-api';
397
434
  import { User } from './user';
398
435
  import { CreateOneUserV2Dto } from './create-one-user-v2.dto';
@@ -428,6 +465,13 @@ Great, now you have a versioned User API, and you can access it at the `/v1/user
428
465
 
429
466
  ![User API Versioned](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README/images/dynamic-api-versioning.Jpeg?raw=true "User API Versioned")
430
467
 
468
+ ___
469
+
470
+ - TOC > [Introduction](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#how-to-enjoy-it)
471
+ / [Swagger UI](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#swagger-ui-optional-but-strongly-recommended)
472
+ / [Validation](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#validation-optional)
473
+ / [Authentication](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#authentication-optional)
474
+ / [Casl](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#casl-only-with-authentication)
431
475
 
432
476
  ___
433
477
 
@@ -439,7 +483,7 @@ By default, the caching is activated globally for all the routes. It uses the ne
439
483
  **Configuration**
440
484
 
441
485
  ```typescript
442
- // app.module.ts
486
+ // src/app.module.ts
443
487
  import { DynamicApiModule } from 'mongodb-dynamic-api';
444
488
 
445
489
  @Module({
@@ -463,7 +507,7 @@ export class AppModule {}
463
507
  **[Not recommended]** The cache can also be disabled globally with the `useGlobalCache` property set to `false` in the `DynamicApiModule.forRoot` method.
464
508
 
465
509
  ```typescript
466
- // app.module.ts
510
+ // src/app.module.ts
467
511
  import { DynamicApiModule } from 'mongodb-dynamic-api';
468
512
 
469
513
  @Module({
@@ -505,6 +549,417 @@ When you request the `/users` route with the `GET` method, the response will be
505
549
  ```
506
550
  ![Third GET request](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README/images/dynamic-api-caching-4-GET-third-request.Jpeg?raw=true "Third GET request")
507
551
 
552
+ ___
553
+
554
+ - TOC > [Introduction](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#how-to-enjoy-it)
555
+ / [Swagger UI](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#swagger-ui-optional-but-strongly-recommended)
556
+ / [Validation](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#validation-optional)
557
+ / [Versioning](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#versioning-optional)
558
+ / [Casl](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#casl-only-with-authentication)
559
+
560
+ ___
561
+
562
+ ### [Authentication](https://docs.nestjs.com/security/authorization#integrating-casl) (optional)
563
+
564
+ An authentication strategy like <a href="https://docs.nestjs.com/security/authentication#jwt-token" target="_blank">JWT</a> is already implemented in the Dynamic API.
565
+ All you have to do is to pass the User object and some options to the `useAuth` property of the `DynamicApiModule.forRoot` method.
566
+
567
+ **Configuration**
568
+
569
+ Ok, let's update our `User` class to add a `password` field.
570
+
571
+ ```typescript
572
+ // src/users/user.ts
573
+ import { IsEmail } from 'class-validator';
574
+
575
+ @Schema({ collection: 'users' })
576
+ export class User extends BaseEntity {
577
+ @ApiProperty()
578
+ @IsNotEmpty()
579
+ @IsString()
580
+ @Prop({ type: String, required: true })
581
+ email: string;
582
+
583
+ @Exclude()
584
+ @IsNotEmpty()
585
+ @IsString()
586
+ @Prop({ type: String, required: true })
587
+ password: string;
588
+
589
+ @ApiPropertyOptional({ type: Boolean, default: false })
590
+ @IsBoolean()
591
+ @IsOptional()
592
+ @Prop({ type: Boolean, default: false })
593
+ isAdmin: boolean;
594
+
595
+ @ApiPropertyOptional()
596
+ @IsNotEmpty()
597
+ @IsString()
598
+ @IsOptional()
599
+ @Prop({ type: String })
600
+ company?: string;
601
+ }
602
+ ```
603
+
604
+ Now, we are going to add the `useAuth` property to the `DynamicApiModule.forRoot` method and pass the `User` object and some options.
605
+ <br>By default, the login field is `email` and the password field is `password`. Your User class must have these fields.
606
+ <br>If you want to use other fields, you can specify them in the `user` property by passing the `loginField` and / or `passwordField` properties.
607
+
608
+ ```typescript
609
+ // src/app.module.ts
610
+ import { DynamicApiModule } from 'mongodb-dynamic-api';
611
+ import { User } from './users/user';
612
+ import { UsersModule } from './users/users.module';
613
+
614
+ @Module({
615
+ imports: [
616
+ DynamicApiModule.forRoot('...', {
617
+ // ...,
618
+ useAuth: { // <- add this
619
+ user: {
620
+ entity: User, // <- put here the entity which will represent a User of your API
621
+ },
622
+ },
623
+ }),
624
+ UsersModule,
625
+ ],
626
+ controllers: [AppController],
627
+ providers: [AppService],
628
+ })
629
+ export class AppModule {}
630
+ ```
631
+
632
+ By setting the `useAuth` property, the Dynamic API will automatically add the authentication API.
633
+ <br>It will add the `/auth/register`, `/auth/login`, and `/auth/account` routes to the API.
634
+
635
+ By default, only the `/auth/register` and `/auth/login` routes are public.
636
+ All other routes are protected and require a valid `JWT token` to access them.
637
+
638
+ **Swagger Configuration**
639
+
640
+ For Swagger users, you must enable the bearer Auth option by setting the `bearerAuth` property to `true` in the enableDynamicAPISwagger method.
641
+ This will add the Authorize button in the Swagger UI. This button will allow you to pass the `JWT Token` and unlock the protected routes.
642
+
643
+ ```typescript
644
+ // src/main.ts
645
+ import { enableDynamicAPISwagger } from 'mongodb-dynamic-api';
646
+
647
+ async function bootstrap() {
648
+ const app = await NestFactory.create(AppModule);
649
+ // ...
650
+ enableDynamicAPISwagger(app, {
651
+ // ...,
652
+ swaggerExtraConfig: { // <- add this line in your main.ts file
653
+ bearerAuth: true,
654
+ },
655
+ });
656
+
657
+ await app.listen(3000);
658
+ }
659
+ ```
660
+
661
+ ![Swagger UI - Authentication API](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README/images/dynamic-api-authentication.Jpeg?raw=true "Swagger UI - Authentication API")
662
+
663
+ <a href="https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README/swagger-authentication-api.md" target="_blank">See more Authentication API screenshots</a>
664
+
665
+
666
+ **Usage**
667
+
668
+ Ok let's add a new user with the `POST` method on the `/auth/register` route.
669
+ <br>You will receive a valid `JWT token` in the response.
670
+
671
+ ```text
672
+ POST /auth/register
673
+
674
+ curl -X 'POST' \
675
+ '<your-host>/auth/register' \
676
+ -H 'accept: application/json' \
677
+ -H 'Content-Type: application/json' \
678
+ -d '{
679
+ "email": "<your-email>",
680
+ "password": "<your-password>" // <- the password will be hashed automatically before saving in the database
681
+ }'
682
+ ```
683
+ ```json
684
+ # Server response
685
+ {"accessToken":"<your-jwt-token>"}
686
+ ```
687
+
688
+ If you go to `/auth/login` and request the route with the `POST` method passing the `email` and `password` fields in the body.
689
+ <br>You will also receive a valid `JWT token` in the response.
690
+
691
+ ```text
692
+ POST /auth/login
693
+
694
+ curl -X 'POST' \
695
+ '<your-host>/auth/login' \
696
+ -H 'accept: application/json' \
697
+ -H 'Content-Type: application/json' \
698
+ -d '{
699
+ "email": "<your-email>",
700
+ "password": "<your-password>"
701
+ }'
702
+ ```
703
+ ```json
704
+ # Server response
705
+ {"accessToken":"<your-jwt-token>"}
706
+ ```
707
+
708
+ Now let's request the `/auth/account` protected route with the `GET` method and pass our valid JWT token in the `Authorization` header.
709
+
710
+ ```text
711
+ GET /auth/account
712
+
713
+ curl -X 'GET' \
714
+ '<your-host>/auth/account' \
715
+ -H 'accept: application/json' \
716
+ -H 'Authorization: Bearer <your-jwt-token>'
717
+ ```
718
+ ```json
719
+ # Server response
720
+ {"id":"65edc717c1ec...","email":"<your-email>"}
721
+ ```
722
+
723
+ Great, now you have a fully functional authentication API.
724
+
725
+ All other routes are protected and require a valid JWT token to be accessed. You can easily make it public by adding the `isPublic` property to the `controllerOptions` object or to the `route` object in the `DynamicApiModule.forFeature` method.
726
+
727
+ ```typescript
728
+ // src/users/users.module.ts
729
+ import { DynamicApiModule } from 'mongodb-dynamic-api';
730
+ import { User } from './user';
731
+
732
+ @Module({
733
+ imports: [
734
+ DynamicApiModule.forFeature({
735
+ entity: User,
736
+ controllerOptions: {
737
+ path: 'users',
738
+ isPublic: true, // <- add this to make all user API routes public
739
+ },
740
+ // ...
741
+ }),
742
+ ],
743
+ })
744
+ export class UsersModule {}
745
+ ```
746
+ ```typescript
747
+ // src/users/users.module.ts
748
+ import { DynamicApiModule } from 'mongodb-dynamic-api';
749
+ import { User } from './user';
750
+
751
+ @Module({
752
+ imports: [
753
+ DynamicApiModule.forFeature({
754
+ entity: User,
755
+ controllerOptions: {
756
+ path: 'users',
757
+ },
758
+ routes: [
759
+ { type: 'GetMany' }, // <- protected route
760
+ { type: 'GetOne', isPublic: true }, // <- public route
761
+ { type: 'UpdateOne' }, // <- protected route
762
+ { type: 'DeleteOne' }, // <- protected route
763
+ ],
764
+ }),
765
+ ],
766
+ })
767
+ export class UsersModule {}
768
+ ```
769
+
770
+ ___
771
+
772
+ - TOC > [Introduction](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#how-to-enjoy-it)
773
+ / [Swagger UI](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#swagger-ui-optional-but-strongly-recommended)
774
+ / [Validation](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#validation-optional)
775
+ / [Versioning](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#versioning-optional)
776
+ / [Caching](https://github.com/MikeDev75015/mongodb-dynamic-api/blob/develop/README.md#caching-enabled-by-default)
777
+
778
+ ___
779
+
780
+ ### [Casl](https://docs.nestjs.com/security/authorization#integrating-casl) (only with authentication)
781
+
782
+ Casl will allow you to condition the actions of your users for each protected route of your APIs.
783
+ <br>Authentication is required, you need to enable it or implement your own strategy that adds the User object in the request.
784
+
785
+ **MongoDB dynamic API** uses the `User` object in the requests to apply the ability predicates defined in the `DynamicApiModule.forFeature`.
786
+ <br>You can define them either **in the controller options**,
787
+ or **in each route object** declared in the routes property.
788
+ <br>*If the ability predicates are specified in 2, those defined in the route will have priority.*
789
+
790
+ **An ability predicate is an arrow function that takes a subject and the User object (optional) as arguments and returns a boolean.**
791
+
792
+ Let's create a new Article content and set the ability predicates to the `UpdateOne`, `DeleteOne` and `DeleteMany` routes.
793
+
794
+ **Configuration**
795
+
796
+ ```typescript
797
+ // src/articles/article.ts
798
+ import { Prop } from '@nestjs/mongoose';
799
+ import { ApiProperty } from '@nestjs/swagger';
800
+ import { BaseEntity } from 'mongodb-dynamic-api';
801
+
802
+ export class Article extends BaseEntity {
803
+ @ApiProperty({ type: Boolean, default: false })
804
+ @Prop({ type: Boolean, default: false })
805
+ isPublished: boolean;
806
+
807
+ @ApiProperty()
808
+ @Prop({ type: String })
809
+ authorId: string;
810
+ }
811
+ ```
812
+
813
+ ```typescript
814
+ // src/articles/articles.module.ts
815
+ import { Module } from '@nestjs/common';
816
+ import { DynamicApiModule } from 'mongodb-dynamic-api';
817
+ import { User } from '../users/user';
818
+ import { Article } from './article';
819
+
820
+ @Module({
821
+ imports: [
822
+ DynamicApiModule.forFeature({
823
+ entity: Article,
824
+ controllerOptions: {
825
+ path: 'articles',
826
+ abilityPredicates: [ // <- declare the ability predicates in the controller options
827
+ {
828
+ targets: ['DeleteMany', 'DeleteOne'], // <- declare the targets
829
+ predicate: (_: Article, user: User) => user.isAdmin, // <- add the condition
830
+ },
831
+ ],
832
+ },
833
+ routes: [
834
+ { type: 'GetMany', isPublic: true },
835
+ { type: 'GetOne', isPublic: true },
836
+ { type: 'CreateOne' },
837
+ {
838
+ type: 'UpdateOne',
839
+ abilityPredicate: (article: Article, user: User) => // <- declare the ability predicate in the route object
840
+ article.authorId === user.id && !article.isPublished,
841
+ },
842
+ ],
843
+ }),
844
+ ],
845
+ })
846
+ export class ArticlesModule {}
847
+ ```
848
+
849
+ ```typescript
850
+ // src/app.module.ts
851
+ import { Module } from '@nestjs/common';
852
+ import { DynamicApiModule } from 'mongodb-dynamic-api';
853
+ import { AppController } from './app.controller';
854
+ import { AppService } from './app.service';
855
+ import { User } from './users/user';
856
+ import { ArticlesModule } from './articles/articles.module';
857
+
858
+ @Module({
859
+ imports: [
860
+ DynamicApiModule.forRoot(
861
+ 'your-mongodb-uri',
862
+ {
863
+ useAuth: {
864
+ user: {
865
+ entity: User,
866
+ additionalFields: {
867
+ toRegister: ['isAdmin'], // <- here you can set additional fields to display in the register body
868
+ toRequest: ['isAdmin', 'company'], // <- here you can set additional fields to the User object in the request
869
+ },
870
+ },
871
+ },
872
+ },
873
+ ),
874
+ ArticlesModule,
875
+ ],
876
+ controllers: [AppController],
877
+ providers: [AppService],
878
+ })
879
+ export class AppModule {}
880
+ ```
881
+
882
+
883
+ **Usage**
884
+
885
+ First, let's create an admin user with the `POST` method on the `/auth/register` public route.
886
+ ```text
887
+ POST /auth/register
888
+
889
+ curl -X 'POST' \
890
+ '<your-host>/auth/register' \
891
+ -H 'accept: application/json' \
892
+ -H 'Content-Type: application/json' \
893
+ -d '{
894
+ "email": "admin@test.co",
895
+ "isAdmin": true,
896
+ "password": "admin"
897
+ }'
898
+ ```
899
+
900
+ Then, we are going to protect the `/auth/register` route by setting the `protectRegister` property to `true` and add a **register ability predicate** in the useAuth Object of the `DynamicApiModule.forRoot` method.
901
+ ```typescript
902
+ // src/app.module.ts
903
+ @Module({
904
+ imports: [
905
+ DynamicApiModule.forRoot(
906
+ 'your-mongodb-uri',
907
+ {
908
+ useAuth: {
909
+ // ...,
910
+ protectRegister: true, // <- add this line
911
+ registerAbilityPredicate: (user: User) => user.isAdmin,
912
+ },
913
+ },
914
+ ),
915
+ ```
916
+
917
+ Ok, now let's create a non admin user with the `POST` method on the `/auth/register` route.
918
+ ```text
919
+ POST /auth/register
920
+
921
+ curl -X 'POST' \
922
+ '<your-host>/auth/register' \
923
+ -H 'accept: application/json' \
924
+ -H 'Content-Type: application/json' \
925
+ -d '{
926
+ "email": "toto@test.co",
927
+ "password": "toto"
928
+ }'
929
+ ```
930
+ ```json
931
+ # Server response
932
+ {"accessToken":"<toto-jwt-token>"}
933
+ ```
934
+
935
+ Next, under toto's account (not admin), we will try to register a new user with the `POST` method on the `/auth/register` route.
936
+ <br>The register ability predicate will return `false` and we will receive a `403 Forbidden` error.
937
+
938
+ ```text
939
+ POST /auth/register
940
+
941
+ curl -X 'POST' \
942
+ 'http://localhost:5000/auth/register' \
943
+ -H 'accept: application/json' \
944
+ -H 'Authorization: Bearer <toto-jwt-token>' \
945
+ -H 'Content-Type: application/json' \
946
+ -d '{
947
+ "email": "bill@test.co",
948
+ "password": "bill"
949
+ }'
950
+ ```
951
+ ```json
952
+ # Server response
953
+ {
954
+ "message": "Forbidden resource",
955
+ "error": "Forbidden",
956
+ "statusCode": 403
957
+ }
958
+ ```
959
+
960
+ The register route is now well protected and only an admin user can create new users.
961
+
962
+
508
963
  ___
509
964
 
510
965
  More coming soon...