diff --git a/.gitignore b/.gitignore
index 8f23f904..8baa2e72 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,6 +23,7 @@ package-lock.json
data/
appsettings.*.json
appsettings-*.*.json
+*-settings.json
generated/
*.tmp
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 3c7324c3..05251ded 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -5,97 +5,17 @@
"version": "0.2.0",
"configurations": [
{
- "name": ".NET API",
- "type": "coreclr",
- "request": "launch",
- "program": "${workspaceFolder}/src/Api/bin/Debug/net10.0/Api.dll",
- "args": [],
- "cwd": "${workspaceFolder}/src/Api",
- "serverReadyAction": {
- "pattern": "\\bNow listening on:\\s+(https?://\\S+)"
- },
- "env": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- },
- "envFile": "${workspaceFolder}/src/Api/.env"
- },
- {
- "name": "C#: API Debug",
+ "name": "API",
"type": "dotnet",
"request": "launch",
"projectPath": "${workspaceFolder}/src/Api/Api.csproj"
},
{
- "name": "Blogs",
- "type": "coreclr",
- "request": "launch",
- "preLaunchTask": "build",
- "program": "${workspaceFolder}/src/Yavsc.Blogs/bin/Debug/net10.0/Yavsc.Blogs.dll",
- "args": [],
- "cwd": "${workspaceFolder}/src/Yavsc.Blogs/",
- "stopAtEntry": false,
- "serverReadyAction": {
- "action": "openExternally",
- "pattern": "\\bNow listening on:\\s+(https?://\\S+)"
- },
- "env": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- }
- },
- {
- "name": "C#: Yavsc.Org Debug",
+ "name": "Yavsc.Org",
"type": "dotnet",
"request": "launch",
"projectPath": "${workspaceFolder}/src/Yavsc.Org/Yavsc.Org.csproj"
},
- {
- "name": "Web",
- "type": "coreclr",
- "request": "launch",
- "preLaunchTask": "build-web",
- "program": "${workspaceFolder}/src/Yavsc.Web/bin/Debug/net10.0/Yavsc.Web.dll",
- "args": [],
- "cwd": "${workspaceFolder}/src/Yavsc.Web",
- "stopAtEntry": false,
- "serverReadyAction": {
- "action": "openExternally",
- "pattern": "\\bNow listening on:\\s+(https?://\\S+)"
- },
- "env": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- }
- },
- {
- "name": "cli",
- "type": "coreclr",
- "request": "launch",
- "preLaunchTask": "build",
- "program": "${workspaceFolder}/src/cli/bin/Debug/net10.0/cli.dll",
- "args": [],
- "cwd": "${workspaceFolder}",
- "stopAtEntry": false,
- "console": "internalConsole"
- },
- {
- "name": "Web",
- "type": "coreclr",
- "request": "launch",
- "preLaunchTask": "build",
- "program": "${workspaceFolder}/src/Yavsc.Web/bin/Debug/net10.0/Yavsc.Web.dll",
- "args": [],
- "cwd": "${workspaceFolder}/src/Yavsc.Web",
- "stopAtEntry": false,
- "serverReadyAction": {
- "action": "openExternally",
- "pattern": "\\bNow listening on:\\s+(https?://\\S+)"
- },
- "env": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- },
- "sourceFileMap": {
- "/Views": "${workspaceFolder}/src/Yavsc.Web/Views"
- }
- },
{
"name": "PostIt",
"type": "dotnet",
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 756fef9b..728a2954 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -13,6 +13,7 @@
"envsubst",
"Newtonsoft",
"Npgsql",
+ "postit",
"pschneider",
"SLNDIR",
"validable",
diff --git a/src/PostIt/PostIt/PostIt.csproj b/src/PostIt/PostIt/PostIt.csproj
index 9fee58a3..8cf9465c 100644
--- a/src/PostIt/PostIt/PostIt.csproj
+++ b/src/PostIt/PostIt/PostIt.csproj
@@ -22,8 +22,8 @@
-
+
PreserveNewest
-
\ No newline at end of file
+
diff --git a/src/PostIt/PostIt/Settings/Settings.cs b/src/PostIt/PostIt/Settings/Settings.cs
index 1064004c..3996b540 100644
--- a/src/PostIt/PostIt/Settings/Settings.cs
+++ b/src/PostIt/PostIt/Settings/Settings.cs
@@ -12,7 +12,7 @@ namespace PostIt;
public partial class Settings : ObservableObject
{
- const string SettingsFileName = "settings.json";
+ const string SettingsFileName = "postit-settings.json";
IStorageFolder? folder = null;
[ObservableProperty]
@@ -42,8 +42,13 @@ public partial class Settings : ObservableObject
internal async Task Load()
{
- String configPath =
- Path.Combine(AppContext.BaseDirectory, SettingsFileName);
+ string configDir = Path.Combine(
+ Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
+ "PostIt"
+);
+ Directory.CreateDirectory(configDir);
+
+ string configPath = Path.Combine(configDir, SettingsFileName);
FileInfo configFileInfo = new FileInfo(configPath);
diff --git a/src/PostIt/PostIt/ViewLocator.cs b/src/PostIt/PostIt/ViewLocator.cs
index 38f2b3fe..c6b66dfa 100644
--- a/src/PostIt/PostIt/ViewLocator.cs
+++ b/src/PostIt/PostIt/ViewLocator.cs
@@ -27,6 +27,7 @@ public class ViewLocator : IDataTemplate
{
MainPageViewModel => _services.GetRequiredService(),
SettingsPageViewModel => _services.GetRequiredService(),
+ LoginPageViewModel => _services.GetRequiredService(),
_ => new TextBlock { Text = $"No view for {data.GetType().Name}" }
};
}
diff --git a/src/PostIt/PostIt/ViewModels/LoginPageViewModel.cs b/src/PostIt/PostIt/ViewModels/LoginPageViewModel.cs
new file mode 100644
index 00000000..4fb25097
--- /dev/null
+++ b/src/PostIt/PostIt/ViewModels/LoginPageViewModel.cs
@@ -0,0 +1,67 @@
+using CommunityToolkit.Mvvm.Input;
+using IdentityModel.OidcClient;
+using System;
+using System.Threading.Tasks;
+
+namespace PostIt.ViewModels;
+
+public partial class LoginPageViewModel : ViewModelBase
+{
+ public string UserEmail { get; set; }
+ public string Password { get; set; }
+
+ private string _AccessToken;
+ public string AccessToken { get => _AccessToken; private set => this.SetProperty(ref _AccessToken, value); }
+
+ public bool RememberMe { get; set; }
+ public override bool CanNavigateNext { get => false; protected set => throw new System.NotImplementedException(); }
+ public override bool CanNavigatePrevious { get => true; protected set => throw new System.NotImplementedException(); }
+
+ public Settings Settings { get; }
+
+ private string _StatusMessage;
+ public string StatusMessage { get => _StatusMessage; private set => this.SetProperty(ref _StatusMessage, value); }
+
+ private bool _IsBusy;
+ public bool IsBusy { get=> _IsBusy; private set=> this.SetProperty(ref _IsBusy, value); }
+
+ public LoginPageViewModel()
+ {
+ Settings = new Settings();
+ StatusMessage = "Ready";
+ }
+
+ [RelayCommand]
+ public async Task LoginAsync()
+ {
+ try
+ {
+ Settings.Load().Wait();
+
+ var client = new OidcClient(Settings.GetOidcClientOptions());
+ var loginResult = await client.LoginAsync(new LoginRequest());
+
+ if (loginResult.IsError)
+ {
+ StatusMessage = loginResult.Error;
+ return;
+ }
+
+ StatusMessage = "Interactive token acquired.";
+
+ this.IsBusy = false;
+ AccessToken = loginResult.AccessToken;
+ /* TODO save or not user log and password
+ await Task.Run(() =>
+ {
+ Settings.Save().Wait();
+ });*/
+
+ }
+ catch (Exception ex)
+ {
+ this.IsBusy = false;
+ StatusMessage = "Error: "+ex.Message;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/PostIt/PostIt/ViewModels/MainViewModel.cs b/src/PostIt/PostIt/ViewModels/MainViewModel.cs
index 10f9febe..0f437a99 100644
--- a/src/PostIt/PostIt/ViewModels/MainViewModel.cs
+++ b/src/PostIt/PostIt/ViewModels/MainViewModel.cs
@@ -107,44 +107,6 @@ public partial class MainPageViewModel : ViewModelBase
ApplyFilter();
}
- [RelayCommand]
- internal async Task Login()
- {
- await ExecuteAsync(async () =>
- {
- // Try interactive OIDC login first
- try
- {
-
- var loginWin = new PostIt.Views.LoginPage();
- var result = await loginWin.StartLoginAsync(Settings.GetOidcClientOptions());
-
- if (result is not null && !result.IsError && !string.IsNullOrWhiteSpace(result.AccessToken))
- {
- BearerToken = result.AccessToken;
- StatusMessage = "Interactive token acquired.";
- return;
- }
- }
- catch
- {
- // ignore and fallback to client credentials
- }
-
- // Fallback to client credentials if interactive fails
- var tokenResponse = await RequestClientCredentialsTokenAsync();
- if (string.IsNullOrWhiteSpace(tokenResponse.AccessToken))
- {
- throw new InvalidOperationException("Failed to acquire a token using client credentials.");
- }
-
- BearerToken = tokenResponse.AccessToken;
- StatusMessage = string.IsNullOrWhiteSpace(tokenResponse.Error)
- ? "Bearer token acquired (client credentials)."
- : $"Token acquired with warning: {tokenResponse.ErrorDescription}";
- });
- }
-
[RelayCommand]
internal async Task Save()
{
diff --git a/src/PostIt/PostIt/Views/LoginPage.axaml b/src/PostIt/PostIt/Views/LoginPage.axaml
index 5b79bb60..f7b9fc53 100644
--- a/src/PostIt/PostIt/Views/LoginPage.axaml
+++ b/src/PostIt/PostIt/Views/LoginPage.axaml
@@ -1,37 +1,39 @@
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:vm="using:PostIt.ViewModels"
+ x:Class="PostIt.Views.LoginPage"
+ x:DataType="vm:LoginPageViewModel"
+ Header="Login">
-
+
-
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
+
-
+
-
-
+
+
-
+
diff --git a/src/PostIt/PostIt/Views/LoginPage.axaml.cs b/src/PostIt/PostIt/Views/LoginPage.axaml.cs
index 0d86e47c..85f51312 100644
--- a/src/PostIt/PostIt/Views/LoginPage.axaml.cs
+++ b/src/PostIt/PostIt/Views/LoginPage.axaml.cs
@@ -10,6 +10,8 @@ namespace PostIt.Views;
public partial class LoginPage : ContentPage
{
private TaskCompletionSource _tcs = new();
+ private LoginResult loginResult;
+
public Settings Settings { get; }
@@ -19,25 +21,22 @@ public partial class LoginPage : ContentPage
InitializeComponent();
}
- public async Task StartLoginAsync(OidcClientOptions options)
+ private async void OnLoginClickAsync(object? sender, RoutedEventArgs e)
{
+ // This is where you specify your actual login auth logic
try
{
Settings.Load().Wait();
- var client = new OidcClient(options);
+ var client = new OidcClient(Settings.GetOidcClientOptions());
var loginResult = await client.LoginAsync(new LoginRequest());
- return loginResult;
+ this.loginResult = loginResult;
}
catch (Exception)
{
- return null;
+ this.loginResult = null;
}
- }
- private async void OnLoginClick(object? sender, RoutedEventArgs e)
- {
- // This is where you specify your actual login auth logic
if (Navigation is not null)
await Navigation.PopModalAsync();
}
diff --git a/src/PostIt/PostIt/Views/MainPage.axaml b/src/PostIt/PostIt/Views/MainPage.axaml
index 2313d973..b4b65be9 100644
--- a/src/PostIt/PostIt/Views/MainPage.axaml
+++ b/src/PostIt/PostIt/Views/MainPage.axaml
@@ -8,7 +8,9 @@
xmlns:AvaloniaEdit="clr-namespace:AvaloniaEdit;assembly=AvaloniaEdit"
mc:Ignorable="d"
x:Class="PostIt.Views.MainPage"
- x:DataType="vm:MainPageViewModel" HorizontalAlignment="Center" VerticalAlignment="Center" >
+ x:DataType="vm:MainPageViewModel"
+ HorizontalAlignment="Center"
+ VerticalAlignment="Center" >
@@ -17,7 +19,6 @@
-
diff --git a/src/PostIt/PostIt/Views/MainViewModel.cs b/src/PostIt/PostIt/Views/MainViewModel.cs
deleted file mode 100644
index 5d30ae8f..00000000
--- a/src/PostIt/PostIt/Views/MainViewModel.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using CommunityToolkit.Mvvm.ComponentModel;
-using CommunityToolkit.Mvvm.Input;
-using PostIt.ViewModels;
-
-public partial class MainWindowViewModel : ObservableObject
-{
- // Stocke le ViewModel de la page actuellement affichée
- [ObservableProperty]
- private object? _currentPage;
-
- // Instances des pages pour éviter de les recréer à chaque fois (Optionnel)
- private readonly HomePageViewModel _homePage = new();
- private readonly SettingsPageViewModel _settingsPage = new();
-
- public MainWindowViewModel()
- {
- // Définir la page de démarrage par défaut
- CurrentPage = _homePage;
- }
-
- [RelayCommand]
- private void NavigateToHome() => CurrentPage = _homePage;
-
- [RelayCommand]
- private void NavigateToSettings() => CurrentPage = _settingsPage;
-}
diff --git a/src/PostIt/PostIt/settings.json b/src/PostIt/PostIt/postit-settings sample.json
similarity index 100%
rename from src/PostIt/PostIt/settings.json
rename to src/PostIt/PostIt/postit-settings sample.json