From f0c03a9b8e15387c4defd0a0e3e0298324406fae Mon Sep 17 00:00:00 2001 From: flu0r1ne Date: Mon, 28 Aug 2023 21:33:44 -0500 Subject: Add wg2nd --- pages/logs/[directory].tsx | 4 +- pages/logs/index.tsx | 18 ++-- pages/wg2nd/desc.md | 13 +++ pages/wg2nd/index.tsx | 199 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 224 insertions(+), 10 deletions(-) create mode 100644 pages/wg2nd/desc.md create mode 100644 pages/wg2nd/index.tsx (limited to 'pages') diff --git a/pages/logs/[directory].tsx b/pages/logs/[directory].tsx index c3760f7..59875f1 100644 --- a/pages/logs/[directory].tsx +++ b/pages/logs/[directory].tsx @@ -36,7 +36,7 @@ export const getStaticProps: GetStaticProps = async ( const post = await getPostFromDirectory(directory); const markdown = await getMarkdown(post); - + return { props: { post, markdown }, } @@ -57,4 +57,4 @@ export async function getStaticPaths() { paths, fallback: false }; -} \ No newline at end of file +} diff --git a/pages/logs/index.tsx b/pages/logs/index.tsx index a10fdee..358dff7 100644 --- a/pages/logs/index.tsx +++ b/pages/logs/index.tsx @@ -19,14 +19,16 @@ const Logs : FC = ({ posts }) => { - -
    - { - posts.map(({ directory, meta }) => ( -
  • {meta.name}
  • - )) - } -
+ <> + +
    + { + posts.map(({ directory, meta }) => ( +
  • {meta.name}
  • + )) + } +
+
); }; diff --git a/pages/wg2nd/desc.md b/pages/wg2nd/desc.md new file mode 100644 index 0000000..1d917ac --- /dev/null +++ b/pages/wg2nd/desc.md @@ -0,0 +1,13 @@ +wg2nd +===== + +`wg2nd` converts WireGuard configurations from `wg-quick` format into `systemd-networkd` compatible configurations. +This is a web port of `wg2nd` which converts WireGuard configurations into Bash commands to set up the `networkd` +device and network configurations. Note that the output is not compatible with Zsh. **The web port operates entirely on the client-side, +ensuring that no sensitive data is transmitted or stored externally.** For more comprehensive control and features, +including batch conversions and the option to install a firewall, the Linux tool `wg2nd` is available [here](https://www.git.flu0r1ne.net/wg2nd) +and can be installed from source. + +Both versions are open-source and dual-licensed under GPL-2.0 and MIT. Limitations and further details for each version +are elaborated in this [comprehensive post](/logs/announcing-wg2nd). For installation instructions +for the Linux tool and additional information, please refer to the [README](https://www.git.flu0r1ne.net/wg2nd/tree/README.md?h=main). diff --git a/pages/wg2nd/index.tsx b/pages/wg2nd/index.tsx new file mode 100644 index 0000000..02537b3 --- /dev/null +++ b/pages/wg2nd/index.tsx @@ -0,0 +1,199 @@ +// pages/index.tsx +import Head from 'next/head'; +import { useEffect, useRef, useState } from 'react'; + +import Box from '../../components/Box'; +import TextArea from '../../components/TextArea'; +import Input from '../../components/Input'; +import Button from '../../components/Button'; +import Markdown from '../../components/Markdown'; +import Typography from '../../components/Typography'; + +import Script from 'next/script'; + +// @ts-ignore +import desc from './desc.md'; + + +/* + * HOOK THE MODULE FROM THE DOM + */ + +declare global { + interface Window { + Module: any; + } +} + +const useModule = (onInitCallback? : (module: T) => void): T | null => { + const [module, setModule] = useState(null); + + useEffect(() => { + + var Module = { + onRuntimeInitialized: function () { + if(onInitCallback !== undefined) { + onInitCallback(window.Module); + } + + setModule(window.Module); + }, + }; + + if(module === null && typeof window.Module === "object") { + if(onInitCallback !== undefined) { + onInitCallback(window.Module); + } + + setModule(window.Module); + } + + }); + + + return module; +}; + + +const DEMO_CONFIG = `[Interface] +PrivateKey = 0OCS+dV5wsDje6qUAEDQzPmTNWOLE9HE8kfGU1wJUE0= +Address = 10.55.127.342/32, ab00:aaaa:aaa:aa02::5:abcd/128 +DNS = 10.64.0.1 + +[Peer] +PublicKey = WBSnuq6Vswxz5G5zz9pUt60ZSA+JfZ1iTXdg0RJGjks= +AllowedIPs = 0.0.0.0/0,::0/0 +Endpoint = 128.45.210.64:51821 +`; + +let rows = 0; +for(const char of DEMO_CONFIG) + if(char == '\n') rows++; + +interface PanelProps { + children?: React.ReactNode; + customStyle?: React.CSSProperties; +}; + +const Panel: React.FC = ({ children, customStyle }) => ( +
+ {children} +
+); + +interface Wg2ndModule { + wg2nd_cmdseq: (intfName : string, intfconfig : string) => string; +}; + +import { Breadcrumbs, LinkCrumb } from "../../components/Breadcrumbs"; + +const Wg2nd = () => { + const intfNameRef = useRef(null); + const intfConfigRef = useRef(null); + const ndConfigRef = useRef(null); + const parentDebounceDiv = useRef(null); + + const convertConfig = (module : Wg2ndModule | null) => { + if(intfNameRef.current === null || intfConfigRef.current === null || module === null) + return; + + const intfName = intfNameRef.current!.value; + const intfConfig = intfConfigRef.current!.value; + + console.log(module); + const result = module.wg2nd_cmdseq(intfName, intfConfig); + + // This is a hack: adjust a wrapper around the output text area + // Thus, we can detect the scrollHeight of the TextArea without + // the screen moving. + parentDebounceDiv.current!.style.height = ndConfigRef.current!.style.height; + ndConfigRef.current!.style.height = `0px`; + + ndConfigRef.current!.value = result; + + const scrollHeight = ndConfigRef.current!.scrollHeight; + ndConfigRef.current!.style.height = `${scrollHeight}px`; + parentDebounceDiv.current!.style.height = 'auto'; + }; + + const module = useModule(convertConfig); + + return ( + <> +