From 68b5ba6474e08bfb352606bcd0806f4c9116cadc Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Tue, 17 Sep 2019 22:58:38 -0400 Subject: [PATCH] update to apple iap service --- src/Core/Services/IAppleIapService.cs | 10 ++- .../Implementations/AppleIapService.cs | 72 ++++++++----------- 2 files changed, 34 insertions(+), 48 deletions(-) diff --git a/src/Core/Services/IAppleIapService.cs b/src/Core/Services/IAppleIapService.cs index 73bfaca38a..021d8d5028 100644 --- a/src/Core/Services/IAppleIapService.cs +++ b/src/Core/Services/IAppleIapService.cs @@ -1,15 +1,13 @@ using System; using System.Threading.Tasks; +using Bit.Billing.Models; namespace Bit.Core.Services { public interface IAppleIapService { - Task VerifyReceiptAsync(string receiptData); - Task GetVerifiedLastTransactionIdAsync(string receiptData); - Task GetVerifiedLastExpiresDateAsync(string receiptData); - string HashReceipt(string receiptData); - Task SaveReceiptAsync(string receiptData); - Task GetReceiptAsync(string hash); + Task GetVerifiedReceiptStatusAsync(string receiptData); + Task SaveReceiptAsync(AppleReceiptStatus receiptStatus); + Task> GetReceiptAsync(string originalTransactionId); } } diff --git a/src/Core/Services/Implementations/AppleIapService.cs b/src/Core/Services/Implementations/AppleIapService.cs index 6e832fad12..cca24e26e7 100644 --- a/src/Core/Services/Implementations/AppleIapService.cs +++ b/src/Core/Services/Implementations/AppleIapService.cs @@ -34,47 +34,7 @@ namespace Bit.Core.Services.Implementations _logger = logger; } - public async Task VerifyReceiptAsync(string receiptData) - { - var receiptStatus = await GetVerifiedReceiptStatusAsync(receiptData); - return receiptStatus != null; - } - - public async Task GetVerifiedLastTransactionIdAsync(string receiptData) - { - var receiptStatus = await GetVerifiedReceiptStatusAsync(receiptData); - return receiptStatus?.LatestReceiptInfo?.LastOrDefault()?.TransactionId; - } - - public async Task GetVerifiedLastExpiresDateAsync(string receiptData) - { - var receiptStatus = await GetVerifiedReceiptStatusAsync(receiptData); - return receiptStatus?.LatestReceiptInfo?.LastOrDefault()?.ExpiresDate; - } - - public string HashReceipt(string receiptData) - { - using(var sha256 = SHA256.Create()) - { - var hash = sha256.ComputeHash(Convert.FromBase64String(receiptData)); - return BitConverter.ToString(hash).Replace("-", string.Empty); - } - } - - public async Task SaveReceiptAsync(string receiptData) - { - var hash = HashReceipt(receiptData); - await _metaDataRespository.UpsertAsync("appleReceipt", hash, - new KeyValuePair("data", receiptData)); - } - - public async Task GetReceiptAsync(string hash) - { - var receipt = await _metaDataRespository.GetAsync("appleReceipt", hash); - return receipt != null && receipt.ContainsKey("data") ? receipt["data"] : null; - } - - private async Task GetVerifiedReceiptStatusAsync(string receiptData) + public async Task GetVerifiedReceiptStatusAsync(string receiptData) { var receiptStatus = await GetReceiptStatusAsync(receiptData); if(receiptStatus?.Status != 0) @@ -86,13 +46,41 @@ namespace Bit.Core.Services.Implementations var validProductBundle = receiptStatus.Receipt.BundleId == "com.bitwarden.desktop" || receiptStatus.Receipt.BundleId == "com.8bit.bitwarden"; var validProduct = receiptStatus.LatestReceiptInfo.LastOrDefault()?.ProductId == "premium_annually"; - if(validEnvironment && validProductBundle && validProduct) + if(validEnvironment && validProductBundle && validProduct && + receiptStatus.GetOriginalTransactionId() != null && + receiptStatus.GetLastTransactionId() != null) { return receiptStatus; } return null; } + public async Task SaveReceiptAsync(AppleReceiptStatus receiptStatus) + { + var originalTransactionId = receiptStatus.GetOriginalTransactionId(); + if(string.IsNullOrWhiteSpace(originalTransactionId)) + { + throw new Exception("OriginalTransactionId is null"); + } + await _metaDataRespository.UpsertAsync("AppleReceipt", originalTransactionId, + new Dictionary + { + ["Data"] = receiptStatus.GetReceiptData(), + ["UserId"] = receiptStatus.GetReceiptData() + }); + } + + public async Task> GetReceiptAsync(string originalTransactionId) + { + var receipt = await _metaDataRespository.GetAsync("AppleReceipt", originalTransactionId); + if(receipt == null) + { + return null; + } + return new Tuple(receipt.ContainsKey("Data") ? receipt["Data"] : null, + receipt.ContainsKey("UserId") ? new Guid(receipt["UserId"]) : (Guid?)null); + } + private async Task GetReceiptStatusAsync(string receiptData, bool prod = true, int attempt = 0, AppleReceiptStatus lastReceiptStatus = null) {