feat: implement Tier 1 IRC numerics #72

Merged
sneak merged 4 commits from feat/tier1-irc-numerics into main 2026-03-13 00:41:26 +01:00
5 changed files with 19 additions and 42 deletions
Showing only changes of commit 761bce32de - Show all commits

View File

@@ -1146,25 +1146,6 @@ func (database *Database) GetAway(
return msg, nil return msg, nil
} }
// GetAwayByNick returns the away message for a nick.
// Returns an empty string if the user is not away.
func (database *Database) GetAwayByNick(
ctx context.Context,
nick string,
) (string, error) {
var msg string
err := database.conn.QueryRowContext(ctx,
"SELECT away_message FROM sessions WHERE nick = ?",
nick,
).Scan(&msg)
if err != nil {
return "", fmt.Errorf("get away by nick: %w", err)
}
return msg, nil
}
// SetTopicMeta sets the topic along with who set it and // SetTopicMeta sets the topic along with who set it and
// when. // when.
func (database *Database) SetTopicMeta( func (database *Database) SetTopicMeta(

View File

@@ -8,6 +8,7 @@ CREATE TABLE IF NOT EXISTS sessions (
nick TEXT NOT NULL UNIQUE, nick TEXT NOT NULL UNIQUE,
password_hash TEXT NOT NULL DEFAULT '', password_hash TEXT NOT NULL DEFAULT '',
signing_key TEXT NOT NULL DEFAULT '', signing_key TEXT NOT NULL DEFAULT '',
away_message TEXT NOT NULL DEFAULT '',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP, created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
last_seen DATETIME DEFAULT CURRENT_TIMESTAMP last_seen DATETIME DEFAULT CURRENT_TIMESTAMP
); );
@@ -30,6 +31,8 @@ CREATE TABLE IF NOT EXISTS channels (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE, name TEXT NOT NULL UNIQUE,
topic TEXT NOT NULL DEFAULT '', topic TEXT NOT NULL DEFAULT '',
topic_set_by TEXT NOT NULL DEFAULT '',
topic_set_at DATETIME,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP, created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
); );

View File

@@ -1,6 +0,0 @@
-- Add away message to sessions
ALTER TABLE sessions ADD COLUMN away_message TEXT NOT NULL DEFAULT '';
-- Add topic metadata to channels
ALTER TABLE channels ADD COLUMN topic_set_by TEXT NOT NULL DEFAULT '';
ALTER TABLE channels ADD COLUMN topic_set_at DATETIME;

View File

@@ -71,11 +71,10 @@ func (hdlr *Handlers) requireAuth(
sessionID, clientID, nick, err := sessionID, clientID, nick, err :=
hdlr.authSession(request) hdlr.authSession(request)
if err != nil { if err != nil {
hdlr.respondError( hdlr.respondJSON(writer, request, map[string]any{
writer, request, "error": "not registered",
"unauthorized", "numeric": irc.ErrNotRegistered,
http.StatusUnauthorized, }, http.StatusUnauthorized)
)
return 0, 0, "", false return 0, 0, "", false
} }
@@ -925,8 +924,8 @@ func (hdlr *Handlers) handlePrivmsg(
if target == "" { if target == "" {
hdlr.enqueueNumeric( hdlr.enqueueNumeric(
request.Context(), clientID, request.Context(), clientID,
irc.ErrNeedMoreParams, nick, []string{command}, irc.ErrNoRecipient, nick, []string{command},
"Not enough parameters", "No recipient given",
) )
hdlr.broker.Notify(sessionID) hdlr.broker.Notify(sessionID)
hdlr.respondJSON(writer, request, hdlr.respondJSON(writer, request,
@@ -940,8 +939,8 @@ func (hdlr *Handlers) handlePrivmsg(
if len(lines) == 0 { if len(lines) == 0 {
hdlr.enqueueNumeric( hdlr.enqueueNumeric(
request.Context(), clientID, request.Context(), clientID,
irc.ErrNeedMoreParams, nick, []string{command}, irc.ErrNoTextToSend, nick, []string{command},
"Not enough parameters", "No text to send",
) )
hdlr.broker.Notify(sessionID) hdlr.broker.Notify(sessionID)
hdlr.respondJSON(writer, request, hdlr.respondJSON(writer, request,
@@ -1028,8 +1027,8 @@ func (hdlr *Handlers) handleChannelMsg(
if !isMember { if !isMember {
hdlr.respondIRCError( hdlr.respondIRCError(
writer, request, clientID, sessionID, writer, request, clientID, sessionID,
irc.ErrNotOnChannel, nick, []string{target}, irc.ErrCannotSendToChan, nick, []string{target},
"You're not on that channel", "Cannot send to channel",
) )
return return

View File

@@ -810,9 +810,9 @@ func TestMessageMissingBody(t *testing.T) {
msgs, _ := tserver.pollMessages(token, lastID) msgs, _ := tserver.pollMessages(token, lastID)
if !findNumeric(msgs, "461") { if !findNumeric(msgs, "412") {
t.Fatalf( t.Fatalf(
"expected ERR_NEEDMOREPARAMS (461), got %v", "expected ERR_NOTEXTTOSEND (412), got %v",
msgs, msgs,
) )
} }
@@ -834,9 +834,9 @@ func TestMessageMissingTo(t *testing.T) {
msgs, _ := tserver.pollMessages(token, lastID) msgs, _ := tserver.pollMessages(token, lastID)
if !findNumeric(msgs, "461") { if !findNumeric(msgs, "411") {
t.Fatalf( t.Fatalf(
"expected ERR_NEEDMOREPARAMS (461), got %v", "expected ERR_NORECIPIENT (411), got %v",
msgs, msgs,
) )
} }
@@ -869,9 +869,9 @@ func TestNonMemberCannotSend(t *testing.T) {
msgs, _ := tserver.pollMessages(aliceToken, lastID) msgs, _ := tserver.pollMessages(aliceToken, lastID)
if !findNumeric(msgs, "442") { if !findNumeric(msgs, "404") {
t.Fatalf( t.Fatalf(
"expected ERR_NOTONCHANNEL (442), got %v", "expected ERR_CANNOTSENDTOCHAN (404), got %v",
msgs, msgs,
) )
} }