Skip to content

Add HTTP endpoint for end users to change their own password #351

Description

@melvincarvalho

Summary

A logged-in user has no way to change their own password through the running JSS. The only password-management interface today is the jss passwd <user> CLI (#232), which requires shell access on the server. End users in a multi-user pod or anyone running JSS without local shell access (containers, managed hosts, etc.) is stuck.

Current state

  • CLI: jss passwd <user> — operator-only, shell required.
  • HTTP IDP:
    • POST /idp/credentials — login only (issues token).
    • No change-password / password-reset endpoint.
  • Account records carry passwordHash (bcrypt) so the data layer already supports a rotation, just no API.

Proposed shape

A single authenticated endpoint, owner-only (the caller's WebID must match the account's WebID), gated by re-supplying the current password as proof:

PUT /idp/credentials
Authorization: <existing session / DPoP>
Content-Type: application/json

{
  "currentPassword": "...",
  "newPassword": "..."
}
  • 200 + new bcrypt hash written, all other sessions invalidated, current session re-issued.
  • 401 if current password is wrong.
  • 401 if not authenticated.
  • 403 if the authenticated WebID doesn't match the target account.

(Path bikeshed: PUT /idp/credentials matches the existing POST /idp/credentials shape; alternatives are POST /idp/account/password or PATCH /idp/credentials. Not load-bearing — pick whatever lands cleanly with the existing IDP routes.)

Out of scope

  • Password recovery / forgot-password flow (no current password). That's a separate feature that needs an email channel + token store. File as a follow-up if/when there's a recovery story.
  • WebAuthn / passkey rotation (separate auth mechanism, tracked in feat: Add passkey (WebAuthn) authentication support #78).

Acceptance

  • New endpoint accepts a valid {currentPassword, newPassword} from the authenticated owner and rotates the hash.
  • Wrong currentPassword → 401, hash unchanged.
  • Cross-account write attempts (authenticated as A, targeting B's password) → 403.
  • Any other active sessions for the rotated account are invalidated (refresh tokens revoked, etc.).
  • Existing jss passwd <user> CLI continues to work unchanged.
  • Tests cover happy path + the three failure modes above + session-invalidation behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions