//! Tests for Administrator repository operations and security invariants. use nx9_wg_core::crypto::{hash_password, verify_password}; use nx9_wg_db::Store; #[tokio::test] async fn test_admin_single_identity_and_crud() { let store = Store::connect_in_memory().await.expect("connect"); store.migrate().await.expect("migrate"); // Initially no admin exists assert!(!store.admin_exists().await.expect("admin_exists")); assert!(store.get_admin().await.expect("get_admin").is_none()); // Create single admin with Argon2id hash let password = "CorrectHorseBatteryStaple123!"; let password_hash = hash_password(password).expect("hash password"); let admin = store .create_admin("admin", &password_hash) .await .expect("create_admin"); assert_eq!(admin.id, 1); assert_eq!(admin.username, "admin"); assert!(!admin.totp_enabled); assert!(admin.last_login_at.is_none()); // Verify admin_exists returns true assert!(store.admin_exists().await.expect("admin_exists")); // Verify lookup by username let fetched = store .get_admin_by_username("admin") .await .expect("get_admin_by_username") .expect("admin found"); assert_eq!(fetched.id, 1); assert!(verify_password(password, &fetched.password_hash).expect("verify password")); // Reject second admin creation let second_res = store.create_admin("admin2", "hash2").await; assert!(second_res.is_err(), "second admin must be rejected"); // Test password change let new_password = "NewSuperSecurePassword456!"; let new_hash = hash_password(new_password).expect("new hash"); store .update_admin_password(&new_hash) .await .expect("update_admin_password"); let updated = store.get_admin().await.expect("get_admin").expect("admin"); assert!(verify_password(new_password, &updated.password_hash).expect("verify new")); assert!(!verify_password(password, &updated.password_hash).expect("old password fails")); // Test TOTP update store .update_admin_totp(Some("JBSWY3DPEHPK3PXP"), true) .await .expect("update_admin_totp"); let totp_admin = store.get_admin().await.expect("get_admin").expect("admin"); assert!(totp_admin.totp_enabled); assert_eq!(totp_admin.totp_secret.as_deref(), Some("JBSWY3DPEHPK3PXP")); // Test recording login store .record_admin_login(Some("192.168.1.100")) .await .expect("record_admin_login"); let login_admin = store.get_admin().await.expect("get_admin").expect("admin"); assert!(login_admin.last_login_at.is_some()); assert_eq!(login_admin.last_login_ip.as_deref(), Some("192.168.1.100")); // Verify Debug formatting redacts password_hash and totp_secret let debug_str = format!("{:?}", login_admin); assert!(debug_str.contains("[REDACTED]")); assert!(!debug_str.contains(password)); assert!(!debug_str.contains(new_password)); assert!(!debug_str.contains("JBSWY3DPEHPK3PXP")); }