#!/usr/bin/env node
/**
* OAuth Setup Script for Google Apps Script API
* This script helps you obtain and securely store OAuth tokens
*/
import 'dotenv/config';
import { manualOAuthFlow } from '../lib/oauth-helper.js';
import { TokenManager } from '../lib/tokenManager.js';
import { readFileSync } from 'fs';
console.log('π Google Apps Script API OAuth Setup');
console.log('=====================================\n');
async function setupOAuth() {
console.log('π This script will help you set up OAuth authentication for Google Apps Script API.');
console.log('π You need to have your CLIENT_ID and CLIENT_SECRET configured in .env file.\n');
const tokenManager = new TokenManager();
// Handle info command
if (process.argv.includes('--info')) {
const tokenInfo = tokenManager.getTokenInfo();
console.log('π Token Information:');
console.log('=====================\n');
if (tokenInfo.hasTokens) {
console.log('β
Tokens found');
console.log(`π Location: ${tokenInfo.location}`);
console.log(`πΎ Saved at: ${tokenInfo.savedAt}`);
console.log(`β° Expires at: ${tokenInfo.expiresAt}`);
console.log(`π Status: ${tokenInfo.status}`);
console.log(`π Scope: ${tokenInfo.scope || 'Not specified'}`);
} else {
console.log('β No tokens found');
console.log(`π Expected location: ${tokenInfo.location}`);
console.log('\nπ‘ Run "node oauth-setup.js" to set up OAuth tokens');
}
process.exit(0);
}
// Handle clear command
if (process.argv.includes('--clear')) {
tokenManager.clearTokens();
console.log('β
Tokens cleared successfully.');
process.exit(0);
}
// Check if tokens already exist
const tokenInfo = tokenManager.getTokenInfo();
if (tokenInfo.hasTokens) {
console.log('π Found existing tokens:');
console.log(` π Location: ${tokenInfo.location}`);
console.log(` πΎ Saved at: ${tokenInfo.savedAt}`);
console.log(` β° Expires at: ${tokenInfo.expiresAt}`);
console.log(` π Status: ${tokenInfo.status}`);
console.log(` π Scope: ${tokenInfo.scope || 'Not specified'}\n`);
if (!tokenInfo.isExpired) {
console.log('β
You already have valid tokens stored.');
console.log('π‘ To get new tokens, run: node oauth-setup.js --force');
console.log('ποΈ To clear existing tokens, run: node oauth-setup.js --clear\n');
if (!process.argv.includes('--force')) {
process.exit(0);
}
}
}
try {
// Check if .env file exists and has required credentials
const envPath = '.env';
let envContent = '';
try {
envContent = readFileSync(envPath, 'utf8');
console.log('β
Found .env file');
} catch (error) {
console.error('β No .env file found. Please create one first with your CLIENT_ID and CLIENT_SECRET.');
console.log('\nπ Example .env file content:');
console.log('GOOGLE_APP_SCRIPT_API_CLIENT_ID=your_client_id_here');
console.log('GOOGLE_APP_SCRIPT_API_CLIENT_SECRET=your_client_secret_here');
console.log('\nπ Note: Refresh token is now stored securely and not needed in .env file');
process.exit(1);
}
// Check for required credentials
const hasClientId = envContent.includes('GOOGLE_APP_SCRIPT_API_CLIENT_ID=') &&
!envContent.includes('GOOGLE_APP_SCRIPT_API_CLIENT_ID=your_client_id_here');
const hasClientSecret = envContent.includes('GOOGLE_APP_SCRIPT_API_CLIENT_SECRET=') &&
!envContent.includes('GOOGLE_APP_SCRIPT_API_CLIENT_SECRET=your_client_secret_here');
if (!hasClientId || !hasClientSecret) {
console.error('β Missing CLIENT_ID or CLIENT_SECRET in .env file.');
console.log('\nπ§ Please update your .env file with valid credentials:');
console.log(' - GOOGLE_APP_SCRIPT_API_CLIENT_ID=your_actual_client_id');
console.log(' - GOOGLE_APP_SCRIPT_API_CLIENT_SECRET=your_actual_client_secret');
console.log('\nπ See OAUTH_SETUP.md for instructions on obtaining these credentials.');
process.exit(1);
}
console.log('β
Found required credentials in .env file');
console.log('\nπ Starting OAuth flow...');
console.log('π± Your browser will open automatically');
console.log('π Please authorize the application when prompted');
console.log('β³ Waiting for authorization...\n');
// Start OAuth flow
const tokens = await manualOAuthFlow();
if (tokens.refresh_token) {
console.log('\nπ OAuth setup successful!');
console.log('π Access token obtained:', tokens.access_token ? 'β
' : 'β');
console.log('π Refresh token obtained:', tokens.refresh_token ? 'β
' : 'β');
// Save tokens securely using TokenManager
try {
tokenManager.saveTokens(tokens);
console.log('πΎ Tokens saved securely');
const tokenInfo = tokenManager.getTokenInfo();
console.log(`π Token location: ${tokenInfo.location}`);
console.log(`π File permissions: Owner read/write only`);
console.log('\nβ
Setup complete! Your OAuth tokens are now stored securely.');
console.log('π Refresh tokens are stored in a secure OS-specific location');
console.log('π You can now use the MCP server and API tools');
console.log('\nπ§ͺ Test your setup with:');
console.log(' node test-token-management.js');
} catch (saveError) {
console.error('\nβ Failed to save tokens:', saveError.message);
console.log('π§ Please check file permissions and try again');
process.exit(1);
}
} else {
console.log('\nβ οΈ OAuth completed but no refresh token received.');
console.log('π You may need to revoke and re-authorize the application.');
console.log('π Check the Google Cloud Console for your OAuth settings.');
}
} catch (error) {
console.error('\nβ OAuth setup failed:', error.message);
console.log('\nπ§ Troubleshooting:');
console.log(' 1. Check your internet connection');
console.log(' 2. Verify your CLIENT_ID and CLIENT_SECRET are correct');
console.log(' 3. Ensure the redirect URI is registered in Google Cloud Console');
console.log(' 4. Make sure Google Apps Script API is enabled');
console.log(' 5. Try revoking and re-creating your OAuth credentials');
console.log('\nπ For detailed setup instructions, see OAUTH_SETUP.md');
process.exit(1);
}
}
// Run setup
setupOAuth().catch((error) => {
console.error('π₯ Unexpected error:', error);
process.exit(1);
});