diff --git a/main.py b/main.py index a0c396c..4240f13 100644 --- a/main.py +++ b/main.py @@ -145,7 +145,7 @@ def hash_password(password: str) -> str: def generate_token() -> str: return secrets.token_urlsafe(32) -async def get_current_user(token_id: Optional[int] = Form(None), +async def DELETE_get_current_user(token_id: Optional[int] = Form(None), token_key: Optional[str] = Form(None), user_id: Optional[int] = Form(None)): if not all([token_id, token_key, user_id]): @@ -328,7 +328,7 @@ async def get_rants( token_key: Optional[str] = None, user_id: Optional[int] = None ): - current_user_id = await get_current_user(token_id, token_key, user_id) if token_id else None + current_user_id = await authenticate_user(token_id, token_key, user_id) if token_id else None # Get rants with user info order_by = "r.created_time DESC" if sort == "recent" else "r.score DESC" @@ -393,7 +393,7 @@ async def get_rant( token_key: Optional[str] = None, user_id: Optional[int] = None ): - current_user_id = await get_current_user(token_id, token_key, user_id) if token_id else None + current_user_id = await authenticate_user(token_id, token_key, user_id) if token_id else None # Get rant with user info rant_row = await db.query_one( @@ -485,7 +485,7 @@ async def create_rant( user_id: int = Form(...), image: Optional[UploadFile] = File(None) ): - current_user_id = await get_current_user(token_id, token_key, user_id) + current_user_id = await authenticate_user(token_id, token_key, user_id) if not current_user_id: return {"success": False, "error": "Authentication required"} @@ -539,7 +539,7 @@ async def update_rant( token_key: str = Form(...), user_id: int = Form(...) ): - current_user_id = await get_current_user(token_id, token_key, user_id) + current_user_id = await authenticate_user(token_id, token_key, user_id) if not current_user_id: return {"success": False, "error": "Authentication required"} @@ -568,7 +568,7 @@ async def delete_rant( token_key: str = None, user_id: int = None ): - current_user_id = await get_current_user(token_id, token_key, user_id) + current_user_id = await authenticate_user(token_id, token_key, user_id) if not current_user_id: return {"success": False, "error": "Authentication required"} @@ -599,7 +599,7 @@ async def vote_rant( token_key: str = Form(...), user_id: int = Form(...) ): - current_user_id = await get_current_user(token_id, token_key, user_id) + current_user_id = await authenticate_user(token_id, token_key, user_id) if not current_user_id: return {"success": False, "error": "Authentication required"} @@ -696,7 +696,7 @@ async def favorite_rant( token_key: str = Form(...), user_id: int = Form(...) ): - current_user_id = await get_current_user(token_id, token_key, user_id) + current_user_id = await authenticate_user(token_id, token_key, user_id) if not current_user_id: return {"success": False, "error": "Authentication required"} @@ -717,7 +717,7 @@ async def unfavorite_rant( token_key: str = Form(...), user_id: int = Form(...) ): - current_user_id = await get_current_user(token_id, token_key, user_id) + current_user_id = await authenticate_user(token_id, token_key, user_id) if not current_user_id: return {"success": False, "error": "Authentication required"} @@ -738,7 +738,7 @@ async def create_comment( user_id: int = Form(...), image: Optional[UploadFile] = File(None) ): - current_user_id = await get_current_user(token_id, token_key, user_id) + current_user_id = await authenticate_user(token_id, token_key, user_id) if not current_user_id: return {"success": False, "confirmed": False} @@ -792,7 +792,7 @@ async def get_comment( token_key: Optional[str] = None, user_id: Optional[int] = None ): - current_user_id = await get_current_user(token_id, token_key, user_id) if token_id else None + current_user_id = await authenticate_user(token_id, token_key, user_id) if token_id else None row = await db.query_one( """SELECT c.*, u.id as user_id, u.username, u.score as user_score, @@ -835,7 +835,7 @@ async def update_comment( token_key: str = Form(...), user_id: int = Form(...) ): - current_user_id = await get_current_user(token_id, token_key, user_id) + current_user_id = await authenticate_user(token_id, token_key, user_id) if not current_user_id: return {"success": False, "error": "Authentication required"} @@ -864,7 +864,7 @@ async def delete_comment( token_key: str = None, user_id: int = None ): - current_user_id = await get_current_user(token_id, token_key, user_id) + current_user_id = await authenticate_user(token_id, token_key, user_id) if not current_user_id: return {"success": False, "error": "Authentication required"} @@ -893,7 +893,7 @@ async def vote_comment( token_key: str = Form(...), user_id: int = Form(...) ): - current_user_id = await get_current_user(token_id, token_key, user_id) + current_user_id = await authenticate_user(token_id, token_key, user_id) if not current_user_id: return {"success": False, "error": "Authentication required"} @@ -952,7 +952,7 @@ async def get_profile( token_key: Optional[str] = None, auth_user_id: Optional[int] = None ): - current_user_id = await get_current_user(token_id, token_key, auth_user_id) if token_id else None + current_user_id = await authenticate_user(token_id, token_key, auth_user_id) if token_id else None # Get user user = await db.get("users", {"id": user_id}) @@ -1105,7 +1105,7 @@ async def search( token_key: Optional[str] = None, user_id: Optional[int] = None ): - current_user_id = await get_current_user(token_id, token_key, user_id) if token_id else None + current_user_id = await authenticate_user(token_id, token_key, user_id) if token_id else None # Search rants rows = await db.query_raw( @@ -1148,11 +1148,12 @@ async def get_notifications( ext_prof: int = 1, last_time: Optional[int] = None, app: int = 3, - token_id: int = None, - token_key: str = None, - user_id: int = None + token_id: Optional[int] = None, + token_key: Optional[str] = None, + user_id: Optional[int] = None ): - current_user_id = await get_current_user(token_id, token_key, user_id) + # Use the generic authenticate_user function + current_user_id = await authenticate_user(token_id, token_key, user_id) if not current_user_id: return {"success": False, "error": "Authentication required"} @@ -1185,8 +1186,9 @@ async def get_notifications( if not row['read']: unread_count += 1 - # Mark as read - await db.update("notifications", {"read": 1}, {"user_id": current_user_id}) + # Mark notifications as read + if rows: # Only update if there are notifications + await db.update("notifications", {"read": 1}, {"user_id": current_user_id}) return { "success": True, @@ -1206,6 +1208,25 @@ async def get_notifications( } } +async def authenticate_user(token_id: Optional[int] = None, + token_key: Optional[str] = None, + user_id: Optional[int] = None): + """Generic authentication function that works with any parameter source""" + if not all([token_id, token_key, user_id]): + return None + + token = await db.get("auth_tokens", { + "id": token_id, + "token_key": token_key, + "user_id": user_id + }) + + if not token or token['expire_time'] <= int(datetime.now().timestamp()): + return None + + return user_id + + @app.delete("/api/users/me/notif-feed") async def clear_notifications( app: int = Form(3), @@ -1213,7 +1234,7 @@ async def clear_notifications( token_key: str = Form(...), user_id: int = Form(...) ): - current_user_id = await get_current_user(token_id, token_key, user_id) + current_user_id = await authenticate_user(token_id, token_key, user_id) if not current_user_id: return {"success": False, "error": "Authentication required"} @@ -1233,7 +1254,7 @@ async def edit_profile( token_key: str = Form(...), user_id: int = Form(...) ): - current_user_id = await get_current_user(token_id, token_key, user_id) + current_user_id = await authenticate_user(token_id, token_key, user_id) if not current_user_id: return {"success": False, "error": "Authentication required"} @@ -1262,7 +1283,7 @@ async def resend_confirmation( token_key: str = Form(...), user_id: int = Form(...) ): - current_user_id = await get_current_user(token_id, token_key, user_id) + current_user_id = await authenticate_user(token_id, token_key, user_id) if not current_user_id: return {"success": False, "error": "Authentication required"} @@ -1277,7 +1298,7 @@ async def mark_news_read( token_key: str = Form(...), user_id: int = Form(...) ): - current_user_id = await get_current_user(token_id, token_key, user_id) + current_user_id = await authenticate_user(token_id, token_key, user_id) if not current_user_id: return {"success": False, "error": "Authentication required"} diff --git a/static/index.html b/static/index.html index fedbf7f..5772b6d 100644 --- a/static/index.html +++ b/static/index.html @@ -636,39 +636,41 @@ document.getElementById('createRantBtn').style.display = isLoggedIn ? 'flex' : 'none'; } - async function apiCall(endpoint, options = {}) { - const url = `${API_URL}${endpoint}`; - - // Add auth to FormData or URLSearchParams if logged in - if (currentUser && options.body) { - if (options.body instanceof FormData) { - options.body.append('app', APP_ID); - options.body.append('token_id', currentUser.token_id); - options.body.append('token_key', currentUser.token_key); - options.body.append('user_id', currentUser.id); - } else if (options.body instanceof URLSearchParams) { - options.body.append('app', APP_ID); - options.body.append('token_id', currentUser.token_id); - options.body.append('token_key', currentUser.token_key); - options.body.append('user_id', currentUser.id); - } - } - // Add auth to query params for GET requests - if (currentUser && (options.method === 'GET' || !options.method)) { - const separator = endpoint.includes('?') ? '&' : '?'; - endpoint += `${separator}app=${APP_ID}&token_id=${currentUser.token_id}&token_key=${currentUser.token_key}&user_id=${currentUser.id}`; - } - - try { - const response = await fetch(url, options); - const data = await response.json(); - return data; - } catch (error) { - console.error('API Error:', error); - return { success: false, error: error.message }; - } +async function apiCall(endpoint, options = {}) { + let url = `${API_URL}${endpoint}`; + + // Add auth to FormData or URLSearchParams if logged in + if (currentUser && options.body) { + if (options.body instanceof FormData) { + options.body.append('app', APP_ID); + options.body.append('token_id', currentUser.token_id); + options.body.append('token_key', currentUser.token_key); + options.body.append('user_id', currentUser.id); + } else if (options.body instanceof URLSearchParams) { + options.body.append('app', APP_ID); + options.body.append('token_id', currentUser.token_id); + options.body.append('token_key', currentUser.token_key); + options.body.append('user_id', currentUser.id); } + } + + // Add auth to query params for GET requests + if (currentUser && (options.method === 'GET' || !options.method)) { + const separator = endpoint.includes('?') ? '&' : '?'; + url += `${separator}app=${APP_ID}&token_id=${currentUser.token_id}&token_key=${currentUser.token_key}&user_id=${currentUser.id}`; + } + + try { + const response = await fetch(url, options); + const data = await response.json(); + return data; + } catch (error) { + console.error('API Error:', error); + return { success: false, error: error.message }; + } +} + // View functions async function showFeed(sort = 'recent') { @@ -981,57 +983,66 @@ } } - async function showNotifications() { - currentView = 'notifications'; - - const content = document.getElementById('content'); - content.innerHTML = ` -
-
-

Loading notifications...

+async function showNotifications() { + currentView = 'notifications'; + + const content = document.getElementById('content'); + content.innerHTML = ` +
+
+

Loading notifications...

+
+ `; + + const params = new URLSearchParams({ + ext_prof: 1, + last_time: Math.floor(Date.now() / 1000) - 86400 + }); + + const data = await apiCall(`/users/me/notif-feed?${params}`); + + if (data.success) { + const items = data.data.items; + + content.innerHTML = ` +

Notifications

+ ${items.length === 0 ? '

No notifications

' : ''} + ${items.map(notif => ` +
+

${notif.username} ${notif.type === 'comment' ? 'commented on your rant' : 'mentioned you'}

+

${formatTime(notif.created_time)}

- `; - - const params = new URLSearchParams({ - ext_prof: 1, - last_time: Math.floor(Date.now() / 1000) - 86400, - app: APP_ID - }); - const data = await apiCall(`/users/me/notif-feed?${params}`); - - if (data.success) { - const items = data.data.items; - - content.innerHTML = ` -

Notifications

- ${items.length === 0 ? '

No notifications

' : ''} - ${items.map(notif => ` -
-

${notif.username} ${notif.type === 'comment' ? 'commented on your rant' : 'mentioned you'}

-

${formatTime(notif.created_time)}

-
- `).join('')} - `; - - // Update notification count - updateNotificationCount(0); - } - } + `).join('')} + `; + + // Update notification count + updateNotificationCount(0); + } else { + content.innerHTML = ` +

Notifications

+

Failed to load notifications: ${data.error || 'Unknown error'}

+ `; + } +} + + + + +async function checkNotifications() { + if (!currentUser) return; + + const params = new URLSearchParams({ + ext_prof: 1, + last_time: Math.floor(Date.now() / 1000) - 86400 + }); + + const data = await apiCall(`/users/me/notif-feed?${params}`); + + if (data.success) { + updateNotificationCount(data.data.num_unread); + } +} - async function checkNotifications() { - if (!currentUser) return; - - const params = new URLSearchParams({ - ext_prof: 1, - last_time: Math.floor(Date.now() / 1000) - 86400, - app: APP_ID - }); - const data = await apiCall(`/users/me/notif-feed?${params}`); - - if (data.success) { - updateNotificationCount(data.data.num_unread); - } - } function updateNotificationCount(count) { const notifCount = document.getElementById('notifCount');