@hackthedev/dsync-ipsec 1.0.1 → 1.0.3

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.
@@ -0,0 +1,43 @@
1
+ name: Publish to npm
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+
8
+ permissions:
9
+ contents: write
10
+
11
+ jobs:
12
+ publish:
13
+ runs-on: ubuntu-latest
14
+
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ with:
18
+ persist-credentials: true
19
+
20
+ - name: Skip version bump commits
21
+ run: |
22
+ if git log -1 --pretty=%B | grep -q "chore: bump version"; then
23
+ echo "Version bump commit detected, skipping."
24
+ exit 0
25
+ fi
26
+
27
+ - uses: actions/setup-node@v4
28
+ with:
29
+ node-version: 20
30
+ registry-url: https://registry.npmjs.org/
31
+
32
+ - run: npm ci
33
+
34
+ - run: |
35
+ git config user.name "github-actions"
36
+ git config user.email "actions@github.com"
37
+ npm version patch -m "chore: bump version %s"
38
+ git push
39
+
40
+ - run: npm publish --access public
41
+ env:
42
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
43
+
package/README.md CHANGED
@@ -7,6 +7,10 @@ This library comes with features meant to prevent abuse in form of spam and othe
7
7
 
8
8
  The library was designed for usage with `express` and filtering abusive and (potentially) malicious traffic based on the IP address.
9
9
 
10
+ > [!IMPORTANT]
11
+ >
12
+ > It is highly recommended that you cache or store the API response!!!!
13
+
10
14
  ------
11
15
 
12
16
  ## Setup
package/index.mjs CHANGED
@@ -19,7 +19,9 @@ export default class dSyncIPSec {
19
19
  "::1",
20
20
  "127.0.0.1",
21
21
  "localhost"
22
- ]
22
+ ],
23
+ //
24
+ checkCache = null
23
25
  } = {}) {
24
26
 
25
27
  this.blockBogon = blockBogon;
@@ -30,72 +32,78 @@ export default class dSyncIPSec {
30
32
  this.blockVPN = blockVPN;
31
33
  this.blockTor = blockTor;
32
34
  this.blockAbuser = blockAbuser;
33
- this.blockedCountryCodes = blockedCountryCodes;
34
35
 
35
- this.urlWhitelist = new ArrayTools(whitelistedUrls)
36
- this.ipWhitelist = new ArrayTools(whitelistedIps)
37
- this.ipBlacklist = new ArrayTools(blacklistedIps)
38
- this.companyDomainWhitelist = new ArrayTools(whitelistedCompanyDomains)
39
- this.blockedCountriesByCode = new ArrayTools(blockedCountryCodes)
36
+ this.urlWhitelist = whitelistedUrls;
37
+ this.ipWhitelist = whitelistedIps;
38
+ this.ipBlacklist = blacklistedIps;
39
+ this.companyDomainWhitelist = whitelistedCompanyDomains;
40
+ this.blockedCountriesByCode = blockedCountryCodes;
41
+
42
+ this.checkCache = checkCache;
40
43
  }
41
44
 
42
45
  updateRule({
43
- blockBogon = null,
44
- blockDatacenter = null,
45
- blockSatelite = null,
46
- blockCrawler = null,
47
- blockProxy = null,
48
- blockVPN = null,
49
- blockTor = null,
50
- blockAbuser = null,
46
+ blockBogon = null,
47
+ blockDatacenter = null,
48
+ blockSatelite = null,
49
+ blockCrawler = null,
50
+ blockProxy = null,
51
+ blockVPN = null,
52
+ blockTor = null,
53
+ blockAbuser = null,
51
54
 
52
55
  whitelistedUrls = null,
53
56
  whitelistedIps = null,
54
57
  blockedCountryCodes = null,
55
58
  whitelistedCompanyDomains = null,
56
59
  blacklistedIps = null,
57
- }){
58
-
59
- if(blockBogon !== null) this.blockBogon = blockBogon
60
- if(blockDatacenter !== null) this.blockDatacenter = blockDatacenter
61
- if(blockSatelite !== null) this.blockSatelite =blockSatelite
62
- if(blockCrawler !== null) this.blockCrawler = blockCrawler
63
- if(blockProxy !== null) this.blockProxy = blockProxy
64
- if(blockVPN !== null) this.blockVPN = blockVPN
65
- if(blockTor !== null) this.blockTor = blockTor
66
- if(blockAbuser !== null) this.blockAbuser = blockAbuser
67
-
68
- if(whitelistedUrls !== null) this.urlWhitelist = new ArrayTools(whitelistedUrls)
69
- if(whitelistedIps !== null) this.ipWhitelist = new ArrayTools(whitelistedIps)
70
- if(blacklistedIps !== null) this.ipBlacklist = new ArrayTools(blacklistedIps)
71
- if(blockedCountryCodes !== null) this.blockedCountriesByCode = new ArrayTools(blockedCountryCodes)
60
+ }) {
61
+
62
+ if (blockBogon !== null) this.blockBogon = blockBogon
63
+ if (blockDatacenter !== null) this.blockDatacenter = blockDatacenter
64
+ if (blockSatelite !== null) this.blockSatelite = blockSatelite
65
+ if (blockCrawler !== null) this.blockCrawler = blockCrawler
66
+ if (blockProxy !== null) this.blockProxy = blockProxy
67
+ if (blockVPN !== null) this.blockVPN = blockVPN
68
+ if (blockTor !== null) this.blockTor = blockTor
69
+ if (blockAbuser !== null) this.blockAbuser = blockAbuser
70
+
71
+ if (whitelistedUrls !== null) this.urlWhitelist = whitelistedUrls
72
+ if (whitelistedIps !== null) this.ipWhitelist = whitelistedIps
73
+ if (blacklistedIps !== null) this.ipBlacklist = blacklistedIps
74
+ if (blockedCountryCodes !== null) this.blockedCountriesByCode = blockedCountryCodes
72
75
  }
