Skip to content

fix(link): refresh masked-password URLs on re-link#117

Merged
tonychang04 merged 1 commit into
mainfrom
fix/refresh-masked-database-url
May 12, 2026
Merged

fix(link): refresh masked-password URLs on re-link#117
tonychang04 merged 1 commit into
mainfrom
fix/refresh-masked-database-url

Conversation

@tonychang04
Copy link
Copy Markdown
Contributor

@tonychang04 tonychang04 commented May 12, 2026

Why

Pre-0.1.72 cloud `link --auth` wrote DATABASE_URL with a literal placeholder password:

```
DATABASE_URL=postgresql://postgres:********@m8s5kmam.us-east.database.insforge.app:5432/insforge?sslmode=require
```

The cloud's `/database-connection-string` endpoint masks the password as `********`; the unmask via the separate `/database-password` endpoint only landed in #108 (shipped in 0.1.72).

Users who linked under an older CLI still have the masked URL in `.env.local`. Re-linking under 0.1.72+ doesn't fix it because `refreshStaleEnvDefaults` only replaces values that match the manifest's literal default (`postgresql://postgres:postgres@127.0.0.1:5432/insforge`). The masked-cloud URL matches neither the default nor a real user customization — it falls into a gap.

The symptom is BA's pg pool failing on every sign-up:

```
password authentication failed for user "postgres"
```

What this PR does

Treat any `:***@` (one or more ``) password pattern as stale and refresh from the platform value, alongside the existing "matches the manifest default" branch.

```diff

  • if (def !== undefined && real !== undefined && userValue === def && real !== def) {
  • if (def === undefined || real === undefined || real === def) return line;
  • const matchesDefault = userValue === def;
  • const isMaskedPassword = MASKED_PASSWORD_PATTERN.test(userValue);
  • if (matchesDefault || isMaskedPassword) {
    refreshed.push(key);
    return `${key}=${real}`;
    }
    ```

The masked password is never a valid Postgres credential, so the "treat as stale" carries no risk of clobbering real user data.

Test plan

  • Unit test added: `refreshes a masked-password URL even if it differs from the manifest default`
  • 14/14 `apply.test.ts` tests pass
  • Existing "preserves user value when it differs from the manifest default" test still passes — a real user customization without the `:****@` pattern is left alone
  • Manual: re-link a project that has the masked URL → `.env.local` gets the real password spliced in → `npm run setup` succeeds

🤖 Generated with Claude Code


Summary by cubic

Fixes re-linking so masked DATABASE_URL values from older cloud links are replaced with the real password. Detects :****@ patterns and refreshes from platform values to prevent Postgres auth failures.

  • Bug Fixes
    • Extend refreshStaleEnvDefaults to refresh values with masked passwords (:\*+@) in addition to default-match cases.
    • Preserve real user edits and add a unit test for the masked-URL refresh case.

Written for commit 50709e2. Summary will update on new commits.

Summary by CodeRabbit

  • Bug Fixes
    • Fixed refresh handling for database connection strings containing masked passwords in environment configuration files. Previously, connection strings with placeholder passwords were not being updated to use actual platform credentials.

Review Change Stack

