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
14 changes: 14 additions & 0 deletions dashboard/admin.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Zero-Trust Admin Dashboard</title>
<link rel="stylesheet" href="admin.css">
</head>
<body>
<h1>Admin Dashboard</h1>
<div id="users"></div>
<div id="policies"></div>
<script src="admin.js"></script>
</body>
</html>
8 changes: 8 additions & 0 deletions dashboard/admin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Admin Dashboard JS
fetch('/api/admin/users').then(r => r.json()).then(users => {
document.getElementById('users').innerHTML = '<h2>Users</h2>' + users.map(u => `<div>${u.id}: ${u.role}</div>`).join('');
});
fetch('/api/admin/policies').then(r => r.json()).then(policies => {
document.getElementById('policies').innerHTML = '<h2>Policies</h2>' + policies.map(p => `<div>${p.endpoint}: maxRisk=${p.maxRisk}</div>`).join('');
});
// ...more dashboard features...
19 changes: 19 additions & 0 deletions middleware/policy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Dynamic Policy Enforcement Middleware
const { getPolicyForEndpoint } = require('../models/policy');

module.exports = async function policyMiddleware(req, res, next) {
const endpoint = req.path;
const user = req.user;
const riskScore = req.riskScore;
const policy = await getPolicyForEndpoint(endpoint, user.role);
if (!policy) {
return res.status(403).json({ error: 'No policy for endpoint' });
}
// Dynamic enforcement: check risk, context, etc.
if (riskScore > policy.maxRisk) {
return res.status(403).json({ error: 'Access denied: high risk' });
}
// Additional contextual checks (time, geo, device, etc.)
// ...
next();
}
26 changes: 26 additions & 0 deletions middleware/zeroTrustAuth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Zero-Trust Continuous Authentication Middleware
const { getSessionByToken } = require('../models/session');
const { getUserById } = require('../models/user');
const riskEngine = require('../risk/riskEngine');

module.exports = async function zeroTrustAuth(req, res, next) {
const token = req.headers['authorization'];
if (!token) {
return res.status(401).json({ error: 'Missing auth token' });
}
const session = await getSessionByToken(token);
if (!session) {
return res.status(401).json({ error: 'Invalid session' });
}
const user = await getUserById(session.userId);
if (!user) {
return res.status(401).json({ error: 'User not found' });
}
// Continuous authentication: check device, biometrics, etc. (placeholder)
// Risk analysis
const riskScore = await riskEngine.calculateRisk(req, user, session);
req.user = user;
req.session = session;
req.riskScore = riskScore;
next();
}
19 changes: 19 additions & 0 deletions middleware/zeroTrustPolicy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Zero-Trust Dynamic Policy Enforcement Middleware
const { getPolicyForEndpoint } = require('../models/policy');

module.exports = async function zeroTrustPolicy(req, res, next) {
const endpoint = req.path;
const user = req.user;
const riskScore = req.riskScore;
const policy = await getPolicyForEndpoint(endpoint, user.role);
if (!policy) {
return res.status(403).json({ error: 'No policy for endpoint' });
}
// Dynamic enforcement: check risk, context, etc.
if (riskScore > policy.maxRisk) {
return res.status(403).json({ error: 'Access denied: high risk' });
}
// Additional contextual checks (time, geo, device, etc.)
// ...
next();
}
11 changes: 11 additions & 0 deletions models/policy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Policy Model
const policies = [
{ endpoint: '/api/transfer', role: 'admin', maxRisk: 5 },
{ endpoint: '/api/transfer', role: 'user', maxRisk: 2 }
];

async function getPolicyForEndpoint(endpoint, role) {
return policies.find(p => p.endpoint === endpoint && p.role === role);
}

module.exports = { getPolicyForEndpoint };
19 changes: 19 additions & 0 deletions public/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Real-Time Payment Anomaly Detection

