Browse Source

fixes

drawing-pad
Stephanie Gredell 1 month ago
parent
commit
95443472d2
  1. 1
      .do/app.yaml
  2. 1
      .gitignore
  3. 1
      DEPLOYMENT.md
  4. 1
      QUICKSTART.md
  5. 1
      backend/package.json
  6. 1
      backend/src/config/database.ts
  7. 1
      backend/src/config/env.ts
  8. 11
      backend/src/controllers/auth.controller.ts
  9. 1
      backend/src/controllers/channels.controller.ts
  10. 1
      backend/src/middleware/auth.ts
  11. 1
      backend/src/middleware/errorHandler.ts
  12. 1
      backend/src/middleware/rateLimiter.ts
  13. 1
      backend/src/routes/auth.routes.ts
  14. 1
      backend/src/routes/channels.routes.ts
  15. 1
      backend/src/routes/videos.routes.ts
  16. 7
      backend/src/services/auth.service.ts
  17. 1
      backend/src/services/youtube.service.ts
  18. 1
      backend/src/setup/initialSetup.ts
  19. 1
      backend/src/types/index.ts
  20. 1
      backend/tsconfig.json
  21. 1
      frontend/index.html
  22. 1
      frontend/package.json
  23. 1
      frontend/src/App.css
  24. 1
      frontend/src/App.tsx
  25. 1
      frontend/src/components/ChannelManager/ChannelManager.css
  26. 1
      frontend/src/components/ChannelManager/ChannelManager.tsx
  27. 1
      frontend/src/components/ErrorBoundary.tsx
  28. 1
      frontend/src/components/ProtectedRoute.tsx
  29. 1
      frontend/src/components/SearchFilter/SearchFilter.css
  30. 1
      frontend/src/components/SearchFilter/SearchFilter.tsx
  31. 1
      frontend/src/components/VideoCard/VideoCard.css
  32. 1
      frontend/src/components/VideoCard/VideoCard.tsx
  33. 1
      frontend/src/components/VideoGrid/VideoGrid.css
  34. 1
      frontend/src/components/VideoGrid/VideoGrid.tsx
  35. 1
      frontend/src/components/VideoPlayer/VideoPlayer.css
  36. 1
      frontend/src/components/VideoPlayer/VideoPlayer.tsx
  37. 1
      frontend/src/hooks/useAuth.tsx
  38. 1
      frontend/src/hooks/useChannels.ts
  39. 1
      frontend/src/main.tsx
  40. 1
      frontend/src/pages/AdminPage.css
  41. 1
      frontend/src/pages/AdminPage.tsx
  42. 1
      frontend/src/pages/LoginPage.css
  43. 1
      frontend/src/pages/LoginPage.tsx
  44. 1
      frontend/src/services/apiClient.ts
  45. 1
      frontend/tsconfig.json
  46. 1
      frontend/tsconfig.node.json
  47. 1
      frontend/vite.config.ts
  48. 1
      navbar-refactor-plan.md
  49. 1
      package.json

1
.do/app.yaml

@ -68,3 +68,4 @@ static_sites:
routes: routes:
- path: / - path: /

1
.gitignore vendored

@ -41,3 +41,4 @@ coverage/
# Misc # Misc
.turso/ .turso/

1
DEPLOYMENT.md

@ -240,3 +240,4 @@ Available sizes:
**Ready to deploy?** Follow the steps above and you'll be live in minutes! 🚀 **Ready to deploy?** Follow the steps above and you'll be live in minutes! 🚀

1
QUICKSTART.md

@ -79,3 +79,4 @@ See [DEPLOYMENT.md](./DEPLOYMENT.md) for detailed instructions and troubleshooti
**Total: $5/month** **Total: $5/month**

1
backend/package.json

@ -34,3 +34,4 @@
} }
} }

1
backend/src/config/database.ts

@ -29,3 +29,4 @@ export async function setSetting(key: string, value: string): Promise<void> {
}); });
} }

1
backend/src/config/env.ts

@ -58,3 +58,4 @@ export const env = {
initialAdminPassword: process.env.INITIAL_ADMIN_PASSWORD initialAdminPassword: process.env.INITIAL_ADMIN_PASSWORD
}; };

11
backend/src/controllers/auth.controller.ts

