Skip to content

Commit

Permalink
Library: some fixes in logging;
Browse files Browse the repository at this point in the history
Demo app: push notification sample code added
  • Loading branch information
justdmitry committed Oct 7, 2019
1 parent 7d8ecd7 commit 112f37e
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 15 deletions.
71 changes: 62 additions & 9 deletions PassKitHelper.Demo/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,54 @@
{
using System;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;

public class Program
{
/// <summary>
/// Identifiers from your Apple developer account.
/// </summary>
private const string PassTypeIdentifier = "pass.com.apple.devpubs.example";
private const string TeamIdentifier = "A93A5CM278";

/// <summary>
/// Filename and password for your PFX file.
/// </summary>
/// <remarks>See `hot_to_create_pfx.md` file for instructions how to obtain your PFX file.</remarks>
private const string PassPfxFile = "pass.pfx";
private const string PassPfxPassword = "";

/// <summary>
/// Valud `pushToken` value from pass registration (<see cref="IPassKitService.RegisterDeviceAsync"/>).
/// </summary>
private const string RegisterationPushToken = "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef";

public static async Task Main()
{
const string passTypeIdentifier = "pass.com.apple.devpubs.example";
const string teamIdentifier = "A93A5CM278";
const string passPfxFile = "pass.pfx";
const string passPfxPassword = null;
await GenerateSamplePass();

//// uncomment to send push notification
//// attention! your pass (you push update for) must already include WebService fields (auth.token and endpoint), and your web service/app must be up and running
// await SendEmptyPushNotification(RegisterationPushToken);
}

public static async Task GenerateSamplePass()
{
var libraryVersion = typeof(PassInfoBuilder).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion;

var pass = new PassInfoBuilder()
.Standard
.PassTypeIdentifier(passTypeIdentifier)
.PassTypeIdentifier(PassTypeIdentifier)
.SerialNumber("PassKitHelper")
.TeamIdentifier(teamIdentifier)
.TeamIdentifier(TeamIdentifier)
.OrganizationName("PassKit")
.Description("PassKitHelper demo pass")
//.WebService
// .AuthenticationToken("some-nonce")
// .WebServiceURL("https://www.example.com/")
.VisualAppearance
.Barcodes("1234567890128", BarcodeFormat.Code128)
.LogoText("PassKit Helper demo pass")
Expand All @@ -42,17 +68,44 @@ public static async Task Main()
.Build();

var appleBytes = await File.ReadAllBytesAsync("AppleWWDRCA.cer");
var passBytes = await File.ReadAllBytesAsync(passPfxFile);
var passBytes = await File.ReadAllBytesAsync(PassPfxFile);

var package = await new PassPackageBuilder(pass)
.Icon(await File.ReadAllBytesAsync("images/icon.png"))
.Icon2X(await File.ReadAllBytesAsync("images/[email protected]"))
.Logo(await File.ReadAllBytesAsync("images/logo.jpg"))
.Strip(await File.ReadAllBytesAsync("images/strip.jpg"))
.Strip2X(await File.ReadAllBytesAsync("images/[email protected]"))
.SignAndBuildAsync(appleBytes, passBytes, passPfxPassword);
.SignAndBuildAsync(appleBytes, passBytes, PassPfxPassword);

await File.WriteAllBytesAsync("Sample.pkpass", package.ToArray());
}

public static async Task SendEmptyPushNotification(string pushToken)
{
var cert = string.IsNullOrEmpty(PassPfxFile)
? new X509Certificate2(await File.ReadAllBytesAsync(PassPfxFile))
: new X509Certificate2(await File.ReadAllBytesAsync(PassPfxFile), PassPfxPassword);

using var clientHandler = new HttpClientHandler();
clientHandler.ClientCertificates.Add(cert);
clientHandler.ClientCertificateOptions = ClientCertificateOption.Manual;

using var content = new StringContent("{\"aps\":\"\"}");
using var client = new HttpClient(clientHandler);

var req = new HttpRequestMessage(HttpMethod.Post, $"https://api.push.apple.com/3/device/{pushToken}")
{
Version = new Version(2, 0),
Content = content,
};

using var response = await client.SendAsync(req);

var responseText = await response.Content.ReadAsStringAsync();

Console.WriteLine(response.IsSuccessStatusCode ? "SUCCESS. Response:" : "FAILED. Response:");
Console.WriteLine(responseText);
}
}
}
2 changes: 1 addition & 1 deletion PassKitHelper/PassKitHelper.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<RepositoryType>git</RepositoryType>
<PackageProjectUrl>https://github.com/justdmitry/PassKitHelper</PackageProjectUrl>
<RepositoryUrl>https://github.com/justdmitry/PassKitHelper.git</RepositoryUrl>
<Version>1.0.0</Version>
<Version>1.0.1</Version>
<Description>Helper library for all your Apple PassKit (Apple Wallet, Apple Passbook) needs: create passes, sign pass packages, receive webhooks into your aspnetcore app. Apple Developer Account required!</Description>
<PackageTags>apple passkit passbook pass webservice</PackageTags>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
Expand Down
13 changes: 8 additions & 5 deletions PassKitHelper/PassKitMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,15 @@ public async Task InvokeDevicesAsync(HttpContext context, PathString devicesRema
var passTypeIdentifier = pathParts[2];

var serialNumber = pathParts.Length == 3 ? null : pathParts[3];
var authorizationToken = GetAuthorizationToken(context.Request.Headers);

var service = context.RequestServices.GetRequiredService<IPassKitService>();

switch (context.Request.Method)
{
case "POST": // Registering a Device to Receive Push Notifications for a Pass
if (authorizationToken == null)
var postAuthorizationToken = GetAuthorizationToken(context.Request.Headers);

if (postAuthorizationToken == null)
{
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
return;
Expand All @@ -120,14 +121,16 @@ public async Task InvokeDevicesAsync(HttpContext context, PathString devicesRema
return;
}

var regStatus = await service.RegisterDeviceAsync(deviceLibraryIdentifier, passTypeIdentifier, serialNumber, authorizationToken, payload.PushToken);
var regStatus = await service.RegisterDeviceAsync(deviceLibraryIdentifier, passTypeIdentifier, serialNumber, postAuthorizationToken, payload.PushToken);
context.Response.StatusCode = regStatus;
}

break;

case "DELETE": // Unregistering a Device
if (authorizationToken == null)
var deleteAuthorizationToken = GetAuthorizationToken(context.Request.Headers);

if (deleteAuthorizationToken == null)
{
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
return;
Expand All @@ -140,7 +143,7 @@ public async Task InvokeDevicesAsync(HttpContext context, PathString devicesRema
return;
}

var unregStatus = await service.UnregisterDeviceAsync(deviceLibraryIdentifier, passTypeIdentifier, serialNumber, authorizationToken);
var unregStatus = await service.UnregisterDeviceAsync(deviceLibraryIdentifier, passTypeIdentifier, serialNumber, deleteAuthorizationToken);
context.Response.StatusCode = unregStatus;

break;
Expand Down

0 comments on commit 112f37e

Please sign in to comment.