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,101 +0,0 @@
|
|
|
1
|
-
import { type OAuthProviders, oAuthProviders } from 'studiocms:plugins/auth/providers';
|
|
2
|
-
import { Effect, genLogger } from '@withstudiocms/effect';
|
|
3
|
-
import type { APIContext, APIRoute } from 'astro';
|
|
4
|
-
import { StudioCMSAPIError } from '#frontend/utils/errors.js';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Creates a standardized HTTP response for authentication provider errors.
|
|
8
|
-
*
|
|
9
|
-
* @param error - The error message to include in the response body.
|
|
10
|
-
* @param status - The HTTP status code for the response.
|
|
11
|
-
* @returns A `Response` object with a JSON body containing the error message and the specified status code.
|
|
12
|
-
*/
|
|
13
|
-
export const ProviderResponse = (
|
|
14
|
-
error: string,
|
|
15
|
-
status: number
|
|
16
|
-
): Effect.Effect<Response, never, never> =>
|
|
17
|
-
Effect.succeed(new Response(JSON.stringify({ error }), { status }));
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Executes the provided API route handler function with the given context and returns its resulting Promise.
|
|
21
|
-
*
|
|
22
|
-
* @param fn - The API route handler function to execute.
|
|
23
|
-
* @param context - The context object to pass to the handler function.
|
|
24
|
-
* @returns A Promise that resolves to a Response object returned by the handler.
|
|
25
|
-
*/
|
|
26
|
-
async function promisifyFn(fn: APIRoute, context: APIContext): Promise<Response> {
|
|
27
|
-
return await fn(context);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Wraps an API route handler function in an Effect, converting it into a promise-based effectful computation.
|
|
32
|
-
*
|
|
33
|
-
* @param fn - The API route handler function to be executed.
|
|
34
|
-
* @param context - The API context to be passed to the handler.
|
|
35
|
-
* @returns An Effect that resolves with the result of the handler or rejects with an error if execution fails.
|
|
36
|
-
*
|
|
37
|
-
* @remarks
|
|
38
|
-
* If the handler throws an error, it is caught and wrapped in a new `Error` with a descriptive message.
|
|
39
|
-
*/
|
|
40
|
-
const promisify = Effect.fn(function* (fn: APIRoute, context: APIContext) {
|
|
41
|
-
return yield* Effect.tryPromise({
|
|
42
|
-
try: () => promisifyFn(fn, context),
|
|
43
|
-
catch: (error) =>
|
|
44
|
-
new StudioCMSAPIError({ message: `Failed to execute API route: ${error}`, cause: error }),
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Dispatches an authentication request to the appropriate OAuth provider handler.
|
|
50
|
-
*
|
|
51
|
-
* This generator function locates the specified provider by its `safeName` from the provided list,
|
|
52
|
-
* checks if the provider is enabled, and then invokes the appropriate handler (`initSession` or `initCallback`)
|
|
53
|
-
* for the authentication flow. If the provider or handler is not found, or if the provider is not enabled,
|
|
54
|
-
* it yields an appropriate error response.
|
|
55
|
-
*
|
|
56
|
-
* @param context - The API context containing request parameters and other relevant data.
|
|
57
|
-
* @param handler - The handler to invoke, either `'initSession'` or `'initCallback'`.
|
|
58
|
-
* @param providers - An array of provider configurations, each containing a `safeName`, `enabled` flag,
|
|
59
|
-
* and optional `initSession` and `initCallback` route handlers.
|
|
60
|
-
* @returns A generator yielding the result of the provider handler or an error response.
|
|
61
|
-
*/
|
|
62
|
-
const dispatchToAuthProvider = (
|
|
63
|
-
context: APIContext,
|
|
64
|
-
handler: 'initSession' | 'initCallback',
|
|
65
|
-
providers: OAuthProviders
|
|
66
|
-
) =>
|
|
67
|
-
genLogger('OAuthAPIEffect.dispatchToAuthProvider')(function* () {
|
|
68
|
-
const provider = context.params.provider;
|
|
69
|
-
const matchedProvider = providers.find((p) => p.safeName === provider);
|
|
70
|
-
if (!matchedProvider) {
|
|
71
|
-
return yield* ProviderResponse('Provider not found', 404);
|
|
72
|
-
}
|
|
73
|
-
if (!matchedProvider.enabled) {
|
|
74
|
-
return yield* ProviderResponse('Provider is not configured', 403);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const handlerFn = matchedProvider[handler];
|
|
78
|
-
|
|
79
|
-
if (!handlerFn) {
|
|
80
|
-
return yield* ProviderResponse('Provider handler not found', 501);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return yield* promisify(handlerFn, context);
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
export class OAuthAPIEffect extends Effect.Service<OAuthAPIEffect>()('OAuthAPIEffect', {
|
|
87
|
-
effect: genLogger('studiocms/routes/api/auth/[provider]/_shared')(function* () {
|
|
88
|
-
return {
|
|
89
|
-
initSession: (context: APIContext) =>
|
|
90
|
-
dispatchToAuthProvider(context, 'initSession', oAuthProviders),
|
|
91
|
-
initCallback: (context: APIContext) =>
|
|
92
|
-
dispatchToAuthProvider(context, 'initCallback', oAuthProviders),
|
|
93
|
-
};
|
|
94
|
-
}),
|
|
95
|
-
}) {
|
|
96
|
-
// Export Dependency Providers
|
|
97
|
-
/**
|
|
98
|
-
* Main Dependencies Provider
|
|
99
|
-
*/
|
|
100
|
-
static Provide = Effect.provide(OAuthAPIEffect.Default);
|
|
101
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createJsonResponse,
|
|
3
|
-
Effect,
|
|
4
|
-
genLogger,
|
|
5
|
-
parseFormDataEntryToString,
|
|
6
|
-
readAPIContextFormData,
|
|
7
|
-
readAPIContextJson,
|
|
8
|
-
Schema,
|
|
9
|
-
} from '@withstudiocms/effect';
|
|
10
|
-
import type { APIContext } from 'astro';
|
|
11
|
-
import { AstroError } from 'astro/errors';
|
|
12
|
-
import { z } from 'astro/zod';
|
|
13
|
-
|
|
14
|
-
export class FormDataEntryFields extends Schema.Class<FormDataEntryFields>('FormDataEntryFields')({
|
|
15
|
-
title: Schema.String,
|
|
16
|
-
description: Schema.String,
|
|
17
|
-
}) {}
|
|
18
|
-
|
|
19
|
-
export class AuthAPIUtils extends Effect.Service<AuthAPIUtils>()(
|
|
20
|
-
'studiocms/routes/api/auth/shared/AuthAPIUtils',
|
|
21
|
-
{
|
|
22
|
-
effect: genLogger('studiocms/routes/api/auth/shared/AuthAPIUtils.effect')(function* () {
|
|
23
|
-
return {
|
|
24
|
-
parseFormDataEntryToString: parseFormDataEntryToString,
|
|
25
|
-
// biome-ignore lint/suspicious/noExplicitAny: This is a generic utility function
|
|
26
|
-
readJson: (context: APIContext) => readAPIContextJson<any>(context),
|
|
27
|
-
readFormData: (context: APIContext) => readAPIContextFormData(context),
|
|
28
|
-
badFormDataEntry: (title: string, description: string) =>
|
|
29
|
-
genLogger('studiocms/routes/api/auth/shared/AuthAPIUtils.badFormDataEntry')(function* () {
|
|
30
|
-
const error = yield* Schema.decode(FormDataEntryFields)({ title, description });
|
|
31
|
-
return createJsonResponse(
|
|
32
|
-
{ error },
|
|
33
|
-
{
|
|
34
|
-
status: 400,
|
|
35
|
-
statusText: 'Bad Request',
|
|
36
|
-
}
|
|
37
|
-
);
|
|
38
|
-
}),
|
|
39
|
-
validateEmail: (email: string) =>
|
|
40
|
-
Effect.try({
|
|
41
|
-
try: () => {
|
|
42
|
-
const emailSchema = z.coerce.string().email({ message: 'Email address is invalid' });
|
|
43
|
-
return emailSchema.safeParse(email);
|
|
44
|
-
},
|
|
45
|
-
catch: () => new AstroError('Failed to parse email with zod.'),
|
|
46
|
-
}),
|
|
47
|
-
};
|
|
48
|
-
}),
|
|
49
|
-
}
|
|
50
|
-
) {
|
|
51
|
-
static Provide = Effect.provide(this.Default);
|
|
52
|
-
}
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import { developerConfig } from 'studiocms:config';
|
|
2
|
-
import { apiResponseLogger } from 'studiocms:logger';
|
|
3
|
-
import { SDKCore } from 'studiocms:sdk';
|
|
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, DELETE, OPTIONS, ALL } = createEffectAPIRoutes(
|
|
15
|
-
{
|
|
16
|
-
POST: (ctx) =>
|
|
17
|
-
genLogger('studiocms/routes/api/dashboard/api-tokens.POST')(function* () {
|
|
18
|
-
const sdk = yield* SDKCore;
|
|
19
|
-
|
|
20
|
-
// Check if demo mode is enabled
|
|
21
|
-
if (developerConfig.demoMode !== false) {
|
|
22
|
-
return apiResponseLogger(403, 'Demo mode is enabled, this action is not allowed.');
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Get user data
|
|
26
|
-
const userData = ctx.locals.StudioCMS.security?.userSessionData;
|
|
27
|
-
|
|
28
|
-
// Check if user is logged in
|
|
29
|
-
if (!userData?.isLoggedIn) {
|
|
30
|
-
return apiResponseLogger(403, 'Unauthorized');
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Check if user has permission
|
|
34
|
-
const isAuthorized = ctx.locals.StudioCMS.security?.userPermissionLevel.isEditor;
|
|
35
|
-
if (!isAuthorized) {
|
|
36
|
-
return apiResponseLogger(403, 'Unauthorized');
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Get Json Data
|
|
40
|
-
const jsonData = yield* readAPIContextJson<{
|
|
41
|
-
description: string;
|
|
42
|
-
user: string;
|
|
43
|
-
}>(ctx);
|
|
44
|
-
|
|
45
|
-
// Validate form data
|
|
46
|
-
if (!jsonData.description) {
|
|
47
|
-
return apiResponseLogger(400, 'Invalid form data, description is required');
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (!jsonData.user) {
|
|
51
|
-
return apiResponseLogger(400, 'Invalid form data, user is required');
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const newToken = yield* sdk.REST_API.tokens.new(jsonData.user, jsonData.description);
|
|
55
|
-
|
|
56
|
-
return createJsonResponse({ token: newToken.key });
|
|
57
|
-
}),
|
|
58
|
-
DELETE: (ctx) =>
|
|
59
|
-
genLogger('studiocms/routes/api/dashboard/api-tokens.DELETE')(function* () {
|
|
60
|
-
const sdk = yield* SDKCore;
|
|
61
|
-
|
|
62
|
-
// Check if demo mode is enabled
|
|
63
|
-
if (developerConfig.demoMode !== false) {
|
|
64
|
-
return apiResponseLogger(403, 'Demo mode is enabled, this action is not allowed.');
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Get user data
|
|
68
|
-
const userData = ctx.locals.StudioCMS.security?.userSessionData;
|
|
69
|
-
|
|
70
|
-
// Check if user is logged in
|
|
71
|
-
if (!userData?.isLoggedIn) {
|
|
72
|
-
return apiResponseLogger(403, 'Unauthorized');
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Check if user has permission
|
|
76
|
-
const isAuthorized = ctx.locals.StudioCMS.security?.userPermissionLevel.isEditor;
|
|
77
|
-
if (!isAuthorized) {
|
|
78
|
-
return apiResponseLogger(403, 'Unauthorized');
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Get Json Data
|
|
82
|
-
const jsonData = yield* readAPIContextJson<{
|
|
83
|
-
tokenID: string;
|
|
84
|
-
userID: string;
|
|
85
|
-
}>(ctx);
|
|
86
|
-
|
|
87
|
-
// Validate form data
|
|
88
|
-
if (!jsonData.tokenID) {
|
|
89
|
-
return apiResponseLogger(400, 'Invalid form data, tokenID is required');
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (!jsonData.userID) {
|
|
93
|
-
return apiResponseLogger(400, 'Invalid form data, userID is required');
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
yield* sdk.REST_API.tokens.delete({ tokenId: jsonData.tokenID, userId: jsonData.userID });
|
|
97
|
-
|
|
98
|
-
return apiResponseLogger(200, 'Token deleted');
|
|
99
|
-
}),
|
|
100
|
-
OPTIONS: () => Effect.try(() => OptionsResponse({ allowedMethods: ['POST', 'DELETE'] })),
|
|
101
|
-
ALL: () => Effect.try(() => AllResponse()),
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
cors: { methods: ['POST', 'DELETE', 'OPTIONS'] },
|
|
105
|
-
onError: (error) => {
|
|
106
|
-
console.error('API Error:', error);
|
|
107
|
-
return createJsonResponse(
|
|
108
|
-
{ error: 'Internal Server Error' },
|
|
109
|
-
{
|
|
110
|
-
status: 500,
|
|
111
|
-
}
|
|
112
|
-
);
|
|
113
|
-
},
|
|
114
|
-
}
|
|
115
|
-
);
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { apiResponseLogger } from 'studiocms:logger';
|
|
2
|
-
import { SDKCore } from 'studiocms:sdk';
|
|
3
|
-
import type { StudioCMSSiteConfig } 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/config.POST')(function* () {
|
|
18
|
-
const sdk = yield* SDKCore;
|
|
19
|
-
|
|
20
|
-
// Get user data
|
|
21
|
-
const userData = ctx.locals.StudioCMS.security?.userSessionData;
|
|
22
|
-
|
|
23
|
-
// Check if user is logged in
|
|
24
|
-
if (!userData?.isLoggedIn) {
|
|
25
|
-
return apiResponseLogger(403, 'Unauthorized');
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Check if user has permission
|
|
29
|
-
const isAuthorized = ctx.locals.StudioCMS.security?.userPermissionLevel.isOwner;
|
|
30
|
-
if (!isAuthorized) {
|
|
31
|
-
return apiResponseLogger(403, 'Unauthorized');
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Get Json Data
|
|
35
|
-
const siteConfig =
|
|
36
|
-
yield* readAPIContextJson<Omit<StudioCMSSiteConfig, '_config_version'>>(ctx);
|
|
37
|
-
|
|
38
|
-
// Validate form data
|
|
39
|
-
if (!siteConfig.title) {
|
|
40
|
-
return apiResponseLogger(400, 'Invalid form data, title is required');
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (!siteConfig.description) {
|
|
44
|
-
return apiResponseLogger(400, 'Invalid form data, description is required');
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (!siteConfig.loginPageBackground) {
|
|
48
|
-
return apiResponseLogger(400, 'Invalid form data, loginPageBackground is required');
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (siteConfig.loginPageBackground === 'custom' && !siteConfig.loginPageCustomImage) {
|
|
52
|
-
return apiResponseLogger(400, 'Invalid form data, loginPageCustomImage is required');
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
yield* sdk.UPDATE.siteConfig(siteConfig);
|
|
56
|
-
|
|
57
|
-
return apiResponseLogger(200, 'Site config updated');
|
|
58
|
-
}),
|
|
59
|
-
OPTIONS: () => Effect.try(() => OptionsResponse({ allowedMethods: ['POST'] })),
|
|
60
|
-
ALL: () => Effect.try(() => AllResponse()),
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
cors: { methods: ['POST', 'OPTIONS'] },
|
|
64
|
-
onError: (error) => {
|
|
65
|
-
console.error('API Error:', error);
|
|
66
|
-
return createJsonResponse(
|
|
67
|
-
{ error: 'Internal Server Error' },
|
|
68
|
-
{
|
|
69
|
-
status: 500,
|
|
70
|
-
}
|
|
71
|
-
);
|
|
72
|
-
},
|
|
73
|
-
}
|
|
74
|
-
);
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { apiResponseLogger } from 'studiocms:logger';
|
|
2
|
-
import { Notifications } from 'studiocms:notifier';
|
|
3
|
-
import { SDKCore } from 'studiocms:sdk';
|
|
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/content/diff.POST')(function* () {
|
|
18
|
-
const [notify, sdk] = yield* Effect.all([Notifications, SDKCore]);
|
|
19
|
-
|
|
20
|
-
// Get user data
|
|
21
|
-
const userData = ctx.locals.StudioCMS.security?.userSessionData;
|
|
22
|
-
|
|
23
|
-
// Check if user is logged in
|
|
24
|
-
if (!userData?.isLoggedIn) {
|
|
25
|
-
return apiResponseLogger(403, 'Unauthorized');
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Check if user has permission
|
|
29
|
-
const isAuthorized = ctx.locals.StudioCMS.security?.userPermissionLevel.isEditor;
|
|
30
|
-
if (!isAuthorized) {
|
|
31
|
-
return apiResponseLogger(403, 'Unauthorized');
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const jsonData = yield* readAPIContextJson<{
|
|
35
|
-
id: string;
|
|
36
|
-
type: 'data' | 'content' | 'both';
|
|
37
|
-
}>(ctx);
|
|
38
|
-
|
|
39
|
-
const { id, type } = jsonData;
|
|
40
|
-
|
|
41
|
-
if (!id || !type) {
|
|
42
|
-
return apiResponseLogger(400, 'Invalid ID or Type');
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (!['data', 'content', 'both'].includes(type)) {
|
|
46
|
-
return apiResponseLogger(400, 'Invalid Type');
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const data = yield* sdk.diffTracking.revertToDiff(id, type);
|
|
50
|
-
|
|
51
|
-
yield* Effect.all([
|
|
52
|
-
sdk.CLEAR.pages,
|
|
53
|
-
notify.sendEditorNotification('page_updated', data.pageMetaData.end.title || ''),
|
|
54
|
-
]);
|
|
55
|
-
|
|
56
|
-
return apiResponseLogger(200, 'Page Reverted successfully');
|
|
57
|
-
}).pipe(Notifications.Provide),
|
|
58
|
-
OPTIONS: () => Effect.try(() => OptionsResponse({ allowedMethods: ['POST'] })),
|
|
59
|
-
ALL: () => Effect.try(() => AllResponse()),
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
cors: { methods: ['POST', 'OPTIONS'] },
|
|
63
|
-
onError: (error) => {
|
|
64
|
-
console.error('Error in diff API:', error);
|
|
65
|
-
return createJsonResponse(
|
|
66
|
-
{ error: 'Internal Server Error' },
|
|
67
|
-
{
|
|
68
|
-
status: 500,
|
|
69
|
-
}
|
|
70
|
-
);
|
|
71
|
-
},
|
|
72
|
-
}
|
|
73
|
-
);
|
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
import { apiResponseLogger } from 'studiocms:logger';
|
|
2
|
-
import { Notifications } from 'studiocms:notifier';
|
|
3
|
-
import { SDKCore } from 'studiocms:sdk';
|
|
4
|
-
import {
|
|
5
|
-
AllResponse,
|
|
6
|
-
createEffectAPIRoutes,
|
|
7
|
-
createJsonResponse,
|
|
8
|
-
Effect,
|
|
9
|
-
genLogger,
|
|
10
|
-
OptionsResponse,
|
|
11
|
-
readAPIContextJson,
|
|
12
|
-
Schema,
|
|
13
|
-
} from '@withstudiocms/effect';
|
|
14
|
-
import { StudioCMSPageData, StudioCMSPageFolderStructure } from '@withstudiocms/sdk/tables';
|
|
15
|
-
|
|
16
|
-
interface FolderBase {
|
|
17
|
-
folderName: string;
|
|
18
|
-
parentFolder: string | null;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
interface FolderEdit extends FolderBase {
|
|
22
|
-
id: string;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export const { POST, PATCH, DELETE, OPTIONS, ALL } = createEffectAPIRoutes(
|
|
26
|
-
{
|
|
27
|
-
POST: (ctx) =>
|
|
28
|
-
genLogger('studiocms/routes/api/dashboard/content/folder.POST')(function* () {
|
|
29
|
-
const [notify, sdk] = yield* Effect.all([Notifications, SDKCore]);
|
|
30
|
-
|
|
31
|
-
// Get user data
|
|
32
|
-
const userData = ctx.locals.StudioCMS.security?.userSessionData;
|
|
33
|
-
|
|
34
|
-
// Check if user is logged in
|
|
35
|
-
if (!userData?.isLoggedIn) {
|
|
36
|
-
return apiResponseLogger(403, 'Unauthorized');
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Check if user has permission
|
|
40
|
-
const isAuthorized = ctx.locals.StudioCMS.security?.userPermissionLevel.isAdmin;
|
|
41
|
-
if (!isAuthorized) {
|
|
42
|
-
return apiResponseLogger(403, 'Unauthorized');
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const { folderName, parentFolder } = yield* readAPIContextJson<FolderBase>(ctx);
|
|
46
|
-
|
|
47
|
-
if (!folderName) {
|
|
48
|
-
return apiResponseLogger(400, 'Invalid form data, folderName is required');
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
yield* Effect.all([
|
|
52
|
-
sdk.POST.folder({
|
|
53
|
-
id: crypto.randomUUID(),
|
|
54
|
-
name: folderName,
|
|
55
|
-
parent: parentFolder || null,
|
|
56
|
-
}),
|
|
57
|
-
sdk.UPDATE.folderList,
|
|
58
|
-
sdk.UPDATE.folderTree,
|
|
59
|
-
notify.sendEditorNotification('new_folder', folderName),
|
|
60
|
-
]);
|
|
61
|
-
|
|
62
|
-
return apiResponseLogger(200, 'Folder created successfully');
|
|
63
|
-
}).pipe(Notifications.Provide),
|
|
64
|
-
PATCH: (ctx) =>
|
|
65
|
-
genLogger('studiocms/routes/api/dashboard/content/folder.PATCH')(function* () {
|
|
66
|
-
const [notify, sdk] = yield* Effect.all([Notifications, SDKCore]);
|
|
67
|
-
|
|
68
|
-
// Get user data
|
|
69
|
-
const userData = ctx.locals.StudioCMS.security?.userSessionData;
|
|
70
|
-
|
|
71
|
-
// Check if user is logged in
|
|
72
|
-
if (!userData?.isLoggedIn) {
|
|
73
|
-
return apiResponseLogger(403, 'Unauthorized');
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Check if user has permission
|
|
77
|
-
const isAuthorized = ctx.locals.StudioCMS.security?.userPermissionLevel.isEditor;
|
|
78
|
-
if (!isAuthorized) {
|
|
79
|
-
return apiResponseLogger(403, 'Unauthorized');
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const { id, folderName, parentFolder } = yield* readAPIContextJson<FolderEdit>(ctx);
|
|
83
|
-
|
|
84
|
-
if (!id) {
|
|
85
|
-
return apiResponseLogger(400, 'Invalid form data, id is required');
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (!folderName) {
|
|
89
|
-
return apiResponseLogger(400, 'Invalid form data, folderName is required');
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Ensure parent folder is not the same as the folder being edited
|
|
93
|
-
if (parentFolder === id) {
|
|
94
|
-
return apiResponseLogger(400, 'A folder cannot be its own parent');
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
yield* Effect.all([
|
|
98
|
-
sdk.UPDATE.folder({
|
|
99
|
-
id,
|
|
100
|
-
name: folderName,
|
|
101
|
-
parent: parentFolder || null,
|
|
102
|
-
}),
|
|
103
|
-
sdk.UPDATE.folderList,
|
|
104
|
-
sdk.UPDATE.folderTree,
|
|
105
|
-
notify.sendEditorNotification('folder_updated', folderName),
|
|
106
|
-
]);
|
|
107
|
-
|
|
108
|
-
return apiResponseLogger(200, 'Folder updated successfully');
|
|
109
|
-
}).pipe(Notifications.Provide),
|
|
110
|
-
DELETE: (ctx) =>
|
|
111
|
-
genLogger('studiocms/routes/api/dashboard/content/folder.DELETE')(function* () {
|
|
112
|
-
const [notify, sdk] = yield* Effect.all([Notifications, SDKCore]);
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Check for child folders before deletion
|
|
116
|
-
*/
|
|
117
|
-
const checkForChildrenFolders = sdk.dbService.withCodec({
|
|
118
|
-
encoder: Schema.String,
|
|
119
|
-
decoder: Schema.Array(StudioCMSPageFolderStructure),
|
|
120
|
-
callbackFn: (client, id) =>
|
|
121
|
-
client((db) =>
|
|
122
|
-
db
|
|
123
|
-
.selectFrom('StudioCMSPageFolderStructure')
|
|
124
|
-
.where('parent', '=', id)
|
|
125
|
-
.selectAll()
|
|
126
|
-
.execute()
|
|
127
|
-
),
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Check for child pages before deletion
|
|
132
|
-
*/
|
|
133
|
-
const checkForChildrenPages = sdk.dbService.withCodec({
|
|
134
|
-
encoder: Schema.String,
|
|
135
|
-
decoder: Schema.Array(StudioCMSPageData),
|
|
136
|
-
callbackFn: (client, id) =>
|
|
137
|
-
client((db) =>
|
|
138
|
-
db
|
|
139
|
-
.selectFrom('StudioCMSPageData')
|
|
140
|
-
.where('parentFolder', '=', id)
|
|
141
|
-
.selectAll()
|
|
142
|
-
.execute()
|
|
143
|
-
),
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Check for any children (folders or pages) before deletion
|
|
148
|
-
*/
|
|
149
|
-
const checkForChildren = Effect.fn((id: string) =>
|
|
150
|
-
Effect.all({
|
|
151
|
-
folders: checkForChildrenFolders(id),
|
|
152
|
-
pages: checkForChildrenPages(id),
|
|
153
|
-
}).pipe(
|
|
154
|
-
Effect.map(({ folders, pages }) => {
|
|
155
|
-
return { hasChildren: folders.length > 0 || pages.length > 0 };
|
|
156
|
-
})
|
|
157
|
-
)
|
|
158
|
-
);
|
|
159
|
-
|
|
160
|
-
// Get user data
|
|
161
|
-
const userData = ctx.locals.StudioCMS.security?.userSessionData;
|
|
162
|
-
|
|
163
|
-
// Check if user is logged in
|
|
164
|
-
if (!userData?.isLoggedIn) {
|
|
165
|
-
return apiResponseLogger(403, 'Unauthorized');
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// Check if user has permission
|
|
169
|
-
const isAuthorized = ctx.locals.StudioCMS.security?.userPermissionLevel.isAdmin;
|
|
170
|
-
if (!isAuthorized) {
|
|
171
|
-
return apiResponseLogger(403, 'Unauthorized');
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
const { id } = yield* readAPIContextJson<{ id: string }>(ctx);
|
|
175
|
-
|
|
176
|
-
if (!id) {
|
|
177
|
-
return apiResponseLogger(400, 'Invalid form data, id is required');
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
const { name: folderName } = (yield* sdk.GET.folder(id)) || {};
|
|
181
|
-
|
|
182
|
-
if (!folderName) {
|
|
183
|
-
return apiResponseLogger(404, 'Folder not found');
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
const { hasChildren } = yield* checkForChildren(id);
|
|
187
|
-
|
|
188
|
-
if (hasChildren) {
|
|
189
|
-
return apiResponseLogger(
|
|
190
|
-
400,
|
|
191
|
-
'Folder cannot be deleted because it contains subfolders or pages'
|
|
192
|
-
);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
yield* Effect.all([
|
|
196
|
-
sdk.DELETE.folder(id),
|
|
197
|
-
sdk.UPDATE.folderList,
|
|
198
|
-
sdk.UPDATE.folderTree,
|
|
199
|
-
notify.sendEditorNotification('folder_deleted', folderName),
|
|
200
|
-
]);
|
|
201
|
-
|
|
202
|
-
return apiResponseLogger(200, 'Folder deleted successfully');
|
|
203
|
-
}).pipe(Notifications.Provide),
|
|
204
|
-
OPTIONS: () =>
|
|
205
|
-
Effect.try(() => OptionsResponse({ allowedMethods: ['POST', 'PATCH', 'DELETE'] })),
|
|
206
|
-
ALL: () => Effect.try(() => AllResponse()),
|
|
207
|
-
},
|
|
208
|
-
{
|
|
209
|
-
cors: { methods: ['POST', 'PATCH', 'DELETE'] },
|
|
210
|
-
onError: (error) => {
|
|
211
|
-
console.error('Error in folder API:', error);
|
|
212
|
-
return createJsonResponse(
|
|
213
|
-
{ error: 'Internal Server Error' },
|
|
214
|
-
{
|
|
215
|
-
status: 500,
|
|
216
|
-
}
|
|
217
|
-
);
|
|
218
|
-
},
|
|
219
|
-
}
|
|
220
|
-
);
|