pub struct PostgresRevocationStore { /* private fields */ }Expand description
PostgreSQL-backed JWT revocation store.
Persists revoked jti claims in fraiseql_revoked_tokens, so revocations
survive a restart and are shared across replicas — unlike the in-memory
backend, which the server silently fell back to for backend = "postgres"
before this was implemented (#357). Each row carries an expires_at matching
the JWT’s remaining lifetime; is_revoked ignores expired rows and
cleanup_expired prunes them.
Implementations§
Source§impl PostgresRevocationStore
impl PostgresRevocationStore
Sourcepub async fn new(pool: PgPool) -> Result<Self, RevocationError>
pub async fn new(pool: PgPool) -> Result<Self, RevocationError>
Create a Postgres revocation store, ensuring the backing table exists (idempotent DDL).
§Errors
Returns RevocationError::Backend if the schema cannot be created.
Sourcepub async fn cleanup_expired(&self) -> Result<u64, RevocationError>
pub async fn cleanup_expired(&self) -> Result<u64, RevocationError>
Delete expired revocation rows. Optional housekeeping; is_revoked already
ignores expired entries, so this only reclaims space.
§Errors
Returns RevocationError::Backend if the delete fails.
Trait Implementations§
Source§impl RevocationStore for PostgresRevocationStore
impl RevocationStore for PostgresRevocationStore
Source§fn is_revoked<'life0, 'life1, 'async_trait>(
&'life0 self,
jti: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<bool, RevocationError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn is_revoked<'life0, 'life1, 'async_trait>(
&'life0 self,
jti: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<bool, RevocationError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn revoke<'life0, 'life1, 'async_trait>(
&'life0 self,
jti: &'life1 str,
ttl_secs: u64,
) -> Pin<Box<dyn Future<Output = Result<(), RevocationError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn revoke<'life0, 'life1, 'async_trait>(
&'life0 self,
jti: &'life1 str,
ttl_secs: u64,
) -> Pin<Box<dyn Future<Output = Result<(), RevocationError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
ttl_secs is the remaining JWT lifetime —
the store should auto-expire the entry after this duration.Source§fn revoke_all_for_user<'life0, 'life1, 'async_trait>(
&'life0 self,
sub: &'life1 str,
ttl_secs: u64,
) -> Pin<Box<dyn Future<Output = Result<(), RevocationError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn revoke_all_for_user<'life0, 'life1, 'async_trait>(
&'life0 self,
sub: &'life1 str,
ttl_secs: u64,
) -> Pin<Box<dyn Future<Output = Result<(), RevocationError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
sub whose iat (issued-at) is at or before now is henceforth rejected by
user_revoked_after. Read moreSource§fn user_revoked_after<'life0, 'life1, 'async_trait>(
&'life0 self,
sub: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<i64>, RevocationError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn user_revoked_after<'life0, 'life1, 'async_trait>(
&'life0 self,
sub: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<i64>, RevocationError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
revoke-all epoch (unix seconds) currently in effect for sub, or
None when the user has no active epoch. Tokens with iat <= epoch are revoked.Auto Trait Implementations§
impl !RefUnwindSafe for PostgresRevocationStore
impl !UnwindSafe for PostgresRevocationStore
impl Freeze for PostgresRevocationStore
impl Send for PostgresRevocationStore
impl Sync for PostgresRevocationStore
impl Unpin for PostgresRevocationStore
impl UnsafeUnpin for PostgresRevocationStore
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more