Skip to content

Commit

Permalink
feat: user authentication added 💯
Browse files Browse the repository at this point in the history
  • Loading branch information
fless-lab committed Jul 1, 2024
1 parent 612dbab commit bc41182
Show file tree
Hide file tree
Showing 13 changed files with 672 additions and 170 deletions.
9 changes: 9 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,21 @@
"author": "Abdou-Raouf ATARMLA",
"license": "ISC",
"dependencies": {
"@types/connect-flash": "^0.0.40",
"@types/express-session": "^1.18.0",
"bcrypt": "^5.1.1",
"connect-flash": "^0.1.1",
"cors": "^2.8.5",
"dotenv": "^16.4.5",
"ejs": "^3.1.10",
"express": "^4.19.2",
"express-brute": "^1.0.1",
"express-brute-mongo": "^1.0.0",
"express-brute-redis": "^0.0.1",
"express-list-endpoints": "^7.1.0",
"express-rate-limit": "^7.3.1",
"express-session": "^1.18.0",
"handlebars": "^4.7.8",
"helmet": "^7.1.0",
"ioredis": "^5.4.1",
"joi": "^17.13.3",
Expand All @@ -52,12 +59,14 @@
"devDependencies": {
"@commitlint/cli": "^19.3.0",
"@commitlint/config-conventional": "^19.2.2",
"@types/bcrypt": "^5.0.2",
"@types/cors": "^2.8.17",
"@types/express": "^4.17.21",
"@types/express-brute": "^1.0.5",
"@types/express-brute-mongo": "^0.0.39",
"@types/jsonwebtoken": "^9.0.6",
"@types/morgan": "^1.9.9",
"@types/nodemailer": "^6.4.15",
"@typescript-eslint/eslint-plugin": "^5.57.1",
"@typescript-eslint/parser": "^5.57.1",
"eslint": "^8.56.0",
Expand Down
163 changes: 163 additions & 0 deletions src/app/controllers/auth.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { Request, Response, NextFunction } from 'express';
import ApiResponse from '../utils/handlers/api-reponse';
import { ErrorResponseType } from '../utils/types';
import AuthService from '../services/auth.service';

class AuthController {
static async register(
req: Request,
res: Response,
next: NextFunction,
): Promise<void> {
try {
const response = await AuthService.register(req.body);
if (response.success) {
ApiResponse.success(res, response, 201);
} else {
throw response;
}
} catch (error) {
ApiResponse.error(res, error as ErrorResponseType);
}
}

static async verifyAccount(
req: Request,
res: Response,
next: NextFunction,
): Promise<void> {
try {
const response = await AuthService.verifyAccount(req.body);
if (response.success) {
ApiResponse.success(res, response);
} else {
throw response;
}
} catch (error) {
ApiResponse.error(res, error as ErrorResponseType);
}
}

static async loginWithPassword(
req: Request,
res: Response,
next: NextFunction,
): Promise<void> {
try {
const response = await AuthService.loginWithPassword(req.body);
if (response.success) {
ApiResponse.success(res, response);
} else {
throw response;
}
} catch (error) {
ApiResponse.error(res, error as ErrorResponseType);
}
}

static async generateLoginOtp(
req: Request,
res: Response,
next: NextFunction,
): Promise<void> {
try {
const response = await AuthService.generateLoginOtp(req.body.email);
if (response.success) {
ApiResponse.success(res, response);
} else {
throw response;
}
} catch (error) {
ApiResponse.error(res, error as ErrorResponseType);
}
}

static async loginWithOtp(
req: Request,
res: Response,
next: NextFunction,
): Promise<void> {
try {
const response = await AuthService.loginWithOtp(req.body);
if (response.success) {
ApiResponse.success(res, response);
} else {
throw response;
}
} catch (error) {
ApiResponse.error(res, error as ErrorResponseType);
}
}

static async refreshToken(
req: Request,
res: Response,
next: NextFunction,
): Promise<void> {
try {
const response = await AuthService.refresh(req.body.refreshToken);
if (response.success) {
ApiResponse.success(res, response);
} else {
throw response;
}
} catch (error) {
ApiResponse.error(res, error as ErrorResponseType);
}
}

static async logout(
req: Request,
res: Response,
next: NextFunction,
): Promise<void> {
try {
const { accessToken, refreshToken } = req.body;
const response = await AuthService.logout(accessToken, refreshToken);
if (response.success) {
ApiResponse.success(res, response, 202);
} else {
throw response;
}
} catch (error) {
ApiResponse.error(res, error as ErrorResponseType);
}
}

static async forgotPassword(
req: Request,
res: Response,
next: NextFunction,
): Promise<void> {
try {
const response = await AuthService.forgotPassword(req.body.email);
if (response.success) {
ApiResponse.success(res, response);
} else {
throw response;
}
} catch (error) {
ApiResponse.error(res, error as ErrorResponseType);
}
}

static async resetPassword(
req: Request,
res: Response,
next: NextFunction,
): Promise<void> {
try {
const response = await AuthService.resetPassword(req.body);
if (response.success) {
ApiResponse.success(res, response);
} else {
throw response;
}
} catch (error) {
ApiResponse.error(res, error as ErrorResponseType);
}
}
}

export default AuthController;
54 changes: 54 additions & 0 deletions src/app/controllers/user.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,60 @@ class UserController {
ApiResponse.error(res, error as ErrorResponseType);
}
}

static async getUserById(
req: Request,
res: Response,
next: NextFunction,
): Promise<void> {
try {
const userId = req.params.id;
const response = await UserService.findOne({
_id: userId,
});

if (response.success) {
ApiResponse.success(res, response);
} else {
throw response;
}
} catch (error) {
ApiResponse.error(res, error as ErrorResponseType);
}
}
}

