Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions src/plugins/profile/password-reset.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@
static get properties () {
return {
passwords_mismatched: { type: Boolean },
alert_message: { type: String }
alert_message: { type: String },
current_password_error: { type: String }
}
}

initialize () {
this.passwords_mismatched = false;
this.alert_message = '';
this.current_password_error = '';
}

render () {
Expand All @@ -38,7 +40,21 @@

if (this.checkPasswordsMatch(ev)) return;

const data = new FormData(ev.target);
const current_password = data.get('current_password');
const password = data.get('password');

if (!current_password) {
this.current_password_error = __('Please enter your current password');
return;
}
this.current_password_error = '';

const jid = _converse.session.get('jid');
const domain = _converse.session.get('domain');
const connection = api.connection.get();
const bare_jid = Strophe.getBareJidFromJid(jid);

const iq = stx`
<iq type="get" to="${domain}" xmlns="jabber:client">
<query xmlns="${Strophe.NS.REGISTER}"></query>
Expand All @@ -60,9 +76,6 @@

const username = iq_response.querySelector('username').textContent;

const data = new FormData(ev.target);
const password = data.get('password');

const reset_iq = stx`
<iq type="set" to="${domain}" xmlns="jabber:client">
<query xmlns="${Strophe.NS.REGISTER}">
Expand All @@ -74,6 +87,8 @@
const iq_result = await api.sendIQ(reset_iq);
if (iq_result === null) {
this.alert_message = __('Timeout error while trying to set your password');
} else if (sizzle(`error not-authorized[xmlns="${Strophe.NS.STANZAS}"]`, iq_result).length) {
this.alert_message = __('The current password you provided is incorrect');
} else if (sizzle(`error not-allowed[xmlns="${Strophe.NS.STANZAS}"]`, iq_result).length) {
this.alert_message = __('Your server does not allow password reset');
} else if (sizzle(`error forbidden[xmlns="${Strophe.NS.STANZAS}"]`, iq_result).length) {
Expand Down
16 changes: 16 additions & 0 deletions src/plugins/profile/templates/password-reset.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,28 @@ import { html } from 'lit';
export default el => {
const i18n_submit = __('Submit');
const i18n_passwords_must_match = __('The new passwords must match');
const i18n_current_password = __('Current password');
const i18n_new_password = __('New password');
const i18n_confirm_password = __('Confirm new password');

return html`<form class="converse-form passwordreset-form" method="POST" @submit=${ev => el.onSubmit(ev)}>
${el.alert_message ? html`<div class="alert alert-danger" role="alert">${el.alert_message}</div>` : ''}

<div class="py-2">
<label for="converse_password_reset_current" class="form-label">${i18n_current_password}</label>
<input
class="form-control"
type="password"
value=""
name="current_password"
required="required"
id="converse_password_reset_current"
autocomplete="current-password"
minlength="8"
?disabled="${el.alert_message}"
/>
</div>

<div class="py-2">
<label for="converse_password_reset_new" class="form-label">${i18n_new_password}</label>
<input
Expand Down
44 changes: 43 additions & 1 deletion src/plugins/profile/tests/password-reset.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import converse from '../../../../dist/converse.js';

const { Strophe, sizzle, u, stx } = converse.env;

async function submitPasswordResetForm(_converse) {
async function submitPasswordResetForm(_converse, current_password = 'current-password') {
await mock.openControlBox(_converse);
const cbview = _converse.chatboxviews.get('controlbox');
cbview.querySelector('a.show-profile')?.click();
Expand All @@ -13,6 +13,8 @@ async function submitPasswordResetForm(_converse) {
modal.querySelector('#passwordreset-tab').click();
const form = await u.waitUntil(() => modal.querySelector('.passwordreset-form'));

const current_pw_input = form.querySelector('input[name="current_password"]');
current_pw_input.value = current_password;
const pw_input = form.querySelector('input[name="password"]');
pw_input.value = 'secret-password';
const pw_check_input = form.querySelector('input[name="password_check"]');
Expand Down Expand Up @@ -150,4 +152,44 @@ describe('The profile modal', function () {
expect(alert.textContent).toBe('You are not allowed to change your password');
}),
);

it(
'informs you if the current password is incorrect',
mock.initConverse(converse, [], {}, async function (_converse) {
const modal = await submitPasswordResetForm(_converse);

const sent_IQs = _converse.api.connection.get().IQ_stanzas;
const query_iq = await u.waitUntil(() =>
sent_IQs.filter((iq) => sizzle('query[xmlns="jabber:iq:register"]', iq).length).pop(),
);

_converse.api.connection.get()._dataRecv(
mock.createRequest(_converse,
u.toStanza(`
<iq type='result' id='${query_iq.getAttribute('id')}'>
<query xmlns='jabber:iq:register'>
<username>romeo@montague.lit</username>
<password/>
</query>
</iq>`),
),
);

const set_iq = await u.waitUntil(() =>
sent_IQs.filter((iq) => sizzle('iq[type="set"] query[xmlns="jabber:iq:register"]', iq).length).pop(),
);

_converse.api.connection.get()._dataRecv(
mock.createRequest(_converse,
u.toStanza(`
<iq type='result' id="${set_iq.getAttribute('id')}">
<error type="auth"><not-authorized xmlns="${Strophe.NS.STANZAS}"/></error>
</iq>`),
),
);

const alert = await u.waitUntil(() => modal.querySelector('.alert-danger'));
expect(alert.textContent).toBe('The current password you provided is incorrect');
}),
);
});
Loading