@vitnode/core 1.2.0-canary.59 → 1.2.0-canary.61

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 (283) hide show
  1. package/dist/scripts/get-config.js +15 -0
  2. package/dist/scripts/plugin.js +188 -0
  3. package/dist/scripts/prepare-database.js +177 -0
  4. package/dist/scripts/prepare-plugins-files.js +134 -0
  5. package/dist/scripts/run-interactive-shell-command.js +21 -0
  6. package/dist/scripts/scripts.js +39 -13
  7. package/dist/scripts/shared/file-utils.js +203 -0
  8. package/dist/src/api/adapters/sso/discord.js +1 -77
  9. package/dist/src/api/adapters/sso/facebook.js +1 -76
  10. package/dist/src/api/adapters/sso/google.js +1 -87
  11. package/dist/src/api/config.js +1 -67
  12. package/dist/src/api/lib/check-plugin-id.js +1 -43
  13. package/dist/src/api/lib/cron.js +1 -22
  14. package/dist/src/api/lib/logger-middleware.js +1 -35
  15. package/dist/src/api/lib/module.js +1 -22
  16. package/dist/src/api/lib/plugin.js +1 -22
  17. package/dist/src/api/lib/route.js +1 -27
  18. package/dist/src/api/lib/with-pagination.js +1 -83
  19. package/dist/src/api/middlewares/captcha.middleware.js +1 -63
  20. package/dist/src/api/middlewares/cron-auth.middleware.js +1 -19
  21. package/dist/src/api/middlewares/global.middleware.d.ts.map +1 -1
  22. package/dist/src/api/middlewares/global.middleware.js +1 -104
  23. package/dist/src/api/middlewares/rate-limiter.middleware.js +1 -32
  24. package/dist/src/api/models/device.js +1 -61
  25. package/dist/src/api/models/email.d.ts.map +1 -1
  26. package/dist/src/api/models/email.js +1 -77
  27. package/dist/src/api/models/password.js +1 -36
  28. package/dist/src/api/models/session-admin.d.ts.map +1 -1
  29. package/dist/src/api/models/session-admin.js +1 -97
  30. package/dist/src/api/models/session.d.ts.map +1 -1
  31. package/dist/src/api/models/session.js +1 -76
  32. package/dist/src/api/models/sso.js +1 -120
  33. package/dist/src/api/models/user/get-user-by-id.js +1 -19
  34. package/dist/src/api/models/user/sign-in-with-passwords.js +1 -22
  35. package/dist/src/api/models/user/sign-up.js +1 -73
  36. package/dist/src/api/models/user.js +1 -8
  37. package/dist/src/api/modules/admin/admin.module.js +1 -19
  38. package/dist/src/api/modules/admin/advanced/advanced.admin.module.js +1 -11
  39. package/dist/src/api/modules/admin/advanced/cron/cron.admin.module.js +1 -12
  40. package/dist/src/api/modules/admin/advanced/cron/routes/get.route.js +1 -66
  41. package/dist/src/api/modules/admin/advanced/cron/routes/run.route.js +1 -95
  42. package/dist/src/api/modules/admin/debug/debug.admin.module.js +1 -10
  43. package/dist/src/api/modules/admin/debug/routes/logs.route.js +1 -94
  44. package/dist/src/api/modules/admin/routes/session.route.js +1 -47
  45. package/dist/src/api/modules/admin/users/routes/list.route.js +1 -79
  46. package/dist/src/api/modules/admin/users/routes/users.route.js +1 -84
  47. package/dist/src/api/modules/admin/users/users.admin.module.js +1 -10
  48. package/dist/src/api/modules/cron/cron/clean.cron.js +1 -24
  49. package/dist/src/api/modules/cron/cron.module.js +1 -14
  50. package/dist/src/api/modules/cron/helpers/process-cron-jobs.d.ts.map +1 -1
  51. package/dist/src/api/modules/cron/helpers/process-cron-jobs.js +1 -72
  52. package/dist/src/api/modules/cron/routes/cron.route.d.ts.map +1 -1
  53. package/dist/src/api/modules/cron/routes/cron.route.js +1 -95
  54. package/dist/src/api/modules/middleware/middleware.module.js +1 -10
  55. package/dist/src/api/modules/middleware/route.js +1 -49
  56. package/dist/src/api/modules/users/avatar-color.js +1 -43
  57. package/dist/src/api/modules/users/routes/change-password.route.js +1 -58
  58. package/dist/src/api/modules/users/routes/reset-passowrd.route.js +1 -91
  59. package/dist/src/api/modules/users/routes/session.route.js +1 -46
  60. package/dist/src/api/modules/users/routes/sign-in.route.js +1 -71
  61. package/dist/src/api/modules/users/routes/sign-out.route.js +1 -43
  62. package/dist/src/api/modules/users/routes/sign-up.route.js +1 -77
  63. package/dist/src/api/modules/users/routes/test.route.js +1 -33
  64. package/dist/src/api/modules/users/sso/routes/callback.route.js +1 -52
  65. package/dist/src/api/modules/users/sso/routes/create-url.route.js +1 -36
  66. package/dist/src/api/modules/users/sso/sso.module.js +1 -12
  67. package/dist/src/api/modules/users/users.module.js +1 -26
  68. package/dist/src/api/plugin.js +1 -15
  69. package/dist/src/app/login/page.js +1 -16
  70. package/dist/src/app/login/reset-password/page.js +1 -18
  71. package/dist/src/app/login/sso/[providerId]/page.js +1 -10
  72. package/dist/src/app/register/page.js +1 -16
  73. package/dist/src/app_admin/core/advanced/cron/page.js +1 -42
  74. package/dist/src/app_admin/core/debug/page.js +1 -45
  75. package/dist/src/app_admin/core/page.js +1 -5
  76. package/dist/src/app_admin/core/test/page.js +1 -5
  77. package/dist/src/app_admin/core/users/page.js +1 -38
  78. package/dist/src/components/avatar.js +1 -14
  79. package/dist/src/components/confirm-action/confirm-action-alert-dialog.js +1 -42
  80. package/dist/src/components/confirm-action/content.js +1 -31
  81. package/dist/src/components/date-format.js +1 -41
  82. package/dist/src/components/form/auto-form.js +1 -103
  83. package/dist/src/components/form/common/desc.js +1 -9
  84. package/dist/src/components/form/common/label.js +1 -18
  85. package/dist/src/components/form/fields/checkbox.js +1 -37
  86. package/dist/src/components/form/fields/combobox-async.js +1 -123
  87. package/dist/src/components/form/fields/combobox.js +1 -87
  88. package/dist/src/components/form/fields/input.js +1 -39
  89. package/dist/src/components/form/fields/radio-group.js +1 -50
  90. package/dist/src/components/form/fields/select.js +1 -58
  91. package/dist/src/components/form/fields/switch.js +1 -36
  92. package/dist/src/components/form/fields/textarea.js +1 -36
  93. package/dist/src/components/i18n-provider.js +1 -43
  94. package/dist/src/components/logo-vitnode.js +1 -119
  95. package/dist/src/components/switchers/langs/language-switcher.js +1 -47
  96. package/dist/src/components/switchers/themes/theme-switcher.js +1 -28
  97. package/dist/src/components/table/content.js +1 -81
  98. package/dist/src/components/table/data-table.js +1 -68
  99. package/dist/src/components/table/order-table-head.js +1 -50
  100. package/dist/src/components/table/pagination.js +1 -122
  101. package/dist/src/components/tiptap/extension.js +1 -33
  102. package/dist/src/components/tiptap/toolbar/actions/alignment-action.js +1 -91
  103. package/dist/src/components/tiptap/toolbar/actions/bold-action.js +1 -39
  104. package/dist/src/components/tiptap/toolbar/actions/headings-action.js +1 -93
  105. package/dist/src/components/tiptap/toolbar/actions/italic-action.js +1 -38
  106. package/dist/src/components/tiptap/toolbar/actions/list-action.js +1 -61
  107. package/dist/src/components/tiptap/toolbar/actions/text-format-more/text-format-more.js +1 -59
  108. package/dist/src/components/tiptap/toolbar/actions/underline-action.js +1 -38
  109. package/dist/src/components/tiptap/toolbar/actions/undo-redo-actions.js +1 -63
  110. package/dist/src/components/tiptap/toolbar/actions/utils/tooltip-shortcut.js +1 -11
  111. package/dist/src/components/tiptap/toolbar/tiptap-toolbar.js +1 -55
  112. package/dist/src/components/tiptap/toolbar/use-toolbar-editor.js +1 -5
  113. package/dist/src/components/ui/accordion.js +1 -46
  114. package/dist/src/components/ui/alert-dialog.js +1 -123
  115. package/dist/src/components/ui/alert.js +1 -39
  116. package/dist/src/components/ui/badge.js +1 -28
  117. package/dist/src/components/ui/button-client.js +1 -57
  118. package/dist/src/components/ui/button.js +1 -32
  119. package/dist/src/components/ui/card.js +1 -52
  120. package/dist/src/components/ui/checkbox.js +1 -20
  121. package/dist/src/components/ui/collapsible.js +1 -22
  122. package/dist/src/components/ui/command.js +1 -98
  123. package/dist/src/components/ui/context-menu.js +1 -140
  124. package/dist/src/components/ui/dialog.js +1 -189
  125. package/dist/src/components/ui/drawer.js +1 -83
  126. package/dist/src/components/ui/dropdown-menu.js +1 -141
  127. package/dist/src/components/ui/editor-content.js +1 -10
  128. package/dist/src/components/ui/editor.js +1 -35
  129. package/dist/src/components/ui/form.js +1 -148
  130. package/dist/src/components/ui/header-content.js +1 -30
  131. package/dist/src/components/ui/hover-card.js +1 -29
  132. package/dist/src/components/ui/input-otp.js +1 -48
  133. package/dist/src/components/ui/input.js +1 -11
  134. package/dist/src/components/ui/label.js +1 -12
  135. package/dist/src/components/ui/loader.js +1 -16
  136. package/dist/src/components/ui/menubar.js +1 -151
  137. package/dist/src/components/ui/navigation-menu.js +1 -82
  138. package/dist/src/components/ui/popover.js +1 -35
  139. package/dist/src/components/ui/progress.js +1 -19
  140. package/dist/src/components/ui/radio-group.js +1 -27
  141. package/dist/src/components/ui/scroll-area.js +1 -33
  142. package/dist/src/components/ui/select.js +1 -113
  143. package/dist/src/components/ui/separator.js +1 -14
  144. package/dist/src/components/ui/sheet.js +1 -92
  145. package/dist/src/components/ui/sidebar.js +1 -433
  146. package/dist/src/components/ui/skeleton.js +1 -10
  147. package/dist/src/components/ui/slider.js +1 -50
  148. package/dist/src/components/ui/sonner.js +1 -26
  149. package/dist/src/components/ui/switch.js +1 -16
  150. package/dist/src/components/ui/table.js +1 -63
  151. package/dist/src/components/ui/tabs.js +1 -33
  152. package/dist/src/components/ui/textarea.js +1 -10
  153. package/dist/src/components/ui/toggle-group.js +1 -45
  154. package/dist/src/components/ui/toggle.js +1 -34
  155. package/dist/src/components/ui/tooltip.js +1 -57
  156. package/dist/src/config.js +1 -4
  157. package/dist/src/database/admins.js +1 -74
  158. package/dist/src/database/cron.js +1 -22
  159. package/dist/src/database/languages.js +1 -52
  160. package/dist/src/database/logs.js +1 -34
  161. package/dist/src/database/moderators.js +1 -37
  162. package/dist/src/database/roles.js +1 -13
  163. package/dist/src/database/sessions.js +1 -60
  164. package/dist/src/database/users.js +1 -145
  165. package/dist/src/drizzle.config.js +1 -67
  166. package/dist/src/emails/default-template.js +1 -99
  167. package/dist/src/emails/reset-password.js +1 -132
  168. package/dist/src/emails/ui/button.js +1 -36
  169. package/dist/src/emails/ui/card.js +1 -39
  170. package/dist/src/hooks/use-before-unload.js +1 -30
  171. package/dist/src/hooks/use-captcha.js +1 -122
  172. package/dist/src/hooks/use-mobile.js +1 -16
  173. package/dist/src/lib/api/get-middleware-api.js +1 -13
  174. package/dist/src/lib/api/get-next-cron-run-date.js +1 -14
  175. package/dist/src/lib/api/get-next-cron-run-date.test.js +1 -55
  176. package/dist/src/lib/api/get-session-admin-api.js +1 -19
  177. package/dist/src/lib/api/get-session-api.js +1 -14
  178. package/dist/src/lib/api/should-cron-job-run.js +1 -16
  179. package/dist/src/lib/api/should-cron-job-run.test.js +1 -213
  180. package/dist/src/lib/api/validate-cron-schedule.d.ts +2 -0
  181. package/dist/src/lib/api/validate-cron-schedule.d.ts.map +1 -0
  182. package/dist/src/lib/api/validate-cron-schedule.js +1 -0
  183. package/dist/src/lib/api/validate-cron-schedule.test.d.ts +2 -0
  184. package/dist/src/lib/api/validate-cron-schedule.test.d.ts.map +1 -0
  185. package/dist/src/lib/api/validate-cron-schedule.test.js +1 -0
  186. package/dist/src/lib/colors.js +1 -140
  187. package/dist/src/lib/colors.test.js +1 -173
  188. package/dist/src/lib/config.js +1 -14
  189. package/dist/src/lib/ctrl-or-command-character.js +1 -5
  190. package/dist/src/lib/fetcher/cookie-from-string-to-object.js +1 -12
  191. package/dist/src/lib/fetcher/cookie-from-string-to-object.test.js +1 -78
  192. package/dist/src/lib/fetcher/core.js +3 -48
  193. package/dist/src/lib/fetcher/helpers-server.js +1 -18
  194. package/dist/src/lib/fetcher/helpers.js +1 -16
  195. package/dist/src/lib/fetcher/helpers.test.js +1 -37
  196. package/dist/src/lib/fetcher/types.js +1 -1
  197. package/dist/src/lib/fetcher-client.js +1 -17
  198. package/dist/src/lib/fetcher.js +1 -33
  199. package/dist/src/lib/helpers/auto-form.js +1 -98
  200. package/dist/src/lib/helpers/auto-form.test.js +1 -336
  201. package/dist/src/lib/navigation.d.ts +15 -13
  202. package/dist/src/lib/navigation.d.ts.map +1 -1
  203. package/dist/src/lib/navigation.js +1 -11
  204. package/dist/src/lib/plugin.js +1 -3
  205. package/dist/src/lib/special-characters.js +1 -4
  206. package/dist/src/lib/special-characters.test.js +1 -56
  207. package/dist/src/lib/utils.js +1 -5
  208. package/dist/src/locales/en.json +308 -0
  209. package/dist/src/tests/setup.js +1 -6
  210. package/dist/src/views/admin/layouts/admin-layout.js +1 -73
  211. package/dist/src/views/admin/layouts/sidebar/nav/item.js +1 -98
  212. package/dist/src/views/admin/layouts/sidebar/nav/nav.js +1 -60
  213. package/dist/src/views/admin/layouts/sidebar/sidebar.js +1 -28
  214. package/dist/src/views/admin/layouts/sidebar/sign-out.js +1 -14
  215. package/dist/src/views/admin/layouts/user-bar/client.js +1 -69
  216. package/dist/src/views/admin/layouts/user-bar/user-bar.js +1 -32
  217. package/dist/src/views/admin/sign-in/sign-in-admin-view.js +1 -27
  218. package/dist/src/views/admin/views/core/advanced/cron/cron-table-view.js +1 -97
  219. package/dist/src/views/admin/views/core/advanced/cron/run-action/mutation-api.js +1 -23
  220. package/dist/src/views/admin/views/core/advanced/cron/run-action/run-action.js +1 -38
  221. package/dist/src/views/admin/views/core/dashboard/dashboard-admin-view.js +1 -44
  222. package/dist/src/views/admin/views/core/debug/actions/clear-cache/clear-cache.js +1 -35
  223. package/dist/src/views/admin/views/core/debug/actions/clear-cache/mutation-api.js +1 -5
  224. package/dist/src/views/admin/views/core/debug/system-logs/actions/more/content.js +1 -281
  225. package/dist/src/views/admin/views/core/debug/system-logs/actions/more/more.js +1 -67
  226. package/dist/src/views/admin/views/core/debug/system-logs/badges/badge-status.js +1 -14
  227. package/dist/src/views/admin/views/core/debug/system-logs/badges/badge-type-log.js +1 -30
  228. package/dist/src/views/admin/views/core/debug/system-logs/system-logs-view.js +1 -96
  229. package/dist/src/views/admin/views/core/test.js +1 -161
  230. package/dist/src/views/admin/views/core/users/users-admin-view.js +1 -89
  231. package/dist/src/views/auth/password-reset/change-password-form/form.js +1 -48
  232. package/dist/src/views/auth/password-reset/change-password-form/mutation-api.js +1 -22
  233. package/dist/src/views/auth/password-reset/change-password-form/use-form.js +1 -36
  234. package/dist/src/views/auth/password-reset/form/form.js +1 -104
  235. package/dist/src/views/auth/password-reset/form/mutation-api.js +1 -21
  236. package/dist/src/views/auth/password-reset/form/use-form.js +1 -33
  237. package/dist/src/views/auth/password-reset/password-reset-view.js +1 -37
  238. package/dist/src/views/auth/sign-in/form/form.js +1 -64
  239. package/dist/src/views/auth/sign-in/form/mutation-api.js +1 -33
  240. package/dist/src/views/auth/sign-in/form/use-form.d.ts.map +1 -1
  241. package/dist/src/views/auth/sign-in/form/use-form.js +1 -38
  242. package/dist/src/views/auth/sign-in/sign-in-view.js +1 -61
  243. package/dist/src/views/auth/sign-up/components/password-input.js +1 -96
  244. package/dist/src/views/auth/sign-up/email-confirmation-view.js +1 -55
  245. package/dist/src/views/auth/sign-up/form/form.js +1 -89
  246. package/dist/src/views/auth/sign-up/form/mutation-api.js +1 -30
  247. package/dist/src/views/auth/sign-up/form/use-form.js +1 -70
  248. package/dist/src/views/auth/sign-up/sign-up-view.js +1 -65
  249. package/dist/src/views/auth/sign-up/wrapper.js +1 -22
  250. package/dist/src/views/auth/sso/buttons/client.js +1 -22
  251. package/dist/src/views/auth/sso/buttons/mutation-api.js +1 -24
  252. package/dist/src/views/auth/sso/buttons/sso-buttons.js +1 -56
  253. package/dist/src/views/auth/sso/callback/callback-sso-view.js +1 -32
  254. package/dist/src/views/auth/sso/callback/client/client.js +1 -68
  255. package/dist/src/views/auth/sso/callback/client/mutation-api.js +1 -32
  256. package/dist/src/views/error/back-button.js +1 -14
  257. package/dist/src/views/error/error-view.js +1 -58
  258. package/dist/src/views/error/global-error-view.js +1 -50
  259. package/dist/src/views/layouts/provider.js +1 -44
  260. package/dist/src/views/layouts/root-layout.js +1 -25
  261. package/dist/src/views/layouts/theme/header/header.js +1 -38
  262. package/dist/src/views/layouts/theme/header/user/auth/auth.js +1 -33
  263. package/dist/src/views/layouts/theme/header/user/auth/client.js +1 -47
  264. package/dist/src/views/layouts/theme/header/user/auth/log-out-mutation-api.js +1 -27
  265. package/dist/src/views/layouts/theme/header/user/user.js +1 -32
  266. package/dist/src/views/layouts/theme/layout.js +1 -16
  267. package/dist/src/vitnode.config.d.ts.map +1 -1
  268. package/dist/src/vitnode.config.js +1 -42
  269. package/dist/tsconfig.tsbuildinfo +1 -1
  270. package/dist/tsup.config.js +18 -0
  271. package/dist/vitest.config.d.ts.map +1 -1
  272. package/dist/vitest.config.js +49 -0
  273. package/eslint.config.mjs +2 -0
  274. package/package.json +40 -44
  275. package/dist/src/api/adapters/cron/node-cron.adapter.d.ts +0 -3
  276. package/dist/src/api/adapters/cron/node-cron.adapter.d.ts.map +0 -1
  277. package/dist/src/api/adapters/cron/node-cron.adapter.js +0 -11
  278. package/dist/src/api/adapters/email/nodemailer.d.ts +0 -10
  279. package/dist/src/api/adapters/email/nodemailer.d.ts.map +0 -1
  280. package/dist/src/api/adapters/email/nodemailer.js +0 -30
  281. package/dist/src/api/adapters/email/resend.d.ts +0 -6
  282. package/dist/src/api/adapters/email/resend.d.ts.map +0 -1
  283. package/dist/src/api/adapters/email/resend.js +0 -21
