fars/api/
exchange_refresh_token.rs

1//! Implements the exchange refresh token API of the Firebase Auth.
2//!
3//! You can refresh a Firebase ID token by issuing an HTTP POST request to the securetoken.googleapis.com endpoint.
4//!
5//! See also [API reference](https://firebase.google.com/docs/reference/rest/auth#section-refresh-token)
6
7use serde::{Deserialize, Serialize};
8
9use crate::ApiKey;
10use crate::Client;
11use crate::Endpoint;
12use crate::Result;
13
14/// Request body payload for the exchange refresh token API.
15///
16/// See also [API reference](https://firebase.google.com/docs/reference/rest/auth#section-refresh-token).
17#[derive(Serialize)]
18pub struct ExchangeRefreshTokenRequestBodyPayload {
19    /// The refresh token's grant type, always "refresh_token".
20    #[serde(rename = "grant_type")]
21    grant_type: String,
22    /// A Firebase Auth refresh token.
23    #[serde(rename = "refresh_token")]
24    refresh_token: String,
25}
26
27impl ExchangeRefreshTokenRequestBodyPayload {
28    /// Creates a new request body payload for the exchange refresh token API.
29    ///
30    /// See also [API reference](https://firebase.google.com/docs/reference/rest/auth#section-refresh-token).
31    ///
32    /// ## Arguments
33    /// - `refresh_token` - A Firebase Auth refresh token.
34    pub fn new(refresh_token: String) -> Self {
35        Self {
36            grant_type: "refresh_token".to_string(),
37            refresh_token,
38        }
39    }
40}
41
42/// Response payload for the exchange refresh token API.
43///
44/// See also [API reference](https://firebase.google.com/docs/reference/rest/auth#section-refresh-token).
45#[derive(Deserialize, Debug)]
46pub struct ExchangeRefreshTokenResponsePayload {
47    /// The number of seconds in which the ID token expires.
48    #[serde(rename = "expires_in")]
49    pub expires_in: String,
50    /// The type of the refresh token, always "Bearer".
51    #[serde(rename = "token_type")]
52    pub token_type: String,
53    /// The Firebase Auth refresh token provided in the request or a new refresh token.
54    #[serde(rename = "refresh_token")]
55    pub refresh_token: String,
56    /// A Firebase Auth ID token.
57    #[serde(rename = "id_token")]
58    pub id_token: String,
59    /// The uid corresponding to the provided ID token.
60    #[serde(rename = "user_id")]
61    pub user_id: String,
62    /// Your Firebase project ID.
63    #[serde(rename = "project_id")]
64    pub project_id: String,
65}
66
67/// Exchanges a refresh token for an access token and an ID token.
68///
69/// See also [API reference](https://firebase.google.com/docs/reference/rest/auth#section-refresh-token).
70///
71/// ## Arguments
72/// - `client` - HTTP client.
73/// - `api_key` - Your Firebase project's API key.
74/// - `request` - Request body payload.
75///
76/// ## Errors
77/// - `Error::HttpRequestError` - Failed to send a request.
78/// - `Error::ReadResponseTextFailed` - Failed to read the response body as text.
79/// - `Error::DeserializeResponseJsonFailed` - Failed to deserialize the response body as JSON.
80/// - `Error::DeserializeErrorResponseJsonFailed` - Failed to deserialize the error response body as JSON.
81/// - `Error::ApiError` - API error on the Firebase Auth.
82///
83/// ## Common error codes
84/// - TOKEN_EXPIRED: The user's credential is no longer valid. The user must sign in again.
85/// - USER_DISABLED: The user account has been disabled by an administrator.
86/// - USER_NOT_FOUND: The user corresponding to the refresh token was not found. It is likely the user was deleted.
87/// - API key not valid. Please pass a valid API key. (invalid API key provided)
88/// - INVALID_REFRESH_TOKEN: An invalid refresh token is provided.
89/// - Invalid JSON payload received. Unknown name \"refresh_tokens\": Cannot bind query parameter. Field 'refresh_tokens' could not be found in request message.
90/// - INVALID_GRANT_TYPE: the grant type specified is invalid.
91/// - MISSING_REFRESH_TOKEN: no refresh token provided.
92///
93/// ## Example
94/// ```
95/// use fars::api;
96/// use fars::Client;
97/// use fars::ApiKey;
98///
99/// let request_payload = api::ExchangeRefreshTokenRequestBodyPayload::new(
100///     "refresh-token".to_string(),
101/// );
102///
103/// let response_payload = api::exchange_refresh_token(
104///     Client::new(),
105///     ApiKey::new("your-firebase-project-api-key"),
106///     request_payload,
107/// ).await?;
108/// ```
109pub async fn exchange_refresh_token(
110    client: &Client,
111    api_key: &ApiKey,
112    request_payload: ExchangeRefreshTokenRequestBodyPayload,
113) -> Result<ExchangeRefreshTokenResponsePayload> {
114    client.send_post::<
115        ExchangeRefreshTokenRequestBodyPayload,
116        ExchangeRefreshTokenResponsePayload,
117    >(
118        Endpoint::Token,
119        api_key,
120        request_payload,
121        None,
122    )
123    .await
124}