Add nav seed data and nixserver route modules, update schema/seed
This commit is contained in:
@@ -427,3 +427,23 @@ model Setting {
|
|||||||
|
|
||||||
@@map("settings")
|
@@map("settings")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ─── Nav Modules ─────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
model NavModule {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
name String @unique
|
||||||
|
label String
|
||||||
|
sectionId String
|
||||||
|
sectionLabel String
|
||||||
|
sectionIcon String @default("Settings")
|
||||||
|
sectionTo String?
|
||||||
|
sectionWeight Int @default(100)
|
||||||
|
weight Int @default(100)
|
||||||
|
route String
|
||||||
|
enabled Boolean @default(true)
|
||||||
|
builtIn Boolean @default(true)
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
|
||||||
|
@@map("nav_modules")
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,256 @@
|
|||||||
|
type Seed = {
|
||||||
|
name: string; label: string; route: string
|
||||||
|
sectionId: string; sectionLabel: string; sectionIcon: string
|
||||||
|
sectionTo?: string; sectionWeight: number; weight: number
|
||||||
|
}
|
||||||
|
|
||||||
|
const s = (sId: string, sLbl: string, icon: string, sw: number, sTo?: string) =>
|
||||||
|
(nm: string, lbl: string, rt: string, w: number): Seed =>
|
||||||
|
({ name: nm, label: lbl, route: rt, sectionId: sId, sectionLabel: sLbl, sectionIcon: icon, sectionTo: sTo, sectionWeight: sw, weight: w })
|
||||||
|
|
||||||
|
const sc = s('server-config', 'Server Configuration', 'Settings', 10, '/server-configuration')
|
||||||
|
const su = s('support', 'Support', 'HelpCircle', 20)
|
||||||
|
const nw = s('networking', 'Networking Setup', 'Network', 30)
|
||||||
|
const co = s('contacts', 'Server Contacts', 'BookUser', 40)
|
||||||
|
const rs = s('resellers', 'Resellers', 'UserCog', 50)
|
||||||
|
const sv = s('service-config', 'Service Configuration', 'Wrench', 60)
|
||||||
|
const lc = s('locales', 'Locales', 'Languages', 70)
|
||||||
|
const bk = s('backup', 'Backup', 'HardDrive', 80)
|
||||||
|
const cl = s('clusters', 'Clusters', 'GitFork', 90)
|
||||||
|
const rb = s('reboot', 'System Reboot', 'RotateCcw', 100)
|
||||||
|
const st = s('server-status', 'Server Status', 'Activity', 110)
|
||||||
|
const ai = s('account-info', 'Account Information', 'Users', 120)
|
||||||
|
const af = s('account-functions', 'Account Functions', 'UserCheck', 130)
|
||||||
|
const ma = s('multi-account', 'Multi Account Functions', 'Users', 140)
|
||||||
|
const tr = s('transfers', 'Transfers', 'ArrowRightLeft',150)
|
||||||
|
const th = s('themes', 'Themes', 'Paintbrush', 160)
|
||||||
|
const pk = s('packages', 'Packages', 'Package', 170)
|
||||||
|
const dn = s('dns', 'DNS Functions', 'Globe', 180)
|
||||||
|
const db = s('databases', 'Database Services', 'Database', 190)
|
||||||
|
const ip = s('ip', 'IP Functions', 'Wifi', 200)
|
||||||
|
const sw2= s('software', 'Software', 'Box', 210)
|
||||||
|
const em = s('email', 'Email', 'Mail', 220)
|
||||||
|
const sh = s('system-health', 'System Health', 'HeartPulse', 230)
|
||||||
|
const np = s('nixpanel', 'NixPanel', 'LayoutDashboard',240)
|
||||||
|
const sl = s('ssl', 'SSL/TLS', 'Lock', 250)
|
||||||
|
const mk = s('market', 'Market', 'ShoppingBag', 260)
|
||||||
|
const re = s('restart-services', 'Restart Services', 'RefreshCw', 270)
|
||||||
|
const dv = s('development', 'Development', 'Code2', 280)
|
||||||
|
const pl = s('plugins', 'Plugins', 'Puzzle', 290)
|
||||||
|
|
||||||
|
export const NAV_SEED: Seed[] = [
|
||||||
|
sc('basic-nixserver-setup', 'Basic NixServer Setup', '/server-configuration/basic-setup', 10),
|
||||||
|
sc('change-root', 'Change Root Password', '/server-configuration/change-root', 20),
|
||||||
|
sc('configure-analytics', 'Configure Analytics', '/server-configuration/analytics', 30),
|
||||||
|
sc('configure-cron-jobs', 'Configure Cron Jobs', '/server-configuration/cron-jobs', 40),
|
||||||
|
sc('initial-quota-setup', 'Initial Quota Setup', '/server-configuration/quota-setup', 50),
|
||||||
|
sc('link-server-nodes', 'Link Server Nodes', '/server-configuration/link-nodes', 60),
|
||||||
|
sc('server-profile', 'Server Profile', '/server-configuration/server-profile', 70),
|
||||||
|
sc('server-time', 'Server Time', '/server-configuration/server-time', 80),
|
||||||
|
sc('statistics-software', 'Statistics Software', '/server-configuration/statistics-software', 90),
|
||||||
|
sc('terminal', 'Terminal', '/server-configuration/terminal', 100),
|
||||||
|
sc('tweak-settings', 'Tweak Settings', '/server-configuration/tweak-settings', 110),
|
||||||
|
sc('update-preferences', 'Update Preferences', '/server-configuration/update-preferences', 120),
|
||||||
|
sc('nixserver-marketplace', 'NixServer Marketplace', '/server-configuration/marketplace', 130),
|
||||||
|
su('grant-support-access', 'Grant NixPanel Support Access', '/security', 10),
|
||||||
|
su('support-center', 'Support Center', '/settings', 20),
|
||||||
|
nw('change-hostname', 'Change Hostname', '/security', 10),
|
||||||
|
nw('resolver-config', 'Resolver Configuration', '/security', 20),
|
||||||
|
nw('security-center', 'Security Center', '/security', 30),
|
||||||
|
nw('apache-mod-userdir', 'Apache mod_userdir Tweak', '/webserver', 40),
|
||||||
|
nw('smtp-restrictions', 'SMTP Restrictions', '/email', 50),
|
||||||
|
nw('compiler-access', 'Compiler Access', '/security', 60),
|
||||||
|
nw('security-policies', 'Configure Security Policies', '/security', 70),
|
||||||
|
nw('mxstop-brute-force', 'mXSTOP Brute Force Protection', '/security', 80),
|
||||||
|
nw('host-access-control', 'Host Access Control', '/security', 90),
|
||||||
|
nw('external-auth', 'Manage External Authentications', '/security', 100),
|
||||||
|
nw('root-ssh-keys', "Manage root's SSH Keys", '/security', 110),
|
||||||
|
nw('wheel-users', 'Manage Wheel Group Users', '/security', 120),
|
||||||
|
nw('modsecurity-config', 'ModSecurity Configuration', '/security', 130),
|
||||||
|
nw('modsecurity-tools', 'ModSecurity Tools', '/security', 140),
|
||||||
|
nw('modsecurity-vendors', 'ModSecurity Vendors', '/security', 150),
|
||||||
|
nw('password-strength', 'Password Strength Configuration', '/security', 160),
|
||||||
|
nw('security-advisor', 'Security Advisor', '/security', 170),
|
||||||
|
nw('security-questions', 'Security Questions', '/security', 180),
|
||||||
|
nw('shell-fork-bomb', 'Shell Fork Bomb Protection', '/security', 190),
|
||||||
|
nw('ssh-password-auth', 'SSH Password Authorization Tweak', '/security', 200),
|
||||||
|
nw('traceroute', 'Traceroute Enable/Disable', '/security', 210),
|
||||||
|
nw('two-factor-auth', 'Two-Factor Authentication', '/security', 220),
|
||||||
|
co('contact-manager', 'Contact Manager', '/settings', 10),
|
||||||
|
co('system-mail-prefs', 'Edit System Mail Preferences', '/email', 20),
|
||||||
|
rs('change-account-owner', 'Change Ownership of an Account', '/resellers', 10),
|
||||||
|
rs('change-multi-owner', 'Change Ownership of Multiple Accounts', '/resellers', 20),
|
||||||
|
rs('edit-reseller-ns', 'Edit Reseller Nameservers and Privileges', '/resellers', 30),
|
||||||
|
rs('email-all-resellers', 'Email All Resellers', '/resellers', 40),
|
||||||
|
rs('reseller-ip-delegation', "Manage Reseller's IP Delegation", '/resellers', 50),
|
||||||
|
rs('reseller-shared-ip', "Manage Reseller's Shared IP", '/resellers', 60),
|
||||||
|
rs('reseller-center', 'Reseller Center', '/resellers', 70),
|
||||||
|
rs('reset-resellers', 'Reset Resellers', '/resellers', 80),
|
||||||
|
rs('show-reseller-accounts', 'Show Reseller Accounts', '/resellers', 90),
|
||||||
|
rs('view-reseller-usage', 'View Reseller Usage', '/resellers', 100),
|
||||||
|
sv('apache-configuration', 'Apache Configuration', '/webserver', 10),
|
||||||
|
sv('log-rotation', 'Log Rotation Configuration', '/settings', 20),
|
||||||
|
sv('web-disk-config', 'Web Disk Configuration', '/settings', 30),
|
||||||
|
sv('web-services-config', 'Web Services Configuration', '/settings', 40),
|
||||||
|
sv('exim-config', 'Exim Configuration Manager', '/email', 50),
|
||||||
|
sv('ftp-server-selection', 'FTP Server Selection', '/settings', 60),
|
||||||
|
sv('mailserver-config', 'Mailserver Configuration', '/email', 70),
|
||||||
|
sv('manage-service-ssl', 'Manage Service SSL Certificates', '/ssl', 80),
|
||||||
|
sv('nameserver-selection', 'Nameserver Selection', '/dns', 90),
|
||||||
|
sv('service-manager', 'Service Manager', '/services', 100),
|
||||||
|
lc('configure-locales', 'Configure Application Locales', '/settings', 10),
|
||||||
|
lc('copy-locale', 'Copy a Locale', '/settings', 20),
|
||||||
|
lc('delete-locale', 'Delete a Locale', '/settings', 30),
|
||||||
|
lc('edit-locale', 'Edit a Locale', '/settings', 40),
|
||||||
|
lc('locale-xml-download', 'Locale XML Download', '/settings', 50),
|
||||||
|
lc('locale-xml-upload', 'Locale XML Upload', '/settings', 60),
|
||||||
|
lc('view-locales', 'View Available Locales', '/settings', 70),
|
||||||
|
bk('backup-configuration', 'Backup Configuration', '/backup', 10),
|
||||||
|
bk('backup-restoration', 'Backup Restoration', '/backup', 20),
|
||||||
|
bk('backup-user-selection', 'Backup User Selection', '/backup', 30),
|
||||||
|
bk('file-dir-restoration', 'File and Directory Restoration', '/backup', 40),
|
||||||
|
cl('config-cluster', 'Configuration Cluster', '/settings', 10),
|
||||||
|
cl('dns-cluster', 'DNS Cluster', '/dns', 20),
|
||||||
|
cl('remote-access-key', 'Remote Access Key', '/security', 30),
|
||||||
|
rb('force-reboot', 'Forceful Server Reboot', '/system', 10),
|
||||||
|
rb('graceful-reboot', 'Graceful Server Reboot', '/system', 20),
|
||||||
|
st('apache-status', 'Apache Status', '/webserver', 10),
|
||||||
|
st('daily-process-log', 'Daily Process Log', '/system', 20),
|
||||||
|
st('server-information', 'Server Information', '/system', 30),
|
||||||
|
st('service-status', 'Service Status', '/services', 40),
|
||||||
|
st('task-queue-monitor', 'Task Queue Monitor', '/system', 50),
|
||||||
|
ai('list-accounts', 'List Accounts', '/accounts/list', 10),
|
||||||
|
ai('list-parked-domains', 'List Parked Domains', '/accounts/parked-domains', 20),
|
||||||
|
ai('list-subdomains', 'List Subdomains', '/accounts/subdomains', 30),
|
||||||
|
ai('list-suspended', 'List Suspended Accounts', '/accounts/suspended', 40),
|
||||||
|
ai('show-over-quota', 'Show Accounts Over Quota', '/accounts/over-quota', 50),
|
||||||
|
ai('view-bandwidth', 'View Bandwidth Usage', '/accounts/bandwidth', 60),
|
||||||
|
af('change-site-ip', "Change Site's IP Address", '/accounts/change-ip', 10),
|
||||||
|
af('create-account', 'Create a New Account', '/accounts/create', 20),
|
||||||
|
af('email-all-users', 'Email All Users', '/accounts/email-users', 30),
|
||||||
|
af('force-password-change', 'Force Password Change', '/accounts/force-password', 40),
|
||||||
|
af('limit-bandwidth', 'Limit Bandwidth Usage', '/accounts/limit-bandwidth',50),
|
||||||
|
af('manage-suspension', 'Manage Account Suspension', '/accounts/suspension', 60),
|
||||||
|
af('manage-demo-mode', 'Manage Demo Mode', '/accounts/demo-mode', 70),
|
||||||
|
af('manage-shell-access', 'Manage Shell Access', '/accounts/shell-access', 80),
|
||||||
|
af('modify-account', 'Modify an Account', '/accounts/modify', 90),
|
||||||
|
af('password-modification', 'Password Modification', '/accounts/password', 100),
|
||||||
|
af('quota-modification', 'Quota Modification', '/accounts/quota', 110),
|
||||||
|
af('raw-apache-log', 'Raw Apache Log Download', '/accounts/apache-logs', 120),
|
||||||
|
af('raw-nginx-log', 'Raw NGINX Log Download', '/accounts/nginx-logs', 130),
|
||||||
|
af('rearrange-account', 'Rearrange an Account', '/accounts/rearrange', 140),
|
||||||
|
af('reset-acct-bandwidth', 'Reset Account Bandwidth', '/accounts/reset-bandwidth',150),
|
||||||
|
af('terminate-accounts', 'Terminate Accounts', '/accounts/terminate', 160),
|
||||||
|
af('unsuspend-bw', 'Unsuspend Bandwidth Exceeders', '/accounts/unsuspend-bandwidth',170),
|
||||||
|
af('upgrade-downgrade', 'Upgrade/Downgrade an Account', '/accounts/upgrade', 180),
|
||||||
|
af('web-template-editor', 'Web Template Editor', '/accounts/web-template', 190),
|
||||||
|
ma('bulk-ip', "Change Multiple Sites' IP Addresses",'/accounts/bulk-ip', 10),
|
||||||
|
ma('bulk-modify', 'Modify/Upgrade Multiple Accounts', '/accounts/bulk-modify', 20),
|
||||||
|
tr('addon-to-account', 'Convert Addon Domain to Account', '/accounts', 10),
|
||||||
|
tr('review-transfers', 'Review Transfers and Restores', '/accounts', 20),
|
||||||
|
tr('transfer-cpanel', 'Transfer or Restore a cPanel Account','/accounts',30),
|
||||||
|
tr('transfer-tool', 'Transfer Tool', '/accounts', 40),
|
||||||
|
th('theme-manager', 'Theme Manager', '/settings', 10),
|
||||||
|
pk('add-package', 'Add a Package', '/packages', 10),
|
||||||
|
pk('delete-package', 'Delete a Package', '/packages', 20),
|
||||||
|
pk('edit-package', 'Edit a Package', '/packages', 30),
|
||||||
|
pk('feature-manager', 'Feature Manager', '/packages', 40),
|
||||||
|
dn('add-dns-zone', 'Add a DNS Zone', '/dns', 10),
|
||||||
|
dn('add-a-entry', 'Add an A Entry for Hostname', '/dns', 20),
|
||||||
|
dn('delete-dns-zone', 'Delete a DNS Zone', '/dns', 30),
|
||||||
|
dn('dns-zone-manager', 'DNS Zone Manager', '/dns', 40),
|
||||||
|
dn('edit-zone-templates', 'Edit Zone Templates', '/dns', 50),
|
||||||
|
dn('email-dns-records', 'Email DNS Record Manager', '/dns', 60),
|
||||||
|
dn('email-routing-config', 'Email Routing Configuration', '/email', 70),
|
||||||
|
dn('enable-dkim-spf', 'Enable DKIM/SPF Globally', '/email', 80),
|
||||||
|
dn('ns-record-report', 'Nameserver Record Report', '/dns', 90),
|
||||||
|
dn('park-domain', 'Park a Domain', '/dns', 100),
|
||||||
|
dn('dns-cleanup', 'Perform a DNS Cleanup', '/dns', 110),
|
||||||
|
dn('set-zone-ttl', 'Set Zone TTL', '/dns', 120),
|
||||||
|
dn('domain-forwarding', 'Setup/Edit Domain Forwarding', '/dns', 130),
|
||||||
|
dn('sync-dns-records', 'Synchronize DNS Records', '/dns', 140),
|
||||||
|
db('change-db-root-pass', 'Change Database Root Password', '/settings', 10),
|
||||||
|
db('change-db-user-pass', 'Change Database User Password', '/settings', 20),
|
||||||
|
db('db-map-tool', 'Database Map Tool', '/settings', 30),
|
||||||
|
db('edit-db-config', 'Edit Database Configuration', '/settings', 40),
|
||||||
|
db('manage-db-hosts', 'Manage Database Access Hosts', '/settings', 50),
|
||||||
|
db('manage-db-profiles', 'Manage Database Profiles', '/settings', 60),
|
||||||
|
db('manage-db-users', 'Manage Database Users', '/settings', 70),
|
||||||
|
db('manage-databases', 'Manage Databases', '/settings', 80),
|
||||||
|
db('phpmyadmin', 'phpMyAdmin', '/settings', 90),
|
||||||
|
db('repair-databases', 'Repair Databases', '/settings', 100),
|
||||||
|
db('show-db-processes', 'Show Database Processes', '/settings', 110),
|
||||||
|
db('upgrade-db-version', 'Upgrade Database Version', '/settings', 120),
|
||||||
|
ip('ipv6-ranges', 'IPv6 Ranges', '/security', 10),
|
||||||
|
ip('add-ip', 'Add a New IP Address', '/security', 20),
|
||||||
|
ip('assign-ipv6', 'Assign IPv6 Address', '/security', 30),
|
||||||
|
ip('configure-remote-ips', 'Configure Remote Service IPs', '/security', 40),
|
||||||
|
ip('ip-migration', 'IP Migration Wizard', '/security', 50),
|
||||||
|
ip('rebuild-ip-pool', 'Rebuild the IP Address Pool', '/security', 60),
|
||||||
|
ip('show-ip-usage', 'Show IP Address Usage', '/security', 70),
|
||||||
|
ip('show-delete-ips', 'Show or Delete Current IPs', '/security', 80),
|
||||||
|
ip('reserved-ips', 'Show/Edit Reserved IPs', '/security', 90),
|
||||||
|
sw2('install-perl-module', 'Install a Perl Module', '/system', 10),
|
||||||
|
sw2('install-distro-pkgs', 'Install Distro Packages', '/system', 20),
|
||||||
|
sw2('module-installers', 'Module Installers', '/system', 30),
|
||||||
|
sw2('multiphp-ini-editor', 'MultiPHP INI Editor', '/php', 40),
|
||||||
|
sw2('multiphp-manager', 'MultiPHP Manager', '/php', 50),
|
||||||
|
sw2('nginx-manager', 'NGINX Manager', '/webserver', 60),
|
||||||
|
sw2('rebuild-rpm-db', 'Rebuild RPM Database', '/system', 70),
|
||||||
|
sw2('system-update', 'System Update', '/system', 80),
|
||||||
|
sw2('update-server-software','Update Server Software', '/system', 90),
|
||||||
|
sw2('easyapache4', 'EasyApache 4', '/webserver', 100),
|
||||||
|
em('email-deliverability', 'Email Deliverability', '/email', 10),
|
||||||
|
em('filter-by-country', 'Filter Incoming Emails by Country', '/email', 20),
|
||||||
|
em('filter-by-domain', 'Filter Incoming Emails by Domain', '/email', 30),
|
||||||
|
em('greylisting', 'Greylisting', '/email', 40),
|
||||||
|
em('mail-delivery-reports', 'Mail Delivery Reports', '/email', 50),
|
||||||
|
em('mail-queue-manager', 'Mail Queue Manager', '/email', 60),
|
||||||
|
em('mail-troubleshooter', 'Mail Troubleshooter', '/email', 70),
|
||||||
|
em('mailbox-conversion', 'Mailbox Conversion', '/email', 80),
|
||||||
|
em('repair-mailbox-perms', 'Repair Mailbox Permissions', '/email', 90),
|
||||||
|
em('spamd-startup', 'Spamd Startup Configuration', '/email', 100),
|
||||||
|
em('view-mail-stats', 'View Mail Statistics Summary', '/email', 110),
|
||||||
|
em('view-relayers', 'View Relayers', '/email', 120),
|
||||||
|
em('view-sent-summary', 'View Sent Summary', '/email', 130),
|
||||||
|
sh('bg-process-killer', 'Background Process Killer', '/system', 10),
|
||||||
|
sh('process-manager', 'Process Manager', '/system', 20),
|
||||||
|
sh('show-disk-usage', 'Show Current Disk Usage', '/system', 30),
|
||||||
|
sh('show-processes', 'Show Current Running Processes', '/system', 40),
|
||||||
|
np('changelog', 'Change Log', '/settings', 10),
|
||||||
|
np('customization', 'Customization', '/settings', 20),
|
||||||
|
np('manage-plugins', 'Manage Plugins', '/modules', 30),
|
||||||
|
np('modify-news', 'Modify NixPanel News', '/settings', 40),
|
||||||
|
np('reset-mailman-pass', 'Reset a Mailman Password', '/email', 50),
|
||||||
|
np('upgrade-latest', 'Upgrade to Latest Version', '/settings', 60),
|
||||||
|
sl('generate-ssl', 'Generate an SSL Certificate and Signing Request', '/ssl', 10),
|
||||||
|
sl('install-ssl', 'Install an SSL Certificate on a Domain', '/ssl', 20),
|
||||||
|
sl('manage-autossl', 'Manage AutoSSL', '/ssl', 30),
|
||||||
|
sl('manage-ssl-hosts', 'Manage SSL Hosts', '/ssl', 40),
|
||||||
|
sl('purchase-ssl', 'Purchase and Install an SSL Certificate', '/ssl', 50),
|
||||||
|
sl('ssl-storage', 'SSL Storage Manager', '/ssl', 60),
|
||||||
|
sl('ssl-config', 'SSL/TLS Configuration', '/ssl', 70),
|
||||||
|
mk('market-provider', 'Market Provider Manager', '/settings', 10),
|
||||||
|
re('restart-db', 'Database Server', '/services', 10),
|
||||||
|
re('restart-dns', 'DNS Server', '/services', 20),
|
||||||
|
re('restart-apache', 'HTTP Server (Apache)', '/services', 30),
|
||||||
|
re('restart-imap', 'IMAP Server', '/services', 40),
|
||||||
|
re('restart-exim', 'Mail Server (Exim)', '/services', 50),
|
||||||
|
re('restart-mailman', 'Mailing List Manager (Mailman)', '/services', 60),
|
||||||
|
re('restart-php-fpm', 'PHP-FPM service for Apache', '/services', 70),
|
||||||
|
re('restart-ssh', 'SSH Server (OpenSSH)', '/services', 80),
|
||||||
|
dv('appconfig-apps', 'Apps Managed by AppConfig', '/settings', 10),
|
||||||
|
dv('dev-forum', 'NixPanel Development Forum', '/settings', 20),
|
||||||
|
dv('plugin-file-gen', 'NixPanel Plugin File Generator', '/settings', 30),
|
||||||
|
dv('developer-docs', 'Developer Documentation', '/settings', 40),
|
||||||
|
dv('manage-api-tokens', 'Manage API Tokens', '/settings', 50),
|
||||||
|
dv('manage-hooks', 'Manage Hooks', '/settings', 60),
|
||||||
|
dv('openapi-nixpanel', 'OpenAPI Documentation for NixPanel', '/settings', 70),
|
||||||
|
dv('openapi-nixserver', 'OpenAPI Documentation for NixServer','/settings', 80),
|
||||||
|
pl('backuply', 'Backuply by Softaculous', '/backup', 10),
|
||||||
|
pl('imunifyav', 'ImunifyAV', '/security', 20),
|
||||||
|
pl('server-monitoring', 'Server Monitoring', '/system', 30),
|
||||||
|
pl('sitepad', 'SitePad Website Builder', '/settings', 40),
|
||||||
|
pl('softaculous', 'Softaculous - Instant Installs', '/settings', 50),
|
||||||
|
pl('wp-toolkit', 'WP Toolkit', '/settings', 60),
|
||||||
|
]
|
||||||
@@ -90,6 +90,22 @@ async function main() {
|
|||||||
}
|
}
|
||||||
console.log('Created default settings')
|
console.log('Created default settings')
|
||||||
|
|
||||||
|
// Nav modules
|
||||||
|
const { NAV_SEED } = await import('./navSeed.js')
|
||||||
|
for (const m of NAV_SEED) {
|
||||||
|
await prisma.navModule.upsert({
|
||||||
|
where: { name: m.name },
|
||||||
|
update: {
|
||||||
|
label: m.label, route: m.route,
|
||||||
|
sectionId: m.sectionId, sectionLabel: m.sectionLabel,
|
||||||
|
sectionIcon: m.sectionIcon, sectionTo: m.sectionTo ?? null,
|
||||||
|
sectionWeight: m.sectionWeight, weight: m.weight,
|
||||||
|
},
|
||||||
|
create: { ...m, sectionTo: m.sectionTo ?? null, enabled: true, builtIn: true },
|
||||||
|
})
|
||||||
|
}
|
||||||
|
console.log(`Seeded ${NAV_SEED.length} nav modules`)
|
||||||
|
|
||||||
console.log('Seed complete.')
|
console.log('Seed complete.')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,106 @@
|
|||||||
|
import type { FastifyInstance } from 'fastify'
|
||||||
|
import { z } from 'zod'
|
||||||
|
import prisma from '../../../db/client.js'
|
||||||
|
import { requireAdmin } from '../../../middleware/auth.js'
|
||||||
|
|
||||||
|
const ModuleBody = z.object({
|
||||||
|
name: z.string().min(1).max(64).regex(/^[a-z0-9-]+$/),
|
||||||
|
label: z.string().min(1).max(128),
|
||||||
|
sectionId: z.string().min(1).max(64),
|
||||||
|
sectionLabel: z.string().min(1).max(128),
|
||||||
|
sectionIcon: z.string().min(1).max(64).default('Settings'),
|
||||||
|
sectionTo: z.string().optional(),
|
||||||
|
sectionWeight: z.number().int().default(100),
|
||||||
|
weight: z.number().int().default(100),
|
||||||
|
route: z.string().min(1).max(256),
|
||||||
|
})
|
||||||
|
|
||||||
|
const UpdateBody = z.object({
|
||||||
|
label: z.string().min(1).max(128).optional(),
|
||||||
|
sectionId: z.string().min(1).max(64).optional(),
|
||||||
|
sectionLabel: z.string().min(1).max(128).optional(),
|
||||||
|
sectionIcon: z.string().min(1).max(64).optional(),
|
||||||
|
sectionTo: z.string().nullable().optional(),
|
||||||
|
sectionWeight: z.number().int().optional(),
|
||||||
|
weight: z.number().int().optional(),
|
||||||
|
route: z.string().min(1).max(256).optional(),
|
||||||
|
enabled: z.boolean().optional(),
|
||||||
|
})
|
||||||
|
|
||||||
|
export default async function moduleRoutes(fastify: FastifyInstance) {
|
||||||
|
// ── GET /nav — grouped nav for sidebar (enabled modules only) ──────────────
|
||||||
|
fastify.get('/nav', { preHandler: [requireAdmin] }, async (_req, reply) => {
|
||||||
|
const modules = await prisma.navModule.findMany({
|
||||||
|
where: { enabled: true },
|
||||||
|
orderBy: [{ sectionWeight: 'asc' }, { weight: 'asc' }],
|
||||||
|
})
|
||||||
|
|
||||||
|
// Group by sectionId
|
||||||
|
const sectionMap = new Map<string, {
|
||||||
|
id: string; label: string; icon: string; to?: string | null; items: typeof modules
|
||||||
|
}>()
|
||||||
|
|
||||||
|
for (const m of modules) {
|
||||||
|
if (!sectionMap.has(m.sectionId)) {
|
||||||
|
sectionMap.set(m.sectionId, {
|
||||||
|
id: m.sectionId, label: m.sectionLabel,
|
||||||
|
icon: m.sectionIcon, to: m.sectionTo,
|
||||||
|
items: [],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
sectionMap.get(m.sectionId)!.items.push(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
return reply.send({ success: true, data: Array.from(sectionMap.values()) })
|
||||||
|
})
|
||||||
|
|
||||||
|
// ── GET / — all modules for Module Manager ─────────────────────────────────
|
||||||
|
fastify.get('/', { preHandler: [requireAdmin] }, async (_req, reply) => {
|
||||||
|
const modules = await prisma.navModule.findMany({
|
||||||
|
orderBy: [{ sectionWeight: 'asc' }, { weight: 'asc' }],
|
||||||
|
})
|
||||||
|
return reply.send({ success: true, data: modules })
|
||||||
|
})
|
||||||
|
|
||||||
|
// ── POST / — install a new module ──────────────────────────────────────────
|
||||||
|
fastify.post('/', { preHandler: [requireAdmin] }, async (request, reply) => {
|
||||||
|
const body = ModuleBody.safeParse(request.body)
|
||||||
|
if (!body.success) return reply.code(400).send({ success: false, error: body.error.issues[0].message })
|
||||||
|
|
||||||
|
const existing = await prisma.navModule.findUnique({ where: { name: body.data.name } })
|
||||||
|
if (existing) return reply.code(409).send({ success: false, error: 'Module name already exists' })
|
||||||
|
|
||||||
|
const module = await prisma.navModule.create({
|
||||||
|
data: { ...body.data, sectionTo: body.data.sectionTo ?? null, enabled: true, builtIn: false },
|
||||||
|
})
|
||||||
|
return reply.code(201).send({ success: true, data: module })
|
||||||
|
})
|
||||||
|
|
||||||
|
// ── PUT /:id — update module ───────────────────────────────────────────────
|
||||||
|
fastify.put('/:id', { preHandler: [requireAdmin] }, async (request, reply) => {
|
||||||
|
const id = parseInt((request.params as { id: string }).id)
|
||||||
|
if (isNaN(id)) return reply.code(400).send({ success: false, error: 'Invalid id' })
|
||||||
|
|
||||||
|
const body = UpdateBody.safeParse(request.body)
|
||||||
|
if (!body.success) return reply.code(400).send({ success: false, error: body.error.issues[0].message })
|
||||||
|
|
||||||
|
const module = await prisma.navModule.findUnique({ where: { id } })
|
||||||
|
if (!module) return reply.code(404).send({ success: false, error: 'Module not found' })
|
||||||
|
|
||||||
|
const updated = await prisma.navModule.update({ where: { id }, data: body.data })
|
||||||
|
return reply.send({ success: true, data: updated })
|
||||||
|
})
|
||||||
|
|
||||||
|
// ── DELETE /:id — remove a non-built-in module ─────────────────────────────
|
||||||
|
fastify.delete('/:id', { preHandler: [requireAdmin] }, async (request, reply) => {
|
||||||
|
const id = parseInt((request.params as { id: string }).id)
|
||||||
|
if (isNaN(id)) return reply.code(400).send({ success: false, error: 'Invalid id' })
|
||||||
|
|
||||||
|
const module = await prisma.navModule.findUnique({ where: { id } })
|
||||||
|
if (!module) return reply.code(404).send({ success: false, error: 'Module not found' })
|
||||||
|
if (module.builtIn) return reply.code(403).send({ success: false, error: 'Cannot delete a built-in module' })
|
||||||
|
|
||||||
|
await prisma.navModule.delete({ where: { id } })
|
||||||
|
return reply.send({ success: true, data: null })
|
||||||
|
})
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user