feat: use current token for go to app instead of refresh token

This commit is contained in:
Fu Zi Xiang 2023-11-09 10:31:24 +08:00
parent 680d6fe5b1
commit e2d6d1df02
No known key found for this signature in database
3 changed files with 36 additions and 53 deletions

View File

@ -8,6 +8,7 @@ use axum::{
};
use axum_extra::extract::CookieJar;
use gotrue::grant::{Grant, RefreshTokenGrant};
use gotrue_entity::dto::GotrueTokenResponse;
use jwt::{Claims, Header};
use redis::{aio::ConnectionManager, AsyncCommands, FromRedisValue, ToRedisArgs};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
@ -66,17 +67,12 @@ impl SessionStorage {
#[derive(Debug, Serialize, Deserialize)]
pub struct UserSession {
pub session_id: String,
pub access_token: String,
pub refresh_token: String,
pub token: GotrueTokenResponse,
}
impl UserSession {
pub fn new(session_id: String, access_token: String, refresh_token: String) -> Self {
Self {
session_id,
access_token,
refresh_token,
}
pub fn new(session_id: String, token: GotrueTokenResponse) -> Self {
Self { session_id, token }
}
}
@ -103,9 +99,9 @@ impl FromRequestParts<AppState> for UserSession {
.await
.ok_or(SessionRejection::SessionNotFound)?;
if has_expired(session.access_token.as_str()) {
if has_expired(session.token.access_token.as_str()) {
// Get new pair of access token and refresh token
let refresh_token = session.refresh_token;
let refresh_token = session.token.refresh_token;
let new_token = state
.gotrue_client
.clone()
@ -113,8 +109,8 @@ impl FromRequestParts<AppState> for UserSession {
.await
.map_err(|err| SessionRejection::RefreshTokenError(err.to_string()))?;
session.access_token = new_token.access_token;
session.refresh_token = new_token.refresh_token;
session.token.access_token = new_token.access_token;
session.token.refresh_token = new_token.refresh_token;
// Update session in redis
let _ = state

View File

@ -14,7 +14,6 @@ use axum::Form;
use axum::{extract::State, routing::post, Router};
use axum_extra::extract::cookie::Cookie;
use axum_extra::extract::CookieJar;
use gotrue::grant::{Grant, RefreshTokenGrant};
use gotrue::params::{AdminDeleteUserParams, AdminUserParams, GenerateLinkParams, MagicLinkParams};
use gotrue_entity::dto::{UpdateGotrueUserParams, User};
@ -43,27 +42,14 @@ pub fn router() -> Router<AppState> {
}
// provide a link which when open in browser, opens the appflowy app
pub async fn open_app_handler(
State(state): State<AppState>,
session: UserSession,
) -> Result<HeaderMap, WebApiError<'static>> {
let access_token_resp = state
.gotrue_client
.token(&Grant::RefreshToken(RefreshTokenGrant {
refresh_token: session.refresh_token.to_owned(),
}))
.await?;
// appflowy-flutter:// -> scheme that opens the Appflowy app
// login-callback -> agreed upon convention that frontend recognizes
// The rest are params that are passed to the app needed for login
pub async fn open_app_handler(session: UserSession) -> Result<HeaderMap, WebApiError<'static>> {
let app_sign_in_url = format!(
"appflowy-flutter://login-callback#access_token={}&expires_at={}&expires_in={}&refresh_token={}&token_type={}",
access_token_resp.access_token,
access_token_resp.expires_at,
access_token_resp.expires_in,
access_token_resp.refresh_token,
access_token_resp.token_type,
session.token.access_token,
session.token.expires_at,
session.token.expires_in,
session.token.refresh_token,
session.token.token_type,
);
Ok(htmx_redirect(&app_sign_in_url))
}
@ -78,7 +64,7 @@ pub async fn invite_handler(
state
.gotrue_client
.magic_link(
&session.access_token,
&session.token.access_token,
&MagicLinkParams {
email: param.email,
..Default::default()
@ -102,7 +88,7 @@ pub async fn change_password_handler(
let res = state
.gotrue_client
.update_user(
&session.access_token,
&session.token.access_token,
&UpdateGotrueUserParams {
password: Some(param.new_password),
..Default::default()
@ -147,7 +133,7 @@ pub async fn admin_update_user_handler(
let res = state
.gotrue_client
.admin_update_user(
&session.access_token,
&session.token.access_token,
&user_uuid,
&AdminUserParams {
password: Some(param.password.to_owned()),
@ -167,7 +153,7 @@ pub async fn post_user_generate_link_handler(
let res = state
.gotrue_client
.admin_generate_link(
&session.access_token,
&session.token.access_token,
&GenerateLinkParams {
email,
..Default::default()
@ -185,7 +171,7 @@ pub async fn admin_delete_user_handler(
state
.gotrue_client
.admin_delete_user(
&session.access_token,
&session.token.access_token,
&user_uuid,
&AdminDeleteUserParams {
should_soft_delete: true,
@ -208,7 +194,7 @@ pub async fn admin_add_user_handler(
};
let user = state
.gotrue_client
.admin_add_user(&session.access_token, &add_user_params)
.admin_add_user(&session.token.access_token, &add_user_params)
.await?;
Ok(user.into())
}
@ -226,11 +212,7 @@ pub async fn login_refresh_handler(
.await?;
let new_session_id = uuid::Uuid::new_v4();
let new_session = session::UserSession::new(
new_session_id.to_string(),
token.access_token.to_string(),
token.refresh_token.to_owned(),
);
let new_session = session::UserSession::new(new_session_id.to_string(), token);
state.session_store.put_user_session(&new_session).await?;
let mut cookie = Cookie::new("session_id", new_session_id.to_string());
@ -257,11 +239,7 @@ pub async fn login_handler(
.await?;
let new_session_id = uuid::Uuid::new_v4();
let new_session = session::UserSession::new(
new_session_id.to_string(),
token.access_token.to_string(),
token.refresh_token.to_owned(),
);
let new_session = session::UserSession::new(new_session_id.to_string(), token);
state.session_store.put_user_session(&new_session).await?;
Ok((

View File

@ -57,7 +57,10 @@ pub async fn user_user_handler(
State(state): State<AppState>,
session: UserSession,
) -> Result<Html<String>, WebAppError> {
let user = state.gotrue_client.user_info(&session.access_token).await?;
let user = state
.gotrue_client
.user_info(&session.token.access_token)
.await?;
render_template(templates::UserDetails { user: &user })
}
@ -73,7 +76,10 @@ pub async fn home_handler(
State(state): State<AppState>,
session: UserSession,
) -> Result<Html<String>, WebAppError> {
let user = state.gotrue_client.user_info(&session.access_token).await?;
let user = state
.gotrue_client
.user_info(&session.token.access_token)
.await?;
render_template(templates::Home {
user: &user,
is_admin: is_admin(&user),
@ -84,7 +90,10 @@ pub async fn admin_home_handler(
State(state): State<AppState>,
session: UserSession,
) -> Result<Html<String>, WebAppError> {
let user = state.gotrue_client.user_info(&session.access_token).await?;
let user = state
.gotrue_client
.user_info(&session.token.access_token)
.await?;
render_template(templates::AdminHome { user: &user })
}
@ -94,7 +103,7 @@ pub async fn admin_users_handler(
) -> Result<Html<String>, WebAppError> {
let users = state
.gotrue_client
.admin_list_user(&session.access_token)
.admin_list_user(&session.token.access_token)
.await
.map_or_else(
|err| {
@ -117,7 +126,7 @@ pub async fn admin_user_details_handler(
) -> Result<Html<String>, WebAppError> {
let user = state
.gotrue_client
.admin_user_details(&session.access_token, &user_id)
.admin_user_details(&session.token.access_token, &user_id)
.await
.unwrap(); // TODO: handle error