summary refs log tree commit diff homepage
diff options
context:
space:
mode:
authorNguyễn Gia Phong <mcsinyx@disroot.org>2023-03-15 02:48:05 +0900
committerNguyễn Gia Phong <mcsinyx@disroot.org>2023-03-15 02:48:05 +0900
commit64c3842e02e65bb173d275e4ac2cdbea5afcf562 (patch)
tree8c8c371173435cb0ec3bf659858908f16142699f
parentd378edca8215080fb0a86899f6dc52643bdb0852 (diff)
downloadhybring-64c3842e02e65bb173d275e4ac2cdbea5afcf562.tar.gz
Hopefully improve accessibility
-rw-r--r--spec/server.cr5
-rw-r--r--src/http.cr10
-rw-r--r--src/xhtml.cr22
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