Skip to content

docs(specs): login migration — password-for-existing + nag-to-link-github#117

Merged
themightychris merged 2 commits into
mainfrom
feat/login-migration-strategy
May 31, 2026
Merged

docs(specs): login migration — password-for-existing + nag-to-link-github#117
themightychris merged 2 commits into
mainfrom
feat/login-migration-strategy

Conversation

@themightychris
Copy link
Copy Markdown
Member

Summary

A directional change to the cutover auth strategy. Today's spec treats GitHub OAuth as the only auth path and gates existing laddr users with a one-shot claim flow at first sign-in. The new design:

  • Existing users keep password sign-in indefinitely. Every successful login auto-rehashes the unsalted-SHA1 credential to argon2id so the corpus drifts toward modern hashing without forcing resets.
  • New accounts are still GitHub-only — preserves the spam argument that drove the original GitHub-only decision (which was specifically about new-account sign-up, not existing users).
  • Linking GitHub becomes a per-user opt-in surfaced via a persistent yellow banner on `/account`. No deadline pressure; users link when ready. The banner is the only nag mechanism — no modals, no email reminders.
  • Sunset deferred — no fixed deprecation date.

Verified facts driving the design

Confirmed against `JarvusInnovations/emergence-skeleton/php-classes/User.class.php:33`:

```php
public static $passwordHasher = 'SHA1';
```

And the verifier:

```php
public function verifyPassword($password)
{
return $this->Password && call_user_func(static::$passwordHasher, $password) == $this->Password;
}
```

Unsalted SHA-1, with loose `==` comparison (timing-leaky). The new `password-hash-rotation.md` spec mandates constant-time compare + rehash-on-login so this corpus drifts to argon2id naturally.

Files changed

  • `specs/deferred.md` — splits "email/password auth" into "sign-up: GitHub-only" + note that existing users keep password sign-in
  • `specs/behaviors/account-migration.md` — rewritten around three sign-in paths; cutover-window deadline removed
  • `specs/behaviors/password-hash-rotation.md` (new) — hash-format detection, constant-time SHA-1 compare, rehash-on-login, anti-enumeration timing floor, argon2id params
  • `specs/api/auth.md` — adds `POST /api/auth/login`, `POST /api/auth/password-reset/{request,confirm}`, `POST /api/auth/link-github`; `/api/auth/me` grows `hasGitHubLink` + `lastLoginMethod`
  • `specs/screens/login.md` — collapsed secondary "Or sign in with your Code for Philly password" disclosure
  • `specs/screens/account.md` — Card 1 gains State A (linked) / State B (not linked, shows banner)
  • `plans/login-migration-strategy.md` (new) — plan file with the design rationale + impl follow-up

What's NOT in this PR

This is doc-only. Implementation (route handlers, argon2id dep, rehash logic, password-reset routes, link-github route, SPA banner + secondary login form) lives in a follow-up plan after these specs are reviewed.

Test plan

  • No tests apply — pure documentation change.
  • Plan validation list ticked except the last item ("PR review confirms direction") which is this PR itself.

🤖 Generated with Claude Code

themightychris and others added 2 commits May 30, 2026 22:10
Doc-only plan capturing a strategic shift in the cutover auth story:
keep password login working for existing users (with auto-rehash from
laddr's unsalted SHA1 to argon2id on every successful login), restrict
new signups to GitHub, and surface GitHub-linking via a non-blocking
banner on /account. Sunset deferred.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…thub

A directional change to the cutover auth strategy. Today's spec treats
GitHub OAuth as the only auth path and gates existing laddr users with
a one-shot claim flow at first sign-in. The new design:

  - Existing users keep password sign-in indefinitely. Every successful
    login auto-rehashes the unsalted-SHA1 credential (confirmed against
    JarvusInnovations/emergence-skeleton User.class.php:33) to argon2id
    so the corpus drifts toward modern hashing without forcing resets.
  - New accounts are still GitHub-only — preserves the spam argument
    that drove the original GitHub-only decision (which was specifically
    about new-account sign-up, not existing users).
  - Linking GitHub becomes a per-user opt-in surfaced via a persistent
    yellow banner on /account. No deadline pressure; users link when
    ready. The banner is the only nag mechanism.
  - Sunset of password sign-in is deferred — no fixed deprecation date
    or coverage threshold. Tracked separately when usage data justifies.

Doc-only change. The implementation work (POST /api/auth/login route,
rehash logic, link flow, banner, password-reset routes) lands in a
follow-up plan after these specs are reviewed.

Spec changes:

  specs/deferred.md                       — flips "email/password auth"
    from "deleted entirely" to "sign-up GitHub-only, existing users
    keep password indefinitely."

  specs/behaviors/account-migration.md    — rewritten around the three
    sign-in paths (GitHub-new, GitHub-matched, legacy-password) and
    the link-when-ready banner. Cutover-window deadline policy
    removed; users aren't time-pressured.

  specs/behaviors/password-hash-rotation.md (new) — SHA-1/bcrypt/argon2
    format detection, constant-time compare, rehash-on-login,
    anti-enumeration timing (dummy argon2 verify on missing user/cred
    paths), argon2id parameter source-of-truth.

  specs/api/auth.md                       — adds POST /api/auth/login,
    POST /api/auth/password-reset/{request,confirm}, POST /api/auth/
    link-github. /api/auth/me grows hasGitHubLink + lastLoginMethod.
    Notes section updated to reflect the password-for-migrated-users
    posture.

  specs/screens/login.md                  — adds a collapsed secondary
    "Or sign in with your Code for Philly password" disclosure with
    the password form + "Forgot your password?" affordance.

  specs/screens/account.md                — Card 1 (Identity) gains
    State A (linked) / State B (not yet linked, shows banner). Link
    action wired to POST /api/auth/link-github.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@themightychris themightychris merged commit 50a6b94 into main May 31, 2026
1 check passed
@themightychris themightychris deleted the feat/login-migration-strategy branch May 31, 2026 03:57
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