@@ -556,8 +556,10 @@ pub struct SecurityConfig {
556556
557557/// Defines an allowlist type.
558558pub trait Allowlist {
559+ /// Returns all features associated with the allowlist struct.
560+ fn all_features ( ) -> Vec < & ' static str > ;
559561 /// Returns the tauri features enabled on this allowlist.
560- fn to_features ( & self ) -> Vec < & str > ;
562+ fn to_features ( & self ) -> Vec < & ' static str > ;
561563}
562564
563565macro_rules! check_feature {
@@ -568,11 +570,29 @@ macro_rules! check_feature {
568570 } ;
569571}
570572
573+ /// Filesystem API scope definition.
574+ /// It is a list of glob patterns that restrict the filesystem API access from the webview.
575+ /// Each pattern can start with a variable that resolves to a system base directory.
576+ /// The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`,
577+ /// `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`,
578+ /// `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$CWD`.
579+ #[ derive( Debug , PartialEq , Clone , Deserialize , Serialize ) ]
580+ #[ cfg_attr( feature = "schema" , derive( JsonSchema ) ) ]
581+ pub struct FsAllowlistScope ( pub Vec < PathBuf > ) ;
582+
583+ impl Default for FsAllowlistScope {
584+ fn default ( ) -> Self {
585+ Self ( vec ! [ "$APP/**" . into( ) ] )
586+ }
587+ }
588+
571589/// Allowlist for the file system APIs.
572590#[ derive( Debug , Default , PartialEq , Clone , Deserialize , Serialize ) ]
573591#[ cfg_attr( feature = "schema" , derive( JsonSchema ) ) ]
574592#[ serde( rename_all = "camelCase" , deny_unknown_fields) ]
575593pub struct FsAllowlistConfig {
594+ /// The access scope for the filesystem APIs.
595+ pub scope : FsAllowlistScope ,
576596 /// Use this flag to enable all file system API features.
577597 #[ serde( default ) ]
578598 pub all : bool ,
@@ -609,7 +629,27 @@ pub struct FsAllowlistConfig {
609629}
610630
611631impl Allowlist for FsAllowlistConfig {
612- fn to_features ( & self ) -> Vec < & str > {
632+ fn all_features ( ) -> Vec < & ' static str > {
633+ let allowlist = Self {
634+ scope : Default :: default ( ) ,
635+ all : false ,
636+ read_text_file : true ,
637+ read_binary_file : true ,
638+ write_file : true ,
639+ write_binary_file : true ,
640+ read_dir : true ,
641+ copy_file : true ,
642+ create_dir : true ,
643+ remove_dir : true ,
644+ remove_file : true ,
645+ rename_file : true ,
646+ } ;
647+ let mut features = allowlist. to_features ( ) ;
648+ features. push ( "fs-all" ) ;
649+ features
650+ }
651+
652+ fn to_features ( & self ) -> Vec < & ' static str > {
613653 if self . all {
614654 vec ! [ "fs-all" ]
615655 } else {
@@ -643,7 +683,17 @@ pub struct WindowAllowlistConfig {
643683}
644684
645685impl Allowlist for WindowAllowlistConfig {
646- fn to_features ( & self ) -> Vec < & str > {
686+ fn all_features ( ) -> Vec < & ' static str > {
687+ let allowlist = Self {
688+ all : false ,
689+ create : true ,
690+ } ;
691+ let mut features = allowlist. to_features ( ) ;
692+ features. push ( "window-all" ) ;
693+ features
694+ }
695+
696+ fn to_features ( & self ) -> Vec < & ' static str > {
647697 if self . all {
648698 vec ! [ "window-all" ]
649699 } else {
@@ -671,7 +721,18 @@ pub struct ShellAllowlistConfig {
671721}
672722
673723impl Allowlist for ShellAllowlistConfig {
674- fn to_features ( & self ) -> Vec < & str > {
724+ fn all_features ( ) -> Vec < & ' static str > {
725+ let allowlist = Self {
726+ all : false ,
727+ execute : true ,
728+ open : true ,
729+ } ;
730+ let mut features = allowlist. to_features ( ) ;
731+ features. push ( "shell-all" ) ;
732+ features
733+ }
734+
735+ fn to_features ( & self ) -> Vec < & ' static str > {
675736 if self . all {
676737 vec ! [ "shell-all" ]
677738 } else {
@@ -700,7 +761,18 @@ pub struct DialogAllowlistConfig {
700761}
701762
702763impl Allowlist for DialogAllowlistConfig {
703- fn to_features ( & self ) -> Vec < & str > {
764+ fn all_features ( ) -> Vec < & ' static str > {
765+ let allowlist = Self {
766+ all : false ,
767+ open : true ,
768+ save : true ,
769+ } ;
770+ let mut features = allowlist. to_features ( ) ;
771+ features. push ( "dialog-all" ) ;
772+ features
773+ }
774+
775+ fn to_features ( & self ) -> Vec < & ' static str > {
704776 if self . all {
705777 vec ! [ "dialog-all" ]
706778 } else {
@@ -726,7 +798,17 @@ pub struct HttpAllowlistConfig {
726798}
727799
728800impl Allowlist for HttpAllowlistConfig {
729- fn to_features ( & self ) -> Vec < & str > {
801+ fn all_features ( ) -> Vec < & ' static str > {
802+ let allowlist = Self {
803+ all : false ,
804+ request : true ,
805+ } ;
806+ let mut features = allowlist. to_features ( ) ;
807+ features. push ( "http-all" ) ;
808+ features
809+ }
810+
811+ fn to_features ( & self ) -> Vec < & ' static str > {
730812 if self . all {
731813 vec ! [ "http-all" ]
732814 } else {
@@ -748,7 +830,14 @@ pub struct NotificationAllowlistConfig {
748830}
749831
750832impl Allowlist for NotificationAllowlistConfig {
751- fn to_features ( & self ) -> Vec < & str > {
833+ fn all_features ( ) -> Vec < & ' static str > {
834+ let allowlist = Self { all : false } ;
835+ let mut features = allowlist. to_features ( ) ;
836+ features. push ( "notification-all" ) ;
837+ features
838+ }
839+
840+ fn to_features ( & self ) -> Vec < & ' static str > {
752841 if self . all {
753842 vec ! [ "notification-all" ]
754843 } else {
@@ -768,7 +857,14 @@ pub struct GlobalShortcutAllowlistConfig {
768857}
769858
770859impl Allowlist for GlobalShortcutAllowlistConfig {
771- fn to_features ( & self ) -> Vec < & str > {
860+ fn all_features ( ) -> Vec < & ' static str > {
861+ let allowlist = Self { all : false } ;
862+ let mut features = allowlist. to_features ( ) ;
863+ features. push ( "global-shortcut-all" ) ;
864+ features
865+ }
866+
867+ fn to_features ( & self ) -> Vec < & ' static str > {
772868 if self . all {
773869 vec ! [ "global-shortcut-all" ]
774870 } else {
@@ -788,7 +884,14 @@ pub struct OsAllowlistConfig {
788884}
789885
790886impl Allowlist for OsAllowlistConfig {
791- fn to_features ( & self ) -> Vec < & str > {
887+ fn all_features ( ) -> Vec < & ' static str > {
888+ let allowlist = Self { all : false } ;
889+ let mut features = allowlist. to_features ( ) ;
890+ features. push ( "os-all" ) ;
891+ features
892+ }
893+
894+ fn to_features ( & self ) -> Vec < & ' static str > {
792895 if self . all {
793896 vec ! [ "os-all" ]
794897 } else {
@@ -808,7 +911,14 @@ pub struct PathAllowlistConfig {
808911}
809912
810913impl Allowlist for PathAllowlistConfig {
811- fn to_features ( & self ) -> Vec < & str > {
914+ fn all_features ( ) -> Vec < & ' static str > {
915+ let allowlist = Self { all : false } ;
916+ let mut features = allowlist. to_features ( ) ;
917+ features. push ( "path-all" ) ;
918+ features
919+ }
920+
921+ fn to_features ( & self ) -> Vec < & ' static str > {
812922 if self . all {
813923 vec ! [ "path-all" ]
814924 } else {
@@ -817,6 +927,44 @@ impl Allowlist for PathAllowlistConfig {
817927 }
818928}
819929
930+ /// Allowlist for the custom protocols.
931+ #[ derive( Debug , Default , PartialEq , Clone , Deserialize , Serialize ) ]
932+ #[ cfg_attr( feature = "schema" , derive( JsonSchema ) ) ]
933+ #[ serde( rename_all = "camelCase" , deny_unknown_fields) ]
934+ pub struct ProtocolAllowlistConfig {
935+ /// The access scope for the asset protocol.
936+ pub asset_scope : FsAllowlistScope ,
937+ /// Use this flag to enable all custom protocols.
938+ #[ serde( default ) ]
939+ pub all : bool ,
940+ /// Enables the asset protocol.
941+ #[ serde( default ) ]
942+ pub asset : bool ,
943+ }
944+
945+ impl Allowlist for ProtocolAllowlistConfig {
946+ fn all_features ( ) -> Vec < & ' static str > {
947+ let allowlist = Self {
948+ asset_scope : Default :: default ( ) ,
949+ all : false ,
950+ asset : true ,
951+ } ;
952+ let mut features = allowlist. to_features ( ) ;
953+ features. push ( "protocol-all" ) ;
954+ features
955+ }
956+
957+ fn to_features ( & self ) -> Vec < & ' static str > {
958+ if self . all {
959+ vec ! [ "protocol-all" ]
960+ } else {
961+ let mut features = Vec :: new ( ) ;
962+ check_feature ! ( self , features, asset, "protocol-asset" ) ;
963+ features
964+ }
965+ }
966+ }
967+
820968/// Allowlist configuration.
821969#[ derive( Debug , Default , PartialEq , Clone , Deserialize , Serialize ) ]
822970#[ cfg_attr( feature = "schema" , derive( JsonSchema ) ) ]
@@ -852,10 +1000,28 @@ pub struct AllowlistConfig {
8521000 /// Path API allowlist.
8531001 #[ serde( default ) ]
8541002 pub path : PathAllowlistConfig ,
1003+ /// Custom protocol allowlist.
1004+ #[ serde( default ) ]
1005+ pub protocol : ProtocolAllowlistConfig ,
8551006}
8561007
8571008impl Allowlist for AllowlistConfig {
858- fn to_features ( & self ) -> Vec < & str > {
1009+ fn all_features ( ) -> Vec < & ' static str > {
1010+ let mut features = Vec :: new ( ) ;
1011+ features. extend ( FsAllowlistConfig :: all_features ( ) ) ;
1012+ features. extend ( WindowAllowlistConfig :: all_features ( ) ) ;
1013+ features. extend ( ShellAllowlistConfig :: all_features ( ) ) ;
1014+ features. extend ( DialogAllowlistConfig :: all_features ( ) ) ;
1015+ features. extend ( HttpAllowlistConfig :: all_features ( ) ) ;
1016+ features. extend ( NotificationAllowlistConfig :: all_features ( ) ) ;
1017+ features. extend ( GlobalShortcutAllowlistConfig :: all_features ( ) ) ;
1018+ features. extend ( OsAllowlistConfig :: all_features ( ) ) ;
1019+ features. extend ( PathAllowlistConfig :: all_features ( ) ) ;
1020+ features. extend ( ProtocolAllowlistConfig :: all_features ( ) ) ;
1021+ features
1022+ }
1023+
1024+ fn to_features ( & self ) -> Vec < & ' static str > {
8591025 if self . all {
8601026 vec ! [ "api-all" ]
8611027 } else {
@@ -869,6 +1035,7 @@ impl Allowlist for AllowlistConfig {
8691035 features. extend ( self . global_shortcut . to_features ( ) ) ;
8701036 features. extend ( self . os . to_features ( ) ) ;
8711037 features. extend ( self . path . to_features ( ) ) ;
1038+ features. extend ( self . protocol . to_features ( ) ) ;
8721039 features
8731040 }
8741041 }
@@ -1616,6 +1783,37 @@ mod build {
16161783 }
16171784 }
16181785
1786+ impl ToTokens for FsAllowlistScope {
1787+ fn to_tokens ( & self , tokens : & mut TokenStream ) {
1788+ let allowed_paths = vec_lit ( & self . 0 , path_buf_lit) ;
1789+ tokens. append_all ( quote ! { :: tauri:: utils:: config:: FsAllowlistScope ( #allowed_paths) } )
1790+ }
1791+ }
1792+
1793+ impl ToTokens for FsAllowlistConfig {
1794+ fn to_tokens ( & self , tokens : & mut TokenStream ) {
1795+ let scope = & self . scope ;
1796+ tokens. append_all ( quote ! { :: tauri:: utils:: config:: FsAllowlistConfig { scope: #scope, ..Default :: default ( ) } } )
1797+ }
1798+ }
1799+
1800+ impl ToTokens for ProtocolAllowlistConfig {
1801+ fn to_tokens ( & self , tokens : & mut TokenStream ) {
1802+ let asset_scope = & self . asset_scope ;
1803+ tokens. append_all ( quote ! { :: tauri:: utils:: config:: ProtocolAllowlistConfig { asset_scope: #asset_scope, ..Default :: default ( ) } } )
1804+ }
1805+ }
1806+
1807+ impl ToTokens for AllowlistConfig {
1808+ fn to_tokens ( & self , tokens : & mut TokenStream ) {
1809+ let fs = & self . fs ;
1810+ let protocol = & self . protocol ;
1811+ tokens. append_all (
1812+ quote ! { :: tauri:: utils:: config:: AllowlistConfig { fs: #fs, protocol: #protocol, ..Default :: default ( ) } } ,
1813+ )
1814+ }
1815+ }
1816+
16191817 impl ToTokens for TauriConfig {
16201818 fn to_tokens ( & self , tokens : & mut TokenStream ) {
16211819 let windows = vec_lit ( & self . windows , identity) ;
@@ -1624,7 +1822,7 @@ mod build {
16241822 let updater = & self . updater ;
16251823 let security = & self . security ;
16261824 let system_tray = opt_lit ( self . system_tray . as_ref ( ) ) ;
1627- let allowlist = quote ! ( Default :: default ( ) ) ;
1825+ let allowlist = & self . allowlist ;
16281826 let macos_private_api = self . macos_private_api ;
16291827
16301828 literal_struct ! (
0 commit comments