@sonicjs-cms/core 3.0.0-beta.2 → 3.0.0-beta.20
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/README.md +48 -49
- package/dist/admin-documents-form.template-DDSH6ROU.js +6 -0
- package/dist/{admin-documents-form.template-NLSI6Z42.js.map → admin-documents-form.template-DDSH6ROU.js.map} +1 -1
- package/dist/admin-documents-form.template-LSZKGA5J.cjs +19 -0
- package/dist/{admin-layout-catalyst.template-WHJGSWWD.js.map → admin-documents-form.template-LSZKGA5J.cjs.map} +1 -1
- package/dist/{filter-bar.template-DlVYMk-T.d.ts → admin-layout-catalyst.template-DrwDUfsE.d.cts} +25 -1
- package/dist/{filter-bar.template-DlVYMk-T.d.cts → admin-layout-catalyst.template-DrwDUfsE.d.ts} +25 -1
- package/dist/admin-layout-catalyst.template-KDHKVLXR.cjs +21 -0
- package/dist/{admin-layout-catalyst.template-ZK5HD545.cjs.map → admin-layout-catalyst.template-KDHKVLXR.cjs.map} +1 -1
- package/dist/admin-layout-catalyst.template-YQ4EMF2J.js +7 -0
- package/dist/{admin-documents-form.template-KN7JF66Q.cjs.map → admin-layout-catalyst.template-YQ4EMF2J.js.map} +1 -1
- package/dist/{app-Bo0X1OWX.d.ts → app-01M0dIwt.d.ts} +1 -1
- package/dist/{app-Do66yCcV.d.cts → app-aj39TGHB.d.cts} +1 -1
- package/dist/{chunk-ZEZ245PW.js → chunk-2XAQTPAE.js} +4 -236
- package/dist/chunk-2XAQTPAE.js.map +1 -0
- package/dist/{chunk-BDDABDAB.cjs → chunk-36Z3AKX3.cjs} +3 -239
- package/dist/chunk-36Z3AKX3.cjs.map +1 -0
- package/dist/{chunk-VXE42MYF.cjs → chunk-3E7IROND.cjs} +695 -428
- package/dist/chunk-3E7IROND.cjs.map +1 -0
- package/dist/{chunk-BLMTL57B.js → chunk-3TMTYJAJ.js} +26 -4
- package/dist/chunk-3TMTYJAJ.js.map +1 -0
- package/dist/{chunk-AAWNRBRB.cjs → chunk-4SHNHNRP.cjs} +95 -20
- package/dist/chunk-4SHNHNRP.cjs.map +1 -0
- package/dist/{chunk-QAYFOER6.cjs → chunk-5ARIHAGN.cjs} +285 -3
- package/dist/chunk-5ARIHAGN.cjs.map +1 -0
- package/dist/{chunk-XW56B23A.cjs → chunk-5RSB5SEK.cjs} +4 -4
- package/dist/{chunk-XW56B23A.cjs.map → chunk-5RSB5SEK.cjs.map} +1 -1
- package/dist/{chunk-VD2EA3WT.js → chunk-5UCMLBRQ.js} +328 -62
- package/dist/chunk-5UCMLBRQ.js.map +1 -0
- package/dist/{chunk-3TB6AT6X.js → chunk-5V62WT6M.js} +35 -4
- package/dist/chunk-5V62WT6M.js.map +1 -0
- package/dist/{chunk-LRZIAW7U.cjs → chunk-AQJEMVAY.cjs} +3 -3
- package/dist/chunk-AQJEMVAY.cjs.map +1 -0
- package/dist/{chunk-WULONYGB.cjs → chunk-CRGUD4KC.cjs} +9 -9
- package/dist/{chunk-WULONYGB.cjs.map → chunk-CRGUD4KC.cjs.map} +1 -1
- package/dist/{chunk-NLJVSER2.js → chunk-DSXEVMOM.js} +3 -2
- package/dist/chunk-DSXEVMOM.js.map +1 -0
- package/dist/{chunk-H2AXVCLS.cjs → chunk-DTGCXWWM.cjs} +141 -74
- package/dist/chunk-DTGCXWWM.cjs.map +1 -0
- package/dist/{chunk-NUKJ54GA.cjs → chunk-GMMCCIQO.cjs} +6 -6
- package/dist/{chunk-NUKJ54GA.cjs.map → chunk-GMMCCIQO.cjs.map} +1 -1
- package/dist/{chunk-6OUHGKFD.js → chunk-GMZ5TGYP.js} +3 -3
- package/dist/{chunk-6OUHGKFD.js.map → chunk-GMZ5TGYP.js.map} +1 -1
- package/dist/{chunk-6JQOUUOB.js → chunk-JQISFW6U.js} +3 -3
- package/dist/{chunk-6JQOUUOB.js.map → chunk-JQISFW6U.js.map} +1 -1
- package/dist/{chunk-NAVPFIG5.cjs → chunk-K623Q6WD.cjs} +35 -3
- package/dist/chunk-K623Q6WD.cjs.map +1 -0
- package/dist/{chunk-JEQ7FLOD.cjs → chunk-KIGVVO6N.cjs} +16 -10
- package/dist/chunk-KIGVVO6N.cjs.map +1 -0
- package/dist/{chunk-2CB4KY7I.cjs → chunk-LTZ5WYOK.cjs} +29 -7
- package/dist/chunk-LTZ5WYOK.cjs.map +1 -0
- package/dist/{chunk-YHSQVQXX.js → chunk-MYQ7KZUQ.js} +135 -68
- package/dist/chunk-MYQ7KZUQ.js.map +1 -0
- package/dist/{chunk-DNQCEKUK.cjs → chunk-N32OWET6.cjs} +5 -5
- package/dist/{chunk-DNQCEKUK.cjs.map → chunk-N32OWET6.cjs.map} +1 -1
- package/dist/{chunk-HDWE5FRJ.js → chunk-OBA2RYZN.js} +3 -3
- package/dist/{chunk-HDWE5FRJ.js.map → chunk-OBA2RYZN.js.map} +1 -1
- package/dist/{chunk-MVIZJOO5.cjs → chunk-PXNTCCPE.cjs} +8 -8
- package/dist/{chunk-MVIZJOO5.cjs.map → chunk-PXNTCCPE.cjs.map} +1 -1
- package/dist/{chunk-ZGGXCFR6.js → chunk-RDH6PUOP.js} +282 -4
- package/dist/chunk-RDH6PUOP.js.map +1 -0
- package/dist/{chunk-EF2NQUIQ.js → chunk-RMRJGMDE.js} +3 -3
- package/dist/{chunk-EF2NQUIQ.js.map → chunk-RMRJGMDE.js.map} +1 -1
- package/dist/{chunk-IVPRUGTY.js → chunk-SOZUG52O.js} +4 -4
- package/dist/{chunk-IVPRUGTY.js.map → chunk-SOZUG52O.js.map} +1 -1
- package/dist/{chunk-DSA4UX5B.cjs → chunk-TQG5FNNR.cjs} +3 -2
- package/dist/chunk-TQG5FNNR.cjs.map +1 -0
- package/dist/{chunk-GCDZZNIN.js → chunk-UWUP2VMT.js} +16 -10
- package/dist/chunk-UWUP2VMT.js.map +1 -0
- package/dist/{chunk-IESEVHXL.js → chunk-VVYVFCML.js} +12 -3
- package/dist/chunk-VVYVFCML.js.map +1 -0
- package/dist/{chunk-NMPEMSU4.js → chunk-W53J3BJ2.js} +3 -3
- package/dist/chunk-W53J3BJ2.js.map +1 -0
- package/dist/{chunk-RZ6H7OZK.js → chunk-WCA4VENG.js} +87 -12
- package/dist/chunk-WCA4VENG.js.map +1 -0
- package/dist/{chunk-HIKBY7MS.cjs → chunk-XWVDSM2L.cjs} +12 -3
- package/dist/chunk-XWVDSM2L.cjs.map +1 -0
- package/dist/{collection-config-JgHOpFCG.d.ts → collection-config-BTzAvKt2.d.cts} +25 -0
- package/dist/{collection-config-JgHOpFCG.d.cts → collection-config-BTzAvKt2.d.ts} +25 -0
- package/dist/config-6FB2BXMP.js +6 -0
- package/dist/{config-HFXANXCC.js.map → config-6FB2BXMP.js.map} +1 -1
- package/dist/config-OCH7S4WK.cjs +19 -0
- package/dist/{config-ON6FNMYX.cjs.map → config-OCH7S4WK.cjs.map} +1 -1
- package/dist/{define-plugin-BzNHc1ZI.d.ts → define-plugin-BYIey6sp.d.ts} +1 -1
- package/dist/{define-plugin-IWDKYaVm.d.cts → define-plugin-DsKiGu1q.d.cts} +1 -1
- package/dist/document-projection-4HG75S5S.js +4 -0
- package/dist/{document-projection-YYMC6I4U.js.map → document-projection-4HG75S5S.js.map} +1 -1
- package/dist/document-projection-JQHSTSFD.cjs +13 -0
- package/dist/{document-projection-TDWRJX3Z.cjs.map → document-projection-JQHSTSFD.cjs.map} +1 -1
- package/dist/index.cjs +928 -378
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +200 -12
- package/dist/index.d.ts +200 -12
- package/dist/index.js +612 -75
- package/dist/index.js.map +1 -1
- package/dist/middleware.cjs +37 -34
- package/dist/middleware.d.cts +2 -2
- package/dist/middleware.d.ts +2 -2
- package/dist/middleware.js +8 -5
- package/dist/migrations-HZJ6U6SX.js +4 -0
- package/dist/{migrations-WCAVBD7C.js.map → migrations-HZJ6U6SX.js.map} +1 -1
- package/dist/migrations-VQAFXMU7.cjs +13 -0
- package/dist/{migrations-NJJWQUKK.cjs.map → migrations-VQAFXMU7.cjs.map} +1 -1
- package/dist/{plugin-bootstrap-B8ThJU21.d.cts → plugin-bootstrap-BHWQ2df8.d.cts} +1 -1
- package/dist/{plugin-bootstrap-qu8hJgUt.d.ts → plugin-bootstrap-Bj4fxX1q.d.ts} +1 -1
- package/dist/plugins.cjs +40 -40
- package/dist/plugins.d.cts +2 -2
- package/dist/plugins.d.ts +2 -2
- package/dist/plugins.js +3 -3
- package/dist/rbac-7QZ4JZ2E.cjs +14 -0
- package/dist/{rbac-VONLJJKB.cjs.map → rbac-7QZ4JZ2E.cjs.map} +1 -1
- package/dist/rbac-Y43IEQOP.js +5 -0
- package/dist/{rbac-O73MFKDA.js.map → rbac-Y43IEQOP.js.map} +1 -1
- package/dist/routes.cjs +34 -34
- package/dist/routes.d.cts +2 -2
- package/dist/routes.d.ts +2 -2
- package/dist/routes.js +14 -14
- package/dist/services.cjs +42 -42
- package/dist/services.d.cts +16 -3
- package/dist/services.d.ts +16 -3
- package/dist/services.js +3 -3
- package/dist/{telemetry-B9vIV4wh.d.cts → telemetry-Cku1ax74.d.cts} +1 -1
- package/dist/{telemetry-B9vIV4wh.d.ts → telemetry-Cku1ax74.d.ts} +1 -1
- package/dist/templates.cjs +17 -17
- package/dist/templates.d.cts +2 -24
- package/dist/templates.d.ts +2 -24
- package/dist/templates.js +3 -3
- package/dist/{types-Dea1eNxU.d.ts → types-DT7XN5TX.d.cts} +1 -1
- package/dist/{types-Dea1eNxU.d.cts → types-DT7XN5TX.d.ts} +1 -1
- package/dist/types.d.cts +2 -2
- package/dist/types.d.ts +2 -2
- package/dist/utils.cjs +8 -8
- package/dist/utils.d.cts +2 -2
- package/dist/utils.d.ts +2 -2
- package/dist/utils.js +2 -2
- package/package.json +1 -1
- package/dist/admin-documents-form.template-KN7JF66Q.cjs +0 -19
- package/dist/admin-documents-form.template-NLSI6Z42.js +0 -6
- package/dist/admin-layout-catalyst.template-WHJGSWWD.js +0 -7
- package/dist/admin-layout-catalyst.template-ZK5HD545.cjs +0 -17
- package/dist/chunk-2CB4KY7I.cjs.map +0 -1
- package/dist/chunk-3TB6AT6X.js.map +0 -1
- package/dist/chunk-AAWNRBRB.cjs.map +0 -1
- package/dist/chunk-BDDABDAB.cjs.map +0 -1
- package/dist/chunk-BLMTL57B.js.map +0 -1
- package/dist/chunk-DSA4UX5B.cjs.map +0 -1
- package/dist/chunk-GCDZZNIN.js.map +0 -1
- package/dist/chunk-H2AXVCLS.cjs.map +0 -1
- package/dist/chunk-HIKBY7MS.cjs.map +0 -1
- package/dist/chunk-IESEVHXL.js.map +0 -1
- package/dist/chunk-JEQ7FLOD.cjs.map +0 -1
- package/dist/chunk-LRZIAW7U.cjs.map +0 -1
- package/dist/chunk-NAVPFIG5.cjs.map +0 -1
- package/dist/chunk-NLJVSER2.js.map +0 -1
- package/dist/chunk-NMPEMSU4.js.map +0 -1
- package/dist/chunk-QAYFOER6.cjs.map +0 -1
- package/dist/chunk-RZ6H7OZK.js.map +0 -1
- package/dist/chunk-VD2EA3WT.js.map +0 -1
- package/dist/chunk-VXE42MYF.cjs.map +0 -1
- package/dist/chunk-YHSQVQXX.js.map +0 -1
- package/dist/chunk-ZEZ245PW.js.map +0 -1
- package/dist/chunk-ZGGXCFR6.js.map +0 -1
- package/dist/config-HFXANXCC.js +0 -6
- package/dist/config-ON6FNMYX.cjs +0 -19
- package/dist/document-projection-TDWRJX3Z.cjs +0 -13
- package/dist/document-projection-YYMC6I4U.js +0 -4
- package/dist/migrations-NJJWQUKK.cjs +0 -13
- package/dist/migrations-WCAVBD7C.js +0 -4
- package/dist/rbac-O73MFKDA.js +0 -5
- package/dist/rbac-VONLJJKB.cjs +0 -14
package/dist/index.js
CHANGED
|
@@ -1,41 +1,43 @@
|
|
|
1
|
-
import { createAuth } from './chunk-
|
|
2
|
-
import { getEmailService, hasEmailService, setEmailService, invalidateVariablesCache, resolveVariablesInObject, resolveDocScope, denyIfNotAllowed, DocumentRepository, dispatchHookEvent, getCustomData, renderTable, getVariablesCached, setVariablesCache, TenantService, isValidMemberRole, renderConfirmationDialog, getConfirmationDialogScript, VALID_MEMBER_ROLES, userProfilesPlugin, lexicalEditorPlugin, api_media_default, api_system_default, apiDocumentsRoutes, api_default, adminDocumentsRoutes, admin_api_default, adminCollectionsRoutes, adminSettingsRoutes, router2, admin_content_default, adminMediaRoutes, router, adminPluginRoutes, adminLogsRoutes, userRoutes, auth_default, test_cleanup_default } from './chunk-
|
|
3
|
-
export { ROUTES_INFO, admin_api_default as adminApiRoutes, adminCheckboxRoutes, adminCollectionsRoutes, admin_content_default as adminContentRoutes, router as adminDashboardRoutes, adminLogsRoutes, adminMediaRoutes, adminPluginRoutes, adminSettingsRoutes, userRoutes as adminUsersRoutes, api_content_crud_default as apiContentCrudRoutes, api_media_default as apiMediaRoutes, api_default as apiRoutes, api_system_default as apiSystemRoutes, auth_default as authRoutes, createUserProfilesPlugin, defineUserProfile, getUserProfileConfig, userProfilesPlugin } from './chunk-
|
|
4
|
-
import './chunk-
|
|
5
|
-
import './chunk-
|
|
6
|
-
import { SettingsService, setAppInstance } from './chunk-
|
|
7
|
-
export { Logger, getLogger, initLogger } from './chunk-
|
|
1
|
+
import { createAuth } from './chunk-SOZUG52O.js';
|
|
2
|
+
import { getEmailService, hasEmailService, setEmailService, invalidateVariablesCache, resolveVariablesInObject, resolveDocScope, denyIfNotAllowed, DocumentRepository, dispatchHookEvent, getCustomData, createDocumentSchema, renderTable, getVariablesCached, setVariablesCache, TenantService, isValidMemberRole, renderConfirmationDialog, getConfirmationDialogScript, VALID_MEMBER_ROLES, userProfilesPlugin, lexicalEditorPlugin, api_media_default, api_system_default, apiDocumentsRoutes, api_default, adminDocumentsRoutes, admin_api_default, adminCollectionsRoutes, adminSettingsRoutes, router2, admin_content_default, adminMediaRoutes, router, adminPluginRoutes, adminLogsRoutes, userRoutes, auth_default, test_cleanup_default } from './chunk-5UCMLBRQ.js';
|
|
3
|
+
export { DocumentRepository, ROUTES_INFO, admin_api_default as adminApiRoutes, adminCheckboxRoutes, adminCollectionsRoutes, admin_content_default as adminContentRoutes, router as adminDashboardRoutes, adminLogsRoutes, adminMediaRoutes, adminPluginRoutes, adminSettingsRoutes, userRoutes as adminUsersRoutes, api_content_crud_default as apiContentCrudRoutes, api_media_default as apiMediaRoutes, api_default as apiRoutes, api_system_default as apiSystemRoutes, auth_default as authRoutes, createUserProfilesPlugin, defineUserProfile, getUserProfileConfig, userProfilesPlugin } from './chunk-5UCMLBRQ.js';
|
|
4
|
+
import './chunk-VVYVFCML.js';
|
|
5
|
+
import './chunk-RMRJGMDE.js';
|
|
6
|
+
import { SettingsService, setAppInstance } from './chunk-2XAQTPAE.js';
|
|
7
|
+
export { Logger, getLogger, initLogger } from './chunk-2XAQTPAE.js';
|
|
8
8
|
import { getAllCacheStats, CACHE_CONFIGS, getCacheService, clearAllCaches, parseCacheKey } from './chunk-K25XHMM3.js';
|
|
9
9
|
import { schema_exports } from './chunk-AI663NBO.js';
|
|
10
10
|
export { apiTokens, content, contentVersions, insertContentSchema, insertLogConfigSchema, insertMediaSchema, insertPluginActivityLogSchema, insertPluginAssetSchema, insertPluginHookSchema, insertPluginRouteSchema, insertPluginSchema, insertSystemLogSchema, insertUserSchema, insertWorkflowHistorySchema, logConfig, media, pluginActivityLog, pluginAssets, pluginHooks, pluginRoutes, plugins, selectContentSchema, selectLogConfigSchema, selectMediaSchema, selectPluginActivityLogSchema, selectPluginAssetSchema, selectPluginHookSchema, selectPluginRouteSchema, selectPluginSchema, selectSystemLogSchema, selectUserSchema, selectWorkflowHistorySchema, systemLogs, users, workflowHistory } from './chunk-AI663NBO.js';
|
|
11
|
-
import { requireAuth, DocumentTypeRegistry, requireRbac, requireRole, getJwtExpirySecondsFromDb, AuthManager, metricsMiddleware, bootstrapMiddleware, securityHeadersMiddleware, csrfProtection } from './chunk-
|
|
12
|
-
export { AuthManager, PermissionManager, bootstrapDocumentTypes, bootstrapMiddleware, cacheHeaders, compressionMiddleware, detailedLoggingMiddleware, getActivePlugins, isPluginActive, logActivity, loggingMiddleware, optionalAuth, performanceLoggingMiddleware, requireActivePlugin, requireActivePlugins, requireAnyPermission, requireAuth, requirePermission, requireRole, securityHeadersMiddleware as securityHeaders, securityLoggingMiddleware } from './chunk-
|
|
13
|
-
import { RbacService, DocumentsService } from './chunk-
|
|
14
|
-
export { RbacService } from './chunk-
|
|
15
|
-
import { nanoid } from './chunk-
|
|
16
|
-
import { PluginService, PLUGIN_REGISTRY, invalidateTenantCache, getCollectionRegistry, TENANT_COOKIE, MULTI_TENANT_PLUGIN_ID, collectionRecordToRow, tenantMiddleware } from './chunk-
|
|
17
|
-
export { PluginBootstrapService, PluginService as PluginServiceClass, getAvailableCollectionNames, loadCollectionConfig, loadCollectionConfigs, registerCollections, validateCollectionConfig } from './chunk-
|
|
18
|
-
export { MigrationService } from './chunk-
|
|
19
|
-
export { renderFilterBar } from './chunk-
|
|
20
|
-
import { renderAdminLayout } from './chunk-
|
|
21
|
-
export { getConfirmationDialogScript, renderAlert, renderConfirmationDialog, renderForm, renderFormField, renderPagination, renderTable } from './chunk-
|
|
22
|
-
import { init_admin_layout_catalyst_template, renderAdminLayoutCatalyst } from './chunk-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
11
|
+
import { requireAuth, DocumentTypeRegistry, requireRbac, requireRole, getJwtExpirySecondsFromDb, AuthManager, metricsMiddleware, bootstrapMiddleware, securityHeadersMiddleware, csrfProtection } from './chunk-WCA4VENG.js';
|
|
12
|
+
export { AuthManager, PermissionManager, bootstrapDocumentTypes, bootstrapMiddleware, cacheHeaders, compressionMiddleware, detailedLoggingMiddleware, getActivePlugins, isPluginActive, logActivity, loggingMiddleware, optionalAuth, performanceLoggingMiddleware, requireActivePlugin, requireActivePlugins, requireAnyPermission, requireAuth, requirePermission, requireRole, securityHeadersMiddleware as securityHeaders, securityLoggingMiddleware } from './chunk-WCA4VENG.js';
|
|
13
|
+
import { RbacService, DocumentsService } from './chunk-3TMTYJAJ.js';
|
|
14
|
+
export { DocumentsService, RbacService } from './chunk-3TMTYJAJ.js';
|
|
15
|
+
import { nanoid } from './chunk-UWUP2VMT.js';
|
|
16
|
+
import { PluginService, PLUGIN_REGISTRY, invalidateTenantCache, getCollectionRegistry, TENANT_COOKIE, MULTI_TENANT_PLUGIN_ID, collectionRecordToRow, tenantMiddleware } from './chunk-RDH6PUOP.js';
|
|
17
|
+
export { PluginBootstrapService, PluginService as PluginServiceClass, getAvailableCollectionNames, loadCollectionConfig, loadCollectionConfigs, registerCollections, validateCollectionConfig } from './chunk-RDH6PUOP.js';
|
|
18
|
+
export { MigrationService } from './chunk-DSXEVMOM.js';
|
|
19
|
+
export { renderFilterBar } from './chunk-JQISFW6U.js';
|
|
20
|
+
import { renderAdminLayout } from './chunk-OBA2RYZN.js';
|
|
21
|
+
export { getConfirmationDialogScript, renderAlert, renderConfirmationDialog, renderForm, renderFormField, renderPagination, renderTable } from './chunk-OBA2RYZN.js';
|
|
22
|
+
import { init_admin_layout_catalyst_template, renderAdminLayoutCatalyst } from './chunk-5V62WT6M.js';
|
|
23
|
+
export { renderAdminLayoutCatalyst } from './chunk-5V62WT6M.js';
|
|
24
|
+
import { TurnstileService, HookSystemImpl, createPluginWirer, registerPluginRoutes, setPluginMenu, resolvePluginMenuItems } from './chunk-MYQ7KZUQ.js';
|
|
25
|
+
export { HookSystemImpl, HookUtils, PluginDependencyCycleError, PluginManager as PluginManagerClass, PluginRegistryImpl, PluginValidator as PluginValidatorClass, RegisterPluginsError, ScopedHookSystem as ScopedHookSystemClass, collectCronSchedules, collectCrons, createScheduledHandler, dispatchCronTick, getPluginMenu, registerPlugins, resetPluginMenu, resolvePluginMenuItems, setPluginMenu, topoSort } from './chunk-MYQ7KZUQ.js';
|
|
26
|
+
import { definePlugin, setPluginDefinitions } from './chunk-GMZ5TGYP.js';
|
|
27
|
+
export { applySchemaDefaults, definePlugin, isDefinedPlugin, parseConfigSchema, parseFormDataToSettings, renderSchemaFields } from './chunk-GMZ5TGYP.js';
|
|
27
28
|
import { setHookSystem } from './chunk-RNZFGN4R.js';
|
|
28
29
|
export { getHookSystem, getTypedHooks, hasHookSystem, resetHookSystem, setHookSystem } from './chunk-RNZFGN4R.js';
|
|
29
30
|
export { QueryFilterBuilder, TemplateRenderer, buildQuery, renderTemplate, templateRenderer } from './chunk-QZGABF2M.js';
|
|
30
|
-
import './chunk-X7ZAEI5S.js';
|
|
31
31
|
export { metricsTracker } from './chunk-FICTAGD4.js';
|
|
32
|
-
import
|
|
33
|
-
|
|
32
|
+
import './chunk-X7ZAEI5S.js';
|
|
33
|
+
import { getCoreVersion, package_default } from './chunk-W53J3BJ2.js';
|
|
34
|
+
export { SONICJS_VERSION, getCoreVersion } from './chunk-W53J3BJ2.js';
|
|
34
35
|
import { escapeHtml, sanitizeInput } from './chunk-TQABQWOP.js';
|
|
35
36
|
export { escapeHtml, sanitizeInput, sanitizeObject } from './chunk-TQABQWOP.js';
|
|
36
37
|
export { HOOKS } from './chunk-QXOZI5Q2.js';
|
|
37
38
|
import './chunk-V4OQ3NZ2.js';
|
|
38
39
|
import { Hono } from 'hono';
|
|
40
|
+
import { cors } from 'hono/cors';
|
|
39
41
|
import { z } from 'zod';
|
|
40
42
|
import { setCookie, getCookie } from 'hono/cookie';
|
|
41
43
|
import { html } from 'hono/html';
|
|
@@ -49,6 +51,7 @@ var DatabaseToolsService = class {
|
|
|
49
51
|
constructor(db) {
|
|
50
52
|
this.db = db;
|
|
51
53
|
}
|
|
54
|
+
db;
|
|
52
55
|
/**
|
|
53
56
|
* Get database statistics
|
|
54
57
|
*/
|
|
@@ -907,6 +910,7 @@ var EmailSettingsService = class {
|
|
|
907
910
|
constructor(db) {
|
|
908
911
|
this.db = db;
|
|
909
912
|
}
|
|
913
|
+
db;
|
|
910
914
|
async load() {
|
|
911
915
|
let row = null;
|
|
912
916
|
try {
|
|
@@ -935,6 +939,8 @@ var SiteConfigService = class {
|
|
|
935
939
|
this.db = db;
|
|
936
940
|
this.env = env;
|
|
937
941
|
}
|
|
942
|
+
db;
|
|
943
|
+
env;
|
|
938
944
|
async load() {
|
|
939
945
|
const settings = new SettingsService(this.db);
|
|
940
946
|
const general = await settings.getGeneralSettings();
|
|
@@ -1272,6 +1278,8 @@ var EmailValidationError = class extends Error {
|
|
|
1272
1278
|
this.reason = reason;
|
|
1273
1279
|
this.name = "EmailValidationError";
|
|
1274
1280
|
}
|
|
1281
|
+
field;
|
|
1282
|
+
reason;
|
|
1275
1283
|
code = "EMAIL_VALIDATION_FAILED";
|
|
1276
1284
|
};
|
|
1277
1285
|
|
|
@@ -1307,6 +1315,9 @@ var CfGraphqlClient = class {
|
|
|
1307
1315
|
throw new EmailValidationError("apiToken", "EMAIL_API_TOKEN is required for GraphQL queries");
|
|
1308
1316
|
}
|
|
1309
1317
|
}
|
|
1318
|
+
zoneId;
|
|
1319
|
+
apiToken;
|
|
1320
|
+
fetchImpl;
|
|
1310
1321
|
async queryEmailSends(input) {
|
|
1311
1322
|
const startIso = new Date(input.startSeconds * 1e3).toISOString();
|
|
1312
1323
|
const endIso = new Date(input.endSeconds * 1e3).toISOString();
|
|
@@ -1369,6 +1380,7 @@ var EmailLogService = class {
|
|
|
1369
1380
|
constructor(db) {
|
|
1370
1381
|
this.db = db;
|
|
1371
1382
|
}
|
|
1383
|
+
db;
|
|
1372
1384
|
/**
|
|
1373
1385
|
* Records a successful submission to CF Email Service. `status` =
|
|
1374
1386
|
* `'submitted'`, `delivery_state` remains NULL until reconciliation runs.
|
|
@@ -1542,6 +1554,8 @@ var ReconciliationService = class {
|
|
|
1542
1554
|
this.graphql = graphql;
|
|
1543
1555
|
this.emailLog = emailLog;
|
|
1544
1556
|
}
|
|
1557
|
+
graphql;
|
|
1558
|
+
emailLog;
|
|
1545
1559
|
async run(input = {}) {
|
|
1546
1560
|
const windowHours = input.windowHours ?? 24;
|
|
1547
1561
|
const nowMs = input.now ?? Date.now();
|
|
@@ -1950,6 +1964,7 @@ var CloudflareEmailProvider = class {
|
|
|
1950
1964
|
constructor(binding) {
|
|
1951
1965
|
this.binding = binding;
|
|
1952
1966
|
}
|
|
1967
|
+
binding;
|
|
1953
1968
|
name = "cloudflare";
|
|
1954
1969
|
isConfigured() {
|
|
1955
1970
|
return !!this.binding;
|
|
@@ -2132,6 +2147,7 @@ var OTPService = class {
|
|
|
2132
2147
|
constructor(db) {
|
|
2133
2148
|
this.db = db;
|
|
2134
2149
|
}
|
|
2150
|
+
db;
|
|
2135
2151
|
/**
|
|
2136
2152
|
* Generate a secure random OTP code
|
|
2137
2153
|
*/
|
|
@@ -2766,6 +2782,7 @@ var OAuthService = class {
|
|
|
2766
2782
|
constructor(db) {
|
|
2767
2783
|
this.db = db;
|
|
2768
2784
|
}
|
|
2785
|
+
db;
|
|
2769
2786
|
/**
|
|
2770
2787
|
* Build the authorization redirect URL for a provider.
|
|
2771
2788
|
*/
|
|
@@ -3282,6 +3299,7 @@ var EmbeddingService = class {
|
|
|
3282
3299
|
constructor(ai) {
|
|
3283
3300
|
this.ai = ai;
|
|
3284
3301
|
}
|
|
3302
|
+
ai;
|
|
3285
3303
|
/**
|
|
3286
3304
|
* Generate embedding for a single text
|
|
3287
3305
|
*/
|
|
@@ -3486,6 +3504,9 @@ var CustomRAGService = class {
|
|
|
3486
3504
|
this.embeddingService = new EmbeddingService(ai);
|
|
3487
3505
|
this.chunkingService = new ChunkingService();
|
|
3488
3506
|
}
|
|
3507
|
+
db;
|
|
3508
|
+
ai;
|
|
3509
|
+
vectorize;
|
|
3489
3510
|
embeddingService;
|
|
3490
3511
|
chunkingService;
|
|
3491
3512
|
/**
|
|
@@ -3776,6 +3797,9 @@ var AISearchService = class {
|
|
|
3776
3797
|
console.log("[AISearchService] Custom RAG not available, using keyword search only");
|
|
3777
3798
|
}
|
|
3778
3799
|
}
|
|
3800
|
+
db;
|
|
3801
|
+
ai;
|
|
3802
|
+
vectorize;
|
|
3779
3803
|
customRAG;
|
|
3780
3804
|
/**
|
|
3781
3805
|
* Get plugin settings
|
|
@@ -4216,6 +4240,9 @@ var IndexManager = class {
|
|
|
4216
4240
|
console.log("[IndexManager] Custom RAG initialized");
|
|
4217
4241
|
}
|
|
4218
4242
|
}
|
|
4243
|
+
db;
|
|
4244
|
+
ai;
|
|
4245
|
+
vectorize;
|
|
4219
4246
|
customRAG;
|
|
4220
4247
|
/**
|
|
4221
4248
|
* Index all content items within a collection using Custom RAG
|
|
@@ -5149,6 +5176,8 @@ var SecurityAuditService = class {
|
|
|
5149
5176
|
tenantId: TENANT
|
|
5150
5177
|
});
|
|
5151
5178
|
}
|
|
5179
|
+
db;
|
|
5180
|
+
settings;
|
|
5152
5181
|
docsService;
|
|
5153
5182
|
async logEvent(event) {
|
|
5154
5183
|
const doc = await this.docsService.create({
|
|
@@ -6092,6 +6121,7 @@ var BruteForceDetector = class {
|
|
|
6092
6121
|
this.kv = kv;
|
|
6093
6122
|
this.settings = settings || DEFAULT_SETTINGS2.bruteForce;
|
|
6094
6123
|
}
|
|
6124
|
+
kv;
|
|
6095
6125
|
settings;
|
|
6096
6126
|
async recordFailedAttempt(ip, email) {
|
|
6097
6127
|
if (!this.settings.enabled || !this.kv) {
|
|
@@ -6644,11 +6674,465 @@ var securityAuditPlugin = definePlugin({
|
|
|
6644
6674
|
deactivate: async () => console.log("[SecurityAudit] Plugin deactivated")
|
|
6645
6675
|
});
|
|
6646
6676
|
|
|
6677
|
+
// src/plugins/core-plugins/api-keys-plugin/services/api-key-service.ts
|
|
6678
|
+
var API_KEY_QUERYABLE = [
|
|
6679
|
+
{ name: "keyHash", kind: "scalar", type: "text", column: "q_apikey_hash" },
|
|
6680
|
+
{ name: "userId", kind: "scalar", type: "text", column: "q_apikey_user_id" },
|
|
6681
|
+
{ name: "revoked", kind: "scalar", type: "integer", column: "q_apikey_revoked" }
|
|
6682
|
+
];
|
|
6683
|
+
var KEY_PREFIX = "sk_";
|
|
6684
|
+
var KEY_BYTES = 24;
|
|
6685
|
+
var DISPLAY_PREFIX_LEN = KEY_PREFIX.length + 8;
|
|
6686
|
+
function generateApiKeySecret() {
|
|
6687
|
+
const bytes = new Uint8Array(KEY_BYTES);
|
|
6688
|
+
crypto.getRandomValues(bytes);
|
|
6689
|
+
let hex = "";
|
|
6690
|
+
for (const b of bytes) hex += b.toString(16).padStart(2, "0");
|
|
6691
|
+
return KEY_PREFIX + hex;
|
|
6692
|
+
}
|
|
6693
|
+
async function hashApiKey(secret) {
|
|
6694
|
+
const data = new TextEncoder().encode(secret);
|
|
6695
|
+
const digest = await crypto.subtle.digest("SHA-256", data);
|
|
6696
|
+
const view = new Uint8Array(digest);
|
|
6697
|
+
let hex = "";
|
|
6698
|
+
for (const b of view) hex += b.toString(16).padStart(2, "0");
|
|
6699
|
+
return hex;
|
|
6700
|
+
}
|
|
6701
|
+
var ApiKeyService = class {
|
|
6702
|
+
constructor(db, tenantId = "default") {
|
|
6703
|
+
this.db = db;
|
|
6704
|
+
this.tenantId = tenantId;
|
|
6705
|
+
}
|
|
6706
|
+
db;
|
|
6707
|
+
tenantId;
|
|
6708
|
+
docService() {
|
|
6709
|
+
return new DocumentsService(this.db, {
|
|
6710
|
+
queryableFields: API_KEY_QUERYABLE,
|
|
6711
|
+
tenantId: this.tenantId,
|
|
6712
|
+
maxVersionsPerRoot: 1
|
|
6713
|
+
});
|
|
6714
|
+
}
|
|
6715
|
+
/** Count a user's active (non-revoked) keys — used to enforce the per-user cap. */
|
|
6716
|
+
async countForUser(userId) {
|
|
6717
|
+
const row = await this.db.prepare(
|
|
6718
|
+
`SELECT COUNT(*) AS c FROM documents
|
|
6719
|
+
WHERE type_id = 'api_key' AND tenant_id = ? AND is_current_draft = 1
|
|
6720
|
+
AND deleted_at IS NULL AND q_apikey_user_id = ? AND q_apikey_revoked = 0`
|
|
6721
|
+
).bind(this.tenantId, userId).first();
|
|
6722
|
+
return row?.c ?? 0;
|
|
6723
|
+
}
|
|
6724
|
+
/**
|
|
6725
|
+
* Mint a new key for a user. The returned `key` is the only time the plaintext
|
|
6726
|
+
* exists outside the caller — it is hashed before storage.
|
|
6727
|
+
*/
|
|
6728
|
+
async create(input) {
|
|
6729
|
+
const name = input.name.trim() || "API Key";
|
|
6730
|
+
const secret = generateApiKeySecret();
|
|
6731
|
+
const keyHash = await hashApiKey(secret);
|
|
6732
|
+
const prefix = secret.slice(0, DISPLAY_PREFIX_LEN);
|
|
6733
|
+
const expiresAt = input.expiresAt ?? null;
|
|
6734
|
+
const doc = await this.docService().create(
|
|
6735
|
+
createDocumentSchema.parse({
|
|
6736
|
+
typeId: "api_key",
|
|
6737
|
+
tenantId: this.tenantId,
|
|
6738
|
+
title: name,
|
|
6739
|
+
ownerId: input.userId,
|
|
6740
|
+
publishOnCreate: true,
|
|
6741
|
+
data: {
|
|
6742
|
+
name,
|
|
6743
|
+
userId: input.userId,
|
|
6744
|
+
keyHash,
|
|
6745
|
+
keyPrefix: prefix,
|
|
6746
|
+
revoked: 0,
|
|
6747
|
+
lastUsedAt: null,
|
|
6748
|
+
expiresAt
|
|
6749
|
+
}
|
|
6750
|
+
}),
|
|
6751
|
+
input.userId
|
|
6752
|
+
);
|
|
6753
|
+
return { id: doc.rootId, key: secret, name, prefix, expiresAt };
|
|
6754
|
+
}
|
|
6755
|
+
/** List a user's non-revoked keys (metadata only — never the secret or hash). */
|
|
6756
|
+
async list(userId) {
|
|
6757
|
+
const res = await this.db.prepare(
|
|
6758
|
+
`SELECT root_id, data, created_at FROM documents
|
|
6759
|
+
WHERE type_id = 'api_key' AND tenant_id = ? AND is_current_draft = 1
|
|
6760
|
+
AND deleted_at IS NULL AND q_apikey_user_id = ? AND q_apikey_revoked = 0
|
|
6761
|
+
ORDER BY created_at DESC`
|
|
6762
|
+
).bind(this.tenantId, userId).all();
|
|
6763
|
+
return (res.results ?? []).map((row) => {
|
|
6764
|
+
const d = JSON.parse(row.data);
|
|
6765
|
+
return {
|
|
6766
|
+
id: row.root_id,
|
|
6767
|
+
name: d.name ?? "API Key",
|
|
6768
|
+
prefix: d.keyPrefix ?? "",
|
|
6769
|
+
createdAt: row.created_at,
|
|
6770
|
+
lastUsedAt: d.lastUsedAt ?? null,
|
|
6771
|
+
expiresAt: d.expiresAt ?? null
|
|
6772
|
+
};
|
|
6773
|
+
});
|
|
6774
|
+
}
|
|
6775
|
+
/**
|
|
6776
|
+
* Revoke (hard-delete) a key owned by `userId`. Credentials are erased, not
|
|
6777
|
+
* soft-flagged. Returns false if the key does not exist or is not owned by
|
|
6778
|
+
* the caller (no information leak about other users' keys).
|
|
6779
|
+
*/
|
|
6780
|
+
async revoke(rootId, userId) {
|
|
6781
|
+
const row = await this.db.prepare(
|
|
6782
|
+
`SELECT q_apikey_user_id AS owner FROM documents
|
|
6783
|
+
WHERE root_id = ? AND tenant_id = ? AND type_id = 'api_key' AND is_current_draft = 1 AND deleted_at IS NULL`
|
|
6784
|
+
).bind(rootId, this.tenantId).first();
|
|
6785
|
+
if (!row || row.owner !== userId) return false;
|
|
6786
|
+
await this.docService().erase(rootId, this.tenantId);
|
|
6787
|
+
return true;
|
|
6788
|
+
}
|
|
6789
|
+
/**
|
|
6790
|
+
* Resolve a presented secret to its owning user, or null. Rejects unknown,
|
|
6791
|
+
* revoked, expired keys and inactive users. Best-effort updates lastUsedAt.
|
|
6792
|
+
*/
|
|
6793
|
+
async resolve(secret) {
|
|
6794
|
+
if (!secret || !secret.startsWith(KEY_PREFIX)) return null;
|
|
6795
|
+
const keyHash = await hashApiKey(secret);
|
|
6796
|
+
const keyRow2 = await this.db.prepare(
|
|
6797
|
+
`SELECT root_id, data FROM documents
|
|
6798
|
+
WHERE type_id = 'api_key' AND tenant_id = ? AND is_current_draft = 1 AND deleted_at IS NULL
|
|
6799
|
+
AND q_apikey_hash = ? AND q_apikey_revoked = 0
|
|
6800
|
+
LIMIT 1`
|
|
6801
|
+
).bind(this.tenantId, keyHash).first();
|
|
6802
|
+
if (!keyRow2) return null;
|
|
6803
|
+
const d = JSON.parse(keyRow2.data);
|
|
6804
|
+
if (d.expiresAt != null && Date.now() > Number(d.expiresAt)) return null;
|
|
6805
|
+
const user = await this.db.prepare(`SELECT id, email, role, is_active, is_super_admin FROM auth_user WHERE id = ?`).bind(d.userId).first();
|
|
6806
|
+
if (!user || user.is_active !== 1) return null;
|
|
6807
|
+
try {
|
|
6808
|
+
await this.touchLastUsed(keyRow2.root_id, d);
|
|
6809
|
+
} catch {
|
|
6810
|
+
}
|
|
6811
|
+
return {
|
|
6812
|
+
userId: user.id,
|
|
6813
|
+
email: user.email,
|
|
6814
|
+
role: user.role ?? "viewer",
|
|
6815
|
+
isSuperAdmin: user.is_super_admin === 1
|
|
6816
|
+
};
|
|
6817
|
+
}
|
|
6818
|
+
/** Update lastUsedAt in-place (single-version type, no history churn). */
|
|
6819
|
+
async touchLastUsed(rootId, data) {
|
|
6820
|
+
const next = JSON.stringify({ ...data, lastUsedAt: Date.now() });
|
|
6821
|
+
await this.db.prepare(
|
|
6822
|
+
`UPDATE documents SET data = ? WHERE root_id = ? AND tenant_id = ? AND type_id = 'api_key' AND is_current_draft = 1`
|
|
6823
|
+
).bind(next, rootId, this.tenantId).run();
|
|
6824
|
+
}
|
|
6825
|
+
};
|
|
6826
|
+
|
|
6827
|
+
// src/plugins/core-plugins/api-keys-plugin/components/keys-page.ts
|
|
6828
|
+
init_admin_layout_catalyst_template();
|
|
6829
|
+
function fmtDate(ms) {
|
|
6830
|
+
if (!ms) return "\u2014";
|
|
6831
|
+
try {
|
|
6832
|
+
return new Date(ms).toISOString().slice(0, 10);
|
|
6833
|
+
} catch {
|
|
6834
|
+
return "\u2014";
|
|
6835
|
+
}
|
|
6836
|
+
}
|
|
6837
|
+
function keyRow(k) {
|
|
6838
|
+
const name = escapeHtml(k.name);
|
|
6839
|
+
const prefix = escapeHtml(k.prefix);
|
|
6840
|
+
const id = escapeHtml(k.id);
|
|
6841
|
+
return `
|
|
6842
|
+
<tr class="border-t border-zinc-950/5 dark:border-white/10" data-key-id="${id}">
|
|
6843
|
+
<td class="py-3 pr-4 text-sm font-medium text-zinc-950 dark:text-white">${name}</td>
|
|
6844
|
+
<td class="py-3 pr-4 text-sm font-mono text-zinc-500 dark:text-zinc-400">${prefix}\u2026</td>
|
|
6845
|
+
<td class="py-3 pr-4 text-sm text-zinc-500 dark:text-zinc-400">${fmtDate(k.createdAt ? k.createdAt * 1e3 : null)}</td>
|
|
6846
|
+
<td class="py-3 pr-4 text-sm text-zinc-500 dark:text-zinc-400">${k.lastUsedAt ? fmtDate(k.lastUsedAt) : "Never"}</td>
|
|
6847
|
+
<td class="py-3 pr-4 text-sm text-zinc-500 dark:text-zinc-400">${k.expiresAt ? fmtDate(k.expiresAt) : "Never"}</td>
|
|
6848
|
+
<td class="py-3 text-right">
|
|
6849
|
+
<button type="button" onclick="revokeApiKey('${id}', '${name.replace(/'/g, "\\'")}')"
|
|
6850
|
+
class="rounded-lg bg-red-50 dark:bg-red-900/20 px-3 py-1.5 text-sm font-medium text-red-700 dark:text-red-400 hover:bg-red-100 dark:hover:bg-red-900/40 ring-1 ring-red-200 dark:ring-red-800 transition-colors">
|
|
6851
|
+
Revoke
|
|
6852
|
+
</button>
|
|
6853
|
+
</td>
|
|
6854
|
+
</tr>`;
|
|
6855
|
+
}
|
|
6856
|
+
function renderApiKeysPage(data) {
|
|
6857
|
+
const { keys, user, version, dynamicMenuItems } = data;
|
|
6858
|
+
const rows = keys.length ? keys.map(keyRow).join("") : `<tr><td colspan="6" class="py-8 text-center text-sm text-zinc-500 dark:text-zinc-400">No API keys yet. Create one to enable programmatic access.</td></tr>`;
|
|
6859
|
+
const content2 = `
|
|
6860
|
+
<div>
|
|
6861
|
+
<div class="sm:flex sm:items-center sm:justify-between mb-6">
|
|
6862
|
+
<div class="sm:flex-auto">
|
|
6863
|
+
<h1 class="text-2xl/8 font-semibold text-zinc-950 dark:text-white sm:text-xl/8">API Keys</h1>
|
|
6864
|
+
<p class="mt-2 text-sm/6 text-zinc-500 dark:text-zinc-400">
|
|
6865
|
+
Long-lived secrets for headless / server-to-server REST access. Send a key as the
|
|
6866
|
+
<code class="font-mono">x-api-key</code> header or <code class="font-mono">Authorization: Bearer <key></code>.
|
|
6867
|
+
The secret is shown once at creation \u2014 store it now.
|
|
6868
|
+
</p>
|
|
6869
|
+
</div>
|
|
6870
|
+
<div class="mt-4 sm:mt-0 sm:ml-16">
|
|
6871
|
+
<button type="button" onclick="document.getElementById('create-key-modal').classList.remove('hidden')"
|
|
6872
|
+
class="inline-flex items-center justify-center rounded-lg bg-cyan-600 px-4 py-2.5 text-sm font-semibold text-white hover:bg-cyan-500 transition-colors shadow-sm">
|
|
6873
|
+
Create API key
|
|
6874
|
+
</button>
|
|
6875
|
+
</div>
|
|
6876
|
+
</div>
|
|
6877
|
+
|
|
6878
|
+
<!-- Newly-created secret banner (populated by JS, shown once) -->
|
|
6879
|
+
<div id="new-key-banner" class="hidden mb-6 rounded-xl bg-emerald-50 dark:bg-emerald-900/20 p-4 ring-1 ring-emerald-200 dark:ring-emerald-800">
|
|
6880
|
+
<p class="text-sm font-medium text-emerald-800 dark:text-emerald-300 mb-2">
|
|
6881
|
+
Copy your new key now \u2014 it will not be shown again.
|
|
6882
|
+
</p>
|
|
6883
|
+
<div class="flex items-center gap-2">
|
|
6884
|
+
<code id="new-key-value" class="flex-1 rounded-lg bg-white dark:bg-zinc-900 px-3 py-2 text-sm font-mono text-zinc-950 dark:text-white ring-1 ring-zinc-950/10 dark:ring-white/10 break-all"></code>
|
|
6885
|
+
<button type="button" onclick="copyNewKey()"
|
|
6886
|
+
class="rounded-lg bg-emerald-600 px-3 py-2 text-sm font-semibold text-white hover:bg-emerald-500 transition-colors">
|
|
6887
|
+
Copy
|
|
6888
|
+
</button>
|
|
6889
|
+
</div>
|
|
6890
|
+
</div>
|
|
6891
|
+
|
|
6892
|
+
<div class="rounded-xl bg-white/80 dark:bg-zinc-900/80 backdrop-blur-xl p-6 ring-1 ring-zinc-950/5 dark:ring-white/10 shadow-sm overflow-x-auto">
|
|
6893
|
+
<table class="w-full text-left">
|
|
6894
|
+
<thead>
|
|
6895
|
+
<tr class="text-xs font-semibold uppercase tracking-wide text-zinc-500 dark:text-zinc-400">
|
|
6896
|
+
<th class="pb-2 pr-4">Name</th>
|
|
6897
|
+
<th class="pb-2 pr-4">Prefix</th>
|
|
6898
|
+
<th class="pb-2 pr-4">Created</th>
|
|
6899
|
+
<th class="pb-2 pr-4">Last used</th>
|
|
6900
|
+
<th class="pb-2 pr-4">Expires</th>
|
|
6901
|
+
<th class="pb-2 text-right">Actions</th>
|
|
6902
|
+
</tr>
|
|
6903
|
+
</thead>
|
|
6904
|
+
<tbody id="keys-tbody">${rows}</tbody>
|
|
6905
|
+
</table>
|
|
6906
|
+
</div>
|
|
6907
|
+
</div>
|
|
6908
|
+
|
|
6909
|
+
<!-- Create modal -->
|
|
6910
|
+
<div id="create-key-modal" class="hidden fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4">
|
|
6911
|
+
<div class="w-full max-w-md rounded-xl bg-white dark:bg-zinc-900 p-6 ring-1 ring-zinc-950/10 dark:ring-white/10 shadow-xl">
|
|
6912
|
+
<h2 class="text-base font-semibold text-zinc-950 dark:text-white mb-4">Create API key</h2>
|
|
6913
|
+
<label class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-1">Name</label>
|
|
6914
|
+
<input id="new-key-name" type="text" placeholder="e.g. CI deploy token"
|
|
6915
|
+
class="w-full rounded-lg border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white mb-4 ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10">
|
|
6916
|
+
<label class="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-1">Expires in (days, optional)</label>
|
|
6917
|
+
<input id="new-key-expiry" type="number" min="1" max="3650" placeholder="Never"
|
|
6918
|
+
class="w-full rounded-lg border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-950 dark:text-white mb-4 ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10">
|
|
6919
|
+
<div class="flex justify-end gap-2">
|
|
6920
|
+
<button type="button" onclick="document.getElementById('create-key-modal').classList.add('hidden')"
|
|
6921
|
+
class="rounded-lg bg-white dark:bg-zinc-800 px-4 py-2 text-sm font-semibold text-zinc-950 dark:text-white ring-1 ring-inset ring-zinc-950/10 dark:ring-white/10">
|
|
6922
|
+
Cancel
|
|
6923
|
+
</button>
|
|
6924
|
+
<button type="button" onclick="createApiKey()"
|
|
6925
|
+
class="rounded-lg bg-cyan-600 px-4 py-2 text-sm font-semibold text-white hover:bg-cyan-500 transition-colors">
|
|
6926
|
+
Create
|
|
6927
|
+
</button>
|
|
6928
|
+
</div>
|
|
6929
|
+
</div>
|
|
6930
|
+
</div>
|
|
6931
|
+
|
|
6932
|
+
<script>
|
|
6933
|
+
// CSRF: the csrf_token cookie is JS-readable (httpOnly:false); echo it back
|
|
6934
|
+
// as X-CSRF-Token on state-changing requests (signed double-submit).
|
|
6935
|
+
function csrfHeader() {
|
|
6936
|
+
const m = document.cookie.match(/(?:^|; )csrf_token=([^;]+)/)
|
|
6937
|
+
return m ? { 'X-CSRF-Token': decodeURIComponent(m[1]) } : {}
|
|
6938
|
+
}
|
|
6939
|
+
async function createApiKey() {
|
|
6940
|
+
const name = document.getElementById('new-key-name').value.trim()
|
|
6941
|
+
if (!name) { window.showNotification && window.showNotification('Name is required', 'error'); return }
|
|
6942
|
+
const expiry = parseInt(document.getElementById('new-key-expiry').value, 10)
|
|
6943
|
+
const body = { name }
|
|
6944
|
+
if (Number.isFinite(expiry) && expiry > 0) body.expiresInDays = expiry
|
|
6945
|
+
const res = await fetch('/admin/plugins/api-keys/api/keys', {
|
|
6946
|
+
method: 'POST',
|
|
6947
|
+
headers: { 'Content-Type': 'application/json', ...csrfHeader() },
|
|
6948
|
+
body: JSON.stringify(body),
|
|
6949
|
+
})
|
|
6950
|
+
if (!res.ok) {
|
|
6951
|
+
const e = await res.json().catch(() => ({}))
|
|
6952
|
+
window.showNotification && window.showNotification(e.error || 'Failed to create key', 'error')
|
|
6953
|
+
return
|
|
6954
|
+
}
|
|
6955
|
+
const { apiKey } = await res.json()
|
|
6956
|
+
document.getElementById('create-key-modal').classList.add('hidden')
|
|
6957
|
+
document.getElementById('new-key-value').textContent = apiKey.key
|
|
6958
|
+
document.getElementById('new-key-banner').classList.remove('hidden')
|
|
6959
|
+
setTimeout(() => location.reload(), 1500)
|
|
6960
|
+
}
|
|
6961
|
+
function copyNewKey() {
|
|
6962
|
+
const v = document.getElementById('new-key-value').textContent
|
|
6963
|
+
navigator.clipboard.writeText(v).then(() => window.showNotification && window.showNotification('Copied', 'success'))
|
|
6964
|
+
}
|
|
6965
|
+
async function revokeApiKey(id, name) {
|
|
6966
|
+
if (!confirm('Revoke "' + name + '"? This cannot be undone and will break any client using it.')) return
|
|
6967
|
+
const res = await fetch('/admin/plugins/api-keys/api/keys/' + id, { method: 'DELETE', headers: { ...csrfHeader() } })
|
|
6968
|
+
if (res.ok) {
|
|
6969
|
+
const row = document.querySelector('[data-key-id="' + id + '"]')
|
|
6970
|
+
if (row) row.remove()
|
|
6971
|
+
window.showNotification && window.showNotification('Key revoked', 'success')
|
|
6972
|
+
} else {
|
|
6973
|
+
window.showNotification && window.showNotification('Failed to revoke', 'error')
|
|
6974
|
+
}
|
|
6975
|
+
}
|
|
6976
|
+
</script>`;
|
|
6977
|
+
const layoutData = {
|
|
6978
|
+
title: "API Keys",
|
|
6979
|
+
pageTitle: "API Keys",
|
|
6980
|
+
currentPath: "/admin/plugins/api-keys",
|
|
6981
|
+
user,
|
|
6982
|
+
content: content2,
|
|
6983
|
+
version,
|
|
6984
|
+
dynamicMenuItems
|
|
6985
|
+
};
|
|
6986
|
+
return renderAdminLayoutCatalyst(layoutData);
|
|
6987
|
+
}
|
|
6988
|
+
|
|
6989
|
+
// src/plugins/core-plugins/api-keys-plugin/types.ts
|
|
6990
|
+
var DEFAULT_SETTINGS3 = {
|
|
6991
|
+
maxKeysPerUser: 50,
|
|
6992
|
+
defaultExpiryDays: 0
|
|
6993
|
+
};
|
|
6994
|
+
|
|
6995
|
+
// src/plugins/core-plugins/api-keys-plugin/routes/admin.ts
|
|
6996
|
+
var adminRoutes4 = new Hono();
|
|
6997
|
+
var DAY_MS = 24 * 60 * 60 * 1e3;
|
|
6998
|
+
var createSchema = z.object({
|
|
6999
|
+
name: z.string().min(1).max(100),
|
|
7000
|
+
// Optional lifetime in days; omitted/null → plugin default (which may be "never").
|
|
7001
|
+
expiresInDays: z.number().int().positive().max(3650).nullish()
|
|
7002
|
+
});
|
|
7003
|
+
async function getSettings3(db) {
|
|
7004
|
+
try {
|
|
7005
|
+
const plugin2 = await new PluginService(db).getPlugin("api-keys");
|
|
7006
|
+
if (plugin2?.settings) {
|
|
7007
|
+
const s = typeof plugin2.settings === "string" ? JSON.parse(plugin2.settings) : plugin2.settings;
|
|
7008
|
+
return { ...DEFAULT_SETTINGS3, ...s };
|
|
7009
|
+
}
|
|
7010
|
+
} catch {
|
|
7011
|
+
}
|
|
7012
|
+
return DEFAULT_SETTINGS3;
|
|
7013
|
+
}
|
|
7014
|
+
adminRoutes4.use("*", requireAuth());
|
|
7015
|
+
adminRoutes4.use("*", async (c, next) => {
|
|
7016
|
+
const user = c.get("user");
|
|
7017
|
+
if (user?.role !== "admin") {
|
|
7018
|
+
return c.json({ error: "Access denied" }, 403);
|
|
7019
|
+
}
|
|
7020
|
+
return next();
|
|
7021
|
+
});
|
|
7022
|
+
adminRoutes4.get("/", async (c) => {
|
|
7023
|
+
const user = c.get("user");
|
|
7024
|
+
const tenantId = c.get("tenantId") || "default";
|
|
7025
|
+
const keys = await new ApiKeyService(c.env.DB, tenantId).list(user.userId);
|
|
7026
|
+
return c.html(
|
|
7027
|
+
renderApiKeysPage({
|
|
7028
|
+
keys,
|
|
7029
|
+
user: { name: user.email, email: user.email, role: user.role },
|
|
7030
|
+
version: c.get("appVersion"),
|
|
7031
|
+
dynamicMenuItems: c.get("pluginMenuItems")
|
|
7032
|
+
})
|
|
7033
|
+
);
|
|
7034
|
+
});
|
|
7035
|
+
adminRoutes4.get("/api/keys", async (c) => {
|
|
7036
|
+
const user = c.get("user");
|
|
7037
|
+
const tenantId = c.get("tenantId") || "default";
|
|
7038
|
+
const keys = await new ApiKeyService(c.env.DB, tenantId).list(user.userId);
|
|
7039
|
+
return c.json({ keys });
|
|
7040
|
+
});
|
|
7041
|
+
adminRoutes4.post("/api/keys", async (c) => {
|
|
7042
|
+
const user = c.get("user");
|
|
7043
|
+
const tenantId = c.get("tenantId") || "default";
|
|
7044
|
+
const body = await c.req.json().catch(() => ({}));
|
|
7045
|
+
const parsed = createSchema.safeParse(body);
|
|
7046
|
+
if (!parsed.success) {
|
|
7047
|
+
return c.json({ error: "Invalid request", details: parsed.error.flatten() }, 400);
|
|
7048
|
+
}
|
|
7049
|
+
const settings = await getSettings3(c.env.DB);
|
|
7050
|
+
const svc = new ApiKeyService(c.env.DB, tenantId);
|
|
7051
|
+
if (await svc.countForUser(user.userId) >= settings.maxKeysPerUser) {
|
|
7052
|
+
return c.json({ error: `API key limit reached (max ${settings.maxKeysPerUser})` }, 409);
|
|
7053
|
+
}
|
|
7054
|
+
const days = parsed.data.expiresInDays ?? (settings.defaultExpiryDays > 0 ? settings.defaultExpiryDays : null);
|
|
7055
|
+
const expiresAt = days ? Date.now() + days * DAY_MS : null;
|
|
7056
|
+
const created = await svc.create({ userId: user.userId, name: parsed.data.name, expiresAt });
|
|
7057
|
+
return c.json({ apiKey: created }, 201);
|
|
7058
|
+
});
|
|
7059
|
+
adminRoutes4.delete("/api/keys/:id", async (c) => {
|
|
7060
|
+
const user = c.get("user");
|
|
7061
|
+
const tenantId = c.get("tenantId") || "default";
|
|
7062
|
+
const ok = await new ApiKeyService(c.env.DB, tenantId).revoke(c.req.param("id") ?? "", user.userId);
|
|
7063
|
+
if (!ok) return c.json({ error: "API key not found" }, 404);
|
|
7064
|
+
return c.json({ success: true });
|
|
7065
|
+
});
|
|
7066
|
+
|
|
7067
|
+
// src/plugins/core-plugins/api-keys-plugin/middleware/api-key-auth.ts
|
|
7068
|
+
function apiKeyAuthMiddleware() {
|
|
7069
|
+
return async (c, next) => {
|
|
7070
|
+
if (!c.get("user")) {
|
|
7071
|
+
const authz = c.req.header("authorization") || "";
|
|
7072
|
+
const bearer = authz.toLowerCase().startsWith("bearer ") ? authz.slice(7).trim() : "";
|
|
7073
|
+
const presented = c.req.header("x-api-key") || (bearer.startsWith("sk_") ? bearer : "");
|
|
7074
|
+
if (presented) {
|
|
7075
|
+
try {
|
|
7076
|
+
const tenantId = c.get("tenantId") || "default";
|
|
7077
|
+
const resolved = await new ApiKeyService(c.env.DB, tenantId).resolve(presented);
|
|
7078
|
+
if (resolved) {
|
|
7079
|
+
c.set("user", {
|
|
7080
|
+
userId: resolved.userId,
|
|
7081
|
+
email: resolved.email,
|
|
7082
|
+
role: resolved.role,
|
|
7083
|
+
isSuperAdmin: resolved.isSuperAdmin,
|
|
7084
|
+
// API keys are stateless bearer creds — no session window.
|
|
7085
|
+
exp: 0,
|
|
7086
|
+
iat: 0
|
|
7087
|
+
});
|
|
7088
|
+
}
|
|
7089
|
+
} catch {
|
|
7090
|
+
}
|
|
7091
|
+
}
|
|
7092
|
+
}
|
|
7093
|
+
await next();
|
|
7094
|
+
};
|
|
7095
|
+
}
|
|
7096
|
+
|
|
7097
|
+
// src/plugins/core-plugins/api-keys-plugin/index.ts
|
|
7098
|
+
var KEY_ICON = `<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z"/></svg>`;
|
|
7099
|
+
var apiKeysPlugin = definePlugin({
|
|
7100
|
+
id: "api-keys",
|
|
7101
|
+
version: "1.0.0-beta.1",
|
|
7102
|
+
name: "API Keys",
|
|
7103
|
+
description: "Programmatic API access keys for headless / server-to-server REST access.",
|
|
7104
|
+
sonicjsVersionRange: "^3.0.0",
|
|
7105
|
+
author: { name: "SonicJS Team" },
|
|
7106
|
+
register(app2) {
|
|
7107
|
+
app2.route("/admin/plugins/api-keys", adminRoutes4);
|
|
7108
|
+
},
|
|
7109
|
+
menu: [
|
|
7110
|
+
{ label: "API Keys", path: "/admin/plugins/api-keys", icon: KEY_ICON, order: 86 }
|
|
7111
|
+
],
|
|
7112
|
+
configSchema: {
|
|
7113
|
+
maxKeysPerUser: {
|
|
7114
|
+
type: "number",
|
|
7115
|
+
label: "Max keys per user",
|
|
7116
|
+
description: "Hard cap on active keys a single user may hold.",
|
|
7117
|
+
default: 50
|
|
7118
|
+
},
|
|
7119
|
+
defaultExpiryDays: {
|
|
7120
|
+
type: "number",
|
|
7121
|
+
label: "Default expiry (days)",
|
|
7122
|
+
description: "Lifetime applied to new keys when no explicit expiry is given. 0 = never expires.",
|
|
7123
|
+
default: 0
|
|
7124
|
+
}
|
|
7125
|
+
},
|
|
7126
|
+
activate: async () => console.log("[ApiKeys] Plugin activated"),
|
|
7127
|
+
deactivate: async () => console.log("[ApiKeys] Plugin deactivated")
|
|
7128
|
+
});
|
|
7129
|
+
|
|
6647
7130
|
// src/plugins/core-plugins/stripe-plugin/services/subscription-service.ts
|
|
6648
7131
|
var SubscriptionService = class {
|
|
6649
7132
|
constructor(db) {
|
|
6650
7133
|
this.db = db;
|
|
6651
7134
|
}
|
|
7135
|
+
db;
|
|
6652
7136
|
/**
|
|
6653
7137
|
* Ensure the subscriptions table exists
|
|
6654
7138
|
*/
|
|
@@ -6887,6 +7371,7 @@ var StripeEventService = class {
|
|
|
6887
7371
|
constructor(db) {
|
|
6888
7372
|
this.db = db;
|
|
6889
7373
|
}
|
|
7374
|
+
db;
|
|
6890
7375
|
async ensureTable() {
|
|
6891
7376
|
await this.db.prepare(`
|
|
6892
7377
|
CREATE TABLE IF NOT EXISTS stripe_events (
|
|
@@ -7371,7 +7856,7 @@ function renderEventPagination(page, totalPages, type, status) {
|
|
|
7371
7856
|
}
|
|
7372
7857
|
|
|
7373
7858
|
// src/plugins/core-plugins/stripe-plugin/types.ts
|
|
7374
|
-
var
|
|
7859
|
+
var DEFAULT_SETTINGS4 = {
|
|
7375
7860
|
stripePublishableKey: "",
|
|
7376
7861
|
stripeSecretKey: "",
|
|
7377
7862
|
stripeWebhookSecret: "",
|
|
@@ -7381,28 +7866,28 @@ var DEFAULT_SETTINGS3 = {
|
|
|
7381
7866
|
};
|
|
7382
7867
|
|
|
7383
7868
|
// src/plugins/core-plugins/stripe-plugin/routes/admin.ts
|
|
7384
|
-
var
|
|
7385
|
-
|
|
7386
|
-
|
|
7869
|
+
var adminRoutes5 = new Hono();
|
|
7870
|
+
adminRoutes5.use("*", requireAuth());
|
|
7871
|
+
adminRoutes5.use("*", async (c, next) => {
|
|
7387
7872
|
const user = c.get("user");
|
|
7388
7873
|
if (user?.role !== "admin") {
|
|
7389
7874
|
return c.text("Access denied", 403);
|
|
7390
7875
|
}
|
|
7391
7876
|
return next();
|
|
7392
7877
|
});
|
|
7393
|
-
async function
|
|
7878
|
+
async function getSettings4(db) {
|
|
7394
7879
|
try {
|
|
7395
7880
|
const pluginService = new PluginService(db);
|
|
7396
7881
|
const plugin2 = await pluginService.getPlugin("stripe");
|
|
7397
7882
|
if (plugin2?.settings) {
|
|
7398
7883
|
const settings = typeof plugin2.settings === "string" ? JSON.parse(plugin2.settings) : plugin2.settings;
|
|
7399
|
-
return { ...
|
|
7884
|
+
return { ...DEFAULT_SETTINGS4, ...settings };
|
|
7400
7885
|
}
|
|
7401
7886
|
} catch {
|
|
7402
7887
|
}
|
|
7403
|
-
return
|
|
7888
|
+
return DEFAULT_SETTINGS4;
|
|
7404
7889
|
}
|
|
7405
|
-
|
|
7890
|
+
adminRoutes5.get("/", async (c) => {
|
|
7406
7891
|
const db = c.env.DB;
|
|
7407
7892
|
const user = c.get("user");
|
|
7408
7893
|
const subscriptionService = new SubscriptionService(db);
|
|
@@ -7425,7 +7910,7 @@ adminRoutes4.get("/", async (c) => {
|
|
|
7425
7910
|
});
|
|
7426
7911
|
return c.html(html4);
|
|
7427
7912
|
});
|
|
7428
|
-
|
|
7913
|
+
adminRoutes5.get("/events", async (c) => {
|
|
7429
7914
|
const db = c.env.DB;
|
|
7430
7915
|
const user = c.get("user");
|
|
7431
7916
|
const eventService = new StripeEventService(db);
|
|
@@ -7451,11 +7936,11 @@ adminRoutes4.get("/events", async (c) => {
|
|
|
7451
7936
|
});
|
|
7452
7937
|
return c.html(html4);
|
|
7453
7938
|
});
|
|
7454
|
-
|
|
7939
|
+
adminRoutes5.get("/settings", async (c) => {
|
|
7455
7940
|
const db = c.env.DB;
|
|
7456
7941
|
const user = c.get("user");
|
|
7457
|
-
const settings = await
|
|
7458
|
-
const { renderAdminLayoutCatalyst: renderAdminLayoutCatalyst2 } = await import('./admin-layout-catalyst.template-
|
|
7942
|
+
const settings = await getSettings4(db);
|
|
7943
|
+
const { renderAdminLayoutCatalyst: renderAdminLayoutCatalyst2 } = await import('./admin-layout-catalyst.template-YQ4EMF2J.js');
|
|
7459
7944
|
const content2 = `
|
|
7460
7945
|
<div>
|
|
7461
7946
|
<div class="mb-6">
|
|
@@ -7561,7 +8046,7 @@ adminRoutes4.get("/settings", async (c) => {
|
|
|
7561
8046
|
dynamicMenuItems: c.get("pluginMenuItems")
|
|
7562
8047
|
}));
|
|
7563
8048
|
});
|
|
7564
|
-
|
|
8049
|
+
adminRoutes5.post("/settings", async (c) => {
|
|
7565
8050
|
try {
|
|
7566
8051
|
const body = await c.req.json();
|
|
7567
8052
|
const db = c.env.DB;
|
|
@@ -7583,6 +8068,7 @@ var StripeAPI = class {
|
|
|
7583
8068
|
constructor(secretKey) {
|
|
7584
8069
|
this.secretKey = secretKey;
|
|
7585
8070
|
}
|
|
8071
|
+
secretKey;
|
|
7586
8072
|
baseUrl = "https://api.stripe.com/v1";
|
|
7587
8073
|
/**
|
|
7588
8074
|
* Verify a webhook signature
|
|
@@ -7712,17 +8198,17 @@ function timingSafeEqual(a, b) {
|
|
|
7712
8198
|
|
|
7713
8199
|
// src/plugins/core-plugins/stripe-plugin/routes/api.ts
|
|
7714
8200
|
var apiRoutes3 = new Hono();
|
|
7715
|
-
async function
|
|
8201
|
+
async function getSettings5(db) {
|
|
7716
8202
|
try {
|
|
7717
8203
|
const pluginService = new PluginService(db);
|
|
7718
8204
|
const plugin2 = await pluginService.getPlugin("stripe");
|
|
7719
8205
|
if (plugin2?.settings) {
|
|
7720
8206
|
const settings = typeof plugin2.settings === "string" ? JSON.parse(plugin2.settings) : plugin2.settings;
|
|
7721
|
-
return { ...
|
|
8207
|
+
return { ...DEFAULT_SETTINGS4, ...settings };
|
|
7722
8208
|
}
|
|
7723
8209
|
} catch {
|
|
7724
8210
|
}
|
|
7725
|
-
return
|
|
8211
|
+
return DEFAULT_SETTINGS4;
|
|
7726
8212
|
}
|
|
7727
8213
|
function mapStripeStatus(status) {
|
|
7728
8214
|
const map = {
|
|
@@ -7739,7 +8225,7 @@ function mapStripeStatus(status) {
|
|
|
7739
8225
|
}
|
|
7740
8226
|
apiRoutes3.post("/webhook", async (c) => {
|
|
7741
8227
|
const db = c.env.DB;
|
|
7742
|
-
const settings = await
|
|
8228
|
+
const settings = await getSettings5(db);
|
|
7743
8229
|
if (!settings.stripeWebhookSecret) {
|
|
7744
8230
|
return c.json({ error: "Webhook secret not configured" }, 500);
|
|
7745
8231
|
}
|
|
@@ -7869,7 +8355,7 @@ apiRoutes3.post("/create-checkout-session", requireAuth(), async (c) => {
|
|
|
7869
8355
|
const db = c.env.DB;
|
|
7870
8356
|
const user = c.get("user");
|
|
7871
8357
|
if (!user) return c.json({ error: "Unauthorized" }, 401);
|
|
7872
|
-
const settings = await
|
|
8358
|
+
const settings = await getSettings5(db);
|
|
7873
8359
|
if (!settings.stripeSecretKey) {
|
|
7874
8360
|
return c.json({ error: "Stripe not configured" }, 500);
|
|
7875
8361
|
}
|
|
@@ -7946,7 +8432,7 @@ apiRoutes3.post("/sync-subscriptions", requireAuth(), async (c) => {
|
|
|
7946
8432
|
const user = c.get("user");
|
|
7947
8433
|
if (user?.role !== "admin") return c.json({ error: "Access denied" }, 403);
|
|
7948
8434
|
const db = c.env.DB;
|
|
7949
|
-
const settings = await
|
|
8435
|
+
const settings = await getSettings5(db);
|
|
7950
8436
|
if (!settings.stripeSecretKey) {
|
|
7951
8437
|
return c.json({ error: "Stripe secret key not configured" }, 400);
|
|
7952
8438
|
}
|
|
@@ -8021,7 +8507,7 @@ var stripePlugin = definePlugin({
|
|
|
8021
8507
|
sonicjsVersionRange: "^3.0.0",
|
|
8022
8508
|
author: { name: "SonicJS Team" },
|
|
8023
8509
|
register(app2) {
|
|
8024
|
-
app2.route("/admin/plugins/stripe",
|
|
8510
|
+
app2.route("/admin/plugins/stripe", adminRoutes5);
|
|
8025
8511
|
app2.route("/api/stripe", apiRoutes3);
|
|
8026
8512
|
},
|
|
8027
8513
|
menu: [
|
|
@@ -9714,6 +10200,7 @@ function renderFormCreatePage(data) {
|
|
|
9714
10200
|
}
|
|
9715
10201
|
|
|
9716
10202
|
// src/routes/admin-forms.ts
|
|
10203
|
+
var isTableMissing = (err) => String(err?.message ?? err?.cause?.message ?? "").includes("no such table: forms");
|
|
9717
10204
|
var adminFormsRoutes = new Hono();
|
|
9718
10205
|
adminFormsRoutes.use("*", requireAuth());
|
|
9719
10206
|
adminFormsRoutes.get("/", async (c) => {
|
|
@@ -9755,6 +10242,14 @@ adminFormsRoutes.get("/", async (c) => {
|
|
|
9755
10242
|
};
|
|
9756
10243
|
return c.html(renderFormsListPage(pageData));
|
|
9757
10244
|
} catch (error) {
|
|
10245
|
+
if (isTableMissing(error)) {
|
|
10246
|
+
const user = c.get("user");
|
|
10247
|
+
return c.html(renderFormsListPage({
|
|
10248
|
+
forms: [],
|
|
10249
|
+
user: user ? { name: user.email, email: user.email, role: user.role } : void 0,
|
|
10250
|
+
version: c.get("appVersion")
|
|
10251
|
+
}));
|
|
10252
|
+
}
|
|
9758
10253
|
console.error("Error listing forms:", error);
|
|
9759
10254
|
return c.html("<p>Error loading forms</p>", 500);
|
|
9760
10255
|
}
|
|
@@ -9865,6 +10360,7 @@ adminFormsRoutes.post("/", async (c) => {
|
|
|
9865
10360
|
).run();
|
|
9866
10361
|
return c.redirect(`/admin/forms/${formId}/builder`);
|
|
9867
10362
|
} catch (error) {
|
|
10363
|
+
if (isTableMissing(error)) return c.json({ error: "Forms storage not configured \u2014 run database migrations" }, 503);
|
|
9868
10364
|
console.error("Error creating form:", error);
|
|
9869
10365
|
return c.json({ error: "Failed to create form" }, 500);
|
|
9870
10366
|
}
|
|
@@ -9902,6 +10398,7 @@ adminFormsRoutes.get("/:id/builder", async (c) => {
|
|
|
9902
10398
|
};
|
|
9903
10399
|
return c.html(renderFormBuilderPage(pageData));
|
|
9904
10400
|
} catch (error) {
|
|
10401
|
+
if (isTableMissing(error)) return c.html("<p>Forms storage not configured \u2014 run database migrations</p>", 503);
|
|
9905
10402
|
console.error("Error showing form builder:", error);
|
|
9906
10403
|
return c.html("<p>Error loading form builder</p>", 500);
|
|
9907
10404
|
}
|
|
@@ -9931,6 +10428,7 @@ adminFormsRoutes.put("/:id", async (c) => {
|
|
|
9931
10428
|
).run();
|
|
9932
10429
|
return c.json({ success: true, message: "Form saved successfully" });
|
|
9933
10430
|
} catch (error) {
|
|
10431
|
+
if (isTableMissing(error)) return c.json({ error: "Forms storage not configured \u2014 run database migrations" }, 503);
|
|
9934
10432
|
console.error("Error updating form:", error);
|
|
9935
10433
|
return c.json({ error: "Failed to save form" }, 500);
|
|
9936
10434
|
}
|
|
@@ -9952,6 +10450,7 @@ adminFormsRoutes.delete("/:id", async (c) => {
|
|
|
9952
10450
|
await db.prepare("DELETE FROM forms WHERE id = ?").bind(formId).run();
|
|
9953
10451
|
return c.json({ success: true, message: "Form deleted successfully" });
|
|
9954
10452
|
} catch (error) {
|
|
10453
|
+
if (isTableMissing(error)) return c.json({ error: "Forms storage not configured \u2014 run database migrations" }, 503);
|
|
9955
10454
|
console.error("Error deleting form:", error);
|
|
9956
10455
|
return c.json({ error: "Failed to delete form" }, 500);
|
|
9957
10456
|
}
|
|
@@ -10012,6 +10511,7 @@ adminFormsRoutes.get("/:id/submissions", async (c) => {
|
|
|
10012
10511
|
`;
|
|
10013
10512
|
return c.html(html4);
|
|
10014
10513
|
} catch (error) {
|
|
10514
|
+
if (isTableMissing(error)) return c.html("<p>Forms storage not configured \u2014 run database migrations</p>", 503);
|
|
10015
10515
|
console.error("Error loading submissions:", error);
|
|
10016
10516
|
return c.html("<p>Error loading submissions</p>", 500);
|
|
10017
10517
|
}
|
|
@@ -10032,6 +10532,7 @@ function sanitizeDeep(value) {
|
|
|
10032
10532
|
}
|
|
10033
10533
|
return value;
|
|
10034
10534
|
}
|
|
10535
|
+
var isTableMissing2 = (err) => String(err?.message ?? err?.cause?.message ?? "").includes("no such table: form");
|
|
10035
10536
|
var publicFormsRoutes = new Hono();
|
|
10036
10537
|
publicFormsRoutes.get("/:identifier/turnstile-config", async (c) => {
|
|
10037
10538
|
try {
|
|
@@ -10059,6 +10560,7 @@ publicFormsRoutes.get("/:identifier/turnstile-config", async (c) => {
|
|
|
10059
10560
|
appearance: formSettings.appearance || globalSettings.appearance || "always"
|
|
10060
10561
|
});
|
|
10061
10562
|
} catch (error) {
|
|
10563
|
+
if (isTableMissing2(error)) return c.json({ enabled: false });
|
|
10062
10564
|
console.error("Error fetching Turnstile config:", error);
|
|
10063
10565
|
return c.json({ error: "Failed to fetch config" }, 500);
|
|
10064
10566
|
}
|
|
@@ -10086,6 +10588,7 @@ publicFormsRoutes.get("/:identifier/schema", async (c) => {
|
|
|
10086
10588
|
submitUrl: `/api/forms/${form.id}/submit`
|
|
10087
10589
|
});
|
|
10088
10590
|
} catch (error) {
|
|
10591
|
+
if (isTableMissing2(error)) return c.json({ error: "Form not found" }, 404);
|
|
10089
10592
|
console.error("Error fetching form schema:", error);
|
|
10090
10593
|
return c.json({ error: "Failed to fetch form schema" }, 500);
|
|
10091
10594
|
}
|
|
@@ -10452,6 +10955,7 @@ publicFormsRoutes.get("/:name", async (c) => {
|
|
|
10452
10955
|
`;
|
|
10453
10956
|
return c.html(html4);
|
|
10454
10957
|
} catch (error) {
|
|
10958
|
+
if (isTableMissing2(error)) return c.html("<h1>Form not found</h1><p>This form does not exist or is not publicly available.</p>", 404);
|
|
10455
10959
|
console.error("Error rendering form:", error);
|
|
10456
10960
|
return c.html("<p>Error loading form</p>", 500);
|
|
10457
10961
|
}
|
|
@@ -10525,6 +11029,7 @@ publicFormsRoutes.post("/:identifier/submit", async (c) => {
|
|
|
10525
11029
|
message: "Form submitted successfully"
|
|
10526
11030
|
});
|
|
10527
11031
|
} catch (error) {
|
|
11032
|
+
if (isTableMissing2(error)) return c.json({ error: "Form not found" }, 404);
|
|
10528
11033
|
console.error("Error submitting form:", error);
|
|
10529
11034
|
return c.json({ error: "Failed to submit form" }, 500);
|
|
10530
11035
|
}
|
|
@@ -10672,7 +11177,7 @@ adminRbacRoutes.get("/", async (c) => {
|
|
|
10672
11177
|
${r.is_system ? `<code class="text-xs text-zinc-500 dark:text-zinc-400">${esc(r.name)}</code><span class="rounded-full bg-zinc-100 dark:bg-white/10 px-2 py-0.5 text-[11px] text-zinc-500 dark:text-zinc-400">system</span>` : `<input form="roles-bulk-form" class="${inpSm} w-28" name="name_${esc(r.id)}" value="${esc(r.name)}" required>`}
|
|
10673
11178
|
<label class="ml-auto inline-flex items-center gap-2 rounded-md bg-white/5 px-2.5 py-1 text-xs font-medium text-zinc-700 dark:text-zinc-300 ring-1 ring-inset ring-zinc-500/20">
|
|
10674
11179
|
<input form="roles-bulk-form" type="checkbox" name="portal_${esc(r.id)}" value="1" ${portalChecked ? "checked" : ""} ${portalDisabled ? "disabled" : ""} class="h-3.5 w-3.5 rounded border-zinc-400 text-cyan-600 focus:ring-cyan-500">
|
|
10675
|
-
|
|
11180
|
+
Admin Panel
|
|
10676
11181
|
</label>
|
|
10677
11182
|
<a href="/admin/tenants/roles/${esc(r.name)}" data-role-tenants="${esc(r.name)}" class="text-xs text-cyan-600 dark:text-cyan-400 hover:underline" title="Per-tenant assignments of this role">tenants</a>
|
|
10678
11183
|
${r.is_system ? "" : `<button form="delete-role-${esc(r.id)}" type="submit" onclick="return confirm('Delete role ${esc(r.name)}?')" class="text-xs text-red-600 dark:text-red-400 hover:underline">delete</button>`}
|
|
@@ -10776,7 +11281,7 @@ adminRbacRoutes.get("/", async (c) => {
|
|
|
10776
11281
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
|
|
10777
11282
|
<div class="${card}">
|
|
10778
11283
|
<h3 class="text-base font-semibold text-zinc-950 dark:text-white mb-3">Roles</h3>
|
|
10779
|
-
<p class="mb-3 text-xs text-zinc-500 dark:text-zinc-400">Use <strong>
|
|
11284
|
+
<p class="mb-3 text-xs text-zinc-500 dark:text-zinc-400">Use <strong>Admin Panel</strong> to allow a role into the admin backend. Resource permissions are configured in the <strong>Matrix</strong> tab.</p>
|
|
10780
11285
|
${roleList}
|
|
10781
11286
|
</div>
|
|
10782
11287
|
<div class="${card}">
|
|
@@ -11074,14 +11579,24 @@ function pluginMenuMiddleware() {
|
|
|
11074
11579
|
}
|
|
11075
11580
|
} catch {
|
|
11076
11581
|
}
|
|
11077
|
-
|
|
11582
|
+
const user = c.get("user");
|
|
11583
|
+
const singletonItems = resolvePluginMenuItems(user ? { role: user.role } : void 0);
|
|
11584
|
+
const existingPaths = new Set(activeMenuItems.map((i) => i.path));
|
|
11585
|
+
for (const item of singletonItems) {
|
|
11586
|
+
if (!existingPaths.has(item.path)) {
|
|
11587
|
+
activeMenuItems.push({ label: item.label, path: item.path, icon: item.icon, order: item.order });
|
|
11588
|
+
}
|
|
11589
|
+
}
|
|
11590
|
+
activeMenuItems.sort((a, b) => a.order - b.order);
|
|
11591
|
+
c.set("pluginMenuItems", activeMenuItems.map((m) => ({ label: m.label, path: m.path, icon: resolveIcon(m.icon) || m.icon || "" })));
|
|
11078
11592
|
await next();
|
|
11079
|
-
|
|
11593
|
+
const finalItems = c.get("pluginMenuItems") ?? [];
|
|
11594
|
+
if (finalItems.length > 0 && c.res.headers.get("content-type")?.includes("text/html")) {
|
|
11080
11595
|
const status = c.res.status;
|
|
11081
11596
|
const headers = new Headers(c.res.headers);
|
|
11082
11597
|
const html4 = await c.res.text();
|
|
11083
11598
|
if (html4.includes(MARKER)) {
|
|
11084
|
-
const renderedItems =
|
|
11599
|
+
const renderedItems = finalItems.map((item) => renderMenuItem(item, path)).join("");
|
|
11085
11600
|
const newHtml = html4.split(MARKER).join(renderedItems);
|
|
11086
11601
|
c.res = new Response(newHtml, { status, headers });
|
|
11087
11602
|
} else {
|
|
@@ -11091,16 +11606,16 @@ function pluginMenuMiddleware() {
|
|
|
11091
11606
|
};
|
|
11092
11607
|
}
|
|
11093
11608
|
init_admin_layout_catalyst_template();
|
|
11094
|
-
var
|
|
11095
|
-
|
|
11096
|
-
|
|
11609
|
+
var adminRoutes6 = new Hono();
|
|
11610
|
+
adminRoutes6.use("*", requireAuth());
|
|
11611
|
+
adminRoutes6.use("*", async (c, next) => {
|
|
11097
11612
|
const user = c.get("user");
|
|
11098
11613
|
if (user?.role !== "admin") {
|
|
11099
11614
|
return c.text("Access denied", 403);
|
|
11100
11615
|
}
|
|
11101
11616
|
return next();
|
|
11102
11617
|
});
|
|
11103
|
-
|
|
11618
|
+
adminRoutes6.get("/", async (c) => {
|
|
11104
11619
|
const user = c.get("user");
|
|
11105
11620
|
const db = c.env.DB;
|
|
11106
11621
|
let totalRequests = 0;
|
|
@@ -11245,6 +11760,7 @@ var EventTrackingService = class {
|
|
|
11245
11760
|
tenantId: TENANT2
|
|
11246
11761
|
});
|
|
11247
11762
|
}
|
|
11763
|
+
db;
|
|
11248
11764
|
docsService;
|
|
11249
11765
|
async trackEvent(input) {
|
|
11250
11766
|
const doc = await this.docsService.create({
|
|
@@ -11456,7 +11972,7 @@ var analyticsPlugin = definePlugin({
|
|
|
11456
11972
|
author: { name: "SonicJS Team", email: "team@sonicjs.com" },
|
|
11457
11973
|
register(app2) {
|
|
11458
11974
|
app2.route("/api/events", apiRoutes4);
|
|
11459
|
-
app2.route("/admin/analytics",
|
|
11975
|
+
app2.route("/admin/analytics", adminRoutes6);
|
|
11460
11976
|
},
|
|
11461
11977
|
menu: [
|
|
11462
11978
|
{
|
|
@@ -11738,8 +12254,8 @@ apiRoutes5.delete("/:id", async (c) => {
|
|
|
11738
12254
|
return c.json({ success: false, error: "Failed to delete variable" }, 500);
|
|
11739
12255
|
}
|
|
11740
12256
|
});
|
|
11741
|
-
var
|
|
11742
|
-
|
|
12257
|
+
var adminRoutes7 = new Hono();
|
|
12258
|
+
adminRoutes7.use("*", async (c, next) => {
|
|
11743
12259
|
try {
|
|
11744
12260
|
const db = c.env?.DB;
|
|
11745
12261
|
if (db) {
|
|
@@ -11750,7 +12266,7 @@ adminRoutes6.use("*", async (c, next) => {
|
|
|
11750
12266
|
}
|
|
11751
12267
|
await next();
|
|
11752
12268
|
});
|
|
11753
|
-
|
|
12269
|
+
adminRoutes7.get("/", async (c) => {
|
|
11754
12270
|
const db = c.env.DB;
|
|
11755
12271
|
let variables = [];
|
|
11756
12272
|
try {
|
|
@@ -11780,7 +12296,7 @@ adminRoutes6.get("/", async (c) => {
|
|
|
11780
12296
|
}
|
|
11781
12297
|
return c.html(renderAdminPage(variables, { editorActive, activeEditorName, enableEditorIntegration }));
|
|
11782
12298
|
});
|
|
11783
|
-
|
|
12299
|
+
adminRoutes7.put("/:id", async (c) => {
|
|
11784
12300
|
const db = c.env.DB;
|
|
11785
12301
|
const id = c.req.param("id");
|
|
11786
12302
|
let body;
|
|
@@ -11796,7 +12312,7 @@ adminRoutes6.put("/:id", async (c) => {
|
|
|
11796
12312
|
}
|
|
11797
12313
|
return c.html('<span class="text-green-400 text-xs">Saved</span>');
|
|
11798
12314
|
});
|
|
11799
|
-
|
|
12315
|
+
adminRoutes7.post("/:id/toggle", async (c) => {
|
|
11800
12316
|
const db = c.env.DB;
|
|
11801
12317
|
const id = c.req.param("id");
|
|
11802
12318
|
await db.prepare("UPDATE global_variables SET is_active = CASE WHEN is_active = 1 THEN 0 ELSE 1 END, updated_at = strftime('%s', 'now') WHERE id = ?").bind(id).run();
|
|
@@ -11804,7 +12320,7 @@ adminRoutes6.post("/:id/toggle", async (c) => {
|
|
|
11804
12320
|
c.header("HX-Redirect", "/admin/global-variables");
|
|
11805
12321
|
return c.body(null, 204);
|
|
11806
12322
|
});
|
|
11807
|
-
|
|
12323
|
+
adminRoutes7.post("/", async (c) => {
|
|
11808
12324
|
const db = c.env.DB;
|
|
11809
12325
|
const form = await c.req.parseBody();
|
|
11810
12326
|
const key = (form.key || "").trim();
|
|
@@ -11825,7 +12341,7 @@ adminRoutes6.post("/", async (c) => {
|
|
|
11825
12341
|
c.header("HX-Redirect", "/admin/global-variables");
|
|
11826
12342
|
return c.body(null, 204);
|
|
11827
12343
|
});
|
|
11828
|
-
|
|
12344
|
+
adminRoutes7.post("/settings/editor-integration", async (c) => {
|
|
11829
12345
|
const db = c.env.DB;
|
|
11830
12346
|
try {
|
|
11831
12347
|
const row = await db.prepare("SELECT settings FROM plugins WHERE id = 'global-variables'").first();
|
|
@@ -11837,7 +12353,7 @@ adminRoutes6.post("/settings/editor-integration", async (c) => {
|
|
|
11837
12353
|
return c.json({ success: false, error: "Failed to update setting" }, 500);
|
|
11838
12354
|
}
|
|
11839
12355
|
});
|
|
11840
|
-
|
|
12356
|
+
adminRoutes7.delete("/:id", async (c) => {
|
|
11841
12357
|
const db = c.env.DB;
|
|
11842
12358
|
await db.prepare("DELETE FROM global_variables WHERE id = ?").bind(c.req.param("id")).run();
|
|
11843
12359
|
invalidateVariablesCache();
|
|
@@ -12168,7 +12684,7 @@ var globalVariablesPlugin = definePlugin({
|
|
|
12168
12684
|
capabilities: ["hooks.content:subscribe"],
|
|
12169
12685
|
register(app2) {
|
|
12170
12686
|
app2.route("/api/global-variables", apiRoutes5);
|
|
12171
|
-
app2.route("/admin/global-variables",
|
|
12687
|
+
app2.route("/admin/global-variables", adminRoutes7);
|
|
12172
12688
|
},
|
|
12173
12689
|
menu: [
|
|
12174
12690
|
{ label: "Global Variables", path: "/admin/global-variables", icon: "bolt", order: 45, permissions: ["global-variables:view"] }
|
|
@@ -12489,8 +13005,8 @@ apiRoutes6.delete("/:id", async (c) => {
|
|
|
12489
13005
|
return c.json({ success: false, error: "Failed to delete shortcode" }, 500);
|
|
12490
13006
|
}
|
|
12491
13007
|
});
|
|
12492
|
-
var
|
|
12493
|
-
|
|
13008
|
+
var adminRoutes8 = new Hono();
|
|
13009
|
+
adminRoutes8.use("*", async (c, next) => {
|
|
12494
13010
|
try {
|
|
12495
13011
|
const db = c.env?.DB;
|
|
12496
13012
|
if (db) {
|
|
@@ -12501,7 +13017,7 @@ adminRoutes7.use("*", async (c, next) => {
|
|
|
12501
13017
|
}
|
|
12502
13018
|
await next();
|
|
12503
13019
|
});
|
|
12504
|
-
|
|
13020
|
+
adminRoutes8.get("/", async (c) => {
|
|
12505
13021
|
const db = c.env.DB;
|
|
12506
13022
|
let shortcodes = [];
|
|
12507
13023
|
try {
|
|
@@ -12531,7 +13047,7 @@ adminRoutes7.get("/", async (c) => {
|
|
|
12531
13047
|
}
|
|
12532
13048
|
return c.html(renderAdminPage2(shortcodes, { editorActive, activeEditorName, enableEditorIntegration }));
|
|
12533
13049
|
});
|
|
12534
|
-
|
|
13050
|
+
adminRoutes8.post("/", async (c) => {
|
|
12535
13051
|
const db = c.env.DB;
|
|
12536
13052
|
const form = await c.req.parseBody();
|
|
12537
13053
|
const name = (form.name || "").trim();
|
|
@@ -12552,7 +13068,7 @@ adminRoutes7.post("/", async (c) => {
|
|
|
12552
13068
|
c.header("HX-Redirect", "/admin/shortcodes");
|
|
12553
13069
|
return c.body(null, 204);
|
|
12554
13070
|
});
|
|
12555
|
-
|
|
13071
|
+
adminRoutes8.post("/settings/editor-integration", async (c) => {
|
|
12556
13072
|
const db = c.env.DB;
|
|
12557
13073
|
try {
|
|
12558
13074
|
const row = await db.prepare("SELECT settings FROM plugins WHERE id = 'shortcodes'").first();
|
|
@@ -12564,7 +13080,7 @@ adminRoutes7.post("/settings/editor-integration", async (c) => {
|
|
|
12564
13080
|
return c.json({ success: false, error: "Failed to update setting" }, 500);
|
|
12565
13081
|
}
|
|
12566
13082
|
});
|
|
12567
|
-
|
|
13083
|
+
adminRoutes8.delete("/:id", async (c) => {
|
|
12568
13084
|
await c.env.DB.prepare("DELETE FROM shortcodes WHERE id = ?").bind(c.req.param("id")).run();
|
|
12569
13085
|
return c.html("");
|
|
12570
13086
|
});
|
|
@@ -12775,7 +13291,7 @@ var shortcodesPlugin = definePlugin({
|
|
|
12775
13291
|
capabilities: ["hooks.content:subscribe"],
|
|
12776
13292
|
register(app2) {
|
|
12777
13293
|
app2.route("/api/shortcodes", apiRoutes6);
|
|
12778
|
-
app2.route("/admin/shortcodes",
|
|
13294
|
+
app2.route("/admin/shortcodes", adminRoutes8);
|
|
12779
13295
|
},
|
|
12780
13296
|
menu: [
|
|
12781
13297
|
{ label: "Shortcodes", path: "/admin/shortcodes", icon: "bolt", order: 46, permissions: ["shortcodes:view"] }
|
|
@@ -12884,6 +13400,9 @@ var helloWorldPlugin = definePlugin({
|
|
|
12884
13400
|
console.info("\u274C Hello World plugin deactivated");
|
|
12885
13401
|
}
|
|
12886
13402
|
});
|
|
13403
|
+
function createHelloWorldPlugin() {
|
|
13404
|
+
return helloWorldPlugin;
|
|
13405
|
+
}
|
|
12887
13406
|
|
|
12888
13407
|
// src/plugins/core-plugins/multi-tenant-plugin/manifest.json
|
|
12889
13408
|
var manifest_default2 = {
|
|
@@ -16057,6 +16576,7 @@ function createSonicJSApp(config = {}) {
|
|
|
16057
16576
|
const magicLinkPlugin = createMagicLinkAuthPlugin();
|
|
16058
16577
|
const corePluginsBeforeCatchAll = [
|
|
16059
16578
|
securityAuditPlugin,
|
|
16579
|
+
apiKeysPlugin,
|
|
16060
16580
|
aiSearchPlugin,
|
|
16061
16581
|
oauthProvidersPlugin,
|
|
16062
16582
|
userProfilesPlugin,
|
|
@@ -16154,6 +16674,17 @@ function createSonicJSApp(config = {}) {
|
|
|
16154
16674
|
app2.use("*", async (_c, next) => {
|
|
16155
16675
|
await next();
|
|
16156
16676
|
});
|
|
16677
|
+
app2.use("*", cors({
|
|
16678
|
+
origin: (origin, c) => {
|
|
16679
|
+
const allowed = c.env?.CORS_ORIGINS;
|
|
16680
|
+
if (!allowed) return null;
|
|
16681
|
+
const list = allowed.split(",").map((s) => s.trim());
|
|
16682
|
+
return list.includes(origin) ? origin : null;
|
|
16683
|
+
},
|
|
16684
|
+
allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
|
16685
|
+
allowHeaders: ["Content-Type", "Authorization", "X-API-Key"],
|
|
16686
|
+
credentials: true
|
|
16687
|
+
}));
|
|
16157
16688
|
app2.use("*", securityHeadersMiddleware());
|
|
16158
16689
|
app2.use("*", csrfProtection());
|
|
16159
16690
|
app2.use("*", async (c, next) => {
|
|
@@ -16187,6 +16718,7 @@ function createSonicJSApp(config = {}) {
|
|
|
16187
16718
|
}
|
|
16188
16719
|
await next();
|
|
16189
16720
|
});
|
|
16721
|
+
app2.use("*", apiKeyAuthMiddleware());
|
|
16190
16722
|
if (config.middleware?.afterAuth) {
|
|
16191
16723
|
for (const middleware of config.middleware.afterAuth) {
|
|
16192
16724
|
app2.use("*", middleware);
|
|
@@ -16211,7 +16743,7 @@ function createSonicJSApp(config = {}) {
|
|
|
16211
16743
|
if (!user?.userId) return next();
|
|
16212
16744
|
let perms = [];
|
|
16213
16745
|
try {
|
|
16214
|
-
const { RbacService: RbacService2 } = await import('./rbac-
|
|
16746
|
+
const { RbacService: RbacService2 } = await import('./rbac-Y43IEQOP.js');
|
|
16215
16747
|
perms = await new RbacService2(c.env.DB, c.env.CACHE_KV).permissionsForUser(user.userId);
|
|
16216
16748
|
} catch {
|
|
16217
16749
|
return next();
|
|
@@ -16285,7 +16817,10 @@ function createSonicJSApp(config = {}) {
|
|
|
16285
16817
|
...corePluginsAfterCatchAll,
|
|
16286
16818
|
...config.plugins?.register ?? []
|
|
16287
16819
|
];
|
|
16288
|
-
|
|
16820
|
+
const userPlugins = (config.plugins?.register ?? []).filter(
|
|
16821
|
+
(p) => !PLUGIN_REGISTRY[p.id]
|
|
16822
|
+
);
|
|
16823
|
+
setPluginMenu(userPlugins.flatMap((p) => p.menu ?? []));
|
|
16289
16824
|
setPluginDefinitions(allMountedPlugins);
|
|
16290
16825
|
}
|
|
16291
16826
|
app2.get("/favicon.svg", (c) => {
|
|
@@ -17150,6 +17685,8 @@ var RedirectService = class {
|
|
|
17150
17685
|
this.cloudflareService = new CloudflareBulkService(env);
|
|
17151
17686
|
}
|
|
17152
17687
|
}
|
|
17688
|
+
db;
|
|
17689
|
+
env;
|
|
17153
17690
|
cloudflareService = null;
|
|
17154
17691
|
getDocService() {
|
|
17155
17692
|
return new DocumentsService(this.db, {
|
|
@@ -19914,6 +20451,6 @@ function createDb(d1) {
|
|
|
19914
20451
|
// src/index.ts
|
|
19915
20452
|
var VERSION = package_default.version;
|
|
19916
20453
|
|
|
19917
|
-
export { BUILT_IN_PROVIDERS, CloudflareEmailProvider2 as CloudflareEmailProvider, OAuthService, VERSION, createDb, createOAuthProvidersPlugin, createRedirectPlugin, createSonicJSApp, emailReconciliationPlugin, generateTriggersComment, oauthProvidersPlugin, parseCronTriggers, redirectPlugin, setupCoreMiddleware, setupCoreRoutes, site_settings_collection_default as siteSettingsCollection, updateWranglerTriggers };
|
|
20454
|
+
export { BUILT_IN_PROVIDERS, CloudflareEmailProvider2 as CloudflareEmailProvider, OAuthService, VERSION, createDb, createHelloWorldPlugin, createOAuthProvidersPlugin, createRedirectPlugin, createSonicJSApp, emailReconciliationPlugin, generateTriggersComment, helloWorldPlugin, oauthProvidersPlugin, parseCronTriggers, redirectPlugin, setupCoreMiddleware, setupCoreRoutes, site_settings_collection_default as siteSettingsCollection, updateWranglerTriggers };
|
|
19918
20455
|
//# sourceMappingURL=index.js.map
|
|
19919
20456
|
//# sourceMappingURL=index.js.map
|