@starklabs/backend-core 1.1.0 → 1.2.0

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 (42) hide show
  1. package/.env.example +21 -0
  2. package/README.md +7 -7
  3. package/dist/js/config/cloudinary.js +18 -0
  4. package/dist/js/config/config.js +11 -0
  5. package/dist/js/config/duration.js +22 -0
  6. package/dist/js/core/app.js +122 -0
  7. package/dist/js/core/auth/OTP.js +115 -0
  8. package/dist/js/core/auth/auth.controller.js +63 -0
  9. package/dist/js/core/auth/auth.service.js +290 -0
  10. package/dist/js/core/auth/auth.validation.js +95 -0
  11. package/dist/js/core/crud/crud.controller.js +95 -0
  12. package/dist/js/core/crud/crud.service.js +296 -0
  13. package/dist/js/core/index.js +3 -0
  14. package/dist/js/index.js +44 -55
  15. package/dist/js/lib/db.js +40 -0
  16. package/dist/js/lib/field.types.js +174 -0
  17. package/dist/js/lib/model.factory.js +19 -0
  18. package/dist/js/lib/model.registry.js +4 -0
  19. package/dist/js/lib/schema.builder.js +35 -0
  20. package/dist/js/lib/zod.validations.js +247 -0
  21. package/dist/js/middleware/auth.middleware.js +51 -0
  22. package/dist/js/middleware/error.middleware.js +28 -0
  23. package/dist/js/middleware/socket.middleware.js +29 -0
  24. package/dist/js/utils/AppLog.js +2 -1
  25. package/dist/js/utils/deleteFile.js +22 -0
  26. package/dist/js/utils/index.js +10 -1
  27. package/dist/js/utils/jwt.js +12 -20
  28. package/dist/js/utils/libsodium.js +19 -3
  29. package/dist/js/utils/rateLimiter.js +25 -0
  30. package/dist/js/utils/uploadFile.js +43 -0
  31. package/handlerMap.js +33 -0
  32. package/package.json +18 -5
  33. package/test.js +36 -0
  34. package/dist/cjs/db.cjs +0 -17
  35. package/dist/cjs/index.cjs +0 -59
  36. package/dist/cjs/utils/AppError.cjs +0 -13
  37. package/dist/cjs/utils/AppLog.cjs +0 -13
  38. package/dist/cjs/utils/asyncHandler.cjs +0 -6
  39. package/dist/cjs/utils/jwt.cjs +0 -38
  40. package/dist/cjs/utils/libsodium.cjs +0 -145
  41. package/dist/cjs/utils/successResponse.cjs +0 -13
  42. package/dist/js/db.js +0 -19
