Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions dlp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Real-Time Data Loss Prevention (DLP)

## Overview
This module provides real-time DLP for outgoing data in ExpenseFlow. It scans API responses and exports for sensitive information and enforces policies (block, alert, log).

## Components
- `dlp-engine.js`: Core detection and policy evaluation
- `dlp-middleware.js`: Express middleware for outgoing responses
- `dlp-config.js`: Patterns and policies configuration
- `dlp-logger.js`: Audit trail for DLP events
- `dlp-utils.js`: Helper functions (masking, etc.)
- `dlp-test.js`: Unit tests

## Usage
1. Add `dlp-middleware` to your Express routes.
2. Configure patterns and policies in `dlp-config.js`.
3. Check `dlp-audit.log` for DLP events.

## Extending
- Add new patterns/policies in `dlp-config.js`.
- Integrate with alerting systems as needed.
17 changes: 17 additions & 0 deletions dlp/dlp-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// DLP Configuration: Patterns and policies
// ...existing code...

module.exports = {
patterns: [
{ type: 'email', regex: '[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+', severity: 'high' },
{ type: 'ssn', regex: '\b\d{3}-\d{2}-\d{4}\b', severity: 'high' },
{ type: 'credit_card', regex: '\b(?:\d[ -]*?){13,16}\b', severity: 'high' },
{ type: 'phone', regex: '\b\d{3}[-.\s]?\d{3}[-.\s]?\d{4}\b', severity: 'medium' },
// Add more patterns as needed
],
policies: [
{ types: ['email', 'ssn', 'credit_card'], action: 'block', message: 'Sensitive data detected. Action blocked.' },
{ types: ['phone'], action: 'alert', message: 'Phone number detected. Alert logged.' },
// Add more policies as needed
],
};
43 changes: 43 additions & 0 deletions dlp/dlp-engine.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// DLP Engine: Core detection and policy evaluation
// ...existing code...

class DLPEngine {
constructor(config) {
this.config = config;
this.patterns = config.patterns || [];
this.policies = config.policies || [];
}

scanData(data) {
let findings = [];
for (const pattern of this.patterns) {
const regex = new RegExp(pattern.regex, 'gi');
if (regex.test(data)) {
findings.push({
type: pattern.type,
match: data.match(regex),
severity: pattern.severity || 'medium',
});
}
}
return findings;
}

evaluatePolicies(findings) {
let actions = [];
for (const policy of this.policies) {
for (const finding of findings) {
if (policy.types.includes(finding.type)) {
actions.push({
action: policy.action,
finding,
message: policy.message || 'Policy violation detected',
});
}
}
}
return actions;
}
}

module.exports = DLPEngine;
15 changes: 15 additions & 0 deletions dlp/dlp-logger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// DLP Logger: Audit trail for DLP events
// ...existing code...
const fs = require('fs');
const path = require('path');

const LOG_FILE = path.join(__dirname, 'dlp-audit.log');

function logDLPEvent(event) {
const entry = `${new Date().toISOString()} | ${event.action} | ${event.finding.type} | ${event.finding.match} | ${event.message}\n`;
fs.appendFile(LOG_FILE, entry, err => {
if (err) console.error('DLP Logger error:', err);
});
}

module.exports = logDLPEvent;
29 changes: 29 additions & 0 deletions dlp/dlp-middleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// DLP Middleware: Intercepts outgoing responses
// ...existing code...

const DLPEngine = require('./dlp-engine');
const dlpConfig = require('./dlp-config');
const logDLPEvent = require('./dlp-logger');

const dlpEngine = new DLPEngine(dlpConfig);

