summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Göransson <david.goransson@mullvad.net>2026-04-02 11:21:28 +0200
committerDavid Göransson <david.goransson@mullvad.net>2026-04-02 11:21:28 +0200
commita124229440cd7c83450a00886f1bddbf99871f8b (patch)
tree2791fc72cb193723bd8a83eba9321ace11ee0af2
parentcc6fbb2731689317ae3a48625904dde15a5c1daf (diff)
parentd471cbeea9cc7858e194d25ee27874d91feff035 (diff)
downloadmullvadvpn-a124229440cd7c83450a00886f1bddbf99871f8b.tar.xz
mullvadvpn-a124229440cd7c83450a00886f1bddbf99871f8b.zip
Merge branch 'clean-up-obfuscation-id'
-rw-r--r--android/lib/billing/src/main/kotlin/net/mullvad/mullvadvpn/lib/billing/BillingPaymentRepository.kt13
-rw-r--r--android/lib/billing/src/main/kotlin/net/mullvad/mullvadvpn/lib/billing/BillingRepository.kt7
-rw-r--r--android/lib/billing/src/test/kotlin/net/mullvad/mullvadvpn/lib/billing/BillingPaymentRepositoryTest.kt23
-rw-r--r--android/lib/billing/src/test/kotlin/net/mullvad/mullvadvpn/lib/billing/BillingRepositoryTest.kt9
-rw-r--r--android/lib/grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/grpc/ManagementService.kt5
-rw-r--r--android/lib/grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/grpc/mapper/ToDomain.kt6
-rw-r--r--android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/PlayExternalObfuscatedAccountId.kt3
-rw-r--r--desktop/packages/management-interface/dist/management_interface_grpc_pb.d.ts20
-rw-r--r--desktop/packages/management-interface/dist/management_interface_grpc_pb.js26
-rw-r--r--desktop/packages/management-interface/dist/management_interface_pb.d.ts20
-rw-r--r--desktop/packages/management-interface/dist/management_interface_pb.js152
-rw-r--r--mullvad-api/src/lib.rs4
-rw-r--r--mullvad-daemon/src/device/mod.rs8
-rw-r--r--mullvad-daemon/src/lib.rs6
-rw-r--r--mullvad-daemon/src/management_interface.rs14
-rw-r--r--mullvad-management-interface/proto/management_interface.proto4
-rw-r--r--mullvad-management-interface/src/types/conversions/account.rs11
-rw-r--r--mullvad-types/src/account.rs5
18 files changed, 271 insertions, 65 deletions
diff --git a/android/lib/billing/src/main/kotlin/net/mullvad/mullvadvpn/lib/billing/BillingPaymentRepository.kt b/android/lib/billing/src/main/kotlin/net/mullvad/mullvadvpn/lib/billing/BillingPaymentRepository.kt
index 2c9d72b188..9964ee71d3 100644
--- a/android/lib/billing/src/main/kotlin/net/mullvad/mullvadvpn/lib/billing/BillingPaymentRepository.kt
+++ b/android/lib/billing/src/main/kotlin/net/mullvad/mullvadvpn/lib/billing/BillingPaymentRepository.kt
@@ -22,6 +22,7 @@ import net.mullvad.mullvadvpn.lib.billing.extension.toPaymentStatus
import net.mullvad.mullvadvpn.lib.billing.extension.toPurchaseResult
import net.mullvad.mullvadvpn.lib.billing.model.BillingException
import net.mullvad.mullvadvpn.lib.billing.model.PurchaseEvent
+import net.mullvad.mullvadvpn.lib.model.PlayExternalObfuscatedAccountId
import net.mullvad.mullvadvpn.lib.model.PlayPurchase
import net.mullvad.mullvadvpn.lib.model.PlayPurchaseInitError
import net.mullvad.mullvadvpn.lib.model.PlayPurchasePaymentToken
@@ -83,7 +84,7 @@ class BillingPaymentRepository(
// Get transaction id
emit(PurchaseResult.FetchingObfuscationId)
- val obfuscatedId: PlayPurchasePaymentToken =
+ val obfuscatedId: PlayExternalObfuscatedAccountId =
initializePurchase()
.fold(
{
@@ -96,7 +97,7 @@ class BillingPaymentRepository(
val result =
billingRepository.startPurchaseFlow(
productDetails = productDetails,
- obfuscatedId = obfuscatedId.value,
+ obfuscatedId = obfuscatedId,
activityProvider = activityProvider,
)
@@ -126,7 +127,7 @@ class BillingPaymentRepository(
} else {
emit(PurchaseResult.VerificationStarted)
emit(
- verifyPurchase(event.purchases.first())
+ verifyPurchase(purchase)
.fold(
{ PurchaseResult.Error.VerificationError(null) },
{ productId -> PurchaseResult.Completed.Success(productId) },
@@ -160,7 +161,7 @@ class BillingPaymentRepository(
if (it.value.isNotEmpty()) {
it.right()
} else {
- Logger.e("PlayPurchasePaymentToken is empty")
+ Logger.e("Obfuscated account id is empty")
PlayPurchaseInitError.OtherError.left()
}
}
@@ -173,6 +174,10 @@ class BillingPaymentRepository(
Logger.e("Purchase has no products")
PlayPurchaseVerifyError.OtherError
}
+ ensure(purchase.accountIdentifiers?.obfuscatedAccountId != null) {
+ Logger.e("Purchase is missing obfuscatedAccountId")
+ PlayPurchaseVerifyError.OtherError
+ }
ensure(purchase.purchaseToken.isNotEmpty()) {
Logger.e("Purchase has no purchase token")
PlayPurchaseVerifyError.OtherError
diff --git a/android/lib/billing/src/main/kotlin/net/mullvad/mullvadvpn/lib/billing/BillingRepository.kt b/android/lib/billing/src/main/kotlin/net/mullvad/mullvadvpn/lib/billing/BillingRepository.kt
index 78ab7a6f35..463188837c 100644
--- a/android/lib/billing/src/main/kotlin/net/mullvad/mullvadvpn/lib/billing/BillingRepository.kt
+++ b/android/lib/billing/src/main/kotlin/net/mullvad/mullvadvpn/lib/billing/BillingRepository.kt
@@ -28,6 +28,7 @@ import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import net.mullvad.mullvadvpn.lib.billing.model.BillingException
import net.mullvad.mullvadvpn.lib.billing.model.PurchaseEvent
+import net.mullvad.mullvadvpn.lib.model.PlayExternalObfuscatedAccountId
class BillingRepository(context: Context) {
@@ -118,13 +119,13 @@ class BillingRepository(context: Context) {
suspend fun startPurchaseFlow(
productDetails: ProductDetails,
- obfuscatedId: String,
+ obfuscatedId: PlayExternalObfuscatedAccountId,
activityProvider: () -> Activity,
): BillingResult {
return try {
ensureConnected()
- if (obfuscatedId.isEmpty()) {
+ if (obfuscatedId.value.isEmpty()) {
Logger.e("Obfuscated id is empty")
return BillingResult.newBuilder().setResponseCode(BillingResponseCode.ERROR).build()
}
@@ -139,7 +140,7 @@ class BillingRepository(context: Context) {
val billingFlowParams =
BillingFlowParams.newBuilder()
.setProductDetailsParamsList(productDetailsParamsList)
- .setObfuscatedAccountId(obfuscatedId)
+ .setObfuscatedAccountId(obfuscatedId.value)
.build()
val activity = activityProvider()
diff --git a/android/lib/billing/src/test/kotlin/net/mullvad/mullvadvpn/lib/billing/BillingPaymentRepositoryTest.kt b/android/lib/billing/src/test/kotlin/net/mullvad/mullvadvpn/lib/billing/BillingPaymentRepositoryTest.kt
index 97815d41ee..9c0ae33398 100644
--- a/android/lib/billing/src/test/kotlin/net/mullvad/mullvadvpn/lib/billing/BillingPaymentRepositoryTest.kt
+++ b/android/lib/billing/src/test/kotlin/net/mullvad/mullvadvpn/lib/billing/BillingPaymentRepositoryTest.kt
@@ -3,6 +3,7 @@ package net.mullvad.mullvadvpn.lib.billing
import app.cash.turbine.test
import arrow.core.left
import arrow.core.right
+import com.android.billingclient.api.AccountIdentifiers
import com.android.billingclient.api.BillingClient.BillingResponseCode
import com.android.billingclient.api.BillingResult
import com.android.billingclient.api.ProductDetails
@@ -19,8 +20,8 @@ import kotlinx.coroutines.test.runTest
import net.mullvad.mullvadvpn.lib.billing.extension.toPaymentProduct
import net.mullvad.mullvadvpn.lib.billing.model.PurchaseEvent
import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
+import net.mullvad.mullvadvpn.lib.model.PlayExternalObfuscatedAccountId
import net.mullvad.mullvadvpn.lib.model.PlayPurchaseInitError
-import net.mullvad.mullvadvpn.lib.model.PlayPurchasePaymentToken
import net.mullvad.mullvadvpn.lib.model.PlayPurchaseVerifyError
import net.mullvad.mullvadvpn.lib.payment.model.PaymentAvailability
import net.mullvad.mullvadvpn.lib.payment.model.PaymentProduct
@@ -197,7 +198,7 @@ class BillingPaymentRepositoryTest {
coEvery { mockBillingRepository.queryProducts(listOf(mockProductId.value)) } returns
mockProductDetailsResult
coEvery { mockPlayPurchaseRepository.initializePlayPurchase() } returns
- PlayPurchasePaymentToken("").right()
+ PlayExternalObfuscatedAccountId("").right()
// Act, Assert
paymentRepository.purchaseProduct(mockProductId, mockk()).test {
@@ -233,7 +234,7 @@ class BillingPaymentRepositoryTest {
)
} returns mockBillingResult
coEvery { mockPlayPurchaseRepository.initializePlayPurchase() } returns
- PlayPurchasePaymentToken("MOCK").right()
+ PlayExternalObfuscatedAccountId("MOCK").right()
// Act, Assert
paymentRepository.purchaseProduct(mockProductId, mockk()).test {
@@ -257,7 +258,7 @@ class BillingPaymentRepositoryTest {
every { mockProductDetailsResult.productDetailsList } returns listOf(mockProductDetails)
coEvery { mockBillingRepository.queryProducts(listOf(mockProductId.value)) } returns
mockProductDetailsResult
- val mockObfuscatedId = "MOCK-ID"
+ val mockObfuscatedId = PlayExternalObfuscatedAccountId("MOCK-ID")
val mockBillingResult: BillingResult = mockk()
every { mockBillingResult.responseCode } returns BillingResponseCode.OK
coEvery {
@@ -268,7 +269,7 @@ class BillingPaymentRepositoryTest {
)
} returns mockBillingResult
coEvery { mockPlayPurchaseRepository.initializePlayPurchase() } returns
- PlayPurchasePaymentToken(mockObfuscatedId).right()
+ mockObfuscatedId.right()
// Act, Assert
paymentRepository.purchaseProduct(mockProductId, mockk()).test {
@@ -298,10 +299,13 @@ class BillingPaymentRepositoryTest {
val mockPurchaseToken = "TOKEN"
val mockBillingPurchase: Purchase = mockk()
val mockBillingResult: BillingResult = mockk()
+ val mockAccountIdentifiers: AccountIdentifiers = mockk()
every { mockBillingPurchase.purchaseState } returns Purchase.PurchaseState.PURCHASED
every { mockBillingResult.responseCode } returns BillingResponseCode.OK
every { mockBillingPurchase.products } returns listOf(mockProductId.value)
every { mockBillingPurchase.purchaseToken } returns mockPurchaseToken
+ every { mockBillingPurchase.accountIdentifiers } returns mockAccountIdentifiers
+ every { mockAccountIdentifiers.obfuscatedAccountId } returns "Something"
coEvery {
mockBillingRepository.startPurchaseFlow(
productDetails = any(),
@@ -310,7 +314,7 @@ class BillingPaymentRepositoryTest {
)
} returns mockBillingResult
coEvery { mockPlayPurchaseRepository.initializePlayPurchase() } returns
- PlayPurchasePaymentToken("MOCK-ID").right()
+ PlayExternalObfuscatedAccountId("MOCK-ID").right()
coEvery { mockPlayPurchaseRepository.verifyPlayPurchase(any()) } returns
PlayPurchaseVerifyError.OtherError.left()
@@ -341,10 +345,13 @@ class BillingPaymentRepositoryTest {
val mockPurchaseToken = "TOKEN"
val mockBillingPurchase: Purchase = mockk()
val mockBillingResult: BillingResult = mockk()
+ val mockAccountIdentifiers: AccountIdentifiers = mockk()
every { mockBillingPurchase.purchaseState } returns Purchase.PurchaseState.PURCHASED
every { mockBillingResult.responseCode } returns BillingResponseCode.OK
every { mockBillingPurchase.products } returns listOf(mockProductId.value)
every { mockBillingPurchase.purchaseToken } returns mockPurchaseToken
+ every { mockBillingPurchase.accountIdentifiers } returns mockAccountIdentifiers
+ every { mockAccountIdentifiers.obfuscatedAccountId } returns "Something"
coEvery {
mockBillingRepository.startPurchaseFlow(
productDetails = any(),
@@ -353,7 +360,7 @@ class BillingPaymentRepositoryTest {
)
} returns mockBillingResult
coEvery { mockPlayPurchaseRepository.initializePlayPurchase() } returns
- PlayPurchasePaymentToken("MOCK").right()
+ PlayExternalObfuscatedAccountId("MOCK").right()
coEvery { mockPlayPurchaseRepository.verifyPlayPurchase(any()) } returns Unit.right()
// Act, Assert
@@ -395,7 +402,7 @@ class BillingPaymentRepositoryTest {
)
} returns mockBillingResult
coEvery { mockPlayPurchaseRepository.initializePlayPurchase() } returns
- PlayPurchasePaymentToken("MOCK").right()
+ PlayExternalObfuscatedAccountId("MOCK").right()
// Act, Assert
paymentRepository.purchaseProduct(mockProductId, mockk()).test {
diff --git a/android/lib/billing/src/test/kotlin/net/mullvad/mullvadvpn/lib/billing/BillingRepositoryTest.kt b/android/lib/billing/src/test/kotlin/net/mullvad/mullvadvpn/lib/billing/BillingRepositoryTest.kt
index bce573a6b6..cdb59430b0 100644
--- a/android/lib/billing/src/test/kotlin/net/mullvad/mullvadvpn/lib/billing/BillingRepositoryTest.kt
+++ b/android/lib/billing/src/test/kotlin/net/mullvad/mullvadvpn/lib/billing/BillingRepositoryTest.kt
@@ -34,6 +34,7 @@ import net.mullvad.mullvadvpn.lib.billing.model.BillingException
import net.mullvad.mullvadvpn.lib.billing.model.PurchaseEvent
import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
import net.mullvad.mullvadvpn.lib.common.test.assertLists
+import net.mullvad.mullvadvpn.lib.model.PlayExternalObfuscatedAccountId
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
@@ -153,7 +154,7 @@ class BillingRepositoryTest {
// Arrange
val mockProductBillingResult: BillingResult = mockk()
val mockBillingResult: BillingResult = mockk()
- val transactionId = "MOCK22"
+ val obfuscatedAccountId = PlayExternalObfuscatedAccountId("MOCK22")
val mockProductDetails: ProductDetails = mockk(relaxed = true)
val mockActivityProvider: () -> Activity = mockk()
every { mockBillingResult.responseCode } returns BillingResponseCode.OK
@@ -169,7 +170,7 @@ class BillingRepositoryTest {
val result =
billingRepository.startPurchaseFlow(
mockProductDetails,
- transactionId,
+ obfuscatedAccountId,
mockActivityProvider,
)
@@ -182,7 +183,7 @@ class BillingRepositoryTest {
runTest {
// Arrange
val mockBillingResult: BillingResult = mockk()
- val transactionId = "MOCK22"
+ val transactionId = PlayExternalObfuscatedAccountId("MOCK22")
val mockProductDetails: ProductDetails = mockk(relaxed = true)
val mockActivityProvider: () -> Activity = mockk()
every { mockBillingResult.responseCode } returns BillingResponseCode.BILLING_UNAVAILABLE
@@ -208,7 +209,7 @@ class BillingRepositoryTest {
@Test
fun `starting purchase flow with empty transaction id should return error`() = runTest {
// Arrange
- val transactionId = ""
+ val transactionId = PlayExternalObfuscatedAccountId("")
val mockProductDetails: ProductDetails = mockk(relaxed = true)
val mockActivityProvider: () -> Activity = mockk()
every { mockBillingClient.isReady } returns true
diff --git a/android/lib/grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/grpc/ManagementService.kt b/android/lib/grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/grpc/ManagementService.kt
index e0522df9dd..05266556f7 100644
--- a/android/lib/grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/grpc/ManagementService.kt
+++ b/android/lib/grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/grpc/ManagementService.kt
@@ -93,9 +93,9 @@ import net.mullvad.mullvadvpn.lib.model.NewAccessMethodSetting
import net.mullvad.mullvadvpn.lib.model.ObfuscationMode
import net.mullvad.mullvadvpn.lib.model.ObfuscationSettings
import net.mullvad.mullvadvpn.lib.model.Ownership as ModelOwnership
+import net.mullvad.mullvadvpn.lib.model.PlayExternalObfuscatedAccountId
import net.mullvad.mullvadvpn.lib.model.PlayPurchase
import net.mullvad.mullvadvpn.lib.model.PlayPurchaseInitError
-import net.mullvad.mullvadvpn.lib.model.PlayPurchasePaymentToken
import net.mullvad.mullvadvpn.lib.model.PlayPurchaseVerifyError
import net.mullvad.mullvadvpn.lib.model.Port
import net.mullvad.mullvadvpn.lib.model.Providers
@@ -796,7 +796,8 @@ class ManagementService(
}
}
- suspend fun initializePlayPurchase(): Either<PlayPurchaseInitError, PlayPurchasePaymentToken> =
+ suspend fun initializePlayPurchase():
+ Either<PlayPurchaseInitError, PlayExternalObfuscatedAccountId> =
Either.catch { grpc.initPlayPurchase(Empty.getDefaultInstance()).toDomain() }
.onLeft { Logger.e("Initialize play purchase error") }
.mapLeft { PlayPurchaseInitError.OtherError }
diff --git a/android/lib/grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/grpc/mapper/ToDomain.kt b/android/lib/grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/grpc/mapper/ToDomain.kt
index 91924b4d35..96b9cab684 100644
--- a/android/lib/grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/grpc/mapper/ToDomain.kt
+++ b/android/lib/grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/grpc/mapper/ToDomain.kt
@@ -55,7 +55,7 @@ import net.mullvad.mullvadvpn.lib.model.ObfuscationSettings
import net.mullvad.mullvadvpn.lib.model.ObfuscationType
import net.mullvad.mullvadvpn.lib.model.Ownership
import net.mullvad.mullvadvpn.lib.model.ParameterGenerationError
-import net.mullvad.mullvadvpn.lib.model.PlayPurchasePaymentToken
+import net.mullvad.mullvadvpn.lib.model.PlayExternalObfuscatedAccountId
import net.mullvad.mullvadvpn.lib.model.Port
import net.mullvad.mullvadvpn.lib.model.PortRange
import net.mullvad.mullvadvpn.lib.model.ProviderId
@@ -670,8 +670,8 @@ internal fun ManagementInterface.SplitTunnelSettings.toDomain(): SplitTunnelSett
excludedApps = appsList.map { AppId(it) }.toSet(),
)
-internal fun ManagementInterface.PlayPurchasePaymentToken.toDomain(): PlayPurchasePaymentToken =
- PlayPurchasePaymentToken(value = token)
+internal fun ManagementInterface.PlayExternalObfuscatedAccountId.toDomain():
+ PlayExternalObfuscatedAccountId = PlayExternalObfuscatedAccountId(value = id)
internal fun ManagementInterface.ApiAccessMethodSettings.toDomain(): List<ApiAccessMethodSetting> =
buildList {
diff --git a/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/PlayExternalObfuscatedAccountId.kt b/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/PlayExternalObfuscatedAccountId.kt
new file mode 100644
index 0000000000..9404d2b6d0
--- /dev/null
+++ b/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/PlayExternalObfuscatedAccountId.kt
@@ -0,0 +1,3 @@
+package net.mullvad.mullvadvpn.lib.model
+
+@JvmInline value class PlayExternalObfuscatedAccountId(val value: String)
diff --git a/desktop/packages/management-interface/dist/management_interface_grpc_pb.d.ts b/desktop/packages/management-interface/dist/management_interface_grpc_pb.d.ts
index 51d3363bb6..6bbf42de4d 100644
--- a/desktop/packages/management-interface/dist/management_interface_grpc_pb.d.ts
+++ b/desktop/packages/management-interface/dist/management_interface_grpc_pb.d.ts
@@ -762,14 +762,14 @@ interface IManagementServiceService_IGetExcludedProcesses extends grpc.MethodDef
responseSerialize: grpc.serialize<management_interface_pb.ExcludedProcessList>;
responseDeserialize: grpc.deserialize<management_interface_pb.ExcludedProcessList>;
}
-interface IManagementServiceService_IInitPlayPurchase extends grpc.MethodDefinition<google_protobuf_empty_pb.Empty, management_interface_pb.PlayPurchasePaymentToken> {
+interface IManagementServiceService_IInitPlayPurchase extends grpc.MethodDefinition<google_protobuf_empty_pb.Empty, management_interface_pb.PlayExternalObfuscatedAccountId> {
path: "/mullvad_daemon.management_interface.ManagementService/InitPlayPurchase";
requestStream: false;
responseStream: false;
requestSerialize: grpc.serialize<google_protobuf_empty_pb.Empty>;
requestDeserialize: grpc.deserialize<google_protobuf_empty_pb.Empty>;
- responseSerialize: grpc.serialize<management_interface_pb.PlayPurchasePaymentToken>;
- responseDeserialize: grpc.deserialize<management_interface_pb.PlayPurchasePaymentToken>;
+ responseSerialize: grpc.serialize<management_interface_pb.PlayExternalObfuscatedAccountId>;
+ responseDeserialize: grpc.deserialize<management_interface_pb.PlayExternalObfuscatedAccountId>;
}
interface IManagementServiceService_IVerifyPlayPurchase extends grpc.MethodDefinition<management_interface_pb.PlayPurchase, google_protobuf_empty_pb.Empty> {
path: "/mullvad_daemon.management_interface.ManagementService/VerifyPlayPurchase";
@@ -1001,7 +1001,7 @@ export interface IManagementServiceServer extends grpc.UntypedServiceImplementat
setSplitTunnelState: grpc.handleUnaryCall<google_protobuf_wrappers_pb.BoolValue, google_protobuf_empty_pb.Empty>;
clearSplitTunnelApps: grpc.handleUnaryCall<google_protobuf_empty_pb.Empty, google_protobuf_empty_pb.Empty>;
getExcludedProcesses: grpc.handleUnaryCall<google_protobuf_empty_pb.Empty, management_interface_pb.ExcludedProcessList>;
- initPlayPurchase: grpc.handleUnaryCall<google_protobuf_empty_pb.Empty, management_interface_pb.PlayPurchasePaymentToken>;
+ initPlayPurchase: grpc.handleUnaryCall<google_protobuf_empty_pb.Empty, management_interface_pb.PlayExternalObfuscatedAccountId>;
verifyPlayPurchase: grpc.handleUnaryCall<management_interface_pb.PlayPurchase, google_protobuf_empty_pb.Empty>;
needFullDiskPermissions: grpc.handleUnaryCall<google_protobuf_empty_pb.Empty, google_protobuf_wrappers_pb.BoolValue>;
checkVolumes: grpc.handleUnaryCall<google_protobuf_empty_pb.Empty, google_protobuf_empty_pb.Empty>;
@@ -1239,9 +1239,9 @@ export interface IManagementServiceClient {
getExcludedProcesses(request: google_protobuf_empty_pb.Empty, callback: (error: grpc.ServiceError | null, response: management_interface_pb.ExcludedProcessList) => void): grpc.ClientUnaryCall;
getExcludedProcesses(request: google_protobuf_empty_pb.Empty, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: management_interface_pb.ExcludedProcessList) => void): grpc.ClientUnaryCall;
getExcludedProcesses(request: google_protobuf_empty_pb.Empty, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: management_interface_pb.ExcludedProcessList) => void): grpc.ClientUnaryCall;
- initPlayPurchase(request: google_protobuf_empty_pb.Empty, callback: (error: grpc.ServiceError | null, response: management_interface_pb.PlayPurchasePaymentToken) => void): grpc.ClientUnaryCall;
- initPlayPurchase(request: google_protobuf_empty_pb.Empty, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: management_interface_pb.PlayPurchasePaymentToken) => void): grpc.ClientUnaryCall;
- initPlayPurchase(request: google_protobuf_empty_pb.Empty, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: management_interface_pb.PlayPurchasePaymentToken) => void): grpc.ClientUnaryCall;
+ initPlayPurchase(request: google_protobuf_empty_pb.Empty, callback: (error: grpc.ServiceError | null, response: management_interface_pb.PlayExternalObfuscatedAccountId) => void): grpc.ClientUnaryCall;
+ initPlayPurchase(request: google_protobuf_empty_pb.Empty, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: management_interface_pb.PlayExternalObfuscatedAccountId) => void): grpc.ClientUnaryCall;
+ initPlayPurchase(request: google_protobuf_empty_pb.Empty, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: management_interface_pb.PlayExternalObfuscatedAccountId) => void): grpc.ClientUnaryCall;
verifyPlayPurchase(request: management_interface_pb.PlayPurchase, callback: (error: grpc.ServiceError | null, response: google_protobuf_empty_pb.Empty) => void): grpc.ClientUnaryCall;
verifyPlayPurchase(request: management_interface_pb.PlayPurchase, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: google_protobuf_empty_pb.Empty) => void): grpc.ClientUnaryCall;
verifyPlayPurchase(request: management_interface_pb.PlayPurchase, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: google_protobuf_empty_pb.Empty) => void): grpc.ClientUnaryCall;
@@ -1512,9 +1512,9 @@ export class ManagementServiceClient extends grpc.Client implements IManagementS
public getExcludedProcesses(request: google_protobuf_empty_pb.Empty, callback: (error: grpc.ServiceError | null, response: management_interface_pb.ExcludedProcessList) => void): grpc.ClientUnaryCall;
public getExcludedProcesses(request: google_protobuf_empty_pb.Empty, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: management_interface_pb.ExcludedProcessList) => void): grpc.ClientUnaryCall;
public getExcludedProcesses(request: google_protobuf_empty_pb.Empty, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: management_interface_pb.ExcludedProcessList) => void): grpc.ClientUnaryCall;
- public initPlayPurchase(request: google_protobuf_empty_pb.Empty, callback: (error: grpc.ServiceError | null, response: management_interface_pb.PlayPurchasePaymentToken) => void): grpc.ClientUnaryCall;
- public initPlayPurchase(request: google_protobuf_empty_pb.Empty, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: management_interface_pb.PlayPurchasePaymentToken) => void): grpc.ClientUnaryCall;
- public initPlayPurchase(request: google_protobuf_empty_pb.Empty, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: management_interface_pb.PlayPurchasePaymentToken) => void): grpc.ClientUnaryCall;
+ public initPlayPurchase(request: google_protobuf_empty_pb.Empty, callback: (error: grpc.ServiceError | null, response: management_interface_pb.PlayExternalObfuscatedAccountId) => void): grpc.ClientUnaryCall;
+ public initPlayPurchase(request: google_protobuf_empty_pb.Empty, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: management_interface_pb.PlayExternalObfuscatedAccountId) => void): grpc.ClientUnaryCall;
+ public initPlayPurchase(request: google_protobuf_empty_pb.Empty, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: management_interface_pb.PlayExternalObfuscatedAccountId) => void): grpc.ClientUnaryCall;
public verifyPlayPurchase(request: management_interface_pb.PlayPurchase, callback: (error: grpc.ServiceError | null, response: google_protobuf_empty_pb.Empty) => void): grpc.ClientUnaryCall;
public verifyPlayPurchase(request: management_interface_pb.PlayPurchase, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: google_protobuf_empty_pb.Empty) => void): grpc.ClientUnaryCall;
public verifyPlayPurchase(request: management_interface_pb.PlayPurchase, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: google_protobuf_empty_pb.Empty) => void): grpc.ClientUnaryCall;
diff --git a/desktop/packages/management-interface/dist/management_interface_grpc_pb.js b/desktop/packages/management-interface/dist/management_interface_grpc_pb.js
index f07ed529ce..a6664a655a 100644
--- a/desktop/packages/management-interface/dist/management_interface_grpc_pb.js
+++ b/desktop/packages/management-interface/dist/management_interface_grpc_pb.js
@@ -316,26 +316,26 @@ function deserialize_mullvad_daemon_management_interface_ObfuscationSettings(buf
return management_interface_pb.ObfuscationSettings.deserializeBinary(new Uint8Array(buffer_arg));
}
-function serialize_mullvad_daemon_management_interface_PlayPurchase(arg) {
- if (!(arg instanceof management_interface_pb.PlayPurchase)) {
- throw new Error('Expected argument of type mullvad_daemon.management_interface.PlayPurchase');
+function serialize_mullvad_daemon_management_interface_PlayExternalObfuscatedAccountId(arg) {
+ if (!(arg instanceof management_interface_pb.PlayExternalObfuscatedAccountId)) {
+ throw new Error('Expected argument of type mullvad_daemon.management_interface.PlayExternalObfuscatedAccountId');
}
return Buffer.from(arg.serializeBinary());
}
-function deserialize_mullvad_daemon_management_interface_PlayPurchase(buffer_arg) {
- return management_interface_pb.PlayPurchase.deserializeBinary(new Uint8Array(buffer_arg));
+function deserialize_mullvad_daemon_management_interface_PlayExternalObfuscatedAccountId(buffer_arg) {
+ return management_interface_pb.PlayExternalObfuscatedAccountId.deserializeBinary(new Uint8Array(buffer_arg));
}
-function serialize_mullvad_daemon_management_interface_PlayPurchasePaymentToken(arg) {
- if (!(arg instanceof management_interface_pb.PlayPurchasePaymentToken)) {
- throw new Error('Expected argument of type mullvad_daemon.management_interface.PlayPurchasePaymentToken');
+function serialize_mullvad_daemon_management_interface_PlayPurchase(arg) {
+ if (!(arg instanceof management_interface_pb.PlayPurchase)) {
+ throw new Error('Expected argument of type mullvad_daemon.management_interface.PlayPurchase');
}
return Buffer.from(arg.serializeBinary());
}
-function deserialize_mullvad_daemon_management_interface_PlayPurchasePaymentToken(buffer_arg) {
- return management_interface_pb.PlayPurchasePaymentToken.deserializeBinary(new Uint8Array(buffer_arg));
+function deserialize_mullvad_daemon_management_interface_PlayPurchase(buffer_arg) {
+ return management_interface_pb.PlayPurchase.deserializeBinary(new Uint8Array(buffer_arg));
}
function serialize_mullvad_daemon_management_interface_PublicKey(arg) {
@@ -1290,11 +1290,11 @@ initPlayPurchase: {
requestStream: false,
responseStream: false,
requestType: google_protobuf_empty_pb.Empty,
- responseType: management_interface_pb.PlayPurchasePaymentToken,
+ responseType: management_interface_pb.PlayExternalObfuscatedAccountId,
requestSerialize: serialize_google_protobuf_Empty,
requestDeserialize: deserialize_google_protobuf_Empty,
- responseSerialize: serialize_mullvad_daemon_management_interface_PlayPurchasePaymentToken,
- responseDeserialize: deserialize_mullvad_daemon_management_interface_PlayPurchasePaymentToken,
+ responseSerialize: serialize_mullvad_daemon_management_interface_PlayExternalObfuscatedAccountId,
+ responseDeserialize: deserialize_mullvad_daemon_management_interface_PlayExternalObfuscatedAccountId,
},
verifyPlayPurchase: {
path: '/mullvad_daemon.management_interface.ManagementService/VerifyPlayPurchase',
diff --git a/desktop/packages/management-interface/dist/management_interface_pb.d.ts b/desktop/packages/management-interface/dist/management_interface_pb.d.ts
index 7bf62a78f9..0abc998706 100644
--- a/desktop/packages/management-interface/dist/management_interface_pb.d.ts
+++ b/desktop/packages/management-interface/dist/management_interface_pb.d.ts
@@ -3228,6 +3228,26 @@ export namespace LeakInfo {
}
}
+export class PlayExternalObfuscatedAccountId extends jspb.Message {
+ getId(): string;
+ setId(value: string): PlayExternalObfuscatedAccountId;
+
+ serializeBinary(): Uint8Array;
+ toObject(includeInstance?: boolean): PlayExternalObfuscatedAccountId.AsObject;
+ static toObject(includeInstance: boolean, msg: PlayExternalObfuscatedAccountId): PlayExternalObfuscatedAccountId.AsObject;
+ static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
+ static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
+ static serializeBinaryToWriter(message: PlayExternalObfuscatedAccountId, writer: jspb.BinaryWriter): void;
+ static deserializeBinary(bytes: Uint8Array): PlayExternalObfuscatedAccountId;
+ static deserializeBinaryFromReader(message: PlayExternalObfuscatedAccountId, reader: jspb.BinaryReader): PlayExternalObfuscatedAccountId;
+}
+
+export namespace PlayExternalObfuscatedAccountId {
+ export type AsObject = {
+ id: string,
+ }
+}
+
export class PlayPurchase extends jspb.Message {
getProductId(): string;
setProductId(value: string): PlayPurchase;
diff --git a/desktop/packages/management-interface/dist/management_interface_pb.js b/desktop/packages/management-interface/dist/management_interface_pb.js
index a8375479f3..cc5e4f8bc8 100644
--- a/desktop/packages/management-interface/dist/management_interface_pb.js
+++ b/desktop/packages/management-interface/dist/management_interface_pb.js
@@ -111,6 +111,7 @@ goog.exportSymbol('proto.mullvad_daemon.management_interface.ObfuscationSettings
goog.exportSymbol('proto.mullvad_daemon.management_interface.ObfuscationSettings.Udp2TcpObfuscation', null, global);
goog.exportSymbol('proto.mullvad_daemon.management_interface.ObfuscationSettings.WireguardPort', null, global);
goog.exportSymbol('proto.mullvad_daemon.management_interface.Ownership', null, global);
+goog.exportSymbol('proto.mullvad_daemon.management_interface.PlayExternalObfuscatedAccountId', null, global);
goog.exportSymbol('proto.mullvad_daemon.management_interface.PlayPurchase', null, global);
goog.exportSymbol('proto.mullvad_daemon.management_interface.PlayPurchasePaymentToken', null, global);
goog.exportSymbol('proto.mullvad_daemon.management_interface.PortRange', null, global);
@@ -2291,6 +2292,27 @@ if (goog.DEBUG && !COMPILED) {
* @extends {jspb.Message}
* @constructor
*/
+proto.mullvad_daemon.management_interface.PlayExternalObfuscatedAccountId = function(opt_data) {
+ jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.mullvad_daemon.management_interface.PlayExternalObfuscatedAccountId, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+ /**
+ * @public
+ * @override
+ */
+ proto.mullvad_daemon.management_interface.PlayExternalObfuscatedAccountId.displayName = 'proto.mullvad_daemon.management_interface.PlayExternalObfuscatedAccountId';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
proto.mullvad_daemon.management_interface.PlayPurchase = function(opt_data) {
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
@@ -24916,6 +24938,136 @@ if (jspb.Message.GENERATE_TO_OBJECT) {
* http://goto/soy-param-migration
* @return {!Object}
*/
+proto.mullvad_daemon.management_interface.PlayExternalObfuscatedAccountId.prototype.toObject = function(opt_includeInstance) {
+ return proto.mullvad_daemon.management_interface.PlayExternalObfuscatedAccountId.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ * the JSPB instance for transitional soy proto support:
+ * http://goto/soy-param-migration
+ * @param {!proto.mullvad_daemon.management_interface.PlayExternalObfuscatedAccountId} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.mullvad_daemon.management_interface.PlayExternalObfuscatedAccountId.toObject = function(includeInstance, msg) {
+ var f, obj = {
+ id: jspb.Message.getFieldWithDefault(msg, 1, "")
+ };
+
+ if (includeInstance) {
+ obj.$jspbMessageInstance = msg;
+ }
+ return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.mullvad_daemon.management_interface.PlayExternalObfuscatedAccountId}
+ */
+proto.mullvad_daemon.management_interface.PlayExternalObfuscatedAccountId.deserializeBinary = function(bytes) {
+ var reader = new jspb.BinaryReader(bytes);
+ var msg = new proto.mullvad_daemon.management_interface.PlayExternalObfuscatedAccountId;
+ return proto.mullvad_daemon.management_interface.PlayExternalObfuscatedAccountId.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.mullvad_daemon.management_interface.PlayExternalObfuscatedAccountId} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.mullvad_daemon.management_interface.PlayExternalObfuscatedAccountId}
+ */
+proto.mullvad_daemon.management_interface.PlayExternalObfuscatedAccountId.deserializeBinaryFromReader = function(msg, reader) {
+ while (reader.nextField()) {
+ if (reader.isEndGroup()) {
+ break;
+ }
+ var field = reader.getFieldNumber();
+ switch (field) {
+ case 1:
+ var value = /** @type {string} */ (reader.readString());
+ msg.setId(value);
+ break;
+ default:
+ reader.skipField();
+ break;
+ }
+ }
+ return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.mullvad_daemon.management_interface.PlayExternalObfuscatedAccountId.prototype.serializeBinary = function() {
+ var writer = new jspb.BinaryWriter();
+ proto.mullvad_daemon.management_interface.PlayExternalObfuscatedAccountId.serializeBinaryToWriter(this, writer);
+ return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.mullvad_daemon.management_interface.PlayExternalObfuscatedAccountId} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.mullvad_daemon.management_interface.PlayExternalObfuscatedAccountId.serializeBinaryToWriter = function(message, writer) {
+ var f = undefined;
+ f = message.getId();
+ if (f.length > 0) {
+ writer.writeString(
+ 1,
+ f
+ );
+ }
+};
+
+
+/**
+ * optional string id = 1;
+ * @return {string}
+ */
+proto.mullvad_daemon.management_interface.PlayExternalObfuscatedAccountId.prototype.getId = function() {
+ return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.mullvad_daemon.management_interface.PlayExternalObfuscatedAccountId} returns this
+ */
+proto.mullvad_daemon.management_interface.PlayExternalObfuscatedAccountId.prototype.setId = function(value) {
+ return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ * net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ * JSPB instance for transitional soy proto support:
+ * http://goto/soy-param-migration
+ * @return {!Object}
+ */
proto.mullvad_daemon.management_interface.PlayPurchase.prototype.toObject = function(opt_includeInstance) {
return proto.mullvad_daemon.management_interface.PlayPurchase.toObject(opt_includeInstance, this);
};
diff --git a/mullvad-api/src/lib.rs b/mullvad-api/src/lib.rs
index 5761d79ac5..c3feee218f 100644
--- a/mullvad-api/src/lib.rs
+++ b/mullvad-api/src/lib.rs
@@ -5,7 +5,7 @@ use futures::channel::mpsc;
use hyper::body::Incoming;
use mullvad_types::account::{AccountData, AccountNumber, VoucherSubmission};
#[cfg(target_os = "android")]
-use mullvad_types::account::{PlayPurchase, PlayPurchasePaymentToken};
+use mullvad_types::account::{PlayExternalObfuscatedAccountId, PlayPurchase};
use proxy::{ApiConnectionMode, ConnectionModeProvider};
use std::{collections::BTreeMap, future::Future, io, net::SocketAddr, path::Path, sync::Arc};
use talpid_types::ErrorExt;
@@ -642,7 +642,7 @@ impl AccountsProxy {
pub fn init_play_purchase(
&mut self,
account: AccountNumber,
- ) -> impl Future<Output = Result<PlayPurchasePaymentToken, rest::Error>> + use<> {
+ ) -> impl Future<Output = Result<PlayExternalObfuscatedAccountId, rest::Error>> + use<> {
#[derive(serde::Deserialize)]
struct PlayPurchaseInitResponse {
obfuscated_id: String,
diff --git a/mullvad-daemon/src/device/mod.rs b/mullvad-daemon/src/device/mod.rs
index 535c11c83d..6e14efbc3d 100644
--- a/mullvad-daemon/src/device/mod.rs
+++ b/mullvad-daemon/src/device/mod.rs
@@ -6,7 +6,9 @@ use futures::{
use mullvad_api::rest;
#[cfg(target_os = "android")]
-use mullvad_types::account::{PlayPurchase, PlayPurchasePaymentToken};
+use mullvad_types::account::{
+ PlayExternalObfuscatedAccountId, PlayPurchase, PlayPurchasePaymentToken,
+};
use mullvad_types::{
account::{AccountNumber, VoucherSubmission},
device::{
@@ -304,7 +306,7 @@ enum AccountManagerCommand {
ValidateDevice(ResponseTx<()>),
SubmitVoucher(String, ResponseTx<VoucherSubmission>),
#[cfg(target_os = "android")]
- InitPlayPurchase(ResponseTx<PlayPurchasePaymentToken>),
+ InitPlayPurchase(ResponseTx<PlayExternalObfuscatedAccountId>),
#[cfg(target_os = "android")]
VerifyPlayPurchase(ResponseTx<()>, PlayPurchase),
CheckExpiry(ResponseTx<DateTime<Utc>>),
@@ -368,7 +370,7 @@ impl AccountManagerHandle {
}
#[cfg(target_os = "android")]
- pub async fn init_play_purchase(&self) -> Result<PlayPurchasePaymentToken, Error> {
+ pub async fn init_play_purchase(&self) -> Result<PlayExternalObfuscatedAccountId, Error> {
self.send_command(AccountManagerCommand::InitPlayPurchase)
.await
}
diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs
index ff4a6906d4..becdd3039c 100644
--- a/mullvad-daemon/src/lib.rs
+++ b/mullvad-daemon/src/lib.rs
@@ -49,7 +49,7 @@ use mullvad_api::{
use mullvad_encrypted_dns_proxy::state::EncryptedDnsProxyState;
use mullvad_relay_selector::{Config, RelaySelector};
#[cfg(target_os = "android")]
-use mullvad_types::account::{PlayPurchase, PlayPurchasePaymentToken};
+use mullvad_types::account::{PlayExternalObfuscatedAccountId, PlayPurchase};
#[cfg(any(target_os = "windows", target_os = "android", target_os = "macos"))]
use mullvad_types::settings::SplitApp;
#[cfg(daita)]
@@ -418,7 +418,7 @@ pub enum DaemonCommand {
BypassSocket(RawFd, oneshot::Sender<()>),
/// Initialize a google play purchase through the API.
#[cfg(target_os = "android")]
- InitPlayPurchase(ResponseTx<PlayPurchasePaymentToken, Error>),
+ InitPlayPurchase(ResponseTx<PlayExternalObfuscatedAccountId, Error>),
/// Verify that a google play payment was successful through the API.
#[cfg(target_os = "android")]
VerifyPlayPurchase(ResponseTx<(), Error>, PlayPurchase),
@@ -3392,7 +3392,7 @@ impl Daemon {
}
#[cfg(target_os = "android")]
- fn on_init_play_purchase(&mut self, tx: ResponseTx<PlayPurchasePaymentToken, Error>) {
+ fn on_init_play_purchase(&mut self, tx: ResponseTx<PlayExternalObfuscatedAccountId, Error>) {
let manager = self.account_manager.clone();
tokio::spawn(async move {
Self::oneshot_send(
diff --git a/mullvad-daemon/src/management_interface.rs b/mullvad-daemon/src/management_interface.rs
index fcb24ded90..d26adb2812 100644
--- a/mullvad-daemon/src/management_interface.rs
+++ b/mullvad-daemon/src/management_interface.rs
@@ -1088,19 +1088,19 @@ impl ManagementService for ManagementServiceImpl {
async fn init_play_purchase(
&self,
_request: Request<()>,
- ) -> ServiceResult<types::PlayPurchasePaymentToken> {
+ ) -> ServiceResult<types::PlayExternalObfuscatedAccountId> {
log::debug!("init_play_purchase");
let (tx, rx) = oneshot::channel();
self.send_command_to_daemon(DaemonCommand::InitPlayPurchase(tx))?;
- let payment_token = self
+ let external_obufscated_account_id = self
.wait_for_result(rx)
.await?
- .map(types::PlayPurchasePaymentToken::from)
+ .map(types::PlayExternalObfuscatedAccountId::from)
.map_err(map_daemon_error)?;
- Ok(Response::new(payment_token))
+ Ok(Response::new(external_obufscated_account_id))
}
/// On non-Android platforms, the return value will be useless.
@@ -1108,10 +1108,10 @@ impl ManagementService for ManagementServiceImpl {
async fn init_play_purchase(
&self,
_: Request<()>,
- ) -> ServiceResult<types::PlayPurchasePaymentToken> {
+ ) -> ServiceResult<types::PlayExternalObfuscatedAccountId> {
log::error!("Called `init_play_purchase` on non-Android platform");
- Ok(Response::new(types::PlayPurchasePaymentToken {
- token: String::default(),
+ Ok(Response::new(types::PlayExternalObfuscatedAccountId {
+ id: String::default(),
}))
}
diff --git a/mullvad-management-interface/proto/management_interface.proto b/mullvad-management-interface/proto/management_interface.proto
index 79bd7474ab..14fc1800b1 100644
--- a/mullvad-management-interface/proto/management_interface.proto
+++ b/mullvad-management-interface/proto/management_interface.proto
@@ -118,7 +118,7 @@ service ManagementService {
rpc GetExcludedProcesses(google.protobuf.Empty) returns (ExcludedProcessList) {}
// Play payment (Android)
- rpc InitPlayPurchase(google.protobuf.Empty) returns (PlayPurchasePaymentToken) {}
+ rpc InitPlayPurchase(google.protobuf.Empty) returns (PlayExternalObfuscatedAccountId) {}
rpc VerifyPlayPurchase(PlayPurchase) returns (google.protobuf.Empty) {}
// Check whether the app needs TCC approval for split tunneling (macOS)
@@ -850,6 +850,8 @@ message LeakInfo {
string interface = 2;
}
+message PlayExternalObfuscatedAccountId { string id = 1; }
+
message PlayPurchase {
string product_id = 1;
PlayPurchasePaymentToken purchase_token = 2;
diff --git a/mullvad-management-interface/src/types/conversions/account.rs b/mullvad-management-interface/src/types/conversions/account.rs
index 8354658e6e..262811bdaf 100644
--- a/mullvad-management-interface/src/types/conversions/account.rs
+++ b/mullvad-management-interface/src/types/conversions/account.rs
@@ -2,7 +2,9 @@ use crate::types;
use chrono::DateTime;
use mullvad_types::account::{AccountData, VoucherSubmission};
#[cfg(target_os = "android")]
-use mullvad_types::account::{PlayPurchase, PlayPurchasePaymentToken};
+use mullvad_types::account::{
+ PlayExternalObfuscatedAccountId, PlayPurchase, PlayPurchasePaymentToken,
+};
use super::FromProtobufTypeError;
@@ -92,3 +94,10 @@ impl From<PlayPurchasePaymentToken> for types::PlayPurchasePaymentToken {
Self { token }
}
}
+
+#[cfg(target_os = "android")]
+impl From<PlayExternalObfuscatedAccountId> for types::PlayExternalObfuscatedAccountId {
+ fn from(id: PlayExternalObfuscatedAccountId) -> Self {
+ Self { id }
+ }
+}
diff --git a/mullvad-types/src/account.rs b/mullvad-types/src/account.rs
index 9940bbb657..5460c5fa46 100644
--- a/mullvad-types/src/account.rs
+++ b/mullvad-types/src/account.rs
@@ -10,9 +10,12 @@ pub type AccessToken = String;
/// Account identifier (not used for authentication).
pub type AccountId = String;
-/// The payment token returned by initiating a google play purchase.
+/// The external obfuscated id returned by initiating a google play purchase.
/// In the API this is called the `obfuscated_id`.
#[cfg(target_os = "android")]
+pub type PlayExternalObfuscatedAccountId = String;
+
+#[cfg(target_os = "android")]
pub type PlayPurchasePaymentToken = String;
/// Account expiration info returned by the API via `/v1/me`.