package/test.js ADDED
@@ -0,0 +1,36 @@
1
+ import StarkCore, { startServer } from "./dist/js/index.js";
2
+ import "dotenv/config";
3
+
4
+ import {
5
+ authCollection,
6
+ usersCollection,
7
+ productCollection,
8
+ healthCollection,
9
+ } from "./collections/index.js";
10
+
11
+ const core = StarkCore.create({
12
+ port: Number.parseInt(process.env.PORT),
13
+ collections: [
14
+ authCollection,
15
+ usersCollection,
16
+ productCollection,
17
+ healthCollection,
18
+ ],
19
+ apiVersion: process.env.API_VERSION,
20
+ jwtSecret: process.env.JWT_SECRET,
21
+ isOffline: process.env.ISOFFLINE === "true",
22
+ masterKey: process.env.MASTER_KEY,
23
+ ENV: process.env.ENV,
24
+ tokenExpiry: process.env.TOKEN_EXPIRY,
25
+ internalRoles: JSON.parse(process.env.INTERNAL_ROLES),
26
+ resendAPIKey: process.env.RESEND_API_KEY,
27
+ rateLimitDuration: process.env.RATE_LIMIT_DURATION,
28
+ maxReqLimit: Number.parseInt(process.env.RATE_LIMIT_REQ),
29
+ rateLimitMsg: process.env.RATE_LIMIT_MSG,
30
+ cloudinaryAPIKey: process.env.CLOUDINARY_API_KEY,
31
+ cloudinaryCloudName: process.env.CLOUDINARY_CLOUD_NAME,
32
+ cloudinaryAPISecret: process.env.CLOUDINARY_API_SECRET,
33
+ cloudinaryFolderName: process.env.CLOUDINARY_FOLDER_NAME,
34
+ });
35
+
36
+ startServer();
package/dist/cjs/db.cjs DELETED
@@ -1,17 +0,0 @@
1
- const mongoose = require("mongoose");
2
- const AppLog = require("./utils/AppLog.cjs");
3
-
4
- // connecting to db
5
- const connectDB = async (uri, db) => {
6
- const mongodbUri = uri || "mongodb://localhost:27017";
7
- try {
8
- await mongoose.connect(`${mongodbUri}/${db || "test"}`);
9
- AppLog("check", "db.js", "Connected successfully!");
10
- } catch (error) {
11
- AppLog("X", "db.js", "Error while connecting!");
12
- AppLog("X", "db.js", error.message);
13
- }
14
- };
15
-
16
- // export
17
- module.exports = connectDB;
@@ -1,59 +0,0 @@
1
- const connectDB = require("./db.cjs");
2
- const { seal, unSeal, generateMasterKey, generateJWTSecret, hash, verifyHash } = require("./utils/libsodium.cjs");
3
- const { signJWT, verifyJWT } = require("./utils/jwt.cjs");
4
-
5
- const privateKeys = new WeakMap();
6
-
7
- class StarkAuth {
8
- constructor(config) {
9
- privateKeys.set(this, {
10
- _masterKey: config.MASTER_KEY,
11
- _JWT_SECRET: config.JWT_SECRET,
12
- _JWT_EXPIRY: config.JWT_EXPIRY,
13
- });
14
- }
15
-
16
- static async create(config) {
17
- await connectDB(config.MONGO_URI, config.DB_NAME);
18
- return new StarkAuth(config);
19
- }
20
-
21
- async encrypt(str) {
22
- const { _masterKey } = privateKeys.get(this);
23
- return seal(str, _masterKey);
24
- }
25
-
26
- async decrypt(str, nonce, publicKey, securedPrivateKey) {
27
- const { _masterKey } = privateKeys.get(this);
28
- return unSeal(str, nonce, publicKey, securedPrivateKey, _masterKey);
29
- }
30
-
31
- signJWT(payLoad) {
32
- const { _JWT_SECRET, _JWT_EXPIRY } = privateKeys.get(this);
33
- return signJWT(payLoad, _JWT_SECRET, _JWT_EXPIRY);
34
- }
35
-
36
- verifyJWT(token) {
37
- const { _JWT_SECRET } = privateKeys.get(this);
38
- return verifyJWT(token, _JWT_SECRET);
39
- }
40
- }
41
-
42
- module.exports = StarkAuth;
43
-
44
- const crypto = {
45
- generateMasterKey,
46
- generateJWTSecret,
47
- hash,
48
- verifyHash,
49
- };
50
-
51
- const AppError = require("./utils/AppError.cjs");
52
- const AppLog = require("./utils/AppLog.cjs");
53
- const asyncHandler = require("./utils/asyncHandler.cjs");
54
-
55
- module.exports = StarkAuth;
56
- module.exports.crypto = crypto;
57
- module.exports.AppError = AppError;
58
- module.exports.AppLog = AppLog;
59
- module.exports.asyncHandler = asyncHandler;
@@ -1,13 +0,0 @@
1
- // custom error class
2
- class AppError extends Error {
3
- // constructor
4
- constructor(message, statusCode) {
5
- // calling parent constructor
6
- super(message);
7
-
8
- this.statusCode = statusCode;
9
- this.isOperational = true;
10
- }
11
- }
12
-
13
- module.exports = AppError;
@@ -1,13 +0,0 @@
1
- // emojis object
2
- const emojis = {
3
- check: "✅",
4
- X: "❌",
5
- };
6
-
7
- // console logs
8
- const AppLog = (emoji, file, message) => {
9
- console.log(`${emojis[emoji]} [${file}] ${message}`);
10
- };
11
-
12
- // export
13
- module.exports = AppLog;
@@ -1,6 +0,0 @@
1
- // async handler wrapper
2
- const asyncHandler = (fn) => async (req, res, next) => {
3
- Promise.resolve(fn(req, res, next)).catch(next);
4
- };
5
-
6
- module.exports = asyncHandler;
@@ -1,38 +0,0 @@
1
- const jwt = require("jsonwebtoken");
2
- const AppError = require("./AppError.cjs");
3
-
4
- const EXPIRY = {
5
- "2m": 1000 * 60 * 2,
6
- "10m": 1000 * 60 * 10,
7
- "1h": 1000 * 60 * 60,
8
- "6h": 1000 * 60 * 60 * 6,
9
- "12h": 1000 * 60 * 60 * 12,
10
- "1d": 1000 * 60 * 60 * 24,
11
- "3d": 1000 * 60 * 60 * 24 * 3,
12
- "7d": 1000 * 60 * 60 * 24 * 7,
13
- "14d": 1000 * 60 * 60 * 24 * 14,
14
- "30d": 1000 * 60 * 60 * 24 * 30,
15
- };
16
-
17
- const getExpiry = (key) => {
18
- if (!EXPIRY[key]) throw new Error("Invalid expiry key");
19
- return EXPIRY[key];
20
- };
21
-
22
- const signJWT = (payLoad, JWT_SECRET, JWT_EXPIRY) => {
23
- try {
24
- return jwt.sign(payLoad, JWT_SECRET, { expiresIn: JWT_EXPIRY });
25
- } catch (error) {
26
- throw new AppError(error.message);
27
- }
28
- };
29
-
30
- const verifyJWT = (token, JWT_SECRET) => {
31
- try {
32
- return jwt.verify(token, JWT_SECRET);
33
- } catch (error) {
34
- throw new AppError("Invalid or expired token", 401);
35
- }
36
- };
37
-
38
- module.exports = { EXPIRY, signJWT, verifyJWT };
@@ -1,145 +0,0 @@
1
- const sodium = require("libsodium-wrappers-sumo");
2
- const AppError = require("./AppError.cjs");
3
-
4
- // Hash password
5
- const hash = async (password) => {
6
- await sodium.ready;
7
-
8
- const salt = sodium.randombytes_buf(sodium.crypto_pwhash_SALTBYTES);
9
-
10
- const hashStr = sodium.crypto_pwhash(
11
- 32,
12
- password,
13
- salt,
14
- sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE,
15
- sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE,
16
- sodium.crypto_pwhash_ALG_DEFAULT
17
- );
18
-
19
- // store salt + hashStr together
20
- return sodium.to_base64(salt) + ":" + sodium.to_base64(hashStr);
21
- };
22
-
23
- // verifyPassword
24
- const verifyHash = async (password, storedHash) => {
25
- await sodium.ready;
26
-
27
- const [saltB64, hashB64] = storedHash.split(":");
28
-
29
- const salt = sodium.from_base64(saltB64);
30
- const originalHash = sodium.from_base64(hashB64);
31
-
32
- const testHash = sodium.crypto_pwhash(
33
- 32,
34
- password,
35
- salt,
36
- sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE,
37
- sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE,
38
- sodium.crypto_pwhash_ALG_DEFAULT
39
- );
40
-
41
- return sodium.memcmp(originalHash, testHash);
42
- };
43
-
44
- // generate master key
45
- const generateMasterKey = async () => {
46
- await sodium.ready;
47
-
48
- const key = sodium.crypto_secretbox_keygen();
49
-
50
- const base64Key = sodium.to_base64(
51
- key,
52
- sodium.base64_variants.ORIGINAL
53
- );
54
-
55
-
56
- console.log(base64Key);
57
- return base64Key
58
- };
59
-
60
- // generate JWT secret
61
- const generateJWTSecret = async () => {
62
- await sodium.ready;
63
-
64
- const secret = sodium.randombytes_buf(64);
65
-
66
- const base64Secret = sodium.to_base64(secret, sodium.base64_variants.ORIGINAL);
67
- console.log(base64Secret);
68
- return base64Secret;
69
- };
70
-
71
- // seal
72
- const seal = async (string, masterKey) => {
73
- try {
74
- await sodium.ready;
75
-
76
- const keyPair = sodium.crypto_box_keypair();
77
- const strBytes = sodium.from_string(string);
78
-
79
- const encrypted = sodium.crypto_box_seal(strBytes, keyPair.publicKey);
80
- const str = sodium.to_base64(encrypted);
81
-
82
- masterKey = sodium.from_base64(masterKey, sodium.base64_variants.ORIGINAL);
83
- let nonce = sodium.randombytes_buf(24);
84
-
85
- const pk = sodium.crypto_secretbox_easy(
86
- keyPair.privateKey,
87
- nonce,
88
- masterKey
89
- );
90
-
91
- nonce = sodium.to_base64(nonce);
92
-
93
- const securedPrivateKey = sodium.to_base64(pk);
94
- const publicKey = sodium.to_base64(keyPair.publicKey);
95
-
96
- return {
97
- str,
98
- nonce,
99
- publicKey,
100
- securedPrivateKey,
101
- };
102
- } catch (error) {
103
- console.log(error.message);
104
- throw new AppError("Error while encrypting");
105
- }
106
- };
107
-
108
- // unSeal
109
- const unSeal = async (str, nonce, publicKey, securedPrivateKey, masterKey) => {
110
- try {
111
- if (!str || !nonce || !publicKey || !securedPrivateKey)
112
- throw new AppError(
113
- "Str, nonce, public key and secured private key are required"
114
- );
115
-
116
- await sodium.ready;
117
-
118
- masterKey = sodium.from_base64(masterKey, sodium.base64_variants.ORIGINAL);
119
- nonce = sodium.from_base64(nonce);
120
- securedPrivateKey = sodium.from_base64(securedPrivateKey);
121
- publicKey = sodium.from_base64(publicKey);
122
- str = sodium.from_base64(str);
123
-
124
- const privateKey = sodium.crypto_secretbox_open_easy(
125
- securedPrivateKey,
126
- nonce,
127
- masterKey
128
- );
129
-
130
- const decrypted = sodium.crypto_box_seal_open(str, publicKey, privateKey);
131
- return sodium.to_string(decrypted);
132
- } catch (error) {
133
- console.log(error.message);
134
- throw new AppError("Error while decrypting");
135
- }
136
- };
137
-
138
- module.exports = {
139
- hash,
140
- verifyHash,
141
- generateMasterKey,
142
- generateJWTSecret,
143
- seal,
144
- unSeal,
145
- };
@@ -1,13 +0,0 @@
1
- // success response to client
2
- const successResponse = (res, data, status) => {
3
- const response = { success: true };
4
-
5
- if (data) {
6
- response.data = data;
7
- }
8
-
9
- res.status(status).json(response);
10
- };
11
-
12
- // export
13
- module.exports = successResponse;
package/dist/js/db.js DELETED
@@ -1,19 +0,0 @@
1
- // module imports
2
- import mongoose from "mongoose";
3
-
4
- import AppLog from "./utils/AppLog.js";
5
-
6
- // connecting to db
7
- const connectDB = async (uri, db) => {
8
- const mongodbUri = uri || "mongodb://localhost:27017";
9
- try {
10
- AppLog("check", "db.js", "Connected successfully!");
11
- return await mongoose.connect(`${mongodbUri}/${db || "test"}`);
12
- } catch (error) {
13
- AppLog("X", "db.js", "Error while connecting!");
14
- AppLog("X", "db.js", error.message);
15
- }
16
- };
17
-
18
- // export
19
- export default connectDB;