Add invite-only registration: a new account waits for a confirmed member to VOUCH
Some checks failed
CI / check (push) Failing after 5m12s
Some checks failed
CI / check (push) Failing after 5m12s
This commit is contained in:
parent
140b19ee04
commit
1c6b8c799f
18 changed files with 123 additions and 12 deletions
|
|
@ -7,6 +7,7 @@ mod register;
|
|||
#[path = "identify.rs"]
|
||||
mod identify;
|
||||
mod login;
|
||||
mod vouch;
|
||||
#[path = "logout.rs"]
|
||||
mod logout;
|
||||
#[path = "cert.rs"]
|
||||
|
|
@ -53,6 +54,7 @@ const TOPICS: &[HelpEntry] = &[
|
|||
HelpEntry { cmd: "REGISTER", summary: "register your nick as an account", detail: "Syntax: \x02REGISTER <password> [email]\x02\nRegisters your current nick as an account. If an email is given and confirmation is on, you get a code to \x02CONFIRM\x02." },
|
||||
HelpEntry { cmd: "IDENTIFY", summary: "log in to your account", detail: "Syntax: \x02IDENTIFY [account] <password>\x02\nLogs you in. Also \x02ID\x02." },
|
||||
HelpEntry { cmd: "LOGIN", summary: "log in and reclaim your nick", detail: "Syntax: \x02LOGIN <nick> <password>\x02\nLogs you in to <nick>'s account and moves you onto that nick, freeing any session already holding it." },
|
||||
HelpEntry { cmd: "VOUCH", summary: "confirm a pending member", detail: "Syntax: \x02VOUCH <nick>\x02\nOn an invite-only network, confirms a newly-registered account so it becomes active. Any identified member may vouch." },
|
||||
HelpEntry { cmd: "LOGOUT", summary: "log out to a guest nick", detail: "Syntax: \x02LOGOUT\x02\nLogs you out and moves you to a guest nick. Also \x02LOGOFF\x02." },
|
||||
HelpEntry { cmd: "INFO", summary: "show account information", detail: "Syntax: \x02INFO [account]\x02\nShows account information. The email is shown only to the owner." },
|
||||
HelpEntry { cmd: "ALIST", summary: "list channels you have access on", detail: "Syntax: \x02ALIST\x02\nLists the channels you hold access on." },
|
||||
|
|
@ -129,6 +131,7 @@ impl Service for NickServ {
|
|||
Some("RECOVER") => ghost::handle(me, &self.guest_nick, &mut self.guest_seq, from, args, ctx, net, db, true),
|
||||
Some("RESETPASS") => resetpass::handle(me, from, args, ctx, db),
|
||||
Some("CONFIRM") => confirm::handle(me, from, args, ctx, db),
|
||||
Some("VOUCH") => vouch::handle(me, from, args, ctx, db),
|
||||
Some("AJOIN") => ajoin::handle(me, from, args, ctx, net, db),
|
||||
Some("SUSPEND") => suspend::handle(me, from, args, ctx, net, db, true),
|
||||
Some("UNSUSPEND") => suspend::handle(me, from, args, ctx, net, db, false),
|
||||
|
|
|
|||
45
modules/nickserv/src/vouch.rs
Normal file
45
modules/nickserv/src/vouch.rs
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
use echo_api::{Sender, ServiceCtx, Store};
|
||||
use echo_api::t;
|
||||
|
||||
// VOUCH <nick>: confirm a pending (invite-only) account so it becomes active. Any
|
||||
// identified member may vouch; the action is announced to staff so a bad account
|
||||
// can be traced back to whoever vouched for it.
|
||||
pub fn handle(me: &str, from: &Sender, args: &[&str], ctx: &mut ServiceCtx, db: &mut dyn Store) {
|
||||
if !db.registration_vouch() {
|
||||
ctx.notice(me, from.uid, "Vouching isn't enabled on this network.");
|
||||
return;
|
||||
}
|
||||
let Some(account) = from.account else {
|
||||
ctx.notice(me, from.uid, "You must be identified to vouch for someone.");
|
||||
return;
|
||||
};
|
||||
// Only an already-confirmed member may vouch, or the invite gate is trivially
|
||||
// bypassed by registering a second account and self-vouching.
|
||||
if !db.is_verified(account) {
|
||||
ctx.notice(me, from.uid, "Only confirmed members can vouch for others.");
|
||||
return;
|
||||
}
|
||||
let Some(&target) = args.get(1) else {
|
||||
ctx.notice(me, from.uid, "Syntax: VOUCH <nick>");
|
||||
return;
|
||||
};
|
||||
let Some(tacct) = db.resolve_account(target).map(str::to_string) else {
|
||||
ctx.notice(me, from.uid, t!(ctx, "\x02{target}\x02 isn't registered.", target = target));
|
||||
return;
|
||||
};
|
||||
if tacct.eq_ignore_ascii_case(account) {
|
||||
ctx.notice(me, from.uid, "You can't vouch for yourself.");
|
||||
return;
|
||||
}
|
||||
if db.is_verified(&tacct) {
|
||||
ctx.notice(me, from.uid, t!(ctx, "\x02{account}\x02 is already confirmed.", account = tacct));
|
||||
return;
|
||||
}
|
||||
match db.verify_account(&tacct) {
|
||||
Ok(()) => {
|
||||
ctx.notice(me, from.uid, t!(ctx, "You vouched for \x02{account}\x02; their account is now active.", account = tacct));
|
||||
ctx.alert("REGISTER", format!("vouched for \x02{tacct}\x02"));
|
||||
}
|
||||
Err(_) => ctx.notice(me, from.uid, "Sorry, that didn't work. Please try again in a moment."),
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue