@skalfa/skalfa-api-core 1.0.3 → 1.0.8

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 (284) hide show
  1. package/CONTRIBUTING.md +45 -0
  2. package/LICENSE +21 -0
  3. package/README.md +60 -0
  4. package/dist/auth/auth.d.ts +18 -15
  5. package/dist/auth/auth.js +20 -203
  6. package/dist/auth/auth.js.map +1 -1
  7. package/dist/auth/create-access-token.d.ts +4 -0
  8. package/dist/auth/create-access-token.js +26 -0
  9. package/dist/auth/create-access-token.js.map +1 -0
  10. package/dist/auth/create-user-mail-token.d.ts +4 -0
  11. package/dist/auth/create-user-mail-token.js +19 -0
  12. package/dist/auth/create-user-mail-token.js.map +1 -0
  13. package/dist/auth/helpers/generate-agent-id.d.ts +1 -0
  14. package/dist/auth/helpers/generate-agent-id.js +7 -0
  15. package/dist/auth/helpers/generate-agent-id.js.map +1 -0
  16. package/dist/auth/helpers/get-request-ip.d.ts +1 -0
  17. package/dist/auth/helpers/get-request-ip.js +4 -0
  18. package/dist/auth/helpers/get-request-ip.js.map +1 -0
  19. package/dist/auth/helpers/get-user-permissions.d.ts +1 -0
  20. package/dist/auth/helpers/get-user-permissions.js +9 -0
  21. package/dist/auth/helpers/get-user-permissions.js.map +1 -0
  22. package/dist/auth/helpers/index.d.ts +3 -0
  23. package/dist/auth/helpers/index.js +4 -0
  24. package/dist/auth/helpers/index.js.map +1 -0
  25. package/dist/auth/list-user-sessions.d.ts +1 -0
  26. package/dist/auth/list-user-sessions.js +10 -0
  27. package/dist/auth/list-user-sessions.js.map +1 -0
  28. package/dist/auth/revalidate-user-permissions-by-role.d.ts +1 -0
  29. package/dist/auth/revalidate-user-permissions-by-role.js +12 -0
  30. package/dist/auth/revalidate-user-permissions-by-role.js.map +1 -0
  31. package/dist/auth/revalidate-user-permissions.d.ts +1 -0
  32. package/dist/auth/revalidate-user-permissions.js +21 -0
  33. package/dist/auth/revalidate-user-permissions.js.map +1 -0
  34. package/dist/auth/revoke-access-token.d.ts +1 -0
  35. package/dist/auth/revoke-access-token.js +5 -0
  36. package/dist/auth/revoke-access-token.js.map +1 -0
  37. package/dist/auth/verify-access-token.d.ts +1 -0
  38. package/dist/auth/verify-access-token.js +47 -0
  39. package/dist/auth/verify-access-token.js.map +1 -0
  40. package/dist/auth/verify-user-mail-token.d.ts +1 -0
  41. package/dist/auth/verify-user-mail-token.js +21 -0
  42. package/dist/auth/verify-user-mail-token.js.map +1 -0
  43. package/dist/commands/cli.js +18 -27
  44. package/dist/commands/cli.js.map +1 -1
  45. package/dist/commands/make/basic-controller.js +1 -1
  46. package/dist/commands/make/basic-controller.js.map +1 -1
  47. package/dist/commands/make/basic-migration.d.ts +1 -1
  48. package/dist/commands/make/basic-migration.js +2 -2
  49. package/dist/commands/make/basic-migration.js.map +1 -1
  50. package/dist/commands/make/basic-model.js +1 -1
  51. package/dist/commands/make/basic-model.js.map +1 -1
  52. package/dist/commands/make/basic-seeder.js +1 -1
  53. package/dist/commands/make/basic-seeder.js.map +1 -1
  54. package/dist/commands/make/blueprint.js +1 -1
  55. package/dist/commands/make/blueprint.js.map +1 -1
  56. package/dist/commands/make/da-migration.js +3 -3
  57. package/dist/commands/make/da-migration.js.map +1 -1
  58. package/dist/commands/make/mail.js +2 -2
  59. package/dist/commands/make/mail.js.map +1 -1
  60. package/dist/commands/make/notification.js +1 -1
  61. package/dist/commands/make/notification.js.map +1 -1
  62. package/dist/commands/make/queue.js +1 -1
  63. package/dist/commands/make/queue.js.map +1 -1
  64. package/dist/commands/make/resource.d.ts +2 -0
  65. package/dist/commands/make/resource.js +19 -0
  66. package/dist/commands/make/resource.js.map +1 -0
  67. package/dist/commands/make/skalfa-controller.d.ts +3 -0
  68. package/dist/commands/make/{light-controller.js → skalfa-controller.js} +9 -9
  69. package/dist/commands/make/skalfa-controller.js.map +1 -0
  70. package/dist/commands/make/skalfa-model.d.ts +3 -0
  71. package/dist/commands/make/{light-model.js → skalfa-model.js} +11 -11
  72. package/dist/commands/make/skalfa-model.js.map +1 -0
  73. package/dist/commands/runner/barrels.js.map +1 -1
  74. package/dist/commands/runner/blueprint/controller-generation.js +2 -2
  75. package/dist/commands/runner/blueprint/controller-generation.js.map +1 -1
  76. package/dist/commands/runner/blueprint/documentation-generation.js.map +1 -1
  77. package/dist/commands/runner/blueprint/migration-generation.js +3 -3
  78. package/dist/commands/runner/blueprint/migration-generation.js.map +1 -1
  79. package/dist/commands/runner/blueprint/model-generation.js +2 -2
  80. package/dist/commands/runner/blueprint/model-generation.js.map +1 -1
  81. package/dist/commands/runner/blueprint/runner.js +7 -8
  82. package/dist/commands/runner/blueprint/runner.js.map +1 -1
  83. package/dist/commands/runner/blueprint/seeder-generation.js +3 -3
  84. package/dist/commands/runner/blueprint/seeder-generation.js.map +1 -1
  85. package/dist/commands/runner/da-migration.js +1 -2
  86. package/dist/commands/runner/da-migration.js.map +1 -1
  87. package/dist/commands/runner/generate-docs.d.ts +2 -0
  88. package/dist/commands/runner/generate-docs.js +400 -0
  89. package/dist/commands/runner/generate-docs.js.map +1 -0
  90. package/dist/commands/runner/migration.js +1 -1
  91. package/dist/commands/runner/migration.js.map +1 -1
  92. package/dist/commands/runner/seeder.js +1 -1
  93. package/dist/commands/runner/seeder.js.map +1 -1
  94. package/dist/commands/stubs/index.d.ts +4 -4
  95. package/dist/commands/stubs/index.js +4 -4
  96. package/dist/commands/stubs/index.js.map +1 -1
  97. package/dist/context/context.js +6 -0
  98. package/dist/context/context.js.map +1 -1
  99. package/dist/controller/controller.d.ts +17 -30
  100. package/dist/controller/controller.js +39 -121
  101. package/dist/controller/controller.js.map +1 -1
  102. package/dist/controller/response.d.ts +6 -0
  103. package/dist/controller/response.js +63 -0
  104. package/dist/controller/response.js.map +1 -0
  105. package/dist/controller/storage.d.ts +9 -0
  106. package/dist/controller/storage.js +56 -0
  107. package/dist/controller/storage.js.map +1 -0
  108. package/dist/conversion/conversion.d.ts +3 -0
  109. package/dist/conversion/conversion.js +28 -4
  110. package/dist/conversion/conversion.js.map +1 -1
  111. package/dist/conversion/date.d.ts +1 -0
  112. package/dist/conversion/date.js +77 -0
  113. package/dist/conversion/date.js.map +1 -0
  114. package/dist/index.d.ts +2 -0
  115. package/dist/index.js +2 -0
  116. package/dist/index.js.map +1 -1
  117. package/dist/logger/logger.js +33 -0
  118. package/dist/logger/logger.js.map +1 -1
  119. package/dist/mail/mail.js +6 -6
  120. package/dist/mail/mail.js.map +1 -1
  121. package/dist/middleware/access-log.d.ts +31 -0
  122. package/dist/middleware/access-log.js +13 -0
  123. package/dist/middleware/access-log.js.map +1 -0
  124. package/dist/middleware/auth.d.ts +37 -0
  125. package/dist/middleware/auth.js +16 -0
  126. package/dist/middleware/auth.js.map +1 -0
  127. package/dist/middleware/body-parse.d.ts +35 -0
  128. package/dist/middleware/body-parse.js +87 -0
  129. package/dist/middleware/body-parse.js.map +1 -0
  130. package/dist/middleware/context.d.ts +29 -0
  131. package/dist/middleware/context.js +8 -0
  132. package/dist/middleware/context.js.map +1 -0
  133. package/dist/middleware/cors.d.ts +31 -0
  134. package/dist/middleware/cors.js +27 -0
  135. package/dist/middleware/cors.js.map +1 -0
  136. package/dist/middleware/error-handler.d.ts +33 -0
  137. package/dist/middleware/error-handler.js +17 -0
  138. package/dist/middleware/error-handler.js.map +1 -0
  139. package/dist/middleware/middleware.d.ts +31 -10
  140. package/dist/middleware/middleware.js +41 -209
  141. package/dist/middleware/middleware.js.map +1 -1
  142. package/dist/middleware/private.d.ts +29 -0
  143. package/dist/middleware/private.js +8 -0
  144. package/dist/middleware/private.js.map +1 -0
  145. package/dist/middleware/rate-limiter.d.ts +32 -0
  146. package/dist/middleware/rate-limiter.js +30 -0
  147. package/dist/middleware/rate-limiter.js.map +1 -0
  148. package/dist/notification/index.d.ts +1 -0
  149. package/dist/notification/index.js +2 -0
  150. package/dist/notification/index.js.map +1 -0
  151. package/dist/notification/notification.d.ts +16 -0
  152. package/dist/notification/notification.js +64 -0
  153. package/dist/notification/notification.js.map +1 -0
  154. package/dist/permission/permission.js +9 -0
  155. package/dist/permission/permission.js.map +1 -1
  156. package/dist/registry/registry.d.ts +0 -6
  157. package/dist/registry/registry.js +6 -6
  158. package/dist/registry/registry.js.map +1 -1
  159. package/dist/storage/storage.d.ts +3 -3
  160. package/dist/storage/storage.js.map +1 -1
  161. package/dist/validation/validation.js +43 -51
  162. package/dist/validation/validation.js.map +1 -1
  163. package/package.json +4 -4
  164. package/src/auth/auth.ts +21 -252
  165. package/src/auth/create-access-token.ts +29 -0
  166. package/src/auth/create-user-mail-token.ts +24 -0
  167. package/src/auth/helpers/generate-agent-id.ts +8 -0
  168. package/src/auth/helpers/get-request-ip.ts +3 -0
  169. package/src/auth/helpers/get-user-permissions.ts +15 -0
  170. package/src/auth/helpers/index.ts +3 -0
  171. package/src/auth/list-user-sessions.ts +11 -0
  172. package/src/auth/revalidate-user-permissions-by-role.ts +13 -0
  173. package/src/auth/revalidate-user-permissions.ts +26 -0
  174. package/src/auth/revoke-access-token.ts +5 -0
  175. package/src/auth/verify-access-token.ts +56 -0
  176. package/src/auth/verify-user-mail-token.ts +24 -0
  177. package/src/commands/cli.ts +19 -29
  178. package/src/commands/make/basic-controller.ts +4 -2
  179. package/src/commands/make/basic-migration.ts +5 -3
  180. package/src/commands/make/basic-model.ts +3 -1
  181. package/src/commands/make/basic-seeder.ts +3 -1
  182. package/src/commands/make/blueprint.ts +3 -1
  183. package/src/commands/make/da-migration.ts +6 -5
  184. package/src/commands/make/mail.ts +4 -2
  185. package/src/commands/make/notification.ts +3 -1
  186. package/src/commands/make/queue.ts +3 -1
  187. package/src/commands/make/resource.ts +21 -0
  188. package/src/commands/make/{light-controller.ts → skalfa-controller.ts} +10 -8
  189. package/src/commands/make/{light-model.ts → skalfa-model.ts} +12 -10
  190. package/src/commands/runner/barrels.ts +4 -0
  191. package/src/commands/runner/blueprint/controller-generation.ts +4 -2
  192. package/src/commands/runner/blueprint/documentation-generation.ts +2 -0
  193. package/src/commands/runner/blueprint/migration-generation.ts +5 -3
  194. package/src/commands/runner/blueprint/model-generation.ts +4 -2
  195. package/src/commands/runner/blueprint/runner.ts +15 -8
  196. package/src/commands/runner/blueprint/seeder-generation.ts +5 -3
  197. package/src/commands/runner/da-migration.ts +3 -2
  198. package/src/commands/runner/generate-docs.ts +495 -0
  199. package/src/commands/runner/migration.ts +1 -1
  200. package/src/commands/runner/seeder.ts +1 -1
  201. package/src/commands/stubs/index.ts +4 -4
  202. package/src/context/context.ts +23 -17
  203. package/src/controller/controller.ts +124 -239
  204. package/src/controller/response.ts +78 -0
  205. package/src/controller/storage.ts +78 -0
  206. package/src/conversion/conversion.ts +90 -64
  207. package/src/conversion/date.ts +74 -0
  208. package/src/index.ts +2 -0
  209. package/src/logger/logger.ts +217 -176
  210. package/src/mail/mail.ts +85 -85
  211. package/src/middleware/access-log.ts +15 -0
  212. package/src/middleware/auth.ts +19 -0
  213. package/src/middleware/body-parse.ts +83 -0
  214. package/src/middleware/context.ts +11 -0
  215. package/src/middleware/cors.ts +31 -0
  216. package/src/middleware/error-handler.ts +20 -0
  217. package/src/middleware/middleware.ts +91 -288
  218. package/src/middleware/private.ts +8 -0
  219. package/src/middleware/rate-limiter.ts +41 -0
  220. package/src/notification/index.ts +1 -0
  221. package/src/notification/notification.ts +86 -0
  222. package/src/permission/permission.ts +140 -136
  223. package/src/registry/registry.ts +17 -15
  224. package/src/route/route.ts +11 -11
  225. package/src/storage/storage.ts +104 -106
  226. package/src/validation/validation.ts +322 -346
  227. package/dist/auth.util.d.ts +0 -19
  228. package/dist/auth.util.js +0 -183
  229. package/dist/auth.util.js.map +0 -1
  230. package/dist/commands/make/light-controller.d.ts +0 -3
  231. package/dist/commands/make/light-controller.js.map +0 -1
  232. package/dist/commands/make/light-model.d.ts +0 -3
  233. package/dist/commands/make/light-model.js.map +0 -1
  234. package/dist/context.util.d.ts +0 -7
  235. package/dist/context.util.js +0 -11
  236. package/dist/context.util.js.map +0 -1
  237. package/dist/controller.util.d.ts +0 -118
  238. package/dist/controller.util.js +0 -144
  239. package/dist/controller.util.js.map +0 -1
  240. package/dist/conversion.util.d.ts +0 -8
  241. package/dist/conversion.util.js +0 -52
  242. package/dist/conversion.util.js.map +0 -1
  243. package/dist/db/db.d.ts +0 -84
  244. package/dist/db/db.js +0 -177
  245. package/dist/db/db.js.map +0 -1
  246. package/dist/db/index.d.ts +0 -1
  247. package/dist/db/index.js +0 -2
  248. package/dist/db/index.js.map +0 -1
  249. package/dist/db.util.d.ts +0 -84
  250. package/dist/db.util.js +0 -177
  251. package/dist/db.util.js.map +0 -1
  252. package/dist/logger.util.d.ts +0 -30
  253. package/dist/logger.util.js +0 -126
  254. package/dist/logger.util.js.map +0 -1
  255. package/dist/mail.util.d.ts +0 -21
  256. package/dist/mail.util.js +0 -53
  257. package/dist/mail.util.js.map +0 -1
  258. package/dist/middleware.util.d.ts +0 -263
  259. package/dist/middleware.util.js +0 -233
  260. package/dist/middleware.util.js.map +0 -1
  261. package/dist/model/index.d.ts +0 -3
  262. package/dist/model/index.js +0 -4
  263. package/dist/model/index.js.map +0 -1
  264. package/dist/model/model.d.ts +0 -204
  265. package/dist/model/model.js +0 -1495
  266. package/dist/model/model.js.map +0 -1
  267. package/dist/model.util.d.ts +0 -204
  268. package/dist/model.util.js +0 -1495
  269. package/dist/model.util.js.map +0 -1
  270. package/dist/permission.util.d.ts +0 -38
  271. package/dist/permission.util.js +0 -91
  272. package/dist/permission.util.js.map +0 -1
  273. package/dist/registry.util.d.ts +0 -28
  274. package/dist/registry.util.js +0 -19
  275. package/dist/registry.util.js.map +0 -1
  276. package/dist/route.util.d.ts +0 -1
  277. package/dist/route.util.js +0 -12
  278. package/dist/route.util.js.map +0 -1
  279. package/dist/storage.util.d.ts +0 -56
  280. package/dist/storage.util.js +0 -82
  281. package/dist/storage.util.js.map +0 -1
  282. package/dist/validation.util.d.ts +0 -7
  283. package/dist/validation.util.js +0 -237
  284. package/dist/validation.util.js.map +0 -1
