From 8b6c7a42bd406286c52c9e8691460d70a961ca22 Mon Sep 17 00:00:00 2001 From: nully0x Date: Tue, 14 Oct 2025 09:59:27 +0100 Subject: [PATCH 1/2] remove soft delete for credential --- backend/migrations/20250717010813_init.sql | 4 +- backend/src/auth/handlers.rs | 2 +- backend/src/database/models.rs | 2 - .../src/repositories/credential_repository.rs | 75 ++++++++++++------- docs/build-nix.md | 6 -- frontend/package-lock.json | 11 --- 6 files changed, 51 insertions(+), 49 deletions(-) diff --git a/backend/migrations/20250717010813_init.sql b/backend/migrations/20250717010813_init.sql index 0ad9fc0..bc99f24 100644 --- a/backend/migrations/20250717010813_init.sql +++ b/backend/migrations/20250717010813_init.sql @@ -91,8 +91,6 @@ CREATE TABLE IF NOT EXISTS credentials ( is_active BOOLEAN NOT NULL DEFAULT 1, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - is_deleted BOOLEAN NOT NULL DEFAULT 0, - deleted_at DATETIME DEFAULT NULL, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, FOREIGN KEY (account_id) REFERENCES accounts(id) ON DELETE CASCADE ); @@ -101,7 +99,7 @@ CREATE INDEX idx_credentials_user_id ON credentials(user_id); CREATE INDEX idx_credentials_account_id ON credentials(account_id); CREATE INDEX idx_credentials_node_type ON credentials(node_type); -CREATE UNIQUE INDEX idx_credentials_user_unique ON credentials(user_id) WHERE is_deleted = 0; +CREATE UNIQUE INDEX idx_credentials_user_unique ON credentials(user_id); CREATE TRIGGER credentials_updated_at AFTER UPDATE ON credentials diff --git a/backend/src/auth/handlers.rs b/backend/src/auth/handlers.rs index 41ca386..d8b04cf 100644 --- a/backend/src/auth/handlers.rs +++ b/backend/src/auth/handlers.rs @@ -147,7 +147,7 @@ pub async fn revoke_node_credentials( } }; - // Soft delete the credential + // Delete the credential if let Err(_e) = credential_repo.delete_credential(&credential.id).await { let error_response = ApiResponse::<()>::error("Failed to revoke credentials", "database_error", None); diff --git a/backend/src/database/models.rs b/backend/src/database/models.rs index c8256ec..1e95131 100644 --- a/backend/src/database/models.rs +++ b/backend/src/database/models.rs @@ -195,8 +195,6 @@ pub struct Credential { pub is_active: bool, pub created_at: DateTime, pub updated_at: DateTime, - pub is_deleted: bool, - pub deleted_at: Option>, } #[derive(Debug, Clone, Serialize, Deserialize, Validate)] diff --git a/backend/src/repositories/credential_repository.rs b/backend/src/repositories/credential_repository.rs index 93e3d31..f3cd5f9 100644 --- a/backend/src/repositories/credential_repository.rs +++ b/backend/src/repositories/credential_repository.rs @@ -59,9 +59,7 @@ impl<'a> CredentialRepository<'a> { ca_cert as "ca_cert?", is_active as "is_active!", created_at as "created_at!: DateTime", - updated_at as "updated_at!: DateTime", - is_deleted as "is_deleted!", - deleted_at as "deleted_at?: DateTime" + updated_at as "updated_at!: DateTime" "#, credential.id, credential.user_id, @@ -89,16 +87,44 @@ impl<'a> CredentialRepository<'a> { /// * `id` - Credential ID (UUID format) /// /// # Returns - /// `Some(Credential)` if found and not deleted, `None` otherwise - /// - /// # Security + /// `Some(Credential)` if found, `None` otherwise + pub async fn get_credential_by_id(&self, id: &str) -> Result> { + let credential = sqlx::query_as!( + Credential, + r#" + SELECT + id as "id!", + user_id as "user_id!", + account_id as "account_id!", + node_id as "node_id!", + node_alias as "node_alias!", + macaroon as "macaroon!", + tls_cert as "tls_cert!", + address as "address!", + node_type as "node_type?", + client_cert as "client_cert?", + client_key as "client_key?", + ca_cert as "ca_cert?", + is_active as "is_active!", + created_at as "created_at!: DateTime", + updated_at as "updated_at!: DateTime" + FROM credentials WHERE id = ? + "#, + id + ) + .fetch_optional(self.pool) + .await?; + + Ok(credential) + } + /// Retrieves credentials associated with a specific user. /// /// # Arguments /// * `user_id` - User ID (UUID format) /// /// # Returns - /// `Some(Credential)` if found and not deleted, `None` otherwise + /// `Some(Credential)` if found, `None` otherwise pub async fn get_credential_by_user_id(&self, user_id: &str) -> Result> { let credential = sqlx::query_as!( Credential, @@ -118,10 +144,8 @@ impl<'a> CredentialRepository<'a> { ca_cert as "ca_cert?", is_active as "is_active!", created_at as "created_at!: DateTime", - updated_at as "updated_at!: DateTime", - is_deleted as "is_deleted!", - deleted_at as "deleted_at?: DateTime" - FROM credentials WHERE user_id = ? AND is_deleted = 0 + updated_at as "updated_at!: DateTime" + FROM credentials WHERE user_id = ? "#, user_id ) @@ -137,8 +161,11 @@ impl<'a> CredentialRepository<'a> { /// * `account_id` - Account ID (UUID format) /// /// # Returns - /// `Some(Credential)` if found and not deleted, `None` otherwise - pub async fn get_credential_by_account_id(&self, account_id: &str) -> Result> { + /// `Some(Credential)` if found, `None` otherwise + pub async fn get_credential_by_account_id( + &self, + account_id: &str, + ) -> Result> { let credential = sqlx::query_as!( Credential, r#" @@ -157,10 +184,8 @@ impl<'a> CredentialRepository<'a> { ca_cert as "ca_cert?", is_active as "is_active!", created_at as "created_at!: DateTime", - updated_at as "updated_at!: DateTime", - is_deleted as "is_deleted!", - deleted_at as "deleted_at?: DateTime" - FROM credentials WHERE account_id = ? AND is_deleted = 0 + updated_at as "updated_at!: DateTime" + FROM credentials WHERE account_id = ? "#, account_id ) @@ -170,24 +195,22 @@ impl<'a> CredentialRepository<'a> { Ok(credential) } - /// Marks a credential as deleted (soft deletion). + /// Deletes a credential permanently from the database. /// /// # Arguments - /// * `id` - Credential ID to deactivate + /// * `id` - Credential ID to delete /// /// # Effects - /// - Sets `is_deleted` flag to true - /// - Records deletion timestamp - /// - Credential remains in database but won't appear in normal queries + /// - Permanently removes credential from database + /// - Cannot be recovered after deletion /// /// # Security - /// - Prevents credential from being used while preserving audit trail + /// - Ensures credential cannot be used after deletion pub async fn delete_credential(&self, id: &str) -> Result<()> { sqlx::query!( r#" - UPDATE credentials - SET is_deleted = 1, deleted_at = CURRENT_TIMESTAMP - WHERE id = ? AND is_deleted = 0 + DELETE FROM credentials + WHERE id = ? "#, id ) diff --git a/docs/build-nix.md b/docs/build-nix.md index dfe418f..7222287 100644 --- a/docs/build-nix.md +++ b/docs/build-nix.md @@ -94,12 +94,6 @@ Run database migrations: sqlx migrate run --source backend/migrations ``` -Generate offline SQLx data: - -```bash -cargo sqlx prepare --workspace -``` - #### Step 5: Build and Run Using the provided Makefile (recommended): diff --git a/frontend/package-lock.json b/frontend/package-lock.json index a8df72d..d2c35fa 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -2263,7 +2263,6 @@ "integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "csstype": "^3.0.2" } @@ -2274,7 +2273,6 @@ "integrity": "sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw==", "devOptional": true, "license": "MIT", - "peer": true, "peerDependencies": { "@types/react": "^19.0.0" } @@ -2325,7 +2323,6 @@ "integrity": "sha512-kVIaQE9vrN9RLCQMQ3iyRlVJpTiDUY6woHGb30JDkfJErqrQEmtdWH3gV0PBAfGZgQXoqzXOO0T3K6ioApbbAA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.37.0", "@typescript-eslint/types": "8.37.0", @@ -2843,7 +2840,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3767,7 +3763,6 @@ "integrity": "sha512-QldCVh/ztyKJJZLr4jXNUByx3gR+TDYZCRXEktiZoUR3PGy4qCmSbkxcIle8GEwGpb5JBZazlaJ/CxLidXdEbQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", @@ -3942,7 +3937,6 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -6140,7 +6134,6 @@ "resolved": "https://registry.npmjs.org/preact/-/preact-10.26.9.tgz", "integrity": "sha512-SSjF9vcnF27mJK1XyFMNJzFd5u3pQiATFqoaDy03XuN00u4ziveVVEGt5RKJrDR8MHE/wJo9Nnad56RLzS2RMA==", "license": "MIT", - "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" @@ -6222,7 +6215,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -6232,7 +6224,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", "license": "MIT", - "peer": true, "dependencies": { "scheduler": "^0.26.0" }, @@ -7009,7 +7000,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -7169,7 +7159,6 @@ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" From 21d521dcdf532b2a9a9bbd2422833d14dca2440d Mon Sep 17 00:00:00 2001 From: nully0x Date: Wed, 26 Nov 2025 19:23:17 +0100 Subject: [PATCH 2/2] remove cred by id --- ...2e90326158f5d88d0bb72346a08817a8fc24f.json | 86 ------------- ...5a0c38e79902a858e278dcfd97d6f0eff147c.json | 116 ------------------ ...5f7c5e92881178432355b75386150ae65bd2d.json | 116 ------------------ ...03d8a0b0f788c98afff1cf1ea067d69d45469.json | 20 --- ...e71bfe40b83b66fb7b98eec1229dd05571e09.json | 20 --- ...0881a3d6be047bef242ed23f8ecc0e93a471a.json | 80 ------------ ...416ad36e93f483b4073fcb6e0ac7ea345ac10.json | 38 ------ ...d4f2dbe8a4a7bb93dc645a18a36d8429bbe9b.json | 20 --- ...9ebd54aa96bc5ff420b2242d297aaff361df2.json | 116 ------------------ ...bb758098409e63f62f6c77834e6e06f5882ff.json | 86 ------------- ...a672613f3e6d33429586dc4c9bd1ee7c49566.json | 20 --- ...4df95c77f8e4b6e2048e8c0bb993e2a8c6d06.json | 86 ------------- ...1a63af1fa8e1fe484dcab468f81d79801c60a.json | 12 -- .../src/repositories/credential_repository.rs | 37 ------ backend/src/services/credential_service.rs | 16 +-- shell.nix | 1 - 16 files changed, 8 insertions(+), 862 deletions(-) delete mode 100644 .sqlx/query-19ce23d1e2354ea30f1fbb4c2992e90326158f5d88d0bb72346a08817a8fc24f.json delete mode 100644 .sqlx/query-1eaecd9d13968a56a6f653f21445a0c38e79902a858e278dcfd97d6f0eff147c.json delete mode 100644 .sqlx/query-29a2ff5d0f9001739685ac715e25f7c5e92881178432355b75386150ae65bd2d.json delete mode 100644 .sqlx/query-3fecf33281c788eae0b098234ae03d8a0b0f788c98afff1cf1ea067d69d45469.json delete mode 100644 .sqlx/query-51498bb5ab503b04e960c88f79ae71bfe40b83b66fb7b98eec1229dd05571e09.json delete mode 100644 .sqlx/query-5dba476fde4bc28079e0844cfe20881a3d6be047bef242ed23f8ecc0e93a471a.json delete mode 100644 .sqlx/query-6c3e2843d0546f1b480fda0f44d416ad36e93f483b4073fcb6e0ac7ea345ac10.json delete mode 100644 .sqlx/query-74ea3158ee23c0dabbce8a41d97d4f2dbe8a4a7bb93dc645a18a36d8429bbe9b.json delete mode 100644 .sqlx/query-89626327ed8ded677cf8bde44089ebd54aa96bc5ff420b2242d297aaff361df2.json delete mode 100644 .sqlx/query-92c484f9a5b4cf67a3faf9f5e43bb758098409e63f62f6c77834e6e06f5882ff.json delete mode 100644 .sqlx/query-933b552d055a1f79a6c5101930da672613f3e6d33429586dc4c9bd1ee7c49566.json delete mode 100644 .sqlx/query-9d73f591b115e2367dfc978e80c4df95c77f8e4b6e2048e8c0bb993e2a8c6d06.json delete mode 100644 .sqlx/query-e5724216e341699305822b3452a1a63af1fa8e1fe484dcab468f81d79801c60a.json diff --git a/.sqlx/query-19ce23d1e2354ea30f1fbb4c2992e90326158f5d88d0bb72346a08817a8fc24f.json b/.sqlx/query-19ce23d1e2354ea30f1fbb4c2992e90326158f5d88d0bb72346a08817a8fc24f.json deleted file mode 100644 index 2bab8b6..0000000 --- a/.sqlx/query-19ce23d1e2354ea30f1fbb4c2992e90326158f5d88d0bb72346a08817a8fc24f.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n SELECT \n id as \"id!\",\n account_id as \"account_id!\",\n inviter_id as \"inviter_id!\",\n invitee_email as \"invitee_email!\",\n token as \"token!\",\n invite_status as \"invite_status: InviteStatus\",\n is_active as \"is_active!\",\n created_at as \"created_at!: DateTime\",\n expires_at as \"expires_at!: DateTime\",\n updated_at as \"updated_at!: DateTime\",\n is_deleted as \"is_deleted!\",\n deleted_at as \"deleted_at?: DateTime\"\n FROM invites\n WHERE account_id = ? AND is_deleted = 0\n ORDER BY created_at DESC\n ", - "describe": { - "columns": [ - { - "name": "id!", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "account_id!", - "ordinal": 1, - "type_info": "Text" - }, - { - "name": "inviter_id!", - "ordinal": 2, - "type_info": "Text" - }, - { - "name": "invitee_email!", - "ordinal": 3, - "type_info": "Text" - }, - { - "name": "token!", - "ordinal": 4, - "type_info": "Text" - }, - { - "name": "invite_status: InviteStatus", - "ordinal": 5, - "type_info": "Integer" - }, - { - "name": "is_active!", - "ordinal": 6, - "type_info": "Bool" - }, - { - "name": "created_at!: DateTime", - "ordinal": 7, - "type_info": "Datetime" - }, - { - "name": "expires_at!: DateTime", - "ordinal": 8, - "type_info": "Datetime" - }, - { - "name": "updated_at!: DateTime", - "ordinal": 9, - "type_info": "Datetime" - }, - { - "name": "is_deleted!", - "ordinal": 10, - "type_info": "Bool" - }, - { - "name": "deleted_at?: DateTime", - "ordinal": 11, - "type_info": "Datetime" - } - ], - "parameters": { - "Right": 1 - }, - "nullable": [ - true, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - true - ] - }, - "hash": "19ce23d1e2354ea30f1fbb4c2992e90326158f5d88d0bb72346a08817a8fc24f" -} diff --git a/.sqlx/query-1eaecd9d13968a56a6f653f21445a0c38e79902a858e278dcfd97d6f0eff147c.json b/.sqlx/query-1eaecd9d13968a56a6f653f21445a0c38e79902a858e278dcfd97d6f0eff147c.json deleted file mode 100644 index 0dbf89e..0000000 --- a/.sqlx/query-1eaecd9d13968a56a6f653f21445a0c38e79902a858e278dcfd97d6f0eff147c.json +++ /dev/null @@ -1,116 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n SELECT\n id as \"id!\",\n user_id as \"user_id!\",\n account_id as \"account_id!\",\n node_id as \"node_id!\",\n node_alias as \"node_alias!\",\n macaroon as \"macaroon!\",\n tls_cert as \"tls_cert!\",\n address as \"address!\",\n node_type as \"node_type?\",\n client_cert as \"client_cert?\",\n client_key as \"client_key?\",\n ca_cert as \"ca_cert?\",\n is_active as \"is_active!\",\n created_at as \"created_at!: DateTime\",\n updated_at as \"updated_at!: DateTime\",\n is_deleted as \"is_deleted!\",\n deleted_at as \"deleted_at?: DateTime\"\n FROM credentials WHERE id = ? AND is_deleted = 0\n ", - "describe": { - "columns": [ - { - "name": "id!", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "user_id!", - "ordinal": 1, - "type_info": "Text" - }, - { - "name": "account_id!", - "ordinal": 2, - "type_info": "Text" - }, - { - "name": "node_id!", - "ordinal": 3, - "type_info": "Text" - }, - { - "name": "node_alias!", - "ordinal": 4, - "type_info": "Text" - }, - { - "name": "macaroon!", - "ordinal": 5, - "type_info": "Text" - }, - { - "name": "tls_cert!", - "ordinal": 6, - "type_info": "Text" - }, - { - "name": "address!", - "ordinal": 7, - "type_info": "Text" - }, - { - "name": "node_type?", - "ordinal": 8, - "type_info": "Text" - }, - { - "name": "client_cert?", - "ordinal": 9, - "type_info": "Text" - }, - { - "name": "client_key?", - "ordinal": 10, - "type_info": "Text" - }, - { - "name": "ca_cert?", - "ordinal": 11, - "type_info": "Text" - }, - { - "name": "is_active!", - "ordinal": 12, - "type_info": "Bool" - }, - { - "name": "created_at!: DateTime", - "ordinal": 13, - "type_info": "Datetime" - }, - { - "name": "updated_at!: DateTime", - "ordinal": 14, - "type_info": "Datetime" - }, - { - "name": "is_deleted!", - "ordinal": 15, - "type_info": "Bool" - }, - { - "name": "deleted_at?: DateTime", - "ordinal": 16, - "type_info": "Datetime" - } - ], - "parameters": { - "Right": 1 - }, - "nullable": [ - true, - false, - false, - false, - true, - false, - false, - false, - true, - true, - true, - true, - false, - false, - false, - false, - true - ] - }, - "hash": "1eaecd9d13968a56a6f653f21445a0c38e79902a858e278dcfd97d6f0eff147c" -} diff --git a/.sqlx/query-29a2ff5d0f9001739685ac715e25f7c5e92881178432355b75386150ae65bd2d.json b/.sqlx/query-29a2ff5d0f9001739685ac715e25f7c5e92881178432355b75386150ae65bd2d.json deleted file mode 100644 index 9d99e53..0000000 --- a/.sqlx/query-29a2ff5d0f9001739685ac715e25f7c5e92881178432355b75386150ae65bd2d.json +++ /dev/null @@ -1,116 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n SELECT\n id as \"id!\",\n user_id as \"user_id!\",\n account_id as \"account_id!\",\n node_id as \"node_id!\",\n node_alias as \"node_alias!\",\n macaroon as \"macaroon!\",\n tls_cert as \"tls_cert!\",\n address as \"address!\",\n node_type as \"node_type?\",\n client_cert as \"client_cert?\",\n client_key as \"client_key?\",\n ca_cert as \"ca_cert?\",\n is_active as \"is_active!\",\n created_at as \"created_at!: DateTime\",\n updated_at as \"updated_at!: DateTime\",\n is_deleted as \"is_deleted!\",\n deleted_at as \"deleted_at?: DateTime\"\n FROM credentials WHERE user_id = ? AND is_deleted = 0\n ", - "describe": { - "columns": [ - { - "name": "id!", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "user_id!", - "ordinal": 1, - "type_info": "Text" - }, - { - "name": "account_id!", - "ordinal": 2, - "type_info": "Text" - }, - { - "name": "node_id!", - "ordinal": 3, - "type_info": "Text" - }, - { - "name": "node_alias!", - "ordinal": 4, - "type_info": "Text" - }, - { - "name": "macaroon!", - "ordinal": 5, - "type_info": "Text" - }, - { - "name": "tls_cert!", - "ordinal": 6, - "type_info": "Text" - }, - { - "name": "address!", - "ordinal": 7, - "type_info": "Text" - }, - { - "name": "node_type?", - "ordinal": 8, - "type_info": "Text" - }, - { - "name": "client_cert?", - "ordinal": 9, - "type_info": "Text" - }, - { - "name": "client_key?", - "ordinal": 10, - "type_info": "Text" - }, - { - "name": "ca_cert?", - "ordinal": 11, - "type_info": "Text" - }, - { - "name": "is_active!", - "ordinal": 12, - "type_info": "Bool" - }, - { - "name": "created_at!: DateTime", - "ordinal": 13, - "type_info": "Datetime" - }, - { - "name": "updated_at!: DateTime", - "ordinal": 14, - "type_info": "Datetime" - }, - { - "name": "is_deleted!", - "ordinal": 15, - "type_info": "Bool" - }, - { - "name": "deleted_at?: DateTime", - "ordinal": 16, - "type_info": "Datetime" - } - ], - "parameters": { - "Right": 1 - }, - "nullable": [ - true, - false, - false, - false, - true, - false, - false, - false, - true, - true, - true, - true, - false, - false, - false, - false, - true - ] - }, - "hash": "29a2ff5d0f9001739685ac715e25f7c5e92881178432355b75386150ae65bd2d" -} diff --git a/.sqlx/query-3fecf33281c788eae0b098234ae03d8a0b0f788c98afff1cf1ea067d69d45469.json b/.sqlx/query-3fecf33281c788eae0b098234ae03d8a0b0f788c98afff1cf1ea067d69d45469.json deleted file mode 100644 index 6181007..0000000 --- a/.sqlx/query-3fecf33281c788eae0b098234ae03d8a0b0f788c98afff1cf1ea067d69d45469.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "db_name": "SQLite", - "query": "SELECT COUNT(*) as count FROM users WHERE email = ? AND id != ? AND is_deleted = 0", - "describe": { - "columns": [ - { - "name": "count", - "ordinal": 0, - "type_info": "Integer" - } - ], - "parameters": { - "Right": 2 - }, - "nullable": [ - false - ] - }, - "hash": "3fecf33281c788eae0b098234ae03d8a0b0f788c98afff1cf1ea067d69d45469" -} diff --git a/.sqlx/query-51498bb5ab503b04e960c88f79ae71bfe40b83b66fb7b98eec1229dd05571e09.json b/.sqlx/query-51498bb5ab503b04e960c88f79ae71bfe40b83b66fb7b98eec1229dd05571e09.json deleted file mode 100644 index 9b2efed..0000000 --- a/.sqlx/query-51498bb5ab503b04e960c88f79ae71bfe40b83b66fb7b98eec1229dd05571e09.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "db_name": "SQLite", - "query": "SELECT COUNT(*) as count FROM users WHERE email = ? AND is_deleted = 0", - "describe": { - "columns": [ - { - "name": "count", - "ordinal": 0, - "type_info": "Integer" - } - ], - "parameters": { - "Right": 1 - }, - "nullable": [ - false - ] - }, - "hash": "51498bb5ab503b04e960c88f79ae71bfe40b83b66fb7b98eec1229dd05571e09" -} diff --git a/.sqlx/query-5dba476fde4bc28079e0844cfe20881a3d6be047bef242ed23f8ecc0e93a471a.json b/.sqlx/query-5dba476fde4bc28079e0844cfe20881a3d6be047bef242ed23f8ecc0e93a471a.json deleted file mode 100644 index ba7bea7..0000000 --- a/.sqlx/query-5dba476fde4bc28079e0844cfe20881a3d6be047bef242ed23f8ecc0e93a471a.json +++ /dev/null @@ -1,80 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n SELECT\n id as \"id!\",\n account_id as \"account_id!\",\n role_id as \"role_id!\",\n username as \"username!\",\n password_hash as \"password_hash!\",\n email as \"email!\",\n is_active as \"is_active!\",\n created_at as \"created_at!: DateTime\",\n updated_at as \"updated_at!: DateTime\",\n is_deleted as \"is_deleted!\",\n deleted_at as \"deleted_at?: DateTime\"\n FROM users WHERE username = ? AND is_deleted = 0\n ", - "describe": { - "columns": [ - { - "name": "id!", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "account_id!", - "ordinal": 1, - "type_info": "Text" - }, - { - "name": "role_id!", - "ordinal": 2, - "type_info": "Text" - }, - { - "name": "username!", - "ordinal": 3, - "type_info": "Text" - }, - { - "name": "password_hash!", - "ordinal": 4, - "type_info": "Text" - }, - { - "name": "email!", - "ordinal": 5, - "type_info": "Text" - }, - { - "name": "is_active!", - "ordinal": 6, - "type_info": "Bool" - }, - { - "name": "created_at!: DateTime", - "ordinal": 7, - "type_info": "Datetime" - }, - { - "name": "updated_at!: DateTime", - "ordinal": 8, - "type_info": "Datetime" - }, - { - "name": "is_deleted!", - "ordinal": 9, - "type_info": "Bool" - }, - { - "name": "deleted_at?: DateTime", - "ordinal": 10, - "type_info": "Datetime" - } - ], - "parameters": { - "Right": 1 - }, - "nullable": [ - true, - false, - false, - false, - false, - false, - false, - false, - false, - false, - true - ] - }, - "hash": "5dba476fde4bc28079e0844cfe20881a3d6be047bef242ed23f8ecc0e93a471a" -} diff --git a/.sqlx/query-6c3e2843d0546f1b480fda0f44d416ad36e93f483b4073fcb6e0ac7ea345ac10.json b/.sqlx/query-6c3e2843d0546f1b480fda0f44d416ad36e93f483b4073fcb6e0ac7ea345ac10.json deleted file mode 100644 index 6bf66f0..0000000 --- a/.sqlx/query-6c3e2843d0546f1b480fda0f44d416ad36e93f483b4073fcb6e0ac7ea345ac10.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n SELECT u.username, u.email, a.name as account_name, r.name as role_name\n FROM users u\n JOIN accounts a ON u.account_id = a.id\n JOIN roles r ON u.role_id = r.id\n WHERE u.id = ? AND u.is_deleted = 0\n ", - "describe": { - "columns": [ - { - "name": "username", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "email", - "ordinal": 1, - "type_info": "Text" - }, - { - "name": "account_name", - "ordinal": 2, - "type_info": "Text" - }, - { - "name": "role_name", - "ordinal": 3, - "type_info": "Text" - } - ], - "parameters": { - "Right": 1 - }, - "nullable": [ - false, - false, - false, - false - ] - }, - "hash": "6c3e2843d0546f1b480fda0f44d416ad36e93f483b4073fcb6e0ac7ea345ac10" -} diff --git a/.sqlx/query-74ea3158ee23c0dabbce8a41d97d4f2dbe8a4a7bb93dc645a18a36d8429bbe9b.json b/.sqlx/query-74ea3158ee23c0dabbce8a41d97d4f2dbe8a4a7bb93dc645a18a36d8429bbe9b.json deleted file mode 100644 index 7637d38..0000000 --- a/.sqlx/query-74ea3158ee23c0dabbce8a41d97d4f2dbe8a4a7bb93dc645a18a36d8429bbe9b.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "db_name": "SQLite", - "query": "SELECT COUNT(*) as count FROM users WHERE username = ? AND is_deleted = 0", - "describe": { - "columns": [ - { - "name": "count", - "ordinal": 0, - "type_info": "Integer" - } - ], - "parameters": { - "Right": 1 - }, - "nullable": [ - false - ] - }, - "hash": "74ea3158ee23c0dabbce8a41d97d4f2dbe8a4a7bb93dc645a18a36d8429bbe9b" -} diff --git a/.sqlx/query-89626327ed8ded677cf8bde44089ebd54aa96bc5ff420b2242d297aaff361df2.json b/.sqlx/query-89626327ed8ded677cf8bde44089ebd54aa96bc5ff420b2242d297aaff361df2.json deleted file mode 100644 index bba6699..0000000 --- a/.sqlx/query-89626327ed8ded677cf8bde44089ebd54aa96bc5ff420b2242d297aaff361df2.json +++ /dev/null @@ -1,116 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n SELECT\n id as \"id!\",\n user_id as \"user_id!\",\n account_id as \"account_id!\",\n node_id as \"node_id!\",\n node_alias as \"node_alias!\",\n macaroon as \"macaroon!\",\n tls_cert as \"tls_cert!\",\n address as \"address!\",\n node_type as \"node_type?\",\n client_cert as \"client_cert?\",\n client_key as \"client_key?\",\n ca_cert as \"ca_cert?\",\n is_active as \"is_active!\",\n created_at as \"created_at!: DateTime\",\n updated_at as \"updated_at!: DateTime\",\n is_deleted as \"is_deleted!\",\n deleted_at as \"deleted_at?: DateTime\"\n FROM credentials WHERE is_deleted = 0\n ", - "describe": { - "columns": [ - { - "name": "id!", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "user_id!", - "ordinal": 1, - "type_info": "Text" - }, - { - "name": "account_id!", - "ordinal": 2, - "type_info": "Text" - }, - { - "name": "node_id!", - "ordinal": 3, - "type_info": "Text" - }, - { - "name": "node_alias!", - "ordinal": 4, - "type_info": "Text" - }, - { - "name": "macaroon!", - "ordinal": 5, - "type_info": "Text" - }, - { - "name": "tls_cert!", - "ordinal": 6, - "type_info": "Text" - }, - { - "name": "address!", - "ordinal": 7, - "type_info": "Text" - }, - { - "name": "node_type?", - "ordinal": 8, - "type_info": "Text" - }, - { - "name": "client_cert?", - "ordinal": 9, - "type_info": "Text" - }, - { - "name": "client_key?", - "ordinal": 10, - "type_info": "Text" - }, - { - "name": "ca_cert?", - "ordinal": 11, - "type_info": "Text" - }, - { - "name": "is_active!", - "ordinal": 12, - "type_info": "Bool" - }, - { - "name": "created_at!: DateTime", - "ordinal": 13, - "type_info": "Datetime" - }, - { - "name": "updated_at!: DateTime", - "ordinal": 14, - "type_info": "Datetime" - }, - { - "name": "is_deleted!", - "ordinal": 15, - "type_info": "Bool" - }, - { - "name": "deleted_at?: DateTime", - "ordinal": 16, - "type_info": "Datetime" - } - ], - "parameters": { - "Right": 0 - }, - "nullable": [ - true, - false, - false, - false, - true, - false, - false, - false, - true, - true, - true, - true, - false, - false, - false, - false, - true - ] - }, - "hash": "89626327ed8ded677cf8bde44089ebd54aa96bc5ff420b2242d297aaff361df2" -} diff --git a/.sqlx/query-92c484f9a5b4cf67a3faf9f5e43bb758098409e63f62f6c77834e6e06f5882ff.json b/.sqlx/query-92c484f9a5b4cf67a3faf9f5e43bb758098409e63f62f6c77834e6e06f5882ff.json deleted file mode 100644 index c8c3b87..0000000 --- a/.sqlx/query-92c484f9a5b4cf67a3faf9f5e43bb758098409e63f62f6c77834e6e06f5882ff.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n SELECT \n id as \"id!\",\n account_id as \"account_id!\",\n inviter_id as \"inviter_id!\",\n invitee_email as \"invitee_email!\",\n token as \"token!\",\n invite_status as \"invite_status: InviteStatus\",\n is_active as \"is_active!\",\n created_at as \"created_at!: DateTime\",\n expires_at as \"expires_at!: DateTime\",\n updated_at as \"updated_at!: DateTime\",\n is_deleted as \"is_deleted!\",\n deleted_at as \"deleted_at?: DateTime\"\n FROM invites WHERE token = ? AND is_deleted = 0\n ", - "describe": { - "columns": [ - { - "name": "id!", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "account_id!", - "ordinal": 1, - "type_info": "Text" - }, - { - "name": "inviter_id!", - "ordinal": 2, - "type_info": "Text" - }, - { - "name": "invitee_email!", - "ordinal": 3, - "type_info": "Text" - }, - { - "name": "token!", - "ordinal": 4, - "type_info": "Text" - }, - { - "name": "invite_status: InviteStatus", - "ordinal": 5, - "type_info": "Integer" - }, - { - "name": "is_active!", - "ordinal": 6, - "type_info": "Bool" - }, - { - "name": "created_at!: DateTime", - "ordinal": 7, - "type_info": "Datetime" - }, - { - "name": "expires_at!: DateTime", - "ordinal": 8, - "type_info": "Datetime" - }, - { - "name": "updated_at!: DateTime", - "ordinal": 9, - "type_info": "Datetime" - }, - { - "name": "is_deleted!", - "ordinal": 10, - "type_info": "Bool" - }, - { - "name": "deleted_at?: DateTime", - "ordinal": 11, - "type_info": "Datetime" - } - ], - "parameters": { - "Right": 1 - }, - "nullable": [ - true, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - true - ] - }, - "hash": "92c484f9a5b4cf67a3faf9f5e43bb758098409e63f62f6c77834e6e06f5882ff" -} diff --git a/.sqlx/query-933b552d055a1f79a6c5101930da672613f3e6d33429586dc4c9bd1ee7c49566.json b/.sqlx/query-933b552d055a1f79a6c5101930da672613f3e6d33429586dc4c9bd1ee7c49566.json deleted file mode 100644 index 95ca5f2..0000000 --- a/.sqlx/query-933b552d055a1f79a6c5101930da672613f3e6d33429586dc4c9bd1ee7c49566.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "db_name": "SQLite", - "query": "SELECT COUNT(*) as count FROM users WHERE username = ? AND id != ? AND is_deleted = 0", - "describe": { - "columns": [ - { - "name": "count", - "ordinal": 0, - "type_info": "Integer" - } - ], - "parameters": { - "Right": 2 - }, - "nullable": [ - false - ] - }, - "hash": "933b552d055a1f79a6c5101930da672613f3e6d33429586dc4c9bd1ee7c49566" -} diff --git a/.sqlx/query-9d73f591b115e2367dfc978e80c4df95c77f8e4b6e2048e8c0bb993e2a8c6d06.json b/.sqlx/query-9d73f591b115e2367dfc978e80c4df95c77f8e4b6e2048e8c0bb993e2a8c6d06.json deleted file mode 100644 index c48a701..0000000 --- a/.sqlx/query-9d73f591b115e2367dfc978e80c4df95c77f8e4b6e2048e8c0bb993e2a8c6d06.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n SELECT \n id as \"id!\",\n account_id as \"account_id!\",\n inviter_id as \"inviter_id!\",\n invitee_email as \"invitee_email!\",\n token as \"token!\",\n invite_status as \"invite_status: InviteStatus\",\n is_active as \"is_active!\",\n created_at as \"created_at!: DateTime\",\n expires_at as \"expires_at!: DateTime\",\n updated_at as \"updated_at!: DateTime\",\n is_deleted as \"is_deleted!\",\n deleted_at as \"deleted_at?: DateTime\"\n FROM invites WHERE invitee_email = ? AND account_id = ? AND is_deleted = 0\n ", - "describe": { - "columns": [ - { - "name": "id!", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "account_id!", - "ordinal": 1, - "type_info": "Text" - }, - { - "name": "inviter_id!", - "ordinal": 2, - "type_info": "Text" - }, - { - "name": "invitee_email!", - "ordinal": 3, - "type_info": "Text" - }, - { - "name": "token!", - "ordinal": 4, - "type_info": "Text" - }, - { - "name": "invite_status: InviteStatus", - "ordinal": 5, - "type_info": "Integer" - }, - { - "name": "is_active!", - "ordinal": 6, - "type_info": "Bool" - }, - { - "name": "created_at!: DateTime", - "ordinal": 7, - "type_info": "Datetime" - }, - { - "name": "expires_at!: DateTime", - "ordinal": 8, - "type_info": "Datetime" - }, - { - "name": "updated_at!: DateTime", - "ordinal": 9, - "type_info": "Datetime" - }, - { - "name": "is_deleted!", - "ordinal": 10, - "type_info": "Bool" - }, - { - "name": "deleted_at?: DateTime", - "ordinal": 11, - "type_info": "Datetime" - } - ], - "parameters": { - "Right": 2 - }, - "nullable": [ - true, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - true - ] - }, - "hash": "9d73f591b115e2367dfc978e80c4df95c77f8e4b6e2048e8c0bb993e2a8c6d06" -} diff --git a/.sqlx/query-e5724216e341699305822b3452a1a63af1fa8e1fe484dcab468f81d79801c60a.json b/.sqlx/query-e5724216e341699305822b3452a1a63af1fa8e1fe484dcab468f81d79801c60a.json deleted file mode 100644 index 98c327b..0000000 --- a/.sqlx/query-e5724216e341699305822b3452a1a63af1fa8e1fe484dcab468f81d79801c60a.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n UPDATE invites \n SET invite_status = ?, \n updated_at = CURRENT_TIMESTAMP\n WHERE id = ? AND is_deleted = 0\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 2 - }, - "nullable": [] - }, - "hash": "e5724216e341699305822b3452a1a63af1fa8e1fe484dcab468f81d79801c60a" -} diff --git a/backend/src/repositories/credential_repository.rs b/backend/src/repositories/credential_repository.rs index f3cd5f9..bbeb3b0 100644 --- a/backend/src/repositories/credential_repository.rs +++ b/backend/src/repositories/credential_repository.rs @@ -81,43 +81,6 @@ impl<'a> CredentialRepository<'a> { Ok(credential) } - /// Retrieves credentials by their unique identifier. - /// - /// # Arguments - /// * `id` - Credential ID (UUID format) - /// - /// # Returns - /// `Some(Credential)` if found, `None` otherwise - pub async fn get_credential_by_id(&self, id: &str) -> Result> { - let credential = sqlx::query_as!( - Credential, - r#" - SELECT - id as "id!", - user_id as "user_id!", - account_id as "account_id!", - node_id as "node_id!", - node_alias as "node_alias!", - macaroon as "macaroon!", - tls_cert as "tls_cert!", - address as "address!", - node_type as "node_type?", - client_cert as "client_cert?", - client_key as "client_key?", - ca_cert as "ca_cert?", - is_active as "is_active!", - created_at as "created_at!: DateTime", - updated_at as "updated_at!: DateTime" - FROM credentials WHERE id = ? - "#, - id - ) - .fetch_optional(self.pool) - .await?; - - Ok(credential) - } - /// Retrieves credentials associated with a specific user. /// /// # Arguments diff --git a/backend/src/services/credential_service.rs b/backend/src/services/credential_service.rs index cc05eba..4e7d9d9 100644 --- a/backend/src/services/credential_service.rs +++ b/backend/src/services/credential_service.rs @@ -99,14 +99,14 @@ impl<'a> CredentialService<'a> { /// /// # Errors /// Returns `ServiceError::NotFound` if credential doesn't exist - pub async fn get_credential_required(&self, id: &str) -> ServiceResult { - let repo = CredentialRepository::new(self.pool); - let credential = repo - .get_credential_by_id(id) - .await? - .ok_or_else(|| ServiceError::not_found("Credential", id))?; - Ok(credential) - } + // pub async fn get_credential_required(&self, id: &str) -> ServiceResult { + // let repo = CredentialRepository::new(self.pool); + // let credential = repo + // .get_credential_by_id(id) + // .await? + // .ok_or_else(|| ServiceError::not_found("Credential", id))?; + // Ok(credential) + // } /// Retrieves credentials by user ID with existence verification. /// diff --git a/shell.nix b/shell.nix index 207c94a..8e9c23e 100644 --- a/shell.nix +++ b/shell.nix @@ -8,7 +8,6 @@ pkgs.mkShell { # Node.js and frontend tools nodejs_22 # Node.js 22 LTS - npm # Node package manager # Database tools (useful with sqlx-cli) sqlite # SQLite database