@ -151,6 +151,16 @@ export async function logout(req: AuthRequest, res: Response) {
export async function getCurrentUser(req: AuthRequest, res: Response) { export async function getCurrentUser(req: AuthRequest, res: Response) {
try { try {
if (!req.userId) {
return res.status(401).json({
success: false,
error: {
code: 'UNAUTHORIZED',
message: 'User not authenticated'
}
});
}
const result = await db.execute({ const result = await db.execute({
sql: 'SELECT id, username, last_login FROM users WHERE id = ?', sql: 'SELECT id, username, last_login FROM users WHERE id = ?',
args: [req.userId] args: [req.userId]
@ -188,3 +198,4 @@ export async function getCurrentUser(req: AuthRequest, res: Response) {
} }
} }

1
backend/src/controllers/channels.controller.ts

@ -271,3 +271,4 @@ export async function refreshChannel(req: AuthRequest, res: Response) {
} }
} }

1
backend/src/middleware/auth.ts

@ -42,3 +42,4 @@ export function authMiddleware(
} }
} }

1
backend/src/middleware/errorHandler.ts

@ -22,3 +22,4 @@ export function errorHandler(
}); });
} }

1
backend/src/middleware/rateLimiter.ts

@ -28,3 +28,4 @@ export const apiLimiter = rateLimit({
legacyHeaders: false legacyHeaders: false
}); });

1
backend/src/routes/auth.routes.ts

@ -13,3 +13,4 @@ router.get('/me', authMiddleware, getCurrentUser);
export default router; export default router;

1
backend/src/routes/channels.routes.ts

@ -15,3 +15,4 @@ router.put('/:id/refresh', authMiddleware, refreshChannel);
export default router; export default router;

1
backend/src/routes/videos.routes.ts

@ -13,3 +13,4 @@ router.post('/refresh', authMiddleware, refreshVideos);
export default router; export default router;

7
backend/src/services/auth.service.ts

@ -9,7 +9,7 @@ export async function createTokens(userId: number, username: string) {
const accessToken = jwt.sign( const accessToken = jwt.sign(
{ userId, username, type: 'access' }, { userId, username, type: 'access' },
env.jwtSecret, env.jwtSecret,
{ expiresIn: env.accessTokenExpiry } { expiresIn: env.accessTokenExpiry as string }
); );
// Refresh token (long-lived) // Refresh token (long-lived)
@ -17,7 +17,7 @@ export async function createTokens(userId: number, username: string) {
const refreshToken = jwt.sign( const refreshToken = jwt.sign(
{ token: refreshTokenValue, userId, type: 'refresh' }, { token: refreshTokenValue, userId, type: 'refresh' },
env.jwtRefreshSecret, env.jwtRefreshSecret,
{ expiresIn: env.refreshTokenExpiry } { expiresIn: env.refreshTokenExpiry as string }
); );
// Store refresh token in database // Store refresh token in database
@ -59,7 +59,7 @@ export async function refreshAccessToken(refreshToken: string) {
const accessToken = jwt.sign( const accessToken = jwt.sign(
{ userId: tokenData.user_id, username: tokenData.username, type: 'access' }, { userId: tokenData.user_id, username: tokenData.username, type: 'access' },
env.jwtSecret, env.jwtSecret,
{ expiresIn: env.accessTokenExpiry } { expiresIn: env.accessTokenExpiry as string }
); );
return { accessToken }; return { accessToken };
@ -90,3 +90,4 @@ export async function hashPassword(password: string): Promise<string> {
return bcrypt.hash(password, 10); return bcrypt.hash(password, 10);
} }

1
backend/src/services/youtube.service.ts

@ -146,3 +146,4 @@ export function formatDuration(isoDuration: string): string {
return `${minutes || '0'}:${seconds.padStart(2, '0')}`; return `${minutes || '0'}:${seconds.padStart(2, '0')}`;
} }

1
backend/src/setup/initialSetup.ts

@ -27,3 +27,4 @@ export async function createInitialAdmin() {
} }
} }

1
backend/src/types/index.ts

@ -59,3 +59,4 @@ export interface ApiResponse<T = any> {
}; };
} }

1
backend/tsconfig.json

@ -17,3 +17,4 @@
"exclude": ["node_modules", "dist"] "exclude": ["node_modules", "dist"]
} }

1
frontend/index.html

@ -12,3 +12,4 @@
</body> </body>
</html> </html>

