Password Reset

UrsaMU does not have a self-service “forgot password” email flow — the server
has no email sending built in. Instead, password resets are a two-step process:
an admin generates a short-lived token in-game, then the player uses that token
to set a new password via the REST API.

Overview

Admin (in-game)                   Player (out of band)
─────────────────────────────     ─────────────────────────────────
@resettoken PlayerName            Receives token from admin
  → token printed in-game   ───▶  POST /api/v1/auth/reset-password
                                    { token, newPassword }
                                  ← 200 OK — password updated

The token is a UUID, stored on the player object, and expires 1 hour after
generation. It is single-use — it is deleted immediately on successful reset.

Admin Steps

Any admin or wizard can generate a reset token for any player character.

In-game command

@resettoken <player>

Example:

@resettoken Talia
Reset token for Talia: 3f8a9b2c-1e4d-4f7a-8b6e-2a9c0d1e3f5a (expires in 1 hour)

The token is printed directly in your in-game session. You then pass it to the
player through any out-of-band channel — Discord, email, direct message, etc.

Security note: The token grants the ability to set a new password for that
account. Treat it like a temporary password and communicate it securely.
If the token is compromised before use, run @resettoken again — the new
token replaces the old one.


Player Steps

The player calls the REST endpoint with the token they received.

POST /api/v1/auth/reset-password

No authentication header required.

Request body:

{
  "token": "3f8a9b2c-1e4d-4f7a-8b6e-2a9c0d1e3f5a",
  "newPassword": "my-new-secure-password"
}

Example with curl:

curl -X POST https://yourgame.example.com/api/v1/auth/reset-password \
  -H "Content-Type: application/json" \
  -d '{"token":"3f8a9b2c-1e4d-4f7a-8b6e-2a9c0d1e3f5a","newPassword":"my-new-secure-password"}'

Success response (200 OK):

{ "message": "Password updated successfully." }

After a successful reset the player can log in with their new password using the
normal POST /api/v1/auth/login endpoint.

API Reference

Field Type Required Notes
token string Yes UUID generated by @resettoken
newPassword string Yes Max 512 characters
Outcome Status Body
Success 200 { "message": "Password updated successfully." }
Missing fields 400 { "error": "token and newPassword are required." }
Password too long 400 { "error": "Password must be 512 characters or fewer." }
Bad or expired token 400 { "error": "Invalid or expired reset token." }

Error Responses

Invalid or expired token

The token is invalid if:

  • It was never generated (or the player name was wrong)
  • More than 1 hour has passed since @resettoken was run
  • It was already used successfully
{ "error": "Invalid or expired reset token." }

Run @resettoken <player> again to generate a fresh token.

Password too long

Passwords are limited to 512 characters.

{ "error": "Password must be 512 characters or fewer." }

Security Notes

  • Tokens are stored as plain UUIDs on the player object and are single-use.
  • Both generation (ADMIN_RESETTOKEN) and consumption (PASSWORD_RESET) are
    written to logs/security.log with the actor ID and client IP.
  • Admins can reset their own token at any time by running @resettoken again —
    the new token overwrites the old one.
  • The @newpassword <player>=<pass> command is an alternative for admins who
    want to set the password directly without involving the player.