diff --git a/crates/storage-pg/migrations/20251023134634_personal_access_tokens_unique_fix.sql b/crates/storage-pg/migrations/20251023134634_personal_access_tokens_unique_fix.sql new file mode 100644 index 000000000..9274d16ac --- /dev/null +++ b/crates/storage-pg/migrations/20251023134634_personal_access_tokens_unique_fix.sql @@ -0,0 +1,14 @@ +-- Copyright 2025 Element Creations Ltd. +-- +-- SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +-- Please see LICENSE in the repository root for full details. + + +-- Fix a faulty constraint. +-- The condition was incorrectly specified as `revoked_at IS NOT NULL` +-- when `revoked_at IS NULL` was meant. + +DROP INDEX personal_access_tokens_personal_session_id_idx; + +-- Ensure we can only have one active personal access token in each family. +CREATE UNIQUE INDEX ON personal_access_tokens (personal_session_id) WHERE revoked_at IS NULL; diff --git a/crates/storage-pg/src/personal/mod.rs b/crates/storage-pg/src/personal/mod.rs index aa4597fec..f540a6be3 100644 --- a/crates/storage-pg/src/personal/mod.rs +++ b/crates/storage-pg/src/personal/mod.rs @@ -384,6 +384,11 @@ mod tests { assert!(!token.is_valid(clock.now())); // Add a second access token, this time without expiration + let _token = repo + .personal_access_token() + .revoke(&clock, token) + .await + .unwrap(); let token = repo .personal_access_token() .add(&mut rng, &clock, &session, SECOND_TOKEN, None)