1
frontend/package.json

@ -23,3 +23,4 @@
} }
} }

1
frontend/src/App.css

@ -59,3 +59,4 @@ body {
background-color: #0556c4; background-color: #0556c4;
} }

1
frontend/src/App.tsx

@ -38,3 +38,4 @@ function App() {
export default App; export default App;

1
frontend/src/components/ChannelManager/ChannelManager.css

@ -172,3 +172,4 @@
} }
} }

1
frontend/src/components/ChannelManager/ChannelManager.tsx

@ -112,3 +112,4 @@ export function ChannelManager() {
); );
} }

1
frontend/src/components/ErrorBoundary.tsx

@ -40,3 +40,4 @@ export class ErrorBoundary extends React.Component<Props, State> {
} }
} }

1
frontend/src/components/ProtectedRoute.tsx

@ -19,3 +19,4 @@ export function ProtectedRoute({ children }: ProtectedRouteProps) {
return <>{children}</>; return <>{children}</>;
} }

1
frontend/src/components/SearchFilter/SearchFilter.css

@ -108,3 +108,4 @@
} }
} }

1
frontend/src/components/SearchFilter/SearchFilter.tsx

@ -80,3 +80,4 @@ export function SearchFilter({
); );
} }

1
frontend/src/components/VideoCard/VideoCard.css

@ -101,3 +101,4 @@
} }
} }

1
frontend/src/components/VideoCard/VideoCard.tsx

@ -61,3 +61,4 @@ export function VideoCard({ video, onClick }: VideoCardProps) {
); );
} }

1
frontend/src/components/VideoGrid/VideoGrid.css

@ -153,3 +153,4 @@
} }
} }

1
frontend/src/components/VideoGrid/VideoGrid.tsx

@ -117,3 +117,4 @@ export function VideoGrid({
); );
} }

1
frontend/src/components/VideoPlayer/VideoPlayer.css

@ -79,3 +79,4 @@
} }
} }

1
frontend/src/components/VideoPlayer/VideoPlayer.tsx

@ -42,3 +42,4 @@ export function VideoPlayer({ videoId, onClose }: VideoPlayerProps) {
); );
} }

1
frontend/src/hooks/useAuth.tsx

@ -69,3 +69,4 @@ export const useAuth = () => {
return context; return context;
}; };

1
frontend/src/hooks/useChannels.ts

@ -53,3 +53,4 @@ export function useChannels() {
}; };
} }

1
frontend/src/main.tsx

@ -8,3 +8,4 @@ ReactDOM.createRoot(document.getElementById('root')!).render(
</React.StrictMode>, </React.StrictMode>,
) )

1
frontend/src/pages/AdminPage.css

@ -23,3 +23,4 @@
color: #606060; color: #606060;
} }

1
frontend/src/pages/AdminPage.tsx

@ -14,3 +14,4 @@ export function AdminPage() {
); );
} }

1
frontend/src/pages/LoginPage.css

@ -97,3 +97,4 @@
cursor: not-allowed; cursor: not-allowed;
} }

1
frontend/src/pages/LoginPage.tsx

@ -72,3 +72,4 @@ export function LoginPage() {
); );
} }

1
frontend/src/services/apiClient.ts

@ -119,3 +119,4 @@ export const videosApi = {
api.post('/videos/refresh', { channelIds }) api.post('/videos/refresh', { channelIds })
}; };

1
frontend/tsconfig.json

@ -20,3 +20,4 @@
"references": [{ "path": "./tsconfig.node.json" }] "references": [{ "path": "./tsconfig.node.json" }]
} }

1
frontend/tsconfig.node.json

@ -9,3 +9,4 @@
"include": ["vite.config.ts"] "include": ["vite.config.ts"]
} }

1
frontend/vite.config.ts

@ -8,3 +8,4 @@ export default defineConfig({
} }
}) })

1
navbar-refactor-plan.md

@ -226,3 +226,4 @@ But this requires lifting state to App level and prop drilling.
**Estimated time:** 30-45 minutes **Estimated time:** 30-45 minutes
**Complexity:** Medium (URL params + responsive styling) **Complexity:** Medium (URL params + responsive styling)

1
package.json

@ -34,3 +34,4 @@
"tsx": "^4.7.0" "tsx": "^4.7.0"
} }
} }

Loading…
Cancel
Save