feat(GODT-2772): new login layout.

This commit is contained in:
Xavier Michelon
2023-08-21 13:34:16 +02:00
parent 81afc5fb1f
commit 6e86c95640
14 changed files with 920 additions and 882 deletions

View File

@ -400,7 +400,7 @@ Status GRPCService::Login(ServerContext *, LoginRequest const *request, Empty *)
return Status::OK;
}
if (usersTab.nextUserTwoPasswordsRequired()) {
qtProxy_.sendDelayedEvent(newLoginTwoPasswordsRequestedEvent());
qtProxy_.sendDelayedEvent(newLoginTwoPasswordsRequestedEvent(loginUsername_));
return Status::OK;
}
@ -425,7 +425,7 @@ Status GRPCService::Login2FA(ServerContext *, LoginRequest const *request, Empty
return Status::OK;
}
if (usersTab.nextUserTwoPasswordsRequired()) {
qtProxy_.sendDelayedEvent(newLoginTwoPasswordsRequestedEvent());
qtProxy_.sendDelayedEvent(newLoginTwoPasswordsRequestedEvent(loginUsername_));
return Status::OK;
}

View File

@ -233,7 +233,7 @@ signals: // Signals received from the Go backend, to be forwarded to QML
void login2FARequested(QString const &username); ///< Signal for the 'login2FARequested' gRPC stream event.
void login2FAError(QString const &errorMsg); ///< Signal for the 'login2FAError' gRPC stream event.
void login2FAErrorAbort(QString const &errorMsg); ///< Signal for the 'login2FAErrorAbort' gRPC stream event.
void login2PasswordRequested(); ///< Signal for the 'login2PasswordRequested' gRPC stream event.
void login2PasswordRequested(QString const &username); ///< Signal for the 'login2PasswordRequested' gRPC stream event.
void login2PasswordError(QString const &errorMsg); ///< Signal for the 'login2PasswordError' gRPC stream event.
void login2PasswordErrorAbort(QString const &errorMsg); ///< Signal for the 'login2PasswordErrorAbort' gRPC stream event.
void loginFinished(int index, bool wasSignedOut); ///< Signal for the 'loginFinished' gRPC stream event.

View File

