Skip to content

Commit 4334c60

Browse files
committed
feat: browse 페이지에 로그인 기능 추가
1 parent 6ff1a18 commit 4334c60

File tree

3 files changed

+91
-12
lines changed

3 files changed

+91
-12
lines changed

src/pages/browse/[userId].tsx

Lines changed: 79 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
import {
2-
GetServerSideProps,
1+
import type {
32
GetStaticPaths,
43
GetStaticProps,
5-
InferGetServerSidePropsType,
64
InferGetStaticPropsType,
75
} from 'next';
8-
import { createServerSideHelpers } from '@trpc/react-query/server';
6+
import { useState, useEffect, useCallback } from 'react';
97
import { api } from '~/utils/api';
108
import { formatDistanceToNow } from 'date-fns';
119
import styled from '@emotion/styled';
@@ -45,11 +43,80 @@ const FileCard = styled('div')({
4543
const BrowsePage = ({
4644
userId,
4745
}: InferGetStaticPropsType<typeof getStaticProps>) => {
48-
const { data: filesData } = api.s3.listUserFiles.useQuery(
49-
{ userId },
50-
{ enabled: userId !== undefined }
46+
const [token, setToken] = useState<string | null>(null);
47+
const utils = api.useContext();
48+
49+
const { data: currentUser } = api.account.getCurrentUser.useQuery(undefined, {
50+
enabled: !!token,
51+
});
52+
53+
const signInMutation = api.account.signIn.useMutation({
54+
onSuccess: (data) => {
55+
setToken(data.token);
56+
localStorage.setItem('authToken', data.token);
57+
void utils.s3.listUserFiles.invalidate();
58+
},
59+
});
60+
61+
const { data: filesData, error: filesError } = api.s3.listUserFiles.useQuery(
62+
undefined,
63+
{ enabled: !!token }
5164
);
5265

66+
const handleLogin = useCallback(async () => {
67+
const email = window.prompt('Email:');
68+
if (!email) return;
69+
70+
const password = window.prompt('Password:');
71+
if (!password) return;
72+
73+
void signInMutation.mutate({ email, password });
74+
}, [signInMutation]);
75+
76+
// Check for stored token on mount
77+
useEffect(() => {
78+
const storedToken = localStorage.getItem('authToken');
79+
if (storedToken) {
80+
if (!currentUser || currentUser.name === userId) {
81+
setToken(storedToken);
82+
} else {
83+
localStorage.removeItem('authToken');
84+
}
85+
} else if (!signInMutation.isPending && !signInMutation.error) {
86+
void handleLogin();
87+
}
88+
}, [currentUser, userId, handleLogin, signInMutation]);
89+
90+
if (signInMutation.error) {
91+
return (
92+
<Container>
93+
<Title>Login Failed</Title>
94+
<div className="text-center text-red-500">
95+
Please refresh to try again.
96+
</div>
97+
</Container>
98+
);
99+
}
100+
101+
if (!token || !currentUser) {
102+
return (
103+
<Container>
104+
<Title>Waiting for authentication...</Title>
105+
</Container>
106+
);
107+
}
108+
109+
if (currentUser.name !== userId) {
110+
return (
111+
<Container>
112+
<Title>Access Denied</Title>
113+
<div className="text-center text-red-500">
114+
You cannot access files that do not belong to you.
115+
</div>
116+
</Container>
117+
);
118+
}
119+
53120
return (
54121
<Container>
55122
<Title>My Files</Title>
@@ -74,6 +141,11 @@ const BrowsePage = ({
74141
{filesData?.files.length === 0 && (
75142
<div className="text-center text-gray-500">No files found</div>
76143
)}
144+
{filesError && (
145+
<div className="text-center text-red-500">
146+
Error loading files. Please try again later.
147+
</div>
148+
)}
77149
</Grid>
78150
</Container>
79151
);

src/server/api/routers/s3.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@ import { env } from '~/env.js';
66
import {
77
createTRPCRouter,
88
protectedProcedure,
9-
publicProcedure,
109
} from '~/server/api/trpc';
1110
export const s3Router = createTRPCRouter({
12-
listUserFiles: publicProcedure
11+
listUserFiles: protectedProcedure
1312
.meta({
1413
openapi: {
1514
method: 'GET',
@@ -19,7 +18,7 @@ export const s3Router = createTRPCRouter({
1918
description: 'Returns list of files uploaded by the current user',
2019
},
2120
})
22-
.input(z.object({ userId: z.string() }))
21+
.input(z.void())
2322
.output(
2423
z.object({
2524
files: z.array(
@@ -33,10 +32,13 @@ export const s3Router = createTRPCRouter({
3332
),
3433
})
3534
)
36-
.query(async ({ ctx, input: { userId } }) => {
35+
.query(async ({ ctx }) => {
36+
// Use the authenticated user's name from the session
37+
const userName = ctx.session.user.name;
38+
3739
const response = await ctx.s3.listObjectsV2({
3840
Bucket: env.BUCKET_NAME,
39-
Prefix: `${userId}/`, // Only list objects that are in the user's folder
41+
Prefix: `${userName}/`, // Only list objects that are in the user's folder
4042
});
4143

4244
return {

src/utils/api.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ export const api = createTRPCNext<AppRouter>({
4040
*/
4141
transformer: superjson,
4242
url: `${getBaseUrl()}/api/trpc`,
43+
headers() {
44+
// Add auth token to all requests
45+
const token = localStorage.getItem("authToken");
46+
return token ? { Authorization: `Bearer ${token}` } : {};
47+
},
4348
}),
4449
],
4550
};

0 commit comments

Comments
 (0)