wip: email sync via imap with status tracking and auto cron
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
import { getServerIntegration } from 'officerdb';
|
||||
import { PermanentError } from '../../queue/types';
|
||||
|
||||
type TokenRefreshResult = { accessToken: string; expiresAt: number };
|
||||
|
||||
export async function refreshGoogleAccessToken(refreshToken: string): Promise<TokenRefreshResult> {
|
||||
const serverGoogle = await getServerIntegration('google');
|
||||
const serverConfig = serverGoogle?.config as Record<string, unknown> | undefined;
|
||||
if (!serverConfig?.clientId || !serverConfig?.clientSecret) {
|
||||
throw new PermanentError('Google OAuth not configured on server');
|
||||
}
|
||||
|
||||
const response = await fetch('https://oauth2.googleapis.com/token', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
body: new URLSearchParams({
|
||||
client_id: serverConfig.clientId as string,
|
||||
client_secret: serverConfig.clientSecret as string,
|
||||
refresh_token: refreshToken,
|
||||
grant_type: 'refresh_token',
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const text = await response.text();
|
||||
throw new Error(`Google token refresh failed: ${text}`);
|
||||
}
|
||||
|
||||
const data = (await response.json()) as { access_token: string; expires_in: number };
|
||||
return {
|
||||
accessToken: data.access_token,
|
||||
expiresAt: Date.now() + data.expires_in * 1000,
|
||||
};
|
||||
}
|
||||
@@ -259,11 +259,16 @@ export const googleCallbackHandler = async (ctx: any) => {
|
||||
|
||||
const serverIntegration = await getServerIntegration('google');
|
||||
|
||||
// Merge with existing config to preserve fields like imapAppPassword
|
||||
const existingIntegration = await getUserIntegration(dbUser.id, 'google');
|
||||
const existingConfig = (existingIntegration?.config as Record<string, unknown>) ?? {};
|
||||
|
||||
await upsertUserIntegration({
|
||||
userId: dbUser.id,
|
||||
provider: 'google',
|
||||
serverIntegrationId: serverIntegration?.id,
|
||||
config: {
|
||||
...existingConfig,
|
||||
accessToken: tokens.access_token,
|
||||
refreshToken: tokens.refresh_token,
|
||||
expiresAt: Date.now() + tokens.expires_in * 1000,
|
||||
|
||||
Reference in New Issue
Block a user