Skip to content

Feature: Password Security Bar - #199

Open
FirTheDeveloper wants to merge 3 commits into
PlanetaryOrbit:mainfrom
FirTheDeveloper:main
Open

Feature: Password Security Bar#199
FirTheDeveloper wants to merge 3 commits into
PlanetaryOrbit:mainfrom
FirTheDeveloper:main

Conversation

@FirTheDeveloper

@FirTheDeveloper FirTheDeveloper commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Pull Request

Thank you for contributing to Orbit! 🐈

Before submitting, please make sure you have read the Contributing Guide.

Description

Related Issues

Type of Change

  • Bug fix
  • New feature
  • [ x ] Enhancement
  • Documentation
  • Refactor
  • Performance improvement
  • Dependency update
  • Other

Testing

Describe how you tested your changes.

  • [ x ] Tested locally
  • [ x ] Tested using Docker
  • Tested database changes (if applicable)

Screenshots / Videos

image image

Checklist

  • [ x ] I have read the contributing guidelines.
  • [ x ] My changes follow the project's style guidelines.
  • [ x ] I have tested my changes.
  • [ x ] I have updated documentation if needed.
  • [ x ] This PR does not contain unrelated changes.

Additional Notes

Added 1 package. Made all components require a password score of 3+ to accept the password.

Summary by CodeRabbit

  • New Features
    • Added real-time password strength indicators with color-coded progress bars and descriptive labels.
    • Added guidance for improving weak passwords.
  • Bug Fixes
    • Password creation and reset forms now require a strong password before submission.
    • Submission buttons are disabled when passwords are too weak or while processing.
    • Existing password confirmation matching remains supported.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Added shared password-strength calculation and a visual strength indicator. Signup and password-reset forms now require a strong password before submission.

Changes

Password strength validation

Layer / File(s) Summary
Strength calculation and indicator
utils/passwordStrength.ts, components/passwordStrengthBar.tsx
Added typed password-strength calculation with zxcvbn and a client-side indicator with score bars, labels, and weak-password guidance.
Signup password validation
pages/login.tsx, pages/welcome.tsx
Signup validation now requires a strength score of at least 3. Both forms display the indicator and disable submission for weaker passwords.
Password reset validation
pages/forgot-password.tsx
The final reset step now requires a strength score of at least 3, displays the indicator, and disables reset submission for weaker passwords.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant PasswordForm
  participant calculatePasswordStrength
  participant PasswordStrengthBar
  participant SubmitButton
  PasswordForm->>calculatePasswordStrength: calculate current password score
  calculatePasswordStrength-->>PasswordForm: return score and label
  PasswordForm->>PasswordStrengthBar: display score and guidance
  PasswordForm->>SubmitButton: disable when score is below 3
Loading

Suggested reviewers: breadddevv, brennanpeters

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: adding a password security bar.
Description check ✅ Passed The description uses the expected sections, identifies the change, records testing, includes screenshots, and lists checklist status.
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.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

components/passwordStrengthBar.tsx

ESLint skipped: missing config or dependency (missing-dependency). The ESLint configuration references a package that is not available in the sandbox.

pages/forgot-password.tsx

ESLint skipped: the ESLint configuration for this file references a package that is not available in the sandbox.

pages/login.tsx

ESLint skipped: the ESLint configuration for this file references a package that is not available in the sandbox.

  • 2 others

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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)
pages/login.tsx (1)

800-846: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Enforce the password policy in all three API handlers.

/api/auth/signup/finish, /api/setupworkspace, and /api/auth/reset/finish do not enforce calculatePasswordStrength(password).score >= 3 before hashing the password.

🤖 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 `@pages/login.tsx` around lines 800 - 846, Enforce
calculatePasswordStrength(password).score >= 3 in all three server-side API
handlers before hashing: /api/auth/signup/finish (pages/login.tsx, lines
800-846), /api/setupworkspace (pages/welcome.tsx, lines 383-445), and
/api/auth/reset/finish (pages/forgot-password.tsx, lines 292-332). Reject
passwords below the threshold using the handlers’ existing validation/error
response pattern; the client-side checks in the signup and reset flows require
no direct change.
🤖 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 `@utils/passwordStrength.ts`:
- Line 18: Update the password scoring call around zxcvbn to pass only
password.slice(0, 100). Apply the same 100-character bound consistently wherever
password inputs are processed and password-writing APIs accept or persist
passwords.

---

Outside diff comments:
In `@pages/login.tsx`:
- Around line 800-846: Enforce calculatePasswordStrength(password).score >= 3 in
all three server-side API handlers before hashing: /api/auth/signup/finish
(pages/login.tsx, lines 800-846), /api/setupworkspace (pages/welcome.tsx, lines
383-445), and /api/auth/reset/finish (pages/forgot-password.tsx, lines 292-332).
Reject passwords below the threshold using the handlers’ existing
validation/error response pattern; the client-side checks in the signup and
reset flows require no direct change.
🪄 Autofix

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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d2624137-4eee-435f-869c-b5931c9be7c9

📥 Commits

Reviewing files that changed from the base of the PR and between d9ce9e8 and 893c144.

📒 Files selected for processing (5)
  • components/passwordStrengthBar.tsx
  • pages/forgot-password.tsx
  • pages/login.tsx
  • pages/welcome.tsx
  • utils/passwordStrength.ts

Comment thread utils/passwordStrength.ts
};
}

