studiocms 0.2.0 → 0.4.0
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/CHANGELOG.md +122 -0
- package/dist/cli/add/index.d.ts +2 -2
- package/dist/cli/add/index.js +4 -3
- package/dist/cli/add/npm-utils.d.ts +6 -6
- package/dist/cli/add/tryToInstallPlugins.d.ts +1 -1
- package/dist/cli/add/tryToInstallPlugins.js +6 -5
- package/dist/cli/add/updateStudioCMSConfig.d.ts +1 -1
- package/dist/cli/add/updateStudioCMSConfig.js +3 -4
- package/dist/cli/add/validatePlugins.d.ts +1 -2
- package/dist/cli/add/validatePlugins.js +15 -9
- package/dist/cli/crypto/genJWT/index.d.ts +1 -1
- package/dist/cli/crypto/genJWT/index.js +8 -9
- package/dist/cli/crypto/index.d.ts +1 -1
- package/dist/cli/init/steps/env.js +14 -4
- package/dist/cli/init/steps/next.d.ts +1 -1
- package/dist/cli/init/steps/next.js +6 -5
- package/dist/cli/migrator/index.d.ts +1 -1
- package/dist/cli/migrator/index.js +2 -2
- package/dist/cli/users/index.d.ts +1 -1
- package/dist/cli/users/shared.js +2 -2
- package/dist/cli/users/steps/createUsers.js +7 -7
- package/dist/cli/users/steps/modifyUsers.js +2 -2
- package/dist/cli/users/steps/next.d.ts +1 -1
- package/dist/cli/utils/checkRequiredEnvVars.js +2 -2
- package/dist/cli/utils/context.d.ts +2 -4
- package/dist/cli/utils/context.js +1 -3
- package/dist/cli/utils/getCliDbClient.d.ts +1 -1
- package/dist/cli/utils/intro.d.ts +1 -1
- package/dist/cli/utils/loadConfig.d.ts +54 -49
- package/dist/cli/utils/loadConfig.js +5 -8
- package/dist/cli/utils/logger.js +3 -3
- package/dist/cli/utils/user-utils.d.ts +1 -1
- package/dist/cli/utils/user-utils.js +4 -3
- package/dist/client/apiClient.d.ts +4923 -0
- package/dist/client/apiClient.js +72 -0
- package/dist/config.d.ts +1734 -1
- package/dist/consts.d.ts +5 -5
- package/dist/consts.js +3 -2
- package/dist/db/plugins.d.ts +1 -1
- package/dist/db/plugins.js +5 -8
- package/dist/handlers/frontend/routes.d.ts +4 -18
- package/dist/handlers/frontend/routes.js +13 -152
- package/dist/handlers/frontend/types.d.ts +1 -1
- package/dist/handlers/frontend/utils.js +0 -18
- package/dist/handlers/pluginHandler.d.ts +34 -257
- package/dist/handlers/pluginHandler.js +92 -46
- package/dist/handlers/routeHandler.js +32 -11
- package/dist/handlers/setupDbStudio.d.ts +3 -1
- package/dist/handlers/setupDbStudio.js +19 -10
- package/dist/handlers/storage-manager/core/effectify-astro-context.d.ts +25 -0
- package/dist/handlers/storage-manager/core/effectify-astro-context.js +78 -0
- package/dist/handlers/storage-manager/no-op.d.ts +2 -2
- package/dist/handlers/storage-manager/no-op.js +2 -3
- package/dist/index.d.ts +0 -1
- package/dist/index.js +10 -20
- package/dist/integrations/robots/index.d.ts +2 -2
- package/dist/integrations/robots/index.js +1 -3
- package/dist/integrations/robots/schema.d.ts +102 -273
- package/dist/integrations/robots/schema.js +220 -209
- package/dist/plugins/analytics/assets/schemas.d.ts +14 -9
- package/dist/plugins/analytics/assets/schemas.js +25 -17
- package/dist/plugins/analytics/db-client.d.ts +1 -1
- package/dist/plugins/analytics/index.d.ts +823 -3
- package/dist/plugins/analytics/index.js +4 -5
- package/dist/plugins/analytics/schemas.d.ts +54 -62
- package/dist/plugins/analytics/schemas.js +64 -13
- package/dist/plugins/analytics/table.d.ts +1 -1
- package/dist/plugins.d.ts +0 -1
- package/dist/schemas/config/api.d.ts +17 -0
- package/dist/schemas/config/api.js +14 -0
- package/dist/schemas/config/auth.d.ts +55 -59
- package/dist/schemas/config/auth.js +34 -11
- package/dist/schemas/config/dashboard.d.ts +43 -79
- package/dist/schemas/config/dashboard.js +43 -12
- package/dist/schemas/config/db.d.ts +15 -17
- package/dist/schemas/config/db.js +13 -5
- package/dist/schemas/config/developer.d.ts +33 -45
- package/dist/schemas/config/developer.js +22 -5
- package/dist/schemas/config/index.d.ts +398 -521
- package/dist/schemas/config/index.js +115 -57
- package/dist/schemas/config/sdk.d.ts +50 -196
- package/dist/schemas/config/sdk.js +61 -73
- package/dist/schemas/custom.d.ts +40 -0
- package/dist/schemas/custom.js +41 -0
- package/dist/schemas/external-schemas.d.ts +171 -0
- package/dist/schemas/external-schemas.js +179 -0
- package/dist/schemas/index.d.ts +2 -0
- package/dist/schemas/index.js +2 -0
- package/dist/schemas/plugins/i18n.d.ts +59 -39
- package/dist/schemas/plugins/i18n.js +42 -5
- package/dist/schemas/plugins/index.d.ts +7126 -10296
- package/dist/schemas/plugins/index.js +260 -276
- package/dist/schemas/plugins/shared.d.ts +1293 -3718
- package/dist/schemas/plugins/shared.js +320 -329
- package/dist/test-utils.d.ts +15 -4
- package/dist/test-utils.js +27 -11
- package/dist/toolbar/db-viewer/db-shared-types.d.ts +6 -6
- package/dist/toolbar/db-viewer/studio/connection.d.ts +8 -4
- package/dist/toolbar/db-viewer/studio/connection.js +2 -28
- package/dist/toolbar/db-viewer/studio/env/libsql.d.ts +7 -0
- package/dist/toolbar/db-viewer/studio/env/libsql.js +17 -0
- package/dist/toolbar/db-viewer/studio/env/mysql.d.ts +7 -0
- package/dist/toolbar/db-viewer/studio/env/mysql.js +23 -0
- package/dist/toolbar/db-viewer/studio/env/postgres.d.ts +7 -0
- package/dist/toolbar/db-viewer/studio/env/postgres.js +23 -0
- package/dist/toolbar/db-viewer/studio/index.js +20 -56
- package/dist/toolbar/db-viewer/studio/type.d.ts +1 -2
- package/dist/toolbar/db-viewer/studio/virtual-connection/libsql.d.ts +3 -0
- package/dist/toolbar/db-viewer/studio/virtual-connection/libsql.js +24 -0
- package/dist/toolbar/db-viewer/studio/virtual-connection/mysql.d.ts +3 -0
- package/dist/toolbar/db-viewer/studio/virtual-connection/mysql.js +9 -0
- package/dist/toolbar/db-viewer/studio/virtual-connection/postgres.d.ts +3 -0
- package/dist/toolbar/db-viewer/studio/virtual-connection/postgres.js +9 -0
- package/dist/toolbar/db-viewer/viewer.js +20 -21
- package/dist/types.d.ts +30 -0
- package/dist/utils/effects/smtp.d.ts +1 -1
- package/dist/utils/lang-helper.d.ts +10 -2
- package/dist/virtual.d.ts +35 -28
- package/dist/virtuals/auth/core.d.ts +5 -5
- package/dist/virtuals/auth/verify-email.d.ts +6 -6
- package/dist/virtuals/components/Generator.astro +2 -2
- package/dist/virtuals/components/Renderer.astro +9 -1
- package/dist/virtuals/components/renderFn.d.ts +3 -1
- package/dist/virtuals/components/renderFn.js +18 -0
- package/dist/virtuals/lib/headDefaults.d.ts +4 -2
- package/dist/virtuals/lib/headDefaults.js +0 -2
- package/dist/virtuals/lib/routeMap.d.ts +0 -12
- package/dist/virtuals/lib/routeMap.js +2 -14
- package/dist/virtuals/mailer/index.d.ts +3 -3
- package/dist/virtuals/notifier/index.d.ts +5 -5
- package/dist/virtuals/plugins/dashboard-pages.d.ts +2 -64
- package/dist/virtuals/scripts/StorageFileBrowser.d.ts +1 -172
- package/dist/virtuals/scripts/StorageFileBrowser.js +216 -119
- package/dist/virtuals/template-engine/index.d.ts +4 -4
- package/frontend/components/dashboard/configuration/ConfigForm.astro +218 -110
- package/frontend/components/dashboard/content-mgmt/ContentSearch.astro +21 -22
- package/frontend/components/dashboard/content-mgmt/CreateFolder.astro +66 -54
- package/frontend/components/dashboard/content-mgmt/CreatePage.astro +58 -104
- package/frontend/components/dashboard/content-mgmt/EditFolder.astro +65 -67
- package/frontend/components/dashboard/content-mgmt/EditPage.astro +86 -134
- package/frontend/components/dashboard/content-mgmt/InnerSidebarElement.astro +0 -1
- package/frontend/components/dashboard/content-mgmt/PageHeader.astro +33 -52
- package/frontend/components/dashboard/content-mgmt/PageTypeHandler.astro +2 -2
- package/frontend/components/dashboard/profile/APITokens.astro +219 -158
- package/frontend/components/dashboard/profile/BasicInfo.astro +165 -106
- package/frontend/components/dashboard/profile/Notifications.astro +27 -18
- package/frontend/components/dashboard/profile/UpdatePassword.astro +134 -94
- package/frontend/components/dashboard/sidebar/VersionCheck.astro +31 -16
- package/frontend/components/dashboard/sidebar/VersionCheckChangelog.astro +18 -11
- package/frontend/components/dashboard/sidebar-modals/VersionModal.astro +2 -2
- package/frontend/components/dashboard/smtp-config/TemplateEditor.astro +14 -14
- package/frontend/components/dashboard/taxonomy/InnerSidebarElement.astro +0 -1
- package/frontend/components/dashboard/taxonomy/MetaContainer.astro +0 -2
- package/frontend/components/dashboard/taxonomy/PageHeader.astro +16 -24
- package/frontend/components/dashboard/taxonomy/TaxonomySearch.astro +23 -27
- package/frontend/components/dashboard/user-mgmt/InnerSidebarElement.astro +111 -104
- package/frontend/components/dashboard/user-mgmt/UserListItem.astro +9 -22
- package/frontend/components/dashboard/user-mgmt/UserListItems.astro +18 -0
- package/frontend/components/first-time-setup/snippets/{opt2-studiocms.config.diff → studiocms.config.diff} +1 -0
- package/frontend/components/shared/Code.astro +1 -4
- package/frontend/components/shared/DynamicSettingsRenderer.astro +1 -1
- package/frontend/components/shared/SSRUser.astro +2 -4
- package/frontend/components/shared/foldertree/FolderTreeNode.astro +0 -6
- package/frontend/components/shared/storage-manager/StorageCopyOutput.astro +0 -1
- package/frontend/components/shared/taxonomy/TaxonomyTreeNode.astro +0 -6
- package/frontend/layouts/DashboardLayout.astro +1 -10
- package/frontend/layouts/TaxonomyLayout.astro +0 -1
- package/frontend/middleware/index.ts +102 -61
- package/frontend/pages/404.astro +5 -9
- package/frontend/pages/[dashboard]/[...pluginPage].astro +10 -1
- package/frontend/pages/[dashboard]/configuration.astro +10 -1
- package/frontend/pages/[dashboard]/content-management/createfolder.astro +10 -1
- package/frontend/pages/[dashboard]/content-management/createpage.astro +10 -1
- package/frontend/pages/[dashboard]/content-management/diff.astro +39 -14
- package/frontend/pages/[dashboard]/content-management/editfolder.astro +10 -1
- package/frontend/pages/[dashboard]/content-management/editpage.astro +10 -1
- package/frontend/pages/[dashboard]/content-management/index.astro +10 -1
- package/frontend/pages/[dashboard]/index.astro +10 -1
- package/frontend/pages/[dashboard]/login.astro +86 -25
- package/frontend/pages/[dashboard]/password-reset.astro +22 -16
- package/frontend/pages/[dashboard]/plugins/[plugin].astro +10 -1
- package/frontend/pages/[dashboard]/profile.astro +10 -1
- package/frontend/pages/[dashboard]/signup.astro +153 -52
- package/frontend/pages/[dashboard]/smtp-configuration.astro +77 -75
- package/frontend/pages/[dashboard]/system-management.astro +10 -1
- package/frontend/pages/[dashboard]/taxonomy/categories.astro +30 -41
- package/frontend/pages/[dashboard]/taxonomy/index.astro +10 -0
- package/frontend/pages/[dashboard]/taxonomy/tags.astro +33 -43
- package/frontend/pages/[dashboard]/unverified-email.astro +29 -21
- package/frontend/pages/[dashboard]/user-management/edit.astro +170 -90
- package/frontend/pages/[dashboard]/user-management/index.astro +10 -1
- package/frontend/pages/studiocms_api/[...all].ts +106 -0
- package/frontend/pages/studiocms_api/_handlers/_utils/auth.ts +26 -0
- package/frontend/pages/studiocms_api/_handlers/_utils/changelog.ts +147 -0
- package/frontend/pages/studiocms_api/_handlers/_utils/db-studio-driver.ts +46 -0
- package/frontend/pages/studiocms_api/_handlers/_utils/parseLogLevel.ts +27 -0
- package/frontend/pages/studiocms_api/_handlers/auth/auth.ts +459 -0
- package/frontend/pages/studiocms_api/_handlers/auth/index.ts +17 -0
- package/frontend/pages/studiocms_api/_handlers/auth/oauth.ts +91 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/_shared.ts +57 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/apiTokens.ts +134 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/config.ts +64 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/content.ts +741 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/create.ts +480 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/emailNotifications.ts +49 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/index.ts +45 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/mailer.ts +136 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/plugins.ts +80 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/profile.ts +275 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/resetPassword.ts +140 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/search.ts +63 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/taxonomy.ts +285 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/templates.ts +75 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/users.ts +312 -0
- package/frontend/pages/studiocms_api/_handlers/dashboard/verifyEndpoints.ts +307 -0
- package/frontend/pages/studiocms_api/_handlers/integration/dbStudio.ts +98 -0
- package/frontend/pages/studiocms_api/_handlers/integration/index.ts +17 -0
- package/frontend/pages/studiocms_api/_handlers/integration/storageManager.ts +107 -0
- package/frontend/pages/studiocms_api/_handlers/rest-api/index.ts +8 -0
- package/frontend/pages/studiocms_api/_handlers/rest-api/v1/_shared.ts +41 -0
- package/frontend/pages/studiocms_api/_handlers/rest-api/v1/index.ts +17 -0
- package/frontend/pages/studiocms_api/_handlers/rest-api/v1/public.ts +195 -0
- package/frontend/pages/studiocms_api/_handlers/rest-api/v1/secure.ts +1726 -0
- package/frontend/pages/studiocms_api/_handlers/sdk.ts +129 -0
- package/frontend/pages/studiocms_api/_middleware/astroLocals.ts +36 -0
- package/frontend/pages/studiocms_api/_middleware/restApi.ts +56 -0
- package/frontend/pages/studiocms_api/integrations/[...all].ts +8 -0
- package/frontend/scripts/formdata.ts +219 -0
- package/frontend/setup-pages/3-done.astro +4 -20
- package/frontend/setup-pages/studiocms_api/dashboard/step-2.ts +3 -6
- package/frontend/styles/dashboard-base.css +0 -1
- package/frontend/web-vitals/endpoint.ts +2 -1
- package/package.json +35 -31
- package/dist/global.d.ts +0 -9
- package/frontend/components/dashboard/LoginChecker.astro +0 -68
- package/frontend/components/dashboard/user-mgmt/RankCheck.astro +0 -57
- package/frontend/components/first-time-setup/snippets/opt1-astro.config.diff +0 -14
- package/frontend/components/first-time-setup/snippets/opt2-astro.config.diff +0 -9
- package/frontend/middleware/_authmap.ts +0 -63
- package/frontend/pages/studiocms_api/auth/[path].ts +0 -390
- package/frontend/pages/studiocms_api/auth/[provider]/[...id].ts +0 -64
- package/frontend/pages/studiocms_api/auth/[provider]/_effects/index.ts +0 -101
- package/frontend/pages/studiocms_api/auth/_shared.ts +0 -52
- package/frontend/pages/studiocms_api/dashboard/api-tokens.ts +0 -115
- package/frontend/pages/studiocms_api/dashboard/config.ts +0 -74
- package/frontend/pages/studiocms_api/dashboard/content/diff.ts +0 -73
- package/frontend/pages/studiocms_api/dashboard/content/folder.ts +0 -220
- package/frontend/pages/studiocms_api/dashboard/content/page.ts +0 -359
- package/frontend/pages/studiocms_api/dashboard/create-reset-link.ts +0 -77
- package/frontend/pages/studiocms_api/dashboard/create-user-invite.ts +0 -231
- package/frontend/pages/studiocms_api/dashboard/create-user.ts +0 -186
- package/frontend/pages/studiocms_api/dashboard/email-notification-settings-site.ts +0 -74
- package/frontend/pages/studiocms_api/dashboard/mailer/check-email.ts +0 -75
- package/frontend/pages/studiocms_api/dashboard/mailer/config.ts +0 -136
- package/frontend/pages/studiocms_api/dashboard/plugins/[plugin].ts +0 -80
- package/frontend/pages/studiocms_api/dashboard/profile.ts +0 -245
- package/frontend/pages/studiocms_api/dashboard/resend-verify-email.ts +0 -77
- package/frontend/pages/studiocms_api/dashboard/reset-password.ts +0 -124
- package/frontend/pages/studiocms_api/dashboard/search-list.ts +0 -59
- package/frontend/pages/studiocms_api/dashboard/taxonomy-search.ts +0 -47
- package/frontend/pages/studiocms_api/dashboard/taxonomy.ts +0 -230
- package/frontend/pages/studiocms_api/dashboard/templates.ts +0 -74
- package/frontend/pages/studiocms_api/dashboard/update-user-notifications.ts +0 -86
- package/frontend/pages/studiocms_api/dashboard/users.ts +0 -236
- package/frontend/pages/studiocms_api/dashboard/verify-email.ts +0 -83
- package/frontend/pages/studiocms_api/dashboard/verify-session.ts +0 -187
- package/frontend/pages/studiocms_api/integrations/[type]/[...id].ts +0 -15
- package/frontend/pages/studiocms_api/integrations/[type]/_routes/db-studio.ts +0 -173
- package/frontend/pages/studiocms_api/integrations/[type]/_routes/storage.ts +0 -88
- package/frontend/pages/studiocms_api/partials/editor.astro +0 -74
- package/frontend/pages/studiocms_api/partials/render.astro +0 -39
- package/frontend/pages/studiocms_api/partials/user-list-items.astro +0 -43
- package/frontend/pages/studiocms_api/rest/utils/auth-token.ts +0 -59
- package/frontend/pages/studiocms_api/rest/v1/[type]/[...id].ts +0 -23
- package/frontend/pages/studiocms_api/rest/v1/[type]/_routes/categories.ts +0 -267
- package/frontend/pages/studiocms_api/rest/v1/[type]/_routes/folders.ts +0 -283
- package/frontend/pages/studiocms_api/rest/v1/[type]/_routes/pages.ts +0 -505
- package/frontend/pages/studiocms_api/rest/v1/[type]/_routes/settings.ts +0 -100
- package/frontend/pages/studiocms_api/rest/v1/[type]/_routes/tags.ts +0 -229
- package/frontend/pages/studiocms_api/rest/v1/[type]/_routes/users.ts +0 -553
- package/frontend/pages/studiocms_api/rest/v1/public/[type]/[...id].ts +0 -19
- package/frontend/pages/studiocms_api/rest/v1/public/[type]/_routes/categories.ts +0 -74
- package/frontend/pages/studiocms_api/rest/v1/public/[type]/_routes/folders.ts +0 -85
- package/frontend/pages/studiocms_api/rest/v1/public/[type]/_routes/pages.ts +0 -103
- package/frontend/pages/studiocms_api/rest/v1/public/[type]/_routes/tags.ts +0 -67
- package/frontend/pages/studiocms_api/sdk/[...path].ts +0 -97
- package/frontend/pages/studiocms_api/sdk/utils/changelog.ts +0 -119
- package/frontend/scripts/auth/formListener.ts +0 -81
- package/frontend/scripts/formdata-utils.ts +0 -116
- package/frontend/utils/build-partial-schema.ts +0 -46
- package/frontend/utils/errors.ts +0 -6
- package/frontend/utils/param-extractor.ts +0 -83
- package/frontend/utils/rest-router.ts +0 -444
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
import { Password, User } from 'studiocms:auth/lib';
|
|
2
|
-
import { apiResponseLogger } from 'studiocms:logger';
|
|
3
|
-
import { Notifications } from 'studiocms:notifier';
|
|
4
|
-
import { SDKCore } from 'studiocms:sdk';
|
|
5
|
-
import { type AvailablePermissionRanks, UserPermissionLevel } from '@withstudiocms/auth-kit/types';
|
|
6
|
-
import {
|
|
7
|
-
AllResponse,
|
|
8
|
-
createEffectAPIRoutes,
|
|
9
|
-
createJsonResponse,
|
|
10
|
-
Effect,
|
|
11
|
-
genLogger,
|
|
12
|
-
OptionsResponse,
|
|
13
|
-
readAPIContextJson,
|
|
14
|
-
} from '@withstudiocms/effect';
|
|
15
|
-
import { z } from 'astro/zod';
|
|
16
|
-
import { ValidRanks } from '#consts';
|
|
17
|
-
|
|
18
|
-
type JSONData = {
|
|
19
|
-
username: string | undefined;
|
|
20
|
-
password: string | undefined;
|
|
21
|
-
email: string | undefined;
|
|
22
|
-
displayname: string | undefined;
|
|
23
|
-
rank: AvailablePermissionRanks | undefined;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export const { POST, OPTIONS, ALL } = createEffectAPIRoutes(
|
|
27
|
-
{
|
|
28
|
-
POST: (ctx) =>
|
|
29
|
-
genLogger('studiocms/routes/api/dashboard/create-user.POST')(function* () {
|
|
30
|
-
const [pass, userHelper, notify, sdk] = yield* Effect.all([
|
|
31
|
-
Password,
|
|
32
|
-
User,
|
|
33
|
-
Notifications,
|
|
34
|
-
SDKCore,
|
|
35
|
-
]);
|
|
36
|
-
|
|
37
|
-
// Get user data
|
|
38
|
-
const userData = ctx.locals.StudioCMS.security?.userSessionData;
|
|
39
|
-
|
|
40
|
-
// Check if user is logged in
|
|
41
|
-
if (!userData?.isLoggedIn) {
|
|
42
|
-
return apiResponseLogger(403, 'Unauthorized');
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// Check if user has permission
|
|
46
|
-
const isAuthorized = ctx.locals.StudioCMS.security?.userPermissionLevel.isAdmin;
|
|
47
|
-
if (!isAuthorized) {
|
|
48
|
-
return apiResponseLogger(403, 'Unauthorized');
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
let { username, password, email, displayname, rank } =
|
|
52
|
-
yield* readAPIContextJson<JSONData>(ctx);
|
|
53
|
-
|
|
54
|
-
// If the username, password, email, or display name is missing, return an error
|
|
55
|
-
if (!username) {
|
|
56
|
-
return apiResponseLogger(400, 'Missing field: Username is required');
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (!password) {
|
|
60
|
-
password = yield* sdk.UTIL.Generators.generateRandomPassword(12);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (!email) {
|
|
64
|
-
return apiResponseLogger(400, 'Missing field: Email is required');
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (!displayname) {
|
|
68
|
-
return apiResponseLogger(400, 'Missing field: Display name is required');
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (!rank) {
|
|
72
|
-
return apiResponseLogger(400, 'Missing field: Rank is required');
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Validate target rank and ensure caller has sufficient privilege
|
|
76
|
-
if (!ValidRanks.has(rank) || rank === 'unknown') {
|
|
77
|
-
return apiResponseLogger(400, 'Invalid rank');
|
|
78
|
-
}
|
|
79
|
-
const callerPerm = yield* userHelper.getUserPermissionLevel(userData);
|
|
80
|
-
const rankToPerm = (r: typeof rank) => {
|
|
81
|
-
switch (r) {
|
|
82
|
-
case 'owner':
|
|
83
|
-
return UserPermissionLevel.owner;
|
|
84
|
-
case 'admin':
|
|
85
|
-
return UserPermissionLevel.admin;
|
|
86
|
-
case 'editor':
|
|
87
|
-
return UserPermissionLevel.editor;
|
|
88
|
-
case 'visitor':
|
|
89
|
-
return UserPermissionLevel.visitor;
|
|
90
|
-
default:
|
|
91
|
-
return UserPermissionLevel.unknown;
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
const targetPerm = rankToPerm(rank);
|
|
95
|
-
// Use explicit weights to avoid relying on enum ordinal
|
|
96
|
-
const permWeight = (lvl: UserPermissionLevel) => {
|
|
97
|
-
switch (lvl) {
|
|
98
|
-
case UserPermissionLevel.owner:
|
|
99
|
-
return 4;
|
|
100
|
-
case UserPermissionLevel.admin:
|
|
101
|
-
return 3;
|
|
102
|
-
case UserPermissionLevel.editor:
|
|
103
|
-
return 2;
|
|
104
|
-
case UserPermissionLevel.visitor:
|
|
105
|
-
return 1;
|
|
106
|
-
default:
|
|
107
|
-
return 0;
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
// Only owners can assign 'owner'
|
|
112
|
-
if (rank === 'owner' && callerPerm !== UserPermissionLevel.owner) {
|
|
113
|
-
return createJsonResponse({ error: 'Forbidden' }, { status: 403 });
|
|
114
|
-
}
|
|
115
|
-
// Allow equality for owner→owner; otherwise require caller >= target
|
|
116
|
-
if (permWeight(callerPerm) < permWeight(targetPerm)) {
|
|
117
|
-
return createJsonResponse({ error: 'Forbidden' }, { status: 403 });
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// If the email is invalid, return an error
|
|
121
|
-
const checkEmail = z.coerce
|
|
122
|
-
.string()
|
|
123
|
-
.email({ message: 'Email address is invalid' })
|
|
124
|
-
.safeParse(email);
|
|
125
|
-
|
|
126
|
-
if (!checkEmail.success) {
|
|
127
|
-
return apiResponseLogger(400, `Invalid email: ${checkEmail.error.message}`);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const [verifyUsernameResponse, verifyPasswordResponse, { usernameSearch, emailSearch }] =
|
|
131
|
-
yield* Effect.all([
|
|
132
|
-
userHelper.verifyUsernameInput(username),
|
|
133
|
-
pass.verifyPasswordStrength(password),
|
|
134
|
-
sdk.AUTH.user.searchUsersForUsernameOrEmail(username, checkEmail.data),
|
|
135
|
-
]);
|
|
136
|
-
|
|
137
|
-
// If the username is invalid, return an error
|
|
138
|
-
if (verifyUsernameResponse !== true) {
|
|
139
|
-
return apiResponseLogger(400, verifyUsernameResponse);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// If the password is invalid, return an error
|
|
143
|
-
if (verifyPasswordResponse !== true) {
|
|
144
|
-
return apiResponseLogger(400, verifyPasswordResponse);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (usernameSearch.length > 0) {
|
|
148
|
-
return apiResponseLogger(400, 'Invalid username: Username is already in use');
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
if (emailSearch.length > 0) {
|
|
152
|
-
return apiResponseLogger(400, 'Invalid email: Email is already in use');
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// Create a new user
|
|
156
|
-
yield* userHelper.createLocalUser(displayname, username, email, password).pipe(
|
|
157
|
-
Effect.flatMap((newUser) =>
|
|
158
|
-
sdk.UPDATE.permissions({
|
|
159
|
-
user: newUser.id,
|
|
160
|
-
rank: rank,
|
|
161
|
-
})
|
|
162
|
-
),
|
|
163
|
-
Effect.tap(() => notify.sendAdminNotification('new_user', username))
|
|
164
|
-
);
|
|
165
|
-
|
|
166
|
-
return apiResponseLogger(
|
|
167
|
-
200,
|
|
168
|
-
JSON.stringify({ username, email, displayname, rank: rank, password })
|
|
169
|
-
);
|
|
170
|
-
}).pipe(Notifications.Provide),
|
|
171
|
-
OPTIONS: () => Effect.try(() => OptionsResponse({ allowedMethods: ['POST'] })),
|
|
172
|
-
ALL: () => Effect.try(() => AllResponse()),
|
|
173
|
-
},
|
|
174
|
-
{
|
|
175
|
-
cors: { methods: ['POST', 'OPTIONS'] },
|
|
176
|
-
onError: (error) => {
|
|
177
|
-
console.error('API Error:', error);
|
|
178
|
-
return createJsonResponse(
|
|
179
|
-
{ error: 'Internal Server Error' },
|
|
180
|
-
{
|
|
181
|
-
status: 500,
|
|
182
|
-
}
|
|
183
|
-
);
|
|
184
|
-
},
|
|
185
|
-
}
|
|
186
|
-
);
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { apiResponseLogger } from 'studiocms:logger';
|
|
2
|
-
import { SDKCore } from 'studiocms:sdk';
|
|
3
|
-
import type { ConfigFinal, StudioCMSNotificationSettings } from 'studiocms:sdk/types';
|
|
4
|
-
import {
|
|
5
|
-
AllResponse,
|
|
6
|
-
createEffectAPIRoutes,
|
|
7
|
-
createJsonResponse,
|
|
8
|
-
Effect,
|
|
9
|
-
genLogger,
|
|
10
|
-
OptionsResponse,
|
|
11
|
-
readAPIContextJson,
|
|
12
|
-
} from '@withstudiocms/effect';
|
|
13
|
-
|
|
14
|
-
export const { POST, OPTIONS, ALL } = createEffectAPIRoutes(
|
|
15
|
-
{
|
|
16
|
-
POST: (ctx) =>
|
|
17
|
-
genLogger('studiocms/routes/api/dashboard/email-notification-settings-site.POST')(
|
|
18
|
-
function* () {
|
|
19
|
-
const sdk = yield* SDKCore;
|
|
20
|
-
|
|
21
|
-
// Get user data
|
|
22
|
-
const userData = ctx.locals.StudioCMS.security?.userSessionData;
|
|
23
|
-
|
|
24
|
-
// Check if user is logged in
|
|
25
|
-
if (!userData?.isLoggedIn) {
|
|
26
|
-
return apiResponseLogger(403, 'Unauthorized');
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// Check if user has permission
|
|
30
|
-
const isAuthorized = ctx.locals.StudioCMS.security?.userPermissionLevel.isOwner;
|
|
31
|
-
if (!isAuthorized) {
|
|
32
|
-
return apiResponseLogger(403, 'Unauthorized');
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
yield* readAPIContextJson<unknown>(ctx).pipe(
|
|
36
|
-
Effect.map((raw) => {
|
|
37
|
-
const rawData = (raw ?? {}) as Record<string, unknown>;
|
|
38
|
-
const safe = {
|
|
39
|
-
emailVerification:
|
|
40
|
-
typeof rawData.emailVerification === 'boolean'
|
|
41
|
-
? rawData.emailVerification
|
|
42
|
-
: undefined,
|
|
43
|
-
requireAdminVerification:
|
|
44
|
-
typeof rawData.requireAdminVerification === 'boolean'
|
|
45
|
-
? rawData.requireAdminVerification
|
|
46
|
-
: undefined,
|
|
47
|
-
requireEditorVerification:
|
|
48
|
-
typeof rawData.requireEditorVerification === 'boolean'
|
|
49
|
-
? rawData.requireEditorVerification
|
|
50
|
-
: undefined,
|
|
51
|
-
oAuthBypassVerification:
|
|
52
|
-
typeof rawData.oAuthBypassVerification === 'boolean'
|
|
53
|
-
? rawData.oAuthBypassVerification
|
|
54
|
-
: undefined,
|
|
55
|
-
} as ConfigFinal<StudioCMSNotificationSettings>;
|
|
56
|
-
return safe;
|
|
57
|
-
}),
|
|
58
|
-
Effect.flatMap((data) => sdk.notificationSettings.site.update(data))
|
|
59
|
-
);
|
|
60
|
-
|
|
61
|
-
return apiResponseLogger(200, 'Notification settings updated');
|
|
62
|
-
}
|
|
63
|
-
),
|
|
64
|
-
OPTIONS: () => Effect.try(() => OptionsResponse({ allowedMethods: ['POST'] })),
|
|
65
|
-
ALL: () => Effect.try(() => AllResponse()),
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
cors: { methods: ['POST', 'OPTIONS'] },
|
|
69
|
-
onError: (error) => {
|
|
70
|
-
console.error('API Error:', error);
|
|
71
|
-
return createJsonResponse({ error: 'Internal Server Error' }, { status: 500 });
|
|
72
|
-
},
|
|
73
|
-
}
|
|
74
|
-
);
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { apiResponseLogger } from 'studiocms:logger';
|
|
2
|
-
import { Mailer } from 'studiocms:mailer';
|
|
3
|
-
import {
|
|
4
|
-
AllResponse,
|
|
5
|
-
createEffectAPIRoutes,
|
|
6
|
-
createJsonResponse,
|
|
7
|
-
Effect,
|
|
8
|
-
genLogger,
|
|
9
|
-
OptionsResponse,
|
|
10
|
-
readAPIContextJson,
|
|
11
|
-
} from '@withstudiocms/effect';
|
|
12
|
-
|
|
13
|
-
export const { POST, OPTIONS, ALL } = createEffectAPIRoutes(
|
|
14
|
-
{
|
|
15
|
-
POST: (ctx) =>
|
|
16
|
-
genLogger('routes/mailer/test-email/POST')(function* () {
|
|
17
|
-
const mailer = yield* Mailer;
|
|
18
|
-
|
|
19
|
-
// Check if mailer is enabled
|
|
20
|
-
if (!ctx.locals.StudioCMS.siteConfig.data.enableMailer) {
|
|
21
|
-
return apiResponseLogger(403, 'Mailer is disabled for this site');
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// Check if user is logged in
|
|
25
|
-
if (!ctx.locals.StudioCMS.security?.userSessionData.isLoggedIn) {
|
|
26
|
-
return apiResponseLogger(403, 'Unauthorized');
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// Check if user has permission
|
|
30
|
-
if (!ctx.locals.StudioCMS.security?.userPermissionLevel.isOwner) {
|
|
31
|
-
return apiResponseLogger(403, 'Unauthorized');
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Get JSON data safely
|
|
35
|
-
let test_email: unknown;
|
|
36
|
-
try {
|
|
37
|
-
({ test_email } = yield* readAPIContextJson<{ test_email?: unknown }>(ctx));
|
|
38
|
-
} catch {
|
|
39
|
-
return apiResponseLogger(400, 'Invalid JSON body');
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Validate form data
|
|
43
|
-
if (typeof test_email !== 'string' || test_email.trim() === '') {
|
|
44
|
-
return apiResponseLogger(400, 'Invalid form data, test_email is required');
|
|
45
|
-
}
|
|
46
|
-
const email = test_email.trim();
|
|
47
|
-
// Basic email sanity-check
|
|
48
|
-
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
|
|
49
|
-
return apiResponseLogger(400, 'Invalid email address');
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Send Test Email
|
|
53
|
-
const response = yield* mailer.sendMail({
|
|
54
|
-
to: test_email,
|
|
55
|
-
subject: 'StudioCMS Test Email',
|
|
56
|
-
text: 'This is a test email from StudioCMS.',
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
if ('error' in response) {
|
|
60
|
-
console.error('Mailer test-email failed:', response.error);
|
|
61
|
-
return apiResponseLogger(500, 'Failed to send test email');
|
|
62
|
-
}
|
|
63
|
-
return apiResponseLogger(200, 'Test email sent');
|
|
64
|
-
}).pipe(Mailer.Provide),
|
|
65
|
-
OPTIONS: () => Effect.try(() => OptionsResponse({ allowedMethods: ['POST'] })),
|
|
66
|
-
ALL: () => Effect.try(() => AllResponse()),
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
cors: { methods: ['POST', 'OPTIONS'] },
|
|
70
|
-
onError: (error) => {
|
|
71
|
-
console.error('API Error:', error);
|
|
72
|
-
return createJsonResponse({ error: 'Internal Server Error' }, { status: 500 });
|
|
73
|
-
},
|
|
74
|
-
}
|
|
75
|
-
);
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
import { apiResponseLogger } from 'studiocms:logger';
|
|
2
|
-
import { Mailer } from 'studiocms:mailer';
|
|
3
|
-
import {
|
|
4
|
-
AllResponse,
|
|
5
|
-
createEffectAPIRoutes,
|
|
6
|
-
createJsonResponse,
|
|
7
|
-
Effect,
|
|
8
|
-
genLogger,
|
|
9
|
-
OptionsResponse,
|
|
10
|
-
parseAPIContextJson,
|
|
11
|
-
Schema,
|
|
12
|
-
} from '@withstudiocms/effect';
|
|
13
|
-
|
|
14
|
-
export class SmtpConfigSchema extends Schema.Class<SmtpConfigSchema>('SmtpConfigSchema')({
|
|
15
|
-
port: Schema.Number,
|
|
16
|
-
host: Schema.String,
|
|
17
|
-
secure: Schema.Boolean,
|
|
18
|
-
proxy: Schema.Union(Schema.String, Schema.Null),
|
|
19
|
-
auth_user: Schema.Union(Schema.String, Schema.Null),
|
|
20
|
-
auth_pass: Schema.Union(Schema.String, Schema.Null),
|
|
21
|
-
tls_rejectUnauthorized: Schema.Union(Schema.Boolean, Schema.Null),
|
|
22
|
-
tls_servername: Schema.Union(Schema.String, Schema.Null),
|
|
23
|
-
default_sender: Schema.String,
|
|
24
|
-
}) {}
|
|
25
|
-
|
|
26
|
-
export const { POST, PATCH, OPTIONS, ALL } = createEffectAPIRoutes(
|
|
27
|
-
{
|
|
28
|
-
POST: (ctx) =>
|
|
29
|
-
genLogger('routes/mailer/config/POST')(function* () {
|
|
30
|
-
const mailer = yield* Mailer;
|
|
31
|
-
|
|
32
|
-
// Check if user is logged in
|
|
33
|
-
if (!ctx.locals.StudioCMS.security?.userSessionData.isLoggedIn) {
|
|
34
|
-
return apiResponseLogger(401, 'Authentication required');
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Check if user has permission
|
|
38
|
-
if (!ctx.locals.StudioCMS.security?.userPermissionLevel.isOwner) {
|
|
39
|
-
return apiResponseLogger(403, 'Forbidden');
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Get Json Data
|
|
43
|
-
const smtpConfig = yield* parseAPIContextJson(ctx, SmtpConfigSchema);
|
|
44
|
-
|
|
45
|
-
// Validate form data
|
|
46
|
-
if (!Number.isInteger(smtpConfig.port) || smtpConfig.port < 1 || smtpConfig.port > 65535) {
|
|
47
|
-
return apiResponseLogger(
|
|
48
|
-
400,
|
|
49
|
-
'Invalid form data, port must be an integer between 1 and 65535'
|
|
50
|
-
);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (typeof smtpConfig.host !== 'string' || smtpConfig.host.trim() === '') {
|
|
54
|
-
return apiResponseLogger(400, 'Invalid form data, host is required');
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (typeof smtpConfig.secure !== 'boolean') {
|
|
58
|
-
return apiResponseLogger(400, 'Invalid form data, secure must be a boolean');
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (
|
|
62
|
-
typeof smtpConfig.default_sender !== 'string' ||
|
|
63
|
-
smtpConfig.default_sender.trim() === ''
|
|
64
|
-
) {
|
|
65
|
-
return apiResponseLogger(400, 'Invalid form data, default_sender is required');
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Update Database
|
|
69
|
-
const config = yield* mailer.createMailerConfigTable(smtpConfig);
|
|
70
|
-
|
|
71
|
-
if (!config) {
|
|
72
|
-
return apiResponseLogger(500, 'Error creating mailer config table');
|
|
73
|
-
}
|
|
74
|
-
return apiResponseLogger(200, 'Mailer config updated');
|
|
75
|
-
}).pipe(Mailer.Provide),
|
|
76
|
-
PATCH: (ctx) =>
|
|
77
|
-
genLogger('routes/mailer/config/PATCH')(function* () {
|
|
78
|
-
const mailer = yield* Mailer;
|
|
79
|
-
|
|
80
|
-
// Check if user is logged in
|
|
81
|
-
if (!ctx.locals.StudioCMS.security?.userSessionData.isLoggedIn) {
|
|
82
|
-
return apiResponseLogger(403, 'Unauthorized');
|
|
83
|
-
}
|
|
84
|
-
// Check if user has permission
|
|
85
|
-
if (!ctx.locals.StudioCMS.security?.userPermissionLevel.isOwner) {
|
|
86
|
-
return apiResponseLogger(403, 'Unauthorized');
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Get Json Data
|
|
90
|
-
const smtpConfig = yield* parseAPIContextJson(ctx, SmtpConfigSchema);
|
|
91
|
-
|
|
92
|
-
// Validate form data
|
|
93
|
-
if (!smtpConfig.port) {
|
|
94
|
-
return apiResponseLogger(400, 'Invalid form data, port is required');
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (!smtpConfig.host) {
|
|
98
|
-
return apiResponseLogger(400, 'Invalid form data, host is required');
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (!smtpConfig.secure) {
|
|
102
|
-
return apiResponseLogger(400, 'Invalid form data, secure is required');
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (!smtpConfig.default_sender) {
|
|
106
|
-
return apiResponseLogger(400, 'Invalid form data, default_sender is required');
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Update Database
|
|
110
|
-
const config = yield* mailer.updateMailerConfigTable(smtpConfig);
|
|
111
|
-
if (!config) {
|
|
112
|
-
return apiResponseLogger(500, 'Error updating mailer config table');
|
|
113
|
-
}
|
|
114
|
-
return apiResponseLogger(200, 'Mailer config updated');
|
|
115
|
-
}).pipe(Mailer.Provide),
|
|
116
|
-
OPTIONS: () => Effect.try(() => OptionsResponse({ allowedMethods: ['POST', 'PATCH'] })),
|
|
117
|
-
ALL: () => Effect.try(() => AllResponse()),
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
cors: { methods: ['POST', 'PATCH', 'OPTIONS'] },
|
|
121
|
-
// biome-ignore lint/suspicious/noExplicitAny: allows for better error handling
|
|
122
|
-
onError: (error: any) => {
|
|
123
|
-
console.error('API Error:', error);
|
|
124
|
-
const isClientError =
|
|
125
|
-
error?.status === 400 ||
|
|
126
|
-
error?.name === 'SyntaxError' ||
|
|
127
|
-
error?._tag === 'ParseError' ||
|
|
128
|
-
error?._tag === 'JSONParseError' ||
|
|
129
|
-
(typeof error?.name === 'string' && error.name.includes('Schema'));
|
|
130
|
-
return createJsonResponse(
|
|
131
|
-
{ error: isClientError ? 'Invalid request body' : 'Internal Server Error' },
|
|
132
|
-
{ status: isClientError ? 400 : 500 }
|
|
133
|
-
);
|
|
134
|
-
},
|
|
135
|
-
}
|
|
136
|
-
);
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { apiResponseLogger } from 'studiocms:logger';
|
|
2
|
-
import pluginList from 'studiocms:plugins';
|
|
3
|
-
import { settingsEndpoints } from 'studiocms:plugins/endpoints';
|
|
4
|
-
import {
|
|
5
|
-
AllResponse,
|
|
6
|
-
createEffectAPIRoutes,
|
|
7
|
-
createJsonResponse,
|
|
8
|
-
Effect,
|
|
9
|
-
genLogger,
|
|
10
|
-
OptionsResponse,
|
|
11
|
-
pipe,
|
|
12
|
-
} from '@withstudiocms/effect';
|
|
13
|
-
import { StudioCMSAPIError } from '#frontend/utils/errors.js';
|
|
14
|
-
|
|
15
|
-
export const { POST, OPTIONS, ALL } = createEffectAPIRoutes(
|
|
16
|
-
{
|
|
17
|
-
POST: (ctx) =>
|
|
18
|
-
genLogger('studiocms/routes/api/dashboard/plugins/[plugin].POST')(function* () {
|
|
19
|
-
// Get user data
|
|
20
|
-
const userData = ctx.locals.StudioCMS.security?.userSessionData;
|
|
21
|
-
|
|
22
|
-
// Check if user is logged in
|
|
23
|
-
if (!userData?.isLoggedIn) {
|
|
24
|
-
return apiResponseLogger(403, 'Unauthorized');
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// Check if user has permission
|
|
28
|
-
const isAuthorized = ctx.locals.StudioCMS.security?.userPermissionLevel?.isAdmin === true;
|
|
29
|
-
if (!isAuthorized) {
|
|
30
|
-
return apiResponseLogger(403, 'Unauthorized');
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const { plugin } = ctx.params;
|
|
34
|
-
|
|
35
|
-
const settingsPage = yield* Effect.try({
|
|
36
|
-
try: () =>
|
|
37
|
-
pipe(
|
|
38
|
-
pluginList.filter(({ settingsPage }) => !!settingsPage),
|
|
39
|
-
(p) => p.find(({ identifier }) => identifier === plugin),
|
|
40
|
-
(p) => {
|
|
41
|
-
if (!p) {
|
|
42
|
-
return apiResponseLogger(404, 'Plugin not found');
|
|
43
|
-
}
|
|
44
|
-
const settingsPage = settingsEndpoints.find(
|
|
45
|
-
({ identifier }) => identifier === plugin
|
|
46
|
-
);
|
|
47
|
-
if (!settingsPage) {
|
|
48
|
-
return apiResponseLogger(404, 'Plugin does not have a settings page');
|
|
49
|
-
}
|
|
50
|
-
return settingsPage;
|
|
51
|
-
}
|
|
52
|
-
),
|
|
53
|
-
catch: (cause) =>
|
|
54
|
-
new StudioCMSAPIError({
|
|
55
|
-
message: 'An error occurred while fetching plugin settings page',
|
|
56
|
-
cause,
|
|
57
|
-
}),
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
if (settingsPage instanceof Response) {
|
|
61
|
-
return settingsPage;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (!settingsPage.onSave) {
|
|
65
|
-
return apiResponseLogger(404, 'Plugin does not have a settings page');
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return settingsPage.onSave(ctx);
|
|
69
|
-
}),
|
|
70
|
-
OPTIONS: () => Effect.try(() => OptionsResponse({ allowedMethods: ['POST'] })),
|
|
71
|
-
ALL: () => Effect.try(() => AllResponse()),
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
cors: { methods: ['POST', 'OPTIONS'] },
|
|
75
|
-
onError: (error) => {
|
|
76
|
-
console.error('API Error:', error);
|
|
77
|
-
return createJsonResponse({ error: 'Internal Server Error' }, { status: 500 });
|
|
78
|
-
},
|
|
79
|
-
}
|
|
80
|
-
);
|