Skip to content

fix(totp): allow /totp add when the server name contains a colon - #3160

Merged
Xephi merged 1 commit into
AuthMe:masterfrom
rishabhvenu:fix/totp-issuer-colon
Oct 8, 2026
Merged

Xephi merged 1 commit into
AuthMe:masterfrom
rishabhvenu:fix/totp-issuer-colon

Conversation

@rishabhvenu

Copy link
Copy Markdown
Contributor

/totp add fails with "An unexpected error occurred trying to execute that command" when settings.serverName contains a colon, for example UT:Rebirth in #3158. TotpAuthenticator.generateTotpKey passes the server name to GoogleAuthenticatorQRGenerator.getOtpAuthTotpURL as the issuer, and googleauth 1.5.0 throws IllegalArgumentException: Issuer cannot contain the ':' character. for it. The command then fails for every player on that server.

The otpauth label has the form issuer:account, and the Key URI format does not allow a colon inside the issuer (a percent-encoded %3A counts as the separator too), so the colon cannot be kept by encoding it. This change replaces : with - in the issuer only when the URL is built, so UT:Rebirth is shown as UT-Rebirth in the authenticator app. I picked a hyphen over a space because it is written unescaped in both the label and the issuer parameter, while a space ends up as %20 in one and + in the other. The configured server name is not changed and is still used as is everywhere else (welcome message, emails).

The colon is the only character googleauth rejects in the issuer. The account name (the player name) is only checked for being non-empty, so nothing changes there.

Testing:

  • Added TotpAuthenticatorTest.shouldGenerateTotpKeyForServerNameWithColon. It fails on master with the exception from the issue and passes with the change.
  • mvn test -pl authme-core (JDK 21): 1444 tests, 0 failures. mvn -V -B clean package (the CI command, JDK 21): all modules build and pass. PurgeServiceTest.shouldRunAutoPurge failed in two earlier runs of that command on a heavily loaded machine (it compares wall-clock timestamps with a 100 ms tolerance and was 132 ms off); it is unrelated to this change and passed in the other runs.
  • In game, with settings.serverName: 'A:B' and an offline-mode bot that registers, logs out, logs in and runs /totp add:
    • Paper 1.21.11 with AuthMe-*-Paper.jar (bot on 1.21.4 through ViaVersion/ViaBackwards): master logs the same stack trace as the issue and the player gets the error message. With the change the player gets the secret and the QR code link, whose data parameter decodes to otpauth://totp/A-B:TotpBot?secret=...&issuer=A-B&algorithm=SHA1&digits=6&period=30, and /totp confirm with a code computed from that secret is accepted.
    • Paper 1.21.4 with AuthMe-*-Spigot-Legacy.jar: same results, also with serverName: 'UT:Rebirth' (issuer UT-Rebirth).

Not tested: scanning the generated QR code with a real authenticator app, and a run under JDK 17 (authme-core is compiled with --release 17, the tests ran on JDK 21).

This touches the same lines as #3128 in TotpAuthenticator.generateTotpKey, so whichever is merged second needs a small conflict resolution there.

Fixes #3158

The server name is passed to googleauth as the TOTP issuer. The library
throws "Issuer cannot contain the ':' character." for such a name, so
/totp add failed with an unexpected error for every player.

The otpauth label has the form "issuer:account", so a colon cannot be
part of the issuer. Replace it with a hyphen when building the URL. The
configured server name itself is not changed.

Fixes AuthMe#3158
@Xephi
Xephi merged commit 4624a4d into AuthMe:master Oct 8, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Command /totp add broken

2 participants