Separate related domains (ROR) from the in-domain sign-in allow-list
RealmConfig.origins is again purely an allow-list of sign-in sites within the realm's domain (unset = rp-id and all subdomains), restoring the restriction semantics the realm rework had silently turned into an always-open subtree. Cross-domain ROR origins move to their own RealmConfig.related_origins field — always additive, capped, validated to be outside the rp-id domain, and the sole source of the /.well-known/webauthn document. Admin API POST/PATCH accept related_origins; misfiled entries are rejected (cross-domain in origins, in-domain in related_origins). Admin UI: the realm dialog edits the two lists separately with end-user-oriented explanations (allowed sign-in sites vs. related domains + the well-known note); the Realms section intro explains the multi-domain model, and the table shows sign-in site and related domain counts.
This commit is contained in:
@@ -430,7 +430,7 @@ defineExpose({ focusFirstElement })
|
||||
<div class="section-header">
|
||||
<h2>Realms</h2>
|
||||
<p class="section-description">
|
||||
Each realm is one passkey rp-id with its own display name, optional dedicated auth host, and allowed origins (including Related Origin Requests origins on unrelated domains). Changes apply immediately.
|
||||
Realms are the domain names this instance serves. Each realm has its own passkeys: users sign in per domain, and a passkey registered on one realm never works on another. Add a realm for every domain you operate. To let several <em>different</em> domain names share the same passkeys, open the realm and configure related domains (WebAuthn Related Origins). Changes apply immediately.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section-actions">
|
||||
@@ -441,13 +441,14 @@ defineExpose({ focusFirstElement })
|
||||
<tr>
|
||||
<th>Realm</th>
|
||||
<th>Auth Host</th>
|
||||
<th class="center">Origins</th>
|
||||
<th class="center">Sign-in Sites</th>
|
||||
<th class="center">Related Domains</th>
|
||||
<th class="center"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-if="!realms || realms.length === 0">
|
||||
<td colspan="4" class="center muted">No realms configured</td>
|
||||
<td colspan="5" class="center muted">No realms configured</td>
|
||||
</tr>
|
||||
<tr v-for="realm in realms" :key="realm.rp_id">
|
||||
<td class="perm-name-cell">
|
||||
@@ -463,7 +464,8 @@ defineExpose({ focusFirstElement })
|
||||
<span v-if="realm.effective_auth_host">{{ realm.effective_auth_host }}<span v-if="!realm.auth_host" class="muted"> (shared)</span></span>
|
||||
<span v-else class="muted">—</span>
|
||||
</td>
|
||||
<td class="center">{{ realm.origins?.length || 0 }}</td>
|
||||
<td class="center">{{ realm.origins?.length || 'All' }}</td>
|
||||
<td class="center">{{ realm.related_origins?.length || '—' }}</td>
|
||||
<td class="center">
|
||||
<button v-if="!realm.is_default" @click="$emit('deleteRealm', realm)" class="icon-btn delete-icon" aria-label="Delete realm" title="Delete realm">❌</button>
|
||||
</td>
|
||||
|
||||
Reference in New Issue
Block a user