diff --git a/backend/models/SenderReputation.js b/backend/models/SenderReputation.js new file mode 100644 index 00000000..f096a49e --- /dev/null +++ b/backend/models/SenderReputation.js @@ -0,0 +1,30 @@ +const mongoose = require('mongoose'); + +const SenderReputationSchema = new mongoose.Schema({ + email: { type: String, required: true, index: true }, + domain: { type: String, required: true, index: true }, + score: { type: Number, default: 50, min: 0, max: 100 }, + spamReports: { type: Number, default: 0 }, + hamReports: { type: Number, default: 0 }, + lastSeen: { type: Date, default: Date.now } +}); + +SenderReputationSchema.methods.recordHam = function() { + this.hamReports += 1; + this.score = Math.min(100, this.score + 2); + return this.save(); +}; + +SenderReputationSchema.methods.recordSpam = function() { + this.spamReports += 1; + this.score = Math.max(0, this.score - 5); + return this.save(); +}; + +SenderReputationSchema.methods.getLevel = function() { + if (this.score >= 70) return 'trusted'; + if (this.score >= 40) return 'neutral'; + return 'suspicious'; +}; + +module.exports = mongoose.model('SenderReputation', SenderReputationSchema); \ No newline at end of file diff --git a/backend/models/UserFeedback.js b/backend/models/UserFeedback.js new file mode 100644 index 00000000..847e6da6 --- /dev/null +++ b/backend/models/UserFeedback.js @@ -0,0 +1,13 @@ +const mongoose = require('mongoose'); + +const UserFeedbackSchema = new mongoose.Schema({ + userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true }, + text: { type: String, required: true }, + predicted_label: { type: String, required: true }, + correct_label: { type: String, required: true }, + sender: { type: String }, + confidence: { type: Number, default: 0 }, + created_at: { type: Date, default: Date.now } +}); + +module.exports = mongoose.model('UserFeedback', UserFeedbackSchema); \ No newline at end of file diff --git a/frontend/src/components/EmailScannerDashboard.jsx b/frontend/src/components/EmailScannerDashboard.jsx index 4a3e67b9..4341f530 100644 --- a/frontend/src/components/EmailScannerDashboard.jsx +++ b/frontend/src/components/EmailScannerDashboard.jsx @@ -118,6 +118,29 @@ const checkConnectionStatus = async () => { } }; + const handleFeedback = async (email, correctLabel) => { + try { + const token = localStorage.getItem('token'); + await axios.post('/api/feedback', { + text: email.body, + predicted_label: email.prediction, + correct_label: correctLabel, + sender: email.sender, + confidence: email.confidence + }, { + headers: { Authorization: `Bearer ${token}` } + }); + + setEmails(prev => prev.map(e => + e.id === email.id ? { ...e, feedbackGiven: true } : e + )); + + toast.success('Thank you for your feedback!'); + } catch (error) { + toast.error('Failed to save feedback'); + } +}; + const handleScan = async (provider) => { if (!provider) return; setScanning(true); @@ -361,6 +384,22 @@ const checkConnectionStatus = async () => { )} +
+ {!email.feedbackGiven && ( + <> + + + + )} + {email.feedbackGiven && ( + ✅ Thanks for your feedback! + )} +
+ {/* IMAP Card */}