mirror of https://github.com/requarks/wiki
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
145 lines
3.1 KiB
145 lines
3.1 KiB
import type { FastifyInstance } from 'fastify'
|
|
|
|
/**
|
|
* Placeholder sent to the client in place of the stored SMTP password. Sending it back unchanged
|
|
* leaves the stored password alone.
|
|
*/
|
|
const PASSWORD_MASK = '********'
|
|
|
|
/**
|
|
* Mail settings, stored as the `mail` key of the settings table.
|
|
*/
|
|
const MAIL_CONFIG_KEYS = [
|
|
'senderName',
|
|
'senderEmail',
|
|
'defaultBaseURL',
|
|
'host',
|
|
'port',
|
|
'name',
|
|
'secure',
|
|
'verifySSL',
|
|
'user',
|
|
'pass',
|
|
'useDKIM',
|
|
'dkimDomainName',
|
|
'dkimKeySelector',
|
|
'dkimPrivateKey'
|
|
] as const
|
|
|
|
/**
|
|
* Mail API Routes
|
|
*/
|
|
async function routes(app: FastifyInstance) {
|
|
/**
|
|
* GET MAIL CONFIG
|
|
*/
|
|
app.get(
|
|
'/config',
|
|
{
|
|
config: {
|
|
permissions: ['manage:system']
|
|
},
|
|
schema: {
|
|
summary: 'Get mail configuration',
|
|
tags: ['Mail'],
|
|
response: {
|
|
200: {
|
|
description: 'Mail configuration',
|
|
type: 'object',
|
|
$ref: 'MailConfig#'
|
|
}
|
|
}
|
|
}
|
|
},
|
|
async () => {
|
|
return {
|
|
...WIKI.config.mail,
|
|
pass: WIKI.config.mail?.pass?.length > 0 ? PASSWORD_MASK : ''
|
|
}
|
|
}
|
|
)
|
|
|
|
/**
|
|
* UPDATE MAIL CONFIG
|
|
*/
|
|
app.put<{
|
|
Body: {
|
|
senderName?: string
|
|
senderEmail?: string
|
|
defaultBaseURL?: string
|
|
host?: string
|
|
port?: number
|
|
name?: string
|
|
secure?: boolean
|
|
verifySSL?: boolean
|
|
user?: string
|
|
pass?: string
|
|
useDKIM?: boolean
|
|
dkimDomainName?: string
|
|
dkimKeySelector?: string
|
|
dkimPrivateKey?: string
|
|
}
|
|
}>(
|
|
'/config',
|
|
{
|
|
config: {
|
|
permissions: ['manage:system']
|
|
},
|
|
schema: {
|
|
summary: 'Update mail configuration',
|
|
tags: ['Mail'],
|
|
body: {
|
|
$ref: 'MailConfig#'
|
|
},
|
|
response: {
|
|
200: {
|
|
description: 'Mail configuration updated successfully',
|
|
type: 'object',
|
|
properties: {
|
|
ok: {
|
|
type: 'boolean'
|
|
},
|
|
message: {
|
|
type: 'string'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
async (req, reply) => {
|
|
const patch: Record<string, any> = {}
|
|
for (const key of MAIL_CONFIG_KEYS) {
|
|
if (req.body[key] !== undefined) {
|
|
patch[key] = req.body[key]
|
|
}
|
|
}
|
|
|
|
// -> Base URLs are used to build links in emails, always without a trailing slash
|
|
if (typeof patch.defaultBaseURL === 'string') {
|
|
patch.defaultBaseURL = patch.defaultBaseURL.replace(/\/+$/, '')
|
|
}
|
|
|
|
// -> The client only ever receives a masked password, so an unchanged one must not be stored
|
|
if (patch.pass === PASSWORD_MASK) {
|
|
delete patch.pass
|
|
}
|
|
|
|
const previousConfig = WIKI.config.mail
|
|
WIKI.config.mail = { ...previousConfig, ...patch }
|
|
|
|
if (!(await WIKI.configSvc.saveToDb(['mail']))) {
|
|
WIKI.config.mail = previousConfig
|
|
return reply.internalServerError('Failed to save mail configuration.')
|
|
}
|
|
|
|
return {
|
|
ok: true,
|
|
message: 'Mail configuration updated successfully.'
|
|
}
|
|
}
|
|
)
|
|
}
|
|
|
|
export default routes
|