Pre-0.1.72 cloud `link --auth` wrote DATABASE_URL with a literal
placeholder password (the cloud `/database-connection-string` endpoint
masks the password as `********`; the unmask via the separate
`/database-password` endpoint only landed in #108 / shipped in 0.1.72).

`refreshStaleEnvDefaults` only refreshes when the user's value matches
the manifest's literal default. Users who linked under an older CLI
have `postgresql://postgres:********@cloud-host/db?sslmode=require` in
their .env.local — that doesn't match the manifest's `localhost:5432`
default, so re-linking under 0.1.72+ never replaces it. BA's pg pool
then fails with "password authentication failed for user 'postgres'"
on every sign-up attempt.

The masked password is never a valid Postgres credential — `:****@`
patterns can be safely treated as stale and replaced from the platform
value alongside the existing "matches the manifest default" branch.

Adds a unit test covering the masked-URL refresh case.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 12, 2026

Walkthrough

The PR adds masked-password detection to the .env.local refresh system. It introduces a pattern constant to identify masked database credentials, updates the refresh logic to detect and replace values matching that pattern, and validates the behavior with a test case.

Changes

Masked-Password Credential Refresh

Layer / File(s) Summary
Pattern Detection
src/auth-providers/apply.ts
Introduces MASKED_PASSWORD_PATTERN regex to detect masked database connection-string passwords (:*+@ format).
Refresh Logic
src/auth-providers/apply.ts
Updates refreshStaleEnvDefaults to refresh .env.local values when they match the masked-password pattern, in addition to the existing condition of matching manifest default with a live platform value difference.
Test Validation
src/auth-providers/apply.test.ts
Adds test case verifying that DATABASE_URL values with masked passwords (postgres:********@...) are replaced with the real platform password and the placeholder is removed.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • InsForge/CLI#106: Extends refreshStaleEnvDefaults logic to detect and replace masked/placeholder passwords when refreshing .env.local values.
  • InsForge/CLI#105: Modifies src/auth-providers/apply.ts to handle DATABASE_URL auto-fill and fetching alongside this PR's masked-password refresh logic.
  • InsForge/CLI#108: Updates logic and tests to detect and replace masked (********) passwords in database connection URLs.

Suggested reviewers

  • jwfing

Poem

🐰 A rabbit hops through masks so dark,
Where asterisks once left a mark.
Now passwords real shine bright and true,
The .env file gets its refresh due! 🌿

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(link): refresh masked-password URLs on re-link' directly and specifically describes the main change: fixing an issue where masked-password URLs are now refreshed during re-link operations.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/refresh-masked-database-url

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/auth-providers/apply.ts (1)

403-407: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Refresh log message is now too specific.

Line 406 says refresh only happens when value matched manifest default, but masked-password refreshes are now another path. Consider neutral wording to avoid confusing users.

Proposed wording update
       clack.log.info(
         `Refreshed stale platform defaults: ${result.envKeysRefreshed.join(', ')}. ` +
-        `Your value matched the manifest's default, so we replaced it with the live one.`,
+        `We detected a stale value and replaced it with the live one.`,
       );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/auth-providers/apply.ts` around lines 403 - 407, The log message in the
apply flow (where result.envKeysRefreshed is checked and clack.log.info is
called) claims refreshes only occur when a value matched the manifest default,
which is no longer always true (masked-passwords can trigger refreshes); make
the message neutral and accurate by removing the specific "matched the
manifest's default" phrasing and instead state that platform defaults or masked
values were refreshed and list result.envKeysRefreshed; update the string in the
clack.log.info call in src/auth-providers/apply.ts to reflect this neutral
wording, preserving the existing use of json to decide whether to log.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/auth-providers/apply.ts`:
- Around line 141-145: The code marks keys as refreshed whenever matchesDefault
or isMaskedPassword is true, even if the actual value hasn't changed; update the
logic so you only push to refreshed and return the updated `${key}=${real}` when
real !== userValue. In the block using MASKED_PASSWORD_PATTERN, check the
equality of real and userValue (and only treat it as refreshed when different);
if they are the same, do not push key into refreshed and return the original
`${key}=${userValue}` (or leave it unchanged). Reference symbols:
MASKED_PASSWORD_PATTERN, refreshed array, key, userValue, real, matchesDefault,
isMaskedPassword.

---

Outside diff comments:
In `@src/auth-providers/apply.ts`:
- Around line 403-407: The log message in the apply flow (where
result.envKeysRefreshed is checked and clack.log.info is called) claims
refreshes only occur when a value matched the manifest default, which is no
longer always true (masked-passwords can trigger refreshes); make the message
neutral and accurate by removing the specific "matched the manifest's default"
phrasing and instead state that platform defaults or masked values were
refreshed and list result.envKeysRefreshed; update the string in the
clack.log.info call in src/auth-providers/apply.ts to reflect this neutral
wording, preserving the existing use of json to decide whether to log.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0f4b036d-1c7c-4590-817e-45ebab49b9ef

📥 Commits

Reviewing files that changed from the base of the PR and between 20f0523 and 50709e2.

📒 Files selected for processing (2)
  • src/auth-providers/apply.test.ts
  • src/auth-providers/apply.ts

Comment on lines +141 to 145
const isMaskedPassword = MASKED_PASSWORD_PATTERN.test(userValue);
if (matchesDefault || isMaskedPassword) {
refreshed.push(key);
return `${key}=${real}`;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Avoid reporting a refresh when the value is unchanged.

At Line 141–145, masked values are marked refreshed even when real === userValue, which causes no-op rewrites and misleading envKeysRefreshed.

Proposed fix
-    if (matchesDefault || isMaskedPassword) {
+    if ((matchesDefault || isMaskedPassword) && real !== userValue) {
       refreshed.push(key);
       return `${key}=${real}`;
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const isMaskedPassword = MASKED_PASSWORD_PATTERN.test(userValue);
if (matchesDefault || isMaskedPassword) {
refreshed.push(key);
return `${key}=${real}`;
}
const isMaskedPassword = MASKED_PASSWORD_PATTERN.test(userValue);
if ((matchesDefault || isMaskedPassword) && real !== userValue) {
refreshed.push(key);
return `${key}=${real}`;
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/auth-providers/apply.ts` around lines 141 - 145, The code marks keys as
refreshed whenever matchesDefault or isMaskedPassword is true, even if the
actual value hasn't changed; update the logic so you only push to refreshed and
return the updated `${key}=${real}` when real !== userValue. In the block using
MASKED_PASSWORD_PATTERN, check the equality of real and userValue (and only
treat it as refreshed when different); if they are the same, do not push key
into refreshed and return the original `${key}=${userValue}` (or leave it
unchanged). Reference symbols: MASKED_PASSWORD_PATTERN, refreshed array, key,
userValue, real, matchesDefault, isMaskedPassword.

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

No issues found across 2 files

Tip: cubic could auto-approve low-risk PRs like this, if it thinks it's safe to merge. Learn more

@tonychang04 tonychang04 enabled auto-merge (squash) May 12, 2026 00:40
Copy link
Copy Markdown
Member

@jwfing jwfing left a comment

Choose a reason for hiding this comment

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

LGTM, approved.

@tonychang04 tonychang04 merged commit e993e76 into main May 12, 2026
3 checks passed
@tonychang04 tonychang04 mentioned this pull request May 12, 2026
2 tasks
tonychang04 added a commit that referenced this pull request May 12, 2026
Ship #117 (refresh masked-password DATABASE_URL on re-link). Users who
linked any cloud project under 0.1.71 or earlier had a placeholder
`********` password in `.env.local`. Re-linking under 0.1.72 didn't
fix it because the masked URL doesn't match the manifest's localhost
default. 0.1.73 detects the `:****@` pattern as stale and refreshes
from the platform-provided real password.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants