cors-whitelist-ip 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.
Files changed (122) hide show
  1. package/README.md +284 -0
  2. package/dist/cjs/adapters/cache/InMemoryCacheAdapter.d.ts +19 -0
  3. package/dist/cjs/adapters/cache/InMemoryCacheAdapter.d.ts.map +1 -0
  4. package/dist/cjs/adapters/cache/InMemoryCacheAdapter.js +69 -0
  5. package/dist/cjs/adapters/cache/InMemoryCacheAdapter.js.map +1 -0
  6. package/dist/cjs/adapters/cache/NoCacheAdapter.d.ts +14 -0
  7. package/dist/cjs/adapters/cache/NoCacheAdapter.d.ts.map +1 -0
  8. package/dist/cjs/adapters/cache/NoCacheAdapter.js +29 -0
  9. package/dist/cjs/adapters/cache/NoCacheAdapter.js.map +1 -0
  10. package/dist/cjs/adapters/cache/index.d.ts +3 -0
  11. package/dist/cjs/adapters/cache/index.d.ts.map +1 -0
  12. package/dist/cjs/adapters/cache/index.js +8 -0
  13. package/dist/cjs/adapters/cache/index.js.map +1 -0
  14. package/dist/cjs/adapters/storage/InMemoryStorageAdapter.d.ts +30 -0
  15. package/dist/cjs/adapters/storage/InMemoryStorageAdapter.d.ts.map +1 -0
  16. package/dist/cjs/adapters/storage/InMemoryStorageAdapter.js +70 -0
  17. package/dist/cjs/adapters/storage/InMemoryStorageAdapter.js.map +1 -0
  18. package/dist/cjs/adapters/storage/index.d.ts +3 -0
  19. package/dist/cjs/adapters/storage/index.d.ts.map +1 -0
  20. package/dist/cjs/adapters/storage/index.js +6 -0
  21. package/dist/cjs/adapters/storage/index.js.map +1 -0
  22. package/dist/cjs/core/CorsWhitelist.d.ts +60 -0
  23. package/dist/cjs/core/CorsWhitelist.d.ts.map +1 -0
  24. package/dist/cjs/core/CorsWhitelist.js +273 -0
  25. package/dist/cjs/core/CorsWhitelist.js.map +1 -0
  26. package/dist/cjs/core/index.d.ts +4 -0
  27. package/dist/cjs/core/index.d.ts.map +1 -0
  28. package/dist/cjs/core/index.js +22 -0
  29. package/dist/cjs/core/index.js.map +1 -0
  30. package/dist/cjs/core/types.d.ts +201 -0
  31. package/dist/cjs/core/types.d.ts.map +1 -0
  32. package/dist/cjs/core/types.js +3 -0
  33. package/dist/cjs/core/types.js.map +1 -0
  34. package/dist/cjs/core/utils.d.ts +31 -0
  35. package/dist/cjs/core/utils.d.ts.map +1 -0
  36. package/dist/cjs/core/utils.js +82 -0
  37. package/dist/cjs/core/utils.js.map +1 -0
  38. package/dist/cjs/frameworks/express.d.ts +15 -0
  39. package/dist/cjs/frameworks/express.d.ts.map +1 -0
  40. package/dist/cjs/frameworks/express.js +49 -0
  41. package/dist/cjs/frameworks/express.js.map +1 -0
  42. package/dist/cjs/frameworks/fastify.d.ts +18 -0
  43. package/dist/cjs/frameworks/fastify.d.ts.map +1 -0
  44. package/dist/cjs/frameworks/fastify.js +49 -0
  45. package/dist/cjs/frameworks/fastify.js.map +1 -0
  46. package/dist/cjs/frameworks/index.d.ts +5 -0
  47. package/dist/cjs/frameworks/index.d.ts.map +1 -0
  48. package/dist/cjs/frameworks/index.js +15 -0
  49. package/dist/cjs/frameworks/index.js.map +1 -0
  50. package/dist/cjs/frameworks/koa.d.ts +15 -0
  51. package/dist/cjs/frameworks/koa.d.ts.map +1 -0
  52. package/dist/cjs/frameworks/koa.js +48 -0
  53. package/dist/cjs/frameworks/koa.js.map +1 -0
  54. package/dist/cjs/frameworks/node-http.d.ts +16 -0
  55. package/dist/cjs/frameworks/node-http.d.ts.map +1 -0
  56. package/dist/cjs/frameworks/node-http.js +46 -0
  57. package/dist/cjs/frameworks/node-http.js.map +1 -0
  58. package/dist/cjs/index.d.ts +12 -0
  59. package/dist/cjs/index.d.ts.map +1 -0
  60. package/dist/cjs/index.js +43 -0
  61. package/dist/cjs/index.js.map +1 -0
  62. package/dist/esm/adapters/cache/InMemoryCacheAdapter.d.ts +19 -0
  63. package/dist/esm/adapters/cache/InMemoryCacheAdapter.d.ts.map +1 -0
  64. package/dist/esm/adapters/cache/InMemoryCacheAdapter.js +69 -0
  65. package/dist/esm/adapters/cache/InMemoryCacheAdapter.js.map +1 -0
  66. package/dist/esm/adapters/cache/NoCacheAdapter.d.ts +14 -0
  67. package/dist/esm/adapters/cache/NoCacheAdapter.d.ts.map +1 -0
  68. package/dist/esm/adapters/cache/NoCacheAdapter.js +29 -0
  69. package/dist/esm/adapters/cache/NoCacheAdapter.js.map +1 -0
  70. package/dist/esm/adapters/cache/index.d.ts +3 -0
  71. package/dist/esm/adapters/cache/index.d.ts.map +1 -0
  72. package/dist/esm/adapters/cache/index.js +8 -0
  73. package/dist/esm/adapters/cache/index.js.map +1 -0
  74. package/dist/esm/adapters/storage/InMemoryStorageAdapter.d.ts +30 -0
  75. package/dist/esm/adapters/storage/InMemoryStorageAdapter.d.ts.map +1 -0
  76. package/dist/esm/adapters/storage/InMemoryStorageAdapter.js +70 -0
  77. package/dist/esm/adapters/storage/InMemoryStorageAdapter.js.map +1 -0
  78. package/dist/esm/adapters/storage/index.d.ts +3 -0
  79. package/dist/esm/adapters/storage/index.d.ts.map +1 -0
  80. package/dist/esm/adapters/storage/index.js +6 -0
  81. package/dist/esm/adapters/storage/index.js.map +1 -0
  82. package/dist/esm/core/CorsWhitelist.d.ts +60 -0
  83. package/dist/esm/core/CorsWhitelist.d.ts.map +1 -0
  84. package/dist/esm/core/CorsWhitelist.js +273 -0
  85. package/dist/esm/core/CorsWhitelist.js.map +1 -0
  86. package/dist/esm/core/index.d.ts +4 -0
  87. package/dist/esm/core/index.d.ts.map +1 -0
  88. package/dist/esm/core/index.js +22 -0
  89. package/dist/esm/core/index.js.map +1 -0
  90. package/dist/esm/core/types.d.ts +201 -0
  91. package/dist/esm/core/types.d.ts.map +1 -0
  92. package/dist/esm/core/types.js +3 -0
  93. package/dist/esm/core/types.js.map +1 -0
  94. package/dist/esm/core/utils.d.ts +31 -0
  95. package/dist/esm/core/utils.d.ts.map +1 -0
  96. package/dist/esm/core/utils.js +82 -0
  97. package/dist/esm/core/utils.js.map +1 -0
  98. package/dist/esm/frameworks/express.d.ts +15 -0
  99. package/dist/esm/frameworks/express.d.ts.map +1 -0
  100. package/dist/esm/frameworks/express.js +49 -0
  101. package/dist/esm/frameworks/express.js.map +1 -0
  102. package/dist/esm/frameworks/fastify.d.ts +18 -0
  103. package/dist/esm/frameworks/fastify.d.ts.map +1 -0
  104. package/dist/esm/frameworks/fastify.js +49 -0
  105. package/dist/esm/frameworks/fastify.js.map +1 -0
  106. package/dist/esm/frameworks/index.d.ts +5 -0
  107. package/dist/esm/frameworks/index.d.ts.map +1 -0
  108. package/dist/esm/frameworks/index.js +15 -0
  109. package/dist/esm/frameworks/index.js.map +1 -0
  110. package/dist/esm/frameworks/koa.d.ts +15 -0
  111. package/dist/esm/frameworks/koa.d.ts.map +1 -0
  112. package/dist/esm/frameworks/koa.js +48 -0
  113. package/dist/esm/frameworks/koa.js.map +1 -0
  114. package/dist/esm/frameworks/node-http.d.ts +16 -0
  115. package/dist/esm/frameworks/node-http.d.ts.map +1 -0
  116. package/dist/esm/frameworks/node-http.js +46 -0
  117. package/dist/esm/frameworks/node-http.js.map +1 -0
  118. package/dist/esm/index.d.ts +12 -0
  119. package/dist/esm/index.d.ts.map +1 -0
  120. package/dist/esm/index.js +43 -0
  121. package/dist/esm/index.js.map +1 -0
  122. package/package.json +147 -0
