-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.js
More file actions
164 lines (139 loc) · 5.67 KB
/
server.js
File metadata and controls
164 lines (139 loc) · 5.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
const express = require('express');
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const cors = require('cors');
// Initialize Express app
const app = express();
app.use(express.json());
app.use(cors());
// MongoDB connection setup
const MONGO_URI = 'mongodb://localhost:27017/personal_finance_tool'; // Replace with your MongoDB URI
mongoose.connect(MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => console.log('Connected to MongoDB'))
.catch((err) => console.log('Failed to connect to MongoDB', err));
// JWT Secret
const JWT_SECRET = 'your_jwt_secret_key'; // Replace with a strong secret key
// User schema and model
const userSchema = new mongoose.Schema({
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true }
});
userSchema.pre('save', async function(next) {
if (this.isModified('password')) {
const salt = await bcrypt.genSalt(10);
this.password = await bcrypt.hash(this.password, salt);
}
next();
});
const User = mongoose.model('User', userSchema);
// Transaction schema and model
const transactionSchema = new mongoose.Schema({
userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
date: { type: Date, required: true },
type: { type: String, enum: ['Income', 'Expense', 'Savings'], required: true },
amount: { type: Number, required: true }, // Ensure amount is a number
category: { type: String, required: true },
description: { type: String }
});
const Transaction = mongoose.model('Transaction', transactionSchema);
// Amount schema and model
const amountSchema = new mongoose.Schema({
userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
totalIncome: { type: Number, default: 0 }, // Number for Income totals
totalExpense: { type: Number, default: 0 }, // Number for Expense totals
totalSavings: { type: Number, default: 0 } // Number for Savings totals
});
const Amount = mongoose.model('Amount', amountSchema);
// Middleware to authenticate token
const authenticateToken = (req, res, next) => {
const token = req.header('Authorization').split(' ')[1];
if (!token) return res.status(401).json({ message: 'No token provided' });
jwt.verify(token, JWT_SECRET, (err, user) => {
if (err) return res.status(403).json({ message: 'Invalid token' });
req.user = user;
next();
});
};
// User registration route
app.post('/api/register', async (req, res) => {
const { name, email, password } = req.body;
try {
let user = await User.findOne({ email });
if (user) return res.status(400).json({ message: 'User already exists' });
user = new User({ name, email, password });
await user.save();
// Create an Amount record for the user
const amount = new Amount({ userId: user._id });
await amount.save();
res.status(201).json({ message: 'User registered successfully' });
} catch (error) {
res.status(500).json({ message: 'Server error' });
}
});
// User login route
app.post('/api/login', async (req, res) => {
const { email, password } = req.body;
try {
const user = await User.findOne({ email });
if (!user) return res.status(400).json({ message: 'Invalid email or password' });
const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch) return res.status(400).json({ message: 'Invalid email or password' });
const token = jwt.sign({ userId: user._id }, JWT_SECRET, { expiresIn: '1h' });
res.json({ token });
} catch (error) {
res.status(500).json({ message: 'Server error' });
}
});
// Add a new transaction and update the amount totals
app.post('/api/transactions', authenticateToken, async (req, res) => {
const { type, amount, category, description } = req.body;
try {
const transaction = new Transaction({
userId: req.user.userId,
date: new Date(),
type,
amount: Number(amount), // Ensure amount is treated as a number
category,
description
});
await transaction.save();
// Update the totals in Amount table
const userAmount = await Amount.findOne({ userId: req.user.userId });
if (type === 'Income') {
userAmount.totalIncome += Number(amount);
} else if (type === 'Expense') {
userAmount.totalExpense += Number(amount);
} else if (type === 'Savings') {
userAmount.totalSavings += Number(amount);
}
await userAmount.save();
res.status(201).json({ message: 'Transaction saved and totals updated successfully' });
} catch (error) {
res.status(500).json({ message: 'Server error' });
}
});
// Get all transactions for the logged-in user
app.get('/api/transactions', authenticateToken, async (req, res) => {
try {
const transactions = await Transaction.find({ userId: req.user.userId });
res.json(transactions);
} catch (error) {
res.status(500).json({ message: 'Server error' });
}
});
// Get transaction totals (income, expenses, savings) for the logged-in user
app.get('/api/transactions/totals', authenticateToken, async (req, res) => {
try {
const totals = await Amount.findOne({ userId: req.user.userId });
res.json(totals);
} catch (error) {
res.status(500).json({ message: 'Server error' });
}
});
// Start the server
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});