1*af2ec015STomasz Sapeta import AuthenticationServices
2*af2ec015STomasz Sapeta import ABI49_0_0ExpoModulesCore
3*af2ec015STomasz Sapeta 
4*af2ec015STomasz Sapeta let credentialRevokedEventName = "Expo.appleIdCredentialRevoked"
5*af2ec015STomasz Sapeta 
6*af2ec015STomasz Sapeta public final class AppleAuthenticationModule: Module {
definitionnull7*af2ec015STomasz Sapeta   public func definition() -> ModuleDefinition {
8*af2ec015STomasz Sapeta     Name("ExpoAppleAuthentication")
9*af2ec015STomasz Sapeta 
10*af2ec015STomasz Sapeta     Events(credentialRevokedEventName)
11*af2ec015STomasz Sapeta 
12*af2ec015STomasz Sapeta     AsyncFunction("isAvailableAsync") {
13*af2ec015STomasz Sapeta       return true
14*af2ec015STomasz Sapeta     }
15*af2ec015STomasz Sapeta 
16*af2ec015STomasz Sapeta     AsyncFunction("requestAsync") { (options: AppleAuthenticationRequestOptions, promise: Promise) in
17*af2ec015STomasz Sapeta       AppleAuthenticationRequest(options: options).performRequest { response, error in
18*af2ec015STomasz Sapeta         if let error {
19*af2ec015STomasz Sapeta           promise.reject(error)
20*af2ec015STomasz Sapeta         } else {
21*af2ec015STomasz Sapeta           promise.resolve(response)
22*af2ec015STomasz Sapeta         }
23*af2ec015STomasz Sapeta       }
24*af2ec015STomasz Sapeta     }
25*af2ec015STomasz Sapeta 
26*af2ec015STomasz Sapeta     AsyncFunction("getCredentialStateAsync") { (userId: String, promise: Promise) in
27*af2ec015STomasz Sapeta       let appleIdProvider = ASAuthorizationAppleIDProvider()
28*af2ec015STomasz Sapeta 
29*af2ec015STomasz Sapeta       appleIdProvider.getCredentialState(forUserID: userId) { credentialState, _ in
30*af2ec015STomasz Sapeta         // We can ignore the error as the credential state cannot be nil
31*af2ec015STomasz Sapeta         // and the error may occur only when the credential state is `notFound`
32*af2ec015STomasz Sapeta         promise.resolve(credentialStateToInt(credentialState))
33*af2ec015STomasz Sapeta       }
34*af2ec015STomasz Sapeta     }
35*af2ec015STomasz Sapeta 
36*af2ec015STomasz Sapeta     View(AppleAuthenticationButton.self) {
37*af2ec015STomasz Sapeta       Events("onButtonPress")
38*af2ec015STomasz Sapeta 
39*af2ec015STomasz Sapeta       Prop("buttonType") { (view, type: ButtonType?) in
40*af2ec015STomasz Sapeta         let type = type ?? .signIn
41*af2ec015STomasz Sapeta 
42*af2ec015STomasz Sapeta         if view.type != type {
43*af2ec015STomasz Sapeta           view.type = type
44*af2ec015STomasz Sapeta           view.needsUpdate = true
45*af2ec015STomasz Sapeta         }
46*af2ec015STomasz Sapeta       }
47*af2ec015STomasz Sapeta 
48*af2ec015STomasz Sapeta       Prop("buttonStyle") { (view, style: ButtonStyle?) in
49*af2ec015STomasz Sapeta         let style = style ?? .white
50*af2ec015STomasz Sapeta 
51*af2ec015STomasz Sapeta         if view.style != style {
52*af2ec015STomasz Sapeta           view.style = style
53*af2ec015STomasz Sapeta           view.needsUpdate = true
54*af2ec015STomasz Sapeta         }
55*af2ec015STomasz Sapeta       }
56*af2ec015STomasz Sapeta 
57*af2ec015STomasz Sapeta       Prop("cornerRadius") { (view, cornerRadius: Double) in
58*af2ec015STomasz Sapeta         view.cornerRadius = cornerRadius
59*af2ec015STomasz Sapeta       }
60*af2ec015STomasz Sapeta 
61*af2ec015STomasz Sapeta       OnViewDidUpdateProps { view in
62*af2ec015STomasz Sapeta         view.updateChildIfNeeded()
63*af2ec015STomasz Sapeta       }
64*af2ec015STomasz Sapeta     }
65*af2ec015STomasz Sapeta 
66*af2ec015STomasz Sapeta     OnStartObserving {
67*af2ec015STomasz Sapeta       NotificationCenter.default.addObserver(
68*af2ec015STomasz Sapeta         self,
69*af2ec015STomasz Sapeta         selector: #selector(didRevokeCredential(_:)),
70*af2ec015STomasz Sapeta         name: ASAuthorizationAppleIDProvider.credentialRevokedNotification,
71*af2ec015STomasz Sapeta         object: nil
72*af2ec015STomasz Sapeta       )
73*af2ec015STomasz Sapeta     }
74*af2ec015STomasz Sapeta 
75*af2ec015STomasz Sapeta     OnStopObserving {
76*af2ec015STomasz Sapeta       NotificationCenter.default.removeObserver(
77*af2ec015STomasz Sapeta         self,
78*af2ec015STomasz Sapeta         name: ASAuthorizationAppleIDProvider.credentialRevokedNotification,
79*af2ec015STomasz Sapeta         object: nil
80*af2ec015STomasz Sapeta       )
81*af2ec015STomasz Sapeta     }
82*af2ec015STomasz Sapeta   }
83*af2ec015STomasz Sapeta 
84*af2ec015STomasz Sapeta   @objc
didRevokeCredentialnull85*af2ec015STomasz Sapeta   func didRevokeCredential(_ notification: Notification) {
86*af2ec015STomasz Sapeta     sendEvent(credentialRevokedEventName)
87*af2ec015STomasz Sapeta   }
88*af2ec015STomasz Sapeta }
89