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.
- package/README.md +284 -0
- package/dist/cjs/adapters/cache/InMemoryCacheAdapter.d.ts +19 -0
- package/dist/cjs/adapters/cache/InMemoryCacheAdapter.d.ts.map +1 -0
- package/dist/cjs/adapters/cache/InMemoryCacheAdapter.js +69 -0
- package/dist/cjs/adapters/cache/InMemoryCacheAdapter.js.map +1 -0
- package/dist/cjs/adapters/cache/NoCacheAdapter.d.ts +14 -0
- package/dist/cjs/adapters/cache/NoCacheAdapter.d.ts.map +1 -0
- package/dist/cjs/adapters/cache/NoCacheAdapter.js +29 -0
- package/dist/cjs/adapters/cache/NoCacheAdapter.js.map +1 -0
- package/dist/cjs/adapters/cache/index.d.ts +3 -0
- package/dist/cjs/adapters/cache/index.d.ts.map +1 -0
- package/dist/cjs/adapters/cache/index.js +8 -0
- package/dist/cjs/adapters/cache/index.js.map +1 -0
- package/dist/cjs/adapters/storage/InMemoryStorageAdapter.d.ts +30 -0
- package/dist/cjs/adapters/storage/InMemoryStorageAdapter.d.ts.map +1 -0
- package/dist/cjs/adapters/storage/InMemoryStorageAdapter.js +70 -0
- package/dist/cjs/adapters/storage/InMemoryStorageAdapter.js.map +1 -0
- package/dist/cjs/adapters/storage/index.d.ts +3 -0
- package/dist/cjs/adapters/storage/index.d.ts.map +1 -0
- package/dist/cjs/adapters/storage/index.js +6 -0
- package/dist/cjs/adapters/storage/index.js.map +1 -0
- package/dist/cjs/core/CorsWhitelist.d.ts +60 -0
- package/dist/cjs/core/CorsWhitelist.d.ts.map +1 -0
- package/dist/cjs/core/CorsWhitelist.js +273 -0
- package/dist/cjs/core/CorsWhitelist.js.map +1 -0
- package/dist/cjs/core/index.d.ts +4 -0
- package/dist/cjs/core/index.d.ts.map +1 -0
- package/dist/cjs/core/index.js +22 -0
- package/dist/cjs/core/index.js.map +1 -0
- package/dist/cjs/core/types.d.ts +201 -0
- package/dist/cjs/core/types.d.ts.map +1 -0
- package/dist/cjs/core/types.js +3 -0
- package/dist/cjs/core/types.js.map +1 -0
- package/dist/cjs/core/utils.d.ts +31 -0
- package/dist/cjs/core/utils.d.ts.map +1 -0
- package/dist/cjs/core/utils.js +82 -0
- package/dist/cjs/core/utils.js.map +1 -0
- package/dist/cjs/frameworks/express.d.ts +15 -0
- package/dist/cjs/frameworks/express.d.ts.map +1 -0
- package/dist/cjs/frameworks/express.js +49 -0
- package/dist/cjs/frameworks/express.js.map +1 -0
- package/dist/cjs/frameworks/fastify.d.ts +18 -0
- package/dist/cjs/frameworks/fastify.d.ts.map +1 -0
- package/dist/cjs/frameworks/fastify.js +49 -0
- package/dist/cjs/frameworks/fastify.js.map +1 -0
- package/dist/cjs/frameworks/index.d.ts +5 -0
- package/dist/cjs/frameworks/index.d.ts.map +1 -0
- package/dist/cjs/frameworks/index.js +15 -0
- package/dist/cjs/frameworks/index.js.map +1 -0
- package/dist/cjs/frameworks/koa.d.ts +15 -0
- package/dist/cjs/frameworks/koa.d.ts.map +1 -0
- package/dist/cjs/frameworks/koa.js +48 -0
- package/dist/cjs/frameworks/koa.js.map +1 -0
- package/dist/cjs/frameworks/node-http.d.ts +16 -0
- package/dist/cjs/frameworks/node-http.d.ts.map +1 -0
- package/dist/cjs/frameworks/node-http.js +46 -0
- package/dist/cjs/frameworks/node-http.js.map +1 -0
- package/dist/cjs/index.d.ts +12 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +43 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/esm/adapters/cache/InMemoryCacheAdapter.d.ts +19 -0
- package/dist/esm/adapters/cache/InMemoryCacheAdapter.d.ts.map +1 -0
- package/dist/esm/adapters/cache/InMemoryCacheAdapter.js +69 -0
- package/dist/esm/adapters/cache/InMemoryCacheAdapter.js.map +1 -0
- package/dist/esm/adapters/cache/NoCacheAdapter.d.ts +14 -0
- package/dist/esm/adapters/cache/NoCacheAdapter.d.ts.map +1 -0
- package/dist/esm/adapters/cache/NoCacheAdapter.js +29 -0
- package/dist/esm/adapters/cache/NoCacheAdapter.js.map +1 -0
- package/dist/esm/adapters/cache/index.d.ts +3 -0
- package/dist/esm/adapters/cache/index.d.ts.map +1 -0
- package/dist/esm/adapters/cache/index.js +8 -0
- package/dist/esm/adapters/cache/index.js.map +1 -0
- package/dist/esm/adapters/storage/InMemoryStorageAdapter.d.ts +30 -0
- package/dist/esm/adapters/storage/InMemoryStorageAdapter.d.ts.map +1 -0
- package/dist/esm/adapters/storage/InMemoryStorageAdapter.js +70 -0
- package/dist/esm/adapters/storage/InMemoryStorageAdapter.js.map +1 -0
- package/dist/esm/adapters/storage/index.d.ts +3 -0
- package/dist/esm/adapters/storage/index.d.ts.map +1 -0
- package/dist/esm/adapters/storage/index.js +6 -0
- package/dist/esm/adapters/storage/index.js.map +1 -0
- package/dist/esm/core/CorsWhitelist.d.ts +60 -0
- package/dist/esm/core/CorsWhitelist.d.ts.map +1 -0
- package/dist/esm/core/CorsWhitelist.js +273 -0
- package/dist/esm/core/CorsWhitelist.js.map +1 -0
- package/dist/esm/core/index.d.ts +4 -0
- package/dist/esm/core/index.d.ts.map +1 -0
- package/dist/esm/core/index.js +22 -0
- package/dist/esm/core/index.js.map +1 -0
- package/dist/esm/core/types.d.ts +201 -0
- package/dist/esm/core/types.d.ts.map +1 -0
- package/dist/esm/core/types.js +3 -0
- package/dist/esm/core/types.js.map +1 -0
- package/dist/esm/core/utils.d.ts +31 -0
- package/dist/esm/core/utils.d.ts.map +1 -0
- package/dist/esm/core/utils.js +82 -0
- package/dist/esm/core/utils.js.map +1 -0
- package/dist/esm/frameworks/express.d.ts +15 -0
- package/dist/esm/frameworks/express.d.ts.map +1 -0
- package/dist/esm/frameworks/express.js +49 -0
- package/dist/esm/frameworks/express.js.map +1 -0
- package/dist/esm/frameworks/fastify.d.ts +18 -0
- package/dist/esm/frameworks/fastify.d.ts.map +1 -0
- package/dist/esm/frameworks/fastify.js +49 -0
- package/dist/esm/frameworks/fastify.js.map +1 -0
- package/dist/esm/frameworks/index.d.ts +5 -0
- package/dist/esm/frameworks/index.d.ts.map +1 -0
- package/dist/esm/frameworks/index.js +15 -0
- package/dist/esm/frameworks/index.js.map +1 -0
- package/dist/esm/frameworks/koa.d.ts +15 -0
- package/dist/esm/frameworks/koa.d.ts.map +1 -0
- package/dist/esm/frameworks/koa.js +48 -0
- package/dist/esm/frameworks/koa.js.map +1 -0
- package/dist/esm/frameworks/node-http.d.ts +16 -0
- package/dist/esm/frameworks/node-http.d.ts.map +1 -0
- package/dist/esm/frameworks/node-http.js +46 -0
- package/dist/esm/frameworks/node-http.js.map +1 -0
- package/dist/esm/index.d.ts +12 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +43 -0
- package/dist/esm/index.js.map +1 -0
- package/package.json +147 -0
|
@@ -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 @@
|
|
|
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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { RequestHandler } from 'express';
|
|
2
|
+
import { CorsWhitelist } from '../core/CorsWhitelist';
|
|
3
|
+
import { CorsWhitelistOptions } from '../core/types';
|
|
4
|
+
/**
|
|
5
|
+
* Create Express middleware for CORS whitelist validation
|
|
6
|
+
*/
|
|
7
|
+
export declare function createExpressMiddleware(corsWhitelist: CorsWhitelist): RequestHandler;
|
|
8
|
+
/**
|
|
9
|
+
* Factory function to create both CorsWhitelist instance and Express middleware
|
|
10
|
+
*/
|
|
11
|
+
export declare function corsWhitelistExpress(options: CorsWhitelistOptions): {
|
|
12
|
+
corsWhitelist: CorsWhitelist;
|
|
13
|
+
middleware: RequestHandler;
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=express.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../../src/frameworks/express.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAmC,MAAM,SAAS,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EACL,oBAAoB,EAGrB,MAAM,eAAe,CAAC;AAEvB;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,aAAa,EAAE,aAAa,GAC3B,cAAc,CAoChB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,oBAAoB,GAC5B;IAAE,aAAa,EAAE,aAAa,CAAC;IAAC,UAAU,EAAE,cAAc,CAAA;CAAE,CAK9D"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createExpressMiddleware = createExpressMiddleware;
|
|
4
|
+
exports.corsWhitelistExpress = corsWhitelistExpress;
|
|
5
|
+
const CorsWhitelist_1 = require("../core/CorsWhitelist");
|
|
6
|
+
/**
|
|
7
|
+
* Create Express middleware for CORS whitelist validation
|
|
8
|
+
*/
|
|
9
|
+
function createExpressMiddleware(corsWhitelist) {
|
|
10
|
+
return async (req, res, next) => {
|
|
11
|
+
const genericReq = {
|
|
12
|
+
headers: req.headers,
|
|
13
|
+
method: req.method,
|
|
14
|
+
url: req.url,
|
|
15
|
+
ip: req.ip || req.socket?.remoteAddress,
|
|
16
|
+
};
|
|
17
|
+
const genericRes = {
|
|
18
|
+
setHeader: (name, value) => res.setHeader(name, value),
|
|
19
|
+
get statusCode() {
|
|
20
|
+
return res.statusCode;
|
|
21
|
+
},
|
|
22
|
+
set statusCode(code) {
|
|
23
|
+
res.statusCode = code;
|
|
24
|
+
},
|
|
25
|
+
end: (body) => {
|
|
26
|
+
if (body) {
|
|
27
|
+
res.setHeader('Content-Type', 'application/json');
|
|
28
|
+
res.end(body);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
res.end();
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
const shouldContinue = await corsWhitelist.handleRequest(genericReq, genericRes);
|
|
36
|
+
if (shouldContinue) {
|
|
37
|
+
next();
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Factory function to create both CorsWhitelist instance and Express middleware
|
|
43
|
+
*/
|
|
44
|
+
function corsWhitelistExpress(options) {
|
|
45
|
+
const corsWhitelist = new CorsWhitelist_1.CorsWhitelist(options);
|
|
46
|
+
const middleware = createExpressMiddleware(corsWhitelist);
|
|
47
|
+
return { corsWhitelist, middleware };
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=express.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"express.js","sourceRoot":"","sources":["../../../src/frameworks/express.ts"],"names":[],"mappings":";;AAWA,0DAsCC;AAKD,oDAOC;AA5DD,yDAAsD;AAOtD;;GAEG;AACH,SAAgB,uBAAuB,CACrC,aAA4B;IAE5B,OAAO,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;QAC/D,MAAM,UAAU,GAAmB;YACjC,OAAO,EAAE,GAAG,CAAC,OAAwD;YACrE,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,GAAG,EAAE,GAAG,CAAC,GAAG;YACZ,EAAE,EAAE,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,MAAM,EAAE,aAAa;SACxC,CAAC;QAEF,MAAM,UAAU,GAAoB;YAClC,SAAS,EAAE,CAAC,IAAY,EAAE,KAAa,EAAE,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC;YACtE,IAAI,UAAU;gBACZ,OAAO,GAAG,CAAC,UAAU,CAAC;YACxB,CAAC;YACD,IAAI,UAAU,CAAC,IAAY;gBACzB,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC;YACxB,CAAC;YACD,GAAG,EAAE,CAAC,IAAa,EAAE,EAAE;gBACrB,IAAI,IAAI,EAAE,CAAC;oBACT,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;oBAClD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAChB,CAAC;qBAAM,CAAC;oBACN,GAAG,CAAC,GAAG,EAAE,CAAC;gBACZ,CAAC;YACH,CAAC;SACF,CAAC;QAEF,MAAM,cAAc,GAAG,MAAM,aAAa,CAAC,aAAa,CACtD,UAAU,EACV,UAAU,CACX,CAAC;QAEF,IAAI,cAAc,EAAE,CAAC;YACnB,IAAI,EAAE,CAAC;QACT,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,oBAAoB,CAClC,OAA6B;IAE7B,MAAM,aAAa,GAAG,IAAI,6BAAa,CAAC,OAAO,CAAC,CAAC;IACjD,MAAM,UAAU,GAAG,uBAAuB,CAAC,aAAa,CAAC,CAAC;IAE1D,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { FastifyPluginCallback } from 'fastify';
|
|
2
|
+
import { CorsWhitelist } from '../core/CorsWhitelist';
|
|
3
|
+
import { CorsWhitelistOptions } from '../core/types';
|
|
4
|
+
export interface FastifyCorsOptions extends CorsWhitelistOptions {
|
|
5
|
+
/** Hook to use for CORS check (default: 'onRequest') */
|
|
6
|
+
hook?: 'onRequest' | 'preValidation' | 'preHandler';
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Fastify plugin for CORS whitelist validation
|
|
10
|
+
*/
|
|
11
|
+
export declare const fastifyCorsWhitelist: FastifyPluginCallback<FastifyCorsOptions>;
|
|
12
|
+
export default fastifyCorsWhitelist;
|
|
13
|
+
declare module 'fastify' {
|
|
14
|
+
interface FastifyInstance {
|
|
15
|
+
corsWhitelist: CorsWhitelist;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=fastify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fastify.d.ts","sourceRoot":"","sources":["../../../src/frameworks/fastify.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,qBAAqB,EAGtB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EACL,oBAAoB,EAGrB,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,kBAAmB,SAAQ,oBAAoB;IAC9D,wDAAwD;IACxD,IAAI,CAAC,EAAE,WAAW,GAAG,eAAe,GAAG,YAAY,CAAC;CACrD;AAED;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,qBAAqB,CAAC,kBAAkB,CAiD1E,CAAC;AAGF,eAAe,oBAAoB,CAAC;AAGpC,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,eAAe;QACvB,aAAa,EAAE,aAAa,CAAC;KAC9B;CACF"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fastifyCorsWhitelist = void 0;
|
|
4
|
+
const CorsWhitelist_1 = require("../core/CorsWhitelist");
|
|
5
|
+
/**
|
|
6
|
+
* Fastify plugin for CORS whitelist validation
|
|
7
|
+
*/
|
|
8
|
+
const fastifyCorsWhitelist = (fastify, options, done) => {
|
|
9
|
+
const corsWhitelist = new CorsWhitelist_1.CorsWhitelist(options);
|
|
10
|
+
const hook = options.hook ?? 'onRequest';
|
|
11
|
+
// Store the instance on fastify for access elsewhere
|
|
12
|
+
fastify.decorate('corsWhitelist', corsWhitelist);
|
|
13
|
+
fastify.addHook(hook, async (req, reply) => {
|
|
14
|
+
const genericReq = {
|
|
15
|
+
headers: req.headers,
|
|
16
|
+
method: req.method,
|
|
17
|
+
url: req.url,
|
|
18
|
+
ip: req.ip,
|
|
19
|
+
};
|
|
20
|
+
let responseSent = false;
|
|
21
|
+
const genericRes = {
|
|
22
|
+
setHeader: (name, value) => reply.header(name, value),
|
|
23
|
+
get statusCode() {
|
|
24
|
+
return reply.statusCode;
|
|
25
|
+
},
|
|
26
|
+
set statusCode(code) {
|
|
27
|
+
reply.status(code);
|
|
28
|
+
},
|
|
29
|
+
end: (body) => {
|
|
30
|
+
responseSent = true;
|
|
31
|
+
if (body) {
|
|
32
|
+
reply.type('application/json').send(body);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
reply.send();
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
const shouldContinue = await corsWhitelist.handleRequest(genericReq, genericRes);
|
|
40
|
+
if (!shouldContinue && !responseSent) {
|
|
41
|
+
return; // Reply already sent
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
done();
|
|
45
|
+
};
|
|
46
|
+
exports.fastifyCorsWhitelist = fastifyCorsWhitelist;
|
|
47
|
+
// For ES module default export compatibility
|
|
48
|
+
exports.default = exports.fastifyCorsWhitelist;
|
|
49
|
+
//# sourceMappingURL=fastify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fastify.js","sourceRoot":"","sources":["../../../src/frameworks/fastify.ts"],"names":[],"mappings":";;;AAMA,yDAAsD;AAYtD;;GAEG;AACI,MAAM,oBAAoB,GAA8C,CAC7E,OAAwB,EACxB,OAA2B,EAC3B,IAA2B,EAC3B,EAAE;IACF,MAAM,aAAa,GAAG,IAAI,6BAAa,CAAC,OAAO,CAAC,CAAC;IACjD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,WAAW,CAAC;IAEzC,qDAAqD;IACrD,OAAO,CAAC,QAAQ,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC;IAEjD,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,GAAmB,EAAE,KAAmB,EAAE,EAAE;QACvE,MAAM,UAAU,GAAmB;YACjC,OAAO,EAAE,GAAG,CAAC,OAAwD;YACrE,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,GAAG,EAAE,GAAG,CAAC,GAAG;YACZ,EAAE,EAAE,GAAG,CAAC,EAAE;SACX,CAAC;QAEF,IAAI,YAAY,GAAG,KAAK,CAAC;QACzB,MAAM,UAAU,GAAoB;YAClC,SAAS,EAAE,CAAC,IAAY,EAAE,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC;YACrE,IAAI,UAAU;gBACZ,OAAO,KAAK,CAAC,UAAU,CAAC;YAC1B,CAAC;YACD,IAAI,UAAU,CAAC,IAAY;gBACzB,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACrB,CAAC;YACD,GAAG,EAAE,CAAC,IAAa,EAAE,EAAE;gBACrB,YAAY,GAAG,IAAI,CAAC;gBACpB,IAAI,IAAI,EAAE,CAAC;oBACT,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC5C,CAAC;qBAAM,CAAC;oBACN,KAAK,CAAC,IAAI,EAAE,CAAC;gBACf,CAAC;YACH,CAAC;SACF,CAAC;QAEF,MAAM,cAAc,GAAG,MAAM,aAAa,CAAC,aAAa,CACtD,UAAU,EACV,UAAU,CACX,CAAC;QAEF,IAAI,CAAC,cAAc,IAAI,CAAC,YAAY,EAAE,CAAC;YACrC,OAAO,CAAC,qBAAqB;QAC/B,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,IAAI,EAAE,CAAC;AACT,CAAC,CAAC;AAjDW,QAAA,oBAAoB,wBAiD/B;AAEF,6CAA6C;AAC7C,kBAAe,4BAAoB,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { createExpressMiddleware, corsWhitelistExpress, } from './express';
|
|
2
|
+
export { fastifyCorsWhitelist, type FastifyCorsOptions, } from './fastify';
|
|
3
|
+
export { createKoaMiddleware, corsWhitelistKoa } from './koa';
|
|
4
|
+
export { createNodeHttpHandler, corsWhitelistHttp, type HttpHandler, } from './node-http';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/frameworks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,oBAAoB,EACpB,KAAK,kBAAkB,GACxB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAC9D,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,KAAK,WAAW,GACjB,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.corsWhitelistHttp = exports.createNodeHttpHandler = exports.corsWhitelistKoa = exports.createKoaMiddleware = exports.fastifyCorsWhitelist = exports.corsWhitelistExpress = exports.createExpressMiddleware = void 0;
|
|
4
|
+
var express_1 = require("./express");
|
|
5
|
+
Object.defineProperty(exports, "createExpressMiddleware", { enumerable: true, get: function () { return express_1.createExpressMiddleware; } });
|
|
6
|
+
Object.defineProperty(exports, "corsWhitelistExpress", { enumerable: true, get: function () { return express_1.corsWhitelistExpress; } });
|
|
7
|
+
var fastify_1 = require("./fastify");
|
|
8
|
+
Object.defineProperty(exports, "fastifyCorsWhitelist", { enumerable: true, get: function () { return fastify_1.fastifyCorsWhitelist; } });
|
|
9
|
+
var koa_1 = require("./koa");
|
|
10
|
+
Object.defineProperty(exports, "createKoaMiddleware", { enumerable: true, get: function () { return koa_1.createKoaMiddleware; } });
|
|
11
|
+
Object.defineProperty(exports, "corsWhitelistKoa", { enumerable: true, get: function () { return koa_1.corsWhitelistKoa; } });
|
|
12
|
+
var node_http_1 = require("./node-http");
|
|
13
|
+
Object.defineProperty(exports, "createNodeHttpHandler", { enumerable: true, get: function () { return node_http_1.createNodeHttpHandler; } });
|
|
14
|
+
Object.defineProperty(exports, "corsWhitelistHttp", { enumerable: true, get: function () { return node_http_1.corsWhitelistHttp; } });
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/frameworks/index.ts"],"names":[],"mappings":";;;AAAA,qCAGmB;AAFjB,kHAAA,uBAAuB,OAAA;AACvB,+GAAA,oBAAoB,OAAA;AAEtB,qCAGmB;AAFjB,+GAAA,oBAAoB,OAAA;AAGtB,6BAA8D;AAArD,0GAAA,mBAAmB,OAAA;AAAE,uGAAA,gBAAgB,OAAA;AAC9C,yCAIqB;AAHnB,kHAAA,qBAAqB,OAAA;AACrB,8GAAA,iBAAiB,OAAA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Middleware } from 'koa';
|
|
2
|
+
import { CorsWhitelist } from '../core/CorsWhitelist';
|
|
3
|
+
import { CorsWhitelistOptions } from '../core/types';
|
|
4
|
+
/**
|
|
5
|
+
* Create Koa middleware for CORS whitelist validation
|
|
6
|
+
*/
|
|
7
|
+
export declare function createKoaMiddleware(corsWhitelist: CorsWhitelist): Middleware;
|
|
8
|
+
/**
|
|
9
|
+
* Factory function to create both CorsWhitelist instance and Koa middleware
|
|
10
|
+
*/
|
|
11
|
+
export declare function corsWhitelistKoa(options: CorsWhitelistOptions): {
|
|
12
|
+
corsWhitelist: CorsWhitelist;
|
|
13
|
+
middleware: Middleware;
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=koa.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"koa.d.ts","sourceRoot":"","sources":["../../../src/frameworks/koa.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,UAAU,EAAE,MAAM,KAAK,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EACL,oBAAoB,EAGrB,MAAM,eAAe,CAAC;AAEvB;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,aAAa,GAAG,UAAU,CAoC5E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,oBAAoB,GAC5B;IAAE,aAAa,EAAE,aAAa,CAAC;IAAC,UAAU,EAAE,UAAU,CAAA;CAAE,CAK1D"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createKoaMiddleware = createKoaMiddleware;
|
|
4
|
+
exports.corsWhitelistKoa = corsWhitelistKoa;
|
|
5
|
+
const CorsWhitelist_1 = require("../core/CorsWhitelist");
|
|
6
|
+
/**
|
|
7
|
+
* Create Koa middleware for CORS whitelist validation
|
|
8
|
+
*/
|
|
9
|
+
function createKoaMiddleware(corsWhitelist) {
|
|
10
|
+
return async (ctx, next) => {
|
|
11
|
+
const genericReq = {
|
|
12
|
+
headers: ctx.headers,
|
|
13
|
+
method: ctx.method,
|
|
14
|
+
url: ctx.url,
|
|
15
|
+
ip: ctx.ip,
|
|
16
|
+
};
|
|
17
|
+
let responseEnded = false;
|
|
18
|
+
const genericRes = {
|
|
19
|
+
setHeader: (name, value) => ctx.set(name, value),
|
|
20
|
+
get statusCode() {
|
|
21
|
+
return ctx.status;
|
|
22
|
+
},
|
|
23
|
+
set statusCode(code) {
|
|
24
|
+
ctx.status = code;
|
|
25
|
+
},
|
|
26
|
+
end: (body) => {
|
|
27
|
+
responseEnded = true;
|
|
28
|
+
if (body) {
|
|
29
|
+
ctx.type = 'application/json';
|
|
30
|
+
ctx.body = body;
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
const shouldContinue = await corsWhitelist.handleRequest(genericReq, genericRes);
|
|
35
|
+
if (shouldContinue && !responseEnded) {
|
|
36
|
+
await next();
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Factory function to create both CorsWhitelist instance and Koa middleware
|
|
42
|
+
*/
|
|
43
|
+
function corsWhitelistKoa(options) {
|
|
44
|
+
const corsWhitelist = new CorsWhitelist_1.CorsWhitelist(options);
|
|
45
|
+
const middleware = createKoaMiddleware(corsWhitelist);
|
|
46
|
+
return { corsWhitelist, middleware };
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=koa.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"koa.js","sourceRoot":"","sources":["../../../src/frameworks/koa.ts"],"names":[],"mappings":";;AAWA,kDAoCC;AAKD,4CAOC;AA1DD,yDAAsD;AAOtD;;GAEG;AACH,SAAgB,mBAAmB,CAAC,aAA4B;IAC9D,OAAO,KAAK,EAAE,GAAY,EAAE,IAAU,EAAE,EAAE;QACxC,MAAM,UAAU,GAAmB;YACjC,OAAO,EAAE,GAAG,CAAC,OAAwD;YACrE,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,GAAG,EAAE,GAAG,CAAC,GAAG;YACZ,EAAE,EAAE,GAAG,CAAC,EAAE;SACX,CAAC;QAEF,IAAI,aAAa,GAAG,KAAK,CAAC;QAC1B,MAAM,UAAU,GAAoB;YAClC,SAAS,EAAE,CAAC,IAAY,EAAE,KAAa,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC;YAChE,IAAI,UAAU;gBACZ,OAAO,GAAG,CAAC,MAAM,CAAC;YACpB,CAAC;YACD,IAAI,UAAU,CAAC,IAAY;gBACzB,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC;YACpB,CAAC;YACD,GAAG,EAAE,CAAC,IAAa,EAAE,EAAE;gBACrB,aAAa,GAAG,IAAI,CAAC;gBACrB,IAAI,IAAI,EAAE,CAAC;oBACT,GAAG,CAAC,IAAI,GAAG,kBAAkB,CAAC;oBAC9B,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;gBAClB,CAAC;YACH,CAAC;SACF,CAAC;QAEF,MAAM,cAAc,GAAG,MAAM,aAAa,CAAC,aAAa,CACtD,UAAU,EACV,UAAU,CACX,CAAC;QAEF,IAAI,cAAc,IAAI,CAAC,aAAa,EAAE,CAAC;YACrC,MAAM,IAAI,EAAE,CAAC;QACf,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,gBAAgB,CAC9B,OAA6B;IAE7B,MAAM,aAAa,GAAG,IAAI,6BAAa,CAAC,OAAO,CAAC,CAAC;IACjD,MAAM,UAAU,GAAG,mBAAmB,CAAC,aAAa,CAAC,CAAC;IAEtD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { IncomingMessage, ServerResponse } from 'http';
|
|
2
|
+
import { CorsWhitelist } from '../core/CorsWhitelist';
|
|
3
|
+
import { CorsWhitelistOptions } from '../core/types';
|
|
4
|
+
export type HttpHandler = (req: IncomingMessage, res: ServerResponse) => Promise<boolean>;
|
|
5
|
+
/**
|
|
6
|
+
* Create plain Node.js HTTP handler for CORS whitelist validation
|
|
7
|
+
*/
|
|
8
|
+
export declare function createNodeHttpHandler(corsWhitelist: CorsWhitelist): HttpHandler;
|
|
9
|
+
/**
|
|
10
|
+
* Factory function to create both CorsWhitelist instance and HTTP handler
|
|
11
|
+
*/
|
|
12
|
+
export declare function corsWhitelistHttp(options: CorsWhitelistOptions): {
|
|
13
|
+
corsWhitelist: CorsWhitelist;
|
|
14
|
+
handler: HttpHandler;
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=node-http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-http.d.ts","sourceRoot":"","sources":["../../../src/frameworks/node-http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EACL,oBAAoB,EAGrB,MAAM,eAAe,CAAC;AAEvB,MAAM,MAAM,WAAW,GAAG,CACxB,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,KAChB,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,aAAa,EAAE,aAAa,GAC3B,WAAW,CAgCb;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,oBAAoB,GAC5B;IAAE,aAAa,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,WAAW,CAAA;CAAE,CAKxD"}
|