|
@@ -164,6 +164,20 @@ a code will display the necessary code.`,
|
164
|
164
|
enabled: servCmdRequiresAuthEnabled,
|
165
|
165
|
minParams: 1,
|
166
|
166
|
},
|
|
167
|
+ "erase": {
|
|
168
|
+ handler: nsUnregisterHandler,
|
|
169
|
+ help: `Syntax: $bERASE <username> [code]$b
|
|
170
|
+
|
|
171
|
+ERASE deletes all records of an account, allowing it to be re-registered.
|
|
172
|
+This should be used with caution, because it violates an expectation that
|
|
173
|
+account names are permanent identifiers. Typically, UNREGISTER should be
|
|
174
|
+used instead. A confirmation code is required; invoking the command
|
|
175
|
+without a code will display the necessary code.`,
|
|
176
|
+ helpShort: `$bERASE$b erases all records of an account, allowing reuse.`,
|
|
177
|
+ enabled: servCmdRequiresAuthEnabled,
|
|
178
|
+ capabs: []string{"accreg"},
|
|
179
|
+ minParams: 1,
|
|
180
|
+ },
|
167
|
181
|
"verify": {
|
168
|
182
|
handler: nsVerifyHandler,
|
169
|
183
|
help: `Syntax: $bVERIFY <username> <code>$b
|
|
@@ -815,6 +829,8 @@ func nsSaregisterHandler(server *Server, client *Client, command string, params
|
815
|
829
|
}
|
816
|
830
|
|
817
|
831
|
func nsUnregisterHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
|
832
|
+ erase := command == "erase"
|
|
833
|
+
|
818
|
834
|
username := params[0]
|
819
|
835
|
var verificationCode string
|
820
|
836
|
if len(params) > 1 {
|
|
@@ -826,39 +842,51 @@ func nsUnregisterHandler(server *Server, client *Client, command string, params
|
826
|
842
|
return
|
827
|
843
|
}
|
828
|
844
|
|
829
|
|
- account, err := server.accounts.LoadAccount(username)
|
830
|
|
- if err == errAccountDoesNotExist {
|
831
|
|
- nsNotice(rb, client.t("Invalid account name"))
|
832
|
|
- return
|
833
|
|
- } else if err != nil {
|
834
|
|
- nsNotice(rb, client.t("Internal error"))
|
835
|
|
- return
|
|
845
|
+ var accountName string
|
|
846
|
+ var registeredAt time.Time
|
|
847
|
+ if erase {
|
|
848
|
+ // account may not be in a loadable state, e.g., if it was unregistered
|
|
849
|
+ accountName = username
|
|
850
|
+ } else {
|
|
851
|
+ account, err := server.accounts.LoadAccount(username)
|
|
852
|
+ if err == errAccountDoesNotExist {
|
|
853
|
+ nsNotice(rb, client.t("Invalid account name"))
|
|
854
|
+ return
|
|
855
|
+ } else if err != nil {
|
|
856
|
+ nsNotice(rb, client.t("Internal error"))
|
|
857
|
+ return
|
|
858
|
+ }
|
|
859
|
+ accountName = account.Name
|
|
860
|
+ registeredAt = account.RegisteredAt
|
836
|
861
|
}
|
837
|
862
|
|
838
|
|
- cfname, _ := CasefoldName(username)
|
839
|
|
- if !(cfname == client.Account() || client.HasRoleCapabs("accreg")) {
|
|
863
|
+ if !(accountName == client.AccountName() || client.HasRoleCapabs("accreg")) {
|
840
|
864
|
nsNotice(rb, client.t("Insufficient oper privs"))
|
841
|
865
|
return
|
842
|
866
|
}
|
843
|
867
|
|
844
|
|
- expectedCode := utils.ConfirmationCode(account.Name, account.RegisteredAt)
|
|
868
|
+ expectedCode := utils.ConfirmationCode(accountName, registeredAt)
|
845
|
869
|
if expectedCode != verificationCode {
|
846
|
|
- nsNotice(rb, ircfmt.Unescape(client.t("$bWarning: unregistering this account will remove its stored privileges.$b")))
|
847
|
|
- nsNotice(rb, fmt.Sprintf(client.t("To confirm account unregistration, type: /NS UNREGISTER %[1]s %[2]s"), cfname, expectedCode))
|
|
870
|
+ if erase {
|
|
871
|
+ nsNotice(rb, ircfmt.Unescape(client.t("$bWarning: erasing this account will allow it to be re-registered; consider UNREGISTER instead.$b")))
|
|
872
|
+ nsNotice(rb, fmt.Sprintf(client.t("To confirm account erase, type: /NS ERASE %[1]s %[2]s"), accountName, expectedCode))
|
|
873
|
+ } else {
|
|
874
|
+ nsNotice(rb, ircfmt.Unescape(client.t("$bWarning: unregistering this account will remove its stored privileges.$b")))
|
|
875
|
+ nsNotice(rb, fmt.Sprintf(client.t("To confirm account unregistration, type: /NS UNREGISTER %[1]s %[2]s"), accountName, expectedCode))
|
|
876
|
+ }
|
848
|
877
|
return
|
849
|
878
|
}
|
850
|
879
|
|
851
|
|
- err = server.accounts.Unregister(cfname)
|
|
880
|
+ err := server.accounts.Unregister(accountName, erase)
|
852
|
881
|
if err == errAccountDoesNotExist {
|
853
|
882
|
nsNotice(rb, client.t(err.Error()))
|
854
|
883
|
} else if err != nil {
|
855
|
884
|
nsNotice(rb, client.t("Error while unregistering account"))
|
856
|
885
|
} else {
|
857
|
|
- nsNotice(rb, fmt.Sprintf(client.t("Successfully unregistered account %s"), cfname))
|
858
|
|
- server.logger.Info("accounts", "client", client.Nick(), "unregistered account", cfname)
|
|
886
|
+ nsNotice(rb, fmt.Sprintf(client.t("Successfully unregistered account %s"), accountName))
|
|
887
|
+ server.logger.Info("accounts", "client", client.Nick(), "unregistered account", accountName)
|
|
888
|
+ client.server.snomasks.Send(sno.LocalAccounts, fmt.Sprintf(ircfmt.Unescape("Client $c[grey][$r%s$c[grey]] unregistered account $c[grey][$r%s$c[grey]]"), client.NickMaskString(), accountName))
|
859
|
889
|
}
|
860
|
|
-
|
861
|
|
- client.server.snomasks.Send(sno.LocalAccounts, fmt.Sprintf(ircfmt.Unescape("Client $c[grey][$r%s$c[grey]] unregistered account $c[grey][$r%s$c[grey]]"), client.NickMaskString(), account.Name))
|
862
|
890
|
}
|
863
|
891
|
|
864
|
892
|
func nsVerifyHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|