Fixes the Android Login process

This commit is contained in:
Paul Schneider 2026-08-25 19:20:03 +01:00
commit 75b298b0f8
Signed by: notazof
GPG key ID: 1DD5D838E5343B06
16 changed files with 106 additions and 129 deletions

View file

@ -1,13 +1,11 @@
using Android;

using Android.App;
using Android.Content;
using Android.Content.PM;
using AndroidX.Core.Provider;
using AndroidX.Emoji2.Text;
using Avalonia;
using Avalonia.Android;
using AndroidX.Core.Provider;
using AndroidX.Emoji2.Text;
using PostIt.Droid.Services;
namespace PostIt.Android;
@ -34,7 +32,7 @@ public class MainActivity : AvaloniaMainActivity
Yavsc.Resource.Array.com_google_android_gms_fonts_certs); //com_google_android_gms_fonts_certs
EmojiCompat.Config config = new FontRequestEmojiCompatConfig(this, fontRequest);
EmojiCompat.Init(config);
PlatformBootstrap.EnsureInitialized();
PlatformBootstrap.InitPlatform();
base.OnCreate(savedInstanceState);
Current = this;
}
@ -50,7 +48,13 @@ public class MainActivity : AvaloniaMainActivity
protected override void OnNewIntent(Intent? intent)
{
base.OnNewIntent(intent);
if (intent is not null) AndroidOidcCallbackSink.Handle(intent);
var url = intent?.DataString;
if (!string.IsNullOrEmpty(url) && url.StartsWith("postit://callback"))
{
OidcCallbackManager.SetResult(url);
}
}
internal static class AndroidOidcCallbackSink

View file

@ -12,14 +12,9 @@ namespace PostIt.Android;
/// </summary>
internal static class PlatformBootstrap
{
private static int _initialized;
internal static void EnsureInitialized()
internal static void InitPlatform()
{
if (System.Threading.Interlocked.Exchange(ref _initialized, 1) != 0)
return;
Platform.DefaultRedirectUri = ViewModels.Settings.AndroidRedirectUri;
Platform.CreateBrowser = () =>
{
var activity = MainActivity.Current;

View file

@ -2,31 +2,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="auto">
<uses-permission android:name="android.permission.INTERNET" />
<application android:label="PostIt" android:icon="@drawable/Icon">
<!--
Deep-link receiver for the OIDC Authorization Code + PKCE flow.
After the user authenticates in the system browser, the OP
redirects to android://postit-signin?... and Android forwards
the Intent to the MainActivity (configured SingleTask so the
existing instance receives OnNewIntent rather than spawning a
new one).
The host value (postit-signin) MUST match the
AndroidRedirectUri constant in PostIt/Settings/Settings.cs and
the corresponding RedirectUri registered for the 'postit'
client in IdentityServer (Yavsc.Org ConfigurationDb).
-->
<activity-alias
android:name="PostIt.Android.OidcCallbackActivity"
android:targetActivity="PostIt.Android.PostItMainActivity"
android:exported="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="android" android:host="postit-signin" />
</intent-filter>
</activity-alias>
</application>
</manifest>

View file

@ -3,6 +3,7 @@ using System.Threading.Tasks;
using Android.App;
using AndroidX.Browser.CustomTabs;
using IdentityModel.OidcClient.Browser;
using PostIt.Droid.Services;
namespace PostIt.Android.Services;
@ -35,9 +36,14 @@ public sealed class AndroidSystemBrowser : IBrowser
};
}
var uri = global::Android.Net.Uri.Parse(options.StartUrl)!;
// 1. Enregistrez la tâche avant de lancer le Custom Tab
var callbackTask = OidcCallbackManager.RegisterCallback(cancellationToken);
var callbackTask = MainActivity.AndroidOidcCallbackSink.AwaitNextCallbackAsync();
// 2. LANCEZ VOTRE CUSTOM TAB ICI (via AndroidX.Browser.CustomTabs)
// ... code pour ouvrir l'URL d'authentification ...
var uri = global::Android.Net.Uri.Parse(options.StartUrl)!;
var tabsIntent = new CustomTabsIntent.Builder()
.SetShowTitle(true)!

View file

@ -0,0 +1,21 @@
using System.Threading;
using System.Threading.Tasks;
namespace PostIt.Droid.Services;
public static class OidcCallbackManager
{
private static TaskCompletionSource<string>? _tcs;
public static Task<string> RegisterCallback(CancellationToken cancellationToken)
{
_tcs = new TaskCompletionSource<string>();
cancellationToken.Register(() => _tcs.TrySetCanceled());
return _tcs.Task;
}
public static void SetResult(string url)
{
_tcs?.TrySetResult(url);
}
}

View file

@ -0,0 +1,35 @@
using Android.App;
using Android.Content;
using Android.Content.PM;
using Android.OS;
using PostIt.Droid.Services;
namespace PostIt.Android;
[Activity(NoHistory = true, LaunchMode = LaunchMode.SingleTop, Exported = true)]
[IntentFilter(new[] { Intent.ActionView },
Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
DataScheme = "postit", // Remplacez par votre schéma personnalisé (ex: yavsc ou postit)
DataHost = "callback")] // Correspond à postit://callback
public class WebAuthenticationCallbackActivity : Activity
{
protected override void OnCreate(Bundle? savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Capturer l'URL de redirection OIDC
var url = Intent?.DataString;
if (!string.IsNullOrEmpty(url))
{
// Transmettre l'URL au gestionnaire partagé pour compléter la Task
OidcCallbackManager.SetResult(url);
}
// Fermer cette activité transparente et ramener l'application au premier plan
var intent = new Intent(this, typeof(MainActivity));
intent.AddFlags(ActivityFlags.ClearTop | ActivityFlags.SingleTop);
StartActivity(intent);
Finish();
}
}