refactor: simplify Phase 1 infrastructure code
- cache-invalidation: extract isExpectedRevalidateError helper - integration-data-cache: flatten early-return chain, extract eviction - redis-handler: extract StoredEntry type, readStreamBody, ensureConnected - svg-purify: single getOwnPropertyDescriptor lookup per prop - session-scoped-providers: simplify auth flow - retryable-loader: use function declarations - translation/request: replace spread-in-reduce with for loop
This commit is contained in:
8 files changed
+148
-134
No files matched your search
@@ -24,16 +24,17 @@ import { composeWrappers } from "./compose";
|
||||
const logger = createLogger({ module: "sessionScopedProviders" });
|
||||
|
||||
export async function SessionScopedProviders({ children }: PropsWithChildren) {
|
||||
const sessionPromise = auth();
|
||||
const userPromise = sessionPromise.then((session) =>
|
||||
const session = await auth();
|
||||
|
||||
const [user, serverSettings] = await Promise.all([
|
||||
session
|
||||
? getRscUserSettingsAsync(session.user.id).catch((error: unknown) => {
|
||||
logger.error(new Error("Failed to load the authenticated user in the root layout", { cause: error }));
|
||||
return null;
|
||||
})
|
||||
: null,
|
||||
);
|
||||
const [session, user, serverSettings] = await Promise.all([sessionPromise, userPromise, getRscServerSettingsAsync()]);
|
||||
: Promise.resolve(null),
|
||||
getRscServerSettingsAsync(),
|
||||
]);
|
||||
|
||||
const StackedProvider = composeWrappers([
|
||||
(innerProps) => <AuthProvider session={session} logoutUrl={env.AUTH_LOGOUT_REDIRECT_URL} {...innerProps} />,
|
||||
|
||||
@@ -68,7 +68,8 @@ describe("SVG sanitization", () => {
|
||||
});
|
||||
|
||||
it("preserves well-formed SVG with self-closing children", () => {
|
||||
const icon = '<svg viewBox="0 0 24 24"><path d="M12 2L2 22h20Z" fill="currentColor"/><circle cx="12" cy="8" r="2"/></svg>';
|
||||
const icon =
|
||||
'<svg viewBox="0 0 24 24"><path d="M12 2L2 22h20Z" fill="currentColor"/><circle cx="12" cy="8" r="2"/></svg>';
|
||||
const clean = sanitizeSvg(icon);
|
||||
expect(clean).toContain("<path");
|
||||
expect(clean).toContain("<circle");
|
||||
|
||||
@@ -6,24 +6,25 @@ const svgSanitizeOptions = {
|
||||
FORBID_TAGS: ["style"],
|
||||
} as const;
|
||||
|
||||
const LINKEDOM_NODE_PROPS = [
|
||||
"ownerDocument",
|
||||
"parentNode",
|
||||
"nextSibling",
|
||||
"previousSibling",
|
||||
"nodeName",
|
||||
"nodeType",
|
||||
"childNodes",
|
||||
] as const;
|
||||
|
||||
// ponytail: linkedom stores DOM tree pointers as own value properties; DOMPurify
|
||||
// resolves them via prototype getters (lookupGetter). Without this shim, sanitize
|
||||
// is a no-op and XSS payloads pass through unchanged.
|
||||
const patchLinkedomNodePrototype = (Node: typeof window.Node) => {
|
||||
for (const prop of [
|
||||
"ownerDocument",
|
||||
"parentNode",
|
||||
"nextSibling",
|
||||
"previousSibling",
|
||||
"nodeName",
|
||||
"nodeType",
|
||||
"childNodes",
|
||||
] as const) {
|
||||
if (Object.getOwnPropertyDescriptor(Node.prototype, prop)?.get) {
|
||||
continue;
|
||||
}
|
||||
for (const prop of LINKEDOM_NODE_PROPS) {
|
||||
const descriptor = Object.getOwnPropertyDescriptor(Node.prototype, prop);
|
||||
if (descriptor?.get) continue;
|
||||
|
||||
if (Object.getOwnPropertyDescriptor(Node.prototype, prop)?.value !== undefined) {
|
||||
if (descriptor?.value !== undefined) {
|
||||
delete Node.prototype[prop as keyof Node];
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user