feat(magiclink) prepare magic link support (login via email)

imortant on security side: magic link  will be enabled only for users who don't have password nor OIDC
This commit is contained in:
Edouard Vanbelle
2026-06-01 21:57:07 +02:00
parent 2011d19e71
commit c3fa1b3e93
15 changed files with 1076 additions and 56 deletions
+12
View File
@@ -7,6 +7,8 @@ use crate::application::services::auth_application_service::AuthApplicationServi
use crate::application::services::user_lifecycle_service::UserLifecycleService;
use crate::common::config::AppConfig;
use crate::common::di::AuthServices;
use crate::domain::repositories::magic_link_token_repository::MagicLinkTokenRepository;
use crate::infrastructure::repositories::pg::MagicLinkTokenPgRepository;
use crate::infrastructure::repositories::{SessionPgRepository, UserPgRepository};
use crate::infrastructure::services::jwt_service::JwtTokenService;
use crate::infrastructure::services::oidc_service::OidcService;
@@ -50,6 +52,16 @@ pub async fn create_auth_services(
// direct FolderService dependency for that path.
auth_app_service = auth_app_service.with_user_lifecycle(user_lifecycle);
// Wire the magic-link token repo. Enables `GET /magic/v1/{token}`
// and the future `POST /api/auth/magic-link/send` endpoint to mint
// and consume tokens. The repo is unconditional (it's just SQL on
// an empty table when the feature is dormant); the feature kill
// switch lives in `config.magic_link.allow_external_users`, checked
// by the issuance side, not by the redemption side.
let magic_link_repo: Arc<dyn MagicLinkTokenRepository> =
Arc::new(MagicLinkTokenPgRepository::new(pool.clone()));
auth_app_service = auth_app_service.with_magic_link_repo(magic_link_repo);
// Configure OIDC service if enabled
if config.oidc.enabled {
tracing::info!(