@@ -1,28 +1,13 @@
1
1
  import validator from "validator";
2
2
  import { db } from "@skalfa/skalfa-orm";
3
- // ==================================>
4
- // ## Check validate field from rules
5
- // ==================================>
3
+ // =====================================>
4
+ // ## Validation: validate request data
5
+ // =====================================>
6
6
  export async function validate(data, rules) {
7
7
  const errors = {};
8
8
  for (const field in rules) {
9
9
  const fieldRules = normalizeRules(rules[field]);
10
10
  if (field.includes("*")) {
11
- // const [arrayPath, childPath] = field.split(".*.")
12
- // const arr = getNestedValue(data, arrayPath)
13
- // if (!Array.isArray(arr)) {
14
- // addError(errors, arrayPath, `${arrayPath} harus berupa array`)
15
- // continue
16
- // }
17
- // for (let i = 0; i < arr.length; i++) {
18
- // const value = childPath
19
- // ? getNestedValue(arr[i], childPath)
20
- // : arr[i]
21
- // const itemField = childPath
22
- // ? `${arrayPath}.${i}.${childPath}`
23
- // : `${arrayPath}.${i}`
24
- // await checkRules({ field: itemField, value, rules: fieldRules, data, errors })
25
- // }
26
11
  const segments = field.split(".");
27
12
  await nestedValidation({ value: data, segments, rules: fieldRules, fieldPath: "", data, errors });
28
13
  continue;
@@ -47,12 +32,16 @@ async function checkRules({ field, value, rules, data, errors }) {
47
32
  break;
48
33
  case "string":
49
34
  case "text":
35
+ if (!value)
36
+ break;
50
37
  if (typeof value !== "string") {
51
38
  addError(errors, field, `${field} harus berupa string`);
52
39
  }
53
40
  break;
54
41
  case "numeric":
55
42
  case "number":
43
+ if (!value)
44
+ break;
56
45
  if (!validator.isNumeric(String(value))) {
57
46
  addError(errors, field, `${field} harus berupa angka`);
58
47
  }
@@ -63,22 +52,30 @@ async function checkRules({ field, value, rules, data, errors }) {
63
52
  }
64
53
  break;
65
54
  case "email":
55
+ if (!value)
56
+ break;
66
57
  if (!validator.isEmail(String(value))) {
67
58
  addError(errors, field, `${field} harus berupa email yang valid`);
68
59
  }
69
60
  break;
70
61
  case "url":
62
+ if (!value)
63
+ break;
71
64
  if (!validator.isURL(String(value))) {
72
65
  addError(errors, field, `${field} harus berupa URL yang valid`);
73
66
  }
74
67
  break;
75
68
  case "date":
69
+ if (!value)
70
+ break;
76
71
  if (!validator.isDate(String(value))) {
77
72
  addError(errors, field, `${field} harus berupa tanggal yang valid`);
78
73
  }
79
74
  break;
80
75
  // === LENGTH ===
81
76
  case "min": {
77
+ if (!value)
78
+ break;
82
79
  const min = parseInt(param);
83
80
  if (!validator.isLength(String(value), { min })) {
84
81
  addError(errors, field, `${field} minimal ${min} karakter`);
@@ -86,6 +83,8 @@ async function checkRules({ field, value, rules, data, errors }) {
86
83
  break;
87
84
  }
88
85
  case "max": {
86
+ if (!value)
87
+ break;
89
88
  const max = parseInt(param);
90
89
  if (!validator.isLength(String(value), { max })) {
91
90
  addError(errors, field, `${field} maksimal ${max} karakter`);
@@ -93,6 +92,8 @@ async function checkRules({ field, value, rules, data, errors }) {
93
92
  break;
94
93
  }
95
94
  case "between": {
95
+ if (!value)
96
+ break;
96
97
  const [minVal, maxVal] = param.split(",").map(Number);
97
98
  if (!validator.isLength(String(value), { min: minVal, max: maxVal })) {
98
99
  addError(errors, field, `${field} harus antara ${minVal} - ${maxVal} karakter`);
@@ -101,6 +102,8 @@ async function checkRules({ field, value, rules, data, errors }) {
101
102
  }
102
103
  // === SET MEMBERSHIP ===
103
104
  case "in": {
105
+ if (!value)
106
+ break;
104
107
  const allowed = param.split(",");
105
108
  if (!allowed.includes(String(value))) {
106
109
  addError(errors, field, `${field} harus salah satu dari: ${allowed.join(", ")}`);
@@ -108,17 +111,22 @@ async function checkRules({ field, value, rules, data, errors }) {
108
111
  break;
109
112
  }
110
113
  case "not_in": {
114
+ if (!value)
115
+ break;
111
116
  const notAllowed = param.split(",");
112
117
  if (notAllowed.includes(String(value))) {
113
118
  addError(errors, field, `${field} tidak boleh salah satu dari: ${notAllowed.join(", ")}`);
114
119
  }
115
120
  break;
116
121
  }
117
- case "array":
122
+ case "array": {
123
+ if (!value)
124
+ break;
118
125
  if (!Array.isArray(value)) {
119
126
  addError(errors, field, `${field} harus berupa array`);
120
127
  }
121
128
  break;
129
+ }
122
130
  // === RELATIONAL ===
123
131
  case "confirmed":
124
132
  if (value !== getNestedValue(data, `${field}_confirmation`)) {
@@ -137,6 +145,8 @@ async function checkRules({ field, value, rules, data, errors }) {
137
145
  break;
138
146
  // === REGEX ===
139
147
  case "regex":
148
+ if (!value)
149
+ break;
140
150
  try {
141
151
  const pattern = new RegExp(param);
142
152
  if (!pattern.test(String(value))) {
@@ -149,14 +159,15 @@ async function checkRules({ field, value, rules, data, errors }) {
149
159
  break;
150
160
  // === DATABASE VALIDATION ===
151
161
  case "unique": {
152
- if (!db) {
153
- console.warn(`[Validation Warning] "unique" rule skipped on field "${field}" because database is not configured/installed.`);
162
+ if (!value)
154
163
  break;
155
- }
156
164
  const [table, column, exceptId] = param.split(",");
157
165
  const query = db.table(table).where(column, value);
158
166
  if (exceptId)
159
167
  query.whereNot("id", exceptId);
168
+ if (await db.schema.hasColumn(table, "deleted_at")) {
169
+ query.whereNull("deleted_at");
170
+ }
160
171
  const existing = await query.first();
161
172
  if (existing) {
162
173
  addError(errors, field, `${field} sudah digunakan`);
@@ -164,12 +175,14 @@ async function checkRules({ field, value, rules, data, errors }) {
164
175
  break;
165
176
  }
166
177
  case "exists": {
167
- if (!db) {
168
- console.warn(`[Validation Warning] "exists" rule skipped on field "${field}" because database is not configured/installed.`);
178
+ if (!value)
169
179
  break;
170
- }
171
180
  const [table, column] = param.split(",");
172
- const existing = await db.table(table).where(column, value).first();
181
+ const query = db.table(table).where(column, value);
182
+ if (await db.schema.hasColumn(table, "deleted_at")) {
183
+ query.whereNull("deleted_at");
184
+ }
185
+ const existing = await query.first();
173
186
  if (!existing) {
174
187
  addError(errors, field, `${field} tidak ditemukan di ${table}`);
175
188
  }
@@ -180,13 +193,7 @@ async function checkRules({ field, value, rules, data, errors }) {
180
193
  }
181
194
  async function nestedValidation({ value, segments, rules, fieldPath, data, errors }) {
182
195
  if (segments.length === 0) {
183
- await checkRules({
184
- field: fieldPath,
185
- value,
186
- rules,
187
- data,
188
- errors
189
- });
196
+ await checkRules({ field: fieldPath, value, rules, data, errors });
190
197
  return;
191
198
  }
192
199
  const [segment, ...rest] = segments;
@@ -196,25 +203,11 @@ async function nestedValidation({ value, segments, rules, fieldPath, data, error
196
203
  return;
197
204
  }
198
205
  for (let i = 0; i < value.length; i++) {
199
- await nestedValidation({
200
- value: value[i],
201
- segments: rest,
202
- rules,
203
- fieldPath: `${fieldPath}.${i}`,
204
- data,
205
- errors
206
- });
206
+ await nestedValidation({ value: value[i], segments: rest, rules, fieldPath: `${fieldPath}.${i}`, data, errors });
207
207
  }
208
208
  }
209
209
  else {
210
- await nestedValidation({
211
- value: value?.[segment],
212
- segments: rest,
213
- rules,
214
- fieldPath: fieldPath ? `${fieldPath}.${segment}` : segment,
215
- data,
216
- errors
217
- });
210
+ await nestedValidation({ value: value?.[segment], segments: rest, rules, fieldPath: fieldPath ? `${fieldPath}.${segment}` : segment, data, errors });
218
211
  }
219
212
  }
220
213
  // ==================================>
@@ -228,9 +221,8 @@ function getNestedValue(obj, path) {
228
221
  .replace(/\['([^']+)'\]/g, '.$1')
229
222
  .replace(/\["([^"]+)"\]/g, '.$1');
230
223
  return normalizedPath.split('.').reduce((acc, key) => {
231
- if (acc && Object.prototype.hasOwnProperty.call(acc, key)) {
224
+ if (acc && Object.prototype.hasOwnProperty.call(acc, key))
232
225
  return acc[key];
233
- }
234
226
  return undefined;
235
227
  }, obj);
236
228
  }
@@ -1 +1 @@
1
- {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/validation/validation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/validation/validation.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@skalfa/skalfa-api-core",
3
- "version": "1.0.3",
4
- "description": "Core utility functions for Skalfa API framework.",
3
+ "version": "1.0.8",
4
+ "description": "Core framework engine and foundational utilities for the Skalfa API backend.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "scripts": {
@@ -15,11 +15,11 @@
15
15
  "author": "",
16
16
  "license": "UNLICENSED",
17
17
  "dependencies": {
18
- "@skalfa/skalfa-orm": "file:../skalfa-orm",
18
+ "@skalfa/skalfa-orm": "^1.0.0",
19
19
  "bcrypt": "^6.0.0",
20
20
  "commander": "^12.1.0",
21
21
  "dotenv": "^17.2.2",
22
- "elysia": "latest",
22
+ "elysia": "^1.2.0",
23
23
  "nodemailer": "^7.0.9",
24
24
  "validator": "^13.15.15"
25
25
  },
package/src/auth/auth.ts CHANGED
@@ -1,282 +1,51 @@
1
- import crypto from 'crypto'
2
- import bcrypt from "bcrypt";
3
- import { db } from '@skalfa/skalfa-orm'
4
- import { registry } from '@utils/registry'
5
-
6
- // =====================================>
7
- // ## Auth: User Access Token
8
- // =====================================>
9
- const TOKEN_PLAIN_LENGTH = 20
10
- const AUTH_PERMISSION = process.env.AUTH_CACHE === "true"
11
- const AUTH_CACHE = process.env.AUTH_CACHE === "true"
12
- const AUTH_CACHE_TTL = Number(process.env.AUTH_CACHE_TTL || 600)
1
+ import { createAccessToken } from './create-access-token'
2
+ import { revokeAccessToken } from './revoke-access-token'
3
+ import { verifyAccessToken } from './verify-access-token'
4
+ import { createUserMailToken } from './create-user-mail-token'
5
+ import { verifyUserMailToken } from './verify-user-mail-token'
6
+ import { listUserSessions } from './list-user-sessions'
7
+ import { revalidateUserPermissions } from './revalidate-user-permissions'
8
+ import { revalidateUserPermissionsByRole } from './revalidate-user-permissions-by-role'
9
+
10
+ export const TOKEN_PLAIN_LENGTH = 20
11
+ export const AUTH_PERMISSION = process.env.AUTH_CACHE === "true"
12
+ export const AUTH_CACHE = process.env.AUTH_CACHE === "true"
13
+ export const AUTH_CACHE_TTL = Number(process.env.AUTH_CACHE_TTL || 600)
13
14
 
14
15
  export const auth = {
15
-
16
16
  // =====================================>
17
17
  // ## Auth: create access token with user id
18
18
  // =====================================>
19
- async createAccessToken(userId: number, req: Request, permission: boolean = true) {
20
- const plain = crypto.randomBytes(TOKEN_PLAIN_LENGTH).toString("hex")
21
- const hash = await bcrypt.hash(plain, 10)
22
- const agent = generateAgentId(req)
23
-
24
- if (!db) {
25
- // get user from db (fallback / stub for no ORM)
26
- return {
27
- token: `1|${plain}`,
28
- tokenId: 1,
29
- }
30
- }
31
-
32
- let permissions: string[] = []
33
- if (AUTH_PERMISSION && permission) {
34
- permissions = await getUserPermissions(userId)
35
- }
36
-
37
- const [row] = await db("user_access_tokens").insert({
38
- user_id : userId,
39
- token : hash,
40
- agent : agent,
41
- permissions : JSON.stringify(permissions),
42
- created_at : new Date(),
43
- }).returning(["id"])
44
-
45
- return {
46
- token : `${row.id}|${plain}`,
47
- tokenId : row.id,
48
- }
49
- },
19
+ createAccessToken,
50
20
 
51
21
  // =====================================>
52
22
  // ## Auth: delete access token with user id
53
23
  // =====================================>
54
- async revokeAccessToken(id: number) {
55
- if (!db) {
56
- // delete user access token from db (stub for no ORM)
57
- return;
58
- }
59
- return db.table('user_access_tokens').where("id", id).delete()
60
- },
24
+ revokeAccessToken,
61
25
 
62
26
  // =====================================>
63
27
  // ## Auth: verify access token
64
28
  // =====================================>
65
- async verifyAccessToken(token: string, req?: Request) {
66
- if (!token.includes("|")) return null
67
-
68
- const [tokenId, plain] = token.split("|", 2)
69
- const agent = req ? generateAgentId(req) : ""
70
- const ip = req ? getRequestIp(req) : ""
71
-
72
- const cacheKey = `auth:token:${tokenId}`
73
-
74
- if (AUTH_CACHE) {
75
- const redis = registry.get('redis')
76
- if (redis) {
77
- const cached = await redis.get(cacheKey)
78
- if (cached) {
79
- const session = JSON.parse(cached)
80
- if (session.agent !== agent) return null
81
- return session
82
- }
83
- }
84
- }
85
-
86
- if (!db) {
87
- // get user and token from db (stub for no ORM)
88
- const user = { id: 1, name: "Admin", email: "admin@example.com" }
89
- const tokenRecord = { id: Number(tokenId), agent, permission: [] }
90
- return { user, token: tokenRecord, permissions: [] }
91
- }
92
-
93
- const tokenRecord = await db("user_access_tokens").where("id", tokenId).first()
94
-
95
- if (!tokenRecord) return null
96
- if (tokenRecord.agent !== agent) return null
97
-
98
- const valid = await bcrypt.compare(plain, tokenRecord.token)
99
- if (!valid) return null
100
-
101
- await db("user_access_tokens").where("id", tokenRecord.id).update({ last_used_at: new Date(), last_used_ip: ip })
102
-
103
- const user = await db("users").where("id", tokenRecord.user_id).first()
104
-
105
- if (AUTH_CACHE) {
106
- const redis = registry.get('redis')
107
- if (redis) {
108
- await redis.setex(
109
- cacheKey,
110
- AUTH_CACHE_TTL,
111
- JSON.stringify({
112
- user : user,
113
- agent : tokenRecord.agent,
114
- permissions : tokenRecord.permission,
115
- })
116
- )
117
- }
118
- }
119
-
120
- return { user, token: tokenRecord, permissions: tokenRecord.permission }
121
- },
29
+ verifyAccessToken,
122
30
 
123
31
  // =====================================>
124
32
  // ## Auth: create user mail token
125
33
  // =====================================>
126
- async createUserMailToken(userId: number) {
127
- const token = Math.floor(100000 + Math.random() * 900000).toString()
128
-
129
- if (!db) {
130
- // create user mail token in db (stub for no ORM)
131
- return {
132
- token: token,
133
- tokenId: 1
134
- }
135
- }
136
-
137
- const hash = crypto.createHash('sha256').update(token).digest('hex')
138
- const trx = await db.transaction()
139
-
140
- await trx.table('user_mail_tokens').insert({
141
- user_id : userId,
142
- token : hash,
143
- created_at : new Date(),
144
- })
145
-
146
- const record = await trx.table('user_mail_tokens').orderBy('id', 'desc').first()
147
-
148
- await trx.commit()
149
-
150
- return {
151
- token : token,
152
- tokenId : record.id
153
- }
154
- },
34
+ createUserMailToken,
155
35
 
156
36
  // =====================================>
157
37
  // ## Auth: Verify user mail token
158
38
  // =====================================>
159
- async verifyUserMailToken(userId: number, token: string) {
160
- if (!db) {
161
- // verify user mail token in db (stub for no ORM)
162
- return true
163
- }
164
-
165
- const hashedToken = crypto.createHash("sha256").update(token).digest("hex");
166
-
167
- const record = await db.table("user_mail_tokens")
168
- .where("user_id", userId)
169
- .whereNull("used_at")
170
- .orderBy("id", "desc")
171
- .first();
172
-
173
- if (!record) return false
174
-
175
- if (record.token !== hashedToken) return false;
176
-
177
- const createdAt = new Date(record.created_at);
178
- const now = new Date();
179
- const diffMinutes = (now.getTime() - createdAt.getTime()) / (1000 * 60);
180
-
181
- if (diffMinutes > 10) return false;
182
-
183
- return true;
184
- },
39
+ verifyUserMailToken,
185
40
 
186
41
  // =====================================>
187
42
  // ## Auth: list user sessions
188
43
  // =====================================>
189
- async listUserSessions(userId: number, currentTokenId?: number) {
190
- if (!db) {
191
- // list user sessions from db (stub for no ORM)
192
- return []
193
- }
194
-
195
- const rows = await db("user_access_tokens").select(["id", "agent", "created_at", "last_used_at", "last_used_ip","expired_at"]).where("user_id", userId).orderBy("last_used_at", "desc")
196
-
197
- return rows.map((r: any) => ({
198
- ...r,
199
- is_active : r.revoked_at === null,
200
- is_current : r.id === currentTokenId,
201
- }))
202
- },
44
+ listUserSessions,
203
45
 
204
46
  // =====================================>
205
47
  // ## Auth: revalidate user permission
206
48
  // =====================================>
207
- revalidateUserPermissions: revalidateUserPermissions,
208
- revalidateUserPermissionsByRole: revalidateUserPermissionsByRole,
209
- }
210
-
211
- function generateAgentId(req: Request) {
212
- const ua = req.headers.get("user-agent") ?? ""
213
- const acc = req.headers.get("accept") ?? ""
214
-
215
- return crypto.createHash("sha256").update(ua + acc).digest("hex")
216
- }
217
-
218
- function getRequestIp(req: Request) {
219
- return (req.headers.get("x-forwarded-for")?.split(",")[0]?.trim() || req.headers.get("x-real-ip") || "unknown")
220
- }
221
-
222
- async function getUserPermissions(userId: number): Promise<string[]> {
223
- if (!db) {
224
- // get user permissions from db (stub for no ORM)
225
- return []
226
- }
227
-
228
- const roleIds = await db("user_roles").where("user_id", userId).pluck("role_id")
229
-
230
- if (roleIds.length === 0) return []
231
-
232
- const rows = await db("permissions").whereIn("role_id", roleIds).pluck("permissions")
233
-
234
- return Array.from(
235
- new Set(
236
- rows.flatMap((p: any) => p ?? [])
237
- )
238
- )
239
- }
240
-
241
- async function revalidateUserPermissions(userId: number) {
242
- if (!db) {
243
- // revalidate user permissions in db (stub for no ORM)
244
- return
245
- }
246
-
247
- const permissions = await getUserPermissions(userId)
248
-
249
- const tokenIds = await db("user_access_tokens").where("user_id", userId).pluck("id")
250
-
251
- if (tokenIds.length === 0) return
252
-
253
- await db("user_access_tokens").whereIn("id", tokenIds).update({
254
- permissions : JSON.stringify(permissions),
255
- updated_at : new Date(),
256
- })
257
-
258
- if (AUTH_CACHE) {
259
- const redis = registry.get('redis')
260
- if (redis) {
261
- await Promise.all(
262
- tokenIds.map((id: any) => redis.del(`auth:token:${id}`))
263
- )
264
- }
265
- }
266
- }
267
-
268
- async function revalidateUserPermissionsByRole(roleId: number) {
269
- if (!db) {
270
- // revalidate user permissions by role in db (stub for no ORM)
271
- return
272
- }
273
-
274
- const userIds = await db("user_roles").where("role_id", roleId).pluck("user_id")
275
-
276
- const queue = registry.get('queue')
277
- if (queue) {
278
- for (const userId of userIds) {
279
- await queue.add("auth:revalidate-permission", { userId })
280
- }
281
- }
49
+ revalidateUserPermissions,
50
+ revalidateUserPermissionsByRole,
282
51
  }
@@ -0,0 +1,29 @@
1
+ import crypto from 'crypto'
2
+ import bcrypt from "bcrypt";
3
+ import { db } from '@skalfa/skalfa-orm'
4
+ import { TOKEN_PLAIN_LENGTH, AUTH_PERMISSION } from './auth'
5
+ import { getUserPermissions, generateAgentId } from './helpers'
6
+
7
+ export async function createAccessToken(userId: number, req: Request, permission: boolean = true) {
8
+ const plain = crypto.randomBytes(TOKEN_PLAIN_LENGTH).toString("hex")
9
+ const hash = await bcrypt.hash(plain, 10)
10
+ const agent = generateAgentId(req)
11
+
12
+ let permissions: string[] = []
13
+ if (AUTH_PERMISSION && permission) {
14
+ permissions = await getUserPermissions(userId)
15
+ }
16
+
17
+ const [row] = await db("user_access_tokens").insert({
18
+ user_id : userId,
19
+ token : hash,
20
+ agent : agent,
21
+ permissions : JSON.stringify(permissions),
22
+ created_at : new Date(),
23
+ }).returning(["id"])
24
+
25
+ return {
26
+ token : `${row.id}|${plain}`,
27
+ tokenId : row.id,
28
+ }
29
+ }
@@ -0,0 +1,24 @@
1
+ import crypto from 'crypto'
2
+ import { db } from '@skalfa/skalfa-orm'
3
+
4
+ export async function createUserMailToken(userId: number) {
5
+ const token = Math.floor(100000 + Math.random() * 900000).toString()
6
+
7
+ const hash = crypto.createHash('sha256').update(token).digest('hex')
8
+ const trx = await db.transaction()
9
+
10
+ await trx.table('user_mail_tokens').insert({
11
+ user_id : userId,
12
+ token : hash,
13
+ created_at : new Date(),
14
+ })
15
+
16
+ const record = await trx.table('user_mail_tokens').orderBy('id', 'desc').first()
17
+
18
+ await trx.commit()
19
+
20
+ return {
21
+ token : token,
22
+ tokenId : record.id
23
+ }
24
+ }
@@ -0,0 +1,8 @@
1
+ import crypto from 'crypto'
2
+
3
+ export function generateAgentId(req: Request) {
4
+ const ua = req.headers.get("user-agent") ?? ""
5
+ const acc = req.headers.get("accept") ?? ""
6
+
7
+ return crypto.createHash("sha256").update(ua + acc).digest("hex")
8
+ }
@@ -0,0 +1,3 @@
1
+ export function getRequestIp(req: Request) {
2
+ return (req.headers.get("x-forwarded-for")?.split(",")[0]?.trim() || req.headers.get("x-real-ip") || "unknown")
3
+ }