password reset seems to work correctly

This commit is contained in:
or-else
2023-02-01 14:38:57 -08:00
parent aa5e9ef5c7
commit 99c9a698a0
48 changed files with 360 additions and 235 deletions
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+4 -4
View File
@@ -1307,8 +1307,8 @@
"obsolete": false
},
"password_reset_email_sent": {
"translation": "Eine E-Mail wurde an {email} gesendet. Folgen Sie den Anweisungen in der E-Mail, um Ihr Passwort zurückzusetzen.",
"defaultMessage": "An email with security code has been sent to {email}. Enter the code below.",
"translation": "Eine E-Mail mit Sicherheitscode wurde gesendet.",
"defaultMessage": "An email with security code has been sent.",
"description": "Notification that the email with password reset instructions has been sent",
"missing": false,
"obsolete": false
@@ -1586,8 +1586,8 @@
"obsolete": false
},
"password_reset_sms_sent": {
"translation": "Eine Textnachricht mit Sicherheitscode wurde an {phone} gesendet. Geben Sie den Code unten ein.",
"defaultMessage": "A text message with security code has been sent to {phone}. Enter the code below.",
"translation": "Eine SMS mit einem Sicherheitscode wurde gesendet.",
"defaultMessage": "A text message with security code has been sent.",
"description": "Notification that the SMS with password reset instructions has been sent",
"missing": false,
"obsolete": false
+4 -4
View File
@@ -1314,8 +1314,8 @@
"obsolete": false
},
"password_reset_email_sent": {
"translation": "An email has been sent to {email}. Follow the directions in the email to reset your password.",
"defaultMessage": "An email with security code has been sent to {email}. Enter the code below.",
"translation": "An email with security code has been sent.",
"defaultMessage": "An email with security code has been sent.",
"description": "Notification that the email with password reset instructions has been sent",
"missing": false,
"obsolete": false
@@ -1586,8 +1586,8 @@
"obsolete": false
},
"password_reset_sms_sent": {
"translation": "A text message with security code has been sent to {phone}. Enter the code below.",
"defaultMessage": "A text message with security code has been sent to {phone}. Enter the code below.",
"translation": "A text message with security code has been sent.",
"defaultMessage": "A text message with security code has been sent.",
"description": "Notification that the SMS with password reset instructions has been sent",
"missing": false,
"obsolete": false
+4 -4
View File
@@ -1307,8 +1307,8 @@
"obsolete": false
},
"password_reset_email_sent": {
"translation": "Se ha enviado un correo electrónico a {email}. Siga las instrucciones del correo electrónico para restablecer su contraseña.",
"defaultMessage": "An email with security code has been sent to {email}. Enter the code below.",
"translation": "Se ha enviado un correo electrónico con el código de seguridad.",
"defaultMessage": "An email with security code has been sent.",
"description": "Notification that the email with password reset instructions has been sent",
"missing": false,
"obsolete": false
@@ -1586,8 +1586,8 @@
"obsolete": false
},
"password_reset_sms_sent": {
"translation": "Se ha enviado un mensaje de texto con un código de seguridad a {phone}. Ingresa el código a continuación.",
"defaultMessage": "A text message with security code has been sent to {phone}. Enter the code below.",
"translation": "Se ha enviado un mensaje de texto con un código de seguridad.",
"defaultMessage": "A text message with security code has been sent.",
"description": "Notification that the SMS with password reset instructions has been sent",
"missing": false,
"obsolete": false
+2 -2
View File
@@ -689,11 +689,11 @@
"description": "Placeholder/prompt for entering password"
},
"password_reset_email_sent": {
"defaultMessage": "An email with security code has been sent to {email}. Enter the code below.",
"defaultMessage": "An email with security code has been sent.",
"description": "Notification that the email with password reset instructions has been sent"
},
"password_reset_sms_sent": {
"defaultMessage": "A text message with security code has been sent to {phone}. Enter the code below.",
"defaultMessage": "A text message with security code has been sent.",
"description": "Notification that the SMS with password reset instructions has been sent"
},
"password_unchanged_prompt": {
+4 -4
View File
@@ -1314,8 +1314,8 @@
"obsolete": false
},
"password_reset_email_sent": {
"translation": "Un email a été envoyé à {email}. Suivez les instructions du mail pour remettre à zéro votre mot de passe.",
"defaultMessage": "An email with security code has been sent to {email}. Enter the code below.",
"translation": "Un e-mail avec code de sécurité a été envoyé.",
"defaultMessage": "An email with security code has been sent.",
"description": "Notification that the email with password reset instructions has been sent",
"missing": false,
"obsolete": false
@@ -1586,8 +1586,8 @@
"obsolete": false
},
"password_reset_sms_sent": {
"translation": "Un SMS avec un code de sécurité a été envoyé à {phone}. Saisissez le code ci-dessous.",
"defaultMessage": "A text message with security code has been sent to {phone}. Enter the code below.",
"translation": "Un message texte avec un code de sécurité a été envoyé.",
"defaultMessage": "A text message with security code has been sent.",
"description": "Notification that the SMS with password reset instructions has been sent",
"missing": false,
"obsolete": false
+4 -4
View File
@@ -1307,8 +1307,8 @@
"obsolete": false
},
"password_reset_email_sent": {
"translation": "이메일이 {email}(으)로 전송되었습니다. 이메일의 지침에 따라 비밀번호를 재설정하세요.",
"defaultMessage": "An email with security code has been sent to {email}. Enter the code below.",
"translation": "보안 코드가 포함된 이메일이 전송되었습니다.",
"defaultMessage": "An email with security code has been sent.",
"description": "Notification that the email with password reset instructions has been sent",
"missing": false,
"obsolete": false
@@ -1586,8 +1586,8 @@
"obsolete": false
},
"password_reset_sms_sent": {
"translation": "보안 코드가 포함된 문자 메시지가 {phone}로 전송되었습니다. 아래 코드를 입력하세요.",
"defaultMessage": "A text message with security code has been sent to {phone}. Enter the code below.",
"translation": "보안 코드가 포함된 문자 메시지가 전송되었습니다.",
"defaultMessage": "A text message with security code has been sent.",
"description": "Notification that the SMS with password reset instructions has been sent",
"missing": false,
"obsolete": false
+4 -4
View File
@@ -1307,8 +1307,8 @@
"obsolete": false
},
"password_reset_email_sent": {
"translation": "Un e-mail a fost trimis către {email}. Urmați instrucțiunile din e-mail pentru a vă reseta parola.",
"defaultMessage": "An email with security code has been sent to {email}. Enter the code below.",
"translation": "A fost trimis un e-mail cu cod de securitate.",
"defaultMessage": "An email with security code has been sent.",
"description": "Notification that the email with password reset instructions has been sent",
"missing": false,
"obsolete": false
@@ -1586,8 +1586,8 @@
"obsolete": false
},
"password_reset_sms_sent": {
"translation": "Un mesaj text cu cod de securitate a fost trimis la {phone}. Introduceți codul de mai jos.",
"defaultMessage": "A text message with security code has been sent to {phone}. Enter the code below.",
"translation": "A fost trimis un mesaj text cu cod de securitate.",
"defaultMessage": "A text message with security code has been sent.",
"description": "Notification that the SMS with password reset instructions has been sent",
"missing": false,
"obsolete": false
+4 -4
View File
@@ -1307,8 +1307,8 @@
"obsolete": false
},
"password_reset_email_sent": {
"translation": "Сообщение было отправлено на адрес {email}. Следуйте инструкциям в сообщении, чтобы изменить пароль.",
"defaultMessage": "An email with security code has been sent to {email}. Enter the code below.",
"translation": "Сообщение было отправлено на указанный email.",
"defaultMessage": "An email with security code has been sent.",
"description": "Notification that the email with password reset instructions has been sent",
"missing": false,
"obsolete": false
@@ -1586,8 +1586,8 @@
"obsolete": false
},
"password_reset_sms_sent": {
"translation": "SMS с защитным кодом отправлено на {phone}. Введите код ниже.",
"defaultMessage": "A text message with security code has been sent to {phone}. Enter the code below.",
"translation": "SMS с защитным кодом отправлен.",
"defaultMessage": "A text message with security code has been sent.",
"description": "Notification that the SMS with password reset instructions has been sent",
"missing": false,
"obsolete": false
+4 -4
View File
@@ -1307,8 +1307,8 @@
"obsolete": false
},
"password_reset_email_sent": {
"translation": "一封電子郵件已發送至 {email}。按照電子郵件中的說明重置密碼。",
"defaultMessage": "An email with security code has been sent to {email}. Enter the code below.",
"translation": "已發送一封帶有安全代碼的電子郵件。",
"defaultMessage": "An email with security code has been sent.",
"description": "Notification that the email with password reset instructions has been sent",
"missing": false,
"obsolete": false
@@ -1586,8 +1586,8 @@
"obsolete": false
},
"password_reset_sms_sent": {
"translation": "帶有安全碼的短信已發送至{phone}。請在下方輸入密碼。",
"defaultMessage": "A text message with security code has been sent to {phone}. Enter the code below.",
"translation": "已發送帶有安全代碼的短信。",
"defaultMessage": "A text message with security code has been sent.",
"description": "Notification that the SMS with password reset instructions has been sent",
"missing": false,
"obsolete": false
+4 -4
View File
@@ -1307,8 +1307,8 @@
"obsolete": false
},
"password_reset_email_sent": {
"translation": "一封电子邮件已发送至 {email}。按照电子邮件中的说明重置密码。",
"defaultMessage": "An email with security code has been sent to {email}. Enter the code below.",
"translation": "已发送一封带有安全代码的电子邮件。",
"defaultMessage": "An email with security code has been sent.",
"description": "Notification that the email with password reset instructions has been sent",
"missing": false,
"obsolete": false
@@ -1586,8 +1586,8 @@
"obsolete": false
},
"password_reset_sms_sent": {
"translation": "带有安全码的短信已发送至{phone}。请在下方输入密码。",
"defaultMessage": "A text message with security code has been sent to {phone}. Enter the code below.",
"translation": "已发送带有安全代码的短信。",
"defaultMessage": "A text message with security code has been sent.",
"description": "Notification that the SMS with password reset instructions has been sent",
"missing": false,
"obsolete": false
+3 -2
View File
@@ -36,8 +36,9 @@ export default class AccountSettingsView extends React.Component {
val={this.state.credEdit.val}
done={this.state.credEdit.done}
onShowCountrySelector={this.props.onShowCountrySelector}
onSubmit={cred => {this.setState({credEdit: undefined}); console.log("Credential editing done", cred)}}
onCancel={_ => this.setState({credEdit: undefined})} />
onSubmit={this.props.onCredAdd}
onCancel={_ => this.setState({credEdit: undefined})}
onError={this.props.onError} />
);
}
+2 -2
View File
@@ -187,7 +187,7 @@ export default class CreateAccountView extends React.PureComponent {
value={this.state.fn} onChange={this.handleFnChange} required/>
}</FormattedMessage>
</div>
{props.reqCredMethod == 'email' ?
{this.props.reqCredMethod == 'email' ?
<div className="panel-form-row">
<FormattedMessage id="email_prompt" defaultMessage="Email, e.g. jdoe@example.com"
description="Input placeholder for email entry">{
@@ -195,7 +195,7 @@ export default class CreateAccountView extends React.PureComponent {
value={this.state.email} onChange={this.handleEmailChange} required/>
}</FormattedMessage>
</div>
: props.reqCredMethod == 'tel' ?
: this.props.reqCredMethod == 'tel' ?
<><div className="panel-form-row">
<label className="small gray"><FormattedMessage id="mobile_phone_number" defaultMessage="Mobile phone number"
description="Prompt for entering a mobile phone number" /></label>
+29 -20
View File
@@ -1,13 +1,26 @@
// A password reset form.
import React, { Suspense } from 'react';
import { FormattedMessage } from 'react-intl';
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
const PhoneEdit = React.lazy(_ => import('../widgets/phone-edit.jsx'));
import VisiblePassword from '../widgets/visible-password.jsx';
import HashNavigation from '../lib/navigation.js';
export default class PasswordResetView extends React.PureComponent {
const messages = defineMessages({
password_reset_email_sent: {
id: 'password_reset_email_sent',
defaultMessage: 'An email with security code has been sent.',
description: 'Notification that the email with password reset instructions has been sent'
},
password_reset_sms_sent: {
id: 'password_reset_sms_sent',
defaultMessage: 'A text message with security code has been sent.',
description: 'Notification that the SMS with password reset instructions has been sent'
}
});
class PasswordResetView extends React.PureComponent {
constructor(props) {
super(props);
@@ -52,13 +65,22 @@ export default class PasswordResetView extends React.PureComponent {
const cred = this.state.email.trim() || this.state.tel.trim();
this.props.onReset(this.state.password.trim(), {
scheme: 'code',
secret: `${this.state.code}:${this.props.reqCredMethod}:${cred}`
secret: btoa(`${this.state.code}:${this.props.reqCredMethod}:${cred}`)
});
} else {
// Send email or SMS with the secret code.
const email = this.state.email.trim();
const tel = this.state.tel.trim();
this.setState({email: email, tel: tel});
this.props.onRequest(this.props.reqCredMethod, email || tel).then(_ => this.setState({sent: true}));
this.props.onRequest(this.props.reqCredMethod, email || tel)
.then(_ => {
this.setState({sent: true});
const msg = this.props.reqCredMethod == 'email' ? messages.password_reset_email_sent :
this.props.reqCredMethod == 'tel' ? messages.password_reset_sms_sent : null;
if (msg) {
this.props.onError(this.props.intl.formatMessage(msg), 'info');
}
});
}
}
@@ -147,21 +169,6 @@ export default class PasswordResetView extends React.PureComponent {
</div>
</>);
const sentNotification = (<>{
this.props.reqCredMethod == 'email' ?
<FormattedMessage id="password_reset_email_sent"
defaultMessage="An email with security code has been sent to {email}. Enter the code below."
values={{email: <tt>{this.state.email}</tt>}}
description="Notification that the email with password reset instructions has been sent" />
: this.props.reqCredMethod == 'tel' ?
<FormattedMessage id="password_reset_sms_sent"
defaultMessage="A text message with security code has been sent to {phone}. Enter the code below."
values={{phone: <tt>{this.state.tel}</tt>}}
description="Notification that the SMS with password reset instructions has been sent" />
:
null
}</>);
const codeInput = (<>
<div>
<label className="small gray" htmlFor="enter-confirmation-code">
@@ -185,7 +192,7 @@ export default class PasswordResetView extends React.PureComponent {
return (
<form id="password-reset-form" onSubmit={this.handleSubmit}>
{this.state.sent ? sentNotification : showCredentialInput ? credentialInput : null}
{!this.state.sent && showCredentialInput ? credentialInput : null}
{this.state.haveCode || this.state.sent ? codeInput : null}
{showPasswordInput ? passwordInput : null}
<div className="dialog-buttons">
@@ -207,3 +214,5 @@ export default class PasswordResetView extends React.PureComponent {
);
}
}
export default injectIntl(PasswordResetView);
+7 -5
View File
@@ -177,7 +177,11 @@ class SidepanelView extends React.PureComponent {
myUserId={this.props.myUserId}
trustedBadges={this.props.trustedBadges}
onShowCountrySelector={this.props.onShowCountrySelector}
onNavigate={this.props.onNavigate} /> :
onNavigate={this.props.onNavigate}
onCredAdd={this.props.onCredAdd}
onCredDelete={this.props.onCredDelete}
onCredConfirm={this.props.onCredConfirm}
onError={this.props.onError} /> :
(view === 'general' || view === 'crop') ?
<TopicCommonView
@@ -187,9 +191,6 @@ class SidepanelView extends React.PureComponent {
reqCredMethod={this.props.reqCredMethod}
onUpdateTopicDesc={this.props.onUpdateAccountDesc}
onUpdateTagsRequest={this.props.onUpdateAccountTags}
onCredAdd={this.props.onCredAdd}
onCredDelete={this.props.onCredDelete}
onCredConfirm={this.props.onCredConfirm}
onError={this.props.onError} /> :
view === 'notif' ?
@@ -254,7 +255,8 @@ class SidepanelView extends React.PureComponent {
onShowCountrySelector={this.props.onShowCountrySelector}
onRequest={this.props.onPasswordResetRequest}
onReset={this.props.onResetPassword}
onCancel={this.props.onCancel} /> :
onCancel={this.props.onCancel}
onError={this.props.onError} /> :
null}
</div>
);
+4 -4
View File
@@ -24,7 +24,7 @@ class ValidationView extends React.PureComponent {
codeReceived: props.credCode
};
this.handleChange = this.handleChange.bind(this);
this.handleCodeChange = this.handleCodeChange.bind(this);
this.handleKeyPress = this.handleKeyPress.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.handleCancel = this.handleCancel.bind(this);
@@ -56,8 +56,8 @@ class ValidationView extends React.PureComponent {
}
handleChange(e) {
this.setState({code: e.target.value.trim()});
handleCodeChange(e) {
this.setState({code: e.target.value.replace(/[^\d]/g, '')});
}
handleKeyPress(e) {
@@ -99,7 +99,7 @@ class ValidationView extends React.PureComponent {
defaultMessage="Numbers only" description="Prompt for numeric conformation code">{
(numbers_only) => <input type="text" id="enter-confirmation-code"
placeholder={numbers_only}
value={this.state.code} onChange={this.handleChange}
value={this.state.code} onChange={this.handleCodeChange}
onKeyPress={this.handleKeyPress} required />
}</FormattedMessage>
</div>
+114 -52
View File
@@ -1,26 +1,45 @@
// Enter one credential at a time.
import React from 'react';
import { FormattedMessage } from 'react-intl';
import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
import PhoneEdit from './phone-edit.jsx';
import { parsePhoneNumber } from 'libphonenumber-js/mobile';
export default class CredentialEdit extends React.PureComponent {
const messages = defineMessages({
password_reset_email_sent: {
id: 'password_reset_email_sent',
defaultMessage: 'An email with security code has been sent.',
description: 'Notification that the email with password reset instructions has been sent'
},
password_reset_sms_sent: {
id: 'password_reset_sms_sent',
defaultMessage: 'A text message with security code has been sent.',
description: 'Notification that the SMS with password reset instructions has been sent'
},
});
class CredentialEdit extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
code: '',
tel: '',
email: ''
email: '',
sent: false
};
this.handleSubmit = this.handleSubmit.bind(this);
this.handleEmailChange = this.handleEmailChange.bind(this);
this.handlePhoneChange = this.handlePhoneChange.bind(this);
this.handleCodeChange = this.handleCodeChange.bind(this);
}
formatPhoneNumber(raw) {
const number = parsePhoneNumber(raw);
static formatPhoneNumber(raw) {
let number;
try {
number = parsePhoneNumber(raw);
} catch (err) {}
return number ? number.formatInternational() : raw;
}
@@ -29,69 +48,110 @@ export default class CredentialEdit extends React.PureComponent {
}
handlePhoneChange(number) {
console.log("handlePhoneChange", number);
this.setState({tel: number});
}
handleCodeChange(e) {
this.setState({code: e.target.value.replace(/[^\d]/g, '')});
}
handleSubmit(e) {
e.preventDefault();
const value = this.props.method == 'email' ? this.state.email : this.state.tel;
console.log("handleSubmit", value);
if (value) {
this.props.onSubmit(value);
this.props.onSubmit(this.props.method, value);
this.setState({sent: true});
const msg = this.props.method == 'email' ? messages.password_reset_email_sent : messages.password_reset_sms_sent;
this.props.onError(this.props.intl.formatMessage(msg), 'info');
}
}
render() {
return (<form className="panel-form-column" onSubmit={this.handleSubmit}>
{this.props.method == 'email' ?
<><div className="panel-form-row">
<label className="large"><FormattedMessage id="change_email" defaultMessage="Change email"
description="Prompt to change current email" /></label>
</div>
<div className="group">
<label className="small gray">
<FormattedMessage id="current_email" defaultMessage="Current email" description="Label for old email" />
</label>
</div></>
: this.props.method == 'tel' ?
const readyForCode = this.state.sent || !this.props.done;
const currentValue = CredentialEdit.formatPhoneNumber(readyForCode ?
(this.state.tel || this.state.email) : this.props.val);
const currentEmail = (
<><div className="panel-form-row">
<label className="large"><FormattedMessage id="change_phonel" defaultMessage="Change phone number"
description="Prompt to change current phone number"/></label>
</div>
<div className="group">
<label className="small gray">
<FormattedMessage id="current_phone" defaultMessage="Current phone number" description="Label for old phone" />
</label>
</div></>
<label className="large"><FormattedMessage id="change_email" defaultMessage="Change email"
description="Prompt to change current email" /></label>
</div>
<div className="group">
<label className="small gray">
<FormattedMessage id="current_email" defaultMessage="Current email" description="Label for old email" />
</label>
</div></>);
const currentPhone = (
<><div className="panel-form-row">
<label className="large"><FormattedMessage id="change_phonel" defaultMessage="Change phone number"
description="Prompt to change current phone number"/></label>
</div>
<div className="group">
<label className="small gray">
<FormattedMessage id="current_phone" defaultMessage="Current phone number" description="Label for old phone" />
</label>
</div></>
);
const newEmailInput = (
<><div className="group">
<label className="small gray"><FormattedMessage id="new_email" defaultMessage="New email"
description="Prompt for entering a new email" /></label>
</div>
<div className="group">
<FormattedMessage id="email_prompt" defaultMessage="Email, e.g. jdoe@example.com"
description="Input placeholder for email entry">{
(email_prompt) => <input type="email" placeholder={email_prompt} autoComplete="email"
value={this.state.email} onChange={this.handleEmailChange} required/>
}</FormattedMessage>
</div></>
);
const newPhoneInput = (
<><div className="group">
<label className="small gray"><FormattedMessage id="new_phone_number" defaultMessage="New phone number"
description="Prompt for entering a new telephone number" /></label>
</div>
<div className="panel-form-row">
<PhoneEdit
autoFocus={true}
onShowCountrySelector={this.props.onShowCountrySelector}
onSubmit={this.handlePhoneChange} />
</div></>
);
const codeInput = (
<><div className="group">
<label className="small gray"><FormattedMessage id="enter_confirmation_code_prompt" defaultMessage="Confirmation code"
description="Request to enter confirmation code" /></label>
</div>
<div className="group">
<FormattedMessage id="numeric_confirmation_code_prompt" defaultMessage="Numbers only"
description="Prompt for numeric conformation code">{
(numbers_only) => <input type="text" placeholder={numbers_only} maxLength={10}
value={this.state.code} onChange={this.handleCodeChange} required/>
}</FormattedMessage>
</div></>
);
return (<form className="panel-form-column" onSubmit={this.handleSubmit}>
{readyForCode ? null :
this.props.method == 'email' ?
currentEmail
: this.props.method == 'tel' ?
currentPhone
: null}
<div className="panel-form-row">
<tt className="quoted">{this.formatPhoneNumber(this.props.val)}</tt>
<tt className="quoted">{currentValue}</tt>
</div>
{this.props.method == 'email' ?
<><div className="group">
<label className="small gray"><FormattedMessage id="new_email" defaultMessage="New email"
description="Prompt for entering a new email" /></label>
</div>
<div className="group">
<FormattedMessage id="email_prompt" defaultMessage="Email, e.g. jdoe@example.com"
description="Input placeholder for email entry">{
(email_prompt) => <input type="email" placeholder={email_prompt} autoComplete="email"
value={this.state.email} onChange={this.handleEmailChange} required/>
}</FormattedMessage>
</div></>
: this.props.method == 'tel' ?
<><div className="group">
<label className="small gray"><FormattedMessage id="new_phone_number" defaultMessage="New phone number"
description="Prompt for entering a new telephone number" /></label>
</div>
<div className="panel-form-row">
<PhoneEdit
autoFocus={true}
onShowCountrySelector={this.props.onShowCountrySelector}
onSubmit={this.handlePhoneChange} />
</div></>
{readyForCode ? null :
this.props.method == 'email' ?
newEmailInput
: this.props.method == 'tel' ?
newPhoneInput
: null}
{readyForCode ? codeInput : null}
<div className="dialog-buttons">
<button className="secondary" onClick={this.props.onCancel}>
<FormattedMessage id="button_cancel" defaultMessage="Cancel" description="Button [Cancel]" />
@@ -103,3 +163,5 @@ export default class CredentialEdit extends React.PureComponent {
</form>);
}
}
export default injectIntl(CredentialEdit);
+2
View File
@@ -55,6 +55,8 @@ class PhoneEdit extends React.PureComponent {
this.inputField.setCustomValidity(this.props.intl.formatMessage(messages.mobile_number_required));
return;
}
this.inputField.setCustomValidity('');
this.props.onSubmit(number.format('E.164'));
}
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+131 -82
View File
@@ -4043,13 +4043,6 @@ class AccountSettingsView extends (react__WEBPACK_IMPORTED_MODULE_0___default().
credentials: me.getCredentials() || [],
credEdit: undefined
};
this.handleEditCred = this.handleEditCred.bind(this);
}
handleEditCred(cred) {
console.log("Start editing cred", cred);
this.setState({
credEdit: cred
});
}
render() {
if (this.state.credEdit) {
@@ -4058,15 +4051,11 @@ class AccountSettingsView extends (react__WEBPACK_IMPORTED_MODULE_0___default().
val: this.state.credEdit.val,
done: this.state.credEdit.done,
onShowCountrySelector: this.props.onShowCountrySelector,
onSubmit: cred => {
this.setState({
credEdit: undefined
});
console.log("Credential editing done", cred);
},
onSubmit: this.props.onCredAdd,
onCancel: _ => this.setState({
credEdit: undefined
})
}),
onError: this.props.onError
});
}
const credentials = [];
@@ -4086,7 +4075,9 @@ class AccountSettingsView extends (react__WEBPACK_IMPORTED_MODULE_0___default().
className: "clickable",
onClick: e => {
e.preventDefault();
this.handleEditCred(cred);
this.setState({
credEdit: cred
});
}
}, val), react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, " ", cred.done ? null : react__WEBPACK_IMPORTED_MODULE_0___default().createElement("i", {
className: "material-icons"
@@ -4588,7 +4579,7 @@ class CreateAccountView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Pu
value: this.state.fn,
onChange: this.handleFnChange,
required: true
}))), props.reqCredMethod == 'email' ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
}))), this.props.reqCredMethod == 'email' ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "panel-form-row"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, {
id: "email_prompt",
@@ -4603,7 +4594,7 @@ class CreateAccountView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Pu
value: this.state.email,
onChange: this.handleEmailChange,
required: true
}))) : props.reqCredMethod == 'tel' ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
}))) : this.props.reqCredMethod == 'tel' ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "panel-form-row"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("label", {
className: "small gray"
@@ -7227,7 +7218,7 @@ class NewTopicView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Compone
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (/* binding */ PasswordResetView)
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react");
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
@@ -7240,6 +7231,22 @@ __webpack_require__.r(__webpack_exports__);
const PhoneEdit = react__WEBPACK_IMPORTED_MODULE_0___default().lazy(_ => Promise.resolve(/*! import() */).then(__webpack_require__.bind(__webpack_require__, /*! ../widgets/phone-edit.jsx */ "./src/widgets/phone-edit.jsx")));
const messages = (0,react_intl__WEBPACK_IMPORTED_MODULE_1__.defineMessages)({
password_reset_email_sent: {
id: "password_reset_email_sent",
defaultMessage: [{
"type": 0,
"value": "An email with security code has been sent."
}]
},
password_reset_sms_sent: {
id: "password_reset_sms_sent",
defaultMessage: [{
"type": 0,
"value": "A text message with security code has been sent."
}]
}
});
class PasswordResetView extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComponent) {
constructor(props) {
super(props);
@@ -7278,7 +7285,7 @@ class PasswordResetView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Pu
const cred = this.state.email.trim() || this.state.tel.trim();
this.props.onReset(this.state.password.trim(), {
scheme: 'code',
secret: `${this.state.code}:${this.props.reqCredMethod}:${cred}`
secret: btoa(`${this.state.code}:${this.props.reqCredMethod}:${cred}`)
});
} else {
const email = this.state.email.trim();
@@ -7287,9 +7294,15 @@ class PasswordResetView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Pu
email: email,
tel: tel
});
this.props.onRequest(this.props.reqCredMethod, email || tel).then(_ => this.setState({
sent: true
}));
this.props.onRequest(this.props.reqCredMethod, email || tel).then(_ => {
this.setState({
sent: true
});
const msg = this.props.reqCredMethod == 'email' ? messages.password_reset_email_sent : this.props.reqCredMethod == 'tel' ? messages.password_reset_sms_sent : null;
if (msg) {
this.props.onError(this.props.intl.formatMessage(msg), 'info');
}
});
}
}
handleEmailChange(e) {
@@ -7397,37 +7410,6 @@ class PasswordResetView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Pu
tel: number
})
}))));
const sentNotification = react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, this.props.reqCredMethod == 'email' ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, {
id: "password_reset_email_sent",
defaultMessage: [{
"type": 0,
"value": "An email with security code has been sent to "
}, {
"type": 1,
"value": "email"
}, {
"type": 0,
"value": ". Enter the code below."
}],
values: {
email: react__WEBPACK_IMPORTED_MODULE_0___default().createElement("tt", null, this.state.email)
}
}) : this.props.reqCredMethod == 'tel' ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, {
id: "password_reset_sms_sent",
defaultMessage: [{
"type": 0,
"value": "A text message with security code has been sent to "
}, {
"type": 1,
"value": "phone"
}, {
"type": 0,
"value": ". Enter the code below."
}],
values: {
phone: react__WEBPACK_IMPORTED_MODULE_0___default().createElement("tt", null, this.state.tel)
}
}) : null);
const codeInput = react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("label", {
className: "small gray",
htmlFor: "enter-confirmation-code"
@@ -7456,7 +7438,7 @@ class PasswordResetView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Pu
return react__WEBPACK_IMPORTED_MODULE_0___default().createElement("form", {
id: "password-reset-form",
onSubmit: this.handleSubmit
}, this.state.sent ? sentNotification : showCredentialInput ? credentialInput : null, this.state.haveCode || this.state.sent ? codeInput : null, showPasswordInput ? passwordInput : null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
}, !this.state.sent && showCredentialInput ? credentialInput : null, this.state.haveCode || this.state.sent ? codeInput : null, showPasswordInput ? passwordInput : null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "dialog-buttons"
}, this.state.haveCode || this.state.sent ? null : react__WEBPACK_IMPORTED_MODULE_0___default().createElement("a", {
href: "#",
@@ -7488,6 +7470,7 @@ class PasswordResetView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Pu
}))));
}
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ((0,react_intl__WEBPACK_IMPORTED_MODULE_1__.injectIntl)(PasswordResetView));
/***/ }),
@@ -7854,7 +7837,11 @@ class SidepanelView extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCo
myUserId: this.props.myUserId,
trustedBadges: this.props.trustedBadges,
onShowCountrySelector: this.props.onShowCountrySelector,
onNavigate: this.props.onNavigate
onNavigate: this.props.onNavigate,
onCredAdd: this.props.onCredAdd,
onCredDelete: this.props.onCredDelete,
onCredConfirm: this.props.onCredConfirm,
onError: this.props.onError
}) : view === 'general' || view === 'crop' ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_topic_common_view_jsx__WEBPACK_IMPORTED_MODULE_5__["default"], {
topic: "me",
tinode: this.props.tinode,
@@ -7862,9 +7849,6 @@ class SidepanelView extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCo
reqCredMethod: this.props.reqCredMethod,
onUpdateTopicDesc: this.props.onUpdateAccountDesc,
onUpdateTagsRequest: this.props.onUpdateAccountTags,
onCredAdd: this.props.onCredAdd,
onCredDelete: this.props.onCredDelete,
onCredConfirm: this.props.onCredConfirm,
onError: this.props.onError
}) : view === 'notif' ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_acc_notifications_view_jsx__WEBPACK_IMPORTED_MODULE_9__["default"], {
messageSounds: this.props.messageSounds,
@@ -7915,7 +7899,8 @@ class SidepanelView extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCo
onShowCountrySelector: this.props.onShowCountrySelector,
onRequest: this.props.onPasswordResetRequest,
onReset: this.props.onResetPassword,
onCancel: this.props.onCancel
onCancel: this.props.onCancel,
onError: this.props.onError
}) : null);
}
}
@@ -9978,7 +9963,7 @@ class ValidationView extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureC
code: props.credCode || '',
codeReceived: props.credCode
};
this.handleChange = this.handleChange.bind(this);
this.handleCodeChange = this.handleCodeChange.bind(this);
this.handleKeyPress = this.handleKeyPress.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.handleCancel = this.handleCancel.bind(this);
@@ -10002,9 +9987,9 @@ class ValidationView extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureC
this.props.onSubmit(this.props.credMethod, this.state.code, this.props.credToken);
}
}
handleChange(e) {
handleCodeChange(e) {
this.setState({
code: e.target.value.trim()
code: e.target.value.replace(/[^\d]/g, '')
});
}
handleKeyPress(e) {
@@ -10062,7 +10047,7 @@ class ValidationView extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureC
id: "enter-confirmation-code",
placeholder: numbers_only,
value: this.state.code,
onChange: this.handleChange,
onChange: this.handleCodeChange,
onKeyPress: this.handleKeyPress,
required: true
}))), react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
@@ -13127,7 +13112,7 @@ class ContextMenu extends (react__WEBPACK_IMPORTED_MODULE_0___default().Componen
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (/* binding */ CredentialEdit)
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react");
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
@@ -13139,19 +13124,41 @@ __webpack_require__.r(__webpack_exports__);
const messages = (0,react_intl__WEBPACK_IMPORTED_MODULE_1__.defineMessages)({
password_reset_email_sent: {
id: "password_reset_email_sent",
defaultMessage: [{
"type": 0,
"value": "An email with security code has been sent."
}]
},
password_reset_sms_sent: {
id: "password_reset_sms_sent",
defaultMessage: [{
"type": 0,
"value": "A text message with security code has been sent."
}]
}
});
class CredentialEdit extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComponent) {
constructor(props) {
super(props);
this.state = {
code: '',
tel: '',
email: ''
email: '',
sent: false
};
this.handleSubmit = this.handleSubmit.bind(this);
this.handleEmailChange = this.handleEmailChange.bind(this);
this.handlePhoneChange = this.handlePhoneChange.bind(this);
this.handleCodeChange = this.handleCodeChange.bind(this);
}
formatPhoneNumber(raw) {
const number = (0,libphonenumber_js_mobile__WEBPACK_IMPORTED_MODULE_3__.parsePhoneNumberWithError)(raw);
static formatPhoneNumber(raw) {
let number;
try {
number = (0,libphonenumber_js_mobile__WEBPACK_IMPORTED_MODULE_3__.parsePhoneNumberWithError)(raw);
} catch (err) {}
return number ? number.formatInternational() : raw;
}
handleEmailChange(e) {
@@ -13160,24 +13167,31 @@ class CredentialEdit extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureC
});
}
handlePhoneChange(number) {
console.log("handlePhoneChange", number);
this.setState({
tel: number
});
}
handleCodeChange(e) {
this.setState({
code: e.target.value.replace(/[^\d]/g, '')
});
}
handleSubmit(e) {
e.preventDefault();
const value = this.props.method == 'email' ? this.state.email : this.state.tel;
console.log("handleSubmit", value);
if (value) {
this.props.onSubmit(value);
this.props.onSubmit(this.props.method, value);
this.setState({
sent: true
});
const msg = this.props.method == 'email' ? messages.password_reset_email_sent : messages.password_reset_sms_sent;
this.props.onError(this.props.intl.formatMessage(msg), 'info');
}
}
render() {
return react__WEBPACK_IMPORTED_MODULE_0___default().createElement("form", {
className: "panel-form-column",
onSubmit: this.handleSubmit
}, this.props.method == 'email' ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
const readyForCode = this.state.sent || !this.props.done;
const currentValue = CredentialEdit.formatPhoneNumber(readyForCode ? this.state.tel || this.state.email : this.props.val);
const currentEmail = react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "panel-form-row"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("label", {
className: "large"
@@ -13197,7 +13211,8 @@ class CredentialEdit extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureC
"type": 0,
"value": "Current email"
}]
})))) : this.props.method == 'tel' ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
}))));
const currentPhone = react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "panel-form-row"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("label", {
className: "large"
@@ -13217,11 +13232,8 @@ class CredentialEdit extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureC
"type": 0,
"value": "Current phone number"
}]
})))) : null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "panel-form-row"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("tt", {
className: "quoted"
}, this.formatPhoneNumber(this.props.val))), this.props.method == 'email' ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
}))));
const newEmailInput = react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "group"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("label", {
className: "small gray"
@@ -13246,7 +13258,8 @@ class CredentialEdit extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureC
value: this.state.email,
onChange: this.handleEmailChange,
required: true
})))) : this.props.method == 'tel' ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
}))));
const newPhoneInput = react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "group"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("label", {
className: "small gray"
@@ -13262,7 +13275,41 @@ class CredentialEdit extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureC
autoFocus: true,
onShowCountrySelector: this.props.onShowCountrySelector,
onSubmit: this.handlePhoneChange
}))) : null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
})));
const codeInput = react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "group"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("label", {
className: "small gray"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, {
id: "enter_confirmation_code_prompt",
defaultMessage: [{
"type": 0,
"value": "Confirmation code"
}]
}))), react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "group"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, {
id: "numeric_confirmation_code_prompt",
defaultMessage: [{
"type": 0,
"value": "Numbers only"
}]
}, numbers_only => react__WEBPACK_IMPORTED_MODULE_0___default().createElement("input", {
type: "text",
placeholder: numbers_only,
maxLength: 10,
value: this.state.code,
onChange: this.handleCodeChange,
required: true
}))));
return react__WEBPACK_IMPORTED_MODULE_0___default().createElement("form", {
className: "panel-form-column",
onSubmit: this.handleSubmit
}, readyForCode ? null : this.props.method == 'email' ? currentEmail : this.props.method == 'tel' ? currentPhone : null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "panel-form-row"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("tt", {
className: "quoted"
}, currentValue)), readyForCode ? null : this.props.method == 'email' ? newEmailInput : this.props.method == 'tel' ? newPhoneInput : null, readyForCode ? codeInput : null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "dialog-buttons"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", {
className: "secondary",
@@ -13285,6 +13332,7 @@ class CredentialEdit extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureC
}))));
}
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ((0,react_intl__WEBPACK_IMPORTED_MODULE_1__.injectIntl)(CredentialEdit));
/***/ }),
@@ -15627,6 +15675,7 @@ class PhoneEdit extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCompon
this.inputField.setCustomValidity(this.props.intl.formatMessage(messages.mobile_number_required));
return;
}
this.inputField.setCustomValidity('');
this.props.onSubmit(number.format('E.164'));
}
handleKeyDown(e) {
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long