From f08740991b7a33a245b317d7d4153ce1d192a2a2 Mon Sep 17 00:00:00 2001 From: h44z Date: Sun, 29 Jun 2025 19:47:53 +0200 Subject: [PATCH] support for raw-wireguard and wg-quick style peer configurations (#441) (#473) --- frontend/src/components/PeerViewModal.vue | 39 +++++++++++++++---- frontend/src/lang/translations/de.json | 3 +- frontend/src/lang/translations/en.json | 3 +- frontend/src/stores/peers.js | 8 ++-- .../app/api/core/assets/doc/v0_swagger.json | 18 +++++++++ .../app/api/core/assets/doc/v0_swagger.yaml | 12 ++++++ internal/app/api/v0/backend/peer_service.go | 26 ++++++++----- .../app/api/v0/handlers/endpoint_peers.go | 29 +++++++++++--- .../api/v1/backend/provisioning_service.go | 8 ++-- internal/app/configfile/manager.go | 10 ++--- internal/app/configfile/template.go | 5 ++- internal/app/configfile/tpl_files/wg_peer.tpl | 16 ++++++-- internal/app/mail/manager.go | 20 ++++++---- internal/domain/base.go | 3 ++ 14 files changed, 149 insertions(+), 51 deletions(-) diff --git a/frontend/src/components/PeerViewModal.vue b/frontend/src/components/PeerViewModal.vue index 686ee8d..91c2d86 100644 --- a/frontend/src/components/PeerViewModal.vue +++ b/frontend/src/components/PeerViewModal.vue @@ -50,7 +50,7 @@ const selectedStats = computed(() => { if (!s) { if (!!props.peerId || props.peerId.length) { - p = profile.Statistics(props.peerId) + s = profile.Statistics(props.peerId) } else { s = freshStats() // dummy stats to avoid 'undefined' exceptions } @@ -79,13 +79,19 @@ const title = computed(() => { } }) +const configStyle = ref("wgquick") + watch(() => props.visible, async (newValue, oldValue) => { if (oldValue === false && newValue === true) { // if modal is shown - await peers.LoadPeerConfig(selectedPeer.value.Identifier) + await peers.LoadPeerConfig(selectedPeer.value.Identifier, configStyle.value) configString.value = peers.configuration } -} -) +}) + +watch(() => configStyle.value, async () => { + await peers.LoadPeerConfig(selectedPeer.value.Identifier, configStyle.value) + configString.value = peers.configuration +}) function download() { // credit: https://www.bitdegree.org/learn/javascript-download @@ -103,7 +109,7 @@ function download() { } function email() { - peers.MailPeerConfig(settings.Setting("MailLinkOnly"), [selectedPeer.value.Identifier]).catch(e => { + peers.MailPeerConfig(settings.Setting("MailLinkOnly"), configStyle.value, [selectedPeer.value.Identifier]).catch(e => { notify({ title: "Failed to send mail with peer configuration!", text: e.toString(), @@ -114,7 +120,7 @@ function email() { function ConfigQrUrl() { if (props.peerId.length) { - return apiWrapper.url(`/peer/config-qr/${base64_url_encode(props.peerId)}`) + return apiWrapper.url(`/peer/config-qr/${base64_url_encode(props.peerId)}?style=${configStyle.value}`) } return '' } @@ -124,6 +130,15 @@ function ConfigQrUrl() { - +} + +.btn-switch-group .btn { + border-width: 1px; + padding: 5px; + line-height: 1; +} + diff --git a/frontend/src/lang/translations/de.json b/frontend/src/lang/translations/de.json index ff8af74..859c70e 100644 --- a/frontend/src/lang/translations/de.json +++ b/frontend/src/lang/translations/de.json @@ -467,7 +467,8 @@ "connected-since": "Verbunden seit", "endpoint": "Endpunkt", "button-download": "Konfiguration herunterladen", - "button-email": "Konfiguration per E-Mail senden" + "button-email": "Konfiguration per E-Mail senden", + "style-label": "Konfigurationsformat" }, "peer-edit": { "headline-edit-peer": "Peer bearbeiten:", diff --git a/frontend/src/lang/translations/en.json b/frontend/src/lang/translations/en.json index 06e95e0..57a129a 100644 --- a/frontend/src/lang/translations/en.json +++ b/frontend/src/lang/translations/en.json @@ -468,7 +468,8 @@ "connected-since": "Connected since", "endpoint": "Endpoint", "button-download": "Download configuration", - "button-email": "Send configuration via E-Mail" + "button-email": "Send configuration via E-Mail", + "style-label": "Configuration Style" }, "peer-edit": { "headline-edit-peer": "Edit peer:", diff --git a/frontend/src/stores/peers.js b/frontend/src/stores/peers.js index c59e4c7..c691a01 100644 --- a/frontend/src/stores/peers.js +++ b/frontend/src/stores/peers.js @@ -142,8 +142,8 @@ export const peerStore = defineStore('peers', { }) }) }, - async MailPeerConfig(linkOnly, ids) { - return apiWrapper.post(`${baseUrl}/config-mail`, { + async MailPeerConfig(linkOnly, style, ids) { + return apiWrapper.post(`${baseUrl}/config-mail?style=${style}`, { Identifiers: ids, LinkOnly: linkOnly }) @@ -158,8 +158,8 @@ export const peerStore = defineStore('peers', { throw new Error(error) }) }, - async LoadPeerConfig(id) { - return apiWrapper.get(`${baseUrl}/config/${base64_url_encode(id)}`) + async LoadPeerConfig(id, style) { + return apiWrapper.get(`${baseUrl}/config/${base64_url_encode(id)}?style=${style}`) .then(this.setPeerConfig) .catch(error => { this.configuration = "" diff --git a/internal/app/api/core/assets/doc/v0_swagger.json b/internal/app/api/core/assets/doc/v0_swagger.json index ad07099..fc2ebc8 100644 --- a/internal/app/api/core/assets/doc/v0_swagger.json +++ b/internal/app/api/core/assets/doc/v0_swagger.json @@ -819,6 +819,12 @@ "schema": { "$ref": "#/definitions/model.PeerMailRequest" } + }, + { + "type": "string", + "description": "The configuration style", + "name": "style", + "in": "query" } ], "responses": { @@ -858,6 +864,12 @@ "name": "id", "in": "path", "required": true + }, + { + "type": "string", + "description": "The configuration style", + "name": "style", + "in": "query" } ], "responses": { @@ -899,6 +911,12 @@ "name": "id", "in": "path", "required": true + }, + { + "type": "string", + "description": "The configuration style", + "name": "style", + "in": "query" } ], "responses": { diff --git a/internal/app/api/core/assets/doc/v0_swagger.yaml b/internal/app/api/core/assets/doc/v0_swagger.yaml index a788505..479cb8d 100644 --- a/internal/app/api/core/assets/doc/v0_swagger.yaml +++ b/internal/app/api/core/assets/doc/v0_swagger.yaml @@ -1072,6 +1072,10 @@ paths: required: true schema: $ref: '#/definitions/model.PeerMailRequest' + - description: The configuration style + in: query + name: style + type: string produces: - application/json responses: @@ -1097,6 +1101,10 @@ paths: name: id required: true type: string + - description: The configuration style + in: query + name: style + type: string produces: - image/png - application/json @@ -1125,6 +1133,10 @@ paths: name: id required: true type: string + - description: The configuration style + in: query + name: style + type: string produces: - application/json responses: diff --git a/internal/app/api/v0/backend/peer_service.go b/internal/app/api/v0/backend/peer_service.go index f590693..ab4a7a8 100644 --- a/internal/app/api/v0/backend/peer_service.go +++ b/internal/app/api/v0/backend/peer_service.go @@ -27,12 +27,12 @@ type PeerServicePeerManager interface { } type PeerServiceConfigFileManager interface { - GetPeerConfig(ctx context.Context, id domain.PeerIdentifier) (io.Reader, error) - GetPeerConfigQrCode(ctx context.Context, id domain.PeerIdentifier) (io.Reader, error) + GetPeerConfig(ctx context.Context, id domain.PeerIdentifier, style string) (io.Reader, error) + GetPeerConfigQrCode(ctx context.Context, id domain.PeerIdentifier, style string) (io.Reader, error) } type PeerServiceMailManager interface { - SendPeerEmail(ctx context.Context, linkOnly bool, peers ...domain.PeerIdentifier) error + SendPeerEmail(ctx context.Context, linkOnly bool, style string, peers ...domain.PeerIdentifier) error } // endregion dependencies @@ -95,16 +95,24 @@ func (p PeerService) DeletePeer(ctx context.Context, id domain.PeerIdentifier) e return p.peers.DeletePeer(ctx, id) } -func (p PeerService) GetPeerConfig(ctx context.Context, id domain.PeerIdentifier) (io.Reader, error) { - return p.configFile.GetPeerConfig(ctx, id) +func (p PeerService) GetPeerConfig(ctx context.Context, id domain.PeerIdentifier, style string) (io.Reader, error) { + return p.configFile.GetPeerConfig(ctx, id, style) } -func (p PeerService) GetPeerConfigQrCode(ctx context.Context, id domain.PeerIdentifier) (io.Reader, error) { - return p.configFile.GetPeerConfigQrCode(ctx, id) +func (p PeerService) GetPeerConfigQrCode(ctx context.Context, id domain.PeerIdentifier, style string) ( + io.Reader, + error, +) { + return p.configFile.GetPeerConfigQrCode(ctx, id, style) } -func (p PeerService) SendPeerEmail(ctx context.Context, linkOnly bool, peers ...domain.PeerIdentifier) error { - return p.mailer.SendPeerEmail(ctx, linkOnly, peers...) +func (p PeerService) SendPeerEmail( + ctx context.Context, + linkOnly bool, + style string, + peers ...domain.PeerIdentifier, +) error { + return p.mailer.SendPeerEmail(ctx, linkOnly, style, peers...) } func (p PeerService) GetPeerStats(ctx context.Context, id domain.InterfaceIdentifier) ([]domain.PeerStatus, error) { diff --git a/internal/app/api/v0/handlers/endpoint_peers.go b/internal/app/api/v0/handlers/endpoint_peers.go index d9a0115..e60a3aa 100644 --- a/internal/app/api/v0/handlers/endpoint_peers.go +++ b/internal/app/api/v0/handlers/endpoint_peers.go @@ -34,11 +34,11 @@ type PeerService interface { // DeletePeer deletes the peer with the given id. DeletePeer(ctx context.Context, id domain.PeerIdentifier) error // GetPeerConfig returns the peer configuration for the given id. - GetPeerConfig(ctx context.Context, id domain.PeerIdentifier) (io.Reader, error) + GetPeerConfig(ctx context.Context, id domain.PeerIdentifier, style string) (io.Reader, error) // GetPeerConfigQrCode returns the peer configuration as qr code for the given id. - GetPeerConfigQrCode(ctx context.Context, id domain.PeerIdentifier) (io.Reader, error) + GetPeerConfigQrCode(ctx context.Context, id domain.PeerIdentifier, style string) (io.Reader, error) // SendPeerEmail sends the peer configuration via email. - SendPeerEmail(ctx context.Context, linkOnly bool, peers ...domain.PeerIdentifier) error + SendPeerEmail(ctx context.Context, linkOnly bool, style string, peers ...domain.PeerIdentifier) error // GetPeerStats returns the peer stats for the given interface. GetPeerStats(ctx context.Context, id domain.InterfaceIdentifier) ([]domain.PeerStatus, error) } @@ -355,6 +355,7 @@ func (e PeerEndpoint) handleDelete() http.HandlerFunc { // @Summary Get peer configuration as string. // @Produce json // @Param id path string true "The peer identifier" +// @Param style query string false "The configuration style" // @Success 200 {object} string // @Failure 400 {object} model.Error // @Failure 500 {object} model.Error @@ -369,7 +370,9 @@ func (e PeerEndpoint) handleConfigGet() http.HandlerFunc { return } - configTxt, err := e.peerService.GetPeerConfig(r.Context(), domain.PeerIdentifier(id)) + configStyle := e.getConfigStyle(r) + + configTxt, err := e.peerService.GetPeerConfig(r.Context(), domain.PeerIdentifier(id), configStyle) if err != nil { respond.JSON(w, http.StatusInternalServerError, model.Error{ Code: http.StatusInternalServerError, Message: err.Error(), @@ -397,6 +400,7 @@ func (e PeerEndpoint) handleConfigGet() http.HandlerFunc { // @Produce png // @Produce json // @Param id path string true "The peer identifier" +// @Param style query string false "The configuration style" // @Success 200 {file} binary // @Failure 400 {object} model.Error // @Failure 500 {object} model.Error @@ -411,7 +415,9 @@ func (e PeerEndpoint) handleQrCodeGet() http.HandlerFunc { return } - configQr, err := e.peerService.GetPeerConfigQrCode(r.Context(), domain.PeerIdentifier(id)) + configStyle := e.getConfigStyle(r) + + configQr, err := e.peerService.GetPeerConfigQrCode(r.Context(), domain.PeerIdentifier(id), configStyle) if err != nil { respond.JSON(w, http.StatusInternalServerError, model.Error{ Code: http.StatusInternalServerError, Message: err.Error(), @@ -438,6 +444,7 @@ func (e PeerEndpoint) handleQrCodeGet() http.HandlerFunc { // @Summary Send peer configuration via email. // @Produce json // @Param request body model.PeerMailRequest true "The peer mail request data" +// @Param style query string false "The configuration style" // @Success 204 "No content if mail sending was successful" // @Failure 400 {object} model.Error // @Failure 500 {object} model.Error @@ -460,11 +467,13 @@ func (e PeerEndpoint) handleEmailPost() http.HandlerFunc { return } + configStyle := e.getConfigStyle(r) + peerIds := make([]domain.PeerIdentifier, len(req.Identifiers)) for i := range req.Identifiers { peerIds[i] = domain.PeerIdentifier(req.Identifiers[i]) } - if err := e.peerService.SendPeerEmail(r.Context(), req.LinkOnly, peerIds...); err != nil { + if err := e.peerService.SendPeerEmail(r.Context(), req.LinkOnly, configStyle, peerIds...); err != nil { respond.JSON(w, http.StatusInternalServerError, model.Error{Code: http.StatusInternalServerError, Message: err.Error()}) return @@ -504,3 +513,11 @@ func (e PeerEndpoint) handleStatsGet() http.HandlerFunc { respond.JSON(w, http.StatusOK, model.NewPeerStats(e.cfg.Statistics.CollectPeerData, stats)) } } + +func (e PeerEndpoint) getConfigStyle(r *http.Request) string { + configStyle := request.QueryDefault(r, "style", domain.ConfigStyleWgQuick) + if configStyle != domain.ConfigStyleWgQuick && configStyle != domain.ConfigStyleRaw { + configStyle = domain.ConfigStyleWgQuick // default to wg-quick style + } + return configStyle +} diff --git a/internal/app/api/v1/backend/provisioning_service.go b/internal/app/api/v1/backend/provisioning_service.go index 4e14ecb..88bbfee 100644 --- a/internal/app/api/v1/backend/provisioning_service.go +++ b/internal/app/api/v1/backend/provisioning_service.go @@ -23,8 +23,8 @@ type ProvisioningServicePeerManagerRepo interface { } type ProvisioningServiceConfigFileManagerRepo interface { - GetPeerConfig(ctx context.Context, id domain.PeerIdentifier) (io.Reader, error) - GetPeerConfigQrCode(ctx context.Context, id domain.PeerIdentifier) (io.Reader, error) + GetPeerConfig(ctx context.Context, id domain.PeerIdentifier, style string) (io.Reader, error) + GetPeerConfigQrCode(ctx context.Context, id domain.PeerIdentifier, style string) (io.Reader, error) } type ProvisioningService struct { @@ -96,7 +96,7 @@ func (p ProvisioningService) GetPeerConfig(ctx context.Context, peerId domain.Pe return nil, err } - peerCfgReader, err := p.configFiles.GetPeerConfig(ctx, peer.Identifier) + peerCfgReader, err := p.configFiles.GetPeerConfig(ctx, peer.Identifier, domain.ConfigStyleWgQuick) if err != nil { return nil, err } @@ -119,7 +119,7 @@ func (p ProvisioningService) GetPeerQrPng(ctx context.Context, peerId domain.Pee return nil, err } - peerCfgQrReader, err := p.configFiles.GetPeerConfigQrCode(ctx, peer.Identifier) + peerCfgQrReader, err := p.configFiles.GetPeerConfigQrCode(ctx, peer.Identifier, domain.ConfigStyleWgQuick) if err != nil { return nil, err } diff --git a/internal/app/configfile/manager.go b/internal/app/configfile/manager.go index 83c07f4..94f06ae 100644 --- a/internal/app/configfile/manager.go +++ b/internal/app/configfile/manager.go @@ -46,7 +46,7 @@ type TemplateRenderer interface { // GetInterfaceConfig returns the configuration file for the given interface. GetInterfaceConfig(iface *domain.Interface, peers []domain.Peer) (io.Reader, error) // GetPeerConfig returns the configuration file for the given peer. - GetPeerConfig(peer *domain.Peer) (io.Reader, error) + GetPeerConfig(peer *domain.Peer, style string) (io.Reader, error) } type EventBus interface { @@ -186,7 +186,7 @@ func (m Manager) GetInterfaceConfig(ctx context.Context, id domain.InterfaceIden // GetPeerConfig returns the configuration file for the given peer. // The file is structured in wg-quick format. -func (m Manager) GetPeerConfig(ctx context.Context, id domain.PeerIdentifier) (io.Reader, error) { +func (m Manager) GetPeerConfig(ctx context.Context, id domain.PeerIdentifier, style string) (io.Reader, error) { peer, err := m.wg.GetPeer(ctx, id) if err != nil { return nil, fmt.Errorf("failed to fetch peer %s: %w", id, err) @@ -196,11 +196,11 @@ func (m Manager) GetPeerConfig(ctx context.Context, id domain.PeerIdentifier) (i return nil, err } - return m.tplHandler.GetPeerConfig(peer) + return m.tplHandler.GetPeerConfig(peer, style) } // GetPeerConfigQrCode returns a QR code image containing the configuration for the given peer. -func (m Manager) GetPeerConfigQrCode(ctx context.Context, id domain.PeerIdentifier) (io.Reader, error) { +func (m Manager) GetPeerConfigQrCode(ctx context.Context, id domain.PeerIdentifier, style string) (io.Reader, error) { peer, err := m.wg.GetPeer(ctx, id) if err != nil { return nil, fmt.Errorf("failed to fetch peer %s: %w", id, err) @@ -210,7 +210,7 @@ func (m Manager) GetPeerConfigQrCode(ctx context.Context, id domain.PeerIdentifi return nil, err } - cfgData, err := m.tplHandler.GetPeerConfig(peer) + cfgData, err := m.tplHandler.GetPeerConfig(peer, style) if err != nil { return nil, fmt.Errorf("failed to get peer config for %s: %w", id, err) } diff --git a/internal/app/configfile/template.go b/internal/app/configfile/template.go index ed40d9b..773ab8c 100644 --- a/internal/app/configfile/template.go +++ b/internal/app/configfile/template.go @@ -55,11 +55,12 @@ func (c TemplateHandler) GetInterfaceConfig(cfg *domain.Interface, peers []domai } // GetPeerConfig returns the rendered configuration file for a WireGuard peer. -func (c TemplateHandler) GetPeerConfig(peer *domain.Peer) (io.Reader, error) { +func (c TemplateHandler) GetPeerConfig(peer *domain.Peer, style string) (io.Reader, error) { var tplBuff bytes.Buffer err := c.templates.ExecuteTemplate(&tplBuff, "wg_peer.tpl", map[string]any{ - "Peer": peer, + "Style": style, + "Peer": peer, "Portal": map[string]any{ "Version": "unknown", }, diff --git a/internal/app/configfile/tpl_files/wg_peer.tpl b/internal/app/configfile/tpl_files/wg_peer.tpl index 8a4bae4..211546b 100644 --- a/internal/app/configfile/tpl_files/wg_peer.tpl +++ b/internal/app/configfile/tpl_files/wg_peer.tpl @@ -1,6 +1,8 @@ # AUTOGENERATED FILE - DO NOT EDIT -# This file uses wg-quick format. +# This file uses {{ .Style }} format. +{{- if eq .Style "wgquick"}} # See https://man7.org/linux/man-pages/man8/wg-quick.8.html#CONFIGURATION +{{- end}} # Lines starting with the -WGP- tag are used by # the WireGuard Portal configuration parser. @@ -21,22 +23,27 @@ # Core settings PrivateKey = {{ .Peer.Interface.KeyPair.PrivateKey }} +{{- if eq .Style "wgquick"}} Address = {{ CidrsToString .Peer.Interface.Addresses }} +{{- end}} # Misc. settings (optional) +{{- if eq .Style "wgquick"}} {{- if .Peer.Interface.DnsStr.GetValue}} DNS = {{ .Peer.Interface.DnsStr.GetValue }} {{- if .Peer.Interface.DnsSearchStr.GetValue}}, {{ .Peer.Interface.DnsSearchStr.GetValue }} {{- end}} {{- end}} {{- if ne .Peer.Interface.Mtu.GetValue 0}} MTU = {{ .Peer.Interface.Mtu.GetValue }} {{- end}} -{{- if ne .Peer.Interface.FirewallMark.GetValue 0}} -FwMark = {{ .Peer.Interface.FirewallMark.GetValue }} -{{- end}} {{- if ne .Peer.Interface.RoutingTable.GetValue ""}} Table = {{ .Peer.Interface.RoutingTable.GetValue }} {{- end}} +{{- end}} +{{- if ne .Peer.Interface.FirewallMark.GetValue 0}} +FwMark = {{ .Peer.Interface.FirewallMark.GetValue }} +{{- end}} +{{- if eq .Style "wgquick"}} # Interface hooks (optional) {{- if .Peer.Interface.PreUp.GetValue}} PreUp = {{ .Peer.Interface.PreUp.GetValue }} @@ -50,6 +57,7 @@ PreDown = {{ .Peer.Interface.PreDown.GetValue }} {{- if .Peer.Interface.PostDown.GetValue}} PostDown = {{ .Peer.Interface.PostDown.GetValue }} {{- end}} +{{- end}} [Peer] PublicKey = {{ .Peer.EndpointPublicKey.GetValue }} diff --git a/internal/app/mail/manager.go b/internal/app/mail/manager.go index c7ff431..7b9b3b9 100644 --- a/internal/app/mail/manager.go +++ b/internal/app/mail/manager.go @@ -21,9 +21,9 @@ type ConfigFileManager interface { // GetInterfaceConfig returns the configuration for the given interface. GetInterfaceConfig(ctx context.Context, id domain.InterfaceIdentifier) (io.Reader, error) // GetPeerConfig returns the configuration for the given peer. - GetPeerConfig(ctx context.Context, id domain.PeerIdentifier) (io.Reader, error) + GetPeerConfig(ctx context.Context, id domain.PeerIdentifier, style string) (io.Reader, error) // GetPeerConfigQrCode returns the QR code for the given peer. - GetPeerConfigQrCode(ctx context.Context, id domain.PeerIdentifier) (io.Reader, error) + GetPeerConfigQrCode(ctx context.Context, id domain.PeerIdentifier, style string) (io.Reader, error) } type UserDatabaseRepo interface { @@ -89,7 +89,7 @@ func NewMailManager( } // SendPeerEmail sends an email to the user linked to the given peers. -func (m Manager) SendPeerEmail(ctx context.Context, linkOnly bool, peers ...domain.PeerIdentifier) error { +func (m Manager) SendPeerEmail(ctx context.Context, linkOnly bool, style string, peers ...domain.PeerIdentifier) error { for _, peerId := range peers { peer, err := m.wg.GetPeer(ctx, peerId) if err != nil { @@ -123,7 +123,7 @@ func (m Manager) SendPeerEmail(ctx context.Context, linkOnly bool, peers ...doma continue } - err = m.sendPeerEmail(ctx, linkOnly, user, peer) + err = m.sendPeerEmail(ctx, linkOnly, style, user, peer) if err != nil { return fmt.Errorf("failed to send peer email for %s: %w", peerId, err) } @@ -132,7 +132,13 @@ func (m Manager) SendPeerEmail(ctx context.Context, linkOnly bool, peers ...doma return nil } -func (m Manager) sendPeerEmail(ctx context.Context, linkOnly bool, user *domain.User, peer *domain.Peer) error { +func (m Manager) sendPeerEmail( + ctx context.Context, + linkOnly bool, + style string, + user *domain.User, + peer *domain.Peer, +) error { qrName := "WireGuardQRCode.png" configName := peer.GetConfigFileName() @@ -148,12 +154,12 @@ func (m Manager) sendPeerEmail(ctx context.Context, linkOnly bool, user *domain. } } else { - peerConfig, err := m.configFiles.GetPeerConfig(ctx, peer.Identifier) + peerConfig, err := m.configFiles.GetPeerConfig(ctx, peer.Identifier, style) if err != nil { return fmt.Errorf("failed to fetch peer config for %s: %w", peer.Identifier, err) } - peerConfigQr, err := m.configFiles.GetPeerConfigQrCode(ctx, peer.Identifier) + peerConfigQr, err := m.configFiles.GetPeerConfigQrCode(ctx, peer.Identifier, style) if err != nil { return fmt.Errorf("failed to fetch peer config QR code for %s: %w", peer.Identifier, err) } diff --git a/internal/domain/base.go b/internal/domain/base.go index 5f549e7..f248ffe 100644 --- a/internal/domain/base.go +++ b/internal/domain/base.go @@ -62,4 +62,7 @@ const ( LockedReasonAdmin = "locked by admin" LockedReasonApi = "locked by admin" + + ConfigStyleRaw = "raw" + ConfigStyleWgQuick = "wgquick" )