export default UserController;

/**
* static async createUser(
req: Request,
res: Response,
next: NextFunction,
): Promise<void> {
try {
const response = (await UserService.create(
req.body,
)) as SuccessResponseType<IUserModel>;
if (response.success) {
// Send email to the newly created user
try {
await mailService.sendMail({
to: response.document.email,
subject: 'Welcome to Our Service',
text: 'Your account has been successfully created. Welcome aboard!',
});
console.log('Welcome email sent successfully');
} catch (emailError) {
console.error('Error sending welcome email:', emailError);
}
ApiResponse.success(res, response, 201);
} else {
throw response;
}
} catch (error) {
ApiResponse.error(res, error as ErrorResponseType);
}
}
*/
16 changes: 16 additions & 0 deletions src/app/routes/auth.routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Router } from 'express';
import AuthController from '../controllers/auth.controller';

const router = Router();

router.post('/register', AuthController.register);
router.post('/verify-account', AuthController.verifyAccount);
router.post('/login', AuthController.loginWithPassword);
router.post('/generate-login-otp', AuthController.generateLoginOtp);
router.post('/login-with-otp', AuthController.loginWithOtp);
router.post('/refresh-token', AuthController.refreshToken);
router.post('/logout', AuthController.logout);
router.post('/forgot-password', AuthController.forgotPassword);
router.patch('/reset-password', AuthController.resetPassword);

export default router;
2 changes: 2 additions & 0 deletions src/app/routes/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import { Router } from 'express';
import userRouter from './user.routes';
import appRoutes from './app.routes';
import otpRoutes from './otp.routes';
import authRoutes from './auth.routes';

const router = Router();

router.use('/', appRoutes);
router.use('/users', userRouter);
router.use('/otp', otpRoutes);
router.use('/auth', authRoutes);

export default router;
13 changes: 5 additions & 8 deletions src/app/routes/user.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,10 @@ import UserController from '../controllers/user.controller';
import { validate } from '../utils/middlewares/validate';
import { createUserSchema } from '../utils/validators/user';

const userRouter = Router();
const router = Router();

userRouter.post('/', validate(createUserSchema), (req, res, next) =>
UserController.createUser(req, res, next),
);
userRouter.get('/', (req, res, next) =>
UserController.getAllUsers(req, res, next),
);
router.post('/', validate(createUserSchema), UserController.createUser);
router.get('/', UserController.getAllUsers);
router.get('/:id', UserController.getUserById);

export default userRouter;
export default router;
Loading

0 comments on commit bc41182

Please sign in to comment.