fix: team invite role resolution, user cleanup, and settings page redesign
All checks were successful
CI / build (push) Successful in 2m9s
CI / docker (push) Successful in 1m33s

- Resolve org role names to Logto role IDs in invite and role change flows
  (fixes entity.relation_foreign_key_not_found on invite)
- Handle existing Logto users on re-invite instead of failing with
  email_already_in_use
- Delete users from Logto when removed from last org membership
- Consolidate tenant settings page into 3 cards: Tenant Details, MFA,
  Authentication Policy — remove duplicate MFA Enforcement and Change
  Password (now in Account Settings)
- Make passkey list scrollable

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-27 22:36:21 +02:00
parent e21a9d6046
commit 7fc8a4d407
5 changed files with 148 additions and 156 deletions

View File

@@ -39,7 +39,7 @@ export function PasskeyNudgeBanner() {
);
}
export function PasskeySection() {
export function PasskeySection({ bare }: { bare?: boolean }) {
const { toast } = useToast();
const { data: passkeys, isLoading } = useAccountPasskeyList();
const renamePasskey = useAccountRenamePasskey();
@@ -85,8 +85,8 @@ export function PasskeySection() {
if (isLoading) return null;
const credentials = passkeys ?? [];
return (
<Card title="Passkeys">
const content = (
<>
<p className={styles.description} style={{ marginTop: 0 }}>
Use your fingerprint, face, or security key to sign in faster.
</p>
@@ -95,7 +95,7 @@ export function PasskeySection() {
No passkeys registered. You can register a passkey during sign-in.
</p>
) : (
<div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
<div style={{ maxHeight: 240, overflowY: 'auto', display: 'flex', flexDirection: 'column', gap: 12 }}>
{credentials.map((pk) => (
<div key={pk.id} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '8px 0', borderBottom: '1px solid var(--border)' }}>
<div style={{ flex: 1 }}>
@@ -131,6 +131,8 @@ export function PasskeySection() {
))}
</div>
)}
</Card>
</>
);
return bare ? content : <Card title="Passkeys">{content}</Card>;
}