Finish Phase 6: Push frontend, WebAuthn frontend, OpenAPI/Swagger
Frontend: - stores/push.ts: fixed VAPID key endpoint, added checkSubscription, proper subscription format - UserSettings.tsx: added [ENABLE PUSH] toggle and [REGISTER PASSKEY] button - LoginForm.tsx: added [SIGN IN WITH PASSKEY] button Backend: - cmd/server/main.go: added Swagger annotations, /docs/* route - docs/: generated swagger.json, swagger.yaml, docs.go - Makefile: added docs target for swag init
This commit is contained in:
@@ -85,6 +85,42 @@ export function LoginForm() {
|
||||
{isLoading ? '[PROCESSING...]' : isRegister ? '[REGISTER]' : '[LOGIN]'}
|
||||
</button>
|
||||
</form>
|
||||
{!isRegister && (
|
||||
<div className="mt-3">
|
||||
<button
|
||||
type="button"
|
||||
onClick={async () => {
|
||||
try {
|
||||
// Get challenge from server
|
||||
const resp = await fetch('/api/v1/auth/webauthn/login/begin', { method: 'POST', credentials: 'include' });
|
||||
if (!resp.ok) throw new Error('Passkey login not available');
|
||||
const options = await resp.json();
|
||||
|
||||
// Use WebAuthn API
|
||||
const credential = await navigator.credentials.get({ publicKey: options });
|
||||
if (!credential) return;
|
||||
|
||||
// Send to server
|
||||
const finishResp = await fetch('/api/v1/auth/webauthn/login/finish', {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(credential),
|
||||
});
|
||||
|
||||
if (finishResp.ok) {
|
||||
navigate('/');
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Passkey login failed:', err);
|
||||
}
|
||||
}}
|
||||
className="terminal-button w-full border-gb-aqua text-gb-aqua"
|
||||
>
|
||||
[SIGN IN WITH PASSKEY]
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
<div className="mt-4 text-center">
|
||||
<button
|
||||
type="button"
|
||||
|
||||
Reference in New Issue
Block a user