summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2021-06-16 10:22:47 +0200
committerDavid Lönnhager <david.l@mullvad.net>2021-06-18 11:53:28 +0200
commit5453eece3a53c4cc45c8987a88789e43fb214912 (patch)
treec36308988a46a5125949f47611e7f76cba21c27a
parent335cc80d9347f43264765a3dd359eda83c782bc8 (diff)
downloadmullvadvpn-5453eece3a53c4cc45c8987a88789e43fb214912.tar.xz
mullvadvpn-5453eece3a53c4cc45c8987a88789e43fb214912.zip
Update account history RPCs
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Event.kt2
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt2
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt13
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt16
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ui/LoginFragment.kt2
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/AccountCache.kt8
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountHistoryAdapter.kt10
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountLogin.kt11
-rw-r--r--gui/src/main/daemon-rpc.ts8
-rw-r--r--gui/src/main/index.ts12
-rw-r--r--gui/src/renderer/app.tsx10
-rw-r--r--gui/src/renderer/components/Login.tsx48
-rw-r--r--gui/src/renderer/components/Support.tsx4
-rw-r--r--gui/src/renderer/containers/LoginPage.tsx2
-rw-r--r--gui/src/renderer/redux/account/actions.ts4
-rw-r--r--gui/src/renderer/redux/account/reducers.ts4
-rw-r--r--gui/src/shared/ipc-schema.ts8
-rw-r--r--mullvad-cli/src/cmds/account.rs13
-rw-r--r--mullvad-daemon/src/account_history.rs2
-rw-r--r--mullvad-daemon/src/lib.rs70
-rw-r--r--mullvad-daemon/src/management_interface.rs15
-rw-r--r--mullvad-jni/src/daemon_interface.rs8
-rw-r--r--mullvad-jni/src/lib.rs21
-rw-r--r--mullvad-management-interface/proto/management_interface.proto9
24 files changed, 103 insertions, 199 deletions
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Event.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Event.kt
index faaba05d89..a5854232a8 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Event.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Event.kt
@@ -17,7 +17,7 @@ sealed class Event : Message.EventMessage() {
protected override val messageKey = MESSAGE_KEY
@Parcelize
- data class AccountHistory(val history: List<String>?) : Event()
+ data class AccountHistory(val history: String?) : Event()
@Parcelize
data class AppVersionInfo(val versionInfo: AppVersionInfoData?) : Event()
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt
index 8093cac415..27a93b0a2d 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt
@@ -54,7 +54,7 @@ sealed class Request : Message.RequestMessage() {
data class RegisterListener(val listener: Messenger) : Request()
@Parcelize
- data class RemoveAccountFromHistory(val account: String?) : Request()
+ object ClearAccountHistory : Request()
@Parcelize
data class RemoveCustomDnsServer(val address: InetAddress) : Request()
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt
index bab7bcf3ce..4565844daa 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt
@@ -52,7 +52,7 @@ class MullvadDaemon(val vpnService: MullvadVpnService) {
return getAccountData(daemonInterfaceAddress, accountToken)
}
- fun getAccountHistory(): ArrayList<String>? {
+ fun getAccountHistory(): String? {
return getAccountHistory(daemonInterfaceAddress)
}
@@ -92,8 +92,8 @@ class MullvadDaemon(val vpnService: MullvadVpnService) {
reconnect(daemonInterfaceAddress)
}
- fun removeAccountFromHistory(accountToken: String) {
- removeAccountFromHistory(daemonInterfaceAddress, accountToken)
+ fun clearAccountHistory() {
+ clearAccountHistory(daemonInterfaceAddress)
}
fun setAccount(accountToken: String?) {
@@ -159,7 +159,7 @@ class MullvadDaemon(val vpnService: MullvadVpnService) {
daemonInterfaceAddress: Long,
accountToken: String
): GetAccountDataResult
- private external fun getAccountHistory(daemonInterfaceAddress: Long): ArrayList<String>?
+ private external fun getAccountHistory(daemonInterfaceAddress: Long): String?
private external fun getWwwAuthToken(daemonInterfaceAddress: Long): String?
private external fun getCurrentLocation(daemonInterfaceAddress: Long): GeoIpLocation?
private external fun getCurrentVersion(daemonInterfaceAddress: Long): String?
@@ -169,10 +169,7 @@ class MullvadDaemon(val vpnService: MullvadVpnService) {
private external fun getVersionInfo(daemonInterfaceAddress: Long): AppVersionInfo?
private external fun getWireguardKey(daemonInterfaceAddress: Long): PublicKey?
private external fun reconnect(daemonInterfaceAddress: Long)
- private external fun removeAccountFromHistory(
- daemonInterfaceAddress: Long,
- accountToken: String
- )
+ private external fun clearAccountHistory(daemonInterfaceAddress: Long)
private external fun setAccount(daemonInterfaceAddress: Long, accountToken: String?)
private external fun setAllowLan(daemonInterfaceAddress: Long, allowLan: Boolean)
private external fun setAutoConnect(daemonInterfaceAddress: Long, alwaysOn: Boolean)
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt
index 5e6524e3a0..768b00e1b5 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt
@@ -42,7 +42,7 @@ class AccountCache(private val endpoint: ServiceEndpoint) {
val onAccountNumberChange = EventNotifier<String?>(null)
val onAccountExpiryChange = EventNotifier<DateTime?>(null)
- val onAccountHistoryChange = EventNotifier<List<String>>(listOf<String>())
+ val onAccountHistoryChange = EventNotifier<String?>(null)
val onLoginStatusChange = EventNotifier<LoginStatus?>(null)
var newlyCreatedAccount = false
@@ -104,10 +104,8 @@ class AccountCache(private val endpoint: ServiceEndpoint) {
invalidateAccountExpiry(request.expiry)
}
- registerHandler(Request.RemoveAccountFromHistory::class) { request ->
- request.account?.let { account ->
- removeAccountFromHistory(account)
- }
+ registerHandler(Request.ClearAccountHistory::class) { _ ->
+ clearAccountHistory()
}
}
}
@@ -162,9 +160,9 @@ class AccountCache(private val endpoint: ServiceEndpoint) {
}
}
- private fun removeAccountFromHistory(accountToken: String) {
- jobTracker.newBackgroundJob("removeAccountFromHistory $accountToken") {
- daemon.await().removeAccountFromHistory(accountToken)
+ private fun clearAccountHistory() {
+ jobTracker.newBackgroundJob("clearAccountHistory") {
+ daemon.await().clearAccountHistory()
fetchAccountHistory()
}
}
@@ -227,7 +225,7 @@ class AccountCache(private val endpoint: ServiceEndpoint) {
private fun fetchAccountHistory() {
jobTracker.newBackgroundJob("fetchHistory") {
- daemon.await().getAccountHistory()?.let { history ->
+ daemon.await().getAccountHistory().let { history ->
accountHistory = history
}
}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/LoginFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/LoginFragment.kt
index 83f0ecc3ad..399490f04b 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/LoginFragment.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/LoginFragment.kt
@@ -51,7 +51,7 @@ class LoginFragment : ServiceDependentFragment(OnNoService.GoToLaunchScreen), Na
accountLogin = view.findViewById<AccountLogin>(R.id.account_login).apply {
onLogin = { accountToken -> login(accountToken) }
- onRemoveFromHistory = { account -> accountCache.removeAccountFromHistory(account) }
+ onClearHistory = { -> accountCache.clearAccountHistory() }
}
view.findViewById<Button>(R.id.create_account)
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/AccountCache.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/AccountCache.kt
index e2c344f63f..9bf5942f4c 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/AccountCache.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/AccountCache.kt
@@ -11,7 +11,7 @@ import org.joda.time.DateTime
class AccountCache(private val connection: Messenger, eventDispatcher: EventDispatcher) {
val onAccountNumberChange = EventNotifier<String?>(null)
val onAccountExpiryChange = EventNotifier<DateTime?>(null)
- val onAccountHistoryChange = EventNotifier<List<String>>(listOf<String>())
+ val onAccountHistoryChange = EventNotifier<String?>(null)
val onLoginStatusChange = EventNotifier<LoginStatus?>(null)
private var accountHistory by onAccountHistoryChange.notifiable()
@@ -20,7 +20,7 @@ class AccountCache(private val connection: Messenger, eventDispatcher: EventDisp
init {
eventDispatcher.apply {
registerHandler(Event.AccountHistory::class) { event ->
- accountHistory = event.history ?: listOf<String>()
+ accountHistory = event.history
}
registerHandler(Event.LoginStatus::class) { event ->
@@ -54,8 +54,8 @@ class AccountCache(private val connection: Messenger, eventDispatcher: EventDisp
connection.send(request.message)
}
- fun removeAccountFromHistory(account: String) {
- connection.send(Request.RemoveAccountFromHistory(account).message)
+ fun clearAccountHistory() {
+ connection.send(Request.ClearAccountHistory.message)
}
fun onDestroy() {
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountHistoryAdapter.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountHistoryAdapter.kt
index caefcfe51f..48a05dd63e 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountHistoryAdapter.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountHistoryAdapter.kt
@@ -14,12 +14,12 @@ class AccountHistoryAdapter : Adapter<AccountHistoryHolder>() {
}
}
- var accountHistory by observable(listOf<String>()) { _, _, _ ->
+ var accountHistory by observable<String?>(null) { _, _, _ ->
notifyDataSetChanged()
}
var onSelectEntry: ((String) -> Unit)? = null
- var onRemoveEntry: ((String) -> Unit)? = null
+ var onRemoveEntry: (() -> Unit)? = null
var onChildFocusChanged: ((String, Boolean) -> Unit)? = null
override fun onCreateViewHolder(parentView: ViewGroup, type: Int): AccountHistoryHolder {
@@ -28,14 +28,14 @@ class AccountHistoryAdapter : Adapter<AccountHistoryHolder>() {
return AccountHistoryHolder(view, formatter).apply {
onSelect = { account -> onSelectEntry?.invoke(account) }
- onRemove = { account -> onRemoveEntry?.invoke(account) }
+ onRemove = { _ -> onRemoveEntry?.invoke() }
onFocusChanged = { account, hasFocus -> onChildFocusChanged?.invoke(account, hasFocus) }
}
}
override fun onBindViewHolder(holder: AccountHistoryHolder, position: Int) {
- holder.accountToken = accountHistory[position]
+ holder.accountToken = accountHistory ?: ""
}
- override fun getItemCount() = accountHistory.size
+ override fun getItemCount() = if (accountHistory !== null) 1 else 0
}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountLogin.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountLogin.kt
index e4256a9dc5..aa3463eb94 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountLogin.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/AccountLogin.kt
@@ -99,13 +99,12 @@ class AccountLogin : RelativeLayout {
val hasFocus
get() = focused
- var accountHistory by observable<List<String>?>(null) { _, _, history ->
- val entryCount = history?.size ?: 0
-
- historyHeight = entryCount * (historyEntryHeight + dividerHeight)
-
+ var accountHistory by observable<String?>(null) { _, _, history ->
if (history != null) {
+ historyHeight = historyEntryHeight + dividerHeight
historyAdapter.accountHistory = history
+ } else {
+ historyHeight = 0
}
}
@@ -123,7 +122,7 @@ class AccountLogin : RelativeLayout {
get() = input.onLogin
set(value) { input.onLogin = value }
- var onRemoveFromHistory: ((String) -> Unit)?
+ var onClearHistory: (() -> Unit)?
get() = historyAdapter.onRemoveEntry
set(value) { historyAdapter.onRemoveEntry = value }
diff --git a/gui/src/main/daemon-rpc.ts b/gui/src/main/daemon-rpc.ts
index 04332a4447..8ed75b8885 100644
--- a/gui/src/main/daemon-rpc.ts
+++ b/gui/src/main/daemon-rpc.ts
@@ -418,13 +418,13 @@ export class DaemonRpc {
}
}
- public async getAccountHistory(): Promise<AccountToken[]> {
+ public async getAccountHistory(): Promise<AccountToken | undefined> {
const response = await this.callEmpty<grpcTypes.AccountHistory>(this.client.getAccountHistory);
- return response.toObject().tokenList;
+ return response.getToken()?.getValue();
}
- public async removeAccountFromHistory(accountToken: AccountToken): Promise<void> {
- await this.callString(this.client.removeAccountFromHistory, accountToken);
+ public async clearAccountHistory(): Promise<void> {
+ await this.callEmpty(this.client.clearAccountHistory);
}
public async getCurrentVersion(): Promise<string> {
diff --git a/gui/src/main/index.ts b/gui/src/main/index.ts
index 2b9bc74a0a..d86a6cba53 100644
--- a/gui/src/main/index.ts
+++ b/gui/src/main/index.ts
@@ -115,7 +115,7 @@ class ApplicationMain {
private quitStage = AppQuitStage.unready;
private accountData?: IAccountData = undefined;
- private accountHistory: AccountToken[] = [];
+ private accountHistory?: AccountToken = undefined;
private tunnelState: TunnelState = { state: 'disconnected' };
private settings: ISettings = {
accountToken: undefined,
@@ -665,7 +665,7 @@ class ApplicationMain {
return daemonEventListener;
}
- private setAccountHistory(accountHistory: AccountToken[]) {
+ private setAccountHistory(accountHistory?: AccountToken) {
this.accountHistory = accountHistory;
if (this.windowController) {
@@ -1128,8 +1128,8 @@ class ApplicationMain {
this.daemonRpc.submitVoucher(voucherCode),
);
- IpcMainEventChannel.accountHistory.handleRemoveItem(async (token: AccountToken) => {
- await this.daemonRpc.removeAccountFromHistory(token);
+ IpcMainEventChannel.accountHistory.handleClear(async () => {
+ await this.daemonRpc.clearAccountHistory();
consumePromise(this.updateAccountHistory());
});
@@ -1162,8 +1162,8 @@ class ApplicationMain {
const reportPath = this.getProblemReportPath(id);
const executable = resolveBin('mullvad-problem-report');
const args = ['collect', '--output', reportPath];
- if (toRedact.length > 0) {
- args.push('--redact', ...toRedact);
+ if (toRedact) {
+ args.push('--redact', toRedact);
}
return new Promise((resolve, reject) => {
diff --git a/gui/src/renderer/app.tsx b/gui/src/renderer/app.tsx
index 7627428059..9fa0e4a456 100644
--- a/gui/src/renderer/app.tsx
+++ b/gui/src/renderer/app.tsx
@@ -148,7 +148,7 @@ export default class AppRenderer {
this.setAccountExpiry(newAccountData && newAccountData.expiry);
});
- IpcRendererEventChannel.accountHistory.listen((newAccountHistory: AccountToken[]) => {
+ IpcRendererEventChannel.accountHistory.listen((newAccountHistory?: AccountToken) => {
this.setAccountHistory(newAccountHistory);
});
@@ -337,8 +337,8 @@ export default class AppRenderer {
return IpcRendererEventChannel.settings.setDnsOptions(dns);
}
- public removeAccountFromHistory(accountToken: AccountToken): Promise<void> {
- return IpcRendererEventChannel.accountHistory.removeItem(accountToken);
+ public clearAccountHistory(): Promise<void> {
+ return IpcRendererEventChannel.accountHistory.clear();
}
public async openLinkWithAuth(link: string): Promise<void> {
@@ -455,7 +455,7 @@ export default class AppRenderer {
return IpcRendererEventChannel.splitTunneling.launchApplication(application);
}
- public collectProblemReport(toRedact: string[]): Promise<string> {
+ public collectProblemReport(toRedact?: string): Promise<string> {
return IpcRendererEventChannel.problemReport.collectLogs(toRedact);
}
@@ -653,7 +653,7 @@ export default class AppRenderer {
}
}
- private setAccountHistory(accountHistory: AccountToken[]) {
+ private setAccountHistory(accountHistory?: AccountToken) {
this.reduxActions.account.updateAccountHistory(accountHistory);
}
diff --git a/gui/src/renderer/components/Login.tsx b/gui/src/renderer/components/Login.tsx
index 6118f7ac8e..e672094f99 100644
--- a/gui/src/renderer/components/Login.tsx
+++ b/gui/src/renderer/components/Login.tsx
@@ -36,13 +36,13 @@ import { AriaControlGroup, AriaControlled, AriaControls } from './AriaGroup';
interface IProps {
accountToken?: AccountToken;
- accountHistory: AccountToken[];
+ accountHistory?: AccountToken;
loginState: LoginState;
openExternalLink: (type: string) => void;
login: (accountToken: AccountToken) => void;
resetLoginError: () => void;
updateAccountToken: (accountToken: AccountToken) => void;
- removeAccountTokenFromHistory: (accountToken: AccountToken) => Promise<void>;
+ clearAccountHistory: () => Promise<void>;
createNewAccount: () => void;
}
@@ -208,7 +208,9 @@ export default class Login extends React.Component<IProps, IState> {
}
private shouldShowAccountHistory() {
- return this.allowInteraction() && this.state.isActive && this.props.accountHistory.length > 0;
+ return (
+ this.allowInteraction() && this.state.isActive && this.props.accountHistory !== undefined
+ );
}
private shouldShowFooter() {
@@ -223,13 +225,13 @@ export default class Login extends React.Component<IProps, IState> {
this.props.login(accountToken);
};
- private onRemoveAccountFromHistory = (accountToken: string) => {
- consumePromise(this.removeAccountFromHistory(accountToken));
+ private onClearAccountHistory = () => {
+ consumePromise(this.clearAccountHistory());
};
- private async removeAccountFromHistory(accountToken: AccountToken) {
+ private async clearAccountHistory() {
try {
- await this.props.removeAccountTokenFromHistory(accountToken);
+ await this.props.clearAccountHistory();
// TODO: Remove account from memory
} catch (error) {
@@ -288,9 +290,9 @@ export default class Login extends React.Component<IProps, IState> {
<Accordion expanded={this.shouldShowAccountHistory()}>
<StyledAccountDropdownContainer>
<AccountDropdown
- items={this.props.accountHistory.slice().reverse()}
+ item={this.props.accountHistory}
onSelect={this.onSelectAccountFromHistory}
- onRemove={this.onRemoveAccountFromHistory}
+ onRemove={this.onClearAccountHistory}
/>
</StyledAccountDropdownContainer>
</Accordion>
@@ -316,28 +318,24 @@ export default class Login extends React.Component<IProps, IState> {
}
interface IAccountDropdownProps {
- items: AccountToken[];
+ item?: AccountToken;
onSelect: (value: AccountToken) => void;
onRemove: (value: AccountToken) => void;
}
function AccountDropdown(props: IAccountDropdownProps) {
- const uniqueItems = [...new Set(props.items)];
+ const token = props.item;
+ if (!token) {
+ return null;
+ }
+ const label = formatAccountToken(token);
return (
- <>
- {uniqueItems.map((token) => {
- const label = formatAccountToken(token);
- return (
- <AccountDropdownItem
- key={token}
- value={token}
- label={label}
- onSelect={props.onSelect}
- onRemove={props.onRemove}
- />
- );
- })}
- </>
+ <AccountDropdownItem
+ value={token}
+ label={label}
+ onSelect={props.onSelect}
+ onRemove={props.onRemove}
+ />
);
}
diff --git a/gui/src/renderer/components/Support.tsx b/gui/src/renderer/components/Support.tsx
index e7960a30c7..d34e6b6b08 100644
--- a/gui/src/renderer/components/Support.tsx
+++ b/gui/src/renderer/components/Support.tsx
@@ -49,13 +49,13 @@ interface ISupportState {
interface ISupportProps {
defaultEmail: string;
defaultMessage: string;
- accountHistory: AccountToken[];
+ accountHistory?: AccountToken;
isOffline: boolean;
onClose: () => void;
viewLog: (path: string) => void;
saveReportForm: (form: ISupportReportForm) => void;
clearReportForm: () => void;
- collectProblemReport: (accountsToRedact: string[]) => Promise<string>;
+ collectProblemReport: (accountToRedact?: string) => Promise<string>;
sendProblemReport: (email: string, message: string, savedReportId: string) => Promise<void>;
outdatedVersion: boolean;
suggestedIsBeta: boolean;
diff --git a/gui/src/renderer/containers/LoginPage.tsx b/gui/src/renderer/containers/LoginPage.tsx
index f937beb590..a56e6ec04a 100644
--- a/gui/src/renderer/containers/LoginPage.tsx
+++ b/gui/src/renderer/containers/LoginPage.tsx
@@ -25,7 +25,7 @@ const mapDispatchToProps = (dispatch: ReduxDispatch, props: IAppContext) => {
},
openExternalLink: (url: string) => props.app.openUrl(url),
updateAccountToken,
- removeAccountTokenFromHistory: (token: string) => props.app.removeAccountFromHistory(token),
+ clearAccountHistory: () => props.app.clearAccountHistory(),
createNewAccount: () => consumePromise(props.app.createNewAccount()),
};
};
diff --git a/gui/src/renderer/redux/account/actions.ts b/gui/src/renderer/redux/account/actions.ts
index 3c0bad3c7b..b8fbe94d39 100644
--- a/gui/src/renderer/redux/account/actions.ts
+++ b/gui/src/renderer/redux/account/actions.ts
@@ -44,7 +44,7 @@ interface IUpdateAccountTokenAction {
interface IUpdateAccountHistoryAction {
type: 'UPDATE_ACCOUNT_HISTORY';
- accountHistory: AccountToken[];
+ accountHistory?: AccountToken;
}
interface IUpdateAccountExpiryAction {
@@ -125,7 +125,7 @@ function updateAccountToken(token: AccountToken): IUpdateAccountTokenAction {
};
}
-function updateAccountHistory(accountHistory: AccountToken[]): IUpdateAccountHistoryAction {
+function updateAccountHistory(accountHistory?: AccountToken): IUpdateAccountHistoryAction {
return {
type: 'UPDATE_ACCOUNT_HISTORY',
accountHistory,
diff --git a/gui/src/renderer/redux/account/reducers.ts b/gui/src/renderer/redux/account/reducers.ts
index 8de7b2d07e..53bc55db1b 100644
--- a/gui/src/renderer/redux/account/reducers.ts
+++ b/gui/src/renderer/redux/account/reducers.ts
@@ -8,14 +8,14 @@ export type LoginState =
| { type: 'failed'; method: LoginMethod; error: Error };
export interface IAccountReduxState {
accountToken?: AccountToken;
- accountHistory: AccountToken[];
+ accountHistory?: AccountToken;
expiry?: string; // ISO8601
status: LoginState;
}
const initialState: IAccountReduxState = {
accountToken: undefined,
- accountHistory: [],
+ accountHistory: undefined,
expiry: undefined,
status: { type: 'none' },
};
diff --git a/gui/src/shared/ipc-schema.ts b/gui/src/shared/ipc-schema.ts
index 5cc347e51e..01c5c53a95 100644
--- a/gui/src/shared/ipc-schema.ts
+++ b/gui/src/shared/ipc-schema.ts
@@ -44,7 +44,7 @@ export interface IAppStateSnapshot {
isConnected: boolean;
autoStart: boolean;
accountData?: IAccountData;
- accountHistory: AccountToken[];
+ accountHistory?: AccountToken;
tunnelState: TunnelState;
settings: ISettings;
location?: ILocation;
@@ -165,8 +165,8 @@ export const ipcSchema = {
submitVoucher: invoke<string, VoucherResponse>(),
},
accountHistory: {
- '': notifyRenderer<AccountToken[]>(),
- removeItem: invoke<AccountToken, void>(),
+ '': notifyRenderer<AccountToken | undefined>(),
+ clear: invoke<void, void>(),
},
autoStart: {
'': notifyRenderer<boolean>(),
@@ -183,7 +183,7 @@ export const ipcSchema = {
launchApplication: invoke<ILinuxSplitTunnelingApplication | string, LaunchApplicationResult>(),
},
problemReport: {
- collectLogs: invoke<string[], string>(),
+ collectLogs: invoke<string | undefined, string>(),
sendReport: invoke<{ email: string; message: string; savedReportId: string }, void>(),
viewLog: invoke<string, string>(),
},
diff --git a/mullvad-cli/src/cmds/account.rs b/mullvad-cli/src/cmds/account.rs
index 803cabde00..af3af0debd 100644
--- a/mullvad-cli/src/cmds/account.rs
+++ b/mullvad-cli/src/cmds/account.rs
@@ -35,10 +35,6 @@ impl Command for Account {
.about("Removes the account number from the settings"),
)
.subcommand(
- clap::SubCommand::with_name("clear-history")
- .about("Clear account history, along with removing all associated keys"),
- )
- .subcommand(
clap::SubCommand::with_name("create")
.about("Creates a new account and sets it as the active one"),
)
@@ -75,8 +71,6 @@ impl Command for Account {
self.get().await
} else if let Some(_matches) = matches.subcommand_matches("unset") {
self.set(None).await
- } else if let Some(_matches) = matches.subcommand_matches("clear-history") {
- self.clear_history().await
} else if let Some(_matches) = matches.subcommand_matches("create") {
self.create().await
} else if let Some(matches) = matches.subcommand_matches("redeem") {
@@ -174,11 +168,4 @@ impl Account {
let utc = chrono::DateTime::<chrono::Utc>::from_utc(ndt, chrono::Utc);
utc.with_timezone(&chrono::Local).to_string()
}
-
- async fn clear_history(&self) -> Result<()> {
- let mut rpc = new_rpc_client().await?;
- rpc.clear_account_history(()).await?;
- println!("Removed account history and all associated keys");
- Ok(())
- }
}
diff --git a/mullvad-daemon/src/account_history.rs b/mullvad-daemon/src/account_history.rs
index 9db71c4000..4b83915ff7 100644
--- a/mullvad-daemon/src/account_history.rs
+++ b/mullvad-daemon/src/account_history.rs
@@ -101,7 +101,7 @@ impl AccountHistory {
.create(true)
.open(path)
.map_err(Error::Read)?,
- None,
+ settings.get_account_token(),
)
};
let file = io::BufWriter::new(file);
diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs
index b78fa9f26d..5aa94d4a85 100644
--- a/mullvad-daemon/src/lib.rs
+++ b/mullvad-daemon/src/lib.rs
@@ -198,10 +198,8 @@ pub enum DaemonCommand {
/// Submit voucher to add time to the current account. Returns time added in seconds
SubmitVoucher(ResponseTx<VoucherSubmission, Error>, String),
/// Request account history
- GetAccountHistory(oneshot::Sender<Vec<AccountToken>>),
- /// Request account history
- RemoveAccountFromHistory(ResponseTx<(), Error>, AccountToken),
- /// Clear account history
+ GetAccountHistory(oneshot::Sender<Option<AccountToken>>),
+ /// Remove the last used account, if there is one
ClearAccountHistory(ResponseTx<(), Error>),
/// Get the list of countries and cities where there are relays.
GetRelayLocations(oneshot::Sender<RelayList>),
@@ -1148,9 +1146,6 @@ where
UpdateRelayLocations => self.on_update_relay_locations().await,
SetAccount(tx, account_token) => self.on_set_account(tx, account_token).await,
GetAccountHistory(tx) => self.on_get_account_history(tx),
- RemoveAccountFromHistory(tx, account_token) => {
- self.on_remove_account_from_history(tx, account_token).await
- }
ClearAccountHistory(tx) => self.on_clear_account_history(tx).await,
UpdateRelaySettings(tx, update) => self.on_update_relay_settings(tx, update).await,
SetAllowLan(tx, allow_lan) => self.on_set_allow_lan(tx, allow_lan).await,
@@ -1559,31 +1554,21 @@ where
Ok(account_changed)
}
- fn on_get_account_history(&mut self, tx: oneshot::Sender<Vec<AccountToken>>) {
+ fn on_get_account_history(&mut self, tx: oneshot::Sender<Option<AccountToken>>) {
Self::oneshot_send(
tx,
- self.account_history
- .get()
- .map(|token| vec![token])
- .unwrap_or(vec![]),
+ self.account_history.get(),
"get_account_history response",
);
}
- async fn on_remove_account_from_history(
- &mut self,
- tx: ResponseTx<(), Error>,
- account_token: AccountToken,
- ) {
- let result = if self.account_history.get() == Some(account_token) {
- self.account_history
- .clear()
- .await
- .map_err(Error::AccountHistory)
- } else {
- Ok(())
- };
- Self::oneshot_send(tx, result, "remove_account_from_history response");
+ async fn on_clear_account_history(&mut self, tx: ResponseTx<(), Error>) {
+ let result = self
+ .account_history
+ .clear()
+ .await
+ .map_err(Error::AccountHistory);
+ Self::oneshot_send(tx, result, "clear_account_history response");
}
// Remove the key associated with the current account, if there is one.
@@ -1617,39 +1602,6 @@ where
}
}
- async fn on_clear_account_history(&mut self, tx: ResponseTx<(), Error>) {
- if let Err(error) = self.remove_current_key_rpc().await {
- Self::oneshot_send(tx, Err(error), "clear_account_history response");
- return;
- }
- if let Err(error) = self.account_history.clear().await {
- Self::oneshot_send(
- tx,
- Err(Error::ClearAccountHistoryError(error)),
- "clear_account_history response",
- );
- return;
- }
-
- match self.settings.set_wireguard(None).await {
- Ok(_) => {
- self.set_target_state(TargetState::Unsecured).await;
- Self::oneshot_send(tx, Ok(()), "clear_account_history response");
- }
- Err(err) => {
- log::error!(
- "{}",
- err.display_chain_with_msg("Failed to clear account history")
- );
- Self::oneshot_send(
- tx,
- Err(Error::SettingsError(err)),
- "clear_account_history response",
- );
- }
- }
- }
-
async fn on_get_version_info(&mut self, tx: oneshot::Sender<Option<AppVersionInfo>>) {
if self.app_version_info.is_none() {
log::debug!("No version cache found. Fetching new info");
diff --git a/mullvad-daemon/src/management_interface.rs b/mullvad-daemon/src/management_interface.rs
index 2dc7c83c4c..2b8bf31a10 100644
--- a/mullvad-daemon/src/management_interface.rs
+++ b/mullvad-daemon/src/management_interface.rs
@@ -434,7 +434,6 @@ impl ManagementService for ManagementServiceImpl {
}
async fn get_account_history(&self, _: Request<()>) -> ServiceResult<types::AccountHistory> {
- // TODO: this might be a stream
log::debug!("get_account_history");
let (tx, rx) = oneshot::channel();
self.send_command_to_daemon(DaemonCommand::GetAccountHistory(tx))?;
@@ -443,20 +442,6 @@ impl ManagementService for ManagementServiceImpl {
.map(|history| Response::new(types::AccountHistory { token: history }))
}
- async fn remove_account_from_history(
- &self,
- request: Request<AccountToken>,
- ) -> ServiceResult<()> {
- log::debug!("remove_account_from_history");
- let account_token = request.into_inner();
- let (tx, rx) = oneshot::channel();
- self.send_command_to_daemon(DaemonCommand::RemoveAccountFromHistory(tx, account_token))?;
- self.wait_for_result(rx)
- .await?
- .map(Response::new)
- .map_err(map_daemon_error)
- }
-
async fn clear_account_history(&self, _: Request<()>) -> ServiceResult<()> {
log::debug!("clear_account_history");
let (tx, rx) = oneshot::channel();
diff --git a/mullvad-jni/src/daemon_interface.rs b/mullvad-jni/src/daemon_interface.rs
index 777cee99c2..6f47fe21e8 100644
--- a/mullvad-jni/src/daemon_interface.rs
+++ b/mullvad-jni/src/daemon_interface.rs
@@ -1,7 +1,7 @@
use futures::{channel::oneshot, executor::block_on};
use mullvad_daemon::{DaemonCommand, DaemonCommandSender};
use mullvad_types::{
- account::{AccountData, VoucherSubmission},
+ account::{AccountData, AccountToken, VoucherSubmission},
location::GeoIpLocation,
relay_constraints::RelaySettingsUpdate,
relay_list::RelayList,
@@ -99,7 +99,7 @@ impl DaemonInterface {
.map_err(Error::RpcError)
}
- pub fn get_account_history(&self) -> Result<Vec<String>> {
+ pub fn get_account_history(&self) -> Result<Option<AccountToken>> {
let (tx, rx) = oneshot::channel();
self.send_command(DaemonCommand::GetAccountHistory(tx))?;
@@ -175,10 +175,10 @@ impl DaemonInterface {
Ok(())
}
- pub fn remove_account_from_history(&self, account_token: String) -> Result<()> {
+ pub fn clear_account_history(&self) -> Result<()> {
let (tx, rx) = oneshot::channel();
- self.send_command(DaemonCommand::RemoveAccountFromHistory(tx, account_token))?;
+ self.send_command(DaemonCommand::ClearAccountHistory(tx))?;
block_on(rx)
.map_err(|_| Error::NoResponse)?
diff --git a/mullvad-jni/src/lib.rs b/mullvad-jni/src/lib.rs
index 32d89a84cf..38c5e54423 100644
--- a/mullvad-jni/src/lib.rs
+++ b/mullvad-jni/src/lib.rs
@@ -510,13 +510,7 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_service_MullvadDaemon_getAcco
Some(daemon_interface) => daemon_interface
.get_account_history()
.map(|history| history.into_java(&env).forget())
- .unwrap_or_else(|err| {
- log::error!(
- "{}",
- err.display_chain_with_msg("Failed to get account history")
- );
- JObject::null()
- }),
+ .unwrap_or(JObject::null()),
None => JObject::null(),
}
}
@@ -758,21 +752,16 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_service_MullvadDaemon_reconne
#[no_mangle]
#[allow(non_snake_case)]
-pub extern "system" fn Java_net_mullvad_mullvadvpn_service_MullvadDaemon_removeAccountFromHistory(
- env: JNIEnv<'_>,
+pub extern "system" fn Java_net_mullvad_mullvadvpn_service_MullvadDaemon_clearAccountHistory(
+ _: JNIEnv<'_>,
_: JObject<'_>,
daemon_interface_address: jlong,
- accountToken: JString<'_>,
) {
- let env = JnixEnv::from(env);
-
if let Some(daemon_interface) = get_daemon_interface(daemon_interface_address) {
- let account = String::from_java(&env, accountToken);
-
- if let Err(error) = daemon_interface.remove_account_from_history(account) {
+ if let Err(error) = daemon_interface.clear_account_history() {
log::error!(
"{}",
- error.display_chain_with_msg("Failed to remove account from history")
+ error.display_chain_with_msg("Failed to clear account history")
);
}
}
diff --git a/mullvad-management-interface/proto/management_interface.proto b/mullvad-management-interface/proto/management_interface.proto
index faa5a73ffd..636148c7d6 100644
--- a/mullvad-management-interface/proto/management_interface.proto
+++ b/mullvad-management-interface/proto/management_interface.proto
@@ -47,7 +47,6 @@ service ManagementService {
rpc SetAccount(google.protobuf.StringValue) returns (google.protobuf.Empty) {}
rpc GetAccountData(google.protobuf.StringValue) returns (AccountData) {}
rpc GetAccountHistory(google.protobuf.Empty) returns (AccountHistory) {}
- rpc RemoveAccountFromHistory(google.protobuf.StringValue) returns (google.protobuf.Empty) {}
rpc ClearAccountHistory(google.protobuf.Empty) returns (google.protobuf.Empty) {}
rpc GetWwwAuthToken(google.protobuf.Empty) returns (google.protobuf.StringValue) {}
rpc SubmitVoucher(google.protobuf.StringValue) returns (VoucherSubmission) {}
@@ -77,6 +76,10 @@ message AccountData {
google.protobuf.Timestamp expiry = 1;
}
+message AccountHistory {
+ google.protobuf.StringValue token = 1;
+}
+
message VoucherSubmission {
uint64 seconds_added = 1;
google.protobuf.Timestamp new_expiry = 2;
@@ -201,10 +204,6 @@ message GeoIpLocation {
string bridge_hostname = 9;
}
-message AccountHistory {
- repeated string token = 1;
-}
-
message BridgeSettings {
message BridgeConstraints {
RelayLocation location = 1;