99using System . Diagnostics ;
1010using System . IO ;
1111using System . Linq ;
12+ using System . Reflection ;
1213using System . Text ;
1314using System . Threading . Tasks ;
1415using Windows . Security . Credentials ;
1516using Windows . Storage ;
1617
1718namespace Graph_Editor
1819{
20+ [ AttributeUsage ( AttributeTargets . Field ) ]
21+ public class SettingKeyAttribute : Attribute
22+ {
23+ public string Key { get ; }
24+
25+ public SettingKeyAttribute ( string key )
26+ {
27+ Key = key ;
28+ }
29+ }
30+
1931 public static class GraphEditorApplication
2032 {
33+ private const string MigrationCompletedFlagKey = "_SettingsMigrationToGuid_Completed" ;
2134 public readonly static int DefaultMaxExecutionRecordCount = 30 ;
2235
2336 public static void NavigateToMainEditor ( )
@@ -88,18 +101,136 @@ public static string RemoveProblematicCharacters(string Input)
88101 return temp ;
89102 }
90103
104+ private static string GetSettingKey ( Settings setting )
105+ {
106+ var fieldInfo = setting . GetType ( ) . GetField ( setting . ToString ( ) ) ;
107+ var attribute = fieldInfo ? . GetCustomAttribute < SettingKeyAttribute > ( ) ;
108+
109+ return attribute ? . Key ?? setting . ToString ( ) ;
110+ }
111+
112+ public static void MigrateAllSettingsToGuidKeys ( )
113+ {
114+ var localSettings = ApplicationData . Current . LocalSettings ;
115+
116+ if ( localSettings . Values . ContainsKey ( MigrationCompletedFlagKey ) )
117+ {
118+ return ;
119+ }
120+
121+ Debug . WriteLine ( "Starting settings migration to GUID keys..." ) ;
122+
123+ MigrateLocalSettings ( ) ;
124+ MigrateConfidentialSettings ( ) ;
125+
126+ localSettings . Values [ MigrationCompletedFlagKey ] = true ;
127+ Debug . WriteLine ( "Settings migration completed." ) ;
128+ }
129+
130+ private static void MigrateLocalSettings ( )
131+ {
132+ var localSettings = ApplicationData . Current . LocalSettings ;
133+
134+ foreach ( Settings setting in Enum . GetValues < Settings > ( ) )
135+ {
136+ try
137+ {
138+ string oldKey = setting . ToString ( ) ;
139+
140+ if ( oldKey . Contains ( "Password" ) )
141+ {
142+ continue ;
143+ }
144+
145+ string newKey = GetSettingKey ( setting ) ;
146+
147+ if ( oldKey == newKey || localSettings . Values . ContainsKey ( newKey ) )
148+ {
149+ continue ;
150+ }
151+
152+ if ( localSettings . Values . ContainsKey ( oldKey ) )
153+ {
154+ var value = localSettings . Values [ oldKey ] ;
155+ localSettings . Values [ newKey ] = value ;
156+ Debug . WriteLine ( $ "Migrated setting: { oldKey } -> { newKey } ") ;
157+ }
158+ }
159+ catch ( Exception ex )
160+ {
161+ Debug . WriteLine ( $ "Failed to migrate setting { setting } : { ex . Message } ") ;
162+ }
163+ }
164+ }
165+
166+ private static void MigrateConfidentialSettings ( )
167+ {
168+ var vault = new PasswordVault ( ) ;
169+
170+ foreach ( Settings setting in Enum . GetValues < Settings > ( ) )
171+ {
172+ if ( ! setting . ToString ( ) . Contains ( "Password" ) )
173+ {
174+ continue ;
175+ }
176+
177+ try
178+ {
179+ string oldKey = setting . ToString ( ) ;
180+ string newKey = GetSettingKey ( setting ) ;
181+
182+ if ( oldKey == newKey )
183+ {
184+ continue ;
185+ }
186+
187+ try
188+ {
189+ var existingNew = vault . Retrieve ( "Graph-Editor" , newKey ) ;
190+ if ( existingNew != null )
191+ {
192+ continue ;
193+ }
194+ }
195+ catch
196+ {
197+ }
198+
199+ try
200+ {
201+ var oldCredential = vault . Retrieve ( "Graph-Editor" , oldKey ) ;
202+ if ( oldCredential != null )
203+ {
204+ oldCredential . RetrievePassword ( ) ;
205+ vault . Add ( new PasswordCredential ( "Graph-Editor" , newKey , oldCredential . Password ) ) ;
206+ Debug . WriteLine ( $ "Migrated confidential setting: { oldKey } -> { newKey } ") ;
207+ }
208+ }
209+ catch
210+ {
211+ }
212+ }
213+ catch ( Exception ex )
214+ {
215+ Debug . WriteLine ( $ "Failed to migrate confidential setting { setting } : { ex . Message } ") ;
216+ }
217+ }
218+ }
219+
91220 public static T GetSetting < T > ( Settings Key , T DefaultValue )
92221 {
93- if ( string . IsNullOrEmpty ( Key . ToString ( ) ) ) {
222+ string settingKey = GetSettingKey ( Key ) ;
223+
224+ if ( string . IsNullOrEmpty ( settingKey ) ) {
94225 return DefaultValue ;
95226 }
96227
97228 try
98229 {
99230 var localSettings = ApplicationData . Current . LocalSettings ;
100- if ( localSettings . Values . ContainsKey ( Key . ToString ( ) ) )
231+ if ( localSettings . Values . ContainsKey ( settingKey ) )
101232 {
102- return ( T ) localSettings . Values [ Key . ToString ( ) ] ;
233+ return ( T ) localSettings . Values [ settingKey ] ;
103234 }
104235 else
105236 {
@@ -122,8 +253,9 @@ public static void SaveSetting(Settings Key, object Value)
122253 throw new Exception ( "Use SaveConfidentialSetting to save password." ) ;
123254 }
124255
256+ string settingKey = GetSettingKey ( Key ) ;
125257 var localSettings = ApplicationData . Current . LocalSettings ;
126- localSettings . Values [ Key . ToString ( ) ] = Value ;
258+ localSettings . Values [ settingKey ] = Value ;
127259 }
128260 catch
129261 {
@@ -134,10 +266,11 @@ public static void SaveSetting(Settings Key, object Value)
134266 public static string GetConfidentialSetting ( Settings Key , String DefaultValue )
135267 {
136268 var vault = new PasswordVault ( ) ;
269+ string settingKey = GetSettingKey ( Key ) ;
137270
138271 try
139272 {
140- var passwordCredential = vault . Retrieve ( "Graph-Editor" , Key . ToString ( ) ) ;
273+ var passwordCredential = vault . Retrieve ( "Graph-Editor" , settingKey ) ;
141274
142275 if ( passwordCredential != null )
143276 {
@@ -160,8 +293,9 @@ public static void SaveConfidentialSetting(Settings Key, string Value)
160293 {
161294 try
162295 {
296+ string settingKey = GetSettingKey ( Key ) ;
163297 var vault = new PasswordVault ( ) ;
164- vault . Add ( new PasswordCredential ( "Graph-Editor" , Key . ToString ( ) , Value ) ) ;
298+ vault . Add ( new PasswordCredential ( "Graph-Editor" , settingKey , Value ) ) ;
165299 }
166300 catch
167301 {
@@ -287,26 +421,88 @@ public static LanguageInfo[] SupportedLanguages
287421
288422 public enum Settings
289423 {
424+ /// <summary>Authentication Wizard: Previously used authentication flow</summary>
425+ [ SettingKey ( "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d" ) ]
290426 AccessTokenWizardMethodSelectionPage__RadioButtons_Method__SelectedIndex ,
427+
428+ /// <summary>Authentication Wizard: Previously used scopes</summary>
429+ [ SettingKey ( "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e" ) ]
291430 AccessTokenWizardBuiltInPage_LastSelectedScopes ,
431+
432+ /// <summary>Authentication Wizard: Previously used tenant name</summary>
433+ [ SettingKey ( "c3d4e5f6-a7b8-4c9d-0e1f-2a3b4c5d6e7f" ) ]
292434 AccessTokenWizardClientSecretPage__TextBox_TenantName__Text ,
435+
436+ /// <summary>Authentication Wizard: Previously used application ID</summary>
437+ [ SettingKey ( "d4e5f6a7-b8c9-4d0e-1f2a-3b4c5d6e7f8a" ) ]
293438 AccessTokenWizardClientSecretPage__TextBox_ApplicationId__Text ,
439+
440+ /// <summary>Authentication Wizard: Previously used client secret</summary>
441+ [ SettingKey ( "e5f6a7b8-c9d0-4e1f-2a3b-4c5d6e7f8a9b" ) ]
294442 AccessTokenWizardClientSecretPage__PasswordBox_ClientSecret__Password ,
443+
444+ /// <summary>Global Setting: Enable request/response logging</summary>
445+ [ SettingKey ( "f6a7b8c9-d0e1-4f2a-3b4c-5d6e7f8a9b0c" ) ]
295446 GlobalSetting_RequestAndResponseLoggingEnabled ,
447+
448+ /// <summary>Global Setting: Request/response log folder path</summary>
449+ [ SettingKey ( "a7b8c9d0-e1f2-4a3b-4c5d-6e7f8a9b0c1d" ) ]
296450 GlobalSetting_RequestAndResponseLoggingFolderPath ,
451+
452+ /// <summary>Global Setting: Request/response log retention days</summary>
453+ [ SettingKey ( "b8c9d0e1-f2a3-4b4c-5d6e-7f8a9b0c1d2e" ) ]
297454 GlobalSetting_RequestAndResponseLoggingRetentionDays ,
455+
456+ /// <summary>Global Setting: Disable logging when app restarts</summary>
457+ [ SettingKey ( "c9d0e1f2-a3b4-4c5d-6e7f-8a9b0c1d2e3f" ) ]
298458 GlobalSetting_DisableRequestAndResponseLoggingWhenAppRestart ,
459+
460+ /// <summary>Global Setting: Exclude Authorization header when logging</summary>
461+ [ SettingKey ( "d0e1f2a3-b4c5-4d6e-7f8a-9b0c1d2e3f4a" ) ]
299462 GlobalSetting_ExcludeAuthorizationHeader ,
463+
464+ /// <summary>Global Setting: Display language override</summary>
465+ [ SettingKey ( "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b" ) ]
300466 GlobalSetting_DisplayLanguageOverride ,
467+
468+ /// <summary>Global Setting: Maximum execution record count</summary>
469+ [ SettingKey ( "f2a3b4c5-d6e7-4f8a-9b0c-1d2e3f4a5b6c" ) ]
301470 GlobalSetting_MaxExecutionRecordCount ,
471+
472+ /// <summary>Global Setting: Encode plus character</summary>
473+ [ SettingKey ( "a3b4c5d6-e7f8-4a9b-0c1d-2e3f4a5b6c7d" ) ]
302474 GlobalSetting_EncodePlusCharacter ,
475+
476+ /// <summary>Global Setting: Encode sharp character</summary>
477+ [ SettingKey ( "b4c5d6e7-f8a9-4b0c-1d2e-3f4a5b6c7d8e" ) ]
303478 GlobalSetting_EncodeSharpCharacter ,
479+
480+ /// <summary>Global Setting: Request sending confirmation (GET)</summary>
481+ [ SettingKey ( "c5d6e7f8-a9b0-4c1d-2e3f-4a5b6c7d8e9f" ) ]
304482 GlobalSetting_RequestSendingConfirmation_GET ,
483+
484+ /// <summary>Global Setting: Request sending confirmation (POST)</summary>
485+ [ SettingKey ( "d6e7f8a9-b0c1-4d2e-3f4a-5b6c7d8e9f0a" ) ]
305486 GlobalSetting_RequestSendingConfirmation_POST ,
487+
488+ /// <summary>Global Setting: Request sending confirmation (PUT)</summary>
489+ [ SettingKey ( "e7f8a9b0-c1d2-4e3f-4a5b-6c7d8e9f0a1b" ) ]
306490 GlobalSetting_RequestSendingConfirmation_PUT ,
491+
492+ /// <summary>Global Setting: Request sending confirmation (PATCH)</summary>
493+ [ SettingKey ( "f8a9b0c1-d2e3-4f4a-5b6c-7d8e9f0a1b2c" ) ]
307494 GlobalSetting_RequestSendingConfirmation_PATCH ,
495+
496+ /// <summary>Global Setting: Request sending confirmation (DELETE)</summary>
497+ [ SettingKey ( "a9b0c1d2-e3f4-4a5b-6c7d-8e9f0a1b2c3d" ) ]
308498 GlobalSetting_RequestSendingConfirmation_DELETE ,
499+
500+ /// <summary>Global Setting: Custom scopes</summary>
501+ [ SettingKey ( "b0c1d2e3-f4a5-4b6c-7d8e-9f0a1b2c3d4e" ) ]
309502 GlobalSetting_CustomScopes ,
503+
504+ /// <summary>Main Editor: Allow automatic redirect</summary>
505+ [ SettingKey ( "c1d2e3f4-a5b6-4c7d-8e9f-0a1b2c3d4e5f" ) ]
310506 MainEditorLoggingHandler_AllowAutoRedirect
311507 }
312508 }
0 commit comments