@sonicjs-cms/core 2.17.2 → 2.18.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 (43) hide show
  1. package/dist/{chunk-P4RAIX7B.cjs → chunk-3XP76LM7.cjs} +8 -8
  2. package/dist/{chunk-P4RAIX7B.cjs.map → chunk-3XP76LM7.cjs.map} +1 -1
  3. package/dist/{chunk-FXWF5D5V.cjs → chunk-56PLLVDG.cjs} +9 -3
  4. package/dist/chunk-56PLLVDG.cjs.map +1 -0
  5. package/dist/{chunk-Q3W6LCEN.cjs → chunk-74BFRAQS.cjs} +3 -3
  6. package/dist/{chunk-Q3W6LCEN.cjs.map → chunk-74BFRAQS.cjs.map} +1 -1
  7. package/dist/{chunk-LVGB5UU5.cjs → chunk-DAESIIWY.cjs} +2 -2
  8. package/dist/{chunk-LVGB5UU5.cjs.map → chunk-DAESIIWY.cjs.map} +1 -1
  9. package/dist/{chunk-K6QVIOTA.js → chunk-GH3HYA7D.js} +4 -4
  10. package/dist/{chunk-K6QVIOTA.js.map → chunk-GH3HYA7D.js.map} +1 -1
  11. package/dist/{chunk-2VY2G7OR.cjs → chunk-LTJ7P7RT.cjs} +242 -124
  12. package/dist/chunk-LTJ7P7RT.cjs.map +1 -0
  13. package/dist/{chunk-I2Z72YTD.js → chunk-NDS4S4AG.js} +3 -3
  14. package/dist/{chunk-I2Z72YTD.js.map → chunk-NDS4S4AG.js.map} +1 -1
  15. package/dist/{chunk-ITGOUYVN.js → chunk-OWJPOVFW.js} +2 -2
  16. package/dist/{chunk-ITGOUYVN.js.map → chunk-OWJPOVFW.js.map} +1 -1
  17. package/dist/{chunk-KJSZMIBF.js → chunk-RYRNZYND.js} +128 -10
  18. package/dist/chunk-RYRNZYND.js.map +1 -0
  19. package/dist/{chunk-NAYUXSNR.js → chunk-YK5IEGQZ.js} +9 -3
  20. package/dist/chunk-YK5IEGQZ.js.map +1 -0
  21. package/dist/index.cjs +196 -153
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.js +65 -22
  24. package/dist/index.js.map +1 -1
  25. package/dist/middleware.cjs +32 -32
  26. package/dist/middleware.js +3 -3
  27. package/dist/migrations-CW2IT5YP.cjs +13 -0
  28. package/dist/{migrations-Q7C6F2RM.cjs.map → migrations-CW2IT5YP.cjs.map} +1 -1
  29. package/dist/migrations-S42BOXI4.js +4 -0
  30. package/dist/{migrations-IFZLGVV3.js.map → migrations-S42BOXI4.js.map} +1 -1
  31. package/dist/routes.cjs +28 -28
  32. package/dist/routes.js +5 -5
  33. package/dist/services.cjs +23 -23
  34. package/dist/services.js +2 -2
  35. package/dist/utils.cjs +11 -11
  36. package/dist/utils.js +1 -1
  37. package/package.json +1 -1
  38. package/dist/chunk-2VY2G7OR.cjs.map +0 -1
  39. package/dist/chunk-FXWF5D5V.cjs.map +0 -1
  40. package/dist/chunk-KJSZMIBF.js.map +0 -1
  41. package/dist/chunk-NAYUXSNR.js.map +0 -1
  42. package/dist/migrations-IFZLGVV3.js +0 -4
  43. package/dist/migrations-Q7C6F2RM.cjs +0 -13
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
- import { renderConfirmationDialog, getConfirmationDialogScript, api_default, api_media_default, api_system_default, admin_api_default, router, adminCollectionsRoutes, adminFormsRoutes, adminSettingsRoutes, public_forms_default, router2, admin_content_default, adminMediaRoutes, userProfilesPlugin, adminPluginRoutes, adminLogsRoutes, userRoutes, auth_default, test_cleanup_default } from './chunk-KJSZMIBF.js';
2
- export { ROUTES_INFO, admin_api_default as adminApiRoutes, adminCheckboxRoutes, admin_code_examples_default as adminCodeExamplesRoutes, adminCollectionsRoutes, admin_content_default as adminContentRoutes, router as adminDashboardRoutes, adminDesignRoutes, adminLogsRoutes, adminMediaRoutes, adminPluginRoutes, adminSettingsRoutes, admin_testimonials_default as adminTestimonialsRoutes, 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-KJSZMIBF.js';
1
+ import { renderConfirmationDialog, getConfirmationDialogScript, api_default, api_media_default, api_system_default, admin_api_default, router, adminCollectionsRoutes, adminFormsRoutes, adminSettingsRoutes, public_forms_default, router2, admin_content_default, adminMediaRoutes, userProfilesPlugin, adminPluginRoutes, adminLogsRoutes, userRoutes, auth_default, test_cleanup_default } from './chunk-RYRNZYND.js';
2
+ export { ROUTES_INFO, admin_api_default as adminApiRoutes, adminCheckboxRoutes, admin_code_examples_default as adminCodeExamplesRoutes, adminCollectionsRoutes, admin_content_default as adminContentRoutes, router as adminDashboardRoutes, adminDesignRoutes, adminLogsRoutes, adminMediaRoutes, adminPluginRoutes, adminSettingsRoutes, admin_testimonials_default as adminTestimonialsRoutes, 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-RYRNZYND.js';
3
3
  import { SettingsService, setAppInstance, schema_exports } from './chunk-QFWHAFEO.js';
4
4
  export { Logger, apiTokens, collections, content, contentVersions, getLogger, initLogger, insertCollectionSchema, insertContentSchema, insertLogConfigSchema, insertMediaSchema, insertPluginActivityLogSchema, insertPluginAssetSchema, insertPluginHookSchema, insertPluginRouteSchema, insertPluginSchema, insertSystemLogSchema, insertUserSchema, insertWorkflowHistorySchema, logConfig, media, pluginActivityLog, pluginAssets, pluginHooks, pluginRoutes, plugins, selectCollectionSchema, selectContentSchema, selectLogConfigSchema, selectMediaSchema, selectPluginActivityLogSchema, selectPluginAssetSchema, selectPluginHookSchema, selectPluginRouteSchema, selectPluginSchema, selectSystemLogSchema, selectUserSchema, selectWorkflowHistorySchema, systemLogs, users, workflowHistory } from './chunk-QFWHAFEO.js';
5
- import { requireAuth, getJwtExpirySecondsFromDb, AuthManager, metricsMiddleware, bootstrapMiddleware, securityHeadersMiddleware, csrfProtection, requireRole } from './chunk-K6QVIOTA.js';
6
- export { AuthManager, PermissionManager, bootstrapMiddleware, cacheHeaders, compressionMiddleware, detailedLoggingMiddleware, getActivePlugins, isPluginActive, logActivity, loggingMiddleware, optionalAuth, performanceLoggingMiddleware, requireActivePlugin, requireActivePlugins, requireAnyPermission, requireAuth, requirePermission, requireRole, securityHeadersMiddleware as securityHeaders, securityLoggingMiddleware } from './chunk-K6QVIOTA.js';
7
- import { PluginService, PLUGIN_REGISTRY } from './chunk-NAYUXSNR.js';
8
- export { PluginBootstrapService, PluginService as PluginServiceClass, backfillFormSubmissions, cleanupRemovedCollections, createContentFromSubmission, deriveCollectionSchemaFromFormio, deriveSubmissionTitle, fullCollectionSync, getAvailableCollectionNames, getManagedCollections, isCollectionManaged, loadCollectionConfig, loadCollectionConfigs, mapFormStatusToContentStatus, registerCollections, syncAllFormCollections, syncCollection, syncCollections, syncFormCollection, validateCollectionConfig } from './chunk-NAYUXSNR.js';
9
- export { MigrationService } from './chunk-ITGOUYVN.js';
5
+ import { requireAuth, getJwtExpirySecondsFromDb, AuthManager, metricsMiddleware, bootstrapMiddleware, securityHeadersMiddleware, csrfProtection, requireRole } from './chunk-GH3HYA7D.js';
6
+ export { AuthManager, PermissionManager, bootstrapMiddleware, cacheHeaders, compressionMiddleware, detailedLoggingMiddleware, getActivePlugins, isPluginActive, logActivity, loggingMiddleware, optionalAuth, performanceLoggingMiddleware, requireActivePlugin, requireActivePlugins, requireAnyPermission, requireAuth, requirePermission, requireRole, securityHeadersMiddleware as securityHeaders, securityLoggingMiddleware } from './chunk-GH3HYA7D.js';
7
+ import { PluginService, PLUGIN_REGISTRY } from './chunk-YK5IEGQZ.js';
8
+ export { PluginBootstrapService, PluginService as PluginServiceClass, backfillFormSubmissions, cleanupRemovedCollections, createContentFromSubmission, deriveCollectionSchemaFromFormio, deriveSubmissionTitle, fullCollectionSync, getAvailableCollectionNames, getManagedCollections, isCollectionManaged, loadCollectionConfig, loadCollectionConfigs, mapFormStatusToContentStatus, registerCollections, syncAllFormCollections, syncCollection, syncCollections, syncFormCollection, validateCollectionConfig } from './chunk-YK5IEGQZ.js';
9
+ export { MigrationService } from './chunk-OWJPOVFW.js';
10
10
  export { renderFilterBar } from './chunk-ON5ZMSU4.js';
11
11
  import { renderAdminLayout } from './chunk-XWIA3HVX.js';
12
12
  export { getConfirmationDialogScript, renderAlert, renderConfirmationDialog, renderForm, renderFormField, renderPagination, renderTable } from './chunk-XWIA3HVX.js';
@@ -14,8 +14,8 @@ import { init_admin_layout_catalyst_template, renderAdminLayoutCatalyst } from '
14
14
  export { HookSystemImpl, HookUtils, PluginManager as PluginManagerClass, PluginRegistryImpl, PluginValidator as PluginValidatorClass, ScopedHookSystem as ScopedHookSystemClass } from './chunk-TFNTM3OA.js';
15
15
  import { PluginBuilder, PluginHelpers } from './chunk-EXNEW5US.js';
16
16
  export { PluginBuilder, PluginHelpers } from './chunk-EXNEW5US.js';
17
- import { package_default, getCoreVersion } from './chunk-I2Z72YTD.js';
18
- export { QueryFilterBuilder, SONICJS_VERSION, TemplateRenderer, buildQuery, getCoreVersion, renderTemplate, templateRenderer } from './chunk-I2Z72YTD.js';
17
+ import { package_default, getCoreVersion } from './chunk-NDS4S4AG.js';
18
+ export { QueryFilterBuilder, SONICJS_VERSION, TemplateRenderer, buildQuery, getCoreVersion, renderTemplate, templateRenderer } from './chunk-NDS4S4AG.js';
19
19
  import './chunk-X7ZAEI5S.js';
20
20
  export { metricsTracker } from './chunk-FICTAGD4.js';
21
21
  export { escapeHtml, sanitizeInput, sanitizeObject } from './chunk-TQABQWOP.js';
@@ -1613,7 +1613,27 @@ var OTPService = class {
1613
1613
  };
1614
1614
 
1615
1615
  // src/plugins/core-plugins/otp-login-plugin/email-templates.ts
1616
+ function sanitizeColor(value) {
1617
+ if (!value) return "";
1618
+ if (/^#[0-9a-fA-F]{3,8}$/.test(value)) return value;
1619
+ if (/^[a-zA-Z]+$/.test(value)) return value;
1620
+ if (/^(rgb|rgba|hsl|hsla)\([0-9.,\s%]+\)$/.test(value)) return value;
1621
+ return "";
1622
+ }
1623
+ function escapeHtml3(value) {
1624
+ return value.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/'/g, "&#39;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
1625
+ }
1616
1626
  function renderOTPEmailHTML(data) {
1627
+ const logoUrl = data.logoUrl ? escapeHtml3(data.logoUrl) : "";
1628
+ const loginUrl = data.loginUrl ? escapeHtml3(data.loginUrl) : "";
1629
+ const appName = escapeHtml3(data.appName);
1630
+ const loginButtonText = escapeHtml3(
1631
+ data.loginButtonText && data.loginButtonText.trim() || `Sign in to ${data.appName}`
1632
+ );
1633
+ const logoWidth = Math.max(20, Math.min(600, Number(data.logoWidth) || 150));
1634
+ const logoBorderWidth = Math.max(0, Math.min(20, Number(data.logoBorderWidth) || 0));
1635
+ const logoBorderColor = sanitizeColor(data.logoBorderColor);
1636
+ const logoBorderStyle = logoBorderWidth > 0 && logoBorderColor ? `border: ${logoBorderWidth}px solid ${logoBorderColor}; border-radius: 8px;` : "";
1617
1637
  return `<!DOCTYPE html>
1618
1638
  <html>
1619
1639
  <head>
@@ -1625,15 +1645,15 @@ function renderOTPEmailHTML(data) {
1625
1645
 
1626
1646
  <div style="background: white; border-radius: 12px; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0,0.1);">
1627
1647
 
1628
- ${data.logoUrl ? `
1648
+ ${logoUrl ? `
1629
1649
  <div style="text-align: center; padding: 30px 20px 20px;">
1630
- <img src="${data.logoUrl}" alt="Logo" style="max-width: 150px; height: auto;">
1650
+ <img src="${logoUrl}" alt="${appName}" style="max-width: ${logoWidth}px; width: 100%; height: auto; ${logoBorderStyle}">
1631
1651
  </div>
1632
1652
  ` : ""}
1633
1653
 
1634
1654
  <div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 40px 30px; text-align: center;">
1635
1655
  <h1 style="margin: 0 0 10px 0; font-size: 32px; font-weight: 600;">Your Login Code</h1>
1636
- <p style="margin: 0; opacity: 0.95; font-size: 16px;">Enter this code to sign in to ${data.appName}</p>
1656
+ <p style="margin: 0; opacity: 0.95; font-size: 16px;">Enter this code to sign in to ${appName}</p>
1637
1657
  </div>
1638
1658
 
1639
1659
  <div style="padding: 40px 30px;">
@@ -1643,6 +1663,14 @@ function renderOTPEmailHTML(data) {
1643
1663
  </div>
1644
1664
  </div>
1645
1665
 
1666
+ ${loginUrl ? `
1667
+ <div style="text-align: center; margin: 0 0 30px 0;">
1668
+ <a href="${loginUrl}" style="display: inline-block; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; text-decoration: none; padding: 14px 32px; border-radius: 8px; font-weight: 600; font-size: 16px;">
1669
+ ${loginButtonText}
1670
+ </a>
1671
+ </div>
1672
+ ` : ""}
1673
+
1646
1674
  <div style="background: #fff3cd; border-left: 4px solid #ffc107; padding: 16px 20px; margin: 0 0 30px 0; border-radius: 6px;">
1647
1675
  <p style="margin: 0; font-size: 14px; color: #856404;">
1648
1676
  <strong>\u26A0\uFE0F This code expires in ${data.expiryMinutes} minutes</strong>
@@ -1664,7 +1692,7 @@ function renderOTPEmailHTML(data) {
1664
1692
  \u{1F512} Security Notice
1665
1693
  </p>
1666
1694
  <p style="margin: 0; font-size: 13px; color: #004080; line-height: 1.6;">
1667
- Never share this code with anyone. ${data.appName} will never ask you for this code via phone, email, or social media.
1695
+ Never share this code with anyone. ${appName} will never ask you for this code via phone, email, or social media.
1668
1696
  </p>
1669
1697
  </div>
1670
1698
  </div>
@@ -1676,22 +1704,23 @@ function renderOTPEmailHTML(data) {
1676
1704
  </p>
1677
1705
 
1678
1706
  <div style="text-align: center; color: #999; font-size: 12px; line-height: 1.6;">
1679
- <p style="margin: 5px 0;">This email was sent to ${data.email}</p>
1680
- ${data.ipAddress ? `<p style="margin: 5px 0;">IP Address: ${data.ipAddress}</p>` : ""}
1681
- <p style="margin: 5px 0;">Time: ${data.timestamp}</p>
1707
+ <p style="margin: 5px 0;">This email was sent to ${escapeHtml3(data.email)}</p>
1708
+ ${data.ipAddress ? `<p style="margin: 5px 0;">IP Address: ${escapeHtml3(data.ipAddress)}</p>` : ""}
1709
+ <p style="margin: 5px 0;">Time: ${escapeHtml3(data.timestamp)}</p>
1682
1710
  </div>
1683
1711
  </div>
1684
1712
 
1685
1713
  </div>
1686
1714
 
1687
1715
  <div style="text-align: center; padding: 20px; color: #999; font-size: 12px;">
1688
- <p style="margin: 0;">&copy; ${(/* @__PURE__ */ new Date()).getFullYear()} ${data.appName}. All rights reserved.</p>
1716
+ <p style="margin: 0;">&copy; ${(/* @__PURE__ */ new Date()).getFullYear()} ${appName}. All rights reserved.</p>
1689
1717
  </div>
1690
1718
 
1691
1719
  </body>
1692
1720
  </html>`;
1693
1721
  }
1694
1722
  function renderOTPEmailText(data) {
1723
+ const ctaLabel = data.loginButtonText && data.loginButtonText.trim() || `Sign in to ${data.appName}`;
1695
1724
  return `Your Login Code for ${data.appName}
1696
1725
 
1697
1726
  Your one-time verification code is:
@@ -1699,6 +1728,9 @@ Your one-time verification code is:
1699
1728
  ${data.code}
1700
1729
 
1701
1730
  This code expires in ${data.expiryMinutes} minutes.
1731
+ ${data.loginUrl ? `
1732
+ ${ctaLabel}: ${data.loginUrl}
1733
+ ` : ""}
1702
1734
 
1703
1735
  Quick Tips:
1704
1736
  \u2022 Enter the code exactly as shown (${data.codeLength} digits)
@@ -1739,7 +1771,13 @@ var DEFAULT_SETTINGS = {
1739
1771
  codeExpiryMinutes: 10,
1740
1772
  maxAttempts: 3,
1741
1773
  rateLimitPerHour: 5,
1742
- allowNewUserRegistration: false
1774
+ allowNewUserRegistration: false,
1775
+ logoUrl: "",
1776
+ logoWidth: 150,
1777
+ logoBorderWidth: 0,
1778
+ logoBorderColor: "#ffffff",
1779
+ loginUrl: "",
1780
+ loginButtonText: ""
1743
1781
  };
1744
1782
  function createOTPLoginPlugin() {
1745
1783
  const builder = PluginBuilder.create({
@@ -1829,7 +1867,12 @@ function createOTPLoginPlugin() {
1829
1867
  ipAddress,
1830
1868
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1831
1869
  appName: siteName,
1832
- logoUrl: settings.logoUrl || ""
1870
+ logoUrl: settings.logoUrl || "",
1871
+ logoWidth: settings.logoWidth,
1872
+ logoBorderWidth: settings.logoBorderWidth,
1873
+ logoBorderColor: settings.logoBorderColor || "",
1874
+ loginUrl: settings.loginUrl || "",
1875
+ loginButtonText: settings.loginButtonText || ""
1833
1876
  });
1834
1877
  const emailPlugin2 = await db.prepare(`
1835
1878
  SELECT settings FROM plugins WHERE id = 'email'
@@ -7868,7 +7911,7 @@ adminRoutes4.get("/", async (c) => {
7868
7911
  <div class="divide-y divide-zinc-950/5 dark:divide-white/10">
7869
7912
  ${topPages.length > 0 ? topPages.map((p) => `
7870
7913
  <div class="flex items-center justify-between px-6 py-3">
7871
- <span class="text-sm text-zinc-700 dark:text-zinc-300 font-mono truncate">${escapeHtml3(p.path)}</span>
7914
+ <span class="text-sm text-zinc-700 dark:text-zinc-300 font-mono truncate">${escapeHtml4(p.path)}</span>
7872
7915
  <span class="text-sm font-medium text-zinc-500 dark:text-zinc-400">${p.views}</span>
7873
7916
  </div>
7874
7917
  `).join("") : `
@@ -7897,7 +7940,7 @@ adminRoutes4.get("/", async (c) => {
7897
7940
  <tbody class="divide-y divide-zinc-950/5 dark:divide-white/10">
7898
7941
  ${recentActivity.length > 0 ? recentActivity.map((a) => `
7899
7942
  <tr>
7900
- <td class="px-6 py-2 font-mono text-zinc-700 dark:text-zinc-300 truncate max-w-xs">${escapeHtml3(a.url || "")}</td>
7943
+ <td class="px-6 py-2 font-mono text-zinc-700 dark:text-zinc-300 truncate max-w-xs">${escapeHtml4(a.url || "")}</td>
7901
7944
  <td class="px-6 py-2"><span class="inline-flex items-center rounded px-1.5 py-0.5 text-xs font-medium ${a.method === "GET" ? "bg-green-50 text-green-700 dark:bg-green-900/30 dark:text-green-400" : "bg-blue-50 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400"}">${a.method || ""}</span></td>
7902
7945
  <td class="px-6 py-2"><span class="inline-flex items-center rounded px-1.5 py-0.5 text-xs font-medium ${(a.status_code || 0) >= 400 ? "bg-red-50 text-red-700 dark:bg-red-900/30 dark:text-red-400" : "bg-green-50 text-green-700 dark:bg-green-900/30 dark:text-green-400"}">${a.status_code || ""}</span></td>
7903
7946
  <td class="px-6 py-2 text-zinc-500 dark:text-zinc-400">${a.duration || 0}ms</td>
@@ -7927,7 +7970,7 @@ adminRoutes4.get("/", async (c) => {
7927
7970
  dynamicMenuItems: c.get("pluginMenuItems")
7928
7971
  }));
7929
7972
  });
7930
- function escapeHtml3(str) {
7973
+ function escapeHtml4(str) {
7931
7974
  return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
7932
7975
  }
7933
7976