Skip to main content

better_auth_api/plugins/oauth/
callbacks.rs

1use super::OAuthPlugin;
2use crate::plugins::endpoint_context::{EndpointContext, WithCallbacks};
3use better_auth_core::{AuthPlugin, AuthResult, AuthSchema};
4use std::{collections::HashMap, future::Future, pin::Pin, sync::Arc};
5
6/// An ID-token verifier that borrows the token and active endpoint.
7pub type OAuthVerifierFuture<'a> = Pin<Box<dyn Future<Output = AuthResult<bool>> + Send + 'a>>;
8type Verify<S> = dyn for<'a> Fn(&'a str, Option<&'a str>, &'a EndpointContext<'_, S>) -> OAuthVerifierFuture<'a>
9    + Send
10    + Sync;
11
12/// Schema-aware verification callbacks keyed by the registered provider name.
13pub struct OAuthCallbacks<S: AuthSchema> {
14    pub(crate) verifiers: HashMap<String, Arc<Verify<S>>>,
15}
16
17impl<S: AuthSchema> Default for OAuthCallbacks<S> {
18    fn default() -> Self {
19        Self {
20            verifiers: HashMap::new(),
21        }
22    }
23}
24
25impl<S: AuthSchema> OAuthCallbacks<S> {
26    /// Override the registered provider's ID-token verifier. False and errors reject the token.
27    /// This callback takes precedence over `OAuthProvider::verify_id_token`.
28    pub fn verify_id_token<F>(mut self, provider: impl Into<String>, callback: F) -> Self
29    where
30        F: for<'a> Fn(
31                &'a str,
32                Option<&'a str>,
33                &'a EndpointContext<'_, S>,
34            ) -> OAuthVerifierFuture<'a>
35            + Send
36            + Sync
37            + 'static,
38    {
39        let _ = self.verifiers.insert(provider.into(), Arc::new(callback));
40        self
41    }
42}
43
44impl OAuthPlugin {
45    /// Attach schema-aware verifiers after configuring providers.
46    pub fn callbacks<S: AuthSchema>(self, callbacks: OAuthCallbacks<S>) -> impl AuthPlugin<S> {
47        WithCallbacks {
48            plugin: self,
49            callbacks: Arc::new(callbacks),
50        }
51    }
52}