feat: add github oauth

This commit is contained in:
2024-11-17 17:54:41 +07:00
parent c8e61ed4aa
commit a6cc450ea7
22 changed files with 419 additions and 74 deletions
@@ -0,0 +1,42 @@
import React, { useEffect, useMemo } from "react";
import { makeRedirectUri, useAuthRequest } from "expo-auth-session";
import appConfig from "@/app.json";
import { Button } from "tamagui";
import { useOAuthCallback } from "../hooks";
import { useServerConfig } from "@/hooks/useServerConfig";
const LoginGithubButton = () => {
const { data: clientId } = useServerConfig("github_client_id");
const discovery = useMemo(() => {
return {
authorizationEndpoint: "https://github.com/login/oauth/authorize",
tokenEndpoint: "https://github.com/login/oauth/access_token",
revocationEndpoint: `https://github.com/settings/connections/applications/${clientId}`,
};
}, [clientId]);
const oauth = useOAuthCallback("github");
const [request, response, promptAsync] = useAuthRequest(
{
clientId: clientId,
scopes: ["identity"],
redirectUri: makeRedirectUri({ scheme: appConfig.scheme }),
},
discovery
);
useEffect(() => {
if (response?.type === "success") {
const { code } = response.params;
oauth.mutate(code);
}
}, [response]);
return (
<Button disabled={!request} onPress={() => promptAsync()}>
Login with Github
</Button>
);
};
export default LoginGithubButton;
+17
View File
@@ -42,3 +42,20 @@ export const useRegisterMutation = () => {
},
});
};
export const useOAuthCallback = (type: string) => {
return useMutation({
mutationFn: async (code: string) => {
const res = await api(`/auth/oauth/${type}/callback?code=${code}`);
const { data } = loginResultSchema.safeParse(res);
if (!data) {
throw new Error("Invalid response!");
}
return data;
},
onSuccess(data) {
authStore.setState({ token: data.sessionId });
router.replace("/");
},
});
};
+16 -2
View File
@@ -6,17 +6,21 @@ import { useZForm } from "@/hooks/useZForm";
import { Link, router, Stack } from "expo-router";
import Button from "@/components/ui/button";
import ThemeSwitcher from "@/components/containers/theme-switcher";
import { useMutation } from "@tanstack/react-query";
import { z } from "zod";
import * as WebBrowser from "expo-web-browser";
import { ErrorAlert } from "@/components/ui/alert";
import { loginSchema } from "./schema";
import Icons from "@/components/ui/icons";
import tamaguiConfig from "@/tamagui.config";
import { useLoginMutation } from "./hooks";
import LoginGithubButton from "./components/login-github";
import { useServerConfig } from "@/hooks/useServerConfig";
WebBrowser.maybeCompleteAuthSession();
export default function LoginPage() {
const form = useZForm(loginSchema);
const login = useLoginMutation();
const { data: oauthList } = useServerConfig("oauth");
const onSubmit = form.handleSubmit((values) => {
login.mutate(values);
@@ -98,6 +102,16 @@ export default function LoginPage() {
</Link>
</XStack>
{oauthList?.length > 0 && (
<>
<Text textAlign="center" fontSize="$3">
or
</Text>
{oauthList.includes("github") && <LoginGithubButton />}
</>
)}
<Separator w="100%" />
<Button
@@ -1,5 +1,5 @@
import React, { useMemo, useState } from "react";
import { Avatar, Button, ListItem, View, YGroup } from "tamagui";
import { Button, ListItem, View, YGroup } from "tamagui";
import MenuButton from "@/components/ui/menu-button";
import Icons from "@/components/ui/icons";
import SearchInput from "@/components/ui/search-input";
@@ -7,6 +7,7 @@ import { useTeamId } from "@/stores/auth";
import { changeRoleModal } from "./change-role-form";
import { useRemoveMemberMutation } from "../hooks/query";
import { showDialog } from "@/hooks/useDialog";
import Avatar from "@/components/ui/avatar";
type Props = {
members?: any[];
@@ -59,11 +60,7 @@ const MemberList = ({ members, allowWrite }: Props) => {
title={member.user?.name}
subTitle={member.role}
pr="$2"
icon={
<Avatar size="$3" circular>
<Avatar.Fallback bg="$blue5" />
</Avatar>
}
icon={<Avatar src={member.user?.image} size="$4" />}
iconAfter={
allowWrite ? (
<MemberActionButton