arkos 1.3.1-beta → 1.3.2-beta

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 (256) hide show
  1. package/dist/cjs/app.js +139 -1
  2. package/dist/cjs/exports/auth/index.js +6 -1
  3. package/dist/cjs/exports/controllers/index.js +11 -1
  4. package/dist/cjs/exports/error-handler/index.js +11 -1
  5. package/dist/cjs/exports/index.js +12 -1
  6. package/dist/cjs/exports/middlewares/index.js +7 -1
  7. package/dist/cjs/exports/prisma/index.js +13 -1
  8. package/dist/cjs/exports/services/index.js +48 -1
  9. package/dist/cjs/exports/utils/index.js +44 -1
  10. package/dist/cjs/exports/validation/index.js +11 -1
  11. package/dist/cjs/modules/auth/auth.controller.js +229 -1
  12. package/dist/cjs/modules/auth/auth.controller.js.map +1 -1
  13. package/dist/cjs/modules/auth/auth.router.js +82 -1
  14. package/dist/cjs/modules/auth/auth.router.js.map +1 -1
  15. package/dist/cjs/modules/auth/auth.service.js +226 -1
  16. package/dist/cjs/modules/auth/utils/auth-error-objects.js +10 -1
  17. package/dist/cjs/modules/auth/utils/helpers/auth.controller.helpers.js +83 -1
  18. package/dist/cjs/modules/auth/utils/services/auth-action.service.js +92 -1
  19. package/dist/cjs/modules/auth/utils/services/auth-action.service.js.map +1 -1
  20. package/dist/cjs/modules/base/base.controller.js +172 -1
  21. package/dist/cjs/modules/base/base.middlewares.js +92 -1
  22. package/dist/cjs/modules/base/base.router.js +22 -1
  23. package/dist/cjs/modules/base/base.service.js +507 -1
  24. package/dist/cjs/modules/base/base.service.js.map +1 -1
  25. package/dist/cjs/modules/base/types/base.service.types.js +3 -1
  26. package/dist/cjs/modules/base/types/base.service.types.js.map +1 -1
  27. package/dist/cjs/modules/base/utils/helpers/base.controller.helpers.js +80 -1
  28. package/dist/cjs/modules/base/utils/helpers/base.middlewares.helpers.js +50 -1
  29. package/dist/cjs/modules/base/utils/helpers/base.router.helpers.js +104 -1
  30. package/dist/cjs/modules/base/utils/helpers/base.service.helpers.js +208 -1
  31. package/dist/cjs/modules/base/utils/router-validator.js +16 -1
  32. package/dist/cjs/modules/base/utils/service-hooks-manager.js +19 -1
  33. package/dist/cjs/modules/email/email.service.js +104 -1
  34. package/dist/cjs/modules/error-handler/error-handler.controller.js +146 -4
  35. package/dist/cjs/modules/error-handler/utils/app-error.js +17 -1
  36. package/dist/cjs/modules/error-handler/utils/catch-async.js +21 -1
  37. package/dist/cjs/modules/error-handler/utils/error-handler.helpers.js +205 -3
  38. package/dist/cjs/modules/file-upload/file-upload.controller.js +233 -1
  39. package/dist/cjs/modules/file-upload/file-upload.router.js +60 -1
  40. package/dist/cjs/modules/file-upload/file-upload.service.js +322 -1
  41. package/dist/cjs/modules/file-upload/utils/helpers/file-upload.helpers.js +97 -1
  42. package/dist/cjs/modules/swagger/swagger.router.js +38 -1
  43. package/dist/cjs/modules/swagger/utils/helpers/get-authentication-json-schema-paths.js +338 -1
  44. package/dist/cjs/modules/swagger/utils/helpers/get-swagger-default-configs.js +64 -1
  45. package/dist/cjs/modules/swagger/utils/helpers/get-system-json-schema-paths.js +37 -1
  46. package/dist/cjs/modules/swagger/utils/helpers/json-schema-generators/generate-class-validator-json-schemas.js +48 -1
  47. package/dist/cjs/modules/swagger/utils/helpers/json-schema-generators/generate-prisma-json-schemas.js +32 -1
  48. package/dist/cjs/modules/swagger/utils/helpers/json-schema-generators/generate-system-json-schemas.js +49 -1
  49. package/dist/cjs/modules/swagger/utils/helpers/json-schema-generators/generate-zod-json-schemas.js +34 -1
  50. package/dist/cjs/modules/swagger/utils/helpers/json-schema-generators/prisma-models/generate-prisma-model-main-routes-paths.js +471 -1
  51. package/dist/cjs/modules/swagger/utils/helpers/json-schema-generators/prisma-models/generate-prisma-model-parent-routes-paths.js +572 -1
  52. package/dist/cjs/modules/swagger/utils/helpers/missing-json-schemas-generator.js +260 -1
  53. package/dist/cjs/modules/swagger/utils/helpers/swagger.router.helpers.js +112 -1
  54. package/dist/cjs/paths.js +9 -1
  55. package/dist/cjs/server.js +94 -5
  56. package/dist/cjs/types/arkos-config.js +3 -1
  57. package/dist/cjs/types/arkos-config.js.map +1 -1
  58. package/dist/cjs/types/auth.js +3 -1
  59. package/dist/cjs/types/index.js +11 -1
  60. package/dist/cjs/types/router-config.js +3 -1
  61. package/dist/cjs/utils/arkos-env.js +9 -1
  62. package/dist/cjs/utils/cli/build.js +214 -5
  63. package/dist/cjs/utils/cli/dev.js +154 -3
  64. package/dist/cjs/utils/cli/generate.js +109 -1
  65. package/dist/cjs/utils/cli/index.js +104 -1
  66. package/dist/cjs/utils/cli/index.js.map +1 -1
  67. package/dist/cjs/utils/cli/prisma-generate.js +120 -0
  68. package/dist/cjs/utils/cli/prisma-generate.js.map +1 -0
  69. package/dist/cjs/utils/cli/start.js +103 -1
  70. package/dist/cjs/utils/cli/utils/cli.helpers.js +24 -1
  71. package/dist/cjs/utils/cli/utils/smart-fs-watcher.js +73 -1
  72. package/dist/cjs/utils/cli/utils/template-generator/templates/auth-configs-template.js +36 -0
  73. package/dist/cjs/utils/cli/utils/template-generator/templates/auth-configs-template.js.map +1 -0
  74. package/dist/cjs/utils/cli/utils/template-generator/templates/controller-template.js +21 -0
  75. package/dist/cjs/utils/cli/utils/template-generator/templates/controller-template.js.map +1 -0
  76. package/dist/cjs/utils/cli/utils/template-generator/templates/hooks-template.js +201 -0
  77. package/dist/cjs/utils/cli/utils/template-generator/templates/hooks-template.js.map +1 -0
  78. package/dist/cjs/utils/cli/utils/template-generator/templates/middlewares-template.js +288 -0
  79. package/dist/cjs/utils/cli/utils/template-generator/templates/{generate-middlewares.js.map → middlewares-template.js.map} +1 -1
  80. package/dist/cjs/utils/cli/utils/template-generator/templates/query-options-template.js +64 -0
  81. package/dist/cjs/utils/cli/utils/template-generator/templates/query-options-template.js.map +1 -0
  82. package/dist/cjs/utils/cli/utils/template-generator/templates/router-template.js +45 -0
  83. package/dist/cjs/utils/cli/utils/template-generator/templates/router-template.js.map +1 -0
  84. package/dist/cjs/utils/cli/utils/template-generator/templates/service-template.js +29 -0
  85. package/dist/cjs/utils/cli/utils/template-generator/templates/service-template.js.map +1 -0
  86. package/dist/cjs/utils/cli/utils/template-generators.js +34 -2
  87. package/dist/cjs/utils/cli/utils/template-generators.js.map +1 -1
  88. package/dist/cjs/utils/cli/utils/watermark-stamper.js +17 -3
  89. package/dist/cjs/utils/dotenv.helpers.js +43 -1
  90. package/dist/cjs/utils/dynamic-loader.js +270 -9
  91. package/dist/cjs/utils/features/api.features.js +169 -1
  92. package/dist/cjs/utils/features/change-case.features.js +67 -1
  93. package/dist/cjs/utils/features/port-and-host-allocator.js +105 -1
  94. package/dist/cjs/utils/helpers/api.features.helpers.js +112 -1
  95. package/dist/cjs/utils/helpers/change-case.helpers.js +177 -1
  96. package/dist/cjs/utils/helpers/deepmerge.helper.js +115 -1
  97. package/dist/cjs/utils/helpers/dynamic-loader.helpers.js +76 -1
  98. package/dist/cjs/utils/helpers/fs.helpers.js +57 -1
  99. package/dist/cjs/utils/helpers/global.helpers.js +94 -1
  100. package/dist/cjs/utils/helpers/prisma.helpers.js +40 -1
  101. package/dist/cjs/utils/helpers/query-parser.helpers.js +45 -1
  102. package/dist/cjs/utils/helpers/routers.helpers.js +37 -1
  103. package/dist/cjs/utils/helpers/text.helpers.js +28 -1
  104. package/dist/cjs/utils/prisma/prisma-json-schema-generator.js +455 -1
  105. package/dist/cjs/utils/prisma/prisma-schema-parser.js +216 -4
  106. package/dist/cjs/utils/prisma/types.js +3 -1
  107. package/dist/cjs/utils/sheu.js +120 -1
  108. package/dist/cjs/utils/validate-dto.js +17 -1
  109. package/dist/cjs/utils/validate-schema.js +15 -1
  110. package/dist/esm/app.js +132 -1
  111. package/dist/esm/exports/auth/index.js +2 -1
  112. package/dist/esm/exports/controllers/index.js +4 -1
  113. package/dist/esm/exports/error-handler/index.js +4 -1
  114. package/dist/esm/exports/index.js +8 -1
  115. package/dist/esm/exports/middlewares/index.js +2 -1
  116. package/dist/esm/exports/prisma/index.js +6 -1
  117. package/dist/esm/exports/services/index.js +9 -1
  118. package/dist/esm/exports/utils/index.js +4 -1
  119. package/dist/esm/exports/validation/index.js +4 -1
  120. package/dist/esm/modules/auth/auth.controller.js +222 -1
  121. package/dist/esm/modules/auth/auth.controller.js.map +1 -1
  122. package/dist/esm/modules/auth/auth.router.js +76 -1
  123. package/dist/esm/modules/auth/auth.router.js.map +1 -1
  124. package/dist/esm/modules/auth/auth.service.js +219 -1
  125. package/dist/esm/modules/auth/utils/auth-error-objects.js +4 -1
  126. package/dist/esm/modules/auth/utils/helpers/auth.controller.helpers.js +73 -1
  127. package/dist/esm/modules/auth/utils/services/auth-action.service.js +90 -1
  128. package/dist/esm/modules/auth/utils/services/auth-action.service.js.map +1 -1
  129. package/dist/esm/modules/base/base.controller.js +165 -1
  130. package/dist/esm/modules/base/base.middlewares.js +81 -1
  131. package/dist/esm/modules/base/base.router.js +15 -1
  132. package/dist/esm/modules/base/base.service.js +500 -1
  133. package/dist/esm/modules/base/base.service.js.map +1 -1
  134. package/dist/esm/modules/base/types/base.service.types.js +2 -1
  135. package/dist/esm/modules/base/types/base.service.types.js.map +1 -1
  136. package/dist/esm/modules/base/utils/helpers/base.controller.helpers.js +76 -1
  137. package/dist/esm/modules/base/utils/helpers/base.middlewares.helpers.js +44 -1
  138. package/dist/esm/modules/base/utils/helpers/base.router.helpers.js +96 -1
  139. package/dist/esm/modules/base/utils/helpers/base.service.helpers.js +198 -1
  140. package/dist/esm/modules/base/utils/router-validator.js +14 -1
  141. package/dist/esm/modules/base/utils/service-hooks-manager.js +17 -1
  142. package/dist/esm/modules/email/email.service.js +97 -1
  143. package/dist/esm/modules/error-handler/error-handler.controller.js +107 -4
  144. package/dist/esm/modules/error-handler/utils/app-error.js +15 -1
  145. package/dist/esm/modules/error-handler/utils/catch-async.js +19 -1
  146. package/dist/esm/modules/error-handler/utils/error-handler.helpers.js +163 -3
  147. package/dist/esm/modules/file-upload/file-upload.controller.js +228 -1
  148. package/dist/esm/modules/file-upload/file-upload.router.js +54 -1
  149. package/dist/esm/modules/file-upload/file-upload.service.js +314 -1
  150. package/dist/esm/modules/file-upload/utils/helpers/file-upload.helpers.js +87 -1
  151. package/dist/esm/modules/swagger/swagger.router.js +32 -1
  152. package/dist/esm/modules/swagger/utils/helpers/get-authentication-json-schema-paths.js +333 -1
  153. package/dist/esm/modules/swagger/utils/helpers/get-swagger-default-configs.js +58 -1
  154. package/dist/esm/modules/swagger/utils/helpers/get-system-json-schema-paths.js +34 -1
  155. package/dist/esm/modules/swagger/utils/helpers/json-schema-generators/generate-class-validator-json-schemas.js +42 -1
  156. package/dist/esm/modules/swagger/utils/helpers/json-schema-generators/generate-prisma-json-schemas.js +26 -1
  157. package/dist/esm/modules/swagger/utils/helpers/json-schema-generators/generate-system-json-schemas.js +46 -1
  158. package/dist/esm/modules/swagger/utils/helpers/json-schema-generators/generate-zod-json-schemas.js +28 -1
  159. package/dist/esm/modules/swagger/utils/helpers/json-schema-generators/prisma-models/generate-prisma-model-main-routes-paths.js +465 -1
  160. package/dist/esm/modules/swagger/utils/helpers/json-schema-generators/prisma-models/generate-prisma-model-parent-routes-paths.js +566 -1
  161. package/dist/esm/modules/swagger/utils/helpers/missing-json-schemas-generator.js +255 -1
  162. package/dist/esm/modules/swagger/utils/helpers/swagger.router.helpers.js +101 -1
  163. package/dist/esm/paths.js +3 -1
  164. package/dist/esm/server.js +85 -5
  165. package/dist/esm/types/arkos-config.js +2 -1
  166. package/dist/esm/types/arkos-config.js.map +1 -1
  167. package/dist/esm/types/auth.js +2 -1
  168. package/dist/esm/types/index.js +8 -1
  169. package/dist/esm/types/router-config.js +2 -1
  170. package/dist/esm/utils/arkos-env.js +7 -1
  171. package/dist/esm/utils/cli/build.js +208 -5
  172. package/dist/esm/utils/cli/dev.js +147 -3
  173. package/dist/esm/utils/cli/generate.js +103 -1
  174. package/dist/esm/utils/cli/index.js +94 -1
  175. package/dist/esm/utils/cli/index.js.map +1 -1
  176. package/dist/esm/utils/cli/prisma-generate.js +114 -0
  177. package/dist/esm/utils/cli/prisma-generate.js.map +1 -0
  178. package/dist/esm/utils/cli/start.js +96 -1
  179. package/dist/esm/utils/cli/utils/cli.helpers.js +16 -1
  180. package/dist/esm/utils/cli/utils/smart-fs-watcher.js +68 -1
  181. package/dist/esm/utils/cli/utils/template-generator/templates/auth-configs-template.js +33 -0
  182. package/dist/esm/utils/cli/utils/template-generator/templates/auth-configs-template.js.map +1 -0
  183. package/dist/esm/utils/cli/utils/template-generator/templates/controller-template.js +18 -0
  184. package/dist/esm/utils/cli/utils/template-generator/templates/controller-template.js.map +1 -0
  185. package/dist/esm/utils/cli/utils/template-generator/templates/hooks-template.js +198 -0
  186. package/dist/esm/utils/cli/utils/template-generator/templates/hooks-template.js.map +1 -0
  187. package/dist/esm/utils/cli/utils/template-generator/templates/middlewares-template.js +285 -0
  188. package/dist/esm/utils/cli/utils/template-generator/templates/{generate-middlewares.js.map → middlewares-template.js.map} +1 -1
  189. package/dist/esm/utils/cli/utils/template-generator/templates/query-options-template.js +61 -0
  190. package/dist/esm/utils/cli/utils/template-generator/templates/query-options-template.js.map +1 -0
  191. package/dist/esm/utils/cli/utils/template-generator/templates/router-template.js +39 -0
  192. package/dist/esm/utils/cli/utils/template-generator/templates/router-template.js.map +1 -0
  193. package/dist/esm/utils/cli/utils/template-generator/templates/service-template.js +26 -0
  194. package/dist/esm/utils/cli/utils/template-generator/templates/service-template.js.map +1 -0
  195. package/dist/esm/utils/cli/utils/template-generators.js +28 -2
  196. package/dist/esm/utils/cli/utils/template-generators.js.map +1 -1
  197. package/dist/esm/utils/cli/utils/watermark-stamper.js +15 -3
  198. package/dist/esm/utils/dotenv.helpers.js +37 -1
  199. package/dist/esm/utils/dynamic-loader.js +254 -9
  200. package/dist/esm/utils/features/api.features.js +162 -1
  201. package/dist/esm/utils/features/change-case.features.js +31 -1
  202. package/dist/esm/utils/features/port-and-host-allocator.js +67 -1
  203. package/dist/esm/utils/helpers/api.features.helpers.js +106 -1
  204. package/dist/esm/utils/helpers/change-case.helpers.js +161 -1
  205. package/dist/esm/utils/helpers/deepmerge.helper.js +113 -1
  206. package/dist/esm/utils/helpers/dynamic-loader.helpers.js +69 -1
  207. package/dist/esm/utils/helpers/fs.helpers.js +48 -1
  208. package/dist/esm/utils/helpers/global.helpers.js +51 -1
  209. package/dist/esm/utils/helpers/prisma.helpers.js +32 -1
  210. package/dist/esm/utils/helpers/query-parser.helpers.js +40 -1
  211. package/dist/esm/utils/helpers/routers.helpers.js +29 -1
  212. package/dist/esm/utils/helpers/text.helpers.js +22 -1
  213. package/dist/esm/utils/prisma/prisma-json-schema-generator.js +448 -1
  214. package/dist/esm/utils/prisma/prisma-schema-parser.js +209 -4
  215. package/dist/esm/utils/prisma/types.js +2 -1
  216. package/dist/esm/utils/sheu.js +118 -1
  217. package/dist/esm/utils/validate-dto.js +11 -1
  218. package/dist/esm/utils/validate-schema.js +9 -1
  219. package/dist/types/modules/auth/utils/services/auth-action.service.d.ts +1 -1
  220. package/dist/types/modules/base/types/base.service.types.d.ts +12 -9
  221. package/dist/types/types/arkos-config.d.ts +3 -2
  222. package/dist/types/utils/cli/prisma-generate.d.ts +1 -0
  223. package/package.json +2 -2
  224. package/dist/cjs/utils/cli/utils/template-generator/templates/generate-auth-configs-template.js +0 -21
  225. package/dist/cjs/utils/cli/utils/template-generator/templates/generate-auth-configs-template.js.map +0 -1
  226. package/dist/cjs/utils/cli/utils/template-generator/templates/generate-controller-template.js +0 -12
  227. package/dist/cjs/utils/cli/utils/template-generator/templates/generate-controller-template.js.map +0 -1
  228. package/dist/cjs/utils/cli/utils/template-generator/templates/generate-hooks-template.js +0 -144
  229. package/dist/cjs/utils/cli/utils/template-generator/templates/generate-hooks-template.js.map +0 -1
  230. package/dist/cjs/utils/cli/utils/template-generator/templates/generate-middlewares.js +0 -256
  231. package/dist/cjs/utils/cli/utils/template-generator/templates/generate-prisma-query-options.js +0 -36
  232. package/dist/cjs/utils/cli/utils/template-generator/templates/generate-prisma-query-options.js.map +0 -1
  233. package/dist/cjs/utils/cli/utils/template-generator/templates/generate-router-template.js +0 -18
  234. package/dist/cjs/utils/cli/utils/template-generator/templates/generate-router-template.js.map +0 -1
  235. package/dist/cjs/utils/cli/utils/template-generator/templates/generate-service-template.js +0 -9
  236. package/dist/cjs/utils/cli/utils/template-generator/templates/generate-service-template.js.map +0 -1
  237. package/dist/esm/utils/cli/utils/template-generator/templates/generate-auth-configs-template.js +0 -21
  238. package/dist/esm/utils/cli/utils/template-generator/templates/generate-auth-configs-template.js.map +0 -1
  239. package/dist/esm/utils/cli/utils/template-generator/templates/generate-controller-template.js +0 -12
  240. package/dist/esm/utils/cli/utils/template-generator/templates/generate-controller-template.js.map +0 -1
  241. package/dist/esm/utils/cli/utils/template-generator/templates/generate-hooks-template.js +0 -144
  242. package/dist/esm/utils/cli/utils/template-generator/templates/generate-hooks-template.js.map +0 -1
  243. package/dist/esm/utils/cli/utils/template-generator/templates/generate-middlewares.js +0 -256
  244. package/dist/esm/utils/cli/utils/template-generator/templates/generate-prisma-query-options.js +0 -36
  245. package/dist/esm/utils/cli/utils/template-generator/templates/generate-prisma-query-options.js.map +0 -1
  246. package/dist/esm/utils/cli/utils/template-generator/templates/generate-router-template.js +0 -18
  247. package/dist/esm/utils/cli/utils/template-generator/templates/generate-router-template.js.map +0 -1
  248. package/dist/esm/utils/cli/utils/template-generator/templates/generate-service-template.js +0 -9
  249. package/dist/esm/utils/cli/utils/template-generator/templates/generate-service-template.js.map +0 -1
  250. /package/dist/types/utils/cli/utils/template-generator/templates/{generate-auth-configs-template.d.ts → auth-configs-template.d.ts} +0 -0
  251. /package/dist/types/utils/cli/utils/template-generator/templates/{generate-controller-template.d.ts → controller-template.d.ts} +0 -0
  252. /package/dist/types/utils/cli/utils/template-generator/templates/{generate-hooks-template.d.ts → hooks-template.d.ts} +0 -0
  253. /package/dist/types/utils/cli/utils/template-generator/templates/{generate-middlewares.d.ts → middlewares-template.d.ts} +0 -0
  254. /package/dist/types/utils/cli/utils/template-generator/templates/{generate-prisma-query-options.d.ts → query-options-template.d.ts} +0 -0
  255. /package/dist/types/utils/cli/utils/template-generator/templates/{generate-router-template.d.ts → router-template.d.ts} +0 -0
  256. /package/dist/types/utils/cli/utils/template-generator/templates/{generate-service-template.d.ts → service-template.d.ts} +0 -0
@@ -1 +1,219 @@
1
- "use strict";import l from"jsonwebtoken";import h from"bcryptjs";import m from"../error-handler/utils/catch-async.js";import c from"../error-handler/utils/app-error.js";import{callNext as y}from"../base/base.middlewares.js";import{getArkosConfig as n}from"../../server.js";import d from"../../utils/arkos-env.js";import{getPrismaInstance as p}from"../../utils/helpers/prisma.helpers.js";import{appModules as T,getModuleComponents as P}from"../../utils/dynamic-loader.js";import{kebabCase as w}from"../../exports/utils/index.js";import{invaliAuthTokenError as g,loginRequiredError as E}from"./utils/auth-error-objects.js";import k from"./utils/services/auth-action.service.js";export class AuthService{constructor(){this.actionsPerResource={},this.authenticate=m(async(e,t,r)=>{if(!n()?.authentication){r();return}e.user=await this.getAuthenticatedUser(e),r()})}signJwtToken(e,t,r){const{authentication:s}=n();if(process.env.NODE_ENV==="production"&&!process.env.JWT_SECRET&&!s?.jwt?.secret)throw new c("Missing JWT secret on production!",500,{},"MissingJWTOnProduction");return r=r||s?.jwt?.secret||process.env.JWT_SECRET||d.JWT_SECRET,t=t||s?.jwt?.expiresIn||process.env.JWT_EXPIRES_IN||d.JWT_EXPIRES_IN,l.sign({id:e},r,{expiresIn:t})}isPasswordHashed(e){return!Number.isNaN(h.getRounds(e)*1)}async isCorrectPassword(e,t){return await h.compare(e,t)}async hashPassword(e){return await h.hash(e,12)}isPasswordStrong(e){return(n()?.authentication?.passwordValidation?.regex||/^(?=.*[A-Z])(?=.*[a-z])(?=.*\d).+$/).test(e)}userChangedPasswordAfter(e,t){if(e.passwordChangedAt){const r=parseInt(String(e.passwordChangedAt.getTime()/1e3),10);return t<r}return!1}async verifyJwtToken(e,t){const{authentication:r}=n();if(process.env.NODE_ENV==="production"&&!process.env.JWT_SECRET&&!r?.jwt?.secret)throw new c("Missing JWT secret!",500);return t=t||r?.jwt?.secret||process.env.JWT_SECRET||d.JWT_SECRET,new Promise((s,o)=>{l.verify(e,t,(i,a)=>{i?o(i):s(a)})})}checkStaticAccessControl(e,t,r){if(!e?.role&&!e.roles)throw Error("Validation Error: In order to use static authentication user needs at least role field or roles for multiple roles.");let s=[];return Array.isArray(r)?s=r:r[t]&&(s=Array.isArray(r[t])?r[t]:r[t].roles),!!(Array.isArray(e?.roles)?e.roles:[e.role]).some(i=>s.includes(i))}async checkDynamicAccessControl(e,t,r){return!!await p().userRole.findFirst({where:{userId:e,role:{permissions:{some:{resource:r,action:t}}}},select:{id:!0}})}handleAccessControl(e,t,r){return k.add(e,t,r),m(async(s,o,i)=>{if(s.user){const a=s.user,f=n();if(a.isSuperUser){i();return}const u=new c("You do not have permission to perfom this action",403,{},"NotEnoughPermissions");if(f?.authentication?.mode==="dynamic"){if(!await this.checkDynamicAccessControl(a.id,e,t))return i(u)}else if(f?.authentication?.mode==="static"&&(!r||!this.checkStaticAccessControl(a,e,r)))return i(u)}i()})}async getAuthenticatedUser(e){if(!n()?.authentication)return null;const r=p();let s;if(e?.headers?.authorization&&e?.headers?.authorization.startsWith("Bearer")?s=e?.headers?.authorization.split(" ")[1]:e?.cookies?.arkos_access_token!=="no-token"&&e.cookies&&(s=e?.cookies?.arkos_access_token),!s)throw E;let o;try{o=await this.verifyJwtToken(s)}catch{throw g}if(!o?.id)throw g;const i=await r.user.findUnique({where:{id:String(o.id)}});if(!i)throw new c("The user belonging to this token does no longer exists",401,{},"UserNoLongerExists");if(this.userChangedPasswordAfter(i,o.iat)&&!e.path?.includes?.("logout"))throw new c("User recently changed password! Please log in again.",401,{},"PasswordChanged");return e.accessToken=s,i}handleAuthenticationControl(e,t){if(t&&typeof t=="object"){if(t[e]===!1)return y;if(t[e]===!0)return this.authenticate}else return this.authenticate;return this.authenticate}permission(e,t,r){if(new Error().stack?.includes("node_modules/express/lib/router/index.js"))throw new Error("authService.permission() should be called during application initialization level.");return k.add(e,t,r),async o=>{const i=n();if(!i?.authentication)throw Error("Validation Error: Trying to use authService.permission without setting up authentication.");if(!o)throw E;return o.isSuperUser?!0:i?.authentication?.mode==="dynamic"?await this.checkDynamicAccessControl(o?.id,e,t):i?.authentication?.mode==="static"?(!r&&T.includes(w(t))&&(r=P(w(t))?.authConfigs?.accessControl),!!r&&this.checkStaticAccessControl(o,e,r)):!1}}}const S=new AuthService;export default S;
1
+ import jwt from "jsonwebtoken";
2
+ import bcrypt from "bcryptjs";
3
+ import catchAsync from "../error-handler/utils/catch-async.js";
4
+ import AppError from "../error-handler/utils/app-error.js";
5
+ import { callNext } from "../base/base.middlewares.js";
6
+ import { getArkosConfig } from "../../server.js";
7
+ import arkosEnv from "../../utils/arkos-env.js";
8
+ import { getPrismaInstance } from "../../utils/helpers/prisma.helpers.js";
9
+ import { appModules, getModuleComponents } from "../../utils/dynamic-loader.js";
10
+ import { kebabCase } from "../../exports/utils/index.js";
11
+ import { invaliAuthTokenError, loginRequiredError, } from "./utils/auth-error-objects.js";
12
+ import authActionService from "./utils/services/auth-action.service.js";
13
+ export class AuthService {
14
+ constructor() {
15
+ this.actionsPerResource = {};
16
+ this.authenticate = catchAsync(async (req, _, next) => {
17
+ const arkosConfig = getArkosConfig();
18
+ if (!arkosConfig?.authentication) {
19
+ next();
20
+ return;
21
+ }
22
+ req.user = (await this.getAuthenticatedUser(req));
23
+ next();
24
+ });
25
+ }
26
+ signJwtToken(id, expiresIn, secret) {
27
+ const { authentication: configs } = getArkosConfig();
28
+ if (process.env.NODE_ENV === "production" &&
29
+ !process.env.JWT_SECRET &&
30
+ !configs?.jwt?.secret)
31
+ throw new AppError("Missing JWT secret on production!", 500, {}, "MissingJWTOnProduction");
32
+ secret =
33
+ secret ||
34
+ configs?.jwt?.secret ||
35
+ process.env.JWT_SECRET ||
36
+ arkosEnv.JWT_SECRET;
37
+ expiresIn = (expiresIn ||
38
+ configs?.jwt?.expiresIn ||
39
+ process.env.JWT_EXPIRES_IN ||
40
+ arkosEnv.JWT_EXPIRES_IN);
41
+ return jwt.sign({ id }, secret, {
42
+ expiresIn: expiresIn,
43
+ });
44
+ }
45
+ isPasswordHashed(password) {
46
+ return !Number.isNaN(bcrypt.getRounds(password) * 1);
47
+ }
48
+ async isCorrectPassword(candidatePassword, userPassword) {
49
+ return await bcrypt.compare(candidatePassword, userPassword);
50
+ }
51
+ async hashPassword(password) {
52
+ return await bcrypt.hash(password, 12);
53
+ }
54
+ isPasswordStrong(password) {
55
+ const initAuthConfigs = getArkosConfig()?.authentication;
56
+ const strongPasswordRegex = initAuthConfigs?.passwordValidation?.regex ||
57
+ /^(?=.*[A-Z])(?=.*[a-z])(?=.*\d).+$/;
58
+ return strongPasswordRegex.test(password);
59
+ }
60
+ userChangedPasswordAfter(user, JWTTimestamp) {
61
+ if (user.passwordChangedAt) {
62
+ const convertedTimestamp = parseInt(String(user.passwordChangedAt.getTime() / 1000), 10);
63
+ return JWTTimestamp < convertedTimestamp;
64
+ }
65
+ return false;
66
+ }
67
+ async verifyJwtToken(token, secret) {
68
+ const { authentication: configs } = getArkosConfig();
69
+ if (process.env.NODE_ENV === "production" &&
70
+ !process.env.JWT_SECRET &&
71
+ !configs?.jwt?.secret)
72
+ throw new AppError("Missing JWT secret!", 500);
73
+ secret =
74
+ secret ||
75
+ configs?.jwt?.secret ||
76
+ process.env.JWT_SECRET ||
77
+ arkosEnv.JWT_SECRET;
78
+ return new Promise((resolve, reject) => {
79
+ jwt.verify(token, secret, (err, decoded) => {
80
+ if (err)
81
+ reject(err);
82
+ else
83
+ resolve(decoded);
84
+ });
85
+ });
86
+ }
87
+ checkStaticAccessControl(user, action, accessControl) {
88
+ if (!user?.role && !user.roles)
89
+ throw Error("Validation Error: In order to use static authentication user needs at least role field or roles for multiple roles.");
90
+ let authorizedRoles = [];
91
+ if (Array.isArray(accessControl))
92
+ authorizedRoles = accessControl;
93
+ else if (accessControl[action])
94
+ authorizedRoles = Array.isArray(accessControl[action])
95
+ ? accessControl[action]
96
+ : accessControl[action].roles;
97
+ const userRoles = Array.isArray(user?.roles) ? user.roles : [user.role];
98
+ return !!userRoles.some((role) => authorizedRoles.includes(role));
99
+ }
100
+ async checkDynamicAccessControl(userId, action, resource) {
101
+ const prisma = getPrismaInstance();
102
+ return !!(await prisma.userRole.findFirst({
103
+ where: {
104
+ userId,
105
+ role: {
106
+ permissions: {
107
+ some: {
108
+ resource,
109
+ action,
110
+ },
111
+ },
112
+ },
113
+ },
114
+ select: { id: true },
115
+ }));
116
+ }
117
+ handleAccessControl(action, resource, accessControl) {
118
+ authActionService.add(action, resource, accessControl);
119
+ return catchAsync(async (req, _, next) => {
120
+ if (req.user) {
121
+ const user = req.user;
122
+ const configs = getArkosConfig();
123
+ if (user.isSuperUser) {
124
+ next();
125
+ return;
126
+ }
127
+ const notEnoughPermissionsError = new AppError("You do not have permission to perfom this action", 403, {}, "NotEnoughPermissions");
128
+ if (configs?.authentication?.mode === "dynamic") {
129
+ const hasPermission = await this.checkDynamicAccessControl(user.id, action, resource);
130
+ if (!hasPermission)
131
+ return next(notEnoughPermissionsError);
132
+ }
133
+ else if (configs?.authentication?.mode === "static") {
134
+ if (!accessControl)
135
+ return next(notEnoughPermissionsError);
136
+ const hasPermission = this.checkStaticAccessControl(user, action, accessControl);
137
+ if (!hasPermission)
138
+ return next(notEnoughPermissionsError);
139
+ }
140
+ }
141
+ next();
142
+ });
143
+ }
144
+ async getAuthenticatedUser(req) {
145
+ const arkosConfig = getArkosConfig();
146
+ if (!arkosConfig?.authentication)
147
+ return null;
148
+ const prisma = getPrismaInstance();
149
+ let token;
150
+ if (req?.headers?.authorization &&
151
+ req?.headers?.authorization.startsWith("Bearer")) {
152
+ token = req?.headers?.authorization.split(" ")[1];
153
+ }
154
+ else if (req?.cookies?.arkos_access_token !== "no-token" && req.cookies) {
155
+ token = req?.cookies?.arkos_access_token;
156
+ }
157
+ if (!token)
158
+ throw loginRequiredError;
159
+ let decoded;
160
+ try {
161
+ decoded = await this.verifyJwtToken(token);
162
+ }
163
+ catch (err) {
164
+ throw invaliAuthTokenError;
165
+ }
166
+ if (!decoded?.id)
167
+ throw invaliAuthTokenError;
168
+ const user = await prisma.user.findUnique({
169
+ where: { id: String(decoded.id) },
170
+ });
171
+ if (!user)
172
+ throw new AppError("The user belonging to this token does no longer exists", 401, {}, "UserNoLongerExists");
173
+ if (this.userChangedPasswordAfter(user, decoded.iat) &&
174
+ !req.path?.includes?.("logout"))
175
+ throw new AppError("User recently changed password! Please log in again.", 401, {}, "PasswordChanged");
176
+ req.accessToken = token;
177
+ return user;
178
+ }
179
+ handleAuthenticationControl(action, authenticationControl) {
180
+ if (authenticationControl && typeof authenticationControl === "object") {
181
+ if (authenticationControl[action] === false)
182
+ return callNext;
183
+ else if (authenticationControl[action] === true)
184
+ return this.authenticate;
185
+ }
186
+ else
187
+ return this.authenticate;
188
+ return this.authenticate;
189
+ }
190
+ permission(action, resource, accessControl) {
191
+ const stack = new Error().stack;
192
+ if (stack?.includes("node_modules/express/lib/router/index.js"))
193
+ throw new Error("authService.permission() should be called during application initialization level.");
194
+ authActionService.add(action, resource, accessControl);
195
+ return async (user) => {
196
+ const configs = getArkosConfig();
197
+ if (!configs?.authentication)
198
+ throw Error("Validation Error: Trying to use authService.permission without setting up authentication.");
199
+ if (!user)
200
+ throw loginRequiredError;
201
+ if (user.isSuperUser)
202
+ return true;
203
+ if (configs?.authentication?.mode === "dynamic") {
204
+ return await this.checkDynamicAccessControl(user?.id, action, resource);
205
+ }
206
+ else if (configs?.authentication?.mode === "static") {
207
+ if (!accessControl && appModules.includes(kebabCase(resource)))
208
+ accessControl = getModuleComponents(kebabCase(resource))?.authConfigs
209
+ ?.accessControl;
210
+ return (!!accessControl &&
211
+ this.checkStaticAccessControl(user, action, accessControl));
212
+ }
213
+ return false;
214
+ };
215
+ }
216
+ }
217
+ const authService = new AuthService();
218
+ export default authService;
219
+ //# sourceMappingURL=auth.service.js.map
@@ -1 +1,4 @@
1
- "use strict";import o from"../../error-handler/utils/app-error.js";export const loginRequiredError=new o("You are not logged in! please log in to get access",401,{},"LoginRequired"),invaliAuthTokenError=new o("Your auth token is invalid, please login again.",401,{},"InvalidAuthToken");
1
+ import AppError from "../../error-handler/utils/app-error.js";
2
+ export const loginRequiredError = new AppError("You are not logged in! please log in to get access", 401, {}, "LoginRequired");
3
+ export const invaliAuthTokenError = new AppError("Your auth token is invalid, please login again.", 401, {}, "InvalidAuthToken");
4
+ //# sourceMappingURL=auth-error-objects.js.map
@@ -1 +1,73 @@
1
- "use strict";import{getArkosConfig as l}from"../../../../server.js";import a from"../../../error-handler/utils/app-error.js";export const determineUsernameField=e=>{const n=l()?.authentication;if(e.query?.usernameField&&typeof e.query?.usernameField=="string"&&n?.login?.allowedUsernames?.includes?.(e.query.usernameField))return e.query.usernameField;if(e.query?.usernameField)throw new a("Invalid usernameField parameter, it is not allowed!",400);return n?.login?.allowedUsernames?.[0]||"username"},createPrismaWhereClause=(e,n)=>{if(!e)return{};const r=e.split("."),t={};if(r.length===1)return t[r[0]]=n,t;let s=t;for(let o=0;o<r.length-1;o++){const i=r[o];s[i]={},s=s[i]}return s[r[r.length-1]]=n,t},getNestedValue=(e,n)=>{if(!e||!n)return;const r=n.split("."),t=r[r.length-1];if(t in e)return e[t]};function u(e){return e.toLowerCase().replace(/years?|yr|year/g,"y").replace(/minutes?|min/g,"m").replace(/seconds?|sec|secs/g,"s").replace(/hours?|hr/g,"h").replace(/days?/g,"d").replace(/weeks?/g,"w").replace(/milliseconds?/g,"ms")}export function toMs(e){if(typeof e=="number")return e*1e3;const n=u(e.trim()),r=/^(\d+(?:\.\d+)?)(ms|s|m|h|d|w|y)$/i,t=n.match(r);if(!t)throw new Error(`Invalid time format: ${e}`);const s=parseFloat(t[1]),o=t[2].toLowerCase();return s*{ms:1,s:1e3,m:6e4,h:36e5,d:864e5,w:6048e5,y:315576e5}[o]}
1
+ import { getArkosConfig } from "../../../../server.js";
2
+ import AppError from "../../../error-handler/utils/app-error.js";
3
+ export const determineUsernameField = (req) => {
4
+ const authConfigs = getArkosConfig()?.authentication;
5
+ if (req.query?.usernameField &&
6
+ typeof req.query?.usernameField === "string" &&
7
+ authConfigs?.login?.allowedUsernames?.includes?.(req.query.usernameField))
8
+ return req.query.usernameField;
9
+ else if (req.query?.usernameField)
10
+ throw new AppError("Invalid usernameField parameter, it is not allowed!", 400);
11
+ return authConfigs?.login?.allowedUsernames?.[0] || "username";
12
+ };
13
+ export const createPrismaWhereClause = (path, value) => {
14
+ if (!path)
15
+ return {};
16
+ const parts = path.split(".");
17
+ const whereClause = {};
18
+ if (parts.length === 1) {
19
+ whereClause[parts[0]] = value;
20
+ return whereClause;
21
+ }
22
+ let current = whereClause;
23
+ for (let i = 0; i < parts.length - 1; i++) {
24
+ const part = parts[i];
25
+ current[part] = {};
26
+ current = current[part];
27
+ }
28
+ current[parts[parts.length - 1]] = value;
29
+ return whereClause;
30
+ };
31
+ export const getNestedValue = (obj, path) => {
32
+ if (!obj || !path)
33
+ return undefined;
34
+ const properties = path.split(".");
35
+ const lastProperty = properties[properties.length - 1];
36
+ if (lastProperty in obj) {
37
+ return obj[lastProperty];
38
+ }
39
+ return undefined;
40
+ };
41
+ function normalizeDuration(input) {
42
+ return input
43
+ .toLowerCase()
44
+ .replace(/years?|yr|year/g, "y")
45
+ .replace(/minutes?|min/g, "m")
46
+ .replace(/seconds?|sec|secs/g, "s")
47
+ .replace(/hours?|hr/g, "h")
48
+ .replace(/days?/g, "d")
49
+ .replace(/weeks?/g, "w")
50
+ .replace(/milliseconds?/g, "ms");
51
+ }
52
+ export function toMs(input) {
53
+ if (typeof input === "number")
54
+ return input * 1000;
55
+ const normalizedInput = normalizeDuration(input.trim());
56
+ const regex = /^(\d+(?:\.\d+)?)(ms|s|m|h|d|w|y)$/i;
57
+ const match = normalizedInput.match(regex);
58
+ if (!match)
59
+ throw new Error(`Invalid time format: ${input}`);
60
+ const value = parseFloat(match[1]);
61
+ const unit = match[2].toLowerCase();
62
+ const multipliers = {
63
+ ms: 1,
64
+ s: 1000,
65
+ m: 60000,
66
+ h: 3600000,
67
+ d: 86400000,
68
+ w: 604800000,
69
+ y: 31557600000,
70
+ };
71
+ return value * multipliers[unit];
72
+ }
73
+ //# sourceMappingURL=auth.controller.helpers.js.map
@@ -1 +1,90 @@
1
- "use strict";import{kebabCase as s}from"../../../../exports/utils/index.js";import{capitalize as o}from"../../../../utils/helpers/text.helpers.js";class a{constructor(){this.authActions=[{roles:[],action:"View",resource:"auth-action",name:"View auth action",description:"Viewm an auth action",errorMessage:"You do not have permission to perform this operation"}]}add(e,r,t){if(!this.getOne(e,r)){const i=this.transformAccessControlToValidAuthAction(e,r,t);this.authActions.push(i)}}getAll(){return this.authActions}getOne(e,r){return this.authActions.find(t=>t.action===e&&t.resource===r)}transformAccessControlToValidAuthAction(e,r,t){const i={roles:t&&(Array.isArray(t)?t:typeof t=="string"?[t]:Array.isArray(t?.[e]||{})?t[e]:t[e]?.roles)||[],action:e,resource:r,name:`${e} ${r}`,description:`${o(s(e).replace(/-/g," "))} ${o(s(r).replace(/-/g," "))}`,errorMessage:"You do not have permission to perform this operation"};if(!t||Array.isArray(t))return i;const n=t[e];if(n){if(Array.isArray(n))return i;if(typeof n=="object")return{...i,name:n.name||i.name,description:n?.description||i.description,errorMessage:n?.errorMessage||i.errorMessage}}return i}getUniqueActions(){return[...new Set(this.authActions.map(e=>e.action))]}getUniqueResources(){return[...new Set(this.authActions.map(e=>e.resource))]}getByResource(e){return this.authActions.find(r=>r.resource===e)}getByAction(e){return this.authActions.filter(r=>r.action===e)}exists(e,r){return!!this.getOne(e,r)}}const u=new a;export default u;
1
+ import { kebabCase } from "../../../../exports/utils/index.js";
2
+ import { capitalize } from "../../../../utils/helpers/text.helpers.js";
3
+ class AuthActionService {
4
+ constructor() {
5
+ this.authActions = [
6
+ {
7
+ roles: [],
8
+ action: "View",
9
+ resource: "auth-action",
10
+ name: "View auth action",
11
+ description: "Viewm an auth action",
12
+ errorMessage: "You do not have permission to perform this operation",
13
+ },
14
+ ];
15
+ }
16
+ add(action, resource, accessControl) {
17
+ if (!this.getOne(action, resource)) {
18
+ const transformedAction = this.transformAccessControlToValidAuthAction(action, resource, accessControl);
19
+ this.authActions.push(transformedAction);
20
+ }
21
+ }
22
+ getAll() {
23
+ return this.authActions;
24
+ }
25
+ getOne(action, resource) {
26
+ return this.authActions.find((authAction) => authAction.action === action && authAction.resource === resource);
27
+ }
28
+ transformAccessControlToValidAuthAction(action, resource, accessControl) {
29
+ const baseAuthAction = {
30
+ roles: (accessControl &&
31
+ (Array.isArray(accessControl)
32
+ ? accessControl
33
+ : typeof accessControl === "string"
34
+ ? [accessControl]
35
+ : Array.isArray(accessControl?.[action] || {})
36
+ ? accessControl[action]
37
+ : accessControl[action]
38
+ ?.roles)) ||
39
+ [],
40
+ action,
41
+ resource,
42
+ name: `${capitalize(kebabCase(action).replace(/-/g, " "))} ${capitalize(kebabCase(resource).replace(/-/g, " "))}`,
43
+ description: `${capitalize(kebabCase(action).replace(/-/g, " "))} ${capitalize(kebabCase(resource).replace(/-/g, " "))}`,
44
+ errorMessage: `You do not have permission to perform this operation`,
45
+ };
46
+ if (!accessControl) {
47
+ return baseAuthAction;
48
+ }
49
+ if (Array.isArray(accessControl)) {
50
+ return baseAuthAction;
51
+ }
52
+ const actionRule = accessControl[action];
53
+ if (actionRule) {
54
+ if (Array.isArray(actionRule)) {
55
+ return baseAuthAction;
56
+ }
57
+ else if (typeof actionRule === "object") {
58
+ return {
59
+ ...baseAuthAction,
60
+ name: actionRule.name || baseAuthAction.name,
61
+ description: actionRule?.description || baseAuthAction.description,
62
+ errorMessage: actionRule?.errorMessage || baseAuthAction.errorMessage,
63
+ };
64
+ }
65
+ }
66
+ return baseAuthAction;
67
+ }
68
+ getUniqueActions() {
69
+ return [
70
+ ...new Set(this.authActions.map((authAction) => authAction.action)),
71
+ ];
72
+ }
73
+ getUniqueResources() {
74
+ return [
75
+ ...new Set(this.authActions.map((authAction) => authAction.resource)),
76
+ ];
77
+ }
78
+ getByResource(resource) {
79
+ return this.authActions.filter((authAction) => authAction.resource === resource);
80
+ }
81
+ getByAction(action) {
82
+ return this.authActions.filter((authAction) => authAction.action === action);
83
+ }
84
+ exists(action, resource) {
85
+ return !!this.getOne(action, resource);
86
+ }
87
+ }
88
+ const authActionService = new AuthActionService();
89
+ export default authActionService;
90
+ //# sourceMappingURL=auth-action.service.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth-action.service.js","sourceRoot":"","sources":["../../../../../../src/modules/auth/utils/services/auth-action.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { kebabCase } from \"../../../../exports/utils\";\nimport {\n AccessControlConfig,\n DetailedAccessControlRule,\n} from \"../../../../types/auth\";\nimport { capitalize } from \"../../../../utils/helpers/text.helpers\";\n\ninterface AuthAction {\n /** role name, e.g Admin, Manager */\n roles: string[];\n /** action name, e.g Create, View, Update, Download, Cancel */\n action: string;\n /** resource name, e.g user, user-role, product, author */\n resource: string;\n /** Human-readable name for this permission (optional) */\n name?: string;\n /** Detailed description of what this permission allows (optional) */\n description?: string;\n /** Detailed error message of what must be returned on forbidden response (optional)\n *\n * Note: not yet implemented\n */\n errorMessage?: string;\n}\n\nclass AuthActionService {\n authActions: AuthAction[] = [\n {\n roles: [],\n action: \"View\",\n resource: \"auth-action\",\n name: \"View auth action\",\n description: \"Viewm an auth action\",\n errorMessage: \"You do not have permission to perform this operation\",\n },\n ];\n\n add(action: string, resource: string, accessControl?: AccessControlConfig) {\n if (!this.getOne(action, resource)) {\n const transformedAction = this.transformAccessControlToValidAuthAction(\n action,\n resource,\n accessControl\n );\n this.authActions.push(transformedAction);\n }\n }\n\n getAll(): AuthAction[] {\n return this.authActions;\n }\n\n getOne(action: string, resource: string): AuthAction | undefined {\n return this.authActions.find(\n (authAction) =>\n authAction.action === action && authAction.resource === resource\n );\n }\n\n private transformAccessControlToValidAuthAction(\n action: string,\n resource: string,\n accessControl?: AccessControlConfig\n ): AuthAction {\n const baseAuthAction: AuthAction = {\n roles:\n (accessControl &&\n (Array.isArray(accessControl)\n ? accessControl\n : typeof accessControl === \"string\"\n ? [accessControl]\n : Array.isArray(accessControl?.[action] || {})\n ? (accessControl[action] as string[])\n : (accessControl[action] as DetailedAccessControlRule)\n ?.roles)) ||\n [],\n action,\n resource,\n name: `${action} ${resource}`,\n description: `${capitalize(kebabCase(action).replace(/-/g, \" \"))} ${capitalize(kebabCase(resource).replace(/-/g, \" \"))}`,\n errorMessage: `You do not have permission to perform this operation`,\n };\n\n // If accessControl is not provided, return the base action\n if (!accessControl) {\n return baseAuthAction;\n }\n\n // If accessControl is an array of roles, just return the base action\n if (Array.isArray(accessControl)) {\n return baseAuthAction;\n }\n\n // If accessControl is an object with specific rules\n const actionRule = accessControl[action];\n\n if (actionRule) {\n if (Array.isArray(actionRule)) {\n // If it's just an array of roles, keep the base action\n return baseAuthAction;\n } else if (typeof actionRule === \"object\") {\n // If it's a detailed rule object, use its metadata\n return {\n ...baseAuthAction,\n name: actionRule.name || baseAuthAction.name,\n description: actionRule?.description || baseAuthAction.description,\n errorMessage: actionRule?.errorMessage || baseAuthAction.errorMessage,\n };\n }\n }\n\n return baseAuthAction;\n }\n\n /**\n * Get all unique actions across all auth actions\n */\n getUniqueActions(): string[] {\n return [\n ...new Set(this.authActions.map((authAction) => authAction.action)),\n ];\n }\n\n /**\n * Get all unique resources across all auth actions\n */\n getUniqueResources(): string[] {\n return [\n ...new Set(this.authActions.map((authAction) => authAction.resource)),\n ];\n }\n\n /**\n * Get all auth actions for a specific resource\n */\n getByResource(resource: string): AuthAction | undefined {\n return this.authActions.find(\n (authAction) => authAction.resource === resource\n );\n }\n\n /**\n * Get all auth actions for a specific action\n */\n getByAction(action: string): AuthAction[] {\n return this.authActions.filter(\n (authAction) => authAction.action === action\n );\n }\n\n /**\n * Check if an auth action exists\n */\n exists(action: string, resource: string): boolean {\n return !!this.getOne(action, resource);\n }\n}\n\nconst authActionService = new AuthActionService();\n\nexport default authActionService;\n"]}
1
+ {"version":3,"file":"auth-action.service.js","sourceRoot":"","sources":["../../../../../../src/modules/auth/utils/services/auth-action.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { kebabCase } from \"../../../../exports/utils\";\nimport {\n AccessControlConfig,\n DetailedAccessControlRule,\n} from \"../../../../types/auth\";\nimport { capitalize } from \"../../../../utils/helpers/text.helpers\";\n\ninterface AuthAction {\n /** role name, e.g Admin, Manager */\n roles: string[];\n /** action name, e.g Create, View, Update, Download, Cancel */\n action: string;\n /** resource name, e.g user, user-role, product, author */\n resource: string;\n /** Human-readable name for this permission (optional) */\n name?: string;\n /** Detailed description of what this permission allows (optional) */\n description?: string;\n /** Detailed error message of what must be returned on forbidden response (optional)\n *\n * Note: not yet implemented\n */\n errorMessage?: string;\n}\n\nclass AuthActionService {\n authActions: AuthAction[] = [\n {\n roles: [],\n action: \"View\",\n resource: \"auth-action\",\n name: \"View auth action\",\n description: \"Viewm an auth action\",\n errorMessage: \"You do not have permission to perform this operation\",\n },\n ];\n\n add(action: string, resource: string, accessControl?: AccessControlConfig) {\n if (!this.getOne(action, resource)) {\n const transformedAction = this.transformAccessControlToValidAuthAction(\n action,\n resource,\n accessControl\n );\n this.authActions.push(transformedAction);\n }\n }\n\n getAll(): AuthAction[] {\n return this.authActions;\n }\n\n getOne(action: string, resource: string): AuthAction | undefined {\n return this.authActions.find(\n (authAction) =>\n authAction.action === action && authAction.resource === resource\n );\n }\n\n private transformAccessControlToValidAuthAction(\n action: string,\n resource: string,\n accessControl?: AccessControlConfig\n ): AuthAction {\n const baseAuthAction: AuthAction = {\n roles:\n (accessControl &&\n (Array.isArray(accessControl)\n ? accessControl\n : typeof accessControl === \"string\"\n ? [accessControl]\n : Array.isArray(accessControl?.[action] || {})\n ? (accessControl[action] as string[])\n : (accessControl[action] as DetailedAccessControlRule)\n ?.roles)) ||\n [],\n action,\n resource,\n name: `${capitalize(kebabCase(action).replace(/-/g, \" \"))} ${capitalize(kebabCase(resource).replace(/-/g, \" \"))}`,\n description: `${capitalize(kebabCase(action).replace(/-/g, \" \"))} ${capitalize(kebabCase(resource).replace(/-/g, \" \"))}`,\n errorMessage: `You do not have permission to perform this operation`,\n };\n\n // If accessControl is not provided, return the base action\n if (!accessControl) {\n return baseAuthAction;\n }\n\n // If accessControl is an array of roles, just return the base action\n if (Array.isArray(accessControl)) {\n return baseAuthAction;\n }\n\n // If accessControl is an object with specific rules\n const actionRule = accessControl[action];\n\n if (actionRule) {\n if (Array.isArray(actionRule)) {\n // If it's just an array of roles, keep the base action\n return baseAuthAction;\n } else if (typeof actionRule === \"object\") {\n // If it's a detailed rule object, use its metadata\n return {\n ...baseAuthAction,\n name: actionRule.name || baseAuthAction.name,\n description: actionRule?.description || baseAuthAction.description,\n errorMessage: actionRule?.errorMessage || baseAuthAction.errorMessage,\n };\n }\n }\n\n return baseAuthAction;\n }\n\n /**\n * Get all unique actions across all auth actions\n */\n getUniqueActions(): string[] {\n return [\n ...new Set(this.authActions.map((authAction) => authAction.action)),\n ];\n }\n\n /**\n * Get all unique resources across all auth actions\n */\n getUniqueResources(): string[] {\n return [\n ...new Set(this.authActions.map((authAction) => authAction.resource)),\n ];\n }\n\n /**\n * Get all auth actions for a specific resource\n */\n getByResource(resource: string): AuthAction[] | undefined {\n return this.authActions.filter(\n (authAction) => authAction.resource === resource\n );\n }\n\n /**\n * Get all auth actions for a specific action\n */\n getByAction(action: string): AuthAction[] {\n return this.authActions.filter(\n (authAction) => authAction.action === action\n );\n }\n\n /**\n * Check if an auth action exists\n */\n exists(action: string, resource: string): boolean {\n return !!this.getOne(action, resource);\n }\n}\n\nconst authActionService = new AuthActionService();\n\nexport default authActionService;\n"]}
@@ -1 +1,165 @@
1
- "use strict";import i from"../error-handler/utils/catch-async.js";import l from"../../utils/features/api.features.js";import{BaseService as f}from"./base.service.js";import o from"../error-handler/utils/app-error.js";import{kebabCase as h,pascalCase as u}from"../../utils/helpers/change-case.helpers.js";import{getModuleComponents as y}from"../../utils/dynamic-loader.js";import w from"pluralize";import k from"../../utils/sheu.js";import O from"../../utils/prisma/prisma-schema-parser.js";export class BaseController{constructor(c){this.createOne=i(async(e,a,s)=>{const t=await this.service.createOne(e.body,e.prismaQueryOptions,{user:e?.user,accessToken:e?.accessToken});if(this.interceptors.afterCreateOne)return e.responseData={data:t},e.responseStatus=201,s();a.status(201).json({data:t})}),this.createMany=i(async(e,a,s)=>{const t=await this.service.createMany(e.body,e.prismaQueryOptions,{user:e?.user,accessToken:e?.accessToken});if(!t)return s(new o("Failed to create the resources. Please check your input.",400,{},"MissingRequestBody"));if(this.interceptors.afterCreateMany)return e.responseData={data:t},e.responseStatus=201,s();a.status(201).json({data:t})}),this.findMany=i(async(e,a,s)=>{const{filters:{where:t,...r}}=new l(e,this.modelName).filter().sort().limitFields().paginate(),[n,d]=await Promise.all([this.service.findMany(t,r,{user:e?.user,accessToken:e?.accessToken}),this.service.count(t,{user:e?.user,accessToken:e?.accessToken})]);if(this.interceptors.afterFindMany)return e.responseData={total:d,results:n.length,data:n},e.responseStatus=200,s();a.status(200).json({total:d,results:n.length,data:n})}),this.findOne=i(async(e,a,s)=>{const t=await this.service.findOne(e.params,e.prismaQueryOptions,{user:e?.user,accessToken:e?.accessToken});if(!t)return Object.keys(e.params).length===1&&"id"in e.params&&e.params.id!=="me"?s(new o(`${u(String(this.modelName))} with ID ${e.params?.id} not found`,404,{},"NotFound")):s(new o(`${u(String(this.modelName))} not found`,404,{},"NotFound"));if(this.interceptors.afterFindOne)return e.responseData={data:t},e.responseStatus=200,s();a.status(200).json({data:t})}),this.updateOne=i(async(e,a,s)=>{const t=await this.service.updateOne(e.params,e.body,e.prismaQueryOptions,{user:e?.user,accessToken:e?.accessToken});if(!t)return Object.keys(e.params).length===1&&"id"in e.params?s(new o(`${u(String(this.modelName))} with ID ${e.params?.id} not found`,404,{},"NotFound")):s(new o(`${u(String(this.modelName))} not found`,404,{},"NotFound"));if(this.interceptors.afterUpdateOne)return e.responseData={data:t},e.responseStatus=200,s();a.status(200).json({data:t})}),this.updateMany=i(async(e,a,s)=>{if(!Object.keys(e.query).some(d=>d!=="prismaQueryOptions"))return s(new o("Filter criteria not provided for bulk update.",400,{},"MissingRequestQueryParameters"));e.query.filterMode=e.query?.filterMode||"AND";const{filters:{where:t,...r}}=new l(e,this.modelName).filter().sort();delete r.include;const n=await this.service.updateMany(t,e.body,r,{user:e?.user,accessToken:e?.accessToken});if(!n||n.count===0)return s(new o(`${w(u(String(this.modelName)))} not found`,404));if(this.interceptors.afterUpdateMany)return e.responseData={results:n.count,data:n},e.responseStatus=200,s();a.status(200).json({results:n.count,data:n})}),this.deleteOne=i(async(e,a,s)=>{const t=await this.service.deleteOne(e.params,{user:e?.user,accessToken:e?.accessToken});if(!t)return Object.keys(e.params).length===1&&"id"in e.params?s(new o(`${u(String(this.modelName))} with ID ${e.params?.id} not found`,404,{},"NotFound")):s(new o(`${u(String(this.modelName))} not found`,404,{},"NotFound"));if(this.interceptors.afterDeleteOne)return e.additionalData={data:t},e.responseStatus=204,s();a.status(204).send()}),this.deleteMany=i(async(e,a,s)=>{if(!Object.keys(e.query).some(n=>n!=="prismaQueryOptions"))return s(new o("Filter criteria not provided for bulk deletion.",400,{},"MissingRequestQueryParameters"));e.query.filterMode=e.query?.filterMode||"AND";const{filters:{where:t}}=new l(e,this.modelName).filter().sort(),r=await this.service.deleteMany(t,{user:e?.user,accessToken:e?.accessToken});if(!r||r.count===0)return s(new o("No records found to delete",404,{},"NotFound"));if(this.interceptors.afterDeleteMany)return e.responseData={results:r.count,data:r},e.responseStatus=200,s();a.status(200).json({results:r.count,data:r})});const p=y(c);this.modelName=c,this.service=new f(c),this.interceptors=p?.interceptors||{}}}export const getAvailableResources=i(async(m,c)=>{k.warn("This route `/api/available-routes` will be deprecated from 1.4.0-beta, consider using /api/auth-actions instead."),c.status(200).json({data:[...O.getModelsAsArrayOfStrings().map(p=>h(p)),"file-upload"]})});
1
+ import catchAsync from "../error-handler/utils/catch-async.js";
2
+ import APIFeatures from "../../utils/features/api.features.js";
3
+ import { BaseService } from "./base.service.js";
4
+ import AppError from "../error-handler/utils/app-error.js";
5
+ import { kebabCase, pascalCase } from "../../utils/helpers/change-case.helpers.js";
6
+ import { getModuleComponents } from "../../utils/dynamic-loader.js";
7
+ import pluralize from "pluralize";
8
+ import sheu from "../../utils/sheu.js";
9
+ import prismaSchemaParser from "../../utils/prisma/prisma-schema-parser.js";
10
+ export class BaseController {
11
+ constructor(modelName) {
12
+ this.createOne = catchAsync(async (req, res, next) => {
13
+ const data = await this.service.createOne(req.body, req.prismaQueryOptions, { user: req?.user, accessToken: req?.accessToken });
14
+ if (this.interceptors.afterCreateOne) {
15
+ req.responseData = { data };
16
+ req.responseStatus = 201;
17
+ return next();
18
+ }
19
+ res.status(201).json({ data });
20
+ });
21
+ this.createMany = catchAsync(async (req, res, next) => {
22
+ const data = await this.service.createMany(req.body, req.prismaQueryOptions, { user: req?.user, accessToken: req?.accessToken });
23
+ if (!data)
24
+ return next(new AppError("Failed to create the resources. Please check your input.", 400, {}, "MissingRequestBody"));
25
+ if (this.interceptors.afterCreateMany) {
26
+ req.responseData = { data };
27
+ req.responseStatus = 201;
28
+ return next();
29
+ }
30
+ res.status(201).json({ data });
31
+ });
32
+ this.findMany = catchAsync(async (req, res, next) => {
33
+ const { filters: { where, ...queryOptions }, } = new APIFeatures(req, this.modelName)
34
+ .filter()
35
+ .sort()
36
+ .limitFields()
37
+ .paginate();
38
+ const [data, total] = (await Promise.all([
39
+ this.service.findMany(where, queryOptions, {
40
+ user: req?.user,
41
+ accessToken: req?.accessToken,
42
+ }),
43
+ this.service.count(where, {
44
+ user: req?.user,
45
+ accessToken: req?.accessToken,
46
+ }),
47
+ ]));
48
+ if (this.interceptors.afterFindMany) {
49
+ req.responseData = { total, results: data.length, data };
50
+ req.responseStatus = 200;
51
+ return next();
52
+ }
53
+ res.status(200).json({ total, results: data.length, data });
54
+ });
55
+ this.findOne = catchAsync(async (req, res, next) => {
56
+ const data = await this.service.findOne(req.params, req.prismaQueryOptions, { user: req?.user, accessToken: req?.accessToken });
57
+ if (!data) {
58
+ if (Object.keys(req.params).length === 1 &&
59
+ "id" in req.params &&
60
+ req.params.id !== "me") {
61
+ return next(new AppError(`${pascalCase(String(this.modelName))} with ID ${req.params?.id} not found`, 404, {}, "NotFound"));
62
+ }
63
+ else {
64
+ return next(new AppError(`${pascalCase(String(this.modelName))} not found`, 404, {}, "NotFound"));
65
+ }
66
+ }
67
+ if (this.interceptors.afterFindOne) {
68
+ req.responseData = { data };
69
+ req.responseStatus = 200;
70
+ return next();
71
+ }
72
+ res.status(200).json({ data });
73
+ });
74
+ this.updateOne = catchAsync(async (req, res, next) => {
75
+ const data = await this.service.updateOne(req.params, req.body, req.prismaQueryOptions, { user: req?.user, accessToken: req?.accessToken });
76
+ if (!data) {
77
+ if (Object.keys(req.params).length === 1 && "id" in req.params) {
78
+ return next(new AppError(`${pascalCase(String(this.modelName))} with ID ${req.params?.id} not found`, 404, {}, "NotFound"));
79
+ }
80
+ else {
81
+ return next(new AppError(`${pascalCase(String(this.modelName))} not found`, 404, {}, "NotFound"));
82
+ }
83
+ }
84
+ if (this.interceptors.afterUpdateOne) {
85
+ req.responseData = { data };
86
+ req.responseStatus = 200;
87
+ return next();
88
+ }
89
+ res.status(200).json({ data });
90
+ });
91
+ this.updateMany = catchAsync(async (req, res, next) => {
92
+ if (!Object.keys(req.query).some((key) => key !== "prismaQueryOptions")) {
93
+ return next(new AppError("Filter criteria not provided for bulk update.", 400, {}, "MissingRequestQueryParameters"));
94
+ }
95
+ req.query.filterMode = req.query?.filterMode || "AND";
96
+ const { filters: { where, ...queryOptions }, } = new APIFeatures(req, this.modelName).filter().sort();
97
+ delete queryOptions.include;
98
+ const data = (await this.service.updateMany(where, req.body, queryOptions, { user: req?.user, accessToken: req?.accessToken }));
99
+ if (!data || data.count === 0)
100
+ return next(new AppError(`${pluralize(pascalCase(String(this.modelName)))} not found`, 404));
101
+ if (this.interceptors.afterUpdateMany) {
102
+ req.responseData = { results: data.count, data };
103
+ req.responseStatus = 200;
104
+ return next();
105
+ }
106
+ res.status(200).json({ results: data.count, data });
107
+ });
108
+ this.deleteOne = catchAsync(async (req, res, next) => {
109
+ const data = await this.service.deleteOne(req.params, {
110
+ user: req?.user,
111
+ accessToken: req?.accessToken,
112
+ });
113
+ if (!data) {
114
+ if (Object.keys(req.params).length === 1 && "id" in req.params) {
115
+ return next(new AppError(`${pascalCase(String(this.modelName))} with ID ${req.params?.id} not found`, 404, {}, "NotFound"));
116
+ }
117
+ else {
118
+ return next(new AppError(`${pascalCase(String(this.modelName))} not found`, 404, {}, "NotFound"));
119
+ }
120
+ }
121
+ if (this.interceptors.afterDeleteOne) {
122
+ req.additionalData = { data };
123
+ req.responseStatus = 204;
124
+ return next();
125
+ }
126
+ res.status(204).send();
127
+ });
128
+ this.deleteMany = catchAsync(async (req, res, next) => {
129
+ if (!Object.keys(req.query).some((key) => key !== "prismaQueryOptions")) {
130
+ return next(new AppError("Filter criteria not provided for bulk deletion.", 400, {}, "MissingRequestQueryParameters"));
131
+ }
132
+ req.query.filterMode = req.query?.filterMode || "AND";
133
+ const { filters: { where }, } = new APIFeatures(req, this.modelName).filter().sort();
134
+ const data = await this.service.deleteMany(where, {
135
+ user: req?.user,
136
+ accessToken: req?.accessToken,
137
+ });
138
+ if (!data || data.count === 0) {
139
+ return next(new AppError(`No records found to delete`, 404, {}, "NotFound"));
140
+ }
141
+ if (this.interceptors.afterDeleteMany) {
142
+ req.responseData = { results: data.count, data };
143
+ req.responseStatus = 200;
144
+ return next();
145
+ }
146
+ res.status(200).json({ results: data.count, data });
147
+ });
148
+ const components = getModuleComponents(modelName);
149
+ this.modelName = modelName;
150
+ this.service = new BaseService(modelName);
151
+ this.interceptors = components?.interceptors || {};
152
+ }
153
+ }
154
+ export const getAvailableResources = catchAsync(async (_, res) => {
155
+ sheu.warn("This route `/api/available-routes` will be deprecated from 1.4.0-beta, consider using /api/auth-actions instead.");
156
+ res.status(200).json({
157
+ data: [
158
+ ...prismaSchemaParser
159
+ .getModelsAsArrayOfStrings()
160
+ .map((model) => kebabCase(model)),
161
+ "file-upload",
162
+ ],
163
+ });
164
+ });
165
+ //# sourceMappingURL=base.controller.js.map