From 2b03aec64515ae9fa6e7bd4d9f1bfa7131c64e9f Mon Sep 17 00:00:00 2001 From: Thomas Scholtes Date: Fri, 3 Nov 2023 10:13:15 +0100 Subject: [PATCH] Implement simplified authentication flow We change the instructions to connect to a local node to use the simplified authentication flow. Signed-off-by: Thomas Scholtes --- httpd-client/tests/session.test.ts | 14 +- httpd-client/tests/support/httpd.ts | 27 ++-- src/App/Header/Authenticate.svelte | 47 +++---- src/App/Header/Connect.svelte | 25 ++-- src/lib/router.ts | 1 + src/lib/router/definitions.ts | 2 +- src/modals/ConnectModal.svelte | 193 ---------------------------- src/views/session/Index.svelte | 4 + tests/e2e/httpd.spec.ts | 27 ---- tests/support/fixtures.ts | 46 ++----- tests/support/heartwood-version | 2 +- 11 files changed, 66 insertions(+), 322 deletions(-) delete mode 100644 src/modals/ConnectModal.svelte delete mode 100644 tests/e2e/httpd.spec.ts diff --git a/httpd-client/tests/session.test.ts b/httpd-client/tests/session.test.ts index 3bbb0164e..744cd1ee9 100644 --- a/httpd-client/tests/session.test.ts +++ b/httpd-client/tests/session.test.ts @@ -6,7 +6,6 @@ import { HttpdClient } from "@httpd-client"; import { authenticate } from "@httpd-client/tests/support/httpd.js"; import { createPeerManager } from "@tests/support/peerManager.js"; import { gitOptions } from "@tests/support/fixtures.js"; -import { sessionPayloadSchema } from "@httpd-client/lib/session"; import { tmpDir } from "@tests/support/support.js"; describe("session", async () => { @@ -29,18 +28,7 @@ describe("session", async () => { }); test("#update(id, {sig, pk})", async () => { - const { stdout } = await peer.rad(["web", "--backend", api.url, "--json"]); - const session = sessionPayloadSchema.safeParse(JSON.parse(stdout)); - - if (!session.success) { - throw new Error("Failed to parse session payload"); - } - - const { sessionId, signature, publicKey } = session.data; - await api.session.update(sessionId, { - sig: signature, - pk: publicKey, - }); + await authenticate(api, peer); }); test("#delete(id)", async () => { diff --git a/httpd-client/tests/support/httpd.ts b/httpd-client/tests/support/httpd.ts index cd21f294b..4be96b128 100644 --- a/httpd-client/tests/support/httpd.ts +++ b/httpd-client/tests/support/httpd.ts @@ -1,24 +1,31 @@ import type { HttpdClient } from "@httpd-client"; import type { RadiclePeer } from "@tests/support/peerManager.js"; -import { sessionPayloadSchema } from "@httpd-client/lib/session.js"; +import assert from "node:assert"; export async function authenticate( api: HttpdClient, peer: RadiclePeer, ): Promise { - const { stdout } = await peer.rad(["web", "--backend", api.url, "--json"]); - const session = sessionPayloadSchema.safeParse(JSON.parse(stdout)); + const { stdout } = await peer.spawn("rad-web", [ + "http://localhost:3001", + "--no-open", + "--connect", + "--listen", + `${peer.httpdBaseUrl.hostname}:${peer.httpdBaseUrl.port}`, + ]); + const match = stdout.match(/Visit (http:\/\/\S+) to connect/); + assert( + match !== null && match[1], + `Failed to get authentication URL from: ${stdout}`, + ); - if (!session.success) { - throw new Error("Failed to parse session payload"); - } + const authUrl = new URL(match[1]); + const sessionId = authUrl.pathname.split("/")[2]; - const { sessionId, signature, publicKey } = session.data; await api.session.update(sessionId, { - sig: signature, - pk: publicKey, + sig: authUrl.searchParams.get("sig")!, + pk: authUrl.searchParams.get("pk")!, }); - return sessionId; } diff --git a/src/App/Header/Authenticate.svelte b/src/App/Header/Authenticate.svelte index a2b723e58..58a14b471 100644 --- a/src/App/Header/Authenticate.svelte +++ b/src/App/Header/Authenticate.svelte @@ -1,12 +1,11 @@ - - - - - - - - Complete the steps below to browse projects on your local machine, -
- create issues, and participate in discussions. -
- -
- {#if $httpdStore.state === "stopped"} -
-
-
-
-
-
- Start httpd server -
-
Authenticate
-
Done
-
-
- -
-
- Run this command in your terminal to connect to your local node: -
- -
- -
-
Port:
-
- httpd.changeHttpdPort(Number(customPort))}> -
- -
-
-
-
- {:else if $httpdStore.state === "running"} -
-
-
-
-
-
Start httpd server
-
Authenticate
-
Done
-
-
- -
-
Httpd server running
-
- radicle.local - - Browse - -
-
-
-
-
- Run this command in your terminal to authenticate yourself: -
- -
-
-
Port:
-
- httpd.changeHttpdPort(Number(customPort))}> -
- -
-
-
-
- {/if} -
- diff --git a/src/views/session/Index.svelte b/src/views/session/Index.svelte index 257f62ec4..a869d271f 100644 --- a/src/views/session/Index.svelte +++ b/src/views/session/Index.svelte @@ -14,6 +14,10 @@ export let activeRoute: Extract; onMount(async () => { + const port = Number.parseInt(activeRoute.params.apiAddr.split(":")[1]); + if (port > 0 && port < 2 ** 16) { + httpd.changeHttpdPort(port); + } const isAuthenticated = await httpd.authenticate(activeRoute.params); if (isAuthenticated) { diff --git a/tests/e2e/httpd.spec.ts b/tests/e2e/httpd.spec.ts deleted file mode 100644 index 730506614..000000000 --- a/tests/e2e/httpd.spec.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { expect, test } from "@tests/support/fixtures.js"; - -test("rad web command reacts to port change", async ({ page, peerManager }) => { - const peer = await peerManager.createPeer({ - name: "port-test", - }); - await peer.startHttpd(8090); - - await page.goto("/"); - await page.getByRole("button", { name: "Authenticate" }).click(); - - await expect( - page.getByText( - "rad web --frontend http://localhost:3001 --backend http://127.0.0.1:8081", - ), - ).toBeVisible(); - await page.locator('input[name="port"]').fill("8090"); - await page.locator('input[name="port"]').press("Enter"); - - await expect( - page.getByText( - "rad web --frontend http://localhost:3001 --backend http://127.0.0.1:8090", - ), - ).toBeVisible(); - - await peer.stopHttpd(); -}); diff --git a/tests/support/fixtures.ts b/tests/support/fixtures.ts index c55dd5a4a..319bf451b 100644 --- a/tests/support/fixtures.ts +++ b/tests/support/fixtures.ts @@ -2,8 +2,8 @@ import type * as Stream from "node:stream"; import * as Fs from "node:fs/promises"; import * as Path from "node:path"; +import assert from "node:assert"; import { test as base, expect, type ViewportSize } from "@playwright/test"; -import { object, string, ZodSchema } from "zod"; import * as Process from "./process.js"; import * as issue from "@tests/support/cobs/issue.js"; @@ -20,18 +20,6 @@ const fixturesDir = Path.resolve(supportDir, "..", "./fixtures"); type ViewportTypes = "iPhoneXR" | "Desktop"; -interface Auth { - sessionId: string; - publicKey: string; - signature: string; -} - -const authSchema = object({ - sessionId: string(), - publicKey: string(), - signature: string(), -}) satisfies ZodSchema; - export const viewportSizes: Record = { iPhoneXR: { width: 414, height: 896 }, Desktop: { width: 1280, height: 720 }, @@ -167,28 +155,22 @@ export const test = base.extend<{ await peer.startHttpd(); await peer.startNode(); - await page.goto("/"); - await page.getByRole("button", { name: "Authenticate" }).click(); - await page - .locator('input[name="port"]') - .fill(peer.httpdBaseUrl.port.toString()); - await page.locator('input[name="port"]').press("Enter"); const { stdout } = await peer.spawn("rad-web", [ - "--frontend", "http://localhost:3001", - "--backend", - `${peer.httpdBaseUrl.scheme}://${peer.httpdBaseUrl.hostname}:${peer.httpdBaseUrl.port}`, - "--json", + "--no-open", + "--connect", + "--listen", + `${peer.httpdBaseUrl.hostname}:${peer.httpdBaseUrl.port}`, ]); - const result = authSchema.safeParse(JSON.parse(stdout)); - if (result.success) { - const { sessionId, publicKey, signature } = result.data; - await page.goto(`/session/${sessionId}?pk=${publicKey}&sig=${signature}`); - await expect(page.getByText("Authenticated")).toBeVisible(); - await page.getByRole("button", { name: "Close" }).click(); - } else { - throw new Error("Not able to parse rad web output"); - } + const match = stdout.match( + /Open the following URL to connect: (http:\/\/\S+)/, + ); + assert( + match !== null && match[1], + `Failed to get authentication URL from: ${stdout}`, + ); + await page.goto(match[1]); + await page.getByText("Successfully authenticated").waitFor(); await use(peer); }, diff --git a/tests/support/heartwood-version b/tests/support/heartwood-version index fd7bbaaf0..30f866e04 100644 --- a/tests/support/heartwood-version +++ b/tests/support/heartwood-version @@ -1 +1 @@ -6ca7da276839e5217b340dbfff8cd9095d8464c5 +59f506dbb5591d3fe68e638038495730c455d72a