ask for google client id

This commit is contained in:
Ramnique Singh 2026-01-26 06:50:18 +05:30
parent 2b828bd138
commit 941a56142b
12 changed files with 285 additions and 33 deletions

View file

@ -0,0 +1,23 @@
type ProviderClientIdOverrides = Map<string, string>;
const providerClientIdOverrides: ProviderClientIdOverrides = new Map();
export function setProviderClientIdOverride(provider: string, clientId: string): void {
const trimmed = clientId.trim();
if (!trimmed) {
return;
}
providerClientIdOverrides.set(provider, trimmed);
}
export function getProviderClientIdOverride(provider: string): string | undefined {
return providerClientIdOverrides.get(provider);
}
export function hasProviderClientIdOverride(provider: string): boolean {
return providerClientIdOverrides.has(provider);
}
export function clearProviderClientIdOverride(provider: string): void {
providerClientIdOverrides.delete(provider);
}

View file

@ -22,7 +22,7 @@ const DiscoverySchema = z.discriminatedUnion('mode', [
const ClientSchema = z.discriminatedUnion('mode', [
z.object({
mode: z.literal('static'),
clientId: z.string().min(1),
clientId: z.string().min(1).optional(),
}),
z.object({
mode: z.literal('dcr'),
@ -58,7 +58,6 @@ const providerConfigs: ProviderConfig = {
},
client: {
mode: 'static',
clientId: '797410052581-ibmmvqec0l68stv5fmgh0juqfvbg08fc.apps.googleusercontent.com',
},
scopes: [
'https://www.googleapis.com/auth/gmail.readonly',

View file

@ -144,9 +144,13 @@ export class FirefliesClientFactory {
if (providerConfig.client.mode === 'static') {
// Discover endpoints, use static client ID
console.log(`[Fireflies] Discovery mode: issuer with static client ID`);
const clientId = providerConfig.client.clientId;
if (!clientId) {
throw new Error('Fireflies client ID not configured.');
}
this.cache.config = await oauthClient.discoverConfiguration(
providerConfig.discovery.issuer,
providerConfig.client.clientId
clientId
);
} else {
// DCR mode - need existing registration
@ -170,10 +174,14 @@ export class FirefliesClientFactory {
}
console.log(`[Fireflies] Using static endpoints (no discovery)`);
const clientId = providerConfig.client.clientId;
if (!clientId) {
throw new Error('Fireflies client ID not configured.');
}
this.cache.config = oauthClient.createStaticConfiguration(
providerConfig.discovery.authorizationEndpoint,
providerConfig.discovery.tokenEndpoint,
providerConfig.client.clientId,
clientId,
providerConfig.discovery.revocationEndpoint
);
}

View file

@ -3,6 +3,7 @@ import container from '../di/container.js';
import { IOAuthRepo } from '../auth/repo.js';
import { IClientRegistrationRepo } from '../auth/client-repo.js';
import { getProviderConfig } from '../auth/providers.js';
import { getProviderClientIdOverride } from '../auth/provider-client-id.js';
import * as oauthClient from '../auth/oauth-client.js';
import type { Configuration } from '../auth/oauth-client.js';
import { OAuthTokens } from '../auth/types.js';
@ -17,12 +18,22 @@ export class GoogleClientFactory {
config: Configuration | null;
client: OAuth2Client | null;
tokens: OAuthTokens | null;
clientId: string | null;
} = {
config: null,
client: null,
tokens: null,
clientId: null,
};
private static resolveClientId(): string {
const override = getProviderClientIdOverride(this.PROVIDER_NAME);
if (!override) {
throw new Error('Google client ID not provided for this session.');
}
return override;
}
/**
* Get or create OAuth2Client, reusing cached instance when possible
*/
@ -36,7 +47,13 @@ export class GoogleClientFactory {
}
// Initialize config cache if needed
await this.initializeConfigCache();
try {
await this.initializeConfigCache();
} catch (error) {
console.error("[OAuth] Failed to initialize Google OAuth configuration:", error);
this.clearCache();
return null;
}
if (!this.cache.config) {
return null;
}
@ -95,6 +112,10 @@ export class GoogleClientFactory {
return false;
}
if (!getProviderClientIdOverride(this.PROVIDER_NAME)) {
return false;
}
const tokens = await oauthRepo.getTokens(this.PROVIDER_NAME);
if (!tokens) {
return false;
@ -116,14 +137,21 @@ export class GoogleClientFactory {
this.cache.config = null;
this.cache.client = null;
this.cache.tokens = null;
this.cache.clientId = null;
}
/**
* Initialize cached configuration (called once)
*/
private static async initializeConfigCache(): Promise<void> {
if (this.cache.config) {
return; // Already initialized
const clientId = this.resolveClientId();
if (this.cache.config && this.cache.clientId === clientId) {
return; // Already initialized for this client ID
}
if (this.cache.clientId && this.cache.clientId !== clientId) {
this.clearCache();
}
console.log(`[OAuth] Initializing Google OAuth configuration...`);
@ -135,7 +163,7 @@ export class GoogleClientFactory {
console.log(`[OAuth] Discovery mode: issuer with static client ID`);
this.cache.config = await oauthClient.discoverConfiguration(
providerConfig.discovery.issuer,
providerConfig.client.clientId
clientId
);
} else {
// DCR mode - need existing registration
@ -162,11 +190,12 @@ export class GoogleClientFactory {
this.cache.config = oauthClient.createStaticConfiguration(
providerConfig.discovery.authorizationEndpoint,
providerConfig.discovery.tokenEndpoint,
providerConfig.client.clientId,
clientId,
providerConfig.discovery.revocationEndpoint
);
}
this.cache.clientId = clientId;
console.log(`[OAuth] Google OAuth configuration initialized`);
}
@ -174,17 +203,7 @@ export class GoogleClientFactory {
* Create OAuth2Client from OAuthTokens
*/
private static createClientFromTokens(tokens: OAuthTokens): OAuth2Client {
const providerConfig = getProviderConfig(this.PROVIDER_NAME);
// Get client ID from config
let clientId: string;
if (providerConfig.client.mode === 'static') {
clientId = providerConfig.client.clientId;
} else {
// For DCR, we'd need to look up the registered client ID
// This is a fallback - normally initializeConfigCache handles this
throw new Error('Cannot create client without static client ID');
}
const clientId = this.resolveClientId();
// Create OAuth2Client directly (PKCE flow doesn't use client secret)
const client = new OAuth2Client(