@vitnode/core 1.2.0-canary.60 → 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 (274) 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.js +1 -93
  22. package/dist/src/api/middlewares/rate-limiter.middleware.js +1 -32
  23. package/dist/src/api/models/device.js +1 -61
  24. package/dist/src/api/models/email.js +1 -76
  25. package/dist/src/api/models/password.js +1 -36
  26. package/dist/src/api/models/session-admin.js +1 -106
  27. package/dist/src/api/models/session.js +1 -85
  28. package/dist/src/api/models/sso.js +1 -120
  29. package/dist/src/api/models/user/get-user-by-id.js +1 -19
  30. package/dist/src/api/models/user/sign-in-with-passwords.js +1 -22
  31. package/dist/src/api/models/user/sign-up.js +1 -73
  32. package/dist/src/api/models/user.js +1 -8
  33. package/dist/src/api/modules/admin/admin.module.js +1 -19
  34. package/dist/src/api/modules/admin/advanced/advanced.admin.module.js +1 -11
  35. package/dist/src/api/modules/admin/advanced/cron/cron.admin.module.js +1 -12
  36. package/dist/src/api/modules/admin/advanced/cron/routes/get.route.js +1 -66
  37. package/dist/src/api/modules/admin/advanced/cron/routes/run.route.js +1 -95
  38. package/dist/src/api/modules/admin/debug/debug.admin.module.js +1 -10
  39. package/dist/src/api/modules/admin/debug/routes/logs.route.js +1 -94
  40. package/dist/src/api/modules/admin/routes/session.route.js +1 -47
  41. package/dist/src/api/modules/admin/users/routes/list.route.js +1 -79
  42. package/dist/src/api/modules/admin/users/routes/users.route.js +1 -84
  43. package/dist/src/api/modules/admin/users/users.admin.module.js +1 -10
  44. package/dist/src/api/modules/cron/cron/clean.cron.js +1 -24
  45. package/dist/src/api/modules/cron/cron.module.js +1 -14
  46. package/dist/src/api/modules/cron/helpers/process-cron-jobs.d.ts.map +1 -1
  47. package/dist/src/api/modules/cron/helpers/process-cron-jobs.js +1 -76
  48. package/dist/src/api/modules/cron/routes/cron.route.js +1 -101
  49. package/dist/src/api/modules/middleware/middleware.module.js +1 -10
  50. package/dist/src/api/modules/middleware/route.js +1 -49
  51. package/dist/src/api/modules/users/avatar-color.js +1 -43
  52. package/dist/src/api/modules/users/routes/change-password.route.js +1 -58
  53. package/dist/src/api/modules/users/routes/reset-passowrd.route.js +1 -91
  54. package/dist/src/api/modules/users/routes/session.route.js +1 -46
  55. package/dist/src/api/modules/users/routes/sign-in.route.js +1 -71
  56. package/dist/src/api/modules/users/routes/sign-out.route.js +1 -43
  57. package/dist/src/api/modules/users/routes/sign-up.route.js +1 -77
  58. package/dist/src/api/modules/users/routes/test.route.js +1 -33
  59. package/dist/src/api/modules/users/sso/routes/callback.route.js +1 -52
  60. package/dist/src/api/modules/users/sso/routes/create-url.route.js +1 -36
  61. package/dist/src/api/modules/users/sso/sso.module.js +1 -12
  62. package/dist/src/api/modules/users/users.module.js +1 -26
  63. package/dist/src/api/plugin.js +1 -15
  64. package/dist/src/app/login/page.js +1 -16
  65. package/dist/src/app/login/reset-password/page.js +1 -18
  66. package/dist/src/app/login/sso/[providerId]/page.js +1 -10
  67. package/dist/src/app/register/page.js +1 -16
  68. package/dist/src/app_admin/core/advanced/cron/page.js +1 -42
  69. package/dist/src/app_admin/core/debug/page.js +1 -45
  70. package/dist/src/app_admin/core/page.js +1 -5
  71. package/dist/src/app_admin/core/test/page.js +1 -5
  72. package/dist/src/app_admin/core/users/page.js +1 -38
  73. package/dist/src/components/avatar.js +1 -14
  74. package/dist/src/components/confirm-action/confirm-action-alert-dialog.js +1 -42
  75. package/dist/src/components/confirm-action/content.js +1 -31
  76. package/dist/src/components/date-format.js +1 -41
  77. package/dist/src/components/form/auto-form.js +1 -103
  78. package/dist/src/components/form/common/desc.js +1 -9
  79. package/dist/src/components/form/common/label.js +1 -18
  80. package/dist/src/components/form/fields/checkbox.js +1 -37
  81. package/dist/src/components/form/fields/combobox-async.js +1 -123
  82. package/dist/src/components/form/fields/combobox.js +1 -87
  83. package/dist/src/components/form/fields/input.js +1 -39
  84. package/dist/src/components/form/fields/radio-group.js +1 -50
  85. package/dist/src/components/form/fields/select.js +1 -58
  86. package/dist/src/components/form/fields/switch.js +1 -36
  87. package/dist/src/components/form/fields/textarea.js +1 -36
  88. package/dist/src/components/i18n-provider.js +1 -43
  89. package/dist/src/components/logo-vitnode.js +1 -119
  90. package/dist/src/components/switchers/langs/language-switcher.js +1 -47
  91. package/dist/src/components/switchers/themes/theme-switcher.js +1 -28
  92. package/dist/src/components/table/content.js +1 -81
  93. package/dist/src/components/table/data-table.js +1 -68
  94. package/dist/src/components/table/order-table-head.js +1 -50
  95. package/dist/src/components/table/pagination.js +1 -122
  96. package/dist/src/components/tiptap/extension.js +1 -33
  97. package/dist/src/components/tiptap/toolbar/actions/alignment-action.js +1 -91
  98. package/dist/src/components/tiptap/toolbar/actions/bold-action.js +1 -39
  99. package/dist/src/components/tiptap/toolbar/actions/headings-action.js +1 -93
  100. package/dist/src/components/tiptap/toolbar/actions/italic-action.js +1 -38
  101. package/dist/src/components/tiptap/toolbar/actions/list-action.js +1 -61
  102. package/dist/src/components/tiptap/toolbar/actions/text-format-more/text-format-more.js +1 -59
  103. package/dist/src/components/tiptap/toolbar/actions/underline-action.js +1 -38
  104. package/dist/src/components/tiptap/toolbar/actions/undo-redo-actions.js +1 -63
  105. package/dist/src/components/tiptap/toolbar/actions/utils/tooltip-shortcut.js +1 -11
  106. package/dist/src/components/tiptap/toolbar/tiptap-toolbar.js +1 -55
  107. package/dist/src/components/tiptap/toolbar/use-toolbar-editor.js +1 -5
  108. package/dist/src/components/ui/accordion.js +1 -46
  109. package/dist/src/components/ui/alert-dialog.js +1 -123
  110. package/dist/src/components/ui/alert.js +1 -39
  111. package/dist/src/components/ui/badge.js +1 -28
  112. package/dist/src/components/ui/button-client.js +1 -57
  113. package/dist/src/components/ui/button.js +1 -32
  114. package/dist/src/components/ui/card.js +1 -52
  115. package/dist/src/components/ui/checkbox.js +1 -20
  116. package/dist/src/components/ui/collapsible.js +1 -22
  117. package/dist/src/components/ui/command.js +1 -98
  118. package/dist/src/components/ui/context-menu.js +1 -140
  119. package/dist/src/components/ui/dialog.js +1 -189
  120. package/dist/src/components/ui/drawer.js +1 -83
  121. package/dist/src/components/ui/dropdown-menu.js +1 -141
  122. package/dist/src/components/ui/editor-content.js +1 -10
  123. package/dist/src/components/ui/editor.js +1 -35
  124. package/dist/src/components/ui/form.js +1 -148
  125. package/dist/src/components/ui/header-content.js +1 -30
  126. package/dist/src/components/ui/hover-card.js +1 -29
  127. package/dist/src/components/ui/input-otp.js +1 -48
  128. package/dist/src/components/ui/input.js +1 -11
  129. package/dist/src/components/ui/label.js +1 -12
  130. package/dist/src/components/ui/loader.js +1 -16
  131. package/dist/src/components/ui/menubar.js +1 -151
  132. package/dist/src/components/ui/navigation-menu.js +1 -82
  133. package/dist/src/components/ui/popover.js +1 -35
  134. package/dist/src/components/ui/progress.js +1 -19
  135. package/dist/src/components/ui/radio-group.js +1 -27
  136. package/dist/src/components/ui/scroll-area.js +1 -33
  137. package/dist/src/components/ui/select.js +1 -113
  138. package/dist/src/components/ui/separator.js +1 -14
  139. package/dist/src/components/ui/sheet.js +1 -92
  140. package/dist/src/components/ui/sidebar.js +1 -433
  141. package/dist/src/components/ui/skeleton.js +1 -10
  142. package/dist/src/components/ui/slider.js +1 -50
  143. package/dist/src/components/ui/sonner.js +1 -26
  144. package/dist/src/components/ui/switch.js +1 -16
  145. package/dist/src/components/ui/table.js +1 -63
  146. package/dist/src/components/ui/tabs.js +1 -33
  147. package/dist/src/components/ui/textarea.js +1 -10
  148. package/dist/src/components/ui/toggle-group.js +1 -45
  149. package/dist/src/components/ui/toggle.js +1 -34
  150. package/dist/src/components/ui/tooltip.js +1 -57
  151. package/dist/src/config.js +1 -4
  152. package/dist/src/database/admins.js +1 -74
  153. package/dist/src/database/cron.js +1 -22
  154. package/dist/src/database/languages.js +1 -52
  155. package/dist/src/database/logs.js +1 -34
  156. package/dist/src/database/moderators.js +1 -37
  157. package/dist/src/database/roles.js +1 -13
  158. package/dist/src/database/sessions.js +1 -60
  159. package/dist/src/database/users.js +1 -145
  160. package/dist/src/drizzle.config.js +1 -67
  161. package/dist/src/emails/default-template.js +1 -99
  162. package/dist/src/emails/reset-password.js +1 -132
  163. package/dist/src/emails/ui/button.js +1 -36
  164. package/dist/src/emails/ui/card.js +1 -39
  165. package/dist/src/hooks/use-before-unload.js +1 -30
  166. package/dist/src/hooks/use-captcha.js +1 -122
  167. package/dist/src/hooks/use-mobile.js +1 -16
  168. package/dist/src/lib/api/get-middleware-api.js +1 -13
  169. package/dist/src/lib/api/get-next-cron-run-date.js +1 -14
  170. package/dist/src/lib/api/get-next-cron-run-date.test.js +1 -55
  171. package/dist/src/lib/api/get-session-admin-api.js +1 -19
  172. package/dist/src/lib/api/get-session-api.js +1 -14
  173. package/dist/src/lib/api/should-cron-job-run.js +1 -16
  174. package/dist/src/lib/api/should-cron-job-run.test.js +1 -213
  175. package/dist/src/lib/api/validate-cron-schedule.d.ts +2 -0
  176. package/dist/src/lib/api/validate-cron-schedule.d.ts.map +1 -0
  177. package/dist/src/lib/api/validate-cron-schedule.js +1 -0
  178. package/dist/src/lib/api/validate-cron-schedule.test.d.ts +2 -0
  179. package/dist/src/lib/api/validate-cron-schedule.test.d.ts.map +1 -0
  180. package/dist/src/lib/api/validate-cron-schedule.test.js +1 -0
  181. package/dist/src/lib/colors.js +1 -140
  182. package/dist/src/lib/colors.test.js +1 -173
  183. package/dist/src/lib/config.js +1 -14
  184. package/dist/src/lib/ctrl-or-command-character.js +1 -5
  185. package/dist/src/lib/fetcher/cookie-from-string-to-object.js +1 -12
  186. package/dist/src/lib/fetcher/cookie-from-string-to-object.test.js +1 -78
  187. package/dist/src/lib/fetcher/core.js +3 -48
  188. package/dist/src/lib/fetcher/helpers-server.js +1 -18
  189. package/dist/src/lib/fetcher/helpers.js +1 -16
  190. package/dist/src/lib/fetcher/helpers.test.js +1 -37
  191. package/dist/src/lib/fetcher/types.js +1 -1
  192. package/dist/src/lib/fetcher-client.js +1 -17
  193. package/dist/src/lib/fetcher.js +1 -33
  194. package/dist/src/lib/helpers/auto-form.js +1 -98
  195. package/dist/src/lib/helpers/auto-form.test.js +1 -336
  196. package/dist/src/lib/navigation.js +1 -11
  197. package/dist/src/lib/plugin.js +1 -3
  198. package/dist/src/lib/special-characters.js +1 -4
  199. package/dist/src/lib/special-characters.test.js +1 -56
  200. package/dist/src/lib/utils.js +1 -5
  201. package/dist/src/locales/en.json +308 -0
  202. package/dist/src/tests/setup.js +1 -6
  203. package/dist/src/views/admin/layouts/admin-layout.js +1 -73
  204. package/dist/src/views/admin/layouts/sidebar/nav/item.js +1 -98
  205. package/dist/src/views/admin/layouts/sidebar/nav/nav.js +1 -60
  206. package/dist/src/views/admin/layouts/sidebar/sidebar.js +1 -28
  207. package/dist/src/views/admin/layouts/sidebar/sign-out.js +1 -14
  208. package/dist/src/views/admin/layouts/user-bar/client.js +1 -69
  209. package/dist/src/views/admin/layouts/user-bar/user-bar.js +1 -32
  210. package/dist/src/views/admin/sign-in/sign-in-admin-view.js +1 -27
  211. package/dist/src/views/admin/views/core/advanced/cron/cron-table-view.js +1 -97
  212. package/dist/src/views/admin/views/core/advanced/cron/run-action/mutation-api.js +1 -23
  213. package/dist/src/views/admin/views/core/advanced/cron/run-action/run-action.js +1 -38
  214. package/dist/src/views/admin/views/core/dashboard/dashboard-admin-view.js +1 -44
  215. package/dist/src/views/admin/views/core/debug/actions/clear-cache/clear-cache.js +1 -35
  216. package/dist/src/views/admin/views/core/debug/actions/clear-cache/mutation-api.js +1 -5
  217. package/dist/src/views/admin/views/core/debug/system-logs/actions/more/content.js +1 -281
  218. package/dist/src/views/admin/views/core/debug/system-logs/actions/more/more.js +1 -67
  219. package/dist/src/views/admin/views/core/debug/system-logs/badges/badge-status.js +1 -14
  220. package/dist/src/views/admin/views/core/debug/system-logs/badges/badge-type-log.js +1 -30
  221. package/dist/src/views/admin/views/core/debug/system-logs/system-logs-view.js +1 -96
  222. package/dist/src/views/admin/views/core/test.js +1 -161
  223. package/dist/src/views/admin/views/core/users/users-admin-view.js +1 -89
  224. package/dist/src/views/auth/password-reset/change-password-form/form.js +1 -48
  225. package/dist/src/views/auth/password-reset/change-password-form/mutation-api.js +1 -22
  226. package/dist/src/views/auth/password-reset/change-password-form/use-form.js +1 -36
  227. package/dist/src/views/auth/password-reset/form/form.js +1 -104
  228. package/dist/src/views/auth/password-reset/form/mutation-api.js +1 -21
  229. package/dist/src/views/auth/password-reset/form/use-form.js +1 -33
  230. package/dist/src/views/auth/password-reset/password-reset-view.js +1 -37
  231. package/dist/src/views/auth/sign-in/form/form.js +1 -64
  232. package/dist/src/views/auth/sign-in/form/mutation-api.js +1 -33
  233. package/dist/src/views/auth/sign-in/form/use-form.js +1 -38
  234. package/dist/src/views/auth/sign-in/sign-in-view.js +1 -61
  235. package/dist/src/views/auth/sign-up/components/password-input.js +1 -96
  236. package/dist/src/views/auth/sign-up/email-confirmation-view.js +1 -55
  237. package/dist/src/views/auth/sign-up/form/form.js +1 -89
  238. package/dist/src/views/auth/sign-up/form/mutation-api.js +1 -30
  239. package/dist/src/views/auth/sign-up/form/use-form.js +1 -70
  240. package/dist/src/views/auth/sign-up/sign-up-view.js +1 -65
  241. package/dist/src/views/auth/sign-up/wrapper.js +1 -22
  242. package/dist/src/views/auth/sso/buttons/client.js +1 -22
  243. package/dist/src/views/auth/sso/buttons/mutation-api.js +1 -24
  244. package/dist/src/views/auth/sso/buttons/sso-buttons.js +1 -56
  245. package/dist/src/views/auth/sso/callback/callback-sso-view.js +1 -32
  246. package/dist/src/views/auth/sso/callback/client/client.js +1 -68
  247. package/dist/src/views/auth/sso/callback/client/mutation-api.js +1 -32
  248. package/dist/src/views/error/back-button.js +1 -14
  249. package/dist/src/views/error/error-view.js +1 -58
  250. package/dist/src/views/error/global-error-view.js +1 -50
  251. package/dist/src/views/layouts/provider.js +1 -44
  252. package/dist/src/views/layouts/root-layout.js +1 -25
  253. package/dist/src/views/layouts/theme/header/header.js +1 -38
  254. package/dist/src/views/layouts/theme/header/user/auth/auth.js +1 -33
  255. package/dist/src/views/layouts/theme/header/user/auth/client.js +1 -47
  256. package/dist/src/views/layouts/theme/header/user/auth/log-out-mutation-api.js +1 -27
  257. package/dist/src/views/layouts/theme/header/user/user.js +1 -32
  258. package/dist/src/views/layouts/theme/layout.js +1 -16
  259. package/dist/src/vitnode.config.js +1 -42
  260. package/dist/tsconfig.tsbuildinfo +1 -1
  261. package/dist/tsup.config.js +18 -0
  262. package/dist/vitest.config.d.ts.map +1 -1
  263. package/dist/vitest.config.js +49 -0
  264. package/eslint.config.mjs +2 -0
  265. package/package.json +6 -10
  266. package/dist/src/api/adapters/cron/node-cron.adapter.d.ts +0 -3
  267. package/dist/src/api/adapters/cron/node-cron.adapter.d.ts.map +0 -1
  268. package/dist/src/api/adapters/cron/node-cron.adapter.js +0 -11
  269. package/dist/src/api/adapters/email/nodemailer.d.ts +0 -10
  270. package/dist/src/api/adapters/email/nodemailer.d.ts.map +0 -1
  271. package/dist/src/api/adapters/email/nodemailer.js +0 -30
  272. package/dist/src/api/adapters/email/resend.d.ts +0 -6
  273. package/dist/src/api/adapters/email/resend.d.ts.map +0 -1
  274. package/dist/src/api/adapters/email/resend.js +0 -21
