From 5213089b03c0326a02c42b8da29b53f28684667a Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Thu, 11 Aug 2022 10:00:03 +0200 Subject: [PATCH] Add -rev flag to generate otpauth-migration:// QR-code Resolves #22 --- README.md | 4 +++- main.go | 10 +++++++--- migration/handler.go | 2 +- migration/qrcode.go | 16 +++++++--------- migration/unmarshal.go | 10 ++++++++++ 5 files changed, 28 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 06a0754..ecb7513 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,9 @@ to plain [otpauth links](https://github.com/google/google-authenticator/wiki/Key -link string migration link (required) -qr - generate QR-codes + generate QR-codes (optauth://) + -rev + reverse QR-code (otpauth-migration://) ``` ## Example diff --git a/main.go b/main.go index ef9a761..582326f 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,6 @@ // Google Authenticator migration decoder // // convert "otpauth-migration" links to plain "otpauth" links -// package main import ( @@ -32,7 +31,8 @@ func main() { cache = flag.String("cache", "migration.bin", "cache file") http = flag.String("http", "", "serve http (e.g. localhost:6060)") eval = flag.Bool("eval", false, "evaluate otps") - qr = flag.Bool("qr", false, "generate QR-codes") + qr = flag.Bool("qr", false, "generate QR-codes (optauth://)") + rev = flag.Bool("rev", false, "reverse QR-code (otpauth-migration://)") info = flag.Bool("info", false, "display batch info") ) flag.Parse() @@ -54,10 +54,14 @@ func main() { } case *qr: for _, op := range p.OtpParameters { - if err := op.WriteFile(op.FileName() + ".png"); err != nil { + if err := migration.PNG(op.FileName()+".png", op.URL()); err != nil { log.Fatal("write file: ", err) } } + case *rev: + if err := migration.PNG("otpauth-migration.png", migration.URL(data)); err != nil { + log.Fatal(err) + } case *eval: for _, op := range p.OtpParameters { fmt.Printf("%06d %s\n", op.Evaluate(), op.Name) diff --git a/migration/handler.go b/migration/handler.go index 402accb..ef335a7 100644 --- a/migration/handler.go +++ b/migration/handler.go @@ -3,7 +3,7 @@ package migration import "net/http" func (op *Payload_OtpParameters) ServeHTTP(w http.ResponseWriter, r *http.Request) { - pic, err := op.QR() + pic, err := QR(op.URL()) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return diff --git a/migration/qrcode.go b/migration/qrcode.go index 2623bc4..bcd9253 100644 --- a/migration/qrcode.go +++ b/migration/qrcode.go @@ -2,23 +2,21 @@ package migration import ( "io/ioutil" + "net/url" "github.com/skip2/go-qrcode" ) // QR image bytes as PNG -func (op *Payload_OtpParameters) QR() ([]byte, error) { - return qrcode.Encode(op.URL().String(), qrcode.Medium, -3) +func QR(u *url.URL) ([]byte, error) { + return qrcode.Encode(u.String(), qrcode.Medium, -3) } -// WriteFile writes QR code as PNG to specified file -func (op *Payload_OtpParameters) WriteFile(fname string) error { - pic, err := op.QR() +// PNG writes QR code as PNG to specified file +func PNG(filename string, u *url.URL) error { + pic, err := QR(u) if err != nil { return err } - if err := ioutil.WriteFile(fname, pic, 0600); err != nil { - return err - } - return nil + return ioutil.WriteFile(filename, pic, 0600) } diff --git a/migration/unmarshal.go b/migration/unmarshal.go index b74055d..93ab5a0 100644 --- a/migration/unmarshal.go +++ b/migration/unmarshal.go @@ -31,6 +31,16 @@ func Data(link string) ([]byte, error) { return base64.StdEncoding.DecodeString(data) } +func URL(data []byte) *url.URL { + v := make(url.Values) + v.Add("data", base64.StdEncoding.EncodeToString(data)) + return &url.URL{ + Scheme: "otpauth-migration", + Host: "offline", + RawQuery: v.Encode(), + } +} + // Unmarshal otpauth-migration data func Unmarshal(data []byte) (*Payload, error) { var p Payload