mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-04-26 08:56:22 +02:00
ask for google client id
This commit is contained in:
parent
2b828bd138
commit
941a56142b
12 changed files with 285 additions and 33 deletions
23
apps/x/packages/core/src/auth/provider-client-id.ts
Normal file
23
apps/x/packages/core/src/auth/provider-client-id.ts
Normal 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);
|
||||
}
|
||||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue