ugly-app 0.1.933 → 0.1.934
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/dist/cli/publish/staticDomain.d.ts +10 -0
- package/dist/cli/publish/staticDomain.d.ts.map +1 -1
- package/dist/cli/publish/staticDomain.js +28 -4
- package/dist/cli/publish/staticDomain.js.map +1 -1
- package/dist/cli/version.d.ts +1 -1
- package/dist/cli/version.js +1 -1
- package/package.json +1 -1
- package/src/cli/publish/staticDomain.test.ts +107 -2
- package/src/cli/publish/staticDomain.ts +32 -4
- package/src/cli/version.ts +1 -1
|
@@ -75,6 +75,16 @@ export declare function ensureR2CustomDomain(args: StaticDomainArgs): Promise<vo
|
|
|
75
75
|
* this, COEP `require-corp` blocks every `fetch()` of a static asset.
|
|
76
76
|
*/
|
|
77
77
|
export declare function putR2BucketCors(args: StaticDomainArgs): Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* Rule ref — stable per HOST, so re-running updates in place instead of
|
|
80
|
+
* stacking.
|
|
81
|
+
*
|
|
82
|
+
* It must be per-host, not a constant: a zone is SHARED by every app on it
|
|
83
|
+
* (~22 live on `ugly.bot`). With one fixed ref, the second app to provision
|
|
84
|
+
* would filter out the first app's rule and replace it with its own, silently
|
|
85
|
+
* un-CORP-ing that app and breaking its no-CORS assets.
|
|
86
|
+
*/
|
|
87
|
+
export declare function corpRuleRef(domain: string): string;
|
|
78
88
|
/**
|
|
79
89
|
* Add `Cross-Origin-Resource-Policy: cross-origin` to responses on the static
|
|
80
90
|
* host, so plain no-CORS subresources (`<img src>`, `<audio src>`) are not
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"staticDomain.d.ts","sourceRoot":"","sources":["../../../src/cli/publish/staticDomain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAMH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAWzE;AAgCD;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CAcjB;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC,IAAI,CAAC,CAmCf;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4B3E;
|
|
1
|
+
{"version":3,"file":"staticDomain.d.ts","sourceRoot":"","sources":["../../../src/cli/publish/staticDomain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAMH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAWzE;AAgCD;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CAcjB;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC,IAAI,CAAC,CAmCf;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4B3E;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAElD;AAWD;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC,IAAI,CAAC,CAuDf;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,gBAAgB,EACtB,GAAG,GAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAGrB,GACA,OAAO,CAAC,IAAI,CAAC,CAgBf"}
|
|
@@ -147,8 +147,26 @@ export async function putR2BucketCors(args) {
|
|
|
147
147
|
}),
|
|
148
148
|
}, 'putR2BucketCors');
|
|
149
149
|
}
|
|
150
|
-
/**
|
|
151
|
-
|
|
150
|
+
/**
|
|
151
|
+
* Rule ref — stable per HOST, so re-running updates in place instead of
|
|
152
|
+
* stacking.
|
|
153
|
+
*
|
|
154
|
+
* It must be per-host, not a constant: a zone is SHARED by every app on it
|
|
155
|
+
* (~22 live on `ugly.bot`). With one fixed ref, the second app to provision
|
|
156
|
+
* would filter out the first app's rule and replace it with its own, silently
|
|
157
|
+
* un-CORP-ing that app and breaking its no-CORS assets.
|
|
158
|
+
*/
|
|
159
|
+
export function corpRuleRef(domain) {
|
|
160
|
+
return `ugly_app_static_corp__${domain.toLowerCase().replace(/[^a-z0-9]+/g, '_')}`;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* The ref used before refs were per-host. Rules written under it are still out
|
|
164
|
+
* there (world3, ugly.chat), so provisioning drops the legacy rule when it
|
|
165
|
+
* targets the host we're about to write — otherwise the old and new rules sit
|
|
166
|
+
* side by side forever and nothing ever cleans the old one up. A legacy rule
|
|
167
|
+
* pointing at a DIFFERENT host belongs to another app and is left alone.
|
|
168
|
+
*/
|
|
169
|
+
const LEGACY_CORP_RULE_REF = 'ugly_app_static_corp';
|
|
152
170
|
/**
|
|
153
171
|
* Add `Cross-Origin-Resource-Policy: cross-origin` to responses on the static
|
|
154
172
|
* host, so plain no-CORS subresources (`<img src>`, `<audio src>`) are not
|
|
@@ -160,6 +178,7 @@ const CORP_RULE_REF = 'ugly_app_static_corp';
|
|
|
160
178
|
*/
|
|
161
179
|
export async function ensureCorpHeaderRule(args) {
|
|
162
180
|
const { token, rulesetToken, zoneId, domain } = args;
|
|
181
|
+
const ruleRef = corpRuleRef(domain);
|
|
163
182
|
const headers = {
|
|
164
183
|
'Authorization': `Bearer ${rulesetToken ?? token}`,
|
|
165
184
|
'Content-Type': 'application/json',
|
|
@@ -170,7 +189,7 @@ export async function ensureCorpHeaderRule(args) {
|
|
|
170
189
|
const existing = listed?.result
|
|
171
190
|
?.rules ?? [];
|
|
172
191
|
const corpRule = {
|
|
173
|
-
ref:
|
|
192
|
+
ref: ruleRef,
|
|
174
193
|
action: 'rewrite',
|
|
175
194
|
description: 'ugly-app: CORP for static assets (COEP require-corp)',
|
|
176
195
|
expression: `http.host eq "${domain}"`,
|
|
@@ -184,7 +203,12 @@ export async function ensureCorpHeaderRule(args) {
|
|
|
184
203
|
},
|
|
185
204
|
};
|
|
186
205
|
// Keep every rule that isn't ours, then append the current definition.
|
|
187
|
-
const
|
|
206
|
+
const expression = corpRule.expression;
|
|
207
|
+
const rules = [
|
|
208
|
+
...existing.filter((r) => r.ref !== ruleRef &&
|
|
209
|
+
!(r.ref === LEGACY_CORP_RULE_REF && r.expression === expression)),
|
|
210
|
+
corpRule,
|
|
211
|
+
];
|
|
188
212
|
await cf(`${base}/phases/http_response_headers_transform/entrypoint`, {
|
|
189
213
|
method: 'PUT',
|
|
190
214
|
headers,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"staticDomain.js","sourceRoot":"","sources":["../../../src/cli/publish/staticDomain.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"staticDomain.js","sourceRoot":"","sources":["../../../src/cli/publish/staticDomain.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const CLI_VERSION = "0.1.
|
|
1
|
+
export declare const CLI_VERSION = "0.1.934";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/cli/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ugly-app",
|
|
3
3
|
"packageManager": "pnpm@10.34.5",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.934",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"comment:files": "Allowlist what ships to npm. dist = runtime; src = sourcemap targets (dist/*.js.map reference ../../src/); templates = CLI scaffold. Everything else at repo root (.pgdata local Postgres, coverage, assets/icons sources, test/, test-results/) is excluded by omission. The !negations strip the scaffold's installed deps + cruft (templates/node_modules is 200MB+ and must never ship). package.json/README/LICENSE ship automatically.",
|
|
7
7
|
"files": [
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
2
2
|
import {
|
|
3
|
+
corpRuleRef,
|
|
3
4
|
ensureCorpHeaderRule,
|
|
4
5
|
ensureR2CustomDomain,
|
|
5
6
|
ensureStaticDomain,
|
|
@@ -180,6 +181,7 @@ describe('ensureCorpHeaderRule', () => {
|
|
|
180
181
|
});
|
|
181
182
|
|
|
182
183
|
it('replaces its own prior rule instead of stacking duplicates', async () => {
|
|
184
|
+
const mine = corpRuleRef('static.myapp.com');
|
|
183
185
|
const fetchMock = vi
|
|
184
186
|
.fn()
|
|
185
187
|
.mockResolvedValueOnce(
|
|
@@ -187,7 +189,7 @@ describe('ensureCorpHeaderRule', () => {
|
|
|
187
189
|
success: true,
|
|
188
190
|
result: {
|
|
189
191
|
rules: [
|
|
190
|
-
{ ref:
|
|
192
|
+
{ ref: mine, description: 'stale version' },
|
|
191
193
|
{ ref: 'someone_elses_rule', description: 'keep me' },
|
|
192
194
|
],
|
|
193
195
|
},
|
|
@@ -200,7 +202,59 @@ describe('ensureCorpHeaderRule', () => {
|
|
|
200
202
|
const [, init] = fetchMock.mock.calls[1]!;
|
|
201
203
|
const body = JSON.parse((init as RequestInit).body as string);
|
|
202
204
|
const refs = body.rules.map((r: { ref: string }) => r.ref);
|
|
203
|
-
expect(refs).toEqual(['someone_elses_rule',
|
|
205
|
+
expect(refs).toEqual(['someone_elses_rule', mine]);
|
|
206
|
+
expect(body.rules).toHaveLength(2);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
// Rules written before refs were per-host must be cleaned up, not doubled.
|
|
210
|
+
it('drops a legacy-ref rule that targets the same host', async () => {
|
|
211
|
+
const fetchMock = vi
|
|
212
|
+
.fn()
|
|
213
|
+
.mockResolvedValueOnce(
|
|
214
|
+
ok({
|
|
215
|
+
success: true,
|
|
216
|
+
result: {
|
|
217
|
+
rules: [
|
|
218
|
+
{
|
|
219
|
+
ref: 'ugly_app_static_corp',
|
|
220
|
+
expression: 'http.host eq "static.myapp.com"',
|
|
221
|
+
},
|
|
222
|
+
],
|
|
223
|
+
},
|
|
224
|
+
}),
|
|
225
|
+
)
|
|
226
|
+
.mockResolvedValueOnce(ok());
|
|
227
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
228
|
+
await ensureCorpHeaderRule(ARGS);
|
|
229
|
+
const body = JSON.parse(
|
|
230
|
+
(fetchMock.mock.calls[1]![1] as RequestInit).body as string,
|
|
231
|
+
);
|
|
232
|
+
expect(body.rules).toHaveLength(1);
|
|
233
|
+
expect(body.rules[0].ref).toBe(corpRuleRef('static.myapp.com'));
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
it('leaves a legacy-ref rule that targets a DIFFERENT host', async () => {
|
|
237
|
+
const fetchMock = vi
|
|
238
|
+
.fn()
|
|
239
|
+
.mockResolvedValueOnce(
|
|
240
|
+
ok({
|
|
241
|
+
success: true,
|
|
242
|
+
result: {
|
|
243
|
+
rules: [
|
|
244
|
+
{
|
|
245
|
+
ref: 'ugly_app_static_corp',
|
|
246
|
+
expression: 'http.host eq "other-static.ugly.bot"',
|
|
247
|
+
},
|
|
248
|
+
],
|
|
249
|
+
},
|
|
250
|
+
}),
|
|
251
|
+
)
|
|
252
|
+
.mockResolvedValueOnce(ok());
|
|
253
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
254
|
+
await ensureCorpHeaderRule(ARGS);
|
|
255
|
+
const body = JSON.parse(
|
|
256
|
+
(fetchMock.mock.calls[1]![1] as RequestInit).body as string,
|
|
257
|
+
);
|
|
204
258
|
expect(body.rules).toHaveLength(2);
|
|
205
259
|
});
|
|
206
260
|
|
|
@@ -323,3 +377,54 @@ describe('ensureCorpHeaderRule — credential selection', () => {
|
|
|
323
377
|
);
|
|
324
378
|
});
|
|
325
379
|
});
|
|
380
|
+
|
|
381
|
+
describe('corpRuleRef — a shared zone must not have one app clobber another', () => {
|
|
382
|
+
it('is distinct per host', () => {
|
|
383
|
+
expect(corpRuleRef('world3-static.ugly.bot')).not.toBe(
|
|
384
|
+
corpRuleRef('game-demo-static.ugly.bot'),
|
|
385
|
+
);
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
it('is stable for the same host so re-publishing updates in place', () => {
|
|
389
|
+
expect(corpRuleRef('world3-static.ugly.bot')).toBe(
|
|
390
|
+
corpRuleRef('world3-static.ugly.bot'),
|
|
391
|
+
);
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
it('contains only ref-safe characters', () => {
|
|
395
|
+
expect(corpRuleRef('world3-static.ugly.bot')).toMatch(/^[a-z0-9_]+$/);
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
// The bug this guards: ~22 apps share the ugly.bot zone. With a constant
|
|
399
|
+
// ref, app B's provisioning filtered out app A's rule and replaced it,
|
|
400
|
+
// silently un-CORP-ing app A.
|
|
401
|
+
it('preserves another app rule on the same zone', async () => {
|
|
402
|
+
const other = corpRuleRef('game-demo-static.ugly.bot');
|
|
403
|
+
const fetchMock = vi
|
|
404
|
+
.fn()
|
|
405
|
+
.mockResolvedValueOnce(
|
|
406
|
+
ok({
|
|
407
|
+
success: true,
|
|
408
|
+
result: {
|
|
409
|
+
rules: [
|
|
410
|
+
{
|
|
411
|
+
ref: other,
|
|
412
|
+
expression: 'http.host eq "game-demo-static.ugly.bot"',
|
|
413
|
+
},
|
|
414
|
+
],
|
|
415
|
+
},
|
|
416
|
+
}),
|
|
417
|
+
)
|
|
418
|
+
.mockResolvedValueOnce(ok());
|
|
419
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
420
|
+
await ensureCorpHeaderRule({ ...ARGS, domain: 'world3-static.ugly.bot' });
|
|
421
|
+
|
|
422
|
+
const body = JSON.parse(
|
|
423
|
+
(fetchMock.mock.calls[1]![1] as RequestInit).body as string,
|
|
424
|
+
);
|
|
425
|
+
const refs = body.rules.map((r: { ref: string }) => r.ref);
|
|
426
|
+
expect(refs).toContain(other);
|
|
427
|
+
expect(refs).toContain(corpRuleRef('world3-static.ugly.bot'));
|
|
428
|
+
expect(body.rules).toHaveLength(2);
|
|
429
|
+
});
|
|
430
|
+
});
|
|
@@ -208,8 +208,27 @@ export async function putR2BucketCors(args: StaticDomainArgs): Promise<void> {
|
|
|
208
208
|
);
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
-
/**
|
|
212
|
-
|
|
211
|
+
/**
|
|
212
|
+
* Rule ref — stable per HOST, so re-running updates in place instead of
|
|
213
|
+
* stacking.
|
|
214
|
+
*
|
|
215
|
+
* It must be per-host, not a constant: a zone is SHARED by every app on it
|
|
216
|
+
* (~22 live on `ugly.bot`). With one fixed ref, the second app to provision
|
|
217
|
+
* would filter out the first app's rule and replace it with its own, silently
|
|
218
|
+
* un-CORP-ing that app and breaking its no-CORS assets.
|
|
219
|
+
*/
|
|
220
|
+
export function corpRuleRef(domain: string): string {
|
|
221
|
+
return `ugly_app_static_corp__${domain.toLowerCase().replace(/[^a-z0-9]+/g, '_')}`;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* The ref used before refs were per-host. Rules written under it are still out
|
|
226
|
+
* there (world3, ugly.chat), so provisioning drops the legacy rule when it
|
|
227
|
+
* targets the host we're about to write — otherwise the old and new rules sit
|
|
228
|
+
* side by side forever and nothing ever cleans the old one up. A legacy rule
|
|
229
|
+
* pointing at a DIFFERENT host belongs to another app and is left alone.
|
|
230
|
+
*/
|
|
231
|
+
const LEGACY_CORP_RULE_REF = 'ugly_app_static_corp';
|
|
213
232
|
|
|
214
233
|
/**
|
|
215
234
|
* Add `Cross-Origin-Resource-Policy: cross-origin` to responses on the static
|
|
@@ -224,6 +243,7 @@ export async function ensureCorpHeaderRule(
|
|
|
224
243
|
args: StaticDomainArgs,
|
|
225
244
|
): Promise<void> {
|
|
226
245
|
const { token, rulesetToken, zoneId, domain } = args;
|
|
246
|
+
const ruleRef = corpRuleRef(domain);
|
|
227
247
|
const headers = {
|
|
228
248
|
'Authorization': `Bearer ${rulesetToken ?? token}`,
|
|
229
249
|
'Content-Type': 'application/json',
|
|
@@ -242,7 +262,7 @@ export async function ensureCorpHeaderRule(
|
|
|
242
262
|
?.rules ?? [];
|
|
243
263
|
|
|
244
264
|
const corpRule = {
|
|
245
|
-
ref:
|
|
265
|
+
ref: ruleRef,
|
|
246
266
|
action: 'rewrite',
|
|
247
267
|
description: 'ugly-app: CORP for static assets (COEP require-corp)',
|
|
248
268
|
expression: `http.host eq "${domain}"`,
|
|
@@ -257,7 +277,15 @@ export async function ensureCorpHeaderRule(
|
|
|
257
277
|
};
|
|
258
278
|
|
|
259
279
|
// Keep every rule that isn't ours, then append the current definition.
|
|
260
|
-
const
|
|
280
|
+
const expression = corpRule.expression;
|
|
281
|
+
const rules = [
|
|
282
|
+
...existing.filter(
|
|
283
|
+
(r) =>
|
|
284
|
+
r.ref !== ruleRef &&
|
|
285
|
+
!(r.ref === LEGACY_CORP_RULE_REF && r.expression === expression),
|
|
286
|
+
),
|
|
287
|
+
corpRule,
|
|
288
|
+
];
|
|
261
289
|
|
|
262
290
|
await cf(
|
|
263
291
|
`${base}/phases/http_response_headers_transform/entrypoint`,
|
package/src/cli/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Auto-generated by prebuild — do not edit manually
|
|
2
|
-
export const CLI_VERSION = "0.1.
|
|
2
|
+
export const CLI_VERSION = "0.1.934";
|