@paywalls-net/filter 1.3.6 → 1.3.8
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/package.json +1 -1
- package/src/index.js +52 -7
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -78,9 +78,24 @@ function isVAIRequest(request, vaiPath = '/pw') {
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
/**
|
|
81
|
-
* Proxy VAI requests to the cloud-api service.
|
|
82
|
-
*
|
|
83
|
-
*
|
|
81
|
+
* Proxy VAI requests to the cloud-api service (Spec §7).
|
|
82
|
+
*
|
|
83
|
+
* Transparent passthrough: cloud-api is authoritative for CORS, domain auth,
|
|
84
|
+
* and security headers. This proxy must NOT inject or modify CORS headers.
|
|
85
|
+
*
|
|
86
|
+
* Header forwarding (§7.2):
|
|
87
|
+
* - X-Forwarded-Origin: browser Origin (Cloudflare Workers control the
|
|
88
|
+
* outbound Origin header, so we relay via a custom header)
|
|
89
|
+
* - X-Original-Host: publisher hostname for domain binding
|
|
90
|
+
* - Access-Control-Request-Method/Headers: for preflight evaluation
|
|
91
|
+
* - Cookie: for session/identity context
|
|
92
|
+
* - User-Agent, X-Forwarded-For: standard proxy headers
|
|
93
|
+
* - Authorization: publisher API key (§7.4)
|
|
94
|
+
*
|
|
95
|
+
* Response passthrough (§7.3):
|
|
96
|
+
* All response headers from cloud-api are returned unchanged — including
|
|
97
|
+
* Access-Control-*, Vary, Cache-Control. The proxy never injects or
|
|
98
|
+
* re-stamps CORS headers.
|
|
84
99
|
*
|
|
85
100
|
* @param {Object} cfg - Configuration object with paywallsAPIHost and paywallsAPIKey
|
|
86
101
|
* @param {Request} request - The incoming request
|
|
@@ -96,26 +111,50 @@ async function proxyVAIRequest(cfg, request) {
|
|
|
96
111
|
// Get all request headers
|
|
97
112
|
const headers = getAllHeaders(request);
|
|
98
113
|
|
|
99
|
-
// Build forwarding headers
|
|
114
|
+
// Build forwarding headers — include everything cloud-api needs
|
|
115
|
+
// for CORS evaluation, domain auth, and request context.
|
|
100
116
|
const forwardHeaders = {
|
|
101
117
|
'User-Agent': headers['user-agent'] || sdkUserAgent,
|
|
102
118
|
'Authorization': `Bearer ${cfg.paywallsAPIKey}`
|
|
103
119
|
};
|
|
104
120
|
|
|
105
|
-
//
|
|
121
|
+
// Client IP forwarding
|
|
106
122
|
if (headers['x-forwarded-for']) {
|
|
107
123
|
forwardHeaders['X-Forwarded-For'] = headers['x-forwarded-for'];
|
|
108
124
|
} else if (headers['cf-connecting-ip']) {
|
|
109
125
|
forwardHeaders['X-Forwarded-For'] = headers['cf-connecting-ip'];
|
|
110
126
|
}
|
|
111
127
|
|
|
128
|
+
// Publisher hostname for domain binding (§7.2, §4)
|
|
129
|
+
// Cloud-api gates reading this on the vai_forwarded_host feature flag.
|
|
112
130
|
if (headers['host']) {
|
|
113
131
|
forwardHeaders['X-Original-Host'] = headers['host'];
|
|
114
132
|
}
|
|
115
133
|
|
|
134
|
+
// Forward browser Origin via custom header for CORS evaluation (§5, §7.2).
|
|
135
|
+
// Cloudflare Workers runtime controls the outbound Origin header on fetch(),
|
|
136
|
+
// so we relay the browser's Origin via X-Forwarded-Origin. Cloud-api's
|
|
137
|
+
// evaluateCORS() reads this to make the authoritative CORS decision.
|
|
138
|
+
if (headers['origin']) {
|
|
139
|
+
forwardHeaders['X-Forwarded-Origin'] = headers['origin'];
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Forward preflight headers so cloud-api can evaluate OPTIONS (§5.4, §7.2)
|
|
143
|
+
if (headers['access-control-request-method']) {
|
|
144
|
+
forwardHeaders['Access-Control-Request-Method'] = headers['access-control-request-method'];
|
|
145
|
+
}
|
|
146
|
+
if (headers['access-control-request-headers']) {
|
|
147
|
+
forwardHeaders['Access-Control-Request-Headers'] = headers['access-control-request-headers'];
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Forward cookies for session/identity context (§7.2)
|
|
151
|
+
if (headers['cookie']) {
|
|
152
|
+
forwardHeaders['Cookie'] = headers['cookie'];
|
|
153
|
+
}
|
|
154
|
+
|
|
116
155
|
// Forward request to cloud-api
|
|
117
156
|
const response = await fetch(`${cfg.paywallsAPIHost}${cloudApiPath}`, {
|
|
118
|
-
method: 'GET',
|
|
157
|
+
method: request.method || 'GET',
|
|
119
158
|
headers: forwardHeaders
|
|
120
159
|
});
|
|
121
160
|
|
|
@@ -123,7 +162,13 @@ async function proxyVAIRequest(cfg, request) {
|
|
|
123
162
|
console.error(`VAI proxy error: ${response.status} ${response.statusText}`);
|
|
124
163
|
}
|
|
125
164
|
|
|
126
|
-
return response
|
|
165
|
+
// Transparent passthrough (§7.3): return cloud-api response unchanged.
|
|
166
|
+
// Cloud-api is authoritative for CORS headers — do not re-stamp or inject.
|
|
167
|
+
return new Response(response.body, {
|
|
168
|
+
status: response.status,
|
|
169
|
+
statusText: response.statusText,
|
|
170
|
+
headers: response.headers
|
|
171
|
+
});
|
|
127
172
|
} catch (err) {
|
|
128
173
|
console.error(`Error proxying VAI request: ${err.message}`);
|
|
129
174
|
return new Response('Internal Server Error', { status: 500 });
|