Code Snippet Server
by ngeojiajun
Verified
- src
- services
import { google } from "googleapis";
import { OAuth2Client } from "google-auth-library";
import * as fs from "fs";
import * as path from "path";
import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const TOKEN_PATH = path.join(__dirname, "../../credentials/google-token.json");
const CREDENTIALS_PATH = path.join(
__dirname,
"../../credentials/google-credentials.json"
);
export class GoogleAuthService {
private static instance: GoogleAuthService;
private oAuth2Client: OAuth2Client | null = null;
private authUrl: string | null = null;
private constructor() {}
static getInstance(): GoogleAuthService {
if (!GoogleAuthService.instance) {
GoogleAuthService.instance = new GoogleAuthService();
}
return GoogleAuthService.instance;
}
async initialize(): Promise<void> {
try {
const credentials = JSON.parse(
fs.readFileSync(CREDENTIALS_PATH, "utf-8")
);
const { client_secret, client_id, redirect_uris } = credentials.installed;
this.oAuth2Client = new google.auth.OAuth2(
client_id,
client_secret,
redirect_uris[0]
);
// Try to load existing token
if (fs.existsSync(TOKEN_PATH)) {
const token = JSON.parse(fs.readFileSync(TOKEN_PATH, "utf-8"));
this.oAuth2Client.setCredentials(token);
}
} catch (error) {
console.error("Error loading client secrets file:", error);
throw error;
}
}
async authenticate(): Promise<void> {
if (!this.oAuth2Client) {
throw new Error("OAuth2Client not initialized");
}
// If we already have a token, no need to authenticate
if (fs.existsSync(TOKEN_PATH)) {
return;
}
// Since we can't authenticate automatically in MCP context,
// throw an error with instructions
throw new Error(
"Google authentication required. Please follow these steps:\n" +
"1. Set up Google Cloud Project and enable required APIs\n" +
"2. Create OAuth 2.0 credentials (Desktop Application type)\n" +
"3. Download credentials and save as 'credentials/google-credentials.json'\n" +
"4. Run the authentication helper script: 'npm run auth-google'\n" +
"5. Restart the MCP server after authentication is complete"
);
}
getAuth(): OAuth2Client {
if (!this.oAuth2Client) {
throw new Error("OAuth2Client not initialized");
}
return this.oAuth2Client;
}
async saveToken(token: any): Promise<void> {
fs.writeFileSync(TOKEN_PATH, JSON.stringify(token));
console.log("Token stored to", TOKEN_PATH);
}
}