73
76
 
74
77
 
75
- whitelistIP(ip, allowDuplicates = false){
76
- if(!ip) throw new Error("Unable to whitelist ip as no ip was provided.");
77
- if(!this.ipWhitelist.matches(ip) && !allowDuplicates) this.ipWhitelist.addEntry(ip);
78
- if(this.ipBlacklist.matches(ip)) this.ipBlacklist.removeEntry(ip);
78
+ whitelistIP(ip, allowDuplicates = false) {
79
+ if (!ip) throw new Error("Unable to whitelist ip as no ip was provided.");
80
+ if (!ArrayTools.matches(this.ipWhitelist, ip) && !allowDuplicates)
81
+ ArrayTools.addEntry(this.ipWhitelist, ip);
82
+ if (ArrayTools.matches(this.ipBlacklist, ip))
83
+ this.ipBlacklist = ArrayTools.removeEntry(this.ipBlacklist, ip);
79
84
  }
80
85
 
81
- blacklistIp(ip, allowDuplicates = false){
82
- if(!ip) throw new Error("Unable to blacklist ip as no ip was provided.");
83
- if(!this.ipBlacklist.matches(ip) && !allowDuplicates) this.ipBlacklist.addEntry(ip);
84
- if(this.ipWhitelist.matches(ip)) this.ipWhitelist.removeEntry(ip);
86
+ blacklistIp(ip, allowDuplicates = false) {
87
+ if (!ip) throw new Error("Unable to blacklist ip as no ip was provided.");
88
+ if (!ArrayTools.matches(this.ipBlacklist, ip) && !allowDuplicates)
89
+ ArrayTools.addEntry(this.ipBlacklist, ip);
90
+ if (ArrayTools.matches(this.ipWhitelist, ip))
91
+ this.ipWhitelist = ArrayTools.removeEntry(this.ipWhitelist, ip);
85
92
  }
86
93
 
87
- isBlacklistedIp(ip){
88
- if(!ip) throw new Error("Coudlnt check ip blacklist as no ip was provided.")
89
- return this.ipBlacklist.matches(ip);
94
+
95
+ isBlacklistedIp(ip) {
96
+ if (!ip) throw new Error("Coudlnt check ip blacklist as no ip was provided.")
97
+ return ArrayTools.matches(this.ipBlacklist, ip)
90
98
  }
91
99
 
92
- isWhitelistedIp(ip){
93
- if(!ip) throw new Error("Coudlnt check ip blacklist as no ip was provided.")
94
- return this.ipWhitelist.matches(ip);
100
+ isWhitelistedIp(ip) {
101
+ if (!ip) throw new Error("Coudlnt check ip blacklist as no ip was provided.")
102
+ return ArrayTools.matches(this.ipWhitelist, ip)
95
103
  }
96
104
 
97
- async filterExpressTraffic(app){
98
- if(!app) throw new Error("Unable to filter express traffic as no express app was provided.");
105
+ async filterExpressTraffic(app) {
106
+ if (!app) throw new Error("Unable to filter express traffic as no express app was provided.");
99
107
 
100
108
  app.use(async (req, res, next) => {
101
109
  const ipInfo = await this.lookupIP(this.getClientIp(req));
@@ -103,18 +111,18 @@ export default class dSyncIPSec {
103
111
 
104
112
  // whitelist some urls for functionality
105
113
  let reqPath = req.path;
106
- if(!reqPath) throw new Error("Unable to get request path from req parameter as it wasnt specified or null");
114
+ if (!reqPath) throw new Error("Unable to get request path from req parameter as it wasnt specified or null");
107
115
 
108
116
  // first check for ip blacklist
109
- if(this.ipBlacklist.matches(ipInfo?.ip)) return res.sendStatus(403);
117
+ if (ArrayTools.matches(this.ipBlacklist, ipInfo?.ip)) return res.sendStatus(403);
110
118
 
111
119
  // then we can check for whitelisted urls as these bypass normal checks
112
120
  // url whitelist
113
- if(this.urlWhitelist.matches(reqPath)) return next();
121
+ if (ArrayTools.matches(this.urlWhitelist, reqPath)) return next();
114
122
  // let whitelisted ips pass
115
- if(this.ipWhitelist.matches(ipInfo?.ip)) return next();
123
+ if (ArrayTools.matches(this.ipWhitelist, ipInfo?.ip)) return next();
116
124
  // company domain whitelist
117
- if(this.companyDomainWhitelist.matches(ipInfo?.company?.domain)) return next();
125
+ if (ArrayTools.matches(this.companyDomainWhitelist, ipInfo?.company?.domain)) return next();
118
126
 
119
127
  // looking kinda beautiful
120
128
  if (ipInfo?.is_bogon && this.blockBogon) return res.sendStatus(403);
@@ -128,7 +136,7 @@ export default class dSyncIPSec {
128
136
 
129
137
  if (
130
138
  ipInfo.location?.country_code &&
131
- this.blockedCountriesByCode.matches(ipInfo?.location?.country_code?.toLowerCase())
139
+ ArrayTools.matches(this.blockedCountriesByCode, ipInfo?.location?.country_code?.toLowerCase())
132
140
  ) return res.sendStatus(403);
133
141
 
134
142
  // continue
@@ -137,25 +145,30 @@ export default class dSyncIPSec {
137
145
  }
138
146
 
139
147
  getClientIp(req) {
140
- if(!req) throw new Error("Unable to get client ip from req parameter as it wasnt specified or null");
148
+ if (!req) throw new Error("Unable to get client ip from req parameter as it wasnt specified or null");
141
149
  const xf = req.headers["x-forwarded-for"];
142
150
  if (xf) return xf.split(",")[0].trim();
143
151
  return req.socket?.remoteAddress || req.connection?.remoteAddress;
144
152
  }
145
153
 
146
- async lookupIP(ip){
147
- if(!ip) throw new Error("Unable to lookup ip as it wasnt provided.")
154
+ async lookupIP(ip) {
155
+ if (!ip) throw new Error("Unable to lookup ip as it wasnt provided.")
148
156
 
149
157
  // if an ip is blacklisted we return with an error "reponse"
150
- if(this.isBlacklistedIp(ip)) return {error: `IP ${ip} was local.`};
158
+ if (this.isBlacklistedIp(ip)) return {error: `IP ${ip} was blacklisted.`};
159
+
160
+ // if we use cache we can skip the fetch
161
+ if (this.checkCache && typeof this.checkCache === "function") {
162
+ let ipInfo = await this.checkCache(ip);
163
+ if (ipInfo) return ipInfo;
164
+ }
151
165
 
152
166
  // make request to get ip info
153
167
  let ipRequest = await fetch(`https://api.ipapi.is/?q=${ip}`);
154
- if(ipRequest.status === 200){
168
+ if (ipRequest.status === 200) {
155
169
  let ipData = await ipRequest.json();
156
170
  return ipData;
157
- }
158
- else{
171
+ } else {
159
172
  return {error: "Failed to fetch IP data"};
160
173
  }
161
174
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hackthedev/dsync-ipsec",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "IP Based Security Library against Abuse",
5
5
  "license": "ISC",
6
6
  "author": "",