@ -1,6 +1,7 @@ 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					use   std ::env ::consts ::EXE_SUFFIX ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					use   std ::{ env ::consts ::EXE_SUFFIX ,   collections ::HashMap } ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					use   std ::process ::exit ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					use   std ::sync ::RwLock ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					use   std ::sync ::OnceLock ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					use   job_scheduler_ng ::Schedule ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					use   once_cell ::sync ::Lazy ;  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -47,6 +48,10 @@ macro_rules! make_config { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             _usr : ConfigBuilder ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             _overrides : Vec < String > ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             domain_hostmap : OnceLock < HostHashMap > ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             domain_origins : OnceLock < HostHashMap > ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             domain_paths : OnceLock < HostHashMap > ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         #[ derive(Clone, Default, Deserialize, Serialize) ]  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -135,13 +140,20 @@ macro_rules! make_config { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             fn  build ( & self )   -> ConfigItems   {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 let   mut   config   =   ConfigItems ::default ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 let   _domain_set   =   self . domain . is_some ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 let   _domain_set   =   self . domain_change_back  . is_some ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 $( $(  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                     config . $name   =   make_config ! {   @ build   self . $name . clone ( ) ,   & config ,   $none_action ,   $( $default ) ?   } ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 ) + ) +  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 config . domain_set   =   _domain_set ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 config . domain   =   config . domain . trim_end_matches ( '/' ) . to_string ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 config . domain_change_back   =   config . domain_change_back . split ( ',' ) . map ( | d |   d . trim_end_matches ( '/' ) ) . fold ( String ::new ( ) ,   | acc ,   d |   {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                     acc . push_str ( d ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                     acc . push ( ',' ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                     acc  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 } ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 // Remove trailing comma
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 config . domain_change_back . pop ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 config . signups_domains_whitelist   =   config . signups_domains_whitelist . trim ( ) . to_lowercase ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 config . org_creation_users   =   config . org_creation_users . trim ( ) . to_lowercase ( ) ;  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -335,6 +347,8 @@ macro_rules! make_config { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					type  HostHashMap   =   HashMap < String ,   String > ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					//STRUCTURE:
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					// /// Short description (without this they won't appear on the list)
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					// group {
  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -414,15 +428,15 @@ make_config! { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     /// General settings
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     settings   {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         /// Domain URL |> This needs to be set to the URL used to access the server, including 'http[s]://'
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         /// and port, if it's different than the default. Some server functions don't work correctly without this value
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         domain :                 String ,   true ,     def ,      "http://localhost" . to_string ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         /// Comma seperated list of Domain URLs |> This needs to be set to the URL used to access the server, including
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         /// 'http[s]://' and port, if it's different than the default. Some server functions don't work correctly without this value
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         // TODO: Change back, this is only done to break existing references
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         domain_change_back :                 String ,   true ,     def ,      "http://localhost" . to_string ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         /// Domain Set |> Indicates if the domain is set by the admin. Otherwise the default will be used.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         domain_set :             bool ,     false ,    def ,      false ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         /// Domain origin |> Domain URL origin (in https://example.com:8443/path, https://example.com:8443 is the origin)
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         domain_origin :          String ,   false ,    auto ,     | c |   extract_url_origin ( & c . domain ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         /// Domain path |> Domain URL path (in https://example.com:8443/path, /path is the path)
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         domain_path :            String ,   false ,    auto ,     | c |   extract_url_path ( & c . domain ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         /// MUST be the same for all domains.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         domain_path :            String ,   false ,    auto ,     | c |   extract_url_path ( & c . domain_change_back . split ( ',' ) . nth ( 0 ) . expect ( "Missing domain" ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         /// Enable web vault
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         web_vault_enabled :      bool ,     false ,    def ,      true ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -667,7 +681,7 @@ make_config! { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         /// Embed images as email attachments.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         smtp_embed_images :             bool ,   true ,   def ,   true ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         /// _smtp_img_src
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         _smtp_img_src :                 String ,   false ,   gen ,   | c |   generate_smtp_img_src ( c . smtp_embed_images ,   & c . domain ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         _smtp_img_src :                 String ,   false ,   gen ,   | c |   generate_smtp_img_src ( c . smtp_embed_images ,   & c . domain_change_back  ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         /// Enable SMTP debugging (Know the risks!) |> DANGEROUS: Enabling this will output very detailed SMTP messages. This could contain sensitive information like passwords and usernames! Only enable this during troubleshooting!
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         smtp_debug :                    bool ,     false ,    def ,       false ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         /// Accept Invalid Certs (Know the risks!) |> DANGEROUS: Allow invalid certificates. This option introduces significant vulnerabilities to man-in-the-middle attacks!
  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -1010,10 +1024,33 @@ fn extract_url_path(url: &str) -> String { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					fn  generate_smtp_img_src ( embed_images : bool ,   domain : & str )   -> String  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					/// Extracts host part from a URL.
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					pub   fn  extract_url_host ( url : & str )   -> String  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     match   Url ::parse ( url )   {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         Ok ( u )   = >   {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             let   Some ( mut   host )   =   u . host_str ( ) . map ( | s |   s . to_string ( ) )   else   {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 println ! ( "Domain does not contain host!" ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 return   String ::new ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             } ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             if   let   Some ( port )   =   u . port ( ) . map ( | p |   p . to_string ( ) )   {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 host . push_str ( & port ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             host  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         Err ( _ )   = >   {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             // we already print it in the method above, no need to do it again
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             String ::new ( )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					fn  generate_smtp_img_src ( embed_images : bool ,   domains : & str )   -> String  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     if   embed_images   {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         "cid:" . to_string ( )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     }   else   {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         let   domain   =   domains . split ( ',' ) . nth ( 0 ) . expect ( "Domain missing" ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         format ! ( "{domain}/vw_static/" )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					}  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -1082,6 +1119,9 @@ impl Config { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 _env ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 _usr ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 _overrides ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 domain_origins : OnceLock ::new ( ) ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 domain_paths : OnceLock ::new ( ) ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 domain_hostmap : OnceLock ::new ( ) ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             } ) ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         } )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     }  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -1249,6 +1289,36 @@ impl Config { 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     pub   fn  domain_origin ( & self ,   host : & str )   -> Option < String >   {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         // This is done to prevent deadlock, when read-locking an rwlock twice
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         let   domains   =   self . domain_change_back ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         self . inner . read ( ) . unwrap ( ) . domain_origins . get_or_init ( | |   {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             domains . split ( ',' )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 . map ( | d |   {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                     ( extract_url_host ( d ) ,   extract_url_origin ( d ) )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 } )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 . collect ( )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         } ) . get ( host ) . map ( | h |   h . clone ( ) )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     pub   fn  host_to_domain ( & self ,   host : & str )   -> Option < String >   {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         // This is done to prevent deadlock, when read-locking an rwlock twice
  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         let   domains   =   self . domain_change_back ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         self . inner . read ( ) . unwrap ( ) . domain_hostmap . get_or_init ( | |   {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             domains . split ( ',' )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 . map ( | d |   {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                     ( extract_url_host ( d ) ,   extract_url_path ( d ) )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 } )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                 . collect ( )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         } ) . get ( host ) . map ( | h |   h . clone ( ) )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     pub   fn  main_domain ( & self )   -> String  {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         self . domain_change_back ( ) . split ( ',' ) . nth ( 0 ) . expect ( "Missing domain" ) . to_string ( )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					use   handlebars ::{