mirror of https://github.com/h44z/wg-portal.git
				
				
				
			This commit is contained in:
		
							parent
							
								
									dd28a8dddf
								
							
						
					
					
						commit
						f08740991b
					
				|  | @ -50,7 +50,7 @@ const selectedStats = computed(() => { | ||||||
| 
 | 
 | ||||||
|   if (!s) { |   if (!s) { | ||||||
|     if (!!props.peerId || props.peerId.length) { |     if (!!props.peerId || props.peerId.length) { | ||||||
|       p = profile.Statistics(props.peerId) |       s = profile.Statistics(props.peerId) | ||||||
|     } else { |     } else { | ||||||
|       s = freshStats() // dummy stats to avoid 'undefined' exceptions |       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) => { | watch(() => props.visible, async (newValue, oldValue) => { | ||||||
|   if (oldValue === false && newValue === true) { // if modal is shown |   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 |     configString.value = peers.configuration | ||||||
|   } |   } | ||||||
| } | }) | ||||||
| ) | 
 | ||||||
|  | watch(() => configStyle.value, async () => { | ||||||
|  |   await peers.LoadPeerConfig(selectedPeer.value.Identifier, configStyle.value) | ||||||
|  |   configString.value = peers.configuration | ||||||
|  | }) | ||||||
| 
 | 
 | ||||||
| function download() { | function download() { | ||||||
|   // credit: https://www.bitdegree.org/learn/javascript-download |   // credit: https://www.bitdegree.org/learn/javascript-download | ||||||
|  | @ -103,7 +109,7 @@ function download() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function email() { | 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({ |     notify({ | ||||||
|       title: "Failed to send mail with peer configuration!", |       title: "Failed to send mail with peer configuration!", | ||||||
|       text: e.toString(), |       text: e.toString(), | ||||||
|  | @ -114,7 +120,7 @@ function email() { | ||||||
| 
 | 
 | ||||||
| function ConfigQrUrl() { | function ConfigQrUrl() { | ||||||
|   if (props.peerId.length) { |   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 '' |   return '' | ||||||
| } | } | ||||||
|  | @ -124,6 +130,15 @@ function ConfigQrUrl() { | ||||||
| <template> | <template> | ||||||
|   <Modal :title="title" :visible="visible" @close="close"> |   <Modal :title="title" :visible="visible" @close="close"> | ||||||
|     <template #default> |     <template #default> | ||||||
|  |       <div class="d-flex justify-content-end align-items-center mb-1"> | ||||||
|  |         <span class="me-2">{{ $t('modals.peer-view.style-label') }}: </span> | ||||||
|  |         <div class="btn-group btn-switch-group" role="group" aria-label="Configuration Style"> | ||||||
|  |           <input type="radio" class="btn-check" name="configstyle" id="raw" value="raw" autocomplete="off" checked="" v-model="configStyle"> | ||||||
|  |           <label class="btn btn-outline-primary btn-sm" for="raw">Raw</label> | ||||||
|  |           <input type="radio" class="btn-check" name="configstyle" id="wgquick" value="wgquick" autocomplete="off" checked="" v-model="configStyle"> | ||||||
|  |           <label class="btn btn-outline-primary btn-sm" for="wgquick">WG-Quick</label> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|       <div class="accordion" id="peerInformation"> |       <div class="accordion" id="peerInformation"> | ||||||
|         <div class="accordion-item"> |         <div class="accordion-item"> | ||||||
|           <h2 class="accordion-header"> |           <h2 class="accordion-header"> | ||||||
|  | @ -213,6 +228,14 @@ function ConfigQrUrl() { | ||||||
|   </template> |   </template> | ||||||
| </Modal></template> | </Modal></template> | ||||||
| 
 | 
 | ||||||
| <style>.config-qr-img { | <style> | ||||||
|  | .config-qr-img { | ||||||
|   max-width: 100%; |   max-width: 100%; | ||||||
| }</style> | } | ||||||
|  | 
 | ||||||
|  | .btn-switch-group .btn { | ||||||
|  |   border-width: 1px; | ||||||
|  |   padding: 5px; | ||||||
|  |   line-height: 1; | ||||||
|  | } | ||||||
|  | </style> | ||||||
|  |  | ||||||
|  | @ -467,7 +467,8 @@ | ||||||
|       "connected-since": "Verbunden seit", |       "connected-since": "Verbunden seit", | ||||||
|       "endpoint": "Endpunkt", |       "endpoint": "Endpunkt", | ||||||
|       "button-download": "Konfiguration herunterladen", |       "button-download": "Konfiguration herunterladen", | ||||||
|       "button-email": "Konfiguration per E-Mail senden" |       "button-email": "Konfiguration per E-Mail senden", | ||||||
|  |       "style-label": "Konfigurationsformat" | ||||||
|     }, |     }, | ||||||
|     "peer-edit": { |     "peer-edit": { | ||||||
|       "headline-edit-peer": "Peer bearbeiten:", |       "headline-edit-peer": "Peer bearbeiten:", | ||||||
|  |  | ||||||
|  | @ -468,7 +468,8 @@ | ||||||
|       "connected-since": "Connected since", |       "connected-since": "Connected since", | ||||||
|       "endpoint": "Endpoint", |       "endpoint": "Endpoint", | ||||||
|       "button-download": "Download configuration", |       "button-download": "Download configuration", | ||||||
|       "button-email": "Send configuration via E-Mail" |       "button-email": "Send configuration via E-Mail", | ||||||
|  |       "style-label": "Configuration Style" | ||||||
|     }, |     }, | ||||||
|     "peer-edit": { |     "peer-edit": { | ||||||
|       "headline-edit-peer": "Edit peer:", |       "headline-edit-peer": "Edit peer:", | ||||||
|  |  | ||||||
|  | @ -142,8 +142,8 @@ export const peerStore = defineStore('peers', { | ||||||
|           }) |           }) | ||||||
|         }) |         }) | ||||||
|     }, |     }, | ||||||
|     async MailPeerConfig(linkOnly, ids) { |     async MailPeerConfig(linkOnly, style, ids) { | ||||||
|       return apiWrapper.post(`${baseUrl}/config-mail`, { |       return apiWrapper.post(`${baseUrl}/config-mail?style=${style}`, { | ||||||
|           Identifiers: ids, |           Identifiers: ids, | ||||||
|           LinkOnly: linkOnly |           LinkOnly: linkOnly | ||||||
|         }) |         }) | ||||||
|  | @ -158,8 +158,8 @@ export const peerStore = defineStore('peers', { | ||||||
|           throw new Error(error) |           throw new Error(error) | ||||||
|         }) |         }) | ||||||
|     }, |     }, | ||||||
|     async LoadPeerConfig(id) { |     async LoadPeerConfig(id, style) { | ||||||
|       return apiWrapper.get(`${baseUrl}/config/${base64_url_encode(id)}`) |       return apiWrapper.get(`${baseUrl}/config/${base64_url_encode(id)}?style=${style}`) | ||||||
|         .then(this.setPeerConfig) |         .then(this.setPeerConfig) | ||||||
|         .catch(error => { |         .catch(error => { | ||||||
|           this.configuration = "" |           this.configuration = "" | ||||||
|  |  | ||||||
|  | @ -819,6 +819,12 @@ | ||||||
|                         "schema": { |                         "schema": { | ||||||
|                             "$ref": "#/definitions/model.PeerMailRequest" |                             "$ref": "#/definitions/model.PeerMailRequest" | ||||||
|                         } |                         } | ||||||
|  |                     }, | ||||||
|  |                     { | ||||||
|  |                         "type": "string", | ||||||
|  |                         "description": "The configuration style", | ||||||
|  |                         "name": "style", | ||||||
|  |                         "in": "query" | ||||||
|                     } |                     } | ||||||
|                 ], |                 ], | ||||||
|                 "responses": { |                 "responses": { | ||||||
|  | @ -858,6 +864,12 @@ | ||||||
|                         "name": "id", |                         "name": "id", | ||||||
|                         "in": "path", |                         "in": "path", | ||||||
|                         "required": true |                         "required": true | ||||||
|  |                     }, | ||||||
|  |                     { | ||||||
|  |                         "type": "string", | ||||||
|  |                         "description": "The configuration style", | ||||||
|  |                         "name": "style", | ||||||
|  |                         "in": "query" | ||||||
|                     } |                     } | ||||||
|                 ], |                 ], | ||||||
|                 "responses": { |                 "responses": { | ||||||
|  | @ -899,6 +911,12 @@ | ||||||
|                         "name": "id", |                         "name": "id", | ||||||
|                         "in": "path", |                         "in": "path", | ||||||
|                         "required": true |                         "required": true | ||||||
|  |                     }, | ||||||
|  |                     { | ||||||
|  |                         "type": "string", | ||||||
|  |                         "description": "The configuration style", | ||||||
|  |                         "name": "style", | ||||||
|  |                         "in": "query" | ||||||
|                     } |                     } | ||||||
|                 ], |                 ], | ||||||
|                 "responses": { |                 "responses": { | ||||||
|  |  | ||||||
|  | @ -1072,6 +1072,10 @@ paths: | ||||||
|         required: true |         required: true | ||||||
|         schema: |         schema: | ||||||
|           $ref: '#/definitions/model.PeerMailRequest' |           $ref: '#/definitions/model.PeerMailRequest' | ||||||
|  |       - description: The configuration style | ||||||
|  |         in: query | ||||||
|  |         name: style | ||||||
|  |         type: string | ||||||
|       produces: |       produces: | ||||||
|       - application/json |       - application/json | ||||||
|       responses: |       responses: | ||||||
|  | @ -1097,6 +1101,10 @@ paths: | ||||||
|         name: id |         name: id | ||||||
|         required: true |         required: true | ||||||
|         type: string |         type: string | ||||||
|  |       - description: The configuration style | ||||||
|  |         in: query | ||||||
|  |         name: style | ||||||
|  |         type: string | ||||||
|       produces: |       produces: | ||||||
|       - image/png |       - image/png | ||||||
|       - application/json |       - application/json | ||||||
|  | @ -1125,6 +1133,10 @@ paths: | ||||||
|         name: id |         name: id | ||||||
|         required: true |         required: true | ||||||
|         type: string |         type: string | ||||||
|  |       - description: The configuration style | ||||||
|  |         in: query | ||||||
|  |         name: style | ||||||
|  |         type: string | ||||||
|       produces: |       produces: | ||||||
|       - application/json |       - application/json | ||||||
|       responses: |       responses: | ||||||
|  |  | ||||||
|  | @ -27,12 +27,12 @@ type PeerServicePeerManager interface { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type PeerServiceConfigFileManager interface { | type PeerServiceConfigFileManager interface { | ||||||
| 	GetPeerConfig(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) (io.Reader, error) | 	GetPeerConfigQrCode(ctx context.Context, id domain.PeerIdentifier, style string) (io.Reader, error) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type PeerServiceMailManager interface { | 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
 | // endregion dependencies
 | ||||||
|  | @ -95,16 +95,24 @@ func (p PeerService) DeletePeer(ctx context.Context, id domain.PeerIdentifier) e | ||||||
| 	return p.peers.DeletePeer(ctx, id) | 	return p.peers.DeletePeer(ctx, id) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (p PeerService) GetPeerConfig(ctx context.Context, id domain.PeerIdentifier) (io.Reader, error) { | func (p PeerService) GetPeerConfig(ctx context.Context, id domain.PeerIdentifier, style string) (io.Reader, error) { | ||||||
| 	return p.configFile.GetPeerConfig(ctx, id) | 	return p.configFile.GetPeerConfig(ctx, id, style) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (p PeerService) GetPeerConfigQrCode(ctx context.Context, id domain.PeerIdentifier) (io.Reader, error) { | func (p PeerService) GetPeerConfigQrCode(ctx context.Context, id domain.PeerIdentifier, style string) ( | ||||||
| 	return p.configFile.GetPeerConfigQrCode(ctx, id) | 	io.Reader, | ||||||
|  | 	error, | ||||||
|  | ) { | ||||||
|  | 	return p.configFile.GetPeerConfigQrCode(ctx, id, style) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (p PeerService) SendPeerEmail(ctx context.Context, linkOnly bool, peers ...domain.PeerIdentifier) error { | func (p PeerService) SendPeerEmail( | ||||||
| 	return p.mailer.SendPeerEmail(ctx, linkOnly, peers...) | 	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) { | func (p PeerService) GetPeerStats(ctx context.Context, id domain.InterfaceIdentifier) ([]domain.PeerStatus, error) { | ||||||
|  |  | ||||||
|  | @ -34,11 +34,11 @@ type PeerService interface { | ||||||
| 	// DeletePeer deletes the peer with the given id.
 | 	// DeletePeer deletes the peer with the given id.
 | ||||||
| 	DeletePeer(ctx context.Context, id domain.PeerIdentifier) error | 	DeletePeer(ctx context.Context, id domain.PeerIdentifier) error | ||||||
| 	// GetPeerConfig returns the peer configuration for the given id.
 | 	// 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 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 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 returns the peer stats for the given interface.
 | ||||||
| 	GetPeerStats(ctx context.Context, id domain.InterfaceIdentifier) ([]domain.PeerStatus, error) | 	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.
 | // @Summary Get peer configuration as string.
 | ||||||
| // @Produce json
 | // @Produce json
 | ||||||
| // @Param id path string true "The peer identifier"
 | // @Param id path string true "The peer identifier"
 | ||||||
|  | // @Param style query string false "The configuration style"
 | ||||||
| // @Success 200 {object} string
 | // @Success 200 {object} string
 | ||||||
| // @Failure 400 {object} model.Error
 | // @Failure 400 {object} model.Error
 | ||||||
| // @Failure 500 {object} model.Error
 | // @Failure 500 {object} model.Error
 | ||||||
|  | @ -369,7 +370,9 @@ func (e PeerEndpoint) handleConfigGet() http.HandlerFunc { | ||||||
| 			return | 			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 { | 		if err != nil { | ||||||
| 			respond.JSON(w, http.StatusInternalServerError, model.Error{ | 			respond.JSON(w, http.StatusInternalServerError, model.Error{ | ||||||
| 				Code: http.StatusInternalServerError, Message: err.Error(), | 				Code: http.StatusInternalServerError, Message: err.Error(), | ||||||
|  | @ -397,6 +400,7 @@ func (e PeerEndpoint) handleConfigGet() http.HandlerFunc { | ||||||
| // @Produce png
 | // @Produce png
 | ||||||
| // @Produce json
 | // @Produce json
 | ||||||
| // @Param id path string true "The peer identifier"
 | // @Param id path string true "The peer identifier"
 | ||||||
|  | // @Param style query string false "The configuration style"
 | ||||||
| // @Success 200 {file} binary
 | // @Success 200 {file} binary
 | ||||||
| // @Failure 400 {object} model.Error
 | // @Failure 400 {object} model.Error
 | ||||||
| // @Failure 500 {object} model.Error
 | // @Failure 500 {object} model.Error
 | ||||||
|  | @ -411,7 +415,9 @@ func (e PeerEndpoint) handleQrCodeGet() http.HandlerFunc { | ||||||
| 			return | 			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 { | 		if err != nil { | ||||||
| 			respond.JSON(w, http.StatusInternalServerError, model.Error{ | 			respond.JSON(w, http.StatusInternalServerError, model.Error{ | ||||||
| 				Code: http.StatusInternalServerError, Message: err.Error(), | 				Code: http.StatusInternalServerError, Message: err.Error(), | ||||||
|  | @ -438,6 +444,7 @@ func (e PeerEndpoint) handleQrCodeGet() http.HandlerFunc { | ||||||
| // @Summary Send peer configuration via email.
 | // @Summary Send peer configuration via email.
 | ||||||
| // @Produce json
 | // @Produce json
 | ||||||
| // @Param request body model.PeerMailRequest true "The peer mail request data"
 | // @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"
 | // @Success 204 "No content if mail sending was successful"
 | ||||||
| // @Failure 400 {object} model.Error
 | // @Failure 400 {object} model.Error
 | ||||||
| // @Failure 500 {object} model.Error
 | // @Failure 500 {object} model.Error
 | ||||||
|  | @ -460,11 +467,13 @@ func (e PeerEndpoint) handleEmailPost() http.HandlerFunc { | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		configStyle := e.getConfigStyle(r) | ||||||
|  | 
 | ||||||
| 		peerIds := make([]domain.PeerIdentifier, len(req.Identifiers)) | 		peerIds := make([]domain.PeerIdentifier, len(req.Identifiers)) | ||||||
| 		for i := range req.Identifiers { | 		for i := range req.Identifiers { | ||||||
| 			peerIds[i] = domain.PeerIdentifier(req.Identifiers[i]) | 			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, | 			respond.JSON(w, http.StatusInternalServerError, | ||||||
| 				model.Error{Code: http.StatusInternalServerError, Message: err.Error()}) | 				model.Error{Code: http.StatusInternalServerError, Message: err.Error()}) | ||||||
| 			return | 			return | ||||||
|  | @ -504,3 +513,11 @@ func (e PeerEndpoint) handleStatsGet() http.HandlerFunc { | ||||||
| 		respond.JSON(w, http.StatusOK, model.NewPeerStats(e.cfg.Statistics.CollectPeerData, stats)) | 		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 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -23,8 +23,8 @@ type ProvisioningServicePeerManagerRepo interface { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type ProvisioningServiceConfigFileManagerRepo interface { | type ProvisioningServiceConfigFileManagerRepo interface { | ||||||
| 	GetPeerConfig(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) (io.Reader, error) | 	GetPeerConfigQrCode(ctx context.Context, id domain.PeerIdentifier, style string) (io.Reader, error) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type ProvisioningService struct { | type ProvisioningService struct { | ||||||
|  | @ -96,7 +96,7 @@ func (p ProvisioningService) GetPeerConfig(ctx context.Context, peerId domain.Pe | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	peerCfgReader, err := p.configFiles.GetPeerConfig(ctx, peer.Identifier) | 	peerCfgReader, err := p.configFiles.GetPeerConfig(ctx, peer.Identifier, domain.ConfigStyleWgQuick) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  | @ -119,7 +119,7 @@ func (p ProvisioningService) GetPeerQrPng(ctx context.Context, peerId domain.Pee | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	peerCfgQrReader, err := p.configFiles.GetPeerConfigQrCode(ctx, peer.Identifier) | 	peerCfgQrReader, err := p.configFiles.GetPeerConfigQrCode(ctx, peer.Identifier, domain.ConfigStyleWgQuick) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -46,7 +46,7 @@ type TemplateRenderer interface { | ||||||
| 	// GetInterfaceConfig returns the configuration file for the given interface.
 | 	// GetInterfaceConfig returns the configuration file for the given interface.
 | ||||||
| 	GetInterfaceConfig(iface *domain.Interface, peers []domain.Peer) (io.Reader, error) | 	GetInterfaceConfig(iface *domain.Interface, peers []domain.Peer) (io.Reader, error) | ||||||
| 	// GetPeerConfig returns the configuration file for the given peer.
 | 	// 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 { | 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.
 | // GetPeerConfig returns the configuration file for the given peer.
 | ||||||
| // The file is structured in wg-quick format.
 | // 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) | 	peer, err := m.wg.GetPeer(ctx, id) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, fmt.Errorf("failed to fetch peer %s: %w", id, err) | 		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 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.
 | // 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) | 	peer, err := m.wg.GetPeer(ctx, id) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, fmt.Errorf("failed to fetch peer %s: %w", id, err) | 		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 | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	cfgData, err := m.tplHandler.GetPeerConfig(peer) | 	cfgData, err := m.tplHandler.GetPeerConfig(peer, style) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, fmt.Errorf("failed to get peer config for %s: %w", id, err) | 		return nil, fmt.Errorf("failed to get peer config for %s: %w", id, err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -55,11 +55,12 @@ func (c TemplateHandler) GetInterfaceConfig(cfg *domain.Interface, peers []domai | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // GetPeerConfig returns the rendered configuration file for a WireGuard peer.
 | // 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 | 	var tplBuff bytes.Buffer | ||||||
| 
 | 
 | ||||||
| 	err := c.templates.ExecuteTemplate(&tplBuff, "wg_peer.tpl", map[string]any{ | 	err := c.templates.ExecuteTemplate(&tplBuff, "wg_peer.tpl", map[string]any{ | ||||||
| 		"Peer": peer, | 		"Style": style, | ||||||
|  | 		"Peer":  peer, | ||||||
| 		"Portal": map[string]any{ | 		"Portal": map[string]any{ | ||||||
| 			"Version": "unknown", | 			"Version": "unknown", | ||||||
| 		}, | 		}, | ||||||
|  |  | ||||||
|  | @ -1,6 +1,8 @@ | ||||||
| # AUTOGENERATED FILE - DO NOT EDIT | # 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 | # See https://man7.org/linux/man-pages/man8/wg-quick.8.html#CONFIGURATION | ||||||
|  | {{- end}} | ||||||
| # Lines starting with the -WGP- tag are used by | # Lines starting with the -WGP- tag are used by | ||||||
| # the WireGuard Portal configuration parser. | # the WireGuard Portal configuration parser. | ||||||
| 
 | 
 | ||||||
|  | @ -21,22 +23,27 @@ | ||||||
| 
 | 
 | ||||||
| # Core settings | # Core settings | ||||||
| PrivateKey = {{ .Peer.Interface.KeyPair.PrivateKey }} | PrivateKey = {{ .Peer.Interface.KeyPair.PrivateKey }} | ||||||
|  | {{- if eq .Style "wgquick"}} | ||||||
| Address = {{ CidrsToString .Peer.Interface.Addresses }} | Address = {{ CidrsToString .Peer.Interface.Addresses }} | ||||||
|  | {{- end}} | ||||||
| 
 | 
 | ||||||
| # Misc. settings (optional) | # Misc. settings (optional) | ||||||
|  | {{- if eq .Style "wgquick"}} | ||||||
| {{- if .Peer.Interface.DnsStr.GetValue}} | {{- if .Peer.Interface.DnsStr.GetValue}} | ||||||
| DNS = {{ .Peer.Interface.DnsStr.GetValue }} {{- if .Peer.Interface.DnsSearchStr.GetValue}}, {{ .Peer.Interface.DnsSearchStr.GetValue }} {{- end}} | DNS = {{ .Peer.Interface.DnsStr.GetValue }} {{- if .Peer.Interface.DnsSearchStr.GetValue}}, {{ .Peer.Interface.DnsSearchStr.GetValue }} {{- end}} | ||||||
| {{- end}} | {{- end}} | ||||||
| {{- if ne .Peer.Interface.Mtu.GetValue 0}} | {{- if ne .Peer.Interface.Mtu.GetValue 0}} | ||||||
| MTU = {{ .Peer.Interface.Mtu.GetValue }} | MTU = {{ .Peer.Interface.Mtu.GetValue }} | ||||||
| {{- end}} | {{- end}} | ||||||
| {{- if ne .Peer.Interface.FirewallMark.GetValue 0}} |  | ||||||
| FwMark = {{ .Peer.Interface.FirewallMark.GetValue }} |  | ||||||
| {{- end}} |  | ||||||
| {{- if ne .Peer.Interface.RoutingTable.GetValue ""}} | {{- if ne .Peer.Interface.RoutingTable.GetValue ""}} | ||||||
| Table = {{ .Peer.Interface.RoutingTable.GetValue }} | Table = {{ .Peer.Interface.RoutingTable.GetValue }} | ||||||
| {{- end}} | {{- end}} | ||||||
|  | {{- end}} | ||||||
|  | {{- if ne .Peer.Interface.FirewallMark.GetValue 0}} | ||||||
|  | FwMark = {{ .Peer.Interface.FirewallMark.GetValue }} | ||||||
|  | {{- end}} | ||||||
| 
 | 
 | ||||||
|  | {{- if eq .Style "wgquick"}} | ||||||
| # Interface hooks (optional) | # Interface hooks (optional) | ||||||
| {{- if .Peer.Interface.PreUp.GetValue}} | {{- if .Peer.Interface.PreUp.GetValue}} | ||||||
| PreUp = {{ .Peer.Interface.PreUp.GetValue }} | PreUp = {{ .Peer.Interface.PreUp.GetValue }} | ||||||
|  | @ -50,6 +57,7 @@ PreDown = {{ .Peer.Interface.PreDown.GetValue }} | ||||||
| {{- if .Peer.Interface.PostDown.GetValue}} | {{- if .Peer.Interface.PostDown.GetValue}} | ||||||
| PostDown = {{ .Peer.Interface.PostDown.GetValue }} | PostDown = {{ .Peer.Interface.PostDown.GetValue }} | ||||||
| {{- end}} | {{- end}} | ||||||
|  | {{- end}} | ||||||
| 
 | 
 | ||||||
| [Peer] | [Peer] | ||||||
| PublicKey = {{ .Peer.EndpointPublicKey.GetValue }} | PublicKey = {{ .Peer.EndpointPublicKey.GetValue }} | ||||||
|  |  | ||||||
|  | @ -21,9 +21,9 @@ type ConfigFileManager interface { | ||||||
| 	// GetInterfaceConfig returns the configuration for the given interface.
 | 	// GetInterfaceConfig returns the configuration for the given interface.
 | ||||||
| 	GetInterfaceConfig(ctx context.Context, id domain.InterfaceIdentifier) (io.Reader, error) | 	GetInterfaceConfig(ctx context.Context, id domain.InterfaceIdentifier) (io.Reader, error) | ||||||
| 	// GetPeerConfig returns the configuration for the given peer.
 | 	// 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 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 { | type UserDatabaseRepo interface { | ||||||
|  | @ -89,7 +89,7 @@ func NewMailManager( | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // SendPeerEmail sends an email to the user linked to the given peers.
 | // 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 { | 	for _, peerId := range peers { | ||||||
| 		peer, err := m.wg.GetPeer(ctx, peerId) | 		peer, err := m.wg.GetPeer(ctx, peerId) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
|  | @ -123,7 +123,7 @@ func (m Manager) SendPeerEmail(ctx context.Context, linkOnly bool, peers ...doma | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		err = m.sendPeerEmail(ctx, linkOnly, user, peer) | 		err = m.sendPeerEmail(ctx, linkOnly, style, user, peer) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return fmt.Errorf("failed to send peer email for %s: %w", peerId, err) | 			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 | 	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" | 	qrName := "WireGuardQRCode.png" | ||||||
| 	configName := peer.GetConfigFileName() | 	configName := peer.GetConfigFileName() | ||||||
| 
 | 
 | ||||||
|  | @ -148,12 +154,12 @@ func (m Manager) sendPeerEmail(ctx context.Context, linkOnly bool, user *domain. | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	} else { | 	} else { | ||||||
| 		peerConfig, err := m.configFiles.GetPeerConfig(ctx, peer.Identifier) | 		peerConfig, err := m.configFiles.GetPeerConfig(ctx, peer.Identifier, style) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return fmt.Errorf("failed to fetch peer config for %s: %w", peer.Identifier, err) | 			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 { | 		if err != nil { | ||||||
| 			return fmt.Errorf("failed to fetch peer config QR code for %s: %w", peer.Identifier, err) | 			return fmt.Errorf("failed to fetch peer config QR code for %s: %w", peer.Identifier, err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | @ -62,4 +62,7 @@ const ( | ||||||
| 
 | 
 | ||||||
| 	LockedReasonAdmin = "locked by admin" | 	LockedReasonAdmin = "locked by admin" | ||||||
| 	LockedReasonApi   = "locked by admin" | 	LockedReasonApi   = "locked by admin" | ||||||
|  | 
 | ||||||
|  | 	ConfigStyleRaw     = "raw" | ||||||
|  | 	ConfigStyleWgQuick = "wgquick" | ||||||
| ) | ) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue