@flowerforce/flowerbase 1.0.1-beta.3

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 (292) hide show
  1. package/CHANGELOG.md +0 -0
  2. package/LICENSE +3 -0
  3. package/README.md +18 -0
  4. package/dist/auth/controller.d.ts +8 -0
  5. package/dist/auth/controller.d.ts.map +1 -0
  6. package/dist/auth/controller.js +76 -0
  7. package/dist/auth/dtos.d.ts +6 -0
  8. package/dist/auth/dtos.d.ts.map +1 -0
  9. package/dist/auth/dtos.js +2 -0
  10. package/dist/auth/plugins/jwt.d.ts +14 -0
  11. package/dist/auth/plugins/jwt.d.ts.map +1 -0
  12. package/dist/auth/plugins/jwt.js +68 -0
  13. package/dist/auth/providers/local-userpass/controller.d.ts +8 -0
  14. package/dist/auth/providers/local-userpass/controller.d.ts.map +1 -0
  15. package/dist/auth/providers/local-userpass/controller.js +184 -0
  16. package/dist/auth/providers/local-userpass/dtos.d.ts +35 -0
  17. package/dist/auth/providers/local-userpass/dtos.d.ts.map +1 -0
  18. package/dist/auth/providers/local-userpass/dtos.js +2 -0
  19. package/dist/auth/utils.d.ts +126 -0
  20. package/dist/auth/utils.d.ts.map +1 -0
  21. package/dist/auth/utils.js +122 -0
  22. package/dist/constants.d.ts +18 -0
  23. package/dist/constants.d.ts.map +1 -0
  24. package/dist/constants.js +34 -0
  25. package/dist/features/endpoints/index.d.ts +10 -0
  26. package/dist/features/endpoints/index.d.ts.map +1 -0
  27. package/dist/features/endpoints/index.js +31 -0
  28. package/dist/features/endpoints/interface.d.ts +27 -0
  29. package/dist/features/endpoints/interface.d.ts.map +1 -0
  30. package/dist/features/endpoints/interface.js +2 -0
  31. package/dist/features/endpoints/utils.d.ts +31 -0
  32. package/dist/features/endpoints/utils.d.ts.map +1 -0
  33. package/dist/features/endpoints/utils.js +85 -0
  34. package/dist/features/functions/controller.d.ts +9 -0
  35. package/dist/features/functions/controller.d.ts.map +1 -0
  36. package/dist/features/functions/controller.js +88 -0
  37. package/dist/features/functions/dtos.d.ts +34 -0
  38. package/dist/features/functions/dtos.d.ts.map +1 -0
  39. package/dist/features/functions/dtos.js +2 -0
  40. package/dist/features/functions/index.d.ts +9 -0
  41. package/dist/features/functions/index.d.ts.map +1 -0
  42. package/dist/features/functions/index.js +28 -0
  43. package/dist/features/functions/interface.d.ts +32 -0
  44. package/dist/features/functions/interface.d.ts.map +1 -0
  45. package/dist/features/functions/interface.js +2 -0
  46. package/dist/features/functions/utils.d.ts +23 -0
  47. package/dist/features/functions/utils.d.ts.map +1 -0
  48. package/dist/features/functions/utils.js +75 -0
  49. package/dist/features/rules/index.d.ts +1 -0
  50. package/dist/features/rules/index.d.ts.map +1 -0
  51. package/dist/features/rules/index.js +1 -0
  52. package/dist/features/rules/interface.d.ts +22 -0
  53. package/dist/features/rules/interface.d.ts.map +1 -0
  54. package/dist/features/rules/interface.js +2 -0
  55. package/dist/features/rules/utils.d.ts +3 -0
  56. package/dist/features/rules/utils.d.ts.map +1 -0
  57. package/dist/features/rules/utils.js +31 -0
  58. package/dist/features/triggers/dtos.d.ts +9 -0
  59. package/dist/features/triggers/dtos.d.ts.map +1 -0
  60. package/dist/features/triggers/dtos.js +2 -0
  61. package/dist/features/triggers/index.d.ts +10 -0
  62. package/dist/features/triggers/index.d.ts.map +1 -0
  63. package/dist/features/triggers/index.js +57 -0
  64. package/dist/features/triggers/interface.d.ts +44 -0
  65. package/dist/features/triggers/interface.d.ts.map +1 -0
  66. package/dist/features/triggers/interface.js +2 -0
  67. package/dist/features/triggers/utils.d.ts +16 -0
  68. package/dist/features/triggers/utils.d.ts.map +1 -0
  69. package/dist/features/triggers/utils.js +153 -0
  70. package/dist/index.d.ts +19 -0
  71. package/dist/index.d.ts.map +1 -0
  72. package/dist/index.js +84 -0
  73. package/dist/model.d.ts +2 -0
  74. package/dist/model.d.ts.map +1 -0
  75. package/dist/model.js +2 -0
  76. package/dist/services/api/index.d.ts +36 -0
  77. package/dist/services/api/index.d.ts.map +1 -0
  78. package/dist/services/api/index.js +36 -0
  79. package/dist/services/api/model.d.ts +33 -0
  80. package/dist/services/api/model.d.ts.map +1 -0
  81. package/dist/services/api/model.js +2 -0
  82. package/dist/services/api/utils.d.ts +16 -0
  83. package/dist/services/api/utils.d.ts.map +1 -0
  84. package/dist/services/api/utils.js +45 -0
  85. package/dist/services/aws/index.d.ts +13 -0
  86. package/dist/services/aws/index.d.ts.map +1 -0
  87. package/dist/services/aws/index.js +50 -0
  88. package/dist/services/index.d.ts +41 -0
  89. package/dist/services/index.d.ts.map +1 -0
  90. package/dist/services/index.js +14 -0
  91. package/dist/services/interface.d.ts +3 -0
  92. package/dist/services/interface.d.ts.map +1 -0
  93. package/dist/services/interface.js +2 -0
  94. package/dist/services/mongodb-atlas/index.d.ts +4 -0
  95. package/dist/services/mongodb-atlas/index.d.ts.map +1 -0
  96. package/dist/services/mongodb-atlas/index.js +483 -0
  97. package/dist/services/mongodb-atlas/model.d.ts +39 -0
  98. package/dist/services/mongodb-atlas/model.d.ts.map +1 -0
  99. package/dist/services/mongodb-atlas/model.js +2 -0
  100. package/dist/services/mongodb-atlas/utils.d.ts +8 -0
  101. package/dist/services/mongodb-atlas/utils.d.ts.map +1 -0
  102. package/dist/services/mongodb-atlas/utils.js +33 -0
  103. package/dist/state.d.ts +6 -0
  104. package/dist/state.d.ts.map +1 -0
  105. package/dist/state.js +18 -0
  106. package/dist/utils/context/helpers.d.ts +74 -0
  107. package/dist/utils/context/helpers.d.ts.map +1 -0
  108. package/dist/utils/context/helpers.js +60 -0
  109. package/dist/utils/context/index.d.ts +14 -0
  110. package/dist/utils/context/index.d.ts.map +1 -0
  111. package/dist/utils/context/index.js +50 -0
  112. package/dist/utils/context/interface.d.ts +18 -0
  113. package/dist/utils/context/interface.d.ts.map +1 -0
  114. package/dist/utils/context/interface.js +2 -0
  115. package/dist/utils/crypto/index.d.ts +19 -0
  116. package/dist/utils/crypto/index.d.ts.map +1 -0
  117. package/dist/utils/crypto/index.js +50 -0
  118. package/dist/utils/helpers/someAsync.d.ts +12 -0
  119. package/dist/utils/helpers/someAsync.d.ts.map +1 -0
  120. package/dist/utils/helpers/someAsync.js +56 -0
  121. package/dist/utils/index.d.ts +3 -0
  122. package/dist/utils/index.d.ts.map +1 -0
  123. package/dist/utils/index.js +11 -0
  124. package/dist/utils/initializer/exposeRoutes.d.ts +8 -0
  125. package/dist/utils/initializer/exposeRoutes.d.ts.map +1 -0
  126. package/dist/utils/initializer/exposeRoutes.js +41 -0
  127. package/dist/utils/initializer/registerPlugins.d.ts +19 -0
  128. package/dist/utils/initializer/registerPlugins.d.ts.map +1 -0
  129. package/dist/utils/initializer/registerPlugins.js +84 -0
  130. package/dist/utils/roles/helpers.d.ts +4 -0
  131. package/dist/utils/roles/helpers.d.ts.map +1 -0
  132. package/dist/utils/roles/helpers.js +47 -0
  133. package/dist/utils/roles/interface.d.ts +33 -0
  134. package/dist/utils/roles/interface.d.ts.map +1 -0
  135. package/dist/utils/roles/interface.js +2 -0
  136. package/dist/utils/roles/machines/commonValidators.d.ts +6 -0
  137. package/dist/utils/roles/machines/commonValidators.d.ts.map +1 -0
  138. package/dist/utils/roles/machines/commonValidators.js +34 -0
  139. package/dist/utils/roles/machines/index.d.ts +14 -0
  140. package/dist/utils/roles/machines/index.d.ts.map +1 -0
  141. package/dist/utils/roles/machines/index.js +27 -0
  142. package/dist/utils/roles/machines/interface.d.ts +46 -0
  143. package/dist/utils/roles/machines/interface.d.ts.map +1 -0
  144. package/dist/utils/roles/machines/interface.js +2 -0
  145. package/dist/utils/roles/machines/machine.d.ts +15 -0
  146. package/dist/utils/roles/machines/machine.d.ts.map +1 -0
  147. package/dist/utils/roles/machines/machine.js +97 -0
  148. package/dist/utils/roles/machines/read/A/index.d.ts +3 -0
  149. package/dist/utils/roles/machines/read/A/index.d.ts.map +1 -0
  150. package/dist/utils/roles/machines/read/A/index.js +27 -0
  151. package/dist/utils/roles/machines/read/B/index.d.ts +3 -0
  152. package/dist/utils/roles/machines/read/B/index.d.ts.map +1 -0
  153. package/dist/utils/roles/machines/read/B/index.js +36 -0
  154. package/dist/utils/roles/machines/read/C/index.d.ts +3 -0
  155. package/dist/utils/roles/machines/read/C/index.d.ts.map +1 -0
  156. package/dist/utils/roles/machines/read/C/index.js +38 -0
  157. package/dist/utils/roles/machines/read/D/index.d.ts +3 -0
  158. package/dist/utils/roles/machines/read/D/index.d.ts.map +1 -0
  159. package/dist/utils/roles/machines/read/D/index.js +26 -0
  160. package/dist/utils/roles/machines/read/D/validators.d.ts +4 -0
  161. package/dist/utils/roles/machines/read/D/validators.d.ts.map +1 -0
  162. package/dist/utils/roles/machines/read/D/validators.js +24 -0
  163. package/dist/utils/roles/machines/read/index.d.ts +2 -0
  164. package/dist/utils/roles/machines/read/index.d.ts.map +1 -0
  165. package/dist/utils/roles/machines/read/index.js +8 -0
  166. package/dist/utils/roles/machines/utils.d.ts +37 -0
  167. package/dist/utils/roles/machines/utils.d.ts.map +1 -0
  168. package/dist/utils/roles/machines/utils.js +54 -0
  169. package/dist/utils/roles/machines/write/A/index.d.ts +3 -0
  170. package/dist/utils/roles/machines/write/A/index.d.ts.map +1 -0
  171. package/dist/utils/roles/machines/write/A/index.js +29 -0
  172. package/dist/utils/roles/machines/write/B/index.d.ts +3 -0
  173. package/dist/utils/roles/machines/write/B/index.d.ts.map +1 -0
  174. package/dist/utils/roles/machines/write/B/index.js +47 -0
  175. package/dist/utils/roles/machines/write/C/index.d.ts +3 -0
  176. package/dist/utils/roles/machines/write/C/index.d.ts.map +1 -0
  177. package/dist/utils/roles/machines/write/C/index.js +26 -0
  178. package/dist/utils/roles/machines/write/C/validators.d.ts +4 -0
  179. package/dist/utils/roles/machines/write/C/validators.d.ts.map +1 -0
  180. package/dist/utils/roles/machines/write/C/validators.js +24 -0
  181. package/dist/utils/roles/machines/write/index.d.ts +2 -0
  182. package/dist/utils/roles/machines/write/index.d.ts.map +1 -0
  183. package/dist/utils/roles/machines/write/index.js +7 -0
  184. package/dist/utils/rules-matcher/interface.d.ts +338 -0
  185. package/dist/utils/rules-matcher/interface.d.ts.map +1 -0
  186. package/dist/utils/rules-matcher/interface.js +26 -0
  187. package/dist/utils/rules-matcher/utils.d.ts +11 -0
  188. package/dist/utils/rules-matcher/utils.d.ts.map +1 -0
  189. package/dist/utils/rules-matcher/utils.js +214 -0
  190. package/dist/utils/rules.d.ts +2 -0
  191. package/dist/utils/rules.d.ts.map +1 -0
  192. package/dist/utils/rules.js +22 -0
  193. package/jest.config.ts +24 -0
  194. package/package.json +63 -0
  195. package/project.json +10 -0
  196. package/rollup.config.js +17 -0
  197. package/src/auth/controller.ts +78 -0
  198. package/src/auth/dtos.ts +6 -0
  199. package/src/auth/plugins/jwt.ts +68 -0
  200. package/src/auth/providers/local-userpass/controller.ts +226 -0
  201. package/src/auth/providers/local-userpass/dtos.ts +40 -0
  202. package/src/auth/utils.ts +165 -0
  203. package/src/babel.config.json +3 -0
  204. package/src/constants.ts +22 -0
  205. package/src/fastify.d.ts +28 -0
  206. package/src/features/endpoints/index.ts +27 -0
  207. package/src/features/endpoints/interface.ts +29 -0
  208. package/src/features/endpoints/utils.ts +72 -0
  209. package/src/features/functions/controller.ts +102 -0
  210. package/src/features/functions/dtos.ts +41 -0
  211. package/src/features/functions/index.ts +21 -0
  212. package/src/features/functions/interface.ts +38 -0
  213. package/src/features/functions/utils.ts +82 -0
  214. package/src/features/rules/index.tsx +0 -0
  215. package/src/features/rules/interface.ts +24 -0
  216. package/src/features/rules/utils.ts +20 -0
  217. package/src/features/triggers/dtos.ts +9 -0
  218. package/src/features/triggers/index.ts +34 -0
  219. package/src/features/triggers/interface.ts +44 -0
  220. package/src/features/triggers/utils.ts +157 -0
  221. package/src/global.d.ts +0 -0
  222. package/src/index.ts +75 -0
  223. package/src/model.ts +1 -0
  224. package/src/services/api/index.ts +50 -0
  225. package/src/services/api/model.ts +38 -0
  226. package/src/services/api/utils.ts +39 -0
  227. package/src/services/aws/index.ts +48 -0
  228. package/src/services/index.ts +9 -0
  229. package/src/services/interface.ts +3 -0
  230. package/src/services/mongodb-atlas/index.ts +569 -0
  231. package/src/services/mongodb-atlas/model.ts +67 -0
  232. package/src/services/mongodb-atlas/utils.ts +44 -0
  233. package/src/state.ts +24 -0
  234. package/src/utils/__tests__/STEP_A_STATES.test.ts +54 -0
  235. package/src/utils/__tests__/STEP_B_STATES.test.ts +113 -0
  236. package/src/utils/__tests__/STEP_C_STATES.test.ts +87 -0
  237. package/src/utils/__tests__/STEP_D_STATES.test.ts +93 -0
  238. package/src/utils/__tests__/checkAdditionalFieldsFn.test.ts +45 -0
  239. package/src/utils/__tests__/checkApplyWhen.test.ts +49 -0
  240. package/src/utils/__tests__/checkFieldsPropertyExists.test.ts +47 -0
  241. package/src/utils/__tests__/checkIsValidFieldNameFn.test.ts +190 -0
  242. package/src/utils/__tests__/comparePassword.test.ts +38 -0
  243. package/src/utils/__tests__/evaluateDocumentsFiltersReadFn.test.ts +57 -0
  244. package/src/utils/__tests__/evaluateDocumentsFiltersWriteFn.test.ts +57 -0
  245. package/src/utils/__tests__/evaluateTopLevelReadFn.test.ts +58 -0
  246. package/src/utils/__tests__/evaluateTopLevelWriteFn.test.ts +66 -0
  247. package/src/utils/__tests__/exposeRoutes.test.ts +65 -0
  248. package/src/utils/__tests__/generateContextData.test.ts +75 -0
  249. package/src/utils/__tests__/getDefaultRule.test.ts +29 -0
  250. package/src/utils/__tests__/getKey.test.ts +12 -0
  251. package/src/utils/__tests__/getKeys.test.ts +11 -0
  252. package/src/utils/__tests__/getWinningRole.test.ts +66 -0
  253. package/src/utils/__tests__/hashPassword.test.ts +28 -0
  254. package/src/utils/__tests__/isEmpty.test.ts +17 -0
  255. package/src/utils/__tests__/logMachineInfo.test.ts +15 -0
  256. package/src/utils/__tests__/operators.test.ts +99 -0
  257. package/src/utils/__tests__/readFileContent.test.ts +35 -0
  258. package/src/utils/__tests__/registerPlugins.test.ts +59 -0
  259. package/src/utils/__tests__/rule.test.ts +51 -0
  260. package/src/utils/__tests__/rulesMatcherInterfaces.test.ts +57 -0
  261. package/src/utils/__tests__/rulesMatcherUtils.test.ts +56 -0
  262. package/src/utils/__tests__/someAsync.test.ts +55 -0
  263. package/src/utils/context/helpers.ts +71 -0
  264. package/src/utils/context/index.ts +52 -0
  265. package/src/utils/context/interface.ts +19 -0
  266. package/src/utils/crypto/index.ts +36 -0
  267. package/src/utils/helpers/someAsync.ts +24 -0
  268. package/src/utils/index.ts +5 -0
  269. package/src/utils/initializer/exposeRoutes.ts +26 -0
  270. package/src/utils/initializer/registerPlugins.ts +97 -0
  271. package/src/utils/roles/helpers.ts +47 -0
  272. package/src/utils/roles/interface.ts +42 -0
  273. package/src/utils/roles/machines/commonValidators.ts +24 -0
  274. package/src/utils/roles/machines/index.ts +20 -0
  275. package/src/utils/roles/machines/interface.ts +46 -0
  276. package/src/utils/roles/machines/machine.ts +85 -0
  277. package/src/utils/roles/machines/read/A/index.ts +19 -0
  278. package/src/utils/roles/machines/read/B/index.ts +31 -0
  279. package/src/utils/roles/machines/read/C/index.ts +30 -0
  280. package/src/utils/roles/machines/read/D/index.ts +20 -0
  281. package/src/utils/roles/machines/read/D/validators.ts +24 -0
  282. package/src/utils/roles/machines/read/index.ts +6 -0
  283. package/src/utils/roles/machines/utils.ts +54 -0
  284. package/src/utils/roles/machines/write/A/index.ts +25 -0
  285. package/src/utils/roles/machines/write/B/index.ts +43 -0
  286. package/src/utils/roles/machines/write/C/index.ts +20 -0
  287. package/src/utils/roles/machines/write/C/validators.ts +24 -0
  288. package/src/utils/roles/machines/write/index.ts +5 -0
  289. package/src/utils/rules-matcher/interface.ts +365 -0
  290. package/src/utils/rules-matcher/utils.ts +281 -0
  291. package/src/utils/rules.ts +19 -0
  292. package/tsconfig.json +28 -0
