CLI: positional rp-id/rp-name; init adds domains to an existing database
- 'paskia init [rp-id] [rp-name]' and 'paskia migrate [rp-id]' are now positional; comma separation and the --rp-id/--rp-name flags are gone. - With an existing paskia.kantadb, init adds the rp-id as a new domain (seeding its OIDC provider) or updates an existing domain's rp-name. - Origin allow-list semantics clarified: the bare '*' entry allows anything within the rp-id domain on any scheme and port (also the empty-list default and its display in the admin UI, replacing the synthetic '*.rp-id' row); '*.x' wildcards are https-only; exact entries match scheme, host and port. Legacy '*.rp-id' wildcards migrate to '*' to preserve their any-scheme meaning.
This commit is contained in:
@@ -113,6 +113,7 @@ function isWellFormedDomain(value) {
|
||||
|
||||
function originHostname(origin) {
|
||||
if (!origin.trim()) return null
|
||||
if (origin.trim() === '*') return '*'
|
||||
if (origin.trim().startsWith('*.')) {
|
||||
const base = origin.trim().slice(2).replace(/\.+$/, '')
|
||||
return isWellFormedDomain(base) ? base : null
|
||||
@@ -126,6 +127,7 @@ function originHostname(origin) {
|
||||
}
|
||||
|
||||
function isWithinDomain(origin, rpId) {
|
||||
if (origin.trim() === '*') return true
|
||||
const hostname = originHostname(origin)
|
||||
if (!hostname) return false
|
||||
return hostname === rpId || hostname.endsWith('.' + rpId)
|
||||
@@ -167,7 +169,7 @@ function validateOrigin(i) {
|
||||
d.originValidation[i] = 'invalid'
|
||||
return
|
||||
}
|
||||
if (value.trim().startsWith('*.')) {
|
||||
if (value.trim() === '*' || value.trim().startsWith('*.')) {
|
||||
d.originValidation[i] = null // wildcards have no concrete site to probe
|
||||
return
|
||||
}
|
||||
@@ -203,15 +205,15 @@ async function testWellKnown() {
|
||||
}
|
||||
watch(() => relatedEntries.value.map(asHttpsOrigin).join('|'), testWellKnown, { immediate: true })
|
||||
|
||||
// Seed the default wildcard entry for a new domain once its rp-id is known,
|
||||
// so the list always shows what is allowed ('*.example.com' = the domain and
|
||||
// all its subdomains). Removing the last in-domain entry is blocked in the
|
||||
// row menu, so the list never becomes empty afterwards.
|
||||
// Seed the default '*' entry for a new domain once its rp-id is known,
|
||||
// so the list always shows what is allowed ('*' = the domain and all its
|
||||
// subdomains, any scheme/port). Removing the last in-domain entry is
|
||||
// blocked in the row menu, so the list never becomes empty afterwards.
|
||||
watch(dialogRpId, rp => {
|
||||
const d = props.dialog?.data
|
||||
if (props.dialog?.type !== 'domain-edit' || !d?.isNew) return
|
||||
if (!d.origins.length && isWellFormedDomain(rp)) {
|
||||
d.origins.push('*.' + rp)
|
||||
d.origins.push('*')
|
||||
d.originValidation.push(null)
|
||||
}
|
||||
})
|
||||
@@ -236,9 +238,10 @@ function setAuthHost(i) {
|
||||
const d = props.dialog?.data
|
||||
if (!d) return
|
||||
let key = entryKey(d.origins[i])
|
||||
if (key.startsWith('*.')) {
|
||||
if (key === '*' || key.startsWith('*.')) {
|
||||
// A wildcard cannot be the auth host — create a concrete auth.<base> entry
|
||||
key = 'auth.' + key.slice(2)
|
||||
const base = key === '*' ? dialogRpId.value : key.slice(2)
|
||||
key = 'auth.' + base
|
||||
if (!d.origins.some(o => entryKey(o) === key)) {
|
||||
d.origins.push(key)
|
||||
d.originValidation.push(null)
|
||||
@@ -387,7 +390,7 @@ function onRemoveOrigin(i) {
|
||||
<p v-else-if="dialog.data.originValidation.some(v => v === 'mismatch')" class="small muted">Some sites are reachable but do not serve this domain.</p>
|
||||
</div>
|
||||
<p class="small muted">
|
||||
Only the listed sites may sign in with this domain's passkeys — <strong>*.{{ dialog.data.rp_id }}</strong> means the domain and all its subdomains.
|
||||
Only the listed sites may sign in with this domain's passkeys — <strong>*</strong> means the domain and all its subdomains on any scheme and port; <strong>*.{{ dialog.data.rp_id }}</strong> restricts that to https.
|
||||
Entries on other domain names become related origins (WebAuthn ROR). The 🔑 site hosts the account and admin interface (set via ⋮).
|
||||
</p>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user