create-nodets-app-nish 1.0.7 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-nodets-app-nish",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "Command line tool to create a new Node.js + Express + MongoDB + TypeScript project template",
5
5
  "license": "ISC",
6
6
  "author": "krish112407",
@@ -14,4 +14,10 @@ app.use(express.urlencoded({extended:true,limit:"16kb"}))
14
14
  app.use(express.static("public"))
15
15
  app.use(cookieParser())
16
16
 
17
+ import adminRouter from "./routers/admin.routes.js";
18
+ import userRouter from "./routers/user.routes.js";
19
+
20
+ app.use("/api/v1/admin", adminRouter);
21
+ app.use("/api/v1/users", userRouter);
22
+
17
23
  export {app}
@@ -0,0 +1,70 @@
1
+ import { Admin } from "../../models/admin.models.js";
2
+ import { asyncHandler } from "../../utils/asyncHandler.js";
3
+ import { returnResponse } from "../../utils/apiResponse.js";
4
+ import { Request , Response} from "express";
5
+
6
+ const createAdmin = asyncHandler(async (req: Request, res: Response) => {
7
+ const { username, email, password } = req.body;
8
+
9
+ if ([username, email, password].some(field => field?.trim() === "")) {
10
+ return returnResponse(res, 400, "All fields are required", null);
11
+ }
12
+
13
+ const existingAdmin = await Admin.findOne({
14
+ $or: [{ username }, { email }]
15
+ });
16
+
17
+ if (existingAdmin) {
18
+ return returnResponse(res, 400, "Admin already exists", null);
19
+ }
20
+
21
+ const admin = await Admin.create({ username, email, password });
22
+
23
+ const createdAdmin = await Admin.findById(admin._id).select("-password");
24
+
25
+ if (!createdAdmin) {
26
+ return returnResponse(res, 500, "Something went wrong while creating admin", null);
27
+ }
28
+
29
+ return returnResponse(res, 201, "Admin created successfully", createdAdmin);
30
+ });
31
+
32
+ const loginAdmin = asyncHandler(async (req: Request, res: Response) => {
33
+ const { email, password } = req.body;
34
+
35
+ if (!email || !password) {
36
+ return returnResponse(res, 400, "Email and password are required", null);
37
+ }
38
+
39
+ const admin = await Admin.findOne({ email });
40
+
41
+ if (!admin) {
42
+ return returnResponse(res, 404, "Admin not found", null);
43
+ }
44
+
45
+ const isPasswordValid = await admin.isPasswordCorrect(password);
46
+
47
+ if (!isPasswordValid) {
48
+ return returnResponse(res, 401, "Invalid credentials", null);
49
+ }
50
+
51
+ const accessToken = admin.generateAccessToken();
52
+
53
+ const loggedInAdmin = await Admin.findById(admin._id).select("-password");
54
+
55
+ const options = {
56
+ httpOnly: true,
57
+ secure: true
58
+ };
59
+
60
+ return res
61
+ .status(200)
62
+ .cookie("accessToken", accessToken, options)
63
+ .json({
64
+ statusCode: 200,
65
+ data: { admin: loggedInAdmin, accessToken },
66
+ message: "Admin logged in successfully"
67
+ });
68
+ });
69
+
70
+ export { createAdmin, loginAdmin };
@@ -0,0 +1,70 @@
1
+ import { User } from "../../models/user.models.js";
2
+ import { asyncHandler } from "../../utils/asyncHandler.js";
3
+ import { returnResponse } from "../../utils/apiResponse.js";
4
+ import { Request, Response } from "express";
5
+
6
+ const registerUser = asyncHandler(async (req: Request, res: Response) => {
7
+ const { username, email, password } = req.body;
8
+
9
+ if ([username, email, password].some(field => field?.trim() === "")) {
10
+ return returnResponse(res, 400, "All fields are required", null);
11
+ }
12
+
13
+ const existingUser = await User.findOne({
14
+ $or: [{ username }, { email }]
15
+ });
16
+
17
+ if (existingUser) {
18
+ return returnResponse(res, 400, "User with this email or username already exists", null);
19
+ }
20
+
21
+ const user = await User.create({ username, email, password });
22
+
23
+ const createdUser = await User.findById(user._id).select("-password");
24
+
25
+ if (!createdUser) {
26
+ return returnResponse(res, 500, "Something went wrong while registering user", null);
27
+ }
28
+
29
+ return returnResponse(res, 201, "User registered successfully", createdUser);
30
+ });
31
+
32
+ const loginUser = asyncHandler(async (req: Request, res: Response) => {
33
+ const { email, password } = req.body;
34
+
35
+ if (!email || !password) {
36
+ return returnResponse(res, 400, "Email and password are required", null);
37
+ }
38
+
39
+ const user = await User.findOne({ email });
40
+
41
+ if (!user) {
42
+ return returnResponse(res, 404, "User not found", null);
43
+ }
44
+
45
+ const isPasswordValid = await user.isPasswordCorrect(password);
46
+
47
+ if (!isPasswordValid) {
48
+ return returnResponse(res, 401, "Invalid credentials", null);
49
+ }
50
+
51
+ const accessToken = user.generateAccessToken();
52
+
53
+ const loggedInUser = await User.findById(user._id).select("-password");
54
+
55
+ const options = {
56
+ httpOnly: true,
57
+ secure: true
58
+ };
59
+
60
+ return res
61
+ .status(200)
62
+ .cookie("accessToken", accessToken, options)
63
+ .json({
64
+ statusCode: 200,
65
+ data: { user: loggedInUser, accessToken },
66
+ message: "User logged in successfully"
67
+ });
68
+ });
69
+
70
+ export { registerUser, loginUser };
@@ -0,0 +1,11 @@
1
+ import { Document } from "mongoose";
2
+
3
+ interface IUser extends Document {
4
+ username: string;
5
+ email: string;
6
+ password: string;
7
+ generateAccessToken(): string;
8
+ isPasswordCorrect(password: string): Promise<boolean>;
9
+ }
10
+
11
+ export type { IUser };
@@ -0,0 +1,62 @@
1
+ import { Request, Response, NextFunction } from "express";
2
+ import jwt from "jsonwebtoken";
3
+ import { asyncHandler } from "../utils/asyncHandler.js";
4
+ import { Admin } from "../models/admin.models.js";
5
+ import { User } from "../models/user.models.js";
6
+ import { returnResponse } from "../utils/apiResponse.js";
7
+
8
+ // Extend Express Request interface to include admin and user
9
+ declare global {
10
+ namespace Express {
11
+ interface Request {
12
+ admin?: any;
13
+ user?: any;
14
+ }
15
+ }
16
+ }
17
+
18
+ export const verifyAdmin = asyncHandler(async (req: Request, res: Response, next: NextFunction) => {
19
+ try {
20
+ const token = req.cookies?.accessToken || req.header("Authorization")?.replace("Bearer ", "");
21
+
22
+ if (!token) {
23
+ return returnResponse(res, 401, "Unauthorized request", null);
24
+ }
25
+
26
+ const decodedToken = jwt.verify(token, process.env.JWT_SECRET as string) as any;
27
+
28
+ const admin = await Admin.findById(decodedToken?._id).select("-password");
29
+
30
+ if (!admin) {
31
+ return returnResponse(res, 401, "Invalid Access Token", null);
32
+ }
33
+
34
+ req.admin = admin;
35
+ next();
36
+ } catch (error) {
37
+ return returnResponse(res, 401, "Invalid Access Token", null);
38
+ }
39
+ });
40
+
41
+ export const verifyUser = asyncHandler(async (req: Request, res: Response, next: NextFunction) => {
42
+ try {
43
+ const token = req.cookies?.accessToken || req.header("Authorization")?.replace("Bearer ", "");
44
+
45
+ if (!token) {
46
+ return returnResponse(res, 401, "Unauthorized request", null);
47
+ }
48
+
49
+ const decodedToken = jwt.verify(token, process.env.JWT_SECRET as string) as any;
50
+
51
+ const user = await User.findById(decodedToken?._id).select("-password");
52
+
53
+ if (!user) {
54
+ return returnResponse(res, 401, "Invalid Access Token", null);
55
+ }
56
+
57
+ req.user = user;
58
+ next();
59
+ } catch (error) {
60
+ return returnResponse(res, 401, "Invalid Access Token", null);
61
+ }
62
+ });
@@ -21,7 +21,7 @@ const AdminSchema = new mongoose.Schema<AdminType>({
21
21
  type: String,
22
22
  required: true
23
23
  }
24
- })
24
+ }, { timestamps: true })
25
25
 
26
26
  AdminSchema.pre("save", async function () {
27
27
  if (this.isModified("password")) {
@@ -0,0 +1,46 @@
1
+ import type { IUser } from "../interface/user.interface.js";
2
+ import mongoose, { Document } from "mongoose";
3
+ import jwt from "jsonwebtoken";
4
+ import bcrypt from "bcrypt";
5
+
6
+ type UserType = IUser & Document;
7
+
8
+ const UserSchema = new mongoose.Schema<UserType>({
9
+ username: {
10
+ type: String,
11
+ required: true,
12
+ unique: true
13
+ },
14
+ email: {
15
+ type: String,
16
+ required: true,
17
+ unique: true
18
+ },
19
+ password: {
20
+ type: String,
21
+ required: true
22
+ }
23
+ }, { timestamps: true });
24
+
25
+ UserSchema.pre("save", async function (next) {
26
+ if (this.isModified("password")) {
27
+ this.password = await bcrypt.hash(this.password, 10);
28
+ }
29
+ next();
30
+ });
31
+
32
+ UserSchema.methods.generateAccessToken = function (): string {
33
+ return jwt.sign({
34
+ _id: this._id,
35
+ username: this.username,
36
+ email: this.email
37
+ }, process.env.JWT_SECRET as string, {
38
+ expiresIn: "1d"
39
+ });
40
+ };
41
+
42
+ UserSchema.methods.isPasswordCorrect = async function (password: string): Promise<boolean> {
43
+ return await bcrypt.compare(password, this.password);
44
+ };
45
+
46
+ export const User = mongoose.model<UserType>("User", UserSchema);
@@ -0,0 +1,9 @@
1
+ import { Router } from "express";
2
+ import { createAdmin, loginAdmin } from "../controllers/admin/admin.auth.controller.js";
3
+
4
+ const router = Router();
5
+
6
+ router.route("/register").post(createAdmin);
7
+ router.route("/login").post(loginAdmin);
8
+
9
+ export default router;
@@ -0,0 +1,9 @@
1
+ import { Router } from "express";
2
+ import { registerUser, loginUser } from "../controllers/user/user.auth.controller.js";
3
+
4
+ const router = Router();
5
+
6
+ router.route("/register").post(registerUser);
7
+ router.route("/login").post(loginUser);
8
+
9
+ export default router;