feat(google-auth): centralize oauth token store and service checks
This commit is contained in:
@@ -1,52 +1,14 @@
|
||||
import { google, type Auth } from 'googleapis';
|
||||
import { readFileSync, existsSync } from 'fs';
|
||||
import { resolve } from 'path';
|
||||
import { homedir } from 'os';
|
||||
import { google } from 'googleapis';
|
||||
import type { GcalConfig } from '../../config/schema.js';
|
||||
import { createGoogleOAuth2Client } from '../../google/oauth.js';
|
||||
import type { Tool, ToolResult } from '../types.js';
|
||||
|
||||
/** Expand ~ to home directory. */
|
||||
function expandPath(p: string): string {
|
||||
if (p.startsWith('~/') || p === '~') {
|
||||
return resolve(homedir(), p.slice(2));
|
||||
}
|
||||
return resolve(p);
|
||||
}
|
||||
|
||||
/** Create an OAuth2 client from Google Calendar config (credentials + token files). */
|
||||
function createOAuth2Client(config: NonNullable<GcalConfig>): Auth.OAuth2Client {
|
||||
const credentialsPath = config.credentials_file;
|
||||
if (!credentialsPath) {
|
||||
throw new Error('No credentials_file configured. Set automation.gcal.credentials_file in config.');
|
||||
}
|
||||
|
||||
const expandedCredsPath = expandPath(credentialsPath);
|
||||
if (!existsSync(expandedCredsPath)) {
|
||||
throw new Error(`Credentials file not found: ${expandedCredsPath}`);
|
||||
}
|
||||
|
||||
const credentials = JSON.parse(readFileSync(expandedCredsPath, 'utf-8'));
|
||||
const { client_id, client_secret, redirect_uris } = credentials.installed ?? credentials.web ?? {};
|
||||
|
||||
if (!client_id || !client_secret) {
|
||||
throw new Error('Invalid credentials file — missing client_id or client_secret');
|
||||
}
|
||||
|
||||
const oauth2Client = new google.auth.OAuth2(
|
||||
client_id,
|
||||
client_secret,
|
||||
redirect_uris?.[0] ?? 'http://localhost',
|
||||
);
|
||||
|
||||
const tokenPath = expandPath(config.token_file ?? '~/.config/flynn/gcal-token.json');
|
||||
if (!existsSync(tokenPath)) {
|
||||
throw new Error(`Token file not found: ${tokenPath}. Run "flynn gcal-auth" to authenticate.`);
|
||||
}
|
||||
|
||||
const token = JSON.parse(readFileSync(tokenPath, 'utf-8'));
|
||||
oauth2Client.setCredentials(token);
|
||||
|
||||
return oauth2Client;
|
||||
function createOAuth2Client(config: NonNullable<GcalConfig>) {
|
||||
return createGoogleOAuth2Client({
|
||||
service: 'gcal',
|
||||
credentialsFile: config.credentials_file,
|
||||
tokenFile: config.token_file,
|
||||
});
|
||||
}
|
||||
|
||||
interface EventSummary {
|
||||
|
||||
@@ -1,52 +1,14 @@
|
||||
import { google, type Auth } from 'googleapis';
|
||||
import { readFileSync, existsSync } from 'fs';
|
||||
import { resolve } from 'path';
|
||||
import { homedir } from 'os';
|
||||
import { google } from 'googleapis';
|
||||
import type { GdocsConfig } from '../../config/schema.js';
|
||||
import { createGoogleOAuth2Client } from '../../google/oauth.js';
|
||||
import type { Tool, ToolResult } from '../types.js';
|
||||
|
||||
/** Expand ~ to home directory. */
|
||||
function expandPath(p: string): string {
|
||||
if (p.startsWith('~/') || p === '~') {
|
||||
return resolve(homedir(), p.slice(2));
|
||||
}
|
||||
return resolve(p);
|
||||
}
|
||||
|
||||
/** Create an OAuth2 client from Google Docs config (credentials + token files). */
|
||||
function createOAuth2Client(config: NonNullable<GdocsConfig>): Auth.OAuth2Client {
|
||||
const credentialsPath = config.credentials_file;
|
||||
if (!credentialsPath) {
|
||||
throw new Error('No credentials_file configured. Set automation.gdocs.credentials_file in config.');
|
||||
}
|
||||
|
||||
const expandedCredsPath = expandPath(credentialsPath);
|
||||
if (!existsSync(expandedCredsPath)) {
|
||||
throw new Error(`Credentials file not found: ${expandedCredsPath}`);
|
||||
}
|
||||
|
||||
const credentials = JSON.parse(readFileSync(expandedCredsPath, 'utf-8'));
|
||||
const { client_id, client_secret, redirect_uris } = credentials.installed ?? credentials.web ?? {};
|
||||
|
||||
if (!client_id || !client_secret) {
|
||||
throw new Error('Invalid credentials file — missing client_id or client_secret');
|
||||
}
|
||||
|
||||
const oauth2Client = new google.auth.OAuth2(
|
||||
client_id,
|
||||
client_secret,
|
||||
redirect_uris?.[0] ?? 'http://localhost',
|
||||
);
|
||||
|
||||
const tokenPath = expandPath(config.token_file ?? '~/.config/flynn/gdocs-token.json');
|
||||
if (!existsSync(tokenPath)) {
|
||||
throw new Error(`Token file not found: ${tokenPath}. Run "flynn gdocs-auth" to authenticate.`);
|
||||
}
|
||||
|
||||
const token = JSON.parse(readFileSync(tokenPath, 'utf-8'));
|
||||
oauth2Client.setCredentials(token);
|
||||
|
||||
return oauth2Client;
|
||||
function createOAuth2Client(config: NonNullable<GdocsConfig>) {
|
||||
return createGoogleOAuth2Client({
|
||||
service: 'gdocs',
|
||||
credentialsFile: config.credentials_file,
|
||||
tokenFile: config.token_file,
|
||||
});
|
||||
}
|
||||
|
||||
interface DocSummary {
|
||||
|
||||
@@ -1,52 +1,14 @@
|
||||
import { google, type Auth } from 'googleapis';
|
||||
import { readFileSync, existsSync } from 'fs';
|
||||
import { resolve } from 'path';
|
||||
import { homedir } from 'os';
|
||||
import { google } from 'googleapis';
|
||||
import type { GdriveConfig } from '../../config/schema.js';
|
||||
import { createGoogleOAuth2Client } from '../../google/oauth.js';
|
||||
import type { Tool, ToolResult } from '../types.js';
|
||||
|
||||
/** Expand ~ to home directory. */
|
||||
function expandPath(p: string): string {
|
||||
if (p.startsWith('~/') || p === '~') {
|
||||
return resolve(homedir(), p.slice(2));
|
||||
}
|
||||
return resolve(p);
|
||||
}
|
||||
|
||||
/** Create an OAuth2 client from config (credentials + token files). */
|
||||
function createOAuth2Client(config: NonNullable<GdriveConfig>): Auth.OAuth2Client {
|
||||
const credentialsPath = config.credentials_file;
|
||||
if (!credentialsPath) {
|
||||
throw new Error('No credentials_file configured. Set automation.gdrive.credentials_file in config.');
|
||||
}
|
||||
|
||||
const expandedCredsPath = expandPath(credentialsPath);
|
||||
if (!existsSync(expandedCredsPath)) {
|
||||
throw new Error(`Credentials file not found: ${expandedCredsPath}`);
|
||||
}
|
||||
|
||||
const credentials = JSON.parse(readFileSync(expandedCredsPath, 'utf-8'));
|
||||
const { client_id, client_secret, redirect_uris } = credentials.installed ?? credentials.web ?? {};
|
||||
|
||||
if (!client_id || !client_secret) {
|
||||
throw new Error('Invalid credentials file — missing client_id or client_secret');
|
||||
}
|
||||
|
||||
const oauth2Client = new google.auth.OAuth2(
|
||||
client_id,
|
||||
client_secret,
|
||||
redirect_uris?.[0] ?? 'http://localhost',
|
||||
);
|
||||
|
||||
const tokenPath = expandPath(config.token_file ?? '~/.config/flynn/gdrive-token.json');
|
||||
if (!existsSync(tokenPath)) {
|
||||
throw new Error(`Token file not found: ${tokenPath}. Run "flynn gdrive-auth" to authenticate.`);
|
||||
}
|
||||
|
||||
const token = JSON.parse(readFileSync(tokenPath, 'utf-8'));
|
||||
oauth2Client.setCredentials(token);
|
||||
|
||||
return oauth2Client;
|
||||
function createOAuth2Client(config: NonNullable<GdriveConfig>) {
|
||||
return createGoogleOAuth2Client({
|
||||
service: 'gdrive',
|
||||
credentialsFile: config.credentials_file,
|
||||
tokenFile: config.token_file,
|
||||
});
|
||||
}
|
||||
|
||||
interface FileSummary {
|
||||
|
||||
@@ -1,53 +1,15 @@
|
||||
import { google, type Auth } from 'googleapis';
|
||||
import { readFileSync, existsSync } from 'fs';
|
||||
import { resolve } from 'path';
|
||||
import { homedir } from 'os';
|
||||
import { google } from 'googleapis';
|
||||
import type { GmailConfig } from '../../config/schema.js';
|
||||
import { createGoogleOAuth2Client } from '../../google/oauth.js';
|
||||
import type { Tool, ToolResult } from '../types.js';
|
||||
import { sanitizeHtml } from '../../utils/html.js';
|
||||
|
||||
/** Expand ~ to home directory. */
|
||||
function expandPath(p: string): string {
|
||||
if (p.startsWith('~/') || p === '~') {
|
||||
return resolve(homedir(), p.slice(2));
|
||||
}
|
||||
return resolve(p);
|
||||
}
|
||||
|
||||
/** Create an OAuth2 client from Gmail config (credentials + token files). */
|
||||
function createOAuth2Client(config: NonNullable<GmailConfig>): Auth.OAuth2Client {
|
||||
const credentialsPath = config.credentials_file;
|
||||
if (!credentialsPath) {
|
||||
throw new Error('No credentials_file configured. Set automation.gmail.credentials_file in config.');
|
||||
}
|
||||
|
||||
const expandedCredsPath = expandPath(credentialsPath);
|
||||
if (!existsSync(expandedCredsPath)) {
|
||||
throw new Error(`Credentials file not found: ${expandedCredsPath}`);
|
||||
}
|
||||
|
||||
const credentials = JSON.parse(readFileSync(expandedCredsPath, 'utf-8'));
|
||||
const { client_id, client_secret, redirect_uris } = credentials.installed ?? credentials.web ?? {};
|
||||
|
||||
if (!client_id || !client_secret) {
|
||||
throw new Error('Invalid credentials file — missing client_id or client_secret');
|
||||
}
|
||||
|
||||
const oauth2Client = new google.auth.OAuth2(
|
||||
client_id,
|
||||
client_secret,
|
||||
redirect_uris?.[0] ?? 'http://localhost',
|
||||
);
|
||||
|
||||
const tokenPath = expandPath(config.token_file ?? '~/.config/flynn/gmail-token.json');
|
||||
if (!existsSync(tokenPath)) {
|
||||
throw new Error(`Token file not found: ${tokenPath}. Run "flynn gmail-auth" to authenticate.`);
|
||||
}
|
||||
|
||||
const token = JSON.parse(readFileSync(tokenPath, 'utf-8'));
|
||||
oauth2Client.setCredentials(token);
|
||||
|
||||
return oauth2Client;
|
||||
function createOAuth2Client(config: NonNullable<GmailConfig>) {
|
||||
return createGoogleOAuth2Client({
|
||||
service: 'gmail',
|
||||
credentialsFile: config.credentials_file,
|
||||
tokenFile: config.token_file,
|
||||
});
|
||||
}
|
||||
|
||||
interface EmailSummary {
|
||||
|
||||
@@ -1,52 +1,14 @@
|
||||
import { google, type Auth } from 'googleapis';
|
||||
import { readFileSync, existsSync } from 'fs';
|
||||
import { resolve } from 'path';
|
||||
import { homedir } from 'os';
|
||||
import { google } from 'googleapis';
|
||||
import type { GtasksConfig } from '../../config/schema.js';
|
||||
import { createGoogleOAuth2Client } from '../../google/oauth.js';
|
||||
import type { Tool, ToolResult } from '../types.js';
|
||||
|
||||
/** Expand ~ to home directory. */
|
||||
function expandPath(p: string): string {
|
||||
if (p.startsWith('~/') || p === '~') {
|
||||
return resolve(homedir(), p.slice(2));
|
||||
}
|
||||
return resolve(p);
|
||||
}
|
||||
|
||||
/** Create an OAuth2 client from Google Tasks config (credentials + token files). */
|
||||
function createOAuth2Client(config: NonNullable<GtasksConfig>): Auth.OAuth2Client {
|
||||
const credentialsPath = config.credentials_file;
|
||||
if (!credentialsPath) {
|
||||
throw new Error('No credentials_file configured. Set automation.gtasks.credentials_file in config.');
|
||||
}
|
||||
|
||||
const expandedCredsPath = expandPath(credentialsPath);
|
||||
if (!existsSync(expandedCredsPath)) {
|
||||
throw new Error(`Credentials file not found: ${expandedCredsPath}`);
|
||||
}
|
||||
|
||||
const credentials = JSON.parse(readFileSync(expandedCredsPath, 'utf-8'));
|
||||
const { client_id, client_secret, redirect_uris } = credentials.installed ?? credentials.web ?? {};
|
||||
|
||||
if (!client_id || !client_secret) {
|
||||
throw new Error('Invalid credentials file — missing client_id or client_secret');
|
||||
}
|
||||
|
||||
const oauth2Client = new google.auth.OAuth2(
|
||||
client_id,
|
||||
client_secret,
|
||||
redirect_uris?.[0] ?? 'http://localhost',
|
||||
);
|
||||
|
||||
const tokenPath = expandPath(config.token_file ?? '~/.config/flynn/gtasks-token.json');
|
||||
if (!existsSync(tokenPath)) {
|
||||
throw new Error(`Token file not found: ${tokenPath}. Run "flynn gtasks-auth" to authenticate.`);
|
||||
}
|
||||
|
||||
const token = JSON.parse(readFileSync(tokenPath, 'utf-8'));
|
||||
oauth2Client.setCredentials(token);
|
||||
|
||||
return oauth2Client;
|
||||
function createOAuth2Client(config: NonNullable<GtasksConfig>) {
|
||||
return createGoogleOAuth2Client({
|
||||
service: 'gtasks',
|
||||
credentialsFile: config.credentials_file,
|
||||
tokenFile: config.token_file,
|
||||
});
|
||||
}
|
||||
|
||||
interface TaskListSummary {
|
||||
|
||||
Reference in New Issue
Block a user