Skip to content

Commit 03773d9

Browse files
committed
fix: resolve ci issues
1 parent 15af719 commit 03773d9

3 files changed

Lines changed: 92 additions & 32 deletions

File tree

apps/backend/src/routes/auth.ts

Lines changed: 53 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1-
import type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';
2-
import { encrypt } from '../utils/encryption.js';
31
import { buildOAuthState, getMobileRedirectUri } from '../services/authService.js';
2+
import { encrypt } from '../utils/encryption.js';
3+
4+
import type {
5+
FastifyInstance,
6+
FastifyReply,
7+
FastifyRequest,
8+
} from 'fastify';
49

510
const GITHUB_AUTH_URL = 'https://github.com/login/oauth/authorize';
611
const GITHUB_TOKEN_URL = 'https://github.com/login/oauth/access_token';
@@ -14,7 +19,9 @@ interface OAuthCallbackQuery {
1419
state?: string;
1520
}
1621

17-
export async function authRoutes(app: FastifyInstance) {
22+
export async function authRoutes(
23+
app: FastifyInstance
24+
): Promise<void> {
1825
// Developer login bypass (development only)
1926
if (process.env.NODE_ENV !== 'production') {
2027
app.post('/dev-login', async (request: FastifyRequest, reply: FastifyReply) => {
@@ -289,13 +296,34 @@ if (existingUser) {
289296
});
290297

291298
// Current user
292-
app.get('/me', { preHandler: [async (request, reply) => {
293-
const server = request.server as any;
294-
if (typeof server?.authenticate === 'function') { await server.authenticate(request, reply); return }
295-
if (typeof (app as any).authenticate === 'function') { await (app as any).authenticate(request, reply); return }
296-
try { await request.jwtVerify() } catch (e) { reply.status(401).send({ error: 'Unauthorized' }) }
297-
}] }, async (request: FastifyRequest, reply: FastifyReply) => {
299+
app.get(
300+
'/me',
301+
{
302+
preHandler: [
303+
async (request, reply): Promise<void> => {
304+
const server = request.server as any;
305+
306+
if (typeof server?.authenticate === 'function') {
307+
await server.authenticate(request, reply);
308+
return;
309+
}
310+
311+
if (typeof (app as any).authenticate === 'function') {
312+
await (app as any).authenticate(request, reply);
313+
return;
314+
}
315+
316+
try {
317+
await request.jwtVerify();
318+
} catch {
319+
reply.status(401).send({ error: 'Unauthorized' });
320+
}
321+
},
322+
],
323+
},
324+
async (request: FastifyRequest, reply: FastifyReply) => {
298325
const userId = (request.user as any).id;
326+
299327
const user = await app.prisma.user.findUnique({
300328
where: { id: userId },
301329
select: {
@@ -310,20 +338,28 @@ if (existingUser) {
310338
avatarUrl: true,
311339
accentColor: true,
312340
createdAt: true,
313-
oauthTokens: { select: { platform: true, scopes: true, createdAt: true } },
341+
oauthTokens: {
342+
select: {
343+
platform: true,
344+
scopes: true,
345+
createdAt: true,
346+
},
347+
},
314348
},
315349
});
316350

317351
if (!user) {
318-
return reply.status(404).send({ error: 'User not found' });
352+
return reply.status(404).send({
353+
error: 'User not found',
354+
});
319355
}
320356

321357
const { oauthTokens, ...userData } = user;
322-
return { ...userData, connectedPlatforms: oauthTokens };
323-
});
324358

325-
app.post('/logout', async (request: FastifyRequest, reply: FastifyReply) => {
326-
reply.clearCookie('token', { path: '/' });
327-
return { message: 'Logged out' };
328-
});
359+
return {
360+
...userData,
361+
connectedPlatforms: oauthTokens,
362+
};
363+
}
364+
);
329365
}

apps/web/src/lib/theme.tsx

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1-
import { createContext, useContext, useEffect, useState, type ReactNode } from 'react';
1+
import {
2+
createContext,
3+
useContext,
4+
useEffect,
5+
useState,
6+
type ReactNode,
7+
} from 'react';
28

3-
type Theme = 'light' | 'dark';
9+
import { getInitialTheme, type Theme } from './theme.utils';
410

511
interface ThemeContextValue {
612
theme: Theme;
@@ -9,29 +15,28 @@ interface ThemeContextValue {
915

1016
const ThemeContext = createContext<ThemeContextValue | null>(null);
1117

12-
function getInitialTheme(): Theme {
13-
if (typeof window === 'undefined') return 'dark';
14-
15-
const stored = localStorage.getItem('devcard-theme');
16-
if (stored === 'light' || stored === 'dark') return stored;
17-
18-
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
19-
}
20-
21-
export function ThemeProvider({ children }: { children: ReactNode }) {
18+
export function ThemeProvider({
19+
children,
20+
}: {
21+
children: ReactNode;
22+
}) {
2223
const [theme, setTheme] = useState<Theme>(getInitialTheme);
2324

2425
useEffect(() => {
2526
const root = document.documentElement;
27+
2628
if (theme === 'dark') {
2729
root.classList.add('dark');
2830
} else {
2931
root.classList.remove('dark');
3032
}
33+
3134
localStorage.setItem('devcard-theme', theme);
3235
}, [theme]);
3336

34-
const toggleTheme = () => setTheme((t) => (t === 'dark' ? 'light' : 'dark'));
37+
const toggleTheme = () => {
38+
setTheme((t) => (t === 'dark' ? 'light' : 'dark'));
39+
};
3540

3641
return (
3742
<ThemeContext.Provider value={{ theme, toggleTheme }}>
@@ -42,6 +47,10 @@ export function ThemeProvider({ children }: { children: ReactNode }) {
4247

4348
export function useTheme(): ThemeContextValue {
4449
const ctx = useContext(ThemeContext);
45-
if (!ctx) throw new Error('useTheme must be used within ThemeProvider');
50+
51+
if (!ctx) {
52+
throw new Error('useTheme must be used within ThemeProvider');
53+
}
54+
4655
return ctx;
47-
}
56+
}

apps/web/src/lib/theme.utils.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export type Theme = 'light' | 'dark';
2+
3+
export function getInitialTheme(): Theme {
4+
if (typeof window === 'undefined') return 'dark';
5+
6+
const stored = localStorage.getItem('devcard-theme');
7+
8+
if (stored === 'light' || stored === 'dark') {
9+
return stored;
10+
}
11+
12+
return window.matchMedia('(prefers-color-scheme: dark)').matches
13+
? 'dark'
14+
: 'light';
15+
}

0 commit comments

Comments
 (0)