Skip to content

Commit

Permalink
mobile auth functional
Browse files Browse the repository at this point in the history
  • Loading branch information
nickcherry committed Jan 31, 2024
1 parent ef7943c commit c4516f1
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 67 deletions.
75 changes: 45 additions & 30 deletions mobile/src/contexts/AuthProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { AuthKitProvider, useSignIn } from '@farcaster/auth-kit';
import {
AuthKitProvider,
StatusAPIResponse,
useSignIn,
} from '@farcaster/auth-kit';
import { FullscreenLoader } from '@mobile/components/loader/FullscreenLoader';
import { useFetchProfile } from '@mobile/hooks/data/profile';
import { User } from '@shared/types/models';
Expand All @@ -10,6 +14,7 @@ import {
useContext,
useEffect,
useReducer,
useRef,
} from 'react';
import { Linking } from 'react-native';

Expand Down Expand Up @@ -87,48 +92,58 @@ type AuthProviderProps = {
function AuthProviderContent({ children }: AuthProviderProps) {
const [state, dispatch] = useReducer(reducer, initialState);
const fetchProfile = useFetchProfile();
const hasConnectedRef = useRef(false);
const hasLinkedUserRef = useRef(false);

const {
connect,
url,
signIn: authKitSignIn,
} = useSignIn({
onSuccess: async (res) => {
const signInResponse = await fetch(
'http://localhost:3000/api/auth/sign-in',
{
method: 'POST',
body: JSON.stringify({
message: res.message,
nonce: res.nonce,
signature: res.signature,
}),
},
);

if (signInResponse.ok) {
const { token, fid }: { token: string; fid: string } =
await signInResponse.json();

const { profile: user } = await fetchProfile({ fid });
dispatch({ type: 'signIn', session: { token, fid }, user });
} else {
alert('Sign in failed');
}
},
onSuccess: useCallback(
async (res: StatusAPIResponse) => {
const signInResponse = await fetch(
'http://localhost:3000/api/auth/sign-in',
{
method: 'POST',
body: JSON.stringify({
message: res.message,
nonce: res.nonce,
signature: res.signature,
}),
},
);

if (signInResponse.ok) {
const { token, fid }: { token: string; fid: string } =
await signInResponse.json();

const { profile: user } = await fetchProfile({ fid });
dispatch({ type: 'signIn', session: { token, fid }, user });
} else {
alert('Sign in failed');
}
},
[fetchProfile],
),
});

const requestSignIn = useCallback(async () => {
if (!url) {
throw new Error('Expected authkit to provide url');
if (!hasConnectedRef.current) {
hasConnectedRef.current = true;
connect();
}
}, [connect, hasConnectedRef]);

useEffect(() => {
if (url) {
await connect();
await authKitSignIn(); // Starts polling
Linking.openURL(url);
authKitSignIn();
if (!hasLinkedUserRef.current) {
hasLinkedUserRef.current = true;
Linking.openURL(url);
}
}
}, [authKitSignIn, connect, url]);
}, [authKitSignIn, url]);

const signOut = useCallback(async () => {
await fetch('http://localhost:3000/api/auth/sign-out', { method: 'POST' });
Expand Down
14 changes: 9 additions & 5 deletions mobile/src/hooks/data/feed.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { baseApiUrl } from '@mobile/constants/api';
import { FeedApiResponse } from '@shared/types/api';
import { useQueryClient, useSuspenseQuery } from '@tanstack/react-query';
import { useCallback } from 'react';

function buildFeedKey({ fid }: { fid: string }) {
return ['feed', fid];
Expand All @@ -23,9 +24,12 @@ export function useFeed({ fid }: { fid: string }) {
export function useFetchFeed() {
const queryClient = useQueryClient();

return async ({ fid }: { fid: string }) => {
const data = buildFeedFetcher({ fid })();
queryClient.setQueryData(buildFeedKey({ fid }), data);
return data;
};
return useCallback(
async ({ fid }: { fid: string }) => {
const data = buildFeedFetcher({ fid })();
queryClient.setQueryData(buildFeedKey({ fid }), data);
return data;
},
[queryClient],
);
}
14 changes: 9 additions & 5 deletions mobile/src/hooks/data/profile.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { baseApiUrl } from '@mobile/constants/api';
import { ProfileApiResponse } from '@shared/types/api';
import { useQueryClient, useSuspenseQuery } from '@tanstack/react-query';
import { useCallback } from 'react';

function buildProfileKey({ fid }: { fid: string }) {
return ['profile', fid];
Expand All @@ -23,9 +24,12 @@ export function useProfile({ fid }: { fid: string }) {
export function useFetchProfile() {
const queryClient = useQueryClient();

return async ({ fid }: { fid: string }) => {
const data = buildProfileFetcher({ fid })();
queryClient.setQueryData(buildProfileKey({ fid }), data);
return data;
};
return useCallback(
async ({ fid }: { fid: string }) => {
const data = buildProfileFetcher({ fid })();
queryClient.setQueryData(buildProfileKey({ fid }), data);
return data;
},
[queryClient],
);
}
14 changes: 9 additions & 5 deletions mobile/src/hooks/data/profileCasts.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { baseApiUrl } from '@mobile/constants/api';
import { ProfileCastsApiResponse } from '@shared/types/api';
import { useQueryClient, useSuspenseQuery } from '@tanstack/react-query';
import { useCallback } from 'react';

function buildProfileCastsKey({ fid }: { fid: string }) {
return ['profileCasts', fid];
Expand All @@ -23,9 +24,12 @@ export function useProfileCasts({ fid }: { fid: string }) {
export function useFetchProfileCasts() {
const queryClient = useQueryClient();

return async ({ fid }: { fid: string }) => {
const data = buildProfileCastsFetcher({ fid })();
queryClient.setQueryData(buildProfileCastsKey({ fid }), data);
return data;
};
return useCallback(
async ({ fid }: { fid: string }) => {
const data = buildProfileCastsFetcher({ fid })();
queryClient.setQueryData(buildProfileCastsKey({ fid }), data);
return data;
},
[queryClient],
);
}
15 changes: 15 additions & 0 deletions web/src/app/api/feed/[fid]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { getFeed } from '@lib/services/feed';
import { FeedApiResponse } from '@shared/types/api';
import { NextResponse } from 'next/server';

export async function GET(
request: Request,
{ params: { fid } }: { params: { fid: string | undefined } },
) {
if (!fid) {
return NextResponse.json({ error: 'fid is required' }, { status: 400 });
}

const payload: FeedApiResponse = { feed: await getFeed({ fid }) };
return NextResponse.json(payload);
}
12 changes: 0 additions & 12 deletions web/src/app/api/feed/route.ts

This file was deleted.

10 changes: 5 additions & 5 deletions web/src/app/api/profiles/[fid]/casts/route.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { getCasts } from "@lib/services/casts";
import { ProfileCastsApiResponse } from "@shared/types/api";
import { NextResponse } from "next/server";
import { getCasts } from '@lib/services/casts';
import { ProfileCastsApiResponse } from '@shared/types/api';
import { NextResponse } from 'next/server';

export async function GET(
_request: Request,
{ params: { fid } }: { params: { fid: string } },
{ params: { fid } }: { params: { fid: string | undefined } },
) {
if (!fid) {
return NextResponse.json({ error: "fid is required" }, { status: 400 });
return NextResponse.json({ error: 'fid is required' }, { status: 400 });
}

const payload: ProfileCastsApiResponse = { casts: await getCasts({ fid }) };
Expand Down
10 changes: 5 additions & 5 deletions web/src/app/api/profiles/[fid]/route.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { getProfile } from "@lib/services/user";
import { ProfileApiResponse } from "@shared/types/api";
import { NextResponse } from "next/server";
import { getProfile } from '@lib/services/user';
import { ProfileApiResponse } from '@shared/types/api';
import { NextResponse } from 'next/server';

export async function GET(
_request: Request,
{ params: { fid } }: { params: { fid: string } },
{ params: { fid } }: { params: { fid: string | undefined } },
) {
if (!fid) {
return NextResponse.json({ error: "fid is required" }, { status: 400 });
return NextResponse.json({ error: 'fid is required' }, { status: 400 });
}

const payload: ProfileApiResponse = { profile: await getProfile({ fid }) };
Expand Down

0 comments on commit c4516f1

Please sign in to comment.