OR
diff --git a/src/pages/vm.tsx b/src/pages/vm.tsx
index 700028b..2e18e6b 100644
--- a/src/pages/vm.tsx
+++ b/src/pages/vm.tsx
@@ -1,10 +1,11 @@
+import "@xterm/xterm/css/xterm.css";
+
import { useLocation, useNavigate, useParams } from "react-router-dom";
import { LNVpsApi, VmInstance, VmPayment } from "../api";
import VpsInstanceRow from "../components/vps-instance";
import useLogin from "../hooks/login";
import { ApiUrl } from "../const";
-import { EventPublisher } from "@snort/system";
-import { useCallback, useEffect, useRef, useState } from "react";
+import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import VpsPayment from "../components/vps-payment";
import CostLabel from "../components/cost";
import { AsyncButton } from "../components/button";
@@ -12,8 +13,10 @@ import { AttachAddon } from "@xterm/addon-attach";
import { Terminal } from "@xterm/xterm";
import { FitAddon } from "@xterm/addon-fit";
import { WebglAddon } from "@xterm/addon-webgl";
-import "@xterm/xterm/css/xterm.css";
import { toEui64 } from "../utils";
+import { Icon } from "../components/icon";
+import Modal from "../components/modal";
+import SSHKeySelector from "../components/ssh-keys";
const fit = new FitAddon();
@@ -23,28 +26,28 @@ export default function VmPage() {
const login = useLogin();
const navigate = useNavigate();
const [payment, setPayment] = useState
();
- const [term, setTerm] = useState()
+ const [term, setTerm] = useState();
const termRef = useRef(null);
+ const [editKey, setEditKey] = useState(false);
+ const [key, setKey] = useState(state?.ssh_key_id ?? -1);
+
+ const api = useMemo(() => {
+ if (!login?.builder) return;
+ return new LNVpsApi(ApiUrl, login.builder);
+ }, [login]);
const renew = useCallback(
async function () {
- if (!login?.signer || !state) return;
- const api = new LNVpsApi(
- ApiUrl,
- new EventPublisher(login.signer, login.pubkey),
- );
+ if (!api || !state) return;
const p = await api.renewVm(state.id);
setPayment(p);
},
- [login, state],
+ [api, state],
);
async function openTerminal() {
- if (!login?.signer || !state) return;
- const api = new LNVpsApi(
- ApiUrl,
- new EventPublisher(login.signer, login.pubkey),
- );
+ if (!login?.builder || !state) return;
+ const api = new LNVpsApi(ApiUrl, login.builder);
const ws = await api.connect_terminal(state.id);
const te = new Terminal();
const webgl = new WebglAddon();
@@ -55,7 +58,7 @@ export default function VmPage() {
te.loadAddon(fit);
te.onResize(({ cols, rows }) => {
ws.send(`${cols}:${rows}`);
- })
+ });
const attach = new AttachAddon(ws);
te.loadAddon(attach);
setTerm(te);
@@ -81,21 +84,9 @@ export default function VmPage() {
}
return (
-
+
{action === undefined && (
<>
-
Renewal
-
-
{new Date(state.expires).toDateString()}
- {state.template?.cost_plan && (
-
-
-
- )}
-
-
navigate("/vm/renew", { state })}>
- Extend Now
-
Network:
{(state.ip_assignments?.length ?? 0) === 0 && (
@@ -118,7 +109,21 @@ export default function VmPage() {
{state.ssh_key?.name}
+
setEditKey(true)} />
+
+
Renewal
+
+
{new Date(state.expires).toDateString()}
+ {state.template?.cost_plan && (
+
+
+
+ )}
+
+
navigate("/vm/renew", { state })}>
+ Extend Now
+
{/*
{!term &&
Connect Terminal}
{term &&
}*/}
@@ -131,11 +136,8 @@ export default function VmPage() {
{
- if (!login?.signer || !state) return;
- const api = new LNVpsApi(
- ApiUrl,
- new EventPublisher(login.signer, login.pubkey),
- );
+ if (!login?.builder || !state) return;
+ const api = new LNVpsApi(ApiUrl, login.builder);
const newState = await api.getVm(state.id);
navigate("/vm", {
state: newState,
@@ -146,6 +148,30 @@ export default function VmPage() {
)}
>
)}
+ {editKey && (
+ setEditKey(false)}>
+
+
+
After selecting a new key, please restart the VM.
+
{
+ if (!state) return;
+ await api?.patchVm(state.id, {
+ ssh_key_id: key,
+ });
+ const ns = await api?.getVm(state?.id);
+ navigate(".", {
+ state: ns,
+ replace: true,
+ });
+ setEditKey(false);
+ }}
+ >
+ Save
+
+
+
+ )}
);
}
diff --git a/src/utils.ts b/src/utils.ts
index 70ae81e..8b3a435 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -31,13 +31,23 @@ export async function openFile(): Promise {
});
}
-
export function toEui64(prefix: string, mac: string) {
const macData = base16.decode(mac.replace(/:/g, "").toUpperCase());
- const macExtended = new Uint8Array([...macData.subarray(0, 3), 0xff, 0xfe, ...macData.subarray(3, 6)])
+ const macExtended = new Uint8Array([
+ ...macData.subarray(0, 3),
+ 0xff,
+ 0xfe,
+ ...macData.subarray(3, 6),
+ ]);
macExtended[0] |= 0x02;
- return (prefix + base16.encode(macExtended.subarray(0, 2)) + ":"
- + base16.encode(macExtended.subarray(2, 4)) + ":"
- + base16.encode(macExtended.subarray(4, 6)) + ":"
- + base16.encode(macExtended.subarray(6, 8))).toLowerCase();
-}
\ No newline at end of file
+ return (
+ prefix +
+ base16.encode(macExtended.subarray(0, 2)) +
+ ":" +
+ base16.encode(macExtended.subarray(2, 4)) +
+ ":" +
+ base16.encode(macExtended.subarray(4, 6)) +
+ ":" +
+ base16.encode(macExtended.subarray(6, 8))
+ ).toLowerCase();
+}
diff --git a/yarn.lock b/yarn.lock
index cc63cd7..f490bd4 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -758,20 +758,20 @@ __metadata:
languageName: node
linkType: hard
-"@snort/system-react@npm:^1.5.7":
- version: 1.5.7
- resolution: "@snort/system-react@npm:1.5.7"
+"@snort/system-react@npm:^1.6.1":
+ version: 1.6.1
+ resolution: "@snort/system-react@npm:1.6.1"
dependencies:
"@snort/shared": "npm:^1.0.17"
- "@snort/system": "npm:^1.5.7"
+ "@snort/system": "npm:^1.6.1"
react: "npm:^18.2.0"
- checksum: 10c0/b8261d72bef88fc6baa91f3f3765a7e65e7775e0f87142079ec425fdc3639871da068b2bfc9c4a2c0f15a20c7c76ffe84d9bc8cbc1e6ef5a76989cd78d3f7049
+ checksum: 10c0/fe3180c1f4341df4fd585c4031ef632a7d59c7637c6aed16ea254a1c22a66e288516d96939c0080efd0fb73940531855a59a24fae5f82c326f6544362eb0394c
languageName: node
linkType: hard
-"@snort/system@npm:^1.5.7":
- version: 1.5.7
- resolution: "@snort/system@npm:1.5.7"
+"@snort/system@npm:^1.6.1":
+ version: 1.6.1
+ resolution: "@snort/system@npm:1.6.1"
dependencies:
"@noble/ciphers": "npm:^0.6.0"
"@noble/curves": "npm:^1.4.0"
@@ -786,7 +786,7 @@ __metadata:
nostr-social-graph: "npm:^1.0.3"
uuid: "npm:^9.0.0"
ws: "npm:^8.14.0"
- checksum: 10c0/9b1d6e36dfc3c0845754d4f2c10eb39665a2c4c4c61a07635e0b792a352f8566dbd79561561568c182272cd92b0d2c421ef137775b16872b7e28fa39366e2094
+ checksum: 10c0/5da01450970f4a51df98369c4cdd2b8886add3480e7962d11ed17498cf7db421bcd5e585abe532ff754efc0bf26b5734b9b24005f958802357ec390ccb74d281
languageName: node
linkType: hard
@@ -2379,8 +2379,8 @@ __metadata:
"@eslint/js": "npm:^9.8.0"
"@scure/base": "npm:^1.2.1"
"@snort/shared": "npm:^1.0.17"
- "@snort/system": "npm:^1.5.7"
- "@snort/system-react": "npm:^1.5.7"
+ "@snort/system": "npm:^1.6.1"
+ "@snort/system-react": "npm:^1.6.1"
"@types/react": "npm:^18.3.3"
"@types/react-dom": "npm:^18.3.0"
"@vitejs/plugin-react": "npm:^4.3.1"