Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 10 additions & 12 deletions apps/http-backend/src/services/token-refresh.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ interface OAuthTokens {
token_type: string;
expiry_date: number;
scope?: string;
email?: string
}
Comment on lines 8 to 11

interface RefreshResult {
Expand Down Expand Up @@ -35,24 +36,21 @@ class TokenRefreshService {
*/
private async refreshToken(credentialId: string, tokens: OAuthTokens): Promise<RefreshResult> {
try {
// Use your existing GoogleSheetsService to refresh the token
const sheetService = new GoogleSheetsService({
access_token: tokens.access_token,
refresh_token: tokens.refresh_token,
token_type: tokens.token_type,
expiry_date: tokens.expiry_date
});

// Use your existing refreshAccessToken method
const newTokens = await sheetService.refreshAccessToken();
const newTokens = await this.oauthService.refreshAccessToken(tokens.refresh_token);

// Use your existing updateCredentials method from GoogleOAuthService
await this.oauthService.updateCredentials(credentialId, {
const updatedTokens = {
access_token: newTokens.access_token,
refresh_token: newTokens.refresh_token || tokens.refresh_token,
token_type: newTokens.token_type,
expiry_date: newTokens.expiry_date
});
expiry_date: newTokens.expiry_date,
scope: newTokens.scope || tokens.scope,
email: newTokens.email || tokens.email
};

// Use your existing updateCredentials method from GoogleOAuthService
await this.oauthService.updateCredentials(credentialId, updatedTokens);

console.log(`✅ Token refreshed for credential: ${credentialId}`);
return { credentialId, success: true };
Expand Down
46 changes: 23 additions & 23 deletions apps/web/app/workflows/[id]/components/ConfigModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ export default function ConfigModal({
key={cred.id}
className="px-2.5 py-1 bg-emerald-500/15 text-emerald-400 text-xs rounded-full border border-emerald-500/20 font-medium"
>
{cred.email || cred.name}
{cred.config?.email || cred.name}
</span>
Comment on lines 459 to 463
))}
</div>
Expand Down Expand Up @@ -674,28 +674,28 @@ export default function ConfigModal({
/>
</div>
);
return (
<div key={field.name} className="form-group">
<label className="block text-sm font-medium text-white mb-1">
{field.label}
{field.required && <span className="text-red-400">*</span>}
</label>
<input
type={field.type}
value={fieldValue}
onFocus={() => setActiveField(field.name)}
placeholder={field.placeholder}
onChange={(e) => {
const newConfig = { ...config, [field.name]: e.target.value };
setConfig(newConfig)
dispatchConfig(newConfig)
}
}
className="w-full p-2.5 border border-[#1e293b] bg-[#0a0e17] text-gray-200 rounded-lg focus:ring-2 focus:ring-indigo-500/50 focus:border-indigo-500/50 transition-all outline-none text-sm placeholder-gray-600"
required={field.required}
/>
</div>
);
// return (
// <div key={field.name} className="form-group">
// <label className="block text-sm font-medium text-white mb-1">
// {field.label}
// {field.required && <span className="text-red-400">*</span>}
// </label>
// <input
// type={field.type}
// value={fieldValue}
// onFocus={() => setActiveField(field.name)}
// placeholder={field.placeholder}
// onChange={(e) => {
// const newConfig = { ...config, [field.name]: e.target.value };
// setConfig(newConfig)
// dispatchConfig(newConfig)
// }
// }
// className="w-full p-2.5 border border-[#1e293b] bg-[#0a0e17] text-gray-200 rounded-lg focus:ring-2 focus:ring-indigo-500/50 focus:border-indigo-500/50 transition-all outline-none text-sm placeholder-gray-600"
// required={field.required}
// />
// </div>
// );
};

return (
Expand Down
49 changes: 47 additions & 2 deletions packages/nodes/src/common/google-oauth-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,39 @@ class GoogleOAuthService {
}
}

isTokenExpired(expiry_date: number): boolean {
if (!expiry_date) return false;

return Date.now() >= expiry_date - (5 * 60 * 1000);
}

async refreshAccessToken(refresh_token: string): Promise<OAuthTokens> {
try {
await this.oauth2Client.setCredentials({ refresh_token: refresh_token })
const { credentials } = await this.oauth2Client.refreshAccessToken();

Comment on lines +109 to +113
// IMPORTANT: Only include refresh_token if Google returns a new one
// Google doesn't always return a new refresh_token on every refresh
const result: OAuthTokens = {
access_token: credentials.access_token || '',
refresh_token: '', // Will be set below if present
token_type: credentials.token_type || '',
expiry_date: credentials.expiry_date || 0,
scope: credentials.scope || ''
};

// Only include refresh_token if Google actually returned one
if (credentials.refresh_token) {
result.refresh_token = credentials.refresh_token;
}

return result;
}
catch (error) {
throw new Error(`Failed to refresh token: ${error}`)
}
}

async getCredentials(
userId: string,
credentialId: string,
Expand All @@ -117,11 +150,23 @@ class GoogleOAuthService {
id: "desc",
},
});
console.log("credentails from oauth service: ", credentials);
if (!credentials) return null;
let tokens = credentials?.config as unknown as OAuthTokens

if (this.isTokenExpired(tokens.expiry_date) && tokens.refresh_token) {
const newTokens = await this.refreshAccessToken(tokens.refresh_token)
if (!newTokens.scope) newTokens.scope = tokens.scope
if (!newTokens.email) newTokens.email = tokens.email
if (!newTokens.refresh_token) newTokens.refresh_token = tokens.refresh_token

await this.updateCredentials(credentialId, newTokens)

tokens = { ...tokens, ...newTokens }
}

return {
id: credentials.id,
tokens: credentials.config as unknown as OAuthTokens,
tokens: tokens as OAuthTokens,
};
} catch (err) {
throw new Error(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,6 @@ class GoogleSheetsNodeExecutor {
};
}

if (sheetService.isTokenExpired()) {
const newTokens = await sheetService.refreshAccessToken();
await this.oauthService.updateCredentials(credentialId, newTokens)
}

const operation = context.config.operation;
console.log("operation from sheet executor: ", operation)
Expand Down Expand Up @@ -444,7 +440,7 @@ class GoogleSheetsNodeExecutor {
async executeClearRows(sheetService: GoogleSheetsService, context: NodeExecutionContext): Promise<NodeExecutionResult> {
try {
const spreadsheetId = context.config.spreadsheetId;
const range = (!context.config.clearEntireTable && context.config.range) ? context.config.range : (context.config.includeHeaderRow ? `${context.config.sheetName}!A1:Z` : `${context.config.sheetName}!A2:Z`);
const range = (!context.config.clearEntireTable && context.config.range) ? `${context.config.sheetName}!${context.config.range}` : (context.config.includeHeaderRow ? `${context.config.sheetName}!A1:Z` : `${context.config.sheetName}!A2:Z`);

const response = await sheetService.clearRows({
spreadsheetId: spreadsheetId,
Expand Down
30 changes: 0 additions & 30 deletions packages/nodes/src/google-sheets/google-sheets.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,37 +162,7 @@ class GoogleSheetsService {
}
}

isTokenExpired(): boolean {
const credentials = this.auth.credentials;
if (!credentials.expiry_date) return false;

return Date.now() >= credentials.expiry_date - (5 * 60 * 1000);
}

async refreshAccessToken(): Promise<GoogleSheetsCredentials> {
try {
const { credentials } = await this.auth.refreshAccessToken();

// IMPORTANT: Only include refresh_token if Google returns a new one
// Google doesn't always return a new refresh_token on every refresh
const result: GoogleSheetsCredentials = {
access_token: credentials.access_token || '',
refresh_token: '', // Will be set below if present
token_type: credentials.token_type || '',
expiry_date: credentials.expiry_date || 0
};

// Only include refresh_token if Google actually returned one
if (credentials.refresh_token) {
result.refresh_token = credentials.refresh_token;
}

return result;
}
catch (error) {
throw new Error(`Failed to refresh token: ${error}`)
}
}
}

export { GoogleSheetsService }
Expand Down