Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revoke post action #80

Merged
merged 2 commits into from
Sep 11, 2024
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
4 changes: 4 additions & 0 deletions src/components/oauth/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@ function Provider({
redirect_to: string;
}): JSX.Element {
const [isConnected, setConnected] = useState(connected);
const [isLoading, setIsLoading] = useState(false);
return (
<div className="mb-4 grid md:grid-cols-2 md:gap-6">
{name}
{isConnected ? (
<Button
disabled={isLoading}
onClick={async (ev) => {
ev.preventDefault();
setIsLoading(true);
const payload: DisconnectOauthProviderRequest = {
userAuthId,
provider: name,
Expand All @@ -39,6 +42,7 @@ function Provider({
setConnected(false);
}
}
setIsLoading(false);
}}
>
Disconnect
Expand Down
60 changes: 49 additions & 11 deletions src/lib/oauth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ export class Intf {
static async connect(_authorizationCode: string): Promise<OauthInput> {
throw Error("Not implemented");
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
static async revoke(_oauthInput: UserOauthInput): Promise<boolean> {
throw Error("Not implemented");
}
}

export class GCloud {
Expand Down Expand Up @@ -102,6 +107,24 @@ export class GCloud {
code: authorizationCode,
});
}

static async revoke(userOauth: OauthInput): Promise<boolean> {
const options = {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams({
token: userOauth.refreshToken,
}),
};
const res = await fetch("https://oauth2.googleapis.com/revoke", options);
if (res.status === 200) {
return true;
}
console.error("GCloud API error", await res.json());
return false;
}
}

export class Calendly {
Expand Down Expand Up @@ -169,6 +192,10 @@ export class Calendly {
const res = await fetch(`${Calendly.AUTH_URL}/oauth/token`, options);
return await Calendly.parseOauthResponse(res);
}

static async revoke(): Promise<boolean> {
return true;
}
}

export function OauthProviderOfString(
Expand Down Expand Up @@ -222,22 +249,27 @@ export async function findConnectedProviders(
return userAuth.UserOauth.map((oauthInfo) => oauthInfo.provider);
}

async function findUserOauth(
userAuthId: string,
provider: OauthProvider,
): Promise<UserOauth | null> {
return await prisma.userOauth.findUnique({
where: {
userAuthId_provider: {
userAuthId,
provider,
},
},
});
}

export async function getAccessToken(
userAuthId: string,
provider: OauthProvider,
userOauth?: UserOauth,
): Promise<string> {
// Try to retrieve the token from the db
let oauthInfo =
userOauth ||
(await prisma.userOauth.findUnique({
where: {
userAuthId_provider: {
userAuthId,
provider,
},
},
}));
let oauthInfo = userOauth || (await findUserOauth(userAuthId, provider));
if (!oauthInfo) {
throw Error(`Tienes que conectarte con el servicio ${provider} primero`);
}
Expand Down Expand Up @@ -273,6 +305,12 @@ export async function disconnectOauth({
userAuthId: string;
provider: OauthProvider;
}): Promise<boolean> {
const oauthInfo = await findUserOauth(userAuthId, provider);
if (!oauthInfo) {
return false;
}
const intf = providerIntf(provider);
const res = await intf.revoke(oauthInfo);
await prisma.userOauth.delete({
where: {
userAuthId_provider: {
Expand All @@ -281,5 +319,5 @@ export async function disconnectOauth({
},
},
});
return true;
return res;
}