From 2280abae905ef41b20cc6913bef975f04eca1396 Mon Sep 17 00:00:00 2001 From: bjarne Date: Fri, 30 Aug 2024 13:26:11 +0000 Subject: [PATCH] initial commit --- .eslintrc.json | 3 + .gitignore | 36 + .idea/.gitignore | 5 + .idea/jsLibraryMappings.xml | 6 + README.md | 36 + app/api/dhcp/config/route.js | 29 + app/api/grant-sudo/route.js | 25 + app/components/Card.jsx | 17 + app/components/Navbar.jsx | 29 + app/components/Notification.jsx | 30 + app/configure/page.js | 153 + app/context/NotificationContext.js | 25 + app/favicon.ico | Bin 0 -> 25931 bytes app/globals.css | 0 app/layout.js | 28 + app/leases/page.js | 40 + app/lib/dhcpConfig.js | 31 + app/lib/parseLeases.js | 36 + app/page.js | 14 + app/page.module.css | 230 ++ jsconfig.json | 7 + next.config.mjs | 4 + package-lock.json | 4344 ++++++++++++++++++++++++++++ package.json | 22 + 24 files changed, 5150 insertions(+) create mode 100644 .eslintrc.json create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/jsLibraryMappings.xml create mode 100644 README.md create mode 100644 app/api/dhcp/config/route.js create mode 100644 app/api/grant-sudo/route.js create mode 100644 app/components/Card.jsx create mode 100644 app/components/Navbar.jsx create mode 100644 app/components/Notification.jsx create mode 100644 app/configure/page.js create mode 100644 app/context/NotificationContext.js create mode 100644 app/favicon.ico create mode 100644 app/globals.css create mode 100644 app/layout.js create mode 100644 app/leases/page.js create mode 100644 app/lib/dhcpConfig.js create mode 100644 app/lib/parseLeases.js create mode 100644 app/page.js create mode 100644 app/page.module.css create mode 100644 jsconfig.json create mode 100644 next.config.mjs create mode 100644 package-lock.json create mode 100644 package.json diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..bffb357 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "next/core-web-vitals" +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fd3dbb5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,36 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js +.yarn/install-state.gz + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..b58b603 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/jsLibraryMappings.xml b/.idea/jsLibraryMappings.xml new file mode 100644 index 0000000..d23208f --- /dev/null +++ b/.idea/jsLibraryMappings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..0dc9ea2 --- /dev/null +++ b/README.md @@ -0,0 +1,36 @@ +This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). + +## Getting Started + +First, run the development server: + +```bash +npm run dev +# or +yarn dev +# or +pnpm dev +# or +bun dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file. + +This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. + +## Learn More + +To learn more about Next.js, take a look at the following resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. + +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! + +## Deploy on Vercel + +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. + +Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. diff --git a/app/api/dhcp/config/route.js b/app/api/dhcp/config/route.js new file mode 100644 index 0000000..2bb93e4 --- /dev/null +++ b/app/api/dhcp/config/route.js @@ -0,0 +1,29 @@ +import { NextResponse } from 'next/server'; +import fs from 'fs'; +import { exec } from 'child_process'; + +const dhcpConfigPath = '/etc/dhcp/dhcpd.conf'; // Make sure this path is correct for your system + +export async function GET() { + try { + const config = fs.readFileSync(dhcpConfigPath, 'utf8'); + return NextResponse.json({ config }); + } catch (error) { + return NextResponse.json({ error: 'Failed to read DHCP configuration' }, { status: 500 }); + } +} + +export async function POST(request) { + try { + const { config } = await request.json(); + fs.writeFileSync(dhcpConfigPath, config, 'utf8'); + exec('sudo systemctl restart isc-dhcp-server', (error, stdout, stderr) => { + if (error) { + throw new Error(`Failed to restart DHCP server: ${stderr}`); + } + }); + return NextResponse.json({ success: true }); + } catch (error) { + return NextResponse.json({ error: 'Failed to write DHCP configuration or restart server' }, { status: 500 }); + } +} diff --git a/app/api/grant-sudo/route.js b/app/api/grant-sudo/route.js new file mode 100644 index 0000000..b78f40b --- /dev/null +++ b/app/api/grant-sudo/route.js @@ -0,0 +1,25 @@ +import { NextResponse } from 'next/server'; +import { exec } from 'child_process'; + +const dhcpConfigPath = '/etc/dhcp/dhcpd.conf'; + +export async function POST(request) { + const { username, password } = await request.json(); + + try { + const command = ` + echo '${password}' | sudo -S visudo -c && + echo '${username} ALL=(ALL) NOPASSWD: /bin/systemctl restart isc-dhcp-server' | sudo tee -a /etc/sudoers && + echo '${password}' | sudo -S chown ${username}:${username} ${dhcpConfigPath} + `; + + exec(command, (error, stdout, stderr) => { + if (error) { + throw new Error(stderr); + } + }); + return NextResponse.json({ success: true }); + } catch (error) { + return NextResponse.json({ error: 'Failed to grant sudo rights or set file permissions' }, { status: 500 }); + } +} diff --git a/app/components/Card.jsx b/app/components/Card.jsx new file mode 100644 index 0000000..2ccb866 --- /dev/null +++ b/app/components/Card.jsx @@ -0,0 +1,17 @@ +import Link from 'next/link'; + +const Card = ({ title, text, url }) => { + return ( +
+
+
+
{title}
+

