@@ -5,6 +5,96 @@ import { CredentialState, UNSUPPORTED, UserDetectionStatus } from './common';
55// SHA256 digest length constant
66const CC_SHA256_DIGEST_LENGTH = 32 ;
77
8+ @NativeClass ( )
9+ class ASAuthorizationControllerDelegateImpl extends NSObject implements ASAuthorizationControllerDelegate {
10+ static ObjCProtocols = [ ASAuthorizationControllerDelegate ] ;
11+ _resolve ;
12+ _reject ;
13+ _options : SignInOptions ;
14+
15+ static initWithCallback ( resolve , reject ) {
16+ const delegate = ASAuthorizationControllerDelegateImpl . new ( ) as ASAuthorizationControllerDelegateImpl ;
17+ delegate . _resolve = resolve ;
18+ delegate . _reject = reject ;
19+ return delegate ;
20+ }
21+
22+ authorizationControllerDidCompleteWithAuthorization ( controller : ASAuthorizationController , authorization : ASAuthorization ) : void {
23+ const credential = authorization . credential as ASAuthorizationAppleIDCredential ;
24+ let identityToken = null ;
25+ const identityTokenData = credential . valueForKey ( 'identityToken' ) ;
26+
27+ if ( identityTokenData ) {
28+ identityToken = NSString . alloc ( ) . initWithDataEncoding ( identityTokenData , NSUTF8StringEncoding ) ;
29+ }
30+
31+ let authorizationCode = null ;
32+ const authorizationCodeData = credential . valueForKey ( 'authorizationCode' ) ;
33+
34+ if ( authorizationCodeData ) {
35+ authorizationCode = NSString . alloc ( ) . initWithDataEncoding ( authorizationCodeData , NSUTF8StringEncoding ) ;
36+ }
37+
38+ let fullName : UserFullName = null ;
39+
40+ const fullNameData = credential . fullName ;
41+ if ( fullNameData ) {
42+ fullName = { } ;
43+ fullName . namePrefix = fullNameData . namePrefix ;
44+ fullName . givenName = fullNameData . givenName ;
45+ fullName . middleName = fullNameData . middleName ;
46+ fullName . familyName = fullNameData . familyName ;
47+ fullName . nameSuffix = fullNameData . nameSuffix ;
48+ fullName . nickname = fullNameData . nickname ;
49+ }
50+
51+ this . _resolve ( {
52+ nonce : this . _options ?. nonce || null ,
53+ user : credential . user ,
54+ fullName,
55+ realUserStatus : getRealUserStatus ( credential . realUserStatus ) ,
56+ authorizedScopes : credential . authorizedScopes ,
57+ identityToken,
58+ email : credential . email || null ,
59+ state : credential . state ,
60+ authorizationCode,
61+ } ) ;
62+ }
63+
64+ authorizationControllerDidCompleteWithError ( controller : ASAuthorizationController , error : NSError ) : void {
65+ this . _reject ?.( SignInError . fromNative ( error ) ) ;
66+ }
67+ }
68+
69+ // Presentation context provider - required by Apple for presenting the authorization UI
70+ @NativeClass ( )
71+ class ASAuthorizationControllerPresentationContextProvidingImpl extends NSObject implements ASAuthorizationControllerPresentationContextProviding {
72+ static ObjCProtocols = [ ASAuthorizationControllerPresentationContextProviding ] ;
73+ presentationAnchorForAuthorizationController ( controller : ASAuthorizationController ) : UIWindow {
74+ // Return the key window for presenting the authorization UI
75+ if ( typeof UIApplication !== 'undefined' ) {
76+ // iOS 13+ approach
77+ const scenes = UIApplication . sharedApplication . connectedScenes ;
78+ const sceneEnumerator = scenes . objectEnumerator ( ) ;
79+ let scene : UIScene ;
80+ while ( ( scene = sceneEnumerator . nextObject ( ) ) ) {
81+ if ( scene . activationState === UISceneActivationState . ForegroundActive && scene instanceof UIWindowScene ) {
82+ const windows = ( scene as UIWindowScene ) . windows ;
83+ for ( let i = 0 ; i < windows . count ; i ++ ) {
84+ const window = windows . objectAtIndex ( i ) ;
85+ if ( window . isKeyWindow ) {
86+ return window ;
87+ }
88+ }
89+ }
90+ }
91+ // Fallback for older code paths
92+ return UIApplication . sharedApplication . keyWindow || UIApplication . sharedApplication . windows . firstObject ;
93+ }
94+ return null ;
95+ }
96+ }
97+
898export class SignInError extends Error {
999 #native: NSError ;
10100 static fromNative ( native : NSError , message ?: string ) {
@@ -80,14 +170,13 @@ function sha256Hash(input: string): string {
80170export class SignIn {
81171 static #controller: ASAuthorizationController ;
82172 static #delegate: ASAuthorizationControllerDelegate ;
83- static #presentationContextProvider: ASAuthorizationControllerPresentationContextProviding ;
173+ static #presentationContextProvider: ASAuthorizationControllerPresentationContextProvidingImpl ;
84174
85175 public static signIn ( options ?: SignInOptions ) {
86176 return new Promise < User > ( ( resolve , reject ) => {
87177 if ( ! SignIn . isSupported ( ) ) {
88178 reject ( UNSUPPORTED ) ;
89179 }
90- ensureClass ( ) ;
91180
92181 this . #delegate = ASAuthorizationControllerDelegateImpl . initWithCallback ( resolve , reject ) ;
93182 ( this . #delegate as any ) . _options = options ;
@@ -126,7 +215,7 @@ export class SignIn {
126215 this . #controller = ASAuthorizationController . alloc ( ) . initWithAuthorizationRequests ( [ request ] ) ;
127216
128217 // Set up presentation context provider (required by Apple)
129- this . #presentationContextProvider = ASAuthorizationControllerPresentationContextProvidingImpl . new ( ) ;
218+ this . #presentationContextProvider = ASAuthorizationControllerPresentationContextProvidingImpl . new ( ) as ASAuthorizationControllerPresentationContextProvidingImpl ;
130219 this . #controller. presentationContextProvider = this . #presentationContextProvider;
131220
132221 this . #controller. delegate = this . #delegate;
@@ -230,110 +319,3 @@ function getRealUserStatus(status: ASUserDetectionStatus): UserDetectionStatus {
230319 return UserDetectionStatus . Unknown ;
231320 }
232321}
233-
234- let ASAuthorizationControllerDelegateImpl ;
235- let ASAuthorizationControllerPresentationContextProvidingImpl ;
236-
237- function ensureClass ( ) {
238- if ( ! SignIn . isSupported ( ) ) {
239- return ;
240- }
241-
242- if ( ASAuthorizationControllerDelegateImpl && ASAuthorizationControllerPresentationContextProvidingImpl ) {
243- return ;
244- }
245-
246- // Presentation context provider - required by Apple for presenting the authorization UI
247- @NativeClass ( )
248- class ASAuthorizationControllerPresentationContextProvidingExt extends NSObject implements ASAuthorizationControllerPresentationContextProviding {
249- static ObjCProtocols = [ ASAuthorizationControllerPresentationContextProviding ] ;
250- presentationAnchorForAuthorizationController ( controller : ASAuthorizationController ) : UIWindow {
251- // Return the key window for presenting the authorization UI
252- if ( typeof UIApplication !== 'undefined' ) {
253- // iOS 13+ approach
254- const scenes = UIApplication . sharedApplication . connectedScenes ;
255- const sceneEnumerator = scenes . objectEnumerator ( ) ;
256- let scene : UIScene ;
257- while ( ( scene = sceneEnumerator . nextObject ( ) ) ) {
258- if ( scene . activationState === UISceneActivationState . ForegroundActive && scene instanceof UIWindowScene ) {
259- const windows = ( scene as UIWindowScene ) . windows ;
260- for ( let i = 0 ; i < windows . count ; i ++ ) {
261- const window = windows . objectAtIndex ( i ) ;
262- if ( window . isKeyWindow ) {
263- return window ;
264- }
265- }
266- }
267- }
268- // Fallback for older code paths
269- return UIApplication . sharedApplication . keyWindow || UIApplication . sharedApplication . windows . firstObject ;
270- }
271- return null ;
272- }
273- }
274-
275- ASAuthorizationControllerPresentationContextProvidingImpl = ASAuthorizationControllerPresentationContextProvidingExt ;
276-
277- @NativeClass ( )
278- class ASAuthorizationControllerDelegateExt extends NSObject implements ASAuthorizationControllerDelegate {
279- static ObjCProtocols = [ ASAuthorizationControllerDelegate ] ;
280- _resolve ;
281- _reject ;
282- _options : SignInOptions ;
283-
284- static initWithCallback ( resolve , reject ) {
285- const delegate = < ASAuthorizationControllerDelegateExt > ASAuthorizationControllerDelegateExt . new ( ) ;
286- delegate . _resolve = resolve ;
287- delegate . _reject = reject ;
288- return delegate ;
289- }
290-
291- authorizationControllerDidCompleteWithAuthorization ( controller : ASAuthorizationController , authorization : ASAuthorization ) : void {
292- const credential = authorization . credential as ASAuthorizationAppleIDCredential ;
293- let identityToken = null ;
294- const identityTokenData = credential . valueForKey ( 'identityToken' ) ;
295-
296- if ( identityTokenData ) {
297- identityToken = NSString . alloc ( ) . initWithDataEncoding ( identityTokenData , NSUTF8StringEncoding ) ;
298- }
299-
300- let authorizationCode = null ;
301- const authorizationCodeData = credential . valueForKey ( 'authorizationCode' ) ;
302-
303- if ( authorizationCodeData ) {
304- authorizationCode = NSString . alloc ( ) . initWithDataEncoding ( authorizationCodeData , NSUTF8StringEncoding ) ;
305- }
306-
307- let fullName : UserFullName = null ;
308-
309- const fullNameData = credential . fullName ;
310- if ( fullNameData ) {
311- fullName = { } ;
312- fullName . namePrefix = fullNameData . namePrefix ;
313- fullName . givenName = fullNameData . givenName ;
314- fullName . middleName = fullNameData . middleName ;
315- fullName . familyName = fullNameData . familyName ;
316- fullName . nameSuffix = fullNameData . nameSuffix ;
317- fullName . nickname = fullNameData . nickname ;
318- }
319-
320- this . _resolve ( {
321- nonce : this . _options ?. nonce || null ,
322- user : credential . user ,
323- fullName,
324- realUserStatus : getRealUserStatus ( credential . realUserStatus ) ,
325- authorizedScopes : credential . authorizedScopes ,
326- identityToken,
327- email : credential . email || null ,
328- state : credential . state ,
329- authorizationCode,
330- } ) ;
331- }
332-
333- authorizationControllerDidCompleteWithError ( controller : ASAuthorizationController , error : NSError ) : void {
334- this . _reject ?.( SignInError . fromNative ( error ) ) ;
335- }
336- }
337-
338- ASAuthorizationControllerDelegateImpl = ASAuthorizationControllerDelegateExt ;
339- }
0 commit comments