From 280b9a13d6196828cc49a1488bfd45abcc46a007 Mon Sep 17 00:00:00 2001 From: Danny Coulombe Date: Tue, 15 Apr 2025 09:32:10 -0400 Subject: [PATCH 1/4] can't access webhook when shared --- composer.json | 2 +- src/queries/get-all-webhooks.sql | 21 ++++++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index 930a198..f407e6f 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "version": "1.0.8", + "version": "1.0.9", "name": "jsonms/server", "description": "The JSON.ms Request Handler Server is a robust backend solution designed to manage and process all incoming requests from the main JSON.ms website.", "license": "BSD-3-Clause", diff --git a/src/queries/get-all-webhooks.sql b/src/queries/get-all-webhooks.sql index ddcd0d5..9c562be 100644 --- a/src/queries/get-all-webhooks.sql +++ b/src/queries/get-all-webhooks.sql @@ -1,5 +1,16 @@ -SELECT - w.* -FROM webhooks AS w -WHERE - w.created_by = :userId +SELECT DISTINCT combined_results.uuid, combined_results.* +FROM ( + SELECT w.* + FROM webhooks AS w + WHERE w.created_by = :userId + + UNION ALL + + SELECT w.* + FROM permissions AS p + INNER JOIN users AS u ON u.email = p.email + INNER JOIN interfaces AS i ON i.uuid = p.interface_uuid + INNER JOIN users AS owner ON owner.id = i.created_by + LEFT JOIN webhooks AS w ON w.uuid = i.webhook + WHERE u.id = :userId + ) AS combined_results \ No newline at end of file From d875fb438082ef24aeb39d4967c83777b76802b1 Mon Sep 17 00:00:00 2001 From: Danny Coulombe Date: Wed, 16 Apr 2025 18:43:25 -0400 Subject: [PATCH 2/4] change interface to structure --- composer.json | 2 +- src/controllers/GoogleController.php | 2 +- src/controllers/SessionController.php | 42 +-- ...Controller.php => StructureController.php} | 268 +++++++++--------- ...ete-interface.sql => delete-structure.sql} | 2 +- src/queries/delete-user-permissions.sql | 2 +- ...l => get-accessible-structure-by-uuid.sql} | 10 +- ...-interfaces.sql => get-all-structures.sql} | 12 +- src/queries/get-all-webhooks.sql | 2 +- ...o-interface.sql => get-demo-structure.sql} | 2 +- ...-by-hash.sql => get-structure-by-hash.sql} | 8 +- ...-by-uuid.sql => get-structure-by-uuid.sql} | 8 +- src/queries/insert-permissions.sql | 2 +- ...ert-interface.sql => insert-structure.sql} | 2 +- ...-uuid.sql => update-structure-by-uuid.sql} | 2 +- 15 files changed, 186 insertions(+), 180 deletions(-) rename src/controllers/{InterfaceController.php => StructureController.php} (54%) rename src/queries/{delete-interface.sql => delete-structure.sql} (67%) rename src/queries/{get-accessible-interface-by-uuid.sql => get-accessible-structure-by-uuid.sql} (55%) rename src/queries/{get-all-interfaces.sql => get-all-structures.sql} (69%) rename src/queries/{get-demo-interface.sql => get-demo-structure.sql} (92%) rename src/queries/{get-interface-by-hash.sql => get-structure-by-hash.sql} (59%) rename src/queries/{get-interface-by-uuid.sql => get-structure-by-uuid.sql} (59%) rename src/queries/{insert-interface.sql => insert-structure.sql} (52%) rename src/queries/{update-interface-by-uuid.sql => update-structure-by-uuid.sql} (84%) diff --git a/composer.json b/composer.json index f407e6f..fe99334 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "version": "1.0.9", + "version": "1.0.10", "name": "jsonms/server", "description": "The JSON.ms Request Handler Server is a robust backend solution designed to manage and process all incoming requests from the main JSON.ms website.", "license": "BSD-3-Clause", diff --git a/src/controllers/GoogleController.php b/src/controllers/GoogleController.php index aec526b..8847dc5 100644 --- a/src/controllers/GoogleController.php +++ b/src/controllers/GoogleController.php @@ -49,7 +49,7 @@ public function callbackAction() { // Redirect to a protected page or dashboard $decodedState = json_decode(urldecode($state), true); - header('Location: ' . $_ENV['INTERFACE_EDITOR_URL'] . $decodedState['path']); + header('Location: ' . $_ENV['STRUCTURE_EDITOR_URL'] . $decodedState['path']); exit; } else { throwError(400, "Error during authentication."); diff --git a/src/controllers/SessionController.php b/src/controllers/SessionController.php index 1618233..8fead56 100644 --- a/src/controllers/SessionController.php +++ b/src/controllers/SessionController.php @@ -4,14 +4,14 @@ class SessionController extends RestfulController { - private function getDemoInterface() { - $stmt = $this->query('get-demo-interface'); + private function getDemoStructure() { + $stmt = $this->query('get-demo-structure'); if ($stmt->rowCount() > 0) { $rows = $stmt->fetchAll(PDO::FETCH_OBJ); foreach ($rows as $row) { $row->permission_admin = []; - $row->permission_interface = []; - $row->type = 'interface,admin'; + $row->permission_structure = []; + $row->type = 'structure,admin'; return $row; } } @@ -33,13 +33,13 @@ public function indexAction() { $loggedIn = isset($_SESSION['access_token']) && $_SESSION['access_token']; $user = null; $loginUrl = null; - $interfaces = []; + $structures = []; $webhooks = []; - // Fetch demo interface - $demo = $this->getDemoInterface(); + // Fetch demo structure + $demo = $this->getDemoStructure(); if ($demo) { - $interfaces[] = $demo; + $structures[] = $demo; } if ($loggedIn) { @@ -88,7 +88,7 @@ public function indexAction() { 'loggedIn' => false, 'user' => $user, 'googleOAuthSignInUrl' => $loginUrl, - 'interfaces' => $interfaces, + 'structures' => $structures, 'webhooks' => $webhooks, ]); } @@ -105,22 +105,22 @@ public function indexAction() { if ($loggedIn && isset($user)) { - // Fetch all interfaces - $stmt = $this->query('get-all-interfaces', [ + // Fetch all structures + $stmt = $this->query('get-all-structures', [ 'userId' => $this->getCurrentUserId(), ]); - $interfaces = []; + $structures = []; if ($stmt->rowCount() > 0) { $rows = $stmt->fetchAll(PDO::FETCH_OBJ); foreach ($rows as $row) { $row->permission_admin = array_filter(explode(',', $row->permission_admin ?? '')); - $row->permission_interface = array_filter(explode(',', $row->permission_interface ?? '')); - $interfaces[] = $row; + $row->permission_structure = array_filter(explode(',', $row->permission_structure ?? '')); + $structures[] = $row; } } } - // Fetch demo interface + // Fetch demo structure $loggedIn = $loggedIn && isset($user); if ($loggedIn) { $webhooks = $this->getWebhooks($user->id); @@ -130,7 +130,7 @@ public function indexAction() { 'loggedIn' => $loggedIn, 'user' => $user, 'googleOAuthSignInUrl' => $loginUrl, - 'interfaces' => $interfaces, + 'structures' => $structures, 'webhooks' => $webhooks, ]); } @@ -150,11 +150,11 @@ public function logoutAction() { // Generate the login URL $loginUrl = $client->createAuthUrl(); - // Fetch demo interface - $interfaces = []; - $demo = $this->getDemoInterface(); + // Fetch demo structure + $structures = []; + $demo = $this->getDemoStructure(); if ($demo) { - $interfaces[] = $demo; + $structures[] = $demo; } // Return the JSON response @@ -162,7 +162,7 @@ public function logoutAction() { 'loggedIn' => false, 'user' => null, 'googleOAuthSignInUrl' => $loginUrl, - 'interfaces' => $interfaces, + 'structures' => $structures, 'webhooks' => [], ]); } diff --git a/src/controllers/InterfaceController.php b/src/controllers/StructureController.php similarity index 54% rename from src/controllers/InterfaceController.php rename to src/controllers/StructureController.php index 81ad009..be1aa66 100644 --- a/src/controllers/InterfaceController.php +++ b/src/controllers/StructureController.php @@ -1,131 +1,137 @@ -query('get-all-interfaces', [ - 'userId' => $this->getCurrentUserId(), - ]); - $users = $stmt->fetchAll(); - $this->responseJson($users); - } - - public function getAction($id) { - $interface = $this->getAccessibleInterface($id); - $this->responseJson($interface); - } - - public function createAction($data) { - $hash = $this->getHash(); - - $this->query('insert-interface', [ - 'hash' => $hash, - 'label' => $data->label, - 'logo' => $data->logo, - 'content' => $data->content, - 'webhook' => $data->webhook, - 'created_by' => $this->getCurrentUserId(), - ]); - - // Get inserted interface - $interface = $this->query('get-interface-by-hash', [ - 'hash' => $hash, - ])->fetch(PDO::FETCH_OBJ); - $this->preparePermissions($interface); - - $this->responseJson($interface); - } - - public function updateAction($id, $data) { - $currentInterface = $this->getAccessibleInterface($id); - if ($currentInterface) { - - // Copy current interface to history table - $this->copyToHistory($currentInterface); - - // Update interface - $this->query('update-interface-by-uuid', [ - 'uuid' => $data->uuid, - 'label' => $data->label, - 'logo' => $data->logo, - 'content' => $data->content, - 'webhook' => $data->webhook, - 'userId' => $this->getCurrentUserId(), - ]); - - // Clear all existing permissions (will be added later on) - if ($data->created_by === $this->getCurrentUserId()) { - $this->updatePermissions($data); - } - - $this->responseJson($data); - } - } - - public function deleteAction($id) { - if ($this->hasAccess($id)) { - $stmt = $this->query('delete-interface', [ - 'uuid' => $id, - 'userId' => $this->getCurrentUserId(), - ]); - if ($stmt->rowCount() > 0) { - $this->responseJson(true); - } - } - } - - private function hasAccess($uuid, $showError = true): bool { - return (bool) $this->getAccessibleInterface($uuid, $showError); - } - - private function getAccessibleInterface($uuid, $showError = true): false | stdClass { - $stmt = $this->query('get-accessible-interface-by-uuid', [ - 'uuid' => $uuid, - 'userId' => $this->getCurrentUserId(), - ]); - if ($stmt->rowCount() > 0) { - $interface = $stmt->fetch(PDO::FETCH_OBJ); - $this->preparePermissions($interface); - return $interface; - } - if ($showError) { - throwError(403, 'You don\'t have permission to view this interface'); - } - return false; - } - - private function preparePermissions(&$interface) { - $interface->permission_admin = array_filter(explode(',', $interface->permission_admin ?? '')); - $interface->permission_interface = array_filter(explode(',', $interface->permission_interface ?? '')); - return $interface; - } - - private function copyToHistory(stdClass $interface) { - $this->query('insert-history', [ - 'uuid' => $interface->uuid, - 'content' => $interface->content, - 'userId' => $this->getCurrentUserId(), - ]); - } - - private function updatePermissions($interface) { - - // Delete current permissions - $this->query('delete-user-permissions', [ - 'uuid' => $interface->uuid, - ]); - - // Update with newest permissions - foreach (['interface', 'admin'] as $type) { - foreach ($interface->{'permission_' . $type} as $email) { - $this->query('insert-permissions', [ - 'uuid' => $interface->uuid, - 'type' => $type, - 'email' => $email, - ]); - } - } - } -} +query('get-all-structures', [ + 'userId' => $this->getCurrentUserId(), + ]); + $users = $stmt->fetchAll(); + $this->responseJson($users); + } + + public function getAction($id) { + $structure = $this->getAccessibleStructure($id); + $this->responseJson($structure); + } + + public function createAction($data) { + $hash = $this->getHash(); + + $this->query('insert-structure', [ + 'hash' => $hash, + 'label' => $data->label, + 'logo' => $data->logo, + 'content' => $data->content, + 'webhook' => $data->webhook, + 'created_by' => $this->getCurrentUserId(), + ]); + + // Get inserted structure + $structure = $this->query('get-structure-by-hash', [ + 'hash' => $hash, + ])->fetch(PDO::FETCH_OBJ); + $this->preparePermissions($structure); + + // Update structure +// $this->updateStructure($hash, $structure); + + $this->responseJson($structure); + } + + public function updateAction($id, $data) { + $currentStructure = $this->getAccessibleStructure($id); + if ($currentStructure) { + + // Copy current structure to history table + $this->copyToHistory($currentStructure); + + // Update structure + $this->query('update-structure-by-uuid', [ + 'uuid' => $data->uuid, + 'label' => $data->label, + 'logo' => $data->logo, + 'content' => $data->content, + 'webhook' => $data->webhook, + 'userId' => $this->getCurrentUserId(), + ]); + + // Clear all existing permissions (will be added later on) + if ($data->created_by === $this->getCurrentUserId()) { + $this->updatePermissions($data); + } + + // Update structure +// $this->updateStructure($data->hash, $structure); + + $this->responseJson($data); + } + } + + public function deleteAction($id) { + if ($this->hasAccess($id)) { + $stmt = $this->query('delete-structure', [ + 'uuid' => $id, + 'userId' => $this->getCurrentUserId(), + ]); + if ($stmt->rowCount() > 0) { + $this->responseJson(true); + } + } + } + + private function hasAccess($uuid, $showError = true): bool { + return (bool) $this->getAccessibleStructure($uuid, $showError); + } + + private function getAccessibleStructure($uuid, $showError = true): false | stdClass { + $stmt = $this->query('get-accessible-structure-by-uuid', [ + 'uuid' => $uuid, + 'userId' => $this->getCurrentUserId(), + ]); + if ($stmt->rowCount() > 0) { + $structure = $stmt->fetch(PDO::FETCH_OBJ); + $this->preparePermissions($structure); + return $structure; + } + if ($showError) { + throwError(403, 'You don\'t have permission to view this structure'); + } + return false; + } + + private function preparePermissions(&$structure) { + $structure->permission_admin = array_filter(explode(',', $structure->permission_admin ?? '')); + $structure->permission_structure = array_filter(explode(',', $structure->permission_structure ?? '')); + return $structure; + } + + private function copyToHistory(stdClass $structure) { + $this->query('insert-history', [ + 'uuid' => $structure->uuid, + 'content' => $structure->content, + 'userId' => $this->getCurrentUserId(), + ]); + } + + private function updatePermissions($structure) { + + // Delete current permissions + $this->query('delete-user-permissions', [ + 'uuid' => $structure->uuid, + ]); + + // Update with newest permissions + foreach (['structure', 'admin'] as $type) { + foreach ($structure->{'permission_' . $type} as $email) { + $this->query('insert-permissions', [ + 'uuid' => $structure->uuid, + 'type' => $type, + 'email' => $email, + ]); + } + } + } +} diff --git a/src/queries/delete-interface.sql b/src/queries/delete-structure.sql similarity index 67% rename from src/queries/delete-interface.sql rename to src/queries/delete-structure.sql index 4d5b0ee..d08b029 100644 --- a/src/queries/delete-interface.sql +++ b/src/queries/delete-structure.sql @@ -1,3 +1,3 @@ -DELETE FROM interfaces +DELETE FROM structures WHERE uuid = :uuid AND created_by = :userId diff --git a/src/queries/delete-user-permissions.sql b/src/queries/delete-user-permissions.sql index b5d0178..438070b 100644 --- a/src/queries/delete-user-permissions.sql +++ b/src/queries/delete-user-permissions.sql @@ -1,2 +1,2 @@ DELETE FROM permissions -WHERE interface_uuid = :uuid +WHERE structure_uuid = :uuid diff --git a/src/queries/get-accessible-interface-by-uuid.sql b/src/queries/get-accessible-structure-by-uuid.sql similarity index 55% rename from src/queries/get-accessible-interface-by-uuid.sql rename to src/queries/get-accessible-structure-by-uuid.sql index 2cf1a00..ca215d4 100644 --- a/src/queries/get-accessible-interface-by-uuid.sql +++ b/src/queries/get-accessible-structure-by-uuid.sql @@ -1,19 +1,19 @@ SELECT i.*, - GROUP_CONCAT(DISTINCT(pi.email)) as permission_interface, + GROUP_CONCAT(DISTINCT(pi.email)) as permission_structure, GROUP_CONCAT(DISTINCT(pa.email)) as permission_admin, 'owner' AS type, u.name AS owner_name -FROM interfaces AS i +FROM structures AS i INNER JOIN users AS u ON u.id = i.created_by - LEFT JOIN permissions AS pa ON pa.interface_uuid = i.uuid AND pa.type = 'admin' - LEFT JOIN permissions AS pi ON pi.interface_uuid = i.uuid AND pi.type = 'interface' + LEFT JOIN permissions AS pa ON pa.structure_uuid = i.uuid AND pa.type = 'admin' + LEFT JOIN permissions AS pi ON pi.structure_uuid = i.uuid AND pi.type = 'structure' WHERE i.uuid = :uuid AND (i.created_by = :userId OR EXISTS ( SELECT 1 FROM permissions AS p JOIN users AS up ON up.email = p.email - WHERE p.interface_uuid = i.uuid AND up.id = :userId + WHERE p.structure_uuid = i.uuid AND up.id = :userId )) GROUP BY i.uuid, u.name; diff --git a/src/queries/get-all-interfaces.sql b/src/queries/get-all-structures.sql similarity index 69% rename from src/queries/get-all-interfaces.sql rename to src/queries/get-all-structures.sql index b4d3f8a..4049e2a 100644 --- a/src/queries/get-all-interfaces.sql +++ b/src/queries/get-all-structures.sql @@ -1,15 +1,15 @@ SELECT i.*, - GROUP_CONCAT(DISTINCT(pi.email)) as permission_interface, + GROUP_CONCAT(DISTINCT(pi.email)) as permission_structure, GROUP_CONCAT(DISTINCT(pa.email)) as permission_admin, 'owner' AS type, u.name AS owner_name, w.url AS server_url, w.secret AS server_secret -FROM interfaces AS i +FROM structures AS i INNER JOIN users AS u ON u.id = i.created_by - LEFT JOIN permissions AS pa ON pa.interface_uuid = i.uuid AND pa.type = 'admin' - LEFT JOIN permissions AS pi ON pi.interface_uuid = i.uuid AND pi.type = 'interface' + LEFT JOIN permissions AS pa ON pa.structure_uuid = i.uuid AND pa.type = 'admin' + LEFT JOIN permissions AS pi ON pi.structure_uuid = i.uuid AND pi.type = 'structure' LEFT JOIN webhooks AS w ON w.uuid = i.webhook WHERE i.created_by = :userId GROUP BY i.uuid @@ -17,7 +17,7 @@ GROUP BY i.uuid UNION ALL SELECT i.*, - null AS permission_interface, + null AS permission_structure, null AS permission_admin, GROUP_CONCAT(DISTINCT(p.type)) as type, owner.name AS owner_name, @@ -25,7 +25,7 @@ SELECT i.*, w.secret AS server_secret FROM permissions AS p INNER JOIN users AS u ON u.email = p.email - INNER JOIN interfaces AS i ON i.uuid = p.interface_uuid + INNER JOIN structures AS i ON i.uuid = p.structure_uuid INNER JOIN users AS owner ON owner.id = i.created_by LEFT JOIN webhooks AS w ON w.uuid = i.webhook WHERE u.id = :userId diff --git a/src/queries/get-all-webhooks.sql b/src/queries/get-all-webhooks.sql index 9c562be..83d519f 100644 --- a/src/queries/get-all-webhooks.sql +++ b/src/queries/get-all-webhooks.sql @@ -9,7 +9,7 @@ FROM ( SELECT w.* FROM permissions AS p INNER JOIN users AS u ON u.email = p.email - INNER JOIN interfaces AS i ON i.uuid = p.interface_uuid + INNER JOIN structures AS i ON i.uuid = p.structure_uuid INNER JOIN users AS owner ON owner.id = i.created_by LEFT JOIN webhooks AS w ON w.uuid = i.webhook WHERE u.id = :userId diff --git a/src/queries/get-demo-interface.sql b/src/queries/get-demo-structure.sql similarity index 92% rename from src/queries/get-demo-interface.sql rename to src/queries/get-demo-structure.sql index e438369..f876263 100644 --- a/src/queries/get-demo-interface.sql +++ b/src/queries/get-demo-structure.sql @@ -3,7 +3,7 @@ SELECT u.name AS owner_name, w.url AS server_url, w.secret AS server_secret -FROM interfaces AS i +FROM structures AS i INNER JOIN users AS u ON u.id = i.created_by LEFT JOIN webhooks AS w ON w.uuid = i.webhook WHERE i.hash = "demo" diff --git a/src/queries/get-interface-by-hash.sql b/src/queries/get-structure-by-hash.sql similarity index 59% rename from src/queries/get-interface-by-hash.sql rename to src/queries/get-structure-by-hash.sql index 04ea819..ea7962f 100644 --- a/src/queries/get-interface-by-hash.sql +++ b/src/queries/get-structure-by-hash.sql @@ -1,15 +1,15 @@ SELECT i.*, - GROUP_CONCAT(DISTINCT(pi.email)) as permission_interface, + GROUP_CONCAT(DISTINCT(pi.email)) as permission_structure, GROUP_CONCAT(DISTINCT(pa.email)) as permission_admin, 'owner' AS type, u.name AS owner_name, w.url AS server_url, w.secret AS server_secret -FROM interfaces AS i +FROM structures AS i INNER JOIN users AS u ON u.id = i.created_by - LEFT JOIN permissions AS pa ON pa.interface_uuid = i.uuid AND pa.type = 'admin' - LEFT JOIN permissions AS pi ON pi.interface_uuid = i.uuid AND pi.type = 'interface' + LEFT JOIN permissions AS pa ON pa.structure_uuid = i.uuid AND pa.type = 'admin' + LEFT JOIN permissions AS pi ON pi.structure_uuid = i.uuid AND pi.type = 'structure' LEFT JOIN webhooks AS w ON w.uuid = i.webhook WHERE i.hash = :hash GROUP BY diff --git a/src/queries/get-interface-by-uuid.sql b/src/queries/get-structure-by-uuid.sql similarity index 59% rename from src/queries/get-interface-by-uuid.sql rename to src/queries/get-structure-by-uuid.sql index 107721e..a913203 100644 --- a/src/queries/get-interface-by-uuid.sql +++ b/src/queries/get-structure-by-uuid.sql @@ -1,15 +1,15 @@ SELECT i.*, - GROUP_CONCAT(DISTINCT(pi.email)) as permission_interface, + GROUP_CONCAT(DISTINCT(pi.email)) as permission_structure, GROUP_CONCAT(DISTINCT(pa.email)) as permission_admin, 'owner' AS type, u.name AS owner_name, w.url AS server_url, w.secret AS server_secret -FROM interfaces AS i +FROM structures AS i INNER JOIN users AS u ON u.id = i.created_by - LEFT JOIN permissions AS pa ON pa.interface_uuid = i.uuid AND pa.type = 'admin' - LEFT JOIN permissions AS pi ON pi.interface_uuid = i.uuid AND pi.type = 'interface' + LEFT JOIN permissions AS pa ON pa.structure_uuid = i.uuid AND pa.type = 'admin' + LEFT JOIN permissions AS pi ON pi.structure_uuid = i.uuid AND pi.type = 'structure' LEFT JOIN webhooks AS w ON w.uuid = i.webhook WHERE i.uuid = :uuid GROUP BY diff --git a/src/queries/insert-permissions.sql b/src/queries/insert-permissions.sql index 6d811b4..7c1dcdf 100644 --- a/src/queries/insert-permissions.sql +++ b/src/queries/insert-permissions.sql @@ -1,2 +1,2 @@ -INSERT INTO permissions (interface_uuid, type, email) +INSERT INTO permissions (structure_uuid, type, email) VALUES (:uuid, :type, :email) diff --git a/src/queries/insert-interface.sql b/src/queries/insert-structure.sql similarity index 52% rename from src/queries/insert-interface.sql rename to src/queries/insert-structure.sql index be1a49a..e594c5e 100644 --- a/src/queries/insert-interface.sql +++ b/src/queries/insert-structure.sql @@ -1,2 +1,2 @@ -INSERT INTO interfaces (hash, label, logo, content, webhook, created_by) +INSERT INTO structures (hash, label, logo, content, webhook, created_by) VALUES (:hash, :label, :logo, :content, :webhook, :created_by) diff --git a/src/queries/update-interface-by-uuid.sql b/src/queries/update-structure-by-uuid.sql similarity index 84% rename from src/queries/update-interface-by-uuid.sql rename to src/queries/update-structure-by-uuid.sql index 7825d99..227be08 100644 --- a/src/queries/update-interface-by-uuid.sql +++ b/src/queries/update-structure-by-uuid.sql @@ -1,3 +1,3 @@ -UPDATE interfaces AS i +UPDATE structures AS i SET i.label = :label, i.logo = :logo, i.content = :content, i.webhook = :webhook, i.updated_at = NOW() WHERE i.uuid = :uuid From a368b7ca307c58038b4a3d252ae6f9d94fbade5e Mon Sep 17 00:00:00 2001 From: Danny Coulombe Date: Thu, 1 May 2025 08:05:00 -0400 Subject: [PATCH 3/4] webhook to endpoint + interface to structure --- .env.example | 4 +- composer.json | 2 +- ...kController.php => EndpointController.php} | 38 +++++++++---------- src/controllers/GoogleController.php | 2 +- src/controllers/SessionController.php | 14 +++---- src/controllers/StructureController.php | 30 ++++++--------- ...y-uuid.sql => delete-endpoint-by-uuid.sql} | 2 +- ...all-webhooks.sql => get-all-endpoints.sql} | 10 ++--- src/queries/get-all-structures.sql | 12 +++--- src/queries/get-demo-structure.sql | 6 +-- src/queries/get-endpoint-by-uuid.sql | 6 +++ src/queries/get-structure-by-hash.sql | 6 +-- src/queries/get-structure-by-uuid.sql | 6 +-- src/queries/get-webhook-by-uuid.sql | 6 --- src/queries/insert-endpoint.sql | 2 + src/queries/insert-structure.sql | 4 +- src/queries/insert-webhook.sql | 2 - src/queries/update-endpoint-by-uuid.sql | 4 ++ src/queries/update-structure-by-uuid.sql | 2 +- src/queries/update-webhook-by-uuid.sql | 4 -- 20 files changed, 78 insertions(+), 84 deletions(-) rename src/controllers/{WebhookController.php => EndpointController.php} (58%) rename src/queries/{delete-webhook-by-uuid.sql => delete-endpoint-by-uuid.sql} (68%) rename src/queries/{get-all-webhooks.sql => get-all-endpoints.sql} (68%) create mode 100644 src/queries/get-endpoint-by-uuid.sql delete mode 100644 src/queries/get-webhook-by-uuid.sql create mode 100644 src/queries/insert-endpoint.sql delete mode 100644 src/queries/insert-webhook.sql create mode 100644 src/queries/update-endpoint-by-uuid.sql delete mode 100644 src/queries/update-webhook-by-uuid.sql diff --git a/.env.example b/.env.example index 362b5d7..984a801 100644 --- a/.env.example +++ b/.env.example @@ -1,12 +1,12 @@ # General INTERFACE_EDITOR_URL=http://localhost:3000 ACCESS_CONTROL_ALLOW_ORIGIN=http://localhost:3000 -JSONMS_CYPHER_KEY=urjMdK071cL935eKdczjEQ== +JSONMS_CYPHER_KEY= # Database DATABASE_HOST=localhost DATABASE_DBNAME= -DATABASE_USERNAME=root +DATABASE_USERNAME= DATABASE_PASSWORD= # Google OAuth diff --git a/composer.json b/composer.json index fe99334..538965d 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "version": "1.0.10", + "version": "1.0.11", "name": "jsonms/server", "description": "The JSON.ms Request Handler Server is a robust backend solution designed to manage and process all incoming requests from the main JSON.ms website.", "license": "BSD-3-Clause", diff --git a/src/controllers/WebhookController.php b/src/controllers/EndpointController.php similarity index 58% rename from src/controllers/WebhookController.php rename to src/controllers/EndpointController.php index ccf201f..8fa4210 100644 --- a/src/controllers/WebhookController.php +++ b/src/controllers/EndpointController.php @@ -2,29 +2,29 @@ use JSONms\Controllers\RestfulController; -class WebhookController extends RestfulController { +class EndpointController extends RestfulController { - public function saveAction($webhooks) { - foreach($webhooks as $webhook) { - if (isset($webhook->uuid)) { - $this->query('update-webhook-by-uuid', [ - 'uuid' => $webhook->uuid, - 'url' => $webhook->url, + public function saveAction($endpoints) { + foreach($endpoints as $endpoint) { + if (isset($endpoint->uuid)) { + $this->query('update-endpoint-by-uuid', [ + 'uuid' => $endpoint->uuid, + 'url' => $endpoint->url, 'userId' => $this->getCurrentUserId(), ]); } else { $cypherKey = $this->getHash(24); $serverSecret = $this->encrypt($this->getHash(24), $cypherKey); $encryptedCypherKey = $this->encrypt($cypherKey, $_ENV['JSONMS_CYPHER_KEY']); - $this->query('insert-webhook', [ - 'url' => $webhook->url, + $this->query('insert-endpoint', [ + 'url' => $endpoint->url, 'secret' => $serverSecret, 'cypher' => $encryptedCypherKey, 'created_by' => $this->getCurrentUserId(), ]); } } - $stmt = $this->query('get-all-webhooks', [ + $stmt = $this->query('get-all-endpoints', [ 'userId' => $this->getCurrentUserId(), ]); @@ -34,7 +34,7 @@ public function saveAction($webhooks) { } public function deleteAction($id) { - $stmt = $this->query('delete-webhook-by-uuid', [ + $stmt = $this->query('delete-endpoint-by-uuid', [ 'uuid' => $id, 'userId' => $this->getCurrentUserId(), ]); @@ -44,20 +44,20 @@ public function deleteAction($id) { } public function secretKeyAction($uuid) { - $webhook = $this->getWebhook($uuid); - $decryptedCypherKey = $this->decrypt($webhook->cypher, $_ENV['JSONMS_CYPHER_KEY']); - $decryptedServerKey = $this->decrypt($webhook->secret, $decryptedCypherKey); + $endpoint = $this->getEndpoint($uuid); + $decryptedCypherKey = $this->decrypt($endpoint->cypher, $_ENV['JSONMS_CYPHER_KEY']); + $decryptedServerKey = $this->decrypt($endpoint->secret, $decryptedCypherKey); $this->responseJson($decryptedServerKey); } public function cypherKeyAction($uuid) { - $webhook = $this->getWebhook($uuid); - $decryptedCypherKey = $this->decrypt($webhook->cypher, $_ENV['JSONMS_CYPHER_KEY']); + $endpoint = $this->getEndpoint($uuid); + $decryptedCypherKey = $this->decrypt($endpoint->cypher, $_ENV['JSONMS_CYPHER_KEY']); $this->responseJson($decryptedCypherKey); } - private function getWebhook($uuid, $showError = true): false | stdClass { - $stmt = $this->query('get-webhook-by-uuid', [ + private function getEndpoint($uuid, $showError = true): false | stdClass { + $stmt = $this->query('get-endpoint-by-uuid', [ 'uuid' => $uuid, 'userId' => $this->getCurrentUserId(), ]); @@ -65,7 +65,7 @@ private function getWebhook($uuid, $showError = true): false | stdClass { return $stmt->fetch(PDO::FETCH_OBJ); } if ($showError) { - throwError(403, 'You don\'t have permission to access this webhook'); + throwError(403, 'You don\'t have permission to access this endpoint'); } return false; } diff --git a/src/controllers/GoogleController.php b/src/controllers/GoogleController.php index 8847dc5..aec526b 100644 --- a/src/controllers/GoogleController.php +++ b/src/controllers/GoogleController.php @@ -49,7 +49,7 @@ public function callbackAction() { // Redirect to a protected page or dashboard $decodedState = json_decode(urldecode($state), true); - header('Location: ' . $_ENV['STRUCTURE_EDITOR_URL'] . $decodedState['path']); + header('Location: ' . $_ENV['INTERFACE_EDITOR_URL'] . $decodedState['path']); exit; } else { throwError(400, "Error during authentication."); diff --git a/src/controllers/SessionController.php b/src/controllers/SessionController.php index 8fead56..5773745 100644 --- a/src/controllers/SessionController.php +++ b/src/controllers/SessionController.php @@ -18,8 +18,8 @@ private function getDemoStructure() { return null; } - private function getWebhooks($userId) { - $stmt = $this->query('get-all-webhooks', [ + private function getEndpoints($userId) { + $stmt = $this->query('get-all-endpoints', [ 'userId' => $userId, ]); if ($stmt->rowCount() > 0) { @@ -34,7 +34,7 @@ public function indexAction() { $user = null; $loginUrl = null; $structures = []; - $webhooks = []; + $endpoints = []; // Fetch demo structure $demo = $this->getDemoStructure(); @@ -89,7 +89,7 @@ public function indexAction() { 'user' => $user, 'googleOAuthSignInUrl' => $loginUrl, 'structures' => $structures, - 'webhooks' => $webhooks, + 'endpoints' => $endpoints, ]); } @@ -123,7 +123,7 @@ public function indexAction() { // Fetch demo structure $loggedIn = $loggedIn && isset($user); if ($loggedIn) { - $webhooks = $this->getWebhooks($user->id); + $endpoints = $this->getEndpoints($user->id); } $this->responseJson([ @@ -131,7 +131,7 @@ public function indexAction() { 'user' => $user, 'googleOAuthSignInUrl' => $loginUrl, 'structures' => $structures, - 'webhooks' => $webhooks, + 'endpoints' => $endpoints, ]); } @@ -163,7 +163,7 @@ public function logoutAction() { 'user' => null, 'googleOAuthSignInUrl' => $loginUrl, 'structures' => $structures, - 'webhooks' => [], + 'endpoints' => [], ]); } } diff --git a/src/controllers/StructureController.php b/src/controllers/StructureController.php index be1aa66..3168d50 100644 --- a/src/controllers/StructureController.php +++ b/src/controllers/StructureController.php @@ -22,10 +22,10 @@ public function createAction($data) { $this->query('insert-structure', [ 'hash' => $hash, - 'label' => $data->label, - 'logo' => $data->logo, - 'content' => $data->content, - 'webhook' => $data->webhook, + 'label' => $data->content->label, + 'logo' => $data->content->logo, + 'content' => $data->content->content, + 'endpoint' => $data->content->endpoint, 'created_by' => $this->getCurrentUserId(), ]); @@ -35,9 +35,6 @@ public function createAction($data) { ])->fetch(PDO::FETCH_OBJ); $this->preparePermissions($structure); - // Update structure -// $this->updateStructure($hash, $structure); - $this->responseJson($structure); } @@ -50,23 +47,20 @@ public function updateAction($id, $data) { // Update structure $this->query('update-structure-by-uuid', [ - 'uuid' => $data->uuid, - 'label' => $data->label, - 'logo' => $data->logo, - 'content' => $data->content, - 'webhook' => $data->webhook, + 'uuid' => $data->content->uuid, + 'label' => $data->content->label, + 'logo' => $data->content->logo, + 'content' => $data->content->content, + 'endpoint' => $data->content->endpoint, 'userId' => $this->getCurrentUserId(), ]); // Clear all existing permissions (will be added later on) - if ($data->created_by === $this->getCurrentUserId()) { - $this->updatePermissions($data); + if ($data->content->created_by === $this->getCurrentUserId()) { + $this->updatePermissions($data->content); } - // Update structure -// $this->updateStructure($data->hash, $structure); - - $this->responseJson($data); + $this->responseJson($data->content); } } diff --git a/src/queries/delete-webhook-by-uuid.sql b/src/queries/delete-endpoint-by-uuid.sql similarity index 68% rename from src/queries/delete-webhook-by-uuid.sql rename to src/queries/delete-endpoint-by-uuid.sql index 2f482b0..e60e542 100644 --- a/src/queries/delete-webhook-by-uuid.sql +++ b/src/queries/delete-endpoint-by-uuid.sql @@ -1,3 +1,3 @@ -DELETE FROM webhooks +DELETE FROM endpoints WHERE uuid = :uuid AND created_by = :userId diff --git a/src/queries/get-all-webhooks.sql b/src/queries/get-all-endpoints.sql similarity index 68% rename from src/queries/get-all-webhooks.sql rename to src/queries/get-all-endpoints.sql index 83d519f..c2fd230 100644 --- a/src/queries/get-all-webhooks.sql +++ b/src/queries/get-all-endpoints.sql @@ -1,16 +1,16 @@ SELECT DISTINCT combined_results.uuid, combined_results.* FROM ( - SELECT w.* - FROM webhooks AS w - WHERE w.created_by = :userId + SELECT e.* + FROM endpoints AS e + WHERE e.created_by = :userId UNION ALL - SELECT w.* + SELECT e.* FROM permissions AS p INNER JOIN users AS u ON u.email = p.email INNER JOIN structures AS i ON i.uuid = p.structure_uuid INNER JOIN users AS owner ON owner.id = i.created_by - LEFT JOIN webhooks AS w ON w.uuid = i.webhook + LEFT JOIN endpoints AS e ON e.uuid = i.endpoint WHERE u.id = :userId ) AS combined_results \ No newline at end of file diff --git a/src/queries/get-all-structures.sql b/src/queries/get-all-structures.sql index 4049e2a..2fd5e0c 100644 --- a/src/queries/get-all-structures.sql +++ b/src/queries/get-all-structures.sql @@ -4,13 +4,13 @@ SELECT GROUP_CONCAT(DISTINCT(pa.email)) as permission_admin, 'owner' AS type, u.name AS owner_name, - w.url AS server_url, - w.secret AS server_secret + e.url AS server_url, + e.secret AS server_secret FROM structures AS i INNER JOIN users AS u ON u.id = i.created_by LEFT JOIN permissions AS pa ON pa.structure_uuid = i.uuid AND pa.type = 'admin' LEFT JOIN permissions AS pi ON pi.structure_uuid = i.uuid AND pi.type = 'structure' - LEFT JOIN webhooks AS w ON w.uuid = i.webhook + LEFT JOIN endpoints AS e ON e.uuid = i.endpoint WHERE i.created_by = :userId GROUP BY i.uuid @@ -21,12 +21,12 @@ SELECT i.*, null AS permission_admin, GROUP_CONCAT(DISTINCT(p.type)) as type, owner.name AS owner_name, - w.url AS server_url, - w.secret AS server_secret + e.url AS server_url, + e.secret AS server_secret FROM permissions AS p INNER JOIN users AS u ON u.email = p.email INNER JOIN structures AS i ON i.uuid = p.structure_uuid INNER JOIN users AS owner ON owner.id = i.created_by - LEFT JOIN webhooks AS w ON w.uuid = i.webhook + LEFT JOIN endpoints AS e ON e.uuid = i.endpoint WHERE u.id = :userId GROUP BY i.uuid diff --git a/src/queries/get-demo-structure.sql b/src/queries/get-demo-structure.sql index f876263..da88dca 100644 --- a/src/queries/get-demo-structure.sql +++ b/src/queries/get-demo-structure.sql @@ -1,10 +1,10 @@ SELECT i.*, u.name AS owner_name, - w.url AS server_url, - w.secret AS server_secret + e.url AS server_url, + e.secret AS server_secret FROM structures AS i INNER JOIN users AS u ON u.id = i.created_by - LEFT JOIN webhooks AS w ON w.uuid = i.webhook + LEFT JOIN endpoints AS e ON e.uuid = i.endpoint WHERE i.hash = "demo" GROUP BY i.uuid diff --git a/src/queries/get-endpoint-by-uuid.sql b/src/queries/get-endpoint-by-uuid.sql new file mode 100644 index 0000000..364b6bd --- /dev/null +++ b/src/queries/get-endpoint-by-uuid.sql @@ -0,0 +1,6 @@ +SELECT + e.* +FROM endpoints AS e +WHERE + e.uuid = :uuid + AND e.created_by = :userId diff --git a/src/queries/get-structure-by-hash.sql b/src/queries/get-structure-by-hash.sql index ea7962f..3996aa6 100644 --- a/src/queries/get-structure-by-hash.sql +++ b/src/queries/get-structure-by-hash.sql @@ -4,13 +4,13 @@ SELECT GROUP_CONCAT(DISTINCT(pa.email)) as permission_admin, 'owner' AS type, u.name AS owner_name, - w.url AS server_url, - w.secret AS server_secret + e.url AS server_url, + e.secret AS server_secret FROM structures AS i INNER JOIN users AS u ON u.id = i.created_by LEFT JOIN permissions AS pa ON pa.structure_uuid = i.uuid AND pa.type = 'admin' LEFT JOIN permissions AS pi ON pi.structure_uuid = i.uuid AND pi.type = 'structure' - LEFT JOIN webhooks AS w ON w.uuid = i.webhook + LEFT JOIN endpoints AS e ON e.uuid = i.endpoint WHERE i.hash = :hash GROUP BY i.uuid, u.name; diff --git a/src/queries/get-structure-by-uuid.sql b/src/queries/get-structure-by-uuid.sql index a913203..3875374 100644 --- a/src/queries/get-structure-by-uuid.sql +++ b/src/queries/get-structure-by-uuid.sql @@ -4,13 +4,13 @@ SELECT GROUP_CONCAT(DISTINCT(pa.email)) as permission_admin, 'owner' AS type, u.name AS owner_name, - w.url AS server_url, - w.secret AS server_secret + e.url AS server_url, + e.secret AS server_secret FROM structures AS i INNER JOIN users AS u ON u.id = i.created_by LEFT JOIN permissions AS pa ON pa.structure_uuid = i.uuid AND pa.type = 'admin' LEFT JOIN permissions AS pi ON pi.structure_uuid = i.uuid AND pi.type = 'structure' - LEFT JOIN webhooks AS w ON w.uuid = i.webhook + LEFT JOIN endpoints AS e ON e.uuid = i.endpoint WHERE i.uuid = :uuid GROUP BY i.uuid, u.name; diff --git a/src/queries/get-webhook-by-uuid.sql b/src/queries/get-webhook-by-uuid.sql deleted file mode 100644 index d3fbc01..0000000 --- a/src/queries/get-webhook-by-uuid.sql +++ /dev/null @@ -1,6 +0,0 @@ -SELECT - w.* -FROM webhooks AS w -WHERE - w.uuid = :uuid - AND w.created_by = :userId diff --git a/src/queries/insert-endpoint.sql b/src/queries/insert-endpoint.sql new file mode 100644 index 0000000..add62a2 --- /dev/null +++ b/src/queries/insert-endpoint.sql @@ -0,0 +1,2 @@ +INSERT INTO endpoints (url, secret, cypher, created_by) +VALUES (:url, :secret, :cypher, :created_by) diff --git a/src/queries/insert-structure.sql b/src/queries/insert-structure.sql index e594c5e..ec487c1 100644 --- a/src/queries/insert-structure.sql +++ b/src/queries/insert-structure.sql @@ -1,2 +1,2 @@ -INSERT INTO structures (hash, label, logo, content, webhook, created_by) -VALUES (:hash, :label, :logo, :content, :webhook, :created_by) +INSERT INTO structures (hash, label, logo, content, endpoint, created_by) +VALUES (:hash, :label, :logo, :content, :endpoint, :created_by) diff --git a/src/queries/insert-webhook.sql b/src/queries/insert-webhook.sql deleted file mode 100644 index 677bc26..0000000 --- a/src/queries/insert-webhook.sql +++ /dev/null @@ -1,2 +0,0 @@ -INSERT INTO webhooks (url, secret, cypher, created_by) -VALUES (:url, :secret, :cypher, :created_by) diff --git a/src/queries/update-endpoint-by-uuid.sql b/src/queries/update-endpoint-by-uuid.sql new file mode 100644 index 0000000..9b46fdf --- /dev/null +++ b/src/queries/update-endpoint-by-uuid.sql @@ -0,0 +1,4 @@ +UPDATE endpoints AS e +SET e.url = :url, e.updated_at = NOW() +WHERE e.uuid = :uuid + AND e.created_by = :userId diff --git a/src/queries/update-structure-by-uuid.sql b/src/queries/update-structure-by-uuid.sql index 227be08..0e8528b 100644 --- a/src/queries/update-structure-by-uuid.sql +++ b/src/queries/update-structure-by-uuid.sql @@ -1,3 +1,3 @@ UPDATE structures AS i -SET i.label = :label, i.logo = :logo, i.content = :content, i.webhook = :webhook, i.updated_at = NOW() +SET i.label = :label, i.logo = :logo, i.content = :content, i.endpoint = :endpoint, i.updated_at = NOW() WHERE i.uuid = :uuid diff --git a/src/queries/update-webhook-by-uuid.sql b/src/queries/update-webhook-by-uuid.sql deleted file mode 100644 index a8630b4..0000000 --- a/src/queries/update-webhook-by-uuid.sql +++ /dev/null @@ -1,4 +0,0 @@ -UPDATE webhooks AS w -SET w.url = :url, w.updated_at = NOW() -WHERE w.uuid = :uuid - AND w.created_by = :userId From 21d6702c612f7875251d0a13257e14956ad9e9ed Mon Sep 17 00:00:00 2001 From: Danny Coulombe Date: Thu, 1 May 2025 08:05:33 -0400 Subject: [PATCH 4/4] readme update + database structure --- .datatable.sql | 159 +++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 52 +++++++++++++++- composer.json | 2 +- 3 files changed, 211 insertions(+), 2 deletions(-) create mode 100644 .datatable.sql diff --git a/.datatable.sql b/.datatable.sql new file mode 100644 index 0000000..154732d --- /dev/null +++ b/.datatable.sql @@ -0,0 +1,159 @@ +-- MySQL dump 10.13 Distrib 8.0.41, for Win64 (x86_64) +-- +-- Host: 127.0.0.1 Database: jsonms_local +-- ------------------------------------------------------ +-- Server version 8.0.41 + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!50503 SET NAMES utf8mb4 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `errors` +-- + +DROP TABLE IF EXISTS `errors`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `errors` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `key` varchar(255) NOT NULL, + `message` text, + `source` varchar(256) DEFAULT NULL, + `line` smallint DEFAULT NULL, + `column` smallint DEFAULT NULL, + `stack` text, + `occurred_on` datetime NOT NULL, + `last_timestamp` bigint NOT NULL, + `version` varchar(16) NOT NULL, + `route` varchar(128) NOT NULL, + `count` smallint NOT NULL DEFAULT '0', + `user_agent` varchar(255) NOT NULL, + `created_on` datetime DEFAULT (now()), + `created_by` int unsigned NOT NULL, + `updated_at` datetime DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `errors_pk` (`key`) +) ENGINE=InnoDB AUTO_INCREMENT=88 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `history` +-- + +DROP TABLE IF EXISTS `history`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `history` ( + `id` int NOT NULL AUTO_INCREMENT, + `uuid` char(36) COLLATE utf8mb4_unicode_ci NOT NULL, + `content` text COLLATE utf8mb4_unicode_ci NOT NULL, + `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_by` int DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `history_interfaces_uuid_fk` (`uuid`), + KEY `history_users_id_fk` (`created_by`), + CONSTRAINT `history_interfaces_uuid_fk` FOREIGN KEY (`uuid`) REFERENCES `structures` (`uuid`) ON DELETE CASCADE, + CONSTRAINT `history_users_id_fk` FOREIGN KEY (`created_by`) REFERENCES `users` (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=378 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `permissions` +-- + +DROP TABLE IF EXISTS `permissions`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `permissions` ( + `id` int NOT NULL AUTO_INCREMENT, + `structure_uuid` char(36) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `type` enum('admin','interface') COLLATE utf8mb4_unicode_ci NOT NULL, + `email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=57 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `structures` +-- + +DROP TABLE IF EXISTS `structures`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `structures` ( + `uuid` char(36) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT (uuid()), + `hash` char(10) COLLATE utf8mb4_unicode_ci NOT NULL, + `label` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `logo` varchar(1024) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `content` text COLLATE utf8mb4_unicode_ci NOT NULL, + `webhook` char(36) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `created_by` int NOT NULL, + `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`uuid`), + KEY `interfaces_users_id_fk` (`created_by`), + KEY `interfaces__hash_index` (`hash`), + KEY `interfaces_webhooks_uuid_fk` (`webhook`), + CONSTRAINT `interfaces_users_id_fk` FOREIGN KEY (`created_by`) REFERENCES `users` (`id`), + CONSTRAINT `interfaces_webhooks_uuid_fk` FOREIGN KEY (`webhook`) REFERENCES `webhooks` (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `users` +-- + +DROP TABLE IF EXISTS `users`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `users` ( + `id` int NOT NULL AUTO_INCREMENT, + `google_id` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `avatar` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `google_id` (`google_id`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `webhooks` +-- + +DROP TABLE IF EXISTS `webhooks`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `webhooks` ( + `uuid` char(36) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT (uuid()), + `url` varchar(1024) COLLATE utf8mb4_unicode_ci DEFAULT NULL, + `secret` varchar(84) COLLATE utf8mb4_unicode_ci NOT NULL, + `cypher` varchar(84) COLLATE utf8mb4_unicode_ci NOT NULL, + `created_by` int NOT NULL, + `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`uuid`), + KEY `interfaces_webhooks_users_id_fk` (`created_by`), + CONSTRAINT `interfaces_webhooks_users_id_fk` FOREIGN KEY (`created_by`) REFERENCES `users` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2025-04-26 18:13:45 diff --git a/README.md b/README.md index fcef110..a1c0980 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,53 @@ # @jsonms/server -The server to use with your instance of [jsonms-www](https://github.com/JSON-ms/www). +Welcome to the **@jsonms/server** project! +This package provides the server-side foundation for managing MySQL schemas and environment configurations for the JSONMS system. + +## Requirements +- PHP 8.x +- MySQL server + +## Getting Started + +Follow these steps to set up and run the project locally: + +### 1. Prepare the MySQL Database + +A `.datatable.sql` file is included in the project. +It contains the necessary schema definitions required to run the application. + +To set up your database: + +```bash +mysql -u your_user -p your_database_name < .datatable.sql +``` + +Replace your_user and your_database_name with your MySQL username and target database name. + +Make sure your MySQL server is running and accessible. + +### 2. Set Up Environment Variables +The project uses environment variables for configuration. +A sample file `.env.example` is provided. + +To create your local `.env` file: + +```bash +cp .env.example .env +``` + +Edit `.env` to match your environment settings, such as database connection credentials, ports, and other options. + +### 3. Running the Server + +You can define your own virtual host with Apache or Nginx but the fastest way to run the server is with a built-in PHP server. + +```bash +php -S localhost:9001 index.php +``` + +## Contributing +Contributions are welcome! Please feel free to submit a pull request or open an issue. + +## License +This project is licensed under the BSD-3-Clause License. See the LICENSE file for details. \ No newline at end of file diff --git a/composer.json b/composer.json index 538965d..6dd7695 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "version": "1.0.11", + "version": "1.0.12", "name": "jsonms/server", "description": "The JSON.ms Request Handler Server is a robust backend solution designed to manage and process all incoming requests from the main JSON.ms website.", "license": "BSD-3-Clause",