This module provides a streaming analytics engine with unsupervised ML (KMeans) for real-time fraud detection in payment systems. It includes:
- Streaming transaction ingestion
- Unsupervised anomaly detection
- Automated defense actions
- Modular dashboard UI

## Usage
Open `fraud-dashboard.html` in your browser and click "Start Monitoring" to view real-time alerts and defense actions.

## Files
- fraud-ml-engine.js
- fraud-stream-connector.js
- fraud-defense-actions.js
- fraud-dashboard.js
- fraud-dashboard.html
- fraud-dashboard.css
- fraud-utils.js
202 changes: 202 additions & 0 deletions public/fraud-ml-engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,142 @@ class FraudMLEngine {
getDefenseActions() {
return this.defenseActions;
}
/**
* FraudMLEngine: Streaming analytics engine for AI-powered fraud detection
* Supports KMeans and DBSCAN clustering, online learning, and outlier scoring.
* Author: Ayaanshaikh12243
*/
class FraudMLEngine {
constructor(windowSize = 1000, clusterCount = 3) {
this.windowSize = windowSize;
this.clusterCount = clusterCount;
this.transactions = [];
this.model = null;
this.dbscanModel = null;
this.alerts = [];
this.defenseActions = [];
this.featureExtractor = new FeatureExtractor();
this.onlineLearning = true;
this.outlierScores = [];
this.modelType = 'kmeans'; // or 'dbscan'
}

/**
* Ingest a new transaction and update models
*/
ingest(transaction) {
this.transactions.push(transaction);
if (this.transactions.length > this.windowSize) this.transactions.shift();
if (this.onlineLearning) this._updateModel();
this._detectAnomaly(transaction);
this._updateOutlierScores(transaction);
}

/**
* Update clustering models (KMeans, DBSCAN)
*/
_updateModel() {
if (this.transactions.length < 10) return;
const features = this.transactions.map(tx => this.featureExtractor.extract(tx));
if (this.modelType === 'kmeans') {
this.model = KMeans.fit(features, this.clusterCount);
} else {
this.dbscanModel = DBSCAN.fit(features, 0.5, 5);
}
}

/**
* Detect anomaly using selected model
*/
_detectAnomaly(transaction) {
if (this.modelType === 'kmeans' && this.model) {
const feature = this.featureExtractor.extract(transaction);
const cluster = this.model.predict([feature])[0];
if (cluster === this.model.anomalyCluster) {
this._triggerAlert(transaction, 'KMeans anomaly');
this._triggerDefense(transaction, 'block');
}
} else if (this.modelType === 'dbscan' && this.dbscanModel) {
const feature = this.featureExtractor.extract(transaction);
const label = this.dbscanModel.predict([feature])[0];
if (label === -1) {
this._triggerAlert(transaction, 'DBSCAN outlier');
this._triggerDefense(transaction, 'escalate');
}
}
}

/**
* Update outlier scores for visualization and audit
*/
_updateOutlierScores(transaction) {
const feature = this.featureExtractor.extract(transaction);
let score = 0;
if (this.modelType === 'kmeans' && this.model) {
score = KMeans.outlierScore(feature, this.model);
} else if (this.modelType === 'dbscan' && this.dbscanModel) {
score = DBSCAN.outlierScore(feature, this.dbscanModel);
}
this.outlierScores.push({ id: transaction.id, score });
if (this.outlierScores.length > this.windowSize) this.outlierScores.shift();
}

/**
* Trigger alert for detected anomaly
*/
_triggerAlert(transaction, reason = 'anomaly') {
this.alerts.push({
transaction,
timestamp: Date.now(),
type: 'anomaly',
reason,
message: 'Potential fraud detected: ' + reason
});
}

/**
* Trigger defense action for detected anomaly
*/
_triggerDefense(transaction, action = 'block') {
this.defenseActions.push({
transaction,
timestamp: Date.now(),
action,
message: `Transaction ${action}ed due to anomaly`
});
}

/**
* Get all alerts
*/
getAlerts() {
return this.alerts;
}

/**
* Get all defense actions
*/
getDefenseActions() {
return this.defenseActions;
}

/**
* Get outlier scores for visualization
*/
getOutlierScores() {
return this.outlierScores;
}

/**
* Switch model type (kmeans/dbscan)
*/
setModelType(type) {
if (type === 'kmeans' || type === 'dbscan') {
this.modelType = type;
this._updateModel();
}
}
}
}

