Skip to content

Full sample #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Mar 5, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# This workflow is a demo of how to use the Gihub Actions workflow steps for SignPath. For a complete documentation,
# view https://github.com/SignPath/github-actions

name: sign-with-signpath
name: build-and-sign
run-name: Demo workflow signing with SignPath
on:
push:
@@ -11,21 +11,29 @@ on:
workflow_dispatch: # Allows you to run this workflow manually from the Actions tab

jobs:
build-and-sign:
build_and_sign:
runs-on: windows-latest
steps:

- name: checkout
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: build
run: "echo \"This is a dummy build step that creates build-output/hello-world.exe\""
run: ./src/Build.ps1

- name: create SBOM
run: ./sbom/Create-SBOM.ps1

- name: package artifacts
run: Compress-Archive -Path .\_BuildResult-unsigned\DemoExample.msi,.\_BuildResult-unsigned\bom.xml -DestinationPath .\_BuildResult-unsigned.zip -Force

- name: upload-unsigned-artifact
uses: actions/upload-artifact@v3
with:
name: "hello-world"
path: "./build-output/hello-world.exe"
name: "demo-application-unsigned"
path: "./_BuildResult-unsigned.zip"
if-no-files-found: error

- name: sign
@@ -34,15 +42,18 @@ jobs:
github-token: '${{ secrets.GITHUB_TOKEN }}'
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
organization-id: '${{ vars.SIGNPATH_ORGANIZATION_ID }}'
project-slug: 'Executable'
signing-policy-slug: 'test-signing'
artifact-configuration-slug: 'initial'
artifact-name: "hello-world"
signed-artifact-destination-path: "build-output/hello-world-signed.exe"
project-slug: 'Demo_Application'
signing-policy-slug: ${{ github.ref == 'refs/heads/main' && 'release-signing' || 'test-signing' }}
artifact-configuration-slug: 'v1'
artifact-name: "demo-application-unsigned"
signed-artifact-destination-path: "_BuildResult-signed.zip"

- name: decompress signed artifact
run: Expand-Archive -Path .\_BuildResult-signed.zip -DestinationPath _BuildResult-signed

- name: upload-signed-artifact
uses: actions/upload-artifact@v3
with:
name: "hello-world-signed"
path: "./build-output/hello-world-signed.exe"
name: "demo-application-signed"
path: "_BuildResult-signed"
if-no-files-found: error
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.store
.vs
bin
node_modules
obj
src/wwwroot/js
_temp
bom.xml
verification
_BuildResult*
Binary file removed build-output/hello-world.exe
Binary file not shown.
Binary file removed build-output/sample.dll
Binary file not shown.
55 changes: 55 additions & 0 deletions sbom/Create-SBOM.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# PowerShell script that will create the SBOM file

# 1 Preparation
# 1.a general settings
$ErrorActionPreference = "Stop"
function Fail-On-Error {
param(
$description
)

if ($LASTEXITCODE -ne 0) {
Write-Host "Executing '$description' failed with exit code $LASTEXITCODE."
exit 1
}
}

# 1.b Create a temporary folder
$tempPath = Join-Path $PSScriptRoot "_temp"
New-Item -ItemType Directory -Force -Path $tempPath

# 2 Create NuGet SBOM
# 2.a install the .Net tool
dotnet tool install cyclonedx --tool-path $tempPath

# 2.b create nuget bom
$cyclonDxToolPath = Join-Path $tempPath "dotnet-CycloneDX.exe"
& "${cyclonDxToolPath}" --output "${tempPath}" -f "nuget.bom.xml" --exclude-dev src\DemoExample.csproj

# 3 Create NPM SBOM
$packageJsonPath = Join-Path $PSScriptRoot ".." "src" "package.json"
$npmBomPath = Join-Path $tempPath "npm.bom.xml"

# 3.a make sure the package is installed
Push-Location (Join-Path $PSScriptRoot ".." "src")
npm install --omit=optional
Fail-On-Error "npm install"
Pop-Location

# 3.b. create actual NPM SBOM
npx --yes "@cyclonedx/cyclonedx-npm" "${packageJsonPath}" --omit dev --output-format XML --output-file "${npmBomPath}"
Fail-On-Error "cyclonedx-npm"

# 4 Merge SBOMs
# 4.a download cyclonedx-cli.exe
$cycloneDxCliToolPath = Join-Path $tempPath "cyclonedx-cli.exe"
if (-Not (Test-Path $cycloneDxCliToolPath)) {
$releases = Invoke-RestMethod -Uri "https://api.github.com/repos/CycloneDX/cyclonedx-cli/releases"
$asset = ($releases | Select-Object -First 1).assets | ? { $_.name -eq "cyclonedx-win-x64.exe" }
Invoke-WebRequest -Uri ($asset.browser_download_url) -OutFile "${cycloneDxCliToolPath}"
}

