Files
calendar/packages/platform/atoms/hooks/useOAuthClient.ts
T
+1
Lauris SkraucisGitHubunknown <>cubic-dev-ai[bot] <1082092+cubic-dev-ai[bot]@users.noreply.github.com>cubic-dev-ai[bot] <1082092+cubic-dev-ai[bot]@users.noreply.github.com>lauris@cal.com <lauris.skraucis@gmail.com>lauris@cal.com <lauris.skraucis@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>cubic-dev-ai[bot] <1082092+cubic-dev-ai[bot]@users.noreply.github.com>Rajiv Sahal
fc602d3b03 feat: OAuth 2.0 support for atoms (#27158)
* fix: useOAuthClient support OAuth 2.0

* fix: cannot read properties of undefined (reading NEXT_PUBLIC_IS_E2E)

* fix: allow OAuth 2.0 token to connect gcal or ms calendar

* fix: allow OAuth 2.0 token to save gcal or ms calendar credentials

* refactor: dont set oauth id header for OAuth 2.0

* fix: calendar events not showing and emails not sent

* feat: CalOAuth2Provider

* chore: make OAuth 2.0 work in examples app

* chore: refresh OAuth 2.0 tokens

* docs: running examples app with oauth 2.0

* fix: remove sensitive console.log statements that leak secrets

Remove logging of:
- OAuth authorization codes (oauth2-user.ts)
- Token-bearing exchange responses (oauth2-user.ts)
- /me response data containing PII (oauth2-user.ts)
- OAuth2 refresh response with tokens (refresh.ts)
- Response payload with access tokens (_app.tsx)

Addresses Cubic AI review feedback for issues with confidence >= 9/10

Co-Authored-By: unknown <>

* docs: update readme

* fix: implemente cubic feedback

* fix: seed script import

* fix: seed script pkce

* fix: correct typos and SQLite capitalization in OAuth2 README (#27176)

Co-authored-by: cubic-dev-ai[bot] <1082092+cubic-dev-ai[bot]@users.noreply.github.com>

* refactor: dont return name in public oauth endpoint

* docs: CalOAuthProvider

* chore: add NEXT_PUBLIC_IS_E2E constant to test

* docs: fix duplicated 'or' in Cal OAuth Provider documentation (#27177)

Co-authored-by: cubic-dev-ai[bot] <1082092+cubic-dev-ai[bot]@users.noreply.github.com>

* revert: is e2e constant

* fix: typecheck

* refactor: example app users select

* update readme

* chore: update oauth atoms readme

* refactor: enable booking managed event types with user.username instead of profile.username

* fix: EventTypeSettings when viewing round robin

* test: add e2e tests for atoms-oauth2 controller

Co-Authored-By: lauris@cal.com <lauris.skraucis@gmail.com>

* fix: correct error message path in atoms-oauth2 e2e test

Co-Authored-By: lauris@cal.com <lauris.skraucis@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <1082092+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Rajiv Sahal <sahalrajiv-extc@atharvacoe.ac.in>
2026-02-04 12:54:15 +01:00

73 lines
1.9 KiB
TypeScript

import type { AxiosError } from "axios";
import { useState, useEffect } from "react";
import { usePrevious } from "react-use";
import { SUCCESS_STATUS } from "@calcom/platform-constants";
import type { ApiResponse } from "@calcom/platform-types";
import http from "../lib/http";
interface OAuthClientData {
clientId: string;
organizationId: number | null;
}
export interface useOAuthClientProps {
isEmbed?: boolean;
clientId: string;
apiUrl?: string;
refreshUrl?: string;
onError: (error: string) => void;
onSuccess: (data: OAuthClientData) => void;
isOAuth2?: boolean;
}
export const useOAuthClient = ({
isEmbed,
clientId,
apiUrl,
refreshUrl,
onError,
onSuccess,
isOAuth2 = false,
}: useOAuthClientProps) => {
const prevClientId = usePrevious(clientId);
const [isInit, setIsInit] = useState<boolean>(false);
useEffect(() => {
if (apiUrl) {
http.setUrl(apiUrl);
setIsInit(true);
}
if (refreshUrl) {
http.setRefreshUrl(refreshUrl);
}
}, [apiUrl, refreshUrl]);
useEffect(() => {
if (!isEmbed && clientId && http.getUrl() && prevClientId !== clientId) {
try {
const fetchUrl = isOAuth2 ? `/atoms/auth/oauth2/clients/${clientId}` : `/provider/${clientId}`;
http
.get<ApiResponse<OAuthClientData>>(fetchUrl)
.then((response) => {
if (response.data.status === SUCCESS_STATUS) {
onSuccess(response.data.data);
}
if (!isOAuth2) {
http.setClientIdHeader(clientId);
}
})
.catch((err: AxiosError) => {
if (err.response?.status === 401) {
onError("Invalid oAuth Client.");
}
});
} catch (err) {
console.error(err);
}
}
}, [isEmbed, clientId, onError, prevClientId, onSuccess, http.getUrl()]);
return { isInit };
};