@adaptic/backend-legacy 0.0.46 → 0.0.47

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.
@@ -1,12 +1,16 @@
1
1
  import { Request, Response, NextFunction } from 'express';
2
2
  /**
3
- * Rate limiter for GraphQL endpoint
4
- * Allows 1000 requests per 15 minutes by default (configurable via RATE_LIMIT_MAX env var)
3
+ * Rate limiter for GraphQL endpoint.
4
+ *
5
+ * Authenticated requests: 1000 requests per 15 minutes (configurable via RATE_LIMIT_MAX)
6
+ * Unauthenticated requests: 200 requests per 15 minutes (configurable via RATE_LIMIT_MAX_UNAUTH)
5
7
  */
6
8
  export declare const graphqlRateLimiter: (req: Request, res: Response, next: NextFunction) => void;
7
9
  /**
8
- * Rate limiter for authentication endpoints
9
- * Allows 50 requests per 15 minutes (stricter for auth)
10
+ * Rate limiter for authentication endpoints.
11
+ *
12
+ * Authenticated requests: 50 requests per 15 minutes
13
+ * Unauthenticated requests: 20 requests per 15 minutes
10
14
  */
11
15
  export declare const authRateLimiter: (req: Request, res: Response, next: NextFunction) => void;
12
16
  //# sourceMappingURL=rate-limiter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rate-limiter.d.ts","sourceRoot":"","sources":["../../../src/middleware/rate-limiter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAoE1D;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QArChB,OAAO,OAAO,QAAQ,QAAQ,YAAY,KAAG,IA2C1D,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,eAAe,QAjDb,OAAO,OAAO,QAAQ,QAAQ,YAAY,KAAG,IAuD1D,CAAC"}
