astro 6.1.9 → 6.1.10
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/infra/build-time-astro-version-provider.js +1 -1
- package/dist/content/content-layer.js +3 -3
- package/dist/core/app/manifest.js +2 -0
- package/dist/core/constants.js +1 -1
- package/dist/core/dev/dev.js +2 -2
- package/dist/core/encryption.d.ts +6 -2
- package/dist/core/encryption.js +12 -18
- package/dist/core/messages/runtime.js +1 -1
- package/dist/core/server-islands/endpoint.js +7 -3
- package/dist/runtime/client/dev-toolbar/apps/audit/index.js +4 -1
- package/dist/runtime/server/render/server-islands.js +7 -3
- package/dist/toolbar/vite-plugin-dev-toolbar.js +23 -1
- package/dist/vite-plugin-environment/index.js +2 -1
- package/package.json +2 -2
|
@@ -192,7 +192,7 @@ ${contentConfig.error.message}`
|
|
|
192
192
|
logger.info("Content config changed");
|
|
193
193
|
shouldClear = true;
|
|
194
194
|
}
|
|
195
|
-
if (previousAstroVersion && previousAstroVersion !== "6.1.
|
|
195
|
+
if (previousAstroVersion && previousAstroVersion !== "6.1.10") {
|
|
196
196
|
logger.info("Astro version changed");
|
|
197
197
|
shouldClear = true;
|
|
198
198
|
}
|
|
@@ -200,8 +200,8 @@ ${contentConfig.error.message}`
|
|
|
200
200
|
logger.info("Clearing content store");
|
|
201
201
|
this.#store.clearAll();
|
|
202
202
|
}
|
|
203
|
-
if ("6.1.
|
|
204
|
-
this.#store.metaStore().set("astro-version", "6.1.
|
|
203
|
+
if ("6.1.10") {
|
|
204
|
+
this.#store.metaStore().set("astro-version", "6.1.10");
|
|
205
205
|
}
|
|
206
206
|
if (currentConfigDigest) {
|
|
207
207
|
this.#store.metaStore().set("content-config-digest", currentConfigDigest);
|
|
@@ -64,6 +64,8 @@ function deserializeRouteData(rawRouteData) {
|
|
|
64
64
|
return {
|
|
65
65
|
route: rawRouteData.route,
|
|
66
66
|
type: rawRouteData.type,
|
|
67
|
+
// nosemgrep: javascript.lang.security.audit.detect-non-literal-regexp.detect-non-literal-regexp
|
|
68
|
+
// This pattern is serialized from Astro's own route manifest.
|
|
67
69
|
pattern: new RegExp(rawRouteData.pattern),
|
|
68
70
|
params: rawRouteData.params,
|
|
69
71
|
component: rawRouteData.component,
|
package/dist/core/constants.js
CHANGED
package/dist/core/dev/dev.js
CHANGED
|
@@ -37,7 +37,7 @@ async function dev(inlineConfig) {
|
|
|
37
37
|
await telemetry.record([]);
|
|
38
38
|
const restart = await createContainerWithAutomaticRestart({ inlineConfig, fs });
|
|
39
39
|
const logger = restart.container.logger;
|
|
40
|
-
const currentVersion = "6.1.
|
|
40
|
+
const currentVersion = "6.1.10";
|
|
41
41
|
const isPrerelease = currentVersion.includes("-");
|
|
42
42
|
if (!isPrerelease) {
|
|
43
43
|
try {
|
|
@@ -89,7 +89,7 @@ async function dev(inlineConfig) {
|
|
|
89
89
|
});
|
|
90
90
|
contentLayer.watchContentConfig();
|
|
91
91
|
await contentLayer.sync();
|
|
92
|
-
} else {
|
|
92
|
+
} else if (config.status !== "does-not-exist") {
|
|
93
93
|
logger.warn("content", "Content config not loaded");
|
|
94
94
|
}
|
|
95
95
|
const devServerAddressInfo = await startContainer(restart.container);
|
|
@@ -22,12 +22,16 @@ export declare function encodeKey(key: CryptoKey): Promise<string>;
|
|
|
22
22
|
export declare function decodeKey(encoded: string): Promise<CryptoKey>;
|
|
23
23
|
/**
|
|
24
24
|
* Using a CryptoKey, encrypt a string into a base64 string.
|
|
25
|
+
* @param additionalData Optional authenticated context (e.g. "props:ComponentName") that is
|
|
26
|
+
* verified during decryption but not included in the ciphertext. Both sides must agree on
|
|
27
|
+
* the same value or decryption will fail.
|
|
25
28
|
*/
|
|
26
|
-
export declare function encryptString(key: CryptoKey, raw: string): Promise<string>;
|
|
29
|
+
export declare function encryptString(key: CryptoKey, raw: string, additionalData?: string): Promise<string>;
|
|
27
30
|
/**
|
|
28
31
|
* Takes a base64 encoded string, decodes it and returns the decrypted text.
|
|
32
|
+
* @param additionalData Must match the value used during encryption, or decryption will fail.
|
|
29
33
|
*/
|
|
30
|
-
export declare function decryptString(key: CryptoKey, encoded: string): Promise<string>;
|
|
34
|
+
export declare function decryptString(key: CryptoKey, encoded: string, additionalData?: string): Promise<string>;
|
|
31
35
|
/**
|
|
32
36
|
* Generates an SHA-256 digest of the given string.
|
|
33
37
|
* @param {string} data The string to hash.
|
package/dist/core/encryption.js
CHANGED
|
@@ -43,30 +43,24 @@ async function decodeKey(encoded) {
|
|
|
43
43
|
const encoder = new TextEncoder();
|
|
44
44
|
const decoder = new TextDecoder();
|
|
45
45
|
const IV_LENGTH = 24;
|
|
46
|
-
async function encryptString(key, raw) {
|
|
46
|
+
async function encryptString(key, raw, additionalData) {
|
|
47
47
|
const iv = crypto.getRandomValues(new Uint8Array(IV_LENGTH / 2));
|
|
48
48
|
const data = encoder.encode(raw);
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
key,
|
|
55
|
-
data
|
|
56
|
-
);
|
|
49
|
+
const params = { name: ALGORITHM, iv };
|
|
50
|
+
if (additionalData) {
|
|
51
|
+
params.additionalData = encoder.encode(additionalData);
|
|
52
|
+
}
|
|
53
|
+
const buffer = await crypto.subtle.encrypt(params, key, data);
|
|
57
54
|
return encodeHexUpperCase(iv) + encodeBase64(new Uint8Array(buffer));
|
|
58
55
|
}
|
|
59
|
-
async function decryptString(key, encoded) {
|
|
56
|
+
async function decryptString(key, encoded, additionalData) {
|
|
60
57
|
const iv = decodeHex(encoded.slice(0, IV_LENGTH));
|
|
61
58
|
const dataArray = decodeBase64(encoded.slice(IV_LENGTH));
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
key,
|
|
68
|
-
dataArray
|
|
69
|
-
);
|
|
59
|
+
const params = { name: ALGORITHM, iv };
|
|
60
|
+
if (additionalData) {
|
|
61
|
+
params.additionalData = encoder.encode(additionalData);
|
|
62
|
+
}
|
|
63
|
+
const decryptedBuffer = await crypto.subtle.decrypt(params, key, dataArray);
|
|
70
64
|
const decryptedString = decoder.decode(decryptedBuffer);
|
|
71
65
|
return decryptedString;
|
|
72
66
|
}
|
|
@@ -112,7 +112,11 @@ function createEndpoint(manifest) {
|
|
|
112
112
|
const key = await manifest.key;
|
|
113
113
|
let componentExport;
|
|
114
114
|
try {
|
|
115
|
-
componentExport = await decryptString(
|
|
115
|
+
componentExport = await decryptString(
|
|
116
|
+
key,
|
|
117
|
+
data.encryptedComponentExport,
|
|
118
|
+
`export:${componentId}`
|
|
119
|
+
);
|
|
116
120
|
} catch (_e) {
|
|
117
121
|
return badRequest("Encrypted componentExport value is invalid.");
|
|
118
122
|
}
|
|
@@ -120,7 +124,7 @@ function createEndpoint(manifest) {
|
|
|
120
124
|
let props = {};
|
|
121
125
|
if (encryptedProps !== "") {
|
|
122
126
|
try {
|
|
123
|
-
const propString = await decryptString(key, encryptedProps);
|
|
127
|
+
const propString = await decryptString(key, encryptedProps, `props:${componentId}`);
|
|
124
128
|
props = JSON.parse(propString);
|
|
125
129
|
} catch (_e) {
|
|
126
130
|
return badRequest("Encrypted props value is invalid.");
|
|
@@ -130,7 +134,7 @@ function createEndpoint(manifest) {
|
|
|
130
134
|
const encryptedSlots = data.encryptedSlots;
|
|
131
135
|
if (encryptedSlots !== "") {
|
|
132
136
|
try {
|
|
133
|
-
const slotsString = await decryptString(key, encryptedSlots);
|
|
137
|
+
const slotsString = await decryptString(key, encryptedSlots, `slots:${componentId}`);
|
|
134
138
|
decryptedSlots = JSON.parse(slotsString);
|
|
135
139
|
} catch (_e) {
|
|
136
140
|
return badRequest("Encrypted slots value is invalid.");
|
|
@@ -147,7 +147,10 @@ var audit_default = {
|
|
|
147
147
|
return;
|
|
148
148
|
}
|
|
149
149
|
if (originalElement.nodeName === "IMG" && !originalElement.complete) {
|
|
150
|
-
|
|
150
|
+
await new Promise((resolve) => {
|
|
151
|
+
originalElement.addEventListener("load", () => resolve(), { once: true });
|
|
152
|
+
originalElement.addEventListener("error", () => resolve(), { once: true });
|
|
153
|
+
});
|
|
151
154
|
}
|
|
152
155
|
audits.push({
|
|
153
156
|
auditedElement: originalElement,
|
|
@@ -126,9 +126,13 @@ class ServerIslandComponent {
|
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
128
|
const key = await this.result.key;
|
|
129
|
-
const componentExportEncrypted = await encryptString(
|
|
130
|
-
|
|
131
|
-
|
|
129
|
+
const componentExportEncrypted = await encryptString(
|
|
130
|
+
key,
|
|
131
|
+
componentExport,
|
|
132
|
+
`export:${componentId}`
|
|
133
|
+
);
|
|
134
|
+
const propsEncrypted = Object.keys(this.props).length === 0 ? "" : await encryptString(key, JSON.stringify(this.props), `props:${componentId}`);
|
|
135
|
+
const slotsEncrypted = Object.keys(renderedSlots).length === 0 ? "" : await encryptString(key, JSON.stringify(renderedSlots), `slots:${componentId}`);
|
|
132
136
|
const hostId = await this.getHostId();
|
|
133
137
|
const slash = this.result.base.endsWith("/") ? "" : "/";
|
|
134
138
|
let serverIslandUrl = `${this.result.base}${slash}_server-islands/${componentId}${this.result.trailingSlash === "always" ? "/" : ""}`;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
1
2
|
import { telemetry } from "../events/index.js";
|
|
2
3
|
import { eventAppToggled } from "../events/toolbar.js";
|
|
3
4
|
const VIRTUAL_MODULE_ID = "astro:toolbar:internal";
|
|
@@ -14,7 +15,28 @@ function astroDevToolbar({ settings, logger }) {
|
|
|
14
15
|
"astro > aria-query",
|
|
15
16
|
"astro > axobject-query",
|
|
16
17
|
...settings.devToolbarApps.length > 0 ? ["astro/toolbar"] : []
|
|
17
|
-
]
|
|
18
|
+
],
|
|
19
|
+
esbuildOptions: {
|
|
20
|
+
plugins: [
|
|
21
|
+
{
|
|
22
|
+
name: "astro:strip-toolbar-sourcemap",
|
|
23
|
+
setup(build) {
|
|
24
|
+
build.onEnd((result) => {
|
|
25
|
+
if (!result.metafile) return;
|
|
26
|
+
for (const outputPath of Object.keys(result.metafile.outputs)) {
|
|
27
|
+
if (!outputPath.includes("entrypoint") || !outputPath.endsWith(".js"))
|
|
28
|
+
continue;
|
|
29
|
+
const code = readFileSync(outputPath, "utf-8");
|
|
30
|
+
const stripped = code.replace(/\/\/# sourceMappingURL=.*$/m, "");
|
|
31
|
+
if (stripped !== code) {
|
|
32
|
+
writeFileSync(outputPath, stripped);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
}
|
|
18
40
|
}
|
|
19
41
|
};
|
|
20
42
|
},
|
|
@@ -60,7 +60,8 @@ function vitePluginEnvironment({
|
|
|
60
60
|
finalEnvironmentOptions.optimizeDeps = {
|
|
61
61
|
include: [
|
|
62
62
|
// For the dev toolbar
|
|
63
|
-
"astro > html-escaper"
|
|
63
|
+
"astro > html-escaper",
|
|
64
|
+
"astro/runtime/client/dev-toolbar/entrypoint.js"
|
|
64
65
|
],
|
|
65
66
|
exclude: ["astro:*", "virtual:astro:*", "astro/virtual-modules/prefetch.js"],
|
|
66
67
|
// Astro files can't be rendered on the client
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astro",
|
|
3
|
-
"version": "6.1.
|
|
3
|
+
"version": "6.1.10",
|
|
4
4
|
"description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "withastro",
|
|
@@ -189,7 +189,7 @@
|
|
|
189
189
|
"undici": "^7.22.0",
|
|
190
190
|
"unified": "^11.0.5",
|
|
191
191
|
"vitest": "^4.1.0",
|
|
192
|
-
"@astrojs/check": "0.9.
|
|
192
|
+
"@astrojs/check": "0.9.9",
|
|
193
193
|
"astro-scripts": "0.0.14"
|
|
194
194
|
},
|
|
195
195
|
"engines": {
|