- 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.
198 lines
5.1 KiB
TypeScript
198 lines
5.1 KiB
TypeScript
/**
|
|
* AuditService - Centralized audit logging
|
|
*/
|
|
|
|
import type { TAuditAction, TAuditResourceType } from '../interfaces/audit.interfaces.ts';
|
|
import { AuditLog } from '../models/index.ts';
|
|
|
|
export interface IAuditContext {
|
|
actorId?: string;
|
|
actorType?: 'user' | 'api_token' | 'system' | 'anonymous';
|
|
actorTokenId?: string;
|
|
actorIp?: string;
|
|
actorUserAgent?: string;
|
|
organizationId?: string;
|
|
repositoryId?: string;
|
|
}
|
|
|
|
export class AuditService {
|
|
private context: IAuditContext;
|
|
|
|
constructor(context: IAuditContext = {}) {
|
|
this.context = context;
|
|
}
|
|
|
|
/**
|
|
* Create a new audit service with context
|
|
*/
|
|
public static withContext(context: IAuditContext): AuditService {
|
|
return new AuditService(context);
|
|
}
|
|
|
|
/**
|
|
* Log an audit event
|
|
*/
|
|
public async log(
|
|
action: TAuditAction,
|
|
resourceType: TAuditResourceType,
|
|
options: {
|
|
resourceId?: string;
|
|
resourceName?: string;
|
|
organizationId?: string;
|
|
repositoryId?: string;
|
|
metadata?: Record<string, unknown>;
|
|
success?: boolean;
|
|
errorCode?: string;
|
|
errorMessage?: string;
|
|
durationMs?: number;
|
|
} = {}
|
|
): Promise<AuditLog> {
|
|
return await AuditLog.log({
|
|
actorId: this.context.actorId,
|
|
actorType: this.context.actorType,
|
|
actorTokenId: this.context.actorTokenId,
|
|
actorIp: this.context.actorIp,
|
|
actorUserAgent: this.context.actorUserAgent,
|
|
action,
|
|
resourceType,
|
|
resourceId: options.resourceId,
|
|
resourceName: options.resourceName,
|
|
organizationId: options.organizationId || this.context.organizationId,
|
|
repositoryId: options.repositoryId || this.context.repositoryId,
|
|
metadata: options.metadata,
|
|
success: options.success,
|
|
errorCode: options.errorCode,
|
|
errorMessage: options.errorMessage,
|
|
durationMs: options.durationMs,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Log a successful action
|
|
*/
|
|
public async logSuccess(
|
|
action: TAuditAction,
|
|
resourceType: TAuditResourceType,
|
|
resourceId?: string,
|
|
resourceName?: string,
|
|
metadata?: Record<string, unknown>
|
|
): Promise<AuditLog> {
|
|
return await this.log(action, resourceType, {
|
|
resourceId,
|
|
resourceName,
|
|
metadata,
|
|
success: true,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Log a failed action
|
|
*/
|
|
public async logFailure(
|
|
action: TAuditAction,
|
|
resourceType: TAuditResourceType,
|
|
errorCode: string,
|
|
errorMessage: string,
|
|
resourceId?: string,
|
|
metadata?: Record<string, unknown>
|
|
): Promise<AuditLog> {
|
|
return await this.log(action, resourceType, {
|
|
resourceId,
|
|
metadata,
|
|
success: false,
|
|
errorCode,
|
|
errorMessage,
|
|
});
|
|
}
|
|
|
|
// Convenience methods for common actions
|
|
|
|
public async logUserLogin(userId: string, success: boolean, errorMessage?: string): Promise<AuditLog> {
|
|
if (success) {
|
|
return await this.logSuccess('USER_LOGIN', 'user', userId);
|
|
}
|
|
return await this.logFailure('USER_LOGIN', 'user', 'LOGIN_FAILED', errorMessage || 'Login failed', userId);
|
|
}
|
|
|
|
public async logUserLogout(userId: string): Promise<AuditLog> {
|
|
return await this.logSuccess('USER_LOGOUT', 'user', userId);
|
|
}
|
|
|
|
public async logTokenCreated(tokenId: string, tokenName: string): Promise<AuditLog> {
|
|
return await this.logSuccess('TOKEN_CREATED', 'api_token', tokenId, tokenName);
|
|
}
|
|
|
|
public async logTokenRevoked(tokenId: string, tokenName: string): Promise<AuditLog> {
|
|
return await this.logSuccess('TOKEN_REVOKED', 'api_token', tokenId, tokenName);
|
|
}
|
|
|
|
public async logPackagePublished(
|
|
packageId: string,
|
|
packageName: string,
|
|
version: string,
|
|
organizationId: string,
|
|
repositoryId: string
|
|
): Promise<AuditLog> {
|
|
return await this.log('PACKAGE_PUBLISHED', 'package', {
|
|
resourceId: packageId,
|
|
resourceName: packageName,
|
|
organizationId,
|
|
repositoryId,
|
|
metadata: { version },
|
|
success: true,
|
|
});
|
|
}
|
|
|
|
public async logPackageDownloaded(
|
|
packageId: string,
|
|
packageName: string,
|
|
version: string,
|
|
organizationId: string,
|
|
repositoryId: string
|
|
): Promise<AuditLog> {
|
|
return await this.log('PACKAGE_DOWNLOADED', 'package', {
|
|
resourceId: packageId,
|
|
resourceName: packageName,
|
|
organizationId,
|
|
repositoryId,
|
|
metadata: { version },
|
|
success: true,
|
|
});
|
|
}
|
|
|
|
public async logOrganizationCreated(orgId: string, orgName: string): Promise<AuditLog> {
|
|
return await this.logSuccess('ORGANIZATION_CREATED', 'organization', orgId, orgName);
|
|
}
|
|
|
|
public async logRepositoryCreated(
|
|
repoId: string,
|
|
repoName: string,
|
|
organizationId: string
|
|
): Promise<AuditLog> {
|
|
return await this.log('REPOSITORY_CREATED', 'repository', {
|
|
resourceId: repoId,
|
|
resourceName: repoName,
|
|
organizationId,
|
|
success: true,
|
|
});
|
|
}
|
|
|
|
public async logPermissionChanged(
|
|
resourceType: TAuditResourceType,
|
|
resourceId: string,
|
|
targetUserId: string,
|
|
oldRole: string | null,
|
|
newRole: string | null
|
|
): Promise<AuditLog> {
|
|
return await this.log('PERMISSION_CHANGED', resourceType, {
|
|
resourceId,
|
|
metadata: {
|
|
targetUserId,
|
|
oldRole,
|
|
newRole,
|
|
},
|
|
success: true,
|
|
});
|
|
}
|
|
}
|