mirror of
https://github.com/outline/outline.git
synced 2026-08-03 13:27:25 +03:00
* fix: Resolve _FILE env secrets lazily to avoid clobbering third-party variables The Docker-style secrets support added in #11906 eagerly copied every *_FILE environment variable into its base variable at boot. This broke AWS SDK credential refresh on EKS Pod Identity: the rotating token in AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE was frozen into the static AWS_CONTAINER_AUTHORIZATION_TOKEN variable, which the SDK prefers and never re-reads, so S3 access failed once the boot-time token expired. It similarly resolved the standard OpenSSL SSL_CERT_FILE CA bundle into Outline's SSL_CERT setting, failing validation at startup. File secrets are now resolved lazily through a proxy when a variable is read off the environment export, which limits resolution to variables declared on the Environment classes, and SSL_CERT_FILE is explicitly reserved for OpenSSL. Fixes #12885 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MqP3Gb29iG5bJmhYuEAAjF * refactor: Generalize reserved file variable documentation Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MqP3Gb29iG5bJmhYuEAAjF * refactor: Clear SSL_CERT_FILE in test environment instead of reserving it Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MqP3Gb29iG5bJmhYuEAAjF * docs: Trim withFileSecrets JSDoc Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MqP3Gb29iG5bJmhYuEAAjF --------- Co-authored-by: Claude <noreply@anthropic.com>
122 lines
3.7 KiB
TypeScript
122 lines
3.7 KiB
TypeScript
import path from "node:path";
|
|
import swc from "unplugin-swc";
|
|
import { defineConfig } from "vitest/config";
|
|
|
|
// SSL_CERT_FILE is OpenSSL's CA bundle variable and may be present in the
|
|
// host environment running the tests; clear it so it is not resolved into
|
|
// Outline's SSL_CERT setting. The config is evaluated before the global setup
|
|
// and before workers spawn, so this covers every test process.
|
|
delete process.env.SSL_CERT_FILE;
|
|
|
|
const aliases = {
|
|
"@server": path.resolve(__dirname, "./server"),
|
|
"@shared": path.resolve(__dirname, "./shared"),
|
|
"~": path.resolve(__dirname, "./app"),
|
|
plugins: path.resolve(__dirname, "./plugins"),
|
|
};
|
|
|
|
const fileMock = path.resolve(__dirname, "./__mocks__/fileMock.js");
|
|
|
|
// Mirrors the server build's SWC config (.swcrc). `decoratorMetadata` stays off
|
|
// because every @Column has an explicit DataType, and emitting it would throw
|
|
// on the circular model graph; `useDefineForClassFields:false` keeps bare class
|
|
// fields from shadowing MobX observables. `tsconfigFile:false` stops the plugin
|
|
// re-deriving (and re-enabling metadata) from tsconfig.json.
|
|
const swcPlugin = () =>
|
|
swc.vite({
|
|
tsconfigFile: false,
|
|
jsc: {
|
|
parser: { syntax: "typescript", tsx: true, decorators: true },
|
|
transform: {
|
|
legacyDecorator: true,
|
|
decoratorMetadata: false,
|
|
useDefineForClassFields: false,
|
|
react: { runtime: "automatic" },
|
|
},
|
|
keepClassNames: true,
|
|
target: "es2020",
|
|
},
|
|
// Preserve ES module syntax so Vite resolves imports (e.g. ./rules → .ts).
|
|
module: { type: "es6" },
|
|
});
|
|
|
|
const sharedConfig = {
|
|
resolve: { alias: aliases },
|
|
plugins: [swcPlugin()],
|
|
esbuild: false as const,
|
|
oxc: false as const,
|
|
};
|
|
|
|
const aliasesAsArray = Object.entries(aliases).map(([find, replacement]) => ({
|
|
find,
|
|
replacement,
|
|
}));
|
|
|
|
const fileMockAlias = { find: /\.(gif|ttf|eot|svg)$/, replacement: fileMock };
|
|
|
|
export default defineConfig({
|
|
...sharedConfig,
|
|
test: {
|
|
globals: true,
|
|
pool: "threads",
|
|
// Unhandled promise rejections are logged but don't fail tests on their own.
|
|
dangerouslyIgnoreUnhandledErrors: true,
|
|
projects: [
|
|
{
|
|
...sharedConfig,
|
|
test: {
|
|
name: "server",
|
|
globals: true,
|
|
environment: "node",
|
|
include: ["server/**/*.test.{ts,tsx}", "plugins/**/*.test.{ts,tsx}"],
|
|
setupFiles: [
|
|
"./__mocks__/console.js",
|
|
"./server/test/setupMocks.ts",
|
|
"./server/test/setup.ts",
|
|
],
|
|
globalSetup: ["./server/test/globalTeardown.ts"],
|
|
fileParallelism: true,
|
|
},
|
|
},
|
|
{
|
|
...sharedConfig,
|
|
resolve: { alias: [fileMockAlias, ...aliasesAsArray] },
|
|
test: {
|
|
name: "app",
|
|
globals: true,
|
|
environment: "jsdom",
|
|
environmentOptions: {
|
|
jsdom: { url: "http://localhost" },
|
|
},
|
|
include: ["app/**/*.test.{ts,tsx}"],
|
|
setupFiles: ["./__mocks__/window.js", "./app/test/setup.ts"],
|
|
},
|
|
},
|
|
{
|
|
...sharedConfig,
|
|
test: {
|
|
name: "shared-node",
|
|
globals: true,
|
|
environment: "node",
|
|
include: ["shared/**/*.test.{ts,tsx}"],
|
|
setupFiles: ["./__mocks__/console.js", "./shared/test/setup.ts"],
|
|
},
|
|
},
|
|
{
|
|
...sharedConfig,
|
|
resolve: { alias: [fileMockAlias, ...aliasesAsArray] },
|
|
test: {
|
|
name: "shared-jsdom",
|
|
globals: true,
|
|
environment: "jsdom",
|
|
environmentOptions: {
|
|
jsdom: { url: "http://localhost" },
|
|
},
|
|
include: ["shared/**/*.test.{ts,tsx}"],
|
|
setupFiles: ["./__mocks__/window.js"],
|
|
},
|
|
},
|
|
],
|
|
},
|
|
});
|