feat: self host support: sign up auto confirm

This commit is contained in:
Fu Zi Xiang 2023-11-09 13:38:32 +08:00
parent e2d6d1df02
commit 6803ff9cca
No known key found for this signature in database
3 changed files with 59 additions and 14 deletions

View File

@ -21,6 +21,7 @@ body {
padding: 4px 8px;
font-size: 16px;
cursor: pointer;
margin: auto;
}
.purple:hover {

View File

@ -15,7 +15,8 @@ use axum::{extract::State, routing::post, Router};
use axum_extra::extract::cookie::Cookie;
use axum_extra::extract::CookieJar;
use gotrue::params::{AdminDeleteUserParams, AdminUserParams, GenerateLinkParams, MagicLinkParams};
use gotrue_entity::dto::{UpdateGotrueUserParams, User};
use gotrue_entity::dto::{GotrueTokenResponse, SignUpResponse, UpdateGotrueUserParams, User};
use gotrue_entity::error::GoTrueError;
pub fn router() -> Router<AppState> {
Router::new()
@ -221,14 +222,15 @@ pub async fn login_refresh_handler(
Ok(jar.add(cookie))
}
// TODO: Support OAuth2 login
// login and set the cookie
// sign up if not exist
pub async fn login_handler(
State(state): State<AppState>,
jar: CookieJar,
Form(param): Form<WebApiLoginRequest>,
) -> Result<(CookieJar, HeaderMap), WebApiError<'static>> {
let token = state
// Attempt to sign in with email and password
let token_res = state
.gotrue_client
.token(&gotrue::grant::Grant::Password(
gotrue::grant::PasswordGrant {
@ -236,16 +238,44 @@ pub async fn login_handler(
password: param.password.to_owned(),
},
))
.await?;
.await;
let new_session_id = uuid::Uuid::new_v4();
let new_session = session::UserSession::new(new_session_id.to_string(), token);
state.session_store.put_user_session(&new_session).await?;
match token_res {
Ok(token) => session_login(State(state), token, jar).await, // login success
Err(err) => match &err {
GoTrueError::ClientError(client_err) => {
match (
client_err.error.as_str(),
client_err.error_description.as_ref().map(|s| s.as_str()),
) {
// Email not exist or wrong password
("invalid_grant", Some("Invalid login credentials")) => {
let sign_up_res = state
.gotrue_client
.sign_up(&param.email, &param.password)
.await;
Ok((
jar.add(new_session_cookie(new_session_id)),
htmx_redirect("/web/home"),
))
match sign_up_res {
Ok(resp) => match resp {
// when GOTRUE_MAILER_AUTOCONFIRM=true, auto sign in
SignUpResponse::Authenticated(token) => {
session_login(State(state), token, jar).await
},
SignUpResponse::NotAuthenticated(user) => match user.identities {
Some(_identities) => todo!(), // new user
None => Err(err.into()), // user exists but sign in password not correct
},
},
Err(err) => Err(err.into()),
}
},
_ => Err(err.into()),
}
},
_ => Err(err.into()),
},
}
}
pub async fn logout_handler(
@ -278,3 +308,18 @@ fn new_session_cookie(id: uuid::Uuid) -> Cookie<'static> {
cookie.set_path("/");
cookie
}
async fn session_login(
State(state): State<AppState>,
token: GotrueTokenResponse,
jar: CookieJar,
) -> Result<(CookieJar, HeaderMap), WebApiError<'static>> {
let new_session_id = uuid::Uuid::new_v4();
let new_session = session::UserSession::new(new_session_id.to_string(), token);
state.session_store.put_user_session(&new_session).await?;
Ok((
jar.add(new_session_cookie(new_session_id)),
htmx_redirect("/web/home"),
))
}

View File

@ -49,14 +49,13 @@
</td>
</tr>
</table>
<br />
<button
class="button cyan"
type="submit"
style="width: 100%; padding: 8px 8px"
style="width: 100%; margin: 16px auto 0; padding: 8px 8px"
id="submitBtn"
>
Sign In
Sign In / Sign Up
</button>
</form>
<br />