@ -45,33 +45,16 @@ Item {
icon.source = "/qml/icons/img-mail-clients.svg";
}
function showLogin() {
descriptionLabel.text = qsTr("Let's start by signing in to your Proton account.");
linkLabel1.setLink("https://proton.me/mail/pricing", qsTr("Create or upgrade your account"));
linkLabel2.clear();
showLoginCommon();
}
showOnboarding()
}
function showLogin2FA() {
descriptionLabel.text = qsTr("You have enabled two-factor authentication. Please enter the 6-digit code provided by your authenticator application.");
linkLabel1.clear();
linkLabel2.clear();
showLoginCommon();
}
function showLoginCommon() {
titleLabel.text = qsTr("Sign in to your Proton Account");
icon.Layout.preferredHeight = 72;
icon.Layout.preferredWidth = 72;
icon.source = "/qml/icons/ic-bridge.svg";
icon.sourceSize.height = 128;
icon.sourceSize.width = 128;
showOnboarding()
}
function showLoginMailboxPassword() {
descriptionLabel.text = qsTr("You have secured your account with a separate mailbox password.");
linkLabel1.clear();
linkLabel2.clear();
showLoginCommon();
showOnboarding()
}
function showOnboarding() {
titleLabel.text = qsTr("Welcome to\nProton Mail Bridge");
titleLabel.text = (Backend.users.count === 0) ? qsTr("Welcome to\nProton Mail Bridge") : qsTr("Add a Proton Mail account");
descriptionLabel.text = qsTr("Bridge is the gateway between your Proton account and your email client. It runs in the background and encrypts and decrypts your messages seamlessly. ");
linkLabel1.setLink("https://proton.me/support/bridge", qsTr("Why do I need Bridge?"));
linkLabel2.clear();
@ -81,11 +64,6 @@ Item {
icon.sourceSize.height = 148;
icon.sourceSize.width = 265;
}
function showOutlookSelector() {
showClientConfigCommon();
linkLabel1.setLink("https://proton.me/support/bridge", qsTr("My version of Outlook is not listed"));
linkLabel2.clear();
}
Connections {
function onLogin2FARequested() {

View File

@ -43,9 +43,6 @@ FocusScope {
mailboxPasswordLayout.reset();
}
implicitHeight: children[0].implicitHeight
implicitWidth: children[0].implicitWidth
StackLayout {
id: stackLayout
function loginFailed() {
@ -91,9 +88,10 @@ FocusScope {
root.reset();
errorLabel.text = qsTr("Incorrect login credentials. Please try again.");
}
function onLogin2PasswordRequested() {
function onLogin2PasswordRequested(username) {
console.assert(stackLayout.currentIndex === Login.RootStack.Login || stackLayout.currentIndex === Login.RootStack.TOTP, "Unexpected login2PasswordRequested");
stackLayout.currentIndex = Login.RootStack.MailboxPassword;
mailboxPasswordUsernameLabel.text = username;
secondPasswordTextField.focus = true;
}
function onLoginAlreadyLoggedIn(_) {
@ -124,299 +122,353 @@ FocusScope {
target: Backend
}
ColumnLayout {
id: loginLayout
function reset(clearUsername = false) {
signInButton.loading = false;
errorLabel.text = "";
usernameTextField.enabled = true;
usernameTextField.error = false;
usernameTextField.errorString = "";
usernameTextField.focus = true;
if (clearUsername) {
usernameTextField.text = "";
Item {
ColumnLayout {
id: loginLayout
function reset(clearUsername = false) {
signInButton.loading = false;
errorLabel.text = "";
usernameTextField.enabled = true;
usernameTextField.error = false;
usernameTextField.errorString = "";
usernameTextField.focus = true;
if (clearUsername) {
usernameTextField.text = "";
}
passwordTextField.enabled = true;
passwordTextField.error = false;
passwordTextField.errorString = "";
passwordTextField.text = "";
}
passwordTextField.enabled = true;
passwordTextField.error = false;
passwordTextField.errorString = "";
passwordTextField.text = "";
}
spacing: 0
anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
spacing: 16
Label {
Layout.alignment: Qt.AlignHCenter
colorScheme: wizard.colorScheme
text: qsTr("Sign in")
type: Label.LabelType.Heading
}
Label {
id: subTitle
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: 8
color: wizard.colorScheme.text_weak
colorScheme: wizard.colorScheme
text: qsTr("Enter your Proton Account details.")
type: Label.LabelType.Lead
}
RowLayout {
Layout.fillWidth: true
Layout.topMargin: 48
spacing: 0
visible: errorLabel.text.length > 0
ColumnLayout {
Layout.fillWidth: true
spacing: 8
ColorImage {
color: wizard.colorScheme.signal_danger
height: errorLabel.lineHeight
source: "/qml/icons/ic-exclamation-circle-filled.svg"
sourceSize.height: errorLabel.lineHeight
Label {
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
colorScheme: wizard.colorScheme
horizontalAlignment: Text.AlignHCenter
text: qsTr("Sign in")
type: Label.LabelType.Title
}
Label {
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
color: wizard.colorScheme.text_weak
colorScheme: wizard.colorScheme
horizontalAlignment: Text.AlignHCenter
text: qsTr("Enter your Proton Account details.")
type: Label.LabelType.Body
}
}
RowLayout {
Layout.fillWidth: true
spacing: 0
visible: errorLabel.text.length > 0
ColorImage {
color: wizard.colorScheme.signal_danger
height: errorLabel.lineHeight
source: "/qml/icons/ic-exclamation-circle-filled.svg"
sourceSize.height: errorLabel.lineHeight
}
Label {
id: errorLabel
Layout.fillWidth: true
Layout.leftMargin: 4
color: wizard.colorScheme.signal_danger
colorScheme: wizard.colorScheme
type: root.error ? Label.LabelType.Caption_semibold : Label.LabelType.Caption
wrapMode: Text.WordWrap
}
}
TextField {
id: usernameTextField
Layout.fillWidth: true
colorScheme: wizard.colorScheme
focus: true
label: qsTr("Email or username")
validateOnEditingFinished: false
validator: function (str) {
if (str.length === 0) {
return qsTr("Enter email or username");
}
}
onAccepted: passwordTextField.forceActiveFocus()
onTextChanged: {
// remove "invalid username / password error"
if (error || errorLabel.text.length > 0) {
errorLabel.text = "";
usernameTextField.error = false;
passwordTextField.error = false;
}
}
}
TextField {
id: passwordTextField
Layout.fillWidth: true
colorScheme: wizard.colorScheme
echoMode: TextInput.Password
label: qsTr("Password")
validateOnEditingFinished: false
validator: function (str) {
if (str.length === 0) {
return qsTr("Enter password");
}
}
onAccepted: signInButton.checkAndSignIn()
onTextChanged: {
// remove "invalid username / password error"
if (error || errorLabel.text.length > 0) {
errorLabel.text = "";
usernameTextField.error = false;
passwordTextField.error = false;
}
}
}
Button {
id: signInButton
function checkAndSignIn() {
usernameTextField.validate();
passwordTextField.validate();
if (usernameTextField.error || passwordTextField.error) {
return;
}
usernameTextField.enabled = false;
passwordTextField.enabled = false;
loading = true;
Backend.login(usernameTextField.text, Qt.btoa(passwordTextField.text));
}
Layout.fillWidth: true
colorScheme: wizard.colorScheme
enabled: !loading
text: loading ? qsTr("Signing in") : qsTr("Sign in")
onClicked: {
checkAndSignIn();
}
}
Button {
Layout.fillWidth: true
colorScheme: wizard.colorScheme
enabled: !signInButton.loading
secondary: true
text: qsTr("Cancel")
onClicked: {
root.abort();
}
}
LinkLabel {
id: linkLabel
Layout.alignment: Qt.AlignHCenter
colorScheme: wizard.colorScheme
text: linkLabel.link("https://proton.me/mail/pricing", qsTr("Create or upgrade your account"))
}
}
}
Item {
ColumnLayout {
id: totpLayout
function reset() {
twoFAButton.loading = false;
twoFactorPasswordTextField.enabled = true;
twoFactorPasswordTextField.error = false;
twoFactorPasswordTextField.errorString = "";
twoFactorPasswordTextField.text = "";
}
anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
spacing: 16
ColumnLayout {
Layout.fillWidth: true
spacing: 8
Label {
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
colorScheme: wizard.colorScheme
horizontalAlignment: Text.AlignHCenter
text: qsTr("Two-factor authentication")
type: Label.LabelType.Title
}
Label {
id: twoFactorUsernameLabel
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
color: wizard.colorScheme.text_weak
colorScheme: wizard.colorScheme
horizontalAlignment: Text.AlignHCenter
text: ""
type: Label.LabelType.Body
}
}
Label {
id: errorLabel
id: descriptionLabel
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
Layout.leftMargin: 4
color: wizard.colorScheme.signal_danger
colorScheme: wizard.colorScheme
type: root.error ? Label.LabelType.Caption_semibold : Label.LabelType.Caption
horizontalAlignment: Text.AlignHCenter
text: qsTr("You have enabled two-factor authentication. Please enter the 6-digit code provided by your authenticator application.")
type: Label.LabelType.Body
wrapMode: Text.WordWrap
}
}
TextField {
id: usernameTextField
Layout.fillWidth: true
Layout.topMargin: 48
colorScheme: wizard.colorScheme
focus: true
label: qsTr("Email or username")
validateOnEditingFinished: false
validator: function (str) {
if (str.length === 0) {
return qsTr("Enter email or username");
TextField {
id: twoFactorPasswordTextField
Layout.fillWidth: true
colorScheme: wizard.colorScheme
label: qsTr("Two-factor code")
validateOnEditingFinished: false
validator: function (str) {
if (str.length === 0) {
return qsTr("Enter the 6-digit code");
}
}
}
onAccepted: passwordTextField.forceActiveFocus()
onTextChanged: {
// remove "invalid username / password error"
if (error || errorLabel.text.length > 0) {
errorLabel.text = "";
usernameTextField.error = false;
passwordTextField.error = false;
}
}
}
TextField {
id: passwordTextField
Layout.fillWidth: true
Layout.topMargin: 48
colorScheme: wizard.colorScheme
echoMode: TextInput.Password
label: qsTr("Password")
validateOnEditingFinished: false
validator: function (str) {
if (str.length === 0) {
return qsTr("Enter password");
}
}
onAccepted: signInButton.checkAndSignIn()
onTextChanged: {
// remove "invalid username / password error"
if (error || errorLabel.text.length > 0) {
errorLabel.text = "";
usernameTextField.error = false;
passwordTextField.error = false;
}
}
}
Button {
id: signInButton
function checkAndSignIn() {
usernameTextField.validate();
passwordTextField.validate();
if (usernameTextField.error || passwordTextField.error) {
return;
}
usernameTextField.enabled = false;
passwordTextField.enabled = false;
loading = true;
Backend.login(usernameTextField.text, Qt.btoa(passwordTextField.text));
}
Layout.fillWidth: true
Layout.topMargin: 48
colorScheme: wizard.colorScheme
enabled: !loading
text: loading ? qsTr("Signing in") : qsTr("Sign in")
onClicked: {
checkAndSignIn();
}
}
Button {
Layout.fillWidth: true
Layout.topMargin: 32
colorScheme: wizard.colorScheme
enabled: !signInButton.loading
secondary: true
text: qsTr("Cancel")
onClicked: {
root.abort();
}
}
}
ColumnLayout {
id: totpLayout
function reset() {
twoFAButton.loading = false;
twoFactorPasswordTextField.enabled = true;
twoFactorPasswordTextField.error = false;
twoFactorPasswordTextField.errorString = "";
twoFactorPasswordTextField.text = "";
}
spacing: 0
Label {
Layout.alignment: Qt.AlignCenter
colorScheme: wizard.colorScheme
text: qsTr("Two-factor authentication")
type: Label.LabelType.Heading
}
Label {
id: twoFactorUsernameLabel
Layout.alignment: Qt.AlignCenter
Layout.topMargin: 8
color: wizard.colorScheme.text_weak
colorScheme: wizard.colorScheme
type: Label.LabelType.Lead
}
TextField {
id: twoFactorPasswordTextField
Layout.fillWidth: true
Layout.topMargin: 32
assistiveText: qsTr("Enter the 6-digit code")
colorScheme: wizard.colorScheme
label: qsTr("Two-factor code")
validateOnEditingFinished: false
validator: function (str) {
if (str.length === 0) {
return qsTr("Enter the 6-digit code");
}
}
onAccepted: {
twoFAButton.onClicked();
}
onTextChanged: {
if (text.length >= 6) {
onAccepted: {
twoFAButton.onClicked();
}
}
}
Button {
id: twoFAButton
Layout.fillWidth: true
Layout.topMargin: 48
colorScheme: wizard.colorScheme
enabled: !loading
text: loading ? qsTr("Authenticating") : qsTr("Authenticate")
onClicked: {
twoFactorPasswordTextField.validate();
if (twoFactorPasswordTextField.error) {
return;
onTextChanged: {
if (text.length >= 6) {
twoFAButton.onClicked();
}
}
twoFactorPasswordTextField.enabled = false;
loading = true;
Backend.login2FA(usernameTextField.text, Qt.btoa(twoFactorPasswordTextField.text));
}
}
Button {
Layout.fillWidth: true
Layout.topMargin: 32
colorScheme: wizard.colorScheme
enabled: !twoFAButton.loading
secondary: true
text: qsTr("Cancel")
Button {
id: twoFAButton
Layout.fillWidth: true
colorScheme: wizard.colorScheme
enabled: !loading
text: loading ? qsTr("Authenticating") : qsTr("Authenticate")
onClicked: {
root.abort();
onClicked: {
twoFactorPasswordTextField.validate();
if (twoFactorPasswordTextField.error) {
return;
}
twoFactorPasswordTextField.enabled = false;
loading = true;
Backend.login2FA(usernameTextField.text, Qt.btoa(twoFactorPasswordTextField.text));
}
}
Button {
Layout.fillWidth: true
colorScheme: wizard.colorScheme
enabled: !twoFAButton.loading
secondary: true
text: qsTr("Cancel")
onClicked: {
root.abort();
}
}
}
}
ColumnLayout {
id: mailboxPasswordLayout
function reset() {
secondPasswordButton.loading = false;
secondPasswordTextField.enabled = true;
secondPasswordTextField.error = false;
secondPasswordTextField.errorString = "";
secondPasswordTextField.text = "";
}
Item {
ColumnLayout {
id: mailboxPasswordLayout
function reset() {
secondPasswordButton.loading = false;
secondPasswordTextField.enabled = true;
secondPasswordTextField.error = false;
secondPasswordTextField.errorString = "";
secondPasswordTextField.text = "";
}
spacing: 0
anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
spacing: 16
Label {
Layout.alignment: Qt.AlignCenter
colorScheme: wizard.colorScheme
text: qsTr("Unlock your mailbox")
type: Label.LabelType.Heading
}
Label {
Layout.alignment: Qt.AlignCenter
Layout.topMargin: 8
color: wizard.colorScheme.text_weak
colorScheme: wizard.colorScheme
type: Label.LabelType.Lead
}
TextField {
id: secondPasswordTextField
Layout.fillWidth: true
Layout.topMargin: 48
colorScheme: wizard.colorScheme
echoMode: TextInput.Password
label: qsTr("Mailbox password")
validateOnEditingFinished: false
validator: function (str) {
if (str.length === 0) {
return qsTr("Enter password");
ColumnLayout {
Layout.fillWidth: true
spacing: 8
Label {
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
colorScheme: wizard.colorScheme
horizontalAlignment: Text.AlignHCenter
text: qsTr("Unlock your mailbox")
type: Label.LabelType.Title
}
Label {
id: mailboxPasswordUsernameLabel
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
color: wizard.colorScheme.text_weak
colorScheme: wizard.colorScheme
horizontalAlignment: Text.AlignHCenter
text: ""
type: Label.LabelType.Body
}
}
onAccepted: {
secondPasswordButton.onClicked();
Label {
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
colorScheme: wizard.colorScheme
horizontalAlignment: Text.AlignHCenter
text: qsTr("You have secured your account with a separate mailbox password.")
type: Label.LabelType.Body
wrapMode: Text.WordWrap
}
}
Button {
id: secondPasswordButton
Layout.fillWidth: true
Layout.topMargin: 48
colorScheme: wizard.colorScheme
enabled: !loading
text: loading ? qsTr("Unlocking") : qsTr("Unlock")
onClicked: {
secondPasswordTextField.validate();
if (secondPasswordTextField.error) {
return;
TextField {
id: secondPasswordTextField
Layout.fillWidth: true
colorScheme: wizard.colorScheme
echoMode: TextInput.Password
label: qsTr("Mailbox password")
validateOnEditingFinished: false
validator: function (str) {
if (str.length === 0) {
return qsTr("Enter password");
}
}
secondPasswordTextField.enabled = false;
loading = true;
Backend.login2Password(usernameTextField.text, Qt.btoa(secondPasswordTextField.text));
}
}
Button {
Layout.fillWidth: true
Layout.topMargin: 32
colorScheme: wizard.colorScheme
enabled: !secondPasswordButton.loading
secondary: true
text: qsTr("Cancel")
onClicked: {
root.abort();
onAccepted: {
secondPasswordButton.onClicked();
}
}
Button {
id: secondPasswordButton
Layout.fillWidth: true
colorScheme: wizard.colorScheme
enabled: !loading
text: loading ? qsTr("Unlocking") : qsTr("Unlock")
onClicked: {
secondPasswordTextField.validate();
if (secondPasswordTextField.error) {
return;
}
secondPasswordTextField.enabled = false;
loading = true;
Backend.login2Password(usernameTextField.text, Qt.btoa(secondPasswordTextField.text));
}
}
Button {
Layout.fillWidth: true
colorScheme: wizard.colorScheme
enabled: !secondPasswordButton.loading
secondary: true
text: qsTr("Cancel")
onClicked: {
root.abort();
}
}
}
}

View File

@ -110,11 +110,6 @@ Item {
leftContent.showOnboarding();
rightContent.currentIndex = SetupWizard.ContentStack.Onboarding;
}
function showOutlookSelector() {
rootStackLayout.currentIndex = SetupWizard.RootStack.TwoPanesView;
leftContent.showOutlookSelector();
rightContent.currentIndex = SetupWizard.ContentStack.ClientConfigOutlookSelector;
}
Connections {
function onLoginFinished(userIndex, wasSignedOut) {

View File

@ -278,8 +278,9 @@ SPStreamEvent newLoginTfaRequestedEvent(QString const &username) {
/// \param[in] username The username.
/// \return The event.
//****************************************************************************************************************************************************
SPStreamEvent newLoginTwoPasswordsRequestedEvent() {
SPStreamEvent newLoginTwoPasswordsRequestedEvent(QString const &username) {
auto event = new ::grpc::LoginTwoPasswordsRequestedEvent;
event->set_username(username.toStdString());
auto loginEvent = new grpc::LoginEvent;
loginEvent->set_allocated_twopasswordrequested(event);
return wrapLoginEvent(loginEvent);

View File

@ -42,7 +42,7 @@ SPStreamEvent newShowMainWindowEvent(); ///< Create a new ShowMainWindowEvent ev
// Login events
SPStreamEvent newLoginError(grpc::LoginErrorType error, QString const &message); ///< Create a new LoginError event.
SPStreamEvent newLoginTfaRequestedEvent(QString const &username); ///< Create a new LoginTfaRequestedEvent event.
SPStreamEvent newLoginTwoPasswordsRequestedEvent(); ///< Create a new LoginTwoPasswordsRequestedEvent event.
SPStreamEvent newLoginTwoPasswordsRequestedEvent(QString const &username); ///< Create a new LoginTwoPasswordsRequestedEvent event.
SPStreamEvent newLoginFinishedEvent(QString const &userID, bool wasSignedOut); ///< Create a new LoginFinishedEvent event.
SPStreamEvent newLoginAlreadyLoggedInEvent(QString const &userID); ///< Create a new LoginAlreadyLoggedInEvent event.

View File

@ -1212,7 +1212,7 @@ void GRPCClient::processLoginEvent(LoginEvent const &event) {
break;
case LoginEvent::kTwoPasswordRequested:
this->logTrace("Login event received: TwoPasswordRequested.");
emit login2PasswordRequested();
emit login2PasswordRequested(QString::fromStdString(event.twopasswordrequested().username()));
break;
case LoginEvent::kFinished: {
this->logTrace("Login event received: Finished.");

View File

@ -146,10 +146,10 @@ signals:
void loginUsernamePasswordError(QString const &errMsg);
void loginFreeUserError();
void loginConnectionError(QString const &errMsg);
void login2FARequested(QString const &userName);
void login2FARequested(QString const &username);
void login2FAError(QString const &errMsg);
void login2FAErrorAbort(QString const &errMsg);
void login2PasswordRequested();
void login2PasswordRequested(QString const &username);
void login2PasswordError(QString const &errMsg);
void login2PasswordErrorAbort(QString const &errMsg);
void loginFinished(QString const &userID, bool wasSignedOut);

File diff suppressed because it is too large Load Diff

View File

@ -319,7 +319,9 @@ message LoginTfaRequestedEvent {
string username = 1;
}
message LoginTwoPasswordsRequestedEvent {}
message LoginTwoPasswordsRequestedEvent {
string username = 1;
}
message LoginFinishedEvent {
string userID = 1;

View File

@ -69,8 +69,8 @@ func NewLoginTfaRequestedEvent(username string) *StreamEvent {
return loginEvent(&LoginEvent{Event: &LoginEvent_TfaRequested{TfaRequested: &LoginTfaRequestedEvent{Username: username}}})
}
func NewLoginTwoPasswordsRequestedEvent() *StreamEvent {
return loginEvent(&LoginEvent{Event: &LoginEvent_TwoPasswordRequested{}})
func NewLoginTwoPasswordsRequestedEvent(username string) *StreamEvent {
return loginEvent(&LoginEvent{Event: &LoginEvent_TwoPasswordRequested{TwoPasswordRequested: &LoginTwoPasswordsRequestedEvent{Username: username}}})
}
func NewLoginFinishedEvent(userID string, wasSignedOut bool) *StreamEvent {

View File

@ -424,7 +424,7 @@ func (s *Service) Login(_ context.Context, login *LoginRequest) (*emptypb.Empty,
_ = s.SendEvent(NewLoginTfaRequestedEvent(login.Username))
case auth.PasswordMode == proton.TwoPasswordMode:
_ = s.SendEvent(NewLoginTwoPasswordsRequestedEvent())
_ = s.SendEvent(NewLoginTwoPasswordsRequestedEvent(login.Username))
default:
s.finishLogin()
@ -469,7 +469,7 @@ func (s *Service) Login2FA(_ context.Context, login *LoginRequest) (*emptypb.Emp
}
if s.auth.PasswordMode == proton.TwoPasswordMode {
_ = s.SendEvent(NewLoginTwoPasswordsRequestedEvent())
_ = s.SendEvent(NewLoginTwoPasswordsRequestedEvent(login.Username))
return
}

View File

@ -126,7 +126,7 @@ func (s *Service) StartEventTest() error {
// login
NewLoginError(LoginErrorType_FREE_USER, "error"),
NewLoginTfaRequestedEvent(dummyAddress),
NewLoginTwoPasswordsRequestedEvent(),
NewLoginTwoPasswordsRequestedEvent(dummyAddress),
NewLoginFinishedEvent("userID", false),
NewLoginAlreadyLoggedInEvent("userID"),