Add passkey (WebAuthn) authentication with self-registration
Enable users to sign up and sign in using passkeys (biometrics/security keys) without needing a manually-created Authentik account. The existing SSO login remains as an alternative. Backend: - Add WebAuthn registration/authentication endpoints via py-webauthn - Issue HS256 JWTs for passkey users, with Redis-backed challenge storage - Dual JWT verification in auth middleware (issuer-based routing: passkey HS256 vs Authentik RS256) - PasskeyCredential model + migration making user.password nullable - UserRepository with full CRUD for users and credentials Frontend: - AuthUser type abstraction unifying OIDC and passkey users - Passkey service using @simplewebauthn/browser for WebAuthn ceremonies - LoginModal redesigned with Sign In / Sign Up tabs - Type migration from oidc-client-ts User to AuthUser across all services and components
This commit is contained in:
parent
95c0ddc4c6
commit
a8b7eace48
26 changed files with 1229 additions and 129 deletions
|
|
@ -1,6 +1,6 @@
|
|||
// Task service for fetching task status
|
||||
|
||||
import type { User } from 'oidc-client-ts';
|
||||
import type { AuthUser } from '@/auth/types';
|
||||
import type { TaskStatusResponse } from '@/types';
|
||||
import { apiRequest } from './apiClient';
|
||||
import { API_ENDPOINTS } from '@/constants';
|
||||
|
|
@ -19,7 +19,7 @@ export interface ClearAllTasksResponse {
|
|||
/**
|
||||
* Fetch all active tasks for the current user
|
||||
*/
|
||||
export async function fetchTasksForUser(user: User): Promise<string[]> {
|
||||
export async function fetchTasksForUser(user: AuthUser): Promise<string[]> {
|
||||
return apiRequest<string[]>(user, API_ENDPOINTS.TASKS_FOR_USER);
|
||||
}
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ export async function fetchTasksForUser(user: User): Promise<string[]> {
|
|||
* Fetch the status of a specific task
|
||||
*/
|
||||
export async function fetchTaskStatus(
|
||||
user: User,
|
||||
user: AuthUser,
|
||||
taskId: string
|
||||
): Promise<TaskStatusResponse> {
|
||||
return apiRequest<TaskStatusResponse>(user, API_ENDPOINTS.TASK_STATUS, {
|
||||
|
|
@ -39,7 +39,7 @@ export async function fetchTaskStatus(
|
|||
* Cancel a running task
|
||||
*/
|
||||
export async function cancelTask(
|
||||
user: User,
|
||||
user: AuthUser,
|
||||
taskId: string
|
||||
): Promise<CancelTaskResponse> {
|
||||
return apiRequest<CancelTaskResponse>(user, API_ENDPOINTS.CANCEL_TASK, {
|
||||
|
|
@ -51,7 +51,7 @@ export async function cancelTask(
|
|||
/**
|
||||
* Clear all tasks for the current user
|
||||
*/
|
||||
export async function clearAllTasks(user: User): Promise<ClearAllTasksResponse> {
|
||||
export async function clearAllTasks(user: AuthUser): Promise<ClearAllTasksResponse> {
|
||||
return apiRequest<ClearAllTasksResponse>(user, API_ENDPOINTS.CLEAR_ALL_TASKS, {
|
||||
method: 'POST',
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue