From b9e362497a3772612e81d4a3517f38484d4771b4 Mon Sep 17 00:00:00 2001 From: dan612 Date: Sun, 22 Mar 2026 13:23:31 -0400 Subject: [PATCH] Adding so many things. --- Dockerfile | 15 --------- composer.json | 2 -- database/schema.sql | 6 +++- docker-compose.yml | 22 +++++++++--- index.php | 7 +++- nginx.conf | 32 ++++++++++++++++++ scripts/create-account.sh | 3 ++ scripts/rebuild.sh | 2 -- scripts/start.sh | 2 -- src/Controller/ApiWebhookController.php | 45 ++++++++++++++++++------- 10 files changed, 95 insertions(+), 41 deletions(-) delete mode 100644 Dockerfile create mode 100644 nginx.conf delete mode 100755 scripts/rebuild.sh delete mode 100755 scripts/start.sh diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index dffe8c8..0000000 --- a/Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM php:8.4-fpm - -# Install SQLite extension and Node.js -RUN apt-get update && apt-get install -y \ - sqlite3 \ - libsqlite3-dev \ - curl \ - && docker-php-ext-install pdo_sqlite \ - && curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - \ - && apt-get install -y nodejs \ - && rm -rf /var/lib/apt/lists/* - -# Set working directory -WORKDIR /app -COPY ./src . diff --git a/composer.json b/composer.json index 5054673..cf08266 100644 --- a/composer.json +++ b/composer.json @@ -16,8 +16,6 @@ "guzzlehttp/guzzle": "^7.10" }, "scripts": { - "start": "sh scripts/start.sh", - "rebuild": "sh scripts/rebuild.sh", "theme": "sh scripts/theme.sh", "db-reset": "sh scripts/db-setup.sh" } diff --git a/database/schema.sql b/database/schema.sql index 664f45d..596bd88 100644 --- a/database/schema.sql +++ b/database/schema.sql @@ -55,9 +55,13 @@ CREATE TABLE IF NOT EXISTS user_accounts ( CREATE TABLE IF NOT EXISTS pageviews ( id INTEGER PRIMARY KEY AUTOINCREMENT, - account_id INTEGER NOT NULL, + account_id TEXT NOT NULL, page TEXT NOT NULL, + title TEXT, user_agent TEXT, + screen_res TEXT, + language TEXT, + timestamp TEXT, referrer TEXT, ip TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, diff --git a/docker-compose.yml b/docker-compose.yml index 41ebcb6..086c0a4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,11 +1,23 @@ services: - app: - build: . - ports: - - "127.0.0.1:9000:9000" + php: + image: dchadwick/planet-express:1.0.1 + working_dir: /app + command: php-fpm -F volumes: - .:/app - - ./database:/app/database # Persists your SQLite file + - ./database:/app/database + networks: + - app-network + + web: + image: nginx:alpine + ports: + - "8000:80" + volumes: + - .:/app + - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro + depends_on: + - php networks: - app-network diff --git a/index.php b/index.php index 2596668..76eb797 100644 --- a/index.php +++ b/index.php @@ -25,7 +25,12 @@ if (!$router->routeExists($path)) { // now we dont have to do this in every controller. // Still allow login on homepage. $request = new Request(); -$allowed_paths = ['/', '/user-login']; +$allowed_paths = [ + '/', + '/user-login', + '/api/v1/webhook' +]; + if ( !$request->getCookie('ORIGOSESS') && !in_array($path, $allowed_paths) diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..01bc2fd --- /dev/null +++ b/nginx.conf @@ -0,0 +1,32 @@ +server { + listen 80; + server_name localhost; + + # This MUST match the working_dir and volume path from your docker-compose.yml + root /app; + index index.php index.html; + + # Using underscores for log files + access_log /var/log/nginx/access_log.log; + error_log /var/log/nginx/error_log.log; + + # Route everything to index.php if the file doesn't explicitly exist + location / { + try_files $uri $uri/ /index.php?$query_string; + } + + # Pass all .php files to the PHP-FPM container + location ~ \.php$ { + try_files $uri =404; + fastcgi_split_path_info ^(.+\.php)(/.+)$; + + # 'php' is the name of the service in your docker-compose.yml + # 9000 is the default port PHP-FPM listens on + fastcgi_pass php:9000; + fastcgi_index index.php; + + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param PATH_INFO $fastcgi_path_info; + } +} diff --git a/scripts/create-account.sh b/scripts/create-account.sh index 2942746..aed6193 100644 --- a/scripts/create-account.sh +++ b/scripts/create-account.sh @@ -1,2 +1,5 @@ #!/usr/bin/env bash + +PASSWORD=$1 +echo -n $1 | shasum -a 256 openssl rand -hex 16 diff --git a/scripts/rebuild.sh b/scripts/rebuild.sh deleted file mode 100755 index aa1eb65..0000000 --- a/scripts/rebuild.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -docker build -t origo . diff --git a/scripts/start.sh b/scripts/start.sh deleted file mode 100755 index 2804698..0000000 --- a/scripts/start.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -docker run --rm -p 8000:8000 -v $(pwd):/app origo php -S 0.0.0.0:8000 diff --git a/src/Controller/ApiWebhookController.php b/src/Controller/ApiWebhookController.php index e44e6b3..24b7bde 100644 --- a/src/Controller/ApiWebhookController.php +++ b/src/Controller/ApiWebhookController.php @@ -30,30 +30,49 @@ class ApiWebhookController extends ControllerBase implements ControllerInterface * The response. */ public function getResponse(): string { - header('Access-Control-Allow-Origin: *'); // Allow all origins. - header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS'); - header('Access-Control-Allow-Headers: Content-Type, Authorization'); + // @todo: Create Enum. + $allowed_origins = [ + 'http://127.0.0.1:8088', + 'http://localhost:8088', + 'https://yourproduction-site.com', + 'https://another-client-site.io' + ]; + $origin = $_SERVER['HTTP_ORIGIN'] ?? ''; + // Check if the requester is in our whitelist + if (in_array($origin, $allowed_origins)) { + header("Access-Control-Allow-Origin: $origin"); + header("Access-Control-Allow-Credentials: true"); + header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); + header("Access-Control-Allow-Headers: Content-Type, Authorization"); + } + // Handle preflight OPTIONS request if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(200); exit(); // Stop here - don't process the request } - // Make sure we have a path and account before proceeding. - $path = $this->request->post('path'); - $account_id = $this->request->post('account'); - if ( - !$path || - !$account_id - ) { + + $raw_input = file_get_contents('php://input'); + $json_data = json_decode($raw_input, true) ?? []; + $path = $json_data['path'] ?? $this->request->post('path'); + $account_id = $json_data['account'] ?? $this->request->post('account'); + + if (!$path || !$account_id) { + // Log what actually arrived to help debugging + error_log("Missing Data - Path: $path, Account: $account_id. Raw: $raw_input"); header("HTTP/1.1 422 Unprocessable Entity"); - die(); + die("Missing required fields"); } // @todo: validate the account id. $entry = [ 'page' => $path, 'account_id' => $account_id, - 'user_agent' => $this->request->post('user_agent'), - 'referrer' => $this->request->post('referrer'), + 'title' => $json_data['title'] ?? null, + 'user_agent' => $json_data['user_agent'] ?? null, + 'screen_res' => $json_data['screen_res'] ?? null, + 'language' => $json_data['lang'] ?? null, + 'timestamp' => $json_data['ts'] ?? null, + 'referrer' => $json_data['referrer'] ?? null, 'ip' => $this->request->ip(), ]; $clean_entry = array_filter($entry);