mirror of
https://github.com/axllent/mailpit.git
synced 2025-02-09 13:38:37 +02:00
Feature: OpenAPI / Swagger schema
Mailpit now has built-in OpenAPI / Swagger documentation, see #65
This commit is contained in:
parent
3bb9f4162a
commit
5350e2eb08
@ -4,6 +4,8 @@ Mailpit provides a simple REST API to access and delete stored messages.
|
|||||||
|
|
||||||
If the Mailpit server is set to use Basic Authentication, then API requests must use Basic Authentication too.
|
If the Mailpit server is set to use Basic Authentication, then API requests must use Basic Authentication too.
|
||||||
|
|
||||||
|
You can view the Swagger API documentation directly within Mailpit by going to `http://0.0.0.0:8025/api/v1/`.
|
||||||
|
|
||||||
The API is split into three main parts:
|
The API is split into three main parts:
|
||||||
|
|
||||||
- [Messages](Messages.md) - Listing, deleting & marking messages as read/unread.
|
- [Messages](Messages.md) - Listing, deleting & marking messages as read/unread.
|
||||||
|
@ -5,12 +5,16 @@ import { sassPlugin } from 'esbuild-sass-plugin'
|
|||||||
const doWatch = process.env.WATCH == 'true' ? true : false;
|
const doWatch = process.env.WATCH == 'true' ? true : false;
|
||||||
const doMinify = process.env.MINIFY == 'true' ? true : false;
|
const doMinify = process.env.MINIFY == 'true' ? true : false;
|
||||||
|
|
||||||
const ctx = await esbuild.context({
|
const ctx = await esbuild.context(
|
||||||
entryPoints: ["server/ui-src/app.js"],
|
{
|
||||||
|
entryPoints: [
|
||||||
|
"server/ui-src/app.js",
|
||||||
|
"server/ui-src/docs.js"
|
||||||
|
],
|
||||||
bundle: true,
|
bundle: true,
|
||||||
minify: doMinify,
|
minify: doMinify,
|
||||||
sourcemap: false,
|
sourcemap: false,
|
||||||
outfile: "server/ui/dist/app.js",
|
outdir: "server/ui/dist/",
|
||||||
plugins: [pluginVue(), sassPlugin()],
|
plugins: [pluginVue(), sassPlugin()],
|
||||||
loader: {
|
loader: {
|
||||||
".svg": "file",
|
".svg": "file",
|
||||||
@ -18,7 +22,8 @@ const ctx = await esbuild.context({
|
|||||||
".woff2": "file",
|
".woff2": "file",
|
||||||
},
|
},
|
||||||
logLevel: "info"
|
logLevel: "info"
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
if (doWatch) {
|
if (doWatch) {
|
||||||
await ctx.watch()
|
await ctx.watch()
|
||||||
|
2717
package-lock.json
generated
2717
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -14,6 +14,7 @@
|
|||||||
"bootstrap5-tags": "^1.4.41",
|
"bootstrap5-tags": "^1.4.41",
|
||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
"prismjs": "^1.29.0",
|
"prismjs": "^1.29.0",
|
||||||
|
"rapidoc": "^9.3.4",
|
||||||
"tinycon": "^0.6.8",
|
"tinycon": "^0.6.8",
|
||||||
"vue": "^3.2.13"
|
"vue": "^3.2.13"
|
||||||
},
|
},
|
||||||
|
@ -16,6 +16,34 @@ import (
|
|||||||
|
|
||||||
// GetMessages returns a paginated list of messages as JSON
|
// GetMessages returns a paginated list of messages as JSON
|
||||||
func GetMessages(w http.ResponseWriter, r *http.Request) {
|
func GetMessages(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// swagger:route GET /api/v1/messages messages GetMessages
|
||||||
|
//
|
||||||
|
// # List messages
|
||||||
|
//
|
||||||
|
// Returns messages from the mailbox ordered from newest to oldest.
|
||||||
|
//
|
||||||
|
// Produces:
|
||||||
|
// - application/json
|
||||||
|
//
|
||||||
|
// Schemes: http, https
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// + name: start
|
||||||
|
// in: query
|
||||||
|
// description: pagination offset
|
||||||
|
// required: false
|
||||||
|
// type: integer
|
||||||
|
// default: 0
|
||||||
|
// + name: limit
|
||||||
|
// in: query
|
||||||
|
// description: limit results
|
||||||
|
// required: false
|
||||||
|
// type: integer
|
||||||
|
// default: 50
|
||||||
|
//
|
||||||
|
// Responses:
|
||||||
|
// 200: MessagesSummaryResponse
|
||||||
|
// default: ErrorResponse
|
||||||
start, limit := getStartLimit(r)
|
start, limit := getStartLimit(r)
|
||||||
|
|
||||||
messages, err := storage.List(start, limit)
|
messages, err := storage.List(start, limit)
|
||||||
@ -40,11 +68,38 @@ func GetMessages(w http.ResponseWriter, r *http.Request) {
|
|||||||
_, _ = w.Write(bytes)
|
_, _ = w.Write(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search returns up to 200 of the latest messages as JSON
|
// Search returns the latest messages as JSON
|
||||||
func Search(w http.ResponseWriter, r *http.Request) {
|
func Search(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// swagger:route GET /api/v1/search messages MessagesSummary
|
||||||
|
//
|
||||||
|
// # Search messages
|
||||||
|
//
|
||||||
|
// Returns the latest messages matching a search.
|
||||||
|
//
|
||||||
|
// Produces:
|
||||||
|
// - application/json
|
||||||
|
//
|
||||||
|
// Schemes: http, https
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// + name: query
|
||||||
|
// in: query
|
||||||
|
// description: search query
|
||||||
|
// required: true
|
||||||
|
// type: string
|
||||||
|
// + name: limit
|
||||||
|
// in: query
|
||||||
|
// description: limit results
|
||||||
|
// required: false
|
||||||
|
// type: integer
|
||||||
|
// default: 50
|
||||||
|
//
|
||||||
|
// Responses:
|
||||||
|
// 200: MessagesSummaryResponse
|
||||||
|
// default: ErrorResponse
|
||||||
search := strings.TrimSpace(r.URL.Query().Get("query"))
|
search := strings.TrimSpace(r.URL.Query().Get("query"))
|
||||||
if search == "" {
|
if search == "" {
|
||||||
fourOFour(w)
|
httpError(w, "Error: no search query")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,15 +127,37 @@ func Search(w http.ResponseWriter, r *http.Request) {
|
|||||||
_, _ = w.Write(bytes)
|
_, _ = w.Write(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMessage (method: GET) returns the *data.Message as JSON
|
// GetMessage (method: GET) returns the Message as JSON
|
||||||
func GetMessage(w http.ResponseWriter, r *http.Request) {
|
func GetMessage(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// swagger:route GET /api/v1/message/{ID} message Message
|
||||||
|
//
|
||||||
|
// # Get message summary
|
||||||
|
//
|
||||||
|
// Returns the summary of a message, marking the message as read.
|
||||||
|
//
|
||||||
|
// Produces:
|
||||||
|
// - application/json
|
||||||
|
//
|
||||||
|
// Schemes: http, https
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// + name: ID
|
||||||
|
// in: path
|
||||||
|
// description: message id
|
||||||
|
// required: true
|
||||||
|
// type: string
|
||||||
|
//
|
||||||
|
// Responses:
|
||||||
|
// 200: Message
|
||||||
|
// default: ErrorResponse
|
||||||
|
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
|
|
||||||
id := vars["id"]
|
id := vars["id"]
|
||||||
|
|
||||||
msg, err := storage.GetMessage(id)
|
msg, err := storage.GetMessage(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
httpError(w, "Message not found")
|
fourOFour(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,6 +168,35 @@ func GetMessage(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// DownloadAttachment (method: GET) returns the attachment data
|
// DownloadAttachment (method: GET) returns the attachment data
|
||||||
func DownloadAttachment(w http.ResponseWriter, r *http.Request) {
|
func DownloadAttachment(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// swagger:route GET /api/v1/message/{ID}/part/{PartID} message Attachment
|
||||||
|
//
|
||||||
|
// # Get message attachment
|
||||||
|
//
|
||||||
|
// This will return the attachment part using the appropriate Content-Type.
|
||||||
|
//
|
||||||
|
// Produces:
|
||||||
|
// - application/*
|
||||||
|
// - image/*
|
||||||
|
// - text/*
|
||||||
|
//
|
||||||
|
// Schemes: http, https
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// + name: ID
|
||||||
|
// in: path
|
||||||
|
// description: message id
|
||||||
|
// required: true
|
||||||
|
// type: string
|
||||||
|
// + name: PartID
|
||||||
|
// in: path
|
||||||
|
// description: attachment part id
|
||||||
|
// required: true
|
||||||
|
// type: string
|
||||||
|
//
|
||||||
|
// Responses:
|
||||||
|
// 200: BinaryResponse
|
||||||
|
// default: ErrorResponse
|
||||||
|
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
|
|
||||||
id := vars["id"]
|
id := vars["id"]
|
||||||
@ -98,7 +204,7 @@ func DownloadAttachment(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
a, err := storage.GetAttachmentPart(id, partID)
|
a, err := storage.GetAttachmentPart(id, partID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
httpError(w, err.Error())
|
fourOFour(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fileName := a.FileName
|
fileName := a.FileName
|
||||||
@ -111,15 +217,37 @@ func DownloadAttachment(w http.ResponseWriter, r *http.Request) {
|
|||||||
_, _ = w.Write(a.Content)
|
_, _ = w.Write(a.Content)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Headers (method: GET) returns the message headers as JSON
|
// GetHeaders (method: GET) returns the message headers as JSON
|
||||||
func Headers(w http.ResponseWriter, r *http.Request) {
|
func GetHeaders(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// swagger:route GET /api/v1/message/{ID}/headers message Headers
|
||||||
|
//
|
||||||
|
// # Get message headers
|
||||||
|
//
|
||||||
|
// Returns the message headers as an array.
|
||||||
|
//
|
||||||
|
// Produces:
|
||||||
|
// - application/json
|
||||||
|
//
|
||||||
|
// Schemes: http, https
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// + name: ID
|
||||||
|
// in: path
|
||||||
|
// description: message id
|
||||||
|
// required: true
|
||||||
|
// type: string
|
||||||
|
//
|
||||||
|
// Responses:
|
||||||
|
// 200: MessageHeaders
|
||||||
|
// default: ErrorResponse
|
||||||
|
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
|
|
||||||
id := vars["id"]
|
id := vars["id"]
|
||||||
|
|
||||||
data, err := storage.GetMessageRaw(id)
|
data, err := storage.GetMessageRaw(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
httpError(w, err.Error())
|
fourOFour(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,8 +258,7 @@ func Headers(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
headers := m.Header
|
bytes, _ := json.Marshal(m.Header)
|
||||||
bytes, _ := json.Marshal(headers)
|
|
||||||
|
|
||||||
w.Header().Add("Content-Type", "application/json")
|
w.Header().Add("Content-Type", "application/json")
|
||||||
_, _ = w.Write(bytes)
|
_, _ = w.Write(bytes)
|
||||||
@ -139,6 +266,28 @@ func Headers(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// DownloadRaw (method: GET) returns the full email source as plain text
|
// DownloadRaw (method: GET) returns the full email source as plain text
|
||||||
func DownloadRaw(w http.ResponseWriter, r *http.Request) {
|
func DownloadRaw(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// swagger:route GET /api/v1/message/{ID}/raw message Raw
|
||||||
|
//
|
||||||
|
// # Get message source
|
||||||
|
//
|
||||||
|
// Returns the full email source as plain text.
|
||||||
|
//
|
||||||
|
// Produces:
|
||||||
|
// - text/plain
|
||||||
|
//
|
||||||
|
// Schemes: http, https
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// + name: ID
|
||||||
|
// in: path
|
||||||
|
// description: message id
|
||||||
|
// required: true
|
||||||
|
// type: string
|
||||||
|
//
|
||||||
|
// Responses:
|
||||||
|
// 200: TextResponse
|
||||||
|
// default: ErrorResponse
|
||||||
|
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
|
|
||||||
id := vars["id"]
|
id := vars["id"]
|
||||||
@ -147,7 +296,7 @@ func DownloadRaw(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
data, err := storage.GetMessageRaw(id)
|
data, err := storage.GetMessageRaw(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
httpError(w, err.Error())
|
fourOFour(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,8 +308,32 @@ func DownloadRaw(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DeleteMessages (method: DELETE) deletes all messages matching IDS.
|
// DeleteMessages (method: DELETE) deletes all messages matching IDS.
|
||||||
// If no IDs are provided then all messages are deleted.
|
|
||||||
func DeleteMessages(w http.ResponseWriter, r *http.Request) {
|
func DeleteMessages(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// swagger:route DELETE /api/v1/messages messages Delete
|
||||||
|
//
|
||||||
|
// # Delete messages
|
||||||
|
//
|
||||||
|
// If no IDs are provided then all messages are deleted.
|
||||||
|
//
|
||||||
|
// Consumes:
|
||||||
|
// - application/json
|
||||||
|
//
|
||||||
|
// Produces:
|
||||||
|
// - text/plain
|
||||||
|
//
|
||||||
|
// Schemes: http, https
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// + name: ids
|
||||||
|
// in: body
|
||||||
|
// description: Message ids to delete
|
||||||
|
// required: false
|
||||||
|
// type: DeleteRequest
|
||||||
|
//
|
||||||
|
// Responses:
|
||||||
|
// 200: OKResponse
|
||||||
|
// default: ErrorResponse
|
||||||
|
|
||||||
decoder := json.NewDecoder(r.Body)
|
decoder := json.NewDecoder(r.Body)
|
||||||
var data struct {
|
var data struct {
|
||||||
IDs []string
|
IDs []string
|
||||||
@ -185,7 +358,33 @@ func DeleteMessages(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetReadStatus (method: PUT) will update the status to Read/Unread for all provided IDs
|
// SetReadStatus (method: PUT) will update the status to Read/Unread for all provided IDs
|
||||||
|
// If no IDs are provided then all messages are updated.
|
||||||
func SetReadStatus(w http.ResponseWriter, r *http.Request) {
|
func SetReadStatus(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// swagger:route PUT /api/v1/messages messages SetReadStatus
|
||||||
|
//
|
||||||
|
// # Set read status
|
||||||
|
//
|
||||||
|
// If no IDs are provided then all messages are updated.
|
||||||
|
//
|
||||||
|
// Consumes:
|
||||||
|
// - application/json
|
||||||
|
//
|
||||||
|
// Produces:
|
||||||
|
// - text/plain
|
||||||
|
//
|
||||||
|
// Schemes: http, https
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// + name: ids
|
||||||
|
// in: body
|
||||||
|
// description: Message ids to update
|
||||||
|
// required: false
|
||||||
|
// type: SetReadStatusRequest
|
||||||
|
//
|
||||||
|
// Responses:
|
||||||
|
// 200: OKResponse
|
||||||
|
// default: ErrorResponse
|
||||||
|
|
||||||
decoder := json.NewDecoder(r.Body)
|
decoder := json.NewDecoder(r.Body)
|
||||||
|
|
||||||
var data struct {
|
var data struct {
|
||||||
@ -239,6 +438,31 @@ func SetReadStatus(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// SetTags (method: PUT) will set the tags for all provided IDs
|
// SetTags (method: PUT) will set the tags for all provided IDs
|
||||||
func SetTags(w http.ResponseWriter, r *http.Request) {
|
func SetTags(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// swagger:route PUT /api/v1/tags tags SetTags
|
||||||
|
//
|
||||||
|
// # Set message tags
|
||||||
|
//
|
||||||
|
// To remove all tags from a message, pass an empty tags array.
|
||||||
|
//
|
||||||
|
// Consumes:
|
||||||
|
// - application/json
|
||||||
|
//
|
||||||
|
// Produces:
|
||||||
|
// - text/plain
|
||||||
|
//
|
||||||
|
// Schemes: http, https
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// + name: ids
|
||||||
|
// in: body
|
||||||
|
// description: Message ids to update
|
||||||
|
// required: true
|
||||||
|
// type: SetTagsRequest
|
||||||
|
//
|
||||||
|
// Responses:
|
||||||
|
// 200: OKResponse
|
||||||
|
// default: ErrorResponse
|
||||||
|
|
||||||
decoder := json.NewDecoder(r.Body)
|
decoder := json.NewDecoder(r.Body)
|
||||||
|
|
||||||
var data struct {
|
var data struct {
|
||||||
|
@ -11,19 +11,41 @@ import (
|
|||||||
"github.com/axllent/mailpit/utils/updater"
|
"github.com/axllent/mailpit/utils/updater"
|
||||||
)
|
)
|
||||||
|
|
||||||
type appVersion struct {
|
// Response includes the current and latest Mailpit versions, database info, and memory usage
|
||||||
|
//
|
||||||
|
// swagger:model AppInformation
|
||||||
|
type appInformation struct {
|
||||||
|
// Current Mailpit version
|
||||||
Version string
|
Version string
|
||||||
|
// Latest Mailpit version
|
||||||
LatestVersion string
|
LatestVersion string
|
||||||
|
// Database path
|
||||||
Database string
|
Database string
|
||||||
|
// Database size in bytes
|
||||||
DatabaseSize int64
|
DatabaseSize int64
|
||||||
|
// Total number of messages in the database
|
||||||
Messages int
|
Messages int
|
||||||
|
// Current memory usage in bytes
|
||||||
Memory uint64
|
Memory uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
// AppInfo returns some basic details about the running app, and latest release.
|
// AppInfo returns some basic details about the running app, and latest release.
|
||||||
func AppInfo(w http.ResponseWriter, r *http.Request) {
|
func AppInfo(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// swagger:route GET /api/v1/info application AppInformation
|
||||||
info := appVersion{}
|
//
|
||||||
|
// # Get the application information
|
||||||
|
//
|
||||||
|
// Returns basic runtime information, message totals and latest release version.
|
||||||
|
//
|
||||||
|
// Produces:
|
||||||
|
// - application/octet-stream
|
||||||
|
//
|
||||||
|
// Schemes: http, https
|
||||||
|
//
|
||||||
|
// Responses:
|
||||||
|
// 200: InfoResponse
|
||||||
|
// default: ErrorResponse
|
||||||
|
info := appInformation{}
|
||||||
info.Version = config.Version
|
info.Version = config.Version
|
||||||
|
|
||||||
var m runtime.MemStats
|
var m runtime.MemStats
|
||||||
|
@ -1,6 +1,30 @@
|
|||||||
package apiv1
|
package apiv1
|
||||||
|
|
||||||
import "github.com/axllent/mailpit/storage"
|
import (
|
||||||
|
"github.com/axllent/mailpit/storage"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MessagesSummary is a summary of a list of messages
|
||||||
|
type MessagesSummary struct {
|
||||||
|
// Total number of messages in mailbox
|
||||||
|
Total int `json:"total"`
|
||||||
|
|
||||||
|
// Total number of unread messages in mailbox
|
||||||
|
Unread int `json:"unread"`
|
||||||
|
|
||||||
|
// Number of results returned
|
||||||
|
Count int `json:"count"`
|
||||||
|
|
||||||
|
// Pagination offset
|
||||||
|
Start int `json:"start"`
|
||||||
|
|
||||||
|
// All current tags
|
||||||
|
Tags []string `json:"tags"`
|
||||||
|
|
||||||
|
// Messages summary
|
||||||
|
// in:body
|
||||||
|
Messages []storage.MessageSummary `json:"messages"`
|
||||||
|
}
|
||||||
|
|
||||||
// The following structs & aliases are provided for easy import
|
// The following structs & aliases are provided for easy import
|
||||||
// and understanding of the JSON structure.
|
// and understanding of the JSON structure.
|
||||||
@ -8,16 +32,6 @@ import "github.com/axllent/mailpit/storage"
|
|||||||
// MessageSummary - summary of a single message
|
// MessageSummary - summary of a single message
|
||||||
type MessageSummary = storage.MessageSummary
|
type MessageSummary = storage.MessageSummary
|
||||||
|
|
||||||
// MessagesSummary - summary of a list of messages
|
|
||||||
type MessagesSummary struct {
|
|
||||||
Total int `json:"total"`
|
|
||||||
Unread int `json:"unread"`
|
|
||||||
Count int `json:"count"`
|
|
||||||
Start int `json:"start"`
|
|
||||||
Tags []string `json:"tags"`
|
|
||||||
Messages []MessageSummary `json:"messages"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Message data
|
// Message data
|
||||||
type Message = storage.Message
|
type Message = storage.Message
|
||||||
|
|
||||||
|
19
server/apiv1/swagger-config.yml
Normal file
19
server/apiv1/swagger-config.yml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
info:
|
||||||
|
description: |-
|
||||||
|
OpenAPI 2.0 documentation for [Mailpit](https://github.com/axllent/mailpit).
|
||||||
|
title: Mailpit API
|
||||||
|
contact:
|
||||||
|
name: GitHub
|
||||||
|
url: https://github.com/axllent/mailpit
|
||||||
|
license:
|
||||||
|
name: MIT license
|
||||||
|
url: https://github.com/axllent/mailpit/blob/develop/LICENSE
|
||||||
|
version: "v1"
|
||||||
|
paths: {}
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
schemes:
|
||||||
|
- http
|
||||||
|
swagger: "2.0"
|
83
server/apiv1/swagger.go
Normal file
83
server/apiv1/swagger.go
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
package apiv1
|
||||||
|
|
||||||
|
// These structs are for the purpose of defining swagger HTTP responses
|
||||||
|
|
||||||
|
// Application information
|
||||||
|
// swagger:response InfoResponse
|
||||||
|
type infoResponse struct {
|
||||||
|
// Application information
|
||||||
|
Body appInformation
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message summary
|
||||||
|
// swagger:response MessagesSummaryResponse
|
||||||
|
type messagesSummaryResponse struct {
|
||||||
|
// The message summary
|
||||||
|
// in: body
|
||||||
|
Body MessagesSummary
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message headers
|
||||||
|
// swagger:model MessageHeaders
|
||||||
|
type messageHeaders map[string][]string
|
||||||
|
|
||||||
|
// Delete request
|
||||||
|
// swagger:model DeleteRequest
|
||||||
|
type deleteRequest struct {
|
||||||
|
// ids
|
||||||
|
// in:body
|
||||||
|
IDs []string `json:"ids"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set read status request
|
||||||
|
// swagger:model SetReadStatusRequest
|
||||||
|
type setReadStatusRequest struct {
|
||||||
|
// Read status
|
||||||
|
Read bool `json:"read"`
|
||||||
|
|
||||||
|
// ids
|
||||||
|
// in:body
|
||||||
|
IDs []string `json:"ids"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set tags request
|
||||||
|
// swagger:model SetTagsRequest
|
||||||
|
type setTagsRequest struct {
|
||||||
|
// Tags
|
||||||
|
// in:body
|
||||||
|
Tags []string `json:"tags"`
|
||||||
|
|
||||||
|
// ids
|
||||||
|
// in:body
|
||||||
|
IDs []string `json:"ids"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Binary data reponse inherits the attachment's content type
|
||||||
|
// swagger:response BinaryResponse
|
||||||
|
type binaryResponse struct {
|
||||||
|
// in: body
|
||||||
|
Body string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Plain text response
|
||||||
|
// swagger:response TextResponse
|
||||||
|
type textResponse struct {
|
||||||
|
// in: body
|
||||||
|
Body string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error reponse
|
||||||
|
// swagger:response ErrorResponse
|
||||||
|
type errorResponse struct {
|
||||||
|
// The error message
|
||||||
|
// in: body
|
||||||
|
Body string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Plain text "ok" reponse
|
||||||
|
// swagger:response OKResponse
|
||||||
|
type okResponse struct {
|
||||||
|
// Default reponse
|
||||||
|
// in: body
|
||||||
|
Body string
|
||||||
|
}
|
@ -24,6 +24,33 @@ var (
|
|||||||
|
|
||||||
// Thumbnail returns a thumbnail image for an attachment (images only)
|
// Thumbnail returns a thumbnail image for an attachment (images only)
|
||||||
func Thumbnail(w http.ResponseWriter, r *http.Request) {
|
func Thumbnail(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// swagger:route GET /api/v1/message/{ID}/part/{PartID}/thumb message Thumbnail
|
||||||
|
//
|
||||||
|
// # Get an attachment image thumbnail
|
||||||
|
//
|
||||||
|
// This will return a cropped 180x120 JPEG thumbnail of an image attachment.
|
||||||
|
// If the image is smaller than 180x120 then the image is padded. If the attachment is not an image then a blank image is returned.
|
||||||
|
//
|
||||||
|
// Produces:
|
||||||
|
// - image/jpeg
|
||||||
|
//
|
||||||
|
// Schemes: http, https
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// + name: ID
|
||||||
|
// in: path
|
||||||
|
// description: message id
|
||||||
|
// required: true
|
||||||
|
// type: string
|
||||||
|
// + name: PartID
|
||||||
|
// in: path
|
||||||
|
// description: attachment part id
|
||||||
|
// required: true
|
||||||
|
// type: string
|
||||||
|
//
|
||||||
|
// Responses:
|
||||||
|
// 200: BinaryResponse
|
||||||
|
// default: ErrorResponse
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
|
|
||||||
id := vars["id"]
|
id := vars["id"]
|
||||||
|
@ -85,7 +85,7 @@ func defaultRoutes() *mux.Router {
|
|||||||
r.HandleFunc(config.Webroot+"api/v1/message/{id}/part/{partID}", middleWareFunc(apiv1.DownloadAttachment)).Methods("GET")
|
r.HandleFunc(config.Webroot+"api/v1/message/{id}/part/{partID}", middleWareFunc(apiv1.DownloadAttachment)).Methods("GET")
|
||||||
r.HandleFunc(config.Webroot+"api/v1/message/{id}/part/{partID}/thumb", middleWareFunc(apiv1.Thumbnail)).Methods("GET")
|
r.HandleFunc(config.Webroot+"api/v1/message/{id}/part/{partID}/thumb", middleWareFunc(apiv1.Thumbnail)).Methods("GET")
|
||||||
r.HandleFunc(config.Webroot+"api/v1/message/{id}/raw", middleWareFunc(apiv1.DownloadRaw)).Methods("GET")
|
r.HandleFunc(config.Webroot+"api/v1/message/{id}/raw", middleWareFunc(apiv1.DownloadRaw)).Methods("GET")
|
||||||
r.HandleFunc(config.Webroot+"api/v1/message/{id}/headers", middleWareFunc(apiv1.Headers)).Methods("GET")
|
r.HandleFunc(config.Webroot+"api/v1/message/{id}/headers", middleWareFunc(apiv1.GetHeaders)).Methods("GET")
|
||||||
r.HandleFunc(config.Webroot+"api/v1/message/{id}", middleWareFunc(apiv1.GetMessage)).Methods("GET")
|
r.HandleFunc(config.Webroot+"api/v1/message/{id}", middleWareFunc(apiv1.GetMessage)).Methods("GET")
|
||||||
r.HandleFunc(config.Webroot+"api/v1/info", middleWareFunc(apiv1.AppInfo)).Methods("GET")
|
r.HandleFunc(config.Webroot+"api/v1/info", middleWareFunc(apiv1.AppInfo)).Methods("GET")
|
||||||
|
|
||||||
|
@ -920,6 +920,12 @@ export default {
|
|||||||
</a>
|
</a>
|
||||||
|
|
||||||
<div class="row g-3">
|
<div class="row g-3">
|
||||||
|
<div class="col-12">
|
||||||
|
<a class="btn btn-primary w-100" href="api/v1/" target="_blank">
|
||||||
|
<i class="bi bi-braces"></i>
|
||||||
|
OpenAPI / Swagger API documentation
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<a class="btn btn-primary w-100" href="https://github.com/axllent/mailpit" target="_blank">
|
<a class="btn btn-primary w-100" href="https://github.com/axllent/mailpit" target="_blank">
|
||||||
<i class="bi bi-github"></i>
|
<i class="bi bi-github"></i>
|
||||||
|
1
server/ui-src/docs.js
Normal file
1
server/ui-src/docs.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
import "rapidoc";
|
28
server/ui/api/v1/index.html
Normal file
28
server/ui/api/v1/index.html
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
|
<title>Mailpit API v1 documentation</title>
|
||||||
|
<meta name="referrer" content="no-referrer">
|
||||||
|
<meta name="robots" content="noindex, nofollow, noarchive">
|
||||||
|
<link rel="icon" href="../../favicon.svg">
|
||||||
|
<script src="../../dist/docs.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<rapi-doc id="thedoc" spec-url="swagger.json" theme="light" layout="column" render-style="read" load-fonts="false"
|
||||||
|
regular-font="system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', 'Noto Sans', 'Liberation Sans', Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'"
|
||||||
|
mono-font="Courier New, Courier, System, fixed-width" font-size="large" allow-spec-url-load="false"
|
||||||
|
allow-spec-file-load="false" allow-server-selection="false" allow-search="false" allow-advanced-search="false"
|
||||||
|
bg-color="#ffffff" nav-bg-color="#e3e8ec" nav-text-color="#212529" nav-hover-bg-color="#fff"
|
||||||
|
header-color="#2c3e50" primary-color="#2c3e50" text-color="#212529">
|
||||||
|
<div slot="header">Mailpit API v1 documentation</div>
|
||||||
|
<a target='_blank' href="../../" slot="logo">
|
||||||
|
<img src="../../mailpit.svg" width="40" alt="Mailpit" />
|
||||||
|
</a>
|
||||||
|
</rapi-doc>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
820
server/ui/api/v1/swagger.json
Normal file
820
server/ui/api/v1/swagger.json
Normal file
@ -0,0 +1,820 @@
|
|||||||
|
{
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"schemes": [
|
||||||
|
"http"
|
||||||
|
],
|
||||||
|
"swagger": "2.0",
|
||||||
|
"info": {
|
||||||
|
"description": "OpenAPI 2.0 documentation for [Mailpit](https://github.com/axllent/mailpit).",
|
||||||
|
"title": "Mailpit API",
|
||||||
|
"contact": {
|
||||||
|
"name": "GitHub",
|
||||||
|
"url": "https://github.com/axllent/mailpit"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT license",
|
||||||
|
"url": "https://github.com/axllent/mailpit/blob/develop/LICENSE"
|
||||||
|
},
|
||||||
|
"version": "v1"
|
||||||
|
},
|
||||||
|
"paths": {
|
||||||
|
"/api/v1/info": {
|
||||||
|
"get": {
|
||||||
|
"description": "Returns basic runtime information, message totals and latest release version.",
|
||||||
|
"produces": [
|
||||||
|
"application/octet-stream"
|
||||||
|
],
|
||||||
|
"schemes": [
|
||||||
|
"http",
|
||||||
|
"https"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"application"
|
||||||
|
],
|
||||||
|
"summary": "Get the application information",
|
||||||
|
"operationId": "AppInformation",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"$ref": "#/responses/InfoResponse"
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"$ref": "#/responses/ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/message/{ID}": {
|
||||||
|
"get": {
|
||||||
|
"description": "Returns the summary of a message, marking the message as read.",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"schemes": [
|
||||||
|
"http",
|
||||||
|
"https"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"message"
|
||||||
|
],
|
||||||
|
"summary": "Get message summary",
|
||||||
|
"operationId": "Message",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "message id",
|
||||||
|
"name": "ID",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Message",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/Message"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"$ref": "#/responses/ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/message/{ID}/headers": {
|
||||||
|
"get": {
|
||||||
|
"description": "Returns the message headers as an array.",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"schemes": [
|
||||||
|
"http",
|
||||||
|
"https"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"message"
|
||||||
|
],
|
||||||
|
"summary": "Get message headers",
|
||||||
|
"operationId": "Headers",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "message id",
|
||||||
|
"name": "ID",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "MessageHeaders",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/MessageHeaders"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"$ref": "#/responses/ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/message/{ID}/part/{PartID}": {
|
||||||
|
"get": {
|
||||||
|
"description": "This will return the attachment part using the appropriate Content-Type.",
|
||||||
|
"produces": [
|
||||||
|
"application/*",
|
||||||
|
"image/*",
|
||||||
|
"text/*"
|
||||||
|
],
|
||||||
|
"schemes": [
|
||||||
|
"http",
|
||||||
|
"https"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"message"
|
||||||
|
],
|
||||||
|
"summary": "Get message attachment",
|
||||||
|
"operationId": "Attachment",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "message id",
|
||||||
|
"name": "ID",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "attachment part id",
|
||||||
|
"name": "PartID",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"$ref": "#/responses/BinaryResponse"
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"$ref": "#/responses/ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/message/{ID}/part/{PartID}/thumb": {
|
||||||
|
"get": {
|
||||||
|
"description": "This will return a cropped 180x120 JPEG thumbnail of an image attachment.\nIf the image is smaller than 180x120 then the image is padded. If the attachment is not an image then a blank image is returned.",
|
||||||
|
"produces": [
|
||||||
|
"image/jpeg"
|
||||||
|
],
|
||||||
|
"schemes": [
|
||||||
|
"http",
|
||||||
|
"https"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"message"
|
||||||
|
],
|
||||||
|
"summary": "Get an attachment image thumbnail",
|
||||||
|
"operationId": "Thumbnail",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "message id",
|
||||||
|
"name": "ID",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "attachment part id",
|
||||||
|
"name": "PartID",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"$ref": "#/responses/BinaryResponse"
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"$ref": "#/responses/ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/message/{ID}/raw": {
|
||||||
|
"get": {
|
||||||
|
"description": "Returns the full email source as plain text.",
|
||||||
|
"produces": [
|
||||||
|
"text/plain"
|
||||||
|
],
|
||||||
|
"schemes": [
|
||||||
|
"http",
|
||||||
|
"https"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"message"
|
||||||
|
],
|
||||||
|
"summary": "Get message source",
|
||||||
|
"operationId": "Raw",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "message id",
|
||||||
|
"name": "ID",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"$ref": "#/responses/TextResponse"
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"$ref": "#/responses/ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/messages": {
|
||||||
|
"get": {
|
||||||
|
"description": "Returns messages from the mailbox ordered from newest to oldest.",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"schemes": [
|
||||||
|
"http",
|
||||||
|
"https"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"messages"
|
||||||
|
],
|
||||||
|
"summary": "List messages",
|
||||||
|
"operationId": "GetMessages",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"default": 0,
|
||||||
|
"description": "pagination offset",
|
||||||
|
"name": "start",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"default": 50,
|
||||||
|
"description": "limit results",
|
||||||
|
"name": "limit",
|
||||||
|
"in": "query"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"$ref": "#/responses/MessagesSummaryResponse"
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"$ref": "#/responses/ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"put": {
|
||||||
|
"description": "If no IDs are provided then all messages are updated.",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"text/plain"
|
||||||
|
],
|
||||||
|
"schemes": [
|
||||||
|
"http",
|
||||||
|
"https"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"messages"
|
||||||
|
],
|
||||||
|
"summary": "Set read status",
|
||||||
|
"operationId": "SetReadStatus",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "Message ids to update",
|
||||||
|
"name": "ids",
|
||||||
|
"in": "body",
|
||||||
|
"schema": {
|
||||||
|
"description": "Message ids to update",
|
||||||
|
"type": "object",
|
||||||
|
"$ref": "#/definitions/SetReadStatusRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"$ref": "#/responses/OKResponse"
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"$ref": "#/responses/ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"description": "If no IDs are provided then all messages are deleted.",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"text/plain"
|
||||||
|
],
|
||||||
|
"schemes": [
|
||||||
|
"http",
|
||||||
|
"https"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"messages"
|
||||||
|
],
|
||||||
|
"summary": "Delete messages",
|
||||||
|
"operationId": "Delete",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "Message ids to delete",
|
||||||
|
"name": "ids",
|
||||||
|
"in": "body",
|
||||||
|
"schema": {
|
||||||
|
"description": "Message ids to delete",
|
||||||
|
"type": "object",
|
||||||
|
"$ref": "#/definitions/DeleteRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"$ref": "#/responses/OKResponse"
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"$ref": "#/responses/ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/search": {
|
||||||
|
"get": {
|
||||||
|
"description": "Returns the latest messages matching a search.",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"schemes": [
|
||||||
|
"http",
|
||||||
|
"https"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"messages"
|
||||||
|
],
|
||||||
|
"summary": "Search messages",
|
||||||
|
"operationId": "MessagesSummary",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "search query",
|
||||||
|
"name": "query",
|
||||||
|
"in": "query",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"default": 50,
|
||||||
|
"description": "limit results",
|
||||||
|
"name": "limit",
|
||||||
|
"in": "query"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"$ref": "#/responses/MessagesSummaryResponse"
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"$ref": "#/responses/ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/tags": {
|
||||||
|
"put": {
|
||||||
|
"description": "To remove all tags from a message, pass an empty tags array.",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"text/plain"
|
||||||
|
],
|
||||||
|
"schemes": [
|
||||||
|
"http",
|
||||||
|
"https"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"tags"
|
||||||
|
],
|
||||||
|
"summary": "Set message tags",
|
||||||
|
"operationId": "SetTags",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "Message ids to update",
|
||||||
|
"name": "ids",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"description": "Message ids to update",
|
||||||
|
"type": "object",
|
||||||
|
"$ref": "#/definitions/SetTagsRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"$ref": "#/responses/OKResponse"
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"$ref": "#/responses/ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"definitions": {
|
||||||
|
"Address": {
|
||||||
|
"description": "An address such as \"Barry Gibbs \u003cbg@example.com\u003e\" is represented\nas Address{Name: \"Barry Gibbs\", Address: \"bg@example.com\"}.",
|
||||||
|
"type": "object",
|
||||||
|
"title": "Address represents a single mail address.",
|
||||||
|
"properties": {
|
||||||
|
"Address": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Name": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-go-package": "net/mail"
|
||||||
|
},
|
||||||
|
"AppInformation": {
|
||||||
|
"description": "Response includes the current and latest Mailpit versions, database info, and memory usage",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"Database": {
|
||||||
|
"description": "Database path",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"DatabaseSize": {
|
||||||
|
"description": "Database size in bytes",
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
},
|
||||||
|
"LatestVersion": {
|
||||||
|
"description": "Latest Mailpit version",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Memory": {
|
||||||
|
"description": "Current memory usage in bytes",
|
||||||
|
"type": "integer",
|
||||||
|
"format": "uint64"
|
||||||
|
},
|
||||||
|
"Messages": {
|
||||||
|
"description": "Total number of messages in the database",
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
},
|
||||||
|
"Version": {
|
||||||
|
"description": "Current Mailpit version",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-go-name": "appInformation",
|
||||||
|
"x-go-package": "github.com/axllent/mailpit/server/apiv1"
|
||||||
|
},
|
||||||
|
"Attachment": {
|
||||||
|
"description": "Attachment struct for inline and attachments",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"ContentID": {
|
||||||
|
"description": "content id",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"ContentType": {
|
||||||
|
"description": "content type",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"FileName": {
|
||||||
|
"description": "file name",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"PartID": {
|
||||||
|
"description": "attachment part id",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Size": {
|
||||||
|
"description": "size in bytes",
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-go-package": "github.com/axllent/mailpit/storage"
|
||||||
|
},
|
||||||
|
"DeleteRequest": {
|
||||||
|
"description": "Delete request",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"ids": {
|
||||||
|
"description": "ids\nin:body",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"x-go-name": "IDs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-go-name": "deleteRequest",
|
||||||
|
"x-go-package": "github.com/axllent/mailpit/server/apiv1"
|
||||||
|
},
|
||||||
|
"Message": {
|
||||||
|
"description": "Message data excluding physical attachments",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"Attachments": {
|
||||||
|
"description": "Message attachments",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/Attachment"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Bcc": {
|
||||||
|
"description": "Bcc addresses",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/Address"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Cc": {
|
||||||
|
"description": "Cc addresses",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/Address"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Date": {
|
||||||
|
"description": "Message date if set, else date received",
|
||||||
|
"type": "string",
|
||||||
|
"format": "date-time"
|
||||||
|
},
|
||||||
|
"From": {
|
||||||
|
"$ref": "#/definitions/Address"
|
||||||
|
},
|
||||||
|
"HTML": {
|
||||||
|
"description": "Message body HTML",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"ID": {
|
||||||
|
"description": "Unique message database id",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Inline": {
|
||||||
|
"description": "Inline message attachments",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/Attachment"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Read": {
|
||||||
|
"description": "Read status",
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"Size": {
|
||||||
|
"description": "Message size in bytes",
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
},
|
||||||
|
"Subject": {
|
||||||
|
"description": "Message subject",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Tags": {
|
||||||
|
"description": "Message tags",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Text": {
|
||||||
|
"description": "Message body text",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"To": {
|
||||||
|
"description": "To addresses",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/Address"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-go-package": "github.com/axllent/mailpit/storage"
|
||||||
|
},
|
||||||
|
"MessageHeaders": {
|
||||||
|
"description": "Message headers",
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-go-name": "messageHeaders",
|
||||||
|
"x-go-package": "github.com/axllent/mailpit/server/apiv1"
|
||||||
|
},
|
||||||
|
"MessageSummary": {
|
||||||
|
"description": "MessageSummary struct for frontend messages",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"Attachments": {
|
||||||
|
"description": "Whether the message has any attachments",
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
},
|
||||||
|
"Bcc": {
|
||||||
|
"description": "Bcc addresses",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/Address"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Cc": {
|
||||||
|
"description": "Cc addresses",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/Address"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Created": {
|
||||||
|
"description": "Created time",
|
||||||
|
"type": "string",
|
||||||
|
"format": "date-time"
|
||||||
|
},
|
||||||
|
"From": {
|
||||||
|
"$ref": "#/definitions/Address"
|
||||||
|
},
|
||||||
|
"ID": {
|
||||||
|
"description": "Unique message database id",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Read": {
|
||||||
|
"description": "Read status",
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"Size": {
|
||||||
|
"description": "Message size in bytes (total)",
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
},
|
||||||
|
"Subject": {
|
||||||
|
"description": "Email subject",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Tags": {
|
||||||
|
"description": "Message tags",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"To": {
|
||||||
|
"description": "To address",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/Address"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-go-package": "github.com/axllent/mailpit/storage"
|
||||||
|
},
|
||||||
|
"MessagesSummary": {
|
||||||
|
"description": "MessagesSummary is a summary of a list of messages",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"count": {
|
||||||
|
"description": "Number of results returned",
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64",
|
||||||
|
"x-go-name": "Count"
|
||||||
|
},
|
||||||
|
"messages": {
|
||||||
|
"description": "Messages summary\nin:body",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/MessageSummary"
|
||||||
|
},
|
||||||
|
"x-go-name": "Messages"
|
||||||
|
},
|
||||||
|
"start": {
|
||||||
|
"description": "Pagination offset",
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64",
|
||||||
|
"x-go-name": "Start"
|
||||||
|
},
|
||||||
|
"tags": {
|
||||||
|
"description": "All current tags",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"x-go-name": "Tags"
|
||||||
|
},
|
||||||
|
"total": {
|
||||||
|
"description": "Total number of messages in mailbox",
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64",
|
||||||
|
"x-go-name": "Total"
|
||||||
|
},
|
||||||
|
"unread": {
|
||||||
|
"description": "Total number of unread messages in mailbox",
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64",
|
||||||
|
"x-go-name": "Unread"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-go-package": "github.com/axllent/mailpit/server/apiv1"
|
||||||
|
},
|
||||||
|
"SetReadStatusRequest": {
|
||||||
|
"description": "Set read status request",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"ids": {
|
||||||
|
"description": "ids\nin:body",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"x-go-name": "IDs"
|
||||||
|
},
|
||||||
|
"read": {
|
||||||
|
"description": "Read status",
|
||||||
|
"type": "boolean",
|
||||||
|
"x-go-name": "Read"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-go-name": "setReadStatusRequest",
|
||||||
|
"x-go-package": "github.com/axllent/mailpit/server/apiv1"
|
||||||
|
},
|
||||||
|
"SetTagsRequest": {
|
||||||
|
"description": "Set tags request",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"ids": {
|
||||||
|
"description": "ids\nin:body",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"x-go-name": "IDs"
|
||||||
|
},
|
||||||
|
"tags": {
|
||||||
|
"description": "Tags\nin:body",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"x-go-name": "Tags"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-go-name": "setTagsRequest",
|
||||||
|
"x-go-package": "github.com/axllent/mailpit/server/apiv1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"BinaryResponse": {
|
||||||
|
"description": "Binary data reponse inherits the attachment's content type"
|
||||||
|
},
|
||||||
|
"ErrorResponse": {
|
||||||
|
"description": "Error reponse"
|
||||||
|
},
|
||||||
|
"InfoResponse": {
|
||||||
|
"description": "Application information",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/AppInformation"
|
||||||
|
},
|
||||||
|
"headers": {
|
||||||
|
"Body": {
|
||||||
|
"description": "Application information"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"MessagesSummaryResponse": {
|
||||||
|
"description": "Message summary",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/MessagesSummary"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"OKResponse": {
|
||||||
|
"description": "Plain text \"ok\" reponse"
|
||||||
|
},
|
||||||
|
"TextResponse": {
|
||||||
|
"description": "Plain text response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,45 +7,81 @@ import (
|
|||||||
"github.com/jhillyerd/enmime"
|
"github.com/jhillyerd/enmime"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Message struct for loading messages. It does not include physical attachments.
|
// Message data excluding physical attachments
|
||||||
|
//
|
||||||
|
// swagger:model Message
|
||||||
type Message struct {
|
type Message struct {
|
||||||
|
// Unique message database id
|
||||||
ID string
|
ID string
|
||||||
|
// Read status
|
||||||
Read bool
|
Read bool
|
||||||
|
// From address
|
||||||
From *mail.Address
|
From *mail.Address
|
||||||
|
// To addresses
|
||||||
To []*mail.Address
|
To []*mail.Address
|
||||||
|
// Cc addresses
|
||||||
Cc []*mail.Address
|
Cc []*mail.Address
|
||||||
|
// Bcc addresses
|
||||||
Bcc []*mail.Address
|
Bcc []*mail.Address
|
||||||
|
// Message subject
|
||||||
Subject string
|
Subject string
|
||||||
|
// Message date if set, else date received
|
||||||
Date time.Time
|
Date time.Time
|
||||||
|
// Message tags
|
||||||
Tags []string
|
Tags []string
|
||||||
|
// Message body text
|
||||||
Text string
|
Text string
|
||||||
|
// Message body HTML
|
||||||
HTML string
|
HTML string
|
||||||
|
// Message size in bytes
|
||||||
Size int
|
Size int
|
||||||
|
// Inline message attachments
|
||||||
Inline []Attachment
|
Inline []Attachment
|
||||||
|
// Message attachments
|
||||||
Attachments []Attachment
|
Attachments []Attachment
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attachment struct for inline and attachments
|
// Attachment struct for inline and attachments
|
||||||
|
//
|
||||||
|
// swagger:model Attachment
|
||||||
type Attachment struct {
|
type Attachment struct {
|
||||||
|
// attachment part id
|
||||||
PartID string
|
PartID string
|
||||||
|
// file name
|
||||||
FileName string
|
FileName string
|
||||||
|
// content type
|
||||||
ContentType string
|
ContentType string
|
||||||
|
// content id
|
||||||
ContentID string
|
ContentID string
|
||||||
|
// size in bytes
|
||||||
Size int
|
Size int
|
||||||
}
|
}
|
||||||
|
|
||||||
// MessageSummary struct for frontend messages
|
// MessageSummary struct for frontend messages
|
||||||
|
//
|
||||||
|
// swagger:model MessageSummary
|
||||||
type MessageSummary struct {
|
type MessageSummary struct {
|
||||||
|
// Unique message database id
|
||||||
ID string
|
ID string
|
||||||
|
// Read status
|
||||||
Read bool
|
Read bool
|
||||||
|
// From address
|
||||||
From *mail.Address
|
From *mail.Address
|
||||||
|
// To address
|
||||||
To []*mail.Address
|
To []*mail.Address
|
||||||
|
// Cc addresses
|
||||||
Cc []*mail.Address
|
Cc []*mail.Address
|
||||||
|
// Bcc addresses
|
||||||
Bcc []*mail.Address
|
Bcc []*mail.Address
|
||||||
|
// Email subject
|
||||||
Subject string
|
Subject string
|
||||||
|
// Created time
|
||||||
Created time.Time
|
Created time.Time
|
||||||
|
// Message tags
|
||||||
Tags []string
|
Tags []string
|
||||||
|
// Message size in bytes (total)
|
||||||
Size int
|
Size int
|
||||||
|
// Whether the message has any attachments
|
||||||
Attachments int
|
Attachments int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user