feat: implement account settings and API tokens management
- Added SettingsComponent for user profile management, including display name and password change functionality. - Introduced TokensComponent for managing API tokens, including creation and revocation. - Created LayoutComponent for consistent application layout with navigation and user information. - Established main application structure in index.html and main.ts. - Integrated Tailwind CSS for styling and responsive design. - Configured TypeScript settings for strict type checking and module resolution.
This commit is contained in:
109
ts/api/handlers/audit.api.ts
Normal file
109
ts/api/handlers/audit.api.ts
Normal file
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* Audit API handlers
|
||||
*/
|
||||
|
||||
import type { IApiContext, IApiResponse } from '../router.ts';
|
||||
import { PermissionService } from '../../services/permission.service.ts';
|
||||
import { AuditLog } from '../../models/auditlog.ts';
|
||||
import type { TAuditAction, TAuditResourceType } from '../../interfaces/audit.interfaces.ts';
|
||||
|
||||
export class AuditApi {
|
||||
private permissionService: PermissionService;
|
||||
|
||||
constructor(permissionService: PermissionService) {
|
||||
this.permissionService = permissionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /api/v1/audit
|
||||
*/
|
||||
public async query(ctx: IApiContext): Promise<IApiResponse> {
|
||||
if (!ctx.actor?.userId) {
|
||||
return { status: 401, body: { error: 'Authentication required' } };
|
||||
}
|
||||
|
||||
try {
|
||||
// Parse query parameters
|
||||
const organizationId = ctx.url.searchParams.get('organizationId') || undefined;
|
||||
const repositoryId = ctx.url.searchParams.get('repositoryId') || undefined;
|
||||
const resourceType = ctx.url.searchParams.get('resourceType') as TAuditResourceType | undefined;
|
||||
const actionsParam = ctx.url.searchParams.get('actions');
|
||||
const actions = actionsParam ? (actionsParam.split(',') as TAuditAction[]) : undefined;
|
||||
const success = ctx.url.searchParams.has('success')
|
||||
? ctx.url.searchParams.get('success') === 'true'
|
||||
: undefined;
|
||||
const startDateParam = ctx.url.searchParams.get('startDate');
|
||||
const endDateParam = ctx.url.searchParams.get('endDate');
|
||||
const startDate = startDateParam ? new Date(startDateParam) : undefined;
|
||||
const endDate = endDateParam ? new Date(endDateParam) : undefined;
|
||||
const limit = parseInt(ctx.url.searchParams.get('limit') || '100', 10);
|
||||
const offset = parseInt(ctx.url.searchParams.get('offset') || '0', 10);
|
||||
|
||||
// Check permissions
|
||||
// Users can view audit logs for:
|
||||
// 1. Their own actions (actorId = userId)
|
||||
// 2. Organizations they manage
|
||||
// 3. System admins can view all
|
||||
|
||||
let actorId: string | undefined;
|
||||
|
||||
if (ctx.actor.user?.isSystemAdmin) {
|
||||
// System admins can see all
|
||||
actorId = ctx.url.searchParams.get('actorId') || undefined;
|
||||
} else if (organizationId) {
|
||||
// Check if user can manage this org
|
||||
const canManage = await this.permissionService.canManageOrganization(
|
||||
ctx.actor.userId,
|
||||
organizationId
|
||||
);
|
||||
if (!canManage) {
|
||||
// User can only see their own actions in this org
|
||||
actorId = ctx.actor.userId;
|
||||
}
|
||||
} else {
|
||||
// Non-admins without org filter can only see their own actions
|
||||
actorId = ctx.actor.userId;
|
||||
}
|
||||
|
||||
const result = await AuditLog.query({
|
||||
actorId,
|
||||
organizationId,
|
||||
repositoryId,
|
||||
resourceType,
|
||||
action: actions,
|
||||
success,
|
||||
startDate,
|
||||
endDate,
|
||||
limit,
|
||||
offset,
|
||||
});
|
||||
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
logs: result.logs.map((log) => ({
|
||||
id: log.id,
|
||||
actorId: log.actorId,
|
||||
actorType: log.actorType,
|
||||
action: log.action,
|
||||
resourceType: log.resourceType,
|
||||
resourceId: log.resourceId,
|
||||
resourceName: log.resourceName,
|
||||
organizationId: log.organizationId,
|
||||
repositoryId: log.repositoryId,
|
||||
success: log.success,
|
||||
errorCode: log.errorCode,
|
||||
timestamp: log.timestamp,
|
||||
metadata: log.metadata,
|
||||
})),
|
||||
total: result.total,
|
||||
limit,
|
||||
offset,
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('[AuditApi] Query error:', error);
|
||||
return { status: 500, body: { error: 'Failed to query audit logs' } };
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user