fix: TOTP label includes org name, passkeys show device as default name
- 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:
@@ -114,10 +114,20 @@ public class AccountService {
|
|||||||
// The secret is only registered after the user verifies the 6-digit code.
|
// The secret is only registered after the user verifies the 6-digit code.
|
||||||
var user = logtoClient.getUser(userId);
|
var user = logtoClient.getUser(userId);
|
||||||
String email = user != null ? String.valueOf(user.getOrDefault("primaryEmail", "")) : "";
|
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(
|
String otpauthUri = String.format(
|
||||||
"otpauth://totp/Cameleer:%s?secret=%s&issuer=Cameleer&algorithm=SHA1&digits=6&period=30",
|
"otpauth://totp/%s:%s?secret=%s&issuer=%s&algorithm=SHA1&digits=6&period=30",
|
||||||
label, secret);
|
encodedIssuer, encodedAccount, secret, encodedIssuer);
|
||||||
|
|
||||||
return new MfaSetupData(secret, otpauthUri);
|
return new MfaSetupData(secret, otpauthUri);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,9 +107,9 @@ export function PasskeySection({ bare }: { bare?: boolean }) {
|
|||||||
</div>
|
</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)' }}>
|
<div style={{ fontSize: '0.75rem', color: 'var(--text-muted)' }}>
|
||||||
{parseAgent(pk.agent)} · Added {pk.createdAt ? new Date(pk.createdAt).toLocaleDateString() : 'unknown'}
|
Added {pk.createdAt ? new Date(pk.createdAt).toLocaleDateString() : 'unknown'}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user