@vitnode/core 1.2.0-canary.60 → 1.2.0-canary.62
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.
- package/dist/scripts/get-config.js +15 -0
- package/dist/scripts/plugin.js +188 -0
- package/dist/scripts/prepare-database.js +177 -0
- package/dist/scripts/prepare-plugins-files.js +134 -0
- package/dist/scripts/run-interactive-shell-command.js +21 -0
- package/dist/scripts/scripts.js +39 -13
- package/dist/scripts/shared/file-utils.js +203 -0
- package/dist/src/api/adapters/sso/discord.js +1 -77
- package/dist/src/api/adapters/sso/facebook.js +1 -76
- package/dist/src/api/adapters/sso/google.js +1 -87
- package/dist/src/api/config.js +1 -67
- package/dist/src/api/lib/check-plugin-id.js +1 -43
- package/dist/src/api/lib/cron.js +1 -22
- package/dist/src/api/lib/logger-middleware.js +1 -35
- package/dist/src/api/lib/module.js +1 -22
- package/dist/src/api/lib/plugin.js +1 -22
- package/dist/src/api/lib/route.js +1 -27
- package/dist/src/api/lib/with-pagination.js +1 -83
- package/dist/src/api/middlewares/captcha.middleware.js +1 -63
- package/dist/src/api/middlewares/cron-auth.middleware.js +1 -19
- package/dist/src/api/middlewares/global.middleware.js +1 -93
- package/dist/src/api/middlewares/rate-limiter.middleware.js +1 -32
- package/dist/src/api/models/device.js +1 -61
- package/dist/src/api/models/email.js +1 -76
- package/dist/src/api/models/password.js +1 -36
- package/dist/src/api/models/session-admin.js +1 -106
- package/dist/src/api/models/session.js +1 -85
- package/dist/src/api/models/sso.js +1 -120
- package/dist/src/api/models/user/get-user-by-id.js +1 -19
- package/dist/src/api/models/user/sign-in-with-passwords.js +1 -22
- package/dist/src/api/models/user/sign-up.js +1 -73
- package/dist/src/api/models/user.js +1 -8
- package/dist/src/api/modules/admin/admin.module.js +1 -19
- package/dist/src/api/modules/admin/advanced/advanced.admin.module.js +1 -11
- package/dist/src/api/modules/admin/advanced/cron/cron.admin.module.js +1 -12
- package/dist/src/api/modules/admin/advanced/cron/routes/get.route.js +1 -66
- package/dist/src/api/modules/admin/advanced/cron/routes/run.route.js +1 -95
- package/dist/src/api/modules/admin/debug/debug.admin.module.js +1 -10
- package/dist/src/api/modules/admin/debug/routes/logs.route.js +1 -94
- package/dist/src/api/modules/admin/routes/session.route.js +1 -47
- package/dist/src/api/modules/admin/users/routes/list.route.js +1 -79
- package/dist/src/api/modules/admin/users/routes/users.route.js +1 -84
- package/dist/src/api/modules/admin/users/users.admin.module.js +1 -10
- package/dist/src/api/modules/cron/cron/clean.cron.js +1 -24
- package/dist/src/api/modules/cron/cron.module.js +1 -14
- package/dist/src/api/modules/cron/helpers/process-cron-jobs.d.ts.map +1 -1
- package/dist/src/api/modules/cron/helpers/process-cron-jobs.js +1 -76
- package/dist/src/api/modules/cron/routes/cron.route.js +1 -101
- package/dist/src/api/modules/middleware/middleware.module.js +1 -10
- package/dist/src/api/modules/middleware/route.js +1 -49
- package/dist/src/api/modules/users/avatar-color.js +1 -43
- package/dist/src/api/modules/users/routes/change-password.route.js +1 -58
- package/dist/src/api/modules/users/routes/reset-passowrd.route.js +1 -91
- package/dist/src/api/modules/users/routes/session.route.js +1 -46
- package/dist/src/api/modules/users/routes/sign-in.route.js +1 -71
- package/dist/src/api/modules/users/routes/sign-out.route.js +1 -43
- package/dist/src/api/modules/users/routes/sign-up.route.js +1 -77
- package/dist/src/api/modules/users/routes/test.route.js +1 -33
- package/dist/src/api/modules/users/sso/routes/callback.route.js +1 -52
- package/dist/src/api/modules/users/sso/routes/create-url.route.js +1 -36
- package/dist/src/api/modules/users/sso/sso.module.js +1 -12
- package/dist/src/api/modules/users/users.module.js +1 -26
- package/dist/src/api/plugin.js +1 -15
- package/dist/src/app/login/page.js +1 -16
- package/dist/src/app/login/reset-password/page.js +1 -18
- package/dist/src/app/login/sso/[providerId]/page.js +1 -10
- package/dist/src/app/register/page.js +1 -16
- package/dist/src/app_admin/core/advanced/cron/page.js +1 -42
- package/dist/src/app_admin/core/debug/page.js +1 -45
- package/dist/src/app_admin/core/page.js +1 -5
- package/dist/src/app_admin/core/test/page.js +1 -5
- package/dist/src/app_admin/core/users/page.js +1 -38
- package/dist/src/components/avatar.js +1 -14
- package/dist/src/components/confirm-action/confirm-action-alert-dialog.js +1 -42
- package/dist/src/components/confirm-action/content.js +1 -31
- package/dist/src/components/date-format.js +1 -41
- package/dist/src/components/form/auto-form.js +1 -103
- package/dist/src/components/form/common/desc.js +1 -9
- package/dist/src/components/form/common/label.js +1 -18
- package/dist/src/components/form/fields/checkbox.js +1 -37
- package/dist/src/components/form/fields/combobox-async.js +1 -123
- package/dist/src/components/form/fields/combobox.js +1 -87
- package/dist/src/components/form/fields/input.js +1 -39
- package/dist/src/components/form/fields/radio-group.js +1 -50
- package/dist/src/components/form/fields/select.js +1 -58
- package/dist/src/components/form/fields/switch.js +1 -36
- package/dist/src/components/form/fields/textarea.js +1 -36
- package/dist/src/components/i18n-provider.js +1 -43
- package/dist/src/components/logo-vitnode.js +1 -119
- package/dist/src/components/switchers/langs/language-switcher.js +1 -47
- package/dist/src/components/switchers/themes/theme-switcher.js +1 -28
- package/dist/src/components/table/content.js +1 -81
- package/dist/src/components/table/data-table.js +1 -68
- package/dist/src/components/table/order-table-head.js +1 -50
- package/dist/src/components/table/pagination.js +1 -122
- package/dist/src/components/tiptap/extension.js +1 -33
- package/dist/src/components/tiptap/toolbar/actions/alignment-action.js +1 -91
- package/dist/src/components/tiptap/toolbar/actions/bold-action.js +1 -39
- package/dist/src/components/tiptap/toolbar/actions/headings-action.js +1 -93
- package/dist/src/components/tiptap/toolbar/actions/italic-action.js +1 -38
- package/dist/src/components/tiptap/toolbar/actions/list-action.js +1 -61
- package/dist/src/components/tiptap/toolbar/actions/text-format-more/text-format-more.js +1 -59
- package/dist/src/components/tiptap/toolbar/actions/underline-action.js +1 -38
- package/dist/src/components/tiptap/toolbar/actions/undo-redo-actions.js +1 -63
- package/dist/src/components/tiptap/toolbar/actions/utils/tooltip-shortcut.js +1 -11
- package/dist/src/components/tiptap/toolbar/tiptap-toolbar.js +1 -55
- package/dist/src/components/tiptap/toolbar/use-toolbar-editor.js +1 -5
- package/dist/src/components/ui/accordion.js +1 -46
- package/dist/src/components/ui/alert-dialog.js +1 -123
- package/dist/src/components/ui/alert.js +1 -39
- package/dist/src/components/ui/badge.js +1 -28
- package/dist/src/components/ui/button-client.js +1 -57
- package/dist/src/components/ui/button.js +1 -32
- package/dist/src/components/ui/card.js +1 -52
- package/dist/src/components/ui/checkbox.js +1 -20
- package/dist/src/components/ui/collapsible.js +1 -22
- package/dist/src/components/ui/command.js +1 -98
- package/dist/src/components/ui/context-menu.js +1 -140
- package/dist/src/components/ui/dialog.js +1 -189
- package/dist/src/components/ui/drawer.js +1 -83
- package/dist/src/components/ui/dropdown-menu.js +1 -141
- package/dist/src/components/ui/editor-content.js +1 -10
- package/dist/src/components/ui/editor.js +1 -35
- package/dist/src/components/ui/form.js +1 -148
- package/dist/src/components/ui/header-content.js +1 -30
- package/dist/src/components/ui/hover-card.js +1 -29
- package/dist/src/components/ui/input-otp.js +1 -48
- package/dist/src/components/ui/input.js +1 -11
- package/dist/src/components/ui/label.js +1 -12
- package/dist/src/components/ui/loader.js +1 -16
- package/dist/src/components/ui/menubar.js +1 -151
- package/dist/src/components/ui/navigation-menu.js +1 -82
- package/dist/src/components/ui/popover.js +1 -35
- package/dist/src/components/ui/progress.js +1 -19
- package/dist/src/components/ui/radio-group.js +1 -27
- package/dist/src/components/ui/scroll-area.js +1 -33
- package/dist/src/components/ui/select.js +1 -113
- package/dist/src/components/ui/separator.js +1 -14
- package/dist/src/components/ui/sheet.js +1 -92
- package/dist/src/components/ui/sidebar.js +1 -433
- package/dist/src/components/ui/skeleton.js +1 -10
- package/dist/src/components/ui/slider.js +1 -50
- package/dist/src/components/ui/sonner.js +1 -26
- package/dist/src/components/ui/switch.js +1 -16
- package/dist/src/components/ui/table.js +1 -63
- package/dist/src/components/ui/tabs.js +1 -33
- package/dist/src/components/ui/textarea.js +1 -10
- package/dist/src/components/ui/toggle-group.js +1 -45
- package/dist/src/components/ui/toggle.js +1 -34
- package/dist/src/components/ui/tooltip.js +1 -57
- package/dist/src/config.js +1 -4
- package/dist/src/database/admins.js +1 -74
- package/dist/src/database/cron.js +1 -22
- package/dist/src/database/languages.js +1 -52
- package/dist/src/database/logs.js +1 -34
- package/dist/src/database/moderators.js +1 -37
- package/dist/src/database/roles.js +1 -13
- package/dist/src/database/sessions.js +1 -60
- package/dist/src/database/users.js +1 -145
- package/dist/src/drizzle.config.js +1 -67
- package/dist/src/emails/default-template.js +1 -99
- package/dist/src/emails/reset-password.js +1 -132
- package/dist/src/emails/ui/button.js +1 -36
- package/dist/src/emails/ui/card.js +1 -39
- package/dist/src/hooks/use-before-unload.js +1 -30
- package/dist/src/hooks/use-captcha.js +1 -122
- package/dist/src/hooks/use-mobile.js +1 -16
- package/dist/src/lib/api/get-middleware-api.js +1 -13
- package/dist/src/lib/api/get-next-cron-run-date.js +1 -14
- package/dist/src/lib/api/get-next-cron-run-date.test.js +1 -55
- package/dist/src/lib/api/get-session-admin-api.js +1 -19
- package/dist/src/lib/api/get-session-api.js +1 -14
- package/dist/src/lib/api/should-cron-job-run.js +1 -16
- package/dist/src/lib/api/should-cron-job-run.test.js +1 -213
- package/dist/src/lib/api/validate-cron-schedule.d.ts +2 -0
- package/dist/src/lib/api/validate-cron-schedule.d.ts.map +1 -0
- package/dist/src/lib/api/validate-cron-schedule.js +1 -0
- package/dist/src/lib/api/validate-cron-schedule.test.d.ts +2 -0
- package/dist/src/lib/api/validate-cron-schedule.test.d.ts.map +1 -0
- package/dist/src/lib/api/validate-cron-schedule.test.js +1 -0
- package/dist/src/lib/colors.js +1 -140
- package/dist/src/lib/colors.test.js +1 -173
- package/dist/src/lib/config.js +1 -14
- package/dist/src/lib/ctrl-or-command-character.js +1 -5
- package/dist/src/lib/fetcher/cookie-from-string-to-object.js +1 -12
- package/dist/src/lib/fetcher/cookie-from-string-to-object.test.js +1 -78
- package/dist/src/lib/fetcher/core.js +3 -48
- package/dist/src/lib/fetcher/helpers-server.js +1 -18
- package/dist/src/lib/fetcher/helpers.js +1 -16
- package/dist/src/lib/fetcher/helpers.test.js +1 -37
- package/dist/src/lib/fetcher/types.js +1 -1
- package/dist/src/lib/fetcher-client.js +1 -17
- package/dist/src/lib/fetcher.js +1 -33
- package/dist/src/lib/helpers/auto-form.js +1 -98
- package/dist/src/lib/helpers/auto-form.test.js +1 -336
- package/dist/src/lib/navigation.js +1 -11
- package/dist/src/lib/plugin.js +1 -3
- package/dist/src/lib/special-characters.js +1 -4
- package/dist/src/lib/special-characters.test.js +1 -56
- package/dist/src/lib/utils.js +1 -5
- package/dist/src/locales/en.json +308 -0
- package/dist/src/tests/setup.js +1 -6
- package/dist/src/views/admin/layouts/admin-layout.js +1 -73
- package/dist/src/views/admin/layouts/sidebar/nav/item.js +1 -98
- package/dist/src/views/admin/layouts/sidebar/nav/nav.js +1 -60
- package/dist/src/views/admin/layouts/sidebar/sidebar.js +1 -28
- package/dist/src/views/admin/layouts/sidebar/sign-out.js +1 -14
- package/dist/src/views/admin/layouts/user-bar/client.js +1 -69
- package/dist/src/views/admin/layouts/user-bar/user-bar.js +1 -32
- package/dist/src/views/admin/sign-in/sign-in-admin-view.js +1 -27
- package/dist/src/views/admin/views/core/advanced/cron/cron-table-view.js +1 -97
- package/dist/src/views/admin/views/core/advanced/cron/run-action/mutation-api.js +1 -23
- package/dist/src/views/admin/views/core/advanced/cron/run-action/run-action.js +1 -38
- package/dist/src/views/admin/views/core/dashboard/dashboard-admin-view.js +1 -44
- package/dist/src/views/admin/views/core/debug/actions/clear-cache/clear-cache.js +1 -35
- package/dist/src/views/admin/views/core/debug/actions/clear-cache/mutation-api.js +1 -5
- package/dist/src/views/admin/views/core/debug/system-logs/actions/more/content.js +1 -281
- package/dist/src/views/admin/views/core/debug/system-logs/actions/more/more.js +1 -67
- package/dist/src/views/admin/views/core/debug/system-logs/badges/badge-status.js +1 -14
- package/dist/src/views/admin/views/core/debug/system-logs/badges/badge-type-log.js +1 -30
- package/dist/src/views/admin/views/core/debug/system-logs/system-logs-view.js +1 -96
- package/dist/src/views/admin/views/core/test.js +1 -161
- package/dist/src/views/admin/views/core/users/users-admin-view.js +1 -89
- package/dist/src/views/auth/password-reset/change-password-form/form.js +1 -48
- package/dist/src/views/auth/password-reset/change-password-form/mutation-api.js +1 -22
- package/dist/src/views/auth/password-reset/change-password-form/use-form.js +1 -36
- package/dist/src/views/auth/password-reset/form/form.js +1 -104
- package/dist/src/views/auth/password-reset/form/mutation-api.js +1 -21
- package/dist/src/views/auth/password-reset/form/use-form.js +1 -33
- package/dist/src/views/auth/password-reset/password-reset-view.js +1 -37
- package/dist/src/views/auth/sign-in/form/form.js +1 -64
- package/dist/src/views/auth/sign-in/form/mutation-api.js +1 -33
- package/dist/src/views/auth/sign-in/form/use-form.js +1 -38
- package/dist/src/views/auth/sign-in/sign-in-view.js +1 -61
- package/dist/src/views/auth/sign-up/components/password-input.js +1 -96
- package/dist/src/views/auth/sign-up/email-confirmation-view.js +1 -55
- package/dist/src/views/auth/sign-up/form/form.js +1 -89
- package/dist/src/views/auth/sign-up/form/mutation-api.js +1 -30
- package/dist/src/views/auth/sign-up/form/use-form.js +1 -70
- package/dist/src/views/auth/sign-up/sign-up-view.js +1 -65
- package/dist/src/views/auth/sign-up/wrapper.js +1 -22
- package/dist/src/views/auth/sso/buttons/client.js +1 -22
- package/dist/src/views/auth/sso/buttons/mutation-api.js +1 -24
- package/dist/src/views/auth/sso/buttons/sso-buttons.js +1 -56
- package/dist/src/views/auth/sso/callback/callback-sso-view.js +1 -32
- package/dist/src/views/auth/sso/callback/client/client.js +1 -68
- package/dist/src/views/auth/sso/callback/client/mutation-api.js +1 -32
- package/dist/src/views/error/back-button.js +1 -14
- package/dist/src/views/error/error-view.js +1 -58
- package/dist/src/views/error/global-error-view.js +1 -50
- package/dist/src/views/layouts/provider.js +1 -44
- package/dist/src/views/layouts/root-layout.js +1 -25
- package/dist/src/views/layouts/theme/header/header.js +1 -38
- package/dist/src/views/layouts/theme/header/user/auth/auth.js +1 -33
- package/dist/src/views/layouts/theme/header/user/auth/client.js +1 -47
- package/dist/src/views/layouts/theme/header/user/auth/log-out-mutation-api.js +1 -27
- package/dist/src/views/layouts/theme/header/user/user.js +1 -32
- package/dist/src/views/layouts/theme/layout.js +1 -16
- package/dist/src/vitnode.config.js +1 -42
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/tsup.config.js +18 -0
- package/dist/vitest.config.d.ts.map +1 -1
- package/dist/vitest.config.js +49 -0
- package/eslint.config.mjs +2 -0
- package/package.json +6 -10
- package/dist/src/api/adapters/cron/node-cron.adapter.d.ts +0 -3
- package/dist/src/api/adapters/cron/node-cron.adapter.d.ts.map +0 -1
- package/dist/src/api/adapters/cron/node-cron.adapter.js +0 -11
- package/dist/src/api/adapters/email/nodemailer.d.ts +0 -10
- package/dist/src/api/adapters/email/nodemailer.d.ts.map +0 -1
- package/dist/src/api/adapters/email/nodemailer.js +0 -30
- package/dist/src/api/adapters/email/resend.d.ts +0 -6
- package/dist/src/api/adapters/email/resend.d.ts.map +0 -1
- package/dist/src/api/adapters/email/resend.js +0 -21
|
@@ -1,101 +1 @@
|
|
|
1
|
-
import {
|
|
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
|
|
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
|
|
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
|
|
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 {
|
|
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 "
|
|
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
|
|
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
|
|
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
|
|
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 }
|
|
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
|
|
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")}});
|