aip-master-node-sumit 1.0.6 → 1.0.7
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/index.js +40 -14
- package/package.json +2 -2
package/index.js
CHANGED
|
@@ -32,21 +32,43 @@ if (API_KEY) {
|
|
|
32
32
|
const aipGuard = (options = { requireLogin: true }) => {
|
|
33
33
|
return async (req, res, next) => {
|
|
34
34
|
|
|
35
|
-
//
|
|
35
|
+
// ==========================================
|
|
36
|
+
// 🛡️ LAYER 0: DYNAMIC CORS & SECURITY HEADERS
|
|
37
|
+
// ==========================================
|
|
38
|
+
const origin = req.headers.origin || req.headers.Origin;
|
|
39
|
+
|
|
40
|
+
if (origin) {
|
|
41
|
+
// If origin is present, dynamically echo it to satisfy strict browser credential policies
|
|
42
|
+
res.setHeader('Access-Control-Allow-Origin', origin);
|
|
43
|
+
res.setHeader('Access-Control-Allow-Credentials', 'true');
|
|
44
|
+
} else {
|
|
45
|
+
// Fallback for non-browser clients (like Postman or cURL)
|
|
46
|
+
res.setHeader('Access-Control-Allow-Origin', process.env.AIP_ALLOWED_ORIGIN || '*');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
res.setHeader('X-Frame-Options', 'DENY');
|
|
50
|
+
res.setHeader('X-Content-Type-Options', 'nosniff');
|
|
51
|
+
res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
|
|
52
|
+
|
|
53
|
+
// Handle preflight requests gracefully
|
|
54
|
+
if (req.method === 'OPTIONS') {
|
|
55
|
+
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS');
|
|
56
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-AIP-Token, X-Requested-With, Accept');
|
|
57
|
+
return res.status(200).end();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// ==========================================
|
|
61
|
+
// 🛡️ LAYER 1: INFRASTRUCTURE SHIELD
|
|
62
|
+
// ==========================================
|
|
36
63
|
const MAX_PAYLOAD_BYTES = 2 * 1024 * 1024;
|
|
37
64
|
|
|
38
65
|
if (req.headers['transfer-encoding'] && req.headers['transfer-encoding'].includes('chunked')) {
|
|
39
|
-
return res.status(411).
|
|
66
|
+
return res.status(411).json({ error: "AIP Infrastructure Shield: Chunked encoding rejected." });
|
|
40
67
|
}
|
|
41
68
|
|
|
42
69
|
if (req.headers['content-length'] && parseInt(req.headers['content-length']) > MAX_PAYLOAD_BYTES) {
|
|
43
|
-
return res.status(413).
|
|
70
|
+
return res.status(413).json({ error: "AIP Infrastructure Shield: Payload Too Large." });
|
|
44
71
|
}
|
|
45
|
-
|
|
46
|
-
res.setHeader('X-Frame-Options', 'DENY');
|
|
47
|
-
res.setHeader('X-Content-Type-Options', 'nosniff');
|
|
48
|
-
res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
|
|
49
|
-
res.setHeader('Access-Control-Allow-Origin', process.env.AIP_ALLOWED_ORIGIN || '*');
|
|
50
72
|
|
|
51
73
|
let token = req.query.token || (req.cookies && req.cookies.aip_session);
|
|
52
74
|
|
|
@@ -56,9 +78,11 @@ const aipGuard = (options = { requireLogin: true }) => {
|
|
|
56
78
|
token = req.headers['x-aip-token'];
|
|
57
79
|
}
|
|
58
80
|
|
|
59
|
-
//
|
|
81
|
+
// ==========================================
|
|
82
|
+
// 🛡️ LAYER 2: IDENTITY CHECK & RBAC
|
|
83
|
+
// ==========================================
|
|
60
84
|
if (options.requireLogin) {
|
|
61
|
-
if (!token) return res.status(401).
|
|
85
|
+
if (!token) return res.status(401).json({ error: "Unauthorized: Missing AIP Session Token" });
|
|
62
86
|
|
|
63
87
|
try {
|
|
64
88
|
const currentAction = req.method + " " + (req.baseUrl + req.path);
|
|
@@ -81,11 +105,13 @@ const aipGuard = (options = { requireLogin: true }) => {
|
|
|
81
105
|
res.clearCookie('aip_session');
|
|
82
106
|
}
|
|
83
107
|
|
|
84
|
-
return res.status(status === 401 ? 401 : 403).
|
|
108
|
+
return res.status(status === 401 ? 401 : 403).json({ error: errMsg });
|
|
85
109
|
}
|
|
86
110
|
}
|
|
87
111
|
|
|
88
|
-
//
|
|
112
|
+
// ==========================================
|
|
113
|
+
// 🛡️ LAYER 3: WAF THREAT SCAN
|
|
114
|
+
// ==========================================
|
|
89
115
|
try {
|
|
90
116
|
const payloadData = JSON.stringify({
|
|
91
117
|
body: req.body || {},
|
|
@@ -113,12 +139,12 @@ const aipGuard = (options = { requireLogin: true }) => {
|
|
|
113
139
|
});
|
|
114
140
|
|
|
115
141
|
if (wafRes.data.action === "block") {
|
|
116
|
-
return res.status(403).
|
|
142
|
+
return res.status(403).json({ error: `AIP Firewall Blocked Request: ${wafRes.data.reason}` });
|
|
117
143
|
}
|
|
118
144
|
|
|
119
145
|
} catch (error) {
|
|
120
146
|
console.error("WAF Engine Unreachable");
|
|
121
|
-
return res.status(500).
|
|
147
|
+
return res.status(500).json({ error: "Security verification failed." });
|
|
122
148
|
}
|
|
123
149
|
|
|
124
150
|
next();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aip-master-node-sumit",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "Enterprise-grade WAF and IAM security middleware for Node.js.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -17,4 +17,4 @@
|
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"axios": "^1.13.6"
|
|
19
19
|
}
|
|
20
|
-
}
|
|
20
|
+
}
|