Skip to content

Commit a2607fd

Browse files
authored
Merge branch 'Kritika75:main' into design/masthead
2 parents ce463f8 + 11494fa commit a2607fd

File tree

5 files changed

+145
-1
lines changed

5 files changed

+145
-1
lines changed

package-lock.json

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
{
22
"dependencies": {
3+
"nodemailer": "^7.0.5",
4+
"zod": "^4.1.3",
35
"nodemailer": "^7.0.5"
46
}
57
}

server/routes/auth.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,16 @@ const express = require('express')
22
const bcrypt = require('bcryptjs')
33
const jwt = require('jsonwebtoken')
44
const User = require('../models/User')
5+
const {
6+
signupSchema,
7+
loginSchema,
8+
forgotPasswordSchema,
9+
resetPasswordSchema,
10+
validate
11+
} = require('../validators/authValidator')
512
const router = express.Router()
613

7-
router.post('/signup', async (req, res) => {
14+
router.post('/signup', validate(signupSchema), async (req, res) => {
815
try {
916
const { username, email, password } = req.body
1017
const existing = await User.findOne({ email })

server/test/auth.test.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
const request = require('supertest');
2+
const app = require('../server'); // Assuming you have an Express app exported from server.js
3+
4+
describe('Auth Routes', () => {
5+
it('should validate signup input', async () => {
6+
const response = await request(app)
7+
.post('/signup')
8+
.send({
9+
username: 'us', // Invalid username
10+
email: 'invalid-email', // Invalid email
11+
password: 'short' // Invalid password
12+
});
13+
expect(response.status).toBe(400);
14+
expect(response.body).toHaveProperty('errors');
15+
});
16+
17+
it('should validate login input', async () => {
18+
const response = await request(app)
19+
.post('/login')
20+
.send({
21+
email: 'invalid-email', // Invalid email
22+
password: '' // Invalid password
23+
});
24+
expect(response.status).toBe(400);
25+
expect(response.body).toHaveProperty('errors');
26+
});
27+
28+
it('should validate forgot password input', async () => {
29+
const response = await request(app)
30+
.post('/forgot-password')
31+
.send({
32+
email: 'invalid-email' // Invalid email
33+
});
34+
expect(response.status).toBe(400);
35+
expect(response.body).toHaveProperty('errors');
36+
});
37+
38+
it('should validate reset password input', async () => {
39+
const response = await request(app)
40+
.post('/reset-password')
41+
.send({
42+
token: '', // Invalid token
43+
password: 'short' // Invalid password
44+
});
45+
expect(response.status).toBe(400);
46+
expect(response.body).toHaveProperty('errors');
47+
});
48+
});

server/validators/authValidator.js

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
const { z } = require('zod');
2+
3+
// Signup validation schema
4+
const signupSchema = z.object({
5+
username: z.string()
6+
.min(3, 'Username must be at least 3 characters long')
7+
.max(30, 'Username cannot exceed 30 characters')
8+
.regex(/^[a-zA-Z0-9_]+$/, 'Username can only contain letters, numbers, and underscores'),
9+
email: z.string()
10+
.email('Invalid email address')
11+
.max(255, 'Email cannot exceed 255 characters'),
12+
password: z.string()
13+
.min(8, 'Password must be at least 8 characters long')
14+
.max(100, 'Password cannot exceed 100 characters')
15+
.regex(/[a-z]/, 'Password must contain at least one lowercase letter')
16+
.regex(/[A-Z]/, 'Password must contain at least one uppercase letter')
17+
.regex(/[0-9]/, 'Password must contain at least one number')
18+
.regex(/[^a-zA-Z0-9]/, 'Password must contain at least one special character')
19+
});
20+
21+
// Login validation schema
22+
const loginSchema = z.object({
23+
email: z.string()
24+
.email('Invalid email address'),
25+
password: z.string()
26+
.min(1, 'Password is required')
27+
});
28+
29+
// Forgot password validation schema
30+
const forgotPasswordSchema = z.object({
31+
email: z.string()
32+
.email('Invalid email address')
33+
});
34+
35+
// Reset password validation schema
36+
const resetPasswordSchema = z.object({
37+
token: z.string()
38+
.min(1, 'Token is required'),
39+
password: z.string()
40+
.min(8, 'Password must be at least 8 characters long')
41+
.max(100, 'Password cannot exceed 100 characters')
42+
.regex(/[a-z]/, 'Password must contain at least one lowercase letter')
43+
.regex(/[A-Z]/, 'Password must contain at least one uppercase letter')
44+
.regex(/[0-9]/, 'Password must contain at least one number')
45+
.regex(/[^a-zA-Z0-9]/, 'Password must contain at least one special character')
46+
});
47+
48+
// Validation middleware function
49+
const validate = (schema) => (req, res, next) => {
50+
try {
51+
schema.parse(req.body);
52+
next();
53+
} catch (error) {
54+
if (error instanceof z.ZodError) {
55+
const errors = error.errors.map(err => ({
56+
field: err.path.join('.'),
57+
message: err.message
58+
}));
59+
return res.status(400).json({
60+
message: 'Validation failed',
61+
errors
62+
});
63+
}
64+
next(error);
65+
}
66+
};
67+
68+
module.exports = {
69+
signupSchema,
70+
loginSchema,
71+
forgotPasswordSchema,
72+
resetPasswordSchema,
73+
validate
74+
};

0 commit comments

Comments
 (0)