feat(gmail-auth): request full Gmail scope for filter permissions

This commit is contained in:
William Valentin
2026-02-22 22:27:57 -08:00
parent e51ca97ce4
commit 50c4f3de57
5 changed files with 21 additions and 8 deletions
+2 -2
View File
@@ -1154,7 +1154,7 @@ Supported delivery modes:
1. Create a Google Cloud project with the Gmail API enabled 1. Create a Google Cloud project with the Gmail API enabled
2. Create OAuth2 credentials (Desktop application type) and download the JSON file 2. Create OAuth2 credentials (Desktop application type) and download the JSON file
3. Run `flynn gmail-auth` to complete the OAuth2 flow and store the refresh token 3. Run `flynn gmail-auth` to complete the OAuth2 flow and store the refresh token
- Requests scopes for both mailbox reads and filter management (`gmail.readonly` + `gmail.settings.basic`) - Requests full Gmail access scope (`https://mail.google.com/`) so all filter operations are allowed
For Pub/Sub delivery (push/pull), also enable the Pub/Sub API and create: For Pub/Sub delivery (push/pull), also enable the Pub/Sub API and create:
- A topic (e.g. `projects/your-project/topics/gmail-push`) - A topic (e.g. `projects/your-project/topics/gmail-push`)
@@ -1218,7 +1218,7 @@ When `automation.gmail.enabled: true`, Flynn registers Gmail tools:
- `gmail.read` — fetch full message body by ID - `gmail.read` — fetch full message body by ID
- `gmail.filter.create` — create Gmail filters (criteria + actions like archive/label/forward) - `gmail.filter.create` — create Gmail filters (criteria + actions like archive/label/forward)
`gmail.filter.create` requires a token with `gmail.settings.basic`. If your token was created before this scope was added, re-run `flynn gmail-auth`. `gmail.filter.create` requires a token issued with current scopes. If your token predates this change, re-run `flynn gmail-auth`.
### Template Variables ### Template Variables
+1 -1
View File
@@ -452,7 +452,7 @@ memory:
# credentials_file: ~/.config/flynn/gmail-credentials.json # credentials_file: ~/.config/flynn/gmail-credentials.json
# token_file: ~/.config/flynn/gmail-token.json # token_file: ~/.config/flynn/gmail-token.json
# # Authenticate with: flynn gmail-auth # # Authenticate with: flynn gmail-auth
# # (requests gmail.readonly + gmail.settings.basic for gmail.filter.create support) # # (requests full Gmail scope https://mail.google.com/ for complete Gmail filter permissions)
# #
# # Optional Pub/Sub delivery # # Optional Pub/Sub delivery
# # Push mode: configure a topic and a push subscription that POSTs to /gmail/push # # Push mode: configure a topic and a push subscription that POSTs to /gmail/push
+15 -1
View File
@@ -3,6 +3,20 @@
"updated_at": "2026-02-23", "updated_at": "2026-02-23",
"description": "Tracks the status of all Flynn plans and implementation phases", "description": "Tracks the status of all Flynn plans and implementation phases",
"plans": { "plans": {
"gmail-filter-full-scope-auth": {
"status": "completed",
"date": "2026-02-23",
"updated": "2026-02-23",
"summary": "Expanded `flynn gmail-auth` to request full Gmail OAuth scope (`https://mail.google.com/`) so Flynn tokens have complete Gmail filter permissions. Updated auth URL tests and operator docs/comments to reflect the broader scope and re-auth guidance.",
"files_modified": [
"src/cli/gmail-auth.ts",
"src/cli/gmail-auth.test.ts",
"README.md",
"config/default.yaml",
"docs/plans/state.json"
],
"test_status": "pnpm test:run src/cli/gmail-auth.test.ts + pnpm typecheck passing"
},
"gmail-filter-creation-tooling": { "gmail-filter-creation-tooling": {
"status": "completed", "status": "completed",
"date": "2026-02-23", "date": "2026-02-23",
@@ -6292,7 +6306,7 @@
"operator_dx_milestone": "Phase 3 (Live Ops Dashboard): 2/2 plans complete — milestone done", "operator_dx_milestone": "Phase 3 (Live Ops Dashboard): 2/2 plans complete — milestone done",
"dashboard_observability": "completed — service health graphs + core service log viewer added to web UI via observability RPCs and bounded backend sampling", "dashboard_observability": "completed — service health graphs + core service log viewer added to web UI via observability RPCs and bounded backend sampling",
"gmail_auth_cli": "flynn gmail-auth command implemented with OAuth2 flow, doctor check, config routed to Telegram", "gmail_auth_cli": "flynn gmail-auth command implemented with OAuth2 flow, doctor check, config routed to Telegram",
"gmail_filter_creation": "completed — gmail.filter.create tool added with criteria/action validation; gmail-auth now requests gmail.settings.basic for filter-management permissions", "gmail_filter_creation": "completed — gmail.filter.create tool added with criteria/action validation; gmail-auth now requests full Gmail scope (https://mail.google.com/) for complete filter permissions",
"native_audio_support": "completed — smart routing for native audio (Gemini/OpenAI/GitHub) vs Whisper transcription fallback, plus 2026-02-23 arg hydration hardening, tool.args_rewritten audit metric, transient fetch retry/timeout hardening, localhost->127.0.0.1 fallback for transcription endpoint connectivity, and whisper docker-compose entrypoint arg fix for port 18801", "native_audio_support": "completed — smart routing for native audio (Gemini/OpenAI/GitHub) vs Whisper transcription fallback, plus 2026-02-23 arg hydration hardening, tool.args_rewritten audit metric, transient fetch retry/timeout hardening, localhost->127.0.0.1 fallback for transcription endpoint connectivity, and whisper docker-compose entrypoint arg fix for port 18801",
"remaining_phases_completion": "Phase 1: 3/3 (100%) — context levels, command registry, memory structure. Phase 2: 3/3 (100%) — component registry, confidence routing, history index. Phase 3: 2/2 (100%) — adaptive memory/compaction, truthfulness/autonomy hardening", "remaining_phases_completion": "Phase 1: 3/3 (100%) — context levels, command registry, memory structure. Phase 2: 3/3 (100%) — component registry, confidence routing, history index. Phase 3: 2/2 (100%) — adaptive memory/compaction, truthfulness/autonomy hardening",
"next_up": "Track OpenClaw evolution regularly for inspiration and feature ideas" "next_up": "Track OpenClaw evolution regularly for inspiration and feature ideas"
+1 -2
View File
@@ -71,8 +71,7 @@ describe('gmail-auth', () => {
expect(url).toContain('https://accounts.google.com/o/oauth2/v2/auth'); expect(url).toContain('https://accounts.google.com/o/oauth2/v2/auth');
expect(url).toContain('client_id=my-client-id'); expect(url).toContain('client_id=my-client-id');
expect(url).toContain('redirect_uri=http%3A%2F%2Flocalhost%3A3000'); expect(url).toContain('redirect_uri=http%3A%2F%2Flocalhost%3A3000');
expect(url).toContain('scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgmail.readonly'); expect(url).toContain('scope=https%3A%2F%2Fmail.google.com%2F');
expect(url).toContain('https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgmail.settings.basic');
expect(url).toContain('access_type=offline'); expect(url).toContain('access_type=offline');
expect(url).toContain('prompt=consent'); expect(url).toContain('prompt=consent');
}); });
+2 -2
View File
@@ -7,8 +7,8 @@ import { URL } from 'url';
import { loadConfigSafe } from './shared.js'; import { loadConfigSafe } from './shared.js';
const SCOPES = [ const SCOPES = [
'https://www.googleapis.com/auth/gmail.readonly', // Full Gmail access (includes all filter operations and settings APIs).
'https://www.googleapis.com/auth/gmail.settings.basic', 'https://mail.google.com/',
]; ];
const REDIRECT_PORT = 3000; const REDIRECT_PORT = 3000;
const REDIRECT_URI = `http://localhost:${REDIRECT_PORT}`; const REDIRECT_URI = `http://localhost:${REDIRECT_PORT}`;