# 4.b merge both SBOMs into a final one
$nugetBomPath = Join-Path $tempPath "nuget.bom.xml"
$finalBomPath = Join-Path $PSScriptRoot ".." "_BuildResult-unsigned" "bom.xml"
& "${cycloneDxCliToolPath}" merge --input-files "${npmBomPath}" "${nugetBomPath}" --output-format "xml" --output-file "${finalBomPath}" --group "com.SignPath.demos" --name "SignPath Demo Application" --version "1.0.0"
26 changes: 26 additions & 0 deletions sbom/Verify-SBOM.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
New-Item -ItemType Directory -Force -Path verification

# Get signing request details
$signingRequestDetails = Invoke-RestMethod -Headers @{ Authorization = "Bearer ${env:SIGNPATH_CI_USER_TOKEN}" } `
"https://app.signpath.io/Api/v1/${env:SIGNPATH_ORGANIZATION_ID}/SigningRequests/${env:SIGNPATH_SIGNING_REQUEST_ID}"
# Get project details
$projectDetails = Invoke-RestMethod -Headers @{ Authorization = "Bearer ${env:SIGNPATH_CI_USER_TOKEN}" } `
"https://app.signpath.io/Api/v1-pre/${env:SIGNPATH_ORGANIZATION_ID}/Projects/$($signingRequestDetails.projectSlug)"
# Extract signing policy from project details
$signingPolicyDetails = $projectDetails.signingPolicies `
| Where-Object {$_.metadata.slug -eq $signingRequestDetails.signingPolicySlug} `
| Select -First 1

