﻿B4i=true
Group=Default Group
ModulesStructureVersion=1
Type=Class
Version=6.3
@EndOfDesignText@
'Integrated with FirebaseAuth. V1.01
Sub Class_Globals
	Private mEventName As String 'ignore
	Private mCallBack As Object 'ignore
	Private mBase As B4XView 'ignore
	Private xui As XUI 'ignore
	Public btn As B4XView
	Private dele_gate As Object 'ignore
	Private non_ce As String 'ignore
End Sub

Public Sub Initialize (Callback As Object, EventName As String)
	mEventName = EventName
	mCallBack = Callback
End Sub

'Base type must be Object
Public Sub DesignerCreateView (Base As Object, Lbl As Label, Props As Map)
	mBase = Base
	Dim NativeButton As NativeObject
	If Main.App.OSVersion < 13 Then
		mBase.RemoveViewFromParent
		Return
	End If
	btn = NativeButton.Initialize("ASAuthorizationAppleIDButton").RunMethod("new", Null)
	Dim no As NativeObject = Me
	no.RunMethod("SetButton:", Array(btn))
	mBase.AddView(btn, 0, 0, mBase.Width, mBase.Height)
	dele_gate = no.Initialize("AuthorizationDelegate").RunMethod("new", Null)
End Sub

Private Sub Base_Resize (Width As Double, Height As Double)
	btn.SetLayoutAnimated(0, 0, 0, Width, Height)
End Sub

Private Sub Auth_Start
	Log("auth start")

End Sub

Private Sub Auth_Error (ErrorMessage As String)
	Log("Auth_Error: " & ErrorMessage)
End Sub


'Private Sub Auth_Result(Success As Boolean, Result As Object)
'	If Success Then
'		Dim no As NativeObject = Result
'		Dim credential As NativeObject = no.GetField("credential")
'		If GetType(credential) = "ASAuthorizationAppleIDCredential" Then
'			Dim Email, name As String
'			If credential.GetField("email").IsInitialized Then
'				Dim formatter As NativeObject
'				name = formatter.Initialize("NSPersonNameComponentsFormatter").RunMethod("localizedStringFromPersonNameComponents:style:options:", _
'					Array(credential.GetField("fullName"), 0, 0)).AsString
'				Email = credential.GetField("email").AsString
'			End If
'		Else
'			Log("Unexpected type: " & GetType(credential))
'		End If
'	End If
'End Sub


#if OBJC
@import CommonCrypto;
#import <FirebaseAuth/FirebaseAuth.h>
#import <AuthenticationServices/AuthenticationServices.h>
- (void) SetButton:(ASAuthorizationAppleIDButton*)btn {
	 [btn addTarget:self action:@selector(handleAuthorizationAppleIDButtonPress:) forControlEvents:UIControlEventTouchUpInside];
}
- (void) handleAuthorizationAppleIDButtonPress:(UIButton *) sender {
	NSLog(@"handleAuthorizationAppleIDButtonPress");
	[self.bi raiseEvent:nil event:@"auth_start" params:nil];
	self._non_ce = [self randomNonce:32];
	ASAuthorizationAppleIDProvider* provider = [ASAuthorizationAppleIDProvider new];
	ASAuthorizationAppleIDRequest* req = [provider createRequest];
	req.requestedScopes = @[ASAuthorizationScopeEmail, ASAuthorizationScopeFullName];
	req.nonce = [self stringBySha256HashingString:self._non_ce];

	ASAuthorizationController* controller = [[ASAuthorizationController alloc] initWithAuthorizationRequests:
		@[req]];
	controller.delegate = self._dele_gate;
	controller.presentationContextProvider = self._dele_gate;
	[self._dele_gate setValue:self.bi forKey:@"bi"];
	[self._dele_gate setValue:self._non_ce forKey:@"nonce"];
	controller.performRequests;
}
- (NSString *)stringBySha256HashingString:(NSString *)input {
  const char *string = [input UTF8String];
  unsigned char result[CC_SHA256_DIGEST_LENGTH];
  CC_SHA256(string, (CC_LONG)strlen(string), result);

  NSMutableString *hashed = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2];
  for (NSInteger i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) {
    [hashed appendFormat:@"%02x", result[i]];
  }
  return hashed;
}
- (NSString *)randomNonce:(NSInteger)length {
  NSAssert(length > 0, @"Expected nonce to have positive length");
  NSString *characterSet = @"0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._";
  NSMutableString *result = [NSMutableString string];
  NSInteger remainingLength = length;

  while (remainingLength > 0) {
    NSMutableArray *randoms = [NSMutableArray arrayWithCapacity:16];
    for (NSInteger i = 0; i < 16; i++) {
      uint8_t random = 0;
      int errorCode = SecRandomCopyBytes(kSecRandomDefault, 1, &random);
      NSAssert(errorCode == errSecSuccess, @"Unable to generate nonce: OSStatus %i", errorCode);

      [randoms addObject:@(random)];
    }

    for (NSNumber *random in randoms) {
      if (remainingLength == 0) {
        break;
      }

      if (random.unsignedIntValue < characterSet.length) {
        unichar character = [characterSet characterAtIndex:random.unsignedIntValue];
        [result appendFormat:@"%C", character];
        remainingLength--;
      }
    }
  }

  return result;
}

@end
@interface AuthorizationDelegate : NSObject<ASAuthorizationControllerDelegate, ASAuthorizationControllerPresentationContextProviding>
@property (nonatomic) B4I* bi;
@property (nonatomic) NSString* nonce;

@end
@implementation AuthorizationDelegate
- (void)authorizationController:(ASAuthorizationController *)controller 
   didCompleteWithAuthorization:(ASAuthorization *)authorization {
   NSLog(@"authorizationController");
   if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) {
    ASAuthorizationAppleIDCredential *appleIDCredential = authorization.credential;
    NSString *rawNonce = self.nonce;
    NSAssert(rawNonce != nil, @"Invalid state: A login callback was received, but no login request was sent.");

    if (appleIDCredential.identityToken == nil) {
      NSLog(@"Unable to fetch identity token.");
      return;
    }

    NSString *idToken = [[NSString alloc] initWithData:appleIDCredential.identityToken
                                              encoding:NSUTF8StringEncoding];
    if (idToken == nil) {
      NSLog(@"Unable to serialize id token from data: %@", appleIDCredential.identityToken);
    }

    // Initialize a Firebase credential.
    FIROAuthCredential *credential = [FIROAuthProvider credentialWithProviderID:@"apple.com"
                                                                        IDToken:idToken
                                                                       rawNonce:rawNonce];


    // Sign in with Firebase.
    [[FIRAuth auth] signInWithCredential:credential
                              completion:^(FIRAuthDataResult * _Nullable authResult,
                                           NSError * _Nullable error) {
		NSLog(@"signInWithCredential, error = %@", error);
      if (error != nil) {
	  
        [self.bi raiseUIEvent:nil event:@"auth_error:" params:@[[error description]]];
        return;
      }
      // Sign-in succeeded!
    }];
	 //[self.bi raiseUIEvent:nil event:@"auth_result::" params:@[@(true), authorization]];
  }

  }
 - (void)authorizationController:(ASAuthorizationController *)controller 
           didCompleteWithError:(NSError *)error {
	 NSLog(@"error: %@", error);
	 [self.bi raiseUIEvent:nil event:@"auth_error:" params:@[[error description]]];
}
- (ASPresentationAnchor)presentationAnchorForAuthorizationController:(ASAuthorizationController *)controller  {
	NSLog(@"presentationAnchorForAuthorizationController");
	return UIApplication.sharedApplication.keyWindow;
}


#End If