diff --git a/.gitignore b/.gitignore index e69de29..10cd624 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1,4 @@ +*/target +*.env +*.log* +*.lock diff --git a/backend/.env b/backend/.env index 5b5a9be..0fd4590 100644 --- a/backend/.env +++ b/backend/.env @@ -1 +1,2 @@ DATABASE_URL="postgresql://chatapp:chatapp@100.118.108.58:5432/chatapp" +ROCKET_SECRET_KEY="fCHCI6x/uItqldCJTdbruqQvXQXAeH/+vGtXmu3Hv6A=" diff --git a/backend/.gitignore b/backend/.gitignore deleted file mode 100644 index ea8c4bf..0000000 --- a/backend/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 0000000..a20c1d8 --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,47 @@ +FROM docker.io/rust:1-slim-bookworm AS build + +## cargo package name: customize here or provide via --build-arg +ARG pkg=backend +ARG DATABASE_URL + +WORKDIR /build + +COPY .cargo .cargo +COPY cdn cdn +COPY src src +COPY Cargo.toml Cargo.toml +COPY Rocket.toml Rocket.toml +COPY static static +COPY templates templates + +RUN apt-get update && apt-get install -y libssl-dev pkg-config + +RUN --mount=type=cache,target=/build/target \ + --mount=type=cache,target=/usr/local/cargo/registry \ + --mount=type=cache,target=/usr/local/cargo/git \ + set -eux; \ + cargo build --release; \ + objcopy --compress-debug-sections target/release/$pkg ./main + +################################################################################ + +FROM docker.io/debian:bookworm-slim + +RUN apt-get update && apt-get install -y libssl-dev pkg-config + +WORKDIR /app + +## copy the main binary +COPY --from=build /build/main ./ + +## copy runtime assets which may or may not exist +COPY --from=build /build/Rocket.toml ./Rocket.toml +COPY --from=build /build/static ./static +COPY --from=build /build/cdn ./cdn +COPY --from=build /build/template[s] ./templates + +## ensure the container listens globally on port 8000 +ENV ROCKET_ADDRESS=0.0.0.0 +ENV ROCKET_PORT=8000 + +CMD ./main diff --git a/backend/Rocket.toml b/backend/Rocket.toml index 0d6fba7..b48347e 100644 --- a/backend/Rocket.toml +++ b/backend/Rocket.toml @@ -1,6 +1,12 @@ [debug] secret_key = "yYhvCGnRh/TrcHtB8sZqCFifrVmJxoKFLBYw/WWBZeU=" +address = "127.0.0.1" port = 8000 [default.databases.postgres_db] url = "postgresql://chatapp:chatapp@100.118.108.58:5432/chatapp" + +[default] # run inside a docker container or pod +secret_key = "fCHCI6x/uItqldCJTdbruqQvXQXAeH/+vGtXmu3Hv6A=" +address = "0.0.0.0" +port = 8082 diff --git a/backend/src/auth.rs b/backend/src/auth.rs index f699632..65219f0 100644 --- a/backend/src/auth.rs +++ b/backend/src/auth.rs @@ -99,7 +99,7 @@ pub async fn mfa_page(session: Session) -> Template { } #[get("/api/totp.jpg")] -pub async fn gen_totp(s: Session) -> Option { +pub async fn get_totp(s: Session) -> Option { let totp = TOTP::new( Algorithm::SHA1, 6, diff --git a/backend/src/main.rs b/backend/src/main.rs index 0643a54..19bc680 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -2,7 +2,7 @@ #[macro_use] extern crate rocket; -use rocket::fs::FileServer; +use rocket::fs::{FileServer, NamedFile}; use rocket::http::Method; use rocket::serde::json::Json; use rocket::{Build, Rocket}; @@ -66,16 +66,29 @@ fn rocket() -> Rocket { .mount( "/", routes![ - users, - username_for_id, + favicon, messages::chat_page, + auth::signup_page, + auth::login_page, + auth::mfa_page, + ], + ) + .mount( + "/api", + routes![ messages::get_messages, messages::post_message, messages::event_stream, + users, + username_for_id, auth::signup, - auth::signup_page, - auth::login_page, - auth::login + auth::login, + auth::get_totp, ], ) } + +#[get("/favicon.ico")] +async fn favicon() -> NamedFile { + NamedFile::open("static/favicon.ico").await.unwrap() +} diff --git a/backend/static/css/index.css b/backend/static/css/index.css index 5dc0fdd..8560511 100644 --- a/backend/static/css/index.css +++ b/backend/static/css/index.css @@ -34,7 +34,7 @@ body { display: flex; flex-direction: column; height: 100vh; - max-width: 100vw; + min-width: 100vw; margin: 0 0; background: #121212; position: relative; diff --git a/backend/static/favicon.ico b/backend/static/favicon.ico new file mode 100644 index 0000000..62a6d8c Binary files /dev/null and b/backend/static/favicon.ico differ diff --git a/backend/templates/chat.html.tera b/backend/templates/chat.html.tera index 4cd8dcd..fbe19d0 100644 --- a/backend/templates/chat.html.tera +++ b/backend/templates/chat.html.tera @@ -165,7 +165,7 @@ function sendMessage() { const message = input.value.trim(); if (message) { - fetch("http://localhost:8000/chat", { + fetch("/api/chat", { method: "POST", body: JSON.stringify({ user_id: user_id, @@ -189,11 +189,11 @@ async function loadData() { try { - const userIds = await fetch("http://localhost:8000/users/") + const userIds = await fetch("/api/users/") .then(r => r.json()); const userPromises = userIds.map(userId => - fetch(`http://localhost:8000/users/${userId}`) + fetch(`/api/users/${userId}`) .then(r => r.text()) .then(username => ({ userId, username })) ); @@ -206,7 +206,8 @@ console.log('Users loaded:', users); - const messageSource = new EventSource("http://localhost:8000/events"); + const messageSource = new EventSource("/api/events"); + messageSource.onopen = () => messagesContainer.innerHTML = ''; messageSource.onmessage = (event) => insertMessage(JSON.parse(event.data)); messageSource.onerror = (error) => { console.error('EventSource error:', error); diff --git a/backend/templates/login.html.tera b/backend/templates/login.html.tera index a4a1c0e..67b36c0 100644 --- a/backend/templates/login.html.tera +++ b/backend/templates/login.html.tera @@ -109,7 +109,7 @@ try { // Replace with your actual backend endpoint const response = await fetch( - "http://localhost:8000/login", + "/api/login", { method: "POST", headers: { diff --git a/backend/templates/signup.html.tera b/backend/templates/signup.html.tera index 936b7dc..fa49b7e 100644 --- a/backend/templates/signup.html.tera +++ b/backend/templates/signup.html.tera @@ -225,7 +225,7 @@ try { // Replace with your actual backend endpoint const response = await fetch( - "http://localhost:8000/signup", + "/api/signup", { method: "POST", headers: { diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..094bebf --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,14 @@ +services: + backend: + image: git.zxq5.dev/zxq5/chatapp-backend:latest + ports: + - "8000:8000" + depends_on: + - redis + environment: + - ROCKET_SECRET_KEY=$ROCKET_SECRET_KEY + - DATABASE_URL="postgresql://chatapp:chatapp@100.118.108.58:5432/chatapp" + redis: + image: docker.io/library/redis:alpine + ports: + - "6379:6379"