@@ -1,67 +1 @@
1
- import { swaggerUI } from "@hono/swagger-ui";
2
- import { cors } from "hono/cors";
3
- import { csrf } from "hono/csrf";
4
- import { HTTPException } from "hono/http-exception";
5
- import { newBuildPluginApiCore } from "./plugin.js";
6
- import { CONFIG_PLUGIN } from "../config.js";
7
- import { globalAdminMiddleware, globalMiddleware } from "./middlewares/global.middleware.js";
8
- import { rateLimiterMiddleware } from "./middlewares/rate-limiter.middleware.js";
9
- export function VitNodeAPI({ app, cors: corsOptions, csrf: csrfOptions, vitNodeApiConfig }) {
10
- app.doc("/swagger/doc", {
11
- openapi: "3.0.0",
12
- info: {
13
- version: CONFIG_PLUGIN.version,
14
- title: "VitNode API"
15
- }
16
- });
17
- app.use(cors(corsOptions));
18
- app.use(csrf(csrfOptions));
19
- app.use("*", rateLimiterMiddleware(vitNodeApiConfig.rateLimiter));
20
- app.get("/swagger", swaggerUI({
21
- url: "/api/swagger/doc"
22
- }));
23
- app.use("*", globalMiddleware({
24
- pathToMessages: vitNodeApiConfig.pathToMessages,
25
- email: vitNodeApiConfig.email,
26
- metadata: vitNodeApiConfig.metadata,
27
- authorization: vitNodeApiConfig.authorization,
28
- dbProvider: vitNodeApiConfig.dbProvider,
29
- captcha: vitNodeApiConfig.captcha,
30
- plugins: [
31
- newBuildPluginApiCore,
32
- ...vitNodeApiConfig.plugins
33
- ]
34
- }));
35
- app.use(async (c, next)=>{
36
- if (c.req.path.includes("/admin/")) {
37
- return await globalAdminMiddleware()(c, next);
38
- }
39
- return next();
40
- });
41
- if (vitNodeApiConfig.cronAdapter) {
42
- vitNodeApiConfig.cronAdapter.schedule();
43
- }
44
- [
45
- newBuildPluginApiCore,
46
- ...vitNodeApiConfig.plugins
47
- ].map((root)=>{
48
- app.route(`/${root.pluginId}`, root.hono);
49
- });
50
- app.onError(async (error, c)=>{
51
- if (error instanceof HTTPException) {
52
- return error.getResponse();
53
- }
54
- const errorMessage = error?.message ?? "Unknown error";
55
- try {
56
- const logger = c.get("log");
57
- if (logger) {
58
- await logger.error(`Unhandled error: ${errorMessage}`);
59
- }
60
- } catch {
61
- /* empty */ }
62
- return new Response(process.env.NODE_ENV === "development" ? errorMessage : "Internal Server Error", {
63
- status: 500
64
- });
65
- });
66
- return app;
67
- }
1
+ import{swaggerUI}from"@hono/swagger-ui";import{cors}from"hono/cors";import{csrf}from"hono/csrf";import{HTTPException}from"hono/http-exception";import{newBuildPluginApiCore}from"./plugin.js";import{CONFIG_PLUGIN}from"../config.js";import{globalAdminMiddleware,globalMiddleware}from"./middlewares/global.middleware.js";import{rateLimiterMiddleware}from"./middlewares/rate-limiter.middleware.js";export function VitNodeAPI({app,cors:corsOptions,csrf:csrfOptions,vitNodeApiConfig}){app.doc("/swagger/doc",{openapi:"3.0.0",info:{version:CONFIG_PLUGIN.version,title:"VitNode API"}});app.use(cors(corsOptions));app.use(csrf(csrfOptions));app.use("*",rateLimiterMiddleware(vitNodeApiConfig.rateLimiter));app.get("/swagger",swaggerUI({url:"/api/swagger/doc"}));app.use("*",globalMiddleware({pathToMessages:vitNodeApiConfig.pathToMessages,email:vitNodeApiConfig.email,metadata:vitNodeApiConfig.metadata,authorization:vitNodeApiConfig.authorization,dbProvider:vitNodeApiConfig.dbProvider,captcha:vitNodeApiConfig.captcha,plugins:[newBuildPluginApiCore,...vitNodeApiConfig.plugins]}));app.use(async(c,next)=>{if(c.req.path.includes("/admin/")){return await globalAdminMiddleware()(c,next)}return next()});if(vitNodeApiConfig.cronAdapter){vitNodeApiConfig.cronAdapter.schedule()}[newBuildPluginApiCore,...vitNodeApiConfig.plugins].map(root=>{app.route(`/${root.pluginId}`,root.hono)});app.onError(async(error,c)=>{if(error instanceof HTTPException){return error.getResponse()}const errorMessage=error?.message??"Unknown error";try{const logger=c.get("log");if(logger){await logger.error(`Unhandled error: ${errorMessage}`)}}catch{}return new Response(process.env.NODE_ENV==="development"?errorMessage:"Internal Server Error",{status:500})});return app}
@@ -1,43 +1 @@
1
- import { existsSync, readFileSync } from "node:fs";
2
- import { join, resolve } from "node:path";
3
- import { CONFIG } from "../../lib/config.js";
4
- export const checkPluginId = (pluginName)=>{
5
- if (!CONFIG.node_development) return null;
6
- const findMonorepoRoot = (startPath)=>{
7
- let currentPath = startPath;
8
- while(currentPath !== resolve(currentPath, "..")){
9
- const turboConfigPath = join(currentPath, "turbo.json");
10
- if (existsSync(turboConfigPath)) {
11
- return currentPath;
12
- }
13
- currentPath = resolve(currentPath, "..");
14
- }
15
- return null;
16
- };
17
- const findPluginPath = (pluginName)=>{
18
- const cwd = process.cwd();
19
- const monorepoRoot = findMonorepoRoot(cwd);
20
- // Check in current working directory first
21
- const cwdPluginPath = join(cwd, "node_modules", pluginName, "package.json");
22
- if (existsSync(cwdPluginPath)) {
23
- return cwdPluginPath;
24
- }
25
- // Check in monorepo root if it exists and is different from cwd
26
- if (monorepoRoot && monorepoRoot !== cwd) {
27
- const rootPluginPath = join(monorepoRoot, "node_modules", pluginName, "package.json");
28
- if (existsSync(rootPluginPath)) {
29
- return rootPluginPath;
30
- }
31
- }
32
- return null;
33
- };
34
- const path = findPluginPath(pluginName);
35
- if (!path) {
36
- throw new Error(`package.json file not found for plugin "${pluginName}". Please ensure you are using the correct plugin name as specified in its package.json.`);
37
- }
38
- const content = JSON.parse(readFileSync(path, "utf-8"));
39
- if (content.name !== pluginName) {
40
- throw new Error(`The plugin name in package.json (${content.name}) does not match the requested plugin name (${pluginName}). Please check the plugin name.`);
41
- }
42
- return content;
43
- };
1
+ import{existsSync,readFileSync}from"node:fs";import{join,resolve}from"node:path";import{CONFIG}from"../../lib/config.js";export const checkPluginId=pluginName=>{if(!CONFIG.node_development)return null;const findMonorepoRoot=startPath=>{let currentPath=startPath;while(currentPath!==resolve(currentPath,"..")){const turboConfigPath=join(currentPath,"turbo.json");if(existsSync(turboConfigPath)){return currentPath}currentPath=resolve(currentPath,"..")}return null};const findPluginPath=pluginName=>{const cwd=process.cwd();const monorepoRoot=findMonorepoRoot(cwd);const cwdPluginPath=join(cwd,"node_modules",pluginName,"package.json");if(existsSync(cwdPluginPath)){return cwdPluginPath}if(monorepoRoot&&monorepoRoot!==cwd){const rootPluginPath=join(monorepoRoot,"node_modules",pluginName,"package.json");if(existsSync(rootPluginPath)){return rootPluginPath}}return null};const path=findPluginPath(pluginName);if(!path){throw new Error(`package.json file not found for plugin "${pluginName}". Please ensure you are using the correct plugin name as specified in its package.json.`)}const content=JSON.parse(readFileSync(path,"utf-8"));if(content.name!==pluginName){throw new Error(`The plugin name in package.json (${content.name}) does not match the requested plugin name (${pluginName}). Please check the plugin name.`)}return content};
@@ -1,22 +1 @@
1
- import { CONFIG } from "../../lib/config.js";
2
- export function buildCron({ name, schedule, handler, description }) {
3
- return {
4
- name,
5
- schedule,
6
- handler,
7
- description
8
- };
9
- }
10
- export const handleCronJobs = async ()=>{
11
- const url = new URL("/api/@vitnode/core/cron", CONFIG.api.origin);
12
- const headers = {
13
- "Content-Type": "application/json"
14
- };
15
- if (CONFIG.cronJobSecret) {
16
- headers.authorization = `Bearer ${CONFIG.cronJobSecret}`;
17
- }
18
- await fetch(url.toString(), {
19
- method: "POST",
20
- headers
21
- });
22
- };
1
+ import{CONFIG}from"../../lib/config.js";export function buildCron({name,schedule,handler,description}){return{name,schedule,handler,description}}export const handleCronJobs=async()=>{const url=new URL("/api/@vitnode/core/cron",CONFIG.api.origin);const headers={"Content-Type":"application/json"};if(CONFIG.cronJobSecret){headers.authorization=`Bearer ${CONFIG.cronJobSecret}`}await fetch(url.toString(),{method:"POST",headers})};
@@ -1,35 +1 @@
1
- /* eslint-disable no-console */ import { core_logs } from "../../database/logs.js";
2
- export const loggerMiddleware = (c)=>{
3
- const logToDbAndConsole = async (content, type)=>{
4
- const pluginId = c.get("plugin")?.id ?? "core";
5
- const ipAddress = c.get("ipAddress");
6
- await c.get("db").insert(core_logs).values({
7
- pluginId,
8
- type,
9
- content,
10
- ipAddress,
11
- method: c.req.method.toUpperCase(),
12
- path: c.req.path,
13
- userAgent: c.req.header("User-Agent"),
14
- statusCode: c.res.status,
15
- userId: c.get("user")?.id
16
- });
17
- const loggers = {
18
- debug: (msg)=>console.debug(`\x1b[34m[VitNode]\x1b[0m \x1b[38;5;208mDebug (${pluginId})\x1b[0m: ${msg}`),
19
- error: (msg)=>console.error(`\x1b[34m[VitNode]\x1b[0m \x1b[31mError (${pluginId})\x1b[0m: ${msg}`),
20
- warn: (msg)=>console.warn(`\x1b[34m[VitNode]\x1b[0m \x1b[33mWarning (${pluginId})\x1b[0m: ${msg}`)
21
- };
22
- (loggers[type] ?? loggers.debug)(content);
23
- };
24
- return {
25
- debug: async (content)=>{
26
- await logToDbAndConsole(content, "debug");
27
- },
28
- error: async (content)=>{
29
- await logToDbAndConsole(content, "error");
30
- },
31
- warn: async (content)=>{
32
- await logToDbAndConsole(content, "warn");
33
- }
34
- };
35
- };
1
+ import{core_logs}from"../../database/logs.js";export const loggerMiddleware=c=>{const logToDbAndConsole=async(content,type)=>{const pluginId=c.get("plugin")?.id??"core";const ipAddress=c.get("ipAddress");await c.get("db").insert(core_logs).values({pluginId,type,content,ipAddress,method:c.req.method.toUpperCase(),path:c.req.path,userAgent:c.req.header("User-Agent"),statusCode:c.res.status,userId:c.get("user")?.id});const loggers={debug:msg=>console.debug(`\x1b[34m[VitNode]\x1b[0m \x1b[38;5;208mDebug (${pluginId})\x1b[0m: ${msg}`),error:msg=>console.error(`\x1b[34m[VitNode]\x1b[0m \x1b[31mError (${pluginId})\x1b[0m: ${msg}`),warn:msg=>console.warn(`\x1b[34m[VitNode]\x1b[0m \x1b[33mWarning (${pluginId})\x1b[0m: ${msg}`)};(loggers[type]??loggers.debug)(content)};return{debug:async content=>{await logToDbAndConsole(content,"debug")},error:async content=>{await logToDbAndConsole(content,"error")},warn:async content=>{await logToDbAndConsole(content,"warn")}}};
@@ -1,22 +1 @@
1
- import { OpenAPIHono } from "@hono/zod-openapi";
2
- export function buildModule({ routes, pluginId, name, modules, cronJobs = [] }) {
3
- const hono = new OpenAPIHono();
4
- if (routes) {
5
- routes.forEach(({ handler, route })=>{
6
- hono.openapi(route, handler);
7
- });
8
- }
9
- if (modules) {
10
- modules.forEach((module)=>{
11
- hono.route(`/${module.name}`, module.hono);
12
- });
13
- }
14
- return {
15
- routes,
16
- pluginId,
17
- hono,
18
- name,
19
- modules,
20
- cronJobs
21
- };
22
- }
1
+ import{OpenAPIHono}from"@hono/zod-openapi";export function buildModule({routes,pluginId,name,modules,cronJobs=[]}){const hono=new OpenAPIHono;if(routes){routes.forEach(({handler,route})=>{hono.openapi(route,handler)})}if(modules){modules.forEach(module=>{hono.route(`/${module.name}`,module.hono)})}return{routes,pluginId,hono,name,modules,cronJobs}}
@@ -1,22 +1 @@
1
- import { OpenAPIHono } from "@hono/zod-openapi";
2
- import { checkPluginId } from "./check-plugin-id.js";
3
- export function buildApiPlugin({ pluginId, modules = [] }) {
4
- // Run for checking if the plugin is valid
5
- checkPluginId(pluginId);
6
- const hono = new OpenAPIHono();
7
- const cronJobs = [];
8
- modules.forEach((handler)=>{
9
- hono.route(`/${handler.name}`, handler.hono);
10
- handler.cronJobs?.forEach((cron)=>{
11
- cronJobs.push({
12
- ...cron,
13
- module: handler.name
14
- });
15
- });
16
- });
17
- return {
18
- pluginId,
19
- hono,
20
- cronJobs
21
- };
22
- }
1
+ import{OpenAPIHono}from"@hono/zod-openapi";import{checkPluginId}from"./check-plugin-id.js";export function buildApiPlugin({pluginId,modules=[]}){checkPluginId(pluginId);const hono=new OpenAPIHono;const cronJobs=[];modules.forEach(handler=>{hono.route(`/${handler.name}`,handler.hono);handler.cronJobs?.forEach(cron=>{cronJobs.push({...cron,module:handler.name})})});return{pluginId,hono,cronJobs}}
@@ -1,27 +1 @@
1
- import { createRoute as createRouteHono } from "@hono/zod-openapi";
2
- import { captchaMiddleware } from "../middlewares/captcha.middleware.js";
3
- import { pluginMiddleware } from "../middlewares/global.middleware.js";
4
- export const buildRoute = ({ route, handler, pluginId })=>{
5
- const pluginTag = pluginId.split(/[-_]/).map((word)=>word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
6
- const tags = [
7
- pluginTag,
8
- ...route.tags ?? []
9
- ];
10
- return {
11
- route: createRouteHono({
12
- tags,
13
- middleware: [
14
- pluginMiddleware(pluginId),
15
- ...route.withCaptcha ? [
16
- captchaMiddleware()
17
- ] : [],
18
- ...Array.isArray(route.middleware) ? route.middleware : route.middleware ? [
19
- route.middleware
20
- ] : []
21
- ],
22
- ...route
23
- }),
24
- handler: handler,
25
- pluginId
26
- };
27
- };
1
+ import{createRoute as createRouteHono}from"@hono/zod-openapi";import{captchaMiddleware}from"../middlewares/captcha.middleware.js";import{pluginMiddleware}from"../middlewares/global.middleware.js";export const buildRoute=({route,handler,pluginId})=>{const pluginTag=pluginId.split(/[-_]/).map(word=>word.charAt(0).toUpperCase()+word.slice(1)).join(" ");const tags=[pluginTag,...route.tags??[]];return{route:createRouteHono({tags,middleware:[pluginMiddleware(pluginId),...route.withCaptcha?[captchaMiddleware()]:[],...Array.isArray(route.middleware)?route.middleware:route.middleware?[route.middleware]:[]],...route}),handler:handler,pluginId}};
@@ -1,83 +1 @@
1
- import { z } from "@hono/zod-openapi";
2
- import { and, asc, count, desc, gt, lt } from "drizzle-orm";
3
- function parsePaginationParams(params) {
4
- const cursor = params.query.cursor ? parseInt(params.query.cursor, 10) : undefined;
5
- const first = params.query.first ? Math.min(parseInt(params.query.first, 10), 100) : undefined;
6
- const last = params.query.last ? Math.min(parseInt(params.query.last, 10), 100) : undefined;
7
- if (first !== undefined && last !== undefined) {
8
- throw new Error("Cannot specify both first and last");
9
- }
10
- if (first !== undefined && first < 0) {
11
- throw new Error("first must be positive");
12
- }
13
- if (last !== undefined && last < 0) {
14
- throw new Error("last must be positive");
15
- }
16
- return {
17
- cursor,
18
- first,
19
- last
20
- };
21
- }
22
- function getOrderFn(isForward, order) {
23
- if (isForward) {
24
- return order === "asc" ? asc : desc;
25
- }
26
- return order === "asc" ? desc : asc;
27
- }
28
- function buildWhereWithCursor(baseWhere, cursor, isForward, order, table, primaryCursor) {
29
- if (!cursor) return baseWhere;
30
- const cursorFilter = isForward && order === "asc" || !isForward && order === "desc" ? gt : lt;
31
- const cursorWhere = cursorFilter(table[primaryCursor.name], cursor);
32
- return baseWhere ? and(baseWhere, cursorWhere) : cursorWhere;
33
- }
34
- async function fetchTotalCount(c, table, where) {
35
- const [{ count: totalCount }] = await c.get("db").select({
36
- count: count()
37
- }).from(table).where(where);
38
- return totalCount;
39
- }
40
- export async function withPagination({ query, table, params, where: whereFromParams, primaryCursor, orderBy: orderByFromParams, c }) {
41
- const { cursor, first, last } = parsePaginationParams(params);
42
- const isForward = last === undefined;
43
- const orderFn = getOrderFn(isForward, orderByFromParams.order);
44
- const orderBy = orderFn(table[orderByFromParams.column.name]);
45
- const where = buildWhereWithCursor(whereFromParams, cursor, isForward, orderByFromParams.order, table, primaryCursor);
46
- const totalCount = await fetchTotalCount(c, table, whereFromParams);
47
- const limit = (first ?? last ?? 50) + 1;
48
- const edges = await query({
49
- limit,
50
- where,
51
- orderBy
52
- });
53
- const requested = first ?? last ?? edges.length;
54
- const hasMore = edges.length > requested;
55
- const slicedEdges = edges.slice(0, requested);
56
- const finalEdges = isForward ? slicedEdges : slicedEdges.reverse();
57
- const startCursor = finalEdges[0]?.[primaryCursor.name] ?? null;
58
- const endCursor = finalEdges.at(-1)?.[primaryCursor.name] ?? null;
59
- return {
60
- pageInfo: {
61
- totalCount,
62
- count: finalEdges.length,
63
- hasNextPage: isForward ? hasMore : !!cursor,
64
- hasPreviousPage: isForward ? !!cursor : hasMore,
65
- startCursor,
66
- endCursor
67
- },
68
- edges: finalEdges
69
- };
70
- }
71
- export const zodPaginationPageInfo = z.object({
72
- totalCount: z.number(),
73
- count: z.number(),
74
- hasNextPage: z.boolean(),
75
- hasPreviousPage: z.boolean(),
76
- startCursor: z.number().nullable(),
77
- endCursor: z.number().nullable()
78
- });
79
- export const zodPaginationQuery = z.object({
80
- cursor: z.string().optional(),
81
- first: z.string().optional(),
82
- last: z.string().optional()
83
- });
1
+ import{z}from"@hono/zod-openapi";import{and,asc,count,desc,gt,lt}from"drizzle-orm";function parsePaginationParams(params){const cursor=params.query.cursor?parseInt(params.query.cursor,10):undefined;const first=params.query.first?Math.min(parseInt(params.query.first,10),100):undefined;const last=params.query.last?Math.min(parseInt(params.query.last,10),100):undefined;if(first!==undefined&&last!==undefined){throw new Error("Cannot specify both first and last")}if(first!==undefined&&first<0){throw new Error("first must be positive")}if(last!==undefined&&last<0){throw new Error("last must be positive")}return{cursor,first,last}}function getOrderFn(isForward,order){if(isForward){return order==="asc"?asc:desc}return order==="asc"?desc:asc}function buildWhereWithCursor(baseWhere,cursor,isForward,order,table,primaryCursor){if(!cursor)return baseWhere;const cursorFilter=isForward&&order==="asc"||!isForward&&order==="desc"?gt:lt;const cursorWhere=cursorFilter(table[primaryCursor.name],cursor);return baseWhere?and(baseWhere,cursorWhere):cursorWhere}async function fetchTotalCount(c,table,where){const[{count:totalCount}]=await c.get("db").select({count:count()}).from(table).where(where);return totalCount}export async function withPagination({query,table,params,where:whereFromParams,primaryCursor,orderBy:orderByFromParams,c}){const{cursor,first,last}=parsePaginationParams(params);const isForward=last===undefined;const orderFn=getOrderFn(isForward,orderByFromParams.order);const orderBy=orderFn(table[orderByFromParams.column.name]);const where=buildWhereWithCursor(whereFromParams,cursor,isForward,orderByFromParams.order,table,primaryCursor);const totalCount=await fetchTotalCount(c,table,whereFromParams);const limit=(first??last??50)+1;const edges=await query({limit,where,orderBy});const requested=first??last??edges.length;const hasMore=edges.length>requested;const slicedEdges=edges.slice(0,requested);const finalEdges=isForward?slicedEdges:slicedEdges.reverse();const startCursor=finalEdges[0]?.[primaryCursor.name]??null;const endCursor=finalEdges.at(-1)?.[primaryCursor.name]??null;return{pageInfo:{totalCount,count:finalEdges.length,hasNextPage:isForward?hasMore:!!cursor,hasPreviousPage:isForward?!!cursor:hasMore,startCursor,endCursor},edges:finalEdges}}export const zodPaginationPageInfo=z.object({totalCount:z.number(),count:z.number(),hasNextPage:z.boolean(),hasPreviousPage:z.boolean(),startCursor:z.number().nullable(),endCursor:z.number().nullable()});export const zodPaginationQuery=z.object({cursor:z.string().optional(),first:z.string().optional(),last:z.string().optional()});
@@ -1,63 +1 @@
1
- import { HTTPException } from "hono/http-exception";
2
- const getResFromReCaptcha = async ({ token, userIp, captchaConfig })=>{
3
- if (captchaConfig.type === "cloudflare_turnstile") {
4
- const res = await fetch("https://challenges.cloudflare.com/turnstile/v0/siteverify", {
5
- method: "POST",
6
- body: JSON.stringify({
7
- secret: captchaConfig.secretKey,
8
- response: token,
9
- remoteip: userIp
10
- }),
11
- headers: {
12
- "Content-Type": "application/json"
13
- }
14
- });
15
- const data = await res.json();
16
- return {
17
- success: data.success,
18
- score: data.success ? 1 : 0,
19
- "error-codes": data["error-codes"]
20
- };
21
- }
22
- if (captchaConfig.type === "recaptcha_v3") {
23
- const res = await fetch(`https://www.google.com/recaptcha/api/siteverify?secret=${captchaConfig.secretKey}&response=${token}&remoteip=${userIp}`, {
24
- method: "POST"
25
- });
26
- const data = await res.json();
27
- return {
28
- success: data.success,
29
- score: data.score ?? 0,
30
- "error-codes": data["error-codes"]
31
- };
32
- }
33
- return {
34
- success: false,
35
- score: 0
36
- };
37
- };
38
- export const captchaMiddleware = ()=>{
39
- return async (c, next)=>{
40
- const token = c.req.header("x-vitnode-captcha-token");
41
- const captchaConfig = c.get("core").captcha;
42
- if (!captchaConfig) {
43
- await next();
44
- return;
45
- }
46
- if (!token) {
47
- throw new HTTPException(400, {
48
- message: "Captcha token is required"
49
- });
50
- }
51
- const res = await getResFromReCaptcha({
52
- token,
53
- userIp: c.get("ipAddress"),
54
- captchaConfig
55
- });
56
- if (!res.success || res.score < 0.5) {
57
- throw new HTTPException(400, {
58
- message: "Captcha validation failed"
59
- });
60
- }
61
- await next();
62
- };
63
- };
1
+ import{HTTPException}from"hono/http-exception";const getResFromReCaptcha=async({token,userIp,captchaConfig})=>{if(captchaConfig.type==="cloudflare_turnstile"){const res=await fetch("https://challenges.cloudflare.com/turnstile/v0/siteverify",{method:"POST",body:JSON.stringify({secret:captchaConfig.secretKey,response:token,remoteip:userIp}),headers:{"Content-Type":"application/json"}});const data=await res.json();return{success:data.success,score:data.success?1:0,"error-codes":data["error-codes"]}}if(captchaConfig.type==="recaptcha_v3"){const res=await fetch(`https://www.google.com/recaptcha/api/siteverify?secret=${captchaConfig.secretKey}&response=${token}&remoteip=${userIp}`,{method:"POST"});const data=await res.json();return{success:data.success,score:data.score??0,"error-codes":data["error-codes"]}}return{success:false,score:0}};export const captchaMiddleware=()=>{return async(c,next)=>{const token=c.req.header("x-vitnode-captcha-token");const captchaConfig=c.get("core").captcha;if(!captchaConfig){await next();return}if(!token){throw new HTTPException(400,{message:"Captcha token is required"})}const res=await getResFromReCaptcha({token,userIp:c.get("ipAddress"),captchaConfig});if(!res.success||res.score<.5){throw new HTTPException(400,{message:"Captcha validation failed"})}await next()}};
@@ -1,19 +1 @@
1
- import { HTTPException } from "hono/http-exception";
2
- export const cronAuthMiddleware = ()=>{
3
- return async (c, next)=>{
4
- const cronSecret = c.get("core").cronSecret;
5
- if (!cronSecret) {
6
- throw new HTTPException(403, {
7
- message: "Cron access not configured"
8
- });
9
- }
10
- const authHeader = c.req.header("authorization");
11
- const providedSecret = authHeader?.replace("Bearer ", "");
12
- if (providedSecret !== cronSecret) {
13
- throw new HTTPException(403, {
14
- message: "Invalid cron authorization"
15
- });
16
- }
17
- await next();
18
- };
19
- };
1
+ import{HTTPException}from"hono/http-exception";export const cronAuthMiddleware=()=>{return async(c,next)=>{const cronSecret=c.get("core").cronSecret;if(!cronSecret){throw new HTTPException(403,{message:"Cron access not configured"})}const authHeader=c.req.header("authorization");const providedSecret=authHeader?.replace("Bearer ","");if(providedSecret!==cronSecret){throw new HTTPException(403,{message:"Invalid cron authorization"})}await next()}};
@@ -1 +1 @@
1
- {"version":3,"file":"global.middleware.d.ts","sourceRoot":"","sources":["../../../../src/api/middlewares/global.middleware.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"global.middleware.d.ts","sourceRoot":"","sources":["../../../../src/api/middlewares/global.middleware.ts"],"names":[],"mappings":"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"}
@@ -1,104 +1 @@
1
- import { HTTPException } from "hono/http-exception";
2
- import { EmailModel } from "../models/email.js";
3
- import { SessionModel } from "../models/session.js";
4
- import { SessionAdminModel } from "../models/session-admin.js";
5
- import { CONFIG } from "../../lib/config.js";
6
- import { loggerMiddleware } from "../lib/logger-middleware.js";
7
- export const globalMiddleware = ({ authorization, metadata, email, dbProvider, captcha, plugins, pathToMessages })=>{
8
- const pluginsMetadata = plugins.map((plugin)=>({
9
- id: plugin.pluginId
10
- }));
11
- const cronMetadata = plugins.flatMap((plugin)=>plugin.cronJobs.map((cronJob)=>({
12
- pluginId: plugin.pluginId,
13
- module: cronJob.module,
14
- name: cronJob.name,
15
- schedule: cronJob.schedule,
16
- handler: cronJob.handler,
17
- description: cronJob.description
18
- })));
19
- const ipHeaderKeys = [
20
- "x-forwarded-for",
21
- "x-real-ip",
22
- "cf-connecting-ip",
23
- "x-client-ip",
24
- "x-forwarded",
25
- "x-cluster-client-ip",
26
- "forwarded-for",
27
- "forwarded",
28
- "via",
29
- "remote-addr",
30
- "client-ip",
31
- "ip",
32
- "x-ip",
33
- "true-client-ip",
34
- "fastly-client-ip",
35
- "x-fastly-client-ip"
36
- ];
37
- return async (c, next)=>{
38
- let ipAddress;
39
- // Try to get IP from Hono's request header method first
40
- for (const key of ipHeaderKeys){
41
- const value = c.req.header(key);
42
- if (value) {
43
- ipAddress = value;
44
- break;
45
- }
46
- }
47
- // If not found, try raw headers (for edge runtimes, etc.)
48
- if (!ipAddress) {
49
- for (const key of ipHeaderKeys){
50
- const value = c.req.raw.headers.get(key);
51
- if (value) {
52
- ipAddress = value;
53
- break;
54
- }
55
- }
56
- }
57
- // Fallback to localhost if nothing found
58
- c.set("ipAddress", ipAddress ?? "127.0.0.1");
59
- c.set("db", dbProvider);
60
- c.set("email", new EmailModel(c));
61
- c.set("core", {
62
- pathToMessages,
63
- metadata,
64
- email,
65
- authorization: {
66
- cookieName: authorization?.cookieName ?? "vitnode_auth",
67
- cookie_expires: authorization?.cookieExpires ?? 1000 * 60 * 60 * 24 * 90,
68
- ssoAdapters: authorization?.ssoAdapters ?? [],
69
- deviceCookieName: authorization?.deviceCookieName ?? "vitnode_device",
70
- deviceCookieExpires: authorization?.deviceCookieExpires ?? 1000 * 60 * 60 * 24 * 365,
71
- adminCookieName: authorization?.adminCookieName ?? "vitnode_auth_admin",
72
- adminCookieExpires: authorization?.adminCookieExpires ?? 1000 * 60 * 60 * 24 * 1,
73
- cookieSecure: authorization?.cookieSecure ?? true
74
- },
75
- captcha,
76
- cronSecret: CONFIG.cronJobSecret,
77
- plugins: pluginsMetadata,
78
- cron: cronMetadata
79
- });
80
- const user = await new SessionModel(c).getUser();
81
- c.set("user", user);
82
- c.set("admin", null);
83
- c.set("log", loggerMiddleware(c));
84
- await next();
85
- };
86
- };
87
- export const pluginMiddleware = (pluginId)=>{
88
- return async (c, next)=>{
89
- c.set("plugin", {
90
- id: pluginId
91
- });
92
- await next();
93
- };
94
- };
95
- export const globalAdminMiddleware = ()=>{
96
- return async (c, next)=>{
97
- const user = await new SessionAdminModel(c).getUser();
98
- if (!user) throw new HTTPException(403);
99
- c.set("admin", {
100
- user
101
- });
102
- await next();
103
- };
104
- };
1
+ import{HTTPException}from"hono/http-exception";import{EmailModel}from"../models/email.js";import{SessionModel}from"../models/session.js";import{SessionAdminModel}from"../models/session-admin.js";import{CONFIG}from"../../lib/config.js";import{loggerMiddleware}from"../lib/logger-middleware.js";export const globalMiddleware=({authorization,metadata,email,dbProvider,captcha,plugins,pathToMessages})=>{const pluginsMetadata=plugins.map(plugin=>({id:plugin.pluginId}));const cronMetadata=plugins.flatMap(plugin=>plugin.cronJobs.map(cronJob=>({pluginId:plugin.pluginId,module:cronJob.module,name:cronJob.name,schedule:cronJob.schedule,handler:cronJob.handler,description:cronJob.description})));const ipHeaderKeys=["x-forwarded-for","x-real-ip","cf-connecting-ip","x-client-ip","x-forwarded","x-cluster-client-ip","forwarded-for","forwarded","via","remote-addr","client-ip","ip","x-ip","true-client-ip","fastly-client-ip","x-fastly-client-ip"];return async(c,next)=>{let ipAddress;for(const key of ipHeaderKeys){ipAddress=c.req.header(key);if(ipAddress)break;ipAddress=c.req.raw.headers.get(key)??undefined;if(ipAddress)break}c.set("ipAddress",ipAddress??"127.0.0.1");c.set("db",dbProvider);c.set("email",new EmailModel(c));c.set("core",{pathToMessages,metadata,email,authorization:{cookieName:authorization?.cookieName??"vitnode_auth",cookie_expires:authorization?.cookieExpires??1e3*60*60*24*90,ssoAdapters:authorization?.ssoAdapters??[],deviceCookieName:authorization?.deviceCookieName??"vitnode_device",deviceCookieExpires:authorization?.deviceCookieExpires??1e3*60*60*24*365,adminCookieName:authorization?.adminCookieName??"vitnode_auth_admin",adminCookieExpires:authorization?.adminCookieExpires??1e3*60*60*24*1,cookieSecure:authorization?.cookieSecure??true},captcha,cronSecret:CONFIG.cronJobSecret,plugins:pluginsMetadata,cron:cronMetadata});const user=await new SessionModel(c).getUser();c.set("user",user);c.set("admin",null);c.set("log",loggerMiddleware(c));await next()}};export const pluginMiddleware=pluginId=>{return async(c,next)=>{c.set("plugin",{id:pluginId});await next()}};export const globalAdminMiddleware=()=>{return async(c,next)=>{const user=await new SessionAdminModel(c).getUser();if(!user)throw new HTTPException(403);c.set("admin",{user});await next()}};
@@ -1,32 +1 @@
1
- import { RateLimiterMemory } from "rate-limiter-flexible";
2
- import { CONFIG } from "../../lib/config.js";
3
- const createRateLimiter = ({ keyPrefix, ...options })=>{
4
- // TODO: Add support for Redis or other storage options
5
- return new RateLimiterMemory({
6
- keyPrefix,
7
- points: options?.points ?? 80,
8
- duration: options?.duration ?? 60,
9
- ...options
10
- });
11
- };
12
- export const rateLimiterMiddleware = (options)=>{
13
- if (CONFIG.node_development) {
14
- // In development, we disable the rate limiter for easier testing
15
- return async (_c, next)=>{
16
- await next();
17
- };
18
- }
19
- const rateLimiter = createRateLimiter({
20
- ...options,
21
- keyPrefix: "vitnode-api-rate-limiter"
22
- });
23
- return async (c, next)=>{
24
- const key = c.get("ipAddress");
25
- try {
26
- await rateLimiter.consume(key);
27
- } catch {
28
- return c.text("Too Many Requests", 429);
29
- }
30
- await next();
31
- };
32
- };
1
+ import{RateLimiterMemory}from"rate-limiter-flexible";import{CONFIG}from"../../lib/config.js";const createRateLimiter=({keyPrefix,...options})=>{return new RateLimiterMemory({keyPrefix,points:options?.points??80,duration:options?.duration??60,...options})};export const rateLimiterMiddleware=options=>{if(CONFIG.node_development){return async(_c,next)=>{await next()}}const rateLimiter=createRateLimiter({...options,keyPrefix:"vitnode-api-rate-limiter"});return async(c,next)=>{const key=c.get("ipAddress");try{await rateLimiter.consume(key)}catch{return c.text("Too Many Requests",429)}await next()}};