1
+ {"version":3,"file":"rate-limiter.d.ts","sourceRoot":"","sources":["../../../src/middleware/rate-limiter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAuG1D;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,QA5ChB,OAAO,OAAO,QAAQ,QAAQ,YAAY,KAAG,IAmD1D,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,eAAe,QA3Db,OAAO,OAAO,QAAQ,QAAQ,YAAY,KAAG,IAkE1D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../../../src/middleware/rate-limiter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../../../src/middleware/rate-limiter.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,32 @@
1
1
  // Integration: add to server.ts - app.use('/graphql', graphqlRateLimiter) and app.use('/auth', authRateLimiter)
2
2
  /**
3
- * Creates a simple in-memory rate limiter middleware
3
+ * Checks whether a request carries a valid-looking authentication token.
4
+ * Does not verify the token -- only checks for its presence in the
5
+ * Authorization header as a Bearer token with three dot-separated parts
6
+ * (standard JWT structure).
7
+ */
8
+ function isAuthenticated(req) {
9
+ const authHeader = req.headers.authorization || '';
10
+ if (!authHeader.startsWith('Bearer ')) {
11
+ return false;
12
+ }
13
+ const token = authHeader.slice(7);
14
+ // Google OAuth tokens (ya29.) and JWTs (three dot-separated segments) count
15
+ if (token.startsWith('ya29.')) {
16
+ return true;
17
+ }
18
+ return token.split('.').length === 3;
19
+ }
20
+ /**
21
+ * Creates a simple in-memory rate limiter middleware with separate limits
22
+ * for authenticated and unauthenticated requests.
23
+ *
24
+ * Response headers (when standardHeaders is enabled):
25
+ * X-RateLimit-Limit - maximum requests allowed in the current window
26
+ * X-RateLimit-Remaining - requests remaining in the current window
27
+ * X-RateLimit-Reset - seconds until the current window resets
28
+ * Retry-After - seconds to wait before retrying (only on 429)
29
+ *
4
30
  * @param config - Rate limit configuration
5
31
  * @returns Express middleware function
6
32
  */
@@ -17,26 +43,31 @@ function createRateLimiter(config) {
17
43
  }, 60000);
18
44
  return (req, res, next) => {
19
45
  const identifier = req.ip || req.connection.remoteAddress || 'unknown';
46
+ const authenticated = isAuthenticated(req);
47
+ const effectiveMax = authenticated ? config.maxAuthenticated : config.maxUnauthenticated;
48
+ const storeKey = `${identifier}:${authenticated ? 'auth' : 'anon'}`;
20
49
  const now = Date.now();
21
- if (!store[identifier] || store[identifier].resetTime < now) {
22
- store[identifier] = {
50
+ if (!store[storeKey] || store[storeKey].resetTime < now) {
51
+ store[storeKey] = {
23
52
  count: 1,
24
53
  resetTime: now + config.windowMs,
25
54
  };
26
55
  }
27
56
  else {
28
- store[identifier].count += 1;
57
+ store[storeKey].count += 1;
29
58
  }
30
- const current = store[identifier];
31
- const remaining = Math.max(0, config.max - current.count);
32
- const resetTime = Math.ceil((current.resetTime - now) / 1000);
59
+ const current = store[storeKey];
60
+ const remaining = Math.max(0, effectiveMax - current.count);
61
+ const resetSeconds = Math.ceil((current.resetTime - now) / 1000);
33
62
  // Add rate limit headers
34
63
  if (config.standardHeaders !== false) {
35
- res.setHeader('X-RateLimit-Limit', config.max.toString());
64
+ res.setHeader('X-RateLimit-Limit', effectiveMax.toString());
36
65
  res.setHeader('X-RateLimit-Remaining', remaining.toString());
37
- res.setHeader('X-RateLimit-Reset', resetTime.toString());
66
+ res.setHeader('X-RateLimit-Reset', resetSeconds.toString());
38
67
  }
39
- if (current.count > config.max) {
68
+ if (current.count > effectiveMax) {
69
+ // Include Retry-After header on 429 responses (RFC 6585 / RFC 7231)
70
+ res.setHeader('Retry-After', resetSeconds.toString());
40
71
  res.status(429).json(config.message);
41
72
  return;
42
73
  }
@@ -44,23 +75,29 @@ function createRateLimiter(config) {
44
75
  };
45
76
  }
46
77
  /**
47
- * Rate limiter for GraphQL endpoint
48
- * Allows 1000 requests per 15 minutes by default (configurable via RATE_LIMIT_MAX env var)
78
+ * Rate limiter for GraphQL endpoint.
79
+ *
80
+ * Authenticated requests: 1000 requests per 15 minutes (configurable via RATE_LIMIT_MAX)
81
+ * Unauthenticated requests: 200 requests per 15 minutes (configurable via RATE_LIMIT_MAX_UNAUTH)
49
82
  */
50
83
  export const graphqlRateLimiter = createRateLimiter({
51
84
  windowMs: 15 * 60 * 1000, // 15 minutes
52
- max: parseInt(process.env.RATE_LIMIT_MAX || '1000', 10),
85
+ maxAuthenticated: parseInt(process.env.RATE_LIMIT_MAX || '1000', 10),
86
+ maxUnauthenticated: parseInt(process.env.RATE_LIMIT_MAX_UNAUTH || '200', 10),
53
87
  standardHeaders: true,
54
88
  legacyHeaders: false,
55
89
  message: { errors: [{ message: 'Too many requests, please try again later.' }] },
56
90
  });
57
91
  /**
58
- * Rate limiter for authentication endpoints
59
- * Allows 50 requests per 15 minutes (stricter for auth)
92
+ * Rate limiter for authentication endpoints.
93
+ *
94
+ * Authenticated requests: 50 requests per 15 minutes
95
+ * Unauthenticated requests: 20 requests per 15 minutes
60
96
  */
61
97
  export const authRateLimiter = createRateLimiter({
62
98
  windowMs: 15 * 60 * 1000, // 15 minutes
63
- max: 50,
99
+ maxAuthenticated: 50,
100
+ maxUnauthenticated: 20,
64
101
  standardHeaders: true,
65
102
  legacyHeaders: false,
66
103
  message: { errors: [{ message: 'Too many authentication attempts.' }] },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adaptic/backend-legacy",
3
- "version": "0.0.46",
3
+ "version": "0.0.47",
4
4
  "description": "Backend executable CRUD functions with dynamic variables construction, and type definitions for the Adaptic AI platform.",
5
5
  "type": "module",
6
6
  "types": "index.d.ts",