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

Commit d75b571

Browse files
committed
feat: Add option to base64-encode keys
1 parent 60805a2 commit d75b571

File tree

3 files changed

+181
-34
lines changed

3 files changed

+181
-34
lines changed

pkg/components/export_key_modal.go

Lines changed: 92 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,21 @@ const (
1313
type ExportKeyModal struct {
1414
app.Compo
1515

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

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

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

26-
skipPublicKeyArmor bool
27-
skipPrivateKeyArmor bool
26+
skipPublicKeyArmor bool
27+
publicKeyBase64Encode bool
28+
29+
skipPrivateKeyArmor bool
30+
privateKeyBase64Encode bool
2831
}
2932

3033
func (c *ExportKeyModal) Render() app.UI {
@@ -91,6 +94,42 @@ func (c *ExportKeyModal) Render() app.UI {
9194
),
9295
),
9396
),
97+
app.Div().
98+
Aria("role", "group").
99+
Class("pf-c-form__group").
100+
Body(
101+
app.Div().
102+
Class("pf-c-form__group-control").
103+
Body(
104+
app.Div().
105+
Class("pf-c-check").
106+
Body(
107+
&Controlled{
108+
Component: app.Input().
109+
Class("pf-c-check__input").
110+
Type("checkbox").
111+
ID("public-base64-checkbox").
112+
OnInput(func(ctx app.Context, e app.Event) {
113+
c.publicKeyBase64Encode = !c.publicKeyBase64Encode
114+
}),
115+
Properties: map[string]interface{}{
116+
"checked": c.publicKeyBase64Encode,
117+
},
118+
},
119+
app.Label().
120+
Class("pf-c-check__label").
121+
For("public-base64-checkbox").
122+
Body(
123+
app.I().
124+
Class("fas fa-shield-alt pf-u-mr-sm"),
125+
app.Text("Base64 encode"),
126+
),
127+
app.Span().
128+
Class("pf-c-check__description").
129+
Text("Use a reduced alphabet for better portability."),
130+
),
131+
),
132+
),
94133
),
95134
),
96135
app.Div().
@@ -108,7 +147,7 @@ func (c *ExportKeyModal) Render() app.UI {
108147
Type("submit").
109148
Form(exportPublicKeyForm).
110149
OnClick(func(ctx app.Context, e app.Event) {
111-
c.OnDownloadPublicKey(!c.skipPublicKeyArmor)
150+
c.OnDownloadPublicKey(!c.skipPublicKeyArmor, c.publicKeyBase64Encode)
112151
}).
113152
Body(
114153
app.Span().
@@ -121,13 +160,13 @@ func (c *ExportKeyModal) Render() app.UI {
121160
app.Text("Download public key"),
122161
),
123162
app.If(
124-
!c.skipPublicKeyArmor,
163+
!c.skipPublicKeyArmor || c.publicKeyBase64Encode,
125164
app.Button().
126165
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").
127166
Type("submit").
128167
Form(exportPublicKeyForm).
129168
OnClick(func(ctx app.Context, e app.Event) {
130-
c.OnViewPublicKey()
169+
c.OnViewPublicKey(!c.skipPublicKeyArmor, c.publicKeyBase64Encode)
131170
}).
132171
Body(
133172
app.Span().
@@ -202,6 +241,42 @@ func (c *ExportKeyModal) Render() app.UI {
202241
),
203242
),
204243
),
244+
app.Div().
245+
Aria("role", "group").
246+
Class("pf-c-form__group").
247+
Body(
248+
app.Div().
249+
Class("pf-c-form__group-control").
250+
Body(
251+
app.Div().
252+
Class("pf-c-check").
253+
Body(
254+
&Controlled{
255+
Component: app.Input().
256+
Class("pf-c-check__input").
257+
Type("checkbox").
258+
ID("private-base64-checkbox").
259+
OnInput(func(ctx app.Context, e app.Event) {
260+
c.privateKeyBase64Encode = !c.privateKeyBase64Encode
261+
}),
262+
Properties: map[string]interface{}{
263+
"checked": c.privateKeyBase64Encode,
264+
},
265+
},
266+
app.Label().
267+
Class("pf-c-check__label").
268+
For("private-base64-checkbox").
269+
Body(
270+
app.I().
271+
Class("fas fa-shield-alt pf-u-mr-sm"),
272+
app.Text("Base64 encode"),
273+
),
274+
app.Span().
275+
Class("pf-c-check__description").
276+
Text("Use a reduced alphabet for better portability."),
277+
),
278+
),
279+
),
205280
),
206281
),
207282
app.Div().
@@ -219,7 +294,7 @@ func (c *ExportKeyModal) Render() app.UI {
219294
Type("submit").
220295
Form(exportPrivateKeyForm).
221296
OnClick(func(ctx app.Context, e app.Event) {
222-
c.OnDownloadPrivateKey(!c.skipPrivateKeyArmor)
297+
c.OnDownloadPrivateKey(!c.skipPrivateKeyArmor, c.privateKeyBase64Encode)
223298
}).
224299
Body(
225300
app.Span().
@@ -232,13 +307,13 @@ func (c *ExportKeyModal) Render() app.UI {
232307
app.Text("Download private key"),
233308
),
234309
app.If(
235-
!c.skipPrivateKeyArmor,
310+
!c.skipPrivateKeyArmor || c.privateKeyBase64Encode,
236311
app.Button().
237312
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").
238313
Type("submit").
239314
Form(exportPrivateKeyForm).
240315
OnClick(func(ctx app.Context, e app.Event) {
241-
c.OnViewPrivateKey()
316+
c.OnViewPrivateKey(!c.skipPrivateKeyArmor, c.privateKeyBase64Encode)
242317
}).
243318
Body(
244319
app.Span().
@@ -274,5 +349,8 @@ func (c *ExportKeyModal) Render() app.UI {
274349

275350
func (c *ExportKeyModal) clear() {
276351
c.skipPublicKeyArmor = false
352+
c.publicKeyBase64Encode = false
353+
277354
c.skipPrivateKeyArmor = false
355+
c.privateKeyBase64Encode = false
278356
}

pkg/components/home.go

Lines changed: 81 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package components
22

33
import (
4+
"encoding/base64"
45
"encoding/json"
56
"errors"
67
"log"
@@ -55,6 +56,9 @@ type Home struct {
5556

5657
viewPrivateKey bool
5758

59+
viewArmor bool
60+
viewBase64 bool
61+
5862
err error
5963
onRecover func()
6064

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

8993
privateKey := PGPKey{}
9094
privateKeyExport := []byte{}
95+
privateKeyExportBase64 := ""
9196
privateKeyExportArmored := ""
97+
privateKeyExportArmoredBase64 := ""
9298
for _, candidate := range c.keys {
9399
if candidate.ID == c.privateKeyID {
94100
privateKey = candidate
@@ -100,6 +106,8 @@ func (c *Home) Render() app.UI {
100106
break
101107
}
102108

109+
privateKeyExportBase64 = base64.StdEncoding.EncodeToString(rawKey)
110+
103111
parsedKey, err := crypto.NewKey(rawKey)
104112
if err != nil {
105113
c.panic(err, func() {})
@@ -121,13 +129,17 @@ func (c *Home) Render() app.UI {
121129
break
122130
}
123131

132+
privateKeyExportArmoredBase64 = base64.StdEncoding.EncodeToString(privateKeyExport)
133+
124134
break
125135
}
126136
}
127137

128138
publicKey := PGPKey{}
129139
publicKeyExport := []byte{}
140+
publicKeyExportBase64 := ""
130141
publicKeyExportArmored := ""
142+
publicKeyExportArmoredBase64 := ""
131143
for _, candidate := range c.keys {
132144
if candidate.ID == c.publicKeyID {
133145
publicKey = candidate
@@ -139,6 +151,8 @@ func (c *Home) Render() app.UI {
139151
break
140152
}
141153

154+
publicKeyExportBase64 = base64.StdEncoding.EncodeToString(rawKey)
155+
142156
parsedKey, err := crypto.NewKey(rawKey)
143157
if err != nil {
144158
c.panic(err, func() {})
@@ -160,6 +174,8 @@ func (c *Home) Render() app.UI {
160174
break
161175
}
162176

177+
publicKeyExportArmoredBase64 = base64.StdEncoding.EncodeToString(publicKeyExport)
178+
163179
break
164180
}
165181
}
@@ -882,31 +898,51 @@ func (c *Home) Render() app.UI {
882898
c.exportKeyModalOpen,
883899
&ExportKeyModal{
884900
PublicKey: c.publicKeyID != "",
885-
OnDownloadPublicKey: func(armor bool) {
901+
OnDownloadPublicKey: func(armor, base64encode bool) {
886902
if armor {
887-
c.download([]byte(publicKeyExportArmored), publicKey.Label+".asc", "text/plain")
903+
if base64encode {
904+
c.download([]byte(publicKeyExportArmoredBase64), publicKey.Label+".asc.txt", "text/plain")
905+
} else {
906+
c.download([]byte(publicKeyExportArmored), publicKey.Label+".asc", "text/plain")
907+
}
888908
} else {
889-
c.download(publicKeyExport, publicKey.Label+".pgp", "application/octet-stream")
909+
if base64encode {
910+
c.download([]byte(publicKeyExportBase64), publicKey.Label+".pgp.txt", "application/octet-stream")
911+
} else {
912+
c.download(publicKeyExport, publicKey.Label+".pgp", "application/octet-stream")
913+
}
890914
}
891915
},
892-
OnViewPublicKey: func() {
916+
OnViewPublicKey: func(armor, base64encode bool) {
893917
c.exportKeyModalOpen = false
894918
c.viewPrivateKey = false
895919
c.viewKeyModalOpen = true
920+
c.viewArmor = armor
921+
c.viewBase64 = base64encode
896922
},
897923

898924
PrivateKey: c.privateKeyID != "",
899-
OnDownloadPrivateKey: func(armor bool) {
925+
OnDownloadPrivateKey: func(armor, base64encode bool) {
900926
if armor {
901-
c.download([]byte(privateKeyExportArmored), privateKey.Label+".asc", "text/plain")
927+
if base64encode {
928+
c.download([]byte(privateKeyExportArmoredBase64), privateKey.Label+".asc.txt", "text/plain")
929+
} else {
930+
c.download([]byte(privateKeyExportArmored), privateKey.Label+".asc", "text/plain")
931+
}
902932
} else {
903-
c.download(privateKeyExport, privateKey.Label+".pgp", "application/octet-stream")
933+
if base64encode {
934+
c.download([]byte(privateKeyExportBase64), privateKey.Label+".pgp.txt", "application/octet-stream")
935+
} else {
936+
c.download(privateKeyExport, privateKey.Label+".pgp", "application/octet-stream")
937+
}
904938
}
905939
},
906-
OnViewPrivateKey: func() {
940+
OnViewPrivateKey: func(armor, base64encode bool) {
907941
c.exportKeyModalOpen = false
908942
c.viewPrivateKey = true
909943
c.viewKeyModalOpen = true
944+
c.viewArmor = armor
945+
c.viewBase64 = base64encode
910946
},
911947

912948
OnOK: func() {
@@ -922,8 +958,24 @@ func (c *Home) Render() app.UI {
922958
tabs := []TextOutputModalTab{
923959
{
924960
Language: "text/plain",
925-
Title: publicKey.Label + ".pub",
926-
Body: publicKeyExportArmored,
961+
Title: publicKey.Label + func() string {
962+
if c.viewArmor {
963+
if c.viewBase64 {
964+
return ".asc.txt"
965+
}
966+
967+
return ".asc"
968+
}
969+
970+
return ".txt"
971+
}(),
972+
Body: func() string {
973+
if c.viewBase64 {
974+
return publicKeyExportArmoredBase64
975+
}
976+
977+
return publicKeyExportArmored
978+
}(),
927979
},
928980
}
929981
title := `View Public Key "` + publicKey.Label + `"`
@@ -932,8 +984,24 @@ func (c *Home) Render() app.UI {
932984
tabs = []TextOutputModalTab{
933985
{
934986
Language: "text/plain",
935-
Title: privateKey.Label,
936-
Body: privateKeyExportArmored,
987+
Title: privateKey.Label + ".asc" + func() string {
988+
if c.viewArmor {
989+
if c.viewBase64 {
990+
return ".asc.txt"
991+
}
992+
993+
return ".asc"
994+
}
995+
996+
return ".txt"
997+
}(),
998+
Body: func() string {
999+
if c.viewBase64 {
1000+
return privateKeyExportArmoredBase64
1001+
}
1002+
1003+
return privateKeyExportArmored
1004+
}(),
9371005
},
9381006
}
9391007
title = `View Private Key "` + privateKey.Label + `"`
@@ -945,6 +1013,7 @@ func (c *Home) Render() app.UI {
9451013
OnClose: func() {
9461014
c.viewKeyModalOpen = false
9471015
c.exportKeyModalOpen = true
1016+
c.viewBase64 = false
9481017

9491018
c.Update()
9501019
},

pkg/stories/export_key_modal.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,19 @@ func (c *ExportKeyModalStory) Render() app.UI {
2727
c.WithRoot(
2828
&components.ExportKeyModal{
2929
PublicKey: true,
30-
OnDownloadPublicKey: func(armor bool) {
31-
app.Window().Call("alert", fmt.Sprintf("Downloaded public key with armor set to %v", armor))
30+
OnDownloadPublicKey: func(armor, base64encode bool) {
31+
app.Window().Call("alert", fmt.Sprintf("Downloaded public key with armor set to %v with base64encode %v", armor, base64encode))
3232
},
33-
OnViewPublicKey: func() {
34-
app.Window().Call("alert", "Viewed public key")
33+
OnViewPublicKey: func(armor, base64encode bool) {
34+
app.Window().Call("alert", fmt.Sprintf("Viewed public key with armor set to %v with base64encode %v", armor, base64encode))
3535
},
3636

3737
PrivateKey: true,
38-
OnDownloadPrivateKey: func(armor bool) {
39-
app.Window().Call("alert", fmt.Sprintf("Downloaded private key with armor set to %v", armor))
38+
OnDownloadPrivateKey: func(armor, base64encode bool) {
39+
app.Window().Call("alert", fmt.Sprintf("Downloaded private key with armor set to %v with base64encode %v", armor, base64encode))
4040
},
41-
OnViewPrivateKey: func() {
42-
app.Window().Call("alert", "Viewed private key")
41+
OnViewPrivateKey: func(armor, base64encode bool) {
42+
app.Window().Call("alert", fmt.Sprintf("Viewed private key with armor set to %v with base64encode %v", armor, base64encode))
4343
},
4444

4545
OnOK: func() {

0 commit comments

Comments
 (0)