import Button from "@components/Button"; import Code from "@components/Code"; import FancyToggleSwitch from "@components/FancyToggleSwitch"; import HelpText from "@components/HelpText"; import InlineLink from "@components/InlineLink"; import { Input } from "@components/Input"; import { Label } from "@components/Label"; import { Modal, ModalClose, ModalContent, ModalFooter, ModalTrigger, } from "@components/modal/Modal"; import ModalHeader from "@components/modal/ModalHeader"; import { notify } from "@components/Notification"; import Paragraph from "@components/Paragraph"; import { PeerGroupSelector } from "@components/PeerGroupSelector"; import Separator from "@components/Separator"; import { IconRepeat } from "@tabler/icons-react"; import { useApiCall } from "@utils/api"; import { cn } from "@utils/helpers"; import { trim } from "lodash"; import { AlarmClock, CopyIcon, ExternalLinkIcon, MonitorSmartphoneIcon, PlusCircle, PowerOffIcon, } from "lucide-react"; import React, { useMemo, useState } from "react"; import { useSWRConfig } from "swr"; import SetupKeysIcon from "@/assets/icons/SetupKeysIcon"; import useCopyToClipboard from "@/hooks/useCopyToClipboard"; import { SetupKey } from "@/interfaces/SetupKey"; import useGroupHelper from "@/modules/groups/useGroupHelper"; type Props = { children?: React.ReactNode; open: boolean; setOpen: (open: boolean) => void; }; const copyMessage = "Setup-Key was copied to your clipboard!"; export default function SetupKeyModal({ children, open, setOpen, }: Readonly) { const [successModal, setSuccessModal] = useState(false); const [setupKey, setSetupKey] = useState(); const [, copy] = useCopyToClipboard(setupKey?.key); const handleSuccess = (setupKey: SetupKey) => { setSetupKey(setupKey); setSuccessModal(true); }; return ( <> {children && {children}} { setSuccessModal(open); setOpen(open); }} > e.preventDefault()} onInteractOutside={(e) => e.preventDefault()} onPointerDownOutside={(e) => e.preventDefault()} maxWidthClass={"max-w-md"} className={"mt-20"} showClose={false} >

Setup key created successfully!

This key will not be shown again, so be sure to copy it and store in a secure location.
{setupKey?.key || "Setup key could not be created..."}
); } type ModalProps = { onSuccess?: (setupKey: SetupKey) => void; }; export function SetupKeyModalContent({ onSuccess }: Readonly) { const setupKeyRequest = useApiCall("/setup-keys", true); const { mutate } = useSWRConfig(); const [name, setName] = useState(""); const [reusable, setReusable] = useState(false); const [usageLimit, setUsageLimit] = useState(""); const [expiresIn, setExpiresIn] = useState("7"); const [ephemeralPeers, setEphemeralPeers] = useState(false); const [selectedGroups, setSelectedGroups, { save: saveGroups }] = useGroupHelper({ initial: [], }); const usageLimitPlaceholder = useMemo(() => { return reusable ? "Unlimited" : "1"; }, [reusable]); const isDisabled = useMemo(() => { const trimmedName = trim(name); return trimmedName.length === 0; }, [name]); const submit = () => { if (!selectedGroups) return; notify({ title: "Create Setup Key", description: "Setup key created successfully. You can now enroll peers with your new key.", promise: saveGroups().then(async (groups) => { return setupKeyRequest .post({ name, type: reusable ? "reusable" : "one-off", expires_in: parseInt(expiresIn || "0") * 24 * 60 * 60, // Days to seconds, defaults to 7 days revoked: false, auto_groups: groups.map((group) => group.id), usage_limit: reusable ? parseInt(usageLimit) : 1, ephemeral: ephemeralPeers, }) .then((setupKey) => { onSuccess && onSuccess(setupKey); mutate("/setup-keys"); mutate("/groups"); }); }), loadingMessage: "Creating your setup key...", }); }; return ( } title={"Create New Setup Key"} description={"Use this key to register new machines in your network"} color={"netbird"} />
Set an easily identifiable name for your key setName(e.target.value)} />
Make this key reusable } helpText={"Use this type to enroll multiple peers"} />
For example, set to 30 if you want to enroll 30 peers
setUsageLimit(e.target.value)} placeholder={usageLimitPlaceholder} customPrefix={ } customSuffix={"Peer(s)"} />
Days until the key expires.
Leave empty for no expiration.
setExpiresIn(e.target.value)} customPrefix={ } customSuffix={"Day(s)"} />
Ephemeral Peers } helpText={ "Peers that are offline for over 10 minutes will be removed automatically" } />
These groups will be automatically assigned to peers enrolled with this key
Learn more about Setup Keys
); }