{text}

+ Go to {title} +
+
+
+ ); +}; + +export default Card; diff --git a/app/components/Navbar.jsx b/app/components/Navbar.jsx new file mode 100644 index 0000000..acd7db1 --- /dev/null +++ b/app/components/Navbar.jsx @@ -0,0 +1,29 @@ +import Link from 'next/link'; + +const Navbar = () => { + return ( + + ); +}; + +export default Navbar; diff --git a/app/components/Notification.jsx b/app/components/Notification.jsx new file mode 100644 index 0000000..5c30b94 --- /dev/null +++ b/app/components/Notification.jsx @@ -0,0 +1,30 @@ +'use client'; + +import { useNotification } from '../context/NotificationContext'; + +const Notification = () => { + const { notification, clearNotification } = useNotification(); + + if (!notification) return null; + + const notificationTypeClass = { + success: 'alert-success', + error: 'alert-danger', + warning: 'alert-warning', + info: 'alert-info', + }[notification.type] || 'alert-info'; + + return ( +
+ {notification.message} + +
+ ); +}; + +export default Notification; diff --git a/app/configure/page.js b/app/configure/page.js new file mode 100644 index 0000000..a680931 --- /dev/null +++ b/app/configure/page.js @@ -0,0 +1,153 @@ +'use client'; + +import { useState, useEffect } from 'react'; +import { useNotification } from '@/app/context/NotificationContext'; + +export default function ConfigurePage() { + const [config, setConfig] = useState(''); + const { showNotification } = useNotification(); + const [showDialog, setShowDialog] = useState(false); + const [username, setUsername] = useState(''); + const [password, setPassword] = useState(''); + + // Function to fetch the DHCP configuration + const fetchConfig = async () => { + try { + const response = await fetch('/api/dhcp/config'); + const data = await response.json(); + if (response.ok) { + setConfig(data.config); + showNotification('DHCP configuration loaded successfully.', 'success'); + } else { + showNotification(data.error, 'error'); + } + } catch (error) { + showNotification('Error loading DHCP configuration', 'error'); + } + }; + + useEffect(() => { + // Initial load of the DHCP configuration + fetchConfig(); + }, []); + + const handleConfigChange = (event) => { + setConfig(event.target.value); + }; + + const handleSave = async () => { + try { + const response = await fetch('/api/dhcp/config', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ config }), + }); + const data = await response.json(); + if (response.ok) { + showNotification('DHCP configuration updated and server restarted successfully.', 'success'); + } else { + showNotification(data.error, 'error'); + } + } catch (error) { + showNotification('Error updating configuration or restarting server', 'error'); + } + }; + + // automatically add webserver to sudo + const openDialog = () => { + setShowDialog(true); + }; + + const closeDialog = () => { + setShowDialog(false); + }; + + const handleGrantSudoRights = async () => { + try { + const response = await fetch('/api/grant-sudo', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ username, password }), + }); + const data = await response.json(); + if (response.ok) { + showNotification('Sudo rights granted successfully.', 'success'); + } else { + showNotification(data.error, 'error'); + } + closeDialog(); + } catch (error) { + showNotification('Error granting sudo rights', 'error'); + } + }; + + + return ( +
+

Configure DHCP Options

+
+ +