Skip to content

Commit

Permalink
feat(BRIDGE-37): Remote notification support
Browse files Browse the repository at this point in the history
  • Loading branch information
ElectroNafta committed Aug 29, 2024
1 parent ed1b657 commit f04350c
Show file tree
Hide file tree
Showing 43 changed files with 2,334 additions and 1,152 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ require (
github.com/Masterminds/semver/v3 v3.2.0
github.com/ProtonMail/gluon v0.17.1-0.20240514133734-79cdd0fec41c
github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a
github.com/ProtonMail/go-proton-api v0.4.1-0.20240827122236-ca6bb6449bba
github.com/ProtonMail/go-proton-api v0.4.1-0.20240829112804-d663a2ef90c2
github.com/ProtonMail/gopenpgp/v2 v2.7.4-proton
github.com/PuerkitoBio/goquery v1.8.1
github.com/abiosoft/ishell v2.0.0+incompatible
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ github.com/ProtonMail/go-proton-api v0.4.1-0.20240827084449-71096377c391 h1:PW6b
github.com/ProtonMail/go-proton-api v0.4.1-0.20240827084449-71096377c391/go.mod h1:3A0cpdo0BIenIPjTG6u8EbzJ8uuJy7rVvM/NaynjCKA=
github.com/ProtonMail/go-proton-api v0.4.1-0.20240827122236-ca6bb6449bba h1:QtDxgIbgPqRQg7VT+nIUJlaOyNFAoGyg59oW3Hji/0A=
github.com/ProtonMail/go-proton-api v0.4.1-0.20240827122236-ca6bb6449bba/go.mod h1:3A0cpdo0BIenIPjTG6u8EbzJ8uuJy7rVvM/NaynjCKA=
github.com/ProtonMail/go-proton-api v0.4.1-0.20240827132526-849231fc34a1 h1:gATlMoj4raG32WyGGh8SpipoQeR2AlU7g+8NAMicTcw=
github.com/ProtonMail/go-proton-api v0.4.1-0.20240827132526-849231fc34a1/go.mod h1:3A0cpdo0BIenIPjTG6u8EbzJ8uuJy7rVvM/NaynjCKA=
github.com/ProtonMail/go-proton-api v0.4.1-0.20240829112804-d663a2ef90c2 h1:yx0iejqB5c21HIN5jn9IsbyzUns0dPUUaGfyUHF3TmQ=
github.com/ProtonMail/go-proton-api v0.4.1-0.20240829112804-d663a2ef90c2/go.mod h1:3A0cpdo0BIenIPjTG6u8EbzJ8uuJy7rVvM/NaynjCKA=
github.com/ProtonMail/go-smtp v0.0.0-20231109081432-2b3d50599865 h1:EP1gnxLL5Z7xBSymE9nSTM27nRYINuvssAtDmG0suD8=
github.com/ProtonMail/go-smtp v0.0.0-20231109081432-2b3d50599865/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ=
github.com/ProtonMail/go-srp v0.0.7 h1:Sos3Qk+th4tQR64vsxGIxYpN3rdnG9Wf9K4ZloC1JrI=
Expand Down
6 changes: 6 additions & 0 deletions internal/bridge/bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import (
"github.com/ProtonMail/proton-bridge/v3/internal/safe"
"github.com/ProtonMail/proton-bridge/v3/internal/sentry"
"github.com/ProtonMail/proton-bridge/v3/internal/services/imapsmtpserver"
"github.com/ProtonMail/proton-bridge/v3/internal/services/notifications"
"github.com/ProtonMail/proton-bridge/v3/internal/services/observability"
"github.com/ProtonMail/proton-bridge/v3/internal/services/syncservice"
"github.com/ProtonMail/proton-bridge/v3/internal/telemetry"
Expand Down Expand Up @@ -144,6 +145,9 @@ type Bridge struct {

// observabilityService is responsible for handling calls to the observability system
observabilityService *observability.Service

// notificationStore is used for notification deduplication
notificationStore *notifications.Store
}

var logPkg = logrus.WithField("pkg", "bridge") //nolint:gochecknoglobals
Expand Down Expand Up @@ -307,6 +311,8 @@ func newBridge(
unleashService: unleashService,

observabilityService: observability.NewService(ctx, panicHandler),

notificationStore: notifications.NewStore(locator.ProvideNotificationsCachePath),
}

bridge.serverManager = imapsmtpserver.NewService(context.Background(),
Expand Down
1 change: 1 addition & 0 deletions internal/bridge/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type Locator interface {
Clear(...string) error
ProvideIMAPSyncConfigPath() (string, error)
ProvideUnleashCachePath() (string, error)
ProvideNotificationsCachePath() (string, error)
}

type ProxyController interface {
Expand Down
3 changes: 3 additions & 0 deletions internal/bridge/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,9 @@ func (bridge *Bridge) addUserWithVault(
bridge.observabilityService,
syncSettingsPath,
isNew,
bridge.notificationStore,
bridge.unleashService.GetFlagValue,
bridge.observabilityService.AddMetric,
)
if err != nil {
return fmt.Errorf("failed to create user: %w", err)
Expand Down
13 changes: 13 additions & 0 deletions internal/events/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,3 +212,16 @@ type UserLoadedCheckResync struct {
func (event UserLoadedCheckResync) String() string {
return fmt.Sprintf("UserLoadedCheckResync: UserID: %s", event.UserID)
}

type UserNotification struct {
eventBase

UserID string
Title string
Subtitle string
Body string
}

func (event UserNotification) String() string {
return fmt.Sprintf("UserNotification: UserID: %s, Title: %s, Subtitle: %s, Body: %s", event.UserID, event.Title, event.Subtitle, event.Body)
}
40 changes: 40 additions & 0 deletions internal/frontend/bridge-gui/bridge-gui-tester/Tabs/UsersTab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ UsersTab::UsersTab(QWidget *parent)
connect(ui_.checkUsernamePasswordError, &QCheckBox::toggled, this, &UsersTab::updateGUIState);
connect(ui_.checkSync, &QCheckBox::toggled, this, &UsersTab::onCheckSyncToggled);
connect(ui_.sliderSync, &QSlider::valueChanged, this, &UsersTab::onSliderSyncValueChanged);
connect(ui_.sendNotificationButton, &QPushButton::clicked, this, &UsersTab::onSendUserNotification);

users_.append(defaultUser());

Expand Down Expand Up @@ -216,6 +217,7 @@ void UsersTab::updateGUIState() {
ui_.editUsernamePasswordError->setEnabled(ui_.checkUsernamePasswordError->isChecked());
ui_.spinUsedBytes->setValue(user ? user->usedBytes() : 0.0);
ui_.groupboxSync->setEnabled(user.get());
ui_.groupBoxNotification->setEnabled(hasSelectedUser && (UserState::Connected == state));

if (user)
ui_.editIMAPLoginFailedUsername->setText(user->primaryEmailOrUsername());
Expand Down Expand Up @@ -489,3 +491,41 @@ void UsersTab::onSliderSyncValueChanged(int value) {
app().grpc().sendEvent(newSyncProgressEvent(user->id(), progress, 1, 1)); // we do not simulate elapsed & remaining.
this->updateGUIState();
}

//****************************************************************************************************************************************************
/// \return the title for the notification.
//****************************************************************************************************************************************************
QString UsersTab::notificationTitle() const {
return ui_.notificationTitle->text();
}

//****************************************************************************************************************************************************
/// \return the subtitle for the notification.
//****************************************************************************************************************************************************
QString UsersTab::notificationSubtitle() const {
return ui_.notificationSubtitleText->text();
}

//****************************************************************************************************************************************************
/// \return the body for the notification.
//****************************************************************************************************************************************************
QString UsersTab::notificationBody() const {
return ui_.notticationBodyText->text();
}


void UsersTab::onSendUserNotification() {
SPUser const user = selectedUser();
if (!user) {
app().log().error(QString("%1 failed. Unkown user.").arg(__FUNCTION__));
return;
}

GRPCService &grpc = app().grpc();

if (grpc.isStreaming()) {
QString const userID = user->id();
grpc.sendEvent(newUserNotificationEvent(userID, notificationTitle(), notificationSubtitle(), notificationBody()));
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
#include "Tabs/ui_UsersTab.h"
#include "UserTable.h"


//****************************************************************************************************************************************************
/// \brief The 'Users' tab of the main window.
//****************************************************************************************************************************************************
Expand All @@ -50,12 +49,15 @@ Q_OBJECT
bool nextUserTwoPasswordsError() const; ///< Check if next user login should trigger 2nd password error.
bool nextUserTwoPasswordsAbort() const; ///< Check if next user login should trigger 2nd password abort.
QString usernamePasswordErrorMessage() const; ///< Return the username password error message.
QString notificationTitle() const; ///< Return the user notification title.
QString notificationSubtitle() const; ///< Return the user notification subtitle.
QString notificationBody() const; ///< Return the user notification body.

public slots:
void setUserSplitMode(QString const &userID, bool makeItActive); ///< Slot for the split mode.
void logoutUser(QString const &userID); ///< slot for the logging out of a user.
void removeUser(QString const &userID); ///< Slot for the removal of a user.
static void configureUserAppleMail(QString const &userID, QString const &address); ///< Slot for the configuration of Apple mail.
static void configureUserAppleMail(QString const &userID, QString const &address); ///< Slot for the configuration of Apple mail.
void processBadEventUserFeedback(QString const& userID, bool doResync); ///< Slot for the reception of a bad event user feedback.

private slots:
Expand All @@ -69,6 +71,7 @@ private slots:
void onCheckSyncToggled(bool checked); ///< Slot for the 'Synchronizing' check box.
void onSliderSyncValueChanged(int value); ///< Slot for the sync 'Progress' slider.
void updateGUIState(); ///< Update the GUI state.
void onSendUserNotification(); ///< Send a user notification event to the GUI.

private: // member functions.
qint32 selectedIndex() const; ///< Get the index of the selected row.
Expand Down
Loading

0 comments on commit f04350c

Please sign in to comment.