Skip to content
Merged
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
1,007 changes: 350 additions & 657 deletions package-lock.json

Large diffs are not rendered by default.

10 changes: 8 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
"name": "typescript-node-sequelize-boilerplate",
"version": "0.1.0",
"description": "",
"author": "",
"license": " ",
"author": "Nabadeep Thakuria",
"homepage": "https://github.com/nabadeep25/typescript-node-sequelize-boilerplate",
"license": "MIT",
"keywords": ["typescript","node","express","sequelize","mysql","postgres","boilerplate","template","typescript node sequelize boilerplate","typescript node","typescript sequelize boilerplate"],
"scripts": {
"build-ts": "tsc",
"build": "npm run build-ts && npm run lint ",
Expand Down Expand Up @@ -40,6 +42,8 @@
"nodemailer": "^6.6.1",
"otplib": "^12.0.1",
"sequelize": "^6.25.3",
"swagger-jsdoc": "^6.2.5",
"swagger-ui-express": "^4.6.0",
"winston": "3.3.3"
},
"devDependencies": {
Expand All @@ -54,6 +58,8 @@
"@types/nodemailer": "6.4.0",
"@types/request": "2.48.5",
"@types/request-promise": "4.1.47",
"@types/swagger-jsdoc": "^6.0.1",
"@types/swagger-ui-express": "^4.1.3",
"@types/winston": "2.4.4",
"@typescript-eslint/eslint-plugin": "4.14.2",
"@typescript-eslint/parser": "4.14.2",
Expand Down
10 changes: 4 additions & 6 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ import express from "express";
import logger from "morgan";
import dbInit from "./model/init";
import cors from "cors";
import { customRequest } from "./middleware/requiresUser";
import { customRequest } from "./types/customDefinition";
import { deserializeUser } from "./middleware";
import userRouter from "./routes/userRoutes";
import authRouter from "./routes/authRoute";
import appRouter from "./routes/v1";

// Create Express server
const app = express();
Expand All @@ -23,8 +22,7 @@ app.use(deserializeUser);
* Primary app routes.
*/

app.use("/api/auth", authRouter);
app.use("/api/user", userRouter);
app.use("/api/v1", appRouter);

/**
* route to test server
Expand All @@ -39,7 +37,7 @@ app.get("/api/", (req: customRequest, res) => {
*/
app.patch("/api/sync", async (req, res) => {
try {
const sync = await dbInit(req.body?.alter);
const sync = await dbInit();
res.status(200).json({ ...sync, error: false });
} catch (err) {
console.log("ERR", err);
Expand Down
26 changes: 26 additions & 0 deletions src/config/option.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const swaggerOption = {
definition: {
openapi: "3.0.0",
info: {
title: "typescript-node-sequelize-boilerplate API documentation",
version: "1.0.0",
},
servers: [
{
url: `http://localhost:${process.env.PORT || 3000}/api/v1`,
},
],
components: {
securitySchemes: {
bearerAuth: {
type: "http",
scheme: "bearer",
bearerFormat: "JWT",
},
},
},
},

apis: ["src/routes/v1/*.ts"],
};
export { swaggerOption };
10 changes: 5 additions & 5 deletions src/controllers/user.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { findOneUser, updateUserById } from "../services/userService";
import { Request, Response } from "express";
import { Response } from "express";
import { omit } from "lodash";
import { customRequest } from "../middleware/requiresUser";
import { customRequest } from "../types/customDefinition";

const omitData = ["password"];
export const updateUser = async (req: Request, res: Response) => {
export const updateUser = async (req: customRequest, res: Response) => {
try {
const { userId } = req.params;
const { id: userId } = req.user;

let body = req.body;
body = omit(body, omitData);
Expand Down Expand Up @@ -39,7 +39,6 @@ export const getUserData = async (req: customRequest, res: Response) => {
try {
return res.status(200).json({
data: req.user,

error: false,
});
} catch (err) {
Expand All @@ -52,3 +51,4 @@ export const getUserData = async (req: customRequest, res: Response) => {
return res.status(400).json({ errorMsg: msg, error: true });
}
};

4 changes: 2 additions & 2 deletions src/middleware/deserializeUser.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { get } from "lodash";
import { verify } from "../util/jwt";
import { Request, Response, NextFunction } from "express";
import { customRequest } from "./requiresUser";
import { Response, NextFunction } from "express";
import { customRequest } from "../types/customDefinition";

const deserializeUser = async (
req: customRequest,
Expand Down
2 changes: 1 addition & 1 deletion src/middleware/isAdmin.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { get } from "lodash";
import { Response, NextFunction } from "express";
import { customRequest } from "./requiresUser";
import { customRequest } from "../types/customDefinition";

const isAdmin = async (
req: customRequest,
Expand Down
7 changes: 2 additions & 5 deletions src/middleware/requiresUser.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import { get } from "lodash";
import { getUserById } from "../services/userService";
import { Request, Response, NextFunction } from "express";

export interface customRequest extends Request {
user: any;
}
import { Response, NextFunction } from "express";
import { customRequest } from "../types/customDefinition";

const requireUser = async (
req: customRequest,
Expand Down
4 changes: 2 additions & 2 deletions src/model/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ export const modelList = {

/**
* Sync database
* @param alter

* @returns boolean
*/

const dbInit = async (alter: boolean) => {
const dbInit = async () => {
try {
await sequelizeConnection.sync({ alter: isDev });
return { success: true };
Expand Down
17 changes: 0 additions & 17 deletions src/routes/authRoute.ts

This file was deleted.

16 changes: 0 additions & 16 deletions src/routes/userRoutes.ts

This file was deleted.

165 changes: 165 additions & 0 deletions src/routes/v1/authRoute.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import { Router } from "express";
import { validateRequest } from "../../middleware";
import {
forgotPassword,
loginUser,
registerUser,
resetPassword,
} from "../../controllers/auth";
import { loginSchema, registerSchema } from "../../validation/user";
const authRouter = Router();

authRouter.post("/register", validateRequest(registerSchema), registerUser);
authRouter.post("/login", validateRequest(loginSchema), loginUser);
authRouter.post("/forgot-password", forgotPassword);
authRouter.post("/reset-password", resetPassword);

export default authRouter;

/**
* @swagger
* tags:
* name: Auth
* description: Authentication
*/

/**
* @swagger
* /auth/register:
* post:
* summary: Register as user
* tags: [Auth]
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - name
* - email
* - password
* properties:
* name:
* type: string
* email:
* type: string
* format: email
* description: must be unique
* password:
* type: string
* format: password
* minLength: 8
* description: At least one number and one letter
* example:
* name: name
* email: name@example.com
* password: password1
* responses:
* "201":
* description: Created
*
*
* "400":
* description: Bad Request
*/

/**
* @swagger
* /auth/login:
* post:
* summary: Login
* tags: [Auth]
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - email
* - password
* properties:
* email:
* type: string
* format: email
* password:
* type: string
* format: password
* example:
* email: name@example.com
* password: password1
* responses:
* "200":
* description: OK
*
* "401":
* description: Invalid email or password
*
*/

/**
* @swagger
* /auth/forgot-password:
* post:
* summary: Forgot password
* description: An email will be sent to reset password.
* tags: [Auth]
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - email
* properties:
* email:
* type: string
* format: email
* example:
* email: fake@example.com
* responses:
* "204":
* description: No content
* "404":
* description: Email not found
*
*/

/**
* @swagger
* /auth/reset-password:
* post:
* summary: Reset password
* tags: [Auth]
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - email
* - password
* - otp
* properties:
* email:
* type: string
* format: email
* password:
* type: string
* format: password
* otp:
* type: string
* example:
* email: name@example.com
* password: password1
* otp: 123344
* responses:
* "204":
* description: No content
* "401":
* description: Password reset failed

*/
12 changes: 12 additions & 0 deletions src/routes/v1/docsRoute.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Router } from "express";
import swaggerUi from "swagger-ui-express";
import swaggerJSDocs from "swagger-jsdoc";
import { swaggerOption } from "../../config/option";

const swaggerSpec = swaggerJSDocs(swaggerOption);
const docsRouter = Router();

docsRouter.use("/", swaggerUi.serve);
docsRouter.get("/", swaggerUi.setup(swaggerSpec));

export default docsRouter;
Loading