From 64c3842e02e65bb173d275e4ac2cdbea5afcf562 Mon Sep 17 00:00:00 2001 From: Nguyễn Gia Phong Date: Wed, 15 Mar 2023 02:48:05 +0900 Subject: Hopefully improve accessibility --- spec/server.cr | 5 +++-- src/http.cr | 10 +++++----- src/xhtml.cr | 22 +++++++++++++--------- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/spec/server.cr b/spec/server.cr index 69bb543..d24fe1d 100644 --- a/spec/server.cr +++ b/spec/server.cr @@ -110,13 +110,14 @@ describe Server do it "rejects too long nick" do msg = "Must be within #{MAX_NICK_LENGTH} characters" - expect_errors url, {"nick" => "x" * (MAX_NICK_LENGTH + 1)}, {"nick" => msg} + expect_errors url, {"nick" => "x" * (MAX_NICK_LENGTH + 1)}, + {"nick" => "Must match #{NICK_PATTERN}"} end it "rejects nicks that are not lowercase alphanumeric" do %w(camelCase pun/tu?a#tion).each do |nick| expect_errors url, {"nick" => nick}, - {"nick" => "Must be ASCII lowercase alphanumeric"} + {"nick" => "Must match #{NICK_PATTERN}"} end end diff --git a/src/http.cr b/src/http.cr index 248a746..9562c2e 100644 --- a/src/http.cr +++ b/src/http.cr @@ -26,6 +26,7 @@ require "./xhtml" HTML_HEADINGS = Set{"applicants", "criteria", "joining", "members"} MAX_CONTENT_LENGTH = 4096 MAX_NICK_LENGTH = 32 +NICK_PATTERN = "[0-9a-z]{1,#{MAX_NICK_LENGTH}}" OPENNIC_TLD = Set{".bbs", ".chan", ".cyb", ".dyn", ".epic", ".geek", ".gopher", ".indy", ".libre", ".neo", ".null", ".o", ".oss", ".oz", ".parody", ".pirate"} @@ -63,11 +64,9 @@ class Server params[key] = value case key when "nick" - if value.size > MAX_NICK_LENGTH - next errors["nick"] = "Must be within #{MAX_NICK_LENGTH} characters" - end - if /^[0-9a-z]+$/ !~ value - next errors["nick"] = "Must be ASCII lowercase alphanumeric" + if /^#{NICK_PATTERN}$/ !~ value + # Manually crafted request or non-mainstream browser engine + next errors["nick"] = "Must match #{NICK_PATTERN}" end when "opennic" uri = URI.parse value @@ -135,6 +134,7 @@ class Server obj = arg.as Server case table when "member" + # FIXME: query in a different conn obj.opennic_page.write obj.icann_page.write end diff --git a/src/xhtml.cr b/src/xhtml.cr index 8db5995..52d089a 100644 --- a/src/xhtml.cr +++ b/src/xhtml.cr @@ -19,6 +19,7 @@ require "uri" require "xml" +require "./http" require "./sqlite" CSS = " @@ -28,6 +29,8 @@ CSS = " } body { margin-bottom: 2rem } h1, h2, h3, h4, h5, h6 { margin: 1ex 0 } + a { text-decoration: none } + a:hover { text-decoration: underline } form { display: grid; grid-template-columns: max-content 1fr 0; @@ -35,7 +38,7 @@ CSS = " form input { margin-bottom: 1ex } form label { margin-right: 1ch } form label.error { - color: red; + color: ActiveText; margin-top: -1ex; margin-bottom: 1ex; } @@ -84,10 +87,10 @@ class Page end end - def input(xml, name, label, hint, error, value) + def input(xml, type, name, pattern, label, error, value) xml.element "label", for: name do xml.text label end - xml.element "input", name: name, placeholder: hint, value: value, - required: "required" + xml.element "input", type: type, name: name, pattern: pattern, + value: value, required: "required" xml.element "br" if error xml.element "label", for: name, class: "error" do xml.text "Error:" end @@ -101,16 +104,16 @@ class Page xml.element "p" do xml.text "Then, please fill out the form below." end nick = params.fetch("nick", nil) xml.element "form", action: @api_url, method: "POST" do - input xml, "nick", "Nickname:", "digits or lowercase letters", + input xml, "text", "nick", NICK_PATTERN, "Nickname:", errors.fetch("nick", nil), nick || "" - input xml, "opennic", "OpenNIC URL:", "e.g. http://example.null", + input xml, "url", "opennic", "https?://.*", "OpenNIC URL:", errors.fetch("opennic", nil), params.fetch("opennic", "") - input xml, "icann", "ICANN URL:", "e.g. https://example.net", + input xml, "url", "icann", "https://.*", "ICANN URL:", errors.fetch("icann", nil), params.fetch("icann", "") + xml.element "input", type: "hidden", name: "host", value: @static_host xml.element "span" do - xml.element "input", type: "hidden", name: "host", value: @static_host + xml.element "input", type: "submit", value: "Let me in!" end - xml.element "input", type: "submit", value: "Let me in!" xml.element "br" end @@ -141,6 +144,7 @@ class Page xml.element "head" do xml.element "meta", name: "viewport", content: "width=device-width,initial-scale=1.0" + xml.element "meta", name: "color-scheme", content: "light dark" xml.element "link", rel: "icon", href: "data:," xml.element "style" do xml.text CSS end xml.element "title" do xml.text "le cercle libre" end -- cgit 1.4.1