Add files via upload
This commit is contained in:
209
README.md
209
README.md
@@ -1 +1,208 @@
|
||||
# email-sigs
|
||||
# Email Signature Manager
|
||||
|
||||
A self-hosted, Dockerized Google Workspace email signature manager.
|
||||
Runs as a single container — designed for Unraid but works on any Docker host.
|
||||
|
||||
## Features
|
||||
|
||||
- Pulls user data automatically from Google Workspace Directory API
|
||||
- Renders per-user HTML signatures via Handlebars templates
|
||||
- Pushes signatures directly to Gmail via `sendAs` API (web + mobile)
|
||||
- Nightly batch push via configurable cron schedule
|
||||
- Web admin UI — live template editor with real-time preview
|
||||
- Single-user push for testing and onboarding
|
||||
- SQLite audit log of every push event
|
||||
- Basic auth protected UI
|
||||
- Zero external services — single container, no database server
|
||||
|
||||
---
|
||||
|
||||
## Environment Variables
|
||||
|
||||
All secrets and configuration are passed as **environment variables at runtime**.
|
||||
No `.env` file is committed to this repo — see `.env.example` for all variable names and descriptions.
|
||||
|
||||
| Variable | Description | Default |
|
||||
|---|---|---|
|
||||
| `GOOGLE_ADMIN_EMAIL` | Workspace admin email for Directory API | *(required)* |
|
||||
| `GOOGLE_CUSTOMER_ID` | Use `my_customer` for primary domain | `my_customer` |
|
||||
| `SERVICE_ACCOUNT_KEY_PATH` | Path to sa.json inside container | `/app/secrets/sa.json` |
|
||||
| `ADMIN_USERNAME` | Web UI login username | *(required)* |
|
||||
| `ADMIN_PASSWORD` | Web UI login password | *(required)* |
|
||||
| `PORT` | Internal app port | `3000` |
|
||||
| `CRON_SCHEDULE` | Cron expression for nightly push | `0 2 * * *` |
|
||||
| `NODE_ENV` | Node environment | `production` |
|
||||
|
||||
### On Unraid
|
||||
Set each variable directly in the **Docker container template UI** under the
|
||||
"Variables" section. No file needed on the host.
|
||||
|
||||
### For Local Development
|
||||
Copy `.env.example` to `.env`, fill in your values, then run:
|
||||
```bash
|
||||
docker-compose --env-file .env up -d --build
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Google Workspace Setup (One-Time)
|
||||
|
||||
### 1. Create GCP Project & Enable APIs
|
||||
1. Go to https://console.cloud.google.com → New Project
|
||||
2. Enable **Admin SDK API** and **Gmail API**
|
||||
|
||||
### 2. Create Service Account
|
||||
1. APIs & Services → Credentials → Create Credentials → Service Account
|
||||
2. Name it `email-sig-manager` → Create
|
||||
3. Open the service account → Keys tab → Add Key → JSON
|
||||
4. Save the downloaded file as `sa.json`
|
||||
5. Place it at: `secrets/sa.json` on the Docker host (mounted as a volume, never in git)
|
||||
|
||||
### 3. Enable Domain-Wide Delegation
|
||||
1. Edit the service account → check **Enable Google Workspace Domain-wide Delegation** → Save
|
||||
2. Note the **Client ID** (long numeric string)
|
||||
|
||||
### 4. Authorize Scopes in Google Admin
|
||||
1. Go to https://admin.google.com
|
||||
2. Security → Access and data control → API controls → Manage Domain Wide Delegation
|
||||
3. Add new entry:
|
||||
- **Client ID:** *(your service account client ID)*
|
||||
- **OAuth Scopes:**
|
||||
```
|
||||
https://www.googleapis.com/auth/admin.directory.user.readonly,https://www.googleapis.com/auth/gmail.settings.basic
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Unraid Deployment
|
||||
|
||||
### 1. Clone the repo
|
||||
```bash
|
||||
cd /mnt/user/appdata
|
||||
git clone https://github.com/YOURUSERNAME/email-sig-manager.git
|
||||
cd email-sig-manager
|
||||
```
|
||||
|
||||
### 2. Place the service account key
|
||||
```bash
|
||||
# Copy sa.json to the secrets folder (NOT tracked by git)
|
||||
cp /path/to/sa.json secrets/sa.json
|
||||
```
|
||||
|
||||
### 3. Add your company logo
|
||||
```
|
||||
public/assets/logo.png
|
||||
```
|
||||
|
||||
### 4. Add container in Unraid Docker UI
|
||||
- **Repository:** *(or build from path)*
|
||||
- **Port:** Map host port → `3000`
|
||||
- **Volumes:**
|
||||
- `/mnt/user/appdata/email-sig-manager/secrets` → `/app/secrets`
|
||||
- `/mnt/user/appdata/email-sig-manager/data` → `/app/data`
|
||||
- `/mnt/user/appdata/email-sig-manager/public/assets` → `/app/public/assets`
|
||||
- **Variables:** Add all variables from the table above
|
||||
|
||||
### 5. Build and start
|
||||
```bash
|
||||
docker-compose up -d --build
|
||||
```
|
||||
Or use the Unraid UI to start the container after configuring it.
|
||||
|
||||
### Access the UI
|
||||
```
|
||||
http://UNRAID-IP:3000
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## First Run Checklist
|
||||
|
||||
- [ ] `secrets/sa.json` is in place on the host
|
||||
- [ ] All environment variables are set in Unraid Docker UI
|
||||
- [ ] Logo placed at `public/assets/logo.png`
|
||||
- [ ] Open UI → Template Editor → preview looks correct
|
||||
- [ ] Push single user (yourself) to verify Gmail signature
|
||||
- [ ] Push to all users
|
||||
|
||||
---
|
||||
|
||||
## Updating
|
||||
|
||||
```bash
|
||||
cd /mnt/user/appdata/email-sig-manager
|
||||
git pull
|
||||
docker-compose up -d --build
|
||||
```
|
||||
|
||||
`secrets/`, `data/`, and any host-managed files are gitignored and unaffected by pulls.
|
||||
|
||||
---
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
email-sig-manager/
|
||||
├── src/
|
||||
│ ├── index.js # Express app entry
|
||||
│ ├── routes/
|
||||
│ │ ├── admin.js # Template, logs, users API
|
||||
│ │ └── push.js # Signature push logic + batch runner
|
||||
│ ├── services/
|
||||
│ │ ├── googleAdmin.js # Directory API — fetch all users
|
||||
│ │ ├── gmailApi.js # Gmail sendAs patch
|
||||
│ │ ├── renderer.js # Handlebars template renderer
|
||||
│ │ └── scheduler.js # node-cron nightly job
|
||||
│ └── db/
|
||||
│ ├── sqlite.js # DB init and connection
|
||||
│ └── audit.js # Audit log read/write
|
||||
├── templates/
|
||||
│ └── default.hbs # 2-column HTML signature template
|
||||
├── public/
|
||||
│ ├── dashboard.html # Admin dashboard UI
|
||||
│ ├── editor.html # Template editor with live preview
|
||||
│ └── assets/
|
||||
│ └── logo.png # Company logo (add your own)
|
||||
├── secrets/ # Gitignored — sa.json goes here
|
||||
├── data/ # Gitignored — SQLite DB lives here
|
||||
├── Dockerfile
|
||||
├── docker-compose.yml
|
||||
├── package.json
|
||||
└── .env.example # Variable reference — safe to commit
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Cron Schedule Reference
|
||||
|
||||
| Expression | Meaning |
|
||||
|---|---|
|
||||
| `0 2 * * *` | 2:00 AM every day *(default)* |
|
||||
| `0 6 * * *` | 6:00 AM every day |
|
||||
| `0 2 * * 1` | 2:00 AM every Monday |
|
||||
| `0 2 1 * *` | 2:00 AM on the 1st of each month |
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Container won't start**
|
||||
Run `docker logs email-sig-manager` — most likely a missing env variable or malformed `sa.json`.
|
||||
|
||||
**"No primary sendAs" error**
|
||||
The user may not have an active Gmail account, or domain-wide delegation scopes weren't saved correctly.
|
||||
|
||||
**Signatures not showing on mobile**
|
||||
Gmail iOS/Android automatically uses the web signature. Have the user force-close and reopen the app.
|
||||
|
||||
**Template changes not saving**
|
||||
Verify the container has write access to the `templates/` directory. A `.bak` file is created on every save.
|
||||
|
||||
---
|
||||
|
||||
## Security Notes
|
||||
|
||||
- `sa.json` grants impersonation rights to every user in your domain — treat it like a master key
|
||||
- Never commit `sa.json` or a populated `.env` to GitHub
|
||||
- Change `ADMIN_PASSWORD` before first deployment
|
||||
- Consider placing the UI behind HTTPS if accessible outside your LAN
|
||||
|
||||
Reference in New Issue
Block a user