@periodic/titanium 1.0.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.
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractClientIp = extractClientIp;
4
+ exports.normalizeIp = normalizeIp;
5
+ exports.getDefaultIdentifier = getDefaultIdentifier;
6
+ /**
7
+ * Extract client IP address from Express request
8
+ * Handles various proxy and load balancer scenarios
9
+ *
10
+ * Priority:
11
+ * 1. X-Forwarded-For header (first IP if multiple)
12
+ * 2. X-Real-IP header
13
+ * 3. Socket remote address
14
+ * 4. 'unknown' as fallback
15
+ *
16
+ * @param req - Express request object
17
+ * @returns IP address string
18
+ */
19
+ function extractClientIp(req) {
20
+ // X-Forwarded-For can contain multiple IPs (client, proxy1, proxy2)
21
+ // We want the first one (the original client)
22
+ const forwardedFor = req.headers["x-forwarded-for"];
23
+ if (forwardedFor) {
24
+ const ips = Array.isArray(forwardedFor) ? forwardedFor[0] : forwardedFor;
25
+ const firstIp = ips.split(",")[0].trim();
26
+ if (firstIp) {
27
+ return firstIp;
28
+ }
29
+ }
30
+ // X-Real-IP is set by some proxies (nginx)
31
+ const realIp = req.headers["x-real-ip"];
32
+ if (realIp && typeof realIp === "string") {
33
+ return realIp.trim();
34
+ }
35
+ // Direct connection IP
36
+ const socketIp = req.socket.remoteAddress;
37
+ if (socketIp) {
38
+ return socketIp;
39
+ }
40
+ // Fallback
41
+ return "unknown";
42
+ }
43
+ /**
44
+ * Normalize IP address for consistent key generation
45
+ * Handles IPv6 to IPv4 mapping
46
+ *
47
+ * @param ip - IP address string
48
+ * @returns Normalized IP address
49
+ */
50
+ function normalizeIp(ip) {
51
+ // Convert IPv6-mapped IPv4 address to IPv4
52
+ // ::ffff:192.168.1.1 -> 192.168.1.1
53
+ if (ip.startsWith("::ffff:")) {
54
+ return ip.substring(7);
55
+ }
56
+ return ip;
57
+ }
58
+ /**
59
+ * Extract and normalize client identifier from request
60
+ *
61
+ * @param req - Express request object
62
+ * @returns Normalized IP address
63
+ */
64
+ function getDefaultIdentifier(req) {
65
+ const ip = extractClientIp(req);
66
+ return normalizeIp(ip);
67
+ }
68
+ //# sourceMappingURL=ip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ip.js","sourceRoot":"","sources":["../../src/utils/ip.ts"],"names":[],"mappings":";;AAeA,0CA0BC;AASD,kCAQC;AAQD,oDAGC;AAnED;;;;;;;;;;;;GAYG;AACH,SAAgB,eAAe,CAAC,GAAY;IAC1C,oEAAoE;IACpE,8CAA8C;IAC9C,MAAM,YAAY,GAAG,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACpD,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;QACzE,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACzC,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,OAAO,CAAC;QACjB,CAAC;IACH,CAAC;IAED,2CAA2C;IAC3C,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IACxC,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QACzC,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC;IAED,uBAAuB;IACvB,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC;IAC1C,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,WAAW;IACX,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,WAAW,CAAC,EAAU;IACpC,2CAA2C;IAC3C,oCAAoC;IACpC,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IACzB,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,oBAAoB,CAAC,GAAY;IAC/C,MAAM,EAAE,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IAChC,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC;AACzB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "@periodic/titanium",
3
+ "version": "1.0.0",
4
+ "description": "Production-ready Redis-backed rate limiting middleware for Express with TypeScript support, fail-safe design, and flexible configuration",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "prepublishOnly": "npm run build",
10
+ "test": "jest",
11
+ "lint": "eslint src --ext .ts",
12
+ "format": "prettier --write \"src/**/*.ts\""
13
+ },
14
+ "keywords": [
15
+ "rate-limit",
16
+ "rate-limiting",
17
+ "ratelimit",
18
+ "express",
19
+ "middleware",
20
+ "redis",
21
+ "throttle",
22
+ "api",
23
+ "ddos",
24
+ "typescript",
25
+ "security"
26
+ ],
27
+ "author": "Uday Thakur <udaythakurwork@gmail.com>",
28
+ "license": "MIT",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/thaku7469/periodic-titanium.git"
32
+ },
33
+ "bugs": {
34
+ "url": "https://github.com/thaku7469/periodic-titanium/issues"
35
+ },
36
+ "homepage": "https://github.com/thaku7469/periodic-titanium#readme",
37
+ "publishConfig": {
38
+ "access": "public"
39
+ },
40
+ "files": [
41
+ "dist",
42
+ "README.md",
43
+ "LICENSE"
44
+ ],
45
+ "engines": {
46
+ "node": ">=14.0.0"
47
+ },
48
+ "peerDependencies": {
49
+ "express": "^4.0.0 || ^5.0.0",
50
+ "redis": "^4.0.0"
51
+ },
52
+ "devDependencies": {
53
+ "@types/express": "^4.17.21",
54
+ "@types/jest": "^29.5.11",
55
+ "@types/node": "^20.10.6",
56
+ "@typescript-eslint/eslint-plugin": "^6.17.0",
57
+ "@typescript-eslint/parser": "^6.17.0",
58
+ "eslint": "^8.56.0",
59
+ "jest": "^29.7.0",
60
+ "prettier": "^3.1.1",
61
+ "ts-jest": "^29.1.1",
62
+ "typescript": "^5.3.3"
63
+ }
64
+ }