Skip to content

Commit d963ed0

Browse files
committed
Add CSharpier
1 parent 6915b2f commit d963ed0

14 files changed

+283
-174
lines changed

.config/dotnet-tools.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"version": 1,
3+
"isRoot": true,
4+
"tools": {
5+
"csharpier": {
6+
"version": "0.30.6",
7+
"commands": ["dotnet-csharpier"],
8+
"rollForward": false
9+
}
10+
}
11+
}

.editorconfig

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
trim_trailing_whitespace = true
7+
indent_style = space
8+
max_line_length = 120
9+
10+
[{*.ts,*.xml,*.csproj,*.yml,*.yaml,*.json,*.sh}]
11+
indent_size = 2
12+
13+
[*.cs]
14+
indent_size = 4

.github/workflows/build.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ jobs:
1515

1616
steps:
1717
- uses: actions/checkout@v4
18+
- run: |
19+
dotnet tool restore
20+
dotnet csharpier --check .
1821
1922
- name: Setup .NET
2023
uses: actions/setup-dotnet@v4

src/AppStoreServerApiClient.cs

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
using System.Text;
55
using System.Text.Json;
66
using System.Web;
7-
using Mimo.AppStoreServerLibrary.Exceptions;
8-
using Mimo.AppStoreServerLibrary.Models;
97
using Microsoft.IdentityModel.JsonWebTokens;
108
using Microsoft.IdentityModel.Tokens;
9+
using Mimo.AppStoreServerLibrary.Exceptions;
10+
using Mimo.AppStoreServerLibrary.Models;
1111

1212
namespace Mimo.AppStoreServerLibrary;
1313

