mirror of
https://github.com/bitwarden/server.git
synced 2025-02-28 03:51:23 +01:00
apple iap service
This commit is contained in:
parent
7a2e86c2ba
commit
8290ddbb94
@ -1,9 +1,15 @@
|
||||
using System.Threading.Tasks;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
public interface IAppleIapService
|
||||
{
|
||||
Task<bool> VerifyReceiptAsync(string receiptData);
|
||||
Task<string> GetVerifiedLastTransactionIdAsync(string receiptData);
|
||||
Task<DateTime?> GetVerifiedLastExpiresDateAsync(string receiptData);
|
||||
string HashReceipt(string receiptData);
|
||||
Task SaveReceiptAsync(string receiptData);
|
||||
Task<string> GetReceiptAsync(string hash);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Billing.Models;
|
||||
using Bit.Core.Repositories;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
@ -13,20 +18,79 @@ namespace Bit.Core.Services.Implementations
|
||||
private readonly HttpClient _httpClient = new HttpClient();
|
||||
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
private readonly IHostingEnvironment _hostingEnvironment;
|
||||
private readonly IMetaDataRespository _metaDataRespository;
|
||||
private readonly ILogger<AppleIapService> _logger;
|
||||
|
||||
public AppleIapService(
|
||||
GlobalSettings globalSettings,
|
||||
IHostingEnvironment hostingEnvironment,
|
||||
IMetaDataRespository metaDataRespository,
|
||||
ILogger<AppleIapService> logger)
|
||||
{
|
||||
_globalSettings = globalSettings;
|
||||
_hostingEnvironment = hostingEnvironment;
|
||||
_metaDataRespository = metaDataRespository;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<bool> VerifyReceiptAsync(string receiptData)
|
||||
{
|
||||
var receiptStatus = await GetVerifiedReceiptStatusAsync(receiptData);
|
||||
return receiptStatus != null;
|
||||
}
|
||||
|
||||
public async Task<string> GetVerifiedLastTransactionIdAsync(string receiptData)
|
||||
{
|
||||
var receiptStatus = await GetVerifiedReceiptStatusAsync(receiptData);
|
||||
return receiptStatus?.LatestReceiptInfo?.LastOrDefault()?.TransactionId;
|
||||
}
|
||||
|
||||
public async Task<DateTime?> 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<string, string>("data", receiptData));
|
||||
}
|
||||
|
||||
public async Task<string> GetReceiptAsync(string hash)
|
||||
{
|
||||
var receipt = await _metaDataRespository.GetAsync("appleReceipt", hash);
|
||||
return receipt != null && receipt.ContainsKey("data") ? receipt["data"] : null;
|
||||
}
|
||||
|
||||
private async Task<AppleReceiptStatus> GetVerifiedReceiptStatusAsync(string receiptData)
|
||||
{
|
||||
var receiptStatus = await GetReceiptStatusAsync(receiptData);
|
||||
return receiptStatus?.Status == 0;
|
||||
if(receiptStatus?.Status != 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var validEnvironment = (!_hostingEnvironment.IsProduction() && receiptStatus.Environment == "Sandbox") ||
|
||||
(_hostingEnvironment.IsProduction() && receiptStatus.Environment != "Sandbox");
|
||||
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)
|
||||
{
|
||||
return receiptStatus;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private async Task<AppleReceiptStatus> GetReceiptStatusAsync(string receiptData, bool prod = true,
|
||||
|
Loading…
Reference in New Issue
Block a user