Track HiveGrid Cloud planning reference
This commit is contained in:
1 parent
b3d5ea6764
commit
e341c5938a
5784 files changed
+1104929
-3
No files matched your search
@@ -0,0 +1,70 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
PLUGIN_SETTING_ARRAY_MAX_LENGTH,
|
||||
PLUGIN_SETTING_KEY_MAX_LENGTH,
|
||||
PLUGIN_SETTING_OBJECT_MAX_KEYS,
|
||||
PLUGIN_SETTING_VALUE_MAX_BYTES,
|
||||
isPluginSettingKeyFormatSafe,
|
||||
isPluginSettingKeyReserved,
|
||||
isPluginSettingKeySecretLike,
|
||||
isPluginSettingValue,
|
||||
isPluginSettingValueShapeSafe,
|
||||
isPluginSettingValueWithinSize,
|
||||
isSafePluginSettingKey,
|
||||
} from "./pluginSettingsValidation";
|
||||
|
||||
describe("plugin settings validation", () => {
|
||||
it("keeps frame and persistence setting keys on the same safe-key contract", () => {
|
||||
expect(isSafePluginSettingKey("theme.accent:color-1")).toBe(true);
|
||||
expect(isPluginSettingKeyFormatSafe("k".repeat(PLUGIN_SETTING_KEY_MAX_LENGTH))).toBe(true);
|
||||
expect(isPluginSettingKeyFormatSafe("k".repeat(PLUGIN_SETTING_KEY_MAX_LENGTH + 1))).toBe(false);
|
||||
|
||||
for (const key of [
|
||||
"../theme",
|
||||
"__proto__",
|
||||
"constructor",
|
||||
"prototype",
|
||||
"apiKey",
|
||||
"access-token",
|
||||
"password",
|
||||
"secret.value",
|
||||
"authorization",
|
||||
"credentials",
|
||||
"auth.header",
|
||||
"bearer",
|
||||
"cookie",
|
||||
"sessionId",
|
||||
"private_key",
|
||||
"clientSecret",
|
||||
"webhookUrl",
|
||||
]) {
|
||||
expect(isSafePluginSettingKey(key)).toBe(false);
|
||||
}
|
||||
expect(isPluginSettingKeyReserved("__proto__")).toBe(true);
|
||||
expect(isPluginSettingKeySecretLike("refresh-token")).toBe(true);
|
||||
expect(isPluginSettingKeySecretLike("authorization")).toBe(true);
|
||||
expect(isPluginSettingKeySecretLike("clientSecret")).toBe(true);
|
||||
});
|
||||
|
||||
it("rejects values that cannot cross the iframe-to-persistence boundary safely", () => {
|
||||
expect(isPluginSettingValue({ theme: "dark", flags: [true, false], count: 2 })).toBe(true);
|
||||
expect(isPluginSettingValue(Number.NaN)).toBe(false);
|
||||
expect(isPluginSettingValue(Array.from({ length: PLUGIN_SETTING_ARRAY_MAX_LENGTH + 1 }, () => true))).toBe(false);
|
||||
expect(isPluginSettingValue(Object.fromEntries(Array.from({ length: PLUGIN_SETTING_OBJECT_MAX_KEYS + 1 }, (_, index) => [`key${index}`, true])))).toBe(
|
||||
false
|
||||
);
|
||||
expect(isPluginSettingValue(JSON.parse('{"theme":"dark","__proto__":{"polluted":true}}'))).toBe(false);
|
||||
expect(isPluginSettingValue({ theme: { accessToken: "must-not-persist" } })).toBe(false);
|
||||
expect(isPluginSettingValue({ request: { authorization: "Bearer must-not-persist" } })).toBe(false);
|
||||
expect(isPluginSettingValue({ endpoint: { webhookUrl: "https://hooks.example.test/secret" } })).toBe(false);
|
||||
});
|
||||
|
||||
it("separates JSON shape errors from serialized size errors for server error mapping", () => {
|
||||
const oversized = "x".repeat(PLUGIN_SETTING_VALUE_MAX_BYTES);
|
||||
|
||||
expect(isPluginSettingValueShapeSafe(oversized)).toBe(true);
|
||||
expect(isPluginSettingValueWithinSize(oversized)).toBe(false);
|
||||
expect(isPluginSettingValue(oversized)).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user