1. Change Password fixed. 2. Personal Data implemented. 3. New alerts style. 4. Better dropdowns.

This commit is contained in:
AG
2025-11-19 22:52:32 +02:00
parent bb705c8a63
commit 8cc9ab29b7
14 changed files with 1266 additions and 632 deletions

View File

@@ -7,19 +7,34 @@ const router = express.Router();
const prisma = new PrismaClient();
const JWT_SECRET = process.env.JWT_SECRET || 'secret';
// Get Current User
router.get('/me', async (req, res) => {
try {
const token = req.headers.authorization?.split(' ')[1];
if (!token) return res.status(401).json({ error: 'Unauthorized' });
const decoded = jwt.verify(token, JWT_SECRET) as any;
const user = await prisma.user.findUnique({
where: { id: decoded.userId },
include: { profile: true }
});
if (!user) {
return res.status(404).json({ error: 'User not found' });
}
const { password: _, ...userSafe } = user;
res.json({ success: true, user: userSafe });
} catch (error) {
res.status(401).json({ error: 'Invalid token' });
}
});
// Login
router.post('/login', async (req, res) => {
try {
const { email, password } = req.body;
// Admin check (hardcoded for now as per original logic, or we can seed it)
// For now, let's stick to DB users, but maybe seed admin if needed.
// The original code had hardcoded admin. Let's support that via a special check or just rely on DB.
// Let's rely on DB for consistency, but if the user wants the specific admin account, they should register it.
// However, to match original behavior, I'll add a check or just let them register 'admin@gymflow.ai'.
const user = await prisma.user.findUnique({
where: { email },
include: { profile: true }
@@ -47,4 +62,73 @@ router.post('/login', async (req, res) => {
}
});
// Change Password
router.post('/change-password', async (req, res) => {
console.log('DEBUG: change-password route hit');
try {
const token = req.headers.authorization?.split(' ')[1];
if (!token) return res.status(401).json({ error: 'Unauthorized' });
const { userId, newPassword } = req.body;
// Verify token
const decoded = jwt.verify(token, JWT_SECRET) as any;
if (decoded.userId !== userId) {
return res.status(403).json({ error: 'Forbidden' });
}
if (!newPassword || newPassword.length < 4) {
return res.status(400).json({ error: 'Password too short' });
}
const hashed = await bcrypt.hash(newPassword, 10);
await prisma.user.update({
where: { id: userId },
data: {
password: hashed,
isFirstLogin: false
}
});
res.json({ success: true });
} catch (error) {
console.error(error);
res.status(500).json({ error: 'Server error' });
}
});
// Update Profile
router.patch('/profile', async (req, res) => {
try {
const token = req.headers.authorization?.split(' ')[1];
if (!token) return res.status(401).json({ error: 'Unauthorized' });
const { userId, profile } = req.body;
// Verify token
const decoded = jwt.verify(token, JWT_SECRET) as any;
if (decoded.userId !== userId) {
return res.status(403).json({ error: 'Forbidden' });
}
// Update or create profile
await prisma.userProfile.upsert({
where: { userId: userId },
update: {
...profile
},
create: {
userId: userId,
...profile
}
});
res.json({ success: true });
} catch (error) {
console.error(error);
res.status(500).json({ error: 'Server error' });
}
});
export default router;