@@ -0,0 +1,273 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CorsWhitelist = void 0;
4
+ const NoCacheAdapter_1 = require("../adapters/cache/NoCacheAdapter");
5
+ const utils_1 = require("./utils");
6
+ const DEFAULT_CORS_HEADERS = {
7
+ allowOrigin: '',
8
+ allowMethods: 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
9
+ allowHeaders: 'Content-Type, Authorization, X-Requested-With',
10
+ allowCredentials: true,
11
+ maxAge: 86400, // 24 hours
12
+ };
13
+ const DEFAULT_CACHE_TTL = 3600; // 1 hour
14
+ /**
15
+ * Main CORS Whitelist class that handles origin validation
16
+ * and CORS header management in a framework-agnostic way.
17
+ */
18
+ class CorsWhitelist {
19
+ constructor(options) {
20
+ this.storage = options.storage;
21
+ this.cache = options.cache ?? new NoCacheAdapter_1.NoCacheAdapter();
22
+ this.cacheTtl = options.cacheTtl ?? DEFAULT_CACHE_TTL;
23
+ this.logger = options.logger ?? console;
24
+ this.corsHeaders = { ...DEFAULT_CORS_HEADERS, ...options.corsHeaders };
25
+ this.allowNoOrigin = options.allowNoOrigin ?? true;
26
+ this.customGetClientIp = options.getClientIp;
27
+ this.debug = options.debug ?? false;
28
+ }
29
+ /**
30
+ * Initialize the CORS middleware (call before handling requests)
31
+ */
32
+ async initialize() {
33
+ if (this.storage.initialize) {
34
+ await this.storage.initialize();
35
+ }
36
+ if (this.cache.initialize) {
37
+ await this.cache.initialize();
38
+ }
39
+ }
40
+ /**
41
+ * Clean up resources
42
+ */
43
+ async dispose() {
44
+ if (this.storage.dispose) {
45
+ await this.storage.dispose();
46
+ }
47
+ if (this.cache.dispose) {
48
+ await this.cache.dispose();
49
+ }
50
+ }
51
+ /**
52
+ * Main handler for CORS requests. Returns whether to continue processing.
53
+ * @param req - Generic request object
54
+ * @param res - Generic response object
55
+ * @returns true if request should continue, false if handled (blocked or preflight)
56
+ */
57
+ async handleRequest(req, res) {
58
+ try {
59
+ const origin = this.getOrigin(req);
60
+ const method = req.method.toUpperCase();
61
+ const clientIp = this.getClientIp(req);
62
+ this.log(`[CORS] Request from IP: ${clientIp}, Origin: ${origin}, Path: ${req.url}, Method: ${method}`);
63
+ // Handle preflight OPTIONS requests
64
+ if (method === 'OPTIONS') {
65
+ return await this.handlePreflight(req, res, origin);
66
+ }
67
+ // Handle regular requests
68
+ return await this.handleRegularRequest(req, res, origin);
69
+ }
70
+ catch (error) {
71
+ this.logger.error(`[CORS] Error in CORS handler: ${error.message}`, error.stack);
72
+ res.statusCode = 500;
73
+ res.end(JSON.stringify({ error: 'Internal Server Error' }));
74
+ return false;
75
+ }
76
+ }
77
+ /**
78
+ * Validate if an origin is allowed
79
+ * @param origin - The origin to validate
80
+ * @returns Validation result with details
81
+ */
82
+ async validateOrigin(origin) {
83
+ const cacheKey = `cors:validation:${origin}`;
84
+ // Try cache first
85
+ const cached = await this.cache.get(cacheKey);
86
+ if (cached) {
87
+ this.log(`[CORS] Cache hit for origin validation: ${origin}`);
88
+ return cached;
89
+ }
90
+ const result = await this.performValidation(origin);
91
+ // Cache the result
92
+ await this.cache.set(cacheKey, result, this.cacheTtl);
93
+ return result;
94
+ }
95
+ /**
96
+ * Invalidate cache for a specific domain or pattern
97
+ */
98
+ async invalidateCache(pattern) {
99
+ if (pattern) {
100
+ await this.cache.deletePattern(`cors:*${pattern}*`);
101
+ }
102
+ else {
103
+ await this.cache.deletePattern('cors:*');
104
+ }
105
+ }
106
+ /**
107
+ * Get the storage adapter instance
108
+ */
109
+ getStorage() {
110
+ return this.storage;
111
+ }
112
+ /**
113
+ * Get the cache adapter instance
114
+ */
115
+ getCache() {
116
+ return this.cache;
117
+ }
118
+ // ─────────────────────────────────────────────────────────────────
119
+ // Private methods
120
+ // ─────────────────────────────────────────────────────────────────
121
+ async handlePreflight(_req, res, origin) {
122
+ if (!origin) {
123
+ this.log('[CORS] Preflight without origin, denying');
124
+ res.statusCode = 403;
125
+ res.end(JSON.stringify({ error: 'Origin header required for preflight' }));
126
+ return false;
127
+ }
128
+ const validation = await this.validateOrigin(origin);
129
+ if (validation.allowed) {
130
+ this.log(`[CORS] Preflight allowed for origin: ${origin}`);
131
+ this.setPreflightHeaders(res, origin);
132
+ res.statusCode = 204;
133
+ res.end();
134
+ return false; // Preflight handled, don't continue
135
+ }
136
+ this.logger.warn(`[CORS] Preflight blocked for origin: ${origin}`);
137
+ res.statusCode = 403;
138
+ res.end(JSON.stringify({ error: 'CORS not allowed for this origin' }));
139
+ return false;
140
+ }
141
+ async handleRegularRequest(_req, res, origin) {
142
+ // No origin = not a CORS request, allow through
143
+ if (!origin) {
144
+ if (this.allowNoOrigin) {
145
+ this.log('[CORS] No origin header, allowing request');
146
+ return true;
147
+ }
148
+ res.statusCode = 403;
149
+ res.end(JSON.stringify({ error: 'Origin header required' }));
150
+ return false;
151
+ }
152
+ const validation = await this.validateOrigin(origin);
153
+ if (validation.allowed) {
154
+ this.log(`[CORS] Request allowed for origin: ${origin}`);
155
+ this.setCorsHeaders(res, origin);
156
+ return true; // Continue processing
157
+ }
158
+ this.logger.warn(`[CORS] Request blocked for origin: ${origin}`);
159
+ res.statusCode = 403;
160
+ res.end(JSON.stringify({ error: 'CORS not allowed for this origin' }));
161
+ return false;
162
+ }
163
+ async performValidation(origin) {
164
+ // 1. Check global whitelist
165
+ const globalWhitelist = await this.getGlobalWhitelist();
166
+ if (globalWhitelist.includes('*')) {
167
+ return { allowed: true, reason: 'Global wildcard (*) allows all origins' };
168
+ }
169
+ if (globalWhitelist.includes(origin)) {
170
+ return { allowed: true, reason: 'Origin in global whitelist' };
171
+ }
172
+ // 2. Extract domain from origin
173
+ const domain = (0, utils_1.extractDomain)(origin);
174
+ if (!domain) {
175
+ return { allowed: false, reason: 'Invalid origin format' };
176
+ }
177
+ // Check if full origin URL is in global whitelist
178
+ if (globalWhitelist.includes(domain)) {
179
+ return { allowed: true, reason: 'Domain in global whitelist' };
180
+ }
181
+ // 3. Check if domain is associated with an API key
182
+ const orgId = await this.storage.findOrganisationByDomain(domain);
183
+ if (orgId) {
184
+ const apiKey = await this.storage.getApiKey(orgId, 'client');
185
+ if (apiKey) {
186
+ return {
187
+ allowed: true,
188
+ reason: 'Domain associated with API key',
189
+ organisationId: orgId,
190
+ apiKey,
191
+ };
192
+ }
193
+ }
194
+ // 4. Check IP whitelist (if origin is IP-based)
195
+ if ((0, utils_1.isIpAddress)(domain)) {
196
+ const isWhitelisted = await this.storage.isIpWhitelisted(domain);
197
+ if (isWhitelisted) {
198
+ return { allowed: true, reason: 'IP address in whitelist' };
199
+ }
200
+ return { allowed: false, reason: 'IP address not in whitelist' };
201
+ }
202
+ // 5. Check domain pattern whitelist (including wildcards)
203
+ const isDomainAllowed = await this.storage.isDomainWhitelisted(domain);
204
+ if (isDomainAllowed) {
205
+ return { allowed: true, reason: 'Domain matches whitelist pattern' };
206
+ }
207
+ return { allowed: false, reason: 'Origin not in any whitelist' };
208
+ }
209
+ async getGlobalWhitelist() {
210
+ const cacheKey = 'cors:global:whitelist';
211
+ const cached = await this.cache.get(cacheKey);
212
+ if (cached) {
213
+ return cached;
214
+ }
215
+ const whitelist = await this.storage.getGlobalWhitelist();
216
+ await this.cache.set(cacheKey, whitelist, this.cacheTtl);
217
+ return whitelist;
218
+ }
219
+ setPreflightHeaders(res, origin) {
220
+ res.setHeader('Access-Control-Allow-Origin', origin);
221
+ res.setHeader('Access-Control-Allow-Methods', this.corsHeaders.allowMethods);
222
+ res.setHeader('Access-Control-Allow-Headers', this.corsHeaders.allowHeaders);
223
+ res.setHeader('Access-Control-Allow-Credentials', String(this.corsHeaders.allowCredentials));
224
+ res.setHeader('Access-Control-Max-Age', String(this.corsHeaders.maxAge));
225
+ if (this.corsHeaders.exposeHeaders) {
226
+ res.setHeader('Access-Control-Expose-Headers', this.corsHeaders.exposeHeaders);
227
+ }
228
+ }
229
+ setCorsHeaders(res, origin) {
230
+ res.setHeader('Access-Control-Allow-Origin', origin);
231
+ res.setHeader('Access-Control-Allow-Credentials', String(this.corsHeaders.allowCredentials));
232
+ if (this.corsHeaders.exposeHeaders) {
233
+ res.setHeader('Access-Control-Expose-Headers', this.corsHeaders.exposeHeaders);
234
+ }
235
+ }
236
+ getOrigin(req) {
237
+ const origin = req.headers['origin'];
238
+ if (Array.isArray(origin)) {
239
+ return origin[0] || null;
240
+ }
241
+ return origin || null;
242
+ }
243
+ getClientIp(req) {
244
+ if (this.customGetClientIp) {
245
+ return this.customGetClientIp(req);
246
+ }
247
+ return this.defaultGetClientIp(req);
248
+ }
249
+ defaultGetClientIp(req) {
250
+ const forwarded = req.headers['x-forwarded-for'];
251
+ if (forwarded) {
252
+ const ips = (Array.isArray(forwarded) ? forwarded[0] : forwarded).split(',');
253
+ return ips[0].trim();
254
+ }
255
+ const realIp = req.headers['x-real-ip'];
256
+ if (realIp) {
257
+ return Array.isArray(realIp) ? realIp[0] : realIp;
258
+ }
259
+ return req.ip || 'unknown';
260
+ }
261
+ log(message) {
262
+ if (this.debug) {
263
+ if (this.logger.debug) {
264
+ this.logger.debug(message);
265
+ }
266
+ else {
267
+ this.logger.log(message);
268
+ }
269
+ }
270
+ }
271
+ }
272
+ exports.CorsWhitelist = CorsWhitelist;
273
+ //# sourceMappingURL=CorsWhitelist.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CorsWhitelist.js","sourceRoot":"","sources":["../../../src/core/CorsWhitelist.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export * from './types';
2
+ export * from './utils';
3
+ export { CorsWhitelist } from './CorsWhitelist';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.CorsWhitelist = void 0;
18
+ __exportStar(require("./types"), exports);
19
+ __exportStar(require("./utils"), exports);
20
+ var CorsWhitelist_1 = require("./CorsWhitelist");
21
+ Object.defineProperty(exports, "CorsWhitelist", { enumerable: true, get: function () { return CorsWhitelist_1.CorsWhitelist; } });
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,0CAAwB;AACxB,iDAAgD;AAAvC,8GAAA,aAAa,OAAA"}
@@ -0,0 +1,201 @@
1
+ /**
2
+ * Whitelist entry types
3
+ */
4
+ export type WhitelistType = 'IP' | 'DOMAIN';
5
+ /**
6
+ * Represents a whitelist entry (IP or domain)
7
+ */
8
+ export interface WhitelistEntry {
9
+ id: string | number;
10
+ organisationId?: string | number;
11
+ type: WhitelistType;
12
+ value: string;
13
+ isActive: boolean;
14
+ description?: string;
15
+ }
16
+ /**
17
+ * Represents a global CORS whitelist configuration
18
+ */
19
+ export interface GlobalWhitelist {
20
+ id: string | number;
21
+ domains: string[];
22
+ isActive: boolean;
23
+ }
24
+ /**
25
+ * Represents an API key association with an organisation
26
+ */
27
+ export interface ApiKeyEntry {
28
+ organisationId: string | number;
29
+ apiKey: string;
30
+ type: 'client' | 'server';
31
+ }
32
+ /**
33
+ * Result of origin validation
34
+ */
35
+ export interface ValidationResult {
36
+ allowed: boolean;
37
+ reason: string;
38
+ matchedEntry?: WhitelistEntry | GlobalWhitelist;
39
+ organisationId?: string | number;
40
+ apiKey?: string;
41
+ }
42
+ /**
43
+ * CORS headers configuration
44
+ */
45
+ export interface CorsHeaders {
46
+ allowOrigin: string;
47
+ allowMethods: string;
48
+ allowHeaders: string;
49
+ allowCredentials: boolean;
50
+ maxAge: number;
51
+ exposeHeaders?: string;
52
+ }
53
+ /**
54
+ * Storage adapter interface for fetching whitelist data.
55
+ * Implement this interface to support your database of choice.
56
+ */
57
+ export interface StorageAdapter {
58
+ /**
59
+ * Get the global CORS whitelist
60
+ * @returns Promise resolving to an array of allowed domains
61
+ */
62
+ getGlobalWhitelist(): Promise<string[]>;
63
+ /**
64
+ * Get all whitelist entries (IP and DOMAIN) that are active
65
+ * @returns Promise resolving to an array of whitelist entries
66
+ */
67
+ getWhitelistEntries(): Promise<WhitelistEntry[]>;
68
+ /**
69
+ * Get whitelist entries for a specific organisation
70
+ * @param organisationId - The organisation identifier
71
+ * @returns Promise resolving to an array of whitelist entries
72
+ */
73
+ getOrganisationWhitelist(organisationId: string | number): Promise<WhitelistEntry[]>;
74
+ /**
75
+ * Find the organisation ID associated with a domain
76
+ * @param domain - The domain to look up (exact or wildcard match)
77
+ * @returns Promise resolving to organisation ID or null if not found
78
+ */
79
+ findOrganisationByDomain(domain: string): Promise<string | number | null>;
80
+ /**
81
+ * Get the API key for an organisation
82
+ * @param organisationId - The organisation identifier
83
+ * @param type - The API key type (default: 'client')
84
+ * @returns Promise resolving to API key or null if not found
85
+ */
86
+ getApiKey(organisationId: string | number, type?: 'client' | 'server'): Promise<string | null>;
87
+ /**
88
+ * Check if an IP address is whitelisted (globally or for any organisation)
89
+ * @param ip - The IP address to check
90
+ * @returns Promise resolving to true if whitelisted
91
+ */
92
+ isIpWhitelisted(ip: string): Promise<boolean>;
93
+ /**
94
+ * Check if a domain pattern is whitelisted (globally or for any organisation)
95
+ * @param domain - The domain to check (will match against wildcards)
96
+ * @returns Promise resolving to true if whitelisted
97
+ */
98
+ isDomainWhitelisted(domain: string): Promise<boolean>;
99
+ /**
100
+ * Optional: Initialize the storage adapter (e.g., connection setup)
101
+ */
102
+ initialize?(): Promise<void>;
103
+ /**
104
+ * Optional: Clean up resources (e.g., close connections)
105
+ */
106
+ dispose?(): Promise<void>;
107
+ }
108
+ /**
109
+ * Cache adapter interface for caching whitelist lookups.
110
+ * Implement this interface to use Redis, Memcached, or other caching solutions.
111
+ */
112
+ export interface CacheAdapter {
113
+ /**
114
+ * Get a value from cache
115
+ * @param key - Cache key
116
+ * @returns Promise resolving to cached value or null if not found
117
+ */
118
+ get<T = string>(key: string): Promise<T | null>;
119
+ /**
120
+ * Set a value in cache with TTL
121
+ * @param key - Cache key
122
+ * @param value - Value to cache
123
+ * @param ttlSeconds - Time-to-live in seconds
124
+ */
125
+ set<T = string>(key: string, value: T, ttlSeconds: number): Promise<void>;
126
+ /**
127
+ * Delete a specific key from cache
128
+ * @param key - Cache key to delete
129
+ */
130
+ delete(key: string): Promise<void>;
131
+ /**
132
+ * Delete all keys matching a pattern
133
+ * @param pattern - Pattern to match (e.g., "domain:*")
134
+ */
135
+ deletePattern(pattern: string): Promise<void>;
136
+ /**
137
+ * Clear all cached data
138
+ */
139
+ clear(): Promise<void>;
140
+ /**
141
+ * Check if a key exists in cache
142
+ * @param key - Cache key
143
+ */
144
+ has(key: string): Promise<boolean>;
145
+ /**
146
+ * Optional: Initialize the cache adapter
147
+ */
148
+ initialize?(): Promise<void>;
149
+ /**
150
+ * Optional: Clean up resources
151
+ */
152
+ dispose?(): Promise<void>;
153
+ }
154
+ /**
155
+ * Configuration options for CorsWhitelist
156
+ */
157
+ export interface CorsWhitelistOptions {
158
+ /** Storage adapter for fetching whitelist data */
159
+ storage: StorageAdapter;
160
+ /** Optional cache adapter for caching whitelist lookups */
161
+ cache?: CacheAdapter;
162
+ /** Cache TTL in seconds (default: 3600) */
163
+ cacheTtl?: number;
164
+ /** Custom logger (default: console) */
165
+ logger?: Logger;
166
+ /** Default CORS headers configuration */
167
+ corsHeaders?: Partial<CorsHeaders>;
168
+ /** Whether to allow requests with no origin header (default: true) */
169
+ allowNoOrigin?: boolean;
170
+ /** Custom function to extract client IP from request */
171
+ getClientIp?: (req: GenericRequest) => string;
172
+ /** Enable debug logging (default: false) */
173
+ debug?: boolean;
174
+ }
175
+ /**
176
+ * Generic request interface for framework-agnostic handling
177
+ */
178
+ export interface GenericRequest {
179
+ headers: Record<string, string | string[] | undefined>;
180
+ method: string;
181
+ url: string;
182
+ ip?: string;
183
+ }
184
+ /**
185
+ * Generic response interface for framework-agnostic handling
186
+ */
187
+ export interface GenericResponse {
188
+ setHeader: (name: string, value: string) => void;
189
+ statusCode: number;
190
+ end: (body?: string) => void;
191
+ }
192
+ /**
193
+ * Logger interface
194
+ */
195
+ export interface Logger {
196
+ log: (message: string) => void;
197
+ warn: (message: string) => void;
198
+ error: (message: string, trace?: string) => void;
199
+ debug?: (message: string) => void;
200
+ }
201
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Check if a string is a valid IPv4 address
3
+ */
4
+ export declare function isIPv4(str: string): boolean;
5
+ /**
6
+ * Check if a string is a valid IPv6 address
7
+ */
8
+ export declare function isIPv6(str: string): boolean;
9
+ /**
10
+ * Check if a string is any valid IP address
11
+ */
12
+ export declare function isIpAddress(str: string): boolean;
13
+ /**
14
+ * Extract domain/hostname from an origin URL
15
+ */
16
+ export declare function extractDomain(origin: string): string | null;
17
+ /**
18
+ * Check if a domain matches a wildcard pattern
19
+ * @param domain - The domain to check (e.g., "app.example.com")
20
+ * @param pattern - The pattern to match against (e.g., "*.example.com")
21
+ */
22
+ export declare function matchesWildcard(domain: string, pattern: string): boolean;
23
+ /**
24
+ * Validate domain format
25
+ */
26
+ export declare function isValidDomain(str: string): boolean;
27
+ /**
28
+ * Validate wildcard domain format
29
+ */
30
+ export declare function isValidWildcardDomain(str: string): boolean;
31
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/core/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAU3C;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAI3C;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAU3D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAUxE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAIlD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAG1D"}
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isIPv4 = isIPv4;
4
+ exports.isIPv6 = isIPv6;
5
+ exports.isIpAddress = isIpAddress;
6
+ exports.extractDomain = extractDomain;
7
+ exports.matchesWildcard = matchesWildcard;
8
+ exports.isValidDomain = isValidDomain;
9
+ exports.isValidWildcardDomain = isValidWildcardDomain;
10
+ /**
11
+ * Check if a string is a valid IPv4 address
12
+ */
13
+ function isIPv4(str) {
14
+ const ipv4Regex = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
15
+ const match = str.match(ipv4Regex);
16
+ if (!match)
17
+ return false;
18
+ // Validate each octet is 0-255
19
+ return match.slice(1).every((octet) => {
20
+ const num = parseInt(octet, 10);
21
+ return num >= 0 && num <= 255;
22
+ });
23
+ }
24
+ /**
25
+ * Check if a string is a valid IPv6 address
26
+ */
27
+ function isIPv6(str) {
28
+ const ipv6Regex = /^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$|^([0-9a-fA-F]{1,4}:){1,7}:$|^([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}$|^([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}$|^([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}$|^([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}$|^([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}$|^[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})$|^:((:[0-9a-fA-F]{1,4}){1,7}|:)$|^fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]+$|^::(ffff(:0{1,4})?:)?((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9])$|^([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1?[0-9])?[0-9])\.){3}(25[0-5]|(2[0-4]|1?[0-9])?[0-9])$/;
29
+ return ipv6Regex.test(str);
30
+ }
31
+ /**
32
+ * Check if a string is any valid IP address
33
+ */
34
+ function isIpAddress(str) {
35
+ return isIPv4(str) || isIPv6(str);
36
+ }
37
+ /**
38
+ * Extract domain/hostname from an origin URL
39
+ */
40
+ function extractDomain(origin) {
41
+ try {
42
+ if (isIpAddress(origin)) {
43
+ return origin;
44
+ }
45
+ const url = new URL(origin);
46
+ return url.hostname;
47
+ }
48
+ catch {
49
+ return null;
50
+ }
51
+ }
52
+ /**
53
+ * Check if a domain matches a wildcard pattern
54
+ * @param domain - The domain to check (e.g., "app.example.com")
55
+ * @param pattern - The pattern to match against (e.g., "*.example.com")
56
+ */
57
+ function matchesWildcard(domain, pattern) {
58
+ if (pattern === domain)
59
+ return true;
60
+ if (pattern.startsWith('*.')) {
61
+ const suffix = pattern.substring(2);
62
+ // Must end with suffix and have at least one char before it
63
+ return domain.endsWith(`.${suffix}`) || domain === suffix;
64
+ }
65
+ return false;
66
+ }
67
+ /**
68
+ * Validate domain format
69
+ */
70
+ function isValidDomain(str) {
71
+ const domainRegex = /^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/;
72
+ return domainRegex.test(str);
73
+ }
74
+ /**
75
+ * Validate wildcard domain format
76
+ */
77
+ function isValidWildcardDomain(str) {
78
+ if (!str.startsWith('*.'))
79
+ return false;
80
+ return isValidDomain(str.substring(2));
81
+ }
82
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/core/utils.ts"],"names":[],"mappings":";;AAGA,wBAUC;AAKD,wBAIC;AAKD,kCAEC;AAKD,sCAUC;AAOD,0CAUC;AAKD,sCAIC;AAKD,sDAGC;AA9ED;;GAEG;AACH,SAAgB,MAAM,CAAC,GAAW;IAChC,MAAM,SAAS,GAAG,8CAA8C,CAAC;IACjE,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACnC,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IAEzB,+BAA+B;IAC/B,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACpC,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAChC,OAAO,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,GAAG,CAAC;IAChC,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAgB,MAAM,CAAC,GAAW;IAChC,MAAM,SAAS,GACb,0nBAA0nB,CAAC;IAC7nB,OAAO,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,SAAgB,WAAW,CAAC,GAAW;IACrC,OAAO,MAAM,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,SAAgB,aAAa,CAAC,MAAc;IAC1C,IAAI,CAAC;QACH,IAAI,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;YACxB,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;QAC5B,OAAO,GAAG,CAAC,QAAQ,CAAC;IACtB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAgB,eAAe,CAAC,MAAc,EAAE,OAAe;IAC7D,IAAI,OAAO,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAEpC,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QACpC,4DAA4D;QAC5D,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,MAAM,EAAE,CAAC,IAAI,MAAM,KAAK,MAAM,CAAC;IAC5D,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAgB,aAAa,CAAC,GAAW;IACvC,MAAM,WAAW,GACf,gEAAgE,CAAC;IACnE,OAAO,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,SAAgB,qBAAqB,CAAC,GAAW;IAC/C,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACxC,OAAO,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AACzC,CAAC"}