@sonicjs-cms/core 2.17.2 → 2.18.1
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/dist/{chunk-ITGOUYVN.js → chunk-4R3NOOL3.js} +2 -2
- package/dist/{chunk-ITGOUYVN.js.map → chunk-4R3NOOL3.js.map} +1 -1
- package/dist/{chunk-LVGB5UU5.cjs → chunk-C54YUA23.cjs} +2 -2
- package/dist/{chunk-LVGB5UU5.cjs.map → chunk-C54YUA23.cjs.map} +1 -1
- package/dist/{chunk-P4RAIX7B.cjs → chunk-DSUJ5YQH.cjs} +8 -8
- package/dist/{chunk-P4RAIX7B.cjs.map → chunk-DSUJ5YQH.cjs.map} +1 -1
- package/dist/{chunk-NAYUXSNR.js → chunk-EW5NOBVU.js} +9 -3
- package/dist/chunk-EW5NOBVU.js.map +1 -0
- package/dist/{chunk-K6QVIOTA.js → chunk-I2H5NGJQ.js} +4 -4
- package/dist/{chunk-K6QVIOTA.js.map → chunk-I2H5NGJQ.js.map} +1 -1
- package/dist/{chunk-I2Z72YTD.js → chunk-MGFRZO24.js} +3 -3
- package/dist/{chunk-I2Z72YTD.js.map → chunk-MGFRZO24.js.map} +1 -1
- package/dist/{chunk-Q3W6LCEN.cjs → chunk-SQ6FNXU2.cjs} +3 -3
- package/dist/{chunk-Q3W6LCEN.cjs.map → chunk-SQ6FNXU2.cjs.map} +1 -1
- package/dist/{chunk-2VY2G7OR.cjs → chunk-SXXTQETM.cjs} +245 -125
- package/dist/chunk-SXXTQETM.cjs.map +1 -0
- package/dist/{chunk-FXWF5D5V.cjs → chunk-T3Q5V33G.cjs} +9 -3
- package/dist/chunk-T3Q5V33G.cjs.map +1 -0
- package/dist/{chunk-KJSZMIBF.js → chunk-XXDFQERJ.js} +131 -12
- package/dist/chunk-XXDFQERJ.js.map +1 -0
- package/dist/index.cjs +211 -158
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +80 -27
- package/dist/index.js.map +1 -1
- package/dist/middleware.cjs +32 -32
- package/dist/middleware.js +3 -3
- package/dist/migrations-IYNTWDC6.cjs +13 -0
- package/dist/{migrations-Q7C6F2RM.cjs.map → migrations-IYNTWDC6.cjs.map} +1 -1
- package/dist/migrations-R337UD46.js +4 -0
- package/dist/{migrations-IFZLGVV3.js.map → migrations-R337UD46.js.map} +1 -1
- package/dist/routes.cjs +28 -28
- package/dist/routes.js +5 -5
- package/dist/services.cjs +23 -23
- package/dist/services.js +2 -2
- package/dist/utils.cjs +11 -11
- package/dist/utils.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-2VY2G7OR.cjs.map +0 -1
- package/dist/chunk-FXWF5D5V.cjs.map +0 -1
- package/dist/chunk-KJSZMIBF.js.map +0 -1
- package/dist/chunk-NAYUXSNR.js.map +0 -1
- package/dist/migrations-IFZLGVV3.js +0 -4
- 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-
|
|
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-
|
|
1
|
+
import { getCustomData, 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-XXDFQERJ.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-XXDFQERJ.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-
|
|
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-
|
|
7
|
-
import { PluginService, PLUGIN_REGISTRY } from './chunk-
|
|
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-
|
|
9
|
-
export { MigrationService } from './chunk-
|
|
5
|
+
import { requireAuth, getJwtExpirySecondsFromDb, AuthManager, metricsMiddleware, bootstrapMiddleware, securityHeadersMiddleware, csrfProtection, requireRole } from './chunk-I2H5NGJQ.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-I2H5NGJQ.js';
|
|
7
|
+
import { PluginService, PLUGIN_REGISTRY } from './chunk-EW5NOBVU.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-EW5NOBVU.js';
|
|
9
|
+
export { MigrationService } from './chunk-4R3NOOL3.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-
|
|
18
|
-
export { QueryFilterBuilder, SONICJS_VERSION, TemplateRenderer, buildQuery, getCoreVersion, renderTemplate, templateRenderer } from './chunk-
|
|
17
|
+
import { package_default, getCoreVersion } from './chunk-MGFRZO24.js';
|
|
18
|
+
export { QueryFilterBuilder, SONICJS_VERSION, TemplateRenderer, buildQuery, getCoreVersion, renderTemplate, templateRenderer } from './chunk-MGFRZO24.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, "&").replace(/"/g, """).replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">");
|
|
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
|
-
${
|
|
1648
|
+
${logoUrl ? `
|
|
1629
1649
|
<div style="text-align: center; padding: 30px 20px 20px;">
|
|
1630
|
-
<img src="${
|
|
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 ${
|
|
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. ${
|
|
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;">© ${(/* @__PURE__ */ new Date()).getFullYear()} ${
|
|
1716
|
+
<p style="margin: 0;">© ${(/* @__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'
|
|
@@ -1918,7 +1961,7 @@ function createOTPLoginPlugin() {
|
|
|
1918
1961
|
}, 401);
|
|
1919
1962
|
}
|
|
1920
1963
|
let user = await db.prepare(`
|
|
1921
|
-
SELECT id, email, role, is_active
|
|
1964
|
+
SELECT id, email, username, first_name, last_name, role, is_active, created_at
|
|
1922
1965
|
FROM users
|
|
1923
1966
|
WHERE email = ?
|
|
1924
1967
|
`).bind(normalizedEmail).first();
|
|
@@ -1932,7 +1975,16 @@ function createOTPLoginPlugin() {
|
|
|
1932
1975
|
password_hash, role, is_active, email_verified, created_at, updated_at
|
|
1933
1976
|
) VALUES (?, ?, ?, '', '', NULL, 'viewer', 1, 1, ?, ?)
|
|
1934
1977
|
`).bind(userId, normalizedEmail, username, now, now).run();
|
|
1935
|
-
user = {
|
|
1978
|
+
user = {
|
|
1979
|
+
id: userId,
|
|
1980
|
+
email: normalizedEmail,
|
|
1981
|
+
username,
|
|
1982
|
+
first_name: "",
|
|
1983
|
+
last_name: "",
|
|
1984
|
+
role: "viewer",
|
|
1985
|
+
is_active: 1,
|
|
1986
|
+
created_at: now
|
|
1987
|
+
};
|
|
1936
1988
|
}
|
|
1937
1989
|
if (!user) {
|
|
1938
1990
|
return c.json({
|
|
@@ -1952,12 +2004,13 @@ function createOTPLoginPlugin() {
|
|
|
1952
2004
|
sameSite: "Strict",
|
|
1953
2005
|
maxAge: tokenTtl
|
|
1954
2006
|
});
|
|
2007
|
+
const customData = await getCustomData(db, user.id);
|
|
2008
|
+
const { is_active, ...publicUser } = user;
|
|
1955
2009
|
return c.json({
|
|
1956
2010
|
success: true,
|
|
1957
2011
|
user: {
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
role: user.role
|
|
2012
|
+
...publicUser,
|
|
2013
|
+
...customData
|
|
1961
2014
|
},
|
|
1962
2015
|
token,
|
|
1963
2016
|
message: "Authentication successful"
|
|
@@ -7868,7 +7921,7 @@ adminRoutes4.get("/", async (c) => {
|
|
|
7868
7921
|
<div class="divide-y divide-zinc-950/5 dark:divide-white/10">
|
|
7869
7922
|
${topPages.length > 0 ? topPages.map((p) => `
|
|
7870
7923
|
<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">${
|
|
7924
|
+
<span class="text-sm text-zinc-700 dark:text-zinc-300 font-mono truncate">${escapeHtml4(p.path)}</span>
|
|
7872
7925
|
<span class="text-sm font-medium text-zinc-500 dark:text-zinc-400">${p.views}</span>
|
|
7873
7926
|
</div>
|
|
7874
7927
|
`).join("") : `
|
|
@@ -7897,7 +7950,7 @@ adminRoutes4.get("/", async (c) => {
|
|
|
7897
7950
|
<tbody class="divide-y divide-zinc-950/5 dark:divide-white/10">
|
|
7898
7951
|
${recentActivity.length > 0 ? recentActivity.map((a) => `
|
|
7899
7952
|
<tr>
|
|
7900
|
-
<td class="px-6 py-2 font-mono text-zinc-700 dark:text-zinc-300 truncate max-w-xs">${
|
|
7953
|
+
<td class="px-6 py-2 font-mono text-zinc-700 dark:text-zinc-300 truncate max-w-xs">${escapeHtml4(a.url || "")}</td>
|
|
7901
7954
|
<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
7955
|
<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
7956
|
<td class="px-6 py-2 text-zinc-500 dark:text-zinc-400">${a.duration || 0}ms</td>
|
|
@@ -7927,7 +7980,7 @@ adminRoutes4.get("/", async (c) => {
|
|
|
7927
7980
|
dynamicMenuItems: c.get("pluginMenuItems")
|
|
7928
7981
|
}));
|
|
7929
7982
|
});
|
|
7930
|
-
function
|
|
7983
|
+
function escapeHtml4(str) {
|
|
7931
7984
|
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
7932
7985
|
}
|
|
7933
7986
|
|