mirror of
https://github.com/complexcaresolutions/dak.c2s.git
synced 2026-03-17 16:03:41 +00:00
feat: add profile/avatar/MFA types and service functions
Extend User and UserResponse interfaces with first_name, last_name, display_name, avatar_url fields. Add ProfileUpdatePayload, ChangePasswordPayload, MFASetupResponse, MFAVerifyPayload types. Add authService functions for profile update, avatar upload/delete, password change, and MFA setup/verify/disable. Add refreshUser to AuthContext so components can re-fetch user data after changes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
fc609401c3
commit
832f5c0a63
3 changed files with 76 additions and 1 deletions
|
|
@ -9,6 +9,7 @@ interface AuthContextType {
|
|||
login: (data: LoginRequest) => Promise<void>
|
||||
register: (data: RegisterRequest) => Promise<void>
|
||||
logout: () => Promise<void>
|
||||
refreshUser: () => Promise<void>
|
||||
}
|
||||
|
||||
const AuthContext = createContext<AuthContextType | null>(null)
|
||||
|
|
@ -46,6 +47,11 @@ export function AuthProvider({ children }: { children: ReactNode }) {
|
|||
setUser(null)
|
||||
}
|
||||
|
||||
const refreshUserFn = async () => {
|
||||
const updatedUser = await authService.getMe()
|
||||
setUser(updatedUser)
|
||||
}
|
||||
|
||||
return (
|
||||
<AuthContext.Provider value={{
|
||||
user,
|
||||
|
|
@ -54,6 +60,7 @@ export function AuthProvider({ children }: { children: ReactNode }) {
|
|||
login: loginFn,
|
||||
register: registerFn,
|
||||
logout: logoutFn,
|
||||
refreshUser: refreshUserFn,
|
||||
}}>
|
||||
{children}
|
||||
</AuthContext.Provider>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import api from './api'
|
||||
import type { LoginRequest, RegisterRequest, TokenResponse, User } from '@/types'
|
||||
import type { LoginRequest, RegisterRequest, TokenResponse, User, ProfileUpdatePayload, ChangePasswordPayload, MFASetupResponse, MFAVerifyPayload } from '@/types'
|
||||
|
||||
export async function login(data: LoginRequest): Promise<TokenResponse> {
|
||||
const response = await api.post<TokenResponse>('/auth/login', data)
|
||||
|
|
@ -29,3 +29,39 @@ export async function getMe(): Promise<User> {
|
|||
const response = await api.get<User>('/auth/me')
|
||||
return response.data
|
||||
}
|
||||
|
||||
export async function updateProfile(data: ProfileUpdatePayload): Promise<User> {
|
||||
const response = await api.put<User>('/auth/profile', data)
|
||||
return response.data
|
||||
}
|
||||
|
||||
export async function uploadAvatar(file: File): Promise<User> {
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
const response = await api.post<User>('/auth/avatar', formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
})
|
||||
return response.data
|
||||
}
|
||||
|
||||
export async function deleteAvatar(): Promise<User> {
|
||||
const response = await api.delete<User>('/auth/avatar')
|
||||
return response.data
|
||||
}
|
||||
|
||||
export async function changePassword(data: ChangePasswordPayload): Promise<void> {
|
||||
await api.post('/auth/change-password', data)
|
||||
}
|
||||
|
||||
export async function setupMFA(): Promise<MFASetupResponse> {
|
||||
const response = await api.post<MFASetupResponse>('/auth/mfa/setup')
|
||||
return response.data
|
||||
}
|
||||
|
||||
export async function verifyMFA(data: MFAVerifyPayload): Promise<void> {
|
||||
await api.post('/auth/mfa/verify', data)
|
||||
}
|
||||
|
||||
export async function disableMFA(password: string): Promise<void> {
|
||||
await api.delete('/auth/mfa', { data: { password } })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@ export interface User {
|
|||
id: number
|
||||
username: string
|
||||
email: string
|
||||
first_name: string | null
|
||||
last_name: string | null
|
||||
display_name: string | null
|
||||
avatar_url: string | null
|
||||
role: 'admin' | 'dak_mitarbeiter'
|
||||
mfa_enabled: boolean
|
||||
is_active: boolean
|
||||
|
|
@ -196,6 +200,10 @@ export interface UserResponse {
|
|||
id: number
|
||||
username: string
|
||||
email: string
|
||||
first_name: string | null
|
||||
last_name: string | null
|
||||
display_name: string | null
|
||||
avatar_url: string | null
|
||||
role: 'admin' | 'dak_mitarbeiter'
|
||||
is_active: boolean
|
||||
mfa_enabled: boolean
|
||||
|
|
@ -217,6 +225,30 @@ export interface UpdateUserPayload {
|
|||
is_active?: boolean
|
||||
}
|
||||
|
||||
// Account / Profile
|
||||
export interface ProfileUpdatePayload {
|
||||
first_name?: string
|
||||
last_name?: string
|
||||
display_name?: string
|
||||
username?: string
|
||||
email?: string
|
||||
}
|
||||
|
||||
export interface ChangePasswordPayload {
|
||||
old_password: string
|
||||
new_password: string
|
||||
}
|
||||
|
||||
export interface MFASetupResponse {
|
||||
secret: string
|
||||
qr_uri: string
|
||||
}
|
||||
|
||||
export interface MFAVerifyPayload {
|
||||
secret: string
|
||||
code: string
|
||||
}
|
||||
|
||||
// Admin Invitations
|
||||
export interface InvitationResponse {
|
||||
id: number
|
||||
|
|
|
|||
Loading…
Reference in a new issue