astro 4.13.3 → 4.13.4
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/@types/astro.d.ts +2 -1
- package/dist/actions/runtime/virtual/server.js +9 -3
- package/dist/actions/runtime/virtual/shared.js +25 -3
- package/dist/container/index.js +3 -1
- package/dist/core/app/common.js +4 -1
- package/dist/core/app/index.js +5 -3
- package/dist/core/app/types.d.ts +3 -1
- package/dist/core/build/generate.js +4 -2
- package/dist/core/build/index.js +3 -1
- package/dist/core/build/plugins/plugin-manifest.js +5 -2
- package/dist/core/build/plugins/plugin-ssr.js +5 -1
- package/dist/core/build/static-build.js +2 -0
- package/dist/core/build/types.d.ts +1 -0
- package/dist/core/constants.js +1 -1
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/encryption.d.ts +24 -0
- package/dist/core/encryption.js +64 -0
- package/dist/core/messages.js +2 -2
- package/dist/core/render-context.js +1 -0
- package/dist/core/server-islands/endpoint.js +5 -1
- package/dist/runtime/server/render/server-islands.js +7 -4
- package/dist/vite-plugin-astro-server/plugin.js +2 -0
- package/dist/vite-plugin-scanner/scan.js +1 -1
- package/package.json +9 -8
package/dist/@types/astro.d.ts
CHANGED
|
@@ -2167,7 +2167,7 @@ export type GetDataEntryInfoReturnType = {
|
|
|
2167
2167
|
};
|
|
2168
2168
|
export interface AstroAdapterFeatures {
|
|
2169
2169
|
/**
|
|
2170
|
-
* Creates
|
|
2170
|
+
* Creates an edge function that will communiate with the Astro middleware
|
|
2171
2171
|
*/
|
|
2172
2172
|
edgeMiddleware: boolean;
|
|
2173
2173
|
/**
|
|
@@ -2960,6 +2960,7 @@ export interface SSRResult {
|
|
|
2960
2960
|
cookies: AstroCookies | undefined;
|
|
2961
2961
|
serverIslandNameMap: Map<string, string>;
|
|
2962
2962
|
trailingSlash: AstroConfig['trailingSlash'];
|
|
2963
|
+
key: Promise<CryptoKey>;
|
|
2963
2964
|
_metadata: SSRMetadata;
|
|
2964
2965
|
}
|
|
2965
2966
|
/**
|
|
@@ -62,11 +62,17 @@ function formDataToObject(formData, schema) {
|
|
|
62
62
|
const obj = {};
|
|
63
63
|
for (const [key, baseValidator] of Object.entries(schema.shape)) {
|
|
64
64
|
let validator = baseValidator;
|
|
65
|
-
while (validator instanceof z.ZodOptional || validator instanceof z.ZodNullable) {
|
|
65
|
+
while (validator instanceof z.ZodOptional || validator instanceof z.ZodNullable || validator instanceof z.ZodDefault) {
|
|
66
|
+
if (validator instanceof z.ZodDefault && !formData.has(key)) {
|
|
67
|
+
obj[key] = validator._def.defaultValue();
|
|
68
|
+
}
|
|
66
69
|
validator = validator._def.innerType;
|
|
67
70
|
}
|
|
68
|
-
if (
|
|
69
|
-
|
|
71
|
+
if (!formData.has(key) && key in obj) {
|
|
72
|
+
continue;
|
|
73
|
+
} else if (validator instanceof z.ZodBoolean) {
|
|
74
|
+
const val = formData.get(key);
|
|
75
|
+
obj[key] = val === "true" ? true : val === "false" ? false : formData.has(key);
|
|
70
76
|
} else if (validator instanceof z.ZodArray) {
|
|
71
77
|
obj[key] = handleFormDataGetAll(key, formData, validator);
|
|
72
78
|
} else {
|
|
@@ -132,14 +132,16 @@ function getActionProps(action) {
|
|
|
132
132
|
}
|
|
133
133
|
function serializeActionResult(res) {
|
|
134
134
|
if (res.error) {
|
|
135
|
+
if (import.meta.env?.DEV) {
|
|
136
|
+
actionResultErrorStack.set(res.error.stack);
|
|
137
|
+
}
|
|
135
138
|
return {
|
|
136
139
|
type: "error",
|
|
137
140
|
status: res.error.status,
|
|
138
141
|
contentType: "application/json",
|
|
139
142
|
body: JSON.stringify({
|
|
140
143
|
...res.error,
|
|
141
|
-
message: res.error.message
|
|
142
|
-
stack: import.meta.env.PROD ? void 0 : res.error.stack
|
|
144
|
+
message: res.error.message
|
|
143
145
|
})
|
|
144
146
|
};
|
|
145
147
|
}
|
|
@@ -161,7 +163,16 @@ function serializeActionResult(res) {
|
|
|
161
163
|
}
|
|
162
164
|
function deserializeActionResult(res) {
|
|
163
165
|
if (res.type === "error") {
|
|
164
|
-
|
|
166
|
+
if (import.meta.env?.PROD) {
|
|
167
|
+
return { error: ActionError.fromJson(JSON.parse(res.body)), data: void 0 };
|
|
168
|
+
} else {
|
|
169
|
+
const error = ActionError.fromJson(JSON.parse(res.body));
|
|
170
|
+
error.stack = actionResultErrorStack.get();
|
|
171
|
+
return {
|
|
172
|
+
error,
|
|
173
|
+
data: void 0
|
|
174
|
+
};
|
|
175
|
+
}
|
|
165
176
|
}
|
|
166
177
|
if (res.type === "empty") {
|
|
167
178
|
return { data: void 0, error: void 0 };
|
|
@@ -173,6 +184,17 @@ function deserializeActionResult(res) {
|
|
|
173
184
|
error: void 0
|
|
174
185
|
};
|
|
175
186
|
}
|
|
187
|
+
const actionResultErrorStack = /* @__PURE__ */ function actionResultErrorStackFn() {
|
|
188
|
+
let errorStack;
|
|
189
|
+
return {
|
|
190
|
+
set(stack) {
|
|
191
|
+
errorStack = stack;
|
|
192
|
+
},
|
|
193
|
+
get() {
|
|
194
|
+
return errorStack;
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
}();
|
|
176
198
|
export {
|
|
177
199
|
ACTION_ERROR_CODES,
|
|
178
200
|
ACTION_QUERY_PARAMS,
|
package/dist/container/index.js
CHANGED
|
@@ -2,6 +2,7 @@ import { posix } from "node:path";
|
|
|
2
2
|
import { getDefaultClientDirectives } from "../core/client-directive/index.js";
|
|
3
3
|
import { ASTRO_CONFIG_DEFAULTS } from "../core/config/schema.js";
|
|
4
4
|
import { validateConfig } from "../core/config/validate.js";
|
|
5
|
+
import { createKey } from "../core/encryption.js";
|
|
5
6
|
import { Logger } from "../core/logger/core.js";
|
|
6
7
|
import { nodeLogDestination } from "../core/logger/node.js";
|
|
7
8
|
import { removeLeadingForwardSlash } from "../core/path.js";
|
|
@@ -31,7 +32,8 @@ function createManifest(manifest, renderers, middleware) {
|
|
|
31
32
|
i18n: manifest?.i18n,
|
|
32
33
|
checkOrigin: false,
|
|
33
34
|
middleware: manifest?.middleware ?? middleware ?? defaultMiddleware,
|
|
34
|
-
experimentalEnvGetSecretEnabled: false
|
|
35
|
+
experimentalEnvGetSecretEnabled: false,
|
|
36
|
+
key: createKey()
|
|
35
37
|
};
|
|
36
38
|
}
|
|
37
39
|
class experimental_AstroContainer {
|
package/dist/core/app/common.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { decodeKey } from "../encryption.js";
|
|
1
2
|
import { deserializeRouteData } from "../routing/manifest/serialization.js";
|
|
2
3
|
function deserializeManifest(serializedManifest) {
|
|
3
4
|
const routes = [];
|
|
@@ -14,6 +15,7 @@ function deserializeManifest(serializedManifest) {
|
|
|
14
15
|
const inlinedScripts = new Map(serializedManifest.inlinedScripts);
|
|
15
16
|
const clientDirectives = new Map(serializedManifest.clientDirectives);
|
|
16
17
|
const serverIslandNameMap = new Map(serializedManifest.serverIslandNameMap);
|
|
18
|
+
const key = decodeKey(serializedManifest.key);
|
|
17
19
|
return {
|
|
18
20
|
// in case user middleware exists, this no-op middleware will be reassigned (see plugin-ssr.ts)
|
|
19
21
|
middleware(_, next) {
|
|
@@ -25,7 +27,8 @@ function deserializeManifest(serializedManifest) {
|
|
|
25
27
|
inlinedScripts,
|
|
26
28
|
clientDirectives,
|
|
27
29
|
routes,
|
|
28
|
-
serverIslandNameMap
|
|
30
|
+
serverIslandNameMap,
|
|
31
|
+
key
|
|
29
32
|
};
|
|
30
33
|
}
|
|
31
34
|
export {
|
package/dist/core/app/index.js
CHANGED
|
@@ -298,9 +298,11 @@ class App {
|
|
|
298
298
|
`${this.#baseWithoutTrailingSlash}/${status}${maybeDotHtml}`,
|
|
299
299
|
url
|
|
300
300
|
);
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
301
|
+
if (statusURL.toString() !== request.url) {
|
|
302
|
+
const response2 = await fetch(statusURL.toString());
|
|
303
|
+
const override = { status };
|
|
304
|
+
return this.#mergeResponses(response2, originalResponse, override);
|
|
305
|
+
}
|
|
304
306
|
}
|
|
305
307
|
const mod = await this.#pipeline.getModuleForRoute(errorRouteData);
|
|
306
308
|
try {
|
package/dist/core/app/types.d.ts
CHANGED
|
@@ -52,6 +52,7 @@ export type SSRManifest = {
|
|
|
52
52
|
pageMap?: Map<ComponentPath, ImportComponentInstance>;
|
|
53
53
|
serverIslandMap?: Map<string, () => Promise<ComponentInstance>>;
|
|
54
54
|
serverIslandNameMap?: Map<string, string>;
|
|
55
|
+
key: Promise<CryptoKey>;
|
|
55
56
|
i18n: SSRManifestI18n | undefined;
|
|
56
57
|
middleware: MiddlewareHandler;
|
|
57
58
|
checkOrigin: boolean;
|
|
@@ -64,11 +65,12 @@ export type SSRManifestI18n = {
|
|
|
64
65
|
defaultLocale: string;
|
|
65
66
|
domainLookupTable: Record<string, string>;
|
|
66
67
|
};
|
|
67
|
-
export type SerializedSSRManifest = Omit<SSRManifest, 'middleware' | 'routes' | 'assets' | 'componentMetadata' | 'inlinedScripts' | 'clientDirectives' | 'serverIslandNameMap'> & {
|
|
68
|
+
export type SerializedSSRManifest = Omit<SSRManifest, 'middleware' | 'routes' | 'assets' | 'componentMetadata' | 'inlinedScripts' | 'clientDirectives' | 'serverIslandNameMap' | 'key'> & {
|
|
68
69
|
routes: SerializedRouteInfo[];
|
|
69
70
|
assets: string[];
|
|
70
71
|
componentMetadata: [string, SSRComponentMetadata][];
|
|
71
72
|
inlinedScripts: [string, string][];
|
|
72
73
|
clientDirectives: [string, string][];
|
|
73
74
|
serverIslandNameMap: [string, string][];
|
|
75
|
+
key: string;
|
|
74
76
|
};
|
|
@@ -54,7 +54,8 @@ async function generatePages(options, internals) {
|
|
|
54
54
|
options.settings,
|
|
55
55
|
internals,
|
|
56
56
|
renderers.renderers,
|
|
57
|
-
middleware
|
|
57
|
+
middleware,
|
|
58
|
+
options.key
|
|
58
59
|
);
|
|
59
60
|
}
|
|
60
61
|
const pipeline = BuildPipeline.create({ internals, manifest, options });
|
|
@@ -358,7 +359,7 @@ function getPrettyRouteName(route) {
|
|
|
358
359
|
return route.component;
|
|
359
360
|
}
|
|
360
361
|
}
|
|
361
|
-
function createBuildManifest(settings, internals, renderers, middleware) {
|
|
362
|
+
function createBuildManifest(settings, internals, renderers, middleware, key) {
|
|
362
363
|
let i18nManifest = void 0;
|
|
363
364
|
if (settings.config.i18n) {
|
|
364
365
|
i18nManifest = {
|
|
@@ -388,6 +389,7 @@ function createBuildManifest(settings, internals, renderers, middleware) {
|
|
|
388
389
|
buildFormat: settings.config.build.format,
|
|
389
390
|
middleware,
|
|
390
391
|
checkOrigin: settings.config.security?.checkOrigin ?? false,
|
|
392
|
+
key,
|
|
391
393
|
experimentalEnvGetSecretEnabled: false
|
|
392
394
|
};
|
|
393
395
|
}
|
package/dist/core/build/index.js
CHANGED
|
@@ -15,6 +15,7 @@ import { resolveConfig } from "../config/config.js";
|
|
|
15
15
|
import { createNodeLogger } from "../config/logging.js";
|
|
16
16
|
import { createSettings } from "../config/settings.js";
|
|
17
17
|
import { createVite } from "../create-vite.js";
|
|
18
|
+
import { createKey } from "../encryption.js";
|
|
18
19
|
import { levels, timerMessage } from "../logger/core.js";
|
|
19
20
|
import { apply as applyPolyfill } from "../polyfill.js";
|
|
20
21
|
import { createRouteManifest } from "../routing/index.js";
|
|
@@ -135,7 +136,8 @@ class AstroBuilder {
|
|
|
135
136
|
origin: this.origin,
|
|
136
137
|
pageNames,
|
|
137
138
|
teardownCompiler: this.teardownCompiler,
|
|
138
|
-
viteConfig
|
|
139
|
+
viteConfig,
|
|
140
|
+
key: createKey()
|
|
139
141
|
};
|
|
140
142
|
const { internals, ssrOutputChunkNames, contentFileNames } = await viteBuild(opts);
|
|
141
143
|
await staticBuild(opts, internals, ssrOutputChunkNames, contentFileNames);
|
|
@@ -5,6 +5,7 @@ import { normalizeTheLocale } from "../../../i18n/index.js";
|
|
|
5
5
|
import { toRoutingStrategy } from "../../../i18n/utils.js";
|
|
6
6
|
import { runHookBuildSsr } from "../../../integrations/hooks.js";
|
|
7
7
|
import { BEFORE_HYDRATION_SCRIPT_ID, PAGE_SCRIPT_ID } from "../../../vite-plugin-scripts/index.js";
|
|
8
|
+
import { encodeKey } from "../../encryption.js";
|
|
8
9
|
import { fileExtension, joinPaths, prependForwardSlash } from "../../path.js";
|
|
9
10
|
import { serializeRouteData } from "../../routing/index.js";
|
|
10
11
|
import { addRollupInput } from "../add-rollup-input.js";
|
|
@@ -103,7 +104,8 @@ async function createManifest(buildOpts, internals) {
|
|
|
103
104
|
internals.staticFiles.add(file);
|
|
104
105
|
}
|
|
105
106
|
const staticFiles = internals.staticFiles;
|
|
106
|
-
|
|
107
|
+
const encodedKey = await encodeKey(await buildOpts.key);
|
|
108
|
+
return buildManifest(buildOpts, internals, Array.from(staticFiles), encodedKey);
|
|
107
109
|
}
|
|
108
110
|
function injectManifest(manifest, chunk) {
|
|
109
111
|
const code = chunk.code;
|
|
@@ -111,7 +113,7 @@ function injectManifest(manifest, chunk) {
|
|
|
111
113
|
return JSON.stringify(manifest);
|
|
112
114
|
});
|
|
113
115
|
}
|
|
114
|
-
function buildManifest(opts, internals, staticFiles) {
|
|
116
|
+
function buildManifest(opts, internals, staticFiles, encodedKey) {
|
|
115
117
|
const { settings } = opts;
|
|
116
118
|
const routes = [];
|
|
117
119
|
const domainLookupTable = {};
|
|
@@ -214,6 +216,7 @@ function buildManifest(opts, internals, staticFiles) {
|
|
|
214
216
|
buildFormat: settings.config.build.format,
|
|
215
217
|
checkOrigin: settings.config.security?.checkOrigin ?? false,
|
|
216
218
|
serverIslandNameMap: Array.from(settings.serverIslandNameMap),
|
|
219
|
+
key: encodedKey,
|
|
217
220
|
experimentalEnvGetSecretEnabled: settings.config.experimental.env !== void 0 && (settings.adapter?.supportedAstroFeatures.envGetSecret ?? "unsupported") !== "unsupported"
|
|
218
221
|
};
|
|
219
222
|
}
|
|
@@ -24,6 +24,10 @@ function vitePluginSSR(internals, adapter, options) {
|
|
|
24
24
|
}
|
|
25
25
|
inputs.add(getVirtualModulePageName(ASTRO_PAGE_MODULE_ID, pageData.component));
|
|
26
26
|
}
|
|
27
|
+
const adapterServerEntrypoint = options.settings.adapter?.serverEntrypoint;
|
|
28
|
+
if (adapterServerEntrypoint) {
|
|
29
|
+
inputs.add(adapterServerEntrypoint);
|
|
30
|
+
}
|
|
27
31
|
inputs.add(SSR_VIRTUAL_MODULE_ID);
|
|
28
32
|
return addRollupInput(opts, Array.from(inputs));
|
|
29
33
|
},
|
|
@@ -195,8 +199,8 @@ function generateSSRCode(settings, adapter, middlewareId) {
|
|
|
195
199
|
const pageMap = isFunctionPerRouteEnabled(adapter) ? "pageModule" : "pageMap";
|
|
196
200
|
const imports = [
|
|
197
201
|
`import { renderers } from '${RENDERERS_MODULE_ID}';`,
|
|
198
|
-
`import { manifest as defaultManifest } from '${SSR_MANIFEST_VIRTUAL_MODULE_ID}';`,
|
|
199
202
|
`import * as serverEntrypointModule from '${adapter.serverEntrypoint}';`,
|
|
203
|
+
`import { manifest as defaultManifest } from '${SSR_MANIFEST_VIRTUAL_MODULE_ID}';`,
|
|
200
204
|
edgeMiddleware ? `` : `import { onRequest as middleware } from '${middlewareId}';`,
|
|
201
205
|
settings.config.experimental.serverIslands ? `import { serverIslandMap } from '${VIRTUAL_ISLAND_MAP_ID}';` : ""
|
|
202
206
|
];
|
|
@@ -199,6 +199,8 @@ async function ssrBuild(opts, internals, input, container, logger) {
|
|
|
199
199
|
return "renderers.mjs";
|
|
200
200
|
} else if (chunkInfo.facadeModuleId === RESOLVED_SSR_MANIFEST_VIRTUAL_MODULE_ID) {
|
|
201
201
|
return "manifest_[hash].mjs";
|
|
202
|
+
} else if (chunkInfo.facadeModuleId === settings.adapter?.serverEntrypoint) {
|
|
203
|
+
return "adapter_[hash].mjs";
|
|
202
204
|
} else if (settings.config.experimental.contentCollectionCache && chunkInfo.facadeModuleId && hasAnyContentFlag(chunkInfo.facadeModuleId)) {
|
|
203
205
|
const moduleId = reverseSymlink({
|
|
204
206
|
symlinks,
|
|
@@ -39,6 +39,7 @@ export interface StaticBuildOptions {
|
|
|
39
39
|
pageNames: string[];
|
|
40
40
|
viteConfig: InlineConfig;
|
|
41
41
|
teardownCompiler: boolean;
|
|
42
|
+
key: Promise<CryptoKey>;
|
|
42
43
|
}
|
|
43
44
|
type ImportComponentInstance = () => Promise<ComponentInstance>;
|
|
44
45
|
export interface SinglePageBuiltModule {
|
package/dist/core/constants.js
CHANGED
package/dist/core/dev/dev.js
CHANGED
|
@@ -19,7 +19,7 @@ async function dev(inlineConfig) {
|
|
|
19
19
|
await telemetry.record([]);
|
|
20
20
|
const restart = await createContainerWithAutomaticRestart({ inlineConfig, fs });
|
|
21
21
|
const logger = restart.container.logger;
|
|
22
|
-
const currentVersion = "4.13.
|
|
22
|
+
const currentVersion = "4.13.4";
|
|
23
23
|
const isPrerelease = currentVersion.includes("-");
|
|
24
24
|
if (!isPrerelease) {
|
|
25
25
|
try {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a CryptoKey object that can be used to encrypt any string.
|
|
3
|
+
*/
|
|
4
|
+
export declare function createKey(): Promise<CryptoKey>;
|
|
5
|
+
/**
|
|
6
|
+
* Takes a key that has been serialized to an array of bytes and returns a CryptoKey
|
|
7
|
+
*/
|
|
8
|
+
export declare function importKey(bytes: Uint8Array): Promise<CryptoKey>;
|
|
9
|
+
/**
|
|
10
|
+
* Encodes a CryptoKey to base64 string, so that it can be embedded in JSON / JavaScript
|
|
11
|
+
*/
|
|
12
|
+
export declare function encodeKey(key: CryptoKey): Promise<string>;
|
|
13
|
+
/**
|
|
14
|
+
* Decodes a base64 string into bytes and then imports the key.
|
|
15
|
+
*/
|
|
16
|
+
export declare function decodeKey(encoded: string): Promise<CryptoKey>;
|
|
17
|
+
/**
|
|
18
|
+
* Using a CryptoKey, encrypt a string into a base64 string.
|
|
19
|
+
*/
|
|
20
|
+
export declare function encryptString(key: CryptoKey, raw: string): Promise<string>;
|
|
21
|
+
/**
|
|
22
|
+
* Takes a base64 encoded string, decodes it and returns the decrypted text.
|
|
23
|
+
*/
|
|
24
|
+
export declare function decryptString(key: CryptoKey, encoded: string): Promise<string>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { decodeBase64, decodeHex, encodeBase64, encodeHexUpperCase } from "@oslojs/encoding";
|
|
2
|
+
const ALGORITHM = "AES-GCM";
|
|
3
|
+
async function createKey() {
|
|
4
|
+
const key = await crypto.subtle.generateKey(
|
|
5
|
+
{
|
|
6
|
+
name: ALGORITHM,
|
|
7
|
+
length: 256
|
|
8
|
+
},
|
|
9
|
+
true,
|
|
10
|
+
["encrypt", "decrypt"]
|
|
11
|
+
);
|
|
12
|
+
return key;
|
|
13
|
+
}
|
|
14
|
+
async function importKey(bytes) {
|
|
15
|
+
const key = await crypto.subtle.importKey("raw", bytes, ALGORITHM, true, ["encrypt", "decrypt"]);
|
|
16
|
+
return key;
|
|
17
|
+
}
|
|
18
|
+
async function encodeKey(key) {
|
|
19
|
+
const exported = await crypto.subtle.exportKey("raw", key);
|
|
20
|
+
const encodedKey = encodeBase64(new Uint8Array(exported));
|
|
21
|
+
return encodedKey;
|
|
22
|
+
}
|
|
23
|
+
async function decodeKey(encoded) {
|
|
24
|
+
const bytes = decodeBase64(encoded);
|
|
25
|
+
return crypto.subtle.importKey("raw", bytes, ALGORITHM, true, ["encrypt", "decrypt"]);
|
|
26
|
+
}
|
|
27
|
+
const encoder = new TextEncoder();
|
|
28
|
+
const decoder = new TextDecoder();
|
|
29
|
+
const IV_LENGTH = 24;
|
|
30
|
+
async function encryptString(key, raw) {
|
|
31
|
+
const iv = crypto.getRandomValues(new Uint8Array(IV_LENGTH / 2));
|
|
32
|
+
const data = encoder.encode(raw);
|
|
33
|
+
const buffer = await crypto.subtle.encrypt(
|
|
34
|
+
{
|
|
35
|
+
name: ALGORITHM,
|
|
36
|
+
iv
|
|
37
|
+
},
|
|
38
|
+
key,
|
|
39
|
+
data
|
|
40
|
+
);
|
|
41
|
+
return encodeHexUpperCase(iv) + encodeBase64(new Uint8Array(buffer));
|
|
42
|
+
}
|
|
43
|
+
async function decryptString(key, encoded) {
|
|
44
|
+
const iv = decodeHex(encoded.slice(0, IV_LENGTH));
|
|
45
|
+
const dataArray = decodeBase64(encoded.slice(IV_LENGTH));
|
|
46
|
+
const decryptedBuffer = await crypto.subtle.decrypt(
|
|
47
|
+
{
|
|
48
|
+
name: ALGORITHM,
|
|
49
|
+
iv
|
|
50
|
+
},
|
|
51
|
+
key,
|
|
52
|
+
dataArray
|
|
53
|
+
);
|
|
54
|
+
const decryptedString = decoder.decode(decryptedBuffer);
|
|
55
|
+
return decryptedString;
|
|
56
|
+
}
|
|
57
|
+
export {
|
|
58
|
+
createKey,
|
|
59
|
+
decodeKey,
|
|
60
|
+
decryptString,
|
|
61
|
+
encodeKey,
|
|
62
|
+
encryptString,
|
|
63
|
+
importKey
|
|
64
|
+
};
|
package/dist/core/messages.js
CHANGED
|
@@ -38,7 +38,7 @@ function serverStart({
|
|
|
38
38
|
host,
|
|
39
39
|
base
|
|
40
40
|
}) {
|
|
41
|
-
const version = "4.13.
|
|
41
|
+
const version = "4.13.4";
|
|
42
42
|
const localPrefix = `${dim("\u2503")} Local `;
|
|
43
43
|
const networkPrefix = `${dim("\u2503")} Network `;
|
|
44
44
|
const emptyPrefix = " ".repeat(11);
|
|
@@ -270,7 +270,7 @@ function printHelp({
|
|
|
270
270
|
message.push(
|
|
271
271
|
linebreak(),
|
|
272
272
|
` ${bgGreen(black(` ${commandName} `))} ${green(
|
|
273
|
-
`v${"4.13.
|
|
273
|
+
`v${"4.13.4"}`
|
|
274
274
|
)} ${headline}`
|
|
275
275
|
);
|
|
276
276
|
}
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
renderTemplate
|
|
4
4
|
} from "../../runtime/server/index.js";
|
|
5
5
|
import { createSlotValueFromString } from "../../runtime/server/render/slot.js";
|
|
6
|
+
import { decryptString } from "../encryption.js";
|
|
6
7
|
import { getPattern } from "../routing/manifest/pattern.js";
|
|
7
8
|
const SERVER_ISLAND_ROUTE = "/_server-islands/[name]";
|
|
8
9
|
const SERVER_ISLAND_COMPONENT = "_server-islands.astro";
|
|
@@ -51,7 +52,10 @@ function createEndpoint(manifest) {
|
|
|
51
52
|
statusText: "Not found"
|
|
52
53
|
});
|
|
53
54
|
}
|
|
54
|
-
const
|
|
55
|
+
const key = await manifest.key;
|
|
56
|
+
const encryptedProps = data.encryptedProps;
|
|
57
|
+
const propString = await decryptString(key, encryptedProps);
|
|
58
|
+
const props = JSON.parse(propString);
|
|
55
59
|
const componentModule = await imp();
|
|
56
60
|
const Component = componentModule[data.componentExport];
|
|
57
61
|
const slots = {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { encryptString } from "../../../core/encryption.js";
|
|
1
2
|
import { renderChild } from "./any.js";
|
|
2
3
|
import { renderSlotToString } from "./slot.js";
|
|
3
4
|
const internalProps = /* @__PURE__ */ new Set([
|
|
@@ -21,9 +22,9 @@ function renderServerIsland(result, _displayName, props, slots) {
|
|
|
21
22
|
if (!componentId) {
|
|
22
23
|
throw new Error(`Could not find server component name`);
|
|
23
24
|
}
|
|
24
|
-
for (const
|
|
25
|
-
if (internalProps.has(
|
|
26
|
-
delete props[
|
|
25
|
+
for (const key2 of Object.keys(props)) {
|
|
26
|
+
if (internalProps.has(key2)) {
|
|
27
|
+
delete props[key2];
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
destination.write("<!--server-island-start-->");
|
|
@@ -36,6 +37,8 @@ function renderServerIsland(result, _displayName, props, slots) {
|
|
|
36
37
|
await renderChild(destination, slots.fallback(result));
|
|
37
38
|
}
|
|
38
39
|
}
|
|
40
|
+
const key = await result.key;
|
|
41
|
+
const propsEncrypted = await encryptString(key, JSON.stringify(props));
|
|
39
42
|
const hostId = crypto.randomUUID();
|
|
40
43
|
const serverIslandUrl = `${result.base}_server-islands/${componentId}${result.trailingSlash === "always" ? "/" : ""}`;
|
|
41
44
|
destination.write(`<script async type="module" data-island-id="${hostId}">
|
|
@@ -44,7 +47,7 @@ let componentExport = ${safeJsonStringify(componentExport)};
|
|
|
44
47
|
let script = document.querySelector('script[data-island-id="${hostId}"]');
|
|
45
48
|
let data = {
|
|
46
49
|
componentExport,
|
|
47
|
-
|
|
50
|
+
encryptedProps: ${safeJsonStringify(propsEncrypted)},
|
|
48
51
|
slots: ${safeJsonStringify(renderedSlots)},
|
|
49
52
|
};
|
|
50
53
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
2
|
import { IncomingMessage } from "node:http";
|
|
3
|
+
import { createKey } from "../core/encryption.js";
|
|
3
4
|
import { getViteErrorPayload } from "../core/errors/dev/index.js";
|
|
4
5
|
import { AstroError, AstroErrorData } from "../core/errors/index.js";
|
|
5
6
|
import { patchOverlay } from "../core/errors/overlay.js";
|
|
@@ -117,6 +118,7 @@ function createDevelopmentManifest(settings) {
|
|
|
117
118
|
i18n: i18nManifest,
|
|
118
119
|
checkOrigin: settings.config.security?.checkOrigin ?? false,
|
|
119
120
|
experimentalEnvGetSecretEnabled: false,
|
|
121
|
+
key: createKey(),
|
|
120
122
|
middleware(_, next) {
|
|
121
123
|
return next();
|
|
122
124
|
}
|
|
@@ -35,7 +35,7 @@ async function scan(code, id, settings) {
|
|
|
35
35
|
const { n: name, le: endOfLocalName } = _export;
|
|
36
36
|
if (BOOLEAN_EXPORTS.has(name)) {
|
|
37
37
|
const prefix = code.slice(0, endOfLocalName).split("export").pop().trim().replace("prerender", "").trim();
|
|
38
|
-
const suffix = code.slice(endOfLocalName).trim().replace(/=/, "").trim().split(/[;\n]/)[0];
|
|
38
|
+
const suffix = code.slice(endOfLocalName).trim().replace(/=/, "").trim().split(/[;\n\r]/)[0].trim();
|
|
39
39
|
if (prefix !== "const" || !(isTruthy(suffix) || isFalsy(suffix))) {
|
|
40
40
|
throw new AstroError({
|
|
41
41
|
...AstroErrorData.InvalidPrerenderExport,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astro",
|
|
3
|
-
"version": "4.13.
|
|
3
|
+
"version": "4.13.4",
|
|
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",
|
|
@@ -107,13 +107,14 @@
|
|
|
107
107
|
"vendor"
|
|
108
108
|
],
|
|
109
109
|
"dependencies": {
|
|
110
|
-
"@astrojs/compiler": "^2.10.
|
|
110
|
+
"@astrojs/compiler": "^2.10.2",
|
|
111
111
|
"@babel/core": "^7.25.2",
|
|
112
112
|
"@babel/generator": "^7.25.0",
|
|
113
113
|
"@babel/parser": "^7.25.3",
|
|
114
114
|
"@babel/plugin-transform-react-jsx": "^7.25.2",
|
|
115
115
|
"@babel/traverse": "^7.25.3",
|
|
116
116
|
"@babel/types": "^7.25.2",
|
|
117
|
+
"@oslojs/encoding": "^0.4.1",
|
|
117
118
|
"@types/babel__core": "^7.20.5",
|
|
118
119
|
"@types/cookie": "^0.6.0",
|
|
119
120
|
"acorn": "^8.12.1",
|
|
@@ -159,22 +160,22 @@
|
|
|
159
160
|
"tsconfck": "^3.1.1",
|
|
160
161
|
"unist-util-visit": "^5.0.0",
|
|
161
162
|
"vfile": "^6.0.2",
|
|
162
|
-
"vite": "^5.
|
|
163
|
+
"vite": "^5.4.0",
|
|
163
164
|
"vitefu": "^0.2.5",
|
|
164
165
|
"which-pm": "^3.0.0",
|
|
165
166
|
"yargs-parser": "^21.1.1",
|
|
166
167
|
"zod": "^3.23.8",
|
|
167
168
|
"zod-to-json-schema": "^3.23.2",
|
|
168
|
-
"@astrojs/internal-helpers": "0.4.1",
|
|
169
169
|
"@astrojs/markdown-remark": "5.2.0",
|
|
170
|
+
"@astrojs/internal-helpers": "0.4.1",
|
|
170
171
|
"@astrojs/telemetry": "3.1.0"
|
|
171
172
|
},
|
|
172
173
|
"optionalDependencies": {
|
|
173
174
|
"sharp": "^0.33.3"
|
|
174
175
|
},
|
|
175
176
|
"devDependencies": {
|
|
176
|
-
"@astrojs/check": "^0.9.
|
|
177
|
-
"@playwright/test": "^1.
|
|
177
|
+
"@astrojs/check": "^0.9.2",
|
|
178
|
+
"@playwright/test": "^1.46.0",
|
|
178
179
|
"@types/aria-query": "^5.0.4",
|
|
179
180
|
"@types/babel__generator": "^7.6.8",
|
|
180
181
|
"@types/babel__traverse": "^7.20.6",
|
|
@@ -191,7 +192,7 @@
|
|
|
191
192
|
"@types/prompts": "^2.4.9",
|
|
192
193
|
"@types/semver": "^7.5.8",
|
|
193
194
|
"@types/yargs-parser": "^21.0.3",
|
|
194
|
-
"cheerio": "1.0.0
|
|
195
|
+
"cheerio": "1.0.0",
|
|
195
196
|
"eol": "^0.9.1",
|
|
196
197
|
"expect-type": "^0.19.0",
|
|
197
198
|
"mdast-util-mdx": "^3.0.0",
|
|
@@ -205,7 +206,7 @@
|
|
|
205
206
|
"remark-code-titles": "^0.1.2",
|
|
206
207
|
"rollup": "^4.20.0",
|
|
207
208
|
"sass": "^1.77.8",
|
|
208
|
-
"undici": "^6.19.
|
|
209
|
+
"undici": "^6.19.7",
|
|
209
210
|
"unified": "^11.0.5",
|
|
210
211
|
"astro-scripts": "0.0.14"
|
|
211
212
|
},
|