@@ -715,12 +715,8 @@ fn managed_client_name_for_expiration(row: &PeerRow) -> Option<&str> {
715715 return None ;
716716 }
717717 let config_name = row. config_name . as_deref ( ) ?;
718- let ( interface_name, filename_client_name) = config_name. rsplit_once ( "-client-" ) ?;
719718 let friendly_name = row. friendly_name . as_deref ( ) ?;
720- ( !interface_name. is_empty ( )
721- && filename_client_name == friendly_name
722- && crate :: admin:: script_bridge:: validate_client_name ( friendly_name) . is_ok ( ) )
723- . then_some ( friendly_name)
719+ crate :: admin:: script_bridge:: managed_client_name_from_config ( config_name, friendly_name)
724720 } )
725721}
726722
@@ -6108,6 +6104,78 @@ mod tests {
61086104 assert_eq ! ( row. managed_client_name. as_deref( ) , Some ( "alice" ) ) ;
61096105 }
61106106
6107+ #[ tokio:: test]
6108+ async fn expiration_edits_use_stable_identity_during_config_remap ( ) {
6109+ let db = test_db ( ) . await ;
6110+ let api_id = insert_peer ( & db, "EXPIRY_REMAP_API_KEY=" , Some ( "Alice" ) ) . await ;
6111+ crate :: db:: peers:: apply_config_mapping (
6112+ & db. pool ,
6113+ "EXPIRY_REMAP_API_KEY=" ,
6114+ "awg0-client-alice" ,
6115+ "/etc/amnezia/amneziawg/clients/awg0-client-alice.conf" ,
6116+ "alice" ,
6117+ Some ( "alice" ) ,
6118+ )
6119+ . await
6120+ . unwrap ( ) ;
6121+ crate :: db:: peers:: clear_all_config_mappings ( & db. pool )
6122+ . await
6123+ . unwrap ( ) ;
6124+
6125+ let html_id = insert_peer ( & db, "EXPIRY_REMAP_HTML_KEY=" , Some ( "Bob" ) ) . await ;
6126+ crate :: db:: peers:: apply_config_mapping (
6127+ & db. pool ,
6128+ "EXPIRY_REMAP_HTML_KEY=" ,
6129+ "awg0-client-bob" ,
6130+ "/etc/amnezia/amneziawg/clients/awg0-client-bob.conf" ,
6131+ "bob" ,
6132+ Some ( "bob" ) ,
6133+ )
6134+ . await
6135+ . unwrap ( ) ;
6136+ crate :: db:: peers:: clear_all_config_mappings ( & db. pool )
6137+ . await
6138+ . unwrap ( ) ;
6139+
6140+ let app = test_router ( db. clone ( ) ) ;
6141+ let response = app
6142+ . clone ( )
6143+ . oneshot (
6144+ Request :: builder ( )
6145+ . method ( "PATCH" )
6146+ . uri ( format ! ( "/api/peers/{api_id}" ) )
6147+ . header ( "content-type" , "application/json" )
6148+ . body ( Body :: from ( r#"{"expiration_days":7}"# ) )
6149+ . unwrap ( ) ,
6150+ )
6151+ . await
6152+ . unwrap ( ) ;
6153+ assert_eq ! ( response. status( ) , StatusCode :: OK ) ;
6154+
6155+ let response = app
6156+ . oneshot (
6157+ Request :: builder ( )
6158+ . method ( "POST" )
6159+ . uri ( format ! ( "/peers/{html_id}" ) )
6160+ . header ( "content-type" , "application/x-www-form-urlencoded" )
6161+ . body ( Body :: from ( "display_name=Bob&comment=&expiration_days=7" ) )
6162+ . unwrap ( ) ,
6163+ )
6164+ . await
6165+ . unwrap ( ) ;
6166+ assert_eq ! ( response. status( ) , StatusCode :: SEE_OTHER ) ;
6167+
6168+ for ( id, expected_name) in [ ( api_id, "alice" ) , ( html_id, "bob" ) ] {
6169+ let row = crate :: db:: peers:: find_by_id ( & db. pool , id)
6170+ . await
6171+ . unwrap ( )
6172+ . unwrap ( ) ;
6173+ assert_eq ! ( row. has_config, 0 ) ;
6174+ assert_eq ! ( row. managed_client_name. as_deref( ) , Some ( expected_name) ) ;
6175+ assert ! ( row. expires_at. is_some( ) ) ;
6176+ }
6177+ }
6178+
61116179 #[ tokio:: test]
61126180 async fn patch_peer_rejects_expiration_for_unmanaged_peer ( ) {
61136181 let db = test_db ( ) . await ;
@@ -7314,6 +7382,7 @@ mod tests {
73147382 "test-client" ,
73157383 conf_path. to_str ( ) . unwrap ( ) ,
73167384 "test-client" ,
7385+ None ,
73177386 )
73187387 . await
73197388 . unwrap ( ) ;
@@ -7732,6 +7801,7 @@ mod tests {
77327801 "existing-client" ,
77337802 "/etc/amnezia/amneziawg/existing-client.conf" ,
77347803 "existing-client" ,
7804+ None ,
77357805 )
77367806 . await
77377807 . unwrap( ) ) ;
@@ -7757,6 +7827,7 @@ mod tests {
77577827 "test-dl" ,
77587828 "/etc/awg/test-dl.conf" ,
77597829 "test-dl" ,
7830+ None ,
77607831 )
77617832 . await
77627833 . unwrap ( ) ;
@@ -8602,6 +8673,7 @@ mod tests {
86028673 "test-qr" ,
86038674 conf_path. to_str ( ) . unwrap ( ) ,
86048675 "test-qr" ,
8676+ None ,
86058677 )
86068678 . await
86078679 . unwrap ( ) ;
@@ -8664,6 +8736,7 @@ mod tests {
86648736 "big-qr" ,
86658737 conf_path. to_str ( ) . unwrap ( ) ,
86668738 "big-qr" ,
8739+ None ,
86678740 )
86688741 . await
86698742 . unwrap ( ) ;
@@ -8713,6 +8786,7 @@ mod tests {
87138786 "test-qrui" ,
87148787 "/etc/awg/test-qrui.conf" ,
87158788 "test-qrui" ,
8789+ None ,
87168790 )
87178791 . await
87188792 . unwrap ( ) ;
@@ -8822,6 +8896,7 @@ mod tests {
88228896 "escaped" ,
88238897 outside_conf. to_str ( ) . unwrap ( ) ,
88248898 "escaped" ,
8899+ None ,
88258900 )
88268901 . await
88278902 . unwrap ( ) ;
@@ -8859,6 +8934,7 @@ mod tests {
88598934 "escaped-qr" ,
88608935 outside_conf. to_str ( ) . unwrap ( ) ,
88618936 "escaped-qr" ,
8937+ None ,
88628938 )
88638939 . await
88648940 . unwrap ( ) ;
@@ -8900,6 +8976,7 @@ mod tests {
89008976 "link" ,
89018977 link_conf. to_str ( ) . unwrap ( ) ,
89028978 "link" ,
8979+ None ,
89038980 )
89048981 . await
89058982 . unwrap ( ) ;
@@ -8939,6 +9016,7 @@ mod tests {
89399016 "link-qr" ,
89409017 link_conf. to_str ( ) . unwrap ( ) ,
89419018 "link-qr" ,
9019+ None ,
89429020 )
89439021 . await
89449022 . unwrap ( ) ;
0 commit comments