Skip to content

Commit

Permalink
Merge branch 'instruct-user-to-enable-full-disk-access-for-the-app-de…
Browse files Browse the repository at this point in the history
…s-966'
  • Loading branch information
raksooo committed May 31, 2024
2 parents 71d3cfa + 4650984 commit f5795bb
Show file tree
Hide file tree
Showing 9 changed files with 298 additions and 211 deletions.
18 changes: 17 additions & 1 deletion gui/locales/messages.pot
Original file line number Diff line number Diff line change
Expand Up @@ -1087,7 +1087,11 @@ msgid "Disconnected and unsecure"
msgstr ""

msgctxt "notifications"
msgid "Failed to enable split tunneling. Please try again or disable it."
msgid "Failed to enable split tunneling."
msgstr ""

msgctxt "notifications"
msgid "Failed to enable split tunneling. Please try reconnecting or disable split tunneling."
msgstr ""

msgctxt "notifications"
Expand Down Expand Up @@ -1682,6 +1686,14 @@ msgctxt "tray-icon-tooltip"
msgid "Connecting. %(location)s"
msgstr ""

msgctxt "troubleshoot"
msgid "Enable “Full Disk Access” for “Mullvad VPN” in the macOS system settings."
msgstr ""

msgctxt "troubleshoot"
msgid "Failed to enable split tunneling. This is because the app is missing system permissions. What you can do:"
msgstr ""

msgctxt "troubleshoot"
msgid "If these steps do not work please send a problem report."
msgstr ""
Expand All @@ -1690,6 +1702,10 @@ msgctxt "troubleshoot"
msgid "Make sure you have NF tables support."
msgstr ""

msgctxt "troubleshoot"
msgid "Open system settings"
msgstr ""

msgctxt "troubleshoot"
msgid "This error can happen when something other than Mullvad is actively updating the DNS."
msgstr ""
Expand Down
3 changes: 1 addition & 2 deletions gui/src/main/daemon-rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1047,10 +1047,9 @@ function convertFromTunnelStateError(state: grpcTypes.ErrorState.AsObject): Erro
cause: ErrorStateCause.splitTunnelError,
};
case grpcTypes.ErrorState.Cause.NEED_FULL_DISK_PERMISSIONS:
// TODO: handle correctly
return {
...baseError,
cause: ErrorStateCause.splitTunnelError,
cause: ErrorStateCause.needFullDiskPermissions,
};
case grpcTypes.ErrorState.Cause.VPN_PERMISSION_DENIED:
// VPN_PERMISSION_DENIED is only ever created on Android
Expand Down
12 changes: 10 additions & 2 deletions gui/src/main/user-interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,20 @@ export default class UserInterface implements WindowControllerDelegate {
});

IpcMainEventChannel.app.handleShowLaunchDaemonSettings(async () => {
try {
await execAsync('open x-apple.systempreferences:com.apple.LoginItems-Settings.extension');
} catch (error) {
log.error(`Failed to open launch daemon settings: ${error}`);
}
});

IpcMainEventChannel.app.handleShowFullDiskAccessSettings(async () => {
try {
await execAsync(
'open -W x-apple.systempreferences:com.apple.LoginItems-Settings.extension',
'open "x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles"',
);
} catch (error) {
log.error(`Failed to open launch daemon settings: ${error}`);
log.error(`Failed to open Full Disk Access settings: ${error}`);
}
});
}
Expand Down
4 changes: 4 additions & 0 deletions gui/src/renderer/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,10 @@ export default class AppRenderer {
await IpcRendererEventChannel.app.showLaunchDaemonSettings();
}

public showFullDiskAccessSettings = async () => {
await IpcRendererEventChannel.app.showFullDiskAccessSettings();
};

public async sendProblemReport(
email: string,
message: string,
Expand Down
40 changes: 31 additions & 9 deletions gui/src/renderer/components/NotificationArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ interface IProps {
}

export default function NotificationArea(props: IProps) {
const { showFullDiskAccessSettings } = useAppContext();

const account = useSelector((state: IReduxState) => state.account);
const locale = useSelector((state: IReduxState) => state.userInterface.locale);
const tunnelState = useSelector((state: IReduxState) => state.connection.status);
Expand All @@ -65,7 +67,7 @@ export default function NotificationArea(props: IProps) {
blockWhenDisconnected,
hasExcludedApps,
}),
new ErrorNotificationProvider({ tunnelState, hasExcludedApps }),
new ErrorNotificationProvider({ tunnelState, hasExcludedApps, showFullDiskAccessSettings }),
new InconsistentVersionNotificationProvider({ consistent: version.consistent }),
new UnsupportedVersionNotificationProvider(version),
];
Expand Down Expand Up @@ -168,20 +170,40 @@ function NotificationActionWrapper(props: INotificationActionWrapperProps) {
}
}

const problemReportButton = troubleshootInfo?.buttons ? (
<AppButton.BlueButton key="problem-report" onClick={goToProblemReport}>
{messages.pgettext('in-app-notifications', 'Send problem report')}
</AppButton.BlueButton>
) : (
<AppButton.GreenButton key="problem-report" onClick={goToProblemReport}>
{messages.pgettext('in-app-notifications', 'Send problem report')}
</AppButton.GreenButton>
);

let buttons = [
problemReportButton,
<AppButton.BlueButton key="back" onClick={closeTroubleshootInfo}>
{messages.gettext('Back')}
</AppButton.BlueButton>,
];

if (troubleshootInfo?.buttons) {
const actionButtons = troubleshootInfo.buttons.map((button) => (
<AppButton.GreenButton key={button.label} onClick={button.action}>
{button.label}
</AppButton.GreenButton>
));

buttons = actionButtons.concat(buttons);
}

return (
<>
<NotificationActions>{actionComponent}</NotificationActions>
<ModalAlert
isOpen={troubleshootInfo !== undefined}
type={ModalAlertType.info}
buttons={[
<AppButton.GreenButton key="problem-report" onClick={goToProblemReport}>
{messages.pgettext('in-app-notifications', 'Send problem report')}
</AppButton.GreenButton>,
<AppButton.BlueButton key="back" onClick={closeTroubleshootInfo}>
{messages.gettext('Back')}
</AppButton.BlueButton>,
]}
buttons={buttons}
close={closeTroubleshootInfo}>
<ModalMessage>{troubleshootInfo?.details}</ModalMessage>
<ModalMessage>
Expand Down
4 changes: 3 additions & 1 deletion gui/src/shared/daemon-rpc-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export enum ErrorStateCause {
tunnelParameterError,
isOffline,
splitTunnelError,
needFullDiskPermissions,
}

export enum AuthFailedError {
Expand All @@ -71,7 +72,8 @@ export type ErrorState =
| ErrorStateCause.setDnsError
| ErrorStateCause.startTunnelError
| ErrorStateCause.isOffline
| ErrorStateCause.splitTunnelError;
| ErrorStateCause.splitTunnelError
| ErrorStateCause.needFullDiskPermissions;
blockingError?: FirewallPolicyError;
}
| {
Expand Down
1 change: 1 addition & 0 deletions gui/src/shared/ipc-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ export const ipcSchema = {
openUrl: invoke<string, void>(),
showOpenDialog: invoke<Electron.OpenDialogOptions, Electron.OpenDialogReturnValue>(),
showLaunchDaemonSettings: invoke<void, void>(),
showFullDiskAccessSettings: invoke<void, void>(),
getPathBaseName: invoke<string, string>(),
},
tunnel: {
Expand Down
Loading

0 comments on commit f5795bb

Please sign in to comment.