diff --git a/lib/ios/iOS17CredentialProvider/XamariniOS17CredentialProvider/XamariniOS17CredentialProviderBinding/ApiDefinitions.cs b/lib/ios/iOS17CredentialProvider/XamariniOS17CredentialProvider/XamariniOS17CredentialProviderBinding/ApiDefinitions.cs index 0ab92fcff..a65968da4 100644 --- a/lib/ios/iOS17CredentialProvider/XamariniOS17CredentialProvider/XamariniOS17CredentialProviderBinding/ApiDefinitions.cs +++ b/lib/ios/iOS17CredentialProvider/XamariniOS17CredentialProvider/XamariniOS17CredentialProviderBinding/ApiDefinitions.cs @@ -5,8 +5,30 @@ using ObjCRuntime; namespace XamariniOS17CredentialProviderBinding { - // @interface ASCredentialRequestCompat : NSObject - [BaseType (typeof(NSObject))] + interface IASCredentialProviderCompatDelegate { } + + // @protocol ASCredentialProviderCompatDelegate + [Protocol, Model(AutoGeneratedName = true)] + interface ASCredentialProviderCompatDelegate + { + // @required -(void)prepareInterfaceToProvideCredentialCompatFor:(ASCredentialRequestCompat * _Nonnull)credentialRequest; + [Abstract] + [Export("prepareInterfaceToProvideCredentialCompatFor:")] + void PrepareInterfaceToProvideCredentialCompatFor(ASCredentialRequestCompat credentialRequest); + + // @required -(void)provideCredentialWithoutUserInteractionCompatFor:(ASCredentialRequestCompat * _Nonnull)credentialRequest; + [Abstract] + [Export("provideCredentialWithoutUserInteractionCompatFor:")] + void ProvideCredentialWithoutUserInteractionCompatFor(ASCredentialRequestCompat credentialRequest); + + // @required -(void)prepareInterfaceCompatForPasskeyRegistration:(ASCredentialRequestCompat * _Nonnull)registrationRequest; + [Abstract] + [Export("prepareInterfaceCompatForPasskeyRegistration:")] + void PrepareInterfaceCompatForPasskeyRegistration(ASCredentialRequestCompat registrationRequest); + } + + // @interface ASCredentialRequestCompat : NSObject + [BaseType (typeof(NSObject))] [DisableDefaultCtor] interface ASCredentialRequestCompat { @@ -62,35 +84,38 @@ namespace XamariniOS17CredentialProviderBinding [BaseType (typeof(ASCredentialProviderViewController))] interface BaseASCredentialProviderViewController { - // -(void)prepareInterfaceToProvideCredentialForRequest:(id _Nonnull)credentialRequest; - //[Export ("prepareInterfaceToProvideCredentialForRequest:")] - //void PrepareInterfaceToProvideCredentialForRequest (ASCredentialRequest credentialRequest); + // -(void)prepareInterfaceToProvideCredentialForRequest:(id _Nonnull)credentialRequest; + //[Export ("prepareInterfaceToProvideCredentialForRequest:")] + //void PrepareInterfaceToProvideCredentialForRequest (ASCredentialRequest credentialRequest); - //// -(void)provideCredentialWithoutUserInteractionForRequest:(id _Nonnull)credentialRequest; - //[Export ("provideCredentialWithoutUserInteractionForRequest:")] - //void ProvideCredentialWithoutUserInteractionForRequest (ASCredentialRequest credentialRequest); + //// -(void)provideCredentialWithoutUserInteractionForRequest:(id _Nonnull)credentialRequest; + //[Export ("provideCredentialWithoutUserInteractionForRequest:")] + //void ProvideCredentialWithoutUserInteractionForRequest (ASCredentialRequest credentialRequest); - //// -(void)prepareInterfaceForPasskeyRegistration:(id _Nonnull)registrationRequest; - //[Export ("prepareInterfaceForPasskeyRegistration:")] - //void PrepareInterfaceForPasskeyRegistration (ASCredentialRequest registrationRequest); + //// -(void)prepareInterfaceForPasskeyRegistration:(id _Nonnull)registrationRequest; + //[Export ("prepareInterfaceForPasskeyRegistration:")] + //void PrepareInterfaceForPasskeyRegistration (ASCredentialRequest registrationRequest); - // -(void)prepareInterfaceToProvideCredentialCompatFor:(ASCredentialRequestCompat * _Nonnull)credentialRequest; - [Export ("prepareInterfaceToProvideCredentialCompatFor:")] - [Abstract] - void PrepareInterfaceToProvideCredentialCompatFor (ASCredentialRequestCompat credentialRequest); + // -(void)prepareInterfaceToProvideCredentialCompatFor:(ASCredentialRequestCompat * _Nonnull)credentialRequest; + //[Export ("prepareInterfaceToProvideCredentialCompatFor:")] + // [Abstract] + // void PrepareInterfaceToProvideCredentialCompatFor (ASCredentialRequestCompat credentialRequest); - // -(void)provideCredentialWithoutUserInteractionCompatFor:(ASCredentialRequestCompat * _Nonnull)credentialRequest; - [Export ("provideCredentialWithoutUserInteractionCompatFor:")] - [Abstract] - void ProvideCredentialWithoutUserInteractionCompatFor (ASCredentialRequestCompat credentialRequest); + //// -(void)provideCredentialWithoutUserInteractionCompatFor:(ASCredentialRequestCompat * _Nonnull)credentialRequest; + //[Export ("provideCredentialWithoutUserInteractionCompatFor:")] + // [Abstract] + // void ProvideCredentialWithoutUserInteractionCompatFor (ASCredentialRequestCompat credentialRequest); - // -(void)prepareInterfaceCompatForPasskeyRegistration:(ASCredentialRequestCompat * _Nonnull)registrationRequest; - [Export ("prepareInterfaceCompatForPasskeyRegistration:")] - [Abstract] - void PrepareInterfaceCompatForPasskeyRegistration (ASCredentialRequestCompat registrationRequest); + //// -(void)prepareInterfaceCompatForPasskeyRegistration:(ASCredentialRequestCompat * _Nonnull)registrationRequest; + //[Export ("prepareInterfaceCompatForPasskeyRegistration:")] + // [Abstract] + // void PrepareInterfaceCompatForPasskeyRegistration (ASCredentialRequestCompat registrationRequest); - // -(instancetype _Nonnull)initWithNibName:(NSString * _Nullable)nibNameOrNil bundle:(NSBundle * _Nullable)nibBundleOrNil __attribute__((objc_designated_initializer)); - [Export ("initWithNibName:bundle:")] + [Export("SetCompatDelegate:")] + void SetCompatDelegate(IASCredentialProviderCompatDelegate @delegate); + + // -(instancetype _Nonnull)initWithNibName:(NSString * _Nullable)nibNameOrNil bundle:(NSBundle * _Nullable)nibBundleOrNil __attribute__((objc_designated_initializer)); + [Export ("initWithNibName:bundle:")] [DesignatedInitializer] IntPtr Constructor ([NullAllowed] string nibNameOrNil, [NullAllowed] NSBundle nibBundleOrNil); diff --git a/lib/ios/iOS17CredentialProvider/iOS17CredentialProvider/iOS17CredentialProvider/BaseASCredentialProviderViewController.swift b/lib/ios/iOS17CredentialProvider/iOS17CredentialProvider/iOS17CredentialProvider/BaseASCredentialProviderViewController.swift index a3a931389..d60009162 100644 --- a/lib/ios/iOS17CredentialProvider/iOS17CredentialProvider/iOS17CredentialProvider/BaseASCredentialProviderViewController.swift +++ b/lib/ios/iOS17CredentialProvider/iOS17CredentialProvider/iOS17CredentialProvider/BaseASCredentialProviderViewController.swift @@ -115,29 +115,34 @@ open class BaseASCredentialProviderViewController : ASCredentialProviderViewCont // MARK: iOS 17 new methods override final public func prepareInterfaceToProvideCredential(for credentialRequest: ASCredentialRequest) { - prepareInterfaceToProvideCredentialCompat(for: convertRequestToCompat(from: credentialRequest)) + guard let compatDelegate = compatDelegate else { + return + } + compatDelegate.prepareInterfaceToProvideCredentialCompat(for: convertRequestToCompat(from: credentialRequest)) } override final public func provideCredentialWithoutUserInteraction(for credentialRequest: ASCredentialRequest) { - provideCredentialWithoutUserInteractionCompat(for: convertRequestToCompat(from: credentialRequest)) + guard let compatDelegate = compatDelegate else { + return + } + compatDelegate.provideCredentialWithoutUserInteractionCompat(for: convertRequestToCompat(from: credentialRequest)) } override final public func prepareInterface(forPasskeyRegistration registrationRequest: ASCredentialRequest) { - prepareInterfaceCompat(forPasskeyRegistration: convertRequestToCompat(from: registrationRequest)) + guard let compatDelegate = compatDelegate else { + return + } + compatDelegate.prepareInterfaceCompat(forPasskeyRegistration: convertRequestToCompat(from: registrationRequest)) } - // MARK: Compat methods + // MARK: Compat + + var compatDelegate: ASCredentialProviderCompatDelegate? = nil; @objc - open func prepareInterfaceToProvideCredentialCompat(for credentialRequest: ASCredentialRequestCompat){ - } - - @objc - open func provideCredentialWithoutUserInteractionCompat(for credentialRequest: ASCredentialRequestCompat) { - } - - @objc - open func prepareInterfaceCompat(forPasskeyRegistration registrationRequest: ASCredentialRequestCompat) { + public func SetCompatDelegate(_ delegate: ASCredentialProviderCompatDelegate) + { + compatDelegate = delegate } func convertRequestToCompat(from credentialRequest: ASCredentialRequest) -> ASCredentialRequestCompat { @@ -146,3 +151,16 @@ open class BaseASCredentialProviderViewController : ASCredentialProviderViewCont credentialIdentity: credentialRequest.credentialIdentity) } } + +@objc(ASCredentialProviderCompatDelegate) +public protocol ASCredentialProviderCompatDelegate +{ + @objc + func prepareInterfaceToProvideCredentialCompat(for credentialRequest: ASCredentialRequestCompat) + + @objc + func provideCredentialWithoutUserInteractionCompat(for credentialRequest: ASCredentialRequestCompat) + + @objc + func prepareInterfaceCompat(forPasskeyRegistration registrationRequest: ASCredentialRequestCompat) +} diff --git a/src/iOS.Autofill/CredentialProviderViewController.cs b/src/iOS.Autofill/CredentialProviderViewController.cs index 377c11688..dcdf63882 100644 --- a/src/iOS.Autofill/CredentialProviderViewController.cs +++ b/src/iOS.Autofill/CredentialProviderViewController.cs @@ -50,6 +50,8 @@ namespace Bit.iOS.Autofill { ExtContext = ExtensionContext }; + var del = new ASCredentialProviderDelegate(this); + SetCompatDelegate(del); } catch (Exception ex) { @@ -164,60 +166,6 @@ namespace Bit.iOS.Autofill } } - #region iOS 17 Beta - - public override async void PrepareInterfaceToProvideCredentialCompatFor(ASCredentialRequestCompat credentialRequest) - { - try - { - InitAppIfNeeded(); - if (!await IsAuthed()) - { - await _accountsManager.NavigateOnAccountChangeAsync(false); - return; - } - _context.CredentialIdentity = credentialRequest.PasswordCredentialIdentity; - await CheckLockAsync(async () => await ProvideCredentialAsync()); - } - catch (Exception ex) - { - LoggerHelper.LogEvenIfCantBeResolved(ex); - throw; - } - } - - public override void ProvideCredentialWithoutUserInteractionCompatFor(ASCredentialRequestCompat credentialRequest) - { - Console.WriteLine("entered"); - //try - //{ - // InitAppIfNeeded(); - // await _stateService.Value.SetPasswordRepromptAutofillAsync(false); - // await _stateService.Value.SetPasswordVerifiedAutofillAsync(false); - // if (!await IsAuthed() || await IsLocked()) - // { - // var err = new NSError(new NSString("ASExtensionErrorDomain"), - // Convert.ToInt32(ASExtensionErrorCode.UserInteractionRequired), null); - // ExtensionContext.CancelRequest(err); - // return; - // } - // _context.CredentialIdentity = credentialRequest.PasswordCredentialIdentity; - // await ProvideCredentialAsync(false); - //} - //catch (Exception ex) - //{ - // LoggerHelper.LogEvenIfCantBeResolved(ex); - // throw; - //} - } - - public override void PrepareInterfaceCompatForPasskeyRegistration(ASCredentialRequestCompat registrationRequest) - { - // DO STUFF - } - - #endregion - public void CompleteRequest(string id = null, string username = null, string password = null, string totp = null) { @@ -706,4 +654,65 @@ namespace Bit.iOS.Autofill } } } + + public class ASCredentialProviderDelegate : NSObject, IASCredentialProviderCompatDelegate + { + public ASCredentialProviderDelegate(CredentialProviderViewController controller) + { + CredentialProviderViewController = controller; + } + + public CredentialProviderViewController CredentialProviderViewController { get; } + + public void PrepareInterfaceToProvideCredentialCompatFor(ASCredentialRequestCompat credentialRequest) + { + CredentialProviderViewController?.CompleteRequest(null, "lala", "qerqrw"); + //try + //{ + // InitAppIfNeeded(); + // if (!await IsAuthed()) + // { + // await _accountsManager.NavigateOnAccountChangeAsync(false); + // return; + // } + // _context.CredentialIdentity = credentialRequest.PasswordCredentialIdentity; + // await CheckLockAsync(async () => await ProvideCredentialAsync()); + //} + //catch (Exception ex) + //{ + // LoggerHelper.LogEvenIfCantBeResolved(ex); + // throw; + //} + } + + public void ProvideCredentialWithoutUserInteractionCompatFor(ASCredentialRequestCompat credentialRequest) + { + CredentialProviderViewController?.CompleteRequest(null, "nouserinteraction", "qerqrw"); + //try + //{ + // InitAppIfNeeded(); + // await _stateService.Value.SetPasswordRepromptAutofillAsync(false); + // await _stateService.Value.SetPasswordVerifiedAutofillAsync(false); + // if (!await IsAuthed() || await IsLocked()) + // { + // var err = new NSError(new NSString("ASExtensionErrorDomain"), + // Convert.ToInt32(ASExtensionErrorCode.UserInteractionRequired), null); + // ExtensionContext.CancelRequest(err); + // return; + // } + // _context.CredentialIdentity = credentialRequest.PasswordCredentialIdentity; + // await ProvideCredentialAsync(false); + //} + //catch (Exception ex) + //{ + // LoggerHelper.LogEvenIfCantBeResolved(ex); + // throw; + //} + } + + public void PrepareInterfaceCompatForPasskeyRegistration(ASCredentialRequestCompat registrationRequest) + { + CredentialProviderViewController?.CompleteRequest(null, "passkey", "qerqrw"); + } + } }