class FeatureExtractor {
Expand All @@ -76,6 +212,22 @@ class FeatureExtractor {
];
}
}
/**
* FeatureExtractor: Extracts features from transactions for ML
*/
class FeatureExtractor {
extract(tx) {
// Features: amount, time, user risk score, device risk, location risk, type
return [
Math.log(1 + tx.amount),
tx.timestamp % 86400000 / 86400000, // time of day
tx.userRiskScore || 0.5,
tx.deviceRisk || 0.5,
tx.locationRisk || 0.5,
tx.type === 'payment' ? 1 : tx.type === 'refund' ? 0.5 : 0
];
}
}

// Dummy KMeans implementation for demonstration
class KMeans {
Expand All @@ -87,5 +239,55 @@ class KMeans {
};
}
}
/**
* KMeans clustering (dummy implementation)
*/
class KMeans {
static fit(features, k) {
// ...actual clustering logic...
return {
predict: (X) => [Math.floor(Math.random() * k)],
anomalyCluster: k - 1,
centroids: Array(k).fill().map(() => Array(features[0].length).fill(0))
};
}
static outlierScore(feature, model) {
// Dummy: distance to random centroid
let minDist = Infinity;
for (let c of model.centroids) {
let dist = KMeans._euclidean(feature, c);
if (dist < minDist) minDist = dist;
}
return minDist;
}
static _euclidean(a, b) {
let sum = 0;
for (let i = 0; i < a.length; i++) {
sum += (a[i] - b[i]) ** 2;
}
return Math.sqrt(sum);
}
}

/**
* DBSCAN clustering (dummy implementation)
*/
class DBSCAN {
static fit(features, eps, minPts) {
// ...actual DBSCAN logic...
return {
predict: (X) => [Math.random() > 0.95 ? -1 : 1], // -1 = outlier
labels: features.map(() => 1)
};
}
static outlierScore(feature, model) {
// Dummy: random score
return Math.random();
}
}

// Export engine
export { FraudMLEngine };
// ...more ML logic, feature extraction, online learning, etc. (expand as needed)

export { FraudMLEngine };
5 changes: 5 additions & 0 deletions public/test-transactions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[
{"id":1,"amount":1200,"currency":"USD","userId":"user101","timestamp":1678901234567,"location":"US","device":"mobile","type":"payment"},
{"id":2,"amount":9500,"currency":"INR","userId":"user202","timestamp":1678901235567,"location":"IN","device":"web","type":"payment"},
{"id":3,"amount":50,"currency":"EUR","userId":"user303","timestamp":1678901236567,"location":"UK","device":"tablet","type":"refund"}
]
19 changes: 19 additions & 0 deletions risk/riskEngine.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Contextual Risk Analysis Engine
const { getUserBehavior } = require('../models/user');

module.exports = {
async calculateRisk(req, user, session) {
// Example: combine device, geo, behavior, anomaly
let risk = 0;
if (req.headers['x-device-id'] !== session.deviceId) risk += 2;
if (req.ip !== session.lastIp) risk += 1;
// Behavioral anomaly (placeholder)
const behavior = await getUserBehavior(user.id);
if (behavior.anomalyScore > 0.7) risk += 3;
// Time-based risk
const hour = new Date().getHours();
if (hour < 6 || hour > 22) risk += 1;
// ...more factors...
return risk;
}
};
Loading