markemacht/resources/views/components/passkey-verify.blade.php
Kevin Adametz 00796a35d5
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (8.3) (push) Has been cancelled
tests / ci (8.4) (push) Has been cancelled
tests / ci (8.5) (push) Has been cancelled
Markenwissen-Wissensbasis: Konsistenz-Korrekturen + Copyright-Hygiene
Konsolidierter, bereinigter Stand der Wissensbasis (docs/). Frischer
Wurzel-Commit, um urheberrechtlich problematische Volltexte aus der
Historie zu entfernen (die bisherige Historie bestand aus einem einzigen
Initial-Commit).

Enthaltene Änderungen (vgl. docs/_Steuerung/CHANGELOG.md, 2026-05-29):
- Copyright-Hygiene: 25 Volltext-/Übersetzungsdateien (Sharp 14 Kap.,
  Wala 11 Kap.) entfernt; je Quelle _Fundstellen-Index.md als
  Provenienzbeleg; Quellnachweise + Steuerungsdateien angepasst.
- Konsistenz-Korrekturen: Reichweite 000-013 (Scorecard-Regeln),
  Rule-ID MW-WK-DIFF-101, Quellnachweis-Dateiverweis, Dok.000 v2.0.2.
- Dateinamen-Normalisierung: Startdatei ohne Leerzeichen.

Originale (Wala/Sharp E-Books) privat außerhalb des Repos archiviert.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-29 08:23:03 +00:00

76 lines
2.5 KiB
PHP

@props([
'optionsRoute' => 'passkey.login-options',
'submitRoute' => 'passkey.login',
'label' => __('Sign in with a passkey'),
'loadingLabel' => __('Authenticating...'),
'separator' => __('Or continue with email'),
])
@assets
@vite('resources/js/passkeys.js')
@endassets
<div
x-data="{
supported: false,
loading: false,
error: null,
updateSupport() {
this.supported = Boolean(window.Passkeys?.isSupported());
},
init() {
this.updateSupport();
window.addEventListener('passkeys:ready', () => this.updateSupport(), { once: true });
},
async verify() {
this.loading = true;
this.error = null;
try {
const response = await window.Passkeys.verify({
routes: {
options: '{{ route($optionsRoute) }}',
submit: '{{ route($submitRoute) }}',
},
});
Livewire.navigate(response.redirect || '/dashboard');
} catch (e) {
if (e.constructor?.name !== 'UserCancelledError') {
this.error = e.message;
}
} finally {
this.loading = false;
}
},
}"
>
<template x-if="supported">
<div>
<div class="grid gap-2">
<flux:button
variant="outline"
icon="finger-print"
class="w-full"
x-on:click="verify()"
x-bind:disabled="loading"
>
<span x-show="!loading">{{ $label }}</span>
<span x-show="loading" x-cloak>{{ $loadingLabel }}</span>
</flux:button>
<p x-show="error" x-text="error" x-cloak
class="text-sm text-center text-red-600 dark:text-red-400"></p>
</div>
<div class="relative my-6">
<div class="absolute inset-0 flex items-center">
<div class="w-full border-t border-zinc-200 dark:border-zinc-700"></div>
</div>
<div class="relative flex justify-center text-xs uppercase">
<span class="px-2 text-zinc-500 dark:text-zinc-400 bg-white dark:bg-zinc-900">
{{ $separator }}
</span>
</div>
</div>
</div>
</template>
</div>