const result = zxcvbn(password);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- candidate files ---'
git ls-files | grep -E '(^|/)(passwordStrength\.ts|package\.json|tsconfig[^/]*\.json|.*lock.*)$' || true
printf '%s\n' '--- passwordStrength.ts ---'
file=$(git ls-files | grep -E '(^|/)utils/passwordStrength\.ts$' | head -n 1)
if [ -n "${file:-}" ]; then
  cat -n "$file"
  printf '%s\n' '--- references ---'
  rg -n -C 3 'passwordStrength|zxcvbn|password' --glob '!**/node_modules/**' --glob '!**/dist/**' .
fi
printf '%s\n' '--- package/config declarations ---'
for f in $(git ls-files | grep -E '(^|/)(package\.json|tsconfig[^/]*\.json|.*lock.*)$' || true); do
  printf '\n### %s\n' "$f"
  case "$f" in
    *.json) sed -n '1,240p' "$f" ;;
    *) rg -n -C 2 'zxcvbn|password|maximum|maxLength|100' "$f" || true ;;
  esac
done

Repository: PlanetaryOrbit/orbit

Length of output: 50376


🌐 Web query:

zxcvbn GitHub Dropbox maximum password length first 100 characters scoring latency recommendation

💡 Result:

Zxcvbn, originally developed by Dropbox, is a password strength estimator that uses pattern matching and conservative estimation [1][2]. Because its internal pattern-matching algorithms can exhibit super-quadratic runtime for certain adversarial inputs, the library includes mechanisms to manage performance and mitigate potential denial-of-service (DoS) risks [1][3]. Performance and Latency Under typical conditions, zxcvbn operates well below the threshold of human-perceived latency [1][4]. For standard inputs, scoring takes approximately 5–20ms for passwords around 25 characters and grows to about 100ms for passwords around 100 characters [1][2][4]. However, performance can degrade significantly with long or complex, adversarial inputs (e.g., repeated patterns or complex character combinations), sometimes leading to multi-second delays [3][5][6]. Recommendations for Password Length To maintain consistent performance and protect against DoS attacks, it is strongly recommended to bound the input size passed to the library [1][7]. The official Dropbox implementation documentation suggests that for very long passwords, you should consider passing only the first 100 characters of the user input to the scoring function [1][2][8]. Many implementations of the library enforce a maximum length limit to prevent resource exhaustion. For example, some ports (such as the Python implementation) default to a 72-character limit and advise against increasing it [7][9][10]. Other implementations (such as the Ruby port) may set a default limit of 256 characters [3]. Developers are advised to apply a length check before calling the library and to be cautious if overriding these default maximums, as doing so can re-expose the application to runtime risks [3][7][9].

Citations:


🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- relevant password inputs and API handlers ---'
for f in pages/login.tsx pages/welcome.tsx pages/forgot-password.tsx pages/api/auth/signup/finish.ts pages/api/auth/reset/finish.ts pages/api/setupworkspace.ts; do
  if git ls-files --error-unmatch "$f" >/dev/null 2>&1; then
    printf '\n### %s\n' "$f"
    rg -n -C 8 'register\(.*password|type="password"|password\.length|req\.body\.password|const \{[^}]*password|bcryptjs\.hash' "$f" || true
  fi
done
printf '%s\n' '--- Input component ---'
input_file=$(git ls-files | grep -E '(^|/)components/.*/?input\.tsx$|(^|/)components/input\.tsx$' | head -n 1 || true)
if [ -n "${input_file:-}" ]; then
  cat -n "$input_file"
else
  rg -l 'function Input|const Input|export default.*Input' components pages | head -n 10 | while read -r f; do
    printf '\n### %s\n' "$f"
    rg -n -C 12 'function Input|const Input|export default.*Input' "$f"
  done
fi
printf '%s\n' '--- upstream README and implementation references ---'
curl -L --fail --silent --show-error https://raw.githubusercontent.com/dropbox/zxcvbn/master/README.md |
  rg -n -C 4 '100|long password|maximum|performance|latency' || true
curl -L --fail --silent --show-error https://raw.githubusercontent.com/dropbox/zxcvbn/master/src/main.coffee |
  rg -n -C 4 'length|password' | head -n 120 || true

Repository: PlanetaryOrbit/orbit

Length of output: 16958


🏁 Script executed:

#!/bin/bash
set -eu
python3 - <<'PY'
from pathlib import Path
import re

strength = Path("utils/passwordStrength.ts").read_text()
print("strength_call:", re.findall(r"zxcvbn\(([^)]*)\)", strength))

targets = [
    "pages/login.tsx",
    "pages/welcome.tsx",
    "pages/forgot-password.tsx",
    "pages/api/auth/signup/finish.ts",
    "pages/api/auth/reset/finish.ts",
    "pages/api/setupworkspace.ts",
]
for name in targets:
    text = Path(name).read_text()
    if name.startswith("pages/api/"):
        password_checks = re.findall(
            r"(?i).{0,80}(?:password\.length|maxLength|password.{0,20}100|100.{0,20}password).{0,120}",
            text,
        )
        print(f"{name}: password_length_checks={password_checks}")
    else:
        usages = []
        for match in re.finditer(r"<Input\b[\s\S]*?/>", text):
            element = match.group(0)
            if re.search(r'type="password"', element):
                usages.append("maxLength" in element)
        print(f"{name}: password_input_maxLength_flags={usages}")
PY

Repository: PlanetaryOrbit/orbit

Length of output: 589


Bound password input before scoring.

zxcvbn recommends scoring only the first 100 characters for very long inputs. Pass password.slice(0, 100) to zxcvbn. Apply the same 100-character limit to password inputs and password-writing APIs.

🤖 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 `@utils/passwordStrength.ts` at line 18, Update the password scoring call
around zxcvbn to pass only password.slice(0, 100). Apply the same 100-character
bound consistently wherever password inputs are processed and password-writing
APIs accept or persist passwords.

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.

1 participant