fix: TOTP label includes org name, passkeys show device as default name
All checks were successful
CI / build (push) Successful in 2m10s
CI / docker (push) Successful in 1m27s

- TOTP otpauth URI issuer changed from "Cameleer" to "Cameleer - <org>"
  so authenticator apps display the organization name
- Passkeys without a custom name now show parsed device info (e.g.
  "Chrome on Windows") instead of "Unnamed passkey"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-27 22:53:05 +02:00
parent 7fe9c581b0
commit 06134d6e67
2 changed files with 15 additions and 5 deletions

View File

@@ -114,10 +114,20 @@ public class AccountService {
// The secret is only registered after the user verifies the 6-digit code.
var user = logtoClient.getUser(userId);
String email = user != null ? String.valueOf(user.getOrDefault("primaryEmail", "")) : "";
String label = email.isBlank() ? userId : email;
String account = email.isBlank() ? userId : email;
// Include org name in issuer so authenticator apps show "Cameleer - OrgName"
String issuer = "Cameleer";
var orgs = logtoClient.getUserOrganizations(userId);
if (!orgs.isEmpty()) {
issuer = "Cameleer - " + orgs.getFirst().get("name");
}
String encodedIssuer = java.net.URLEncoder.encode(issuer, java.nio.charset.StandardCharsets.UTF_8);
String encodedAccount = java.net.URLEncoder.encode(account, java.nio.charset.StandardCharsets.UTF_8);
String otpauthUri = String.format(
"otpauth://totp/Cameleer:%s?secret=%s&issuer=Cameleer&algorithm=SHA1&digits=6&period=30",
label, secret);
"otpauth://totp/%s:%s?secret=%s&issuer=%s&algorithm=SHA1&digits=6&period=30",
encodedIssuer, encodedAccount, secret, encodedIssuer);
return new MfaSetupData(secret, otpauthUri);
}

View File

@@ -107,9 +107,9 @@ export function PasskeySection({ bare }: { bare?: boolean }) {
</div>
) : (
<>
<div style={{ fontWeight: 500 }}>{pk.name || 'Unnamed passkey'}</div>
<div style={{ fontWeight: 500 }}>{pk.name || parseAgent(pk.agent)}</div>
<div style={{ fontSize: '0.75rem', color: 'var(--text-muted)' }}>
{parseAgent(pk.agent)} &middot; Added {pk.createdAt ? new Date(pk.createdAt).toLocaleDateString() : 'unknown'}
Added {pk.createdAt ? new Date(pk.createdAt).toLocaleDateString() : 'unknown'}
</div>
</>
)}