@@ -26,7 +26,8 @@ public class AppStoreServerApiClient(
2626
string issuerId,
2727
string bundleId,
2828
AppStoreEnvironment environment,
29-
HttpClient? httpClient = null)
29+
HttpClient? httpClient = null
30+
)
3031
{
3132
private readonly HttpClient httpClient = httpClient ?? new HttpClient();
3233

@@ -50,7 +51,8 @@ public Task<SubscriptionStatusResponse> GetAllSubscriptionStatuses(string transa
5051
/// <returns>A list of notifications and their attempts</returns>
5152
public Task<NotificationHistoryResponse?> GetNotificationHistory(
5253
NotificationHistoryRequest notificationHistoryRequest,
53-
string paginationToken = "")
54+
string paginationToken = ""
55+
)
5456
{
5557
//Call to https://developer.apple.com/documentation/appstoreserverapi/get_notification_history
5658
Dictionary<string, string> queryParameters = new();
@@ -61,17 +63,19 @@ public Task<SubscriptionStatusResponse> GetAllSubscriptionStatuses(string transa
6163

6264
string path = $"v1/notifications/history";
6365

64-
return this.MakeRequest<NotificationHistoryResponse>(path, HttpMethod.Post, queryParameters,
65-
notificationHistoryRequest);
66+
return this.MakeRequest<NotificationHistoryResponse>(
67+
path,
68+
HttpMethod.Post,
69+
queryParameters,
70+
notificationHistoryRequest
71+
);
6672
}
6773

6874
/// <summary>
6975
/// Get a customer’s in-app purchase transaction history for your app.
7076
/// </summary>
7177
/// <returns>A list of transactions associated with the provided Transaction Id</returns>
72-
public Task<TransactionHistoryResponse?> GetTransactionHistory(
73-
string transactionId,
74-
string revisionToken = "")
78+
public Task<TransactionHistoryResponse?> GetTransactionHistory(string transactionId, string revisionToken = "")
7579
{
7680
//Call to https://developer.apple.com/documentation/appstoreserverapi/get_transaction_history
7781
Dictionary<string, string> queryParameters = new();
@@ -114,15 +118,12 @@ private static string CreateBearerToken(string keyId, string issuerId, string si
114118
{
115119
{ "iss", issuerId },
116120
{ "aud", "appstoreconnect-v1" },
117-
{ "bid", bundleId }
121+
{ "bid", bundleId },
118122
},
119-
TokenType = "JWT"
123+
TokenType = "JWT",
120124
};
121125

122-
var securityKey = new ECDsaSecurityKey(prvKey)
123-
{
124-
KeyId = keyId
125-
};
126+
var securityKey = new ECDsaSecurityKey(prvKey) { KeyId = keyId };
126127

127128
securityDescriptor.SigningCredentials = new SigningCredentials(securityKey, "ES256");
128129

@@ -134,7 +135,9 @@ private static string CreateBearerToken(string keyId, string issuerId, string si
134135
HttpMethod method,
135136
Dictionary<string, string>? queryParameters = null,
136137
object? body = null,
137-
bool fetchResponse = true) where TReturn : class
138+
bool fetchResponse = true
139+
)
140+
where TReturn : class
138141
{
139142
string token = CreateBearerToken(keyId, issuerId, signingKey, bundleId);
140143

@@ -153,10 +156,7 @@ private static string CreateBearerToken(string keyId, string issuerId, string si
153156
builder.Query = query.ToString();
154157
}
155158

156-
var jsonOptions = new JsonSerializerOptions
157-
{
158-
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
159-
};
159+
var jsonOptions = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
160160

161161
try
162162
{
@@ -168,23 +168,28 @@ private static string CreateBearerToken(string keyId, string issuerId, string si
168168
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
169169
httpResponse = await this.httpClient.SendAsync(request);
170170
}
171-
172171
else if (method == HttpMethod.Post)
173172
{
174173
var request = new HttpRequestMessage(HttpMethod.Post, builder.Uri);
175174
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
176-
request.Content = new StringContent(JsonSerializer.Serialize(body, jsonOptions), Encoding.UTF8, "application/json");
175+
request.Content = new StringContent(
176+
JsonSerializer.Serialize(body, jsonOptions),
177+
Encoding.UTF8,
178+
"application/json"
179+
);
177180
httpResponse = await this.httpClient.SendAsync(request);
178181
}
179-
180182
else if (method == HttpMethod.Put)
181183
{
182184
var request = new HttpRequestMessage(HttpMethod.Put, builder.Uri);
183185
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
184-
request.Content = new StringContent(JsonSerializer.Serialize(body, jsonOptions), Encoding.UTF8, "application/json");
186+
request.Content = new StringContent(
187+
JsonSerializer.Serialize(body, jsonOptions),
188+
Encoding.UTF8,
189+
"application/json"
190+
);
185191
httpResponse = await this.httpClient.SendAsync(request);
186192
}
187-
188193
else
189194
{
190195
throw new NotSupportedException($"Method {method} not supported");
@@ -200,12 +205,10 @@ private static string CreateBearerToken(string keyId, string issuerId, string si
200205
var error = JsonSerializer.Deserialize<ErrorResponse>(responseContent, jsonOptions);
201206

202207
throw new ApiException(httpResponse.StatusCode, error);
203-
204208
}
205-
206209
catch (HttpRequestException ex)
207210
{
208211
throw new ApiException(ex.StatusCode, null, ex);
209212
}
210213
}
211-
}
214+
}

src/Exceptions/ApiException.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33

44
namespace Mimo.AppStoreServerLibrary.Exceptions;
55

6-
public class ApiException(HttpStatusCode? httpStatusCode, ErrorResponse? errorResponse = null, Exception? innerException = null) : Exception(errorResponse?.ErrorMessage, innerException)
6+
public class ApiException(
7+
HttpStatusCode? httpStatusCode,
8+
ErrorResponse? errorResponse = null,
9+
Exception? innerException = null
10+
) : Exception(errorResponse?.ErrorMessage, innerException)
711
{
812
public HttpStatusCode? HttpStatusCode { get; } = httpStatusCode;
913

@@ -13,6 +17,7 @@ public class ApiException(HttpStatusCode? httpStatusCode, ErrorResponse? errorRe
1317

1418
public override string ToString()
1519
{
16-
return base.ToString() + $" HttpStatusCode: {this.HttpStatusCode}, ApiErrorCode: {this.ApiErrorCode}, ApiErrorMessage: {this.ApiErrorMessage}";
20+
return base.ToString()
21+
+ $" HttpStatusCode: {this.HttpStatusCode}, ApiErrorCode: {this.ApiErrorCode}, ApiErrorMessage: {this.ApiErrorMessage}";
1722
}
18-
}
23+
}
Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
21
namespace Mimo.AppStoreServerLibrary.Exceptions;
32

4-
public class VerificationException(string message) : Exception(message)
5-
{
6-
7-
}
3+
public class VerificationException(string message) : Exception(message) { }

src/Models/AppStoreDataTypes.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -487,10 +487,9 @@ public enum TransactionsItemSubscriptionStatus
487487
/// <summary>
488488
/// The auto-renewable subscription is revoked.
489489
/// </summary>
490-
Revoked = 5
490+
Revoked = 5,
491491
}
492492

493-
494493
/// <summary>
495494
/// The request body for notification history.
496495
/// https://developer.apple.com/documentation/appstoreserverapi/notificationhistoryrequest
@@ -604,12 +603,11 @@ public class TransactionHistoryResponse
604603
public List<string> SignedTransactions { get; set; } = null!;
605604
}
606605

