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.
Files changed (293) hide show
  1. package/CHANGELOG.md +122 -0
  2. package/dist/cli/add/index.d.ts +2 -2
  3. package/dist/cli/add/index.js +4 -3
  4. package/dist/cli/add/npm-utils.d.ts +6 -6
  5. package/dist/cli/add/tryToInstallPlugins.d.ts +1 -1
  6. package/dist/cli/add/tryToInstallPlugins.js +6 -5
  7. package/dist/cli/add/updateStudioCMSConfig.d.ts +1 -1
  8. package/dist/cli/add/updateStudioCMSConfig.js +3 -4
  9. package/dist/cli/add/validatePlugins.d.ts +1 -2
  10. package/dist/cli/add/validatePlugins.js +15 -9
  11. package/dist/cli/crypto/genJWT/index.d.ts +1 -1
  12. package/dist/cli/crypto/genJWT/index.js +8 -9
  13. package/dist/cli/crypto/index.d.ts +1 -1
  14. package/dist/cli/init/steps/env.js +14 -4
  15. package/dist/cli/init/steps/next.d.ts +1 -1
  16. package/dist/cli/init/steps/next.js +6 -5
  17. package/dist/cli/migrator/index.d.ts +1 -1
  18. package/dist/cli/migrator/index.js +2 -2
  19. package/dist/cli/users/index.d.ts +1 -1
  20. package/dist/cli/users/shared.js +2 -2
  21. package/dist/cli/users/steps/createUsers.js +7 -7
  22. package/dist/cli/users/steps/modifyUsers.js +2 -2
  23. package/dist/cli/users/steps/next.d.ts +1 -1
  24. package/dist/cli/utils/checkRequiredEnvVars.js +2 -2
  25. package/dist/cli/utils/context.d.ts +2 -4
  26. package/dist/cli/utils/context.js +1 -3
  27. package/dist/cli/utils/getCliDbClient.d.ts +1 -1
  28. package/dist/cli/utils/intro.d.ts +1 -1
  29. package/dist/cli/utils/loadConfig.d.ts +54 -49
  30. package/dist/cli/utils/loadConfig.js +5 -8
  31. package/dist/cli/utils/logger.js +3 -3
  32. package/dist/cli/utils/user-utils.d.ts +1 -1
  33. package/dist/cli/utils/user-utils.js +4 -3
  34. package/dist/client/apiClient.d.ts +4923 -0
  35. package/dist/client/apiClient.js +72 -0
  36. package/dist/config.d.ts +1734 -1
  37. package/dist/consts.d.ts +5 -5
  38. package/dist/consts.js +3 -2
  39. package/dist/db/plugins.d.ts +1 -1
  40. package/dist/db/plugins.js +5 -8
  41. package/dist/handlers/frontend/routes.d.ts +4 -18
  42. package/dist/handlers/frontend/routes.js +13 -152
  43. package/dist/handlers/frontend/types.d.ts +1 -1
  44. package/dist/handlers/frontend/utils.js +0 -18
  45. package/dist/handlers/pluginHandler.d.ts +34 -257
  46. package/dist/handlers/pluginHandler.js +92 -46
  47. package/dist/handlers/routeHandler.js +32 -11
  48. package/dist/handlers/setupDbStudio.d.ts +3 -1
  49. package/dist/handlers/setupDbStudio.js +19 -10
  50. package/dist/handlers/storage-manager/core/effectify-astro-context.d.ts +25 -0
  51. package/dist/handlers/storage-manager/core/effectify-astro-context.js +78 -0
  52. package/dist/handlers/storage-manager/no-op.d.ts +2 -2
  53. package/dist/handlers/storage-manager/no-op.js +2 -3
  54. package/dist/index.d.ts +0 -1
  55. package/dist/index.js +10 -20
  56. package/dist/integrations/robots/index.d.ts +2 -2
  57. package/dist/integrations/robots/index.js +1 -3
  58. package/dist/integrations/robots/schema.d.ts +102 -273
  59. package/dist/integrations/robots/schema.js +220 -209
  60. package/dist/plugins/analytics/assets/schemas.d.ts +14 -9
  61. package/dist/plugins/analytics/assets/schemas.js +25 -17
  62. package/dist/plugins/analytics/db-client.d.ts +1 -1
  63. package/dist/plugins/analytics/index.d.ts +823 -3
  64. package/dist/plugins/analytics/index.js +4 -5
  65. package/dist/plugins/analytics/schemas.d.ts +54 -62
  66. package/dist/plugins/analytics/schemas.js +64 -13
  67. package/dist/plugins/analytics/table.d.ts +1 -1
  68. package/dist/plugins.d.ts +0 -1
  69. package/dist/schemas/config/api.d.ts +17 -0
  70. package/dist/schemas/config/api.js +14 -0
  71. package/dist/schemas/config/auth.d.ts +55 -59
  72. package/dist/schemas/config/auth.js +34 -11
  73. package/dist/schemas/config/dashboard.d.ts +43 -79
  74. package/dist/schemas/config/dashboard.js +43 -12
  75. package/dist/schemas/config/db.d.ts +15 -17
  76. package/dist/schemas/config/db.js +13 -5
  77. package/dist/schemas/config/developer.d.ts +33 -45
  78. package/dist/schemas/config/developer.js +22 -5
  79. package/dist/schemas/config/index.d.ts +398 -521
  80. package/dist/schemas/config/index.js +115 -57
  81. package/dist/schemas/config/sdk.d.ts +50 -196
  82. package/dist/schemas/config/sdk.js +61 -73
  83. package/dist/schemas/custom.d.ts +40 -0
  84. package/dist/schemas/custom.js +41 -0
  85. package/dist/schemas/external-schemas.d.ts +171 -0
  86. package/dist/schemas/external-schemas.js +179 -0
  87. package/dist/schemas/index.d.ts +2 -0
  88. package/dist/schemas/index.js +2 -0
  89. package/dist/schemas/plugins/i18n.d.ts +59 -39
  90. package/dist/schemas/plugins/i18n.js +42 -5
  91. package/dist/schemas/plugins/index.d.ts +7126 -10296
  92. package/dist/schemas/plugins/index.js +260 -276
  93. package/dist/schemas/plugins/shared.d.ts +1293 -3718
  94. package/dist/schemas/plugins/shared.js +320 -329
  95. package/dist/test-utils.d.ts +15 -4
  96. package/dist/test-utils.js +27 -11
  97. package/dist/toolbar/db-viewer/db-shared-types.d.ts +6 -6
  98. package/dist/toolbar/db-viewer/studio/connection.d.ts +8 -4
  99. package/dist/toolbar/db-viewer/studio/connection.js +2 -28
  100. package/dist/toolbar/db-viewer/studio/env/libsql.d.ts +7 -0
  101. package/dist/toolbar/db-viewer/studio/env/libsql.js +17 -0
  102. package/dist/toolbar/db-viewer/studio/env/mysql.d.ts +7 -0
  103. package/dist/toolbar/db-viewer/studio/env/mysql.js +23 -0
  104. package/dist/toolbar/db-viewer/studio/env/postgres.d.ts +7 -0
  105. package/dist/toolbar/db-viewer/studio/env/postgres.js +23 -0
  106. package/dist/toolbar/db-viewer/studio/index.js +20 -56
  107. package/dist/toolbar/db-viewer/studio/type.d.ts +1 -2
  108. package/dist/toolbar/db-viewer/studio/virtual-connection/libsql.d.ts +3 -0
  109. package/dist/toolbar/db-viewer/studio/virtual-connection/libsql.js +24 -0
  110. package/dist/toolbar/db-viewer/studio/virtual-connection/mysql.d.ts +3 -0
  111. package/dist/toolbar/db-viewer/studio/virtual-connection/mysql.js +9 -0
  112. package/dist/toolbar/db-viewer/studio/virtual-connection/postgres.d.ts +3 -0
  113. package/dist/toolbar/db-viewer/studio/virtual-connection/postgres.js +9 -0
  114. package/dist/toolbar/db-viewer/viewer.js +20 -21
  115. package/dist/types.d.ts +30 -0
  116. package/dist/utils/effects/smtp.d.ts +1 -1
  117. package/dist/utils/lang-helper.d.ts +10 -2
  118. package/dist/virtual.d.ts +35 -28
  119. package/dist/virtuals/auth/core.d.ts +5 -5
  120. package/dist/virtuals/auth/verify-email.d.ts +6 -6
  121. package/dist/virtuals/components/Generator.astro +2 -2
  122. package/dist/virtuals/components/Renderer.astro +9 -1
  123. package/dist/virtuals/components/renderFn.d.ts +3 -1
  124. package/dist/virtuals/components/renderFn.js +18 -0
  125. package/dist/virtuals/lib/headDefaults.d.ts +4 -2
  126. package/dist/virtuals/lib/headDefaults.js +0 -2
  127. package/dist/virtuals/lib/routeMap.d.ts +0 -12
  128. package/dist/virtuals/lib/routeMap.js +2 -14
  129. package/dist/virtuals/mailer/index.d.ts +3 -3
  130. package/dist/virtuals/notifier/index.d.ts +5 -5
  131. package/dist/virtuals/plugins/dashboard-pages.d.ts +2 -64
  132. package/dist/virtuals/scripts/StorageFileBrowser.d.ts +1 -172
  133. package/dist/virtuals/scripts/StorageFileBrowser.js +216 -119
  134. package/dist/virtuals/template-engine/index.d.ts +4 -4
  135. package/frontend/components/dashboard/configuration/ConfigForm.astro +218 -110
  136. package/frontend/components/dashboard/content-mgmt/ContentSearch.astro +21 -22
  137. package/frontend/components/dashboard/content-mgmt/CreateFolder.astro +66 -54
  138. package/frontend/components/dashboard/content-mgmt/CreatePage.astro +58 -104
  139. package/frontend/components/dashboard/content-mgmt/EditFolder.astro +65 -67
  140. package/frontend/components/dashboard/content-mgmt/EditPage.astro +86 -134
  141. package/frontend/components/dashboard/content-mgmt/InnerSidebarElement.astro +0 -1
  142. package/frontend/components/dashboard/content-mgmt/PageHeader.astro +33 -52
  143. package/frontend/components/dashboard/content-mgmt/PageTypeHandler.astro +2 -2
  144. package/frontend/components/dashboard/profile/APITokens.astro +219 -158
  145. package/frontend/components/dashboard/profile/BasicInfo.astro +165 -106
  146. package/frontend/components/dashboard/profile/Notifications.astro +27 -18
  147. package/frontend/components/dashboard/profile/UpdatePassword.astro +134 -94
  148. package/frontend/components/dashboard/sidebar/VersionCheck.astro +31 -16
  149. package/frontend/components/dashboard/sidebar/VersionCheckChangelog.astro +18 -11
  150. package/frontend/components/dashboard/sidebar-modals/VersionModal.astro +2 -2
  151. package/frontend/components/dashboard/smtp-config/TemplateEditor.astro +14 -14
  152. package/frontend/components/dashboard/taxonomy/InnerSidebarElement.astro +0 -1
  153. package/frontend/components/dashboard/taxonomy/MetaContainer.astro +0 -2
  154. package/frontend/components/dashboard/taxonomy/PageHeader.astro +16 -24
  155. package/frontend/components/dashboard/taxonomy/TaxonomySearch.astro +23 -27
  156. package/frontend/components/dashboard/user-mgmt/InnerSidebarElement.astro +111 -104
  157. package/frontend/components/dashboard/user-mgmt/UserListItem.astro +9 -22
  158. package/frontend/components/dashboard/user-mgmt/UserListItems.astro +18 -0
  159. package/frontend/components/first-time-setup/snippets/{opt2-studiocms.config.diff → studiocms.config.diff} +1 -0
  160. package/frontend/components/shared/Code.astro +1 -4
  161. package/frontend/components/shared/DynamicSettingsRenderer.astro +1 -1
  162. package/frontend/components/shared/SSRUser.astro +2 -4
  163. package/frontend/components/shared/foldertree/FolderTreeNode.astro +0 -6
  164. package/frontend/components/shared/storage-manager/StorageCopyOutput.astro +0 -1
  165. package/frontend/components/shared/taxonomy/TaxonomyTreeNode.astro +0 -6
  166. package/frontend/layouts/DashboardLayout.astro +1 -10
  167. package/frontend/layouts/TaxonomyLayout.astro +0 -1
  168. package/frontend/middleware/index.ts +102 -61
  169. package/frontend/pages/404.astro +5 -9
  170. package/frontend/pages/[dashboard]/[...pluginPage].astro +10 -1
  171. package/frontend/pages/[dashboard]/configuration.astro +10 -1
  172. package/frontend/pages/[dashboard]/content-management/createfolder.astro +10 -1
  173. package/frontend/pages/[dashboard]/content-management/createpage.astro +10 -1
  174. package/frontend/pages/[dashboard]/content-management/diff.astro +39 -14
  175. package/frontend/pages/[dashboard]/content-management/editfolder.astro +10 -1
  176. package/frontend/pages/[dashboard]/content-management/editpage.astro +10 -1
  177. package/frontend/pages/[dashboard]/content-management/index.astro +10 -1
  178. package/frontend/pages/[dashboard]/index.astro +10 -1
  179. package/frontend/pages/[dashboard]/login.astro +86 -25
  180. package/frontend/pages/[dashboard]/password-reset.astro +22 -16
  181. package/frontend/pages/[dashboard]/plugins/[plugin].astro +10 -1
  182. package/frontend/pages/[dashboard]/profile.astro +10 -1
  183. package/frontend/pages/[dashboard]/signup.astro +153 -52
  184. package/frontend/pages/[dashboard]/smtp-configuration.astro +77 -75
  185. package/frontend/pages/[dashboard]/system-management.astro +10 -1
  186. package/frontend/pages/[dashboard]/taxonomy/categories.astro +30 -41
  187. package/frontend/pages/[dashboard]/taxonomy/index.astro +10 -0
  188. package/frontend/pages/[dashboard]/taxonomy/tags.astro +33 -43
  189. package/frontend/pages/[dashboard]/unverified-email.astro +29 -21
  190. package/frontend/pages/[dashboard]/user-management/edit.astro +170 -90
  191. package/frontend/pages/[dashboard]/user-management/index.astro +10 -1
  192. package/frontend/pages/studiocms_api/[...all].ts +106 -0
  193. package/frontend/pages/studiocms_api/_handlers/_utils/auth.ts +26 -0
  194. package/frontend/pages/studiocms_api/_handlers/_utils/changelog.ts +147 -0
  195. package/frontend/pages/studiocms_api/_handlers/_utils/db-studio-driver.ts +46 -0
  196. package/frontend/pages/studiocms_api/_handlers/_utils/parseLogLevel.ts +27 -0
  197. package/frontend/pages/studiocms_api/_handlers/auth/auth.ts +459 -0
  198. package/frontend/pages/studiocms_api/_handlers/auth/index.ts +17 -0
  199. package/frontend/pages/studiocms_api/_handlers/auth/oauth.ts +91 -0
  200. package/frontend/pages/studiocms_api/_handlers/dashboard/_shared.ts +57 -0
  201. package/frontend/pages/studiocms_api/_handlers/dashboard/apiTokens.ts +134 -0
  202. package/frontend/pages/studiocms_api/_handlers/dashboard/config.ts +64 -0
  203. package/frontend/pages/studiocms_api/_handlers/dashboard/content.ts +741 -0
  204. package/frontend/pages/studiocms_api/_handlers/dashboard/create.ts +480 -0
  205. package/frontend/pages/studiocms_api/_handlers/dashboard/emailNotifications.ts +49 -0
  206. package/frontend/pages/studiocms_api/_handlers/dashboard/index.ts +45 -0
  207. package/frontend/pages/studiocms_api/_handlers/dashboard/mailer.ts +136 -0
  208. package/frontend/pages/studiocms_api/_handlers/dashboard/plugins.ts +80 -0
  209. package/frontend/pages/studiocms_api/_handlers/dashboard/profile.ts +275 -0
  210. package/frontend/pages/studiocms_api/_handlers/dashboard/resetPassword.ts +140 -0
  211. package/frontend/pages/studiocms_api/_handlers/dashboard/search.ts +63 -0
  212. package/frontend/pages/studiocms_api/_handlers/dashboard/taxonomy.ts +285 -0
  213. package/frontend/pages/studiocms_api/_handlers/dashboard/templates.ts +75 -0
  214. package/frontend/pages/studiocms_api/_handlers/dashboard/users.ts +312 -0
  215. package/frontend/pages/studiocms_api/_handlers/dashboard/verifyEndpoints.ts +307 -0
  216. package/frontend/pages/studiocms_api/_handlers/integration/dbStudio.ts +98 -0
  217. package/frontend/pages/studiocms_api/_handlers/integration/index.ts +17 -0
  218. package/frontend/pages/studiocms_api/_handlers/integration/storageManager.ts +107 -0
  219. package/frontend/pages/studiocms_api/_handlers/rest-api/index.ts +8 -0
  220. package/frontend/pages/studiocms_api/_handlers/rest-api/v1/_shared.ts +41 -0
  221. package/frontend/pages/studiocms_api/_handlers/rest-api/v1/index.ts +17 -0
  222. package/frontend/pages/studiocms_api/_handlers/rest-api/v1/public.ts +195 -0
  223. package/frontend/pages/studiocms_api/_handlers/rest-api/v1/secure.ts +1726 -0
  224. package/frontend/pages/studiocms_api/_handlers/sdk.ts +129 -0
  225. package/frontend/pages/studiocms_api/_middleware/astroLocals.ts +36 -0
  226. package/frontend/pages/studiocms_api/_middleware/restApi.ts +56 -0
  227. package/frontend/pages/studiocms_api/integrations/[...all].ts +8 -0
  228. package/frontend/scripts/formdata.ts +219 -0
  229. package/frontend/setup-pages/3-done.astro +4 -20
  230. package/frontend/setup-pages/studiocms_api/dashboard/step-2.ts +3 -6
  231. package/frontend/styles/dashboard-base.css +0 -1
  232. package/frontend/web-vitals/endpoint.ts +2 -1
  233. package/package.json +35 -31
  234. package/dist/global.d.ts +0 -9
  235. package/frontend/components/dashboard/LoginChecker.astro +0 -68
  236. package/frontend/components/dashboard/user-mgmt/RankCheck.astro +0 -57
  237. package/frontend/components/first-time-setup/snippets/opt1-astro.config.diff +0 -14
  238. package/frontend/components/first-time-setup/snippets/opt2-astro.config.diff +0 -9
  239. package/frontend/middleware/_authmap.ts +0 -63
  240. package/frontend/pages/studiocms_api/auth/[path].ts +0 -390
  241. package/frontend/pages/studiocms_api/auth/[provider]/[...id].ts +0 -64
  242. package/frontend/pages/studiocms_api/auth/[provider]/_effects/index.ts +0 -101
  243. package/frontend/pages/studiocms_api/auth/_shared.ts +0 -52
  244. package/frontend/pages/studiocms_api/dashboard/api-tokens.ts +0 -115
  245. package/frontend/pages/studiocms_api/dashboard/config.ts +0 -74
  246. package/frontend/pages/studiocms_api/dashboard/content/diff.ts +0 -73
  247. package/frontend/pages/studiocms_api/dashboard/content/folder.ts +0 -220
  248. package/frontend/pages/studiocms_api/dashboard/content/page.ts +0 -359
  249. package/frontend/pages/studiocms_api/dashboard/create-reset-link.ts +0 -77
  250. package/frontend/pages/studiocms_api/dashboard/create-user-invite.ts +0 -231
  251. package/frontend/pages/studiocms_api/dashboard/create-user.ts +0 -186
  252. package/frontend/pages/studiocms_api/dashboard/email-notification-settings-site.ts +0 -74
  253. package/frontend/pages/studiocms_api/dashboard/mailer/check-email.ts +0 -75
  254. package/frontend/pages/studiocms_api/dashboard/mailer/config.ts +0 -136
  255. package/frontend/pages/studiocms_api/dashboard/plugins/[plugin].ts +0 -80
  256. package/frontend/pages/studiocms_api/dashboard/profile.ts +0 -245
  257. package/frontend/pages/studiocms_api/dashboard/resend-verify-email.ts +0 -77
  258. package/frontend/pages/studiocms_api/dashboard/reset-password.ts +0 -124
  259. package/frontend/pages/studiocms_api/dashboard/search-list.ts +0 -59
  260. package/frontend/pages/studiocms_api/dashboard/taxonomy-search.ts +0 -47
  261. package/frontend/pages/studiocms_api/dashboard/taxonomy.ts +0 -230
  262. package/frontend/pages/studiocms_api/dashboard/templates.ts +0 -74
  263. package/frontend/pages/studiocms_api/dashboard/update-user-notifications.ts +0 -86
  264. package/frontend/pages/studiocms_api/dashboard/users.ts +0 -236
  265. package/frontend/pages/studiocms_api/dashboard/verify-email.ts +0 -83
  266. package/frontend/pages/studiocms_api/dashboard/verify-session.ts +0 -187
  267. package/frontend/pages/studiocms_api/integrations/[type]/[...id].ts +0 -15
  268. package/frontend/pages/studiocms_api/integrations/[type]/_routes/db-studio.ts +0 -173
  269. package/frontend/pages/studiocms_api/integrations/[type]/_routes/storage.ts +0 -88
  270. package/frontend/pages/studiocms_api/partials/editor.astro +0 -74
  271. package/frontend/pages/studiocms_api/partials/render.astro +0 -39
  272. package/frontend/pages/studiocms_api/partials/user-list-items.astro +0 -43
  273. package/frontend/pages/studiocms_api/rest/utils/auth-token.ts +0 -59
  274. package/frontend/pages/studiocms_api/rest/v1/[type]/[...id].ts +0 -23
  275. package/frontend/pages/studiocms_api/rest/v1/[type]/_routes/categories.ts +0 -267
  276. package/frontend/pages/studiocms_api/rest/v1/[type]/_routes/folders.ts +0 -283
  277. package/frontend/pages/studiocms_api/rest/v1/[type]/_routes/pages.ts +0 -505
  278. package/frontend/pages/studiocms_api/rest/v1/[type]/_routes/settings.ts +0 -100
  279. package/frontend/pages/studiocms_api/rest/v1/[type]/_routes/tags.ts +0 -229
  280. package/frontend/pages/studiocms_api/rest/v1/[type]/_routes/users.ts +0 -553
  281. package/frontend/pages/studiocms_api/rest/v1/public/[type]/[...id].ts +0 -19
  282. package/frontend/pages/studiocms_api/rest/v1/public/[type]/_routes/categories.ts +0 -74
  283. package/frontend/pages/studiocms_api/rest/v1/public/[type]/_routes/folders.ts +0 -85
  284. package/frontend/pages/studiocms_api/rest/v1/public/[type]/_routes/pages.ts +0 -103
  285. package/frontend/pages/studiocms_api/rest/v1/public/[type]/_routes/tags.ts +0 -67
  286. package/frontend/pages/studiocms_api/sdk/[...path].ts +0 -97
  287. package/frontend/pages/studiocms_api/sdk/utils/changelog.ts +0 -119
  288. package/frontend/scripts/auth/formListener.ts +0 -81
  289. package/frontend/scripts/formdata-utils.ts +0 -116
  290. package/frontend/utils/build-partial-schema.ts +0 -46
  291. package/frontend/utils/errors.ts +0 -6
  292. package/frontend/utils/param-extractor.ts +0 -83
  293. package/frontend/utils/rest-router.ts +0 -444
