- Redesign the Identity module with a richer domain model. - Extend the User entity to support username, Authentik integration, activity tracking, and storage information. - Add Role and Permission domain models with many-to-many relationships. - Implement RBAC foundation using UserRole, RolePermission, and UserPermission mappings. - Add user storage quota and usage fields with default values. - Introduce Authentik identifiers and synchronization metadata. - Refactor user domain logic for role and permission management. - Update Prisma schema to support the new identity architecture. - Improve JWT authentication and permission guard integration. - Update repositories, handlers, controllers, mappers, DTOs, and Swagger configuration. - Refresh environment configuration and project dependencies.
74 lines
2.4 KiB
TypeScript
74 lines
2.4 KiB
TypeScript
import { request } from '@playwright/test';
|
|
import { env } from './env';
|
|
import { getToken } from './auth';
|
|
|
|
async function buildContext(token?: string) {
|
|
const headers: any = { 'Content-Type': 'application/json' };
|
|
if (token) headers['Authorization'] = `Bearer ${token}`;
|
|
|
|
const api = await request.newContext({ baseURL: env.BASE_URL || 'http://localhost:3000', extraHTTPHeaders: headers });
|
|
return api;
|
|
}
|
|
|
|
export async function requestGet(path: string, role: 'owner' | 'admin' | 'employee' | null = 'admin', opts: any = {}) {
|
|
const token = role ? await getToken(role) : undefined;
|
|
const api = await buildContext(token);
|
|
try {
|
|
const res = await api.get(path, opts);
|
|
const body = await parseResponseSafe(res);
|
|
return { status: res.status(), body, headers: res.headers() };
|
|
} finally {
|
|
await api.dispose();
|
|
}
|
|
}
|
|
|
|
export async function requestPost(path: string, role: 'owner' | 'admin' | 'employee' | null = 'admin', data?: any, opts: any = {}) {
|
|
const token = role ? await getToken(role) : undefined;
|
|
const api = await buildContext(token);
|
|
try {
|
|
const res = await api.post(path, { data, ...opts });
|
|
const body = await parseResponseSafe(res);
|
|
return { status: res.status(), body, headers: res.headers() };
|
|
} finally {
|
|
await api.dispose();
|
|
}
|
|
}
|
|
|
|
export async function requestPatch(path: string, role: 'owner' | 'admin' | 'employee' | null = 'admin', data?: any, opts: any = {}) {
|
|
const token = role ? await getToken(role) : undefined;
|
|
const api = await buildContext(token);
|
|
try {
|
|
const res = await api.patch(path, { data, ...opts });
|
|
const body = await parseResponseSafe(res);
|
|
return { status: res.status(), body, headers: res.headers() };
|
|
} finally {
|
|
await api.dispose();
|
|
}
|
|
}
|
|
|
|
export async function requestDelete(path: string, role: 'owner' | 'admin' | 'employee' | null = 'admin', opts: any = {}) {
|
|
const token = role ? await getToken(role) : undefined;
|
|
const api = await buildContext(token);
|
|
try {
|
|
const res = await api.delete(path, opts);
|
|
const body = await parseResponseSafe(res);
|
|
return { status: res.status(), body, headers: res.headers() };
|
|
} finally {
|
|
await api.dispose();
|
|
}
|
|
}
|
|
|
|
async function parseResponseSafe(res: any) {
|
|
const ct = res.headers()['content-type'] || '';
|
|
try {
|
|
if (ct.includes('application/json')) return await res.json();
|
|
return await res.text();
|
|
} catch (e) {
|
|
try {
|
|
return await res.text();
|
|
} catch (e2) {
|
|
return null;
|
|
}
|
|
}
|
|
}
|