diff --git a/README.md b/README.md index c474cb2b7301478ce677f21bd09c2e17d9865693..b65c825601e78074bf10cc859a3f6922dfba2c47 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,38 @@ -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: +## Configuration +1. Create a `.env.local` file in the root directory of the project: ```bash -yarn dev +# 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= + +# 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= ``` -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 +## Development -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! +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 diff --git a/next.config.mjs b/next.config.mjs index 4678774e6d606704bce1897a5dab960cd798bf66..be0bab08716a4abdf44ee665cea1f7a170d3d7ca 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://${process.env.INTERNAL_API_HOST}/:path*`, + }, + ]; + }, +}; export default nextConfig; diff --git a/package.json b/package.json index cac58db53d1b9e0241135667b8c6a6219835222f..cffa4de9f6e25b885165b200968c3e9bfb3d5282 100644 --- a/package.json +++ b/package.json @@ -9,9 +9,10 @@ "lint": "next lint" }, "dependencies": { + "next": "14.2.15", "react": "^18", "react-dom": "^18", - "next": "14.2.13" + "ws": "^8.18.0" }, "devDependencies": { "postcss": "^8", diff --git a/src/app/analysis/[id]/page.js b/src/app/analysis/[id]/page.js index 7058e3f756878690c7557f6b4e6ef6b4c50268b0..4dc844d58f0d83d275e9be2396681a80394265c7 100644 --- a/src/app/analysis/[id]/page.js +++ b/src/app/analysis/[id]/page.js @@ -1,35 +1,93 @@ +'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 { notFound } from "next/navigation"; +import "@/styles/analysis/activity-timeline.css"; import "@/styles/analysis/page.css"; export default function Analysis({ params: { id } }) { + const [report, setReport] = useState(null); + const [failed, setFailed] = useState(false); + + validateId(id, setFailed); + + useEffect(() => { + if (failed) { + notFound(); + } + }, [failed]); + + useEffect(() => { + const ws = new WebSocket(`ws://${process.env.NEXT_PUBLIC_API_HOST}/status/${id}`); + + ws.onmessage = (event) => { + setReport(JSON.parse(event.data)); + } + + return () => { + ws.close(); + } + }, [id, setReport]); + 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" - /> - <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" - /> - </div> - <div className="pagerow"> - <ActivityTimeline /> - </div> - <RedirectButton name="go back" href="/" /> - </div> + <main> + {report && ( + <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={formatFileSize(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> + {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="/" /> + </div> + )} + </main> ); } + +function validateId(id, setFailed) { + 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`); + } + setFailed(false); + }) + .catch((err) => { + //console.error('fetch()', err); + setFailed(true); + }); +} + +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 diff --git a/src/styles/analysis/activity-timeline.css b/src/styles/analysis/activity-timeline.css index 6d481f7f8363f2c1bc382fc3d86ac59075597ad4..37633a945ab38deb006ad26acc4ea8f5673e6d95 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,12 @@ text-align: center; border-bottom: 1px solid #1F1C1A; } + +.activity-timeline div { + margin-bottom: 0.5em; +} + +.at-error { + color: #FF0000; + font-weight: bold; +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 388879cd168ae497906335a566ef62a4f98c1c52..651400db7406a96eab8b67bd3c8bf969b0edac85 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" @@ -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"