Bring stale and spliced comments back in line
Four comments cited Web#unauthorized, which is the error handler now.
web.rb, setup.rb and the Dockerfile described tailscale serve in front
of the app where ProxyAuth and the README describe a proxy writing
Remote-User; the Dockerfile's now says to publish the port on
localhost alone, since the app trusts whatever header it is handed.
Three import comments had been spliced mid-sentence, and one claimed
a doubled membership raises when add_member ignores it.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013VNdx5qiRSWADBoVfDRcrd
diff --git a/Dockerfile b/Dockerfile
index 1cfd158..d52f9eb 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -34,6 +34,8 @@ COPY --from=build /app /app
EXPOSE 9292
-# 0.0.0.0 reaches only the container's own network namespace — exposure
-# to clients is tailscale serve's job, in front of the published port.
+# 0.0.0.0 reaches only the container's own network namespace. Exposure to
+# clients is the proxy's job (ProxyAuth): publish the port on localhost
+# alone (-p 127.0.0.1:9292:9292), because reached directly the app trusts
+# whatever Remote-User it is handed.
CMD ["rackup", "-o", "0.0.0.0"]
diff --git a/lib/pro_tacts/exchange_log.rb b/lib/pro_tacts/exchange_log.rb
index bb9253c..d162df3 100644
--- a/lib/pro_tacts/exchange_log.rb
+++ b/lib/pro_tacts/exchange_log.rb
@@ -131,7 +131,7 @@ module ProTacts
end
# A 401 is the identity gate refusing a request that names nobody
- # (Web#unauthorized): nothing went wrong, and unless everything is
+ # (Web's error handler): nothing went wrong, and unless everything is
# asked for, a body from outside the tailnet stays off disk.
#: (Integer status) -> bool
def failed?(status)
diff --git a/lib/pro_tacts/import/vcf.rb b/lib/pro_tacts/import/vcf.rb
index ce62c57..68a7b59 100644
--- a/lib/pro_tacts/import/vcf.rb
+++ b/lib/pro_tacts/import/vcf.rb
@@ -27,6 +27,13 @@ module ProTacts
# A file that is not a set of vCards.
class Invalid < StandardError; end
+ # Apple's own name for a row, carried on a line of its own beside
+ # the one it names (`item1.X-ABLabel:_$!<Spouse>!$_`). Known, and
+ # named apart from the rest because what happens to the line it
+ # annotates happens to it too: a label whose line is gone names
+ # nothing (#read).
+ LABEL = "X-ABLABEL" #: String
+
# The properties this address book reads, and so the properties
# an import brings in. The envelope (BEGIN, END, VERSION, UID),
# the fields a screen shows (Contact's own readers: N, FN,
@@ -40,13 +47,6 @@ module ProTacts
# screen for a property is what brings it in, and until then
# importing one would only pad the cards with what nobody can
# read.
- # Apple's own name for a row, carried on a line of its own beside
- # the one it names (`item1.X-ABLabel:_$!<Spouse>!$_`). Known, and
- # named apart from the rest because what happens to the line it
- # annotates happens to it too: a label whose line is gone names
- # nothing (#read).
- LABEL = "X-ABLABEL" #: String
-
KNOWN = [
*%w[BEGIN END VERSION UID N FN NICKNAME BDAY TEL EMAIL ADR NOTE PHOTO],
LABEL,
diff --git a/lib/pro_tacts/import/write.rb b/lib/pro_tacts/import/write.rb
index bf3fe92..c246ec0 100644
--- a/lib/pro_tacts/import/write.rb
+++ b/lib/pro_tacts/import/write.rb
@@ -87,8 +87,8 @@ module ProTacts
# them off this same store. Deduplicated because two of these
# can mean one group — a name typed for a group that the box
# above it already offers, or everyone's book arriving both
- # ticked and asked for — and a membership written twice is a
- # constraint violation rather than a second membership.
+ # ticked and asked for — and a second join of one group would
+ # only be asked of Store#add_member to come to nothing.
join = [*chosen, *named.map { group_id(it) }]
join << group_id(Group::EVERYONE) if everyone
@store.regroup(id, join: join.uniq, leave: []) unless join.empty?
@@ -151,9 +151,9 @@ module ProTacts
# into an empty store creates `sync:*` (Store#everyone_group_id),
# and a list read before that would send this to create it again.
# Memoized so that a card given the same name twice reads the
- # list once rather than making the group twice. The choices read, not the whole groups read:
- # the match is on name, and a group's members are no part of it
- # (Store#group_choices).
+ # list once rather than making the group twice. The choices read,
+ # not the whole groups read: the match is on name, and a group's
+ # members are no part of it (Store#group_choices).
#: (String name) -> String
def group_id(name)
@group_ids[name] ||= @store.group_choices.find { it.name == name }&.id || @store.create_group(name:)
diff --git a/lib/pro_tacts/proxy_auth.rb b/lib/pro_tacts/proxy_auth.rb
index f54e168..1193e0c 100644
--- a/lib/pro_tacts/proxy_auth.rb
+++ b/lib/pro_tacts/proxy_auth.rb
@@ -27,7 +27,7 @@ module ProTacts
# The header the proxy writes the login to, and Rack's spelling of
# the same field in the environment. One pair, because three places
# name it: the read below, the 401 that says which header was read
- # (Web#unauthorized), and the Sentry scrubber that keeps it out of
+ # (Web's error handler), and the Sentry scrubber that keeps it out of
# an event (config.ru).
HEADER = "Remote-User" #: String
ENV_KEY = "HTTP_#{HEADER.upcase.tr("-", "_")}" #: String
diff --git a/lib/pro_tacts/stub_login.rb b/lib/pro_tacts/stub_login.rb
index 90f61d6..bdf2edb 100644
--- a/lib/pro_tacts/stub_login.rb
+++ b/lib/pro_tacts/stub_login.rb
@@ -4,8 +4,8 @@ require "pro_tacts/proxy_auth"
module ProTacts
# Rack middleware that writes a fixed login to Remote-User, the way the
# proxy in front of a deployment does, so a server with nothing in
- # front answers instead of refusing every request (ProxyAuth,
- # Web#unauthorized). A request that already carries the header keeps
+ # front answers instead of refusing every request (ProxyAuth, and
+ # Web's error handler). A request that already carries the header keeps
# its own, so `curl -H` can still ask as someone else.
#
# It stands in for the proxy, so it belongs only where there is none.
diff --git a/lib/pro_tacts/web.rb b/lib/pro_tacts/web.rb
index cabd7cc..34b2e0c 100644
--- a/lib/pro_tacts/web.rb
+++ b/lib/pro_tacts/web.rb
@@ -25,8 +25,8 @@ module ProTacts
# The vendored Gloss CSS and the admin app's own stylesheet (see
# docs/DESIGN.md); relative to this file rather than $0 for the same
# reason Store::MIGRATIONS is, and served by Roda's own `public`
- # plugin rather than a reverse proxy — there is no reverse proxy
- # here, `tailscale serve` hands requests straight to this app.
+ # plugin rather than by the proxy in front, which passes every
+ # request through and writes the login on it (ProxyAuth).
PUBLIC_ROOT = Pathname.new(
__dir__ #: String
).parent.parent / "public" #: Pathname
@@ -55,7 +55,7 @@ module ProTacts
# Inside CaptureExceptions, so the exchange tag lands on the scope it
# opens for the request. Outside the route's identity gate
- # (#unauthorized), and safe there because a 401 is not a failure it
+ # (the error handler below), and safe there because a 401 is not a failure it
# keeps (ExchangeLog#failed?). The log opens when Roda builds the
# stack, not here, so requiring the app writes nothing.
use ProTacts::ExchangeLog, path: ProTacts.config.exchange_log_path, everything: ProTacts.config.debug?
diff --git a/lib/pro_tacts/web/import.rb b/lib/pro_tacts/web/import.rb
index 858ad9e..509abe2 100644
--- a/lib/pro_tacts/web/import.rb
+++ b/lib/pro_tacts/web/import.rb
@@ -150,8 +150,6 @@ module ProTacts
end
# A row opened: the card it arrived as beside the card that is
- # coming in — or the contact itself, for a card this walk has
- # One contact, the card it arrived as beside the card that is
# coming in. The right-hand half is the contact editor itself, not a
# copy of it: a field the two disagreed about would be a field an
# import writes and an edit cannot undo.
diff --git a/lib/pro_tacts/web/setup.rb b/lib/pro_tacts/web/setup.rb
index 385a8dc..e926500 100644
--- a/lib/pro_tacts/web/setup.rb
+++ b/lib/pro_tacts/web/setup.rb
@@ -16,8 +16,8 @@ module ProTacts
# the address a device reached this app at is reachable from that
# device by construction, where an environment variable is a claim
# about some other machine's idea of where we live. It is the
- # client's Host header, which behind `tailscale serve` is serve's
- # own — and past the identity gate in web.rb's trunk, the only
+ # client's Host header, which the proxy in front passes along
+ # (ProxyAuth) — and past the identity gate in web.rb's trunk, the only
# devices asking are on the tailnet.
hash_branch("setup") do |r|
r.is do