UNPKG

fortify2-js

Version:

MOST POWERFUL JavaScript Security Library! Military-grade cryptography + 19 enhanced object methods + quantum-resistant algorithms + perfect TypeScript support. More powerful than Lodash with built-in security.

332 lines (329 loc) 10.3 kB
'use strict'; /*************************************************************************** * FortifyJS - Secure Array Metadata Manager * * This file contains the metadata management system for SecureArray * * @author Nehonix * * @license MIT * * Copyright (c) 2025 Nehonix. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. ***************************************************************************** */ /** * Manages metadata for SecureArray elements */ class ArrayMetadataManager { constructor() { this.metadata = new Map(); } /** * Updates metadata for an element at the specified index */ update(index, type, isSecure, accessed = false) { const existing = this.metadata.get(index); const now = new Date(); if (existing) { existing.type = type; existing.isSecure = isSecure; if (accessed) { existing.lastAccessed = now; existing.accessCount++; } } else { this.metadata.set(index, { type, isSecure, created: now, lastAccessed: now, accessCount: accessed ? 1 : 0, index, }); } } /** * Gets metadata for an element at the specified index */ get(index) { return this.metadata.get(index); } /** * Checks if metadata exists for an element at the specified index */ has(index) { return this.metadata.has(index); } /** * Deletes metadata for an element at the specified index */ delete(index) { return this.metadata.delete(index); } /** * Gets all metadata */ getAll() { return new Map(this.metadata); } /** * Clears all metadata */ clear() { this.metadata.clear(); } /** * Gets statistics about the metadata */ getStats() { if (this.metadata.size === 0) { return { totalElements: 0, secureElements: 0, totalAccesses: 0, averageAccessCount: 0, oldestElement: null, newestElement: null, }; } let secureElements = 0; let totalAccesses = 0; let oldestElement = null; let newestElement = null; for (const metadata of this.metadata.values()) { if (metadata.isSecure) { secureElements++; } totalAccesses += metadata.accessCount; if (!oldestElement || metadata.created < oldestElement) { oldestElement = metadata.created; } if (!newestElement || metadata.created > newestElement) { newestElement = metadata.created; } } return { totalElements: this.metadata.size, secureElements, totalAccesses, averageAccessCount: totalAccesses / this.metadata.size, oldestElement, newestElement, }; } /** * Compacts metadata by removing entries for indices that no longer exist */ compact(maxIndex) { const toDelete = []; for (const index of this.metadata.keys()) { if (index >= maxIndex) { toDelete.push(index); } } for (const index of toDelete) { this.metadata.delete(index); } } /** * Shifts metadata indices when elements are inserted or removed */ shiftIndices(startIndex, shift) { const newMetadata = new Map(); for (const [index, metadata] of this.metadata.entries()) { if (index >= startIndex) { const newIndex = index + shift; if (newIndex >= 0) { metadata.index = newIndex; newMetadata.set(newIndex, metadata); } } else { newMetadata.set(index, metadata); } } this.metadata = newMetadata; } /** * Gets metadata for secure elements only */ getSecureElementsMetadata() { const secureMetadata = new Map(); for (const [index, metadata] of this.metadata.entries()) { if (metadata.isSecure) { secureMetadata.set(index, metadata); } } return secureMetadata; } /** * Gets elements that haven't been accessed recently */ getStaleElements(maxAge) { const now = new Date(); const staleIndices = []; for (const [index, metadata] of this.metadata.entries()) { const age = now.getTime() - metadata.lastAccessed.getTime(); if (age > maxAge) { staleIndices.push(index); } } return staleIndices; } /** * Gets the most frequently accessed elements */ getMostAccessedElements(limit = 10) { const elements = Array.from(this.metadata.entries()) .map(([index, metadata]) => ({ index, accessCount: metadata.accessCount, })) .sort((a, b) => b.accessCount - a.accessCount) .slice(0, limit); return elements; } /** * Gets elements by type */ getElementsByType(type) { const indices = []; for (const [index, metadata] of this.metadata.entries()) { if (metadata.type === type) { indices.push(index); } } return indices; } /** * Validates metadata integrity */ validateIntegrity() { const errors = []; const warnings = []; // Check for negative indices for (const index of this.metadata.keys()) { if (index < 0) { errors.push(`Invalid negative index: ${index}`); } } // Check for metadata consistency for (const [index, metadata] of this.metadata.entries()) { if (metadata.index !== index) { errors.push(`Index mismatch: metadata.index=${metadata.index}, key=${index}`); } if (metadata.accessCount < 0) { errors.push(`Invalid access count: ${metadata.accessCount} at index ${index}`); } if (metadata.created > new Date()) { warnings.push(`Future creation date at index ${index}`); } if (metadata.lastAccessed < metadata.created) { warnings.push(`Last accessed before creation at index ${index}`); } } return { isValid: errors.length === 0, errors, warnings, }; } /** * Exports metadata to a serializable format */ export() { return Array.from(this.metadata.entries()); } /** * Imports metadata from a serializable format */ import(data) { this.metadata.clear(); for (const [index, metadata] of data) { this.metadata.set(index, { ...metadata, created: new Date(metadata.created), lastAccessed: new Date(metadata.lastAccessed), }); } } /** * Gets the size of the metadata map */ size() { return this.metadata.size; } /** * Gets all metadata (alias for getAll) */ getAllMetadata() { return this.getAll(); } /** * Handles splice operations on metadata */ splice(start, deleteCount, insertCount) { const newMetadata = new Map(); // Copy metadata before the splice point for (const [index, metadata] of this.metadata.entries()) { if (index < start) { newMetadata.set(index, metadata); } else if (index >= start + deleteCount) { // Shift indices after the splice point const newIndex = index - deleteCount + insertCount; metadata.index = newIndex; newMetadata.set(newIndex, metadata); } // Skip metadata in the deleted range } this.metadata = newMetadata; } /** * Reverses the metadata indices */ reverse(length) { const newMetadata = new Map(); for (const [index, metadata] of this.metadata.entries()) { const newIndex = length - 1 - index; metadata.index = newIndex; newMetadata.set(newIndex, metadata); } this.metadata = newMetadata; } /** * Reorders metadata based on new index mapping */ reorder(newIndices) { const newMetadata = new Map(); for (let i = 0; i < newIndices.length; i++) { const oldIndex = newIndices[i]; const metadata = this.metadata.get(oldIndex); if (metadata) { metadata.index = i; newMetadata.set(i, metadata); } } this.metadata = newMetadata; } } exports.ArrayMetadataManager = ArrayMetadataManager; //# sourceMappingURL=metadata-manager.js.map