@warpgogol/werkstatt-shared 0.8.2 → 0.8.3
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
CHANGED
|
@@ -219,6 +219,8 @@ export interface ImageVariantEntry {
|
|
|
219
219
|
* stale derived variants (same contract as video.variants.generate RFC-0210).
|
|
220
220
|
*/
|
|
221
221
|
sourceHash?: string;
|
|
222
|
+
/** RFC-0928: WebP quality used by image.variants.generate (minimum 90). */
|
|
223
|
+
quality?: number;
|
|
222
224
|
}
|
|
223
225
|
|
|
224
226
|
/** Top-level manifest written by `image.variants.generate` and read by createBuildPortableProvider. */
|
|
@@ -45,6 +45,16 @@ function isDevOrAltHost(host: string): boolean {
|
|
|
45
45
|
return host.startsWith("dev.") || host.startsWith("alt.");
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Paths exempt from access protection on dev/alt subdomains.
|
|
50
|
+
* Browsers fetch these without sending Basic Auth credentials, causing 401 console errors.
|
|
51
|
+
*/
|
|
52
|
+
const PUBLIC_STATIC_EXEMPTIONS = ["/manifest.webmanifest"];
|
|
53
|
+
|
|
54
|
+
function isExemptPath(pathname: string): boolean {
|
|
55
|
+
return PUBLIC_STATIC_EXEMPTIONS.includes(pathname);
|
|
56
|
+
}
|
|
57
|
+
|
|
48
58
|
/**
|
|
49
59
|
* RFC-0899: Check access protection for a request. Called from the Worker entry point
|
|
50
60
|
* (worker.ts) before passing to the Astro handler. This is necessary because Astro
|
|
@@ -66,6 +76,9 @@ export function checkAccessProtection(
|
|
|
66
76
|
const host = request.headers.get("host") ?? "";
|
|
67
77
|
if (!isDevOrAltHost(host)) return null;
|
|
68
78
|
|
|
79
|
+
const url = new URL(request.url);
|
|
80
|
+
if (isExemptPath(url.pathname)) return null;
|
|
81
|
+
|
|
69
82
|
const pin = (env.ACCESS_PIN as string | undefined) ?? undefined;
|
|
70
83
|
|
|
71
84
|
// No PIN set — allow access (caller should add X-Robots-Tag)
|
|
@@ -144,6 +157,13 @@ export const accessProtectionMiddleware = defineMiddleware(async (context: any,
|
|
|
144
157
|
return next();
|
|
145
158
|
}
|
|
146
159
|
|
|
160
|
+
const url = new URL(context.request.url);
|
|
161
|
+
if (isExemptPath(url.pathname)) {
|
|
162
|
+
const response = await next();
|
|
163
|
+
response.headers.set("X-Robots-Tag", NOINDEX_HEADER);
|
|
164
|
+
return response;
|
|
165
|
+
}
|
|
166
|
+
|
|
147
167
|
const pin = await resolveAccessPin();
|
|
148
168
|
|
|
149
169
|
// No PIN set — allow access but still set noindex headers
|
|
@@ -25,7 +25,7 @@ describe("RFC-0899: access protection middleware", () => {
|
|
|
25
25
|
) => Promise<Response>;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
function makeContext(host: string, authHeader?: string) {
|
|
28
|
+
function makeContext(host: string, authHeader?: string, pathname = "/") {
|
|
29
29
|
const headers = new Map<string, string>();
|
|
30
30
|
headers.set("host", host);
|
|
31
31
|
if (authHeader) headers.set("authorization", authHeader);
|
|
@@ -34,6 +34,7 @@ describe("RFC-0899: access protection middleware", () => {
|
|
|
34
34
|
headers: {
|
|
35
35
|
get: (name: string) => headers.get(name.toLowerCase()) ?? null,
|
|
36
36
|
},
|
|
37
|
+
url: `https://${host}${pathname}`,
|
|
37
38
|
},
|
|
38
39
|
};
|
|
39
40
|
}
|
|
@@ -42,10 +43,11 @@ describe("RFC-0899: access protection middleware", () => {
|
|
|
42
43
|
handler: (context: unknown, next: () => Promise<Response>) => Promise<Response>,
|
|
43
44
|
host: string,
|
|
44
45
|
authHeader?: string,
|
|
46
|
+
pathname = "/",
|
|
45
47
|
): Promise<Response & { _nextCalled: boolean }> {
|
|
46
48
|
let nextCalled = false;
|
|
47
49
|
const nextResponse = new Response("page content", { status: 200 });
|
|
48
|
-
const result = await handler(makeContext(host, authHeader), async () => {
|
|
50
|
+
const result = await handler(makeContext(host, authHeader, pathname), async () => {
|
|
49
51
|
nextCalled = true;
|
|
50
52
|
return nextResponse;
|
|
51
53
|
});
|
|
@@ -120,4 +122,21 @@ describe("RFC-0899: access protection middleware", () => {
|
|
|
120
122
|
const res = await runMiddleware(handler, "example.com");
|
|
121
123
|
expect(res.headers.get("X-Robots-Tag")).toBe(null);
|
|
122
124
|
});
|
|
125
|
+
|
|
126
|
+
it("exempts /manifest.webmanifest from auth on dev.* when PIN is set", async () => {
|
|
127
|
+
mockEnv.ACCESS_PIN = "1234";
|
|
128
|
+
const handler = await loadMiddleware();
|
|
129
|
+
const res = await runMiddleware(handler, "dev.example.com", undefined, "/manifest.webmanifest");
|
|
130
|
+
expect(res._nextCalled).toBe(true);
|
|
131
|
+
expect(res.status).toBe(200);
|
|
132
|
+
expect(res.headers.get("X-Robots-Tag")).toBe("noindex, nofollow, noai, noimageai");
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it("exempts /manifest.webmanifest from auth on alt.* when PIN is set", async () => {
|
|
136
|
+
mockEnv.ACCESS_PIN = "1234";
|
|
137
|
+
const handler = await loadMiddleware();
|
|
138
|
+
const res = await runMiddleware(handler, "alt.example.com", undefined, "/manifest.webmanifest");
|
|
139
|
+
expect(res._nextCalled).toBe(true);
|
|
140
|
+
expect(res.status).toBe(200);
|
|
141
|
+
});
|
|
123
142
|
});
|