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