WebAuthenticator API (#1062)
* Initial work for WebAuthenticator API * Fix page loaded in sample * Fix weird generated item * Fix error message * Fix filename, too many .'s * Remove unnecessary comment * Tweak AppleSignIn API * Cancel any previous waiting tasks * Use WebAuthenticationBroker on UWP * Make code more readable * iOS10+ is only supported so remove check * Move last fallback into TVOS * Remove unnecessary duplicate attribute * Change exception type. * Better error message * Make AppleSignIn accessible from shared code * Added sample aspnet project for auth * Apple Signin for iOS only for now * Make auth sample use sample server * Added some tests * Make some methods private that shouldn't be public * Add docs * Increase device test timeout * Add human interaction traits to some new tests * Update devicetests cake Updated to newer addins Stop using cake bootstrappers * Run device tests with cake dotnet core * Bump xunit device runner * Tests go back to netcore 2 * Bump xunit device runner in rest of devicetest projs * Build that android app first! * Cleanup web auth - Change result type name - Clean up result type properties - Remove IsSupported from apple public api - Throw not supported in public apple api on < iOS 13 * Update sample to check for iOS 13 independently * Update docs * Make code a bit more readable. * More readable code changes * Fix test * Add some detection of callback activity This adds some code to ensure the developer has subclassed `WebAuthenticatorCallbackActivity` and registered an appropriate intentfilter for it based on the `callbackUrl` being used. Co-authored-by: James Montemagno <james.montemagno@gmail.com>
This commit is contained in:
Родитель
72447a0c0a
Коммит
ad22d9dea6
|
@ -165,6 +165,8 @@ publish/
|
|||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
appsettings.Development.json
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
<PackageReference Include="Xamarin.Android.Support.Core.Utils" Version="28.0.0.3" />
|
||||
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.devices" Version="2.3.3" />
|
||||
<PackageReference Include="xunit.runner.devices" Version="2.5.25" />
|
||||
<PackageReference Include="UnitTests.HeadlessRunner" Version="2.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
|
||||
<PackageReference Include="Xamarin.Forms" Version="4.2.0.848062" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.devices" Version="2.3.3" />
|
||||
<PackageReference Include="xunit.runner.devices" Version="2.5.25" />
|
||||
<PackageReference Include="UnitTests.HeadlessRunner" Version="2.0.0" />
|
||||
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
|
||||
<ProjectReference Include="..\..\Xamarin.Essentials\Xamarin.Essentials.csproj" />
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Xamarin.Essentials;
|
||||
using Xunit;
|
||||
|
||||
namespace DeviceTests
|
||||
{
|
||||
public class WebAuthenticator_Tests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(
|
||||
"https://xamarin-essentials-auth-sample.azurewebsites.net/redirect",
|
||||
"xamarinessentials",
|
||||
"testtokenvalue",
|
||||
"testrefreshvalue",
|
||||
99)]
|
||||
[Trait(Traits.InteractionType, Traits.InteractionTypes.Human)]
|
||||
public async Task Redirect(string urlBase, string callbackScheme, string accessToken, string refreshToken, int expires)
|
||||
{
|
||||
var r = await WebAuthenticator.AuthenticateAsync(
|
||||
new Uri($"{urlBase}?access_token={accessToken}&refresh_token={refreshToken}&expires={expires}"),
|
||||
new Uri($"{callbackScheme}://"));
|
||||
|
||||
Assert.Equal(accessToken, r?.AccessToken);
|
||||
Assert.Equal(refreshToken, r?.RefreshToken);
|
||||
Assert.NotNull(r?.ExpiresIn);
|
||||
Assert.True(r?.ExpiresIn > DateTime.UtcNow);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("xamarinessentials://#access_token=blah&refresh_token=blah2&expires=1", "blah", "blah2", "1")]
|
||||
[InlineData("xamarinessentials://?access_token=blah&refresh_token=blah2&expires=1", "blah", "blah2", "1")]
|
||||
[Trait(Traits.InteractionType, Traits.InteractionTypes.Human)]
|
||||
public void ParseQueryString(string url, string accessToken, string refreshToken, string expires)
|
||||
{
|
||||
var r = WebUtils.ParseQueryString(url);
|
||||
|
||||
Assert.Equal(accessToken, r?["access_token"]);
|
||||
Assert.Equal(refreshToken, r?["refresh_token"]);
|
||||
Assert.Equal(expires, r?["expires"]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -117,7 +117,7 @@
|
|||
<PackageReference Include="Xamarin.Forms" Version="4.2.0.848062" />
|
||||
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform" Version="6.1.9" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.devices" Version="2.3.3" />
|
||||
<PackageReference Include="xunit.runner.devices" Version="2.5.25" />
|
||||
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Xamarin.Forms" Version="4.2.0.848062" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.devices" Version="2.3.3" />
|
||||
<PackageReference Include="xunit.runner.devices" Version="2.5.25" />
|
||||
<PackageReference Include="UnitTests.HeadlessRunner" Version="2.0.0" />
|
||||
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#addin nuget:?package=Cake.AppleSimulator
|
||||
#addin nuget:?package=Cake.Android.Adb&version=2.0.6
|
||||
#addin nuget:?package=Cake.Android.AvdManager&version=1.0.3
|
||||
#addin nuget:?package=Cake.AppleSimulator&version=0.2.0
|
||||
#addin nuget:?package=Cake.Android.Adb&version=3.2.0
|
||||
#addin nuget:?package=Cake.Android.AvdManager&version=2.2.0
|
||||
#addin nuget:?package=Cake.FileHelpers
|
||||
|
||||
var TARGET = Argument("target", "Default");
|
||||
|
@ -17,14 +17,14 @@ var ANDROID_APK_PATH = "./DeviceTests.Android/bin/Release/com.xamarin.essentials
|
|||
var ANDROID_TEST_RESULTS_PATH = "./xunit-android.xml";
|
||||
var ANDROID_AVD = EnvironmentVariable("ANDROID_AVD") ?? "CABOODLE";
|
||||
var ANDROID_PKG_NAME = "com.xamarin.essentials.devicetests";
|
||||
var ANDROID_EMU_TARGET = EnvironmentVariable("ANDROID_EMU_TARGET") ?? "system-images;android-26;google_apis;x86";
|
||||
var ANDROID_EMU_DEVICE = EnvironmentVariable("ANDROID_EMU_DEVICE") ?? "Nexus 5X";
|
||||
var ANDROID_EMU_TARGET = EnvironmentVariable("ANDROID_EMU_TARGET") ?? "system-images;android-29;google_apis_playstore;x86_64";
|
||||
var ANDROID_EMU_DEVICE = EnvironmentVariable("ANDROID_EMU_DEVICE") ?? "pixel";
|
||||
|
||||
var UWP_PROJ = "./DeviceTests.UWP/DeviceTests.UWP.csproj";
|
||||
var UWP_TEST_RESULTS_PATH = "./xunit-uwp.xml";
|
||||
var UWP_PACKAGE_ID = "ec0cc741-fd3e-485c-81be-68815c480690";
|
||||
|
||||
var TCP_LISTEN_TIMEOUT = 120;
|
||||
var TCP_LISTEN_TIMEOUT = 240;
|
||||
var TCP_LISTEN_PORT = 10578;
|
||||
var TCP_LISTEN_HOST = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName())
|
||||
.AddressList.First(f => f.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).ToString();
|
||||
|
@ -180,37 +180,19 @@ Task ("test-android-emu")
|
|||
.Does (() =>
|
||||
{
|
||||
var avdSettings = new AndroidAvdManagerToolSettings { SdkRoot = ANDROID_HOME };
|
||||
Information ("Available AVDs:");
|
||||
foreach (var avd in AndroidAvdListAvds (avdSettings)) {
|
||||
Information (" - " + avd);
|
||||
}
|
||||
var emuSettings = new AndroidEmulatorToolSettings { SdkRoot = ANDROID_HOME };
|
||||
|
||||
// Create the AVD if necessary
|
||||
if (EnvironmentVariable("ANDROID_SKIP_AVD_CREATE") == null) {
|
||||
Information ("Creating AVD if necessary: {0}...", ANDROID_AVD);
|
||||
if (!AndroidAvdListAvds (avdSettings).Any (a => a.Name == ANDROID_AVD))
|
||||
AndroidAvdCreate (ANDROID_AVD, ANDROID_EMU_TARGET, ANDROID_EMU_DEVICE, force: true, settings: avdSettings);
|
||||
}
|
||||
// Delete AVD first, if it exists
|
||||
Information ("Deleting AVD if exists: {0}...", ANDROID_AVD);
|
||||
try { AndroidAvdDelete(ANDROID_AVD, avdSettings); }
|
||||
catch { }
|
||||
|
||||
// We need to find `emulator` and the best way is to try within a specified ANDROID_HOME
|
||||
var emulatorExt = IsRunningOnWindows() ? ".bat" : "";
|
||||
string emulatorPath = "emulator" + emulatorExt;
|
||||
|
||||
if (ANDROID_HOME != null) {
|
||||
var andHome = new DirectoryPath(ANDROID_HOME);
|
||||
if (DirectoryExists(andHome)) {
|
||||
emulatorPath = MakeAbsolute(andHome.Combine("tools").CombineWithFilePath("emulator" + emulatorExt)).FullPath;
|
||||
if (!FileExists(emulatorPath))
|
||||
emulatorPath = MakeAbsolute(andHome.Combine("emulator").CombineWithFilePath("emulator" + emulatorExt)).FullPath;
|
||||
if (!FileExists(emulatorPath))
|
||||
emulatorPath = "emulator" + emulatorExt;
|
||||
}
|
||||
}
|
||||
|
||||
// Start up the emulator by name
|
||||
// Create the AVD
|
||||
Information ("Creating AVD: {0}...", ANDROID_AVD);
|
||||
AndroidAvdCreate (ANDROID_AVD, ANDROID_EMU_TARGET, ANDROID_EMU_DEVICE, force: true, settings: avdSettings);
|
||||
|
||||
Information ("Starting Emulator: {0}...", ANDROID_AVD);
|
||||
var emu = StartAndReturnProcess (emulatorPath, new ProcessSettings {
|
||||
Arguments = $"-avd {ANDROID_AVD}" });
|
||||
var emulatorProcess = AndroidEmulatorStart(ANDROID_AVD, emuSettings);
|
||||
|
||||
var adbSettings = new AdbToolSettings { SdkRoot = ANDROID_HOME };
|
||||
|
||||
|
@ -265,8 +247,16 @@ Task ("test-android-emu")
|
|||
|
||||
AddPlatformToTestResults(ANDROID_TEST_RESULTS_PATH, "Android");
|
||||
|
||||
// Close emulator
|
||||
emu.Kill();
|
||||
// Stop / cleanup the emulator
|
||||
AdbEmuKill(adbSettings);
|
||||
|
||||
System.Threading.Thread.Sleep(5000);
|
||||
|
||||
// Finally kill the process if it's not exited already
|
||||
try { emulatorProcess.Kill(); }
|
||||
catch { }
|
||||
|
||||
Information("Done Tests");
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -1,235 +0,0 @@
|
|||
##########################################################################
|
||||
# This is the Cake bootstrapper script for PowerShell.
|
||||
# This file was downloaded from https://github.com/cake-build/resources
|
||||
# Feel free to change this file to fit your needs.
|
||||
##########################################################################
|
||||
|
||||
<#
|
||||
|
||||
.SYNOPSIS
|
||||
This is a Powershell script to bootstrap a Cake build.
|
||||
|
||||
.DESCRIPTION
|
||||
This Powershell script will download NuGet if missing, restore NuGet tools (including Cake)
|
||||
and execute your Cake build script with the parameters you provide.
|
||||
|
||||
.PARAMETER Script
|
||||
The build script to execute.
|
||||
.PARAMETER Target
|
||||
The build script target to run.
|
||||
.PARAMETER Configuration
|
||||
The build configuration to use.
|
||||
.PARAMETER Verbosity
|
||||
Specifies the amount of information to be displayed.
|
||||
.PARAMETER ShowDescription
|
||||
Shows description about tasks.
|
||||
.PARAMETER DryRun
|
||||
Performs a dry run.
|
||||
.PARAMETER Experimental
|
||||
Uses the nightly builds of the Roslyn script engine.
|
||||
.PARAMETER Mono
|
||||
Uses the Mono Compiler rather than the Roslyn script engine.
|
||||
.PARAMETER SkipToolPackageRestore
|
||||
Skips restoring of packages.
|
||||
.PARAMETER ScriptArgs
|
||||
Remaining arguments are added here.
|
||||
|
||||
.LINK
|
||||
https://cakebuild.net
|
||||
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[string]$Script = "build.cake",
|
||||
[string]$Target,
|
||||
[string]$Configuration,
|
||||
[ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")]
|
||||
[string]$Verbosity,
|
||||
[switch]$ShowDescription,
|
||||
[Alias("WhatIf", "Noop")]
|
||||
[switch]$DryRun,
|
||||
[switch]$Experimental,
|
||||
[switch]$Mono,
|
||||
[switch]$SkipToolPackageRestore,
|
||||
[Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)]
|
||||
[string[]]$ScriptArgs
|
||||
)
|
||||
|
||||
[Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null
|
||||
function MD5HashFile([string] $filePath)
|
||||
{
|
||||
if ([string]::IsNullOrEmpty($filePath) -or !(Test-Path $filePath -PathType Leaf))
|
||||
{
|
||||
return $null
|
||||
}
|
||||
|
||||
[System.IO.Stream] $file = $null;
|
||||
[System.Security.Cryptography.MD5] $md5 = $null;
|
||||
try
|
||||
{
|
||||
$md5 = [System.Security.Cryptography.MD5]::Create()
|
||||
$file = [System.IO.File]::OpenRead($filePath)
|
||||
return [System.BitConverter]::ToString($md5.ComputeHash($file))
|
||||
}
|
||||
finally
|
||||
{
|
||||
if ($file -ne $null)
|
||||
{
|
||||
$file.Dispose()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function GetProxyEnabledWebClient
|
||||
{
|
||||
$wc = New-Object System.Net.WebClient
|
||||
$proxy = [System.Net.WebRequest]::GetSystemWebProxy()
|
||||
$proxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials
|
||||
$wc.Proxy = $proxy
|
||||
return $wc
|
||||
}
|
||||
|
||||
Write-Host "Preparing to run build script..."
|
||||
|
||||
if(!$PSScriptRoot){
|
||||
$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
|
||||
}
|
||||
|
||||
$TOOLS_DIR = Join-Path $PSScriptRoot "tools"
|
||||
$ADDINS_DIR = Join-Path $TOOLS_DIR "Addins"
|
||||
$MODULES_DIR = Join-Path $TOOLS_DIR "Modules"
|
||||
$NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe"
|
||||
$CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe"
|
||||
$NUGET_URL = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
|
||||
$PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config"
|
||||
$PACKAGES_CONFIG_MD5 = Join-Path $TOOLS_DIR "packages.config.md5sum"
|
||||
$ADDINS_PACKAGES_CONFIG = Join-Path $ADDINS_DIR "packages.config"
|
||||
$MODULES_PACKAGES_CONFIG = Join-Path $MODULES_DIR "packages.config"
|
||||
|
||||
# Make sure tools folder exists
|
||||
if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) {
|
||||
Write-Verbose -Message "Creating tools directory..."
|
||||
New-Item -Path $TOOLS_DIR -Type directory | out-null
|
||||
}
|
||||
|
||||
# Make sure that packages.config exist.
|
||||
if (!(Test-Path $PACKAGES_CONFIG)) {
|
||||
Write-Verbose -Message "Downloading packages.config..."
|
||||
try {
|
||||
$wc = GetProxyEnabledWebClient
|
||||
$wc.DownloadFile("https://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch {
|
||||
Throw "Could not download packages.config."
|
||||
}
|
||||
}
|
||||
|
||||
# Try find NuGet.exe in path if not exists
|
||||
if (!(Test-Path $NUGET_EXE)) {
|
||||
Write-Verbose -Message "Trying to find nuget.exe in PATH..."
|
||||
$existingPaths = $Env:Path -Split ';' | Where-Object { (![string]::IsNullOrEmpty($_)) -and (Test-Path $_ -PathType Container) }
|
||||
$NUGET_EXE_IN_PATH = Get-ChildItem -Path $existingPaths -Filter "nuget.exe" | Select -First 1
|
||||
if ($NUGET_EXE_IN_PATH -ne $null -and (Test-Path $NUGET_EXE_IN_PATH.FullName)) {
|
||||
Write-Verbose -Message "Found in PATH at $($NUGET_EXE_IN_PATH.FullName)."
|
||||
$NUGET_EXE = $NUGET_EXE_IN_PATH.FullName
|
||||
}
|
||||
}
|
||||
|
||||
# Try download NuGet.exe if not exists
|
||||
if (!(Test-Path $NUGET_EXE)) {
|
||||
Write-Verbose -Message "Downloading NuGet.exe..."
|
||||
try {
|
||||
$wc = GetProxyEnabledWebClient
|
||||
$wc.DownloadFile($NUGET_URL, $NUGET_EXE)
|
||||
} catch {
|
||||
Throw "Could not download NuGet.exe."
|
||||
}
|
||||
}
|
||||
|
||||
# Save nuget.exe path to environment to be available to child processed
|
||||
$ENV:NUGET_EXE = $NUGET_EXE
|
||||
|
||||
# Restore tools from NuGet?
|
||||
if(-Not $SkipToolPackageRestore.IsPresent) {
|
||||
Push-Location
|
||||
Set-Location $TOOLS_DIR
|
||||
|
||||
# Check for changes in packages.config and remove installed tools if true.
|
||||
[string] $md5Hash = MD5HashFile($PACKAGES_CONFIG)
|
||||
if((!(Test-Path $PACKAGES_CONFIG_MD5)) -Or
|
||||
($md5Hash -ne (Get-Content $PACKAGES_CONFIG_MD5 ))) {
|
||||
Write-Verbose -Message "Missing or changed package.config hash..."
|
||||
Get-ChildItem -Exclude packages.config,nuget.exe,Cake.Bakery |
|
||||
Remove-Item -Recurse
|
||||
}
|
||||
|
||||
Write-Verbose -Message "Restoring tools from NuGet..."
|
||||
$NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$TOOLS_DIR`""
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Throw "An error occurred while restoring NuGet tools."
|
||||
}
|
||||
else
|
||||
{
|
||||
$md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII"
|
||||
}
|
||||
Write-Verbose -Message ($NuGetOutput | out-string)
|
||||
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
# Restore addins from NuGet
|
||||
if (Test-Path $ADDINS_PACKAGES_CONFIG) {
|
||||
Push-Location
|
||||
Set-Location $ADDINS_DIR
|
||||
|
||||
Write-Verbose -Message "Restoring addins from NuGet..."
|
||||
$NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$ADDINS_DIR`""
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Throw "An error occurred while restoring NuGet addins."
|
||||
}
|
||||
|
||||
Write-Verbose -Message ($NuGetOutput | out-string)
|
||||
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
# Restore modules from NuGet
|
||||
if (Test-Path $MODULES_PACKAGES_CONFIG) {
|
||||
Push-Location
|
||||
Set-Location $MODULES_DIR
|
||||
|
||||
Write-Verbose -Message "Restoring modules from NuGet..."
|
||||
$NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$MODULES_DIR`""
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Throw "An error occurred while restoring NuGet modules."
|
||||
}
|
||||
|
||||
Write-Verbose -Message ($NuGetOutput | out-string)
|
||||
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
# Make sure that Cake has been installed.
|
||||
if (!(Test-Path $CAKE_EXE)) {
|
||||
Throw "Could not find Cake.exe at $CAKE_EXE"
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Build Cake arguments
|
||||
$cakeArguments = @("$Script");
|
||||
if ($Target) { $cakeArguments += "-target=$Target" }
|
||||
if ($Configuration) { $cakeArguments += "-configuration=$Configuration" }
|
||||
if ($Verbosity) { $cakeArguments += "-verbosity=$Verbosity" }
|
||||
if ($ShowDescription) { $cakeArguments += "-showdescription" }
|
||||
if ($DryRun) { $cakeArguments += "-dryrun" }
|
||||
if ($Experimental) { $cakeArguments += "-experimental" }
|
||||
if ($Mono) { $cakeArguments += "-mono" }
|
||||
$cakeArguments += $ScriptArgs
|
||||
|
||||
# Start Cake
|
||||
Write-Host "Running build script..."
|
||||
&$CAKE_EXE $cakeArguments
|
||||
exit $LASTEXITCODE
|
|
@ -1,117 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
##########################################################################
|
||||
# This is the Cake bootstrapper script for Linux and OS X.
|
||||
# This file was downloaded from https://github.com/cake-build/resources
|
||||
# Feel free to change this file to fit your needs.
|
||||
##########################################################################
|
||||
|
||||
# Define directories.
|
||||
SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
||||
TOOLS_DIR=$SCRIPT_DIR/tools
|
||||
ADDINS_DIR=$TOOLS_DIR/Addins
|
||||
MODULES_DIR=$TOOLS_DIR/Modules
|
||||
NUGET_EXE=$TOOLS_DIR/nuget.exe
|
||||
CAKE_EXE=$TOOLS_DIR/Cake/Cake.exe
|
||||
PACKAGES_CONFIG=$TOOLS_DIR/packages.config
|
||||
PACKAGES_CONFIG_MD5=$TOOLS_DIR/packages.config.md5sum
|
||||
ADDINS_PACKAGES_CONFIG=$ADDINS_DIR/packages.config
|
||||
MODULES_PACKAGES_CONFIG=$MODULES_DIR/packages.config
|
||||
|
||||
# Define md5sum or md5 depending on Linux/OSX
|
||||
MD5_EXE=
|
||||
if [[ "$(uname -s)" == "Darwin" ]]; then
|
||||
MD5_EXE="md5 -r"
|
||||
else
|
||||
MD5_EXE="md5sum"
|
||||
fi
|
||||
|
||||
# Define default arguments.
|
||||
SCRIPT="build.cake"
|
||||
CAKE_ARGUMENTS=()
|
||||
|
||||
# Parse arguments.
|
||||
for i in "$@"; do
|
||||
case $1 in
|
||||
-s|--script) SCRIPT="$2"; shift ;;
|
||||
--) shift; CAKE_ARGUMENTS+=("$@"); break ;;
|
||||
*) CAKE_ARGUMENTS+=("$1") ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# Make sure the tools folder exist.
|
||||
if [ ! -d "$TOOLS_DIR" ]; then
|
||||
mkdir "$TOOLS_DIR"
|
||||
fi
|
||||
|
||||
# Make sure that packages.config exist.
|
||||
if [ ! -f "$TOOLS_DIR/packages.config" ]; then
|
||||
echo "Downloading packages.config..."
|
||||
curl -Lsfo "$TOOLS_DIR/packages.config" https://cakebuild.net/download/bootstrapper/packages
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "An error occurred while downloading packages.config."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Download NuGet if it does not exist.
|
||||
if [ ! -f "$NUGET_EXE" ]; then
|
||||
echo "Downloading NuGet..."
|
||||
curl -Lsfo "$NUGET_EXE" https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "An error occurred while downloading nuget.exe."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Restore tools from NuGet.
|
||||
pushd "$TOOLS_DIR" >/dev/null
|
||||
if [ ! -f "$PACKAGES_CONFIG_MD5" ] || [ "$( cat "$PACKAGES_CONFIG_MD5" | sed 's/\r$//' )" != "$( $MD5_EXE "$PACKAGES_CONFIG" | awk '{ print $1 }' )" ]; then
|
||||
find . -type d ! -name . ! -name 'Cake.Bakery' | xargs rm -rf
|
||||
fi
|
||||
|
||||
mono "$NUGET_EXE" install -ExcludeVersion
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Could not restore NuGet tools."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
$MD5_EXE "$PACKAGES_CONFIG" | awk '{ print $1 }' >| "$PACKAGES_CONFIG_MD5"
|
||||
|
||||
popd >/dev/null
|
||||
|
||||
# Restore addins from NuGet.
|
||||
if [ -f "$ADDINS_PACKAGES_CONFIG" ]; then
|
||||
pushd "$ADDINS_DIR" >/dev/null
|
||||
|
||||
mono "$NUGET_EXE" install -ExcludeVersion
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Could not restore NuGet addins."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
popd >/dev/null
|
||||
fi
|
||||
|
||||
# Restore modules from NuGet.
|
||||
if [ -f "$MODULES_PACKAGES_CONFIG" ]; then
|
||||
pushd "$MODULES_DIR" >/dev/null
|
||||
|
||||
mono "$NUGET_EXE" install -ExcludeVersion
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Could not restore NuGet modules."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
popd >/dev/null
|
||||
fi
|
||||
|
||||
# Make sure that Cake has been installed.
|
||||
if [ ! -f "$CAKE_EXE" ]; then
|
||||
echo "Could not find Cake.exe at '$CAKE_EXE'."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Start Cake
|
||||
exec mono "$CAKE_EXE" $SCRIPT "${CAKE_ARGUMENTS[@]}"
|
|
@ -0,0 +1,53 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Sample.Server.WebAuthenticator
|
||||
{
|
||||
[Route("mobileauth")]
|
||||
[ApiController]
|
||||
public class AuthController : ControllerBase
|
||||
{
|
||||
const string callbackScheme = "xamarinessentials";
|
||||
|
||||
[HttpGet("{scheme}")]
|
||||
public async Task Get([FromRoute]string scheme)
|
||||
{
|
||||
var auth = await Request.HttpContext.AuthenticateAsync(scheme);
|
||||
|
||||
if (!auth.Succeeded
|
||||
|| auth?.Principal == null
|
||||
|| !auth.Principal.Identities.Any(id => id.IsAuthenticated)
|
||||
|| string.IsNullOrEmpty(auth.Properties.GetTokenValue("access_token")))
|
||||
{
|
||||
// Not authenticated, challenge
|
||||
await Request.HttpContext.ChallengeAsync(scheme);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get parameters to send back to the callback
|
||||
var qs = new Dictionary<string, string>
|
||||
{
|
||||
{ "access_token", auth.Properties.GetTokenValue("access_token") },
|
||||
{ "refresh_token", auth.Properties.GetTokenValue("refresh_token") ?? string.Empty },
|
||||
{ "expires", (auth.Properties.ExpiresUtc?.ToUnixTimeSeconds() ?? -1).ToString() }
|
||||
};
|
||||
|
||||
// Build the result url
|
||||
var url = callbackScheme + "://#" + string.Join(
|
||||
"&",
|
||||
qs.Where(kvp => !string.IsNullOrEmpty(kvp.Value) && kvp.Value != "-1")
|
||||
.Select(kvp => $"{WebUtility.UrlEncode(kvp.Key)}={WebUtility.UrlEncode(kvp.Value)}"));
|
||||
|
||||
// Redirect to final url
|
||||
Request.HttpContext.Response.Redirect(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Sample.Server.WebAuthenticator
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
}
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.UseStartup<Startup>();
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AspNet.Security.OAuth.Apple" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Facebook" Version="3.0.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="3.0.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.MicrosoftAccount" Version="3.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,82 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace Sample.Server.WebAuthenticator
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public Startup(IConfiguration configuration, IWebHostEnvironment webHostEnvironment)
|
||||
{
|
||||
Configuration = configuration;
|
||||
WebHostEnvironment = webHostEnvironment;
|
||||
}
|
||||
|
||||
IConfiguration Configuration { get; }
|
||||
|
||||
IWebHostEnvironment WebHostEnvironment { get; }
|
||||
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddControllers();
|
||||
|
||||
services.AddAuthentication()
|
||||
.AddCookie()
|
||||
.AddFacebook(fb =>
|
||||
{
|
||||
fb.AppId = Configuration["FacebookAppId"];
|
||||
fb.AppSecret = Configuration["FacebookAppSecret"];
|
||||
fb.SaveTokens = true;
|
||||
})
|
||||
.AddGoogle(g =>
|
||||
{
|
||||
g.ClientId = Configuration["GoogleClientId"];
|
||||
g.ClientSecret = Configuration["GoogleClientSecret"];
|
||||
g.SaveTokens = true;
|
||||
})
|
||||
.AddMicrosoftAccount(ms =>
|
||||
{
|
||||
ms.ClientId = Configuration["MicrosoftClientId"];
|
||||
ms.ClientSecret = Configuration["MicrosoftClientSecret"];
|
||||
ms.SaveTokens = true;
|
||||
})
|
||||
.AddApple(a =>
|
||||
{
|
||||
a.ClientId = Configuration["AppleClientId"];
|
||||
a.KeyId = Configuration["AppleKeyId"];
|
||||
a.TeamId = Configuration["AppleTeamId"];
|
||||
a.UsePrivateKey(keyId
|
||||
=> WebHostEnvironment.ContentRootFileProvider.GetFileInfo($"AuthKey_{keyId}.p8"));
|
||||
a.SaveTokens = true;
|
||||
});
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||
{
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapControllers();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.Content.PM;
|
||||
using Android.OS;
|
||||
using Android.Runtime;
|
||||
|
@ -25,6 +26,13 @@ namespace Samples.Droid
|
|||
LoadApplication(new App());
|
||||
}
|
||||
|
||||
protected override void OnResume()
|
||||
{
|
||||
base.OnResume();
|
||||
|
||||
Xamarin.Essentials.Platform.OnResume();
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
|
@ -41,4 +49,10 @@ namespace Samples.Droid
|
|||
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
}
|
||||
|
||||
[Activity(NoHistory = true, LaunchMode = LaunchMode.SingleTop)]
|
||||
[IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable }, DataScheme = "xamarinessentials")]
|
||||
public class WebAuthenticationCallbackActivity : Xamarin.Essentials.WebAuthenticatorCallbackActivity
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,13 @@
|
|||
</uap:DefaultTile>
|
||||
<uap:SplashScreen Image="Assets\SplashScreen.png" />
|
||||
</uap:VisualElements>
|
||||
<Extensions>
|
||||
<uap:Extension Category="windows.protocol">
|
||||
<uap:Protocol Name="xamarinessentials">
|
||||
<uap:DisplayName>Xamarin Essentials</uap:DisplayName>
|
||||
</uap:Protocol>
|
||||
</uap:Extension>
|
||||
</Extensions>
|
||||
</Application>
|
||||
</Applications>
|
||||
<Capabilities>
|
||||
|
|
|
@ -16,5 +16,13 @@ namespace Samples.iOS
|
|||
|
||||
return base.FinishedLaunching(app, options);
|
||||
}
|
||||
|
||||
public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
|
||||
{
|
||||
if (Xamarin.Essentials.Platform.OpenUrl(app, url, options))
|
||||
return true;
|
||||
|
||||
return base.OpenUrl(app, url, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,6 +63,16 @@
|
|||
<string>appcenter-APP_SECRET</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>xamarinessentials</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>xamarinessentials</string>
|
||||
</array>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>Camera Photos</string>
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
<views:BasePage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:views="clr-namespace:Samples.View"
|
||||
xmlns:viewmodels="clr-namespace:Samples.ViewModel"
|
||||
x:Class="Samples.View.WebAuthenticatorPage"
|
||||
Title="Web Authenticator">
|
||||
<views:BasePage.BindingContext>
|
||||
<viewmodels:WebAuthenticatorViewModel />
|
||||
</views:BasePage.BindingContext>
|
||||
|
||||
<StackLayout>
|
||||
<Label Text="Quickly and easily authenticate and wait for callbacks on external urls." FontAttributes="Bold" Margin="12" />
|
||||
|
||||
<ScrollView>
|
||||
<StackLayout Padding="12,0,12,12" Spacing="6">
|
||||
|
||||
<Button Text="Microsoft" Command="{Binding MicrosoftCommand}" BackgroundColor="#00A4EF" TextColor="White" />
|
||||
<Button Text="Google" Command="{Binding GoogleCommand}" BackgroundColor="#d34836" TextColor="White" />
|
||||
<Button Text="Facebook" Command="{Binding FacebookCommand}" BackgroundColor="#3b5998" TextColor="White" />
|
||||
<Button Text="Apple" Command="{Binding AppleCommand}" BackgroundColor="Black" TextColor="White" />
|
||||
|
||||
<Label Text="Access Token:" FontAttributes="Bold" Margin="12,12,12,0" />
|
||||
<Label Text="{Binding AccessToken}" TextColor="Red" FontAttributes="Italic" />
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
</StackLayout>
|
||||
|
||||
</views:BasePage>
|
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace Samples.View
|
||||
{
|
||||
public partial class WebAuthenticatorPage : BasePage
|
||||
{
|
||||
public WebAuthenticatorPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -204,6 +204,12 @@ namespace Samples.ViewModel
|
|||
typeof(VibrationPage),
|
||||
"Quickly and easily make the device vibrate.",
|
||||
new[] { "vibration", "vibrate", "hardware", "device" }),
|
||||
new SampleItem(
|
||||
"🔓",
|
||||
"Web Authenticator",
|
||||
typeof(WebAuthenticatorPage),
|
||||
"Quickly and easily authenticate and wait for a callback.",
|
||||
new[] { "auth", "authenticate", "authenticator", "web", "webauth" }),
|
||||
};
|
||||
filteredItems = samples;
|
||||
filterText = string.Empty;
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Xamarin.Essentials;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Samples.ViewModel
|
||||
{
|
||||
public class WebAuthenticatorViewModel : BaseViewModel
|
||||
{
|
||||
const string authenticationUrl = "https://xamarin-essentials-auth-sample.azurewebsites.net/mobileauth/";
|
||||
|
||||
public WebAuthenticatorViewModel()
|
||||
{
|
||||
MicrosoftCommand = new Command(async () => await OnAuthenticate("Microsoft"));
|
||||
GoogleCommand = new Command(async () => await OnAuthenticate("Google"));
|
||||
FacebookCommand = new Command(async () => await OnAuthenticate("Facebook"));
|
||||
AppleCommand = new Command(async () => await OnAuthenticate("Apple"));
|
||||
}
|
||||
|
||||
public ICommand MicrosoftCommand { get; }
|
||||
|
||||
public ICommand GoogleCommand { get; }
|
||||
|
||||
public ICommand FacebookCommand { get; }
|
||||
|
||||
public ICommand AppleCommand { get; }
|
||||
|
||||
string accessToken = string.Empty;
|
||||
|
||||
public string AccessToken
|
||||
{
|
||||
get => accessToken;
|
||||
set => SetProperty(ref accessToken, value);
|
||||
}
|
||||
|
||||
async Task OnAuthenticate(string scheme)
|
||||
{
|
||||
try
|
||||
{
|
||||
WebAuthenticatorResult r = null;
|
||||
|
||||
if (scheme.Equals("Apple")
|
||||
&& DeviceInfo.Platform == DevicePlatform.iOS
|
||||
&& DeviceInfo.Version.Major >= 13)
|
||||
{
|
||||
r = await AppleSignInAuthenticator.AuthenticateAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
var authUrl = new Uri(authenticationUrl + scheme);
|
||||
var callbackUrl = new Uri("xamarinessentials://");
|
||||
|
||||
r = await WebAuthenticator.AuthenticateAsync(authUrl, callbackUrl);
|
||||
}
|
||||
|
||||
AccessToken = r?.AccessToken;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AccessToken = string.Empty;
|
||||
await DisplayAlertAsync($"Failed: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -29,6 +29,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{6330
|
|||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{EE4495FA-9869-45CF-A11D-69F2218C6F62}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.Server.WebAuthenticator", "Samples\Sample.Server.WebAuthenticator\Sample.Server.WebAuthenticator.csproj", "{553D51A8-8E79-40D9-9FB3-9FC2386FF886}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -435,6 +437,34 @@ Global
|
|||
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Release|x86.ActiveCfg = Release|x86
|
||||
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Release|x86.Build.0 = Release|x86
|
||||
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B}.Release|x86.Deploy.0 = Release|x86
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886}.Debug|ARM64.ActiveCfg = Debug|Any CPU
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886}.Debug|ARM64.Build.0 = Debug|Any CPU
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886}.Release|ARM64.ActiveCfg = Release|Any CPU
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886}.Release|ARM64.Build.0 = Release|Any CPU
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886}.Release|x64.Build.0 = Release|Any CPU
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -450,6 +480,7 @@ Global
|
|||
{CB2072E0-A437-4811-AE17-16CAE0DDA1B1} = {EE4495FA-9869-45CF-A11D-69F2218C6F62}
|
||||
{EE8FC716-27FC-405B-BD27-AF17E01A6671} = {EE4495FA-9869-45CF-A11D-69F2218C6F62}
|
||||
{4BD0D88F-7E7A-4C3B-9E34-BF3717A8FF4B} = {EE4495FA-9869-45CF-A11D-69F2218C6F62}
|
||||
{553D51A8-8E79-40D9-9FB3-9FC2386FF886} = {6330A0D0-E784-42A6-B975-451E609B907B}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {E012047E-6826-4037-8D1A-5606CD7D345D}
|
||||
|
|
|
@ -13,15 +13,12 @@ namespace Xamarin.Essentials
|
|||
{
|
||||
public static partial class Permissions
|
||||
{
|
||||
const string appManifestFilename = "AppxManifest.xml";
|
||||
const string appManifestXmlns = "http://schemas.microsoft.com/appx/manifest/foundation/windows10";
|
||||
|
||||
public static bool IsCapabilityDeclared(string capabilityName)
|
||||
{
|
||||
var doc = XDocument.Load(appManifestFilename, LoadOptions.None);
|
||||
var doc = XDocument.Load(Platform.AppManifestFilename, LoadOptions.None);
|
||||
var reader = doc.CreateReader();
|
||||
var namespaceManager = new XmlNamespaceManager(reader.NameTable);
|
||||
namespaceManager.AddNamespace("x", appManifestXmlns);
|
||||
namespaceManager.AddNamespace("x", Platform.AppManifestXmlns);
|
||||
|
||||
// If the manifest doesn't contain a capability we need, throw
|
||||
return (!doc.Root.XPathSelectElements($"//x:DeviceCapability[@Name='{capabilityName}']", namespaceManager)?.Any() ?? false) &&
|
||||
|
|
|
@ -79,6 +79,9 @@ namespace Xamarin.Essentials
|
|||
public static void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults) =>
|
||||
Permissions.OnRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
|
||||
public static void OnResume() =>
|
||||
WebAuthenticator.OnResume(null);
|
||||
|
||||
internal static bool HasSystemFeature(string systemFeature)
|
||||
{
|
||||
var packageManager = AppContext.PackageManager;
|
||||
|
|
|
@ -16,6 +16,11 @@ namespace Xamarin.Essentials
|
|||
{
|
||||
public static partial class Platform
|
||||
{
|
||||
#if __IOS__ || __TVOS__
|
||||
public static bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
|
||||
=> WebAuthenticator.OpenUrl(new Uri(url.AbsoluteString));
|
||||
#endif
|
||||
|
||||
#if __IOS__
|
||||
[DllImport(Constants.SystemLibrary, EntryPoint = "sysctlbyname")]
|
||||
#else
|
||||
|
@ -85,6 +90,27 @@ namespace Xamarin.Essentials
|
|||
|
||||
return viewController;
|
||||
}
|
||||
|
||||
internal static UIWindow GetCurrentWindow(bool throwIfNull = true)
|
||||
{
|
||||
var window = UIApplication.SharedApplication.KeyWindow;
|
||||
|
||||
if (window.WindowLevel == UIWindowLevel.Normal)
|
||||
return window;
|
||||
|
||||
if (window == null)
|
||||
{
|
||||
window = UIApplication.SharedApplication
|
||||
.Windows
|
||||
.OrderByDescending(w => w.WindowLevel)
|
||||
.FirstOrDefault(w => w.RootViewController != null && w.WindowLevel == UIWindowLevel.Normal);
|
||||
}
|
||||
|
||||
if (throwIfNull && window == null)
|
||||
throw new InvalidOperationException("Could not find current window.");
|
||||
|
||||
return window;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if __IOS__ || __WATCHOS__
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
namespace Xamarin.Essentials
|
||||
using Windows.ApplicationModel.Activation;
|
||||
|
||||
namespace Xamarin.Essentials
|
||||
{
|
||||
public static partial class Platform
|
||||
{
|
||||
internal const string AppManifestFilename = "AppxManifest.xml";
|
||||
internal const string AppManifestXmlns = "http://schemas.microsoft.com/appx/manifest/foundation/windows10";
|
||||
|
||||
public static string MapServiceToken { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Xamarin.Essentials
|
||||
{
|
||||
static class WebUtils
|
||||
{
|
||||
internal static IDictionary<string, string> ParseQueryString(string url)
|
||||
{
|
||||
var d = new Dictionary<string, string>();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(url) || (!url.Contains("?") && !url.Contains("#")))
|
||||
return d;
|
||||
|
||||
var qsStartIndex = url.IndexOf('?');
|
||||
if (qsStartIndex < 0)
|
||||
qsStartIndex = url.IndexOf('#');
|
||||
|
||||
if (url.Length - 1 < qsStartIndex + 1)
|
||||
return d;
|
||||
|
||||
var qs = url.Substring(qsStartIndex + 1);
|
||||
|
||||
var kvps = qs.Split('&');
|
||||
|
||||
if (kvps == null || !kvps.Any())
|
||||
return d;
|
||||
|
||||
foreach (var kvp in kvps)
|
||||
{
|
||||
var pair = kvp.Split(new char[] { '=' }, 2);
|
||||
|
||||
if (pair == null || pair.Length != 2)
|
||||
continue;
|
||||
|
||||
d[pair[0]] = pair[1];
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
internal static bool CanHandleCallback(Uri expectedUrl, Uri callbackUrl)
|
||||
{
|
||||
if (!callbackUrl.Scheme.Equals(expectedUrl.Scheme, StringComparison.OrdinalIgnoreCase))
|
||||
return false;
|
||||
|
||||
if (!string.IsNullOrEmpty(expectedUrl.Host))
|
||||
{
|
||||
if (!callbackUrl.Host.Equals(expectedUrl.Host, StringComparison.OrdinalIgnoreCase))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using AuthenticationServices;
|
||||
using Foundation;
|
||||
using UIKit;
|
||||
|
||||
namespace Xamarin.Essentials
|
||||
{
|
||||
public static partial class AppleSignInAuthenticator
|
||||
{
|
||||
static AuthManager authManager;
|
||||
|
||||
static async Task<WebAuthenticatorResult> PlatformAuthenticateAsync(AppleSignInOptions options)
|
||||
{
|
||||
if (DeviceInfo.Version.Major < 13)
|
||||
throw new FeatureNotSupportedException();
|
||||
|
||||
var provider = new ASAuthorizationAppleIdProvider();
|
||||
var req = provider.CreateRequest();
|
||||
|
||||
authManager = new AuthManager(Platform.GetCurrentWindow());
|
||||
|
||||
var scopes = new List<ASAuthorizationScope>();
|
||||
|
||||
if (options.IncludeFullNameScope)
|
||||
scopes.Add(ASAuthorizationScope.FullName);
|
||||
if (options.IncludeEmailScope)
|
||||
scopes.Add(ASAuthorizationScope.Email);
|
||||
|
||||
req.RequestedScopes = scopes.ToArray();
|
||||
var controller = new ASAuthorizationController(new[] { req });
|
||||
|
||||
controller.Delegate = authManager;
|
||||
controller.PresentationContextProvider = authManager;
|
||||
|
||||
controller.PerformRequests();
|
||||
|
||||
var creds = await authManager.Credentials;
|
||||
|
||||
if (creds == null)
|
||||
return null;
|
||||
|
||||
var appleAccount = new WebAuthenticatorResult();
|
||||
appleAccount.Properties.Add("id_token", new NSString(creds.IdentityToken, NSStringEncoding.UTF8).ToString());
|
||||
appleAccount.Properties.Add("email", creds.Email);
|
||||
appleAccount.Properties.Add("user_id", creds.User);
|
||||
appleAccount.Properties.Add("name", NSPersonNameComponentsFormatter.GetLocalizedString(creds.FullName, NSPersonNameComponentsFormatterStyle.Default, NSPersonNameComponentsFormatterOptions.Phonetic));
|
||||
appleAccount.Properties.Add("realuserstatus", creds.RealUserStatus.ToString());
|
||||
|
||||
return appleAccount;
|
||||
}
|
||||
}
|
||||
|
||||
class AuthManager : NSObject, IASAuthorizationControllerDelegate, IASAuthorizationControllerPresentationContextProviding
|
||||
{
|
||||
public Task<ASAuthorizationAppleIdCredential> Credentials
|
||||
=> tcsCredential?.Task;
|
||||
|
||||
TaskCompletionSource<ASAuthorizationAppleIdCredential> tcsCredential;
|
||||
|
||||
UIWindow presentingAnchor;
|
||||
|
||||
public AuthManager(UIWindow presentingWindow)
|
||||
{
|
||||
tcsCredential = new TaskCompletionSource<ASAuthorizationAppleIdCredential>();
|
||||
presentingAnchor = presentingWindow;
|
||||
}
|
||||
|
||||
public UIWindow GetPresentationAnchor(ASAuthorizationController controller)
|
||||
=> presentingAnchor;
|
||||
|
||||
[Export("authorizationController:didCompleteWithAuthorization:")]
|
||||
public void DidComplete(ASAuthorizationController controller, ASAuthorization authorization)
|
||||
{
|
||||
var creds = authorization.GetCredential<ASAuthorizationAppleIdCredential>();
|
||||
tcsCredential?.TrySetResult(creds);
|
||||
}
|
||||
|
||||
[Export("authorizationController:didCompleteWithError:")]
|
||||
public void DidComplete(ASAuthorizationController controller, NSError error)
|
||||
=> tcsCredential?.TrySetException(new Exception(error.LocalizedDescription));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Xamarin.Essentials
|
||||
{
|
||||
public static partial class AppleSignInAuthenticator
|
||||
{
|
||||
static Task<WebAuthenticatorResult> PlatformAuthenticateAsync(AppleSignInOptions options) =>
|
||||
throw ExceptionUtils.NotSupportedOrImplementedException;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Xamarin.Essentials
|
||||
{
|
||||
public static partial class AppleSignInAuthenticator
|
||||
{
|
||||
public static Task<WebAuthenticatorResult> AuthenticateAsync(AppleSignInOptions options = null)
|
||||
=> PlatformAuthenticateAsync(options ?? new AppleSignInOptions());
|
||||
|
||||
public class AppleSignInOptions
|
||||
{
|
||||
public bool IncludeFullNameScope { get; set; } = false;
|
||||
|
||||
public bool IncludeEmailScope { get; set; } = false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Android.Content;
|
||||
using Android.Support.CustomTabs;
|
||||
|
||||
namespace Xamarin.Essentials
|
||||
{
|
||||
public partial class WebAuthenticator
|
||||
{
|
||||
static TaskCompletionSource<WebAuthenticatorResult> tcsResponse = null;
|
||||
|
||||
static Uri uri = null;
|
||||
|
||||
static CustomTabsActivityManager CustomTabsActivityManager { get; set; }
|
||||
|
||||
static Uri RedirectUri { get; set; }
|
||||
|
||||
internal static Task<WebAuthenticatorResult> ResponseTask
|
||||
=> tcsResponse?.Task;
|
||||
|
||||
internal static bool OnResume(Intent intent)
|
||||
{
|
||||
// If we aren't waiting on a task, don't handle the url
|
||||
if (tcsResponse?.Task?.IsCompleted ?? true)
|
||||
return false;
|
||||
|
||||
if (intent == null)
|
||||
{
|
||||
tcsResponse.TrySetCanceled();
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var intentUri = new Uri(intent.Data.ToString());
|
||||
|
||||
// Only handle schemes we expect
|
||||
if (!WebUtils.CanHandleCallback(RedirectUri, intentUri))
|
||||
{
|
||||
tcsResponse.TrySetException(new InvalidOperationException($"Invalid Redirect URI, detected `{intentUri}` but expected a URI in the format of `{RedirectUri}`"));
|
||||
return false;
|
||||
}
|
||||
|
||||
tcsResponse?.TrySetResult(new WebAuthenticatorResult(intentUri));
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
tcsResponse.TrySetException(ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static Task<WebAuthenticatorResult> PlatformAuthenticateAsync(Uri url, Uri callbackUrl)
|
||||
{
|
||||
var packageName = Platform.AppContext.PackageName;
|
||||
|
||||
// Create an intent to see if the app developer wired up the callback activity correctly
|
||||
var intent = new Intent(Intent.ActionView);
|
||||
intent.AddCategory(Intent.CategoryBrowsable);
|
||||
intent.AddCategory(Intent.CategoryDefault);
|
||||
intent.SetPackage(packageName);
|
||||
intent.SetData(global::Android.Net.Uri.Parse(callbackUrl.OriginalString));
|
||||
|
||||
// Try to find the activity for the callback intent
|
||||
var c = intent.ResolveActivity(Platform.AppContext.PackageManager);
|
||||
|
||||
if (c == null || c.PackageName != packageName)
|
||||
throw new InvalidOperationException($"You must subclass the `{nameof(WebAuthenticatorCallbackActivity)}` and create an IntentFilter for it which matches your `{nameof(callbackUrl)}`.");
|
||||
|
||||
// Cancel any previous task that's still pending
|
||||
if (tcsResponse?.Task != null && !tcsResponse.Task.IsCompleted)
|
||||
tcsResponse.TrySetCanceled();
|
||||
|
||||
tcsResponse = new TaskCompletionSource<WebAuthenticatorResult>();
|
||||
tcsResponse.Task.ContinueWith(t =>
|
||||
{
|
||||
// Cleanup when done
|
||||
if (CustomTabsActivityManager != null)
|
||||
{
|
||||
CustomTabsActivityManager.NavigationEvent -= CustomTabsActivityManager_NavigationEvent;
|
||||
CustomTabsActivityManager.CustomTabsServiceConnected -= CustomTabsActivityManager_CustomTabsServiceConnected;
|
||||
|
||||
try
|
||||
{
|
||||
CustomTabsActivityManager?.Client?.Dispose();
|
||||
}
|
||||
finally
|
||||
{
|
||||
CustomTabsActivityManager = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
uri = url;
|
||||
RedirectUri = callbackUrl;
|
||||
|
||||
CustomTabsActivityManager = CustomTabsActivityManager.From(Platform.GetCurrentActivity(true));
|
||||
CustomTabsActivityManager.NavigationEvent += CustomTabsActivityManager_NavigationEvent;
|
||||
CustomTabsActivityManager.CustomTabsServiceConnected += CustomTabsActivityManager_CustomTabsServiceConnected;
|
||||
|
||||
if (!CustomTabsActivityManager.BindService())
|
||||
{
|
||||
// Fall back to opening the system browser if necessary
|
||||
var browserIntent = new Intent(Intent.ActionView, global::Android.Net.Uri.Parse(url.OriginalString));
|
||||
Platform.CurrentActivity.StartActivity(browserIntent);
|
||||
}
|
||||
|
||||
return WebAuthenticator.ResponseTask;
|
||||
}
|
||||
|
||||
static void CustomTabsActivityManager_CustomTabsServiceConnected(ComponentName name, CustomTabsClient client)
|
||||
{
|
||||
var builder = new CustomTabsIntent.Builder(CustomTabsActivityManager.Session)
|
||||
.SetShowTitle(true);
|
||||
|
||||
var customTabsIntent = builder.Build();
|
||||
customTabsIntent.Intent.AddFlags(ActivityFlags.SingleTop | ActivityFlags.NoHistory | ActivityFlags.NewTask);
|
||||
|
||||
var ctx = Platform.CurrentActivity;
|
||||
|
||||
CustomTabsHelper.AddKeepAliveExtra(ctx, customTabsIntent.Intent);
|
||||
|
||||
customTabsIntent.LaunchUrl(ctx, global::Android.Net.Uri.Parse(uri.OriginalString));
|
||||
}
|
||||
|
||||
static void CustomTabsActivityManager_NavigationEvent(int navigationEvent, global::Android.OS.Bundle extras) =>
|
||||
System.Diagnostics.Debug.WriteLine($"CustomTabs.NavigationEvent: {navigationEvent}");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,190 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using AuthenticationServices;
|
||||
using Foundation;
|
||||
#if __IOS__
|
||||
using SafariServices;
|
||||
#endif
|
||||
using UIKit;
|
||||
|
||||
namespace Xamarin.Essentials
|
||||
{
|
||||
public static partial class WebAuthenticator
|
||||
{
|
||||
static TaskCompletionSource<WebAuthenticatorResult> tcsResponse;
|
||||
static UIViewController currentViewController;
|
||||
static Uri redirectUri;
|
||||
|
||||
internal static async Task<WebAuthenticatorResult> PlatformAuthenticateAsync(Uri url, Uri callbackUrl)
|
||||
{
|
||||
// Cancel any previous task that's still pending
|
||||
if (tcsResponse?.Task != null && !tcsResponse.Task.IsCompleted)
|
||||
tcsResponse.TrySetCanceled();
|
||||
|
||||
tcsResponse = new TaskCompletionSource<WebAuthenticatorResult>();
|
||||
redirectUri = callbackUrl;
|
||||
|
||||
try
|
||||
{
|
||||
var scheme = redirectUri.Scheme;
|
||||
|
||||
if (!VerifyHasUrlSchemeOrDoesntRequire(scheme))
|
||||
{
|
||||
tcsResponse.TrySetException(new InvalidOperationException("You must register your URL Scheme handler in your app's Info.plist!"));
|
||||
return await tcsResponse.Task;
|
||||
}
|
||||
|
||||
#if __IOS__
|
||||
void AuthSessionCallback(NSUrl cbUrl, NSError error)
|
||||
{
|
||||
if (error == null)
|
||||
OpenUrl(cbUrl);
|
||||
else
|
||||
tcsResponse.TrySetException(new NSErrorException(error));
|
||||
}
|
||||
|
||||
if (UIDevice.CurrentDevice.CheckSystemVersion(12, 0))
|
||||
{
|
||||
var was = new ASWebAuthenticationSession(new NSUrl(url.OriginalString), scheme, AuthSessionCallback);
|
||||
was.PresentationContextProvider = new ContextProvider(Platform.GetCurrentWindow());
|
||||
was.Start();
|
||||
return await tcsResponse.Task;
|
||||
}
|
||||
|
||||
if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
|
||||
{
|
||||
var sf = new SFAuthenticationSession(new NSUrl(url.OriginalString), scheme, AuthSessionCallback);
|
||||
sf.Start();
|
||||
return await tcsResponse.Task;
|
||||
}
|
||||
|
||||
// THis is only on iOS9+ but we only support 10+ in Essentials anyway
|
||||
var controller = new SFSafariViewController(new NSUrl(url.OriginalString), false)
|
||||
{
|
||||
Delegate = new NativeSFSafariViewControllerDelegate
|
||||
{
|
||||
DidFinishHandler = (svc) =>
|
||||
{
|
||||
// Cancel our task if it wasn't already marked as completed
|
||||
if (!(tcsResponse?.Task?.IsCompleted ?? true))
|
||||
tcsResponse.TrySetException(new OperationCanceledException());
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
currentViewController = controller;
|
||||
await Platform.GetCurrentUIViewController().PresentViewControllerAsync(controller, true);
|
||||
return await tcsResponse.Task;
|
||||
#else
|
||||
var opened = UIApplication.SharedApplication.OpenUrl(url);
|
||||
if (!opened)
|
||||
tcsResponse.TrySetException(new Exception("Error opening Safari"));
|
||||
#endif
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
tcsResponse.TrySetException(ex);
|
||||
}
|
||||
|
||||
return await tcsResponse.Task;
|
||||
}
|
||||
|
||||
internal static bool OpenUrl(Uri uri)
|
||||
{
|
||||
// If we aren't waiting on a task, don't handle the url
|
||||
if (tcsResponse?.Task?.IsCompleted ?? true)
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
// If we can't handle the url, don't
|
||||
if (!WebUtils.CanHandleCallback(redirectUri, uri))
|
||||
return false;
|
||||
|
||||
currentViewController?.DismissViewControllerAsync(true);
|
||||
currentViewController = null;
|
||||
|
||||
tcsResponse.TrySetResult(new WebAuthenticatorResult(uri));
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool VerifyHasUrlSchemeOrDoesntRequire(string scheme)
|
||||
{
|
||||
// iOS11+ uses sfAuthenticationSession which handles its own url routing
|
||||
if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
|
||||
return true;
|
||||
|
||||
var cleansed = scheme.Replace("://", string.Empty);
|
||||
var schemes = GetCFBundleURLSchemes().ToList();
|
||||
return schemes.Any(x => x != null && x.Equals(cleansed, StringComparison.InvariantCultureIgnoreCase));
|
||||
}
|
||||
|
||||
static IEnumerable<string> GetCFBundleURLSchemes()
|
||||
{
|
||||
var schemes = new List<string>();
|
||||
|
||||
NSObject nsobj = null;
|
||||
if (!NSBundle.MainBundle.InfoDictionary.TryGetValue((NSString)"CFBundleURLTypes", out nsobj))
|
||||
return schemes;
|
||||
|
||||
var array = nsobj as NSArray;
|
||||
|
||||
if (array == null)
|
||||
return schemes;
|
||||
|
||||
for (nuint i = 0; i < array.Count; i++)
|
||||
{
|
||||
var d = array.GetItem<NSDictionary>(i);
|
||||
if (d == null || !d.Any())
|
||||
continue;
|
||||
|
||||
if (!d.TryGetValue((NSString)"CFBundleURLSchemes", out nsobj))
|
||||
continue;
|
||||
|
||||
var a = nsobj as NSArray;
|
||||
var urls = ConvertToIEnumerable<NSString>(a).Select(x => x.ToString()).ToArray();
|
||||
foreach (var url in urls)
|
||||
schemes.Add(url);
|
||||
}
|
||||
|
||||
return schemes;
|
||||
}
|
||||
|
||||
static IEnumerable<T> ConvertToIEnumerable<T>(NSArray array)
|
||||
where T : class, ObjCRuntime.INativeObject
|
||||
{
|
||||
for (nuint i = 0; i < array.Count; i++)
|
||||
yield return array.GetItem<T>(i);
|
||||
}
|
||||
|
||||
#if __IOS__
|
||||
class NativeSFSafariViewControllerDelegate : SFSafariViewControllerDelegate
|
||||
{
|
||||
public Action<SFSafariViewController> DidFinishHandler { get; set; }
|
||||
|
||||
public override void DidFinish(SFSafariViewController controller) =>
|
||||
DidFinishHandler?.Invoke(controller);
|
||||
}
|
||||
|
||||
class ContextProvider : NSObject, IASWebAuthenticationPresentationContextProviding
|
||||
{
|
||||
public ContextProvider(UIWindow window) =>
|
||||
Window = window;
|
||||
|
||||
public UIWindow Window { get; private set; }
|
||||
|
||||
public UIWindow GetPresentationAnchor(ASWebAuthenticationSession session)
|
||||
=> Window;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Xamarin.Essentials
|
||||
{
|
||||
public static partial class WebAuthenticator
|
||||
{
|
||||
static Task<WebAuthenticatorResult> PlatformAuthenticateAsync(Uri url, Uri callbackUrl)
|
||||
=> throw ExceptionUtils.NotSupportedOrImplementedException;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Xamarin.Essentials
|
||||
{
|
||||
public static partial class WebAuthenticator
|
||||
{
|
||||
public static Task<WebAuthenticatorResult> AuthenticateAsync(Uri url, Uri callbackUrl)
|
||||
=> PlatformAuthenticateAsync(url, callbackUrl);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using System.Xml.XPath;
|
||||
using Windows.Security.Authentication.Web;
|
||||
|
||||
namespace Xamarin.Essentials
|
||||
{
|
||||
public static partial class WebAuthenticator
|
||||
{
|
||||
static async Task<WebAuthenticatorResult> PlatformAuthenticateAsync(Uri url, Uri callbackUrl)
|
||||
{
|
||||
if (!IsUriProtocolDeclared(callbackUrl.Scheme))
|
||||
throw new InvalidOperationException($"You need to declare the windows.protocol usage of the protocol/scheme `{callbackUrl.Scheme}` in your AppxManifest.xml file");
|
||||
|
||||
var r = await WebAuthenticationBroker.AuthenticateAsync(WebAuthenticationOptions.None, url, callbackUrl);
|
||||
|
||||
switch (r.ResponseStatus)
|
||||
{
|
||||
case WebAuthenticationStatus.Success:
|
||||
// For GET requests this is a URI:
|
||||
var resultUri = new Uri(r.ResponseData.ToString());
|
||||
return new WebAuthenticatorResult(resultUri);
|
||||
case WebAuthenticationStatus.ErrorHttp:
|
||||
throw new UnauthorizedAccessException();
|
||||
default:
|
||||
throw new Exception(r.ResponseData.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsUriProtocolDeclared(string scheme)
|
||||
{
|
||||
var doc = XDocument.Load(Platform.AppManifestFilename, LoadOptions.None);
|
||||
var reader = doc.CreateReader();
|
||||
var namespaceManager = new XmlNamespaceManager(reader.NameTable);
|
||||
namespaceManager.AddNamespace("x", Platform.AppManifestXmlns);
|
||||
namespaceManager.AddNamespace("uap", "http://schemas.microsoft.com/appx/manifest/uap/windows10");
|
||||
|
||||
// Check if the protocol was declared
|
||||
var decl = doc.Root.XPathSelectElements($"//uap:Extension[@Category='windows.protocol']/uap:Protocol[@Name='{scheme}']", namespaceManager);
|
||||
|
||||
return decl != null && decl.Any();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Android.App;
|
||||
using Android.OS;
|
||||
|
||||
namespace Xamarin.Essentials
|
||||
{
|
||||
public abstract class WebAuthenticatorCallbackActivity : Activity
|
||||
{
|
||||
protected override void OnCreate(Bundle savedInstanceState)
|
||||
{
|
||||
base.OnCreate(savedInstanceState);
|
||||
|
||||
WebAuthenticator.OnResume(Intent);
|
||||
|
||||
Finish();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Xamarin.Essentials
|
||||
{
|
||||
public class WebAuthenticatorResult
|
||||
{
|
||||
public WebAuthenticatorResult()
|
||||
{
|
||||
}
|
||||
|
||||
public WebAuthenticatorResult(Uri uri)
|
||||
{
|
||||
foreach (var kvp in WebUtils.ParseQueryString(uri.ToString()))
|
||||
{
|
||||
Properties[kvp.Key] = kvp.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public WebAuthenticatorResult(IDictionary<string, string> properties)
|
||||
{
|
||||
foreach (var kvp in properties)
|
||||
Properties[kvp.Key] = kvp.Value;
|
||||
}
|
||||
|
||||
public DateTimeOffset Timestamp { get; set; } = new DateTimeOffset(DateTime.UtcNow);
|
||||
|
||||
public Dictionary<string, string> Properties { get; set; } = new Dictionary<string, string>();
|
||||
|
||||
public void Put(string key, string value)
|
||||
=> Properties[key] = value;
|
||||
|
||||
public string Get(string key)
|
||||
{
|
||||
if (Properties.TryGetValue(key, out var v))
|
||||
return v;
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
public string AccessToken
|
||||
=> Get("access_token");
|
||||
|
||||
public string TokenType
|
||||
=> Get("token_type");
|
||||
|
||||
public string RefreshToken
|
||||
=> Get("refresh_token");
|
||||
|
||||
public DateTimeOffset? RefreshTokenExpiresIn
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Properties.TryGetValue("refresh_token_expires_in", out var v))
|
||||
{
|
||||
if (int.TryParse(v, out var i))
|
||||
return Timestamp.AddSeconds(i);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public DateTimeOffset? ExpiresIn
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Properties.TryGetValue("expires_in", out var v))
|
||||
{
|
||||
if (int.TryParse(v, out var i))
|
||||
return Timestamp.AddSeconds(i);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@ variables:
|
|||
NugetPackageVersion: '$(CurrentSemanticVersion)'
|
||||
MONO_VERSION: 6_4_0
|
||||
XCODE_VERSION: 11.1
|
||||
NETCORE_VERSION: '3.0.x'
|
||||
NETCORE_VERSION: '3.1.x'
|
||||
NETCORE_TEST_VERSION: '2.2.x'
|
||||
IOS_SIM_NAME: 'iPhone 11'
|
||||
IOS_SIM_RUNTIME: 'com.apple.CoreSimulator.SimRuntime.iOS-13-2'
|
||||
|
@ -200,7 +200,8 @@ jobs:
|
|||
provProfileSecureFile: 'Components iOS Provisioning.mobileprovision'
|
||||
- bash: |
|
||||
cd DeviceTests
|
||||
sh ./build.sh --target=test-ios-emu --settings_skipverification=true --verbosity=diagnostic
|
||||
dotnet tool install -g cake.tool --version 0.36.0
|
||||
dotnet cake --target=test-ios-emu --settings_skipverification=true --verbosity=diagnostic
|
||||
displayName: 'Run Device Tests - iOS'
|
||||
- task: PublishTestResults@2
|
||||
displayName: 'Publish Test Results'
|
||||
|
@ -237,7 +238,8 @@ jobs:
|
|||
PATH="$ANDROID_HOME/tools/bin:$PATH"
|
||||
PATH="$ANDROID_HOME/emulator:$PATH"
|
||||
cd DeviceTests
|
||||
sh ./build.sh --target=test-android-emu --settings_skipverification=true --verbosity=diagnostic
|
||||
dotnet tool install -g cake.tool --version 0.36.0
|
||||
dotnet cake --target=test-android-emu --settings_skipverification=true --verbosity=diagnostic
|
||||
displayName: 'Run Device Tests - Android'
|
||||
- task: PublishTestResults@2
|
||||
displayName: 'Publish Test Results'
|
||||
|
|
|
@ -47,6 +47,14 @@
|
|||
<Member Id="P:Xamarin.Essentials.AppInfo.Version" />
|
||||
<Member Id="P:Xamarin.Essentials.AppInfo.VersionString" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.AppleSignInAuthenticator" Id="T:Xamarin.Essentials.AppleSignInAuthenticator">
|
||||
<Member Id="M:Xamarin.Essentials.AppleSignInAuthenticator.AuthenticateAsync(Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions)" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.AppleSignInAuthenticator/AppleSignInOptions" Id="T:Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions">
|
||||
<Member Id="M:Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions.#ctor" />
|
||||
<Member Id="P:Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions.IncludeEmailScope" />
|
||||
<Member Id="P:Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions.IncludeFullNameScope" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.AppTheme" Id="T:Xamarin.Essentials.AppTheme">
|
||||
<Member Id="F:Xamarin.Essentials.AppTheme.Dark" />
|
||||
<Member Id="F:Xamarin.Essentials.AppTheme.Light" />
|
||||
|
@ -668,6 +676,7 @@
|
|||
<Member Id="M:Xamarin.Essentials.Platform.Init(Android.App.Activity,Android.OS.Bundle)" />
|
||||
<Member Id="M:Xamarin.Essentials.Platform.Init(Android.App.Application)" />
|
||||
<Member Id="M:Xamarin.Essentials.Platform.OnRequestPermissionsResult(System.Int32,System.String[],Android.Content.PM.Permission[])" />
|
||||
<Member Id="M:Xamarin.Essentials.Platform.OnResume" />
|
||||
<Member Id="M:Xamarin.Essentials.Platform.WaitForActivityAsync(System.Threading.CancellationToken)" />
|
||||
<Member Id="P:Xamarin.Essentials.Platform.AppContext" />
|
||||
<Member Id="P:Xamarin.Essentials.Platform.CurrentActivity" />
|
||||
|
@ -846,5 +855,26 @@
|
|||
<Member Id="M:Xamarin.Essentials.Vibration.Vibrate(System.Double)" />
|
||||
<Member Id="M:Xamarin.Essentials.Vibration.Vibrate(System.TimeSpan)" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.WebAuthenticator" Id="T:Xamarin.Essentials.WebAuthenticator">
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticator.AuthenticateAsync(System.Uri,System.Uri)" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.WebAuthenticatorCallbackActivity" Id="T:Xamarin.Essentials.WebAuthenticatorCallbackActivity">
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorCallbackActivity.#ctor" />
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorCallbackActivity.OnCreate(Android.OS.Bundle)" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.WebAuthenticatorResult" Id="T:Xamarin.Essentials.WebAuthenticatorResult">
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.#ctor" />
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.#ctor(System.Collections.Generic.IDictionary{System.String,System.String})" />
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.#ctor(System.Uri)" />
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.Get(System.String)" />
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.Put(System.String,System.String)" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.AccessToken" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.ExpiresIn" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.Properties" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.RefreshToken" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.RefreshTokenExpiresIn" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.Timestamp" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.TokenType" />
|
||||
</Type>
|
||||
</Namespace>
|
||||
</Framework>
|
||||
|
|
|
@ -34,6 +34,14 @@
|
|||
<Member Id="P:Xamarin.Essentials.AppInfo.Version" />
|
||||
<Member Id="P:Xamarin.Essentials.AppInfo.VersionString" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.AppleSignInAuthenticator" Id="T:Xamarin.Essentials.AppleSignInAuthenticator">
|
||||
<Member Id="M:Xamarin.Essentials.AppleSignInAuthenticator.AuthenticateAsync(Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions)" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.AppleSignInAuthenticator/AppleSignInOptions" Id="T:Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions">
|
||||
<Member Id="M:Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions.#ctor" />
|
||||
<Member Id="P:Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions.IncludeEmailScope" />
|
||||
<Member Id="P:Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions.IncludeFullNameScope" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.AppTheme" Id="T:Xamarin.Essentials.AppTheme">
|
||||
<Member Id="F:Xamarin.Essentials.AppTheme.Dark" />
|
||||
<Member Id="F:Xamarin.Essentials.AppTheme.Light" />
|
||||
|
@ -669,6 +677,7 @@
|
|||
</Type>
|
||||
<Type Name="Xamarin.Essentials.Platform" Id="T:Xamarin.Essentials.Platform">
|
||||
<Member Id="M:Xamarin.Essentials.Platform.GetCurrentUIViewController" />
|
||||
<Member Id="M:Xamarin.Essentials.Platform.OpenUrl(UIKit.UIApplication,Foundation.NSUrl,Foundation.NSDictionary)" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.PointExtensions" Id="T:Xamarin.Essentials.PointExtensions">
|
||||
<Member Id="M:Xamarin.Essentials.PointExtensions.ToSystemPoint(CoreGraphics.CGPoint)" />
|
||||
|
@ -846,5 +855,22 @@
|
|||
<Member Id="M:Xamarin.Essentials.Vibration.Vibrate(System.Double)" />
|
||||
<Member Id="M:Xamarin.Essentials.Vibration.Vibrate(System.TimeSpan)" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.WebAuthenticator" Id="T:Xamarin.Essentials.WebAuthenticator">
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticator.AuthenticateAsync(System.Uri,System.Uri)" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.WebAuthenticatorResult" Id="T:Xamarin.Essentials.WebAuthenticatorResult">
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.#ctor" />
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.#ctor(System.Collections.Generic.IDictionary{System.String,System.String})" />
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.#ctor(System.Uri)" />
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.Get(System.String)" />
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.Put(System.String,System.String)" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.AccessToken" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.ExpiresIn" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.Properties" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.RefreshToken" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.RefreshTokenExpiresIn" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.Timestamp" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.TokenType" />
|
||||
</Type>
|
||||
</Namespace>
|
||||
</Framework>
|
||||
|
|
|
@ -34,6 +34,14 @@
|
|||
<Member Id="P:Xamarin.Essentials.AppInfo.Version" />
|
||||
<Member Id="P:Xamarin.Essentials.AppInfo.VersionString" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.AppleSignInAuthenticator" Id="T:Xamarin.Essentials.AppleSignInAuthenticator">
|
||||
<Member Id="M:Xamarin.Essentials.AppleSignInAuthenticator.AuthenticateAsync(Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions)" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.AppleSignInAuthenticator/AppleSignInOptions" Id="T:Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions">
|
||||
<Member Id="M:Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions.#ctor" />
|
||||
<Member Id="P:Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions.IncludeEmailScope" />
|
||||
<Member Id="P:Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions.IncludeFullNameScope" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.AppTheme" Id="T:Xamarin.Essentials.AppTheme">
|
||||
<Member Id="F:Xamarin.Essentials.AppTheme.Dark" />
|
||||
<Member Id="F:Xamarin.Essentials.AppTheme.Light" />
|
||||
|
@ -635,6 +643,7 @@
|
|||
</Type>
|
||||
<Type Name="Xamarin.Essentials.Platform" Id="T:Xamarin.Essentials.Platform">
|
||||
<Member Id="M:Xamarin.Essentials.Platform.GetCurrentUIViewController" />
|
||||
<Member Id="M:Xamarin.Essentials.Platform.OpenUrl(UIKit.UIApplication,Foundation.NSUrl,Foundation.NSDictionary)" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.PointExtensions" Id="T:Xamarin.Essentials.PointExtensions">
|
||||
<Member Id="M:Xamarin.Essentials.PointExtensions.ToSystemPoint(CoreGraphics.CGPoint)" />
|
||||
|
@ -808,5 +817,22 @@
|
|||
<Member Id="M:Xamarin.Essentials.Vibration.Vibrate(System.Double)" />
|
||||
<Member Id="M:Xamarin.Essentials.Vibration.Vibrate(System.TimeSpan)" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.WebAuthenticator" Id="T:Xamarin.Essentials.WebAuthenticator">
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticator.AuthenticateAsync(System.Uri,System.Uri)" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.WebAuthenticatorResult" Id="T:Xamarin.Essentials.WebAuthenticatorResult">
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.#ctor" />
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.#ctor(System.Collections.Generic.IDictionary{System.String,System.String})" />
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.#ctor(System.Uri)" />
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.Get(System.String)" />
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.Put(System.String,System.String)" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.AccessToken" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.ExpiresIn" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.Properties" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.RefreshToken" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.RefreshTokenExpiresIn" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.Timestamp" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.TokenType" />
|
||||
</Type>
|
||||
</Namespace>
|
||||
</Framework>
|
||||
|
|
|
@ -34,6 +34,14 @@
|
|||
<Member Id="P:Xamarin.Essentials.AppInfo.Version" />
|
||||
<Member Id="P:Xamarin.Essentials.AppInfo.VersionString" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.AppleSignInAuthenticator" Id="T:Xamarin.Essentials.AppleSignInAuthenticator">
|
||||
<Member Id="M:Xamarin.Essentials.AppleSignInAuthenticator.AuthenticateAsync(Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions)" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.AppleSignInAuthenticator/AppleSignInOptions" Id="T:Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions">
|
||||
<Member Id="M:Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions.#ctor" />
|
||||
<Member Id="P:Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions.IncludeEmailScope" />
|
||||
<Member Id="P:Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions.IncludeFullNameScope" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.AppTheme" Id="T:Xamarin.Essentials.AppTheme">
|
||||
<Member Id="F:Xamarin.Essentials.AppTheme.Dark" />
|
||||
<Member Id="F:Xamarin.Essentials.AppTheme.Light" />
|
||||
|
@ -808,5 +816,22 @@
|
|||
<Member Id="M:Xamarin.Essentials.Vibration.Vibrate(System.Double)" />
|
||||
<Member Id="M:Xamarin.Essentials.Vibration.Vibrate(System.TimeSpan)" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.WebAuthenticator" Id="T:Xamarin.Essentials.WebAuthenticator">
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticator.AuthenticateAsync(System.Uri,System.Uri)" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.WebAuthenticatorResult" Id="T:Xamarin.Essentials.WebAuthenticatorResult">
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.#ctor" />
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.#ctor(System.Collections.Generic.IDictionary{System.String,System.String})" />
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.#ctor(System.Uri)" />
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.Get(System.String)" />
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.Put(System.String,System.String)" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.AccessToken" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.ExpiresIn" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.Properties" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.RefreshToken" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.RefreshTokenExpiresIn" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.Timestamp" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.TokenType" />
|
||||
</Type>
|
||||
</Namespace>
|
||||
</Framework>
|
||||
|
|
|
@ -34,6 +34,14 @@
|
|||
<Member Id="P:Xamarin.Essentials.AppInfo.Version" />
|
||||
<Member Id="P:Xamarin.Essentials.AppInfo.VersionString" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.AppleSignInAuthenticator" Id="T:Xamarin.Essentials.AppleSignInAuthenticator">
|
||||
<Member Id="M:Xamarin.Essentials.AppleSignInAuthenticator.AuthenticateAsync(Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions)" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.AppleSignInAuthenticator/AppleSignInOptions" Id="T:Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions">
|
||||
<Member Id="M:Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions.#ctor" />
|
||||
<Member Id="P:Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions.IncludeEmailScope" />
|
||||
<Member Id="P:Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions.IncludeFullNameScope" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.AppTheme" Id="T:Xamarin.Essentials.AppTheme">
|
||||
<Member Id="F:Xamarin.Essentials.AppTheme.Dark" />
|
||||
<Member Id="F:Xamarin.Essentials.AppTheme.Light" />
|
||||
|
@ -818,5 +826,22 @@
|
|||
<Member Id="M:Xamarin.Essentials.Vibration.Vibrate(System.Double)" />
|
||||
<Member Id="M:Xamarin.Essentials.Vibration.Vibrate(System.TimeSpan)" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.WebAuthenticator" Id="T:Xamarin.Essentials.WebAuthenticator">
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticator.AuthenticateAsync(System.Uri,System.Uri)" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.WebAuthenticatorResult" Id="T:Xamarin.Essentials.WebAuthenticatorResult">
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.#ctor" />
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.#ctor(System.Collections.Generic.IDictionary{System.String,System.String})" />
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.#ctor(System.Uri)" />
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.Get(System.String)" />
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.Put(System.String,System.String)" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.AccessToken" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.ExpiresIn" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.Properties" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.RefreshToken" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.RefreshTokenExpiresIn" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.Timestamp" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.TokenType" />
|
||||
</Type>
|
||||
</Namespace>
|
||||
</Framework>
|
||||
|
|
|
@ -34,6 +34,14 @@
|
|||
<Member Id="P:Xamarin.Essentials.AppInfo.Version" />
|
||||
<Member Id="P:Xamarin.Essentials.AppInfo.VersionString" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.AppleSignInAuthenticator" Id="T:Xamarin.Essentials.AppleSignInAuthenticator">
|
||||
<Member Id="M:Xamarin.Essentials.AppleSignInAuthenticator.AuthenticateAsync(Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions)" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.AppleSignInAuthenticator/AppleSignInOptions" Id="T:Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions">
|
||||
<Member Id="M:Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions.#ctor" />
|
||||
<Member Id="P:Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions.IncludeEmailScope" />
|
||||
<Member Id="P:Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions.IncludeFullNameScope" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.AppTheme" Id="T:Xamarin.Essentials.AppTheme">
|
||||
<Member Id="F:Xamarin.Essentials.AppTheme.Dark" />
|
||||
<Member Id="F:Xamarin.Essentials.AppTheme.Light" />
|
||||
|
@ -782,5 +790,22 @@
|
|||
<Member Id="M:Xamarin.Essentials.Vibration.Vibrate(System.Double)" />
|
||||
<Member Id="M:Xamarin.Essentials.Vibration.Vibrate(System.TimeSpan)" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.WebAuthenticator" Id="T:Xamarin.Essentials.WebAuthenticator">
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticator.AuthenticateAsync(System.Uri,System.Uri)" />
|
||||
</Type>
|
||||
<Type Name="Xamarin.Essentials.WebAuthenticatorResult" Id="T:Xamarin.Essentials.WebAuthenticatorResult">
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.#ctor" />
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.#ctor(System.Collections.Generic.IDictionary{System.String,System.String})" />
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.#ctor(System.Uri)" />
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.Get(System.String)" />
|
||||
<Member Id="M:Xamarin.Essentials.WebAuthenticatorResult.Put(System.String,System.String)" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.AccessToken" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.ExpiresIn" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.Properties" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.RefreshToken" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.RefreshTokenExpiresIn" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.Timestamp" />
|
||||
<Member Id="P:Xamarin.Essentials.WebAuthenticatorResult.TokenType" />
|
||||
</Type>
|
||||
</Namespace>
|
||||
</Framework>
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
<Type Name="AppleSignInAuthenticator+AppleSignInOptions" FullName="Xamarin.Essentials.AppleSignInAuthenticator+AppleSignInOptions">
|
||||
<TypeSignature Language="C#" Value="public class AppleSignInAuthenticator.AppleSignInOptions" />
|
||||
<TypeSignature Language="ILAsm" Value=".class nested public auto ansi beforefieldinit AppleSignInAuthenticator/AppleSignInOptions extends System.Object" />
|
||||
<TypeSignature Language="DocId" Value="T:Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions" />
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Xamarin.Essentials</AssemblyName>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<Base>
|
||||
<BaseTypeName>System.Object</BaseTypeName>
|
||||
</Base>
|
||||
<Interfaces />
|
||||
<Docs>
|
||||
<summary>Native Apple Sign In Options</summary>
|
||||
<remarks>
|
||||
<para />
|
||||
</remarks>
|
||||
</Docs>
|
||||
<Members>
|
||||
<Member MemberName=".ctor">
|
||||
<MemberSignature Language="C#" Value="public AppleSignInOptions ();" />
|
||||
<MemberSignature Language="ILAsm" Value=".method public hidebysig specialname rtspecialname instance void .ctor() cil managed" />
|
||||
<MemberSignature Language="DocId" Value="M:Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions.#ctor" />
|
||||
<MemberType>Constructor</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Xamarin.Essentials</AssemblyName>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<Parameters />
|
||||
<Docs>
|
||||
<summary>
|
||||
<para />
|
||||
</summary>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="IncludeEmailScope">
|
||||
<MemberSignature Language="C#" Value="public bool IncludeEmailScope { get; set; }" />
|
||||
<MemberSignature Language="ILAsm" Value=".property instance bool IncludeEmailScope" />
|
||||
<MemberSignature Language="DocId" Value="P:Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions.IncludeEmailScope" />
|
||||
<MemberType>Property</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Xamarin.Essentials</AssemblyName>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.Boolean</ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>Request email scope.</summary>
|
||||
<value>To be added.</value>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="IncludeFullNameScope">
|
||||
<MemberSignature Language="C#" Value="public bool IncludeFullNameScope { get; set; }" />
|
||||
<MemberSignature Language="ILAsm" Value=".property instance bool IncludeFullNameScope" />
|
||||
<MemberSignature Language="DocId" Value="P:Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions.IncludeFullNameScope" />
|
||||
<MemberType>Property</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Xamarin.Essentials</AssemblyName>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.Boolean</ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>Request full name scope.</summary>
|
||||
<value>To be added.</value>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
</Members>
|
||||
</Type>
|
|
@ -0,0 +1,41 @@
|
|||
<Type Name="AppleSignInAuthenticator" FullName="Xamarin.Essentials.AppleSignInAuthenticator">
|
||||
<TypeSignature Language="C#" Value="public static class AppleSignInAuthenticator" />
|
||||
<TypeSignature Language="ILAsm" Value=".class public auto ansi abstract sealed beforefieldinit AppleSignInAuthenticator extends System.Object" />
|
||||
<TypeSignature Language="DocId" Value="T:Xamarin.Essentials.AppleSignInAuthenticator" />
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Xamarin.Essentials</AssemblyName>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<Base>
|
||||
<BaseTypeName>System.Object</BaseTypeName>
|
||||
</Base>
|
||||
<Interfaces />
|
||||
<Docs>
|
||||
<summary>Native Apple Sign In authentication API.</summary>
|
||||
<remarks>This API is only supported on iOS 13.0+ and should not be called on other devices at runtime.</remarks>
|
||||
</Docs>
|
||||
<Members>
|
||||
<Member MemberName="AuthenticateAsync">
|
||||
<MemberSignature Language="C#" Value="public static System.Threading.Tasks.Task<Xamarin.Essentials.WebAuthenticatorResult> AuthenticateAsync (Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions options = null);" />
|
||||
<MemberSignature Language="ILAsm" Value=".method public static hidebysig class System.Threading.Tasks.Task`1<class Xamarin.Essentials.WebAuthenticatorResult> AuthenticateAsync(class Xamarin.Essentials.AppleSignInAuthenticator/AppleSignInOptions options) cil managed" />
|
||||
<MemberSignature Language="DocId" Value="M:Xamarin.Essentials.AppleSignInAuthenticator.AuthenticateAsync(Xamarin.Essentials.AppleSignInAuthenticator.AppleSignInOptions)" />
|
||||
<MemberType>Method</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Xamarin.Essentials</AssemblyName>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.Threading.Tasks.Task<Xamarin.Essentials.WebAuthenticatorResult></ReturnType>
|
||||
</ReturnValue>
|
||||
<Parameters>
|
||||
<Parameter Name="options" Type="Xamarin.Essentials.AppleSignInAuthenticator+AppleSignInOptions" />
|
||||
</Parameters>
|
||||
<Docs>
|
||||
<param name="options">To be added.</param>
|
||||
<summary>Performs a native Apple Sign In authentication request.</summary>
|
||||
<returns>To be added.</returns>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
</Members>
|
||||
</Type>
|
|
@ -190,6 +190,50 @@
|
|||
</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="OnResume">
|
||||
<MemberSignature Language="C#" Value="public static void OnResume ();" />
|
||||
<MemberSignature Language="ILAsm" Value=".method public static hidebysig void OnResume() cil managed" />
|
||||
<MemberSignature Language="DocId" Value="M:Xamarin.Essentials.Platform.OnResume" />
|
||||
<MemberType>Method</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Xamarin.Essentials</AssemblyName>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.Void</ReturnType>
|
||||
</ReturnValue>
|
||||
<Parameters />
|
||||
<Docs>
|
||||
<summary>Pass Resume lifecycle events of your main activity to be used for internal API handling.</summary>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="OpenUrl">
|
||||
<MemberSignature Language="C#" Value="public static bool OpenUrl (UIKit.UIApplication app, Foundation.NSUrl url, Foundation.NSDictionary options);" />
|
||||
<MemberSignature Language="ILAsm" Value=".method public static hidebysig bool OpenUrl(class UIKit.UIApplication app, class Foundation.NSUrl url, class Foundation.NSDictionary options) cil managed" />
|
||||
<MemberSignature Language="DocId" Value="M:Xamarin.Essentials.Platform.OpenUrl(UIKit.UIApplication,Foundation.NSUrl,Foundation.NSDictionary)" />
|
||||
<MemberType>Method</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Xamarin.Essentials</AssemblyName>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.Boolean</ReturnType>
|
||||
</ReturnValue>
|
||||
<Parameters>
|
||||
<Parameter Name="app" Type="UIKit.UIApplication" Index="0" FrameworkAlternate="xamarin-essentials-ios;xamarin-essentials-tvos" />
|
||||
<Parameter Name="url" Type="Foundation.NSUrl" Index="1" FrameworkAlternate="xamarin-essentials-ios;xamarin-essentials-tvos" />
|
||||
<Parameter Name="options" Type="Foundation.NSDictionary" Index="2" FrameworkAlternate="xamarin-essentials-ios;xamarin-essentials-tvos" />
|
||||
</Parameters>
|
||||
<Docs>
|
||||
<param name="app">To be added.</param>
|
||||
<param name="url">To be added.</param>
|
||||
<param name="options">To be added.</param>
|
||||
<summary>Passes the OpenUrl callback of your app to be used for internal API handling.</summary>
|
||||
<returns>To be added.</returns>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="WaitForActivityAsync">
|
||||
<MemberSignature Language="C#" Value="public static System.Threading.Tasks.Task<Android.App.Activity> WaitForActivityAsync (System.Threading.CancellationToken cancelToken = null);" />
|
||||
<MemberSignature Language="ILAsm" Value=".method public static hidebysig class System.Threading.Tasks.Task`1<class Android.App.Activity> WaitForActivityAsync(valuetype System.Threading.CancellationToken cancelToken) cil managed" />
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
<Type Name="WebAuthenticator" FullName="Xamarin.Essentials.WebAuthenticator">
|
||||
<TypeSignature Language="C#" Value="public static class WebAuthenticator" />
|
||||
<TypeSignature Language="ILAsm" Value=".class public auto ansi abstract sealed beforefieldinit WebAuthenticator extends System.Object" />
|
||||
<TypeSignature Language="DocId" Value="T:Xamarin.Essentials.WebAuthenticator" />
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Xamarin.Essentials</AssemblyName>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<Base>
|
||||
<BaseTypeName>System.Object</BaseTypeName>
|
||||
</Base>
|
||||
<Interfaces />
|
||||
<Docs>
|
||||
<summary>A web navigation API intended to be used for Authentication with external web services such as OAuth.</summary>
|
||||
<remarks>This API helps with navigating to a start URL and waiting for a callback URL to the app. Your app must be registered to handle the callback scheme you provide in the call to authenticate.</remarks>
|
||||
</Docs>
|
||||
<Members>
|
||||
<Member MemberName="AuthenticateAsync">
|
||||
<MemberSignature Language="C#" Value="public static System.Threading.Tasks.Task<Xamarin.Essentials.WebAuthenticatorResult> AuthenticateAsync (Uri url, Uri callbackUrl);" />
|
||||
<MemberSignature Language="ILAsm" Value=".method public static hidebysig class System.Threading.Tasks.Task`1<class Xamarin.Essentials.WebAuthenticatorResult> AuthenticateAsync(class System.Uri url, class System.Uri callbackUrl) cil managed" />
|
||||
<MemberSignature Language="DocId" Value="M:Xamarin.Essentials.WebAuthenticator.AuthenticateAsync(System.Uri,System.Uri)" />
|
||||
<MemberType>Method</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Xamarin.Essentials</AssemblyName>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.Threading.Tasks.Task<Xamarin.Essentials.WebAuthenticatorResult></ReturnType>
|
||||
</ReturnValue>
|
||||
<Parameters>
|
||||
<Parameter Name="url" Type="System.Uri" />
|
||||
<Parameter Name="callbackUrl" Type="System.Uri" />
|
||||
</Parameters>
|
||||
<Docs>
|
||||
<param name="url">Url to navigate to, beginning the authentication flow.</param>
|
||||
<param name="callbackUrl">Expected callback url that the navigation flow will eventually redirect to.</param>
|
||||
<summary>Begin an authentication flow by navigating to the specified url and waiting for a callback/redirect to the callbackUrl scheme.</summary>
|
||||
<returns>Returns a result parsed out from the callback url.</returns>
|
||||
<remarks>
|
||||
<para />
|
||||
</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
</Members>
|
||||
</Type>
|
|
@ -0,0 +1,59 @@
|
|||
<Type Name="WebAuthenticatorCallbackActivity" FullName="Xamarin.Essentials.WebAuthenticatorCallbackActivity">
|
||||
<TypeSignature Language="C#" Value="public abstract class WebAuthenticatorCallbackActivity : Android.App.Activity" />
|
||||
<TypeSignature Language="ILAsm" Value=".class public auto ansi abstract beforefieldinit WebAuthenticatorCallbackActivity extends Android.App.Activity" />
|
||||
<TypeSignature Language="DocId" Value="T:Xamarin.Essentials.WebAuthenticatorCallbackActivity" />
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Xamarin.Essentials</AssemblyName>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<Base>
|
||||
<BaseTypeName>Android.App.Activity</BaseTypeName>
|
||||
</Base>
|
||||
<Interfaces />
|
||||
<Docs>
|
||||
<summary>The activity meant to be subclassed and implemented to receive callbacks on Android.</summary>
|
||||
<remarks>This activity should be decorated with the appropriate Intent Filter to handle callbacks to the appropriate URI scheme.</remarks>
|
||||
</Docs>
|
||||
<Members>
|
||||
<Member MemberName=".ctor">
|
||||
<MemberSignature Language="C#" Value="protected WebAuthenticatorCallbackActivity ();" />
|
||||
<MemberSignature Language="ILAsm" Value=".method familyhidebysig specialname rtspecialname instance void .ctor() cil managed" />
|
||||
<MemberSignature Language="DocId" Value="M:Xamarin.Essentials.WebAuthenticatorCallbackActivity.#ctor" />
|
||||
<MemberType>Constructor</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Xamarin.Essentials</AssemblyName>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<Parameters />
|
||||
<Docs>
|
||||
<summary>
|
||||
<para />
|
||||
</summary>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="OnCreate">
|
||||
<MemberSignature Language="C#" Value="protected override void OnCreate (Android.OS.Bundle savedInstanceState);" />
|
||||
<MemberSignature Language="ILAsm" Value=".method familyhidebysig virtual instance void OnCreate(class Android.OS.Bundle savedInstanceState) cil managed" />
|
||||
<MemberSignature Language="DocId" Value="M:Xamarin.Essentials.WebAuthenticatorCallbackActivity.OnCreate(Android.OS.Bundle)" />
|
||||
<MemberType>Method</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Xamarin.Essentials</AssemblyName>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.Void</ReturnType>
|
||||
</ReturnValue>
|
||||
<Parameters>
|
||||
<Parameter Name="savedInstanceState" Type="Android.OS.Bundle" />
|
||||
</Parameters>
|
||||
<Docs>
|
||||
<param name="savedInstanceState">To be added.</param>
|
||||
<summary>
|
||||
<para />
|
||||
</summary>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
</Members>
|
||||
</Type>
|
|
@ -0,0 +1,225 @@
|
|||
<Type Name="WebAuthenticatorResult" FullName="Xamarin.Essentials.WebAuthenticatorResult">
|
||||
<TypeSignature Language="C#" Value="public class WebAuthenticatorResult" />
|
||||
<TypeSignature Language="ILAsm" Value=".class public auto ansi beforefieldinit WebAuthenticatorResult extends System.Object" />
|
||||
<TypeSignature Language="DocId" Value="T:Xamarin.Essentials.WebAuthenticatorResult" />
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Xamarin.Essentials</AssemblyName>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<Base>
|
||||
<BaseTypeName>System.Object</BaseTypeName>
|
||||
</Base>
|
||||
<Interfaces />
|
||||
<Docs>
|
||||
<summary>Web Authenticator Result parsed from the callback Url.</summary>
|
||||
<remarks>All of the querystring or url fragment properties are parsed into a dictionary and can be accessed by their key.</remarks>
|
||||
</Docs>
|
||||
<Members>
|
||||
<Member MemberName=".ctor">
|
||||
<MemberSignature Language="C#" Value="public WebAuthenticatorResult ();" />
|
||||
<MemberSignature Language="ILAsm" Value=".method public hidebysig specialname rtspecialname instance void .ctor() cil managed" />
|
||||
<MemberSignature Language="DocId" Value="M:Xamarin.Essentials.WebAuthenticatorResult.#ctor" />
|
||||
<MemberType>Constructor</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Xamarin.Essentials</AssemblyName>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<Parameters />
|
||||
<Docs>
|
||||
<summary>
|
||||
<para />
|
||||
</summary>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName=".ctor">
|
||||
<MemberSignature Language="C#" Value="public WebAuthenticatorResult (System.Collections.Generic.IDictionary<string,string> properties);" />
|
||||
<MemberSignature Language="ILAsm" Value=".method public hidebysig specialname rtspecialname instance void .ctor(class System.Collections.Generic.IDictionary`2<string, string> properties) cil managed" />
|
||||
<MemberSignature Language="DocId" Value="M:Xamarin.Essentials.WebAuthenticatorResult.#ctor(System.Collections.Generic.IDictionary{System.String,System.String})" />
|
||||
<MemberType>Constructor</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Xamarin.Essentials</AssemblyName>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<Parameters>
|
||||
<Parameter Name="properties" Type="System.Collections.Generic.IDictionary<System.String,System.String>" />
|
||||
</Parameters>
|
||||
<Docs>
|
||||
<param name="properties">To be added.</param>
|
||||
<summary>Create a new instance from an existing dictionary.</summary>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName=".ctor">
|
||||
<MemberSignature Language="C#" Value="public WebAuthenticatorResult (Uri uri);" />
|
||||
<MemberSignature Language="ILAsm" Value=".method public hidebysig specialname rtspecialname instance void .ctor(class System.Uri uri) cil managed" />
|
||||
<MemberSignature Language="DocId" Value="M:Xamarin.Essentials.WebAuthenticatorResult.#ctor(System.Uri)" />
|
||||
<MemberType>Constructor</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Xamarin.Essentials</AssemblyName>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<Parameters>
|
||||
<Parameter Name="uri" Type="System.Uri" />
|
||||
</Parameters>
|
||||
<Docs>
|
||||
<param name="uri">To be added.</param>
|
||||
<summary>Create a new instance by parsing a Uri's querystring parameters.</summary>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="AccessToken">
|
||||
<MemberSignature Language="C#" Value="public string AccessToken { get; }" />
|
||||
<MemberSignature Language="ILAsm" Value=".property instance string AccessToken" />
|
||||
<MemberSignature Language="DocId" Value="P:Xamarin.Essentials.WebAuthenticatorResult.AccessToken" />
|
||||
<MemberType>Property</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Xamarin.Essentials</AssemblyName>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.String</ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>The value for the `access_token` key.</summary>
|
||||
<value>To be added.</value>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="ExpiresIn">
|
||||
<MemberSignature Language="C#" Value="public Nullable<DateTimeOffset> ExpiresIn { get; }" />
|
||||
<MemberSignature Language="ILAsm" Value=".property instance valuetype System.Nullable`1<valuetype System.DateTimeOffset> ExpiresIn" />
|
||||
<MemberSignature Language="DocId" Value="P:Xamarin.Essentials.WebAuthenticatorResult.ExpiresIn" />
|
||||
<MemberType>Property</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Xamarin.Essentials</AssemblyName>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.Nullable<System.DateTimeOffset></ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>The expiry date as calculated by the timestamp of when the result was created plus the value in seconds for the `expires_in` key.</summary>
|
||||
<value>To be added.</value>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="Get">
|
||||
<MemberSignature Language="C#" Value="public string Get (string key);" />
|
||||
<MemberSignature Language="ILAsm" Value=".method public hidebysig instance string Get(string key) cil managed" />
|
||||
<MemberSignature Language="DocId" Value="M:Xamarin.Essentials.WebAuthenticatorResult.Get(System.String)" />
|
||||
<MemberType>Method</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Xamarin.Essentials</AssemblyName>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.String</ReturnType>
|
||||
</ReturnValue>
|
||||
<Parameters>
|
||||
<Parameter Name="key" Type="System.String" />
|
||||
</Parameters>
|
||||
<Docs>
|
||||
<param name="key">To be added.</param>
|
||||
<summary>Gets a value for a given key from the dictionary.</summary>
|
||||
<returns>To be added.</returns>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="Properties">
|
||||
<MemberSignature Language="C#" Value="public System.Collections.Generic.Dictionary<string,string> Properties { get; set; }" />
|
||||
<MemberSignature Language="ILAsm" Value=".property instance class System.Collections.Generic.Dictionary`2<string, string> Properties" />
|
||||
<MemberSignature Language="DocId" Value="P:Xamarin.Essentials.WebAuthenticatorResult.Properties" />
|
||||
<MemberType>Property</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Xamarin.Essentials</AssemblyName>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.Collections.Generic.Dictionary<System.String,System.String></ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>The dictionary of parsed key/value pairs.</summary>
|
||||
<value>To be added.</value>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="Put">
|
||||
<MemberSignature Language="C#" Value="public void Put (string key, string value);" />
|
||||
<MemberSignature Language="ILAsm" Value=".method public hidebysig instance void Put(string key, string value) cil managed" />
|
||||
<MemberSignature Language="DocId" Value="M:Xamarin.Essentials.WebAuthenticatorResult.Put(System.String,System.String)" />
|
||||
<MemberType>Method</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Xamarin.Essentials</AssemblyName>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.Void</ReturnType>
|
||||
</ReturnValue>
|
||||
<Parameters>
|
||||
<Parameter Name="key" Type="System.String" />
|
||||
<Parameter Name="value" Type="System.String" />
|
||||
</Parameters>
|
||||
<Docs>
|
||||
<param name="key">To be added.</param>
|
||||
<param name="value">To be added.</param>
|
||||
<summary>Puts a key/value pair into the dictionary.</summary>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="RefreshToken">
|
||||
<MemberSignature Language="C#" Value="public string RefreshToken { get; }" />
|
||||
<MemberSignature Language="ILAsm" Value=".property instance string RefreshToken" />
|
||||
<MemberSignature Language="DocId" Value="P:Xamarin.Essentials.WebAuthenticatorResult.RefreshToken" />
|
||||
<MemberType>Property</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Xamarin.Essentials</AssemblyName>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.String</ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>The value for the `refresh_token` key.</summary>
|
||||
<value>To be added.</value>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="RefreshTokenExpiresIn">
|
||||
<MemberSignature Language="C#" Value="public Nullable<DateTimeOffset> RefreshTokenExpiresIn { get; }" />
|
||||
<MemberSignature Language="ILAsm" Value=".property instance valuetype System.Nullable`1<valuetype System.DateTimeOffset> RefreshTokenExpiresIn" />
|
||||
<MemberSignature Language="DocId" Value="P:Xamarin.Essentials.WebAuthenticatorResult.RefreshTokenExpiresIn" />
|
||||
<MemberType>Property</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Xamarin.Essentials</AssemblyName>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.Nullable<System.DateTimeOffset></ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>The expiry date as calculated by the timestamp of when the result was created plus the value in seconds for the `refresh_token_expires_in` key.</summary>
|
||||
<value>To be added.</value>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="Timestamp">
|
||||
<MemberSignature Language="C#" Value="public DateTimeOffset Timestamp { get; set; }" />
|
||||
<MemberSignature Language="ILAsm" Value=".property instance valuetype System.DateTimeOffset Timestamp" />
|
||||
<MemberSignature Language="DocId" Value="P:Xamarin.Essentials.WebAuthenticatorResult.Timestamp" />
|
||||
<MemberType>Property</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Xamarin.Essentials</AssemblyName>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.DateTimeOffset</ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>The timestamp when the class was instantiated, which usually corresponds with the parsed result of a request.</summary>
|
||||
<value>To be added.</value>
|
||||
<remarks>To be added.</remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
</Members>
|
||||
</Type>
|
|
@ -93,7 +93,7 @@
|
|||
<AttributeName>System.Runtime.Versioning.TargetFramework("MonoAndroid,Version=v10.0", FrameworkDisplayName="Xamarin.Android v10.0 Support")</AttributeName>
|
||||
</Attribute>
|
||||
<Attribute>
|
||||
<AttributeName>System.Reflection.AssemblyInformationalVersion("1.0.0+a719d90eb3b235bbe16cd61ecbadc79db4d0dd7f")</AttributeName>
|
||||
<AttributeName>System.Reflection.AssemblyInformationalVersion("1.0.0+c54a859c367ff3108025090d317b2ab4c66624a9")</AttributeName>
|
||||
</Attribute>
|
||||
</Attributes>
|
||||
</Assembly>
|
||||
|
@ -108,6 +108,8 @@
|
|||
<Type Name="ActivityState" Kind="Enumeration" />
|
||||
<Type Name="ActivityStateChangedEventArgs" Kind="Class" />
|
||||
<Type Name="AppInfo" Kind="Class" />
|
||||
<Type Name="AppleSignInAuthenticator" Kind="Class" />
|
||||
<Type Name="AppleSignInAuthenticator+AppleSignInOptions" Kind="Class" />
|
||||
<Type Name="AppTheme" Kind="Enumeration" />
|
||||
<Type Name="Barometer" Kind="Class" />
|
||||
<Type Name="BarometerChangedEventArgs" Kind="Class" />
|
||||
|
@ -229,6 +231,9 @@
|
|||
<Type Name="UnitConverters" Kind="Class" />
|
||||
<Type Name="VersionTracking" Kind="Class" />
|
||||
<Type Name="Vibration" Kind="Class" />
|
||||
<Type Name="WebAuthenticator" Kind="Class" />
|
||||
<Type Name="WebAuthenticatorCallbackActivity" Kind="Class" />
|
||||
<Type Name="WebAuthenticatorResult" Kind="Class" />
|
||||
</Namespace>
|
||||
</Types>
|
||||
<Title>Untitled</Title>
|
||||
|
|
Загрузка…
Ссылка в новой задаче