feat(ui): improve user dropdown, profile page, and org selector - #5089
feat(ui): improve user dropdown, profile page, and org selector#5089itzzjustmateo wants to merge 14 commits into
Conversation
| import { pullImage } from "../utils/docker/utils"; | ||
| export const initializePostgres = async () => { | ||
| const imageName = "postgres:16"; | ||
| const imageName = "postgres:18"; |
There was a problem hiding this comment.
PostgreSQL upgrade abandons existing data
When setup runs on an existing installation with PostgreSQL 16 data at /var/lib/postgresql/data, it updates the service to PostgreSQL 18 while reusing the volume at a new mount layout without upgrading the cluster, causing the application to connect to a new database location while existing users, projects, services, and settings remain inaccessible.
Knowledge Base Used: Server Setup and Packaging
| ports: | ||
| - "5432:5432" |
There was a problem hiding this comment.
Known credential exposed to network
If the development host's port 5432 is reachable by another network peer, 5432:5432 exposes PostgreSQL on every host interface and the repository-known dokploy password lets that peer read, modify, or delete development data.
How this was verified: The Compose service publishes port 5432 without a loopback address and configures the database with the password committed in the same file.
| ports: | |
| - "5432:5432" | |
| ports: | |
| - "127.0.0.1:5432:5432" |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2335c4e97e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // postgres:18+ images store data under /var/lib/postgresql/<version> | ||
| // and refuse to start when a mount is pinned to the old | ||
| // /var/lib/postgresql/data subpath. Mount the parent instead. | ||
| Target: "/var/lib/postgresql", |
There was a problem hiding this comment.
Preserve the existing Postgres volume layout
When setup is rerun on an installation that already has the dokploy-postgres volume from the previous service, this changes the same named volume from being mounted at /var/lib/postgresql/data to /var/lib/postgresql while also starting postgres:18. The existing cluster files are at the volume root from the old mount, so the new image will not see them at its expected PGDATA path and can initialize/use a fresh empty cluster instead of the existing Dokploy database; a major-version upgrade also needs an explicit migration path rather than just swapping the image and mount target.
Useful? React with 👍 / 👎.
| const wantsPasswordChange = Boolean(data.password || data.currentPassword); | ||
| if (!wantsPasswordChange) return; |
There was a problem hiding this comment.
Clear hidden password fields before validation
If a user enables Change Password, types only one password field or a short new password, then disables the switch to save unrelated profile changes, React Hook Form keeps those unmounted field values and this refinement still treats them as a password-change attempt. The submit is then blocked by errors for fields that are no longer visible, even though onSubmit would omit passwords when changePassword is false; clear the password fields when disabling the switch or gate this validation on the toggle state.
Useful? React with 👍 / 👎.
| }, | ||
| { | ||
| keepValues: true, | ||
| keepValues: false, |
There was a problem hiding this comment.
Preserve unsaved profile edits on refetch
With keepValues changed to false, any api.user.get refetch while the user is editing this form resets all fields back to the server values. In common cases such as returning to the tab/window or another component invalidating/refetching the user query, partially edited names, email, avatar, or password fields are silently discarded before submit; keep the current form values during data refreshes or only reset on the initial load.
Useful? React with 👍 / 👎.
|
almost finished |
|
I am currently fixing the issues Greptile and Codex gave me :P |
…gnup Adds a shared AvatarPicker (no avatar, presets, gradients, solid colors, custom URL, and local image upload with preview) and an OrganizationLogoInput for direct logo uploads. The register/onboarding form now collects the organization name and logo, and the signup after-hook applies them to the new organization.
…migration errors The dev server previously booted against an unmigrated or partially-migrated database, surfacing confusing runtime errors such as 'Failed query: ... from member where role = $1' (see Dokploy#3890). - Run migrations automatically via a predev hook (mirrors the production start script). - Exit non-zero when migrations fail so the server never runs against an incomplete schema. - Add just db / db-down / db-reset recipes and start the compose Postgres from 'just dev'. - Bind the dev Postgres to 127.0.0.1 and align .env.example with docker-compose.dev.yml.
|
to the relations: some may not be correct |
When migrations fail, print recovery steps (just db-reset for local dev, restart the service for production) instead of a bare error, and keep refusing to start against an incomplete schema.
just dev previously failed with a bare 'permission denied while trying to connect to the docker API at unix:///var/run/docker.sock'. The db recipes now check Docker access first and print the exact remediation (usermod -aG docker) or tell the user to start the daemon.
just db failed with 'Bind for 0.0.0.0:5432 failed: port is already allocated' when a leftover Swarm dokploy-postgres service (from dokploy:setup) occupies 5432. The new scripts/dev-db.sh runs docker compose and, on failure, identifies what holds port 5432 (swarm service, container, or host process) and prints the exact remediation (docker service rm dokploy-postgres, stop the container, or use a custom DATABASE_URL).
predev now runs wait-for-postgres before migrating, so a fresh compose DB (which takes a few seconds to initdb) no longer fails with ECONNREFUSED. scripts/dev-db.sh also waits for the container healthcheck to pass before returning. pnpm: finish the v10 config migration by moving the remaining overrides (esbuild, better-call, @better-fetch/fetch, @types/react, @types/react-dom) from the package.json 'pnpm'/'resolutions' keys into pnpm-workspace.yaml. The 'pnpm' key was already ignored by pnpm 10 (emitting a warning on every run), and 'resolutions' silently suppressed the workspace overrides; the lockfile is unchanged apart from the recorded override set ordering. dev: add a dev-only BETTER_AUTH_SECRET to .env.example so better-auth no longer falls back to the hardcoded insecure default during development.
|
before it worked, now I cannot test because I fcked up my docker configs |
| // Only expose the dev database on localhost so the known | ||
| // legacy credential is never reachable from the network. | ||
| HostIp: "127.0.0.1", | ||
| } as PortConfig, |
There was a problem hiding this comment.
Loopback restriction is ignored
When a development setup creates or updates this Swarm service, HostIp is not supported on a Swarm PortConfig, so host-mode port 5432 remains exposed through the host's network interfaces while the service retains the repository-known fallback password.
How this was verified: The service publishes port 5432 through Swarm EndpointSpec.Ports, whose PortConfig has no host-address binding field.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 52f081ae44
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| }, | ||
| // Only expose the dev database on localhost so the known | ||
| // legacy credential is never reachable from the network. | ||
| HostIp: "127.0.0.1", |
There was a problem hiding this comment.
Do not rely on unsupported HostIp for Swarm
When NODE_ENV=development runs dokploy:setup, this still creates/updates a Swarm service publishing 5432; Docker’s service publish docs only support published, target, mode, and protocol, and Swarm’s routing docs state published ports listen on any IP assigned to the node. HostIp is therefore not honored for this service port, so the dev Postgres instance can remain reachable off-host despite the known fallback credential; use the Compose dev DB, avoid publishing the port, or add an explicit firewall rule instead.
Useful? React with 👍 / 👎.
| const POSTGRES_PASSWORD = | ||
| process.env.POSTGRES_PASSWORD ?? LEGACY_POSTGRES_PASSWORD; |
There was a problem hiding this comment.
Align POSTGRES_PASSWORD with the app database URL
When setup is run with only POSTGRES_PASSWORD set and no DATABASE_URL/POSTGRES_PASSWORD_FILE, this initializes or updates the Postgres service with the custom password, but packages/server/src/db/constants.ts still builds the fallback dbUrl from the legacy hard-coded password. The migration that runs immediately after setup and later app startups will then authenticate with the wrong credential; either derive the fallback URL from POSTGRES_PASSWORD too or require DATABASE_URL whenever this env is honored.
Useful? React with 👍 / 👎.
| # Install dependencies + set up the local dev environment | ||
| setup: | ||
| pnpm install | ||
| pnpm run dokploy:setup |
There was a problem hiding this comment.
Avoid setting up the Swarm DB in the dev recipe
If a contributor follows the new just setup recipe and then runs just dev, this line runs dokploy:setup, which creates the Swarm dokploy-postgres service on port 5432; just dev then starts the Compose database and scripts/dev-db.sh explicitly treats that Swarm service as a leftover conflict that must be removed manually. The advertised setup path therefore breaks the next dev command, so this recipe should use the Compose dev DB path instead of dokploy:setup (or otherwise avoid creating the conflicting Swarm service).
Useful? React with 👍 / 👎.
Summary
AvatarPicker(no avatar, preset, gradient, solid color, custom URL, and local image upload with preview) and clip images to the rounded border.OrganizationLogoInputso organization logos can be uploaded directly instead of pasting an external URL; the logo is applied when an organization is created at registration./var/lib/postgresql(postgres:18+ refuses the old/var/lib/postgresql/datasubpath) and only expose the dev database on127.0.0.1; includes adocker-compose.dev.ymlfor local Postgres.just devnow starts the local Postgres (just db) and applies migrations automatically before the server boots. Migration failures now halt startup instead of silently running the server against an incomplete schema (fixes runtime errors likeFailed query: ... from "member" where role = $1on a fresh/unmigrated dev DB). Addedjust db,just db-down, andjust db-resetrecipes.overrides/peerDependencyRules/onlyBuiltDependenciesfrom the ignoredpnpmkey inpackage.jsontopnpm-workspace.yaml.mise.toml(Node 24 / pnpm 10) and ajustfile.Related Issues
Failed query: ... from "member"runtime error: migrations fail silently and the server keeps running against an incomplete schema. This PR makes the migration runner exit non-zero on failure and migrates the dev database automatically before the dev server starts.AvatarPicker.OrganizationLogoInput, instead of pasting an external URL.just db-down/just db-resetfor the Compose-based dev database.Testing
pnpm typecheckpasses across all workspaces.Greptile Summary
The PR redesigns account and organization UI, adds avatar and logo upload controls, improves local development tooling, and updates the bundled PostgreSQL setup.
Confidence Score: 2/5
The PR is not safe to merge until the PostgreSQL 16 upgrade preserves existing clusters and the development Swarm database is genuinely restricted to loopback.
Existing installations are still switched directly to PostgreSQL 18 without a major-version cluster migration, while the volume remount makes the old cluster inaccessible; separately, the Swarm setup relies on an unsupported
HostIpport field and therefore leaves the known database credential network-reachable.Files Needing Attention: packages/server/src/setup/postgres-setup.ts
Security Review
The development Swarm database remains network-reachable because Docker Swarm service ports do not honor the added
HostIpfield; the repository-known fallback password therefore remains exposed on that path.How this was verified: The changed service publishes port 5432 in Swarm host mode through
EndpointSpec.Ports, whosePortConfighas no host-address binding field, while the code retains the known fallback password.Reviews (3): Last reviewed commit: "fix(dev): wait for Postgres readiness an..." | Re-trigger Greptile
Context used: