@tshifhiwa/ohrm-ui-automation-framework
Version:
Playwright and TypeScript–based test automation framework for validating core UI features and workflows of the OrangeHRM demo application.
174 lines (156 loc) • 5.64 kB
text/typescript
import SecretKeyFileManager from "./secretFileManager.js";
import SecretKeyAuditManager from "./secretAuditManager.js";
import SystemInfo from "../../../../utils/shared/systemInfo.js";
import CryptoConstants from "../types/cryptoConstants.js";
import type {
EncryptionEntry,
EncryptionTrackingFile,
EncryptionStats,
} from "../types/encryptionTracking.types.js";
import ErrorHandler from "../../../errorHandling/errorHandler.js";
import logger from "../../../logger/loggerManager.js";
export default class EncryptionTrackerManager {
/**
* Records an encryption operation.
*/
public static async trackEncryption(
keyName: string,
environment: string,
options: {
variablesEncrypted: string[];
skippedVariables?: string[];
alreadyEncrypted?: string[];
emptyVariables?: string[];
performedBy?: string;
durationMs: number;
},
): Promise<void> {
try {
const {
variablesEncrypted,
skippedVariables = [],
alreadyEncrypted = [],
emptyVariables = [],
performedBy = SystemInfo.getCurrentUsername(),
durationMs,
} = options;
const encryptionFile = await this.loadEncryptionTracking();
const now = new Date().toISOString();
const encryptionEntry: EncryptionEntry = {
timestamp: now,
keyName,
environment,
variablesEncrypted,
totalVariables: variablesEncrypted.length,
skippedVariables,
alreadyEncrypted,
emptyVariables,
performedBy,
durationMs,
};
encryptionFile.encryptions.unshift(encryptionEntry);
encryptionFile.totalEncryptions++;
encryptionFile.lastEncryption = now;
// Keep only last 10000 entries
if (encryptionFile.encryptions.length > CryptoConstants.MAX_AUDIT_ENTRIES) {
encryptionFile.encryptions = encryptionFile.encryptions.slice(
0,
CryptoConstants.MAX_AUDIT_ENTRIES,
);
}
await this.saveEncryptionTracking(encryptionFile);
// Also log to audit
await SecretKeyAuditManager.logAudit({
action: "encrypt",
keyName,
environment,
status: "success",
details: `Encrypted ${variablesEncrypted.length} variable(s)`,
metadata: {
totalVariables: variablesEncrypted.length,
skippedCount: skippedVariables.length + alreadyEncrypted.length + emptyVariables.length,
durationMs,
},
performedBy,
});
logger.info(
`Encryption tracked: ${variablesEncrypted.length} variable(s) encrypted by ${performedBy}`,
);
} catch (error) {
ErrorHandler.captureError(error, "trackEncryption", "Failed to track encryption operation");
// Don't throw - tracking failure shouldn't block encryption
}
}
/**
* Gets recent encryption history.
*/
public static async getEncryptionHistory(
limit?: number,
filters?: { keyName?: string; environment?: string; performedBy?: string },
): Promise<EncryptionEntry[]> {
try {
const encryptionFile = await this.loadEncryptionTracking();
let encryptions = encryptionFile.encryptions;
// Apply filters
if (filters) {
if (filters.keyName) {
encryptions = encryptions.filter((e) => e.keyName === filters.keyName);
}
if (filters.environment) {
encryptions = encryptions.filter((e) => e.environment === filters.environment);
}
if (filters.performedBy) {
encryptions = encryptions.filter((e) => e.performedBy === filters.performedBy);
}
}
return limit ? encryptions.slice(0, limit) : encryptions;
} catch (error) {
ErrorHandler.captureError(error, "getEncryptionHistory", "Failed to get encryption history");
return [];
}
}
/**
* Gets encryption statistics for a specific key.
*/
public static async getEncryptionStats(keyName: string): Promise<EncryptionStats> {
try {
const history = await this.getEncryptionHistory(undefined, { keyName });
if (history.length === 0) {
return {
totalEncryptions: 0,
totalVariablesEncrypted: 0,
};
}
const totalVariablesEncrypted = history.reduce((sum, entry) => sum + entry.totalVariables, 0);
return {
totalEncryptions: history.length,
totalVariablesEncrypted,
lastEncryption: history[0]?.timestamp,
mostRecentVariables: history[0]?.variablesEncrypted,
};
} catch (error) {
ErrorHandler.captureError(
error,
"getEncryptionStats",
`Failed to get encryption stats for key "${keyName}"`,
);
return {
totalEncryptions: 0,
totalVariablesEncrypted: 0,
};
}
}
// Private file operations
private static async loadEncryptionTracking(): Promise<EncryptionTrackingFile> {
const filePath = SecretKeyFileManager.getFilePath(CryptoConstants.ENCRYPTION_FILE);
return SecretKeyFileManager.loadJsonFile<EncryptionTrackingFile>(filePath, {
encryptions: [],
totalEncryptions: 0,
lastEncryption: new Date().toISOString(),
});
}
private static async saveEncryptionTracking(data: EncryptionTrackingFile): Promise<void> {
const filePath = SecretKeyFileManager.getFilePath(CryptoConstants.ENCRYPTION_FILE);
await SecretKeyFileManager.saveJsonFile(filePath, data);
}
}