hi-secure 1.0.35 → 1.0.36

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/readme.md +192 -230
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hi-secure",
3
- "version": "1.0.35",
3
+ "version": "1.0.36",
4
4
  "description": "Unified security layer for Express.js: authentication, validation, sanitization, rate limiting and CORS",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
package/readme.md CHANGED
@@ -460,21 +460,24 @@ Execution order is deterministic and isolated to the route.
460
460
  JWT support is optional. Enable it only if you want authentication features.
461
461
  </p>
462
462
 
463
- <pre><code>HiSecure.resetInstance();
464
-
465
- HiSecure.getInstance({
463
+ <pre><code>
464
+
465
+ HiSecure.init({
466
466
  auth: {
467
467
  enabled: true,
468
- jwtSecret: process.env.JWT_SECRET,
469
- jwtExpiresIn: "1d"
470
- }
468
+ jwtSecret:
469
+ process.env.JWT_SECRET , // "at least 32 - if not it shows warning in logs"
470
+ jwtExpiresIn: "1d",
471
+ },
471
472
  });
473
+
474
+
472
475
  </code></pre>
473
476
 
474
477
  <hr/>
475
478
 
476
479
 
477
- <h2>🔐 Final Authentication Setup</h2>
480
+ <h2>Final Authentication Setup</h2>
478
481
 
479
482
  <p>
480
483
  This section demonstrates a complete, production-ready authentication setup using HiSecure.
@@ -493,42 +496,84 @@ It covers signup, JWT login, Google login, role-based access control, and proper
493
496
 
494
497
  <hr/>
495
498
 
496
- <h3>Application Bootstrap (server.js / app.js)</h3>
499
+ <h3>Application Bootstrap (app.ts / app.js)</h3>
497
500
 
498
- <pre><code>import express from "express";
499
- import dotenv from "dotenv";
501
+ <pre><code>
502
+
503
+ import express from "express";
500
504
  import { HiSecure } from "hi-secure";
501
- import authRoutes from "./routes/auth.routes.js";
505
+ import dotenv from "dotenv";
502
506
 
503
507
  dotenv.config();
504
508
 
505
- const app = express();
506
-
507
- HiSecure.resetInstance();
508
-
509
- HiSecure.getInstance({
509
+ HiSecure.init({
510
510
  auth: {
511
511
  enabled: true,
512
- jwtSecret: process.env.JWT_SECRET || "supersecret_32_chars_minimum",
512
+ jwtSecret:
513
+ process.env.JWT_SECRET ,
513
514
  jwtExpiresIn: "1d",
514
- googleClientId: process.env.GOOGLE_CLIENT_ID // this only added if need googleLogin as well
515
- }
515
+ },
516
516
  });
517
517
 
518
+ const app = express();
519
+
518
520
  app.use(HiSecure.middleware("api"));
519
521
 
520
- app.use("/auth", authRoutes);
521
522
 
522
- app.listen(3000);
523
+ // When u use the Frontend [Because - Cors is the browser's security]
524
+ // HiSecure.cors({
525
+ // origin:"*" , // We can add our custome end points as well
526
+ // credentials:true
527
+ // })
528
+
529
+
530
+ import authRoutes from "./routes/auth.route";
531
+ import issueRoutes from "./routes/issue.route";
532
+ import notificationRoutes from "./routes/notification.route";
533
+ import communityRoutes from "./routes/community.route";
534
+
535
+ app.use("/api/auth", authRoutes);
536
+ app.use("/api/issues", issueRoutes);
537
+ app.use("/api/notifications", notificationRoutes);
538
+ app.use("/api/community", communityRoutes);
539
+
540
+ app.get("/", (_req, res) => {
541
+ res.json({ success: true, message: "Backend running" });
542
+ });
543
+
544
+ export default app;
545
+
523
546
  </code></pre>
524
547
 
525
- <p>
526
- <em>Note:</em> <code>resetInstance()</code> is recommended only for tests or starter templates.
527
- It should not be used repeatedly in production runtime.
528
- </p>
548
+
549
+
550
+
551
+ <h3>Application Bootstrap (server.ts / server.js)</h3>
552
+
553
+ <pre><code>
554
+
555
+ import app from "./app";
556
+ import dotenv from "dotenv";
557
+ import { connectDB } from "./config/db";
558
+
559
+ dotenv.config();
560
+
561
+ connectDB();
562
+
563
+ const PORT = process.env.PORT;
564
+
565
+ app.listen(PORT, () => {
566
+ console.log(`Server running on port ${PORT}`);
567
+ });
568
+
569
+ </code></pre>
570
+
571
+
572
+
529
573
 
530
574
  <hr/>
531
575
 
576
+
532
577
  <h3>Authentication Routes</h3>
533
578
 
534
579
  <pre><code>import { Router } from "express";
@@ -552,75 +597,63 @@ router.get(
552
597
  );
553
598
 
554
599
  export default router;
600
+
555
601
  </code></pre>
556
602
 
557
603
  <hr/>
558
604
 
559
605
  <h3>Authentication Controllers</h3>
560
606
 
607
+
561
608
  <h4>Signup (Email and Password)</h4>
562
609
 
563
610
  <pre><code>
564
- import { HiSecure } from "hi-secure";
565
- import { HttpError } from "../core/errors/HttpError.js";
566
- import User from "../models/User.js";
567
-
568
611
 
569
- const JWT_OPTIONS = {
570
- issuer: 'hi-secure-backend',
571
- audience: ['web-app', 'mobile-app'],
572
- expiresIn: '7d',
573
- subject: 'user-authentication'
574
- };
575
612
 
613
+ export const register = async (req: Request, res: Response) => {
614
+ try {
615
+ const { name, email, password, role, hostel, block, room } = req.body;
576
616
 
577
- exports.registerUser = async(req, res) => {
578
- try {
579
- const { name, email, password } = req.body;
580
-
581
- const existingUser = await User.findOne({ email });
582
- if (existingUser) {
583
- return res.status(400).json({
584
- error: 'User already exists'
585
- });
586
- }
587
-
588
- const hashedPassword = await HiSecure.hash(password);
589
-
590
- const user = await User.create({
591
- name,
592
- email,
593
- password: hashedPassword
594
- });
595
-
596
- const token = HiSecure.jwt.sign({
597
- userId: user._id.toString(),
598
- email: user.email,
599
- name: user.name,
600
- role: 'user'
601
- },
602
- JWT_OPTIONS
603
- );
604
-
605
- res.status(201).json({
606
- message: 'User registered successfully',
607
- token,
608
- user: {
609
- id: user._id,
610
- name: user.name,
611
- email: user.email
612
- }
613
- });
614
-
615
- } catch (error) {
616
- console.error('Registration error:', error);
617
- res.status(500).json({
618
- error: 'Registration failed',
619
- details: error.message
620
- });
617
+ const existingUser = await User.findOne({ email });
618
+ if (existingUser) {
619
+ return res.status(400).json({
620
+ success: false,
621
+ message: 'User already exists'
622
+ });
621
623
  }
624
+
625
+ const hashedPassword = await HiSecure.hash(password);
626
+
627
+ const user = await User.create({
628
+ name,
629
+ email,
630
+ password: hashedPassword,
631
+ role: role || 'student',
632
+ hostel,
633
+ block,
634
+ room
635
+ });
636
+
637
+ return res.status(201).json({
638
+ success: true,
639
+ message: 'User registered successfully',
640
+ user: {
641
+ id: user._id,
642
+ name: user.name,
643
+ email: user.email,
644
+ role: user.role
645
+ }
646
+ });
647
+ } catch (error: any) {
648
+ return res.status(500).json({
649
+ success: false,
650
+ message: 'Registration failed',
651
+ error: error.message
652
+ });
653
+ }
622
654
  };
623
655
 
656
+
624
657
  </code></pre>
625
658
 
626
659
  <hr/>
@@ -629,175 +662,104 @@ exports.registerUser = async(req, res) => {
629
662
 
630
663
  <pre><code>
631
664
 
632
- exports.loginUser = async(req, res) => {
633
- try {
634
- const { email, password } = req.body;
635
-
636
- const user = await User.findOne({ email });
637
- if (!user) {
638
- return res.status(401).json({
639
- error: 'Invalid credentials'
640
- });
641
- }
642
-
643
- const isValid = await HiSecure.verify(password, user.password);
644
- if (!isValid) {
645
- return res.status(401).json({
646
- error: 'Invalid credentials'
647
- });
648
- }
649
-
650
- const token = HiSecure.jwt.sign({
651
- userId: user._id.toString(),
652
- email: user.email,
653
- name: user.name,
654
- role: 'user'
655
- },
656
- JWT_OPTIONS
657
- );
658
-
659
- res.json({
660
- message: 'Login successful',
661
- token,
662
- user: {
663
- id: user._id,
664
- name: user.name,
665
- email: user.email
666
- }
667
- });
668
-
669
- } catch (error) {
670
- console.error('Login error:', error);
671
- res.status(500).json({
672
- error: 'Login failed',
673
- details: error.message
674
- });
675
- }
676
- };
677
665
 
678
- </code></pre>
666
+ export const login = async (req: Request, res: Response) => {
667
+ try {
668
+ const { email, password } = req.body;
679
669
 
680
- <hr/>
670
+ const user = await User.findOne({ email });
671
+ if (!user) {
672
+ return res.status(401).json({
673
+ success: false,
674
+ message: 'Invalid credentials'
675
+ });
676
+ }
681
677
 
682
- <h3>Role-Based Protected Routes</h3>
678
+ const isPasswordValid = await HiSecure.verify(password, user.password);
679
+ if (!isPasswordValid) {
680
+ return res.status(401).json({
681
+ success: false,
682
+ message: 'Invalid credentials'
683
+ });
684
+ }
683
685
 
684
- <pre><code>app.get(
685
- "/admin",
686
- HiSecure.auth({ roles: ["admin"] }),
687
- (req, res) => {
688
- res.json({ message: "Welcome Admin" });
686
+ const token = HiSecure.jwt.sign({
687
+ userId: user._id.toString(),
688
+ email: user.email,
689
+ role: user.role
690
+ });
691
+
692
+ return res.status(200).json({
693
+ success: true,
694
+ message: 'Login successful',
695
+ token,
696
+ user: {
697
+ id: user._id,
698
+ name: user.name,
699
+ email: user.email,
700
+ role: user.role
701
+ }
702
+ });
703
+ } catch (error: any) {
704
+ return res.status(500).json({
705
+ success: false,
706
+ message: 'Login failed',
707
+ error: error.message
708
+ });
689
709
  }
690
- );
691
- </code></pre>
692
-
693
-
694
- <pre>
695
- <code>
696
- const router = express.Router();
697
- router.post(
698
- '/register',
699
-
700
- HiSecure.validate([
701
- body("name")
702
- .notEmpty().withMessage("Name is required")
703
- .isLength({ min: 3 }).withMessage("Name must be at least 3 characters"),
704
-
705
- body("email")
706
- .notEmpty().withMessage("Email is required")
707
- .isEmail().withMessage("Invalid email format"),
708
-
709
- body("password")
710
- .notEmpty().withMessage("Password is required")
711
- .isLength({ min: 6 }).withMessage("Password must be at least 6 characters"),
712
- ]),
713
-
714
- registerUser
715
- );
716
-
717
- router.post(
718
- '/login',
719
-
720
- HiSecure.validate([
721
- body("email")
722
- .notEmpty().withMessage("Email is required")
723
- .isEmail().withMessage("Invalid email format"),
724
-
725
- body("password")
726
- .notEmpty().withMessage("Password is required")
727
- ]),
728
-
729
- HiSecure.rateLimit({ max: 5, windowMs: 15 * 60 * 1000 }),
730
-
731
- loginUser
732
- );
733
-
734
- router.get(
735
- '/profile',
736
- HiSecure.auth({ required: true }),
737
- getProfile
738
- );
710
+ };
739
711
 
740
- <!-- U can also add validator [Either zod Or express-validator] -->
741
- router.post('/create', HiSecure.auth({ required: true }), createTask)
742
- router.get('/get', HiSecure.auth({ required: true }), getTask)
743
- router.put('/:id', HiSecure.auth({ required: true }), updateTask)
744
- router.psot('/health',heatlh);
745
- </code>
746
- </pre>
712
+ </code></pre>
747
713
 
748
714
  <hr/>
749
715
 
750
- <h3>JWT Options (Optional)</h3>
751
716
 
752
- <p>
753
- HiSecure does not require JWT options for most use cases.
754
- Default configuration provided during initialization is sufficient.
755
- </p>
756
717
 
757
- <pre><code>HiSecure.getInstance({
758
- auth: {
759
- enabled: true,
760
- jwtSecret: process.env.JWT_SECRET,
761
- jwtExpiresIn: "1d"
762
- }
763
- });
764
- </code></pre>
718
+ <h3>Role-Based Protected Routes</h3>
765
719
 
766
- <p>
767
- Advanced JWT options can be provided only when needed:
768
- </p>
720
+ <pre><code>
721
+
722
+ const router = Router();
769
723
 
770
- <pre><code>HiSecure.jwt.sign(
771
- {
772
- userId: user.id,
773
- roles: user.roles
774
- },
775
- {
776
- issuer: "my-app",
777
- audience: ["web", "mobile"],
778
- subject: "user-auth",
779
- expiresIn: "7d"
780
- }
724
+ router.post(
725
+ "/",
726
+ HiSecure.auth({ roles: ["student", "admin"] }),
727
+ HiSecure.validate([
728
+ body("title").notEmpty(),
729
+ body("description").notEmpty(),
730
+ body("category").notEmpty()
731
+ ]),
732
+ createIssue
781
733
  );
782
- </code></pre>
783
734
 
784
- <p>
785
- JWT options are optional and intended for advanced authentication scenarios.
786
- </p>
735
+ router.get(
736
+ "/my",
737
+ HiSecure.auth({ required: true }),
738
+ getMyIssues
739
+ );
787
740
 
788
- <hr/>
741
+ router.post(
742
+ "/assign",
743
+ HiSecure.auth({ roles: ["admin"] }),
744
+ assignIssue
745
+ );
789
746
 
790
- <h3>Rules to Remember</h3>
747
+ router.put(
748
+ "/status",
749
+ HiSecure.auth({ roles: ["staff", "admin"] }),
750
+ updateIssueStatus
751
+ );
791
752
 
792
- <ul>
793
- <li>Initialize HiSecure once during application startup</li>
794
- <li>Use resetInstance only for tests or starter templates</li>
795
- <li>Do not initialize HiSecure inside controllers</li>
796
- <li>Google login is used for identity verification only</li>
797
- <li>Authorization is enforced using JWT payload and roles</li>
798
- </ul>
753
+ router.put(
754
+ "/close",
755
+ HiSecure.auth({ required: true }),
756
+ closeIssue
757
+ );
799
758
 
800
- <hr/>
759
+ export default router;
760
+
761
+
762
+ </code></pre>
801
763
 
802
764
 
803
765
  <h2>Summary</h2>
@@ -818,4 +780,4 @@ It focuses on correctness, safety and developer productivity.
818
780
  <p align="center">
819
781
  Advanced patterns, RBAC strategies, adapter extensions and deployment guides
820
782
  will be added over time.
821
- </p>
783
+ </p>