From 8363b6d872f3c01db1d97f871368b4243b342427 Mon Sep 17 00:00:00 2001 From: phfr24 <phfr24@inf.ufpr.br> Date: Fri, 11 Oct 2024 10:57:42 -0300 Subject: [PATCH 01/14] upgrade dependencies --- package.json | 4 +- yarn.lock | 138 +++++++++++++++++++++++++-------------------------- 2 files changed, 71 insertions(+), 71 deletions(-) diff --git a/package.json b/package.json index cac58db..8566040 100644 --- a/package.json +++ b/package.json @@ -9,9 +9,9 @@ "lint": "next lint" }, "dependencies": { + "next": "14.2.15", "react": "^18", - "react-dom": "^18", - "next": "14.2.13" + "react-dom": "^18" }, "devDependencies": { "postcss": "^8", diff --git a/yarn.lock b/yarn.lock index 388879c..121ba41 100644 --- a/yarn.lock +++ b/yarn.lock @@ -51,55 +51,55 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" -"@next/env@14.2.13": - version "14.2.13" - resolved "https://registry.yarnpkg.com/@next/env/-/env-14.2.13.tgz#ba341ba9eb70db428fc1c754f49c3c516f7bab47" - integrity sha512-s3lh6K8cbW1h5Nga7NNeXrbe0+2jIIYK9YaA9T7IufDWnZpozdFUp6Hf0d5rNWUKu4fEuSX2rCKlGjCrtylfDw== - -"@next/swc-darwin-arm64@14.2.13": - version "14.2.13" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.13.tgz#76f08d78360c4d27d444df7f35a56f59a48f4808" - integrity sha512-IkAmQEa2Htq+wHACBxOsslt+jMoV3msvxCn0WFSfJSkv/scy+i/EukBKNad36grRxywaXUYJc9mxEGkeIs8Bzg== - -"@next/swc-darwin-x64@14.2.13": - version "14.2.13" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.13.tgz#1d4821d54bb01dacc6a6c32408f8468a4f4af269" - integrity sha512-Dv1RBGs2TTjkwEnFMVL5XIfJEavnLqqwYSD6LXgTPdEy/u6FlSrLBSSfe1pcfqhFEXRAgVL3Wpjibe5wXJzWog== - -"@next/swc-linux-arm64-gnu@14.2.13": - version "14.2.13" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.13.tgz#79d9af8d3408df9990c8911889eca1ca6a308f19" - integrity sha512-yB1tYEFFqo4ZNWkwrJultbsw7NPAAxlPXURXioRl9SdW6aIefOLS+0TEsKrWBtbJ9moTDgU3HRILL6QBQnMevg== - -"@next/swc-linux-arm64-musl@14.2.13": - version "14.2.13" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.13.tgz#b13180645865b120591db2f1e831743ebc02ab36" - integrity sha512-v5jZ/FV/eHGoWhMKYrsAweQ7CWb8xsWGM/8m1mwwZQ/sutJjoFaXchwK4pX8NqwImILEvQmZWyb8pPTcP7htWg== - -"@next/swc-linux-x64-gnu@14.2.13": - version "14.2.13" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.13.tgz#8cb8480dfeee512648e4e08c2095aac0461b876f" - integrity sha512-aVc7m4YL7ViiRv7SOXK3RplXzOEe/qQzRA5R2vpXboHABs3w8vtFslGTz+5tKiQzWUmTmBNVW0UQdhkKRORmGA== - -"@next/swc-linux-x64-musl@14.2.13": - version "14.2.13" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.13.tgz#df5ca922fa1e1ee81b15a06a2d3d3ace0efd2bd7" - integrity sha512-4wWY7/OsSaJOOKvMsu1Teylku7vKyTuocvDLTZQq0TYv9OjiYYWt63PiE1nTuZnqQ4RPvME7Xai+9enoiN0Wrg== - -"@next/swc-win32-arm64-msvc@14.2.13": - version "14.2.13" - resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.13.tgz#8a7db6e71f526212587975f743b28e4d1cb829d1" - integrity sha512-uP1XkqCqV2NVH9+g2sC7qIw+w2tRbcMiXFEbMihkQ8B1+V6m28sshBwAB0SDmOe0u44ne1vFU66+gx/28RsBVQ== - -"@next/swc-win32-ia32-msvc@14.2.13": - version "14.2.13" - resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.13.tgz#6aa664f36f2d70c5ae6ffcbbc56784d33f24522d" - integrity sha512-V26ezyjPqQpDBV4lcWIh8B/QICQ4v+M5Bo9ykLN+sqeKKBxJVDpEc6biDVyluTXTC40f5IqCU0ttth7Es2ZuMw== - -"@next/swc-win32-x64-msvc@14.2.13": - version "14.2.13" - resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.13.tgz#5a920eea82a58affa6146192586716cec6c87fed" - integrity sha512-WwzOEAFBGhlDHE5Z73mNU8CO8mqMNLqaG+AO9ETmzdCQlJhVtWZnOl2+rqgVQS+YHunjOWptdFmNfbpwcUuEsw== +"@next/env@14.2.15": + version "14.2.15" + resolved "https://registry.yarnpkg.com/@next/env/-/env-14.2.15.tgz#06d984e37e670d93ddd6790af1844aeb935f332f" + integrity sha512-S1qaj25Wru2dUpcIZMjxeMVSwkt8BK4dmWHHiBuRstcIyOsMapqT4A4jSB6onvqeygkSSmOkyny9VVx8JIGamQ== + +"@next/swc-darwin-arm64@14.2.15": + version "14.2.15" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.15.tgz#6386d585f39a1c490c60b72b1f76612ba4434347" + integrity sha512-Rvh7KU9hOUBnZ9TJ28n2Oa7dD9cvDBKua9IKx7cfQQ0GoYUwg9ig31O2oMwH3wm+pE3IkAQ67ZobPfEgurPZIA== + +"@next/swc-darwin-x64@14.2.15": + version "14.2.15" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.15.tgz#b7baeedc6a28f7545ad2bc55adbab25f7b45cb89" + integrity sha512-5TGyjFcf8ampZP3e+FyCax5zFVHi+Oe7sZyaKOngsqyaNEpOgkKB3sqmymkZfowy3ufGA/tUgDPPxpQx931lHg== + +"@next/swc-linux-arm64-gnu@14.2.15": + version "14.2.15" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.15.tgz#fa13c59d3222f70fb4cb3544ac750db2c6e34d02" + integrity sha512-3Bwv4oc08ONiQ3FiOLKT72Q+ndEMyLNsc/D3qnLMbtUYTQAmkx9E/JRu0DBpHxNddBmNT5hxz1mYBphJ3mfrrw== + +"@next/swc-linux-arm64-musl@14.2.15": + version "14.2.15" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.15.tgz#30e45b71831d9a6d6d18d7ac7d611a8d646a17f9" + integrity sha512-k5xf/tg1FBv/M4CMd8S+JL3uV9BnnRmoe7F+GWC3DxkTCD9aewFRH1s5rJ1zkzDa+Do4zyN8qD0N8c84Hu96FQ== + +"@next/swc-linux-x64-gnu@14.2.15": + version "14.2.15" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.15.tgz#5065db17fc86f935ad117483f21f812dc1b39254" + integrity sha512-kE6q38hbrRbKEkkVn62reLXhThLRh6/TvgSP56GkFNhU22TbIrQDEMrO7j0IcQHcew2wfykq8lZyHFabz0oBrA== + +"@next/swc-linux-x64-musl@14.2.15": + version "14.2.15" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.15.tgz#3c4a4568d8be7373a820f7576cf33388b5dab47e" + integrity sha512-PZ5YE9ouy/IdO7QVJeIcyLn/Rc4ml9M2G4y3kCM9MNf1YKvFY4heg3pVa/jQbMro+tP6yc4G2o9LjAz1zxD7tQ== + +"@next/swc-win32-arm64-msvc@14.2.15": + version "14.2.15" + resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.15.tgz#fb812cc4ca0042868e32a6a021da91943bb08b98" + integrity sha512-2raR16703kBvYEQD9HNLyb0/394yfqzmIeyp2nDzcPV4yPjqNUG3ohX6jX00WryXz6s1FXpVhsCo3i+g4RUX+g== + +"@next/swc-win32-ia32-msvc@14.2.15": + version "14.2.15" + resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.15.tgz#ec26e6169354f8ced240c1427be7fd485c5df898" + integrity sha512-fyTE8cklgkyR1p03kJa5zXEaZ9El+kDNM5A+66+8evQS5e/6v0Gk28LqA0Jet8gKSOyP+OTm/tJHzMlGdQerdQ== + +"@next/swc-win32-x64-msvc@14.2.15": + version "14.2.15" + resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.15.tgz#18d68697002b282006771f8d92d79ade9efd35c4" + integrity sha512-SzqGbsLsP9OwKNUG9nekShTwhj6JSB9ZLMWQ8g1gG6hdE5gQLncbnbymrwy2yVmH9nikSLYRYxYMFu78Ggp7/g== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -217,9 +217,9 @@ camelcase-css@^2.0.1: integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== caniuse-lite@^1.0.30001579: - version "1.0.30001663" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001663.tgz#1529a723505e429fdfd49532e9fc42273ba7fed7" - integrity sha512-o9C3X27GLKbLeTYZ6HBOLU1tsAcBZsLis28wrVzddShCS16RujjHp9GDHKZqrB3meE0YjhawvMFsGb/igqiPzA== + version "1.0.30001668" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001668.tgz#98e214455329f54bf7a4d70b49c9794f0fbedbed" + integrity sha512-nWLrdxqCdblixUO+27JtGJJE/txpJlyUy5YN1u53wLZkP0emYCo5zgS6QYft7VUYR42LGgi/S5hdLZTrnyIddw== chokidar@^3.5.3: version "3.6.0" @@ -504,12 +504,12 @@ nanoid@^3.3.6, nanoid@^3.3.7: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== -next@14.2.13: - version "14.2.13" - resolved "https://registry.yarnpkg.com/next/-/next-14.2.13.tgz#32da2ee0afbe729e2d4a467c3570def90e1c974d" - integrity sha512-BseY9YNw8QJSwLYD7hlZzl6QVDoSFHL/URN5K64kVEVpCsSOWeyjbIGK+dZUaRViHTaMQX8aqmnn0PHBbGZezg== +next@14.2.15: + version "14.2.15" + resolved "https://registry.yarnpkg.com/next/-/next-14.2.15.tgz#348e5603e22649775d19c785c09a89c9acb5189a" + integrity sha512-h9ctmOokpoDphRvMGnwOJAedT6zKhwqyZML9mDtspgf4Rh3Pn7UTYKqePNoDvhsWBAO5GoPNYshnAUGIazVGmw== dependencies: - "@next/env" "14.2.13" + "@next/env" "14.2.15" "@swc/helpers" "0.5.5" busboy "1.6.0" caniuse-lite "^1.0.30001579" @@ -517,15 +517,15 @@ next@14.2.13: postcss "8.4.31" styled-jsx "5.1.1" optionalDependencies: - "@next/swc-darwin-arm64" "14.2.13" - "@next/swc-darwin-x64" "14.2.13" - "@next/swc-linux-arm64-gnu" "14.2.13" - "@next/swc-linux-arm64-musl" "14.2.13" - "@next/swc-linux-x64-gnu" "14.2.13" - "@next/swc-linux-x64-musl" "14.2.13" - "@next/swc-win32-arm64-msvc" "14.2.13" - "@next/swc-win32-ia32-msvc" "14.2.13" - "@next/swc-win32-x64-msvc" "14.2.13" + "@next/swc-darwin-arm64" "14.2.15" + "@next/swc-darwin-x64" "14.2.15" + "@next/swc-linux-arm64-gnu" "14.2.15" + "@next/swc-linux-arm64-musl" "14.2.15" + "@next/swc-linux-x64-gnu" "14.2.15" + "@next/swc-linux-x64-musl" "14.2.15" + "@next/swc-win32-arm64-msvc" "14.2.15" + "@next/swc-win32-ia32-msvc" "14.2.15" + "@next/swc-win32-x64-msvc" "14.2.15" normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" @@ -543,9 +543,9 @@ object-hash@^3.0.0: integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== package-json-from-dist@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz#e501cd3094b278495eb4258d4c9f6d5ac3019f00" - integrity sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw== + version "1.0.1" + resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505" + integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== path-key@^3.1.0: version "3.1.1" -- GitLab From 46804c7c0cc9a263739e64c178a94cffbe8ebbc4 Mon Sep 17 00:00:00 2001 From: phfr24 <phfr24@inf.ufpr.br> Date: Fri, 11 Oct 2024 10:59:32 -0300 Subject: [PATCH 02/14] add ws --- package.json | 3 ++- yarn.lock | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 8566040..cffa4de 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "dependencies": { "next": "14.2.15", "react": "^18", - "react-dom": "^18" + "react-dom": "^18", + "ws": "^8.18.0" }, "devDependencies": { "postcss": "^8", diff --git a/yarn.lock b/yarn.lock index 121ba41..651400d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -898,6 +898,11 @@ wrap-ansi@^8.1.0: string-width "^5.0.1" strip-ansi "^7.0.1" +ws@^8.18.0: + version "8.18.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" + integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== + yaml@^2.3.4: version "2.5.1" resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.5.1.tgz#c9772aacf62cb7494a95b0c4f1fb065b563db130" -- GitLab From 9a33e4413e6afb45d0617620cdb29dfa8a532b31 Mon Sep 17 00:00:00 2001 From: phfr24 <phfr24@inf.ufpr.br> Date: Fri, 11 Oct 2024 17:24:57 -0300 Subject: [PATCH 03/14] integrate websocket into /analysis --- src/app/analysis/[id]/page.js | 64 ++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 16 deletions(-) diff --git a/src/app/analysis/[id]/page.js b/src/app/analysis/[id]/page.js index 7058e3f..fb874dd 100644 --- a/src/app/analysis/[id]/page.js +++ b/src/app/analysis/[id]/page.js @@ -1,33 +1,65 @@ +'use client' import { AnalysisMetadata, SampleMetadata } from "@/components/analysis/metadata"; -import ActivityTimeline from "@/components/analysis/activity-timeline"; import RedirectButton from "@/components/redirect-button"; +import { useState, useEffect } from 'react'; +import "@/styles/analysis/activity-timeline.css"; import "@/styles/analysis/page.css"; export default function Analysis({ params: { id } }) { + const [report, setReport] = useState([]); + + useEffect(() => { + const ws = new WebSocket(`ws://localhost:8080/status/${id}`); + + ws.onopen = (event) => { + console.log('Connection opened: ', event); + } + ws.onerror = (error) => { + console.error('Error: ', error); + } + ws.onmessage = (event) => { + setReport(JSON.parse(event.data)); + } + ws.onclose = (event) => { + console.log('Connection closed: ', event); + } + + return () => { + ws.close(); + } + }, [id, setReport, report]); + return ( <div> <div className="pagerow"> <AnalysisMetadata - status="running" - id="5e6c83bf-44b3-4f9e-bd45-683585439eed" - driver="1.3.8" - template="9011" - start="08/10/24 11:00:10 -03" - end="08/10/24 11:07:39 -03" + status={report?.status || ''} + id={report?.id || ''} + driver={report?.driverVersion || ''} + template={report?.templateID || ''} + start={report?.startTime || ''} + end={report?.endTime || ''} /> <SampleMetadata - filename="MALWARE2.exe" - extension=".exe" - mimetype="application/octet-stream" - size="2.7 MiB" - lastmod="08/10/24 11:00:10 -03" - md5="6cb20b4c787c4ea918e301310b2667f5" - sha1="5b5d921d69336d06837422438cd0c5225fc78a74" - sha256="83121822f08691834102f7652c673133deb98a134110a0fea22a27b2ccd5d966" + filename={report?.fileMetadata?.filename || ''} + extension={report?.fileMetadata?.extension || ''} + mimetype={report?.fileMetadata?.mimetype || ''} + size={report?.fileMetadata?.size || ''} + lastmod={report?.fileMetadata?.lastModified || ''} + md5={report?.fileMetadata?.md5sum || ''} + sha1={report?.fileMetadata?.sha1sum || ''} + sha256={report?.fileMetadata?.sha256sum || ''} /> </div> <div className="pagerow"> - <ActivityTimeline /> + <div className="activity-timeline"> + <div className="at-title">ACTIVITY TIMELINE</div> + {() => { + if (report) { + return report.log.map((msg, i) => <div key={i}>{msg}</div>); + } + }} + </div> </div> <RedirectButton name="go back" href="/" /> </div> -- GitLab From b1f0f28f8e947f990a8b6424b406e20555395442 Mon Sep 17 00:00:00 2001 From: phfr24 <phfr24@inf.ufpr.br> Date: Fri, 11 Oct 2024 20:06:57 -0300 Subject: [PATCH 04/14] update /analysis page.js --- src/app/analysis/[id]/page.js | 81 +++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 36 deletions(-) diff --git a/src/app/analysis/[id]/page.js b/src/app/analysis/[id]/page.js index fb874dd..01939d0 100644 --- a/src/app/analysis/[id]/page.js +++ b/src/app/analysis/[id]/page.js @@ -6,62 +6,71 @@ import "@/styles/analysis/activity-timeline.css"; import "@/styles/analysis/page.css"; export default function Analysis({ params: { id } }) { - const [report, setReport] = useState([]); + const [report, setReport] = useState(null); + + /* TODO: check if it is possible to make the ws url configurable. + /* TODO: check id against http://backend/analysis/id. if it returns 404, then + * 404. */ + /* TODO: use report.error !!! */ useEffect(() => { const ws = new WebSocket(`ws://localhost:8080/status/${id}`); ws.onopen = (event) => { - console.log('Connection opened: ', event); + //console.log('websocket connection opened: ', event); } ws.onerror = (error) => { - console.error('Error: ', error); + //console.error('websocket connection error: ', error); } ws.onmessage = (event) => { setReport(JSON.parse(event.data)); } ws.onclose = (event) => { - console.log('Connection closed: ', event); + //console.log('websocket connection closed: ', event); } return () => { ws.close(); } - }, [id, setReport, report]); + }, [id, setReport]); return ( <div> - <div className="pagerow"> - <AnalysisMetadata - status={report?.status || ''} - id={report?.id || ''} - driver={report?.driverVersion || ''} - template={report?.templateID || ''} - start={report?.startTime || ''} - end={report?.endTime || ''} - /> - <SampleMetadata - filename={report?.fileMetadata?.filename || ''} - extension={report?.fileMetadata?.extension || ''} - mimetype={report?.fileMetadata?.mimetype || ''} - size={report?.fileMetadata?.size || ''} - lastmod={report?.fileMetadata?.lastModified || ''} - md5={report?.fileMetadata?.md5sum || ''} - sha1={report?.fileMetadata?.sha1sum || ''} - sha256={report?.fileMetadata?.sha256sum || ''} - /> - </div> - <div className="pagerow"> - <div className="activity-timeline"> - <div className="at-title">ACTIVITY TIMELINE</div> - {() => { - if (report) { - return report.log.map((msg, i) => <div key={i}>{msg}</div>); - } - }} - </div> - </div> - <RedirectButton name="go back" href="/" /> + {if (report) { + return ( + <div className="pagerow"> + <AnalysisMetadata + status={report.status} + id={report.id} + driver={report.driverVersion} + template={report.templateID} + start={report.startTime} + end={report.endTime} + /> + <SampleMetadata + filename={report.fileMetadata.filename} + extension={report.fileMetadata.extension} + mimetype={report.fileMetadata.mimetype} + size={report.fileMetadata.size} + lastmod={report.fileMetadata.lastModified} + md5={report.fileMetadata.md5sum} + sha1={report.fileMetadata.sha1sum} + sha256={report.fileMetadata.sha256sum} + /> + </div> + <div className="pagerow"> + <div className="activity-timeline"> + <div className="at-title">ACTIVITY TIMELINE</div> + {() => { + if (report) { + return report.log.map((msg, i) => <div key={i}>{msg}</div>); + } + }} + </div> + </div> + <RedirectButton name="go back" href="/" /> + ); + }} </div> ); } -- GitLab From c52765533dc5842e8d108170b91416937e7a3ffa Mon Sep 17 00:00:00 2001 From: phfr24 <phfr24@inf.ufpr.br> Date: Mon, 14 Oct 2024 10:10:38 -0300 Subject: [PATCH 05/14] update /analysis page.js --- src/app/analysis/[id]/page.js | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/app/analysis/[id]/page.js b/src/app/analysis/[id]/page.js index 01939d0..4304aaf 100644 --- a/src/app/analysis/[id]/page.js +++ b/src/app/analysis/[id]/page.js @@ -35,9 +35,9 @@ export default function Analysis({ params: { id } }) { }, [id, setReport]); return ( - <div> - {if (report) { - return ( + <main> + {report && ( + <div> <div className="pagerow"> <AnalysisMetadata status={report.status} @@ -61,16 +61,12 @@ export default function Analysis({ params: { id } }) { <div className="pagerow"> <div className="activity-timeline"> <div className="at-title">ACTIVITY TIMELINE</div> - {() => { - if (report) { - return report.log.map((msg, i) => <div key={i}>{msg}</div>); - } - }} + {report.log.map((msg, i) => <div key={i}>{msg}</div>)} </div> </div> - <RedirectButton name="go back" href="/" /> - ); - }} - </div> + <RedirectButton name="go back" href="/" /> + </div> + )} + </main> ); } -- GitLab From b0f60bab4fca4023a3e1cc5868f1833f4ad4791e Mon Sep 17 00:00:00 2001 From: phfr24 <phfr24@inf.ufpr.br> Date: Mon, 14 Oct 2024 10:21:32 -0300 Subject: [PATCH 06/14] update activity timeline spacing --- src/styles/analysis/activity-timeline.css | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/styles/analysis/activity-timeline.css b/src/styles/analysis/activity-timeline.css index 6d481f7..9d422b2 100644 --- a/src/styles/analysis/activity-timeline.css +++ b/src/styles/analysis/activity-timeline.css @@ -7,7 +7,7 @@ font-size: 1em; flex: 1; overflow: auto; - padding: 0.5em; + padding: 0.5em 0.5em 0 0.5em; word-wrap: break-word; white-space: pre-wrap; border: 1px solid #1F1C1A; @@ -21,3 +21,7 @@ text-align: center; border-bottom: 1px solid #1F1C1A; } + +.activity-timeline div { + margin-bottom: 0.5em; +} \ No newline at end of file -- GitLab From 397f29faaa8305062e5cd33fef156f7be49c912e Mon Sep 17 00:00:00 2001 From: phfr24 <phfr24@inf.ufpr.br> Date: Mon, 14 Oct 2024 10:33:06 -0300 Subject: [PATCH 07/14] format file size in /analysis --- src/app/analysis/[id]/page.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/app/analysis/[id]/page.js b/src/app/analysis/[id]/page.js index 4304aaf..49cb117 100644 --- a/src/app/analysis/[id]/page.js +++ b/src/app/analysis/[id]/page.js @@ -51,7 +51,7 @@ export default function Analysis({ params: { id } }) { filename={report.fileMetadata.filename} extension={report.fileMetadata.extension} mimetype={report.fileMetadata.mimetype} - size={report.fileMetadata.size} + size={formatFileSize(report.fileMetadata.size)} lastmod={report.fileMetadata.lastModified} md5={report.fileMetadata.md5sum} sha1={report.fileMetadata.sha1sum} @@ -70,3 +70,13 @@ export default function Analysis({ params: { id } }) { </main> ); } + +function formatFileSize(bytes) { + const sizes = ['B', 'KB', 'MB', 'GB']; + + if (bytes === 0) + return '0B'; + + const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024))); + return `${(bytes / Math.pow(1024, i)).toFixed(2)} ${sizes[i]}`; +} \ No newline at end of file -- GitLab From 7995a09ae72f06bf111a7519c47aba5ba3337870 Mon Sep 17 00:00:00 2001 From: phfr24 <phfr24@inf.ufpr.br> Date: Mon, 14 Oct 2024 11:03:53 -0300 Subject: [PATCH 08/14] document project configuration --- README.md | 50 +++++++++++++++++++---------------- next.config.mjs | 11 +++++++- src/app/analysis/[id]/page.js | 1 - 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index c474cb2..45f620d 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,28 @@ -This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). - -## Getting Started - -First, run the development server: - -```bash -yarn dev +## Configuration + +This sucks, but we'll come up with something better later. + +1. Set the API url in the `next.config.mjs` file: +```js +/* next.config.mjs */ +const nextConfig = { + // ... + async rewrites() { + return [ + { + source: "/api/:path*", + destination: "http{s}://{API URL}/:path*", + }, + ]; + }, +}; ``` - -Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. - -You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file. - -This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. - -## Learn More - -To learn more about Next.js, take a look at the following resources: - -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. -- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. - -You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! +2. Set the websocket url in the `src/app/analysis/[id]/page.js` file: +```js +/* src/app/analysis/[id]/page.js */ +export default function Analysis({ params: {id} }) { + // ... + useEffect(() => { + const ws = new WebSocket(`ws{s}://{WEBSOCKET URL}/${id}`); + // ... +``` \ No newline at end of file diff --git a/next.config.mjs b/next.config.mjs index 4678774..48f0bf7 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,4 +1,13 @@ /** @type {import('next').NextConfig} */ -const nextConfig = {}; +const nextConfig = { + async rewrites() { + return [ + { + source: "/api/:path*", + destination: "http://localhost:8080/:path*", + }, + ]; + }, +}; export default nextConfig; diff --git a/src/app/analysis/[id]/page.js b/src/app/analysis/[id]/page.js index 49cb117..152e940 100644 --- a/src/app/analysis/[id]/page.js +++ b/src/app/analysis/[id]/page.js @@ -8,7 +8,6 @@ import "@/styles/analysis/page.css"; export default function Analysis({ params: { id } }) { const [report, setReport] = useState(null); - /* TODO: check if it is possible to make the ws url configurable. /* TODO: check id against http://backend/analysis/id. if it returns 404, then * 404. */ /* TODO: use report.error !!! */ -- GitLab From 3acd85f3a89dce79c34d167c62ddcd0188d03b2a Mon Sep 17 00:00:00 2001 From: phfr24 <phfr24@inf.ufpr.br> Date: Mon, 14 Oct 2024 11:08:04 -0300 Subject: [PATCH 09/14] update readme --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index 45f620d..2024614 100644 --- a/README.md +++ b/README.md @@ -25,4 +25,19 @@ export default function Analysis({ params: {id} }) { useEffect(() => { const ws = new WebSocket(`ws{s}://{WEBSOCKET URL}/${id}`); // ... +``` + +## Development + +1. Enable yarn: +```sh +corepack enable +``` +2. Install dependencies: +```sh +yarn install +``` +3. Start the development server: +```sh +yarn dev ``` \ No newline at end of file -- GitLab From 5c4cb23408b0c36bd2113c101f0a9899c7d60c40 Mon Sep 17 00:00:00 2001 From: phfr24 <phfr24@inf.ufpr.br> Date: Mon, 14 Oct 2024 15:12:28 -0300 Subject: [PATCH 10/14] fernando --- src/app/analysis/[id]/page.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/app/analysis/[id]/page.js b/src/app/analysis/[id]/page.js index 152e940..af1ad71 100644 --- a/src/app/analysis/[id]/page.js +++ b/src/app/analysis/[id]/page.js @@ -4,15 +4,26 @@ import RedirectButton from "@/components/redirect-button"; import { useState, useEffect } from 'react'; import "@/styles/analysis/activity-timeline.css"; import "@/styles/analysis/page.css"; +import { notFound } from "next/navigation"; export default function Analysis({ params: { id } }) { const [report, setReport] = useState(null); + const [failed, setFailed] = useState(false); /* TODO: check id against http://backend/analysis/id. if it returns 404, then * 404. */ /* TODO: use report.error !!! */ + fetch(`/api/analysis/${id}`).then((res) => { + console.log(res); + setFailed(!res.ok); + }); useEffect(() => { + if (failed) { notFound(); } + }, [failed]); + + useEffect(() => { + const ws = new WebSocket(`ws://localhost:8080/status/${id}`); ws.onopen = (event) => { @@ -63,7 +74,7 @@ export default function Analysis({ params: { id } }) { {report.log.map((msg, i) => <div key={i}>{msg}</div>)} </div> </div> - <RedirectButton name="go back" href="/" /> + <RedirectButton name="go back" href="/" /> </div> )} </main> @@ -72,7 +83,7 @@ export default function Analysis({ params: { id } }) { function formatFileSize(bytes) { const sizes = ['B', 'KB', 'MB', 'GB']; - + if (bytes === 0) return '0B'; -- GitLab From 0b4814d8b6ff9f33b7ddfb463e3e74617d417d83 Mon Sep 17 00:00:00 2001 From: pedro friedrich <phfr24@inf.ufpr.br> Date: Mon, 14 Oct 2024 17:06:30 -0300 Subject: [PATCH 11/14] fix insanity --- src/app/analysis/[id]/page.js | 44 +++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/src/app/analysis/[id]/page.js b/src/app/analysis/[id]/page.js index af1ad71..8e21a41 100644 --- a/src/app/analysis/[id]/page.js +++ b/src/app/analysis/[id]/page.js @@ -2,42 +2,32 @@ import { AnalysisMetadata, SampleMetadata } from "@/components/analysis/metadata"; import RedirectButton from "@/components/redirect-button"; import { useState, useEffect } from 'react'; +import { notFound } from "next/navigation"; import "@/styles/analysis/activity-timeline.css"; import "@/styles/analysis/page.css"; -import { notFound } from "next/navigation"; + +/* TODO: use report.error !!! */ + +const api_host = "localhost:8080"; export default function Analysis({ params: { id } }) { const [report, setReport] = useState(null); const [failed, setFailed] = useState(false); - /* TODO: check id against http://backend/analysis/id. if it returns 404, then - * 404. */ - /* TODO: use report.error !!! */ - fetch(`/api/analysis/${id}`).then((res) => { - console.log(res); - setFailed(!res.ok); - }); + validateId(id, setFailed); useEffect(() => { - if (failed) { notFound(); } + if (failed) { + notFound(); + } }, [failed]); useEffect(() => { + const ws = new WebSocket(`ws://${api_host}/status/${id}`); - const ws = new WebSocket(`ws://localhost:8080/status/${id}`); - - ws.onopen = (event) => { - //console.log('websocket connection opened: ', event); - } - ws.onerror = (error) => { - //console.error('websocket connection error: ', error); - } ws.onmessage = (event) => { setReport(JSON.parse(event.data)); } - ws.onclose = (event) => { - //console.log('websocket connection closed: ', event); - } return () => { ws.close(); @@ -81,6 +71,20 @@ export default function Analysis({ params: { id } }) { ); } +function validateId(id, setFailed) { + fetch(`https://${api_host}/analysis/${id}`, { cache: 'no-store' }) + .then((res) => { + if (!res.ok) { + throw new Error(`Failed to validate id: got ${res.status} response from api`); + } + setFailed(false); + }) + .catch((err) => { + //console.error('fetch()', err); + setFailed(true); + }); +} + function formatFileSize(bytes) { const sizes = ['B', 'KB', 'MB', 'GB']; -- GitLab From 4bdb357e8321816627f8f25c9d4a3d7b6b55ac1d Mon Sep 17 00:00:00 2001 From: pedro friedrich <phfr24@inf.ufpr.br> Date: Mon, 14 Oct 2024 17:12:36 -0300 Subject: [PATCH 12/14] display report error --- src/app/analysis/[id]/page.js | 3 +-- src/styles/analysis/activity-timeline.css | 5 +++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/app/analysis/[id]/page.js b/src/app/analysis/[id]/page.js index 8e21a41..e9d0274 100644 --- a/src/app/analysis/[id]/page.js +++ b/src/app/analysis/[id]/page.js @@ -6,8 +6,6 @@ import { notFound } from "next/navigation"; import "@/styles/analysis/activity-timeline.css"; import "@/styles/analysis/page.css"; -/* TODO: use report.error !!! */ - const api_host = "localhost:8080"; export default function Analysis({ params: { id } }) { @@ -62,6 +60,7 @@ export default function Analysis({ params: { id } }) { <div className="activity-timeline"> <div className="at-title">ACTIVITY TIMELINE</div> {report.log.map((msg, i) => <div key={i}>{msg}</div>)} + {report.error && <div className="at-error">{report.error}</div>} </div> </div> <RedirectButton name="go back" href="/" /> diff --git a/src/styles/analysis/activity-timeline.css b/src/styles/analysis/activity-timeline.css index 9d422b2..37633a9 100644 --- a/src/styles/analysis/activity-timeline.css +++ b/src/styles/analysis/activity-timeline.css @@ -24,4 +24,9 @@ .activity-timeline div { margin-bottom: 0.5em; +} + +.at-error { + color: #FF0000; + font-weight: bold; } \ No newline at end of file -- GitLab From 82ab1554ab0cac1ccd6d7d237e6172584338a5c3 Mon Sep 17 00:00:00 2001 From: pedro friedrich <phfr24@inf.ufpr.br> Date: Mon, 14 Oct 2024 17:15:40 -0300 Subject: [PATCH 13/14] update readme --- README.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 2024614..b8a5c44 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ This sucks, but we'll come up with something better later. -1. Set the API url in the `next.config.mjs` file: +1. Set the API host in `next.config.mjs`: ```js /* next.config.mjs */ const nextConfig = { @@ -11,22 +11,21 @@ const nextConfig = { return [ { source: "/api/:path*", - destination: "http{s}://{API URL}/:path*", + destination: "http{s}://{api_host}/:path*", }, ]; }, }; ``` -2. Set the websocket url in the `src/app/analysis/[id]/page.js` file: +2. Set the API host in `src/app/analysis/[id]/page.js`: ```js /* src/app/analysis/[id]/page.js */ -export default function Analysis({ params: {id} }) { - // ... - useEffect(() => { - const ws = new WebSocket(`ws{s}://{WEBSOCKET URL}/${id}`); +const api_host = "{api_host}"; // ... ``` +e.g. api_host = "localhost:8080" + ## Development 1. Enable yarn: -- GitLab From 338bf914f833404ef6e9d266a803e58991f02ff6 Mon Sep 17 00:00:00 2001 From: phfr24 <phfr24@inf.ufpr.br> Date: Tue, 15 Oct 2024 11:14:32 -0300 Subject: [PATCH 14/14] make api_host configurable --- README.md | 42 ++++++++++++++++------------------- next.config.mjs | 2 +- src/app/analysis/[id]/page.js | 6 ++--- 3 files changed, 22 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index b8a5c44..b65c825 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,26 @@ ## Configuration -This sucks, but we'll come up with something better later. +1. Create a `.env.local` file in the root directory of the project: +```bash +# API host for internal requests. +# +# For example, if the API is running on localhost:8080, +# set INTERNAL_API_HOST=localhost:8080. +# +# If the API is running as a docker compose service called "api", +# set INTERNAL_API_HOST=api:8080. +INTERNAL_API_HOST= -1. Set the API host in `next.config.mjs`: -```js -/* next.config.mjs */ -const nextConfig = { - // ... - async rewrites() { - return [ - { - source: "/api/:path*", - destination: "http{s}://{api_host}/:path*", - }, - ]; - }, -}; +# API host for public requests. +# +# This is the host that the client will use to make requests to the API. +# It is needed because the client connects to the API from the browser +# for websocket connections. +# +# For example, if the API is running on saci.inf.ufpr.br:8080, +# set NEXT_PUBLIC_API_HOST=saci.inf.ufpr.br:8080. +NEXT_PUBLIC_API_HOST= ``` -2. Set the API host in `src/app/analysis/[id]/page.js`: -```js -/* src/app/analysis/[id]/page.js */ -const api_host = "{api_host}"; - // ... -``` - -e.g. api_host = "localhost:8080" ## Development diff --git a/next.config.mjs b/next.config.mjs index 48f0bf7..be0bab0 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -4,7 +4,7 @@ const nextConfig = { return [ { source: "/api/:path*", - destination: "http://localhost:8080/:path*", + destination: `http://${process.env.INTERNAL_API_HOST}/:path*`, }, ]; }, diff --git a/src/app/analysis/[id]/page.js b/src/app/analysis/[id]/page.js index e9d0274..4dc844d 100644 --- a/src/app/analysis/[id]/page.js +++ b/src/app/analysis/[id]/page.js @@ -6,8 +6,6 @@ import { notFound } from "next/navigation"; import "@/styles/analysis/activity-timeline.css"; import "@/styles/analysis/page.css"; -const api_host = "localhost:8080"; - export default function Analysis({ params: { id } }) { const [report, setReport] = useState(null); const [failed, setFailed] = useState(false); @@ -21,7 +19,7 @@ export default function Analysis({ params: { id } }) { }, [failed]); useEffect(() => { - const ws = new WebSocket(`ws://${api_host}/status/${id}`); + const ws = new WebSocket(`ws://${process.env.NEXT_PUBLIC_API_HOST}/status/${id}`); ws.onmessage = (event) => { setReport(JSON.parse(event.data)); @@ -71,7 +69,7 @@ export default function Analysis({ params: { id } }) { } function validateId(id, setFailed) { - fetch(`https://${api_host}/analysis/${id}`, { cache: 'no-store' }) + fetch(`http://${process.env.NEXT_PUBLIC_API_HOST}/analysis/${id}`, { cache: 'no-store' }) .then((res) => { if (!res.ok) { throw new Error(`Failed to validate id: got ${res.status} response from api`); -- GitLab