mirror of
				https://github.com/axllent/mailpit.git
				synced 2025-10-31 00:07:43 +02:00 
			
		
		
		
	Chore: Refactor API Swagger definitions and remove unused structs
- Removed deprecated `thumbnailParams` struct from `thumbnails.go`. - Updated `server_test.go` to use an anonymous struct for response unmarshalling. - Enhanced `swagger.json` with detailed definitions for SendRequest and SendMessageResponse. - Introduced new `swaggerParams.go` to define Swagger parameters for various API endpoints. - Created `swaggerResponses.go` to define Swagger responses for API endpoints. - Cleaned up unused JSON error message definitions and consolidated error responses. - Improved documentation for Chaos triggers and web UI configuration responses.
This commit is contained in:
		
							
								
								
									
										1
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							| @@ -26,6 +26,7 @@ | ||||
|         "Mechs", | ||||
|         "navhtml", | ||||
|         "neostandard", | ||||
|         "nolint", | ||||
|         "popperjs", | ||||
|         "readyz", | ||||
|         "RSET", | ||||
|   | ||||
| @@ -25,7 +25,8 @@ var ( | ||||
| ) | ||||
|  | ||||
| // Triggers for the Chaos configuration | ||||
| // swagger:model Triggers | ||||
| // | ||||
| // swagger:model ChaosTriggers | ||||
| type Triggers struct { | ||||
| 	// Sender trigger to fail on From, Sender | ||||
| 	Sender Trigger | ||||
| @@ -36,7 +37,8 @@ type Triggers struct { | ||||
| } | ||||
|  | ||||
| // Trigger for Chaos | ||||
| // swagger:model Trigger | ||||
| // | ||||
| // swagger:model ChaosTrigger | ||||
| type Trigger struct { | ||||
| 	// SMTP error code to return. The value must range from 400 to 599. | ||||
| 	// required: true | ||||
|   | ||||
| @@ -35,9 +35,7 @@ func httpJSONError(w http.ResponseWriter, msg string) { | ||||
| 	w.Header().Set("Referrer-Policy", "no-referrer") | ||||
| 	w.Header().Set("Content-Security-Policy", config.ContentSecurityPolicy) | ||||
| 	w.WriteHeader(http.StatusBadRequest) | ||||
| 	e := JSONErrorMessage{ | ||||
| 		Error: msg, | ||||
| 	} | ||||
| 	e := struct{ Error string }{Error: msg} | ||||
|  | ||||
| 	w.Header().Add("Content-Type", "application/json") | ||||
| 	if err := json.NewEncoder(w).Encode(e); err != nil { | ||||
|   | ||||
| @@ -10,16 +10,7 @@ import ( | ||||
| 	"github.com/axllent/mailpit/internal/stats" | ||||
| ) | ||||
|  | ||||
| // Application information | ||||
| // swagger:response AppInfoResponse | ||||
| type appInfoResponse struct { | ||||
| 	// Application information | ||||
| 	// | ||||
| 	// in: body | ||||
| 	Body stats.AppInformation | ||||
| } | ||||
|  | ||||
| // AppInfo returns some basic details about the running app, and latest release. | ||||
| // AppInfo returns some basic details about the running app including the latest release (unless disabled). | ||||
| func AppInfo(w http.ResponseWriter, _ *http.Request) { | ||||
| 	// swagger:route GET /api/v1/info application AppInformation | ||||
| 	// | ||||
| @@ -42,59 +33,9 @@ func AppInfo(w http.ResponseWriter, _ *http.Request) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Response includes global web UI settings | ||||
| // | ||||
| // swagger:model WebUIConfiguration | ||||
| type webUIConfiguration struct { | ||||
| 	// Optional label to identify this Mailpit instance | ||||
| 	Label string | ||||
| 	// Message Relay information | ||||
| 	MessageRelay struct { | ||||
| 		// Whether message relaying (release) is enabled | ||||
| 		Enabled bool | ||||
| 		// The configured SMTP server address | ||||
| 		SMTPServer string | ||||
| 		// Enforced Return-Path (if set) for relay bounces | ||||
| 		ReturnPath string | ||||
| 		// Only allow relaying to these recipients (regex) | ||||
| 		AllowedRecipients string | ||||
| 		// Block relaying to these recipients (regex) | ||||
| 		BlockedRecipients string | ||||
| 		// Overrides the "From" address for all relayed messages | ||||
| 		OverrideFrom string | ||||
| 		// Preserve the original Message-IDs when relaying messages | ||||
| 		PreserveMessageIDs bool | ||||
|  | ||||
| 		// DEPRECATED 2024/03/12 | ||||
| 		// swagger:ignore | ||||
| 		RecipientAllowlist string | ||||
| 	} | ||||
|  | ||||
| 	// Whether SpamAssassin is enabled | ||||
| 	SpamAssassin bool | ||||
|  | ||||
| 	// Whether Chaos support is enabled at runtime | ||||
| 	ChaosEnabled bool | ||||
|  | ||||
| 	// Whether messages with duplicate IDs are ignored | ||||
| 	DuplicatesIgnored bool | ||||
|  | ||||
| 	// Whether the delete button should be hidden | ||||
| 	HideDeleteAllButton bool | ||||
| } | ||||
|  | ||||
| // Web UI configuration response | ||||
| // swagger:response WebUIConfigurationResponse | ||||
| type webUIConfigurationResponse struct { | ||||
| 	// Web UI configuration settings | ||||
| 	// | ||||
| 	// in: body | ||||
| 	Body webUIConfiguration | ||||
| } | ||||
|  | ||||
| // WebUIConfig returns configuration settings for the web UI. | ||||
| func WebUIConfig(w http.ResponseWriter, _ *http.Request) { | ||||
| 	// swagger:route GET /api/v1/webui application WebUIConfiguration | ||||
| 	// swagger:route GET /api/v1/webui application WebUIConfigurationResponse | ||||
| 	// | ||||
| 	// # Get web UI configuration | ||||
| 	// | ||||
| @@ -110,29 +51,29 @@ func WebUIConfig(w http.ResponseWriter, _ *http.Request) { | ||||
| 	//	  200: WebUIConfigurationResponse | ||||
| 	//	  400: ErrorResponse | ||||
|  | ||||
| 	conf := webUIConfiguration{} | ||||
| 	conf := webUIConfigurationResponse{} | ||||
|  | ||||
| 	conf.Label = config.Label | ||||
| 	conf.MessageRelay.Enabled = config.ReleaseEnabled | ||||
| 	conf.Body.Label = config.Label | ||||
| 	conf.Body.MessageRelay.Enabled = config.ReleaseEnabled | ||||
| 	if config.ReleaseEnabled { | ||||
| 		conf.MessageRelay.SMTPServer = fmt.Sprintf("%s:%d", config.SMTPRelayConfig.Host, config.SMTPRelayConfig.Port) | ||||
| 		conf.MessageRelay.ReturnPath = config.SMTPRelayConfig.ReturnPath | ||||
| 		conf.MessageRelay.AllowedRecipients = config.SMTPRelayConfig.AllowedRecipients | ||||
| 		conf.MessageRelay.BlockedRecipients = config.SMTPRelayConfig.BlockedRecipients | ||||
| 		conf.MessageRelay.OverrideFrom = config.SMTPRelayConfig.OverrideFrom | ||||
| 		conf.MessageRelay.PreserveMessageIDs = config.SMTPRelayConfig.PreserveMessageIDs | ||||
| 		conf.Body.MessageRelay.SMTPServer = fmt.Sprintf("%s:%d", config.SMTPRelayConfig.Host, config.SMTPRelayConfig.Port) | ||||
| 		conf.Body.MessageRelay.ReturnPath = config.SMTPRelayConfig.ReturnPath | ||||
| 		conf.Body.MessageRelay.AllowedRecipients = config.SMTPRelayConfig.AllowedRecipients | ||||
| 		conf.Body.MessageRelay.BlockedRecipients = config.SMTPRelayConfig.BlockedRecipients | ||||
| 		conf.Body.MessageRelay.OverrideFrom = config.SMTPRelayConfig.OverrideFrom | ||||
| 		conf.Body.MessageRelay.PreserveMessageIDs = config.SMTPRelayConfig.PreserveMessageIDs | ||||
|  | ||||
| 		// DEPRECATED 2024/03/12 | ||||
| 		conf.MessageRelay.RecipientAllowlist = config.SMTPRelayConfig.AllowedRecipients | ||||
| 		conf.Body.MessageRelay.RecipientAllowlist = config.SMTPRelayConfig.AllowedRecipients | ||||
| 	} | ||||
|  | ||||
| 	conf.SpamAssassin = config.EnableSpamAssassin != "" | ||||
| 	conf.ChaosEnabled = chaos.Enabled | ||||
| 	conf.DuplicatesIgnored = config.IgnoreDuplicateIDs | ||||
| 	conf.HideDeleteAllButton = config.HideDeleteAllButton | ||||
| 	conf.Body.SpamAssassin = config.EnableSpamAssassin != "" | ||||
| 	conf.Body.ChaosEnabled = chaos.Enabled | ||||
| 	conf.Body.DuplicatesIgnored = config.IgnoreDuplicateIDs | ||||
| 	conf.Body.HideDeleteAllButton = config.HideDeleteAllButton | ||||
|  | ||||
| 	w.Header().Add("Content-Type", "application/json") | ||||
| 	if err := json.NewEncoder(w).Encode(conf); err != nil { | ||||
| 	if err := json.NewEncoder(w).Encode(conf.Body); err != nil { | ||||
| 		httpError(w, err.Error()) | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -7,18 +7,6 @@ import ( | ||||
| 	"github.com/axllent/mailpit/internal/smtpd/chaos" | ||||
| ) | ||||
|  | ||||
| // ChaosTriggers are the Chaos triggers | ||||
| type ChaosTriggers chaos.Triggers | ||||
|  | ||||
| // Response for the Chaos triggers configuration | ||||
| // swagger:response ChaosResponse | ||||
| type chaosResponse struct { | ||||
| 	// The current Chaos triggers | ||||
| 	// | ||||
| 	// in: body | ||||
| 	Body ChaosTriggers | ||||
| } | ||||
|  | ||||
| // GetChaos returns the current Chaos triggers | ||||
| func GetChaos(w http.ResponseWriter, _ *http.Request) { | ||||
| 	// swagger:route GET /api/v1/chaos testing getChaos | ||||
| @@ -50,12 +38,6 @@ func GetChaos(w http.ResponseWriter, _ *http.Request) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // swagger:parameters setChaosParams | ||||
| type setChaosParams struct { | ||||
| 	// in: body | ||||
| 	Body ChaosTriggers | ||||
| } | ||||
|  | ||||
| // SetChaos sets the Chaos configuration. | ||||
| func SetChaos(w http.ResponseWriter, r *http.Request) { | ||||
| 	// swagger:route PUT /api/v1/chaos testing setChaosParams | ||||
|   | ||||
| @@ -11,15 +11,6 @@ import ( | ||||
| 	"github.com/gorilla/mux" | ||||
| ) | ||||
|  | ||||
| // swagger:parameters GetMessageParams | ||||
| type getMessageParams struct { | ||||
| 	// Message database ID or "latest" | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// required: true | ||||
| 	ID string | ||||
| } | ||||
|  | ||||
| // GetMessage (method: GET) returns the Message as JSON | ||||
| func GetMessage(w http.ResponseWriter, r *http.Request) { | ||||
| 	// swagger:route GET /api/v1/message/{ID} message GetMessageParams | ||||
| @@ -66,19 +57,6 @@ func GetMessage(w http.ResponseWriter, r *http.Request) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // swagger:parameters GetHeadersParams | ||||
| type getHeadersParams struct { | ||||
| 	// Message database ID or "latest" | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// required: true | ||||
| 	ID string | ||||
| } | ||||
|  | ||||
| // Message headers | ||||
| // swagger:model MessageHeadersResponse | ||||
| type messageHeaders map[string][]string | ||||
|  | ||||
| // GetHeaders (method: GET) returns the message headers as JSON | ||||
| func GetHeaders(w http.ResponseWriter, r *http.Request) { | ||||
| 	// swagger:route GET /api/v1/message/{ID}/headers message GetHeadersParams | ||||
| @@ -132,21 +110,6 @@ func GetHeaders(w http.ResponseWriter, r *http.Request) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // swagger:parameters AttachmentParams | ||||
| type attachmentParams struct { | ||||
| 	// Message database ID or "latest" | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// required: true | ||||
| 	ID string | ||||
|  | ||||
| 	// Attachment part ID | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// required: true | ||||
| 	PartID string | ||||
| } | ||||
|  | ||||
| // DownloadAttachment (method: GET) returns the attachment data | ||||
| func DownloadAttachment(w http.ResponseWriter, r *http.Request) { | ||||
| 	// swagger:route GET /api/v1/message/{ID}/part/{PartID} message AttachmentParams | ||||
| @@ -199,15 +162,6 @@ func DownloadAttachment(w http.ResponseWriter, r *http.Request) { | ||||
| 	_, _ = w.Write(a.Content) | ||||
| } | ||||
|  | ||||
| // swagger:parameters DownloadRawParams | ||||
| type downloadRawParams struct { | ||||
| 	// Message database ID or "latest" | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// required: true | ||||
| 	ID string | ||||
| } | ||||
|  | ||||
| // DownloadRaw (method: GET) returns the full email source as plain text | ||||
| func DownloadRaw(w http.ResponseWriter, r *http.Request) { | ||||
| 	// swagger:route GET /api/v1/message/{ID}/raw message DownloadRawParams | ||||
|   | ||||
| @@ -8,35 +8,6 @@ import ( | ||||
| 	"github.com/axllent/mailpit/internal/storage" | ||||
| ) | ||||
|  | ||||
| // swagger:parameters GetMessagesParams | ||||
| type getMessagesParams struct { | ||||
| 	// Pagination offset | ||||
| 	// | ||||
| 	// in: query | ||||
| 	// name: start | ||||
| 	// required: false | ||||
| 	// default: 0 | ||||
| 	// type: integer | ||||
| 	Start int `json:"start"` | ||||
|  | ||||
| 	// Limit number of results | ||||
| 	// | ||||
| 	// in: query | ||||
| 	// name: limit | ||||
| 	// required: false | ||||
| 	// default: 50 | ||||
| 	// type: integer | ||||
| 	Limit int `json:"limit"` | ||||
| } | ||||
|  | ||||
| // Summary of messages | ||||
| // swagger:response MessagesSummaryResponse | ||||
| type messagesSummaryResponse struct { | ||||
| 	// The messages summary | ||||
| 	// in: body | ||||
| 	Body MessagesSummary | ||||
| } | ||||
|  | ||||
| // MessagesSummary is a summary of a list of messages | ||||
| type MessagesSummary struct { | ||||
| 	// Total number of messages in mailbox | ||||
| @@ -111,39 +82,6 @@ func GetMessages(w http.ResponseWriter, r *http.Request) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // swagger:parameters SetReadStatusParams | ||||
| type setReadStatusParams struct { | ||||
| 	// in: body | ||||
| 	Body struct { | ||||
| 		// Read status | ||||
| 		// | ||||
| 		// required: false | ||||
| 		// default: false | ||||
| 		// example: true | ||||
| 		Read bool | ||||
|  | ||||
| 		// Optional array of message database IDs | ||||
| 		// | ||||
| 		// required: false | ||||
| 		// default: [] | ||||
| 		// example: ["4oRBnPtCXgAqZniRhzLNmS", "hXayS6wnCgNnt6aFTvmOF6"] | ||||
| 		IDs []string | ||||
|  | ||||
| 		// Optional messages matching a search | ||||
| 		// | ||||
| 		// required: false | ||||
| 		// example: tag:backups | ||||
| 		Search string | ||||
| 	} | ||||
|  | ||||
| 	// Optional [timezone identifier](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) used only for `before:` & `after:` searches (eg: "Pacific/Auckland"). | ||||
| 	// | ||||
| 	// in: query | ||||
| 	// required: false | ||||
| 	// type string | ||||
| 	TZ string `json:"tz"` | ||||
| } | ||||
|  | ||||
| // SetReadStatus (method: PUT) will update the status to Read/Unread for all provided IDs. | ||||
| func SetReadStatus(w http.ResponseWriter, r *http.Request) { | ||||
| 	// swagger:route PUT /api/v1/messages messages SetReadStatusParams | ||||
| @@ -225,19 +163,6 @@ func SetReadStatus(w http.ResponseWriter, r *http.Request) { | ||||
| 	_, _ = w.Write([]byte("ok")) | ||||
| } | ||||
|  | ||||
| // swagger:parameters DeleteMessagesParams | ||||
| type deleteMessagesParams struct { | ||||
| 	// Delete request | ||||
| 	// in: body | ||||
| 	Body struct { | ||||
| 		// Array of message database IDs | ||||
| 		// | ||||
| 		// required: false | ||||
| 		// example: ["4oRBnPtCXgAqZniRhzLNmS", "hXayS6wnCgNnt6aFTvmOF6"] | ||||
| 		IDs []string | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // DeleteMessages (method: DELETE) deletes all messages matching IDS. | ||||
| func DeleteMessages(w http.ResponseWriter, r *http.Request) { | ||||
| 	// swagger:route DELETE /api/v1/messages messages DeleteMessagesParams | ||||
| @@ -279,39 +204,6 @@ func DeleteMessages(w http.ResponseWriter, r *http.Request) { | ||||
| 	_, _ = w.Write([]byte("ok")) | ||||
| } | ||||
|  | ||||
| // swagger:parameters SearchParams | ||||
| type searchParams struct { | ||||
| 	// Search query | ||||
| 	// | ||||
| 	// in: query | ||||
| 	// required: true | ||||
| 	// type: string | ||||
| 	Query string `json:"query"` | ||||
|  | ||||
| 	// Pagination offset | ||||
| 	// | ||||
| 	// in: query | ||||
| 	// required: false | ||||
| 	// default: 0 | ||||
| 	// type integer | ||||
| 	Start string `json:"start"` | ||||
|  | ||||
| 	// Limit results | ||||
| 	// | ||||
| 	// in: query | ||||
| 	// required: false | ||||
| 	// default: 50 | ||||
| 	// type integer | ||||
| 	Limit string `json:"limit"` | ||||
|  | ||||
| 	// Optional [timezone identifier](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) used only for `before:` & `after:` searches (eg: "Pacific/Auckland"). | ||||
| 	// | ||||
| 	// in: query | ||||
| 	// required: false | ||||
| 	// type string | ||||
| 	TZ string `json:"tz"` | ||||
| } | ||||
|  | ||||
| // Search returns the latest messages as JSON | ||||
| func Search(w http.ResponseWriter, r *http.Request) { | ||||
| 	// swagger:route GET /api/v1/search messages SearchParams | ||||
| @@ -369,23 +261,6 @@ func Search(w http.ResponseWriter, r *http.Request) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // swagger:parameters DeleteSearchParams | ||||
| type deleteSearchParams struct { | ||||
| 	// Search query | ||||
| 	// | ||||
| 	// in: query | ||||
| 	// required: true | ||||
| 	// type: string | ||||
| 	Query string `json:"query"` | ||||
|  | ||||
| 	// [Timezone identifier](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) used only for `before:` & `after:` searches (eg: "Pacific/Auckland"). | ||||
| 	// | ||||
| 	// in: query | ||||
| 	// required: false | ||||
| 	// type string | ||||
| 	TZ string `json:"tz"` | ||||
| } | ||||
|  | ||||
| // DeleteSearch will delete all messages matching a search | ||||
| func DeleteSearch(w http.ResponseWriter, r *http.Request) { | ||||
| 	// swagger:route DELETE /api/v1/search messages DeleteSearchParams | ||||
|   | ||||
| @@ -15,19 +15,6 @@ import ( | ||||
| 	"github.com/jhillyerd/enmime/v2" | ||||
| ) | ||||
|  | ||||
| // swagger:parameters HTMLCheckParams | ||||
| type htmlCheckParams struct { | ||||
| 	// Message database ID or "latest" | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// description: Message database ID or "latest" | ||||
| 	// required: true | ||||
| 	ID string | ||||
| } | ||||
|  | ||||
| // HTMLCheckResponse summary response | ||||
| type HTMLCheckResponse = htmlcheck.Response | ||||
|  | ||||
| // HTMLCheck returns a summary of the HTML client support | ||||
| func HTMLCheck(w http.ResponseWriter, r *http.Request) { | ||||
| 	// swagger:route GET /api/v1/message/{ID}/html-check other HTMLCheckParams | ||||
| @@ -93,25 +80,6 @@ func HTMLCheck(w http.ResponseWriter, r *http.Request) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // swagger:parameters LinkCheckParams | ||||
| type linkCheckParams struct { | ||||
| 	// Message database ID or "latest" | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// required: true | ||||
| 	ID string | ||||
|  | ||||
| 	// Follow redirects | ||||
| 	// | ||||
| 	// in: query | ||||
| 	// required: false | ||||
| 	// default: false | ||||
| 	Follow string `json:"follow"` | ||||
| } | ||||
|  | ||||
| // LinkCheckResponse summary response | ||||
| type LinkCheckResponse = linkcheck.Response | ||||
|  | ||||
| // LinkCheck returns a summary of links in the email | ||||
| func LinkCheck(w http.ResponseWriter, r *http.Request) { | ||||
| 	// swagger:route GET /api/v1/message/{ID}/link-check other LinkCheckParams | ||||
| @@ -170,18 +138,6 @@ func LinkCheck(w http.ResponseWriter, r *http.Request) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // swagger:parameters SpamAssassinCheckParams | ||||
| type spamAssassinCheckParams struct { | ||||
| 	// Message database ID or "latest" | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// required: true | ||||
| 	ID string | ||||
| } | ||||
|  | ||||
| // SpamAssassinResponse summary response | ||||
| type SpamAssassinResponse = spamassassin.Result | ||||
|  | ||||
| // SpamAssassinCheck returns a summary of SpamAssassin results (if enabled) | ||||
| func SpamAssassinCheck(w http.ResponseWriter, r *http.Request) { | ||||
| 	// swagger:route GET /api/v1/message/{ID}/sa-check other SpamAssassinCheckParams | ||||
|   | ||||
| @@ -17,25 +17,6 @@ import ( | ||||
| 	"github.com/lithammer/shortuuid/v4" | ||||
| ) | ||||
|  | ||||
| // swagger:parameters ReleaseMessageParams | ||||
| type releaseMessageParams struct { | ||||
| 	// Message database ID | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// description: Message database ID | ||||
| 	// required: true | ||||
| 	ID string | ||||
|  | ||||
| 	// in: body | ||||
| 	Body struct { | ||||
| 		// Array of email addresses to relay the message to | ||||
| 		// | ||||
| 		// required: true | ||||
| 		// example: ["user1@example.com", "user2@example.com"] | ||||
| 		To []string | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // ReleaseMessage (method: POST) will release a message via a pre-configured external SMTP server. | ||||
| func ReleaseMessage(w http.ResponseWriter, r *http.Request) { | ||||
| 	// swagger:route POST /api/v1/message/{ID}/release message ReleaseMessageParams | ||||
|   | ||||
| @@ -17,130 +17,6 @@ import ( | ||||
| 	"github.com/jhillyerd/enmime/v2" | ||||
| ) | ||||
|  | ||||
| // swagger:parameters SendMessageParams | ||||
| type sendMessageParams struct { | ||||
| 	// in: body | ||||
| 	Body *SendRequest | ||||
| } | ||||
|  | ||||
| // SendRequest to send a message via HTTP | ||||
| // swagger:model SendRequest | ||||
| type SendRequest struct { | ||||
| 	// "From" recipient | ||||
| 	// required: true | ||||
| 	From struct { | ||||
| 		// Optional name | ||||
| 		// example: John Doe | ||||
| 		Name string | ||||
| 		// Email address | ||||
| 		// example: john@example.com | ||||
| 		// required: true | ||||
| 		Email string | ||||
| 	} | ||||
|  | ||||
| 	// "To" recipients | ||||
| 	To []struct { | ||||
| 		// Optional name | ||||
| 		// example: Jane Doe | ||||
| 		Name string | ||||
| 		// Email address | ||||
| 		// example: jane@example.com | ||||
| 		// required: true | ||||
| 		Email string | ||||
| 	} | ||||
|  | ||||
| 	// Cc recipients | ||||
| 	Cc []struct { | ||||
| 		// Optional name | ||||
| 		// example: Manager | ||||
| 		Name string | ||||
| 		// Email address | ||||
| 		// example: manager@example.com | ||||
| 		// required: true | ||||
| 		Email string | ||||
| 	} | ||||
|  | ||||
| 	// Bcc recipients email addresses only | ||||
| 	// example: ["jack@example.com"] | ||||
| 	Bcc []string | ||||
|  | ||||
| 	// Optional Reply-To recipients | ||||
| 	ReplyTo []struct { | ||||
| 		// Optional name | ||||
| 		// example: Secretary | ||||
| 		Name string | ||||
| 		// Email address | ||||
| 		// example: secretary@example.com | ||||
| 		// required: true | ||||
| 		Email string | ||||
| 	} | ||||
|  | ||||
| 	// Subject | ||||
| 	// example: Mailpit message via the HTTP API | ||||
| 	Subject string | ||||
|  | ||||
| 	// Message body (text) | ||||
| 	// example: Mailpit is awesome! | ||||
| 	Text string | ||||
|  | ||||
| 	// Message body (HTML) | ||||
| 	// example: <div style="text-align:center"><p style="font-family: arial; font-size: 24px;">Mailpit is <b>awesome</b>!</p><p><img src="cid:mailpit-logo" /></p></div> | ||||
| 	HTML string | ||||
|  | ||||
| 	// Attachments | ||||
| 	Attachments []struct { | ||||
| 		// Base64-encoded string of the file content | ||||
| 		// required: true | ||||
| 		// example: iVBORw0KGgoAAAANSUhEUgAAAEEAAAA8CAMAAAAOlSdoAAAACXBIWXMAAAHrAAAB6wGM2bZBAAAAS1BMVEVHcEwRfnUkZ2gAt4UsSF8At4UtSV4At4YsSV4At4YsSV8At4YsSV4At4YsSV4sSV4At4YsSV4At4YtSV4At4YsSV4At4YtSV8At4YsUWYNAAAAGHRSTlMAAwoXGiktRE5dbnd7kpOlr7zJ0d3h8PD8PCSRAAACWUlEQVR42pXT4ZaqIBSG4W9rhqQYocG+/ys9Y0Z0Br+x3j8zaxUPewFh65K+7yrIMeIY4MT3wPfEJCidKXEMnLaVkxDiELiMz4WEOAZSFghxBIypCOlKiAMgXfIqTnBgSm8CIQ6BImxEUxEckClVQiHGj4Ba4AQHikAIClwTE9KtIghAhUJwoLkmLnCiAHJLRKgIMsEtVUKbBUIwoAg2C4QgQBE6l4VCnApBgSKYLLApCnCa0+96AEMW2BQcmC+Pr3nfp7o5Exy49gIADcIqUELGfeA+bp93LmAJp8QJoEcN3C7NY3sbVANixMyI0nku20/n5/ZRf3KI2k6JEDWQtxcbdGuAqu3TAXG+/799Oyyas1B1MnMiA+XyxHp9q0PUKGPiRAau1fZbLRZV09wZcT8/gHk8QQAxXn8VgaDqcUmU6O/r28nbVwXAqca2mRNtPAF5+zoP2MeN9Fy4NgC6RfcbgE7XITBRYTtOE3U3C2DVff7pk+PkUxgAbvtnPXJaD6DxulMLwOhPS/M3MQkgg1ZFrIXnmfaZoOfpKiFgzeZD/WuKqQEGrfJYkyWf6vlG3xUgTuscnkNkQsb599q124kdpMUjCa/XARHs1gZymVtGt3wLkiFv8rUgTxitYCex5EVGec0Y9VmoDTFBSQte2TfXGXlf7hbdaUM9Sk7fisEN9qfBBTK+FZcvM9fQSdkl2vj4W2oX/bRogO3XasiNH7R0eW7fgRM834ImTg+Lg6BEnx4vz81rhr+MYPBBQg1v8GndEOrthxaCTxNAOut8WKLGZQl+MPz88Q9tAO/hVuSeqQAAAABJRU5ErkJggg== | ||||
| 		Content string | ||||
| 		// Filename | ||||
| 		// required: true | ||||
| 		// example: mailpit.png | ||||
| 		Filename string | ||||
| 		// Optional Content Type for the the attachment. | ||||
| 		// If this field is not set (or empty) then the content type is automatically detected. | ||||
| 		// required: false | ||||
| 		// example: image/png | ||||
| 		ContentType string | ||||
| 		// Optional Content-ID (`cid`) for attachment. | ||||
| 		// If this field is set then the file is attached inline. | ||||
| 		// required: false | ||||
| 		// example: mailpit-logo | ||||
| 		ContentID string | ||||
| 	} | ||||
|  | ||||
| 	// Mailpit tags | ||||
| 	// example: ["Tag 1","Tag 2"] | ||||
| 	Tags []string | ||||
|  | ||||
| 	// Optional headers in {"key":"value"} format | ||||
| 	// example: {"X-IP":"1.2.3.4"} | ||||
| 	Headers map[string]string | ||||
| } | ||||
|  | ||||
| // JSONErrorMessage struct | ||||
| type JSONErrorMessage struct { | ||||
| 	// Error message | ||||
| 	// example: invalid format | ||||
| 	Error string | ||||
| } | ||||
|  | ||||
| // Confirmation message for HTTP send API | ||||
| // swagger:response sendMessageResponse | ||||
| type sendMessageResponse struct { | ||||
| 	// Response for sending messages via the HTTP API | ||||
| 	// | ||||
| 	// in: body | ||||
| 	Body SendMessageConfirmation | ||||
| } | ||||
|  | ||||
| // SendMessageConfirmation struct | ||||
| type SendMessageConfirmation struct { | ||||
| 	// Database ID | ||||
| 	// example: iAfZVVe2UQfNSG5BAjgYwa | ||||
| 	ID string | ||||
| } | ||||
|  | ||||
| // SendMessageHandler handles HTTP requests to send a new message | ||||
| func SendMessageHandler(w http.ResponseWriter, r *http.Request) { | ||||
| 	// swagger:route POST /api/v1/send message SendMessageParams | ||||
| @@ -158,8 +34,8 @@ func SendMessageHandler(w http.ResponseWriter, r *http.Request) { | ||||
| 	//	Schemes: http, https | ||||
| 	// | ||||
| 	//	Responses: | ||||
| 	//	  200: sendMessageResponse | ||||
| 	//	  400: jsonErrorResponse | ||||
| 	//	  200: SendMessageResponse | ||||
| 	//	  400: JSONErrorResponse | ||||
|  | ||||
| 	if config.DemoMode { | ||||
| 		httpJSONError(w, "this functionality has been disabled for demonstration purposes") | ||||
| @@ -168,9 +44,9 @@ func SendMessageHandler(w http.ResponseWriter, r *http.Request) { | ||||
|  | ||||
| 	decoder := json.NewDecoder(r.Body) | ||||
|  | ||||
| 	data := SendRequest{} | ||||
| 	data := sendMessageParams{} | ||||
|  | ||||
| 	if err := decoder.Decode(&data); err != nil { | ||||
| 	if err := decoder.Decode(&data.Body); err != nil { | ||||
| 		httpJSONError(w, err.Error()) | ||||
| 		return | ||||
| 	} | ||||
| @@ -188,14 +64,14 @@ func SendMessageHandler(w http.ResponseWriter, r *http.Request) { | ||||
| 	} | ||||
|  | ||||
| 	w.Header().Add("Content-Type", "application/json") | ||||
| 	if err := json.NewEncoder(w).Encode(SendMessageConfirmation{ID: id}); err != nil { | ||||
| 	if err := json.NewEncoder(w).Encode(struct{ ID string }{ID: id}); err != nil { | ||||
| 		httpError(w, err.Error()) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Send will validate the message structure and attempt to send to Mailpit. | ||||
| // It returns a sending summary or an error. | ||||
| func (d SendRequest) Send(remoteAddr string, httpAuthUser *string) (string, error) { | ||||
| func (d sendMessageParams) Send(remoteAddr string, httpAuthUser *string) (string, error) { | ||||
| 	ip, _, err := net.SplitHostPort(remoteAddr) | ||||
| 	if err != nil { | ||||
| 		return "", fmt.Errorf("error parsing request RemoteAddr: %s", err.Error()) | ||||
| @@ -206,16 +82,16 @@ func (d SendRequest) Send(remoteAddr string, httpAuthUser *string) (string, erro | ||||
| 	addresses := []string{} | ||||
|  | ||||
| 	msg := enmime.Builder(). | ||||
| 		From(d.From.Name, d.From.Email). | ||||
| 		Subject(d.Subject). | ||||
| 		Text([]byte(d.Text)) | ||||
| 		From(d.Body.From.Name, d.Body.From.Email). | ||||
| 		Subject(d.Body.Subject). | ||||
| 		Text([]byte(d.Body.Text)) | ||||
|  | ||||
| 	if d.HTML != "" { | ||||
| 		msg = msg.HTML([]byte(d.HTML)) | ||||
| 	if d.Body.HTML != "" { | ||||
| 		msg = msg.HTML([]byte(d.Body.HTML)) | ||||
| 	} | ||||
|  | ||||
| 	if len(d.To) > 0 { | ||||
| 		for _, a := range d.To { | ||||
| 	if len(d.Body.To) > 0 { | ||||
| 		for _, a := range d.Body.To { | ||||
| 			if _, err := mail.ParseAddress(a.Email); err == nil { | ||||
| 				msg = msg.To(a.Name, a.Email) | ||||
| 				addresses = append(addresses, a.Email) | ||||
| @@ -225,8 +101,8 @@ func (d SendRequest) Send(remoteAddr string, httpAuthUser *string) (string, erro | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if len(d.Cc) > 0 { | ||||
| 		for _, a := range d.Cc { | ||||
| 	if len(d.Body.Cc) > 0 { | ||||
| 		for _, a := range d.Body.Cc { | ||||
| 			if _, err := mail.ParseAddress(a.Email); err == nil { | ||||
| 				msg = msg.CC(a.Name, a.Email) | ||||
| 				addresses = append(addresses, a.Email) | ||||
| @@ -236,8 +112,8 @@ func (d SendRequest) Send(remoteAddr string, httpAuthUser *string) (string, erro | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if len(d.Bcc) > 0 { | ||||
| 		for _, e := range d.Bcc { | ||||
| 	if len(d.Body.Bcc) > 0 { | ||||
| 		for _, e := range d.Body.Bcc { | ||||
| 			if _, err := mail.ParseAddress(e); err == nil { | ||||
| 				msg = msg.BCC("", e) | ||||
| 				addresses = append(addresses, e) | ||||
| @@ -247,8 +123,8 @@ func (d SendRequest) Send(remoteAddr string, httpAuthUser *string) (string, erro | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if len(d.ReplyTo) > 0 { | ||||
| 		for _, a := range d.ReplyTo { | ||||
| 	if len(d.Body.ReplyTo) > 0 { | ||||
| 		for _, a := range d.Body.ReplyTo { | ||||
| 			if _, err := mail.ParseAddress(a.Email); err == nil { | ||||
| 				msg = msg.ReplyTo(a.Name, a.Email) | ||||
| 			} else { | ||||
| @@ -259,13 +135,13 @@ func (d SendRequest) Send(remoteAddr string, httpAuthUser *string) (string, erro | ||||
|  | ||||
| 	restrictedHeaders := []string{"To", "From", "Cc", "Bcc", "Reply-To", "Date", "Subject", "Content-Type", "Mime-Version"} | ||||
|  | ||||
| 	if len(d.Tags) > 0 { | ||||
| 		msg = msg.Header("X-Tags", strings.Join(d.Tags, ", ")) | ||||
| 	if len(d.Body.Tags) > 0 { | ||||
| 		msg = msg.Header("X-Tags", strings.Join(d.Body.Tags, ", ")) | ||||
| 		restrictedHeaders = append(restrictedHeaders, "X-Tags") | ||||
| 	} | ||||
|  | ||||
| 	if len(d.Headers) > 0 { | ||||
| 		for k, v := range d.Headers { | ||||
| 	if len(d.Body.Headers) > 0 { | ||||
| 		for k, v := range d.Body.Headers { | ||||
| 			// check header isn't in "restricted" headers | ||||
| 			if tools.InArray(k, restrictedHeaders) { | ||||
| 				return "", fmt.Errorf("cannot overwrite header: \"%s\"", k) | ||||
| @@ -274,8 +150,8 @@ func (d SendRequest) Send(remoteAddr string, httpAuthUser *string) (string, erro | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if len(d.Attachments) > 0 { | ||||
| 		for _, a := range d.Attachments { | ||||
| 	if len(d.Body.Attachments) > 0 { | ||||
| 		for _, a := range d.Body.Attachments { | ||||
| 			// workaround: split string because JS readAsDataURL() returns the base64 string | ||||
| 			// with the mime type prefix eg: data:image/png;base64,<base64String> | ||||
| 			parts := strings.Split(a.Content, ",") | ||||
| @@ -307,5 +183,5 @@ func (d SendRequest) Send(remoteAddr string, httpAuthUser *string) (string, erro | ||||
| 		return "", fmt.Errorf("error building message: %s", err.Error()) | ||||
| 	} | ||||
|  | ||||
| 	return smtpd.SaveToDatabase(ipAddr, d.From.Email, addresses, buff.Bytes(), httpAuthUser) | ||||
| 	return smtpd.SaveToDatabase(ipAddr, d.Body.From.Email, addresses, buff.Bytes(), httpAuthUser) | ||||
| } | ||||
|   | ||||
| @@ -1,41 +0,0 @@ | ||||
| package apiv1 | ||||
|  | ||||
| // These structs are for the purpose of defining swagger HTTP parameters & responses | ||||
|  | ||||
| // Binary data response which inherits the attachment's content type. | ||||
| // swagger:response BinaryResponse | ||||
| type binaryResponse string | ||||
|  | ||||
| // Plain text response | ||||
| // swagger:response TextResponse | ||||
| type textResponse string | ||||
|  | ||||
| // HTML response | ||||
| // swagger:response HTMLResponse | ||||
| type htmlResponse string | ||||
|  | ||||
| // Server error will return with a 400 status code | ||||
| // with the error message in the body | ||||
| // swagger:response ErrorResponse | ||||
| type errorResponse string | ||||
|  | ||||
| // Not found error will return a 404 status code | ||||
| // swagger:response NotFoundResponse | ||||
| type notFoundResponse string | ||||
|  | ||||
| // Plain text "ok" response | ||||
| // swagger:response OKResponse | ||||
| type okResponse string | ||||
|  | ||||
| // Plain JSON array response | ||||
| // swagger:response ArrayResponse | ||||
| type arrayResponse []string | ||||
|  | ||||
| // JSON error response | ||||
| // swagger:response jsonErrorResponse | ||||
| type jsonErrorResponse struct { | ||||
| 	// A JSON-encoded error response | ||||
| 	// | ||||
| 	// in: body | ||||
| 	Body JSONErrorMessage | ||||
| } | ||||
							
								
								
									
										416
									
								
								server/apiv1/swaggerParams.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										416
									
								
								server/apiv1/swaggerParams.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,416 @@ | ||||
| // Package apiv1 provides the API v1 endpoints for Mailpit. | ||||
| // | ||||
| // These structs are for the purpose of defining swagger HTTP parameters in go-swagger | ||||
| // in order to generate a spec file. They are lowercased to avoid exporting them as public types. | ||||
| // | ||||
| //nolint:unused | ||||
| package apiv1 | ||||
|  | ||||
| import "github.com/axllent/mailpit/internal/smtpd/chaos" | ||||
|  | ||||
| // swagger:parameters setChaosParams | ||||
| type setChaosParams struct { | ||||
| 	// in: body | ||||
| 	Body chaos.Triggers | ||||
| } | ||||
|  | ||||
| // swagger:parameters AttachmentParams | ||||
| type attachmentParams struct { | ||||
| 	// Message database ID or "latest" | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// required: true | ||||
| 	ID string | ||||
|  | ||||
| 	// Attachment part ID | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// required: true | ||||
| 	PartID string | ||||
| } | ||||
|  | ||||
| // swagger:parameters DownloadRawParams | ||||
| type downloadRawParams struct { | ||||
| 	// Message database ID or "latest" | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// required: true | ||||
| 	ID string | ||||
| } | ||||
|  | ||||
| // swagger:parameters GetMessageParams | ||||
| type getMessageParams struct { | ||||
| 	// Message database ID or "latest" | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// required: true | ||||
| 	ID string | ||||
| } | ||||
|  | ||||
| // swagger:parameters GetHeadersParams | ||||
| type getHeadersParams struct { | ||||
| 	// Message database ID or "latest" | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// required: true | ||||
| 	ID string | ||||
| } | ||||
|  | ||||
| // swagger:parameters GetMessagesParams | ||||
| type getMessagesParams struct { | ||||
| 	// Pagination offset | ||||
| 	// | ||||
| 	// in: query | ||||
| 	// name: start | ||||
| 	// required: false | ||||
| 	// default: 0 | ||||
| 	// type: integer | ||||
| 	Start int `json:"start"` | ||||
|  | ||||
| 	// Limit number of results | ||||
| 	// | ||||
| 	// in: query | ||||
| 	// name: limit | ||||
| 	// required: false | ||||
| 	// default: 50 | ||||
| 	// type: integer | ||||
| 	Limit int `json:"limit"` | ||||
| } | ||||
|  | ||||
| // swagger:parameters SetReadStatusParams | ||||
| type setReadStatusParams struct { | ||||
| 	// in: body | ||||
| 	Body struct { | ||||
| 		// Read status | ||||
| 		// | ||||
| 		// required: false | ||||
| 		// default: false | ||||
| 		// example: true | ||||
| 		Read bool | ||||
|  | ||||
| 		// Optional array of message database IDs | ||||
| 		// | ||||
| 		// required: false | ||||
| 		// default: [] | ||||
| 		// example: ["4oRBnPtCXgAqZniRhzLNmS", "hXayS6wnCgNnt6aFTvmOF6"] | ||||
| 		IDs []string | ||||
|  | ||||
| 		// Optional messages matching a search | ||||
| 		// | ||||
| 		// required: false | ||||
| 		// example: tag:backups | ||||
| 		Search string | ||||
| 	} | ||||
|  | ||||
| 	// Optional [timezone identifier](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) used only for `before:` & `after:` searches (eg: "Pacific/Auckland"). | ||||
| 	// | ||||
| 	// in: query | ||||
| 	// required: false | ||||
| 	// type string | ||||
| 	TZ string `json:"tz"` | ||||
| } | ||||
|  | ||||
| // swagger:parameters DeleteMessagesParams | ||||
| type deleteMessagesParams struct { | ||||
| 	// Delete request | ||||
| 	// in: body | ||||
| 	Body struct { | ||||
| 		// Array of message database IDs | ||||
| 		// | ||||
| 		// required: false | ||||
| 		// example: ["4oRBnPtCXgAqZniRhzLNmS", "hXayS6wnCgNnt6aFTvmOF6"] | ||||
| 		IDs []string | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // swagger:parameters SearchParams | ||||
| type searchParams struct { | ||||
| 	// Search query | ||||
| 	// | ||||
| 	// in: query | ||||
| 	// required: true | ||||
| 	// type: string | ||||
| 	Query string `json:"query"` | ||||
|  | ||||
| 	// Pagination offset | ||||
| 	// | ||||
| 	// in: query | ||||
| 	// required: false | ||||
| 	// default: 0 | ||||
| 	// type integer | ||||
| 	Start string `json:"start"` | ||||
|  | ||||
| 	// Limit results | ||||
| 	// | ||||
| 	// in: query | ||||
| 	// required: false | ||||
| 	// default: 50 | ||||
| 	// type integer | ||||
| 	Limit string `json:"limit"` | ||||
|  | ||||
| 	// Optional [timezone identifier](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) used only for `before:` & `after:` searches (eg: "Pacific/Auckland"). | ||||
| 	// | ||||
| 	// in: query | ||||
| 	// required: false | ||||
| 	// type string | ||||
| 	TZ string `json:"tz"` | ||||
| } | ||||
|  | ||||
| // swagger:parameters DeleteSearchParams | ||||
| type deleteSearchParams struct { | ||||
| 	// Search query | ||||
| 	// | ||||
| 	// in: query | ||||
| 	// required: true | ||||
| 	// type: string | ||||
| 	Query string `json:"query"` | ||||
|  | ||||
| 	// [Timezone identifier](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) used only for `before:` & `after:` searches (eg: "Pacific/Auckland"). | ||||
| 	// | ||||
| 	// in: query | ||||
| 	// required: false | ||||
| 	// type string | ||||
| 	TZ string `json:"tz"` | ||||
| } | ||||
|  | ||||
| // swagger:parameters HTMLCheckParams | ||||
| type htmlCheckParams struct { | ||||
| 	// Message database ID or "latest" | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// description: Message database ID or "latest" | ||||
| 	// required: true | ||||
| 	ID string | ||||
| } | ||||
|  | ||||
| // swagger:parameters LinkCheckParams | ||||
| type linkCheckParams struct { | ||||
| 	// Message database ID or "latest" | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// required: true | ||||
| 	ID string | ||||
|  | ||||
| 	// Follow redirects | ||||
| 	// | ||||
| 	// in: query | ||||
| 	// required: false | ||||
| 	// default: false | ||||
| 	Follow string `json:"follow"` | ||||
| } | ||||
|  | ||||
| // swagger:parameters ReleaseMessageParams | ||||
| type releaseMessageParams struct { | ||||
| 	// Message database ID | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// description: Message database ID | ||||
| 	// required: true | ||||
| 	ID string | ||||
|  | ||||
| 	// in: body | ||||
| 	Body struct { | ||||
| 		// Array of email addresses to relay the message to | ||||
| 		// | ||||
| 		// required: true | ||||
| 		// example: ["user1@example.com", "user2@example.com"] | ||||
| 		To []string | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // swagger:parameters SendMessageParams | ||||
| type sendMessageParams struct { | ||||
| 	// in: body | ||||
| 	// Body SendRequest | ||||
| 	Body struct { | ||||
| 		// "From" recipient | ||||
| 		// required: true | ||||
| 		From struct { | ||||
| 			// Optional name | ||||
| 			// example: John Doe | ||||
| 			Name string | ||||
| 			// Email address | ||||
| 			// example: john@example.com | ||||
| 			// required: true | ||||
| 			Email string | ||||
| 		} | ||||
|  | ||||
| 		// "To" recipients | ||||
| 		To []struct { | ||||
| 			// Optional name | ||||
| 			// example: Jane Doe | ||||
| 			Name string | ||||
| 			// Email address | ||||
| 			// example: jane@example.com | ||||
| 			// required: true | ||||
| 			Email string | ||||
| 		} | ||||
|  | ||||
| 		// Cc recipients | ||||
| 		Cc []struct { | ||||
| 			// Optional name | ||||
| 			// example: Manager | ||||
| 			Name string | ||||
| 			// Email address | ||||
| 			// example: manager@example.com | ||||
| 			// required: true | ||||
| 			Email string | ||||
| 		} | ||||
|  | ||||
| 		// Bcc recipients email addresses only | ||||
| 		// example: ["jack@example.com"] | ||||
| 		Bcc []string | ||||
|  | ||||
| 		// Optional Reply-To recipients | ||||
| 		ReplyTo []struct { | ||||
| 			// Optional name | ||||
| 			// example: Secretary | ||||
| 			Name string | ||||
| 			// Email address | ||||
| 			// example: secretary@example.com | ||||
| 			// required: true | ||||
| 			Email string | ||||
| 		} | ||||
|  | ||||
| 		// Subject | ||||
| 		// example: Mailpit message via the HTTP API | ||||
| 		Subject string | ||||
|  | ||||
| 		// Message body (text) | ||||
| 		// example: Mailpit is awesome! | ||||
| 		Text string | ||||
|  | ||||
| 		// Message body (HTML) | ||||
| 		// example: <div style="text-align:center"><p style="font-family: arial; font-size: 24px;">Mailpit is <b>awesome</b>!</p><p><img src="cid:mailpit-logo" /></p></div> | ||||
| 		HTML string | ||||
|  | ||||
| 		// Attachments | ||||
| 		Attachments []struct { | ||||
| 			// Base64-encoded string of the file content | ||||
| 			// required: true | ||||
| 			// example: iVBORw0KGgoAAAANSUhEUgAAAEEAAAA8CAMAAAAOlSdoAAAACXBIWXMAAAHrAAAB6wGM2bZBAAAAS1BMVEVHcEwRfnUkZ2gAt4UsSF8At4UtSV4At4YsSV4At4YsSV8At4YsSV4At4YsSV4sSV4At4YsSV4At4YtSV4At4YsSV4At4YtSV8At4YsUWYNAAAAGHRSTlMAAwoXGiktRE5dbnd7kpOlr7zJ0d3h8PD8PCSRAAACWUlEQVR42pXT4ZaqIBSG4W9rhqQYocG+/ys9Y0Z0Br+x3j8zaxUPewFh65K+7yrIMeIY4MT3wPfEJCidKXEMnLaVkxDiELiMz4WEOAZSFghxBIypCOlKiAMgXfIqTnBgSm8CIQ6BImxEUxEckClVQiHGj4Ba4AQHikAIClwTE9KtIghAhUJwoLkmLnCiAHJLRKgIMsEtVUKbBUIwoAg2C4QgQBE6l4VCnApBgSKYLLApCnCa0+96AEMW2BQcmC+Pr3nfp7o5Exy49gIADcIqUELGfeA+bp93LmAJp8QJoEcN3C7NY3sbVANixMyI0nku20/n5/ZRf3KI2k6JEDWQtxcbdGuAqu3TAXG+/799Oyyas1B1MnMiA+XyxHp9q0PUKGPiRAau1fZbLRZV09wZcT8/gHk8QQAxXn8VgaDqcUmU6O/r28nbVwXAqca2mRNtPAF5+zoP2MeN9Fy4NgC6RfcbgE7XITBRYTtOE3U3C2DVff7pk+PkUxgAbvtnPXJaD6DxulMLwOhPS/M3MQkgg1ZFrIXnmfaZoOfpKiFgzeZD/WuKqQEGrfJYkyWf6vlG3xUgTuscnkNkQsb599q124kdpMUjCa/XARHs1gZymVtGt3wLkiFv8rUgTxitYCex5EVGec0Y9VmoDTFBSQte2TfXGXlf7hbdaUM9Sk7fisEN9qfBBTK+FZcvM9fQSdkl2vj4W2oX/bRogO3XasiNH7R0eW7fgRM834ImTg+Lg6BEnx4vz81rhr+MYPBBQg1v8GndEOrthxaCTxNAOut8WKLGZQl+MPz88Q9tAO/hVuSeqQAAAABJRU5ErkJggg== | ||||
| 			Content string | ||||
| 			// Filename | ||||
| 			// required: true | ||||
| 			// example: mailpit.png | ||||
| 			Filename string | ||||
| 			// Optional Content Type for the the attachment. | ||||
| 			// If this field is not set (or empty) then the content type is automatically detected. | ||||
| 			// required: false | ||||
| 			// example: image/png | ||||
| 			ContentType string | ||||
| 			// Optional Content-ID (`cid`) for attachment. | ||||
| 			// If this field is set then the file is attached inline. | ||||
| 			// required: false | ||||
| 			// example: mailpit-logo | ||||
| 			ContentID string | ||||
| 		} | ||||
|  | ||||
| 		// Mailpit tags | ||||
| 		// example: ["Tag 1","Tag 2"] | ||||
| 		Tags []string | ||||
|  | ||||
| 		// Optional headers in {"key":"value"} format | ||||
| 		// example: {"X-IP":"1.2.3.4"} | ||||
| 		Headers map[string]string | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // swagger:parameters SetTagsParams | ||||
| type setTagsParams struct { | ||||
| 	// in: body | ||||
| 	Body struct { | ||||
| 		// Array of tag names to set | ||||
| 		// | ||||
| 		// required: true | ||||
| 		// example: ["Tag 1", "Tag 2"] | ||||
| 		Tags []string | ||||
|  | ||||
| 		// Array of message database IDs | ||||
| 		// | ||||
| 		// required: true | ||||
| 		// example: ["4oRBnPtCXgAqZniRhzLNmS", "hXayS6wnCgNnt6aFTvmOF6"] | ||||
| 		IDs []string | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // swagger:parameters RenameTagParams | ||||
| type renameTagParams struct { | ||||
| 	// The url-encoded tag name to rename | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// required: true | ||||
| 	// type: string | ||||
| 	Tag string | ||||
|  | ||||
| 	// in: body | ||||
| 	Body struct { | ||||
| 		// New name | ||||
| 		// | ||||
| 		// required: true | ||||
| 		// example: New name | ||||
| 		Name string | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // swagger:parameters DeleteTagParams | ||||
| type deleteTagParams struct { | ||||
| 	// The url-encoded tag name to delete | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// required: true | ||||
| 	Tag string | ||||
| } | ||||
|  | ||||
| // swagger:parameters GetMessageHTMLParams | ||||
| type getMessageHTMLParams struct { | ||||
| 	// Message database ID or "latest" | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// required: true | ||||
| 	ID string | ||||
|  | ||||
| 	// If this is route is to be embedded in an iframe, set embed to `1` in the URL to add `target="_blank"` and `rel="noreferrer noopener"` to all links. | ||||
| 	// | ||||
| 	// In addition, a small script will be added to the end of the document to post (postMessage()) the height of the document back to the parent window for optional iframe height resizing. | ||||
| 	// | ||||
| 	// Note that this will also *transform* the message into a full HTML document (if it isn't already), so this option is useful for viewing but not programmatic testing. | ||||
| 	// | ||||
| 	// in: query | ||||
| 	// required: false | ||||
| 	// type: string | ||||
| 	Embed string `json:"embed"` | ||||
| } | ||||
|  | ||||
| // swagger:parameters GetMessageTextParams | ||||
| type getMessageTextParams struct { | ||||
| 	// Message database ID or "latest" | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// required: true | ||||
| 	ID string | ||||
| } | ||||
|  | ||||
| // swagger:parameters SpamAssassinCheckParams | ||||
| type spamAssassinCheckParams struct { | ||||
| 	// Message database ID or "latest" | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// required: true | ||||
| 	ID string | ||||
| } | ||||
|  | ||||
| // swagger:parameters ThumbnailParams | ||||
| type thumbnailParams struct { | ||||
| 	// Message database ID or "latest" | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// required: true | ||||
| 	ID string | ||||
|  | ||||
| 	// Attachment part ID | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// required: true | ||||
| 	PartID string | ||||
| } | ||||
							
								
								
									
										142
									
								
								server/apiv1/swaggerResponses.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								server/apiv1/swaggerResponses.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,142 @@ | ||||
| // Package apiv1 provides the API v1 endpoints for Mailpit. | ||||
| // | ||||
| // These structs are for the purpose of defining swagger HTTP responses in go-swagger | ||||
| // in order to generate a spec file. They are lowercased to avoid exporting them as public types. | ||||
| // | ||||
| //nolint:unused | ||||
| package apiv1 | ||||
|  | ||||
| import ( | ||||
| 	"github.com/axllent/mailpit/internal/smtpd/chaos" | ||||
| 	"github.com/axllent/mailpit/internal/stats" | ||||
| ) | ||||
|  | ||||
| // Binary data response which inherits the attachment's content type. | ||||
| // swagger:response BinaryResponse | ||||
| type binaryResponse string | ||||
|  | ||||
| // Plain text response | ||||
| // swagger:response TextResponse | ||||
| type textResponse string | ||||
|  | ||||
| // HTML response | ||||
| // swagger:response HTMLResponse | ||||
| type htmlResponse string | ||||
|  | ||||
| // Server error will return with a 400 status code | ||||
| // with the error message in the body | ||||
| // swagger:response ErrorResponse | ||||
| type errorResponse string | ||||
|  | ||||
| // Not found error will return a 404 status code | ||||
| // swagger:response NotFoundResponse | ||||
| type notFoundResponse string | ||||
|  | ||||
| // Plain text "ok" response | ||||
| // swagger:response OKResponse | ||||
| type okResponse string | ||||
|  | ||||
| // Plain JSON array response | ||||
| // swagger:response ArrayResponse | ||||
| type arrayResponse []string | ||||
|  | ||||
| // JSON error response | ||||
| // swagger:response JSONErrorResponse | ||||
| type jsonErrorResponse struct { | ||||
| 	// A JSON-encoded error response | ||||
| 	// | ||||
| 	// in: body | ||||
| 	Body struct { | ||||
| 		// Error message | ||||
| 		// example: invalid format | ||||
| 		Error string | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Web UI configuration response | ||||
| // swagger:response WebUIConfigurationResponse | ||||
| type webUIConfigurationResponse struct { | ||||
| 	// Web UI configuration settings | ||||
| 	// | ||||
| 	// in: body | ||||
| 	Body struct { | ||||
| 		// Optional label to identify this Mailpit instance | ||||
| 		Label string | ||||
| 		// Message Relay information | ||||
| 		MessageRelay struct { | ||||
| 			// Whether message relaying (release) is enabled | ||||
| 			Enabled bool | ||||
| 			// The configured SMTP server address | ||||
| 			SMTPServer string | ||||
| 			// Enforced Return-Path (if set) for relay bounces | ||||
| 			ReturnPath string | ||||
| 			// Only allow relaying to these recipients (regex) | ||||
| 			AllowedRecipients string | ||||
| 			// Block relaying to these recipients (regex) | ||||
| 			BlockedRecipients string | ||||
| 			// Overrides the "From" address for all relayed messages | ||||
| 			OverrideFrom string | ||||
| 			// Preserve the original Message-IDs when relaying messages | ||||
| 			PreserveMessageIDs bool | ||||
|  | ||||
| 			// DEPRECATED 2024/03/12 | ||||
| 			// swagger:ignore | ||||
| 			RecipientAllowlist string | ||||
| 		} | ||||
|  | ||||
| 		// Whether SpamAssassin is enabled | ||||
| 		SpamAssassin bool | ||||
|  | ||||
| 		// Whether Chaos support is enabled at runtime | ||||
| 		ChaosEnabled bool | ||||
|  | ||||
| 		// Whether messages with duplicate IDs are ignored | ||||
| 		DuplicatesIgnored bool | ||||
|  | ||||
| 		// Whether the delete button should be hidden | ||||
| 		HideDeleteAllButton bool | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Application information | ||||
| // swagger:response AppInfoResponse | ||||
| type appInfoResponse struct { | ||||
| 	// Application information | ||||
| 	// | ||||
| 	// in: body | ||||
| 	Body stats.AppInformation | ||||
| } | ||||
|  | ||||
| // Response for the Chaos triggers configuration | ||||
| // swagger:response ChaosResponse | ||||
| type chaosResponse struct { | ||||
| 	// The current Chaos triggers | ||||
| 	// | ||||
| 	// in: body | ||||
| 	Body chaos.Triggers | ||||
| } | ||||
|  | ||||
| // Message headers | ||||
| // swagger:model MessageHeadersResponse | ||||
| type messageHeadersResponse map[string][]string | ||||
|  | ||||
| // Summary of messages | ||||
| // swagger:response MessagesSummaryResponse | ||||
| type messagesSummaryResponse struct { | ||||
| 	// The messages summary | ||||
| 	// in: body | ||||
| 	Body MessagesSummary | ||||
| } | ||||
|  | ||||
| // Confirmation message for HTTP send API | ||||
| // swagger:response SendMessageResponse | ||||
| type sendMessageResponse struct { | ||||
| 	// Response for sending messages via the HTTP API | ||||
| 	// | ||||
| 	// in: body | ||||
| 	Body struct { | ||||
| 		// Database ID | ||||
| 		// example: iAfZVVe2UQfNSG5BAjgYwa | ||||
| 		ID string | ||||
| 	} | ||||
| } | ||||
| @@ -32,24 +32,6 @@ func GetAllTags(w http.ResponseWriter, _ *http.Request) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // swagger:parameters SetTagsParams | ||||
| type setTagsParams struct { | ||||
| 	// in: body | ||||
| 	Body struct { | ||||
| 		// Array of tag names to set | ||||
| 		// | ||||
| 		// required: true | ||||
| 		// example: ["Tag 1", "Tag 2"] | ||||
| 		Tags []string | ||||
|  | ||||
| 		// Array of message database IDs | ||||
| 		// | ||||
| 		// required: true | ||||
| 		// example: ["4oRBnPtCXgAqZniRhzLNmS", "hXayS6wnCgNnt6aFTvmOF6"] | ||||
| 		IDs []string | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // SetMessageTags (method: PUT) will set the tags for all provided IDs | ||||
| func SetMessageTags(w http.ResponseWriter, r *http.Request) { | ||||
| 	// swagger:route PUT /api/v1/tags tags SetTagsParams | ||||
| @@ -98,25 +80,6 @@ func SetMessageTags(w http.ResponseWriter, r *http.Request) { | ||||
| 	_, _ = w.Write([]byte("ok")) | ||||
| } | ||||
|  | ||||
| // swagger:parameters RenameTagParams | ||||
| type renameTagParams struct { | ||||
| 	// The url-encoded tag name to rename | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// required: true | ||||
| 	// type: string | ||||
| 	Tag string | ||||
|  | ||||
| 	// in: body | ||||
| 	Body struct { | ||||
| 		// New name | ||||
| 		// | ||||
| 		// required: true | ||||
| 		// example: New name | ||||
| 		Name string | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // RenameTag (method: PUT) used to rename a tag | ||||
| func RenameTag(w http.ResponseWriter, r *http.Request) { | ||||
| 	// swagger:route PUT /api/v1/tags/{Tag} tags RenameTagParams | ||||
| @@ -161,15 +124,6 @@ func RenameTag(w http.ResponseWriter, r *http.Request) { | ||||
| 	_, _ = w.Write([]byte("ok")) | ||||
| } | ||||
|  | ||||
| // swagger:parameters DeleteTagParams | ||||
| type deleteTagParams struct { | ||||
| 	// The url-encoded tag name to delete | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// required: true | ||||
| 	Tag string | ||||
| } | ||||
|  | ||||
| // DeleteTag (method: DELETE) used to delete a tag | ||||
| func DeleteTag(w http.ResponseWriter, r *http.Request) { | ||||
| 	// swagger:route DELETE /api/v1/tags/{Tag} tags DeleteTagParams | ||||
|   | ||||
| @@ -16,26 +16,6 @@ import ( | ||||
| 	"golang.org/x/net/html/atom" | ||||
| ) | ||||
|  | ||||
| // swagger:parameters GetMessageHTMLParams | ||||
| type getMessageHTMLParams struct { | ||||
| 	// Message database ID or "latest" | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// required: true | ||||
| 	ID string | ||||
|  | ||||
| 	// If this is route is to be embedded in an iframe, set embed to `1` in the URL to add `target="_blank"` and `rel="noreferrer noopener"` to all links. | ||||
| 	// | ||||
| 	// In addition, a small script will be added to the end of the document to post (postMessage()) the height of the document back to the parent window for optional iframe height resizing. | ||||
| 	// | ||||
| 	// Note that this will also *transform* the message into a full HTML document (if it isn't already), so this option is useful for viewing but not programmatic testing. | ||||
| 	// | ||||
| 	// in: query | ||||
| 	// required: false | ||||
| 	// type: string | ||||
| 	Embed string `json:"embed"` | ||||
| } | ||||
|  | ||||
| // GetMessageHTML (method: GET) returns a rendered version of a message's HTML part | ||||
| func GetMessageHTML(w http.ResponseWriter, r *http.Request) { | ||||
| 	// swagger:route GET /view/{ID}.html testing GetMessageHTMLParams | ||||
| @@ -123,15 +103,6 @@ func GetMessageHTML(w http.ResponseWriter, r *http.Request) { | ||||
| 	_, _ = w.Write([]byte(htmlStr)) | ||||
| } | ||||
|  | ||||
| // swagger:parameters GetMessageTextParams | ||||
| type getMessageTextParams struct { | ||||
| 	// Message database ID or "latest" | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// required: true | ||||
| 	ID string | ||||
| } | ||||
|  | ||||
| // GetMessageText (method: GET) returns a message's text part | ||||
| func GetMessageText(w http.ResponseWriter, r *http.Request) { | ||||
| 	// swagger:route GET /view/{ID}.txt testing GetMessageTextParams | ||||
|   | ||||
| @@ -22,21 +22,6 @@ var ( | ||||
| 	thumbHeight = 120 | ||||
| ) | ||||
|  | ||||
| // swagger:parameters ThumbnailParams | ||||
| type thumbnailParams struct { | ||||
| 	// Message database ID or "latest" | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// required: true | ||||
| 	ID string | ||||
|  | ||||
| 	// Attachment part ID | ||||
| 	// | ||||
| 	// in: path | ||||
| 	// required: true | ||||
| 	PartID string | ||||
| } | ||||
|  | ||||
| // Thumbnail returns a thumbnail image for an attachment (images only) | ||||
| func Thumbnail(w http.ResponseWriter, r *http.Request) { | ||||
| 	// swagger:route GET /api/v1/message/{ID}/part/{PartID}/thumb message ThumbnailParams | ||||
|   | ||||
| @@ -283,7 +283,9 @@ func TestAPIv1Send(t *testing.T) { | ||||
| 		t.Errorf("Expected nil, received %s", err.Error()) | ||||
| 	} | ||||
|  | ||||
| 	resp := apiv1.SendMessageConfirmation{} | ||||
| 	resp := struct { | ||||
| 		ID string | ||||
| 	}{} | ||||
|  | ||||
| 	if err := json.Unmarshal(b, &resp); err != nil { | ||||
| 		t.Error(err.Error()) | ||||
|   | ||||
| @@ -785,16 +785,185 @@ | ||||
|             "name": "Body", | ||||
|             "in": "body", | ||||
|             "schema": { | ||||
|               "$ref": "#/definitions/SendRequest" | ||||
|               "type": "object", | ||||
|               "required": [ | ||||
|                 "From" | ||||
|               ], | ||||
|               "properties": { | ||||
|                 "Attachments": { | ||||
|                   "description": "Attachments", | ||||
|                   "type": "array", | ||||
|                   "items": { | ||||
|                     "type": "object", | ||||
|                     "required": [ | ||||
|                       "Content", | ||||
|                       "Filename" | ||||
|                     ], | ||||
|                     "properties": { | ||||
|                       "Content": { | ||||
|                         "description": "Base64-encoded string of the file content", | ||||
|                         "type": "string", | ||||
|                         "example": "iVBORw0KGgoAAAANSUhEUgAAAEEAAAA8CAMAAAAOlSdoAAAACXBIWXMAAAHrAAAB6wGM2bZBAAAAS1BMVEVHcEwRfnUkZ2gAt4UsSF8At4UtSV4At4YsSV4At4YsSV8At4YsSV4At4YsSV4sSV4At4YsSV4At4YtSV4At4YsSV4At4YtSV8At4YsUWYNAAAAGHRSTlMAAwoXGiktRE5dbnd7kpOlr7zJ0d3h8PD8PCSRAAACWUlEQVR42pXT4ZaqIBSG4W9rhqQYocG+/ys9Y0Z0Br+x3j8zaxUPewFh65K+7yrIMeIY4MT3wPfEJCidKXEMnLaVkxDiELiMz4WEOAZSFghxBIypCOlKiAMgXfIqTnBgSm8CIQ6BImxEUxEckClVQiHGj4Ba4AQHikAIClwTE9KtIghAhUJwoLkmLnCiAHJLRKgIMsEtVUKbBUIwoAg2C4QgQBE6l4VCnApBgSKYLLApCnCa0+96AEMW2BQcmC+Pr3nfp7o5Exy49gIADcIqUELGfeA+bp93LmAJp8QJoEcN3C7NY3sbVANixMyI0nku20/n5/ZRf3KI2k6JEDWQtxcbdGuAqu3TAXG+/799Oyyas1B1MnMiA+XyxHp9q0PUKGPiRAau1fZbLRZV09wZcT8/gHk8QQAxXn8VgaDqcUmU6O/r28nbVwXAqca2mRNtPAF5+zoP2MeN9Fy4NgC6RfcbgE7XITBRYTtOE3U3C2DVff7pk+PkUxgAbvtnPXJaD6DxulMLwOhPS/M3MQkgg1ZFrIXnmfaZoOfpKiFgzeZD/WuKqQEGrfJYkyWf6vlG3xUgTuscnkNkQsb599q124kdpMUjCa/XARHs1gZymVtGt3wLkiFv8rUgTxitYCex5EVGec0Y9VmoDTFBSQte2TfXGXlf7hbdaUM9Sk7fisEN9qfBBTK+FZcvM9fQSdkl2vj4W2oX/bRogO3XasiNH7R0eW7fgRM834ImTg+Lg6BEnx4vz81rhr+MYPBBQg1v8GndEOrthxaCTxNAOut8WKLGZQl+MPz88Q9tAO/hVuSeqQAAAABJRU5ErkJggg==" | ||||
|                       }, | ||||
|                       "ContentID": { | ||||
|                         "description": "Optional Content-ID (`cid`) for attachment.\nIf this field is set then the file is attached inline.", | ||||
|                         "type": "string", | ||||
|                         "example": "mailpit-logo" | ||||
|                       }, | ||||
|                       "ContentType": { | ||||
|                         "description": "Optional Content Type for the the attachment.\nIf this field is not set (or empty) then the content type is automatically detected.", | ||||
|                         "type": "string", | ||||
|                         "example": "image/png" | ||||
|                       }, | ||||
|                       "Filename": { | ||||
|                         "description": "Filename", | ||||
|                         "type": "string", | ||||
|                         "example": "mailpit.png" | ||||
|                       } | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|                 "Bcc": { | ||||
|                   "description": "Bcc recipients email addresses only", | ||||
|                   "type": "array", | ||||
|                   "items": { | ||||
|                     "type": "string" | ||||
|                   }, | ||||
|                   "example": [ | ||||
|                     "jack@example.com" | ||||
|                   ] | ||||
|                 }, | ||||
|                 "Cc": { | ||||
|                   "description": "Cc recipients", | ||||
|                   "type": "array", | ||||
|                   "items": { | ||||
|                     "type": "object", | ||||
|                     "required": [ | ||||
|                       "Email" | ||||
|                     ], | ||||
|                     "properties": { | ||||
|                       "Email": { | ||||
|                         "description": "Email address", | ||||
|                         "type": "string", | ||||
|                         "example": "manager@example.com" | ||||
|                       }, | ||||
|                       "Name": { | ||||
|                         "description": "Optional name", | ||||
|                         "type": "string", | ||||
|                         "example": "Manager" | ||||
|                       } | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|                 "From": { | ||||
|                   "description": "\"From\" recipient", | ||||
|                   "type": "object", | ||||
|                   "required": [ | ||||
|                     "Email" | ||||
|                   ], | ||||
|                   "properties": { | ||||
|                     "Email": { | ||||
|                       "description": "Email address", | ||||
|                       "type": "string", | ||||
|                       "example": "john@example.com" | ||||
|                     }, | ||||
|                     "Name": { | ||||
|                       "description": "Optional name", | ||||
|                       "type": "string", | ||||
|                       "example": "John Doe" | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|                 "HTML": { | ||||
|                   "description": "Message body (HTML)", | ||||
|                   "type": "string", | ||||
|                   "example": "\u003cdiv style=\"text-align:center\"\u003e\u003cp style=\"font-family: arial; font-size: 24px;\"\u003eMailpit is \u003cb\u003eawesome\u003c/b\u003e!\u003c/p\u003e\u003cp\u003e\u003cimg src=\"cid:mailpit-logo\" /\u003e\u003c/p\u003e\u003c/div\u003e" | ||||
|                 }, | ||||
|                 "Headers": { | ||||
|                   "description": "Optional headers in {\"key\":\"value\"} format", | ||||
|                   "type": "object", | ||||
|                   "additionalProperties": { | ||||
|                     "type": "string" | ||||
|                   }, | ||||
|                   "example": { | ||||
|                     "X-IP": "1.2.3.4" | ||||
|                   } | ||||
|                 }, | ||||
|                 "ReplyTo": { | ||||
|                   "description": "Optional Reply-To recipients", | ||||
|                   "type": "array", | ||||
|                   "items": { | ||||
|                     "type": "object", | ||||
|                     "required": [ | ||||
|                       "Email" | ||||
|                     ], | ||||
|                     "properties": { | ||||
|                       "Email": { | ||||
|                         "description": "Email address", | ||||
|                         "type": "string", | ||||
|                         "example": "secretary@example.com" | ||||
|                       }, | ||||
|                       "Name": { | ||||
|                         "description": "Optional name", | ||||
|                         "type": "string", | ||||
|                         "example": "Secretary" | ||||
|                       } | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|                 "Subject": { | ||||
|                   "description": "Subject", | ||||
|                   "type": "string", | ||||
|                   "example": "Mailpit message via the HTTP API" | ||||
|                 }, | ||||
|                 "Tags": { | ||||
|                   "description": "Mailpit tags", | ||||
|                   "type": "array", | ||||
|                   "items": { | ||||
|                     "type": "string" | ||||
|                   }, | ||||
|                   "example": [ | ||||
|                     "Tag 1", | ||||
|                     "Tag 2" | ||||
|                   ] | ||||
|                 }, | ||||
|                 "Text": { | ||||
|                   "description": "Message body (text)", | ||||
|                   "type": "string", | ||||
|                   "example": "Mailpit is awesome!" | ||||
|                 }, | ||||
|                 "To": { | ||||
|                   "description": "\"To\" recipients", | ||||
|                   "type": "array", | ||||
|                   "items": { | ||||
|                     "type": "object", | ||||
|                     "required": [ | ||||
|                       "Email" | ||||
|                     ], | ||||
|                     "properties": { | ||||
|                       "Email": { | ||||
|                         "description": "Email address", | ||||
|                         "type": "string", | ||||
|                         "example": "jane@example.com" | ||||
|                       }, | ||||
|                       "Name": { | ||||
|                         "description": "Optional name", | ||||
|                         "type": "string", | ||||
|                         "example": "Jane Doe" | ||||
|                       } | ||||
|                     } | ||||
|                   } | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         ], | ||||
|         "responses": { | ||||
|           "200": { | ||||
|             "$ref": "#/responses/sendMessageResponse" | ||||
|             "$ref": "#/responses/SendMessageResponse" | ||||
|           }, | ||||
|           "400": { | ||||
|             "$ref": "#/responses/jsonErrorResponse" | ||||
|             "$ref": "#/responses/JSONErrorResponse" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
| @@ -984,7 +1153,7 @@ | ||||
|           "application" | ||||
|         ], | ||||
|         "summary": "Get web UI configuration", | ||||
|         "operationId": "WebUIConfiguration", | ||||
|         "operationId": "WebUIConfigurationResponse", | ||||
|         "responses": { | ||||
|           "200": { | ||||
|             "$ref": "#/responses/WebUIConfigurationResponse" | ||||
| @@ -1203,9 +1372,46 @@ | ||||
|       }, | ||||
|       "x-go-package": "github.com/axllent/mailpit/internal/storage" | ||||
|     }, | ||||
|     "ChaosTrigger": { | ||||
|       "description": "Trigger for Chaos", | ||||
|       "type": "object", | ||||
|       "required": [ | ||||
|         "ErrorCode", | ||||
|         "Probability" | ||||
|       ], | ||||
|       "properties": { | ||||
|         "ErrorCode": { | ||||
|           "description": "SMTP error code to return. The value must range from 400 to 599.", | ||||
|           "type": "integer", | ||||
|           "format": "int64", | ||||
|           "example": 451 | ||||
|         }, | ||||
|         "Probability": { | ||||
|           "description": "Probability (chance) of triggering the error. The value must range from 0 to 100.", | ||||
|           "type": "integer", | ||||
|           "format": "int64", | ||||
|           "example": 5 | ||||
|         } | ||||
|       }, | ||||
|       "x-go-name": "Trigger", | ||||
|       "x-go-package": "github.com/axllent/mailpit/internal/smtpd/chaos" | ||||
|     }, | ||||
|     "ChaosTriggers": { | ||||
|       "description": "ChaosTriggers are the Chaos triggers", | ||||
|       "$ref": "#/definitions/Triggers" | ||||
|       "description": "Triggers for the Chaos configuration", | ||||
|       "type": "object", | ||||
|       "properties": { | ||||
|         "Authentication": { | ||||
|           "$ref": "#/definitions/ChaosTrigger" | ||||
|         }, | ||||
|         "Recipient": { | ||||
|           "$ref": "#/definitions/ChaosTrigger" | ||||
|         }, | ||||
|         "Sender": { | ||||
|           "$ref": "#/definitions/ChaosTrigger" | ||||
|         } | ||||
|       }, | ||||
|       "x-go-name": "Triggers", | ||||
|       "x-go-package": "github.com/axllent/mailpit/internal/smtpd/chaos" | ||||
|     }, | ||||
|     "HTMLCheckResponse": { | ||||
|       "description": "Response represents the HTML check response struct", | ||||
| @@ -1384,18 +1590,6 @@ | ||||
|       "x-go-name": "Warning", | ||||
|       "x-go-package": "github.com/axllent/mailpit/internal/htmlcheck" | ||||
|     }, | ||||
|     "JSONErrorMessage": { | ||||
|       "description": "JSONErrorMessage struct", | ||||
|       "type": "object", | ||||
|       "properties": { | ||||
|         "Error": { | ||||
|           "description": "Error message", | ||||
|           "type": "string", | ||||
|           "example": "invalid format" | ||||
|         } | ||||
|       }, | ||||
|       "x-go-package": "github.com/axllent/mailpit/server/apiv1" | ||||
|     }, | ||||
|     "Link": { | ||||
|       "description": "Link struct", | ||||
|       "type": "object", | ||||
| @@ -1571,7 +1765,7 @@ | ||||
|           "type": "string" | ||||
|         } | ||||
|       }, | ||||
|       "x-go-name": "messageHeaders", | ||||
|       "x-go-name": "messageHeadersResponse", | ||||
|       "x-go-package": "github.com/axllent/mailpit/server/apiv1" | ||||
|     }, | ||||
|     "MessageSummary": { | ||||
| @@ -1731,192 +1925,6 @@ | ||||
|       }, | ||||
|       "x-go-package": "github.com/axllent/mailpit/internal/spamassassin" | ||||
|     }, | ||||
|     "SendMessageConfirmation": { | ||||
|       "description": "SendMessageConfirmation struct", | ||||
|       "type": "object", | ||||
|       "properties": { | ||||
|         "ID": { | ||||
|           "description": "Database ID", | ||||
|           "type": "string", | ||||
|           "example": "iAfZVVe2UQfNSG5BAjgYwa" | ||||
|         } | ||||
|       }, | ||||
|       "x-go-package": "github.com/axllent/mailpit/server/apiv1" | ||||
|     }, | ||||
|     "SendRequest": { | ||||
|       "description": "SendRequest to send a message via HTTP", | ||||
|       "type": "object", | ||||
|       "required": [ | ||||
|         "From" | ||||
|       ], | ||||
|       "properties": { | ||||
|         "Attachments": { | ||||
|           "description": "Attachments", | ||||
|           "type": "array", | ||||
|           "items": { | ||||
|             "type": "object", | ||||
|             "required": [ | ||||
|               "Content", | ||||
|               "Filename" | ||||
|             ], | ||||
|             "properties": { | ||||
|               "Content": { | ||||
|                 "description": "Base64-encoded string of the file content", | ||||
|                 "type": "string", | ||||
|                 "example": "iVBORw0KGgoAAAANSUhEUgAAAEEAAAA8CAMAAAAOlSdoAAAACXBIWXMAAAHrAAAB6wGM2bZBAAAAS1BMVEVHcEwRfnUkZ2gAt4UsSF8At4UtSV4At4YsSV4At4YsSV8At4YsSV4At4YsSV4sSV4At4YsSV4At4YtSV4At4YsSV4At4YtSV8At4YsUWYNAAAAGHRSTlMAAwoXGiktRE5dbnd7kpOlr7zJ0d3h8PD8PCSRAAACWUlEQVR42pXT4ZaqIBSG4W9rhqQYocG+/ys9Y0Z0Br+x3j8zaxUPewFh65K+7yrIMeIY4MT3wPfEJCidKXEMnLaVkxDiELiMz4WEOAZSFghxBIypCOlKiAMgXfIqTnBgSm8CIQ6BImxEUxEckClVQiHGj4Ba4AQHikAIClwTE9KtIghAhUJwoLkmLnCiAHJLRKgIMsEtVUKbBUIwoAg2C4QgQBE6l4VCnApBgSKYLLApCnCa0+96AEMW2BQcmC+Pr3nfp7o5Exy49gIADcIqUELGfeA+bp93LmAJp8QJoEcN3C7NY3sbVANixMyI0nku20/n5/ZRf3KI2k6JEDWQtxcbdGuAqu3TAXG+/799Oyyas1B1MnMiA+XyxHp9q0PUKGPiRAau1fZbLRZV09wZcT8/gHk8QQAxXn8VgaDqcUmU6O/r28nbVwXAqca2mRNtPAF5+zoP2MeN9Fy4NgC6RfcbgE7XITBRYTtOE3U3C2DVff7pk+PkUxgAbvtnPXJaD6DxulMLwOhPS/M3MQkgg1ZFrIXnmfaZoOfpKiFgzeZD/WuKqQEGrfJYkyWf6vlG3xUgTuscnkNkQsb599q124kdpMUjCa/XARHs1gZymVtGt3wLkiFv8rUgTxitYCex5EVGec0Y9VmoDTFBSQte2TfXGXlf7hbdaUM9Sk7fisEN9qfBBTK+FZcvM9fQSdkl2vj4W2oX/bRogO3XasiNH7R0eW7fgRM834ImTg+Lg6BEnx4vz81rhr+MYPBBQg1v8GndEOrthxaCTxNAOut8WKLGZQl+MPz88Q9tAO/hVuSeqQAAAABJRU5ErkJggg==" | ||||
|               }, | ||||
|               "ContentID": { | ||||
|                 "description": "Optional Content-ID (`cid`) for attachment.\nIf this field is set then the file is attached inline.", | ||||
|                 "type": "string", | ||||
|                 "example": "mailpit-logo" | ||||
|               }, | ||||
|               "ContentType": { | ||||
|                 "description": "Optional Content Type for the the attachment.\nIf this field is not set (or empty) then the content type is automatically detected.", | ||||
|                 "type": "string", | ||||
|                 "example": "image/png" | ||||
|               }, | ||||
|               "Filename": { | ||||
|                 "description": "Filename", | ||||
|                 "type": "string", | ||||
|                 "example": "mailpit.png" | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "Bcc": { | ||||
|           "description": "Bcc recipients email addresses only", | ||||
|           "type": "array", | ||||
|           "items": { | ||||
|             "type": "string" | ||||
|           }, | ||||
|           "example": [ | ||||
|             "jack@example.com" | ||||
|           ] | ||||
|         }, | ||||
|         "Cc": { | ||||
|           "description": "Cc recipients", | ||||
|           "type": "array", | ||||
|           "items": { | ||||
|             "type": "object", | ||||
|             "required": [ | ||||
|               "Email" | ||||
|             ], | ||||
|             "properties": { | ||||
|               "Email": { | ||||
|                 "description": "Email address", | ||||
|                 "type": "string", | ||||
|                 "example": "manager@example.com" | ||||
|               }, | ||||
|               "Name": { | ||||
|                 "description": "Optional name", | ||||
|                 "type": "string", | ||||
|                 "example": "Manager" | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "From": { | ||||
|           "description": "\"From\" recipient", | ||||
|           "type": "object", | ||||
|           "required": [ | ||||
|             "Email" | ||||
|           ], | ||||
|           "properties": { | ||||
|             "Email": { | ||||
|               "description": "Email address", | ||||
|               "type": "string", | ||||
|               "example": "john@example.com" | ||||
|             }, | ||||
|             "Name": { | ||||
|               "description": "Optional name", | ||||
|               "type": "string", | ||||
|               "example": "John Doe" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "HTML": { | ||||
|           "description": "Message body (HTML)", | ||||
|           "type": "string", | ||||
|           "example": "\u003cdiv style=\"text-align:center\"\u003e\u003cp style=\"font-family: arial; font-size: 24px;\"\u003eMailpit is \u003cb\u003eawesome\u003c/b\u003e!\u003c/p\u003e\u003cp\u003e\u003cimg src=\"cid:mailpit-logo\" /\u003e\u003c/p\u003e\u003c/div\u003e" | ||||
|         }, | ||||
|         "Headers": { | ||||
|           "description": "Optional headers in {\"key\":\"value\"} format", | ||||
|           "type": "object", | ||||
|           "additionalProperties": { | ||||
|             "type": "string" | ||||
|           }, | ||||
|           "example": { | ||||
|             "X-IP": "1.2.3.4" | ||||
|           } | ||||
|         }, | ||||
|         "ReplyTo": { | ||||
|           "description": "Optional Reply-To recipients", | ||||
|           "type": "array", | ||||
|           "items": { | ||||
|             "type": "object", | ||||
|             "required": [ | ||||
|               "Email" | ||||
|             ], | ||||
|             "properties": { | ||||
|               "Email": { | ||||
|                 "description": "Email address", | ||||
|                 "type": "string", | ||||
|                 "example": "secretary@example.com" | ||||
|               }, | ||||
|               "Name": { | ||||
|                 "description": "Optional name", | ||||
|                 "type": "string", | ||||
|                 "example": "Secretary" | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "Subject": { | ||||
|           "description": "Subject", | ||||
|           "type": "string", | ||||
|           "example": "Mailpit message via the HTTP API" | ||||
|         }, | ||||
|         "Tags": { | ||||
|           "description": "Mailpit tags", | ||||
|           "type": "array", | ||||
|           "items": { | ||||
|             "type": "string" | ||||
|           }, | ||||
|           "example": [ | ||||
|             "Tag 1", | ||||
|             "Tag 2" | ||||
|           ] | ||||
|         }, | ||||
|         "Text": { | ||||
|           "description": "Message body (text)", | ||||
|           "type": "string", | ||||
|           "example": "Mailpit is awesome!" | ||||
|         }, | ||||
|         "To": { | ||||
|           "description": "\"To\" recipients", | ||||
|           "type": "array", | ||||
|           "items": { | ||||
|             "type": "object", | ||||
|             "required": [ | ||||
|               "Email" | ||||
|             ], | ||||
|             "properties": { | ||||
|               "Email": { | ||||
|                 "description": "Email address", | ||||
|                 "type": "string", | ||||
|                 "example": "jane@example.com" | ||||
|               }, | ||||
|               "Name": { | ||||
|                 "description": "Optional name", | ||||
|                 "type": "string", | ||||
|                 "example": "Jane Doe" | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       }, | ||||
|       "x-go-package": "github.com/axllent/mailpit/server/apiv1" | ||||
|     }, | ||||
|     "SpamAssassinResponse": { | ||||
|       "description": "Result is a SpamAssassin result", | ||||
|       "type": "object", | ||||
| @@ -1944,107 +1952,6 @@ | ||||
|       }, | ||||
|       "x-go-name": "Result", | ||||
|       "x-go-package": "github.com/axllent/mailpit/internal/spamassassin" | ||||
|     }, | ||||
|     "Trigger": { | ||||
|       "description": "Trigger for Chaos", | ||||
|       "type": "object", | ||||
|       "required": [ | ||||
|         "ErrorCode", | ||||
|         "Probability" | ||||
|       ], | ||||
|       "properties": { | ||||
|         "ErrorCode": { | ||||
|           "description": "SMTP error code to return. The value must range from 400 to 599.", | ||||
|           "type": "integer", | ||||
|           "format": "int64", | ||||
|           "example": 451 | ||||
|         }, | ||||
|         "Probability": { | ||||
|           "description": "Probability (chance) of triggering the error. The value must range from 0 to 100.", | ||||
|           "type": "integer", | ||||
|           "format": "int64", | ||||
|           "example": 5 | ||||
|         } | ||||
|       }, | ||||
|       "x-go-package": "github.com/axllent/mailpit/internal/smtpd/chaos" | ||||
|     }, | ||||
|     "Triggers": { | ||||
|       "description": "Triggers for the Chaos configuration", | ||||
|       "type": "object", | ||||
|       "properties": { | ||||
|         "Authentication": { | ||||
|           "$ref": "#/definitions/Trigger" | ||||
|         }, | ||||
|         "Recipient": { | ||||
|           "$ref": "#/definitions/Trigger" | ||||
|         }, | ||||
|         "Sender": { | ||||
|           "$ref": "#/definitions/Trigger" | ||||
|         } | ||||
|       }, | ||||
|       "x-go-package": "github.com/axllent/mailpit/internal/smtpd/chaos" | ||||
|     }, | ||||
|     "WebUIConfiguration": { | ||||
|       "description": "Response includes global web UI settings", | ||||
|       "type": "object", | ||||
|       "properties": { | ||||
|         "ChaosEnabled": { | ||||
|           "description": "Whether Chaos support is enabled at runtime", | ||||
|           "type": "boolean" | ||||
|         }, | ||||
|         "DuplicatesIgnored": { | ||||
|           "description": "Whether messages with duplicate IDs are ignored", | ||||
|           "type": "boolean" | ||||
|         }, | ||||
|         "HideDeleteAllButton": { | ||||
|           "description": "Whether the delete button should be hidden", | ||||
|           "type": "boolean" | ||||
|         }, | ||||
|         "Label": { | ||||
|           "description": "Optional label to identify this Mailpit instance", | ||||
|           "type": "string" | ||||
|         }, | ||||
|         "MessageRelay": { | ||||
|           "description": "Message Relay information", | ||||
|           "type": "object", | ||||
|           "properties": { | ||||
|             "AllowedRecipients": { | ||||
|               "description": "Only allow relaying to these recipients (regex)", | ||||
|               "type": "string" | ||||
|             }, | ||||
|             "BlockedRecipients": { | ||||
|               "description": "Block relaying to these recipients (regex)", | ||||
|               "type": "string" | ||||
|             }, | ||||
|             "Enabled": { | ||||
|               "description": "Whether message relaying (release) is enabled", | ||||
|               "type": "boolean" | ||||
|             }, | ||||
|             "OverrideFrom": { | ||||
|               "description": "Overrides the \"From\" address for all relayed messages", | ||||
|               "type": "string" | ||||
|             }, | ||||
|             "PreserveMessageIDs": { | ||||
|               "description": "Preserve the original Message-IDs when relaying messages", | ||||
|               "type": "boolean" | ||||
|             }, | ||||
|             "ReturnPath": { | ||||
|               "description": "Enforced Return-Path (if set) for relay bounces", | ||||
|               "type": "string" | ||||
|             }, | ||||
|             "SMTPServer": { | ||||
|               "description": "The configured SMTP server address", | ||||
|               "type": "string" | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         "SpamAssassin": { | ||||
|           "description": "Whether SpamAssassin is enabled", | ||||
|           "type": "boolean" | ||||
|         } | ||||
|       }, | ||||
|       "x-go-name": "webUIConfiguration", | ||||
|       "x-go-package": "github.com/axllent/mailpit/server/apiv1" | ||||
|     } | ||||
|   }, | ||||
|   "responses": { | ||||
| @@ -2087,6 +1994,19 @@ | ||||
|         "type": "string" | ||||
|       } | ||||
|     }, | ||||
|     "JSONErrorResponse": { | ||||
|       "description": "JSON error response", | ||||
|       "schema": { | ||||
|         "type": "object", | ||||
|         "properties": { | ||||
|           "Error": { | ||||
|             "description": "Error message", | ||||
|             "type": "string", | ||||
|             "example": "invalid format" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "MessagesSummaryResponse": { | ||||
|       "description": "Summary of messages", | ||||
|       "schema": { | ||||
| @@ -2105,6 +2025,19 @@ | ||||
|         "type": "string" | ||||
|       } | ||||
|     }, | ||||
|     "SendMessageResponse": { | ||||
|       "description": "Confirmation message for HTTP send API", | ||||
|       "schema": { | ||||
|         "type": "object", | ||||
|         "properties": { | ||||
|           "ID": { | ||||
|             "description": "Database ID", | ||||
|             "type": "string", | ||||
|             "example": "iAfZVVe2UQfNSG5BAjgYwa" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "TextResponse": { | ||||
|       "description": "Plain text response", | ||||
|       "schema": { | ||||
| @@ -2114,19 +2047,63 @@ | ||||
|     "WebUIConfigurationResponse": { | ||||
|       "description": "Web UI configuration response", | ||||
|       "schema": { | ||||
|         "$ref": "#/definitions/WebUIConfiguration" | ||||
|       } | ||||
|     }, | ||||
|     "jsonErrorResponse": { | ||||
|       "description": "JSON error response", | ||||
|       "schema": { | ||||
|         "$ref": "#/definitions/JSONErrorMessage" | ||||
|       } | ||||
|     }, | ||||
|     "sendMessageResponse": { | ||||
|       "description": "Confirmation message for HTTP send API", | ||||
|       "schema": { | ||||
|         "$ref": "#/definitions/SendMessageConfirmation" | ||||
|         "type": "object", | ||||
|         "properties": { | ||||
|           "ChaosEnabled": { | ||||
|             "description": "Whether Chaos support is enabled at runtime", | ||||
|             "type": "boolean" | ||||
|           }, | ||||
|           "DuplicatesIgnored": { | ||||
|             "description": "Whether messages with duplicate IDs are ignored", | ||||
|             "type": "boolean" | ||||
|           }, | ||||
|           "HideDeleteAllButton": { | ||||
|             "description": "Whether the delete button should be hidden", | ||||
|             "type": "boolean" | ||||
|           }, | ||||
|           "Label": { | ||||
|             "description": "Optional label to identify this Mailpit instance", | ||||
|             "type": "string" | ||||
|           }, | ||||
|           "MessageRelay": { | ||||
|             "description": "Message Relay information", | ||||
|             "type": "object", | ||||
|             "properties": { | ||||
|               "AllowedRecipients": { | ||||
|                 "description": "Only allow relaying to these recipients (regex)", | ||||
|                 "type": "string" | ||||
|               }, | ||||
|               "BlockedRecipients": { | ||||
|                 "description": "Block relaying to these recipients (regex)", | ||||
|                 "type": "string" | ||||
|               }, | ||||
|               "Enabled": { | ||||
|                 "description": "Whether message relaying (release) is enabled", | ||||
|                 "type": "boolean" | ||||
|               }, | ||||
|               "OverrideFrom": { | ||||
|                 "description": "Overrides the \"From\" address for all relayed messages", | ||||
|                 "type": "string" | ||||
|               }, | ||||
|               "PreserveMessageIDs": { | ||||
|                 "description": "Preserve the original Message-IDs when relaying messages", | ||||
|                 "type": "boolean" | ||||
|               }, | ||||
|               "ReturnPath": { | ||||
|                 "description": "Enforced Return-Path (if set) for relay bounces", | ||||
|                 "type": "string" | ||||
|               }, | ||||
|               "SMTPServer": { | ||||
|                 "description": "The configured SMTP server address", | ||||
|                 "type": "string" | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           "SpamAssassin": { | ||||
|             "description": "Whether SpamAssassin is enabled", | ||||
|             "type": "boolean" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user