607-
608606
/// <summary>
609607
/// Error response from the App Store Server API.
610608
/// </summary>
611609
public class ErrorResponse
612610
{
613611
public int ErrorCode { get; set; } = 0;
614612
public string ErrorMessage { get; set; } = null!;
615-
}
613+
}

src/Models/AppStoreEnvironment.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,23 @@ namespace Mimo.AppStoreServerLibrary.Models;
22

33
public record AppStoreEnvironment
44
{
5-
public static readonly AppStoreEnvironment Sandbox = new("Sandbox", new Uri("https://api.storekit-sandbox.itunes.apple.com/inApps"));
5+
public static readonly AppStoreEnvironment Sandbox = new(
6+
"Sandbox",
7+
new Uri("https://api.storekit-sandbox.itunes.apple.com/inApps")
8+
);
69

7-
public static readonly AppStoreEnvironment Production = new("Production", new Uri("https://api.storekit.itunes.apple.com/inApps"));
10+
public static readonly AppStoreEnvironment Production = new(
11+
"Production",
12+
new Uri("https://api.storekit.itunes.apple.com/inApps")
13+
);
814

915
/// <summary>
1016
/// Environment used for local unit testing.
1117
/// </summary>
12-
public static readonly AppStoreEnvironment LocalTesting = new("LocalTesting", new Uri("https://local-testing-base-url"));
18+
public static readonly AppStoreEnvironment LocalTesting = new(
19+
"LocalTesting",
20+
new Uri("https://local-testing-base-url")
21+
);
1322

1423
private AppStoreEnvironment(string name, Uri baseUrl)
1524
{
@@ -20,4 +29,4 @@ private AppStoreEnvironment(string name, Uri baseUrl)
2029
public string Name { get; }
2130

2231
public Uri BaseUrl { get; }
23-
}
32+
}

src/Models/ConsumptionRequest.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ public record ConsumptionRequest
6969
[JsonPropertyName("lifetimeDollarsPurchased")]
7070
public required int LifetimeDollarsPurchased { get; set; }
7171

72-
7372
/// <summary>
7473
/// The dollar amount of refunds the customer has received in your app, since purchasing the app, across all platforms:
7574
/// 0: Undeclared
@@ -133,4 +132,4 @@ public record ConsumptionRequest
133132
/// </summary>
134133
[JsonPropertyName("userStatus")]
135134
public required int UserStatus { get; set; }
136-
}
135+
}

src/ReceiptUtility.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,11 @@ public string ExtractTransactionIdFromAppReceipt(string appReceipt)
3434

3535
AsnReader sequence = reader.ReadSequence();
3636
tag = sequence.PeekTag();
37-
if (tag.TagClass != TagClass.Universal || tag.TagValue != (int)UniversalTagNumber.ObjectIdentifier ||
38-
sequence.ReadObjectIdentifier() != "1.2.840.113549.1.7.2")
37+
if (
38+
tag.TagClass != TagClass.Universal
39+
|| tag.TagValue != (int)UniversalTagNumber.ObjectIdentifier
40+
|| sequence.ReadObjectIdentifier() != "1.2.840.113549.1.7.2"
41+
)
3942
{
4043
throw new FormatException("Expected PKCS#7 Object.");
4144
}
@@ -130,7 +133,6 @@ DER Octet String[2]
130133
inAppPurchasesSequence.ReadInteger();
131134
byte[] contentString = inAppPurchasesSequence.ReadOctetString();
132135

133-
134136
if (typeId == TRANSACTION_IDENTIFIER_TYPE_ID)
135137
{
136138
var transactionReader = new AsnReader(contentString, AsnEncodingRules.BER);
@@ -633,4 +635,4 @@ DER Octet String[44]
633635
634636
*
635637
*/
636-
}
638+
}

0 commit comments

Comments
 (0)