-
+
diff --git a/frontend/src/views/InterfaceView.vue b/frontend/src/views/InterfaceView.vue
index fd02516..9074c03 100644
--- a/frontend/src/views/InterfaceView.vue
+++ b/frontend/src/views/InterfaceView.vue
@@ -24,6 +24,24 @@ function calculateInterfaceName(id, name) {
return result
}
+async function download() {
+ await interfaces.LoadInterfaceConfig(interfaces.GetSelected.Identifier)
+
+ // credit: https://www.bitdegree.org/learn/javascript-download
+ let filename = interfaces.GetSelected.Identifier + ".conf"
+ let text = interfaces.configuration
+
+ let element = document.createElement('a')
+ element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text))
+ element.setAttribute('download', filename)
+
+ element.style.display = 'none'
+ document.body.appendChild(element)
+
+ element.click()
+ document.body.removeChild(element)
+}
+
onMounted(async () => {
await interfaces.LoadInterfaces()
await peers.LoadPeers()
@@ -80,7 +98,7 @@ onMounted(async () => {
diff --git a/go.mod b/go.mod
index a0ad195..ac8acf5 100644
--- a/go.mod
+++ b/go.mod
@@ -20,7 +20,6 @@ require (
github.com/vishvananda/netlink v1.1.0
github.com/xhit/go-simple-mail/v2 v2.13.0
github.com/yeqown/go-qrcode/v2 v2.2.1
- github.com/yeqown/go-qrcode/writer/standard v1.2.1
golang.org/x/crypto v0.10.0
golang.org/x/oauth2 v0.9.0
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6
@@ -39,7 +38,6 @@ require (
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dchest/uniuri v1.2.0 // indirect
- github.com/fogleman/gg v1.3.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect
@@ -56,7 +54,6 @@ require (
github.com/goccy/go-json v0.10.2 // indirect
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
github.com/golang-sql/sqlexp v0.1.0 // indirect
- github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/uuid v1.3.0 // indirect
@@ -83,7 +80,6 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
- github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b // indirect
github.com/stretchr/objx v0.5.0 // indirect
@@ -93,7 +89,6 @@ require (
github.com/vishvananda/netns v0.0.4 // indirect
github.com/yeqown/reedsolomon v1.0.0 // indirect
golang.org/x/arch v0.3.0 // indirect
- golang.org/x/image v0.0.0-20200927104501-e162460cd6b5 // indirect
golang.org/x/net v0.11.0 // indirect
golang.org/x/sync v0.3.0 // indirect
golang.org/x/sys v0.9.0 // indirect
diff --git a/go.sum b/go.sum
index 6b85903..3ea2964 100644
--- a/go.sum
+++ b/go.sum
@@ -28,8 +28,6 @@ github.com/dchest/uniuri v1.2.0 h1:koIcOUdrTIivZgSLhHQvKgqdWZq5d7KdMEWF1Ud6+5g=
github.com/dchest/uniuri v1.2.0/go.mod h1:fSzm4SLHzNZvWLvWJew423PhAzkpNQYq+uNLq4kxhkY=
github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko=
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
-github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
-github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
@@ -91,8 +89,6 @@ github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0kt
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
-github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
-github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
@@ -194,8 +190,6 @@ github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZ
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
-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/prometheus-community/pro-bing v0.2.0 h1:hyK7yPFndU3LCDwEQJwPQUCjNkp1DGP/VxyzrWfXZUU=
@@ -250,8 +244,6 @@ github.com/xhit/go-simple-mail/v2 v2.13.0 h1:OANWU9jHZrVfBkNkvLf8Ww0fexwpQVF/v/5
github.com/xhit/go-simple-mail/v2 v2.13.0/go.mod h1:b7P5ygho6SYE+VIqpxA6QkYfv4teeyG4MKqB3utRu98=
github.com/yeqown/go-qrcode/v2 v2.2.1 h1:Jc1Q916fwC05R8C7mpWDbrT9tyLPaLLKDABoC5XBCe8=
github.com/yeqown/go-qrcode/v2 v2.2.1/go.mod h1:2Qsk2APUCPne0TsRo40DIkI5MYnbzYKCnKGEFWrxd24=
-github.com/yeqown/go-qrcode/writer/standard v1.2.1 h1:FMRZiur5yApUIe4fqtqmcdl/XQTZAZWt2DhkPx4VIW0=
-github.com/yeqown/go-qrcode/writer/standard v1.2.1/go.mod h1:ZelyDFiVymrauRjUn454iF7bjsabmB1vixkDA5kq2bw=
github.com/yeqown/reedsolomon v1.0.0 h1:x1h/Ej/uJnNu8jaX7GLHBWmZKCAWjEJTetkqaabr4B0=
github.com/yeqown/reedsolomon v1.0.0/go.mod h1:P76zpcn2TCuL0ul1Fso373qHRc69LKwAw/Iy6g1WiiM=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
@@ -267,8 +259,6 @@ golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
-golang.org/x/image v0.0.0-20200927104501-e162460cd6b5 h1:QelT11PB4FXiDEXucrfNckHoFxwt8USGY1ajP1ZF5lM=
-golang.org/x/image v0.0.0-20200927104501-e162460cd6b5/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
diff --git a/internal/app/filetemplate/manager.go b/internal/app/filetemplate/manager.go
index 170c602..6b05d92 100644
--- a/internal/app/filetemplate/manager.go
+++ b/internal/app/filetemplate/manager.go
@@ -7,7 +7,6 @@ import (
"github.com/h44z/wg-portal/internal/config"
"github.com/h44z/wg-portal/internal/domain"
"github.com/yeqown/go-qrcode/v2"
- "github.com/yeqown/go-qrcode/writer/standard"
"io"
)
@@ -77,7 +76,11 @@ func (m Manager) GetPeerConfigQrCode(ctx context.Context, id domain.PeerIdentifi
buf := bytes.NewBuffer(nil)
wr := nopCloser{Writer: buf}
- qrWriter := standard.NewWithWriter(wr, standard.WithQRWidth(40), standard.WithBuiltinImageEncoder(standard.PNG_FORMAT))
+ option := Option{
+ Padding: 8, // padding pixels around the qr code.
+ BlockSize: 4, // block pixels which represents a bit data.
+ }
+ qrWriter := NewCompressedWriter(wr, &option)
err = code.Save(qrWriter)
if err != nil {
return nil, fmt.Errorf("failed to write code for %s: %w", id, err)
diff --git a/internal/app/filetemplate/qrwriter.go b/internal/app/filetemplate/qrwriter.go
new file mode 100644
index 0000000..c67a42f
--- /dev/null
+++ b/internal/app/filetemplate/qrwriter.go
@@ -0,0 +1,88 @@
+package filetemplate
+
+// waiting for https://github.com/yeqown/go-qrcode/pull/85 to get merged
+// meanwhile we use our own writer implementation
+
+import (
+ "image"
+ "image/color"
+ "image/png"
+ "io"
+
+ "github.com/yeqown/go-qrcode/v2"
+)
+
+type Option struct {
+ Padding int
+ BlockSize int
+}
+
+// compressedWriter implements issue#69, generating compressed images
+// in some special situations, such as, network transferring.
+// https://github.com/yeqown/go-qrcode/issues/69
+type compressedWriter struct {
+ fd io.WriteCloser
+
+ option *Option
+}
+
+var (
+ backgroundColor = color.Gray{Y: 0xff}
+ foregroundColor = color.Gray{Y: 0x00}
+)
+
+func NewCompressedWriter(writer io.WriteCloser, opt *Option) qrcode.Writer {
+ return compressedWriter{fd: writer, option: opt}
+}
+
+func (w compressedWriter) Write(mat qrcode.Matrix) error {
+ padding := w.option.Padding
+ blockWidth := w.option.BlockSize
+ width := mat.Width()*blockWidth + 2*padding
+ height := width
+
+ img := image.NewPaletted(
+ image.Rect(0, 0, width, height),
+ color.Palette([]color.Color{backgroundColor, foregroundColor}),
+ )
+ bgColor := uint8(img.Palette.Index(backgroundColor))
+ fgColor := uint8(img.Palette.Index(foregroundColor))
+
+ rectangle := func(x1, y1 int, x2, y2 int, img *image.Paletted, color uint8) {
+ for x := x1; x < x2; x++ {
+ for y := y1; y < y2; y++ {
+ pos := img.PixOffset(x, y)
+ img.Pix[pos] = color
+ }
+ }
+ }
+
+ // background
+ rectangle(0, 0, width, height, img, bgColor)
+
+ mat.Iterate(qrcode.IterDirection_COLUMN, func(x int, y int, v qrcode.QRValue) {
+ sx := x*blockWidth + padding
+ sy := y*blockWidth + padding
+ es := (x+1)*blockWidth + padding
+ ey := (y+1)*blockWidth + padding
+
+ if v.IsSet() {
+ rectangle(sx, sy, es, ey, img, fgColor)
+ }
+
+ //switch v.IsSet() {
+ //case false:
+ // gray = backgroundColor
+ //default:
+ // gray = foregroundColor
+ //}
+
+ })
+
+ encoder := png.Encoder{CompressionLevel: png.BestCompression}
+ return encoder.Encode(w.fd, img)
+}
+
+func (w compressedWriter) Close() error {
+ return w.fd.Close()
+}