Update profile to include all available fields from Google
This commit is contained in:
parent
022a138e56
commit
42aba64bc2
|
|
@ -23,7 +23,7 @@ oauth2 = "4.4"
|
|||
http = "1.1"
|
||||
tower-http = { version = "0.6.1", features = ["full"] }
|
||||
chrono = { version = "0.4.38", features = ["serde"] }
|
||||
sqlx = { version = "0.8", features = ["sqlite", "runtime-tokio"] }
|
||||
sqlx = { version = "0.8", features = ["sqlite", "runtime-tokio", "macros"] }
|
||||
uuid = { version = "1.10", features = ["v4"] }
|
||||
dotenvy = "0.15"
|
||||
constant_time_eq = "0.3"
|
||||
|
|
|
|||
|
|
@ -56,8 +56,10 @@ pub struct UserData {
|
|||
#[allow(dead_code)]
|
||||
pub id: i64,
|
||||
pub email: String,
|
||||
/* pub name: String,
|
||||
pub discriminator: String,
|
||||
pub name: String,
|
||||
pub family_name: String,
|
||||
pub given_name: String,
|
||||
/* pub discriminator: String,
|
||||
pub avatar: String,
|
||||
pub access_token: String,
|
||||
pub refresh_token: String,
|
||||
|
|
|
|||
|
|
@ -43,16 +43,16 @@ pub async fn inject_user_data(
|
|||
let id = query.0;
|
||||
let expires_at = query.1;
|
||||
if expires_at > Utc::now().timestamp() {
|
||||
let query: Result<(String,), _> =
|
||||
sqlx::query_as(r#"SELECT email FROM users WHERE id=?"#)
|
||||
.bind(id)
|
||||
let row = sqlx::query_as!(UserData, "SELECT * FROM users WHERE id = ?", id)
|
||||
.fetch_one(&db_pool)
|
||||
.await;
|
||||
if let Ok(query) = query {
|
||||
let email = query.0;
|
||||
.await?;
|
||||
|
||||
request.extensions_mut().insert(Some(UserData {
|
||||
id,
|
||||
email,
|
||||
id: row.id,
|
||||
email: row.email,
|
||||
name: row.name,
|
||||
family_name: row.family_name,
|
||||
given_name: row.given_name,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
@ -61,7 +61,6 @@ pub async fn inject_user_data(
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(next.run(request).await)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,6 +81,9 @@ pub async fn login(
|
|||
.add_scope(Scope::new(
|
||||
"https://www.googleapis.com/auth/userinfo.email".to_string(),
|
||||
))
|
||||
.add_scope(Scope::new(
|
||||
"https://www.googleapis.com/auth/userinfo.profile".to_string(),
|
||||
))
|
||||
.set_pkce_challenge(pkce_code_challenge)
|
||||
.url();
|
||||
|
||||
|
|
@ -151,11 +154,27 @@ pub async fn google_auth_return(
|
|||
.map_err(|_| "OAuth: reqwest received invalid userinfo")?;
|
||||
let mut body: serde_json::Value =
|
||||
serde_json::from_str(body.as_str()).map_err(|_| "OAuth: Serde failed to parse userinfo")?;
|
||||
println!("body: {}", body);
|
||||
let email = body["email"]
|
||||
.take()
|
||||
.as_str()
|
||||
.ok_or("OAuth: Serde failed to parse email address")?
|
||||
.to_owned();
|
||||
let name = body["name"]
|
||||
.take()
|
||||
.as_str()
|
||||
.ok_or("OAuth: Serde failed to parse email address")?
|
||||
.to_owned();
|
||||
let family_name = body["family_name"]
|
||||
.take()
|
||||
.as_str()
|
||||
.ok_or("OAuth: Serde failed to parse email address")?
|
||||
.to_owned();
|
||||
let given_name = body["given_name"]
|
||||
.take()
|
||||
.as_str()
|
||||
.ok_or("OAuth: Serde failed to parse email address")?
|
||||
.to_owned();
|
||||
let verified_email = body["verified_email"]
|
||||
.take()
|
||||
.as_bool()
|
||||
|
|
@ -174,8 +193,11 @@ pub async fn google_auth_return(
|
|||
let user_id = if let Ok(query) = query {
|
||||
query.0
|
||||
} else {
|
||||
let query: (i64,) = sqlx::query_as("INSERT INTO users (email) VALUES (?) RETURNING id")
|
||||
let query: (i64,) = sqlx::query_as("INSERT INTO users (email, name, family_name, given_name) VALUES (?, ?, ?, ?) RETURNING id")
|
||||
.bind(email)
|
||||
.bind(name)
|
||||
.bind(family_name)
|
||||
.bind(given_name)
|
||||
.fetch_one(&db_pool)
|
||||
.await?;
|
||||
query.0
|
||||
|
|
|
|||
|
|
@ -10,17 +10,23 @@ use crate::{HtmlTemplate, UserData};
|
|||
struct ProfileTemplate {
|
||||
logged_in: bool,
|
||||
name: String,
|
||||
family_name: String,
|
||||
given_name: String,
|
||||
email: String,
|
||||
}
|
||||
|
||||
pub async fn profile<T>(
|
||||
Extension(user_data): Extension<Option<UserData>>,
|
||||
_request: Request<T>,
|
||||
) -> impl IntoResponse {
|
||||
let email = user_data.map(|s| s.email);
|
||||
let logged_in = email.is_some();
|
||||
let name = email.unwrap_or_default();
|
||||
|
||||
let template = ProfileTemplate { logged_in, name};
|
||||
let Some(UserData {id, email, family_name, given_name, name}) = user_data
|
||||
else {
|
||||
return HtmlTemplate(ProfileTemplate { logged_in: false, name: "".to_owned(), given_name: "".to_owned(), family_name: "".to_owned(), email: "".to_owned() });
|
||||
};
|
||||
let logged_in = id > 0;
|
||||
|
||||
let template = ProfileTemplate { logged_in, name, given_name, family_name, email };
|
||||
HtmlTemplate(template)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@
|
|||
<!-- FOOTER -->
|
||||
<footer>
|
||||
<p class="pull-right"><a href="#">Back to top</a></p>
|
||||
<p>© 2022 Jean-Marie family</p>
|
||||
<p>© 2024 Jean-Marie family</p>
|
||||
</footer>
|
||||
</div><!-- /.container -->
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
{% extends "base.html" %}
|
||||
{% block title %}User Profile{% endblock %}
|
||||
{% block content %}
|
||||
This is your user profile page. <br />
|
||||
Your email address: {{ name }}.
|
||||
<h1>User Profile</h1>
|
||||
Full name: {{ name }}<br/>
|
||||
Given name: {{ given_name }}<br/>
|
||||
Family name: {{ family_name }}<br/>
|
||||
Your email address: {{ email }}<br
|
||||
{% endblock %}
|
||||
|
|
|
|||
Loading…
Reference in New Issue