chore: rename JMAP Webmail to Bulwark Webmail and update all URLs
This commit is contained in:
+3
-3
@@ -1,4 +1,4 @@
|
|||||||
# JMAP Webmail — Production Configuration
|
# Bulwark Webmail — Production Configuration
|
||||||
# Copy this file to .env.local and fill in your values.
|
# Copy this file to .env.local and fill in your values.
|
||||||
# For development with the built-in mock server, see .env.dev.example instead.
|
# For development with the built-in mock server, see .env.dev.example instead.
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
||||||
# App name displayed in the UI
|
# App name displayed in the UI
|
||||||
APP_NAME=JMAP Webmail
|
APP_NAME=Bulwark Webmail
|
||||||
|
|
||||||
# URL of your JMAP-compatible mail server (required)
|
# URL of your JMAP-compatible mail server (required)
|
||||||
JMAP_SERVER_URL=https://your-jmap-server.com
|
JMAP_SERVER_URL=https://your-jmap-server.com
|
||||||
@@ -94,5 +94,5 @@ JMAP_SERVER_URL=https://your-jmap-server.com
|
|||||||
# These are baked into the bundle at build time. The runtime variables above
|
# These are baked into the bundle at build time. The runtime variables above
|
||||||
# take priority when both are set.
|
# take priority when both are set.
|
||||||
#
|
#
|
||||||
# NEXT_PUBLIC_APP_NAME=JMAP Webmail
|
# NEXT_PUBLIC_APP_NAME=Bulwark Webmail
|
||||||
# NEXT_PUBLIC_JMAP_SERVER_URL=https://your-jmap-server.com
|
# NEXT_PUBLIC_JMAP_SERVER_URL=https://your-jmap-server.com
|
||||||
|
|||||||
+6
-6
@@ -1,6 +1,6 @@
|
|||||||
# Contributing to JMAP Webmail
|
# Contributing to Bulwark Webmail
|
||||||
|
|
||||||
Thank you for your interest in contributing to JMAP Webmail! This document provides guidelines and information for contributors.
|
Thank you for your interest in contributing to Bulwark Webmail! This document provides guidelines and information for contributors.
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
@@ -8,8 +8,8 @@ Thank you for your interest in contributing to JMAP Webmail! This document provi
|
|||||||
|
|
||||||
1. **Fork and clone** the repository:
|
1. **Fork and clone** the repository:
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/root-fr/jmap-webmail.git
|
git clone https://github.com/bulwarkmail/webmail.git
|
||||||
cd jmap-webmail
|
cd webmail
|
||||||
```
|
```
|
||||||
|
|
||||||
2. **Install dependencies**:
|
2. **Install dependencies**:
|
||||||
@@ -156,7 +156,7 @@ docs: update README with keyboard shortcuts
|
|||||||
## Project Structure
|
## Project Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
jmap-webmail/
|
webmail/
|
||||||
├── app/ # Next.js App Router pages
|
├── app/ # Next.js App Router pages
|
||||||
│ └── [locale]/ # Locale-aware routing
|
│ └── [locale]/ # Locale-aware routing
|
||||||
├── components/ # React components
|
├── components/ # React components
|
||||||
@@ -187,4 +187,4 @@ If you have questions about contributing, feel free to:
|
|||||||
- Open an issue for discussion
|
- Open an issue for discussion
|
||||||
- Check existing issues and pull requests
|
- Check existing issues and pull requests
|
||||||
|
|
||||||
Thank you for helping improve JMAP Webmail!
|
Thank you for helping improve Bulwark Webmail!
|
||||||
|
|||||||
+3
-3
@@ -8,10 +8,10 @@ RUN npx next build --webpack
|
|||||||
|
|
||||||
FROM node:24-alpine AS runner
|
FROM node:24-alpine AS runner
|
||||||
|
|
||||||
LABEL org.opencontainers.image.title="JMAP Webmail"
|
LABEL org.opencontainers.image.title="Bulwark Webmail"
|
||||||
LABEL org.opencontainers.image.description="Modern webmail client built with Next.js and the JMAP protocol"
|
LABEL org.opencontainers.image.description="Modern webmail client built with Next.js and the JMAP protocol"
|
||||||
LABEL org.opencontainers.image.source="https://github.com/root-fr/jmap-webmail"
|
LABEL org.opencontainers.image.source="https://github.com/bulwarkmail/webmail"
|
||||||
LABEL org.opencontainers.image.url="https://github.com/root-fr/jmap-webmail"
|
LABEL org.opencontainers.image.url="https://github.com/bulwarkmail/webmail"
|
||||||
LABEL org.opencontainers.image.licenses="MIT"
|
LABEL org.opencontainers.image.licenses="MIT"
|
||||||
LABEL org.opencontainers.image.vendor="root.cloud"
|
LABEL org.opencontainers.image.vendor="root.cloud"
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# JMAP Webmail
|
# Bulwark Webmail
|
||||||
|
|
||||||
A webmail client for [Stalwart Mail Server](https://stalw.art/), built with Next.js and the JMAP protocol.
|
A webmail client for [Stalwart Mail Server](https://stalw.art/), built with Next.js and the JMAP protocol.
|
||||||
|
|
||||||
@@ -126,7 +126,7 @@ Stalwart is a mail server written in Rust with native JMAP support, not IMAP/SMT
|
|||||||
|
|
||||||
### Deployment
|
### Deployment
|
||||||
|
|
||||||
- Pre-built Docker images on [Docker Hub](https://hub.docker.com/r/rootfr/jmap-webmail) and [GHCR](https://ghcr.io/root-fr/jmap-webmail) (amd64/arm64)
|
- Pre-built Docker images on [Docker Hub](https://hub.docker.com/r/bulwarkmail/webmail) and [GHCR](https://ghcr.io/bulwarkmail/webmail) (amd64/arm64)
|
||||||
- Multi-stage build with standalone output
|
- Multi-stage build with standalone output
|
||||||
- Runtime environment variables (no rebuild needed)
|
- Runtime environment variables (no rebuild needed)
|
||||||
- Health check endpoint
|
- Health check endpoint
|
||||||
@@ -153,8 +153,8 @@ Stalwart is a mail server written in Rust with native JMAP support, not IMAP/SMT
|
|||||||
### Installation
|
### Installation
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/root-fr/jmap-webmail.git
|
git clone https://github.com/bulwarkmail/webmail.git
|
||||||
cd jmap-webmail
|
cd webmail
|
||||||
npm install
|
npm install
|
||||||
cp .env.example .env.local
|
cp .env.example .env.local
|
||||||
```
|
```
|
||||||
@@ -215,10 +215,10 @@ npm start
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Pre-built image
|
# Pre-built image
|
||||||
docker run -p 3000:3000 -e JMAP_SERVER_URL=https://mail.example.com rootfr/jmap-webmail:latest
|
docker run -p 3000:3000 -e JMAP_SERVER_URL=https://mail.example.com bulwarkmail/webmail:latest
|
||||||
|
|
||||||
# From GHCR
|
# From GHCR
|
||||||
docker run -p 3000:3000 -e JMAP_SERVER_URL=https://mail.example.com ghcr.io/root-fr/jmap-webmail:latest
|
docker run -p 3000:3000 -e JMAP_SERVER_URL=https://mail.example.com ghcr.io/bulwarkmail/webmail:latest
|
||||||
|
|
||||||
# With docker compose
|
# With docker compose
|
||||||
cp .env.example .env.local
|
cp .env.example .env.local
|
||||||
@@ -226,8 +226,8 @@ cp .env.example .env.local
|
|||||||
docker compose up -d
|
docker compose up -d
|
||||||
|
|
||||||
# Build from source
|
# Build from source
|
||||||
docker build -t jmap-webmail .
|
docker build -t bulwark-webmail .
|
||||||
docker run -p 3000:3000 -e JMAP_SERVER_URL=https://mail.example.com jmap-webmail
|
docker run -p 3000:3000 -e JMAP_SERVER_URL=https://mail.example.com bulwark-webmail
|
||||||
```
|
```
|
||||||
|
|
||||||
## Keyboard shortcuts
|
## Keyboard shortcuts
|
||||||
|
|||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
# JMAP Webmail - Roadmap
|
# Bulwark Webmail - Roadmap
|
||||||
|
|
||||||
This document tracks the development status and planned features for JMAP Webmail.
|
This document tracks the development status and planned features for Bulwark Webmail.
|
||||||
|
|
||||||
## Completed Features
|
## Completed Features
|
||||||
|
|
||||||
@@ -230,7 +230,7 @@ This document tracks the development status and planned features for JMAP Webmai
|
|||||||
- [x] Health check endpoint
|
- [x] Health check endpoint
|
||||||
- [x] Docker support (multi-stage build, docker-compose, standalone output)
|
- [x] Docker support (multi-stage build, docker-compose, standalone output)
|
||||||
- [x] Structured server-side logger (text/JSON format, configurable level)
|
- [x] Structured server-side logger (text/JSON format, configurable level)
|
||||||
- [x] Pre-built Docker image on [Docker Hub](https://hub.docker.com/r/rootfr/jmap-webmail) and [GHCR](https://ghcr.io/root-fr/jmap-webmail) with multi-arch support (amd64/arm64)
|
- [x] Pre-built Docker image on [Docker Hub](https://hub.docker.com/r/bulwarkmail/webmail) and [GHCR](https://ghcr.io/bulwarkmail/webmail) with multi-arch support (amd64/arm64)
|
||||||
- [x] GitHub Actions CI/CD for automated image publishing on releases
|
- [x] GitHub Actions CI/CD for automated image publishing on releases
|
||||||
- [x] CVE remediation: remove npm from production image, upgrade Alpine packages
|
- [x] CVE remediation: remove npm from production image, upgrade Alpine packages
|
||||||
- [x] Server-side update check (logs newer version availability on startup)
|
- [x] Server-side update check (logs newer version availability on startup)
|
||||||
|
|||||||
@@ -108,14 +108,14 @@ const emails: MockEmail[] = [
|
|||||||
id: 'email-001', threadId: 'thread-001', mailboxIds: { 'mb-inbox': true }, keywords: {}, size: 4200, receivedAt: daysAgo(0),
|
id: 'email-001', threadId: 'thread-001', mailboxIds: { 'mb-inbox': true }, keywords: {}, size: 4200, receivedAt: daysAgo(0),
|
||||||
from: [{ name: 'Sophie Müller', email: 'sophie@eurotech.example' }],
|
from: [{ name: 'Sophie Müller', email: 'sophie@eurotech.example' }],
|
||||||
to: [{ name: 'Dev User', email: 'dev@localhost' }], cc: [],
|
to: [{ name: 'Dev User', email: 'dev@localhost' }], cc: [],
|
||||||
subject: 'Willkommen bei JMAP Webmail!',
|
subject: 'Willkommen bei Bulwark Webmail!',
|
||||||
preview: 'Hallo! This is a sample email to help you get started with the JMAP Webmail development environment.',
|
preview: 'Hallo! This is a sample email to help you get started with the Bulwark Webmail development environment.',
|
||||||
hasAttachment: false,
|
hasAttachment: false,
|
||||||
textBody: [{ partId: 'p1', blobId: 'blob-001', size: 280, type: 'text/plain' }],
|
textBody: [{ partId: 'p1', blobId: 'blob-001', size: 280, type: 'text/plain' }],
|
||||||
htmlBody: [{ partId: 'p2', blobId: 'blob-002', size: 420, type: 'text/html' }],
|
htmlBody: [{ partId: 'p2', blobId: 'blob-002', size: 420, type: 'text/html' }],
|
||||||
bodyValues: {
|
bodyValues: {
|
||||||
p1: { value: 'Hallo!\n\nThis is a sample email to help you get started with the JMAP Webmail development environment.\n\nFeel free to explore the UI — all data here is mock data.\n\nBeste Grüße,\nSophie' },
|
p1: { value: 'Hallo!\n\nThis is a sample email to help you get started with the Bulwark Webmail development environment.\n\nFeel free to explore the UI — all data here is mock data.\n\nBeste Grüße,\nSophie' },
|
||||||
p2: { value: '<p>Hallo!</p><p>This is a sample email to help you get started with the <strong>JMAP Webmail</strong> development environment.</p><p>Feel free to explore the UI — all data here is mock data.</p><p>Beste Grüße,<br>Sophie</p>' },
|
p2: { value: '<p>Hallo!</p><p>This is a sample email to help you get started with the <strong>Bulwark Webmail</strong> development environment.</p><p>Feel free to explore the UI — all data here is mock data.</p><p>Beste Grüße,<br>Sophie</p>' },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -154,7 +154,7 @@ const emails: MockEmail[] = [
|
|||||||
id: 'email-004', threadId: 'thread-004', mailboxIds: { 'mb-inbox': true }, keywords: { '$label:red': true }, size: 6200, receivedAt: daysAgo(0),
|
id: 'email-004', threadId: 'thread-004', mailboxIds: { 'mb-inbox': true }, keywords: { '$label:red': true }, size: 6200, receivedAt: daysAgo(0),
|
||||||
from: [{ name: 'GitHub Notifications', email: 'notifications@github.com' }],
|
from: [{ name: 'GitHub Notifications', email: 'notifications@github.com' }],
|
||||||
to: [{ name: 'Dev User', email: 'dev@localhost' }], cc: [],
|
to: [{ name: 'Dev User', email: 'dev@localhost' }], cc: [],
|
||||||
subject: '[jmap-webmail] New issue: Add dark mode toggle (#42)',
|
subject: '[bulwark-webmail] New issue: Add dark mode toggle (#42)',
|
||||||
preview: 'A new issue has been opened by @contributor. It would be great to have a dark mode toggle in the settings panel.',
|
preview: 'A new issue has been opened by @contributor. It would be great to have a dark mode toggle in the settings panel.',
|
||||||
hasAttachment: false,
|
hasAttachment: false,
|
||||||
textBody: [{ partId: 'p1', blobId: 'blob-007', size: 350, type: 'text/plain' }],
|
textBody: [{ partId: 'p1', blobId: 'blob-007', size: 350, type: 'text/plain' }],
|
||||||
@@ -236,8 +236,8 @@ const emails: MockEmail[] = [
|
|||||||
textBody: [{ partId: 'p1', blobId: 'blob-034', size: 380, type: 'text/plain' }],
|
textBody: [{ partId: 'p1', blobId: 'blob-034', size: 380, type: 'text/plain' }],
|
||||||
htmlBody: [{ partId: 'p2', blobId: 'blob-035', size: 520, type: 'text/html' }],
|
htmlBody: [{ partId: 'p2', blobId: 'blob-035', size: 520, type: 'text/html' }],
|
||||||
bodyValues: {
|
bodyValues: {
|
||||||
p1: { value: 'Salut,\n\nI just pushed the contact vCard import feature (JMAP-342). Could you review when you get a chance?\n\nPR: https://github.example/jmap-webmail/pull/342\n\nKey changes:\n- New vCard parser with v3/v4 support\n- Batch import with progress indicator\n- Duplicate detection and merge UI\n- Unit tests for edge cases\n\nMerci d\'avance,\nÉlise' },
|
p1: { value: 'Salut,\n\nI just pushed the contact vCard import feature (JMAP-342). Could you review when you get a chance?\n\nPR: https://github.example/bulwark-webmail/pull/342\n\nKey changes:\n- New vCard parser with v3/v4 support\n- Batch import with progress indicator\n- Duplicate detection and merge UI\n- Unit tests for edge cases\n\nMerci d\'avance,\nÉlise' },
|
||||||
p2: { value: '<p>Salut,</p><p>I just pushed the contact vCard import feature (<code>JMAP-342</code>). Could you review when you get a chance?</p><p>PR: <a href="#">jmap-webmail/pull/342</a></p><h4>Key changes:</h4><ul><li>New vCard parser with v3/v4 support</li><li>Batch import with progress indicator</li><li>Duplicate detection and merge UI</li><li>Unit tests for edge cases</li></ul><p>Merci d\'avance,<br>Élise</p>' },
|
p2: { value: '<p>Salut,</p><p>I just pushed the contact vCard import feature (<code>JMAP-342</code>). Could you review when you get a chance?</p><p>PR: <a href="#">bulwark-webmail/pull/342</a></p><h4>Key changes:</h4><ul><li>New vCard parser with v3/v4 support</li><li>Batch import with progress indicator</li><li>Duplicate detection and merge UI</li><li>Unit tests for edge cases</li></ul><p>Merci d\'avance,<br>Élise</p>' },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -407,7 +407,7 @@ const emails: MockEmail[] = [
|
|||||||
textBody: [{ partId: 'p1', blobId: 'blob-063', size: 350, type: 'text/plain' }],
|
textBody: [{ partId: 'p1', blobId: 'blob-063', size: 350, type: 'text/plain' }],
|
||||||
htmlBody: [],
|
htmlBody: [],
|
||||||
bodyValues: {
|
bodyValues: {
|
||||||
p1: { value: '¡Hola!\n\nThe new brand guidelines are finalized. Key updates:\n\n- Primary color shifted to #7c3aed (from #6366f1)\n- New typography scale (Inter for body, Cal Sans for headings)\n- Updated icon set (Lucide → custom icon font)\n- Dark mode color tokens added\n\nI\'ve also updated the Figma component library. Link: figma.example/jmap-webmail-v2\n\nBrand guidelines PDF attached.\n\nMaría' },
|
p1: { value: '¡Hola!\n\nThe new brand guidelines are finalized. Key updates:\n\n- Primary color shifted to #7c3aed (from #6366f1)\n- New typography scale (Inter for body, Cal Sans for headings)\n- Updated icon set (Lucide → custom icon font)\n- Dark mode color tokens added\n\nI\'ve also updated the Figma component library. Link: figma.example/bulwark-webmail-v2\n\nBrand guidelines PDF attached.\n\nMaría' },
|
||||||
},
|
},
|
||||||
attachments: [
|
attachments: [
|
||||||
{ partId: 'att10', blobId: 'blob-att-010', size: 3200000, name: 'Markenrichtlinien-v2.pdf', type: 'application/pdf' },
|
{ partId: 'att10', blobId: 'blob-att-010', size: 3200000, name: 'Markenrichtlinien-v2.pdf', type: 'application/pdf' },
|
||||||
@@ -430,14 +430,14 @@ const emails: MockEmail[] = [
|
|||||||
id: 'email-039', threadId: 'thread-034', mailboxIds: { 'mb-inbox': true }, keywords: {}, size: 3400, receivedAt: hoursAgo(0.25),
|
id: 'email-039', threadId: 'thread-034', mailboxIds: { 'mb-inbox': true }, keywords: {}, size: 3400, receivedAt: hoursAgo(0.25),
|
||||||
from: [{ name: 'CI/CD Pipeline', email: 'ci@github.example' }],
|
from: [{ name: 'CI/CD Pipeline', email: 'ci@github.example' }],
|
||||||
to: [{ name: 'Dev User', email: 'dev@localhost' }], cc: [],
|
to: [{ name: 'Dev User', email: 'dev@localhost' }], cc: [],
|
||||||
subject: '❌ Build failed: main — jmap-webmail #1337',
|
subject: '❌ Build failed: main — bulwark-webmail #1337',
|
||||||
preview: 'Build #1337 on branch main failed. 2 test(s) failed in email-sanitization.test.ts.',
|
preview: 'Build #1337 on branch main failed. 2 test(s) failed in email-sanitization.test.ts.',
|
||||||
hasAttachment: false,
|
hasAttachment: false,
|
||||||
textBody: [{ partId: 'p1', blobId: 'blob-060', size: 450, type: 'text/plain' }],
|
textBody: [{ partId: 'p1', blobId: 'blob-060', size: 450, type: 'text/plain' }],
|
||||||
htmlBody: [{ partId: 'p2', blobId: 'blob-061', size: 600, type: 'text/html' }],
|
htmlBody: [{ partId: 'p2', blobId: 'blob-061', size: 600, type: 'text/html' }],
|
||||||
bodyValues: {
|
bodyValues: {
|
||||||
p1: { value: '❌ Build #1337 FAILED\n\nRepository: jmap-webmail\nBranch: main\nCommit: a3f9c21 "fix: sanitize CSS in email body"\nTriggered by: @elise-moreau\n\nFailed tests:\n ✗ email-sanitization.test.ts > should strip javascript: URLs\n ✗ email-sanitization.test.ts > should handle nested style tags\n\nPassed: 247 | Failed: 2 | Skipped: 0\nDuration: 42.0s\n\nView full logs: https://github.example/jmap-webmail/actions/runs/1337' },
|
p1: { value: '❌ Build #1337 FAILED\n\nRepository: bulwark-webmail\nBranch: main\nCommit: a3f9c21 "fix: sanitize CSS in email body"\nTriggered by: @elise-moreau\n\nFailed tests:\n ✗ email-sanitization.test.ts > should strip javascript: URLs\n ✗ email-sanitization.test.ts > should handle nested style tags\n\nPassed: 247 | Failed: 2 | Skipped: 0\nDuration: 42.0s\n\nView full logs: https://github.example/bulwark-webmail/actions/runs/1337' },
|
||||||
p2: { value: '<h3>❌ Build #1337 FAILED</h3><table><tr><td>Repository</td><td>jmap-webmail</td></tr><tr><td>Branch</td><td><code>main</code></td></tr><tr><td>Commit</td><td><code>a3f9c21</code> "fix: sanitize CSS in email body"</td></tr></table><h4>Failed tests:</h4><ul><li>❌ <code>email-sanitization.test.ts</code> > should strip javascript: URLs</li><li>❌ <code>email-sanitization.test.ts</code> > should handle nested style tags</li></ul><p><strong>Passed: 247</strong> | <strong style="color:red">Failed: 2</strong> | Skipped: 0</p>' },
|
p2: { value: '<h3>❌ Build #1337 FAILED</h3><table><tr><td>Repository</td><td>bulwark-webmail</td></tr><tr><td>Branch</td><td><code>main</code></td></tr><tr><td>Commit</td><td><code>a3f9c21</code> "fix: sanitize CSS in email body"</td></tr></table><h4>Failed tests:</h4><ul><li>❌ <code>email-sanitization.test.ts</code> > should strip javascript: URLs</li><li>❌ <code>email-sanitization.test.ts</code> > should handle nested style tags</li></ul><p><strong>Passed: 247</strong> | <strong style="color:red">Failed: 2</strong> | Skipped: 0</p>' },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// =====================================================================
|
// =====================================================================
|
||||||
@@ -729,8 +729,8 @@ const IDENTITIES = [
|
|||||||
email: 'dev@localhost',
|
email: 'dev@localhost',
|
||||||
replyTo: null,
|
replyTo: null,
|
||||||
bcc: null,
|
bcc: null,
|
||||||
textSignature: '-- \nDev User\nJMAP Webmail Developer',
|
textSignature: '-- \nDev User\nBulwark Webmail Developer',
|
||||||
htmlSignature: '<p>--<br>Dev User<br><em>JMAP Webmail Developer</em></p>',
|
htmlSignature: '<p>--<br>Dev User<br><em>Bulwark Webmail Developer</em></p>',
|
||||||
mayDelete: false,
|
mayDelete: false,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
+1
-1
@@ -15,7 +15,7 @@ const geistMono = Geist_Mono({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "JMAP Webmail",
|
title: "Bulwark Webmail",
|
||||||
description: "Minimalist webmail client using JMAP protocol",
|
description: "Minimalist webmail client using JMAP protocol",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
services:
|
services:
|
||||||
webmail:
|
webmail:
|
||||||
image: ghcr.io/rathlinus/jmap-webmail:latest
|
image: ghcr.io/bulwarkmail/webmail:latest
|
||||||
ports:
|
ports:
|
||||||
- "3000:3000"
|
- "3000:3000"
|
||||||
env_file:
|
env_file:
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { readFileSync } from "fs";
|
import { readFileSync } from "fs";
|
||||||
|
|
||||||
const VERSION_CHECK_URL =
|
const VERSION_CHECK_URL =
|
||||||
"https://raw.githubusercontent.com/root-fr/jmap-webmail/main/VERSION";
|
"https://raw.githubusercontent.com/bulwarkmail/webmail/main/VERSION";
|
||||||
|
|
||||||
const SEMVER_RE = /^\d+\.\d+\.\d+$/;
|
const SEMVER_RE = /^\d+\.\d+\.\d+$/;
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ const pkg = JSON.parse(
|
|||||||
readFileSync(`${process.cwd()}/package.json`, "utf-8")
|
readFileSync(`${process.cwd()}/package.json`, "utf-8")
|
||||||
);
|
);
|
||||||
const current: string = pkg.version ?? "0.0.0";
|
const current: string = pkg.version ?? "0.0.0";
|
||||||
console.info(`JMAP Webmail v${current}`);
|
console.info(`Bulwark Webmail v${current}`);
|
||||||
|
|
||||||
if (process.env.NODE_ENV === "production") {
|
if (process.env.NODE_ENV === "production") {
|
||||||
fetch(VERSION_CHECK_URL, {
|
fetch(VERSION_CHECK_URL, {
|
||||||
@@ -36,7 +36,7 @@ if (process.env.NODE_ENV === "production") {
|
|||||||
if (!SEMVER_RE.test(remote)) return;
|
if (!SEMVER_RE.test(remote)) return;
|
||||||
if (compareVersions(current, remote) > 0) {
|
if (compareVersions(current, remote) > 0) {
|
||||||
console.info(
|
console.info(
|
||||||
`Update available: v${remote} — https://github.com/root-fr/jmap-webmail`
|
`Update available: v${remote} — https://github.com/bulwarkmail/webmail`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "jmap-webmail",
|
"name": "bulwark-webmail",
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "jmap-webmail",
|
"name": "bulwark-webmail",
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
+5
-5
@@ -1,16 +1,16 @@
|
|||||||
{
|
{
|
||||||
"name": "jmap-webmail",
|
"name": "bulwark-webmail",
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"description": "A modern JMAP webmail client built for Stalwart Mail Server",
|
"description": "Bulwark Webmail — a modern webmail client built for Stalwart Mail Server",
|
||||||
"author": "Matthieu MALVACHE <matthieu@root.cloud>",
|
"author": "Matthieu MALVACHE <matthieu@root.cloud>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/root-fr/jmap-webmail.git"
|
"url": "git+https://github.com/bulwarkmail/webmail.git"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/root-fr/jmap-webmail",
|
"homepage": "https://github.com/bulwarkmail/webmail",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/root-fr/jmap-webmail/issues"
|
"url": "https://github.com/bulwarkmail/webmail/issues"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"jmap",
|
"jmap",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# JMAP Webmail - Interactive Setup Script
|
# Bulwark Webmail - Interactive Setup Script
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ set -u
|
|||||||
ENV_FILE="${SCRIPT_DIR}/.env.local"
|
ENV_FILE="${SCRIPT_DIR}/.env.local"
|
||||||
|
|
||||||
# Config values (defaults)
|
# Config values (defaults)
|
||||||
CFG_APP_NAME="JMAP Webmail"
|
CFG_APP_NAME="Bulwark Webmail"
|
||||||
CFG_JMAP_SERVER_URL=""
|
CFG_JMAP_SERVER_URL=""
|
||||||
CFG_STALWART_FEATURES="true"
|
CFG_STALWART_FEATURES="true"
|
||||||
CFG_OAUTH_ENABLED="false"
|
CFG_OAUTH_ENABLED="false"
|
||||||
@@ -396,9 +396,9 @@ draw_header() {
|
|||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
if [[ "$DRY_RUN" == true ]]; then
|
if [[ "$DRY_RUN" == true ]]; then
|
||||||
box "JMAP WEBMAIL SETUP -- DRY RUN" "$MAGENTA"
|
box "BULWARK WEBMAIL SETUP -- DRY RUN" "$MAGENTA"
|
||||||
else
|
else
|
||||||
box "JMAP WEBMAIL SETUP" "$CYAN"
|
box "BULWARK WEBMAIL SETUP" "$CYAN"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
@@ -444,7 +444,7 @@ screen_welcome() {
|
|||||||
local version
|
local version
|
||||||
version=$(cat "${SCRIPT_DIR}/VERSION" 2>/dev/null || echo "dev")
|
version=$(cat "${SCRIPT_DIR}/VERSION" 2>/dev/null || echo "dev")
|
||||||
|
|
||||||
print_center "${BOLD}Welcome to JMAP Webmail${RESET}"
|
print_center "${BOLD}Welcome to Bulwark Webmail${RESET}"
|
||||||
print_center "${DIM}v${version}${RESET}"
|
print_center "${DIM}v${version}${RESET}"
|
||||||
echo ""
|
echo ""
|
||||||
echo ""
|
echo ""
|
||||||
@@ -542,7 +542,7 @@ screen_server_config() {
|
|||||||
draw_header
|
draw_header
|
||||||
|
|
||||||
section_header 1 "Server Configuration" \
|
section_header 1 "Server Configuration" \
|
||||||
"Point JMAP Webmail at your mail server."
|
"Point Bulwark Webmail at your mail server."
|
||||||
|
|
||||||
echo -e " ${BOLD}General${RESET}"
|
echo -e " ${BOLD}General${RESET}"
|
||||||
echo -e " ${DIM}This name appears in the browser tab and on the login page.${RESET}"
|
echo -e " ${DIM}This name appears in the browser tab and on the login page.${RESET}"
|
||||||
@@ -719,7 +719,7 @@ screen_logging_config() {
|
|||||||
draw_header
|
draw_header
|
||||||
|
|
||||||
section_header 4 "Logging" \
|
section_header 4 "Logging" \
|
||||||
"Control how JMAP Webmail writes logs."
|
"Control how Bulwark Webmail writes logs."
|
||||||
|
|
||||||
echo -e " ${BOLD}Log Format${RESET}"
|
echo -e " ${BOLD}Log Format${RESET}"
|
||||||
echo ""
|
echo ""
|
||||||
@@ -788,7 +788,7 @@ screen_deployment() {
|
|||||||
draw_header
|
draw_header
|
||||||
|
|
||||||
section_header 6 "Deployment Method" \
|
section_header 6 "Deployment Method" \
|
||||||
"Choose how you want to run JMAP Webmail."
|
"Choose how you want to run Bulwark Webmail."
|
||||||
|
|
||||||
local docker_available=false
|
local docker_available=false
|
||||||
command -v docker &>/dev/null && docker_available=true
|
command -v docker &>/dev/null && docker_available=true
|
||||||
@@ -940,7 +940,7 @@ write_env_file() {
|
|||||||
|
|
||||||
cat > "$ENV_FILE" << ENVEOF
|
cat > "$ENV_FILE" << ENVEOF
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# JMAP Webmail -- Configuration
|
# Bulwark Webmail -- Configuration
|
||||||
# Generated by setup.sh on $(date '+%Y-%m-%d %H:%M:%S')
|
# Generated by setup.sh on $(date '+%Y-%m-%d %H:%M:%S')
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
||||||
@@ -1026,7 +1026,7 @@ run_deployment() {
|
|||||||
echo -e " ${DIM}[dry-run] Would start: npm start (port ${CFG_PORT})${RESET}"
|
echo -e " ${DIM}[dry-run] Would start: npm start (port ${CFG_PORT})${RESET}"
|
||||||
;;
|
;;
|
||||||
"docker")
|
"docker")
|
||||||
echo -e " ${DIM}[dry-run] Would run: docker pull ghcr.io/rathlinus/jmap-webmail:latest${RESET}"
|
echo -e " ${DIM}[dry-run] Would run: docker pull ghcr.io/bulwarkmail/webmail:latest${RESET}"
|
||||||
echo -e " ${DIM}[dry-run] Would start: container on port ${CFG_PORT}${RESET}"
|
echo -e " ${DIM}[dry-run] Would start: container on port ${CFG_PORT}${RESET}"
|
||||||
;;
|
;;
|
||||||
"compose")
|
"compose")
|
||||||
@@ -1063,8 +1063,8 @@ run_deployment() {
|
|||||||
"docker")
|
"docker")
|
||||||
echo -e " ${BOLD}Pulling Docker image...${RESET}"
|
echo -e " ${BOLD}Pulling Docker image...${RESET}"
|
||||||
echo ""
|
echo ""
|
||||||
(docker pull ghcr.io/rathlinus/jmap-webmail:latest 2>&1) &
|
(docker pull ghcr.io/bulwarkmail/webmail:latest 2>&1) &
|
||||||
spinner $! "Pulling ghcr.io/rathlinus/jmap-webmail:latest"
|
spinner $! "Pulling ghcr.io/bulwarkmail/webmail:latest"
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo -e " ${OK} Image pulled!"
|
echo -e " ${OK} Image pulled!"
|
||||||
@@ -1072,11 +1072,11 @@ run_deployment() {
|
|||||||
echo -e " ${BOLD}To run the container:${RESET}"
|
echo -e " ${BOLD}To run the container:${RESET}"
|
||||||
echo ""
|
echo ""
|
||||||
echo -e " ${CYAN}docker run -d \\${RESET}"
|
echo -e " ${CYAN}docker run -d \\${RESET}"
|
||||||
echo -e " ${CYAN} --name jmap-webmail \\${RESET}"
|
echo -e " ${CYAN} --name bulwark-webmail \\${RESET}"
|
||||||
echo -e " ${CYAN} -p ${CFG_PORT}:3000 \\${RESET}"
|
echo -e " ${CYAN} -p ${CFG_PORT}:3000 \\${RESET}"
|
||||||
echo -e " ${CYAN} --env-file .env.local \\${RESET}"
|
echo -e " ${CYAN} --env-file .env.local \\${RESET}"
|
||||||
echo -e " ${CYAN} --restart unless-stopped \\${RESET}"
|
echo -e " ${CYAN} --restart unless-stopped \\${RESET}"
|
||||||
echo -e " ${CYAN} ghcr.io/rathlinus/jmap-webmail:latest${RESET}"
|
echo -e " ${CYAN} ghcr.io/bulwarkmail/webmail:latest${RESET}"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
"compose")
|
"compose")
|
||||||
@@ -1136,7 +1136,7 @@ screen_complete() {
|
|||||||
echo ""
|
echo ""
|
||||||
hr
|
hr
|
||||||
echo ""
|
echo ""
|
||||||
print_center "${DIM}Thank you for using JMAP Webmail!${RESET}"
|
print_center "${DIM}Thank you for using Bulwark Webmail!${RESET}"
|
||||||
echo ""
|
echo ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1217,7 +1217,7 @@ elif [[ -r /dev/tty ]] 2>/dev/null && (echo < /dev/tty) 2>/dev/null; then
|
|||||||
else
|
else
|
||||||
echo "Error: No interactive terminal available."
|
echo "Error: No interactive terminal available."
|
||||||
echo "Download and run the script directly instead:"
|
echo "Download and run the script directly instead:"
|
||||||
echo " curl -fsSL https://raw.githubusercontent.com/rathlinus/jmap-webmail/main/setup.sh -o setup.sh"
|
echo " curl -fsSL https://raw.githubusercontent.com/bulwarkmail/webmail/main/setup.sh -o setup.sh"
|
||||||
echo " bash setup.sh --dry-run"
|
echo " bash setup.sh --dry-run"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
## 1. Overview
|
## 1. Overview
|
||||||
|
|
||||||
This document describes a system that allows the JMAP Webmail application to be extended through **themes** (visual customization) and **plugins** (functional extensions). Together, these are called **addons**.
|
This document describes a system that allows the Bulwark Webmail application to be extended through **themes** (visual customization) and **plugins** (functional extensions). Together, these are called **addons**.
|
||||||
|
|
||||||
### Design Goals
|
### Design Goals
|
||||||
|
|
||||||
@@ -240,7 +240,7 @@ A plugin exports a single `activate` function and optionally a `deactivate` func
|
|||||||
|
|
||||||
```ts
|
```ts
|
||||||
// index.ts — Plugin entry point
|
// index.ts — Plugin entry point
|
||||||
import type { PluginContext } from "@jmap-webmail/addon-api";
|
import type { PluginContext } from "@bulwarkmail/addon-api";
|
||||||
|
|
||||||
export function activate(ctx: PluginContext) {
|
export function activate(ctx: PluginContext) {
|
||||||
// Register a sidebar section
|
// Register a sidebar section
|
||||||
@@ -817,7 +817,7 @@ Some hooks allow plugins to transform data flowing through them. For example, `e
|
|||||||
ctx.hooks.on("email:compose:before-send", (draft) => {
|
ctx.hooks.on("email:compose:before-send", (draft) => {
|
||||||
return {
|
return {
|
||||||
...draft,
|
...draft,
|
||||||
htmlBody: draft.htmlBody + "<p>Sent from JMAP Webmail</p>",
|
htmlBody: draft.htmlBody + "<p>Sent from Bulwark Webmail</p>",
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
@@ -866,8 +866,8 @@ useHostTheme(): { mode: "light" | "dark"; resolvedMode: "light" | "dark" };
|
|||||||
|
|
||||||
### Phase 3: Developer Experience
|
### Phase 3: Developer Experience
|
||||||
|
|
||||||
- [ ] Create `@jmap-webmail/addon-api` — TypeScript type definitions package.
|
- [ ] Create `@bulwarkmail/addon-api` — TypeScript type definitions package.
|
||||||
- [ ] Create `create-jmap-addon` CLI scaffolding tool.
|
- [ ] Create `create-bulwark-addon` CLI scaffolding tool.
|
||||||
- [ ] Write addon developer documentation with examples.
|
- [ ] Write addon developer documentation with examples.
|
||||||
- [ ] Build a sample plugin (e.g., email translation) as a reference.
|
- [ ] Build a sample plugin (e.g., email translation) as a reference.
|
||||||
- [ ] Add dev mode: hot-reload addons from local filesystem.
|
- [ ] Add dev mode: hot-reload addons from local filesystem.
|
||||||
@@ -896,7 +896,7 @@ nord-theme/
|
|||||||
`addon.json`:
|
`addon.json`:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"id": "org.nordtheme.jmap-webmail",
|
"id": "org.nordtheme.bulwark-webmail",
|
||||||
"name": "Nord",
|
"name": "Nord",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"type": "theme",
|
"type": "theme",
|
||||||
|
|||||||
@@ -1280,8 +1280,8 @@ export const useEmailStore = create<EmailStore>((set, get) => ({
|
|||||||
receivedAt: new Date().toISOString(),
|
receivedAt: new Date().toISOString(),
|
||||||
from: [{ name: "GitHub", email: "notifications@github.com" }],
|
from: [{ name: "GitHub", email: "notifications@github.com" }],
|
||||||
to: [{ email: "you@example.com" }],
|
to: [{ email: "you@example.com" }],
|
||||||
subject: "[jmap-webmail] New pull request #42: Add OAuth2 module",
|
subject: "[bulwark-webmail] New pull request #42: Add OAuth2 module",
|
||||||
preview: "dependabot[bot] opened a pull request in root-fr/jmap-webmail. This PR adds a comprehensive authentication module with OAuth2 PKCE support...",
|
preview: "dependabot[bot] opened a pull request in bulwarkmail/webmail. This PR adds a comprehensive authentication module with OAuth2 PKCE support...",
|
||||||
hasAttachment: false,
|
hasAttachment: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1358,8 +1358,8 @@ export const useEmailStore = create<EmailStore>((set, get) => ({
|
|||||||
receivedAt: new Date(Date.now() - 172800000).toISOString(),
|
receivedAt: new Date(Date.now() - 172800000).toISOString(),
|
||||||
from: [{ name: "Vercel", email: "notifications@vercel.com" }],
|
from: [{ name: "Vercel", email: "notifications@vercel.com" }],
|
||||||
to: [{ email: "you@example.com" }],
|
to: [{ email: "you@example.com" }],
|
||||||
subject: "Deployment successful: jmap-webmail \u2192 Production",
|
subject: "Deployment successful: bulwark-webmail \u2192 Production",
|
||||||
preview: "Your project jmap-webmail has been deployed to production. Build completed in 47s. All checks passed. Preview: https://jmap-webmail.vercel.app...",
|
preview: "Your project bulwark-webmail has been deployed to production. Build completed in 47s. All checks passed. Preview: https://bulwark-webmail.vercel.app...",
|
||||||
hasAttachment: false,
|
hasAttachment: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user