Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | 4x 51x 39x 4x 4x 4x 11x 7x 4x 6x 2x 4x 8x 3x 4x 8x 4x | /**
* Authentication API
*/
import apiClient from './client';
export interface LoginCredentials {
email: string;
password: string;
}
import { UserRole } from '../types';
export interface QuotaOverage {
id: number;
quota_type: string;
display_name: string;
current_usage: number;
allowed_limit: number;
overage_amount: number;
days_remaining: number;
grace_period_ends_at: string;
}
export interface MasqueradeStackEntry {
user_id: number;
username: string;
role: UserRole;
business_id?: number;
business_subdomain?: string;
}
export interface LoginResponse {
// Regular login success
access?: string;
refresh?: string;
user?: {
id: number;
username: string;
email: string;
name: string;
role: UserRole;
avatar_url?: string;
email_verified?: boolean;
is_staff: boolean;
is_superuser: boolean;
business?: number;
business_name?: string;
business_subdomain?: string;
};
masquerade_stack?: MasqueradeStackEntry[];
// MFA challenge response
mfa_required?: boolean;
user_id?: number;
mfa_methods?: ('SMS' | 'TOTP' | 'BACKUP')[];
phone_last_4?: string;
}
export interface User {
id: number;
username: string;
email: string;
name: string;
role: UserRole;
avatar_url?: string;
email_verified?: boolean;
is_staff: boolean;
is_superuser: boolean;
business?: number;
business_name?: string;
business_subdomain?: string;
permissions?: Record<string, boolean>;
can_invite_staff?: boolean;
can_access_tickets?: boolean;
quota_overages?: QuotaOverage[];
}
/**
* Login user
*/
export const login = async (credentials: LoginCredentials): Promise<LoginResponse> => {
const response = await apiClient.post<LoginResponse>('/auth/login/', credentials);
return response.data;
};
/**
* Logout user
*/
export const logout = async (): Promise<void> => {
await apiClient.post('/auth/logout/');
};
/**
* Get current user
*/
export const getCurrentUser = async (): Promise<User> => {
const response = await apiClient.get<User>('/auth/me/');
return response.data;
};
/**
* Refresh access token
*/
export const refreshToken = async (refresh: string): Promise<{ access: string }> => {
const response = await apiClient.post('/auth/refresh/', { refresh });
return response.data;
};
/**
* Masquerade as another user (hijack)
*/
export const masquerade = async (
user_pk: number,
hijack_history?: MasqueradeStackEntry[]
): Promise<LoginResponse> => {
const response = await apiClient.post<LoginResponse>(
'/auth/hijack/acquire/',
{ user_pk, hijack_history }
);
return response.data;
};
/**
* Stop masquerading and return to previous user
*/
export const stopMasquerade = async (
masquerade_stack: MasqueradeStackEntry[]
): Promise<LoginResponse> => {
const response = await apiClient.post<LoginResponse>(
'/auth/hijack/release/',
{ masquerade_stack }
);
return response.data;
};
|