Reworked profile modal; Added rudimentary password reset plugin
This commit is contained in:
parent
5ea00b8008
commit
fa132567da
131
src/plugins/password-reset/index.js
Normal file
131
src/plugins/password-reset/index.js
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
/**
|
||||||
|
* @copyright The Converse.js contributors
|
||||||
|
* @license Mozilla Public License (MPLv2)
|
||||||
|
*/
|
||||||
|
import 'modals/user-details.js';
|
||||||
|
import 'plugins/profile/index.js';
|
||||||
|
import BaseModal from "plugins/modal/base.js";
|
||||||
|
import { modal_close_button } from "plugins/modal/templates/buttons.js";
|
||||||
|
import log from '@converse/headless/log';
|
||||||
|
import { CustomElement } from 'shared/components/element.js';
|
||||||
|
import { html } from "lit";
|
||||||
|
import { _converse, api, converse } from '@converse/headless/core';
|
||||||
|
const u = converse.env.utils;
|
||||||
|
|
||||||
|
const { Strophe, $iq } = converse.env;
|
||||||
|
|
||||||
|
|
||||||
|
converse.plugins.add('converse-passwordreset', {
|
||||||
|
enabled (_converse) {
|
||||||
|
return (
|
||||||
|
!_converse.api.settings.get('blacklisted_plugins').includes('converse-changepassword')
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
dependencies: [],
|
||||||
|
|
||||||
|
|
||||||
|
initialize () {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const password_match_error = (el) => {
|
||||||
|
return html`
|
||||||
|
<span class='error'>The two passwords entered must match.</span>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
const confirm_sure = (el) => {
|
||||||
|
return html`
|
||||||
|
<span>Are you sure?</span>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
class Profile extends CustomElement {
|
||||||
|
|
||||||
|
async initialize () {
|
||||||
|
this.confirmation_active = false;
|
||||||
|
this.passwords_mismatched = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
render () {
|
||||||
|
return ((el) => {
|
||||||
|
return html`
|
||||||
|
<form class="converse-form passwordreset-form" @submit=${el.onSubmit}>
|
||||||
|
<fieldset class="form-group">
|
||||||
|
<label for="converse_passwordreset_password">Password</label>
|
||||||
|
<input class="form-control" type="password" value="" name="password" required="required" id="converse_passwordreset_password">
|
||||||
|
<label for="converse_passwordreset_password_check">Re-type Password</label>
|
||||||
|
<input class="form-control" type="password" value="" name="password_check" @input=${el.checkPasswordsMatch} required="required" id="converse_passwordreset_password_check">
|
||||||
|
${(el.passwords_mismatched) ? password_match_error(el) : ''}
|
||||||
|
</fieldset>
|
||||||
|
${(el.confirmation_active) ? confirm_sure(el) : ''}
|
||||||
|
${modal_close_button}
|
||||||
|
<input class="save-form btn btn-primary" type="submit" value=${(this.confirmation_active) ? "I'm sure." : "Submit"}>
|
||||||
|
</form>`;
|
||||||
|
})(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async checkPasswordsMatch (ev) {
|
||||||
|
let form_data = new FormData(ev.target.form);
|
||||||
|
let password = form_data.get('password');
|
||||||
|
let password_check = form_data.get("password_check");
|
||||||
|
|
||||||
|
if (password != password_check) {
|
||||||
|
this.passwords_mismatched = true;
|
||||||
|
this.confirmation_active = false;
|
||||||
|
} else {
|
||||||
|
this.passwords_mismatched = false;
|
||||||
|
}
|
||||||
|
this.requestUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
async onSubmit (ev) {
|
||||||
|
ev.preventDefault();
|
||||||
|
|
||||||
|
let password = new FormData(ev.target).get('password');
|
||||||
|
let password_check = new FormData(ev.target).get("password_check");
|
||||||
|
|
||||||
|
if (password === password_check) {
|
||||||
|
if (this.confirmation_active) {
|
||||||
|
await this.postNewInfo(password);
|
||||||
|
this.confirmation_active = false;
|
||||||
|
} else {
|
||||||
|
this.confirmation_active = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.passwords_mismatched = true;
|
||||||
|
this.confirmation_active = false;
|
||||||
|
}
|
||||||
|
this.requestUpdate();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async postNewInfo (password) {
|
||||||
|
let domain = Strophe.getDomainFromJid(_converse.bare_jid);
|
||||||
|
let iq = $iq({ 'type': 'get', 'to': domain })
|
||||||
|
.c('query', { 'xmlns': 'jabber:iq:register' });
|
||||||
|
let response = await _converse.api.sendIQ(iq);
|
||||||
|
let username = response.querySelector("username").innerHTML;
|
||||||
|
|
||||||
|
let resetiq = $iq({ 'type': 'set', 'to': domain })
|
||||||
|
.c('query', { 'xmlns': 'jabber:iq:register' })
|
||||||
|
.c('username', {}, username)
|
||||||
|
.c('password', {}, password)
|
||||||
|
|
||||||
|
let iq_result = await _converse.api.sendIQ(resetiq);
|
||||||
|
if (iq_result === null) {
|
||||||
|
api.alert('info', "Password reset failed.", ["Timeout on password reset. Check your connection?"]);
|
||||||
|
} else if (u.isErrorStanza(iq_result)) {
|
||||||
|
api.alert('info', "Permission Denied.", ["Either your former password was incorrect, or you may not change your password."]);
|
||||||
|
} else {
|
||||||
|
api.alert('info', "Password reset.", ["Your password has been reset."]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
api.elements.define("converse-changepassword-profile", Profile);
|
||||||
|
|
@ -3,36 +3,17 @@ import { __ } from 'i18n';
|
|||||||
import { _converse } from "@converse/headless/core";
|
import { _converse } from "@converse/headless/core";
|
||||||
import { html } from "lit";
|
import { html } from "lit";
|
||||||
|
|
||||||
|
|
||||||
|
const passwordreset_page = () => html`
|
||||||
|
<div class="tab-pane" id="passwordreset-tabpanel" role="tabpanel" aria-labelledby="passwordreset-tab">
|
||||||
|
<converse-changepassword-profile></converse-changepassword-profile>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
const omemo_page = (el) => html`
|
const omemo_page = (el) => html`
|
||||||
<div class="tab-pane ${ el.tab === 'omemo' ? 'active' : ''}" id="omemo-tabpanel" role="tabpanel" aria-labelledby="omemo-tab">
|
<div class="tab-pane ${ el.tab === 'omemo' ? 'active' : ''}" id="omemo-tabpanel" role="tabpanel" aria-labelledby="omemo-tab">
|
||||||
<converse-omemo-profile></converse-omemo-profile>
|
<converse-omemo-profile></converse-omemo-profile>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
const navigation = (el) => {
|
|
||||||
const i18n_omemo = __('OMEMO');
|
|
||||||
const i18n_profile = __('Profile');
|
|
||||||
|
|
||||||
return html`<ul class="nav nav-pills justify-content-center">
|
|
||||||
<li role="presentation" class="nav-item">
|
|
||||||
<a class="nav-link ${el.tab === "profile" ? "active" : ""}"
|
|
||||||
id="profile-tab"
|
|
||||||
href="#profile-tabpanel"
|
|
||||||
aria-controls="profile-tabpanel" role="tab"
|
|
||||||
@click=${ev => el.switchTab(ev)}
|
|
||||||
data-name="profile"
|
|
||||||
data-toggle="tab">${i18n_profile}</a>
|
|
||||||
</li>
|
|
||||||
<li role="presentation" class="nav-item">
|
|
||||||
<a class="nav-link ${el.tab === "omemo" ? "active" : ""}"
|
|
||||||
id="omemo-tab"
|
|
||||||
href="#omemo-tabpanel"
|
|
||||||
aria-controls="omemo-tabpanel" role="tab"
|
|
||||||
@click=${ev => el.switchTab(ev)}
|
|
||||||
data-name="omemo"
|
|
||||||
data-toggle="tab">${i18n_omemo}</a>
|
|
||||||
</li>
|
|
||||||
</ul>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default (el) => {
|
export default (el) => {
|
||||||
const o = { ...el.model.toJSON(), ...el.model.vcard.toJSON() };
|
const o = { ...el.model.toJSON(), ...el.model.vcard.toJSON() };
|
||||||
@ -45,8 +26,50 @@ export default (el) => {
|
|||||||
const i18n_role_help = __('Use commas to separate multiple roles. Your roles are shown next to your name on your chat messages.');
|
const i18n_role_help = __('Use commas to separate multiple roles. Your roles are shown next to your name on your chat messages.');
|
||||||
const i18n_url = __('URL');
|
const i18n_url = __('URL');
|
||||||
|
|
||||||
|
const i18n_omemo = __('OMEMO');
|
||||||
|
const i18n_profile = __('Profile');
|
||||||
|
|
||||||
|
const navigation_tabs = [
|
||||||
|
html`<li role="presentation" class="nav-item">
|
||||||
|
<a class="nav-link active"
|
||||||
|
id="profile-tab"
|
||||||
|
href="#profile-tabpanel"
|
||||||
|
aria-controls="profile-tabpanel"
|
||||||
|
role="tab"
|
||||||
|
data-toggle="tab">${i18n_profile}</a>
|
||||||
|
</li>`
|
||||||
|
];
|
||||||
|
|
||||||
|
if (_converse.pluggable.plugins['converse-passwordreset']?.enabled(_converse)) {
|
||||||
|
navigation_tabs.push(
|
||||||
|
html`<li role="presentation" class="nav-item">
|
||||||
|
<a class="nav-link"
|
||||||
|
id="passwordreset-tab"
|
||||||
|
href="#passwordreset-tabpanel"
|
||||||
|
aria-controls="passwordreset-tabpanel"
|
||||||
|
role="tab"
|
||||||
|
data-toggle="tab">Reset Password</a>
|
||||||
|
</li>`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_converse.pluggable.plugins['converse-omemo']?.enabled(_converse)) {
|
||||||
|
navigation_tabs.push(
|
||||||
|
html`<li role="presentation" class="nav-item">
|
||||||
|
<a class="nav-link"
|
||||||
|
id="omemo-tab"
|
||||||
|
href="#omemo-tabpanel"
|
||||||
|
aria-controls="omemo-tabpanel"
|
||||||
|
role="tab" data-toggle="tab">${i18n_omemo}</a>
|
||||||
|
</li>`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't display any navigation tabs if only the profile tab is available
|
||||||
|
const navigation = ((navigation_tabs.length == 1) ? html`` : html`<ul class="nav nav-pills justify-content-center">${navigation_tabs}</ul>`);
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
${_converse.pluggable.plugins['converse-omemo']?.enabled(_converse) ? navigation(el) : ''}
|
${navigation}
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
<div class="tab-pane ${ el.tab === 'profile' ? 'active' : ''}" id="profile-tabpanel" role="tabpanel" aria-labelledby="profile-tab">
|
<div class="tab-pane ${ el.tab === 'profile' ? 'active' : ''}" id="profile-tabpanel" role="tabpanel" aria-labelledby="profile-tab">
|
||||||
<form class="converse-form converse-form--modal profile-form" action="#" @submit=${ev => el.onFormSubmitted(ev)}>
|
<form class="converse-form converse-form--modal profile-form" action="#" @submit=${ev => el.onFormSubmitted(ev)}>
|
||||||
@ -88,7 +111,8 @@ export default (el) => {
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
${ _converse.pluggable.plugins['converse-omemo']?.enabled(_converse) ? omemo_page(el) : '' }
|
${ _converse.pluggable.plugins['converse-passwordreset']?.enabled(_converse) ? passwordreset_page() : '' }
|
||||||
|
${ _converse.pluggable.plugins['converse-omemo']?.enabled(_converse) ? omemo_page() : '' }
|
||||||
</div>
|
</div>
|
||||||
`;
|
</div>`;
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ export const VIEW_PLUGINS = [
|
|||||||
'converse-notification',
|
'converse-notification',
|
||||||
'converse-omemo',
|
'converse-omemo',
|
||||||
'converse-profile',
|
'converse-profile',
|
||||||
|
'converse-passwordreset',
|
||||||
'converse-push',
|
'converse-push',
|
||||||
'converse-register',
|
'converse-register',
|
||||||
'converse-roomslist',
|
'converse-roomslist',
|
||||||
|
Loading…
Reference in New Issue
Block a user