package/dist/global.d.ts DELETED
@@ -1,9 +0,0 @@
1
- import type { BasePluginHooks, StorageManagerPluginHooks } from './schemas/plugins';
2
-
3
- // The interfaces in this file can be extended by users
4
- declare global {
5
- namespace StudioCMS {
6
- export interface PluginHooks extends BasePluginHooks {}
7
- export interface StorageManagerHooks extends BasePluginHooks, StorageManagerPluginHooks {}
8
- }
9
- }
@@ -1,68 +0,0 @@
1
- ---
2
- import { User, VerifyEmail } from 'studiocms:auth/lib';
3
- import type { UserSessionData } from 'studiocms:auth/lib/types';
4
- import type { AvailablePermissionRanks } from '@withstudiocms/auth-kit/types';
5
- import { Effect } from '@withstudiocms/effect';
6
-
7
- interface Props {
8
- requiredPermission: AvailablePermissionRanks;
9
- currentUser: UserSessionData | null;
10
- }
11
-
12
- const { requiredPermission, currentUser } = Astro.props;
13
-
14
- let [isAuthorized, emailVerified] = await Effect.runPromise(
15
- Effect.gen(function* () {
16
- const [{ isUserAllowed }, { isEmailVerified }] = yield* Effect.all([User, VerifyEmail]);
17
-
18
- return yield* Effect.all([
19
- isUserAllowed(currentUser, requiredPermission),
20
- isEmailVerified(currentUser),
21
- ]);
22
- }).pipe(VerifyEmail.Provide)
23
- );
24
-
25
- let redirectProfile = Astro.locals.StudioCMS.routeMap.mainLinks.userProfile;
26
-
27
- if (Astro.locals.StudioCMS.security?.emailVerificationEnabled && emailVerified === false) {
28
- isAuthorized = false;
29
- redirectProfile = Astro.locals.StudioCMS.routeMap.mainLinks.unverifiedEmail;
30
- }
31
-
32
- const redirectLogin = Astro.locals.StudioCMS.routeMap.authLinks.loginURL;
33
- ---
34
-
35
- <login-check
36
- data-is-logged-in={`${currentUser?.isLoggedIn ?? false}`}
37
- data-authorized={`${isAuthorized}`}
38
- data-redirect-profile={redirectProfile}
39
- data-redirect-login={redirectLogin}
40
- style="display: none;"></login-check>
41
-
42
- <script>
43
- if (!customElements.get("login-check")) {
44
- class LoginCheck extends HTMLElement {
45
- constructor() {
46
- super();
47
- const authorized = this.dataset.authorized;
48
- const isLoggedIn = this.dataset.isLoggedIn;
49
- const redirectProfile = this.dataset.redirectProfile;
50
- const redirectLogin = this.dataset.redirectLogin;
51
-
52
- if (isLoggedIn === "false") {
53
- window.location.href = redirectLogin!;
54
- }
55
-
56
- if (window.location.pathname === redirectProfile) {
57
- return;
58
- }
59
-
60
- if (authorized === "false") {
61
- window.location.href = redirectProfile!;
62
- }
63
- }
64
- }
65
-
66
- customElements.define("login-check", LoginCheck);
67
- }
68
- </script>
@@ -1,57 +0,0 @@
1
- ---
2
- import { User } from 'studiocms:auth/lib';
3
- import type { AvailablePermissionRanks } from '@withstudiocms/auth-kit/types';
4
- import { Effect } from '@withstudiocms/effect';
5
-
6
- interface Props {
7
- requiredPermission?: AvailablePermissionRanks;
8
- }
9
-
10
- const { requiredPermission = 'unknown' } = Astro.props;
11
-
12
- const { userSessionData: user } = Astro.locals.StudioCMS?.security ?? {
13
- userSessionData: null,
14
- };
15
-
16
- const isAuthorized = await Effect.runPromise(
17
- Effect.gen(function* () {
18
- const { isUserAllowed } = yield* User;
19
- return yield* isUserAllowed(user, requiredPermission);
20
- })
21
- );
22
-
23
- if (!isAuthorized) {
24
- return Astro.redirect(Astro.locals.StudioCMS.routeMap.mainLinks.userManagement);
25
- }
26
- ---
27
-
28
- {
29
- /*
30
-
31
- // OLD CODE FOR STATIC/HYBRID Setup
32
-
33
- <rank-check
34
- data-authorized={`${isAuthorized}`}
35
- data-redirect={StudioCMSRoutes.mainLinks.userManagement}
36
- style="display: hidden;"
37
- ></rank-check>
38
-
39
- <script>
40
- if (!customElements.get('rank-check')) {
41
- class RankCheck extends HTMLElement {
42
- constructor() {
43
- super();
44
- const authorized = this.dataset.authorized;
45
- const redirect = this.dataset.redirect;
46
-
47
- if (authorized === 'false') {
48
- window.location.href = redirect!;
49
- }
50
- }
51
- }
52
-
53
- customElements.define('rank-check', RankCheck);
54
- }
55
- </script>
56
- */
57
- }
@@ -1,14 +0,0 @@
1
- import db from '@astrojs/db';
2
- import { defineConfig } from 'astro/config';
3
- import studioCMS from 'studiocms';
4
-
5
- // https://astro.build/config
6
- export default defineConfig({
7
- // other config options,
8
- integrations: [
9
- db(),
10
- studioCMS({
11
- dbStartPage: false,
12
- }),
13
- ],
14
- });
@@ -1,9 +0,0 @@
1
- import db from '@astrojs/db';
2
- import { defineConfig } from 'astro/config';
3
- import studioCMS from 'studiocms';
4
-
5
- // https://astro.build/config
6
- export default defineConfig({
7
- // other config options,
8
- integrations: [db(), studioCMS()],
9
- });
@@ -1,63 +0,0 @@
1
- import { dashboardConfig } from 'studiocms:config';
2
-
3
- type AuthenticatedRoute = {
4
- pathname: string;
5
- requiredPermissionLevel: 'owner' | 'admin' | 'editor' | 'visitor';
6
- };
7
-
8
- // Import the dashboard route override from the configuration
9
- // If no override is set, it defaults to 'dashboard'
10
- // This allows for flexibility in the dashboard route without hardcoding it
11
- const dashboardRoute = dashboardConfig.dashboardRouteOverride || 'dashboard';
12
-
13
- /**
14
- * List of authenticated routes with their required permission levels.
15
- * This list is used to determine if a user has the necessary permissions
16
- * to access specific dashboard routes.
17
- */
18
- export const authenticatedRoutes: AuthenticatedRoute[] = [
19
- {
20
- pathname: `/${dashboardRoute}/system-management`,
21
- requiredPermissionLevel: 'owner',
22
- },
23
- {
24
- pathname: `/${dashboardRoute}/smtp-configuration`,
25
- requiredPermissionLevel: 'owner',
26
- },
27
- {
28
- pathname: `/${dashboardRoute}`,
29
- requiredPermissionLevel: 'editor',
30
- },
31
- {
32
- pathname: `/${dashboardRoute}/user-management`,
33
- requiredPermissionLevel: 'admin',
34
- },
35
- {
36
- pathname: `/${dashboardRoute}/user-management/**`,
37
- requiredPermissionLevel: 'admin',
38
- },
39
- {
40
- pathname: `/${dashboardRoute}/taxonomy`,
41
- requiredPermissionLevel: 'editor',
42
- },
43
- {
44
- pathname: `/${dashboardRoute}/taxonomy/categories`,
45
- requiredPermissionLevel: 'editor',
46
- },
47
- {
48
- pathname: `/${dashboardRoute}/taxonomy/tags`,
49
- requiredPermissionLevel: 'editor',
50
- },
51
- {
52
- pathname: `/${dashboardRoute}/plugins/**`,
53
- requiredPermissionLevel: 'editor',
54
- },
55
- {
56
- pathname: `/${dashboardRoute}/content-management`,
57
- requiredPermissionLevel: 'editor',
58
- },
59
- {
60
- pathname: `/${dashboardRoute}/content-management/**`,
61
- requiredPermissionLevel: 'editor',
62
- },
63
- ];
@@ -1,390 +0,0 @@
1
- import { site } from 'astro:config/server';
2
- import { Password, Session, User, VerifyEmail } from 'studiocms:auth/lib';
3
- import { authConfig, developerConfig } from 'studiocms:config';
4
- import { StudioCMSRoutes } from 'studiocms:lib';
5
- import logger, { apiResponseLogger } from 'studiocms:logger';
6
- import { Mailer } from 'studiocms:mailer';
7
- import { Notifications } from 'studiocms:notifier';
8
- import { SDKCore } from 'studiocms:sdk';
9
- import templateEngine from 'studiocms:template-engine';
10
- import {
11
- AllResponse,
12
- appendSearchParamsToUrl,
13
- createEffectAPIRoutes,
14
- createJsonResponse,
15
- Effect,
16
- genLogger,
17
- type HTTPMethod,
18
- Layer,
19
- OptionsResponse,
20
- pipe,
21
- pipeLogger,
22
- } from '@withstudiocms/effect';
23
- import { AuthSessionCookieName } from '#consts';
24
- import { createSimplePathRouter } from '#frontend/utils/rest-router.js';
25
- import { AuthAPIUtils } from './_shared';
26
-
27
- const loginRegisterDependencies = Layer.mergeAll(AuthAPIUtils.Default, VerifyEmail.Default);
28
- const forgotPasswordDependencies = Layer.mergeAll(
29
- Mailer.Default,
30
- Notifications.Default,
31
- AuthAPIUtils.Default
32
- );
33
-
34
- /**
35
- * Generates a password reset link using the provided token and context.
36
- * The link is constructed using the main links from the route map and appending
37
- * the user ID, token, and token ID as search parameters.
38
- *
39
- * @param token - An object containing the token details (id, userId, token).
40
- * @param context - The API context containing the route map for generating the link.
41
- * @returns A URL object representing the password reset link.
42
- */
43
- function generateResetLink(token: { id: string; userId: string; token: string }) {
44
- return pipe(
45
- new URL(StudioCMSRoutes.mainLinks.passwordReset, site),
46
- appendSearchParamsToUrl('userid', token.userId),
47
- appendSearchParamsToUrl('token', token.token),
48
- appendSearchParamsToUrl('id', token.id)
49
- );
50
- }
51
-
52
- const usernameAndPasswordRoutesEnabled =
53
- authConfig.enabled && authConfig.providers.usernameAndPassword;
54
- const userRegistrationEnabled =
55
- authConfig.enabled && authConfig.providers.usernameAndPasswordConfig.allowUserRegistration;
56
-
57
- const onError = (error: unknown) => {
58
- const errorDetails = error instanceof Error ? error.message : String(error);
59
- logger.error(`API Error: ${errorDetails}`);
60
- return createJsonResponse(
61
- { error: 'Internal Server Error' },
62
- {
63
- status: 500,
64
- }
65
- );
66
- };
67
-
68
- const sharedHandlers = {
69
- OPTIONS: () => Effect.try(() => OptionsResponse({ allowedMethods: ['POST'] })),
70
- ALL: () => Effect.try(() => AllResponse()),
71
- };
72
-
73
- const cors: {
74
- methods: HTTPMethod[];
75
- } = {
76
- methods: ['POST', 'OPTIONS'],
77
- };
78
-
79
- const router = {
80
- 'forgot-password': createEffectAPIRoutes(
81
- {
82
- POST: (ctx) =>
83
- genLogger('studiocms/routes/api/auth/forgot-password/POST')(function* () {
84
- const [sdk, { sendMail }, { sendAdminNotification }, { readJson, validateEmail }] =
85
- yield* Effect.all([SDKCore, Mailer, Notifications, AuthAPIUtils]);
86
-
87
- if (!usernameAndPasswordRoutesEnabled) {
88
- return apiResponseLogger(403, 'Username and password routes are disabled.');
89
- }
90
-
91
- // Check if demo mode is enabled
92
- if (developerConfig.demoMode !== false) {
93
- return apiResponseLogger(403, 'Demo mode is enabled, this action is not allowed.');
94
- }
95
-
96
- // Check if the mailer is enabled
97
- const config = ctx.locals.StudioCMS.siteConfig.data;
98
-
99
- // If the mailer is not enabled, return an error
100
- if (!config.enableMailer) {
101
- return apiResponseLogger(500, 'Mailer is not enabled');
102
- }
103
-
104
- // Parse the request body as JSON
105
- const jsonData = yield* readJson(ctx);
106
-
107
- // Get the email from the JSON data
108
- const { email } = jsonData;
109
-
110
- // If the email is not provided, return an error
111
- if (!email) {
112
- return apiResponseLogger(400, 'Invalid form data, email is required');
113
- }
114
-
115
- // If the email is invalid, return an error
116
- const checkEmail = yield* validateEmail(email);
117
-
118
- if (!checkEmail.success) {
119
- return apiResponseLogger(400, checkEmail.error.message);
120
- }
121
-
122
- // Search for the user by email
123
- const { emailSearch } = yield* sdk.AUTH.user.searchUsersForUsernameOrEmail(
124
- '',
125
- checkEmail.data
126
- );
127
-
128
- // If no user is found, return an error
129
- // If no user is found, return a generic success to avoid account enumeration
130
- if (emailSearch.length === 0) {
131
- return apiResponseLogger(
132
- 200,
133
- 'If an account exists for this email, a reset link has been sent.'
134
- );
135
- }
136
-
137
- // Get the first user from the search results
138
- const user = emailSearch[0];
139
-
140
- // Create a new reset token for the user
141
- const token = yield* sdk.resetTokenBucket.new(user.id);
142
-
143
- // If the token could not be created, return an error
144
- if (!token) {
145
- return apiResponseLogger(500, 'Failed to create reset link');
146
- }
147
-
148
- // Send an admin notification that the user has been updated
149
- yield* sendAdminNotification('user_updated', user.username);
150
-
151
- // Generate the reset link using the token and context
152
- const resetLink = generateResetLink(token);
153
-
154
- // If the user does not have an email address, return an error
155
- // This should not happen, but we check it just in case
156
- // as the user may have been created without an email address
157
- // or the email address may have been removed
158
- // after the user was created.
159
- if (!user.email) {
160
- return apiResponseLogger(500, 'Failed to send email to user, no email address found');
161
- }
162
-
163
- // Get the HTML template for the password reset email
164
- const engine = yield* templateEngine;
165
- const { title: siteTitle, description, siteIcon } = config;
166
-
167
- const passwordResetTemplate = yield* engine.render('passwordReset', {
168
- site: { title: siteTitle, description, icon: siteIcon ?? undefined },
169
- data: { link: resetLink.toString() },
170
- });
171
-
172
- // Send the password reset email to the user
173
- const mailRes = yield* sendMail({
174
- to: user.email,
175
- subject: 'Password Reset',
176
- html: passwordResetTemplate,
177
- });
178
-
179
- // If the email could not be sent, return an error
180
- if (!mailRes) {
181
- return apiResponseLogger(500, 'Failed to send email to user');
182
- }
183
-
184
- // If the email response contains an error, return the error
185
- if ('error' in mailRes) {
186
- return apiResponseLogger(500, `Failed to send email to user: ${mailRes.error}`);
187
- }
188
-
189
- // Always return a generic success response
190
- return apiResponseLogger(
191
- 200,
192
- 'If an account exists for this email, a reset link has been sent.'
193
- );
194
- }).pipe(Effect.provide(forgotPasswordDependencies)),
195
- ...sharedHandlers,
196
- },
197
- {
198
- cors,
199
- onError,
200
- }
201
- ),
202
- login: createEffectAPIRoutes(
203
- {
204
- POST: (ctx) =>
205
- genLogger('studiocms/routes/api/auth/login/POST')(function* () {
206
- const [
207
- sdk,
208
- { badFormDataEntry, parseFormDataEntryToString, readFormData },
209
- { verifyPasswordHash },
210
- { createUserSession },
211
- { isEmailVerified },
212
- ] = yield* Effect.all([SDKCore, AuthAPIUtils, Password, Session, VerifyEmail]);
213
-
214
- if (!usernameAndPasswordRoutesEnabled) {
215
- return apiResponseLogger(403, 'Username and password routes are disabled.');
216
- }
217
-
218
- const formData = yield* readFormData(ctx);
219
-
220
- const [username, password] = yield* pipeLogger(
221
- 'studiocms/routes/api/auth/login/POST.parseFormData'
222
- )(
223
- Effect.all([
224
- parseFormDataEntryToString(formData, 'username'),
225
- parseFormDataEntryToString(formData, 'password'),
226
- ])
227
- );
228
-
229
- if (!username)
230
- return yield* badFormDataEntry('Invalid credentials', 'Invalid credentials');
231
- if (!password)
232
- return yield* badFormDataEntry('Invalid credentials', 'Invalid credentials');
233
-
234
- const existingUser = yield* sdk.GET.users.byUsername(username);
235
-
236
- // If the user does not exist, return an ambiguous error
237
- if (!existingUser)
238
- return yield* badFormDataEntry('Invalid credentials', 'Invalid credentials');
239
-
240
- // Check if the user has a password or is using a oAuth login
241
- if (!existingUser.password)
242
- return yield* badFormDataEntry('Invalid credentials', 'Invalid credentials');
243
-
244
- const validPassword = yield* verifyPasswordHash(existingUser.password, password);
245
-
246
- if (!validPassword)
247
- return yield* badFormDataEntry('Invalid credentials', 'Invalid credentials');
248
-
249
- const isEmailAccountVerified = yield* isEmailVerified(existingUser);
250
-
251
- // If the email is not verified, return an error
252
- if (!isEmailAccountVerified)
253
- return yield* badFormDataEntry(
254
- 'Email not verified',
255
- 'Please verify your email before logging in'
256
- );
257
-
258
- yield* createUserSession(existingUser.id, ctx);
259
-
260
- return new Response();
261
- }).pipe(Effect.provide(loginRegisterDependencies)),
262
- ...sharedHandlers,
263
- },
264
- {
265
- cors,
266
- onError,
267
- }
268
- ),
269
- logout: createEffectAPIRoutes(
270
- {
271
- POST: (ctx) =>
272
- genLogger('studiocms/routes/api/auth/logout/POST')(function* () {
273
- const { validateSessionToken, deleteSessionTokenCookie, invalidateSession } =
274
- yield* Session;
275
-
276
- const { cookies, redirect } = ctx;
277
-
278
- const sessionToken = cookies.get(AuthSessionCookieName)?.value ?? null;
279
-
280
- if (!sessionToken) return redirect(StudioCMSRoutes.authLinks.loginURL);
281
-
282
- const { session, user } = yield* validateSessionToken(sessionToken);
283
-
284
- // If there is no session, redirect to the login page
285
- if (session === null) {
286
- yield* deleteSessionTokenCookie(ctx);
287
- return redirect(StudioCMSRoutes.authLinks.loginURL);
288
- }
289
-
290
- // If there is no user, delete cookie and redirect to the login page
291
- if (!user || user === null) {
292
- yield* deleteSessionTokenCookie(ctx);
293
- return redirect(StudioCMSRoutes.authLinks.loginURL);
294
- }
295
-
296
- // Invalidate the session and delete the session token cookie
297
- yield* Effect.all([invalidateSession(session.id), deleteSessionTokenCookie(ctx)]);
298
-
299
- return redirect(StudioCMSRoutes.mainLinks.baseSiteURL);
300
- }),
301
- ...sharedHandlers,
302
- },
303
- {
304
- cors,
305
- onError,
306
- }
307
- ),
308
- register: createEffectAPIRoutes(
309
- {
310
- POST: (ctx) =>
311
- genLogger('studiocms/routes/api/auth/register/POST')(function* () {
312
- const [
313
- sdk,
314
- { badFormDataEntry, parseFormDataEntryToString, readFormData, validateEmail },
315
- { verifyUsernameInput, createLocalUser },
316
- { sendVerificationEmail },
317
- { verifyPasswordStrength },
318
- { createUserSession },
319
- ] = yield* Effect.all([SDKCore, AuthAPIUtils, User, VerifyEmail, Password, Session]);
320
-
321
- if (!userRegistrationEnabled) {
322
- return apiResponseLogger(403, 'User registration is disabled.');
323
- }
324
-
325
- const formData = yield* readFormData(ctx);
326
-
327
- const [username, password, email, name] = yield* pipeLogger(
328
- 'studiocms/routes/api/auth/register/POST.parseFormData'
329
- )(
330
- Effect.all([
331
- parseFormDataEntryToString(formData, 'username'),
332
- parseFormDataEntryToString(formData, 'password'),
333
- parseFormDataEntryToString(formData, 'email'),
334
- parseFormDataEntryToString(formData, 'displayname'),
335
- ])
336
- );
337
-
338
- if (!username) return yield* badFormDataEntry('MISSING_USERNAME', 'Username is required');
339
- if (!password) return yield* badFormDataEntry('MISSING_PASSWORD', 'Password is required');
340
- if (!email) return yield* badFormDataEntry('MISSING_EMAIL', 'Email is required');
341
- if (!name)
342
- return yield* badFormDataEntry('MISSING_DISPLAY_NAME', 'Display name is required');
343
-
344
- const verifyUsernameResponse = yield* verifyUsernameInput(username);
345
- if (verifyUsernameResponse !== true)
346
- return yield* badFormDataEntry('Invalid username', verifyUsernameResponse);
347
-
348
- // If the password is invalid, return an error
349
- const verifyPasswordResponse = yield* verifyPasswordStrength(password);
350
- if (verifyPasswordResponse !== true) {
351
- return yield* badFormDataEntry('Invalid password', verifyPasswordResponse);
352
- }
353
-
354
- const checkEmail = yield* validateEmail(email);
355
-
356
- if (!checkEmail.success)
357
- return yield* badFormDataEntry('Invalid email', checkEmail.error.message);
358
-
359
- const invalidEmailDomains: string[] = ['example.com', 'test.com', 'testing.com'];
360
-
361
- if (invalidEmailDomains.includes(checkEmail.data.split('@')[1])) {
362
- return yield* badFormDataEntry('Invalid Email', 'Must be from a valid domain');
363
- }
364
-
365
- const { usernameSearch, emailSearch } =
366
- yield* sdk.AUTH.user.searchUsersForUsernameOrEmail(username, checkEmail.data);
367
-
368
- if (usernameSearch.length > 0)
369
- return yield* badFormDataEntry('Invalid username', 'Username is already in use');
370
- if (emailSearch.length > 0)
371
- return yield* badFormDataEntry('Invalid email', 'Email is already in use');
372
-
373
- const newUser = yield* createLocalUser(name, username, email, password);
374
-
375
- yield* sendVerificationEmail(newUser.id);
376
-
377
- yield* createUserSession(newUser.id, ctx);
378
-
379
- return new Response();
380
- }).pipe(Effect.provide(loginRegisterDependencies)),
381
- ...sharedHandlers,
382
- },
383
- {
384
- cors,
385
- onError,
386
- }
387
- ),
388
- };
389
-
390
- export const ALL = createSimplePathRouter('studiocms:auth', router);
@@ -1,64 +0,0 @@
1
- import {
2
- AllResponse,
3
- createEffectAPIRoutes,
4
- createJsonResponse,
5
- Effect,
6
- genLogger,
7
- OptionsResponse,
8
- } from '@withstudiocms/effect';
9
- import { createSimplePathRouter } from '#frontend/utils/rest-router.js';
10
- import { OAuthAPIEffect } from './_effects';
11
-
12
- const indexRoute = createEffectAPIRoutes(
13
- {
14
- GET: (ctx) =>
15
- genLogger('studiocms/routes/api/auth/[provider]/index.GET')(function* () {
16
- const { initSession } = yield* OAuthAPIEffect;
17
- return yield* initSession(ctx);
18
- }).pipe(OAuthAPIEffect.Provide),
19
- OPTIONS: () => Effect.try(() => OptionsResponse({ allowedMethods: ['GET'] })),
20
- ALL: () => Effect.try(() => AllResponse()),
21
- },
22
- {
23
- cors: { methods: ['GET', 'OPTIONS'] },
24
- onError: (error) => {
25
- console.error('API Error:', error);
26
- return createJsonResponse(
27
- { error: 'Internal Server Error' },
28
- {
29
- status: 500,
30
- }
31
- );
32
- },
33
- }
34
- );
35
-
36
- const router = {
37
- __index: indexRoute,
38
- index: indexRoute,
39
- callback: createEffectAPIRoutes(
40
- {
41
- GET: (ctx) =>
42
- genLogger('studiocms/routes/api/auth/[provider]/callback.GET')(function* () {
43
- const { initCallback } = yield* OAuthAPIEffect;
44
- return yield* initCallback(ctx);
45
- }).pipe(OAuthAPIEffect.Provide),
46
- OPTIONS: () => Effect.try(() => OptionsResponse({ allowedMethods: ['GET'] })),
47
- ALL: () => Effect.try(() => AllResponse()),
48
- },
49
- {
50
- cors: { methods: ['GET', 'OPTIONS'] },
51
- onError: (error) => {
52
- console.error('API Error:', error);
53
- return createJsonResponse(
54
- { error: 'Internal Server Error' },
55
- {
56
- status: 500,
57
- }
58
- );
59
- },
60
- }
61
- ),
62
- };
63
-
64
- export const ALL = createSimplePathRouter('studiocms:auth', router);