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; return Status::OK;
} }
if (usersTab.nextUserTwoPasswordsRequired()) { if (usersTab.nextUserTwoPasswordsRequired()) {
qtProxy_.sendDelayedEvent(newLoginTwoPasswordsRequestedEvent()); qtProxy_.sendDelayedEvent(newLoginTwoPasswordsRequestedEvent(loginUsername_));
return Status::OK; return Status::OK;
} }
@ -425,7 +425,7 @@ Status GRPCService::Login2FA(ServerContext *, LoginRequest const *request, Empty
return Status::OK; return Status::OK;
} }
if (usersTab.nextUserTwoPasswordsRequired()) { if (usersTab.nextUserTwoPasswordsRequired()) {
qtProxy_.sendDelayedEvent(newLoginTwoPasswordsRequestedEvent()); qtProxy_.sendDelayedEvent(newLoginTwoPasswordsRequestedEvent(loginUsername_));
return Status::OK; 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 login2FARequested(QString const &username); ///< Signal for the 'login2FARequested' gRPC stream event.
void login2FAError(QString const &errorMsg); ///< Signal for the 'login2FAError' 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 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 login2PasswordError(QString const &errorMsg); ///< Signal for the 'login2PasswordError' gRPC stream event.
void login2PasswordErrorAbort(QString const &errorMsg); ///< Signal for the 'login2PasswordErrorAbort' 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. 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"; icon.source = "/qml/icons/img-mail-clients.svg";
} }
function showLogin() { function showLogin() {
descriptionLabel.text = qsTr("Let's start by signing in to your Proton account."); showOnboarding()
linkLabel1.setLink("https://proton.me/mail/pricing", qsTr("Create or upgrade your account")); }
linkLabel2.clear();
showLoginCommon();
}
function showLogin2FA() { function showLogin2FA() {
descriptionLabel.text = qsTr("You have enabled two-factor authentication. Please enter the 6-digit code provided by your authenticator application."); showOnboarding()
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;
} }
function showLoginMailboxPassword() { function showLoginMailboxPassword() {
descriptionLabel.text = qsTr("You have secured your account with a separate mailbox password."); showOnboarding()
linkLabel1.clear();
linkLabel2.clear();
showLoginCommon();
} }
function 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. "); 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?")); linkLabel1.setLink("https://proton.me/support/bridge", qsTr("Why do I need Bridge?"));
linkLabel2.clear(); linkLabel2.clear();
@ -81,11 +64,6 @@ Item {
icon.sourceSize.height = 148; icon.sourceSize.height = 148;
icon.sourceSize.width = 265; 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 { Connections {
function onLogin2FARequested() { function onLogin2FARequested() {

View File

@ -43,9 +43,6 @@ FocusScope {
mailboxPasswordLayout.reset(); mailboxPasswordLayout.reset();
} }
implicitHeight: children[0].implicitHeight
implicitWidth: children[0].implicitWidth
StackLayout { StackLayout {
id: stackLayout id: stackLayout
function loginFailed() { function loginFailed() {
@ -91,9 +88,10 @@ FocusScope {
root.reset(); root.reset();
errorLabel.text = qsTr("Incorrect login credentials. Please try again."); 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"); console.assert(stackLayout.currentIndex === Login.RootStack.Login || stackLayout.currentIndex === Login.RootStack.TOTP, "Unexpected login2PasswordRequested");
stackLayout.currentIndex = Login.RootStack.MailboxPassword; stackLayout.currentIndex = Login.RootStack.MailboxPassword;
mailboxPasswordUsernameLabel.text = username;
secondPasswordTextField.focus = true; secondPasswordTextField.focus = true;
} }
function onLoginAlreadyLoggedIn(_) { function onLoginAlreadyLoggedIn(_) {
@ -124,299 +122,353 @@ FocusScope {
target: Backend target: Backend
} }
ColumnLayout { Item {
id: loginLayout ColumnLayout {
function reset(clearUsername = false) { id: loginLayout
signInButton.loading = false; function reset(clearUsername = false) {
errorLabel.text = ""; signInButton.loading = false;
usernameTextField.enabled = true; errorLabel.text = "";
usernameTextField.error = false; usernameTextField.enabled = true;
usernameTextField.errorString = ""; usernameTextField.error = false;
usernameTextField.focus = true; usernameTextField.errorString = "";
if (clearUsername) { usernameTextField.focus = true;
usernameTextField.text = ""; 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 { ColumnLayout {
Layout.alignment: Qt.AlignHCenter Layout.fillWidth: true
colorScheme: wizard.colorScheme spacing: 8
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
ColorImage { Label {
color: wizard.colorScheme.signal_danger Layout.alignment: Qt.AlignHCenter
height: errorLabel.lineHeight Layout.fillWidth: true
source: "/qml/icons/ic-exclamation-circle-filled.svg" colorScheme: wizard.colorScheme
sourceSize.height: errorLabel.lineHeight 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 { Label {
id: errorLabel id: descriptionLabel
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true Layout.fillWidth: true
Layout.leftMargin: 4
color: wizard.colorScheme.signal_danger
colorScheme: wizard.colorScheme 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 wrapMode: Text.WordWrap
} }
} TextField {
TextField { id: twoFactorPasswordTextField
id: usernameTextField Layout.fillWidth: true
Layout.fillWidth: true colorScheme: wizard.colorScheme
Layout.topMargin: 48 label: qsTr("Two-factor code")
colorScheme: wizard.colorScheme validateOnEditingFinished: false
focus: true validator: function (str) {
label: qsTr("Email or username") if (str.length === 0) {
validateOnEditingFinished: false return qsTr("Enter the 6-digit code");
validator: function (str) { }
if (str.length === 0) {
return qsTr("Enter email or username");
} }
}
onAccepted: passwordTextField.forceActiveFocus() onAccepted: {
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) {
twoFAButton.onClicked(); twoFAButton.onClicked();
} }
} onTextChanged: {
} if (text.length >= 6) {
Button { twoFAButton.onClicked();
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;
} }
twoFactorPasswordTextField.enabled = false;
loading = true;
Backend.login2FA(usernameTextField.text, Qt.btoa(twoFactorPasswordTextField.text));
} }
} Button {
Button { id: twoFAButton
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 32 colorScheme: wizard.colorScheme
colorScheme: wizard.colorScheme enabled: !loading
enabled: !twoFAButton.loading text: loading ? qsTr("Authenticating") : qsTr("Authenticate")
secondary: true
text: qsTr("Cancel")
onClicked: { onClicked: {
root.abort(); 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 { Item {
id: mailboxPasswordLayout ColumnLayout {
function reset() { id: mailboxPasswordLayout
secondPasswordButton.loading = false; function reset() {
secondPasswordTextField.enabled = true; secondPasswordButton.loading = false;
secondPasswordTextField.error = false; secondPasswordTextField.enabled = true;
secondPasswordTextField.errorString = ""; secondPasswordTextField.error = false;
secondPasswordTextField.text = ""; secondPasswordTextField.errorString = "";
} secondPasswordTextField.text = "";
}
spacing: 0 anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
spacing: 16
Label { ColumnLayout {
Layout.alignment: Qt.AlignCenter Layout.fillWidth: true
colorScheme: wizard.colorScheme spacing: 8
text: qsTr("Unlock your mailbox")
type: Label.LabelType.Heading Label {
} Layout.alignment: Qt.AlignHCenter
Label { Layout.fillWidth: true
Layout.alignment: Qt.AlignCenter colorScheme: wizard.colorScheme
Layout.topMargin: 8 horizontalAlignment: Text.AlignHCenter
color: wizard.colorScheme.text_weak text: qsTr("Unlock your mailbox")
colorScheme: wizard.colorScheme type: Label.LabelType.Title
type: Label.LabelType.Lead }
} Label {
TextField { id: mailboxPasswordUsernameLabel
id: secondPasswordTextField Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 48 color: wizard.colorScheme.text_weak
colorScheme: wizard.colorScheme colorScheme: wizard.colorScheme
echoMode: TextInput.Password horizontalAlignment: Text.AlignHCenter
label: qsTr("Mailbox password") text: ""
validateOnEditingFinished: false type: Label.LabelType.Body
validator: function (str) {
if (str.length === 0) {
return qsTr("Enter password");
} }
} }
Label {
onAccepted: { Layout.alignment: Qt.AlignHCenter
secondPasswordButton.onClicked(); 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
} }
} TextField {
Button { id: secondPasswordTextField
id: secondPasswordButton Layout.fillWidth: true
Layout.fillWidth: true colorScheme: wizard.colorScheme
Layout.topMargin: 48 echoMode: TextInput.Password
colorScheme: wizard.colorScheme label: qsTr("Mailbox password")
enabled: !loading validateOnEditingFinished: false
text: loading ? qsTr("Unlocking") : qsTr("Unlock") validator: function (str) {
if (str.length === 0) {
onClicked: { return qsTr("Enter password");
secondPasswordTextField.validate(); }
if (secondPasswordTextField.error) {
return;
} }
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: { onAccepted: {
root.abort(); 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(); leftContent.showOnboarding();
rightContent.currentIndex = SetupWizard.ContentStack.Onboarding; rightContent.currentIndex = SetupWizard.ContentStack.Onboarding;
} }
function showOutlookSelector() {
rootStackLayout.currentIndex = SetupWizard.RootStack.TwoPanesView;
leftContent.showOutlookSelector();
rightContent.currentIndex = SetupWizard.ContentStack.ClientConfigOutlookSelector;
}
Connections { Connections {
function onLoginFinished(userIndex, wasSignedOut) { function onLoginFinished(userIndex, wasSignedOut) {

View File

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

View File

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

View File

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

View File

@ -146,10 +146,10 @@ signals:
void loginUsernamePasswordError(QString const &errMsg); void loginUsernamePasswordError(QString const &errMsg);
void loginFreeUserError(); void loginFreeUserError();
void loginConnectionError(QString const &errMsg); void loginConnectionError(QString const &errMsg);
void login2FARequested(QString const &userName); void login2FARequested(QString const &username);
void login2FAError(QString const &errMsg); void login2FAError(QString const &errMsg);
void login2FAErrorAbort(QString const &errMsg); void login2FAErrorAbort(QString const &errMsg);
void login2PasswordRequested(); void login2PasswordRequested(QString const &username);
void login2PasswordError(QString const &errMsg); void login2PasswordError(QString const &errMsg);
void login2PasswordErrorAbort(QString const &errMsg); void login2PasswordErrorAbort(QString const &errMsg);
void loginFinished(QString const &userID, bool wasSignedOut); 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; string username = 1;
} }
message LoginTwoPasswordsRequestedEvent {} message LoginTwoPasswordsRequestedEvent {
string username = 1;
}
message LoginFinishedEvent { message LoginFinishedEvent {
string userID = 1; string userID = 1;

View File

@ -69,8 +69,8 @@ func NewLoginTfaRequestedEvent(username string) *StreamEvent {
return loginEvent(&LoginEvent{Event: &LoginEvent_TfaRequested{TfaRequested: &LoginTfaRequestedEvent{Username: username}}}) return loginEvent(&LoginEvent{Event: &LoginEvent_TfaRequested{TfaRequested: &LoginTfaRequestedEvent{Username: username}}})
} }
func NewLoginTwoPasswordsRequestedEvent() *StreamEvent { func NewLoginTwoPasswordsRequestedEvent(username string) *StreamEvent {
return loginEvent(&LoginEvent{Event: &LoginEvent_TwoPasswordRequested{}}) return loginEvent(&LoginEvent{Event: &LoginEvent_TwoPasswordRequested{TwoPasswordRequested: &LoginTwoPasswordsRequestedEvent{Username: username}}})
} }
func NewLoginFinishedEvent(userID string, wasSignedOut bool) *StreamEvent { 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)) _ = s.SendEvent(NewLoginTfaRequestedEvent(login.Username))
case auth.PasswordMode == proton.TwoPasswordMode: case auth.PasswordMode == proton.TwoPasswordMode:
_ = s.SendEvent(NewLoginTwoPasswordsRequestedEvent()) _ = s.SendEvent(NewLoginTwoPasswordsRequestedEvent(login.Username))
default: default:
s.finishLogin() s.finishLogin()
@ -469,7 +469,7 @@ func (s *Service) Login2FA(_ context.Context, login *LoginRequest) (*emptypb.Emp
} }
if s.auth.PasswordMode == proton.TwoPasswordMode { if s.auth.PasswordMode == proton.TwoPasswordMode {
_ = s.SendEvent(NewLoginTwoPasswordsRequestedEvent()) _ = s.SendEvent(NewLoginTwoPasswordsRequestedEvent(login.Username))
return return
} }

View File

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