# Download certificate
Invoke-WebRequest -Headers @{ Authorization = "Bearer ${env:SIGNPATH_CI_USER_TOKEN}" } `
"$($signingPolicyDetails.certificateUrl)/X509Certificate" -OutFile verification/certificate.cer
# Extract public key
openssl x509 -pubkey -noout -in verification/certificate.cer -inform DER -out verification/public_key.pem

# Download verify tool
$releases = Invoke-RestMethod -Uri "https://api.github.com/repos/signpath/cyclonedx-cli/releases"
$asset = ($releases | Select-Object -First 1).assets | ? { $_.name -eq "cyclonedx-win-x64.exe" }
Invoke-WebRequest -Uri ($asset.browser_download_url) -OutFile "verification/cyclonedx-cli.exe"

# Actual verification
& ./verification/cyclonedx-cli.exe verify all ./_BuildResult-signed/bom.xml --key-file ./verification/public_key.pem
13 changes: 13 additions & 0 deletions src/Build.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# build .Net application
dotnet build --configuration Release src/DemoExample.csproj

# build MSI installer
Copy-Item .\src\installer\description.wxs .\src\bin\Release\net7.0\description.wxs -Force
Push-Location .\src\bin\Release\net7.0
& "${env:WIX}bin\candle.exe" description.wxs
& "${env:WIX}bin\light.exe" description.wixobj -out DemoExample.msi
Pop-Location

# copy build to output directory
New-Item -ItemType Directory -Path "_BuildResult-unsigned"
Copy-Item src\bin\Release\net7.0\DemoExample.msi _BuildResult-unsigned\DemoExample.msi
18 changes: 18 additions & 0 deletions src/DemoExample.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Serilog.AspNetCore" Version="7.0.0" />
</ItemGroup>

<Target Name="BuildClientAssets" BeforeTargets="Build">
<Exec Command="npm install" />
<Exec Command="npm run build" />
</Target>

</Project>
25 changes: 25 additions & 0 deletions src/Pages/Index.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
@page

<div>
<svg xmlns="http://www.w3.org/2000/svg" id="logo" viewbox="0,0,620.2,124.6" width="620.20001" height="124.6">
<title>SignPath GmbH</title>
<g id="g3684" transform="translate(-27.1 -22.8)">
<path id="path3682" fill="#fff" d="M133.4 22.8H62.6L27.1 84.2l35.4 61.4h70.9l35.4-61.4zm1.7 68.6c-.7 1.6-2.3 2.6-4.1 2.6H94.2c-2.5 0-4.5-2-4.5-4.5s2-4.5 4.5-4.5H121l-10.5-11.9a4.43 4.43 0 0 1 0-5.9L121 55.3H76.7v71.2c0 2.5-2 4.5-4.5 4.5s-4.5-2-4.5-4.5V41.7c0-2.5 2-4.5 4.5-4.5s4.5 2 4.5 4.5v4.6H131c1.8 0 3.4 1 4.1 2.6.7 1.6.4 3.5-.7 4.8L120 70.1l14.4 16.4c1.1 1.4 1.4 3.3.7 4.9z"/>
</g>
<g id="Inhalt" transform="translate(-27.1 -22.8)">
<g id="g3705">
<g id="g3703">
<path id="path3687" stroke="#fff" stroke-width="3" fill="none" d="M208.4 104c7.3 5.8 16 9.2 25.3 9.2 9.1 0 15.5-3.2 15.5-10.4 0-6.2-4-8.7-11.2-11.4l-11.6-4.2c-10.6-3.9-18.7-9.6-18.7-22.7 0-14 12.2-21.7 26.9-21.7 9 0 17.1 2.3 23.5 6.5v13.9c-6.6-5.1-13.9-8.6-23.2-8.6-8.1 0-14 3.1-14 9.6 0 5.8 3.8 8.2 10.4 10.5l12.9 4.7c12.5 4.5 18.2 11.6 18.2 23.1 0 14.5-12.3 22.6-28.6 22.6-10.6 0-19.7-3.1-25.3-7z"/>
<path id="path3689" stroke="#fff" stroke-width="3" fill="none" d="M280.5 56.7c-4.3 0-8.1-3.5-8.1-7.9s3.8-7.9 8.1-7.9 8.1 3.5 8.1 7.9-3.8 7.9-8.1 7.9zm6.5 67.2h-13V66.2h13z"/>
<path id="path3691" stroke="#fff" stroke-width="3" fill="none" d="M339.1 118.2c-2.6 3.1-8.1 6-14.5 6-17 0-26.6-14.2-26.6-29.6 0-15.4 9.6-29.6 26.6-29.6 6.5 0 11.9 2.9 14.5 6v-4.7h13v52.9c0 21-16 28.2-29.6 28.2-7.7 0-14.5-1.9-19.2-4.9v-13.8c6 5.3 11.9 7.3 19.2 7.3 9.2 0 16.6-5.5 16.6-15.8zm0-35c-2.2-3.9-6.9-6.9-12.3-6.9-10 0-15.7 7.7-15.7 18.2s5.7 18.2 15.7 18.2c5.5 0 10.1-3 12.3-6.9z"/>
<path id="path3693" stroke="#fff" stroke-width="3" fill="none" d="M367 66.2h13v5.5c3.1-3.6 8.8-6.8 15.6-6.8 13.1 0 20.4 8.7 20.4 21.4v37.5h-13V88.6c0-7.1-3.5-11.8-10.9-11.8-5.6 0-10.6 3.5-12.1 9.2v37.9h-13z"/>
<path id="path3695" stroke="#fff" stroke-width="3" fill="none" d="M445 94.1v29.7h-13.5V44.1h30.8c16.5 0 27.3 8.6 27.3 25.1 0 16.2-10.8 24.9-27.3 24.9zm17.1-38.3h-17v26.6h17c9.4 0 14.2-5.6 14.2-13.2-.1-7.9-4.9-13.4-14.2-13.4z"/>
<path id="path3697" stroke="#fff" stroke-width="3" fill="none" d="M530.1 87c0-6.5-5.2-10.3-13.2-10.3-6.2 0-11.3 1.9-16 5.1V69.9c3.8-2.7 11-4.9 18.3-4.9 14.9 0 23.4 8.1 23.4 21.2V124h-12.5v-3.2c-1.9 1.9-7.7 4.3-14.2 4.3-11.8 0-21.6-7-21.6-18.8 0-10.9 9.7-18.6 22.5-18.6 5.2 0 10.9 1.8 13.2 3.5zm0 16.8c-1.4-3.6-6.5-5.8-11.7-5.8-5.8 0-11.9 2.5-11.9 8.2 0 5.8 6.1 8.3 11.9 8.3 5.2 0 10.3-2.2 11.7-5.8z"/>
<path id="path3699" stroke="#fff" stroke-width="3" fill="none" d="M575.8 123.9h-13V77h-11.7V66.2h11.7V50.8h13v15.5h13V77h-13z"/>
<path id="path3701" stroke="#fff" stroke-width="3" fill="none" d="M598.3 39.5h13v32.2c3.1-3.6 8.8-6.8 15.6-6.8 13.1 0 20.4 8.7 20.4 21.4v37.5h-13V88.6c0-7.1-3.5-11.8-10.9-11.8-5.6 0-10.7 3.5-12.1 9.2v37.9h-13z"/>
</g>
</g>
</g>
</svg>
<span id='slogan'></span>
</div>
19 changes: 19 additions & 0 deletions src/Pages/Index.cshtml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace DemoExample.Pages;

public class IndexModel : PageModel
{
private readonly ILogger<IndexModel> _logger;

public IndexModel(ILogger<IndexModel> logger)
{
_logger = logger;
}

public void OnGet()
{
_logger.LogInformation("Home page was called");
}
}
17 changes: 17 additions & 0 deletions src/Pages/Shared/_Layout.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>SignPath Demo Example App</title>
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
<script src="~/js/main.js"></script>
</head>
<body>
<div>
<main role="main">
@RenderBody()
</main>
</div>
</body>
</html>
3 changes: 3 additions & 0 deletions src/Pages/_ViewImports.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@using DemoExample
@namespace DemoExample.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
3 changes: 3 additions & 0 deletions src/Pages/_ViewStart.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@{
Layout = "_Layout";
}
28 changes: 28 additions & 0 deletions src/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using Serilog;

var builder = WebApplication.CreateBuilder(args);

builder.Host.UseSerilog((context, configuration) => configuration.ReadFrom.Configuration(context.Configuration));

// Add services to the container.
builder.Services.AddRazorPages();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}

app.UseSerilogRequestLogging();

app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();
34 changes: 34 additions & 0 deletions src/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"Serilog": {
"Using": [ "Serilog.Sinks.File", "Serilog.Sinks.Console" ],
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
},
"WriteTo": [
{
"Name": "Console"
},
{
"Name": "File",
"Args": {
"path": "/logs/log-.txt",
"rollOnFileSizeLimit": true,
"formatter": "Serilog.Formatting.Compact.CompactJsonFormatter,Serilog.Formatting.Compact",
"rollingInterval": "Day"
}
}
],
"Enrich": [ "FromLogContext", "WithThreadId", "WithMachineName" ]
}
}
13 changes: 13 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Vivus from 'vivus';
import Typed from 'typed.js';

document.addEventListener('DOMContentLoaded', function() {
new Vivus('logo', {duration: 100} );

new Typed('#slogan', {
strings: ['Built. Signed. Delivered.'],
typeSpeed: 50,
showCursor: false,
autoInsertCss: false
});
});
75 changes: 75 additions & 0 deletions src/installer/description.wxs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?xml version='1.0' encoding='windows-1252'?>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
<Product Name='SignPath Demo' Id='115FE86C-0356-4AA9-95B2-EF9EAE44DD38' UpgradeCode='115FE86C-7349-453F-94F6-BCB5110BA4FD'
Language='1033' Codepage='1252' Version='1.0.0' Manufacturer='SignPath GmbH (Demo)'>

<Package Id='*' Keywords='Installer' Description="SignPath Demo Example Installer"
Comments='An Installer of the SignPath Demo Example Project' Manufacturer='SignPath GmbH (Demo)'
InstallerVersion='100' Languages='1033' Compressed='yes' SummaryCodepage='1252' />

<Media Id='1' Cabinet='Files.cab' EmbedCab='yes' />

<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id='ProgramFilesFolder' Name='application'>
<Directory Id="INSTALLDIR" Name="SignPath Demo">
</Directory>
</Directory>
</Directory>

<ComponentGroup Id="DemoExample" Directory="INSTALLDIR">
<Component Id="cmpB4EC2627BDB13AAF4ADEC9F474A61E7C" Guid="*">
<File Id="fil7C089284176A351615B1D70217773FA1" KeyPath="yes" Source="appsettings.json" />
</Component>
<Component Id="cmp184FA156A7DCE869481143058C2FA3BF" Guid="*">
<File Id="fil52A478DEE2F1F98AF37FB23783348C0B" KeyPath="yes" Source="Microsoft.Extensions.DependencyModel.dll" />
</Component>
<Component Id="cmp429198165BB8A7365CF79CC666209E97" Guid="*">
<File Id="fil4C32C7BBAA89FE6D4952945A70FFB028" KeyPath="yes" Source="DemoExample.deps.json" />
</Component>
<Component Id="cmp53A17ED33B4966B25AD683D90BDC1F25" Guid="*">
<File Id="filF68789BB59050BCA3FB4846186E1D5AF" KeyPath="yes" Source="DemoExample.dll" />
</Component>
<Component Id="cmpF8FF348BC0CFA551D984F2B9B694009A" Guid="*">
<File Id="fil0A5D0C552FFCDA2C37DAF5CA4DE4E44A" KeyPath="yes" Source="DemoExample.exe" />
</Component>
<Component Id="cmpC0C81FFCBDE18AADB30AE0AC7A55AD51" Guid="*">
<File Id="filD50D3656B3C7897DA8660E5FD66FFC4F" KeyPath="yes" Source="DemoExample.runtimeconfig.json" />
</Component>
<Component Id="cmpEA43EC119CA3987AD64B26976CF541C0" Guid="*">
<File Id="filD67056443534F4A531BF982BF601FDFD" KeyPath="yes" Source="DemoExample.staticwebassets.runtime.json" />
</Component>
<Component Id="cmp077122A497043FB00765F045198924B7" Guid="*">
<File Id="fil9BC3F23B210BAC05F723FA555E36739B" KeyPath="yes" Source="Serilog.AspNetCore.dll" />
</Component>
<Component Id="cmp85006A39828AD6287A0A7BA5C93A7316" Guid="*">
<File Id="fil7EC9A578B53CDFA0B84E5877BF5EB96C" KeyPath="yes" Source="Serilog.dll" />
</Component>
<Component Id="cmp697A10C3A6BC1BEAC8DA7CA8D36D049F" Guid="*">
<File Id="filFFC8D00981218415745CC27972EB1752" KeyPath="yes" Source="Serilog.Extensions.Hosting.dll" />
</Component>
<Component Id="cmpEC6A75A3C04D9A3D5E56DF245E7CD150" Guid="*">
<File Id="fil305291DE444A712034744368AB5747DB" KeyPath="yes" Source="Serilog.Extensions.Logging.dll" />
</Component>
<Component Id="cmpE772DF469EA003204804A9484C264860" Guid="*">
<File Id="filBF4F9183D716FD986615B7B4C627D4FA" KeyPath="yes" Source="Serilog.Formatting.Compact.dll" />
</Component>
<Component Id="cmpCBEE1A0729E31038D781A3C42957F998" Guid="*">
<File Id="fil249A6A712F0C53DF43299E2D926F9BF5" KeyPath="yes" Source="Serilog.Settings.Configuration.dll" />
</Component>
<Component Id="cmp57205D5BEB00C546377AB5252B0F7B1A" Guid="*">
<File Id="fil6B507FC722F4E42D4A05A4E705A0E816" KeyPath="yes" Source="Serilog.Sinks.Console.dll" />
</Component>
<Component Id="cmp6628B9D250F16DED95EB784C6A4962A7" Guid="*">
<File Id="filDB44C26586DE3A655BF59F45FB6836BF" KeyPath="yes" Source="Serilog.Sinks.Debug.dll" />
</Component>
<Component Id="cmp9075985A78A1DF13230357DE5CB220F8" Guid="*">
<File Id="fil973844A6487E78B7324E885EC6786AAB" KeyPath="yes" Source="Serilog.Sinks.File.dll" />
</Component>
</ComponentGroup>

<Feature Id='Complete' Level='1'>
<ComponentGroupRef Id='DemoExample' />
</Feature>

</Product>
</Wix>
2,498 changes: 2,498 additions & 0 deletions src/package-lock.json

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions src/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "org.signpath.example",
"version": "1.0.0",
"description": "SignPath Demo example",
"main": "index.js",
"dependencies": {
"typed.js": "^2.0.16",
"vivus": "^0.4.6"
},
"devDependencies": {
"@cyclonedx/cyclonedx-npm": "^1.16.0",
"webpack": "^5.88.2",
"webpack-cli": "^5.1.4"
},
"scripts": {
"build": "webpack --env NODE_ENV=production --mode=production --config webpack.config.js"
},
"author": "",
"license": "ISC"
}
9 changes: 9 additions & 0 deletions src/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const path = require('path');

module.exports = {
entry: './index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'wwwroot', 'js'),
},
};
38 changes: 38 additions & 0 deletions src/wwwroot/css/site.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
body {
margin:0px;
padding:0px;
height:100%;
background-color: #282828;
color: #fff;
font-family: "Segoe UI", SegoeUI, Helvetica, Arial, sans-serif;
}

html {
height:100%;
}

body > div {
width: 100%;
height: 100%;
}

main {
max-width: 800px;
margin:auto;
box-sizing: border-box;
padding: 20px;
padding-top: 40px;
text-align: center;
}

svg {
max-width: 100%;
}

span#slogan {
display: block;
text-align: right;
font-size: 30px;
margin-top: 10px;
width: 100%;
}