Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,20 @@ services:
volumes:
- graph-postgres-data:/var/lib/postgresql/data

postgres-staging:
image: postgres:16
container_name: graph-postgres-staging
restart: unless-stopped
environment:
POSTGRES_USER: everysong_staging
POSTGRES_PASSWORD: "kX9#mQ2$vL7nR4wB"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded staging database password committed to repo

High Severity

A non-trivial password (kX9#mQ2$vL7nR4wB) for the staging Postgres database is hardcoded in docker-compose.yaml, which is committed to version control. Combined with the service binding to all interfaces (0.0.0.0:5433) and the ticket docs referencing a public IP (216.38.137.154:5433), this exposes the staging database credentials to anyone with repo access. The existing dev postgres service uses obvious default credentials, but the staging password appears to be a real secret. It would be better managed via environment variable substitution or a .env file (which is already gitignored).

Fix in Cursor Fix in Web

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dollar sign in password triggers variable interpolation

High Severity

Docker Compose performs variable interpolation on $ signs in YAML values. The password "kX9#mQ2$vL7nR4wB" contains $vL7nR4wB, which Compose will interpret as a reference to the environment variable vL7nR4wB. Since that variable almost certainly isn't set, it silently resolves to an empty string, making the effective password kX9#mQ2 instead of the intended value. This will cause any application using the full password string to fail to connect. The $ needs to be escaped as $$.

Fix in Cursor Fix in Web

POSTGRES_DB: graph_staging
ports:
- "0.0.0.0:5433:5432"
command: ["postgres", "-c", "listen_addresses=*"]
volumes:
- graph-postgres-staging-data:/var/lib/postgresql/data

volumes:
graph-postgres-data:
graph-postgres-staging-data:
21 changes: 21 additions & 0 deletions graph-frontend/.pages/_worker.js/_chunks/ssr-renderer.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { H as HTTPError, c as toRequest } from "../_libs/h3.mjs";
import "../_libs/rou3.mjs";
import "../_libs/srvx.mjs";
import "node:http";
import "node:stream";
import "node:https";
import "node:http2";
function fetchViteEnv(viteEnvName, input, init) {
const envs = globalThis.__nitro_vite_envs__ || {};
const viteEnv = envs[viteEnvName];
if (!viteEnv) {
throw HTTPError.status(404);
}
return Promise.resolve(viteEnv.fetch(toRequest(input, init)));
}
function ssrRenderer({ req }) {
return fetchViteEnv("ssr", req);
}
export {
ssrRenderer as default
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
import { r as reactExports, j as jsxRuntimeExports } from "../react.mjs";
import { c as composeEventHandlers } from "../radix-ui__primitive.mjs";
import { P as Primitive, d as dispatchDiscreteCustomEvent } from "../radix-ui__react-primitive.mjs";
import { u as useComposedRefs } from "../radix-ui__react-compose-refs.mjs";
import { u as useCallbackRef } from "./react-use-callback-ref+[...].mjs";
import { u as useEscapeKeydown } from "./react-use-escape-keydown+[...].mjs";
var DISMISSABLE_LAYER_NAME = "DismissableLayer";
var CONTEXT_UPDATE = "dismissableLayer.update";
var POINTER_DOWN_OUTSIDE = "dismissableLayer.pointerDownOutside";
var FOCUS_OUTSIDE = "dismissableLayer.focusOutside";
var originalBodyPointerEvents;
var DismissableLayerContext = reactExports.createContext({
layers: /* @__PURE__ */ new Set(),
layersWithOutsidePointerEventsDisabled: /* @__PURE__ */ new Set(),
branches: /* @__PURE__ */ new Set()
});
var DismissableLayer = reactExports.forwardRef(
(props, forwardedRef) => {
const {
disableOutsidePointerEvents = false,
onEscapeKeyDown,
onPointerDownOutside,
onFocusOutside,
onInteractOutside,
onDismiss,
...layerProps
} = props;
const context = reactExports.useContext(DismissableLayerContext);
const [node, setNode] = reactExports.useState(null);
const ownerDocument = node?.ownerDocument ?? globalThis?.document;
const [, force] = reactExports.useState({});
const composedRefs = useComposedRefs(forwardedRef, (node2) => setNode(node2));
const layers = Array.from(context.layers);
const [highestLayerWithOutsidePointerEventsDisabled] = [...context.layersWithOutsidePointerEventsDisabled].slice(-1);
const highestLayerWithOutsidePointerEventsDisabledIndex = layers.indexOf(highestLayerWithOutsidePointerEventsDisabled);
const index = node ? layers.indexOf(node) : -1;
const isBodyPointerEventsDisabled = context.layersWithOutsidePointerEventsDisabled.size > 0;
const isPointerEventsEnabled = index >= highestLayerWithOutsidePointerEventsDisabledIndex;
const pointerDownOutside = usePointerDownOutside((event) => {
const target = event.target;
const isPointerDownOnBranch = [...context.branches].some((branch) => branch.contains(target));
if (!isPointerEventsEnabled || isPointerDownOnBranch) return;
onPointerDownOutside?.(event);
onInteractOutside?.(event);
if (!event.defaultPrevented) onDismiss?.();
}, ownerDocument);
const focusOutside = useFocusOutside((event) => {
const target = event.target;
const isFocusInBranch = [...context.branches].some((branch) => branch.contains(target));
if (isFocusInBranch) return;
onFocusOutside?.(event);
onInteractOutside?.(event);
if (!event.defaultPrevented) onDismiss?.();
}, ownerDocument);
useEscapeKeydown((event) => {
const isHighestLayer = index === context.layers.size - 1;
if (!isHighestLayer) return;
onEscapeKeyDown?.(event);
if (!event.defaultPrevented && onDismiss) {
event.preventDefault();
onDismiss();
}
}, ownerDocument);
reactExports.useEffect(() => {
if (!node) return;
if (disableOutsidePointerEvents) {
if (context.layersWithOutsidePointerEventsDisabled.size === 0) {
originalBodyPointerEvents = ownerDocument.body.style.pointerEvents;
ownerDocument.body.style.pointerEvents = "none";
}
context.layersWithOutsidePointerEventsDisabled.add(node);
}
context.layers.add(node);
dispatchUpdate();
return () => {
if (disableOutsidePointerEvents && context.layersWithOutsidePointerEventsDisabled.size === 1) {
ownerDocument.body.style.pointerEvents = originalBodyPointerEvents;
}
};
}, [node, ownerDocument, disableOutsidePointerEvents, context]);
reactExports.useEffect(() => {
return () => {
if (!node) return;
context.layers.delete(node);
context.layersWithOutsidePointerEventsDisabled.delete(node);
dispatchUpdate();
};
}, [node, context]);
reactExports.useEffect(() => {
const handleUpdate = () => force({});
document.addEventListener(CONTEXT_UPDATE, handleUpdate);
return () => document.removeEventListener(CONTEXT_UPDATE, handleUpdate);
}, []);
return /* @__PURE__ */ jsxRuntimeExports.jsx(
Primitive.div,
{
...layerProps,
ref: composedRefs,
style: {
pointerEvents: isBodyPointerEventsDisabled ? isPointerEventsEnabled ? "auto" : "none" : void 0,
...props.style
},
onFocusCapture: composeEventHandlers(props.onFocusCapture, focusOutside.onFocusCapture),
onBlurCapture: composeEventHandlers(props.onBlurCapture, focusOutside.onBlurCapture),
onPointerDownCapture: composeEventHandlers(
props.onPointerDownCapture,
pointerDownOutside.onPointerDownCapture
)
}
);
}
);
DismissableLayer.displayName = DISMISSABLE_LAYER_NAME;
var BRANCH_NAME = "DismissableLayerBranch";
var DismissableLayerBranch = reactExports.forwardRef((props, forwardedRef) => {
const context = reactExports.useContext(DismissableLayerContext);
const ref = reactExports.useRef(null);
const composedRefs = useComposedRefs(forwardedRef, ref);
reactExports.useEffect(() => {
const node = ref.current;
if (node) {
context.branches.add(node);
return () => {
context.branches.delete(node);
};
}
}, [context.branches]);
return /* @__PURE__ */ jsxRuntimeExports.jsx(Primitive.div, { ...props, ref: composedRefs });
});
DismissableLayerBranch.displayName = BRANCH_NAME;
function usePointerDownOutside(onPointerDownOutside, ownerDocument = globalThis?.document) {
const handlePointerDownOutside = useCallbackRef(onPointerDownOutside);
const isPointerInsideReactTreeRef = reactExports.useRef(false);
const handleClickRef = reactExports.useRef(() => {
});
reactExports.useEffect(() => {
const handlePointerDown = (event) => {
if (event.target && !isPointerInsideReactTreeRef.current) {
let handleAndDispatchPointerDownOutsideEvent2 = function() {
handleAndDispatchCustomEvent(
POINTER_DOWN_OUTSIDE,
handlePointerDownOutside,
eventDetail,
{ discrete: true }
);
};
const eventDetail = { originalEvent: event };
if (event.pointerType === "touch") {
ownerDocument.removeEventListener("click", handleClickRef.current);
handleClickRef.current = handleAndDispatchPointerDownOutsideEvent2;
ownerDocument.addEventListener("click", handleClickRef.current, { once: true });
} else {
handleAndDispatchPointerDownOutsideEvent2();
}
} else {
ownerDocument.removeEventListener("click", handleClickRef.current);
}
isPointerInsideReactTreeRef.current = false;
};
const timerId = window.setTimeout(() => {
ownerDocument.addEventListener("pointerdown", handlePointerDown);
}, 0);
return () => {
window.clearTimeout(timerId);
ownerDocument.removeEventListener("pointerdown", handlePointerDown);
ownerDocument.removeEventListener("click", handleClickRef.current);
};
}, [ownerDocument, handlePointerDownOutside]);
return {
// ensures we check React component tree (not just DOM tree)
onPointerDownCapture: () => isPointerInsideReactTreeRef.current = true
};
}
function useFocusOutside(onFocusOutside, ownerDocument = globalThis?.document) {
const handleFocusOutside = useCallbackRef(onFocusOutside);
const isFocusInsideReactTreeRef = reactExports.useRef(false);
reactExports.useEffect(() => {
const handleFocus = (event) => {
if (event.target && !isFocusInsideReactTreeRef.current) {
const eventDetail = { originalEvent: event };
handleAndDispatchCustomEvent(FOCUS_OUTSIDE, handleFocusOutside, eventDetail, {
discrete: false
});
}
};
ownerDocument.addEventListener("focusin", handleFocus);
return () => ownerDocument.removeEventListener("focusin", handleFocus);
}, [ownerDocument, handleFocusOutside]);
return {
onFocusCapture: () => isFocusInsideReactTreeRef.current = true,
onBlurCapture: () => isFocusInsideReactTreeRef.current = false
};
}
function dispatchUpdate() {
const event = new CustomEvent(CONTEXT_UPDATE);
document.dispatchEvent(event);
}
function handleAndDispatchCustomEvent(name, handler, detail, { discrete }) {
const target = detail.originalEvent.target;
const event = new CustomEvent(name, { bubbles: false, cancelable: true, detail });
if (handler) target.addEventListener(name, handler, { once: true });
if (discrete) {
dispatchDiscreteCustomEvent(target, event);
} else {
target.dispatchEvent(event);
}
}
export {
DismissableLayer as D
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { r as reactExports } from "../react.mjs";
function useCallbackRef(callback) {
const callbackRef = reactExports.useRef(callback);
reactExports.useEffect(() => {
callbackRef.current = callback;
});
return reactExports.useMemo(() => (...args) => callbackRef.current?.(...args), []);
}
export {
useCallbackRef as u
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { r as reactExports, R as React } from "../react.mjs";
import { u as useLayoutEffect2 } from "./react-use-layout-effect+[...].mjs";
var useInsertionEffect = React[" useInsertionEffect ".trim().toString()] || useLayoutEffect2;
function useControllableState({
prop,
defaultProp,
onChange = () => {
},
caller
}) {
const [uncontrolledProp, setUncontrolledProp, onChangeRef] = useUncontrolledState({
defaultProp,
onChange
});
const isControlled = prop !== void 0;
const value = isControlled ? prop : uncontrolledProp;
{
const isControlledRef = reactExports.useRef(prop !== void 0);
reactExports.useEffect(() => {
const wasControlled = isControlledRef.current;
if (wasControlled !== isControlled) {
const from = wasControlled ? "controlled" : "uncontrolled";
const to = isControlled ? "controlled" : "uncontrolled";
console.warn(
`${caller} is changing from ${from} to ${to}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`
);
}
isControlledRef.current = isControlled;
}, [isControlled, caller]);
}
const setValue = reactExports.useCallback(
(nextValue) => {
if (isControlled) {
const value2 = isFunction(nextValue) ? nextValue(prop) : nextValue;
if (value2 !== prop) {
onChangeRef.current?.(value2);
}
} else {
setUncontrolledProp(nextValue);
}
},
[isControlled, prop, setUncontrolledProp, onChangeRef]
);
return [value, setValue];
}
function useUncontrolledState({
defaultProp,
onChange
}) {
const [value, setValue] = reactExports.useState(defaultProp);
const prevValueRef = reactExports.useRef(value);
const onChangeRef = reactExports.useRef(onChange);
useInsertionEffect(() => {
onChangeRef.current = onChange;
}, [onChange]);
reactExports.useEffect(() => {
if (prevValueRef.current !== value) {
onChangeRef.current?.(value);
prevValueRef.current = value;
}
}, [value, prevValueRef]);
return [value, setValue, onChangeRef];
}
function isFunction(value) {
return typeof value === "function";
}
export {
useControllableState as u
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { r as reactExports } from "../react.mjs";
import { u as useCallbackRef } from "./react-use-callback-ref+[...].mjs";
function useEscapeKeydown(onEscapeKeyDownProp, ownerDocument = globalThis?.document) {
const onEscapeKeyDown = useCallbackRef(onEscapeKeyDownProp);
reactExports.useEffect(() => {
const handleKeyDown = (event) => {
if (event.key === "Escape") {
onEscapeKeyDown(event);
}
};
ownerDocument.addEventListener("keydown", handleKeyDown, { capture: true });
return () => ownerDocument.removeEventListener("keydown", handleKeyDown, { capture: true });
}, [onEscapeKeyDown, ownerDocument]);
}
export {
useEscapeKeydown as u
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { r as reactExports } from "../react.mjs";
var useLayoutEffect2 = globalThis?.document ? reactExports.useLayoutEffect : () => {
};
export {
useLayoutEffect2 as u
};
Loading