Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions backend/middleware/auth.middleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import supabase from "../config/db.js";

export const authenticateUser = async (req, res, next) => {
try {
const authHeader = req.headers.authorization;

if (!authHeader || !authHeader.startsWith("Bearer ")) {
return res.status(401).json({
error: "Unauthorized",
});
}

const token = authHeader.split(" ")[1];

const {
data: { user },
error,
} = await supabase.auth.getUser(token);

if (error || !user) {
return res.status(401).json({
error: "Invalid token",
});
}

req.user = user;

next();
} catch (error) {
console.error("Authentication middleware error:", error);

return res.status(500).json({
error: "Internal server error",
});
}
};
6 changes: 5 additions & 1 deletion backend/routes/analytics.routes.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import express from "express";
import { getAnalytics } from "../controllers/analytics.controller.js";

import { authenticateUser } from "../middleware/auth.middleware.js";

const router = express.Router();

router.use(authenticateUser);

router.get("/", getAnalytics);

export default router;
export default router;
4 changes: 3 additions & 1 deletion backend/routes/chat.routes.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import express from "express";
import { getMessages, sendMessage } from "../controllers/chat.controller.js";

import { authenticateUser } from "../middleware/auth.middleware.js";

const router = express.Router();

router.get("/", getMessages);
router.post("/", sendMessage);

router.post("/", authenticateUser, sendMessage);

export default router;
7 changes: 5 additions & 2 deletions backend/routes/feed.routes.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import express from "express";
import { createFeedItem, getFeedItems } from "../controllers/feed.controller.js";

import { authenticateUser } from "../middleware/auth.middleware.js";

const router = express.Router();

router.get("/", getFeedItems);
router.post("/", createFeedItem);

export default router;
router.post("/", authenticateUser, createFeedItem);

export default router;
15 changes: 10 additions & 5 deletions backend/routes/tasks.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,18 @@ import {
deleteTask,
} from "../controllers/tasks.controller.js";

import { authenticateUser } from "../middleware/auth.middleware.js";

const router = express.Router();

router.get("/", getTasks);
router.post("/", createTask);
router.patch("/:id", updateTaskStatus);
router.patch("/:id/edit", updateTask);
router.delete("/:id", deleteTask);

router.post("/", authenticateUser, createTask);

router.patch("/:id", authenticateUser, updateTaskStatus);

router.patch("/:id/edit", authenticateUser, updateTask);

router.delete("/:id", authenticateUser, deleteTask);

export default router;
export default router;
60 changes: 32 additions & 28 deletions frontend/app/chat/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useState, useEffect, useRef, type ChangeEvent } from "react";
import { io, Socket } from "socket.io-client";
import EmojiPicker, { type EmojiClickData } from "emoji-picker-react";
import { Smile, Paperclip, Mic, Square } from "lucide-react";
import { supabase } from "../lib/supabase";

type Message = {
id?: string;
Expand Down Expand Up @@ -200,35 +201,38 @@ socket.on("newMessage", (msg) => {

// SEND
async function handleSend() {
if ((!input.trim() && !selectedImage && !audioBlob) || !username.trim()) return;


const currentImage = selectedImage;
const currentAudio = audioBlob;
// send text to backend
await fetch("http://localhost:5000/api/chat", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
text: input,
username,
image: currentImage,
audio: currentAudio,
}),
});
if ((!input.trim() && !selectedImage && !audioBlob) || !username.trim()) return;

// clear inputs
setInput("");
setSelectedImage(null);
setAudioBlob(null);
setReplyingTo(null);
// auto scroll
bottomRef.current?.scrollIntoView({
behavior: "smooth",
});
}
const currentImage = selectedImage;
const currentAudio = audioBlob;

const session = await supabase?.auth.getSession();

const token = session?.data.session?.access_token;

await fetch("http://localhost:5000/api/chat", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
text: input,
username,
image: currentImage,
audio: currentAudio,
}),
});

setInput("");
setSelectedImage(null);
setAudioBlob(null);
setReplyingTo(null);

