v1.0.0
No files matched your search
@@ -0,0 +1,16 @@
|
||||
/node_modules
|
||||
/dist
|
||||
/build
|
||||
/.astro
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
*.local
|
||||
.*
|
||||
!.env.example
|
||||
!.gitignore
|
||||
!.nvmrc
|
||||
!.vscode/
|
||||
!.github/
|
||||
!.well-known
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"markdown.marp.html": "all"
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
Copyright (c) 2026 Stalwart Labs LLC. All rights reserved.
|
||||
|
||||
This repository and the website published from it at https://stalw.art,
|
||||
including the documentation, blog posts, marketing pages, images, diagrams,
|
||||
source code and any other material (together, the "Content"), are the
|
||||
exclusive property of Stalwart Labs LLC and are protected by copyright law.
|
||||
|
||||
No license or other right in the Content is granted except as expressly
|
||||
stated below.
|
||||
|
||||
Permitted use
|
||||
|
||||
You may, without further permission:
|
||||
|
||||
1. View and read the Content on https://stalw.art or in this repository.
|
||||
2. Make copies of the Content solely for your own personal or internal
|
||||
reference while installing, operating or evaluating Stalwart software
|
||||
obtained from Stalwart Labs LLC.
|
||||
3. Quote short excerpts of the Content in articles, forum posts, issue
|
||||
reports, support requests and similar commentary, provided the excerpt
|
||||
is attributed to Stalwart Labs LLC and accompanied by a link to the
|
||||
original page on https://stalw.art.
|
||||
|
||||
Restrictions
|
||||
|
||||
Except as permitted above, you may not, in whole or in part and by any
|
||||
means:
|
||||
|
||||
1. Copy, reproduce, republish, mirror or redistribute the Content.
|
||||
2. Modify, translate, adapt or create derivative works of the Content.
|
||||
3. Use the Content, or any work derived from it, to document, describe,
|
||||
promote or support any software other than Stalwart software obtained
|
||||
from Stalwart Labs LLC, including any fork, modified version or
|
||||
rebranded distribution of Stalwart software.
|
||||
4. Sell, sublicense or otherwise commercially exploit the Content.
|
||||
|
||||
Any other use requires the prior written permission of Stalwart Labs LLC.
|
||||
Requests can be sent to hello@stalw.art.
|
||||
|
||||
Trademarks
|
||||
|
||||
"Stalwart" and the Stalwart logo are trademarks of Stalwart Labs LLC.
|
||||
Nothing in this notice grants any right to use them.
|
||||
|
||||
Disclaimer
|
||||
|
||||
THE CONTENT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
STALWART LABS LLC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE CONTENT OR ITS USE.
|
||||
@@ -0,0 +1,71 @@
|
||||
# Stalwart Website
|
||||
|
||||
Source of [stalw.art](https://stalw.art), the official website of
|
||||
[Stalwart](https://stalw.art), the all-in-one mail and collaboration server
|
||||
developed by Stalwart Labs LLC.
|
||||
|
||||
The site includes:
|
||||
|
||||
- **Product pages**: features, editions, pricing, company information and
|
||||
legal terms.
|
||||
- **Documentation** ([stalw.art/docs](https://stalw.art/docs)): installation,
|
||||
configuration, administration and reference material for every Stalwart
|
||||
release.
|
||||
- **Blog** ([stalw.art/blog](https://stalw.art/blog)): release announcements,
|
||||
technical articles and project news.
|
||||
|
||||
## License
|
||||
|
||||
Copyright (c) 2026 Stalwart Labs LLC. All rights reserved.
|
||||
|
||||
This repository and the website published from it at https://stalw.art,
|
||||
including the documentation, blog posts, marketing pages, images, diagrams,
|
||||
source code and any other material (together, the "Content"), are the
|
||||
exclusive property of Stalwart Labs LLC and are protected by copyright law.
|
||||
|
||||
No license or other right in the Content is granted except as expressly
|
||||
stated below.
|
||||
|
||||
### Permitted use
|
||||
|
||||
You may, without further permission:
|
||||
|
||||
1. View and read the Content on https://stalw.art or in this repository.
|
||||
2. Make copies of the Content solely for your own personal or internal
|
||||
reference while installing, operating or evaluating Stalwart software
|
||||
obtained from Stalwart Labs LLC.
|
||||
3. Quote short excerpts of the Content in articles, forum posts, issue
|
||||
reports, support requests and similar commentary, provided the excerpt
|
||||
is attributed to Stalwart Labs LLC and accompanied by a link to the
|
||||
original page on https://stalw.art.
|
||||
|
||||
### Restrictions
|
||||
|
||||
Except as permitted above, you may not, in whole or in part and by any
|
||||
means:
|
||||
|
||||
1. Copy, reproduce, republish, mirror or redistribute the Content.
|
||||
2. Modify, translate, adapt or create derivative works of the Content.
|
||||
3. Use the Content, or any work derived from it, to document, describe,
|
||||
promote or support any software other than Stalwart software obtained
|
||||
from Stalwart Labs LLC, including any fork, modified version or
|
||||
rebranded distribution of Stalwart software.
|
||||
4. Sell, sublicense or otherwise commercially exploit the Content.
|
||||
|
||||
Any other use requires the prior written permission of Stalwart Labs LLC.
|
||||
Requests can be sent to hello@stalw.art.
|
||||
|
||||
### Trademarks
|
||||
|
||||
"Stalwart" and the Stalwart logo are trademarks of Stalwart Labs LLC.
|
||||
Nothing in this notice grants any right to use them.
|
||||
|
||||
### Disclaimer
|
||||
|
||||
THE CONTENT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
STALWART LABS LLC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE CONTENT OR ITS USE.
|
||||
|
||||
The full license text is also available in the [LICENSE](LICENSE) file.
|
||||
@@ -0,0 +1,186 @@
|
||||
import { defineConfig } from "astro/config";
|
||||
import sitemap from "@astrojs/sitemap";
|
||||
import starlight from "@astrojs/starlight";
|
||||
import starlightBlog from "starlight-blog";
|
||||
import starlightLinksValidator from "starlight-links-validator";
|
||||
import { visit } from "unist-util-visit";
|
||||
import remarkGemoji from "remark-gemoji";
|
||||
import { buildDocsSidebar } from "./src/lib/sidebar.mjs";
|
||||
|
||||
// Convert ```mermaid fenced code blocks into <pre class="mermaid"> nodes,
|
||||
// rendered client-side by the mermaid script injected via Starlight head.
|
||||
function remarkMermaid() {
|
||||
return (tree) => {
|
||||
visit(tree, "code", (node, index, parent) => {
|
||||
if (node.lang !== "mermaid" || !parent || index == null) return;
|
||||
parent.children[index] = {
|
||||
type: "html",
|
||||
value: `<pre class="mermaid">${node.value}</pre>`,
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export default defineConfig({
|
||||
site: "https://stalw.art",
|
||||
trailingSlash: "ignore",
|
||||
// Astro-level redirects: served in dev (`astro dev`) and built into the
|
||||
// static output too, so they work regardless of host. The Cloudflare
|
||||
// _redirects file in public/ mirrors these for SEO/external bookmarks.
|
||||
// With `trailingSlash: "ignore"` Astro normalises `/docs` and `/docs/`
|
||||
// to the same route — declaring both forms triggers a router collision
|
||||
// warning, so we list the canonical (no trailing slash) form only.
|
||||
redirects: {
|
||||
"/docs": "/docs/install/",
|
||||
"/docs/install/get-started": "/docs/install/",
|
||||
"/docs/management/tasks": "/docs/management/tasks-actions/tasks",
|
||||
"/docs/management/actions": "/docs/management/tasks-actions/actions",
|
||||
"/docs/applications": "/docs/management/applications/",
|
||||
"/docs/applications/update": "/docs/management/applications/update",
|
||||
// v1.0 documentation reorganisation (.ignore/v1/20-reorganisation.md).
|
||||
"/docs/install/performance": "/docs/performance/",
|
||||
"/docs/server/cache": "/docs/performance/caching",
|
||||
"/docs/spamfilter/llm": "/docs/spamfilter/ai/",
|
||||
"/docs/auth/principals": "/docs/auth/accounts/",
|
||||
"/docs/auth/principals/individual": "/docs/auth/accounts/user",
|
||||
"/docs/auth/principals/group": "/docs/auth/accounts/group",
|
||||
"/docs/auth/oauth/oauth-client": "/docs/auth/oauth/clients",
|
||||
"/docs/auth/oauth/client-registration": "/docs/auth/oauth/register-client",
|
||||
"/docs/auth/oauth/flows": "/docs/auth/oauth/authorization",
|
||||
"/docs/auth/oauth/interoperability": "/docs/auth/oauth/mail-clients",
|
||||
"/docs/auth/openid": "/docs/auth/oauth/openid-connect",
|
||||
"/docs/auth/openid/provider": "/docs/auth/oauth/openid-connect#signing",
|
||||
"/docs/auth/openid/id-tokens": "/docs/auth/oauth/openid-connect#id-tokens",
|
||||
"/docs/auth/openid/endpoints": "/docs/auth/oauth/endpoints",
|
||||
"/docs/http/security": "/docs/http/settings#security",
|
||||
"/docs/http/ratelimit": "/docs/http/settings#rate-limiting",
|
||||
"/docs/development/api": "/docs/http/api",
|
||||
"/docs/mta/filter/spam": "/docs/mta/filter/",
|
||||
"/docs/mta/filter/sieve": "/docs/mta/filter/",
|
||||
"/docs/mta/outbound": "/docs/mta/outbound/strategy",
|
||||
"/docs/sieve/interpreter": "/docs/sieve/#two-interpreters",
|
||||
"/docs/sieve/jmap": "/docs/sieve/user-scripts#jmap-for-sieve",
|
||||
"/docs/sieve/managesieve": "/docs/sieve/user-scripts#managesieve",
|
||||
"/docs/spamfilter/dmarc": "/docs/spamfilter/settings/scores#authentication-tags",
|
||||
"/docs/spamfilter/settings/domain_lists": "/docs/spamfilter/settings/domain-lists",
|
||||
"/docs/spamfilter/settings/mime_types": "/docs/spamfilter/settings/mime-types",
|
||||
"/docs/storage/backends/composite/sharded-blob": "/docs/storage/backends/composite#sharded-blob-store",
|
||||
"/docs/storage/backends/composite/sharded-in-memory": "/docs/storage/backends/composite#sharded-in-memory-store",
|
||||
"/docs/storage/backends/composite/sql-replica": "/docs/storage/backends/composite#sql-read-replicas",
|
||||
"/docs/storage/lookup": "/docs/configuration/expressions/lookup/",
|
||||
"/docs/storage/lookup/local": "/docs/configuration/expressions/lookup/local",
|
||||
"/docs/storage/lookup/remote": "/docs/configuration/expressions/lookup/remote",
|
||||
"/docs/cluster/deployment/topology": "/docs/cluster/configuration/roles#planning-node-roles",
|
||||
"/docs/cluster/orchestration/apache-mesos": "/docs/cluster/orchestration/",
|
||||
"/docs/telemetry/tracing/console": "/docs/telemetry/tracing/tracers#console",
|
||||
"/docs/telemetry/tracing/log": "/docs/telemetry/tracing/tracers#log-file",
|
||||
"/docs/telemetry/tracing/journal": "/docs/telemetry/tracing/tracers#journal",
|
||||
"/docs/migration/guide/configure-source/stalwart-old": "/docs/migration/guide/configure-source/previous-stalwart",
|
||||
"/docs/migration/proxy/examples/stalwart-upgrade": "/docs/migration/proxy/examples/stalwart",
|
||||
"/docs/migration/proxy/examples": "/docs/migration/proxy/#examples",
|
||||
"/docs/migration/proxy/mappings/file": "/docs/migration/proxy/mappings/#file-source",
|
||||
"/docs/migration/proxy/mappings/redis": "/docs/migration/proxy/mappings/#redis-source",
|
||||
"/docs/migration/proxy/mappings/sql": "/docs/migration/proxy/mappings/#sql-source",
|
||||
"/docs/migration/proxy/routing/pop3": "/docs/migration/proxy/routing/imap#pop3",
|
||||
"/docs/migration/proxy/routing/managesieve": "/docs/migration/proxy/routing/imap#managesieve",
|
||||
},
|
||||
server: {
|
||||
host: "127.0.0.1",
|
||||
port: 8787,
|
||||
},
|
||||
devToolbar: {
|
||||
enabled: false,
|
||||
},
|
||||
markdown: {
|
||||
shikiConfig: {
|
||||
themes: {
|
||||
light: "github-light",
|
||||
dark: "github-dark-default",
|
||||
},
|
||||
// Sieve isn't bundled with Shiki; treat it as plain text so highlighting
|
||||
// doesn't warn on every page that includes Sieve examples.
|
||||
langAlias: { sieve: "text" },
|
||||
},
|
||||
// remarkGemoji renders Docusaurus/GitHub-style :emoji: shortcodes
|
||||
// (e.g. :white_check_mark:) into the actual Unicode glyphs.
|
||||
remarkPlugins: [remarkMermaid, remarkGemoji],
|
||||
},
|
||||
integrations: [
|
||||
sitemap({
|
||||
// Exclude:
|
||||
// - Starlight tag pages (`/tags/*`)
|
||||
// - blog pagination + tag/author listings (low quality / duplicate)
|
||||
filter: (page) =>
|
||||
!/\/tags\//.test(page) &&
|
||||
!/\/blog\/(?:\d+|tags|authors)\//.test(page),
|
||||
}),
|
||||
starlight({
|
||||
title: "Stalwart",
|
||||
logo: {
|
||||
src: "./public/favicon.svg",
|
||||
alt: "Stalwart",
|
||||
replacesTitle: false,
|
||||
},
|
||||
favicon: "/favicon.svg",
|
||||
editLink: {
|
||||
baseUrl: "https://github.com/stalwartlabs/website/edit/main/",
|
||||
},
|
||||
head: [
|
||||
// GA4, og:image, twitter:image, RSS link, font preload, JSON-LD,
|
||||
// canonical, etc. all live in StarlightHead.astro now so Starlight
|
||||
// and marketing pages share one source of truth (Base.astro mirrors
|
||||
// the same set for marketing routes that don't go through Starlight).
|
||||
],
|
||||
social: [
|
||||
{ icon: "github", label: "GitHub", href: "https://github.com/stalwartlabs" },
|
||||
],
|
||||
components: {
|
||||
Head: "./src/components/StarlightHead.astro",
|
||||
Header: "./src/components/StarlightHeader.astro",
|
||||
// Note: we deliberately do NOT override Footer or PageFrame.
|
||||
// Starlight's default per-page Footer (edit on GitHub, last
|
||||
// updated, prev/next pagination) is what readers want at the
|
||||
// bottom of a docs page; the multi-column marketing footer doesn't
|
||||
// make sense inside the docs/blog layout, where the fixed sidebar
|
||||
// and TOC overlay it. The marketing footer is only on the
|
||||
// marketing pages, served by src/layouts/Base.astro.
|
||||
},
|
||||
pagefind: true,
|
||||
disable404Route: true,
|
||||
// Sidebar is generated from src/content/docs/docs at config-load time:
|
||||
// labels come from per-directory _meta.yml (label, order, collapsed)
|
||||
// and per-file Markdown frontmatter (title, sidebar.order). See
|
||||
// src/lib/sidebar.mjs.
|
||||
sidebar: buildDocsSidebar(),
|
||||
customCss: ["./src/styles/starlight-overrides.css"],
|
||||
routeMiddleware: undefined,
|
||||
pagination: true,
|
||||
lastUpdated: true,
|
||||
plugins: [
|
||||
starlightBlog({
|
||||
title: "Stalwart Blog",
|
||||
metrics: { readingTime: true, words: false },
|
||||
authors: {
|
||||
mdecimus: {
|
||||
name: "Mauro D.",
|
||||
title: "Project Maintainer",
|
||||
url: "https://github.com/mdecimus",
|
||||
picture: "/img/authors/mdecimus.png",
|
||||
},
|
||||
},
|
||||
}),
|
||||
starlightLinksValidator({
|
||||
errorOnRelativeLinks: false,
|
||||
errorOnInvalidHashes: true,
|
||||
exclude: [
|
||||
// Marketing + legal pages are served by the custom [...slug].astro
|
||||
// route and are not visible to the docs link validator.
|
||||
"/legal/**",
|
||||
"/contact",
|
||||
"http://localhost:8081",
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
});
|
||||
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"name": "stalwart-web",
|
||||
"type": "module",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"clean": "rm -rf dist .astro",
|
||||
"includes": "node ./scripts/expand-includes.mjs",
|
||||
"sievepad": "node ./scripts/sievepad-links.mjs",
|
||||
"defaults": "node ./scripts/inject-defaults.mjs",
|
||||
"predev": "npm run clean && npm run includes && npm run defaults && npm run sievepad",
|
||||
"prebuild": "npm run clean && npm run includes && npm run defaults && npm run sievepad",
|
||||
"dev": "astro dev --host 127.0.0.1 --port 8787",
|
||||
"build": "astro build",
|
||||
"preview": "astro preview --host 127.0.0.1 --port 8787",
|
||||
"check:includes": "node ./scripts/expand-includes.mjs --check",
|
||||
"check:sievepad": "node ./scripts/sievepad-links.mjs --check",
|
||||
"check:defaults": "node ./scripts/inject-defaults.mjs --check",
|
||||
"pdfs": "node ./scripts/generate-legal-pdfs.mjs",
|
||||
"slides:dev": "npm --prefix slides run dev",
|
||||
"slides:clean": "npm --prefix slides run clean",
|
||||
"slides:build": "npm --prefix slides run build",
|
||||
"slides:build:offline": "npm --prefix slides run build:offline",
|
||||
"slides:export": "npm --prefix slides run export",
|
||||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/sitemap": "^3.7.2",
|
||||
"@astrojs/starlight": "^0.38.5",
|
||||
"@fontsource-variable/inter": "^5.2.8",
|
||||
"@fontsource-variable/jetbrains-mono": "^5.2.8",
|
||||
"@fontsource-variable/plus-jakarta-sans": "^5.3.0",
|
||||
"astro": "^6.2.2",
|
||||
"astro-og-canvas": "^0.11.1",
|
||||
"lucide-static": "^1.14.0",
|
||||
"mermaid": "^11.14.0",
|
||||
"remark-gemoji": "^8.0.0",
|
||||
"sharp": "^0.34.5",
|
||||
"starlight-blog": "^0.26.1",
|
||||
"starlight-links-validator": "^0.24.0",
|
||||
"unist-util-visit": "^5.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22.12.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"pdf-lib": "^1.17.1",
|
||||
"puppeteer": "^24.43.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
# Stalwart Labs vulnerability disclosure
|
||||
# Full policy: https://stalw.art/legal/security
|
||||
# Refresh this file before the Expires date below (RFC 9116).
|
||||
|
||||
Contact: mailto:security@stalw.art
|
||||
Contact: https://github.com/stalwartlabs/stalwart/security/advisories/new
|
||||
Expires: 2027-05-03T00:00:00.000Z
|
||||
Preferred-Languages: en
|
||||
Canonical: https://stalw.art/.well-known/security.txt
|
||||
Policy: https://stalw.art/legal/security
|
||||
Acknowledgments: https://github.com/stalwartlabs/stalwart/security/advisories
|
||||
@@ -0,0 +1,37 @@
|
||||
# Cloudflare Pages headers (https://developers.cloudflare.com/pages/configuration/headers/)
|
||||
# Order matters: most specific first.
|
||||
|
||||
# Hashed Astro assets are content-addressed; safe to cache forever.
|
||||
/_astro/*
|
||||
Cache-Control: public, max-age=31536000, immutable
|
||||
|
||||
# Static assets that aren't fingerprinted: 1 hour, allow CDN to revalidate.
|
||||
/img/*
|
||||
Cache-Control: public, max-age=3600, must-revalidate
|
||||
/fonts/*
|
||||
Cache-Control: public, max-age=2592000, immutable
|
||||
/favicon.svg
|
||||
Cache-Control: public, max-age=86400
|
||||
|
||||
# llms.txt and robots.txt should be checked daily.
|
||||
/llms.txt
|
||||
Cache-Control: public, max-age=86400
|
||||
Content-Type: text/plain; charset=utf-8
|
||||
/robots.txt
|
||||
Cache-Control: public, max-age=86400
|
||||
|
||||
# Sitemap: revalidate frequently so search/LLM crawlers see fresh URLs.
|
||||
/sitemap-index.xml
|
||||
Cache-Control: public, max-age=3600
|
||||
/sitemap-*.xml
|
||||
Cache-Control: public, max-age=3600
|
||||
|
||||
# HTML pages: short browser cache, longer edge cache; Cloudflare honours
|
||||
# both via cdn-cache-control. Adjust max-age if you need fresher updates.
|
||||
/*
|
||||
X-Frame-Options: SAMEORIGIN
|
||||
X-Content-Type-Options: nosniff
|
||||
Referrer-Policy: strict-origin-when-cross-origin
|
||||
Permissions-Policy: geolocation=(), microphone=(), camera=()
|
||||
Cache-Control: public, max-age=300, must-revalidate
|
||||
CDN-Cache-Control: public, max-age=86400
|
||||
@@ -0,0 +1,92 @@
|
||||
# Cloudflare Pages redirects (https://developers.cloudflare.com/pages/configuration/redirects/)
|
||||
# Format: <source> <destination> <status>
|
||||
# 301 = permanent (default), 302 = temporary, 200 = rewrite (no client redirect).
|
||||
|
||||
# Docusaurus auto-generated category pages -> canonical landing pages.
|
||||
/docs/category/installation /docs/install/ 301
|
||||
/docs/category/sender-authentication /docs/mta/authentication/ 301
|
||||
/docs/category/development /docs/development/ 301
|
||||
/docs/category/server-settings /docs/server/ 301
|
||||
|
||||
# /docs root and the long-published /docs/install/get-started URL both
|
||||
# now point at the renamed install landing page (Welcome to Stalwart).
|
||||
/docs /docs/install/ 301
|
||||
/docs/install/get-started /docs/install/ 301
|
||||
|
||||
# Section overview pages were renamed to index.md; redirect old URLs.
|
||||
/docs/storage/overview /docs/storage/ 301
|
||||
/docs/auth/overview /docs/auth/ 301
|
||||
/docs/encryption/overview /docs/encryption/ 301
|
||||
/docs/mta/overview /docs/mta/ 301
|
||||
/docs/email/overview /docs/email/ 301
|
||||
/docs/collaboration/overview /docs/collaboration/ 301
|
||||
/docs/spamfilter/overview /docs/spamfilter/ 301
|
||||
/docs/sieve/overview /docs/sieve/ 301
|
||||
/docs/cluster/overview /docs/cluster/ 301
|
||||
/docs/telemetry/overview /docs/telemetry/ 301
|
||||
/docs/management/overview /docs/management/ 301
|
||||
/docs/configuration/overview /docs/configuration/ 301
|
||||
/docs/server/overview /docs/server/ 301
|
||||
/docs/development/overview /docs/development/ 301
|
||||
|
||||
# Tasks & Actions moved under their own subdirectory.
|
||||
/docs/management/tasks /docs/management/tasks-actions/tasks 301
|
||||
/docs/management/actions /docs/management/tasks-actions/actions 301
|
||||
|
||||
# Applications moved under Management.
|
||||
/docs/applications /docs/management/applications/ 301
|
||||
/docs/applications/update /docs/management/applications/update 301
|
||||
|
||||
# Wildcard fallback: any nested `/docs/.../overview` path now lives at
|
||||
# `/docs/.../`. Cloudflare splat matching keeps anchors and query strings.
|
||||
/docs/*/overview /docs/:splat/ 301
|
||||
/docs/*/overview/ /docs/:splat/ 301
|
||||
|
||||
# Old blog post URL shape (/blog/<slug>) is unchanged; no redirect needed.
|
||||
|
||||
# v1.0 documentation reorganisation: moved, merged and removed pages.
|
||||
/docs/install/performance /docs/performance/ 301
|
||||
/docs/server/cache /docs/performance/caching 301
|
||||
/docs/spamfilter/llm /docs/spamfilter/ai/ 301
|
||||
/docs/auth/principals /docs/auth/accounts/ 301
|
||||
/docs/auth/principals/individual /docs/auth/accounts/user 301
|
||||
/docs/auth/principals/group /docs/auth/accounts/group 301
|
||||
/docs/auth/oauth/oauth-client /docs/auth/oauth/clients 301
|
||||
/docs/auth/oauth/client-registration /docs/auth/oauth/register-client 301
|
||||
/docs/auth/oauth/flows /docs/auth/oauth/authorization 301
|
||||
/docs/auth/oauth/interoperability /docs/auth/oauth/mail-clients 301
|
||||
/docs/auth/openid /docs/auth/oauth/openid-connect 301
|
||||
/docs/auth/openid/provider /docs/auth/oauth/openid-connect#signing 301
|
||||
/docs/auth/openid/id-tokens /docs/auth/oauth/openid-connect#id-tokens 301
|
||||
/docs/auth/openid/endpoints /docs/auth/oauth/endpoints 301
|
||||
/docs/http/security /docs/http/settings#security 301
|
||||
/docs/http/ratelimit /docs/http/settings#rate-limiting 301
|
||||
/docs/development/api /docs/http/api 301
|
||||
/docs/mta/filter/spam /docs/mta/filter/ 301
|
||||
/docs/mta/filter/sieve /docs/mta/filter/ 301
|
||||
/docs/mta/outbound /docs/mta/outbound/strategy 301
|
||||
/docs/sieve/interpreter /docs/sieve/#two-interpreters 301
|
||||
/docs/sieve/jmap /docs/sieve/user-scripts#jmap-for-sieve 301
|
||||
/docs/sieve/managesieve /docs/sieve/user-scripts#managesieve 301
|
||||
/docs/spamfilter/dmarc /docs/spamfilter/settings/scores#authentication-tags 301
|
||||
/docs/spamfilter/settings/domain_lists /docs/spamfilter/settings/domain-lists 301
|
||||
/docs/spamfilter/settings/mime_types /docs/spamfilter/settings/mime-types 301
|
||||
/docs/storage/backends/composite/sharded-blob /docs/storage/backends/composite#sharded-blob-store 301
|
||||
/docs/storage/backends/composite/sharded-in-memory /docs/storage/backends/composite#sharded-in-memory-store 301
|
||||
/docs/storage/backends/composite/sql-replica /docs/storage/backends/composite#sql-read-replicas 301
|
||||
/docs/storage/lookup /docs/configuration/expressions/lookup/ 301
|
||||
/docs/storage/lookup/local /docs/configuration/expressions/lookup/local 301
|
||||
/docs/storage/lookup/remote /docs/configuration/expressions/lookup/remote 301
|
||||
/docs/cluster/deployment/topology /docs/cluster/configuration/roles#planning-node-roles 301
|
||||
/docs/cluster/orchestration/apache-mesos /docs/cluster/orchestration/ 301
|
||||
/docs/telemetry/tracing/console /docs/telemetry/tracing/tracers#console 301
|
||||
/docs/telemetry/tracing/log /docs/telemetry/tracing/tracers#log-file 301
|
||||
/docs/telemetry/tracing/journal /docs/telemetry/tracing/tracers#journal 301
|
||||
/docs/migration/guide/configure-source/stalwart-old /docs/migration/guide/configure-source/previous-stalwart 301
|
||||
/docs/migration/proxy/examples/stalwart-upgrade /docs/migration/proxy/examples/stalwart 301
|
||||
/docs/migration/proxy/examples /docs/migration/proxy/#examples 301
|
||||
/docs/migration/proxy/mappings/file /docs/migration/proxy/mappings/#file-source 301
|
||||
/docs/migration/proxy/mappings/redis /docs/migration/proxy/mappings/#redis-source 301
|
||||
/docs/migration/proxy/mappings/sql /docs/migration/proxy/mappings/#sql-source 301
|
||||
/docs/migration/proxy/routing/pop3 /docs/migration/proxy/routing/imap#pop3 301
|
||||
/docs/migration/proxy/routing/managesieve /docs/migration/proxy/routing/imap#managesieve 301
|
||||
@@ -0,0 +1,9 @@
|
||||
{"@type":"upsert","object":"Domain","matchOn":["name"],"value":{"dom-a":{"name":"example.com","description":"Primary corporate domain"},"dom-b":{"name":"example.net","description":"Secondary domain (transactional mail)"}}}
|
||||
{"@type":"upsert","object":"Account","matchOn":["name"],"value":{"grp-sales":{"@type":"Group","name":"sales","domainId":"#dom-a","description":"Sales team"},"grp-support":{"@type":"Group","name":"support","domainId":"#dom-a","description":"Customer support"}}}
|
||||
{"@type":"upsert","object":"Account","matchOn":["name"],"value":{"usr-alice":{"@type":"User","name":"alice","domainId":"#dom-a","credentials":{"0":{"@type":"Password","secret":"$argon2id$v=19$m=19456,t=2,p=1$REPLACE_WITH_REAL_SALT$REPLACE_WITH_REAL_HASH"}},"memberGroupIds":{"#grp-sales":true},"description":"Alice Example"},"usr-bob":{"@type":"User","name":"bob","domainId":"#dom-a","credentials":{"0":{"@type":"Password","secret":"$argon2id$v=19$m=19456,t=2,p=1$REPLACE_WITH_REAL_SALT$REPLACE_WITH_REAL_HASH"}},"memberGroupIds":{"#grp-support":true,"#grp-sales":true},"description":"Bob Example"},"usr-carol":{"@type":"User","name":"carol","domainId":"#dom-b","credentials":{"0":{"@type":"Password","secret":"$argon2id$v=19$m=19456,t=2,p=1$REPLACE_WITH_REAL_SALT$REPLACE_WITH_REAL_HASH"}},"memberGroupIds":{},"description":"Carol Example"}}}
|
||||
{"@type":"upsert","object":"DkimSignature","matchOn":["selector"],"value":{"dkim-a-ed25519":{"@type":"Dkim1Ed25519Sha256","canonicalization":"relaxed/relaxed","domainId":"#dom-a","privateKey":{"@type":"Text","secret":"-----BEGIN PRIVATE KEY-----\nREPLACE_WITH_REAL_ED25519_PRIVATE_KEY_BASE64\n-----END PRIVATE KEY-----\n"},"selector":"v1-ed25519-example-com"},"dkim-a-rsa":{"@type":"Dkim1RsaSha256","canonicalization":"relaxed/relaxed","domainId":"#dom-a","privateKey":{"@type":"Text","secret":"-----BEGIN RSA PRIVATE KEY-----\nREPLACE_WITH_REAL_RSA_PRIVATE_KEY_BASE64\n-----END RSA PRIVATE KEY-----\n"},"selector":"v1-rsa-example-com"},"dkim-b-ed25519":{"@type":"Dkim1Ed25519Sha256","canonicalization":"relaxed/relaxed","domainId":"#dom-b","privateKey":{"@type":"Text","secret":"-----BEGIN PRIVATE KEY-----\nREPLACE_WITH_REAL_ED25519_PRIVATE_KEY_BASE64\n-----END PRIVATE KEY-----\n"},"selector":"v1-ed25519-example-net"}}}
|
||||
{"@type":"update","object":"SystemSettings","value":{"defaultDomainId":"#dom-a","defaultHostname":"mail.example.com"}}
|
||||
{"@type":"update","object":"Enterprise","value":{"licenseKey":{"@type":"Value","secret":"REPLACE_WITH_REAL_ENTERPRISE_LICENSE_KEY"},"apiKey":{"@type":"None"}}}
|
||||
{"@type":"update","object":"BlobStore","value":{"@type":"Default"}}
|
||||
{"@type":"update","object":"InMemoryStore","value":{"@type":"Default"}}
|
||||
{"@type":"update","object":"SearchStore","value":{"@type":"Default"}}
|
||||
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 159.95 139.07" fill="#DB2D54">
|
||||
<g transform="translate(-46.07, -56.57)">
|
||||
<path d="M130.1,56.6H122l-75.9,43.8v14l75.9,43.8h8.1l75.9-43.8v-14L130.1,56.6z M185.8,107.4h-59.7V72.9L185.8,107.4z M126.1,141.9l-59.7-34.5L112.1,81v26.4v7v0.8l10.7,6.2h38.8L126.1,141.9z"/>
|
||||
<polygon points="46.1,133.1 46.1,151.7 122,195.6 130.1,195.6 206,151.7 206,133.1 126.1,179.2"/>
|
||||
<polygon points="194.8,195.6 206,189.1 206,170.4 162.5,195.6"/>
|
||||
<polygon points="46.1,189.1 57.3,195.6 89.7,195.6 46.1,170.4"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 572 B |
|
After Width: | Height: | Size: 292 KiB |
|
After Width: | Height: | Size: 220 KiB |
|
After Width: | Height: | Size: 309 KiB |
|
After Width: | Height: | Size: 434 KiB |
|
After Width: | Height: | Size: 301 KiB |
|
After Width: | Height: | Size: 352 KiB |
|
After Width: | Height: | Size: 365 KiB |
|
After Width: | Height: | Size: 285 KiB |
|
After Width: | Height: | Size: 331 KiB |
|
After Width: | Height: | Size: 291 KiB |
|
After Width: | Height: | Size: 111 KiB |
|
After Width: | Height: | Size: 126 KiB |
|
After Width: | Height: | Size: 276 KiB |
|
After Width: | Height: | Size: 253 KiB |
|
After Width: | Height: | Size: 181 KiB |
|
After Width: | Height: | Size: 219 KiB |
|
After Width: | Height: | Size: 239 KiB |
|
After Width: | Height: | Size: 196 KiB |
|
After Width: | Height: | Size: 527 KiB |
|
After Width: | Height: | Size: 545 KiB |
|
After Width: | Height: | Size: 819 KiB |
|
After Width: | Height: | Size: 815 KiB |
|
After Width: | Height: | Size: 620 KiB |
|
After Width: | Height: | Size: 623 KiB |
|
After Width: | Height: | Size: 731 KiB |
|
After Width: | Height: | Size: 731 KiB |
|
After Width: | Height: | Size: 686 KiB |
|
After Width: | Height: | Size: 773 KiB |
|
After Width: | Height: | Size: 564 KiB |
|
After Width: | Height: | Size: 687 KiB |
|
After Width: | Height: | Size: 655 KiB |
|
After Width: | Height: | Size: 557 KiB |
|
After Width: | Height: | Size: 658 KiB |
|
After Width: | Height: | Size: 759 KiB |
|
After Width: | Height: | Size: 456 KiB |
|
After Width: | Height: | Size: 660 KiB |
|
After Width: | Height: | Size: 733 KiB |
|
After Width: | Height: | Size: 533 KiB |
|
After Width: | Height: | Size: 292 KiB |
|
After Width: | Height: | Size: 220 KiB |
|
After Width: | Height: | Size: 309 KiB |
|
After Width: | Height: | Size: 545 KiB |
|
After Width: | Height: | Size: 815 KiB |
|
After Width: | Height: | Size: 819 KiB |
|
After Width: | Height: | Size: 620 KiB |
|
After Width: | Height: | Size: 623 KiB |
|
After Width: | Height: | Size: 731 KiB |
|
After Width: | Height: | Size: 301 KiB |
|
After Width: | Height: | Size: 686 KiB |
|
After Width: | Height: | Size: 773 KiB |
|
After Width: | Height: | Size: 564 KiB |
|
After Width: | Height: | Size: 352 KiB |
|
After Width: | Height: | Size: 655 KiB |
|
After Width: | Height: | Size: 365 KiB |
|
After Width: | Height: | Size: 557 KiB |
|
After Width: | Height: | Size: 285 KiB |
|
After Width: | Height: | Size: 658 KiB |
|
After Width: | Height: | Size: 759 KiB |
|
After Width: | Height: | Size: 456 KiB |
|
After Width: | Height: | Size: 331 KiB |
|
After Width: | Height: | Size: 660 KiB |
|
After Width: | Height: | Size: 733 KiB |
|
After Width: | Height: | Size: 291 KiB |
|
After Width: | Height: | Size: 527 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 102 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 181 KiB |
|
After Width: | Height: | Size: 201 KiB |
|
After Width: | Height: | Size: 446 KiB |
|
After Width: | Height: | Size: 812 B |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 2.5 MiB |
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "Stalwart Labs LLC",
|
||||
"short_name": "Stalwart",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/android-chrome-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"theme_color": "#fff",
|
||||
"background_color": "#fff",
|
||||
"display": "standalone"
|
||||
}
|
||||
|
After Width: | Height: | Size: 45 KiB |