File size: 5,137 Bytes
99c40f3
89e56d1
 
f576901
fcd016f
89e56d1
dd7c356
f576901
 
 
 
 
 
 
 
708fb5f
f576901
 
 
 
280c5dd
5607a19
 
 
280c5dd
 
 
 
f576901
33c0d7a
 
fcd016f
f576901
 
 
 
 
 
 
 
 
337ec73
 
c1fb847
 
337ec73
 
c1fb847
 
 
337ec73
 
 
c1fb847
 
 
 
 
 
 
337ec73
 
 
c1fb847
337ec73
 
 
c1fb847
337ec73
 
c1fb847
337ec73
 
 
 
 
59c12a7
 
e6acbde
 
59c12a7
 
 
 
 
e6acbde
59c12a7
 
 
5607a19
 
 
 
59c12a7
 
 
 
 
 
84669c7
89e56d1
c3052e3
dc80896
84669c7
dc80896
 
c3052e3
89e56d1
521427a
f1436b2
89e56d1
 
f1436b2
dc80896
f1436b2
 
 
 
 
 
59c12a7
e151afc
21cab6c
 
e6acbde
21cab6c
e151afc
21cab6c
 
e151afc
 
 
6f9e59b
21cab6c
e151afc
 
 
 
 
 
 
 
 
 
21cab6c
06932c2
e151afc
 
 
6f9e59b
e151afc
21cab6c
e151afc
 
c82fac4
 
 
 
ba0cefc
 
 
 
 
 
 
 
e151afc
 
 
 
 
 
21cab6c
 
6222fc9
59c12a7
 
 
337ec73
f576901
c1aabc1
59c12a7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
import { Database } from '../database/database.js';
import { MongoStorage } from "@canmertinyo/rate-limiter-mongo";
import { rateLimiter } from "@canmertinyo/rate-limiter-core";
import { ApiKey } from '../models.js';
import { TelegramUseLogNotif } from '../lib/all.js';
import * as config from '../config.js';

const authenticateApiKeyPremium = async (req, res, next) => {
  const apiKey = req.headers['x-api-key'];

  if (!apiKey) {
    return res.status(401).json({ error: 'Premium API Key required' });
  }

  try {
    const keyData = await ApiKey.findOne({ key: apiKey });
    if (!keyData) {
      return res.status(403).json({ error: 'Invalid or non-premium API Key' });
    }

    if (keyData.is_banned) {
      return res.status(403).json({ error: 'Banned API Key' });
    }

    if (keyData.is_expired) {
      return res.status(403).json({ error: 'API Key is expired' });
    }

    if (keyData.expiresAt && new Date() > keyData.expiresAt) {
      keyData.is_expired = true;
      await keyData.save();
      await TelegramUseLogNotif(keyData.owner, keyData.key);
      return res.status(403).json({ error: 'Premium API Key has expired' });
    }

    next();
  } catch (err) {
    res.status(500).json({ error: 'Server error' });
  }
};

const authenticateApiKeyDev = async (req, res, next) => {
  const apiKey = req.headers['x-api-key'];
  const xhacker = req.headers['x-hacker-bypass-v1'];

  const dbClient = new Database("AkenoXJs");
  const db = dbClient.collection("api_keys_dev");

  if (!apiKey && !xhacker) {
    return res.status(401).json({ error: 'API Key or bypass token required' });
  }

  try {
    if (xhacker === "@xpushz") {
      console.log("Bypass activated via x-hacker-bypass-v1");
      return next();
    }


    const keyDoc = await db.findOne({ key: apiKey });
    if (!keyDoc) {
      return res.status(403).json({ error: 'Invalid API Key Dev' });
    }

    if (keyDoc.is_banned === true) {
      return res.status(403).json({ error: 'Banned API Key' });
    }

    next();
  } catch (err) {
    console.error("Error in authenticateApiKeyDev:", err);
    res.status(500).json({ error: 'Server error' });
  }
};


const authenticateApiKey = async (req, res, next) => {
  const apiKey = req.headers['x-api-key'];
  const dbClient = new Database("AkenoXJs");
  const db = dbClient.collection("api_keys");
  if (!apiKey) {
    return res.status(401).json({ error: 'API Key required' });
  }

  try {
    const keyDoc = await db.findOne({key: apiKey});
    if (!keyDoc) {
      return res.status(403).json({ error: 'Invalid API Key' });
    }
    if (keyDoc.is_banned === true) {
      return res.status(403).json({ error: 'Banned API Key' });
    }
  
    next();
  } catch (err) {
    res.status(500).json({ error: 'Server error' });
  }
};


const apiLimiter = rateLimiter({
  /*
  store: new MongoStore({
    uri: dbUrls,
    collectionName: "rateLimits",
  }),
  */
  ms: 2 * 60 * 1000,
  maxRequest: 100,
  keyGenerator: (req) => req.headers["x-api-key"],
  // standardHeaders: true,
  // legacyHeaders: false,
  message: (req, res) => {
    const retryAfterMs = res.getHeaders()["retry-after"] * 1000 || 2 * 60 * 1000;
    const remainingSeconds = Math.ceil(retryAfterMs / 1000);
    const remainingMinutes = Math.floor(remainingSeconds / 60);
    return {
      error: `Too many requests from this API Key. Try again later: ${remainingMinutes}m ${remainingSeconds % 60}s.`
    };
  }
});

class CheckMilWare {
  constructor() {
    this.dbClient = new Database("AkenoXJs");
  }

  async handle(req, res, next) {
    try {
      const xForwardedFor = req.headers['x-forwarded-for'];
      const xRealIP = req.headers['x-real-ip'];
      const cfConnectingIP = req.headers['cf-connecting-ip'];
      let realIP = req.ip;

      if (xForwardedFor) {
        realIP = xForwardedFor.split(',')[0].trim();
      } else if (xRealIP) {
        realIP = xRealIP;
      } else if (cfConnectingIP) {
        realIP = cfConnectingIP;
      }

      req.realIP = realIP;

      const isBlocked = await this.dbClient.CheckIsBlocked(realIP);
      if (isBlocked && isBlocked.blocked) {
        return res.status(403).send("Access denied: IP is blocked");
      }

      if (req.path === '/.env') {
        console.log("Check path /env");
        await this.dbClient.AddIpisBlocked(realIP);
        return res.status(403).send("Access denied: IP is blocked..");
      }
      if (req.path.endsWith('.php')) {
        return res.status(403).send('Access to .php files is forbidden');
      }

      res.on("finish", function() {
        console.log(`Real IP address is: ${realIP}
        path method: ${req.path}
        method: ${req.method}
        statusCode: ${res.statusCode}
        header used: ${xForwardedFor ? "x-forwarded-for" : xRealIP ? "x-real-ip" : cfConnectingIP ? "cf-connecting-ip" : "req.ip"}
        `);
      });

      next();
    } catch (error) {
      console.error("Error in middleware: " + error);
      res.status(500).send("Something bad happened");
    }
  }
}

export { 
  CheckMilWare,
  authenticateApiKey,
  authenticateApiKeyDev,
  authenticateApiKeyPremium,
  apiLimiter
};