@@ -1,101 +1 @@
1
- import { eq } from "drizzle-orm";
2
- import { z } from "zod";
3
- import { buildRoute } from "../../../lib/route.js";
4
- import { cronAuthMiddleware } from "../../../middlewares/cron-auth.middleware.js";
5
- import { CONFIG_PLUGIN } from "../../../../config.js";
6
- import { core_cron } from "../../../../database/cron.js";
7
- import { getNextCronRunDate } from "../../../../lib/api/get-next-cron-run-date.js";
8
- import { cleanupOutdatedCronJobs, processCronJobs, updateCronJobs } from "../helpers/process-cron-jobs.js";
9
- export const runCronRoute = buildRoute({
10
- pluginId: CONFIG_PLUGIN.pluginId,
11
- route: {
12
- method: "post",
13
- description: "Run cron job",
14
- path: "/",
15
- middleware: [
16
- cronAuthMiddleware()
17
- ],
18
- responses: {
19
- 200: {
20
- content: {
21
- "text/plain": {
22
- schema: z.string()
23
- }
24
- },
25
- description: "Cron started successfully"
26
- },
27
- 403: {
28
- description: "Access Denied"
29
- }
30
- }
31
- },
32
- handler: async (c)=>{
33
- const db = c.get("db");
34
- const cronJobs = c.get("core").cron;
35
- try {
36
- const cronFromDb = await db.select().from(core_cron);
37
- await cleanupOutdatedCronJobs(db, cronFromDb, cronJobs);
38
- const now = new Date();
39
- let executedJobs = 0;
40
- const { newJobs, jobsToExecute, jobsToUpdate } = processCronJobs(cronJobs, cronFromDb);
41
- if (newJobs.length > 0) {
42
- try {
43
- const newJobsValues = newJobs.map((job)=>({
44
- name: job.name,
45
- description: job.description ?? null,
46
- lastRun: null,
47
- nextRun: null,
48
- pluginId: job.pluginId,
49
- module: job.module,
50
- schedule: job.schedule
51
- }));
52
- await db.insert(core_cron).values(newJobsValues);
53
- } catch (error) {
54
- await c.get("log").error(`Error inserting new cron jobs: ${error}`);
55
- }
56
- }
57
- try {
58
- await updateCronJobs(db, jobsToUpdate);
59
- } catch (error) {
60
- await c.get("log").error(`Error updating cron jobs: ${error}`);
61
- }
62
- if (jobsToExecute.length > 0) {
63
- // Optimize: Create a Map for O(1) lookup instead of O(n) find operations
64
- const cronFromDbMap = new Map(cronFromDb.map((dbJob)=>[
65
- `${dbJob.pluginId}:${dbJob.module}:${dbJob.name}`,
66
- dbJob
67
- ]));
68
- const executionPromises = jobsToExecute.map(async (job)=>{
69
- try {
70
- await job.handler(c);
71
- const jobKey = `${job.pluginId}:${job.module}:${job.name}`;
72
- const dbJob = cronFromDbMap.get(jobKey);
73
- if (dbJob) {
74
- await db.update(core_cron).set({
75
- lastRun: now,
76
- nextRun: getNextCronRunDate(job.schedule, now)
77
- }).where(eq(core_cron.id, dbJob.id));
78
- }
79
- return {
80
- success: true,
81
- jobName: job.name
82
- };
83
- } catch (error) {
84
- await c.get("log").error(`Error executing cron job "${job.pluginId}:${job.module}:${job.name}": ${error}`);
85
- return {
86
- success: false,
87
- jobName: job.name,
88
- error
89
- };
90
- }
91
- });
92
- const results = await Promise.allSettled(executionPromises);
93
- executedJobs = results.filter((result)=>result.status === "fulfilled" && result.value.success).length;
94
- }
95
- return c.text(`Cron jobs processed. Executed ${executedJobs} jobs.`, 200);
96
- } catch (error) {
97
- await c.get("log").error(`Error processing cron jobs: ${error}`);
98
- return c.text("Error processing cron jobs", 500);
99
- }
100
- }
101
- });
1
+ import{eq}from"drizzle-orm";import{z}from"zod";import{buildRoute}from"../../../lib/route.js";import{cronAuthMiddleware}from"../../../middlewares/cron-auth.middleware.js";import{CONFIG_PLUGIN}from"../../../../config.js";import{core_cron}from"../../../../database/cron.js";import{getNextCronRunDate}from"../../../../lib/api/get-next-cron-run-date.js";import{cleanupOutdatedCronJobs,processCronJobs,updateCronJobs}from"../helpers/process-cron-jobs.js";export const runCronRoute=buildRoute({pluginId:CONFIG_PLUGIN.pluginId,route:{method:"post",description:"Run cron job",path:"/",middleware:[cronAuthMiddleware()],responses:{200:{content:{"text/plain":{schema:z.string()}},description:"Cron started successfully"},403:{description:"Access Denied"}}},handler:async c=>{const db=c.get("db");const cronJobs=c.get("core").cron;try{const cronFromDb=await db.select().from(core_cron);await cleanupOutdatedCronJobs(db,cronFromDb,cronJobs);const now=new Date;let executedJobs=0;const{newJobs,jobsToExecute,jobsToUpdate}=processCronJobs(cronJobs,cronFromDb);if(newJobs.length>0){try{const newJobsValues=newJobs.map(job=>({name:job.name,description:job.description??null,lastRun:null,nextRun:null,pluginId:job.pluginId,module:job.module,schedule:job.schedule}));await db.insert(core_cron).values(newJobsValues)}catch(error){await c.get("log").error(`Error inserting new cron jobs: ${error}`)}}try{await updateCronJobs(db,jobsToUpdate)}catch(error){await c.get("log").error(`Error updating cron jobs: ${error}`)}if(jobsToExecute.length>0){const cronFromDbMap=new Map(cronFromDb.map(dbJob=>[`${dbJob.pluginId}:${dbJob.module}:${dbJob.name}`,dbJob]));const executionPromises=jobsToExecute.map(async job=>{try{await job.handler(c);const jobKey=`${job.pluginId}:${job.module}:${job.name}`;const dbJob=cronFromDbMap.get(jobKey);if(dbJob){await db.update(core_cron).set({lastRun:now,nextRun:getNextCronRunDate(job.schedule,now)}).where(eq(core_cron.id,dbJob.id))}return{success:true,jobName:job.name}}catch(error){await c.get("log").error(`Error executing cron job "${job.pluginId}:${job.module}:${job.name}": ${error}`);return{success:false,jobName:job.name,error}}});const results=await Promise.allSettled(executionPromises);executedJobs=results.filter(result=>result.status==="fulfilled"&&result.value.success).length}return c.text(`Cron jobs processed. Executed ${executedJobs} jobs.`,200)}catch(error){await c.get("log").error(`Error processing cron jobs: ${error}`);return c.text("Error processing cron jobs",500)}}});
@@ -1,10 +1 @@
1
- import { buildModule } from "../../lib/module.js";
2
- import { CONFIG_PLUGIN } from "../../../config.js";
3
- import { routeMiddleware } from "./route.js";
4
- export const middlewareModule = buildModule({
5
- pluginId: CONFIG_PLUGIN.pluginId,
6
- name: "middleware",
7
- routes: [
8
- routeMiddleware
9
- ]
10
- });
1
+ import{buildModule}from"../../lib/module.js";import{CONFIG_PLUGIN}from"../../../config.js";import{routeMiddleware}from"./route.js";export const middlewareModule=buildModule({pluginId:CONFIG_PLUGIN.pluginId,name:"middleware",routes:[routeMiddleware]});
@@ -1,49 +1 @@
1
- import { z } from "zod";
2
- import { buildRoute } from "../../lib/route.js";
3
- import { CONFIG_PLUGIN } from "../../../config.js";
4
- export const routeMiddlewareSchema = z.object({
5
- sso: z.array(z.object({
6
- id: z.string(),
7
- name: z.string()
8
- })),
9
- isEmail: z.boolean(),
10
- captcha: z.object({
11
- siteKey: z.string(),
12
- type: z.enum([
13
- "cloudflare_turnstile",
14
- "recaptcha_v3"
15
- ])
16
- }).optional()
17
- });
18
- export const routeMiddleware = buildRoute({
19
- pluginId: CONFIG_PLUGIN.pluginId,
20
- route: {
21
- path: "/",
22
- method: "get",
23
- description: "Middleware route with user authentication",
24
- responses: {
25
- 200: {
26
- content: {
27
- "application/json": {
28
- schema: routeMiddlewareSchema
29
- }
30
- },
31
- description: "Middleware route"
32
- }
33
- }
34
- },
35
- handler: (c)=>{
36
- const sso = c.get("core").authorization.ssoAdapters;
37
- return c.json({
38
- isEmail: !!c.get("core").email?.adapter,
39
- sso: sso.map((s)=>({
40
- id: s.id,
41
- name: s.name
42
- })),
43
- captcha: c.get("core").captcha ? {
44
- siteKey: c.get("core").captcha?.siteKey ?? "",
45
- type: c.get("core").captcha?.type ?? "cloudflare_turnstile"
46
- } : undefined
47
- }, 200);
48
- }
49
- });
1
+ import{z}from"zod";import{buildRoute}from"../../lib/route.js";import{CONFIG_PLUGIN}from"../../../config.js";export const routeMiddlewareSchema=z.object({sso:z.array(z.object({id:z.string(),name:z.string()})),isEmail:z.boolean(),captcha:z.object({siteKey:z.string(),type:z.enum(["cloudflare_turnstile","recaptcha_v3"])}).optional()});export const routeMiddleware=buildRoute({pluginId:CONFIG_PLUGIN.pluginId,route:{path:"/",method:"get",description:"Middleware route with user authentication",responses:{200:{content:{"application/json":{schema:routeMiddlewareSchema}},description:"Middleware route"}}},handler:c=>{const sso=c.get("core").authorization.ssoAdapters;return c.json({isEmail:!!c.get("core").email?.adapter,sso:sso.map(s=>({id:s.id,name:s.name})),captcha:c.get("core").captcha?{siteKey:c.get("core").captcha?.siteKey??"",type:c.get("core").captcha?.type??"cloudflare_turnstile"}:undefined},200)}});
@@ -1,43 +1 @@
1
- import { convertColor } from "../../../lib/colors.js";
2
- const getHashOfString = (str)=>{
3
- let hash = 0;
4
- for(let i = 0; i < str.length; i++){
5
- hash = str.charCodeAt(i) + ((hash << 5) - hash);
6
- }
7
- hash = Math.abs(hash);
8
- return hash;
9
- };
10
- const normalizeHash = (hash, min, max)=>{
11
- return Math.floor(hash % (max - min) + min);
12
- };
13
- const generateHSLFromName = (name)=>{
14
- const hRange = [
15
- 0,
16
- 360
17
- ];
18
- const lRange = [
19
- 25,
20
- 60
21
- ];
22
- const sRange = [
23
- 50,
24
- 75
25
- ];
26
- const hash = getHashOfString(name);
27
- const h = normalizeHash(hash, hRange[0], hRange[1]);
28
- const s = normalizeHash(hash, sRange[0], sRange[1]);
29
- const l = normalizeHash(hash, lRange[0], lRange[1]);
30
- return [
31
- h,
32
- s,
33
- l
34
- ];
35
- };
36
- export const generateAvatarColor = (name)=>{
37
- const hslName = generateHSLFromName(name);
38
- return convertColor.hslToHex({
39
- h: hslName[0],
40
- s: hslName[1],
41
- l: hslName[2]
42
- });
43
- };
1
+ import{convertColor}from"../../../lib/colors.js";const getHashOfString=str=>{let hash=0;for(let i=0;i<str.length;i++){hash=str.charCodeAt(i)+((hash<<5)-hash)}hash=Math.abs(hash);return hash};const normalizeHash=(hash,min,max)=>{return Math.floor(hash%(max-min)+min)};const generateHSLFromName=name=>{const hRange=[0,360];const lRange=[25,60];const sRange=[50,75];const hash=getHashOfString(name);const h=normalizeHash(hash,hRange[0],hRange[1]);const s=normalizeHash(hash,sRange[0],sRange[1]);const l=normalizeHash(hash,lRange[0],lRange[1]);return[h,s,l]};export const generateAvatarColor=name=>{const hslName=generateHSLFromName(name);return convertColor.hslToHex({h:hslName[0],s:hslName[1],l:hslName[2]})};
@@ -1,58 +1 @@
1
- import { and, eq, gt } from "drizzle-orm";
2
- import { HTTPException } from "hono/http-exception";
3
- import { z } from "zod";
4
- import { buildRoute } from "../../../lib/route.js";
5
- import { PasswordModel } from "../../../models/password.js";
6
- import { CONFIG_PLUGIN } from "../../../../config.js";
7
- import { core_users, core_users_forgot_password } from "../../../../database/users.js";
8
- export const zodChangePasswordSchema = z.object({
9
- password: z.string().min(8).openapi({
10
- example: "Test123!"
11
- }),
12
- userId: z.number().openapi({
13
- example: 123456
14
- }),
15
- token: z.string().openapi({
16
- example: "abcdefg12345"
17
- })
18
- });
19
- export const changePasswordRoute = buildRoute({
20
- pluginId: CONFIG_PLUGIN.pluginId,
21
- route: {
22
- method: "post",
23
- description: "Change user password",
24
- path: "/change-password",
25
- request: {
26
- body: {
27
- required: true,
28
- content: {
29
- "application/json": {
30
- schema: zodChangePasswordSchema
31
- }
32
- }
33
- }
34
- },
35
- responses: {
36
- 201: {
37
- description: "Password changed"
38
- }
39
- }
40
- },
41
- handler: async (c)=>{
42
- const { password, userId, token } = c.req.valid("json");
43
- const [user] = await c.get("db").select().from(core_users_forgot_password).where(and(eq(core_users_forgot_password.userId, userId), eq(core_users_forgot_password.token, token), gt(core_users_forgot_password.expiresAt, new Date()))).limit(1);
44
- if (!user) {
45
- throw new HTTPException(400, {
46
- message: "Invalid token"
47
- });
48
- }
49
- const hashPassword = await new PasswordModel().encryptPassword(password);
50
- await Promise.all([
51
- c.get("db").update(core_users).set({
52
- password: hashPassword
53
- }).where(eq(core_users.id, userId)),
54
- c.get("db").delete(core_users_forgot_password).where(eq(core_users_forgot_password.id, user.id))
55
- ]);
56
- return c.text("Password changed", 201);
57
- }
58
- });
1
+ import{and,eq,gt}from"drizzle-orm";import{HTTPException}from"hono/http-exception";import{z}from"zod";import{buildRoute}from"../../../lib/route.js";import{PasswordModel}from"../../../models/password.js";import{CONFIG_PLUGIN}from"../../../../config.js";import{core_users,core_users_forgot_password}from"../../../../database/users.js";export const zodChangePasswordSchema=z.object({password:z.string().min(8).openapi({example:"Test123!"}),userId:z.number().openapi({example:123456}),token:z.string().openapi({example:"abcdefg12345"})});export const changePasswordRoute=buildRoute({pluginId:CONFIG_PLUGIN.pluginId,route:{method:"post",description:"Change user password",path:"/change-password",request:{body:{required:true,content:{"application/json":{schema:zodChangePasswordSchema}}}},responses:{201:{description:"Password changed"}}},handler:async c=>{const{password,userId,token}=c.req.valid("json");const[user]=await c.get("db").select().from(core_users_forgot_password).where(and(eq(core_users_forgot_password.userId,userId),eq(core_users_forgot_password.token,token),gt(core_users_forgot_password.expiresAt,new Date))).limit(1);if(!user){throw new HTTPException(400,{message:"Invalid token"})}const hashPassword=await new PasswordModel().encryptPassword(password);await Promise.all([c.get("db").update(core_users).set({password:hashPassword}).where(eq(core_users.id,userId)),c.get("db").delete(core_users_forgot_password).where(eq(core_users_forgot_password.id,user.id))]);return c.text("Password changed",201)}});
@@ -1,91 +1 @@
1
- import { eq } from "drizzle-orm";
2
- import { createTranslator } from "use-intl";
3
- import { z } from "zod";
4
- import { buildRoute } from "../../../lib/route.js";
5
- import { ForgotPasswordTokenModel } from "../../../models/password.js";
6
- import { CONFIG_PLUGIN } from "../../../../config.js";
7
- import { core_users, core_users_forgot_password } from "../../../../database/users.js";
8
- import ResetPasswordEmailTemplate from "../../../../emails/reset-password.js";
9
- import { CONFIG } from "../../../../lib/config.js";
10
- export const resetPasswordRoute = buildRoute({
11
- pluginId: CONFIG_PLUGIN.pluginId,
12
- route: {
13
- method: "post",
14
- description: "Request a password reset",
15
- path: "/reset-password",
16
- withCaptcha: true,
17
- request: {
18
- body: {
19
- required: true,
20
- content: {
21
- "application/json": {
22
- schema: z.object({
23
- email: z.email().toLowerCase().openapi({
24
- example: "test@test.com"
25
- })
26
- })
27
- }
28
- }
29
- }
30
- },
31
- responses: {
32
- 201: {
33
- description: "Email sent"
34
- }
35
- }
36
- },
37
- handler: async (c)=>{
38
- const RESPONSE_TEXT = c.text("Email sent", 201);
39
- const { email } = c.req.valid("json");
40
- const [findUser] = await c.get("db").select({
41
- email: core_users.email,
42
- id: core_users.id,
43
- language: core_users.language
44
- }).from(core_users).where(eq(core_users.email, email)).limit(1);
45
- if (!findUser) {
46
- return RESPONSE_TEXT;
47
- }
48
- const hashToken = new ForgotPasswordTokenModel().generateResetToken();
49
- const [findLastRecord] = await c.get("db").select().from(core_users_forgot_password).where(eq(core_users_forgot_password.userId, findUser.id)).limit(1);
50
- // If a record will be found with createdAt in the last 5 minutes, skip
51
- if (findLastRecord?.createdAt > new Date(Date.now() - 1000 * 60 * 5)) {
52
- return RESPONSE_TEXT;
53
- }
54
- const EXPIRES_AT = new Date(Date.now() + 1000 * 60 * 30); // 30 minutes
55
- if (findLastRecord) {
56
- await c.get("db").update(core_users_forgot_password).set({
57
- createdAt: new Date(),
58
- expiresAt: EXPIRES_AT,
59
- token: hashToken,
60
- ipAddress: c.get("ipAddress")
61
- }).where(eq(core_users_forgot_password.id, findLastRecord.id));
62
- } else {
63
- await c.get("db").insert(core_users_forgot_password).values({
64
- token: hashToken,
65
- ipAddress: c.get("ipAddress"),
66
- userId: findUser.id,
67
- expiresAt: EXPIRES_AT
68
- });
69
- }
70
- // Send email
71
- const resetUrlNative = new URL(`login/reset-password?token=${hashToken}&userId=${findUser.id}`, CONFIG.web.href);
72
- await c.get("email").send({
73
- user: {
74
- id: findUser.id,
75
- email: findUser.email,
76
- language: findUser.language
77
- },
78
- content: (props)=>ResetPasswordEmailTemplate({
79
- ...props,
80
- resetUrl: resetUrlNative.href,
81
- expiryDate: EXPIRES_AT,
82
- userIpAddress: c.get("ipAddress")
83
- }),
84
- subject: ({ i18n })=>{
85
- const t = createTranslator(i18n);
86
- return t("core.auth.reset_password.email.subject");
87
- }
88
- });
89
- return RESPONSE_TEXT;
90
- }
91
- });
1
+ import{eq}from"drizzle-orm";import{createTranslator}from"use-intl";import{z}from"zod";import{buildRoute}from"../../../lib/route.js";import{ForgotPasswordTokenModel}from"../../../models/password.js";import{CONFIG_PLUGIN}from"../../../../config.js";import{core_users,core_users_forgot_password}from"../../../../database/users.js";import ResetPasswordEmailTemplate from"../../../../emails/reset-password.js";import{CONFIG}from"../../../../lib/config.js";export const resetPasswordRoute=buildRoute({pluginId:CONFIG_PLUGIN.pluginId,route:{method:"post",description:"Request a password reset",path:"/reset-password",withCaptcha:true,request:{body:{required:true,content:{"application/json":{schema:z.object({email:z.email().toLowerCase().openapi({example:"test@test.com"})})}}}},responses:{201:{description:"Email sent"}}},handler:async c=>{const RESPONSE_TEXT=c.text("Email sent",201);const{email}=c.req.valid("json");const[findUser]=await c.get("db").select({email:core_users.email,id:core_users.id,language:core_users.language}).from(core_users).where(eq(core_users.email,email)).limit(1);if(!findUser){return RESPONSE_TEXT}const hashToken=new ForgotPasswordTokenModel().generateResetToken();const[findLastRecord]=await c.get("db").select().from(core_users_forgot_password).where(eq(core_users_forgot_password.userId,findUser.id)).limit(1);if(findLastRecord?.createdAt>new Date(Date.now()-1e3*60*5)){return RESPONSE_TEXT}const EXPIRES_AT=new Date(Date.now()+1e3*60*30);if(findLastRecord){await c.get("db").update(core_users_forgot_password).set({createdAt:new Date,expiresAt:EXPIRES_AT,token:hashToken,ipAddress:c.get("ipAddress")}).where(eq(core_users_forgot_password.id,findLastRecord.id))}else{await c.get("db").insert(core_users_forgot_password).values({token:hashToken,ipAddress:c.get("ipAddress"),userId:findUser.id,expiresAt:EXPIRES_AT})}const resetUrlNative=new URL(`login/reset-password?token=${hashToken}&userId=${findUser.id}`,CONFIG.web.href);await c.get("email").send({user:{id:findUser.id,email:findUser.email,language:findUser.language},content:props=>ResetPasswordEmailTemplate({...props,resetUrl:resetUrlNative.href,expiryDate:EXPIRES_AT,userIpAddress:c.get("ipAddress")}),subject:({i18n})=>{const t=createTranslator(i18n);return t("core.auth.reset_password.email.subject")}});return RESPONSE_TEXT}});
@@ -1,46 +1 @@
1
- import { z } from "zod";
2
- import { buildRoute } from "../../../lib/route.js";
3
- import { SessionAdminModel } from "../../../models/session-admin.js";
4
- import { CONFIG_PLUGIN } from "../../../../config.js";
5
- export const sessionRoute = buildRoute({
6
- pluginId: CONFIG_PLUGIN.pluginId,
7
- route: {
8
- method: "get",
9
- description: "Verify session",
10
- path: "/session",
11
- responses: {
12
- 200: {
13
- content: {
14
- "application/json": {
15
- schema: z.object({
16
- user: z.object({
17
- id: z.number(),
18
- email: z.string(),
19
- name: z.string(),
20
- nameCode: z.string(),
21
- createdAt: z.date(),
22
- newsletter: z.boolean(),
23
- avatarColor: z.string(),
24
- emailVerified: z.boolean(),
25
- roleId: z.number(),
26
- birthday: z.date().nullable(),
27
- isAdmin: z.boolean()
28
- }).nullable()
29
- })
30
- }
31
- },
32
- description: "User"
33
- }
34
- }
35
- },
36
- handler: async (c)=>{
37
- const user = c.get("user");
38
- const admin = new SessionAdminModel(c);
39
- return c.json({
40
- user: user ? {
41
- ...user,
42
- isAdmin: await admin.checkIfUserIsAdmin(user.id)
43
- } : null
44
- });
45
- }
46
- });
1
+ import{z}from"zod";import{buildRoute}from"../../../lib/route.js";import{SessionAdminModel}from"../../../models/session-admin.js";import{CONFIG_PLUGIN}from"../../../../config.js";export const sessionRoute=buildRoute({pluginId:CONFIG_PLUGIN.pluginId,route:{method:"get",description:"Verify session",path:"/session",responses:{200:{content:{"application/json":{schema:z.object({user:z.object({id:z.number(),email:z.string(),name:z.string(),nameCode:z.string(),createdAt:z.date(),newsletter:z.boolean(),avatarColor:z.string(),emailVerified:z.boolean(),roleId:z.number(),birthday:z.date().nullable(),isAdmin:z.boolean()}).nullable()})}},description:"User"}}},handler:async c=>{const user=c.get("user");const admin=new SessionAdminModel(c);return c.json({user:user?{...user,isAdmin:await admin.checkIfUserIsAdmin(user.id)}:null})}});
@@ -1,71 +1 @@
1
- import { z } from "zod";
2
- import { buildRoute } from "../../../lib/route.js";
3
- import { SessionModel } from "../../../models/session.js";
4
- import { SessionAdminModel } from "../../../models/session-admin.js";
5
- import { UserModel } from "../../../models/user.js";
6
- import { CONFIG_PLUGIN } from "../../../../config.js";
7
- export const zodSignInSchema = z.object({
8
- email: z.email().toLowerCase().openapi({
9
- example: "test@test.com"
10
- }),
11
- password: z.string().openapi({
12
- example: "Test123!"
13
- }),
14
- isAdmin: z.boolean().optional().openapi({
15
- example: false
16
- })
17
- });
18
- export const signInRoute = buildRoute({
19
- pluginId: CONFIG_PLUGIN.pluginId,
20
- route: {
21
- method: "post",
22
- description: "Sign in with email and password",
23
- path: "/sign_in",
24
- request: {
25
- body: {
26
- required: true,
27
- content: {
28
- "application/json": {
29
- schema: zodSignInSchema
30
- }
31
- }
32
- }
33
- },
34
- responses: {
35
- 403: {
36
- description: "Access Denied"
37
- },
38
- 201: {
39
- content: {
40
- "application/json": {
41
- schema: z.object({
42
- id: z.number(),
43
- token: z.string()
44
- })
45
- }
46
- },
47
- description: "User signed in"
48
- }
49
- }
50
- },
51
- handler: async (c)=>{
52
- const { password, isAdmin, email } = c.req.valid("json");
53
- const data = await new UserModel().signInWithPassword({
54
- password,
55
- email,
56
- c
57
- });
58
- if (isAdmin) {
59
- const { token } = await new SessionAdminModel(c).createSessionByUserId(data.id);
60
- return c.json({
61
- id: data.id,
62
- token
63
- }, 201);
64
- }
65
- const { token } = await new SessionModel(c).createSessionByUserId(data.id);
66
- return c.json({
67
- id: data.id,
68
- token
69
- }, 201);
70
- }
71
- });
1
+ import{z}from"zod";import{buildRoute}from"../../../lib/route.js";import{SessionModel}from"../../../models/session.js";import{SessionAdminModel}from"../../../models/session-admin.js";import{UserModel}from"../../../models/user.js";import{CONFIG_PLUGIN}from"../../../../config.js";export const zodSignInSchema=z.object({email:z.email().toLowerCase().openapi({example:"test@test.com"}),password:z.string().openapi({example:"Test123!"}),isAdmin:z.boolean().optional().openapi({example:false})});export const signInRoute=buildRoute({pluginId:CONFIG_PLUGIN.pluginId,route:{method:"post",description:"Sign in with email and password",path:"/sign_in",request:{body:{required:true,content:{"application/json":{schema:zodSignInSchema}}}},responses:{403:{description:"Access Denied"},201:{content:{"application/json":{schema:z.object({id:z.number(),token:z.string()})}},description:"User signed in"}}},handler:async c=>{const{password,isAdmin,email}=c.req.valid("json");const data=await new UserModel().signInWithPassword({password,email,c});if(isAdmin){const{token}=await new SessionAdminModel(c).createSessionByUserId(data.id);return c.json({id:data.id,token},201)}const{token}=await new SessionModel(c).createSessionByUserId(data.id);return c.json({id:data.id,token},201)}});
@@ -1,43 +1 @@
1
- import { z } from "@hono/zod-openapi";
2
- import { buildRoute } from "../../../lib/route.js";
3
- import { SessionModel } from "../../../models/session.js";
4
- import { SessionAdminModel } from "../../../models/session-admin.js";
5
- import { CONFIG_PLUGIN } from "../../../../config.js";
6
- export const signOutRoute = buildRoute({
7
- pluginId: CONFIG_PLUGIN.pluginId,
8
- route: {
9
- method: "delete",
10
- description: "Sign out the current admin",
11
- path: "/sign_out",
12
- request: {
13
- body: {
14
- content: {
15
- "application/json": {
16
- schema: z.object({
17
- isAdmin: z.boolean().optional().openapi({
18
- example: false
19
- })
20
- })
21
- }
22
- }
23
- }
24
- },
25
- responses: {
26
- 200: {
27
- description: "User signed out"
28
- },
29
- 403: {
30
- description: "Access Denied"
31
- }
32
- }
33
- },
34
- handler: async (c)=>{
35
- const { isAdmin } = c.req.valid("json");
36
- if (isAdmin) {
37
- await new SessionAdminModel(c).deleteSession();
38
- return c.json({});
39
- }
40
- await new SessionModel(c).deleteSession();
41
- return c.json({});
42
- }
43
- });
1
+ import{z}from"@hono/zod-openapi";import{buildRoute}from"../../../lib/route.js";import{SessionModel}from"../../../models/session.js";import{SessionAdminModel}from"../../../models/session-admin.js";import{CONFIG_PLUGIN}from"../../../../config.js";export const signOutRoute=buildRoute({pluginId:CONFIG_PLUGIN.pluginId,route:{method:"delete",description:"Sign out the current admin",path:"/sign_out",request:{body:{content:{"application/json":{schema:z.object({isAdmin:z.boolean().optional().openapi({example:false})})}}}},responses:{200:{description:"User signed out"},403:{description:"Access Denied"}}},handler:async c=>{const{isAdmin}=c.req.valid("json");if(isAdmin){await new SessionAdminModel(c).deleteSession();return c.json({})}await new SessionModel(c).deleteSession();return c.json({})}});
@@ -1,77 +1 @@
1
- import { z } from "zod";
2
- import { buildRoute } from "../../../lib/route.js";
3
- import { PasswordModel } from "../../../models/password.js";
4
- import { UserModel } from "../../../models/user.js";
5
- import { CONFIG_PLUGIN } from "../../../../config.js";
6
- import { SessionModel } from "../../../models/session.js";
7
- const nameRegex = /^(?!.* {2})[\p{L}\p{N}._@ -]*$/u;
8
- export const zodSignUpSchema = z.object({
9
- email: z.email().toLowerCase().openapi({
10
- example: "test@test.com"
11
- }),
12
- name: z.string().openapi({
13
- example: "test"
14
- }).min(3).refine((val)=>nameRegex.test(val), {
15
- message: "Invalid name"
16
- }),
17
- password: z.string().min(8).openapi({
18
- example: "Test123!"
19
- }),
20
- newsletter: z.boolean().default(false).optional()
21
- });
22
- export const signUpRoute = buildRoute({
23
- pluginId: CONFIG_PLUGIN.pluginId,
24
- route: {
25
- method: "post",
26
- description: "Create a new user",
27
- path: "/sign_up",
28
- withCaptcha: true,
29
- request: {
30
- body: {
31
- required: true,
32
- content: {
33
- "application/json": {
34
- schema: zodSignUpSchema
35
- }
36
- }
37
- }
38
- },
39
- responses: {
40
- 201: {
41
- content: {
42
- "application/json": {
43
- schema: z.object({
44
- id: z.number(),
45
- emailVerified: z.boolean(),
46
- email: z.email()
47
- })
48
- }
49
- },
50
- description: "User created"
51
- },
52
- 400: {
53
- description: "Bad Request"
54
- },
55
- 409: {
56
- description: "Email or name already exists"
57
- }
58
- }
59
- },
60
- handler: async (c)=>{
61
- const hashedPassword = await new PasswordModel().encryptPassword(c.req.valid("json").password);
62
- const data = await new UserModel().signUp({
63
- ...c.req.valid("json"),
64
- hashedPassword
65
- }, c);
66
- if (data.emailVerified) {
67
- await new SessionModel(c).createSessionByUserId(data.id);
68
- } else {
69
- // TODO: Send verification email
70
- }
71
- return c.json({
72
- id: data.id,
73
- emailVerified: data.emailVerified,
74
- email: data.email
75
- }, 201);
76
- }
77
- });
1
+ import{z}from"zod";import{buildRoute}from"../../../lib/route.js";import{PasswordModel}from"../../../models/password.js";import{UserModel}from"../../../models/user.js";import{CONFIG_PLUGIN}from"../../../../config.js";import{SessionModel}from"../../../models/session.js";const nameRegex=/^(?!.* {2})[\p{L}\p{N}._@ -]*$/u;export const zodSignUpSchema=z.object({email:z.email().toLowerCase().openapi({example:"test@test.com"}),name:z.string().openapi({example:"test"}).min(3).refine(val=>nameRegex.test(val),{message:"Invalid name"}),password:z.string().min(8).openapi({example:"Test123!"}),newsletter:z.boolean().default(false).optional()});export const signUpRoute=buildRoute({pluginId:CONFIG_PLUGIN.pluginId,route:{method:"post",description:"Create a new user",path:"/sign_up",withCaptcha:true,request:{body:{required:true,content:{"application/json":{schema:zodSignUpSchema}}}},responses:{201:{content:{"application/json":{schema:z.object({id:z.number(),emailVerified:z.boolean(),email:z.email()})}},description:"User created"},400:{description:"Bad Request"},409:{description:"Email or name already exists"}}},handler:async c=>{const hashedPassword=await new PasswordModel().encryptPassword(c.req.valid("json").password);const data=await new UserModel().signUp({...c.req.valid("json"),hashedPassword},c);if(data.emailVerified){await new SessionModel(c).createSessionByUserId(data.id)}else{}return c.json({id:data.id,emailVerified:data.emailVerified,email:data.email},201)}});
@@ -1,33 +1 @@
1
- import { z } from "zod";
2
- import { buildRoute } from "../../../lib/route.js";
3
- import { CONFIG_PLUGIN } from "../../../../config.js";
4
- export const testRoute = buildRoute({
5
- pluginId: CONFIG_PLUGIN.pluginId,
6
- route: {
7
- method: "post",
8
- description: "Test route",
9
- path: "/test",
10
- responses: {
11
- 200: {
12
- content: {
13
- "text/plain": {
14
- schema: z.string()
15
- }
16
- },
17
- description: "User"
18
- },
19
- 201: {
20
- content: {
21
- "text/plain": {
22
- schema: z.string()
23
- }
24
- },
25
- description: "User"
26
- }
27
- }
28
- },
29
- handler: async (c)=>{
30
- await c.get("log").warn("This is a test warn log");
31
- return c.text("test");
32
- }
33
- });
1
+ import{z}from"zod";import{buildRoute}from"../../../lib/route.js";import{CONFIG_PLUGIN}from"../../../../config.js";export const testRoute=buildRoute({pluginId:CONFIG_PLUGIN.pluginId,route:{method:"post",description:"Test route",path:"/test",responses:{200:{content:{"text/plain":{schema:z.string()}},description:"User"},201:{content:{"text/plain":{schema:z.string()}},description:"User"}}},handler:async c=>{await c.get("log").warn("This is a test warn log");return c.text("test")}});