Skip to content

Commit

Permalink
Merge pull request #47 from martincostello/AspNet-Core-3
Browse files Browse the repository at this point in the history
Update to ASP.NET Core 3.0
  • Loading branch information
martincostello committed Oct 5, 2019
2 parents 8b46a86 + 68574e7 commit 1003dff
Show file tree
Hide file tree
Showing 28 changed files with 493 additions and 83 deletions.
7 changes: 5 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
sudo: required
dist: xenial
language: csharp
mono: none

os:
- linux
Expand All @@ -22,10 +24,11 @@ addons:
- libicu-dev
- libssl-dev
- libunwind8
chrome: stable

install:
- npm install -g bower
- npm install -g npm
- npm install --global bower
- npm install --global npm

script:
- ./build.sh
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceRoot}/src/ApplePayJS/bin/Debug/netcoreapp2.2/JustEat.ApplePayJS.dll",
"program": "${workspaceRoot}/src/ApplePayJS/bin/Debug/netcoreapp3.0/JustEat.ApplePayJS.dll",
"args": [],
"cwd": "${workspaceRoot}/src/ApplePayJS",
"stopAtEntry": false,
Expand Down
17 changes: 17 additions & 0 deletions ApplePayJS.sln
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
Build.ps1 = Build.ps1
build.sh = build.sh
CODE_OF_CONDUCT.md = CODE_OF_CONDUCT.md
Directory.Build.props = Directory.Build.props
global.json = global.json
LICENSE = LICENSE
NuGet.config = NuGet.config
Expand All @@ -29,6 +30,16 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{A4EF
.github\PULL_REQUEST_TEMPLATE.md = .github\PULL_REQUEST_TEMPLATE.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".vscode", ".vscode", "{F99C01C5-8B5D-4BDD-B40B-35DE14D08D57}"
ProjectSection(SolutionItems) = preProject
.vscode\launch.json = .vscode\launch.json
.vscode\tasks.json = .vscode\tasks.json
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{3F1B1211-EEF9-482B-93CD-6FF250907EB9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApplePayJS.Tests", "tests\ApplePayJS.Tests\ApplePayJS.Tests.csproj", "{20EE5C1E-2059-4291-93F6-AA0F76C08EBE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -39,13 +50,19 @@ Global
{4CFD067B-FD1A-4303-9322-3138E9104B1F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4CFD067B-FD1A-4303-9322-3138E9104B1F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4CFD067B-FD1A-4303-9322-3138E9104B1F}.Release|Any CPU.Build.0 = Release|Any CPU
{20EE5C1E-2059-4291-93F6-AA0F76C08EBE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{20EE5C1E-2059-4291-93F6-AA0F76C08EBE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{20EE5C1E-2059-4291-93F6-AA0F76C08EBE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{20EE5C1E-2059-4291-93F6-AA0F76C08EBE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{4CFD067B-FD1A-4303-9322-3138E9104B1F} = {ABF2B260-1BAE-45CD-9348-C163CA02ECA3}
{A4EFB4F4-BC05-4A67-89AC-4D7D21B71D4E} = {C697BCC9-C4F9-4AD8-8336-E90A239865DE}
{F99C01C5-8B5D-4BDD-B40B-35DE14D08D57} = {C697BCC9-C4F9-4AD8-8336-E90A239865DE}
{20EE5C1E-2059-4291-93F6-AA0F76C08EBE} = {3F1B1211-EEF9-482B-93CD-6FF250907EB9}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8797D09A-407D-424A-A8F0-22FB26F0650C}
Expand Down
3 changes: 3 additions & 0 deletions Build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ else {
Write-Host "Publishing solution..." -ForegroundColor Green
& $dotnet publish $solutionFile --output $OutputPath --configuration $Configuration

Write-Host "Running tests..." -ForegroundColor Green
& $dotnet test $solutionFile --output $OutputPath --configuration $Configuration

if ($LASTEXITCODE -ne 0) {
throw "dotnet publish failed with exit code $LASTEXITCODE"
}
20 changes: 20 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Project>
<PropertyGroup>
<Authors>Martin Costello</Authors>
<Company>Just Eat</Company>
<Copyright>Just Eat (c) 2016-$([System.DateTime]::Now.ToString(yyyy))</Copyright>
<LangVersion>latest</LangVersion>
<NeutralLanguage>en-US</NeutralLanguage>
<Nullable>enable</Nullable>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/justeat/ApplePayJSSample</PackageProjectUrl>
<PackageReleaseNotes>$(PackageProjectUrl)/releases</PackageReleaseNotes>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<PackageTags>applepay</PackageTags>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>$(PackageProjectUrl).git</RepositoryUrl>
<TypeScriptToolsVersion>latest</TypeScriptToolsVersion>
<VersionPrefix>3.0.0</VersionPrefix>
<VersionSuffix></VersionSuffix>
</PropertyGroup>
</Project>
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
|:-:|:-:|:-:|
| **Build Status** | [![Build status](https://img.shields.io/travis/justeat/ApplePayJSSample/master.svg)](https://travis-ci.org/justeat/ApplePayJSSample) | [![Build status](https://img.shields.io/appveyor/ci/justeattech/applepayjssample/master.svg)](https://ci.appveyor.com/project/justeattech/applepayjssample) |

This repository contains a sample implementation of [Apple Pay JS](https://developer.apple.com/reference/applepayjs/) using ASP.NET Core 2.2 written in C# and JavaScript.
This repository contains a sample implementation of [Apple Pay JS](https://developer.apple.com/reference/applepayjs/) using ASP.NET Core 3.0 written in C# and JavaScript.

## Overview

Expand All @@ -24,7 +24,7 @@ The key components to look at for the implementation are:

To setup the repository to run the sample, perform the steps below:

1. Install the [.NET Core 2.2.402 SDK](https://www.microsoft.com/net/download/core), Visual Studio 2019 or Visual Studio Code.
1. Install the [.NET Core 3.0.100 SDK](https://www.microsoft.com/net/download/core), Visual Studio 2019 or Visual Studio Code.
1. Fork this repository.
1. Clone the repository from your fork to your local machine: ```git clone https://github.com/{username}/ApplePayJSSample.git```
1. Restore the Bower, npm and NuGet packages.
Expand Down
7 changes: 4 additions & 3 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
os: Visual Studio 2017
os: Visual Studio 2019
version: 3.0.{build}

environment:
Expand All @@ -10,8 +10,9 @@ branches:
- master

install:
- ps: npm install -g bower --loglevel=error
- ps: npm install -g npm
- ps: npm install --global bower --loglevel=error
- ps: npm install --global npm
- ps: choco upgrade googlechrome --confirm --ignore-checksums --no-progress

build_script:
- ps: .\Build.ps1
Expand Down
2 changes: 2 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ export PATH="$DOTNET_INSTALL_DIR:$PATH"
dotnet_version=$(dotnet --version)

if [ "$dotnet_version" != "$CLI_VERSION" ]; then
curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --version "2.2.402" --install-dir "$DOTNET_INSTALL_DIR"
curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --version "$CLI_VERSION" --install-dir "$DOTNET_INSTALL_DIR"
fi

dotnet publish ./ApplePayJS.sln --output $artifacts/publish --configuration $configuration || exit 1
dotnet test ./ApplePayJS.sln --output $artifacts --configuration $configuration || exit 1
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"sdk": {
"version": "2.2.402"
"version": "3.0.100"
}
}
19 changes: 3 additions & 16 deletions src/ApplePayJS/ApplePayJS.csproj
Original file line number Diff line number Diff line change
@@ -1,36 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<AspNetCoreHostingModel>inprocess</AspNetCoreHostingModel>
<Authors>Martin Costello</Authors>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
<AssemblyName>JustEat.ApplePayJS</AssemblyName>
<Company>Just Eat</Company>
<Copyright>Just Eat (c) 2016-$([System.DateTime]::Now.ToString(yyyy))</Copyright>
<LangVersion>latest</LangVersion>
<NeutralLanguage>en-US</NeutralLanguage>
<OutputType>Exe</OutputType>
<PackageIconUrl>https://avatars3.githubusercontent.com/u/1516790?v=3&amp;s=100</PackageIconUrl>
<PackageId>JustEat.ApplePayJS</PackageId>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/justeat/ApplePayJSSample</PackageProjectUrl>
<PackageReleaseNotes>$(PackageProjectUrl)/releases</PackageReleaseNotes>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<PackageTags>applepay</PackageTags>
<PreserveCompilationContext>true</PreserveCompilationContext>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>$(PackageProjectUrl).git</RepositoryUrl>
<RootNamespace>JustEat.ApplePayJS</RootNamespace>
<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFramework>netcoreapp3.0</TargetFramework>
<TypeScriptToolsVersion>latest</TypeScriptToolsVersion>
<UserSecretsId>JustEat.ApplePayJS</UserSecretsId>
<VersionPrefix>3.0.0</VersionPrefix>
<VersionSuffix></VersionSuffix>
</PropertyGroup>
<ItemGroup>
<Content Update="*.pfx" CopyToPublishDirectory="PreserveNewest" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<PropertyGroup Condition=" '$(InstallWebPackages)' == '' and ('$(CI)' != '' or !Exists('$(MSBuildThisFileDirectory)\node_modules')) ">
<InstallWebPackages>true</InstallWebPackages>
</PropertyGroup>
Expand All @@ -50,6 +37,6 @@
</ItemGroup>
</Target>
<ItemGroup>
<DotNetCliToolReference Include="BundlerMinifier.Core" Version="2.8.391" />
<DotNetCliToolReference Include="BundlerMinifier.Core" Version="3.0.415" />
</ItemGroup>
</Project>
26 changes: 18 additions & 8 deletions src/ApplePayJS/Clients/ApplePayClient.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
// Copyright (c) Just Eat, 2016. All rights reserved.
// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.

using System;
using System.Net.Http;
using System.Net.Mime;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;

namespace JustEat.ApplePayJS.Clients
{
Expand All @@ -15,19 +20,24 @@ public ApplePayClient(HttpClient httpClient)
_httpClient = httpClient;
}

public async Task<JObject> GetMerchantSessionAsync(
public async Task<JsonDocument> GetMerchantSessionAsync(
Uri requestUri,
MerchantSessionRequest request,
CancellationToken cancellationToken = default)
{
// POST the data to create a valid Apple Pay merchant session.
using (var response = await _httpClient.PostAsJsonAsync(requestUri, request, cancellationToken))
{
response.EnsureSuccessStatusCode();
string json = JsonSerializer.Serialize(request);

using var content = new StringContent(json, Encoding.UTF8, MediaTypeNames.Application.Json);

using var response = await _httpClient.PostAsync(requestUri, content, cancellationToken);

response.EnsureSuccessStatusCode();

// Read the opaque merchant session JSON from the response body.
using var stream = await response.Content.ReadAsStreamAsync();

// Read the opaque merchant session JSON from the response body.
return await response.Content.ReadAsAsync<JObject>(cancellationToken);
}
return await JsonDocument.ParseAsync(stream, cancellationToken: cancellationToken);
}
}
}
31 changes: 16 additions & 15 deletions src/ApplePayJS/Clients/MerchantCertificate.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright (c) Just Eat, 2016. All rights reserved.
// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.

using System;
using System.Security.Cryptography.X509Certificates;
using System.Text;
Expand Down Expand Up @@ -32,7 +35,7 @@ public string GetMerchantIdentifier()
{
try
{
var merchantCertificate = GetCertificate();
using var merchantCertificate = GetCertificate();
return GetMerchantIdentifier(merchantCertificate);
}
catch (InvalidOperationException)
Expand Down Expand Up @@ -76,23 +79,21 @@ private X509Certificate2 LoadCertificateFromStore()
// your application, but it is also required to be able to use an X.509
// certificate with a private key if the user profile is not available,
// such as when using IIS hosting in an environment such as Microsoft Azure.
using (var store = new X509Store(StoreName.My, StoreLocation.CurrentUser))
{
store.Open(OpenFlags.ReadOnly);

var certificates = store.Certificates.Find(
X509FindType.FindByThumbprint,
_options.MerchantCertificateThumbprint?.Trim(),
validOnly: false);
using var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);

if (certificates.Count < 1)
{
throw new InvalidOperationException(
$"Could not find Apple Pay merchant certificate with thumbprint '{_options.MerchantCertificateThumbprint}' from store '{store.Name}' in location '{store.Location}'.");
}
var certificates = store.Certificates.Find(
X509FindType.FindByThumbprint,
_options.MerchantCertificateThumbprint?.Trim(),
validOnly: false);

return certificates[0];
if (certificates.Count < 1)
{
throw new InvalidOperationException(
$"Could not find Apple Pay merchant certificate with thumbprint '{_options.MerchantCertificateThumbprint}' from store '{store.Name}' in location '{store.Location}'.");
}

return certificates[0];
}
}
}
21 changes: 12 additions & 9 deletions src/ApplePayJS/Clients/MerchantSessionRequest.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
using Newtonsoft.Json;
// Copyright (c) Just Eat, 2016. All rights reserved.
// Licensed under the Apache 2.0 license. See the LICENSE file in the project root for full license information.

using System.Text.Json.Serialization;

namespace JustEat.ApplePayJS.Clients
{
public class MerchantSessionRequest
{
[JsonProperty("merchantIdentifier")]
public string MerchantIdentifier { get; set; }
[JsonPropertyName("merchantIdentifier")]
public string? MerchantIdentifier { get; set; }

[JsonProperty("displayName")]
public string DisplayName { get; set; }
[JsonPropertyName("displayName")]
public string? DisplayName { get; set; }

[JsonProperty("initiative")]
public string Initiative { get; set; }
[JsonPropertyName("initiative")]
public string? Initiative { get; set; }

[JsonProperty("initiativeContext")]
public string InitiativeContext { get; set; }
[JsonPropertyName("initiativeContext")]
public string? InitiativeContext { get; set; }
}
}
11 changes: 6 additions & 5 deletions src/ApplePayJS/Controllers/HomeController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
namespace JustEat.ApplePayJS.Controllers
{
using System;
using System.Net.Mime;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using JustEat.ApplePayJS.Clients;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Models;
using Newtonsoft.Json.Linq;

public class HomeController : Controller
{
Expand Down Expand Up @@ -42,7 +43,7 @@ public IActionResult Index()
}

[HttpPost]
[Produces("application/json")]
[Produces(MediaTypeNames.Application.Json)]
[Route("applepay/validate", Name = "MerchantValidation")]
public async Task<IActionResult> Validate([FromBody] ValidateMerchantSessionModel model, CancellationToken cancellationToken = default)
{
Expand All @@ -51,7 +52,7 @@ public async Task<IActionResult> Validate([FromBody] ValidateMerchantSessionMode
// these servers are available here: https://developer.apple.com/documentation/applepayjs/setting_up_server_requirements
if (!ModelState.IsValid ||
string.IsNullOrWhiteSpace(model?.ValidationUrl) ||
!Uri.TryCreate(model.ValidationUrl, UriKind.Absolute, out Uri requestUri))
!Uri.TryCreate(model.ValidationUrl, UriKind.Absolute, out Uri? requestUri))
{
return BadRequest();
}
Expand All @@ -65,10 +66,10 @@ public async Task<IActionResult> Validate([FromBody] ValidateMerchantSessionMode
MerchantIdentifier = _certificate.GetMerchantIdentifier(),
};

JObject merchantSession = await _client.GetMerchantSessionAsync(requestUri, request, cancellationToken);
JsonDocument merchantSession = await _client.GetMerchantSessionAsync(requestUri, request, cancellationToken);

// Return the merchant session as-is to the JavaScript as JSON.
return Json(merchantSession);
return Json(merchantSession.RootElement);
}

public IActionResult Error() => View();
Expand Down

0 comments on commit 1003dff

Please sign in to comment.