Web-based stream overlay manager

Dogshit auth but enough

Signed-off-by: Naomi Roberts <mia@naomieow.xyz>

lesbian.skin 7ab2e754 e1c931fa

verified
Changed files
+30 -15
src
+22 -7
src/clover.gleam
··· 6 6 import formal/form 7 7 import gleam/erlang/application 8 8 import gleam/erlang/process 9 + import gleam/http 10 + import gleam/http/cookie 9 11 import gleam/http/request 10 12 import gleam/http/response 11 13 import gleam/int ··· 44 46 ) -> ewe.Response { 45 47 use req <- log_req(req) 46 48 49 + let pass = "1234" 50 + let authed = authenticated(req, pass) 51 + 47 52 case request.path_segments(req) { 48 53 [] -> data.page(index.view()) 49 - ["new"] -> { 54 + ["join"] -> 50 55 case list.key_find(req.headers, "content-type") { 51 56 Ok("application/x-www-form-urlencoded") 52 57 | Ok("application/x-www-form-urlencoded; " <> _) -> { ··· 57 62 let pairs = sort_keys(pairs) 58 63 let form = index.room_form() |> form.add_values(pairs) 59 64 case form.run(form) { 60 - Ok(data) -> data.redirect("/room/" <> data.id) 61 - Error(_) -> data.redirect("/") 65 + Ok(data) if data.password == pass -> 66 + data.redirect("/room/") 67 + |> response.set_cookie( 68 + "password", 69 + data.password, 70 + cookie.defaults(http.Https), 71 + ) 72 + _ -> data.redirect("/") 62 73 } 63 74 } 64 75 } 65 76 } 66 77 _ -> data.redirect("/") 67 78 } 68 - } 69 - ["room", id] -> data.page(room.view(id)) 70 - ["room", id, "html"] -> data.page(room.view_html(id)) 79 + ["room"] if authed -> data.page(room.view()) 80 + ["room", "html"] -> data.page(room.view_html()) 71 81 ["lustre", "runtime.mjs"] -> serve_runtime() 72 - ["ws"] -> serve_counter(req, counter) 82 + ["ws"] if authed -> serve_counter(req, counter) 73 83 _ -> data.not_found() 74 84 } 85 + } 86 + 87 + fn authenticated(req: ewe.Request, password: String) -> Bool { 88 + let cookies = request.get_cookies(req) 89 + list.contains(cookies, #("password", password)) 75 90 } 76 91 77 92 fn sort_keys(pairs: List(#(String, t))) -> List(#(String, t)) {
+5 -5
src/clover/pages/index.gleam
··· 4 4 import lustre/element/html 5 5 6 6 pub type RoomInput { 7 - RoomInput(id: String) 7 + RoomInput(password: String) 8 8 } 9 9 10 10 pub fn room_form() -> form.Form(RoomInput) { 11 11 form.new({ 12 - use id <- form.field("id", form.parse_string) 13 - form.success(RoomInput(id:)) 12 + use password <- form.field("password", form.parse_string) 13 + form.success(RoomInput(password:)) 14 14 }) 15 15 } 16 16 ··· 18 18 let form = room_form() 19 19 html.body([attr.styles([#("max-width", "32rem"), #("margin", "3rem auto")])], [ 20 20 html.h1([], [html.text("Clover")]), 21 - html.form([attr.method("POST"), attr.action("/new")], [ 22 - field_input(form:, label: "Room ID", type_: "text", name: "id"), 21 + html.form([attr.method("POST"), attr.action("/join")], [ 22 + field_input(form:, label: "Password", type_: "password", name: "password"), 23 23 html.div([], [html.input([attr.type_("submit")])]), 24 24 ]), 25 25 ])
+3 -3
src/clover/pages/room.gleam
··· 2 2 import lustre/element/html 3 3 import lustre/server_component 4 4 5 - pub fn view(id: String) { 5 + pub fn view() { 6 6 html.body([attr.styles([#("max-width", "32rem"), #("margin", "3rem auto")])], [ 7 7 html.a([attr.href("/")], [html.text("< Home")]), 8 - html.h1([], [html.text("Room ID: "), html.text(id)]), 8 + html.h1([], [html.text("Admin Menu")]), 9 9 server_component.element([server_component.route("/ws")], []), 10 10 ]) 11 11 } 12 12 13 - pub fn view_html(_id: String) { 13 + pub fn view_html() { 14 14 html.body([attr.styles([#("max-width", "32rem"), #("margin", "3rem auto")])], [ 15 15 server_component.element([server_component.route("/ws")], []), 16 16 ])