SetPassword salted the phrase with the username according to the OUTGOING
algorithm but stored the result under the INCOMING one. SHA1 and SHA2 prepend
the username; Argon2 and PBKDF2 do not. Two live lockouts followed:
- A ServUO-imported SHA2 account logging in with the default Argon2 config was
'upgraded' to argon2(username + password) and tagged Argon2. The next login
rebuilt the phrase as bare password and could never match. One successful
login, then permanent lockout.
- SetPassword also runs from the Account constructor, before _passwordAlgorithm
is assigned, so it is still None. Creating an account under SHA1 or SHA2
hashed the bare password and tagged it with an algorithm that re-adds the
username -- a brand-new account that could never log in.
Derive the phrase from the algorithm being written. Also configures Accounts
persistence in the UOContent test fixture so an Account can be constructed.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>