-
Notifications
You must be signed in to change notification settings - Fork 0
feat: Phase 14/15 — Cloudflare Containers setup for graph-server #70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
c430cfc
3154f6e
1d9e3d0
b2c9a31
872ac07
e38ef5a
2ca7726
d8b4304
3e71b43
c7f0f15
a691ba0
0aa75f3
770072b
fec5266
742dc04
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dollar sign in password triggers variable interpolationHigh Severity Docker Compose performs variable interpolation on |
||
| 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: | ||
| 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 | ||
| }; |


There was a problem hiding this comment.
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 indocker-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 devpostgresservice 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.envfile (which is already gitignored).