Skip to content

fix: percent-encode credentials when building DATABASE_URL (#126)#167

Merged
neonsolstice merged 1 commit into
bookorbit:mainfrom
MohammadYusif:BO-126-encode-database-url-credentials
May 31, 2026
Merged

fix: percent-encode credentials when building DATABASE_URL (#126)#167
neonsolstice merged 1 commit into
bookorbit:mainfrom
MohammadYusif:BO-126-encode-database-url-credentials

Conversation

@MohammadYusif

@MohammadYusif MohammadYusif commented May 30, 2026

Copy link
Copy Markdown
Contributor

Before you submit

New feature? Please open an issue first and get approval from the maintainers before writing any code.
PRs that introduce features without a prior discussion will be closed.

Used AI assistance? That's fine - but make sure you've read and understood every line of the diff
before submitting. PRs that show no sign of self-review will be closed without detailed feedback.

Keep it focused. One thing per PR. Don't bundle a bug fix with a refactor or unrelated cleanup.
If it's not ready, open it as a draft instead.


What does this PR do?

When DATABASE_URL is not explicitly set, server/entrypoint.sh builds
it by interpolating POSTGRES_USER, POSTGRES_PASSWORD, and POSTGRES_DB
raw into a postgres:// URL. Any reserved URL character in the password
(#, /, ?, @, :, space) corrupts the string — a # in particular
turns everything after it into a URL fragment — so pg-connection-string's
new URL() throws ERR_INVALID_URL and the container crashes during
runMigrations before it can boot.

This adds a small urlencode() helper that pipes each credential component
through node -e 'encodeURIComponent(...)' before assembling the URL. Host
and port are intentionally left unencoded.

Fixes #126

How did you test this?

Reproduced the failure with node directly: building the URL the old way with
a password containing # and calling new URL() throws ERR_INVALID_URL.
With the encoded form it parses cleanly, the host/port/db fields are intact,
and decodeURIComponent returns the original plaintext — so Postgres receives
the correct password. Also ran sh -n server/entrypoint.sh to confirm no
syntax errors, and verified the helper handles empty values correctly
(encoding to empty, preserving the existing default-fallback behaviour).

Screenshots

N/A — no UI changes.

Anything non-obvious in the diff?

urlencode() shells out to node -e 'encodeURIComponent(...)' rather than
a pure-shell loop. This is intentional: node is always available here (the
runtime is node:alpine and the very next lines run node dist/scripts/migrate.js
and node dist/main.js), and encodeURIComponent gives a fully-correct
RFC 3986 encoder with no edge cases to hand-roll.

Checklist

  • I've read through my own diff
  • This PR was discussed in an issue and has maintainer approval (for new features) — N/A, this is a bug fix on a tracked issue
  • Lint and tests pass locally (sh -n clean; repo has no shell test suite)
  • No unintended files included (build artifacts, .env, personal configs)

Summary by CodeRabbit

  • Chores
    • Improved database connection configuration during application startup to properly handle credential components containing special characters, ensuring reliable connections regardless of characters used in usernames, passwords, or database names.

Review Change Stack

…#126)

When DATABASE_URL is not provided, entrypoint.sh assembled it by
interpolating POSTGRES_USER, POSTGRES_PASSWORD and POSTGRES_DB directly
into a postgres:// URL. Any reserved URL character in those values (for
example a '#', '/' or '?' in the password) produced an invalid URL, and
pg-connection-string's new URL() call then threw ERR_INVALID_URL,
preventing the container from starting.

Percent-encode the user, password and database components via
encodeURIComponent before building the URL so passwords containing
special characters work without manual escaping.
@github-actions github-actions Bot added the server Changes affecting server-side code, APIs, or backend behavior. label May 30, 2026
@coderabbitai

coderabbitai Bot commented May 30, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 0729eaf5-2b64-4f23-a5d8-9d948693aa34

📥 Commits

Reviewing files that changed from the base of the PR and between 174d76d and 217d1da.

📒 Files selected for processing (1)
  • server/entrypoint.sh

📝 Walkthrough

Walkthrough

The entrypoint script now builds the PostgreSQL connection string by percent-encoding username, password, and database name components using a new urlencode() helper. This prevents special characters in credentials from breaking the URL format.

Changes

Database URL Encoding

Layer / File(s) Summary
URL-encoded Postgres credentials
server/entrypoint.sh
Adds inline urlencode() helper that invokes Node's encodeURIComponent to safely encode Postgres connection parameters when DATABASE_URL is auto-constructed, replacing direct variable interpolation with percent-encoded values.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

🐰 A rabbit hops through URL schemes,
Encoding special chars and dreams,
No more colons break the line—
Your password's safe, all percent-fine! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix: percent-encode credentials when building DATABASE_URL (#126)' directly and clearly describes the main change in the PR.
Description check ✅ Passed The PR description comprehensively covers what was changed, how it was tested, and provides context for the fix, addressing all template requirements.
Linked Issues check ✅ Passed The PR successfully addresses issue #126 by implementing percent-encoding of credentials to prevent URL corruption from reserved characters, resolving the ERR_INVALID_URL crash.
Out of Scope Changes check ✅ Passed All changes are scoped to fixing DATABASE_URL construction in server/entrypoint.sh; no unrelated refactoring or cleanup is included.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@neonsolstice

Copy link
Copy Markdown
Collaborator

Looks good to me. Clean fix and I don't see any issues here. Approving!

@neonsolstice
neonsolstice merged commit a5a069a into bookorbit:main May 31, 2026
36 of 40 checks passed
@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown

🎉 This PR is included in version 1.8.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@github-actions github-actions Bot added the released Issue or PR is included in a released version. label Jun 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

released Issue or PR is included in a released version. server Changes affecting server-side code, APIs, or backend behavior.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Shipping broken: Invalid URL

2 participants