Skip to content
This repository has been archived by the owner on Jul 12, 2024. It is now read-only.

Commit

Permalink
feat: Add option to base64-encode keys
Browse files Browse the repository at this point in the history
  • Loading branch information
pojntfx committed Oct 28, 2022
1 parent 60805a2 commit d75b571
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 34 deletions.
106 changes: 92 additions & 14 deletions pkg/components/export_key_modal.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,21 @@ const (
type ExportKeyModal struct {
app.Compo

PublicKey bool // Whether to display the options for a public key
OnDownloadPublicKey func(armor bool) // Handler to call to download the public key
OnViewPublicKey func() // Handler to call to view the public key
PublicKey bool // Whether to display the options for a public key
OnDownloadPublicKey func(armor, base64encode bool) // Handler to call to download the public key
OnViewPublicKey func(armor, base64encode bool) // Handler to call to view the public key

PrivateKey bool // Whether to display the options for a private key
OnDownloadPrivateKey func(armor bool) // Handler to call to download the private key
OnViewPrivateKey func() // Handler to call to view the private key
PrivateKey bool // Whether to display the options for a private key
OnDownloadPrivateKey func(armor, base64encode bool) // Handler to call to download the private key
OnViewPrivateKey func(armor, base64encode bool) // Handler to call to view the private key

OnOK func() // Handler to call when dismissing the modal

skipPublicKeyArmor bool
skipPrivateKeyArmor bool
skipPublicKeyArmor bool
publicKeyBase64Encode bool

skipPrivateKeyArmor bool
privateKeyBase64Encode bool
}

func (c *ExportKeyModal) Render() app.UI {
Expand Down Expand Up @@ -91,6 +94,42 @@ func (c *ExportKeyModal) Render() app.UI {
),
),
),
app.Div().
Aria("role", "group").
Class("pf-c-form__group").
Body(
app.Div().
Class("pf-c-form__group-control").
Body(
app.Div().
Class("pf-c-check").
Body(
&Controlled{
Component: app.Input().
Class("pf-c-check__input").
Type("checkbox").
ID("public-base64-checkbox").
OnInput(func(ctx app.Context, e app.Event) {
c.publicKeyBase64Encode = !c.publicKeyBase64Encode
}),
Properties: map[string]interface{}{
"checked": c.publicKeyBase64Encode,
},
},
app.Label().
Class("pf-c-check__label").
For("public-base64-checkbox").
Body(
app.I().
Class("fas fa-shield-alt pf-u-mr-sm"),
app.Text("Base64 encode"),
),
app.Span().
Class("pf-c-check__description").
Text("Use a reduced alphabet for better portability."),
),
),
),
),
),
app.Div().
Expand All @@ -108,7 +147,7 @@ func (c *ExportKeyModal) Render() app.UI {
Type("submit").
Form(exportPublicKeyForm).
OnClick(func(ctx app.Context, e app.Event) {
c.OnDownloadPublicKey(!c.skipPublicKeyArmor)
c.OnDownloadPublicKey(!c.skipPublicKeyArmor, c.publicKeyBase64Encode)
}).
Body(
app.Span().
Expand All @@ -121,13 +160,13 @@ func (c *ExportKeyModal) Render() app.UI {
app.Text("Download public key"),
),
app.If(
!c.skipPublicKeyArmor,
!c.skipPublicKeyArmor || c.publicKeyBase64Encode,
app.Button().
Class("pf-c-button pf-m-control pf-u-mr-sm pf-u-display-block pf-u-display-inline-block-on-md pf-u-w-100 pf-u-w-initial-on-md").
Type("submit").
Form(exportPublicKeyForm).
OnClick(func(ctx app.Context, e app.Event) {
c.OnViewPublicKey()
c.OnViewPublicKey(!c.skipPublicKeyArmor, c.publicKeyBase64Encode)
}).
Body(
app.Span().
Expand Down Expand Up @@ -202,6 +241,42 @@ func (c *ExportKeyModal) Render() app.UI {
),
),
),
app.Div().
Aria("role", "group").
Class("pf-c-form__group").
Body(
app.Div().
Class("pf-c-form__group-control").
Body(
app.Div().
Class("pf-c-check").
Body(
&Controlled{
Component: app.Input().
Class("pf-c-check__input").
Type("checkbox").
ID("private-base64-checkbox").
OnInput(func(ctx app.Context, e app.Event) {
c.privateKeyBase64Encode = !c.privateKeyBase64Encode
}),
Properties: map[string]interface{}{
"checked": c.privateKeyBase64Encode,
},
},
app.Label().
Class("pf-c-check__label").
For("private-base64-checkbox").
Body(
app.I().
Class("fas fa-shield-alt pf-u-mr-sm"),
app.Text("Base64 encode"),
),
app.Span().
Class("pf-c-check__description").
Text("Use a reduced alphabet for better portability."),
),
),
),
),
),
app.Div().
Expand All @@ -219,7 +294,7 @@ func (c *ExportKeyModal) Render() app.UI {
Type("submit").
Form(exportPrivateKeyForm).
OnClick(func(ctx app.Context, e app.Event) {
c.OnDownloadPrivateKey(!c.skipPrivateKeyArmor)
c.OnDownloadPrivateKey(!c.skipPrivateKeyArmor, c.privateKeyBase64Encode)
}).
Body(
app.Span().
Expand All @@ -232,13 +307,13 @@ func (c *ExportKeyModal) Render() app.UI {
app.Text("Download private key"),
),
app.If(
!c.skipPrivateKeyArmor,
!c.skipPrivateKeyArmor || c.privateKeyBase64Encode,
app.Button().
Class("pf-c-button pf-m-control pf-u-mr-sm pf-u-display-block pf-u-display-inline-block-on-md pf-u-w-100 pf-u-w-initial-on-md").
Type("submit").
Form(exportPrivateKeyForm).
OnClick(func(ctx app.Context, e app.Event) {
c.OnViewPrivateKey()
c.OnViewPrivateKey(!c.skipPrivateKeyArmor, c.privateKeyBase64Encode)
}).
Body(
app.Span().
Expand Down Expand Up @@ -274,5 +349,8 @@ func (c *ExportKeyModal) Render() app.UI {

func (c *ExportKeyModal) clear() {
c.skipPublicKeyArmor = false
c.publicKeyBase64Encode = false

c.skipPrivateKeyArmor = false
c.privateKeyBase64Encode = false
}
93 changes: 81 additions & 12 deletions pkg/components/home.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package components

import (
"encoding/base64"
"encoding/json"
"errors"
"log"
Expand Down Expand Up @@ -55,6 +56,9 @@ type Home struct {

viewPrivateKey bool

viewArmor bool
viewBase64 bool

err error
onRecover func()

Expand Down Expand Up @@ -88,7 +92,9 @@ func (c *Home) Render() app.UI {

privateKey := PGPKey{}
privateKeyExport := []byte{}
privateKeyExportBase64 := ""
privateKeyExportArmored := ""
privateKeyExportArmoredBase64 := ""
for _, candidate := range c.keys {
if candidate.ID == c.privateKeyID {
privateKey = candidate
Expand All @@ -100,6 +106,8 @@ func (c *Home) Render() app.UI {
break
}

privateKeyExportBase64 = base64.StdEncoding.EncodeToString(rawKey)

parsedKey, err := crypto.NewKey(rawKey)
if err != nil {
c.panic(err, func() {})
Expand All @@ -121,13 +129,17 @@ func (c *Home) Render() app.UI {
break
}

privateKeyExportArmoredBase64 = base64.StdEncoding.EncodeToString(privateKeyExport)

break
}
}

publicKey := PGPKey{}
publicKeyExport := []byte{}
publicKeyExportBase64 := ""
publicKeyExportArmored := ""
publicKeyExportArmoredBase64 := ""
for _, candidate := range c.keys {
if candidate.ID == c.publicKeyID {
publicKey = candidate
Expand All @@ -139,6 +151,8 @@ func (c *Home) Render() app.UI {
break
}

publicKeyExportBase64 = base64.StdEncoding.EncodeToString(rawKey)

parsedKey, err := crypto.NewKey(rawKey)
if err != nil {
c.panic(err, func() {})
Expand All @@ -160,6 +174,8 @@ func (c *Home) Render() app.UI {
break
}

publicKeyExportArmoredBase64 = base64.StdEncoding.EncodeToString(publicKeyExport)

break
}
}
Expand Down Expand Up @@ -882,31 +898,51 @@ func (c *Home) Render() app.UI {
c.exportKeyModalOpen,
&ExportKeyModal{
PublicKey: c.publicKeyID != "",
OnDownloadPublicKey: func(armor bool) {
OnDownloadPublicKey: func(armor, base64encode bool) {
if armor {
c.download([]byte(publicKeyExportArmored), publicKey.Label+".asc", "text/plain")
if base64encode {
c.download([]byte(publicKeyExportArmoredBase64), publicKey.Label+".asc.txt", "text/plain")
} else {
c.download([]byte(publicKeyExportArmored), publicKey.Label+".asc", "text/plain")
}
} else {
c.download(publicKeyExport, publicKey.Label+".pgp", "application/octet-stream")
if base64encode {
c.download([]byte(publicKeyExportBase64), publicKey.Label+".pgp.txt", "application/octet-stream")
} else {
c.download(publicKeyExport, publicKey.Label+".pgp", "application/octet-stream")
}
}
},
OnViewPublicKey: func() {
OnViewPublicKey: func(armor, base64encode bool) {
c.exportKeyModalOpen = false
c.viewPrivateKey = false
c.viewKeyModalOpen = true
c.viewArmor = armor
c.viewBase64 = base64encode
},

PrivateKey: c.privateKeyID != "",
OnDownloadPrivateKey: func(armor bool) {
OnDownloadPrivateKey: func(armor, base64encode bool) {
if armor {
c.download([]byte(privateKeyExportArmored), privateKey.Label+".asc", "text/plain")
if base64encode {
c.download([]byte(privateKeyExportArmoredBase64), privateKey.Label+".asc.txt", "text/plain")
} else {
c.download([]byte(privateKeyExportArmored), privateKey.Label+".asc", "text/plain")
}
} else {
c.download(privateKeyExport, privateKey.Label+".pgp", "application/octet-stream")
if base64encode {
c.download([]byte(privateKeyExportBase64), privateKey.Label+".pgp.txt", "application/octet-stream")
} else {
c.download(privateKeyExport, privateKey.Label+".pgp", "application/octet-stream")
}
}
},
OnViewPrivateKey: func() {
OnViewPrivateKey: func(armor, base64encode bool) {
c.exportKeyModalOpen = false
c.viewPrivateKey = true
c.viewKeyModalOpen = true
c.viewArmor = armor
c.viewBase64 = base64encode
},

OnOK: func() {
Expand All @@ -922,8 +958,24 @@ func (c *Home) Render() app.UI {
tabs := []TextOutputModalTab{
{
Language: "text/plain",
Title: publicKey.Label + ".pub",
Body: publicKeyExportArmored,
Title: publicKey.Label + func() string {
if c.viewArmor {
if c.viewBase64 {
return ".asc.txt"
}

return ".asc"
}

return ".txt"
}(),
Body: func() string {
if c.viewBase64 {
return publicKeyExportArmoredBase64
}

return publicKeyExportArmored
}(),
},
}
title := `View Public Key "` + publicKey.Label + `"`
Expand All @@ -932,8 +984,24 @@ func (c *Home) Render() app.UI {
tabs = []TextOutputModalTab{
{
Language: "text/plain",
Title: privateKey.Label,
Body: privateKeyExportArmored,
Title: privateKey.Label + ".asc" + func() string {
if c.viewArmor {
if c.viewBase64 {
return ".asc.txt"
}

return ".asc"
}

return ".txt"
}(),
Body: func() string {
if c.viewBase64 {
return privateKeyExportArmoredBase64
}

return privateKeyExportArmored
}(),
},
}
title = `View Private Key "` + privateKey.Label + `"`
Expand All @@ -945,6 +1013,7 @@ func (c *Home) Render() app.UI {
OnClose: func() {
c.viewKeyModalOpen = false
c.exportKeyModalOpen = true
c.viewBase64 = false

c.Update()
},
Expand Down
16 changes: 8 additions & 8 deletions pkg/stories/export_key_modal.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,19 @@ func (c *ExportKeyModalStory) Render() app.UI {
c.WithRoot(
&components.ExportKeyModal{
PublicKey: true,
OnDownloadPublicKey: func(armor bool) {
app.Window().Call("alert", fmt.Sprintf("Downloaded public key with armor set to %v", armor))
OnDownloadPublicKey: func(armor, base64encode bool) {
app.Window().Call("alert", fmt.Sprintf("Downloaded public key with armor set to %v with base64encode %v", armor, base64encode))
},
OnViewPublicKey: func() {
app.Window().Call("alert", "Viewed public key")
OnViewPublicKey: func(armor, base64encode bool) {
app.Window().Call("alert", fmt.Sprintf("Viewed public key with armor set to %v with base64encode %v", armor, base64encode))
},

PrivateKey: true,
OnDownloadPrivateKey: func(armor bool) {
app.Window().Call("alert", fmt.Sprintf("Downloaded private key with armor set to %v", armor))
OnDownloadPrivateKey: func(armor, base64encode bool) {
app.Window().Call("alert", fmt.Sprintf("Downloaded private key with armor set to %v with base64encode %v", armor, base64encode))
},
OnViewPrivateKey: func() {
app.Window().Call("alert", "Viewed private key")
OnViewPrivateKey: func(armor, base64encode bool) {
app.Window().Call("alert", fmt.Sprintf("Viewed private key with armor set to %v with base64encode %v", armor, base64encode))
},

OnOK: func() {
Expand Down

0 comments on commit d75b571

Please sign in to comment.