bottomRef.current?.scrollIntoView({
behavior: "smooth",
});
}



Expand Down
23 changes: 22 additions & 1 deletion frontend/app/components/kanban/KanbanBoard.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use client";

import React, { useState, useEffect, useRef } from "react";
import { supabase } from "../../lib/supabase";

import {
DndContext,
Expand Down Expand Up @@ -56,11 +57,17 @@ export function KanbanBoard() {
);

try {
const session = await supabase?.auth.getSession();

const token = session?.data.session?.access_token;
await fetch(
`${process.env.NEXT_PUBLIC_API_URL || "http://localhost:5000"}/api/tasks/${task.id}/edit`,
{
method: "PATCH",
headers: { "Content-Type": "application/json" },
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
title: newTitle,
description: newDescription,
Expand Down Expand Up @@ -241,6 +248,9 @@ export function KanbanBoard() {
setTasks(updatedTasks);

try {
const session = await supabase?.auth.getSession();

const token = session?.data.session?.access_token;
// Send updates for all affected tasks
await Promise.all(
reorderedTasks.map((task) =>
Expand All @@ -250,6 +260,7 @@ export function KanbanBoard() {
method: "PATCH",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
status: task.status,
Expand Down Expand Up @@ -286,10 +297,14 @@ export function KanbanBoard() {
};

try {
const session = await supabase?.auth.getSession();

const token = session?.data.session?.access_token;
await fetch(`${process.env.NEXT_PUBLIC_API_URL || "http://localhost:5000"}/api/tasks`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify(newTask),
});
Expand All @@ -303,8 +318,14 @@ export function KanbanBoard() {
if (!confirm("Are you sure you want to delete this task?")) return;

try {
const session = await supabase?.auth.getSession();

const token = session?.data.session?.access_token;
await fetch(`${process.env.NEXT_PUBLIC_API_URL || "http://localhost:5000"}/api/tasks/${taskId}`, {
method: "DELETE",
headers: {
Authorization: `Bearer ${token}`,
},
});
} catch (error) {
console.error("Failed to delete task", error);
Expand Down
7 changes: 7 additions & 0 deletions frontend/app/insights/analytics/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use client";

import { useEffect, useMemo, useState } from "react";
import { supabase } from "@/app/lib/supabase";
import PerformanceSummary, {
type AnalyticsMetric,
type MemberPerformance,
Expand Down Expand Up @@ -55,8 +56,14 @@ export default function InsightsAnalyticsPage() {
setIsLoading(true);
setLoadError("");
try {
const session = await supabase?.auth.getSession();

const token = session?.data.session?.access_token;
const response = await fetch(`${API_URL}/api/analytics`, {
signal: controller.signal,
headers: {
Authorization: `Bearer ${token}`,
},
});
if (!response.ok) throw new Error("Failed to load analytics");
const body = (await response.json()) as AnalyticsResponse;
Expand Down
9 changes: 8 additions & 1 deletion frontend/app/insights/feed/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useEffect, useMemo, useState } from "react";
import FeedHeader, { type FeedFilter } from "@/app/components/Feed-comp/FeedHeader";
import FeedList, { type FeedActivityItem } from "@/app/components/Feed-comp/FeedList";
import FeedMobileNav from "@/app/components/Feed-comp/FeedMobileNav";
import { supabase } from "@/app/lib/supabase";

const API_URL = process.env.NEXT_PUBLIC_API_URL || "http://localhost:5000";

Expand Down Expand Up @@ -94,9 +95,15 @@ export default function InsightsFeedPage() {
if (!body?.trim()) return;

try {
const session = await supabase?.auth.getSession();

const token = session?.data.session?.access_token;
const response = await fetch(`${API_URL}/api/feed`, {
method: "POST",
headers: { "Content-Type": "application/json" },
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({ title: title.trim(), body: body.trim(), type: "discussion" }),
});
if (!response.ok) throw new Error("Failed to create insight");
Expand Down
Loading