Skip to content

Commit 040ffa7

Browse files
committed
Refactor authentication handling in Supabase integration
- Introduced `getAuthenticatedUser` function to streamline user authentication retrieval for both cookie-based and Bearer token auth. - Updated various API routes to utilize the new `getAuthenticatedUser` function, simplifying the authentication logic. - Modified test files to mock the new authentication method, ensuring consistent behavior across tests. - Added new commands to local settings for building and testing with pnpm. release:patch
1 parent 8c0594b commit 040ffa7

16 files changed

Lines changed: 135 additions & 328 deletions

File tree

.claude/settings.local.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,9 @@
206206
"Bash(./.husky/pre-commit)",
207207
"Bash(gh release edit:*)",
208208
"Bash(base64:*)",
209-
"Bash(jq -r '.version' echo -e \"\\\\n=== Gentoo ===\")"
209+
"Bash(jq -r '.version' echo -e \"\\\\n=== Gentoo ===\")",
210+
"Bash(pnpm turbo build:*)",
211+
"Bash(pnpm turbo test:*)"
210212
],
211213
"deny": [
212214
"Bash(npm *)",

apps/web/src/app/api/auth/session/route.test.ts

Lines changed: 13 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ import { describe, it, expect, vi, beforeEach } from 'vitest';
22
import { GET } from './route';
33
import { createMockSupabaseClient, mockUser, mockProfile } from '@/test/mocks/supabase';
44

5+
const mockGetAuthenticatedUser = vi.fn();
6+
57
vi.mock('@/lib/supabase/server', () => ({
68
createClient: vi.fn(),
9+
getAuthenticatedUser: (...args: unknown[]) => mockGetAuthenticatedUser(...args),
710
}));
811

912
import { createClient } from '@/lib/supabase/server';
@@ -22,15 +25,10 @@ describe('GET /api/auth/session', () => {
2225
});
2326

2427
const mockSupabase = createMockSupabaseClient({
25-
auth: {
26-
getUser: vi.fn().mockResolvedValue({
27-
data: { user: mockUser },
28-
error: null,
29-
}),
30-
},
3128
from: mockFrom,
3229
});
3330
vi.mocked(createClient).mockResolvedValue(mockSupabase as never);
31+
mockGetAuthenticatedUser.mockResolvedValue({ user: mockUser, error: null });
3432

3533
const response = await GET();
3634
const body = await response.json();
@@ -42,15 +40,9 @@ describe('GET /api/auth/session', () => {
4240
});
4341

4442
it('returns null user and profile for unauthenticated request', async () => {
45-
const mockSupabase = createMockSupabaseClient({
46-
auth: {
47-
getUser: vi.fn().mockResolvedValue({
48-
data: { user: null },
49-
error: null,
50-
}),
51-
},
52-
});
43+
const mockSupabase = createMockSupabaseClient({});
5344
vi.mocked(createClient).mockResolvedValue(mockSupabase as never);
45+
mockGetAuthenticatedUser.mockResolvedValue({ user: null, error: null });
5446

5547
const response = await GET();
5648
const body = await response.json();
@@ -61,15 +53,12 @@ describe('GET /api/auth/session', () => {
6153
});
6254

6355
it('returns null when auth error occurs', async () => {
64-
const mockSupabase = createMockSupabaseClient({
65-
auth: {
66-
getUser: vi.fn().mockResolvedValue({
67-
data: { user: null },
68-
error: { message: 'Session expired' },
69-
}),
70-
},
71-
});
56+
const mockSupabase = createMockSupabaseClient({});
7257
vi.mocked(createClient).mockResolvedValue(mockSupabase as never);
58+
mockGetAuthenticatedUser.mockResolvedValue({
59+
user: null,
60+
error: { message: 'Session expired' },
61+
});
7362

7463
const response = await GET();
7564
const body = await response.json();
@@ -90,15 +79,10 @@ describe('GET /api/auth/session', () => {
9079
});
9180

9281
const mockSupabase = createMockSupabaseClient({
93-
auth: {
94-
getUser: vi.fn().mockResolvedValue({
95-
data: { user: mockUser },
96-
error: null,
97-
}),
98-
},
9982
from: mockFrom,
10083
});
10184
vi.mocked(createClient).mockResolvedValue(mockSupabase as never);
85+
mockGetAuthenticatedUser.mockResolvedValue({ user: mockUser, error: null });
10286

10387
const response = await GET();
10488
const body = await response.json();
@@ -119,15 +103,10 @@ describe('GET /api/auth/session', () => {
119103
});
120104

121105
const mockSupabase = createMockSupabaseClient({
122-
auth: {
123-
getUser: vi.fn().mockResolvedValue({
124-
data: { user: mockUser },
125-
error: null,
126-
}),
127-
},
128106
from: mockFrom,
129107
});
130108
vi.mocked(createClient).mockResolvedValue(mockSupabase as never);
109+
mockGetAuthenticatedUser.mockResolvedValue({ user: mockUser, error: null });
131110

132111
const response = await GET();
133112

apps/web/src/app/api/auth/session/route.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
1-
import { createClient } from '@/lib/supabase/server';
1+
import { createClient, getAuthenticatedUser } from '@/lib/supabase/server';
22
import { successResponse, handleApiError } from '@/lib/api';
33

44
export async function GET() {
55
try {
66
const supabase = await createClient();
77

8-
const {
9-
data: { user },
10-
error: authError,
11-
} = await supabase.auth.getUser();
8+
const { user, error: authError } = await getAuthenticatedUser(supabase);
129

1310
if (authError || !user) {
1411
return successResponse({ user: null, profile: null });

apps/web/src/app/api/chat/history/route.test.ts

Lines changed: 15 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ import { describe, it, expect, vi, beforeEach } from 'vitest';
22
import { GET } from './route';
33
import { createMockSupabaseClient, mockUser } from '@/test/mocks/supabase';
44

5+
const mockGetAuthenticatedUser = vi.fn();
6+
57
vi.mock('@/lib/supabase/server', () => ({
68
createClient: vi.fn(),
9+
getAuthenticatedUser: (...args: unknown[]) => mockGetAuthenticatedUser(...args),
710
}));
811

912
import { createClient } from '@/lib/supabase/server';
@@ -57,15 +60,10 @@ describe('GET /api/chat/history', () => {
5760
});
5861

5962
const mockSupabase = createMockSupabaseClient({
60-
auth: {
61-
getUser: vi.fn().mockResolvedValue({
62-
data: { user: mockUser },
63-
error: null,
64-
}),
65-
},
6663
from: mockFrom,
6764
});
6865
vi.mocked(createClient).mockResolvedValue(mockSupabase as never);
66+
mockGetAuthenticatedUser.mockResolvedValue({ user: mockUser, error: null });
6967

7068
const sessionId = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890';
7169
const request = new Request(`http://localhost/api/chat/history?sessionId=${sessionId}`);
@@ -98,15 +96,10 @@ describe('GET /api/chat/history', () => {
9896
});
9997

10098
const mockSupabase = createMockSupabaseClient({
101-
auth: {
102-
getUser: vi.fn().mockResolvedValue({
103-
data: { user: mockUser },
104-
error: null,
105-
}),
106-
},
10799
from: mockFrom,
108100
});
109101
vi.mocked(createClient).mockResolvedValue(mockSupabase as never);
102+
mockGetAuthenticatedUser.mockResolvedValue({ user: mockUser, error: null });
110103

111104
const sessionId = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890';
112105
const request = new Request(`http://localhost/api/chat/history?sessionId=${sessionId}`);
@@ -132,15 +125,10 @@ describe('GET /api/chat/history', () => {
132125
});
133126

134127
const mockSupabase = createMockSupabaseClient({
135-
auth: {
136-
getUser: vi.fn().mockResolvedValue({
137-
data: { user: mockUser },
138-
error: null,
139-
}),
140-
},
141128
from: mockFrom,
142129
});
143130
vi.mocked(createClient).mockResolvedValue(mockSupabase as never);
131+
mockGetAuthenticatedUser.mockResolvedValue({ user: mockUser, error: null });
144132

145133
const sessionId = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890';
146134
const before = '2024-01-01T00:00:30Z';
@@ -165,15 +153,10 @@ describe('GET /api/chat/history', () => {
165153
});
166154

167155
const mockSupabase = createMockSupabaseClient({
168-
auth: {
169-
getUser: vi.fn().mockResolvedValue({
170-
data: { user: mockUser },
171-
error: null,
172-
}),
173-
},
174156
from: mockFrom,
175157
});
176158
vi.mocked(createClient).mockResolvedValue(mockSupabase as never);
159+
mockGetAuthenticatedUser.mockResolvedValue({ user: mockUser, error: null });
177160

178161
const sessionId = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890';
179162
const request = new Request(`http://localhost/api/chat/history?sessionId=${sessionId}&limit=2`);
@@ -186,15 +169,9 @@ describe('GET /api/chat/history', () => {
186169
});
187170

188171
it('returns 400 for invalid session ID', async () => {
189-
const mockSupabase = createMockSupabaseClient({
190-
auth: {
191-
getUser: vi.fn().mockResolvedValue({
192-
data: { user: mockUser },
193-
error: null,
194-
}),
195-
},
196-
});
172+
const mockSupabase = createMockSupabaseClient({});
197173
vi.mocked(createClient).mockResolvedValue(mockSupabase as never);
174+
mockGetAuthenticatedUser.mockResolvedValue({ user: mockUser, error: null });
198175

199176
const request = new Request('http://localhost/api/chat/history?sessionId=invalid');
200177

@@ -203,15 +180,9 @@ describe('GET /api/chat/history', () => {
203180
});
204181

205182
it('returns 400 for missing session ID', async () => {
206-
const mockSupabase = createMockSupabaseClient({
207-
auth: {
208-
getUser: vi.fn().mockResolvedValue({
209-
data: { user: mockUser },
210-
error: null,
211-
}),
212-
},
213-
});
183+
const mockSupabase = createMockSupabaseClient({});
214184
vi.mocked(createClient).mockResolvedValue(mockSupabase as never);
185+
mockGetAuthenticatedUser.mockResolvedValue({ user: mockUser, error: null });
215186

216187
const request = new Request('http://localhost/api/chat/history');
217188

@@ -220,15 +191,9 @@ describe('GET /api/chat/history', () => {
220191
});
221192

222193
it('returns 400 for limit out of range', async () => {
223-
const mockSupabase = createMockSupabaseClient({
224-
auth: {
225-
getUser: vi.fn().mockResolvedValue({
226-
data: { user: mockUser },
227-
error: null,
228-
}),
229-
},
230-
});
194+
const mockSupabase = createMockSupabaseClient({});
231195
vi.mocked(createClient).mockResolvedValue(mockSupabase as never);
196+
mockGetAuthenticatedUser.mockResolvedValue({ user: mockUser, error: null });
232197

233198
const sessionId = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890';
234199
const request = new Request(
@@ -249,15 +214,10 @@ describe('GET /api/chat/history', () => {
249214
});
250215

251216
const mockSupabase = createMockSupabaseClient({
252-
auth: {
253-
getUser: vi.fn().mockResolvedValue({
254-
data: { user: mockUser },
255-
error: null,
256-
}),
257-
},
258217
from: mockFrom,
259218
});
260219
vi.mocked(createClient).mockResolvedValue(mockSupabase as never);
220+
mockGetAuthenticatedUser.mockResolvedValue({ user: mockUser, error: null });
261221

262222
const sessionId = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890';
263223
const request = new Request(`http://localhost/api/chat/history?sessionId=${sessionId}`);
@@ -283,15 +243,10 @@ describe('GET /api/chat/history', () => {
283243
});
284244

285245
const mockSupabase = createMockSupabaseClient({
286-
auth: {
287-
getUser: vi.fn().mockResolvedValue({
288-
data: { user: mockUser },
289-
error: null,
290-
}),
291-
},
292246
from: mockFrom,
293247
});
294248
vi.mocked(createClient).mockResolvedValue(mockSupabase as never);
249+
mockGetAuthenticatedUser.mockResolvedValue({ user: mockUser, error: null });
295250

296251
const sessionId = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890';
297252
const request = new Request(`http://localhost/api/chat/history?sessionId=${sessionId}`);

apps/web/src/app/api/chat/history/route.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createClient } from '@/lib/supabase/server';
1+
import { createClient, getAuthenticatedUser } from '@/lib/supabase/server';
22
import { successResponse, errorResponse, handleApiError } from '@/lib/api';
33
import { z } from 'zod';
44

@@ -24,9 +24,7 @@ export async function GET(request: Request) {
2424
const supabase = await createClient();
2525

2626
// Check authentication (for RLS policies)
27-
const {
28-
data: { user },
29-
} = await supabase.auth.getUser();
27+
const { user } = await getAuthenticatedUser(supabase);
3028

3129
// Build query
3230
let query = supabase

0 commit comments

Comments
 (0)