diff --git a/client/src/screens/browse/components/file-display/index.jsx b/client/src/screens/browse/components/file-display/index.jsx
index b0e0065..07492fc 100644
--- a/client/src/screens/browse/components/file-display/index.jsx
+++ b/client/src/screens/browse/components/file-display/index.jsx
@@ -8,6 +8,7 @@ import { getThumbnail } from "../../../../api/File";
import clientRoot from "../../../../api/server";
import capitalise from "../../../../utils/capitalise.js";
import Share from "../../../share";
+import API_BASE_URL from "../../../../api/server";
import { verifyFile, unverifyFile } from "../../../../api/File";
import {
RemoveFileFromFolder,
@@ -18,12 +19,14 @@ import { getFileDownloadLink } from "../../../../api/File";
import { fetchFolder } from "../../../../api/Folder.js";
const FileDisplay = ({ file, path, code, isMobileView = false }) => {
+ console.log(file._id);
+
const user = useSelector((state) => state.user?.user);
const fileSize = formatFileSize(file.size);
const fileType = formatFileType(file.name);
const [showDialog, setShowDialog] = useState(false);
const [dialogType, setDialogType] = useState("verify");
- const [onConfirmAction, setOnConfirmAction] = useState(() => () => {});
+ const [onConfirmAction, setOnConfirmAction] = useState(() => () => { });
const [isProcessing, setIsProcessing] = useState(false);
let name = file.name;
@@ -96,7 +99,10 @@ const FileDisplay = ({ file, path, code, isMobileView = false }) => {
toast.error("Please login to preview file.");
return;
}
- window.open(preview_url, "_blank");
+ window.open(
+ `${API_BASE_URL}/api/contribution/view/${file._id}`,
+ "_blank"
+ );
};
@@ -144,9 +150,8 @@ const FileDisplay = ({ file, path, code, isMobileView = false }) => {
return (

{
logger.error(
{
message: err.message,
+ microsoftResponse: err.response?.data,
route: req.originalUrl,
method: req.method,
},
diff --git a/server/modules/contribution/contribution.controller.js b/server/modules/contribution/contribution.controller.js
index c607f19..b73af46 100644
--- a/server/modules/contribution/contribution.controller.js
+++ b/server/modules/contribution/contribution.controller.js
@@ -4,9 +4,11 @@ import AppError from "../../utils/appError.js";
import validatePayload from "../../utils/validate.js";
import UploadFile from "../../services/UploadFile.js";
import fs from "fs";
-import { FolderModel } from "../course/course.model.js";
+import { FolderModel, FileModel } from "../course/course.model.js";
import logger from "../../utils/logger.js";
import { normalizeCourseCode, getCourseCodeCaseInsensitiveRegex } from "../../utils/course.js";
+import { getAccessToken } from "../onedrive/onedrive.controller.js";
+import axios from "axios";
async function ContributionCreation(contributionId, data) {
const existingContribution = await Contribution.findOne({ contributionId });
@@ -43,6 +45,7 @@ async function HandleFileToDB(contributionId, fileId) {
async function GetAllContributions(req, res, next) {
const allContributions = await Contribution.find({});
+ console.log(allContributions);
res.json(allContributions);
}
@@ -50,7 +53,7 @@ async function HandleFileUpload(req, res, next) {
logger.info("Handling File Upload");
const contributionId = req.headers["contribution-id"];
const files = req.files;
-
+ console.log(files.length)
if (!files || files.length === 0) {
return res.status(400).json({ error: "No files were uploaded" });
}
@@ -157,6 +160,57 @@ async function GetBrContribution(req, res, next) {
}
}
+async function viewFile(req, res, next) {
+ try {
+ const { id } = req.params;
+
+ console.time("file is fetched")
+
+ const file = await FileModel.findById(id);
+
+ console.timeEnd("file is fetched")
+
+ if (!file) {
+ console.log("file not found")
+ return res.status(404).json({ message: "File not found" });
+ }
+
+ console.time("access token fetched")
+
+ const accessToken = await getAccessToken();
+ if (!accessToken) {
+ return res.status(500).json({ message: "Access token not found" });
+ }
+
+ console.timeEnd("access token fetched")
+
+ console.time("graph request")
+ const response = await axios.get(`https://graph.microsoft.com/v1.0/me/drive/items/${file.fileId}/content`, {
+ headers: {
+ Authorization: ` Bearer ${accessToken}`
+ },
+ responseType: "stream"
+ })
+ if (!response) {
+ return res.status(500).json({ message: "File not found" });
+ }
+ console.timeEnd("graph request")
+
+ console.time("res sent to client")
+ res.setHeader("Content-Type", "application/pdf")
+ console.timeEnd("res sent to client")
+
+ console.time("stream finish")
+ response.data.on("end", () => {
+ console.timeEnd("stream finish");
+ });
+ response.data.pipe(res)
+
+ } catch (error) {
+ next(error);
+ }
+}
+
export default {
GetAllContributions,
CreateNewContribution,
@@ -164,5 +218,6 @@ export default {
GetMyContributions,
DeleteContribution,
GetContributionsUpdatedSince,
- GetBrContribution
+ GetBrContribution,
+ viewFile
};
diff --git a/server/modules/contribution/contribution.routes.js b/server/modules/contribution/contribution.routes.js
index 45c3f96..5caa4ab 100644
--- a/server/modules/contribution/contribution.routes.js
+++ b/server/modules/contribution/contribution.routes.js
@@ -14,5 +14,5 @@ router.post("/upload", upload.array("file"), catchAsync(ContributionController.H
// router.get("/:id", catchAsync(ContributionController.CreateNewContribution));
router.post("/updated", catchAsync(ContributionController.GetContributionsUpdatedSince));
router.post("/br",isAuthenticated, ContributionController.GetBrContribution)
-
+router.get('/view/:id',catchAsync(ContributionController.viewFile))
export default router;
diff --git a/server/modules/onedrive/onedrive.controller.js b/server/modules/onedrive/onedrive.controller.js
index 4479f15..5e7b99c 100644
--- a/server/modules/onedrive/onedrive.controller.js
+++ b/server/modules/onedrive/onedrive.controller.js
@@ -319,14 +319,45 @@ async function visitFile(file, currCourse) {
return NewFile._id;
}
+// export async function getAccessToken() {
+// let data;
+// if (fs.existsSync("./onedrive-refresh-token.token")) {
+// data = await refreshAccessToken();
+// } else {
+// data = await generateAccessToken();
+// }
+// return data.access_token;
+// }
+let cachedAccessToken = null;
+let tokenExpiry = 0;
+
export async function getAccessToken() {
+
+ if (
+ cachedAccessToken &&
+ Date.now() < tokenExpiry
+ ) {
+ console.log("Using cached token");
+ return cachedAccessToken;
+ }
+
+ console.log("Fetching fresh token");
+
let data;
+
if (fs.existsSync("./onedrive-refresh-token.token")) {
data = await refreshAccessToken();
} else {
data = await generateAccessToken();
}
- return data.access_token;
+
+ cachedAccessToken = data.access_token;
+
+ tokenExpiry =
+ Date.now() +
+ (data.expires_in - 60) * 1000;
+
+ return cachedAccessToken;
}
async function refreshAccessToken() {
diff --git a/server/services/UploadFile.js b/server/services/UploadFile.js
index 107fa9d..8c40966 100644
--- a/server/services/UploadFile.js
+++ b/server/services/UploadFile.js
@@ -76,6 +76,8 @@ async function createUploadSession(folderId, fileName) {
async function UploadFile(contributionId, filePath, fileName) {
const folderId = parent_item_id;
+ console.log("Folder ID:", folderId);
+ console.log("ONEDRIVE_FOLDER_ID", process.env.ONEDRIVE_FOLDER_ID);
const session = await createUploadSession(folderId, fileName);
if (!session?.url) {
logger.error("Error uploading!");