diff --git a/VMSetup.md b/VMSetup.md new file mode 100644 index 0000000..ab02aa7 --- /dev/null +++ b/VMSetup.md @@ -0,0 +1,271 @@ +# Deploy Project 2 to the group VM + +This guide assumes the group VM is Ubuntu, Apache is already serving Project 1, +and you can log in over SSH. Replace `XX`, `NTNU-USERNAME`, `OWNER`, and +`REPOSITORY` with the values for your group and GitHub repository. + +Project 2 uses PostgreSQL, not MongoDB or Neo4j. Follow the +[database setup guide](../db/database-setup.md) to install and populate it. +The backend and database should run on the VM; the browser-based frontend must +use the VM's hostname to reach the backend. + +> **Current project status:** `backend/src/index.ts` is still a placeholder that +> only logs a message, and `frontend/src/App.tsx` is still the Vite starter +> screen. The deployment steps below prepare the VM and publish the frontend, +> but the GraphQL API and application UI must be implemented before the project +> can provide its intended functionality. + +## 1. Log in and install Node.js + +Connect to your group's VM: + +```bash +ssh NTNU-USERNAME@it2810-XX.idi.ntnu.no +``` + +Install the tools needed to clone and build the project: + +```bash +sudo apt update +sudo apt install -y curl ca-certificates git build-essential +``` + +Install Node.js for your own user with `nvm`. Do not use `sudo` for `nvm`, +Node.js, npm, or pnpm commands. + +```bash +curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash +touch ~/.bashrc +cat >> ~/.bashrc <<'EOF' +export NVM_DIR="$HOME/.nvm" +[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" +EOF +if [ ! -f ~/.profile ] && [ ! -f ~/.bash_profile ] && [ ! -f ~/.bash_login ]; then + printf 'if [ -f "$HOME/.bashrc" ]; then\n . "$HOME/.bashrc"\nfi\n' > ~/.profile +fi +source ~/.bashrc +nvm install --lts +nvm alias default 'lts/*' +node --version +npm --version +``` + +The install script may report that it could not find a profile file; the +commands above create the Bash startup files and load `nvm` in the current +session. `npm` is installed together with Node.js, so do not install it +separately with `apt`. + +## 2. Give the VM SSH access to GitHub + +Run these commands as your normal VM user. If prompted for a passphrase, set +one and remember it; do not share or copy the private key. + +```bash +ssh-keygen -t ed25519 -C "NTNU-USERNAME@project2-vm" +eval "$(ssh-agent -s)" +ssh-add ~/.ssh/id_ed25519 +cat ~/.ssh/id_ed25519.pub +``` + +Copy the displayed **public** key. In GitHub, open **Settings → SSH and GPG +keys → New SSH key**, give it a recognizable title such as `Project 2 VM`, and +paste the public key. Never paste or upload `~/.ssh/id_ed25519` (the private +key). + +Verify the connection from the VM: + +```bash +ssh -T git@github.com +``` + +The first connection may ask you to confirm GitHub's host key. Confirm only +after checking that the host is `github.com`. GitHub may report that shell +access is unavailable; that is expected if it also confirms authentication. + +Clone the repository using its SSH URL: + +```bash +git clone git@github.com:OWNER/REPOSITORY.git ~/project2 +cd ~/project2 +``` + +If the repository is private, the GitHub account associated with the SSH key +must have access to it. + +## 3. Install dependencies and build the backend + +This repository uses pnpm workspaces. Install pnpm under the Node version +managed by `nvm`, then install the locked dependencies: + +```bash +npm install --global pnpm@10 +cd ~/project2 +pnpm install --frozen-lockfile +``` + +Create the backend environment file and set the password to the PostgreSQL +password configured in the database setup: + +```bash +cp backend/.env.example backend/.env +nano backend/.env +``` + +If `cp` reports that `backend/.env.example` does not exist, do not guess the +environment variables. First verify that the VM has the intended repository +and branch: + +```bash +cd ~/project2 +git remote -v +git branch -vv +git log -1 --oneline +git ls-files backend/.env.example +``` + +The repository layout should match the project you intend to deploy. If the +remote, branch, or layout differs, resolve that before proceeding. If the +repository is correct but has no example file, inspect the backend source and +configuration for the environment variable names it actually reads, then +create `backend/.env` with those names. Do not commit `.env` or put real +credentials in a tracked example file. + +The file should contain values like these: + +```dotenv +DATABASE_URL=postgresql://gameapp:YOUR_PASSWORD@localhost:5432/gamesdb +PORT=3001 +``` + +Keep `backend/.env` private; do not commit it or share its database password. +If the password contains URL-reserved characters, URL-encode them in +`DATABASE_URL`. + +Build the TypeScript backend: + +```bash +pnpm --filter backend build +``` + +The backend's `build` script compiles TypeScript to `backend/dist`; its +`start` script runs the compiled JavaScript. The running application must load +the environment variables (for example, with `dotenv/config`) and open its +GraphQL HTTP endpoint before it can serve requests. + +## 4. Run the backend after logout + +Use PM2 to keep the backend process running under your VM user: + +```bash +npm install --global pm2 +cd ~/project2/backend +pm2 start dist/index.js --name project2-backend +pm2 save +pm2 startup +``` + +`pm2 startup` prints a command that must be run with `sudo` to enable startup +after a VM reboot. Copy and run that exact command, then save the process list +again: + +```bash +pm2 save +``` + +Useful process commands: + +```bash +pm2 status +pm2 logs project2-backend +pm2 restart project2-backend +pm2 stop project2-backend +``` + +Always start, inspect, and stop this PM2 process as the same VM user. Check +that the backend is not already running before attempting to start another +copy. + +## 5. Build and publish the frontend at `/project2` + +The Vite production build uses `/project2/` as its base path when served from +Apache under that subdirectory. This is configured in +`frontend/vite.config.ts`; the local development server continues to use `/`. + +Build the frontend from the repository root: + +```bash +cd ~/project2 +pnpm --filter frontend build +``` + +Copy the *contents* of the build output to a new Project 2 directory. This does +not replace Project 1: + +```bash +sudo install -d -o "$USER" -g www-data /var/www/html/project2 +sudo cp -a frontend/dist/. /var/www/html/project2/ +``` + +The frontend should then be available at: + +```text +http://it2810-XX.idi.ntnu.no/project2/ +``` + +## 6. Point the browser frontend at the backend + +The frontend runs in each visitor's browser. Therefore `localhost` in a +frontend API URL means the visitor's own computer, **not** the VM. Configure +the frontend to use the VM hostname and the actual GraphQL endpoint, for +example: + +```text +http://it2810-XX.idi.ntnu.no:3001/graphql +``` + +Use the route and port the implemented backend actually serves. The backend +must listen on an address reachable from the browser (often `0.0.0.0` when +connecting directly to port `3001`), and the port must be allowed by the +network. Alternatively, configure Apache as a reverse proxy so the browser can +use the VM's normal HTTP port; that requires an Apache proxy configuration +matching the actual GraphQL route. Do not expose PostgreSQL's port for this: +the backend connects to PostgreSQL locally using `localhost`. + +Once the frontend API client supports configuration, provide its URL at build +time, for example: + +```bash +VITE_GRAPHQL_URL=http://it2810-XX.idi.ntnu.no:3001/graphql pnpm --filter frontend build +``` + +The frontend code must read `VITE_GRAPHQL_URL` for this setting to take effect. +Vite embeds `VITE_` variables into the built client, so never put passwords or +other secrets in them. + +## 7. Update and troubleshoot + +To deploy a later version, first update the checkout and rebuild: + +```bash +cd ~/project2 +git pull +pnpm install --frozen-lockfile +pnpm --filter backend build +pnpm --filter frontend build +``` + +Then restart the backend and copy the new frontend build: + +```bash +pm2 restart project2-backend +sudo cp -a frontend/dist/. /var/www/html/project2/ +``` + +Check processes and backend logs with `pm2 status` and +`pm2 logs project2-backend`. Check Apache with +`sudo systemctl status apache2`. A database connection failure should be +debugged on the VM: confirm PostgreSQL is running and that `DATABASE_URL` +matches the local database and credentials. A browser API connection failure +often means the frontend still uses `localhost`, the backend is not listening +on a reachable address, the chosen port is blocked, or the configured GraphQL +route does not match the server. diff --git a/frontend/src/components/techniques/allTechniques/TechniqueCard/getTechniqueCardVisual.tsx b/frontend/src/components/techniques/allTechniques/TechniqueCard/getTechniqueCardVisual.tsx index 8a13b8f..b2c1eeb 100644 --- a/frontend/src/components/techniques/allTechniques/TechniqueCard/getTechniqueCardVisual.tsx +++ b/frontend/src/components/techniques/allTechniques/TechniqueCard/getTechniqueCardVisual.tsx @@ -7,6 +7,7 @@ import { Layers3, Network, Eye, + FileText, } from "lucide-react"; import type { LucideIcon } from "lucide-react"; diff --git a/frontend/src/pages/SavedItems/SavedItems.tsx b/frontend/src/pages/SavedItems/SavedItems.tsx index 473f482..cb224b4 100644 --- a/frontend/src/pages/SavedItems/SavedItems.tsx +++ b/frontend/src/pages/SavedItems/SavedItems.tsx @@ -1,5 +1,5 @@ -import { ArrowRight, Bookmark, Crosshair, Database, Lock, Search, Settings, Shield, Signal, Users } from "lucide-react"; +import { ArrowRight, Bookmark, Crosshair, Database, Lock, Settings, Shield, Signal, Users } from "lucide-react"; import { useState } from "react"; import "./SavedItems.css"; diff --git a/frontend/src/pages/Techniques/TechniqueDetailed.tsx b/frontend/src/pages/Techniques/TechniqueDetailed.tsx index 3668608..fa0e36c 100644 --- a/frontend/src/pages/Techniques/TechniqueDetailed.tsx +++ b/frontend/src/pages/Techniques/TechniqueDetailed.tsx @@ -4,7 +4,7 @@ import TechniqueOverview from "../../components/techniques/specificTechnique/Tec import SubTechniques from "../../components/techniques/specificTechnique/TechniqueSubTechnique/SubTechniques"; import RelatedThreatActors from "../../components/techniques/specificTechnique/RelatedThreatActors/RelatedThreatActors"; import AssociatedSoftware from "../../components/techniques/specificTechnique/AssociatedSoftware/AssociatedSoftware.tsx"; -import worldMap from "../../assets/tungnguyen0905-technology-7111765.jpg"; +//import worldMap from "../../assets/tungnguyen0905-technology-7111765.jpg"; import "./TechniqueDetailed.css"; const subTechniques = [