fix(gmail-auth): request explicit filter settings scope
This commit is contained in:
@@ -1154,7 +1154,7 @@ Supported delivery modes:
|
||||
1. Create a Google Cloud project with the Gmail API enabled
|
||||
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
|
||||
- Requests full Gmail access scope (`https://mail.google.com/`) so all filter operations are allowed
|
||||
- Requests Gmail scopes for settings + read access (`gmail.settings.basic` + `gmail.readonly`)
|
||||
|
||||
For Pub/Sub delivery (push/pull), also enable the Pub/Sub API and create:
|
||||
- A topic (e.g. `projects/your-project/topics/gmail-push`)
|
||||
|
||||
+1
-1
@@ -452,7 +452,7 @@ memory:
|
||||
# credentials_file: ~/.config/flynn/gmail-credentials.json
|
||||
# token_file: ~/.config/flynn/gmail-token.json
|
||||
# # Authenticate with: flynn gmail-auth
|
||||
# # (requests full Gmail scope https://mail.google.com/ for complete Gmail filter permissions)
|
||||
# # (requests gmail.settings.basic + gmail.readonly for filter create + inbox tools)
|
||||
#
|
||||
# # Optional Pub/Sub delivery
|
||||
# # Push mode: configure a topic and a push subscription that POSTs to /gmail/push
|
||||
|
||||
+15
-1
@@ -3,6 +3,20 @@
|
||||
"updated_at": "2026-02-23",
|
||||
"description": "Tracks the status of all Flynn plans and implementation phases",
|
||||
"plans": {
|
||||
"gmail-filter-scope-correction": {
|
||||
"status": "completed",
|
||||
"date": "2026-02-23",
|
||||
"updated": "2026-02-23",
|
||||
"summary": "Corrected Gmail OAuth scopes for filter creation after validating that `mail.google.com` alone still produced `ACCESS_TOKEN_SCOPE_INSUFFICIENT` for `users.settings.filters.create` in live checks. `flynn gmail-auth` now explicitly requests `gmail.settings.basic` (plus `gmail.readonly`). Updated auth tests and operator docs/comments.",
|
||||
"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"
|
||||
},
|
||||
"minimal-tui-multiline-paste-mode": {
|
||||
"status": "completed",
|
||||
"date": "2026-02-23",
|
||||
@@ -6345,7 +6359,7 @@
|
||||
"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",
|
||||
"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 full Gmail scope (https://mail.google.com/) for complete filter permissions",
|
||||
"gmail_filter_creation": "completed — gmail.filter.create tool added with criteria/action validation; gmail-auth requests explicit gmail.settings.basic + gmail.readonly scopes for filter creation and inbox reads",
|
||||
"toolloop_action_intent_recovery": "completed — when a model claims it will execute a tool but emits no tool call, NativeAgent now issues one internal nudge and continues the same turn to execute tools or produce a concrete blocker",
|
||||
"toolloop_execution_claim_recovery": "completed — when a model claims a known tool already succeeded/failed without emitting a tool call, NativeAgent now nudges once and retries the same turn before returning text",
|
||||
"minimal_tui_multiline_paste_mode": "completed — minimal TUI now supports `/paste`/`/multiline` multiline compose mode ending with single '.' line, preventing newline truncation for pasted prompts",
|
||||
|
||||
@@ -71,7 +71,8 @@ describe('gmail-auth', () => {
|
||||
expect(url).toContain('https://accounts.google.com/o/oauth2/v2/auth');
|
||||
expect(url).toContain('client_id=my-client-id');
|
||||
expect(url).toContain('redirect_uri=http%3A%2F%2Flocalhost%3A3000');
|
||||
expect(url).toContain('scope=https%3A%2F%2Fmail.google.com%2F');
|
||||
expect(url).toContain('scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgmail.settings.basic');
|
||||
expect(url).toContain('https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgmail.readonly');
|
||||
expect(url).toContain('access_type=offline');
|
||||
expect(url).toContain('prompt=consent');
|
||||
});
|
||||
|
||||
@@ -7,8 +7,10 @@ import { URL } from 'url';
|
||||
import { loadConfigSafe } from './shared.js';
|
||||
|
||||
const SCOPES = [
|
||||
// Full Gmail access (includes all filter operations and settings APIs).
|
||||
'https://mail.google.com/',
|
||||
// Explicitly request Gmail settings scope required by filters.create.
|
||||
'https://www.googleapis.com/auth/gmail.settings.basic',
|
||||
// Keep readonly mailbox access for list/search/read tooling.
|
||||
'https://www.googleapis.com/auth/gmail.readonly',
|
||||
];
|
||||
const REDIRECT_PORT = 3000;
|
||||
const REDIRECT_URI = `http://localhost:${REDIRECT_PORT}`;
|
||||
|
||||
Reference in New Issue
Block a user