Skip to content

Commit 7accb64

Browse files
committed
revert(zoho-desk): back out both shared lib/oauth changes
Reverting two changes to shared OAuth code because their premise is inferred rather than proven, and neither meets the bar for touching a path every provider runs. `refreshOAuthToken` body-error branch. The premise was that Zoho reports refresh failures with HTTP 200 and an `error` body. That is documented and empirically confirmed for the authorization-code EXCHANGE (see the comment on getToken in auth.ts), but I never confirmed it for the REFRESH grant specifically - and if Zoho returns a proper 4xx there, the existing `!response.ok` path already classifies it via extractErrorCode, making the branch dead code that every one of the ~34 providers still executes on each refresh. A shared branch whose only justification is an unverified inference about one provider is not worth its blast radius. `invalid_code` in TERMINAL_ERRORS. Same problem, worse downside: the code is sourced from a Zoho community post rather than official docs, TERMINAL_ERRORS is consulted for every provider, and a false positive marks a credential dead for an hour. Not adding it simply preserves today's behavior (retry rather than dead-flag), so reverting costs nothing that was previously working. Both are cheap to reinstate, correctly scoped, once a live Zoho account shows what a revoked refresh token actually returns. Kept: the token-redaction on the "no access token" warn, which is an unambiguous improvement independent of Zoho. Also kept, deliberately, is the serializer `trigger-advanced` exclusion - that one rests on a reproduced bug rather than an inference, and it aligns the serializer with the convention the rest of the codebase already follows (blocks.test.ts treats `trigger` and `trigger-advanced` identically in six places, as does the copilot block-metadata tool, and blocks/types.ts documents trigger-advanced as "the advanced side of a trigger field").
1 parent 8c16c9d commit 7accb64

2 files changed

Lines changed: 2 additions & 49 deletions

File tree

apps/sim/lib/oauth/oauth.ts

Lines changed: 2 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1878,48 +1878,6 @@ export async function refreshOAuthToken(
18781878

18791879
const data = await response.json()
18801880

1881-
// Some providers - Zoho notably - report OAuth failures in the JSON body with
1882-
// HTTP 200 rather than a 4xx (e.g. `{"error":"invalid_client"}` for a revoked
1883-
// refresh token). Without this the `!accessToken` guard below returns a
1884-
// failure with no `errorCode`, so `isTerminalRefreshError` cannot recognize a
1885-
// terminal condition, the credential is never marked dead, and every later
1886-
// execution retries a refresh that can never succeed. Classify on the body
1887-
// before trusting the status, matching the token-exchange and service-account
1888-
// mint paths, which already do this.
1889-
// The `!data.access_token` guard matters because this branch runs for EVERY
1890-
// provider: without it, a provider that ever returns an informational `error`
1891-
// alongside a valid token would have all its credentials fail refresh - and
1892-
// if that string is one of TERMINAL_ERRORS, be marked dead for an hour. No
1893-
// current provider does that, but the branch should not depend on it. Zoho's
1894-
// failure bodies carry no token, so the guard costs nothing here.
1895-
if (
1896-
data &&
1897-
typeof data === 'object' &&
1898-
typeof data.error === 'string' &&
1899-
data.error &&
1900-
!data.access_token
1901-
) {
1902-
logger.error('Token refresh failed with an error body:', {
1903-
status: response.status,
1904-
statusText: response.statusText,
1905-
error: data.error,
1906-
errorDescription:
1907-
typeof data.error_description === 'string' ? data.error_description : null,
1908-
providerId,
1909-
tokenEndpoint: config.tokenEndpoint,
1910-
hasClientId: !!config.clientId,
1911-
hasClientSecret: !!config.clientSecret,
1912-
hasRefreshToken: !!refreshToken,
1913-
})
1914-
return {
1915-
ok: false,
1916-
errorCode: data.error,
1917-
message: `Failed to refresh token: ${data.error}${
1918-
typeof data.error_description === 'string' ? ` - ${data.error_description}` : ''
1919-
}`,
1920-
}
1921-
}
1922-
19231881
if (data && typeof data === 'object' && data.ok === false) {
19241882
logger.error('Token refresh failed:', {
19251883
status: response.status,
@@ -1950,8 +1908,8 @@ export async function refreshOAuthToken(
19501908
const expiresIn = data.expires_in || data.expiresIn || 3600
19511909

19521910
if (!accessToken) {
1953-
// Never log `data` itself here - on a partial success it carries live
1954-
// tokens. The error-body branch above already surfaces the diagnosable case.
1911+
// Log only the shape, never `data` itself - on a partial success it can
1912+
// carry live tokens.
19551913
logger.warn('No access token found in refresh response', {
19561914
providerId,
19571915
responseKeys: Object.keys(data ?? {}),

apps/sim/lib/oauth/terminal-errors.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,6 @@ const TERMINAL_ERRORS = new Set<string>([
1111
'bad_client_secret',
1212
'invalid_client_id',
1313
'invalid_client',
14-
// Zoho's code for a revoked or otherwise unusable refresh token (it reserves
15-
// `invalid_client` for a wrong client id/secret). Without this a revoked Zoho
16-
// credential is never dead-flagged and every execution retries a refresh that
17-
// can never succeed.
18-
'invalid_code',
1914
'bad_redirect_uri',
2015
'token_revoked',
2116
])

0 commit comments

Comments
 (0)