diff --git a/README.md b/README.md index 34f88c6..566bef6 100644 --- a/README.md +++ b/README.md @@ -45,89 +45,244 @@ docker-compose --env-file .env up -d --build --- -## Google Workspace Setup (One-Time) +## Part 1 — Google Cloud Console Setup -### 1. Create GCP Project & Enable APIs -1. Go to https://console.cloud.google.com → New Project -2. Enable **Admin SDK API** and **Gmail API** +This section walks through creating the service account and downloading the key +that allows the app to impersonate users in your Google Workspace domain. -### 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) +### Step 1 — Create a Google Cloud Project -### 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) +1. Open https://console.cloud.google.com and sign in with your Google Workspace admin account +2. Click the **project dropdown** in the top navigation bar (next to the Google Cloud logo) +3. Click **New Project** in the top right of the dialog +4. Enter a project name: `email-sig-manager` +5. Leave the organization as your Workspace domain → click **Create** +6. Wait a few seconds, then select the new project from the dropdown to make it active -### 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 - ``` +> **Note:** If your org already has a GCP project you prefer to use, you can skip +> project creation and just enable the APIs inside the existing project. --- -## Unraid Deployment +### Step 2 — Enable Required APIs + +The app needs two Google APIs enabled in your project. + +**Enable Admin SDK API:** +1. In the GCP Console, go to **APIs & Services → Library** (left sidebar) +2. Search for `Admin SDK API` +3. Click the result → click **Enable** + +**Enable Gmail API:** +1. Go back to **APIs & Services → Library** +2. Search for `Gmail API` +3. Click the result → click **Enable** + +Both should now show as **Enabled** under **APIs & Services → Enabled APIs & Services**. + +--- + +### Step 3 — Create the Service Account + +1. In the left sidebar, go to **IAM & Admin → Service Accounts** +2. Click **+ Create Service Account** at the top +3. Fill in the details: + - **Service account name:** `email-sig-manager` + - **Service account ID:** will auto-fill as `email-sig-manager` + - **Description:** `Email signature push service for Google Workspace` +4. Click **Create and Continue** +5. On the "Grant this service account access to project" step — **skip this, click Continue** +6. On the "Grant users access" step — **skip this too, click Done** + +You will land back on the service accounts list and see your new account listed. + +--- + +### Step 4 — Enable Domain-Wide Delegation on the Service Account + +1. Click the service account name (`email-sig-manager`) in the list to open it +2. Click the **Edit** button (pencil icon) at the top +3. Scroll down to find **"Show advanced settings"** — click it to expand +4. Check the box for **"Enable Google Workspace Domain-wide Delegation"** +5. Enter a product name for the consent screen if prompted (e.g., `Email Signature Manager`) +6. Click **Save** + +After saving, return to the service account detail page. You should now see a +**"Domain-wide delegation"** line showing a **Client ID** (a long numeric string, +e.g., `112233445566778899`). **Copy this Client ID** — you will need it in Part 2. + +--- + +### Step 5 — Download the Service Account JSON Key + +1. On the service account detail page, click the **Keys** tab +2. Click **Add Key → Create New Key** +3. Select **JSON** as the key type → click **Create** +4. The key file downloads automatically to your computer +5. **Rename the file to `sa.json`** +6. Store it securely — this file grants impersonation access to all users in your domain + +> This file goes in the `secrets/` folder on your Unraid host. It is gitignored +> and must never be committed to GitHub. + +--- + +## Part 2 — Google Admin Console Authorization + +This section delegates authority to the service account inside Google Admin, +allowing it to impersonate users and update their Gmail signatures. + +### Step 6 — Authorize the Service Account in Google Admin + +1. Open a new tab and go to https://admin.google.com +2. Sign in with your **Google Workspace super admin** account +3. In the left sidebar, navigate to: + **Security → Access and data control → API controls** +4. On the API controls page, click **Manage Domain Wide Delegation** +5. Click **Add new** to add a new authorized client + +Fill in the form: +- **Client ID:** Paste the numeric Client ID you copied in Step 4 + (find it again at GCP Console → IAM & Admin → Service Accounts → your account → Details) +- **OAuth Scopes:** Paste the following exactly, as one comma-separated line: + ``` + https://www.googleapis.com/auth/admin.directory.user.readonly,https://www.googleapis.com/auth/gmail.settings.basic + ``` + +6. Click **Authorize** + +> If you receive an error saying "client ID not found", wait 2–3 minutes after +> enabling domain-wide delegation in Step 4 and try again — GCP propagation +> can take a moment. + +--- + +### Step 7 — Verify the Authorization + +1. After clicking Authorize you should see the new entry in the list +2. Click **View details** next to your entry +3. Confirm both scopes are listed: + - `https://www.googleapis.com/auth/admin.directory.user.readonly` + - `https://www.googleapis.com/auth/gmail.settings.basic` +4. If a scope is missing, click **Edit**, re-enter the full comma-separated scope string, and click **Authorize** again + +> **Multi-party approval note:** If your Google Workspace org has multi-party +> approval enabled for admin actions, another super admin will need to approve +> this delegation before it takes effect. + +--- + +## Part 3 — Unraid Deployment + +### Step 8 — Clone the Repository + +SSH into your Unraid server or use the Unraid terminal: -### 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 +### Step 9 — Place the Service Account Key + +Copy `sa.json` (downloaded in Step 5) into the `secrets/` folder: + ```bash -# Copy sa.json to the secrets folder (NOT tracked by git) -cp /path/to/sa.json secrets/sa.json +# From your PC to Unraid (run this on your PC): +scp sa.json root@UNRAID-IP:/mnt/user/appdata/email-sig-manager/secrets/sa.json ``` -### 3. Add your company logo +Or copy it via your Unraid SMB share using Windows Explorer: ``` -public/assets/logo.png +\\UNRAID-IP\appdata\email-sig-manager\secrets\ ``` -### 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 +### Step 10 — Add Your Company Logo + +Place your logo file at: +``` +/mnt/user/appdata/email-sig-manager/public/assets/logo.png +``` +Recommended: PNG, transparent background, 160×160px or smaller. + +### Step 11 — Configure Container in Unraid Docker UI + +1. In the Unraid web UI, go to **Docker → Add Container** +2. Set the following: + - **Name:** `email-sig-manager` + - **Repository:** *(leave blank if building locally — use the path method below)* + - **Network Type:** Bridge + +**Add these Volume mappings:** + +| Container Path | Host Path | +|---|---| +| `/app/secrets` | `/mnt/user/appdata/email-sig-manager/secrets` | +| `/app/data` | `/mnt/user/appdata/email-sig-manager/data` | +| `/app/public/assets` | `/mnt/user/appdata/email-sig-manager/public/assets` | + +**Add these Port mapping:** + +| Container Port | Host Port | +|---|---| +| `3000` | `3000` *(or any open port)* | + +**Add these Variables** (click Add Variable for each): + +| Name | Value | +|---|---| +| `GOOGLE_ADMIN_EMAIL` | `admin@messagepointmedia.com` | +| `GOOGLE_CUSTOMER_ID` | `my_customer` | +| `SERVICE_ACCOUNT_KEY_PATH` | `/app/secrets/sa.json` | +| `ADMIN_USERNAME` | `admin` | +| `ADMIN_PASSWORD` | *(your chosen password)* | +| `PORT` | `3000` | +| `CRON_SCHEDULE` | `0 2 * * *` | +| `NODE_ENV` | `production` | + +### Step 12 — Build and Start -### 5. Build and start ```bash +cd /mnt/user/appdata/email-sig-manager docker-compose up -d --build ``` -Or use the Unraid UI to start the container after configuring it. -### Access the UI +--- + +## Part 4 — First Run & Verification + +### Step 13 — Access the Admin UI + +Open a browser and navigate to: ``` http://UNRAID-IP:3000 ``` +Log in with your `ADMIN_USERNAME` and `ADMIN_PASSWORD`. + +### Step 14 — Test with a Single User First + +1. Go to the **Template Editor** page +2. Verify the live preview renders correctly with your info +3. Make any template adjustments needed +4. Return to the **Dashboard** +5. In the **Push Single User** field, enter your own email address +6. Click **Push Single User** +7. Open Gmail in a new tab → compose a new email → verify the signature appears correctly +8. Check the Gmail mobile app as well (force-close and reopen if needed) + +### Step 15 — Push to All Users + +Once you've verified your own signature looks correct: + +1. Click **Push to All Users** on the Dashboard +2. Confirm the dialog +3. Watch the audit log populate with success/error statuses +4. The nightly cron will take over automatically from here --- -## 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 +## Updating the Project ```bash cd /mnt/user/appdata/email-sig-manager @@ -135,7 +290,7 @@ git pull docker-compose up -d --build ``` -`secrets/`, `data/`, and any host-managed files are gitignored and unaffected by pulls. +`secrets/`, `data/`, and host-managed files are gitignored and unaffected by pulls. --- @@ -187,17 +342,23 @@ email-sig-manager/ ## Troubleshooting **Container won't start** -Run `docker logs email-sig-manager` — most likely a missing env variable or malformed `sa.json`. +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. +The user may not have an active Gmail account, or domain-wide delegation scopes were not saved correctly in Google Admin. + +**"Client ID not found" when authorizing in Google Admin** +Wait 2–3 minutes after enabling domain-wide delegation in GCP and try again. **Signatures not showing on mobile** -Gmail iOS/Android automatically uses the web signature. Have the user force-close and reopen the app. +Gmail iOS/Android automatically uses the web signature. Have the user force-close and reopen the Gmail app after the push. **Template changes not saving** Verify the container has write access to the `templates/` directory. A `.bak` file is created on every save. +**401 / permission denied errors in logs** +The OAuth scopes in Google Admin may not have saved correctly. Go back to Admin Console → Security → API Controls → Domain Wide Delegation → View Details and verify both scopes are listed. + --- ## Security Notes