function dlpMiddleware(req, res, next) {
const originalSend = res.send;
res.send = function (body) {
const findings = dlpEngine.scanData(typeof body === 'string' ? body : JSON.stringify(body));
const actions = dlpEngine.evaluatePolicies(findings);
actions.forEach(action => logDLPEvent(action));
if (actions.some(a => a.action === 'block')) {
res.status(403);
return originalSend.call(this, { error: 'DLP policy violation', details: actions });
}
if (actions.some(a => a.action === 'alert')) {
// Log or alert (implementation below)
console.log('DLP Alert:', actions);
}
return originalSend.call(this, body);
};
next();
}

module.exports = dlpMiddleware;
25 changes: 25 additions & 0 deletions dlp/dlp-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// DLP Test: Unit tests for DLP engine
// ...existing code...

const DLPEngine = require('./dlp-engine');
const dlpConfig = require('./dlp-config');

const engine = new DLPEngine(dlpConfig);

function testScanData() {
const testData = 'User email: test@example.com, SSN: 123-45-6789, Card: 4111 1111 1111 1111';
const findings = engine.scanData(testData);
console.log('Findings:', findings);
}

function testEvaluatePolicies() {
const findings = [
{ type: 'email', match: ['test@example.com'], severity: 'high' },
{ type: 'ssn', match: ['123-45-6789'], severity: 'high' },
];
const actions = engine.evaluatePolicies(findings);
console.log('Actions:', actions);
}

testScanData();
testEvaluatePolicies();
15 changes: 15 additions & 0 deletions dlp/dlp-utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// DLP Utilities: Helper functions for sensitive data detection
// ...existing code...

function maskSensitiveData(data, patterns) {
let masked = data;
for (const pattern of patterns) {
const regex = new RegExp(pattern.regex, 'gi');
masked = masked.replace(regex, '[MASKED]');
}
return masked;
}

module.exports = {
maskSensitiveData,
};
91 changes: 91 additions & 0 deletions portfolio-rebalancer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// Smart Investment Portfolio Rebalancer
// Monitors portfolio allocations, suggests optimal rebalancing, and automates trades

class Portfolio {
constructor(assets = []) {
this.assets = assets; // [{symbol, allocation, value}]
}

getTotalValue() {
return this.assets.reduce((sum, asset) => sum + asset.value, 0);
}

getAllocations() {
const total = this.getTotalValue();
return this.assets.map(asset => ({
symbol: asset.symbol,
allocation: asset.value / total
}));
}

updateAsset(symbol, value) {
const asset = this.assets.find(a => a.symbol === symbol);
if (asset) asset.value = value;
}

addAsset(symbol, value) {
this.assets.push({symbol, value, allocation: 0});
}
}

class Rebalancer {
constructor(targetAllocations) {
this.targetAllocations = targetAllocations; // {symbol: targetPercent}
}

suggestRebalance(portfolio) {
const allocations = portfolio.getAllocations();
const total = portfolio.getTotalValue();
let actions = [];
allocations.forEach(asset => {
const target = this.targetAllocations[asset.symbol] || 0;
const diff = target - asset.allocation;
if (Math.abs(diff) > 0.01) {
actions.push({
symbol: asset.symbol,
action: diff > 0 ? 'buy' : 'sell',
amount: Math.abs(diff) * total
});
}
});
return actions;
}

automateTrades(portfolio, executeTrade) {
const actions = this.suggestRebalance(portfolio);
actions.forEach(({symbol, action, amount}) => {
executeTrade(symbol, action, amount);
});
}
}

// Example trade executor
function executeTrade(symbol, action, amount) {
console.log(`Executing ${action} of ${amount} for ${symbol}`);
// Integrate with brokerage API here
}

// Portfolio risk analysis utility
function analyzeRisk(portfolio) {
const allocations = portfolio.getAllocations();
let riskScore = 0;
allocations.forEach(asset => {
// Example: higher allocation to volatile assets increases risk
if (asset.symbol === 'TSLA') riskScore += asset.allocation * 2;
else riskScore += asset.allocation;
});
return riskScore;
}

