Skip to content
Open
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
168 changes: 164 additions & 4 deletions src/controllers/studentController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,78 @@ import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken';
import { JWT_SECRET } from '../config/config';

/**
* @swagger
* /api/students/signup:
* post:
* summary: Register a new student
* tags: [Students]
* requestBody:
* required: true
* content:
* multipart/form-data:
* schema:
* type: object
* required:
* - name
* - dob
* - email
* - country
* - password
* properties:
* name:
* type: string
* description: Student's full name
* dob:
* type: string
* format: date
* description: Date of birth
* email:
* type: string
* format: email
* description: Student's email address
* country:
* type: string
* description: Student's country of residence
* password:
* type: string
* format: password
* description: Student's password
* profilePhoto:
* type: string
* format: binary
* description: Student's profile photo
* responses:
* 201:
* description: Student successfully registered
* content:
* application/json:
* schema:
* type: object
* properties:
* token:
* type: string
* description: JWT token for authentication
* student:
* type: object
* properties:
* id:
* type: string
* name:
* type: string
* email:
* type: string
* 400:
* description: Missing required fields
* 409:
* description: Email already registered
* 500:
* description: Server error
*/
export const registerStudent = async (req: Request, res: Response): Promise<void> => {
try {
const { name, dob, email, country, password } = req.body;
const profilePhoto = req.file?.filename;

if (!name || !dob || !email || !country || !password) {
res.status(400).json({ message: 'All fields are required' });
Expand All @@ -20,9 +89,6 @@ export const registerStudent = async (req: Request, res: Response): Promise<void
}

const hashedPassword = await bcrypt.hash(password, 10);
const profilePhoto = req.file?.filename;
console.log(profilePhoto)

const student = new Student({
name,
dob,
Expand All @@ -40,10 +106,104 @@ export const registerStudent = async (req: Request, res: Response): Promise<void

res.status(201).json({
token,
student: { id: student._id, name: student.name, email: student.email },
student: {
id: String(student._id),
name: student.name,
email: student.email,
},
});
} catch (error) {
res.status(500).json({ message: 'Server error', error });
}
};

/**
* @swagger
* /api/students/signin:
* post:
* summary: Sign in a student
* tags: [Students]
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - email
* - password
* properties:
* email:
* type: string
* format: email
* description: Student's email address
* password:
* type: string
* format: password
* description: Student's password
* responses:
* 200:
* description: Student successfully signed in
* content:
* application/json:
* schema:
* type: object
* properties:
* token:
* type: string
* description: JWT token for authentication
* student:
* type: object
* properties:
* id:
* type: string
* name:
* type: string
* email:
* type: string
* 400:
* description: Missing required fields
* 401:
* description: Invalid credentials
* 500:
* description: Server error
*/
export const signinStudent = async (req: Request, res: Response): Promise<void> => {
try {
const { email, password } = req.body;

if (!email || !password) {
res.status(400).json({ message: 'Email and password are required' });
return;
}

const student = await Student.findOne({ email });
if (!student) {
res.status(401).json({ message: 'Invalid credentials' });
return;
}

const isValidPassword = await bcrypt.compare(password, student.password);
if (!isValidPassword) {
res.status(401).json({ message: 'Invalid credentials' });
return;
}

const token = jwt.sign({ id: student._id, email: student.email }, JWT_SECRET, {
expiresIn: '1h',
});

res.status(200).json({
token,
student: {
id: String(student._id),
name: student.name,
email: student.email,
},
});
} catch (error) {
console.error('Signin error:', error);
res.status(500).json({ message: 'Server error' });
}
};

136 changes: 131 additions & 5 deletions src/routes/studentRoutes.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,145 @@
import express from 'express';
import { registerStudent } from '../controllers/studentController';
import { upload } from '../middleware/upload';
import { registerStudent, signinStudent } from '../controllers/studentController';
import { uploadProfilePhoto } from '../middleware/upload';

const router = express.Router();

// Simple route handler for signup
router.post('/signup', upload.single('profilePhoto'), async (req, res, next) => {
/**
* @swagger
* /api/students/signup:
* post:
* summary: Register a new student
* tags: [Students]
* requestBody:
* required: true
* content:
* multipart/form-data:
* schema:
* type: object
* required:
* - name
* - dob
* - email
* - country
* - password
* properties:
* name:
* type: string
* description: Student's full name
* dob:
* type: string
* format: date
* description: Date of birth
* email:
* type: string
* format: email
* description: Student's email address
* country:
* type: string
* description: Student's country of residence
* password:
* type: string
* format: password
* description: Student's password
* profilePhoto:
* type: string
* format: binary
* description: Student's profile photo
* responses:
* 201:
* description: Student successfully registered
* content:
* application/json:
* schema:
* type: object
* properties:
* token:
* type: string
* description: JWT token for authentication
* student:
* type: object
* properties:
* id:
* type: string
* name:
* type: string
* email:
* type: string
* 400:
* description: Missing required fields
* 409:
* description: Email already registered
* 500:
* description: Server error
*/
router.post('/signup', uploadProfilePhoto.single('profilePhoto'), async (req, res, next) => {
try {
console.log('Processing signup request');
await registerStudent(req, res);
} catch (error) {
console.error('Signup error:', error);
next(error);
}
});

/**
* @swagger
* /api/students/signin:
* post:
* summary: Sign in a student
* tags: [Students]
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - email
* - password
* properties:
* email:
* type: string
* format: email
* description: Student's email address
* password:
* type: string
* format: password
* description: Student's password
* responses:
* 200:
* description: Student successfully signed in
* content:
* application/json:
* schema:
* type: object
* properties:
* token:
* type: string
* description: JWT token for authentication
* student:
* type: object
* properties:
* id:
* type: string
* name:
* type: string
* email:
* type: string
* 400:
* description: Missing required fields
* 401:
* description: Invalid credentials
* 500:
* description: Server error
*/
router.post('/signin', async (req, res, next) => {
try {
await signinStudent(req, res);
} catch (error) {
console.error('Signin error:', error);
next(error);
}
});

export default router;