@@ -0,0 +1,226 @@
1
+ import sendGrid from "@sendgrid/mail"
2
+ import { FastifyInstance } from 'fastify'
3
+ import { AUTH_CONFIG, DB_NAME } from '../../../constants'
4
+ import { StateManager } from "../../../state"
5
+ import { GenerateContext } from "../../../utils/context"
6
+ import { comparePassword, generateToken, hashPassword } from '../../../utils/crypto'
7
+ import {
8
+ AUTH_ENDPOINTS,
9
+ AUTH_ERRORS,
10
+ CONFIRM_RESET_SCHEMA,
11
+ getMailConfig,
12
+ LOGIN_SCHEMA,
13
+ PROVIDER_TYPE,
14
+ REGISTRATION_SCHEMA,
15
+ RESET_SCHEMA
16
+ } from '../../utils'
17
+ import { ConfirmResetPasswordDto, LoginDto, RegistrationDto, ResetPasswordDto } from './dtos'
18
+
19
+ /**
20
+ * Controller for handling local user registration and login.
21
+ * @testable
22
+ * @param {FastifyInstance} app - The Fastify instance.
23
+ */
24
+ export async function localUserPassController(app: FastifyInstance) {
25
+ const { authCollection } = AUTH_CONFIG
26
+ const db = app.mongo.client.db(DB_NAME)
27
+
28
+ /**
29
+ * Endpoint for user registration.
30
+ *
31
+ * @route {POST} /register
32
+ * @param {RegistrationDto} req - The request object with registration data.
33
+ * @param {FastifyReply} res - The response object.
34
+ * @returns {Promise<Object>} A promise resolving with the newly created user's ID.
35
+ */
36
+ app.post<RegistrationDto>(
37
+ AUTH_ENDPOINTS.REGISTRATION,
38
+ {
39
+ schema: REGISTRATION_SCHEMA
40
+ },
41
+ async function (req, res) {
42
+ const { email, password } = req.body
43
+ const hashedPassword = await hashPassword(password)
44
+
45
+ const existingUser = await db.collection(authCollection!).findOne({
46
+ email
47
+ })
48
+
49
+ if (existingUser) {
50
+ res.status(409)
51
+ return {
52
+ error: 'This email address is already used'
53
+ }
54
+ }
55
+
56
+ const result = await db.collection(authCollection!).insertOne({
57
+ email: email,
58
+ password: hashedPassword,
59
+ custom_data: {
60
+ // todo li faremo arrivare
61
+ }
62
+ })
63
+
64
+ await db?.collection(authCollection!).updateOne(
65
+ {
66
+ email: email
67
+ },
68
+ {
69
+ $set: {
70
+ identities: [
71
+ {
72
+ id: result?.insertedId.toString(),
73
+ provider_id: result?.insertedId.toString(),
74
+ provider_type: PROVIDER_TYPE,
75
+ provider_data: { email }
76
+ }
77
+ ]
78
+ }
79
+ }
80
+ )
81
+
82
+ res.status(201)
83
+ return {
84
+ userId: result?.insertedId
85
+ }
86
+ }
87
+ )
88
+
89
+ /**
90
+ * Endpoint for user login.
91
+ *
92
+ * @route {POST} /login
93
+ * @param {LoginDto} req - The request object with login data.
94
+ * @returns {Promise<Object>} A promise resolving with access and refresh tokens.
95
+ */
96
+ app.post<LoginDto>(
97
+ AUTH_ENDPOINTS.LOGIN,
98
+ {
99
+ schema: LOGIN_SCHEMA
100
+ },
101
+ async function (req) {
102
+
103
+ const storedUser = await db.collection(authCollection!).findOne({
104
+ email: req.body.username
105
+ })
106
+
107
+ if (!storedUser) {
108
+ throw new Error(AUTH_ERRORS.INVALID_CREDENTIALS)
109
+ }
110
+
111
+ const passwordMatches = await comparePassword(
112
+ req.body.password,
113
+ storedUser.password
114
+ )
115
+
116
+ if (!passwordMatches) {
117
+ throw new Error(AUTH_ERRORS.INVALID_CREDENTIALS)
118
+ }
119
+
120
+ return {
121
+ access_token: this.createAccessToken(storedUser),
122
+ refresh_token: this.createRefreshToken(storedUser),
123
+ device_id: '',
124
+ user_id: storedUser._id.toString()
125
+ }
126
+ }
127
+ )
128
+
129
+ /**
130
+ * Endpoint for reset password.
131
+ *
132
+ * @route {POST} /reset/call
133
+ * @param {ResetPasswordDto} req - The request object with th reset request.
134
+ * @returns {Promise<void>}
135
+ */
136
+ app.post<ResetPasswordDto>(
137
+ AUTH_ENDPOINTS.RESET,
138
+ {
139
+ schema: RESET_SCHEMA
140
+ },
141
+ async function (req) {
142
+ const { resetPasswordCollection, resetPasswordConfig } = AUTH_CONFIG
143
+ const email = req.body.email
144
+ const storedUser = await db.collection(authCollection!).findOne({
145
+ email
146
+ })
147
+
148
+ if (!storedUser) {
149
+ throw new Error(AUTH_ERRORS.INVALID_CREDENTIALS)
150
+ }
151
+
152
+ const token = generateToken()
153
+ const tokenId = generateToken()
154
+
155
+ await db?.collection(resetPasswordCollection).updateOne(
156
+ { email },
157
+ { $set: { token, tokenId, email, createdAt: new Date() } },
158
+ { upsert: true }
159
+ );
160
+
161
+
162
+ if (resetPasswordConfig.runResetFunction && resetPasswordConfig.resetFunctionName) {
163
+ const functionsList = StateManager.select("functions")
164
+ const services = StateManager.select("services")
165
+ const currentFunction = functionsList[resetPasswordConfig.resetFunctionName]
166
+ await GenerateContext({
167
+ args: [{ token, tokenId, email }],
168
+ app,
169
+ rules: {},
170
+ user: {},
171
+ currentFunction,
172
+ functionsList,
173
+ services
174
+ })
175
+ return
176
+ }
177
+
178
+ const { from, subject, mailToken, body } = getMailConfig(resetPasswordConfig, token, tokenId)
179
+ sendGrid.setApiKey(mailToken)
180
+ await sendGrid.send({
181
+ to: email,
182
+ from,
183
+ subject,
184
+ html: body
185
+ });
186
+
187
+ }
188
+ )
189
+
190
+ /**
191
+ * Endpoint for confirm reset password.
192
+ *
193
+ * @route {POST} /reset
194
+ * @param {ConfirmResetPasswordDto} req - The request object with reset data.
195
+ * @returns {Promise<void>}
196
+ */
197
+ app.post<ConfirmResetPasswordDto>(
198
+ AUTH_ENDPOINTS.CONFIRM_RESET,
199
+ {
200
+ schema: CONFIRM_RESET_SCHEMA
201
+ },
202
+ async function (req) {
203
+ const { resetPasswordCollection } = AUTH_CONFIG
204
+ const { token, tokenId, password } = req.body
205
+
206
+ const resetRequest = await db?.collection(resetPasswordCollection).findOne(
207
+ { token, tokenId },
208
+ );
209
+
210
+ if (!resetRequest) {
211
+ throw new Error(AUTH_ERRORS.INVALID_RESET_PARAMS)
212
+ }
213
+ const hashedPassword = await hashPassword(password)
214
+ await db.collection(authCollection!).updateOne({ email: resetRequest.email, }, {
215
+ $set: {
216
+ password: hashedPassword
217
+ }
218
+ })
219
+
220
+ await db?.collection(resetPasswordCollection).deleteOne(
221
+ { _id: resetRequest._id },
222
+ );
223
+
224
+ }
225
+ )
226
+ }
@@ -0,0 +1,40 @@
1
+ export type RegisterUserDto = {
2
+ email: string
3
+ password: string
4
+ }
5
+
6
+ export type LoginUserDto = {
7
+ username: string
8
+ password: string
9
+ }
10
+
11
+ export type LoginSuccessDto = {
12
+ access_token: string
13
+ device_id: string
14
+ refresh_token: string
15
+ user_id: string
16
+ }
17
+
18
+ export interface RegistrationDto {
19
+ Body: RegisterUserDto
20
+ }
21
+
22
+ export interface LoginDto {
23
+ Body: LoginUserDto
24
+ Reply: LoginSuccessDto
25
+ }
26
+
27
+ export interface ResetPasswordDto {
28
+ Body: {
29
+ email: string
30
+ password: string
31
+ }
32
+ }
33
+
34
+ export interface ConfirmResetPasswordDto {
35
+ Body: {
36
+ token: string
37
+ tokenId: string
38
+ password: string
39
+ }
40
+ }
@@ -0,0 +1,165 @@
1
+ import fs from 'fs'
2
+
3
+ export const LOGIN_SCHEMA = {
4
+ body: {
5
+ type: 'object',
6
+ properties: {
7
+ username: { type: 'string' },
8
+ password: { type: 'string' }
9
+ },
10
+ required: ['username', 'password']
11
+ }
12
+ }
13
+
14
+ export const RESET_SCHEMA = {
15
+ body: {
16
+ type: 'object',
17
+ properties: {
18
+ email: { type: 'string' },
19
+ password: { type: 'string' }
20
+ },
21
+ required: ['email', 'password']
22
+ }
23
+ }
24
+
25
+
26
+ export const CONFIRM_RESET_SCHEMA = {
27
+ body: {
28
+ type: 'object',
29
+ properties: {
30
+ password: { type: 'string' },
31
+ token: { type: 'string' },
32
+ tokenId: { type: 'string' }
33
+ },
34
+ required: ['password', 'token', 'tokenId']
35
+ }
36
+ }
37
+
38
+
39
+ export const REGISTRATION_SCHEMA = {
40
+ body: {
41
+ type: 'object',
42
+ properties: {
43
+ email: { type: 'string' },
44
+ password: { type: 'string' }
45
+ },
46
+ required: ['email', 'password']
47
+ }
48
+ }
49
+
50
+ export enum AUTH_ENDPOINTS {
51
+ LOGIN = '/login',
52
+ REGISTRATION = '/register',
53
+ PROFILE = '/profile',
54
+ SESSION = '/session',
55
+ RESET = '/reset/call',
56
+ CONFIRM_RESET = "/reset"
57
+ }
58
+
59
+ export enum AUTH_ERRORS {
60
+ INVALID_CREDENTIALS = 'Invalid credentials',
61
+ INVALID_TOKEN = 'Invalid refresh token provided',
62
+ INVALID_RESET_PARAMS = 'Invalid token or tokenId provided'
63
+ }
64
+
65
+ export interface AuthConfig {
66
+ auth_collection?: string
67
+ 'api-key': ApiKey
68
+ 'local-userpass': LocalUserpass
69
+ }
70
+
71
+ interface ApiKey {
72
+ name: string
73
+ type: string
74
+ disabled: boolean
75
+ }
76
+ interface LocalUserpass {
77
+ name: string
78
+ type: string
79
+ disabled: boolean
80
+ config: Config
81
+ }
82
+
83
+ export interface Config {
84
+ autoConfirm: boolean
85
+ resetFunctionName: string
86
+ resetPasswordUrl: string
87
+ runConfirmationFunction: boolean
88
+ runResetFunction: boolean
89
+ mailConfig: {
90
+ from: string
91
+ subject: string
92
+ mailToken: string
93
+ }
94
+ }
95
+
96
+ export interface CustomUserDataConfig {
97
+ enabled: boolean
98
+ mongo_service_name: string
99
+ database_name: string
100
+ collection_name: string
101
+ user_id_field: string
102
+ }
103
+
104
+ export const PROVIDER_TYPE = 'local-userpass'
105
+
106
+ /**
107
+ * > Loads the auth config json file
108
+ * @testable
109
+ */
110
+ export const loadAuthConfig = (): AuthConfig => {
111
+ return JSON.parse(fs.readFileSync('auth/providers.json', 'utf-8'))
112
+ }
113
+
114
+ /**
115
+ * > Loads the custom user data config json file
116
+ * @testable
117
+ */
118
+ export const loadCustomUserData = (): CustomUserDataConfig => {
119
+ return JSON.parse(fs.readFileSync('auth/custom_user_data.json', 'utf-8'))
120
+ }
121
+
122
+
123
+
124
+ export const getMailConfig = (resetPasswordConfig: Config, token: string, tokenId: string) => {
125
+ const { mailConfig, resetPasswordUrl } = resetPasswordConfig
126
+ const ENV_PREFIX = "ENV"
127
+ const { from, subject, mailToken } = mailConfig
128
+
129
+ const [fromPrefix, fromPath] = from.split(".")
130
+ const currentSender = (fromPrefix === ENV_PREFIX ? process.env[fromPath] : from) ?? ""
131
+ const [subjectPrefix, subjectPath] = subject.split(".")
132
+ const currentSubject = (subjectPrefix === ENV_PREFIX ? process.env[subjectPath] : subject) ?? ""
133
+ const [mailTokenPrefix, mailTokenPath] = mailToken.split(".")
134
+ const currentMailToken = (mailTokenPrefix === "ENV" ? process.env[mailTokenPath] : mailToken) ?? ""
135
+
136
+ const link = `${resetPasswordUrl}/${token}/${tokenId}`;
137
+ const body = `<body style="font-family: Arial, sans-serif; background-color: #f4f4f4; text-align: center; padding: 20px;">
138
+ <table width="100%" cellspacing="0" cellpadding="0">
139
+ <tr>
140
+ <td align="center">
141
+ <table width="600" cellspacing="0" cellpadding="0" style="background: #ffffff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);">
142
+ <tr>
143
+ <td align="center">
144
+ <h2>Password Reset Request</h2>
145
+ <p>If you requested a password reset, click the button below to reset your password.</p>
146
+ <p>If you did not request this, please ignore this email.</p>
147
+ <p>
148
+ <a href="${link}" style="display: inline-block; padding: 12px 20px; font-size: 16px; color: #ffffff; background: #007bff; text-decoration: none; border-radius: 5px;">Reset Password</a>
149
+ </p>
150
+ <p style="margin-top: 20px; font-size: 12px; color: #777;">If the button does not work, copy and paste the following link into your browser:</p>
151
+ <p style="font-size: 12px; color: #777;">${link}</p>
152
+ </td>
153
+ </tr>
154
+ </table>
155
+ </td>
156
+ </tr>
157
+ </table>
158
+ </body>`
159
+ return {
160
+ from: currentSender ?? "",
161
+ subject: currentSubject,
162
+ mailToken: currentMailToken,
163
+ body
164
+ }
165
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "presets": ["@babel/preset-env"]
3
+ }
@@ -0,0 +1,22 @@
1
+ import { loadAuthConfig, loadCustomUserData } from './auth/utils'
2
+
3
+ const { database_name, collection_name = 'users', user_id_field = "id" } = loadCustomUserData()
4
+ const { auth_collection = 'auth_users', ...configuration } = loadAuthConfig()
5
+
6
+ export const DEFAULT_CONFIG = {
7
+ PORT: Number(process.env.PORT) || 3000,
8
+ MONGODB_URL: process.env.MONGODB_URL || '',
9
+ JWT_SECRET: process.env.JWT_SECRET || '',
10
+ API_VERSION: process.env.API_VERSION || "v2.0",
11
+ HTTPS_SCHEMA: process.env.HTTPS_SCHEMA || 'https'
12
+ }
13
+ export const API_VERSION = `/api/client/${DEFAULT_CONFIG.API_VERSION}`
14
+ export const HTTPS_SCHEMA = DEFAULT_CONFIG.HTTPS_SCHEMA
15
+ export const DB_NAME = database_name
16
+ export const AUTH_CONFIG = {
17
+ authCollection: auth_collection,
18
+ userCollection: collection_name,
19
+ resetPasswordCollection: "reset-password-requests",
20
+ resetPasswordConfig: configuration['local-userpass'].config,
21
+ user_id_field
22
+ }
@@ -0,0 +1,28 @@
1
+ import { FastifyRequest as FastifyRequestType } from 'fastify'
2
+
3
+ type User = Record<string, unknown>
4
+ type UserData = Record<string, unknown>
5
+
6
+ declare module 'fastify' {
7
+ interface FastifyInstance {
8
+ jwtAuthentication(req: FastifyRequestType, rep: FastifyReply): Promise<void>
9
+ createAccessToken(user: User): string
10
+ createRefreshToken(user: User): string
11
+ }
12
+
13
+ interface FastifyRequest {
14
+ user:
15
+ | {
16
+ id: string
17
+ typ: 'refresh'
18
+ sub: string
19
+ user_data: UserData
20
+ user: User
21
+ }
22
+ | {
23
+ typ: 'access'
24
+ user_data: UserData
25
+ id: string
26
+ }
27
+ }
28
+ }
@@ -0,0 +1,27 @@
1
+ import { GenerateEndpointsParams } from './interface'
2
+ import { generateHandler, getMethodsConfig } from './utils'
3
+
4
+ /**
5
+ * > Generates all HTTP endpoints
6
+ * @testable
7
+ * @param app -> the fastify instance
8
+ * @param functionsList -> the list of all functions
9
+ * @param endpointsList -> the list of all endpoints
10
+ */
11
+ export const generateEndpoints = async ({
12
+ app,
13
+ functionsList,
14
+ endpointsList
15
+ }: GenerateEndpointsParams) => {
16
+ endpointsList.forEach(({ http_method, route, disabled, function_name }) => {
17
+ const currentFunction = functionsList[function_name]
18
+
19
+ if (disabled || !currentFunction) return
20
+
21
+ const handler = generateHandler({ app, currentFunction, functionsList })
22
+ const currentMethod = getMethodsConfig(app, handler, `/app/:appId/endpoint/${route}`)[
23
+ http_method
24
+ ]
25
+ currentMethod()
26
+ })
27
+ }
@@ -0,0 +1,29 @@
1
+ import { FastifyInstance } from 'fastify'
2
+ import { Function, Functions } from '../functions/interface'
3
+
4
+ export type GenerateEndpointsParams = {
5
+ app: FastifyInstance
6
+ functionsList: Functions
7
+ endpointsList: Endpoints
8
+ }
9
+
10
+ export type GenerateHandlerParams = {
11
+ app: FastifyInstance
12
+ currentFunction: Function
13
+ functionsList: Functions
14
+ }
15
+
16
+ type HTTP_METHOD<T> = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | T
17
+
18
+ export type Endpoint<T = 'ALL'> = {
19
+ http_method: HTTP_METHOD<T>
20
+ route: string
21
+ function_name: string
22
+ secret_name: string
23
+ validation_method: string
24
+ respond_result: boolean
25
+ fetch_custom_user_data: boolean
26
+ create_user_on_auth: boolean
27
+ disabled: boolean
28
+ }
29
+ export type Endpoints<T = 'ALL'> = Endpoint<T>[]
@@ -0,0 +1,72 @@
1
+ import fs from 'fs'
2
+ import { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify'
3
+
4
+ import { services } from '../../services'
5
+
6
+ import { GenerateContext } from '../../utils/context'
7
+ import { Endpoints, GenerateHandlerParams } from './interface'
8
+
9
+ /**
10
+ * > Loads the endpoint config json file
11
+ * @testable
12
+ */
13
+ export const loadEndpoints = async (): Promise<Endpoints> => {
14
+ const config: Endpoints<'*'> = JSON.parse(
15
+ fs.readFileSync('http_endpoints/config.json', 'utf-8')
16
+ )
17
+ return config.map(({ http_method, ...endpoint }) => ({
18
+ http_method: http_method === '*' ? 'ALL' : http_method,
19
+ ...endpoint
20
+ }))
21
+ }
22
+
23
+ /**
24
+ * > Creates an object with a config for all HTTP methods
25
+ * @testable
26
+ * @param app -> the fastify instance
27
+ * @param handler -> the handler function for that route
28
+ * @param endpoint -> the current endpoint
29
+ */
30
+ export const getMethodsConfig = (
31
+ app: FastifyInstance,
32
+ handler: ReturnType<typeof generateHandler>,
33
+ endpoint: string
34
+ ) => ({
35
+ ALL: () => app.all(endpoint, handler),
36
+ GET: () => app.get(endpoint, handler),
37
+ POST: () => app.post(endpoint, handler),
38
+ PUT: () => app.put(endpoint, handler),
39
+ PATCH: () => app.patch(endpoint, handler),
40
+ DELETE: () => app.delete(endpoint, handler)
41
+ })
42
+
43
+ /**
44
+ * > Creates an handler function for a single endpoint
45
+ * @testable
46
+ * @param app -> the fastify instance
47
+ * @param currentFunction -> the name of the function that should be called for that endpoint
48
+ * @param functionsList -> the list of all functions
49
+ */
50
+ export const generateHandler = ({
51
+ app,
52
+ currentFunction,
53
+ functionsList
54
+ }: GenerateHandlerParams) => {
55
+ return async (req: FastifyRequest, res: FastifyReply) => {
56
+ try {
57
+ const response = await GenerateContext({
58
+ args: [req],
59
+ app,
60
+ rules: {}, //TODO -> check rules
61
+ user: req.user,
62
+ currentFunction,
63
+ functionsList,
64
+ services
65
+ })
66
+ res.send(response)
67
+ } catch (e) {
68
+ console.log(e)
69
+ }
70
+ return {}
71
+ }
72
+ }