// Portfolio performance tracker
function trackPerformance(portfolio, historicalValues) {
// historicalValues: [{date, values: {symbol: value}}]
return historicalValues.map(entry => {
const total = Object.values(entry.values).reduce((sum, v) => sum + v, 0);
return { date: entry.date, totalValue: total };
});
}

module.exports = { Portfolio, Rebalancer, executeTrade };
module.exports.analyzeRisk = analyzeRisk;
module.exports.trackPerformance = trackPerformance;
16 changes: 16 additions & 0 deletions portfolio-rebalancer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// README.md
# Smart Investment Portfolio Rebalancer

This tool monitors investment portfolio allocations, suggests optimal rebalancing actions, and automates trades based on user preferences and market conditions.

## Modules
- portfolio-data-model.js: Portfolio structure and asset management
- allocation-monitor.js: Allocation drift detection
- rebalancing-strategy.js: Rebalancing algorithms
- trade-automation.js: Trade execution
- user-preferences.js: User settings
- market-data.js: Market price simulation
- portfolio-ui.js: CLI demo

## Usage
Run portfolio-ui.js to see a demo of the rebalancer in action.
28 changes: 28 additions & 0 deletions portfolio-rebalancer/allocation-monitor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// allocation-monitor.js
// Monitors portfolio allocations and detects drift from target allocations

const Portfolio = require('./portfolio-data-model');

class AllocationMonitor {
constructor(portfolio) {
this.portfolio = portfolio;
}

getDriftReport() {
const allocations = this.portfolio.getAllocations();
return allocations.map(asset => ({
symbol: asset.symbol,
currentAllocation: asset.allocation,
targetAllocation: asset.targetAllocation,
drift: asset.allocation - asset.targetAllocation
}));
}

isRebalancingNeeded(threshold = 0.02) {
// threshold: minimum drift to trigger rebalancing (e.g., 2%)
const report = this.getDriftReport();
return report.some(asset => Math.abs(asset.drift) > threshold);
}
}

module.exports = AllocationMonitor;
30 changes: 30 additions & 0 deletions portfolio-rebalancer/market-data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// market-data.js
// Fetches and updates market data for assets

class MarketData {
constructor() {
this.data = {};
}

updateMarketData(symbol, price) {
this.data[symbol] = price;
}

getMarketPrice(symbol) {
return this.data[symbol];
}

getAllMarketData() {
return this.data;
}

fetchMarketData(symbols) {
// Placeholder: Simulate fetching market prices
symbols.forEach(symbol => {
this.data[symbol] = Math.random() * 100 + 50; // Random price between 50-150
});
return this.data;
}
}

module.exports = MarketData;
46 changes: 46 additions & 0 deletions portfolio-rebalancer/portfolio-data-model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// portfolio-data-model.js
// Smart Investment Portfolio Rebalancer - Portfolio Data Model
// Handles portfolio structure, asset classes, and user holdings

class Portfolio {
constructor(userId, assets = []) {
this.userId = userId;
this.assets = assets; // [{ symbol, allocation, currentValue, targetAllocation }]
}

addAsset(symbol, allocation, currentValue, targetAllocation) {
this.assets.push({ symbol, allocation, currentValue, targetAllocation });
}

updateAsset(symbol, allocation, currentValue, targetAllocation) {
const asset = this.assets.find(a => a.symbol === symbol);
if (asset) {
asset.allocation = allocation;
asset.currentValue = currentValue;
asset.targetAllocation = targetAllocation;
}
}

removeAsset(symbol) {
this.assets = this.assets.filter(a => a.symbol !== symbol);
}

getTotalValue() {
return this.assets.reduce((sum, asset) => sum + asset.currentValue, 0);
}

getAsset(symbol) {
return this.assets.find(a => a.symbol === symbol);
}

getAllocations() {
const total = this.getTotalValue();
return this.assets.map(asset => ({
symbol: asset.symbol,
allocation: asset.currentValue / total,
targetAllocation: asset.targetAllocation
}));
}
}

module.exports = Portfolio;
Loading