diff --git a/crates/frontend/src/routes/app_token.rs b/crates/frontend/src/routes/app_token.rs index 248f9ae..fdf174c 100644 --- a/crates/frontend/src/routes/app_token.rs +++ b/crates/frontend/src/routes/app_token.rs @@ -56,9 +56,13 @@ pub async fn route_post_app_token( assert!(!name.is_empty()); assert_eq!(user_id, user.id); let token = generate_app_token(); - auth_provider + let mut token_id = auth_provider .add_app_token(&user.id, name.to_owned(), token.clone()) .await?; + // Get first 4 characters of token identifier + token_id.truncate(4); + // This will be a hint for the token validator which app token hash to verify against + let token = format!("{token_id}_{token}"); if apple { let profile = AppleConfig { token_name: name, diff --git a/crates/store_sqlite/src/principal_store.rs b/crates/store_sqlite/src/principal_store.rs index 11c2a3c..1259f5e 100644 --- a/crates/store_sqlite/src/principal_store.rs +++ b/crates/store_sqlite/src/principal_store.rs @@ -149,8 +149,23 @@ impl AuthenticationProvider for SqlitePrincipalStore { user_id: &str, token: &str, ) -> Result, Error> { + #[instrument(skip(password))] + fn verify_password(password: &str, hash: &str) -> Result<(), password_auth::VerifyError> { + password_auth::verify_password(password, hash) + } + + // Allow to specify the token id to use to make validation faster + // Doesn't match the whole length of the token id to keep the length in bounds + // Example: asd_selgkh + // where the app token id starts with asd and its value is selgkh + let (token_id_prefix, token) = token.split_once('_').unwrap_or(("", token)); + for app_token in &self.get_app_tokens(user_id).await? { - if password_auth::verify_password(token, app_token.token.as_ref()).is_ok() { + // Wrong token id + if !app_token.id.starts_with(token_id_prefix) { + continue; + } + if verify_password(token, app_token.token.as_ref()).is_ok() { return self.get_principal(user_id).await; } }