Forráskód Böngészése

Reworked profile modal; Added rudimentary password reset plugin

based-a-tron 2 éve
szülő
commit
fa132567da

+ 131 - 0
src/plugins/password-reset/index.js

@@ -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);
+

+ 52 - 28
src/plugins/profile/templates/profile_modal.js

@@ -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>`;
 }
 }

+ 1 - 0
src/shared/constants.js

@@ -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',