mirror of
https://github.com/khairul169/vaulterm.git
synced 2026-09-15 17:03:30 +07:00
feat: add github oauth
This commit is contained in:
@@ -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;
|
||||
@@ -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("/");
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user