nextcloud-libraries / nextcloud-libraries/nextcloud-password-confirmation

Strict mode: dialog shows "Wrong password" when the wrapped request fails for non-auth reasons (e.g. HTTP 500)

Open
#1,458 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
6
Forks
8
PR merge metrics
No merged PRs in 30d

Description

Summary

With addPasswordConfirmationInterceptors and a request tagged confirmPassword: PwdConfirmationMode.Strict, the password dialog displays "Wrong password" whenever the wrapped request fails — even when the Basic auth succeeded and the failure is unrelated to the password (e.g. the endpoint returns HTTP 500).

Reproduction (observed on v5.3.2, same logic present on main)

  1. Tag a request with { confirmPassword: PwdConfirmationMode.Strict } against an endpoint with #[PasswordConfirmationRequired(strict: true)] that fails server-side after auth — e.g. Nextcloud 34's POST /ocs/v2.php/apps/appstore/api/v1/apps/enable for an app the appstore cannot download (returns 500 could not enable app).
  2. Enter the correct password in the dialog.
  3. The request goes out with a correct Authorization: Basic … header, the middleware accepts it, the controller fails → 500.
  4. The dialog stays open and shows "Wrong password".

Cause

In the response interceptor (src/main.ts, dist index.mjs):

(error) => {
    if (error.config?.confirmPassword !== PwdConfirmationMode.Strict) throw error
    if (validatePromise === undefined) { … throw error }
    validatePromise.reject(error)   // <-- rejects for ANY error, not just auth failures
    if (!(error.response?.status === 403 && error.response.data.message === 'Password confirmation is required')) {
        throw error
    }
    return axios.request(error.config)
}

validatePromise.reject(error) runs for every failed strict request. In the dialog component, confirm() catches the rejected validate(password) and sets showError = true, whose helper text is unconditionally Wrong password when a password was entered:

helperText() {
    if (this.showError) {
        return this.password === '' ? t('Please enter your password') : t('Wrong password')
    }
    …
}

So any non-auth failure (5xx, unrelated 4xx, network error) of the wrapped request is misreported to the user as a wrong password.

Expected

Only an actual confirmation failure (the 403 Password confirmation is required case, or a 401/403 clearly attributable to the Basic credentials) should keep the dialog open with "Wrong password". Other errors should resolve/close the dialog (the password was accepted) and let the rejection propagate to the caller, which can show its own error UI.

Context

Found while wiring one-click app install/enable into a Vue library (mirroring the apps/appstore client in Nextcloud 34). The caller correctly receives the rejection and shows its own inline error, but the lingering "Wrong password" dialog on top of it misleads admins into retrying their password.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/main.ts at the response interceptor and trace how validatePromise.reject(error) reaches the dialog component's confirm() and helperText() logic; dist/index.mjs contains the built equivalent. Preserve the dialog for actual password-confirmation failures, while non-authentication errors should close it and propagate to the caller.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
authentication
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.