Files
makelore/electron/api/coding-provider-auth.ts

65 lines
2.6 KiB
TypeScript

import {
PiProviderConfigError,
resolvePiProviderCredentialFromSecretStore,
} from '../coding-runtime/pi/provider-config';
import { getProviderService } from '../services/providers/provider-service';
import {
getFreshWorksSquareAIGatewayCredential,
markWorksSquareAIGatewayCredentialExpired,
} from '../services/works-square-ai-gateway';
const WORKS_SQUARE_AI_GATEWAY_CREDENTIAL_MODE = 'works_square_ai_gateway';
const AUTHENTICATION_ERROR_PATTERN = /\b(?:401|403|unauthori[sz]ed|forbidden|authentication failed|auth failed|invalid (?:api key|credential|access token|bearer token)|(?:access |bearer )?token expired)\b/i;
export class CodingProviderCredentialRefreshError extends Error {
constructor(message: string, options?: ErrorOptions) {
super(message, options);
this.name = 'CodingProviderCredentialRefreshError';
}
}
export function isCodingProviderAuthenticationError(error: unknown): boolean {
return error instanceof CodingProviderCredentialRefreshError
|| (error instanceof PiProviderConfigError && error.code === 'PROVIDER_AUTH_REQUIRED')
|| (error instanceof Error && AUTHENTICATION_ERROR_PATTERN.test(error.message));
}
export async function refreshCodingProviderCredential(accountId: string): Promise<void> {
try {
const providerService = getProviderService();
const account = await providerService.getAccount(accountId);
if (!account?.enabled) {
throw new CodingProviderCredentialRefreshError('Provider account is unavailable');
}
if (account.metadata?.worksSquareCredentialMode === WORKS_SQUARE_AI_GATEWAY_CREDENTIAL_MODE) {
markWorksSquareAIGatewayCredentialExpired();
const credential = await getFreshWorksSquareAIGatewayCredential();
if (!credential) {
throw new CodingProviderCredentialRefreshError('Provider credential refresh failed');
}
await providerService.updateAccount(account.id, {
baseUrl: credential.oneApiBaseUrl,
metadata: {
...account.metadata,
worksSquareCredentialExpiresAt: credential.expiresAt === null
? undefined
: new Date(credential.expiresAt).toISOString(),
},
}, credential.accessToken);
return;
}
const current = await resolvePiProviderCredentialFromSecretStore(account);
if (!current && account.authMode !== 'local') {
throw new CodingProviderCredentialRefreshError('Provider credential is unavailable');
}
} catch (error) {
if (error instanceof CodingProviderCredentialRefreshError) throw error;
throw new CodingProviderCredentialRefreshError(
'Provider credential refresh failed',
{ cause: error },
);
}
}