From 089bc02dddc3419becb3f85ad69d37fbc158a767 Mon Sep 17 00:00:00 2001 From: Zef Hemel Date: Thu, 22 Dec 2022 11:21:12 +0100 Subject: [PATCH] Fixes #206 --- build.ts | 3 + common/spaces/http_space_primitives.ts | 2 +- server/http_server.ts | 49 +++++++++++--- web/auth.html | 92 ++++++++++++++++++++++++++ web/index.html | 3 - 5 files changed, 134 insertions(+), 15 deletions(-) create mode 100644 web/auth.html diff --git a/build.ts b/build.ts index 215897f1..a5ff2d1d 100644 --- a/build.ts +++ b/build.ts @@ -22,6 +22,9 @@ async function prepareAssets(dist: string) { await copy("web/index.html", `${dist}/web/index.html`, { overwrite: true, }); + await copy("web/auth.html", `${dist}/web/auth.html`, { + overwrite: true, + }); await copy("web/images/favicon.png", `${dist}/web/favicon.png`, { overwrite: true, }); diff --git a/common/spaces/http_space_primitives.ts b/common/spaces/http_space_primitives.ts index 38a47044..31585e9f 100644 --- a/common/spaces/http_space_primitives.ts +++ b/common/spaces/http_space_primitives.ts @@ -22,7 +22,7 @@ export class HttpSpacePrimitives implements SpacePrimitives { ): Promise { const result = await fetch(url, options); if (result.status === 401) { - // Invalid credentials, reloading the browser should trigger a BasicAuth dialog + // Invalid credentials, reloading the browser should trigger authentication location.reload(); throw Error("Unauthorized"); } diff --git a/server/http_server.ts b/server/http_server.ts index c8278b08..61e7df25 100644 --- a/server/http_server.ts +++ b/server/http_server.ts @@ -178,22 +178,49 @@ export class HttpServer { } private addPasswordAuth(app: Application) { - const excludedPaths = ["/manifest.json", "/favicon.png"]; + const excludedPaths = [ + "/manifest.json", + "/favicon.png", + "/logo.png", + "/.auth", + ]; if (this.user) { - app.use(async ({ request, response }, next) => { + const b64User = btoa(this.user); + app.use(async ({ request, response, cookies }, next) => { if (!excludedPaths.includes(request.url.pathname)) { - if ( - request.headers.get("Authorization") === - `Basic ${btoa(this.user!)}` - ) { - await next(); + const authCookie = await cookies.get("auth"); + if (!authCookie || authCookie !== b64User) { + response.redirect(`/.auth?refer=${request.url.pathname}`); + return; + } + } + if (request.url.pathname === "/.auth") { + if (request.method === "GET") { + response.headers.set("Content-type", "text/html"); + response.body = this.systemBoot.assetBundle.readTextFileSync( + "web/auth.html", + ); + return; + } else if (request.method === "POST") { + const values = await request.body({ type: "form" }).value; + const username = values.get("username"), + password = values.get("password"), + refer = values.get("refer"); + if (this.user === `${username}:${password}`) { + await cookies.set("auth", b64User, { + expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 7), // in a week + sameSite: "strict", + }); + response.redirect(refer || "/"); + // console.log("All headers", request.headers); + } else { + response.redirect("/.auth?error=1"); + } + return; } else { response.status = 401; - response.headers.set( - "WWW-Authenticate", - `Basic realm="Please enter your username and password"`, - ); response.body = "Unauthorized"; + return; } } else { // Unauthenticated access to excluded paths diff --git a/web/auth.html b/web/auth.html new file mode 100644 index 00000000..3635d66d --- /dev/null +++ b/web/auth.html @@ -0,0 +1,92 @@ + + + + + + + + Login to Silver Bullet + + + + + +
+

Login to Silver Bullet

+
+
+ +
+
+ +
+
+ +
+
+ +
+ +
+ + + + + \ No newline at end of file diff --git a/web/index.html b/web/index.html index 1fceb1ba..d6c539a0 100644 --- a/web/index.html +++ b/web/index.html @@ -32,9 +32,6 @@ overflow: hidden; } -