summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEuAndreh <eu@euandre.org>2026-04-27 22:36:47 -0300
committerEuAndreh <eu@euandre.org>2026-04-27 22:36:47 -0300
commit6553488e7341091feecea01f5f926bdfb285f446 (patch)
tree8fe3cd7bfd4b8750fe47c8fdb43153689cfe35b3 /src
parentaccount-notify and account-tag (diff)
downloadpapod-6553488e7341091feecea01f5f926bdfb285f446.tar.gz
papod-6553488e7341091feecea01f5f926bdfb285f446.tar.xz
chghost, setname, invite-notify capabilities
chghost: advertise the cap. We never rewrite hostnames currently (everything is "localhost"), so this is a passive declaration that clients negotiating the cap will see CHGHOST messages if/when host rewriting lands. setname: SETNAME :<realname> updates the client's stored realname and, for every shared-channel member that negotiated the cap, emits the ":nick\!user@host SETNAME :<realname>" notification. Length cap matches the existing TOPICLEN bound (390); empty/over-length names get FAIL SETNAME INVALID_REALNAME. invite-notify: INVITE delivery now also sends the INVITE line to every channel op (other than inviter/invitee) that negotiated the cap, so mod tooling can track invites without polling. Uses the same account-tag-aware delivery as the recipient path.
Diffstat (limited to 'src')
-rw-r--r--src/papod.clj64
1 files changed, 62 insertions, 2 deletions
diff --git a/src/papod.clj b/src/papod.clj
index c7dec26..d155b27 100644
--- a/src/papod.clj
+++ b/src/papod.clj
@@ -1388,7 +1388,8 @@
" batch labeled-response multi-prefix"
" userhost-in-names extended-join"
" away-notify utf8only"
- " account-notify account-tag"
+ " account-notify account-tag chghost"
+ " setname invite-notify"
" draft/multiline=max-bytes=4096"
",max-lines=32"
" draft/read-marker"
@@ -1402,7 +1403,8 @@
" labeled-response multi-prefix"
" userhost-in-names extended-join"
" away-notify utf8only"
- " account-notify account-tag"
+ " account-notify account-tag chghost"
+ " setname invite-notify"
" draft/multiline draft/read-marker"
" draft/message-redaction"
" draft/message-editing"
@@ -1419,6 +1421,7 @@
"userhost-in-names" "extended-join"
"away-notify" "utf8only"
"account-notify" "account-tag"
+ "chghost" "setname" "invite-notify"
"draft/multiline" "draft/read-marker"
"draft/message-redaction"
"draft/message-editing"
@@ -3775,6 +3778,38 @@
[(numeric-reply client "306"
":You have been marked as being away")]))))
+(defn- handle-setname
+ [params client components]
+ (let [{:keys [clients channels]} components
+ nick (client-target client)
+ src (client-prefix client)
+ raw (when (seq params) (string/join " " params))
+ new-name (when raw
+ (cond-> raw
+ (string/starts-with? raw ":") (subs 1)))]
+ (cond
+ (or (string/blank? new-name)
+ (> (count new-name) 390))
+ [(str "FAIL SETNAME INVALID_REALNAME :Invalid realname")]
+
+ :else
+ (let [line (str ":" src " SETNAME :" new-name)]
+ (swap! client assoc-in [:user :realname] new-name)
+ (when (and clients channels)
+ (let [seen (atom #{nick})]
+ (doseq [[ch members] @channels
+ :when (contains? members nick)
+ mn members
+ :when (not (contains? @seen mn))
+ :let [m (get @clients mn)
+ ca (:client-atom m)
+ caps (or (when ca (:caps @ca))
+ #{})]
+ :when (and m (caps "setname"))]
+ (deliver-to-client! (:w m) line)
+ (swap! seen conj mn))))
+ [line]))))
+
(defn- handle-batch-open!
[message client components]
(let [params (clean-params (:params message))
@@ -4136,6 +4171,9 @@
(= command "AWAY")
(handle-away params client components)
+ (= command "SETNAME")
+ (handle-setname params client components)
+
(= command "NOTICE")
(handle-notice params client components)
@@ -4969,6 +5007,28 @@
tagged-base
base)]
(deliver-to-client! (:w m) line)))
+ ;; invite-notify: also send the INVITE line
+ ;; to channel ops who negotiated the cap
+ ;; (excluding the inviter and the invitee).
+ (when (and chan-exists? clients
+ (:ops components))
+ (let [op-set (or (get @(:ops components)
+ handle) #{})]
+ (doseq [op-nick op-set
+ :when (and (not= op-nick nick)
+ (not= op-nick
+ target))
+ :let [m (get @clients op-nick)
+ ca (:client-atom m)
+ caps (when ca
+ (or (:caps @ca)
+ #{}))]
+ :when (and m
+ (caps "invite-notify"))]
+ (deliver-to-client! (:w m)
+ (if (and tagged-base
+ (caps "account-tag"))
+ tagged-base base)))))
;; When the channel does not exist, also
;; echo the INVITE back to the inviter
;; (RFC1459 behavior). When it exists,