diff --git a/.github/workflows/hydrun.yaml b/.github/workflows/hydrun.yaml
index 82c1ff1..012657f 100644
--- a/.github/workflows/hydrun.yaml
+++ b/.github/workflows/hydrun.yaml
@@ -3,6 +3,8 @@ name: hydrun CI
on:
push:
pull_request:
+ schedule:
+ - cron: "0 0 * * 0"
jobs:
build-linux:
@@ -10,14 +12,37 @@ jobs:
strategy:
matrix:
target:
+ - id: test
+ src: .
+ os: golang:bullseye
+ flags: ""
+ cmd: GOFLAGS="-short" ./Hydrunfile test
+ dst: out/*
+ - id: go
+ src: .
+ os: golang:bullseye
+ flags: ""
+ cmd: ./Hydrunfile go
+ dst: out/*
+ - id: gccgo
+ src: .
+ os: ghcr.io/pojntfx/bagccgop-base-sid
+ flags: -e '--privileged'
+ cmd: ./Hydrunfile gccgo
+ dst: out/*
- id: pwa
src: .
os: golang:bullseye
flags: ""
- cmd: make -j "$(nproc)"
+ cmd: ./Hydrunfile pwa
dst: out/*
steps:
+ - name: Maximize build space
+ run: |
+ sudo rm -rf /usr/share/dotnet
+ sudo rm -rf /usr/local/lib/android
+ sudo rm -rf /opt/ghc
- name: Checkout
uses: actions/checkout@v2
- name: Set up QEMU
@@ -49,10 +74,11 @@ jobs:
uses: actions/download-artifact@v2
with:
path: /tmp/out
- - name: Isolate the repositories
+ - name: Isolate the PWA
run: |
mkdir -p /tmp/github-pages
- cp -r /tmp/out/pwa/web/* /tmp/github-pages
+
+ tar -xvzf /tmp/out/pwa/keystoregaen-pwa.tar.gz --directory /tmp/github-pages
- name: Publish pre-release to GitHub releases
if: ${{ github.ref == 'refs/heads/main' }}
uses: marvinpinto/action-automatic-releases@latest
@@ -71,7 +97,8 @@ jobs:
files: |
/tmp/out/*/*
- name: Publish release to GitHub pages
- if: startsWith(github.ref, 'refs/tags/v')
+ if: startsWith(github.ref, 'refs/tags/v') # Uncomment on first release
+ # if: ${{ github.ref == 'refs/heads/main' }} # Comment on first release
uses: JamesIves/github-pages-deploy-action@4.1.0
with:
branch: gh-pages
diff --git a/.gitignore b/.gitignore
index f897c6d..acbf605 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,6 @@
-web/*.wasm
out
+build
+web/*.wasm
+web/fonts
+web/*.css*
+node_modules
diff --git a/Makefile b/Makefile
index 15165e2..929667e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,31 +1,86 @@
-# Variables
+# Public variables
DESTDIR ?=
+
WWWROOT ?= /var/www/html
WWWPREFIX ?= /keygaen
-all: build
+PREFIX ?= /usr/local
+OUTPUT_DIR ?= out
+BUILD_DIR ?= build
+STATIC_DIR ?= web
+DST ?=
+
+# Private variables
+clis = keygaen-cli
+pwas = keygaen-pwa
+all: $(addprefix build-cli/,$(clis)) $(addprefix build-pwa/,$(pwas))
# Build
-build:
- GOARCH=wasm GOOS=js go build -o web/app.wasm main.go
- go run main.go -prefix $(WWWPREFIX)
- cp -rf web/* out/web/web
- tar -cvzf out/keygaen.tar.gz -C out/web .
+build: $(addprefix build-cli/,$(clis)) $(addprefix build-pwa/,$(pwas))
+
+$(addprefix build-cli/,$(clis)):
+ifdef DST
+ go build -o $(DST) ./cmd/$(subst build-cli/,,$@)
+else
+ go build -o $(OUTPUT_DIR)/$(subst build-cli/,,$@) ./cmd/$(subst build-cli/,,$@)
+endif
+
+$(addprefix build-pwa/,$(pwas)): build-scss
+ mkdir -p $(OUTPUT_DIR) $(BUILD_DIR)
+ GOARCH=wasm GOOS=js go build -o $(STATIC_DIR)/app.wasm ./cmd/$(subst build-pwa/,,$@)
+ go run ./cmd/$(subst build-pwa/,,$@) -dist $(BUILD_DIR) -prefix $(WWWPREFIX)
+ cp -rf $(STATIC_DIR)/* $(BUILD_DIR)/web
+ tar -cvzf $(OUTPUT_DIR)/$(subst build-pwa/,,$@).tar.gz -C $(BUILD_DIR) .
+
+build-scss:
+ npx sass -I . web/main.scss web/main.css
# Install
-install:
+install: $(addprefix install-cli/,$(clis)) $(addprefix install-pwa/,$(pwas))
+
+$(addprefix install-cli/,$(clis)):
+ install -D -m 0755 $(OUTPUT_DIR)/$(subst install-cli/,,$@) $(DESTDIR)$(PREFIX)/bin/$(subst install-cli/,,$@)
+
+$(addprefix install-pwa/,$(pwas)):
mkdir -p $(DESTDIR)$(WWWROOT)$(WWWPREFIX)
- cp -rf out/web/* $(DESTDIR)$(WWWROOT)$(WWWPREFIX)
+ cp -rf $(BUILD_DIR)/* $(DESTDIR)$(WWWROOT)$(WWWPREFIX)
# Uninstall
-uninstall:
+uninstall: $(addprefix uninstall-cli/,$(clis)) $(addprefix uninstall-pwa/,$(pwas))
+
+$(addprefix uninstall-cli/,$(clis)):
+ rm -f $(DESTDIR)$(PREFIX)/bin/$(subst uninstall-cli/,,$@)
+
+$(addprefix uninstall-pwa/,$(pwas)):
rm -rf $(DESTDIR)$(WWWROOT)$(WWWPREFIX)
# Run
-run:
- GOARCH=wasm GOOS=js go build -o web/app.wasm main.go
- go run main.go -serve
+run: $(addprefix run-cli/,$(clis)) $(addprefix run-pwa/,$(pwas))
+
+$(addprefix run-cli/,$(clis)): build
+ $(OUTPUT_DIR)/$(subst run-cli/,,$@) $(ARGS)
+
+$(addprefix run-pwa/,$(pwas)): build-scss
+ GOARCH=wasm GOOS=js go build -o $(STATIC_DIR)/app.wasm ./cmd/$(subst run-pwa/,,$@)
+ go run ./cmd/$(subst run-pwa/,,$@) -serve
+
+# Test
+test:
+ go test -timeout 3600s -parallel $(shell nproc) ./...
+
+# Benchmark
+benchmark:
+ go test -timeout 3600s -bench=./... ./...
# Clean
clean:
- rm -rf out web/app.wasm
+ rm -rf $(OUTPUT_DIR) $(BUILD_DIR) $(STATIC_DIR)/app.wasm
+
+# Dependencies
+depend:
+ npm i
+ find node_modules/@patternfly/patternfly/ -name "*.css" -type f -delete
+ rm -rf $(STATIC_DIR)/fonts
+ mkdir -p $(STATIC_DIR)
+ cp -r node_modules/@patternfly/patternfly/assets/fonts $(STATIC_DIR)
+
diff --git a/README.md b/README.md
index 24fa51d..69308ec 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,20 @@
# keygaen
-
+
-Sign, verify, encrypt and decrypt data with GPG in your browser.
+Sign, verify, encrypt and decrypt data with PGP in your browser.
⚠️ keygaen has not yet been audited! While we try to make keygaen as secure as possible, it has not yet undergone a formal security audit by a third party. Please keep this in mind if you use it for security-critical applications. ⚠️
[](https://github.com/pojntfx/keygaen/actions/workflows/hydrun.yaml)
+
[](https://pkg.go.dev/github.com/pojntfx/keygaen)
[](https://matrix.to/#/#keygaen:matrix.org?via=matrix.org)
+[](https://github.com/pojntfx/keygaen/releases)
+
+## Overview
+
+keygaen is an app to work with PGP without having to install anything on your local system.
## Installation
@@ -20,56 +26,57 @@ The web app is available on [GitHub releases](https://github.com/pojntfx/keygaen
Click on an image to see a larger version.
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
## Acknowledgements
- This project would not have been possible were it not for [@maxence-charriere](https://github.com/maxence-charriere)'s [go-app package](https://go-app.dev/); if you enjoy using keygaen, please donate to him!
- The open source [PatternFly design system](https://www.patternfly.org/v4/) provides the components for the project.
-- [GopenPGP](https://gopenpgp.org/) is the GPG library in use.
-- All the rest of the authors who worked on the dependencies used! Thanks a lot!
+- [GopenPGP](https://gopenpgp.org/) is the PGP library in use.
+
+To all the rest of the authors who worked on the dependencies used: **Thanks a lot!**
## Contributing
@@ -87,6 +94,6 @@ Have any questions or need help? Chat with us [on Matrix](https://matrix.to/#/#k
## License
-keygaen (c) 2021 Felicitas Pojtinger and contributors
+keygaen (c) 2022 Felicitas Pojtinger and contributors
SPDX-License-Identifier: AGPL-3.0
diff --git a/cmd/keygaen-cli/main.go b/cmd/keygaen-cli/main.go
new file mode 100644
index 0000000..5a923cb
--- /dev/null
+++ b/cmd/keygaen-cli/main.go
@@ -0,0 +1,5 @@
+package main
+
+func main() {
+ panic("not implemented")
+}
diff --git a/main.go b/cmd/keygaen-pwa/main.go
similarity index 89%
rename from main.go
rename to cmd/keygaen-pwa/main.go
index 6c1c313..58cc061 100644
--- a/main.go
+++ b/cmd/keygaen-pwa/main.go
@@ -33,8 +33,8 @@ func main() {
Title: "keygaen",
Name: "keygaen",
ShortName: "keygaen",
- Description: "Sign, verify, encrypt and decrypt data with GPG.",
- LoadingLabel: "Sign, verify, encrypt and decrypt data with GPG.",
+ Description: "Sign, verify, encrypt and decrypt data with PGP.",
+ LoadingLabel: "Sign, verify, encrypt and decrypt data with PGP.",
Author: "Felicitas Pojtinger",
ThemeColor: "#151515",
BackgroundColor: "#151515",
@@ -43,7 +43,7 @@ func main() {
Large: `/web/large.png`,
},
Keywords: []string{
- "gpg",
+ "pgp",
"pgp",
"gopenpgp",
"encryption",
@@ -52,13 +52,11 @@ func main() {
RawHeaders: []string{
``,
``,
- ``,
+ ``,
``,
},
Styles: []string{
- `https://unpkg.com/@patternfly/patternfly@4.135.2/patternfly.css`,
- `https://unpkg.com/@patternfly/patternfly@4.135.2/patternfly-addons.css`,
- `/web/index.css`,
+ "/web/main.css",
},
}
diff --git a/assets/decrypt-verify.png b/docs/decrypt-verify.png
similarity index 100%
rename from assets/decrypt-verify.png
rename to docs/decrypt-verify.png
diff --git a/assets/download-cypher.png b/docs/download-cypher.png
similarity index 100%
rename from assets/download-cypher.png
rename to docs/download-cypher.png
diff --git a/assets/download-plaintext.png b/docs/download-plaintext.png
similarity index 100%
rename from assets/download-plaintext.png
rename to docs/download-plaintext.png
diff --git a/assets/empty.png b/docs/empty.png
similarity index 100%
rename from assets/empty.png
rename to docs/empty.png
diff --git a/assets/encrypt-sign.png b/docs/encrypt-sign.png
similarity index 100%
rename from assets/encrypt-sign.png
rename to docs/encrypt-sign.png
diff --git a/assets/export-key.png b/docs/export-key.png
similarity index 100%
rename from assets/export-key.png
rename to docs/export-key.png
diff --git a/assets/icon-dark.svg b/docs/icon-dark.svg
similarity index 100%
rename from assets/icon-dark.svg
rename to docs/icon-dark.svg
diff --git a/assets/icon-light.svg b/docs/icon-light.svg
similarity index 100%
rename from assets/icon-light.svg
rename to docs/icon-light.svg
diff --git a/assets/key-create.png b/docs/key-create.png
similarity index 100%
rename from assets/key-create.png
rename to docs/key-create.png
diff --git a/assets/key-import.png b/docs/key-import.png
similarity index 100%
rename from assets/key-import.png
rename to docs/key-import.png
diff --git a/assets/key-list.png b/docs/key-list.png
similarity index 100%
rename from assets/key-list.png
rename to docs/key-list.png
diff --git a/assets/logo-dark.svg b/docs/logo-dark.svg
similarity index 100%
rename from assets/logo-dark.svg
rename to docs/logo-dark.svg
diff --git a/assets/logo-light.svg b/docs/logo-light.svg
similarity index 100%
rename from assets/logo-light.svg
rename to docs/logo-light.svg
diff --git a/assets/logo-readme.png b/docs/logo-readme.png
similarity index 100%
rename from assets/logo-readme.png
rename to docs/logo-readme.png
diff --git a/assets/view-cypher.png b/docs/view-cypher.png
similarity index 100%
rename from assets/view-cypher.png
rename to docs/view-cypher.png
diff --git a/assets/view-plaintext.png b/docs/view-plaintext.png
similarity index 100%
rename from assets/view-plaintext.png
rename to docs/view-plaintext.png
diff --git a/go.mod b/go.mod
index e21ab4f..e433b3b 100644
--- a/go.mod
+++ b/go.mod
@@ -1,20 +1,21 @@
module github.com/pojntfx/keygaen
-go 1.17
+go 1.18
require (
- github.com/ProtonMail/go-crypto v0.0.0-20210920160938-87db9fbc61c7
- github.com/ProtonMail/gopenpgp/v2 v2.2.4
- github.com/maxence-charriere/go-app/v9 v9.0.0
+ github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad
+ github.com/ProtonMail/gopenpgp/v2 v2.4.10
+ github.com/maxence-charriere/go-app/v9 v9.6.7
)
require (
- github.com/ProtonMail/go-mime v0.0.0-20190923161245-9b5a4261663a // indirect
- github.com/google/uuid v1.2.0 // indirect
- github.com/konsorten/go-windows-terminal-sequences v1.0.1 // indirect
+ github.com/ProtonMail/go-mime v0.0.0-20220429130430-2192574d760f // indirect
+ github.com/cloudflare/circl v1.2.0 // indirect
+ github.com/google/uuid v1.3.0 // indirect
+ github.com/konsorten/go-windows-terminal-sequences v1.0.3 // indirect
github.com/pkg/errors v0.9.1 // indirect
- github.com/sirupsen/logrus v1.4.2 // indirect
- golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 // indirect
- golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44 // indirect
- golang.org/x/text v0.3.6 // indirect
+ github.com/sirupsen/logrus v1.9.0 // indirect
+ golang.org/x/crypto v0.1.0 // indirect
+ golang.org/x/sys v0.1.0 // indirect
+ golang.org/x/text v0.4.0 // indirect
)
diff --git a/go.sum b/go.sum
index dd4f0b0..c05aee9 100644
--- a/go.sum
+++ b/go.sum
@@ -1,38 +1,44 @@
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
-github.com/ProtonMail/go-crypto v0.0.0-20210920160938-87db9fbc61c7 h1:DSqTh6nEes/uO8BlNcGk8PzZsxY2sN9ZL//veWBdTRI=
-github.com/ProtonMail/go-crypto v0.0.0-20210920160938-87db9fbc61c7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
-github.com/ProtonMail/go-mime v0.0.0-20190923161245-9b5a4261663a h1:W6RrgN/sTxg1msqzFFb+G80MFmpjMw61IU+slm+wln4=
-github.com/ProtonMail/go-mime v0.0.0-20190923161245-9b5a4261663a/go.mod h1:NYt+V3/4rEeDuaev/zw1zCq8uqVEuPHzDPo3OZrlGJ4=
-github.com/ProtonMail/gopenpgp/v2 v2.2.4 h1:PEke+LAMLH9CplflEl8WqGyz2IiDoiiipKkB+3cEWFQ=
-github.com/ProtonMail/gopenpgp/v2 v2.2.4/go.mod h1:ygdaHbrbWFPhKjmXii0zOs3/xlSR/01GaVePKqv19Hc=
+github.com/ProtonMail/go-crypto v0.0.0-20220822140716-1678d6eb0cbe/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8=
+github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad h1:QeeqI2zxxgZVe11UrYFXXx6gVxPVF40ygekjBzEg4XY=
+github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8=
+github.com/ProtonMail/go-mime v0.0.0-20220302105931-303f85f7fe0f/go.mod h1:NYt+V3/4rEeDuaev/zw1zCq8uqVEuPHzDPo3OZrlGJ4=
+github.com/ProtonMail/go-mime v0.0.0-20220429130430-2192574d760f h1:4IWzKjHzZxdrW9k4zl/qCwenOVHDbVDADPPHFLjs0Oc=
+github.com/ProtonMail/go-mime v0.0.0-20220429130430-2192574d760f/go.mod h1:qRZgbeASl2a9OwmsV85aWwRqic0NHPh+9ewGAzb4cgM=
+github.com/ProtonMail/gopenpgp/v2 v2.4.10 h1:EYgkxzwmQvsa6kxxkgP1AwzkFqKHscF2UINxaSn6rdI=
+github.com/ProtonMail/gopenpgp/v2 v2.4.10/go.mod h1:CTRA7/toc/4DxDy5Du4hPDnIZnJvXSeQ8LsRTOUJoyc=
+github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
+github.com/bwesterb/go-ristretto v1.2.1/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
+github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I=
+github.com/cloudflare/circl v1.2.0 h1:NheeISPSUcYftKlfrLuOo4T62FkmD4t4jviLfFFYaec=
+github.com/cloudflare/circl v1.2.0/go.mod h1:Ch2UgYr6ti2KTtlejELlROl0YIYj7SLjAC8M+INXlMk=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/gomarkdown/markdown v0.0.0-20210408062403-ad838ccf8cdd/go.mod h1:aii0r/K0ZnHv7G0KF7xy1v0A7s2Ljrb5byB7MO5p6TU=
-github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
-github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
+github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
+github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/maxence-charriere/go-app/v9 v9.0.0 h1:+YuEmk+dl2QeVNqoVBGzpN2NM+UOGy4pvxDR/8YCoqQ=
-github.com/maxence-charriere/go-app/v9 v9.0.0/go.mod h1:zo0n1kh4OMKn7P+MrTUUi7QwUMU2HOfHsZ293TITtxI=
+github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
+github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/maxence-charriere/go-app/v9 v9.6.7 h1:t+wofnLjVsptBB7MNevsFymMYaMIX2hGjLdWgsIFgq4=
+github.com/maxence-charriere/go-app/v9 v9.6.7/go.mod h1:UlniES44R5JoD4HsjMNrAqWXSzyw0smM0Ox+QwnO/IE=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
+github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
-github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-golang.org/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90tenwKoCX93Gn3MAQJMOSBsDQ=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
-golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
+golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
@@ -45,20 +51,26 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210415231046-e915ea6b2b7d/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44 h1:Bli41pIlzTzf3KEY06n+xnzK/BESIg2ze4Pgfh/aI8c=
-golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
+golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
+golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@@ -67,5 +79,4 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..af96512
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,398 @@
+{
+ "name": "@pojntfx/keygaen",
+ "version": "0.0.1",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "@pojntfx/keygaen",
+ "version": "0.0.1",
+ "license": "AGPL-3.0",
+ "dependencies": {
+ "@patternfly/patternfly": "^4.217.1"
+ },
+ "devDependencies": {
+ "sass": "^1.55.0"
+ }
+ },
+ "node_modules/@patternfly/patternfly": {
+ "version": "4.217.1",
+ "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-4.217.1.tgz",
+ "integrity": "sha512-uN7JgfQsyR16YHkuGRCTIcBcnyKIqKjGkB2SGk9x1XXH3yYGenL83kpAavX9Xtozqp17KppOlybJuzcKvZMrgw=="
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
+ "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+ "dev": true,
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "dependencies": {
+ "fill-range": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+ "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ ],
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/immutable": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz",
+ "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==",
+ "dev": true
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/sass": {
+ "version": "1.55.0",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.55.0.tgz",
+ "integrity": "sha512-Pk+PMy7OGLs9WaxZGJMn7S96dvlyVBwwtToX895WmCpAOr5YiJYEUJfiJidMuKb613z2xNWcXCHEuOvjZbqC6A==",
+ "dev": true,
+ "dependencies": {
+ "chokidar": ">=3.0.0 <4.0.0",
+ "immutable": "^4.0.0",
+ "source-map-js": ">=0.6.2 <2.0.0"
+ },
+ "bin": {
+ "sass": "sass.js"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+ "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ }
+ },
+ "dependencies": {
+ "@patternfly/patternfly": {
+ "version": "4.217.1",
+ "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-4.217.1.tgz",
+ "integrity": "sha512-uN7JgfQsyR16YHkuGRCTIcBcnyKIqKjGkB2SGk9x1XXH3yYGenL83kpAavX9Xtozqp17KppOlybJuzcKvZMrgw=="
+ },
+ "anymatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
+ "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+ "dev": true,
+ "requires": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ }
+ },
+ "binary-extensions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "dev": true
+ },
+ "braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "requires": {
+ "fill-range": "^7.0.1"
+ }
+ },
+ "chokidar": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+ "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "dev": true,
+ "requires": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "fsevents": "~2.3.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ }
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "optional": true
+ },
+ "glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.1"
+ }
+ },
+ "immutable": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz",
+ "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==",
+ "dev": true
+ },
+ "is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "requires": {
+ "binary-extensions": "^2.0.0"
+ }
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true
+ },
+ "normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true
+ },
+ "picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true
+ },
+ "readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "requires": {
+ "picomatch": "^2.2.1"
+ }
+ },
+ "sass": {
+ "version": "1.55.0",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.55.0.tgz",
+ "integrity": "sha512-Pk+PMy7OGLs9WaxZGJMn7S96dvlyVBwwtToX895WmCpAOr5YiJYEUJfiJidMuKb613z2xNWcXCHEuOvjZbqC6A==",
+ "dev": true,
+ "requires": {
+ "chokidar": ">=3.0.0 <4.0.0",
+ "immutable": "^4.0.0",
+ "source-map-js": ">=0.6.2 <2.0.0"
+ }
+ },
+ "source-map-js": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+ "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+ "dev": true
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..5fb0c0c
--- /dev/null
+++ b/package.json
@@ -0,0 +1,25 @@
+{
+ "name": "@pojntfx/keygaen",
+ "version": "0.0.1",
+ "description": "Sign, verify, encrypt and decrypt data with PGP in your browser.",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/pojntfx/keygaen.git"
+ },
+ "author": "Felicitas Pojtinger ",
+ "license": "AGPL-3.0",
+ "bugs": {
+ "url": "https://github.com/pojntfx/keygaen/issues"
+ },
+ "homepage": "https://github.com/pojntfx/keygaen#readme",
+ "dependencies": {
+ "@patternfly/patternfly": "^4.217.1"
+ },
+ "devDependencies": {
+ "sass": "^1.55.0"
+ }
+}
diff --git a/pkg/components/decrypt_and_verify_modal.go b/pkg/components/decrypt_and_verify_modal.go
index cc83c66..14de211 100644
--- a/pkg/components/decrypt_and_verify_modal.go
+++ b/pkg/components/decrypt_and_verify_modal.go
@@ -13,7 +13,7 @@ const (
type DecryptAndVerifyModal struct {
app.Compo
- Keys []GPGKey // GPG keys to be available for decryption/verification
+ Keys []PGPKey // PGP keys to be available for decryption/verification
OnSubmit func(
file []byte,
@@ -38,8 +38,8 @@ type DecryptAndVerifyModal struct {
}
func (c *DecryptAndVerifyModal) Render() app.UI {
- privateKeys := []GPGKey{}
- publicKeys := []GPGKey{}
+ privateKeys := []PGPKey{}
+ publicKeys := []PGPKey{}
for _, key := range c.Keys {
if key.Private {
privateKeys = append(privateKeys, key)
diff --git a/pkg/components/encrypt_and_sign_modal.go b/pkg/components/encrypt_and_sign_modal.go
index ce9e2e2..9577590 100644
--- a/pkg/components/encrypt_and_sign_modal.go
+++ b/pkg/components/encrypt_and_sign_modal.go
@@ -12,7 +12,7 @@ const (
type EncryptAndSignModal struct {
app.Compo
- Keys []GPGKey // GPG keys to be available for encryption/signing
+ Keys []PGPKey // PGP keys to be available for encryption/signing
OnSubmit func(
file []byte,
@@ -39,8 +39,8 @@ type EncryptAndSignModal struct {
}
func (c *EncryptAndSignModal) Render() app.UI {
- privateKeys := []GPGKey{}
- publicKeys := []GPGKey{}
+ privateKeys := []PGPKey{}
+ publicKeys := []PGPKey{}
for _, key := range c.Keys {
if key.Private {
privateKeys = append(privateKeys, key)
@@ -374,6 +374,6 @@ func (c *EncryptAndSignModal) clear() {
c.dirty = false
}
-func getKeySummary(key GPGKey) string {
+func getKeySummary(key PGPKey) string {
return key.Label + " " + key.FullName + " <" + key.Email + ">"
}
diff --git a/pkg/components/home.go b/pkg/components/home.go
index 9a8b138..c960357 100644
--- a/pkg/components/home.go
+++ b/pkg/components/home.go
@@ -58,7 +58,7 @@ type Home struct {
err error
onRecover func()
- keys []GPGKey
+ keys []PGPKey
keyPasswordChan chan string
@@ -86,7 +86,7 @@ func (c *Home) Render() app.UI {
c.keyPasswordChan = make(chan string)
}
- privateKey := GPGKey{}
+ privateKey := PGPKey{}
privateKeyExport := []byte{}
privateKeyExportArmored := ""
for _, candidate := range c.keys {
@@ -125,7 +125,7 @@ func (c *Home) Render() app.UI {
}
}
- publicKey := GPGKey{}
+ publicKey := PGPKey{}
publicKeyExport := []byte{}
publicKeyExportArmored := ""
for _, candidate := range c.keys {
@@ -164,7 +164,7 @@ func (c *Home) Render() app.UI {
}
}
- selectedKey := GPGKey{}
+ selectedKey := PGPKey{}
for _, candidate := range c.keys {
if candidate.ID == c.selectedKeyID {
selectedKey = candidate
@@ -417,7 +417,7 @@ func (c *Home) Render() app.UI {
c.selectedKeyID = keyID
c.confirmDeleteKey = func() {
- newKeys := []GPGKey{}
+ newKeys := []PGPKey{}
for _, candidate := range c.keys {
if candidate.ID == c.selectedKeyID {
continue
@@ -468,7 +468,7 @@ func (c *Home) Render() app.UI {
return
}
- c.keys = append(c.keys, GPGKey{
+ c.keys = append(c.keys, PGPKey{
ID: fingerprint, // Since we don't generate subkeys, we'll only have one fingerprint
Label: fingerprint[0:10], // We can safely assume that the fingerprint is at least 10 chars long
FullName: id.Name,
@@ -541,7 +541,7 @@ func (c *Home) Render() app.UI {
return
}
- newKeys := []GPGKey{}
+ newKeys := []PGPKey{}
for _, candidate := range c.keys {
if candidate.ID == fingerprint {
// Replace the key if the existing key is a public key and the imported key is a private key
@@ -560,7 +560,7 @@ func (c *Home) Render() app.UI {
newKeys = append(newKeys, candidate)
}
- newKeys = append(newKeys, GPGKey{
+ newKeys = append(newKeys, PGPKey{
ID: fingerprint, // Since we don't generate subkeys, we'll only have one fingerprint
Label: fingerprint[0:10], // We can safely assume that the fingerprint is at least 10 chars long
FullName: id.Name,
@@ -886,7 +886,7 @@ func (c *Home) Render() app.UI {
if armor {
c.download([]byte(publicKeyExportArmored), publicKey.Label+".asc", "text/plain")
} else {
- c.download(publicKeyExport, publicKey.Label+".gpg", "application/octet-stream")
+ c.download(publicKeyExport, publicKey.Label+".pgp", "application/octet-stream")
}
},
OnViewPublicKey: func() {
@@ -900,7 +900,7 @@ func (c *Home) Render() app.UI {
if armor {
c.download([]byte(privateKeyExportArmored), privateKey.Label+".asc", "text/plain")
} else {
- c.download(privateKeyExport, privateKey.Label+".gpg", "application/octet-stream")
+ c.download(privateKeyExport, privateKey.Label+".pgp", "application/octet-stream")
}
},
OnViewPrivateKey: func() {
@@ -1232,11 +1232,11 @@ func (c *Home) readFromLocalStorage() {
marshalledKeys := app.Window().Get("localStorage").Call("getItem", keyringStorageKey).String()
// Ignore errors in JSON parsing
- newKeys := []GPGKey{}
+ newKeys := []PGPKey{}
_ = json.Unmarshal([]byte(marshalledKeys), &newKeys)
if newKeys == nil {
- c.keys = []GPGKey{}
+ c.keys = []PGPKey{}
return
}
@@ -1262,7 +1262,7 @@ func getEncryptedExtensionAndMIME(content []byte, filename string) (string, stri
return filename + ".asc", "text/plain"
}
- return filename + ".gpg", "application/octet-stream"
+ return filename + ".pgp", "application/octet-stream"
}
func getDecryptedExtensionAndMIME(content []byte, filename string) (string, string) {
diff --git a/pkg/components/key_list.go b/pkg/components/key_list.go
index ca63df0..9d8b979 100644
--- a/pkg/components/key_list.go
+++ b/pkg/components/key_list.go
@@ -8,25 +8,25 @@ const (
keyListID = "key-list"
)
-// GPGKey is a GPG key an it's metadata
-type GPGKey struct {
- ID string `json:"id"` // Internal unique ID of the GPG key, i.e. it's fingerprint
- Label string `json:"label"` // Displayable ID of the GPG key
- FullName string `json:"fullName"` // Full name of the GPG key's holder
- Email string `json:"email"` // Email of the GPG key's holder
- Private bool `json:"private"` // Whether the GPG key is private
- Public bool `json:"public"` // Whether the GPG key is public
- Content []byte `json:"content"` // Raw GPG key (Potentially protected or armored)
+// PGPKey is a PGP key an it's metadata
+type PGPKey struct {
+ ID string `json:"id"` // Internal unique ID of the PGP key, i.e. it's fingerprint
+ Label string `json:"label"` // Displayable ID of the PGP key
+ FullName string `json:"fullName"` // Full name of the PGP key's holder
+ Email string `json:"email"` // Email of the PGP key's holder
+ Private bool `json:"private"` // Whether the PGP key is private
+ Public bool `json:"public"` // Whether the PGP key is public
+ Content []byte `json:"content"` // Raw PGP key (Potentially protected or armored)
}
-// KeyList is a list of GPG keys
+// KeyList is a list of PGP keys
type KeyList struct {
app.Compo
- Keys []GPGKey // GPG keys to list
+ Keys []PGPKey // PGP keys to list
- OnExport func(keyID string) // Handler to call to export a GPG key
- OnDelete func(keyID string) // Handler to call to delete a GPG key
+ OnExport func(keyID string) // Handler to call to export a PGP key
+ OnDelete func(keyID string) // Handler to call to delete a PGP key
expandedKeyID string
diff --git a/pkg/components/navbar.go b/pkg/components/navbar.go
index 41baf60..9d9a88e 100644
--- a/pkg/components/navbar.go
+++ b/pkg/components/navbar.go
@@ -20,7 +20,7 @@ func (c *Navbar) Render() app.UI {
Body(
app.Img().
Class("pf-c-brand").
- Src("/keygaen/web/logo-light.png").
+ Src("/web/logo-light.png").
Alt("Logo"),
),
),
@@ -40,7 +40,7 @@ func (c *Navbar) Render() app.UI {
Aria("label", "Help").
Body(
app.I().
- Class("pf-icon pf-icon-help").
+ Class("pf-icon fas fa-question-circle").
Aria("hidden", true),
),
),
diff --git a/pkg/crypt/gpg.go b/pkg/crypt/gpg.go
index 19c20d1..7d35342 100644
--- a/pkg/crypt/gpg.go
+++ b/pkg/crypt/gpg.go
@@ -69,7 +69,7 @@ func Unarmor(data []byte) ([]byte, error) {
return data, nil
}
-// ReadKey parses a GPG key and unlocks it with a password, which may be empty if the key does not need to be unlocked
+// ReadKey parses a PGP key and unlocks it with a password, which may be empty if the key does not need to be unlocked
func ReadKey(key []byte, password string) (*openpgp.Entity, string, error) {
entity, err := getEntity(key)
if err != nil {
@@ -95,11 +95,11 @@ func ReadKey(key []byte, password string) (*openpgp.Entity, string, error) {
return entity, hex.EncodeToString(entity.PrimaryKey.Fingerprint), nil
}
-// GenerateKey generates a GPG key using x25519
+// GenerateKey generates a PGP key using x25519
func GenerateKey(
- fullName string, // Full name of the GPG key's holder
- email string, // Email of the GPG key's holder
- password string, // Password of the GPG key
+ fullName string, // Full name of the PGP key's holder
+ email string, // Email of the PGP key's holder
+ password string, // Password of the PGP key
) ([]byte, error) { // key, error
key, err := helper.GenerateKey(fullName, email, []byte(password), "x25519", 0)
if err != nil {
@@ -111,13 +111,13 @@ func GenerateKey(
// EncryptConfig provides the information to encrypt something
type EncryptConfig struct {
- PublicKey *openpgp.Entity // The GPG public key
+ PublicKey *openpgp.Entity // The PGP public key
ArmorCyphertext bool // Enables armoring the cyphertext
}
// SignatureConfig provides the information to sign something
type SignatureConfig struct {
- PrivateKey *openpgp.Entity // The GPG private key
+ PrivateKey *openpgp.Entity // The PGP private key
ArmorSignature bool // Enables armoring the signature
DetachSignature bool // Enables creating a detached signature
}
@@ -267,12 +267,12 @@ func EncryptSign(
// DecryptConfig provides the information to decrypt something
type DecryptConfig struct {
- PrivateKey *openpgp.Entity // The GPG private key
+ PrivateKey *openpgp.Entity // The PGP private key
}
// VerifyConfig provides the information to verify something
type VerifyConfig struct {
- PublicKey *openpgp.Entity // The GPG public key
+ PublicKey *openpgp.Entity // The PGP public key
DetachedSignature []byte // The detached signature to use (may also be armored)
}
diff --git a/pkg/stories/key_list.go b/pkg/stories/key_list.go
index 5499834..c06df56 100644
--- a/pkg/stories/key_list.go
+++ b/pkg/stories/key_list.go
@@ -5,7 +5,7 @@ import (
"github.com/pojntfx/keygaen/pkg/components"
)
-var demoKeys = []components.GPGKey{
+var demoKeys = []components.PGPKey{
{
ID: "039292",
Label: "039292",
diff --git a/web/index.css b/web/main.scss
similarity index 55%
rename from web/index.css
rename to web/main.scss
index 03ee1c9..f4c75a8 100644
--- a/web/index.css
+++ b/web/main.scss
@@ -1,3 +1,20 @@
+@import "node_modules/@patternfly/patternfly/sass-utilities/all.scss";
+
+$pf-global--font-path: "fonts";
+$fa-font-path: $pf-global--font-path + "/webfonts";
+
+@import "node_modules/@patternfly/patternfly/patternfly.scss";
+@import "node_modules/@patternfly/patternfly/patternfly-addons.scss";
+
+.pf-x-m-backdrop-blur {
+ backdrop-filter: blur(0.5rem);
+ -webkit-backdrop-filter: blur(0.5rem);
+}
+
+.pf-c-backdrop {
+ @extend .pf-x-m-backdrop-blur;
+}
+
.pf-x-c-tooltip-parent:hover .pf-x-c-tooltip,
.pf-x-c-tooltip-parent:focus .pf-x-c-tooltip {
visibility: visible;