Skip to content

Conversation

@dacsang97
Copy link
Contributor

  • Limit max height of input fields

Copilot AI review requested due to automatic review settings October 8, 2025 01:01
@sonarqubecloud
Copy link

sonarqubecloud bot commented Oct 8, 2025

Quality Gate Failed Quality Gate failed

Failed conditions
34 Security Hotspots
5.0% Duplication on New Code (required ≤ 3%)
B Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Introduces extensive domain modularization and service layer restructuring (far beyond the stated “Improve add ssl dialog” scope). Key additions include new domains (auth, backup, cluster, alerts, dashboard, modsec, logs), extraction of parsing / config logic into dedicated services, and comprehensive auth unit/integration tests.

  • Adds multiple barrel index files and DTO definitions for new domains
  • Refactors nginx/log/backup/config generation & parsing into service classes (some duplicated logic introduced)
  • Implements full auth flow with 2FA, tokens, repositories, and tests; other new complex services lack test coverage

Reviewed Changes

Copilot reviewed 141 out of 250 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
apps/api/src/domains/logs/services/log-parser.service.ts New log parsing service (access/error/modsec) logic extracted.
apps/api/src/domains/logs/logs.service.ts Refactored to consume extracted parsers and new types.
apps/api/src/domains/domains/services/nginx-config.service.ts Generates nginx configs (primary implementation).
apps/api/src/domains/backup/services/backup-operations.service.ts Backup-specific nginx config & SSL file operations (duplicates config generation).
apps/api/src/domains/backup/backup.service.ts Large service handling schedules plus (re)generation of nginx configs (duplicate logic).
apps/api/src/domains/alerts/services/alert-monitoring.service.ts Monitoring service now uses shared TIMEOUT constants.
apps/api/src/domains/alerts/services/notification.service.ts Introduces typed responses for notification sending.
apps/api/src/domains/auth/** Full auth domain (service, repo, controller, tests) with 2FA & token handling.
apps/api/src/domains/cluster/** Cluster & node sync logic added.
apps/api/src/domains/dashboard/** Dashboard stats & metrics services added.
apps/api/src/domains/modsec/** ModSecurity DTOs & barrel exports.
Various index & dto files Barrel exports / DTO structuring across new domains.

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines 77 to 82
return `
upstream ${upstreamName}_backend {
${algorithmDirectives.join('\n ')}
${algorithmDirectives.length > 0 ? '\n ' : ''}${servers}
}
`;
Copy link

Copilot AI Oct 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Upstream block generation logic (including algorithm directive insertion and server lines) is duplicated in backup-related services; centralize this builder in a shared utility to avoid divergence and ease future updates.

Copilot uses AI. Check for mistakes.
Comment on lines 255 to 265
* Generate nginx vhost configuration for a domain during backup restore
*/
async generateNginxConfigForBackup(domain: any): Promise<void> {
const configPath = path.join(
BACKUP_CONSTANTS.NGINX_SITES_AVAILABLE,
`${domain.name}.conf`
);
const enabledPath = path.join(
BACKUP_CONSTANTS.NGINX_SITES_ENABLED,
`${domain.name}.conf`
);
Copy link

Copilot AI Oct 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method reimplements nginx config generation already present in nginx-config.service, creating parallel logic that risks configuration drift; refactor to reuse the canonical generator or extract a shared builder module.

Copilot uses AI. Check for mistakes.
Comment on lines 996 to 1002
let httpServerBlock = `
server {
listen 80;
server_name ${domain.name};

include /etc/nginx/conf.d/acl-rules.conf;
include /etc/nginx/snippets/acme-challenge.conf;
Copy link

Copilot AI Oct 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another reimplementation of HTTP/HTTPS server block assembly appears here (similar logic exists in nginx-config.service and backup-operations.service); consolidate to a single shared function to avoid inconsistent directives (e.g. differing SSL cipher sets or header policies).

Copilot uses AI. Check for mistakes.
Comment on lines 8 to 12
const NGINX_ACCESS_LOG = '/var/log/nginx/access.log';
const NGINX_ERROR_LOG = '/var/log/nginx/error.log';
const MODSEC_AUDIT_LOG = '/var/log/modsec_audit.log';
const NGINX_LOG_DIR = '/var/log/nginx';

Copy link

Copilot AI Oct 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded filesystem paths reduce adaptability across environments; consider moving these to a configuration module or environment-based constants to centralize changes and enable testing with alternative paths.

Copilot uses AI. Check for mistakes.
Comment on lines 17 to 79

const execAsync = promisify(exec);

/**
* Backup Service - Contains business logic for backup operations
*/
export class BackupService {
/**
* Ensure backup directory exists
*/
async ensureBackupDir(): Promise<void> {
try {
await fs.mkdir(BACKUP_CONSTANTS.BACKUP_DIR, { recursive: true });
} catch (error) {
logger.error('Failed to create backup directory:', error);
throw new Error('Failed to create backup directory');
}
}

/**
* Reload nginx configuration
*/
async reloadNginx(): Promise<boolean> {
try {
logger.info('Testing nginx configuration...');
await execAsync('nginx -t');

logger.info('Reloading nginx...');
await execAsync('systemctl reload nginx');

logger.info('Nginx reloaded successfully');
return true;
} catch (error: any) {
logger.error('Failed to reload nginx:', error);
logger.error('Nginx test/reload output:', error.stdout || error.stderr);

try {
logger.info('Trying alternative reload method...');
await execAsync('nginx -s reload');
logger.info('Nginx reloaded successfully (alternative method)');
return true;
} catch (altError) {
logger.error('Alternative reload also failed:', altError);
return false;
}
}
}

/**
* Format bytes to human readable size
*/
formatBytes(bytes: number): string {
if (bytes === 0) return '0 B';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + ' ' + sizes[i];
}

/**
* Get all backup schedules with formatted data
*/
async getBackupSchedules(): Promise<FormattedBackupSchedule[]> {
Copy link

Copilot AI Oct 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BackupService aggregates multiple distinct responsibilities (schedule management, data aggregation, nginx config generation, import/export, SSL file handling) leading to a very large class; consider splitting into focused collaborators (e.g. ScheduleService, ConfigExportService, RestoreService) to reduce complexity and improve testability.

Suggested change
const execAsync = promisify(exec);
/**
* Backup Service - Contains business logic for backup operations
*/
export class BackupService {
/**
* Ensure backup directory exists
*/
async ensureBackupDir(): Promise<void> {
try {
await fs.mkdir(BACKUP_CONSTANTS.BACKUP_DIR, { recursive: true });
} catch (error) {
logger.error('Failed to create backup directory:', error);
throw new Error('Failed to create backup directory');
}
}
/**
* Reload nginx configuration
*/
async reloadNginx(): Promise<boolean> {
try {
logger.info('Testing nginx configuration...');
await execAsync('nginx -t');
logger.info('Reloading nginx...');
await execAsync('systemctl reload nginx');
logger.info('Nginx reloaded successfully');
return true;
} catch (error: any) {
logger.error('Failed to reload nginx:', error);
logger.error('Nginx test/reload output:', error.stdout || error.stderr);
try {
logger.info('Trying alternative reload method...');
await execAsync('nginx -s reload');
logger.info('Nginx reloaded successfully (alternative method)');
return true;
} catch (altError) {
logger.error('Alternative reload also failed:', altError);
return false;
}
}
}
/**
* Format bytes to human readable size
*/
formatBytes(bytes: number): string {
if (bytes === 0) return '0 B';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + ' ' + sizes[i];
}
/**
* Get all backup schedules with formatted data
*/
async getBackupSchedules(): Promise<FormattedBackupSchedule[]> {
import { ScheduleService } from './schedule.service';
import { ConfigExportService } from './config-export.service';
import { RestoreService } from './restore.service';
import { SSLFileService } from './ssl-file.service';
const execAsync = promisify(exec);
/**
* Backup Service - Delegates to focused collaborators for backup operations
*/
export class BackupService {
private scheduleService: ScheduleService;
private configExportService: ConfigExportService;
private restoreService: RestoreService;
private sslFileService: SSLFileService;
constructor() {
this.scheduleService = new ScheduleService();
this.configExportService = new ConfigExportService();
this.restoreService = new RestoreService();
this.sslFileService = new SSLFileService();
}
async ensureBackupDir(): Promise<void> {
await this.configExportService.ensureBackupDir();
}
async reloadNginx(): Promise<boolean> {
return await this.configExportService.reloadNginx();
}
formatBytes(bytes: number): string {
return this.configExportService.formatBytes(bytes);
}
async getBackupSchedules(): Promise<FormattedBackupSchedule[]> {
return await this.scheduleService.getBackupSchedules();
}
// ... Delegate other methods to the appropriate service
}

Copilot uses AI. Check for mistakes.
@vncloudsco vncloudsco changed the base branch from main to beta_developer October 8, 2025 01:06
@vncloudsco vncloudsco merged commit caeb0cc into TinyActive:beta_developer Oct 8, 2025
2 of 3 checks passed
vncloudsco added a commit that referenced this pull request Oct 8, 2025
* Feat: Update Features Backup & Restore (#12)

* feat: Update Features Backup & Restore

* Feat: Slave Mode (#13)

* feat: Update Features Backup & Restore

* Feat: Features update (#14)

* feat: Update software

* Features update version and update noti Change Password (#15)

* feat: Update Features Backup & Restore

* Fix frontend error (#16)

* Refactor services to use centralized API module and token storage

* Feat: Enhance Slave Mode UI with mode switch button and update node mode mutation

* feat: Improve SSLDialog layout with enhanced text wrapping for certificate fields

* refactor: replace js-cookie with localStorage for token management (#17)

* feat: add syncInterval and lastSyncHash columns to system_configs table (#18)

* feat: Update project goal description and remove security recommendation

* feat: Update project goal description and remove security recommendation

* About readme (#21)

* feat: Update project goal description and remove security recommendation

* Refactor be (#22)

* Refactor code structure for improved readability and maintainability

* style: limit max height of certificate, private key, and chain input fields (#23)

---------

Co-authored-by: SangND <dacsang97@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants