react-native-authsignal 0.4.5 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/build.gradle +2 -3
- package/android/gradle/wrapper/gradle-wrapper.properties +2 -1
- package/android/gradle.properties +2 -2
- package/android/src/main/java/com/authsignal/react/AuthsignalEmailModule.java +133 -0
- package/android/src/main/java/com/authsignal/react/AuthsignalModule.java +10 -2
- package/android/src/main/java/com/authsignal/react/AuthsignalPackage.java +4 -1
- package/android/src/main/java/com/authsignal/react/AuthsignalPasskeyModule.java +8 -6
- package/android/src/main/java/com/authsignal/react/AuthsignalPushModule.java +3 -1
- package/android/src/main/java/com/authsignal/react/AuthsignalSMSModule.java +133 -0
- package/android/src/main/java/com/authsignal/react/AuthsignalTOTPModule.java +112 -0
- package/ios/Authsignal.xcodeproj/project.pbxproj +16 -4
- package/ios/AuthsignalEmailModule.m +22 -0
- package/ios/AuthsignalEmailModule.swift +109 -0
- package/ios/AuthsignalModule.m +9 -63
- package/ios/AuthsignalModule.swift +87 -0
- package/ios/AuthsignalPasskeyModule.m +1 -1
- package/ios/AuthsignalPasskeyModule.swift +11 -9
- package/ios/AuthsignalPushModule.m +1 -1
- package/ios/AuthsignalPushModule.swift +9 -7
- package/ios/AuthsignalSMSModule.m +22 -0
- package/ios/AuthsignalSMSModule.swift +109 -0
- package/ios/AuthsignalTOTPModule.m +18 -0
- package/ios/AuthsignalTOTPModule.swift +82 -0
- package/lib/commonjs/email.js +80 -0
- package/lib/commonjs/email.js.map +1 -0
- package/lib/commonjs/error.js +18 -0
- package/lib/commonjs/error.js.map +1 -1
- package/lib/commonjs/index.js +27 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/passkey.js +4 -4
- package/lib/commonjs/passkey.js.map +1 -1
- package/lib/commonjs/sms.js +80 -0
- package/lib/commonjs/sms.js.map +1 -0
- package/lib/commonjs/totp.js +68 -0
- package/lib/commonjs/totp.js.map +1 -0
- package/lib/module/email.js +73 -0
- package/lib/module/email.js.map +1 -0
- package/lib/module/error.js +17 -0
- package/lib/module/error.js.map +1 -1
- package/lib/module/index.js +27 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/passkey.js +4 -4
- package/lib/module/passkey.js.map +1 -1
- package/lib/module/sms.js +73 -0
- package/lib/module/sms.js.map +1 -0
- package/lib/module/totp.js +61 -0
- package/lib/module/totp.js.map +1 -0
- package/lib/typescript/email.d.ts +22 -0
- package/lib/typescript/email.d.ts.map +1 -0
- package/lib/typescript/error.d.ts +9 -0
- package/lib/typescript/error.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +8 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/passkey.d.ts +3 -3
- package/lib/typescript/passkey.d.ts.map +1 -1
- package/lib/typescript/push.d.ts +1 -1
- package/lib/typescript/sms.d.ts +22 -0
- package/lib/typescript/sms.d.ts.map +1 -0
- package/lib/typescript/totp.d.ts +22 -0
- package/lib/typescript/totp.d.ts.map +1 -0
- package/lib/typescript/types.d.ts +10 -2
- package/lib/typescript/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/react-native-authsignal.podspec +1 -1
- package/src/email.ts +94 -0
- package/src/error.ts +19 -0
- package/src/index.tsx +17 -0
- package/src/passkey.ts +5 -5
- package/src/push.ts +1 -1
- package/src/sms.ts +96 -0
- package/src/totp.ts +83 -0
- package/src/types.ts +12 -2
- package/yarn.lock +109 -83
- package/ios/AuthsignalModule.h +0 -11
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import Security
|
|
2
|
+
import Foundation
|
|
3
|
+
import Authsignal
|
|
4
|
+
|
|
5
|
+
@objc(AuthsignalEmailModule)
|
|
6
|
+
class AuthsignalEmailModule: NSObject {
|
|
7
|
+
var authsignal: AuthsignalEmail?
|
|
8
|
+
|
|
9
|
+
@objc static func requiresMainQueueSetup() -> Bool {
|
|
10
|
+
return true
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
@objc func initialize(
|
|
14
|
+
_ tenantID: NSString,
|
|
15
|
+
withBaseURL baseURL: NSString,
|
|
16
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
17
|
+
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
18
|
+
) -> Void {
|
|
19
|
+
self.authsignal = AuthsignalEmail(tenantID: tenantID as String, baseURL: baseURL as String)
|
|
20
|
+
|
|
21
|
+
resolve(nil)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@objc func enroll(
|
|
25
|
+
_ email: NSString,
|
|
26
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
27
|
+
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
28
|
+
) -> Void {
|
|
29
|
+
if (authsignal == nil) {
|
|
30
|
+
resolve(nil)
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let emailStr = email as String
|
|
35
|
+
|
|
36
|
+
Task.init {
|
|
37
|
+
let response = await authsignal!.enroll(email: emailStr)
|
|
38
|
+
|
|
39
|
+
if (response.errorCode == "TOKEN_NOT_SET") {
|
|
40
|
+
reject("tokenNotSetError", "TOKEN_NOT_SET", nil)
|
|
41
|
+
} else if (response.error != nil) {
|
|
42
|
+
reject("enrollError", response.error, nil)
|
|
43
|
+
} else {
|
|
44
|
+
let enrollResponse: [String: String?] = [
|
|
45
|
+
"userAuthenticatorId": response.data!.userAuthenticatorId,
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
resolve(enrollResponse)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@objc func challenge(
|
|
54
|
+
_ resolve: @escaping RCTPromiseResolveBlock,
|
|
55
|
+
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
56
|
+
) -> Void {
|
|
57
|
+
if (authsignal == nil) {
|
|
58
|
+
resolve(nil)
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
Task.init {
|
|
63
|
+
let response = await authsignal!.challenge()
|
|
64
|
+
|
|
65
|
+
if (response.errorCode == "TOKEN_NOT_SET") {
|
|
66
|
+
reject("tokenNotSetError", "TOKEN_NOT_SET", nil)
|
|
67
|
+
} else if (response.error != nil) {
|
|
68
|
+
reject("challengeError", response.error, nil)
|
|
69
|
+
} else {
|
|
70
|
+
let challengeResponse: [String: String?] = [
|
|
71
|
+
"challengeId": response.data!.challengeId,
|
|
72
|
+
]
|
|
73
|
+
|
|
74
|
+
resolve(challengeResponse)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@objc func verify(
|
|
80
|
+
_ code: NSString,
|
|
81
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
82
|
+
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
83
|
+
) -> Void {
|
|
84
|
+
if (authsignal == nil) {
|
|
85
|
+
resolve(nil)
|
|
86
|
+
return
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
let codeStr = code as String
|
|
90
|
+
|
|
91
|
+
Task.init {
|
|
92
|
+
let response = await authsignal!.verify(code: codeStr)
|
|
93
|
+
|
|
94
|
+
if (response.errorCode == "TOKEN_NOT_SET") {
|
|
95
|
+
reject("tokenNotSetError", "TOKEN_NOT_SET", nil)
|
|
96
|
+
} else if (response.error != nil) {
|
|
97
|
+
reject("verifyError", response.error, nil)
|
|
98
|
+
} else {
|
|
99
|
+
let verifyResponse: [String: Any?] = [
|
|
100
|
+
"isVerified": response.data!.isVerified,
|
|
101
|
+
"token": response.data!.token,
|
|
102
|
+
"failureReason": response.data!.failureReason,
|
|
103
|
+
]
|
|
104
|
+
|
|
105
|
+
resolve(verifyResponse)
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
package/ios/AuthsignalModule.m
CHANGED
|
@@ -1,68 +1,14 @@
|
|
|
1
|
-
#import
|
|
2
|
-
#import <
|
|
1
|
+
#import <React/RCTBridgeModule.h>
|
|
2
|
+
#import <Foundation/Foundation.h>
|
|
3
3
|
|
|
4
|
-
@interface AuthsignalModule
|
|
5
|
-
@property (strong, nonatomic) NSObject *session;
|
|
6
|
-
@end
|
|
7
|
-
|
|
8
|
-
@implementation AuthsignalModule
|
|
9
|
-
|
|
10
|
-
RCT_EXPORT_MODULE();
|
|
4
|
+
@interface RCT_EXTERN_MODULE(AuthsignalModule, NSObject)
|
|
11
5
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
6
|
+
RCT_EXTERN_METHOD(launch:(NSString)url
|
|
7
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
8
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
16
9
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
NSString *scheme = @"authsignal";
|
|
21
|
-
|
|
22
|
-
ASWebAuthenticationSession* authenticationSession = [[ASWebAuthenticationSession alloc] initWithURL:authUrl
|
|
23
|
-
callbackURLScheme:scheme
|
|
24
|
-
completionHandler:^(NSURL * _Nullable callbackURL,
|
|
25
|
-
NSError * _Nullable error) {
|
|
26
|
-
if (callbackURL) {
|
|
27
|
-
NSURLComponents *components = [[NSURLComponents alloc] initWithString:callbackURL.absoluteString];
|
|
28
|
-
NSString *token;
|
|
29
|
-
|
|
30
|
-
for (NSURLQueryItem *item in components.queryItems) {
|
|
31
|
-
if ([item.name isEqualToString:@"token"]) {
|
|
32
|
-
token = item.value;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
resolve(token);
|
|
37
|
-
} else if (error) {
|
|
38
|
-
if ([[error domain] isEqualToString:ASWebAuthenticationSessionErrorDomain] &&
|
|
39
|
-
[error code] == ASWebAuthenticationSessionErrorCodeCanceledLogin) {
|
|
40
|
-
resolve(nil);
|
|
41
|
-
} else {
|
|
42
|
-
reject(@"AS_ERROR", error.description, nil);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
self.session = nil;
|
|
47
|
-
}];
|
|
48
|
-
|
|
49
|
-
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000
|
|
50
|
-
if (@available(iOS 13, *)) {
|
|
51
|
-
authenticationSession.presentationContextProvider = self;
|
|
52
|
-
authenticationSession.prefersEphemeralWebBrowserSession = NO;
|
|
53
|
-
}
|
|
54
|
-
#endif
|
|
55
|
-
|
|
56
|
-
self.session = authenticationSession;
|
|
57
|
-
|
|
58
|
-
[(ASWebAuthenticationSession*) self.session start];
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000
|
|
62
|
-
- (ASPresentationAnchor)presentationAnchorForWebAuthenticationSession:(ASWebAuthenticationSession *)session API_AVAILABLE(ios(13.0)){
|
|
63
|
-
return UIApplication.sharedApplication.keyWindow;
|
|
64
|
-
}
|
|
65
|
-
#endif
|
|
10
|
+
RCT_EXTERN_METHOD(setToken:(NSString)token
|
|
11
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
12
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
66
13
|
|
|
67
14
|
@end
|
|
68
|
-
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import AuthenticationServices
|
|
2
|
+
import Authsignal
|
|
3
|
+
import Foundation
|
|
4
|
+
import React
|
|
5
|
+
import Security
|
|
6
|
+
|
|
7
|
+
@objc(AuthsignalModule)
|
|
8
|
+
class AuthsignalModule: NSObject, ASWebAuthenticationPresentationContextProviding {
|
|
9
|
+
var session: ASWebAuthenticationSession?
|
|
10
|
+
|
|
11
|
+
@objc static func requiresMainQueueSetup() -> Bool {
|
|
12
|
+
return true
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@objc func methodQueue() -> DispatchQueue {
|
|
16
|
+
return DispatchQueue.main
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@objc func launch(
|
|
20
|
+
_ url: NSString,
|
|
21
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
22
|
+
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
23
|
+
) -> Void {
|
|
24
|
+
let scheme = "authsignal"
|
|
25
|
+
let urlStr = url as String?
|
|
26
|
+
|
|
27
|
+
guard let authUrl = URL(string: urlStr!) else {
|
|
28
|
+
reject("AS_ERROR", "Invalid URL", nil)
|
|
29
|
+
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let authenticationSession = ASWebAuthenticationSession(url: authUrl, callbackURLScheme: scheme) { callbackURL, error in
|
|
34
|
+
if let error {
|
|
35
|
+
if self.isCanceledLoginError(error) {
|
|
36
|
+
resolve(nil)
|
|
37
|
+
} else {
|
|
38
|
+
reject("AS_ERROR", error.localizedDescription, nil)
|
|
39
|
+
}
|
|
40
|
+
} else if let callbackURL = callbackURL {
|
|
41
|
+
let components = URLComponents(string: callbackURL.absoluteString)
|
|
42
|
+
var token: String?
|
|
43
|
+
|
|
44
|
+
for item in components?.queryItems ?? [] {
|
|
45
|
+
if item.name == "token" {
|
|
46
|
+
token = item.value
|
|
47
|
+
|
|
48
|
+
TokenCache.shared.token = item.value
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
resolve(token)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
self.session = nil
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
#if os(iOS) && swift(>=5.1)
|
|
59
|
+
if #available(iOS 13, *) {
|
|
60
|
+
authenticationSession.presentationContextProvider = self
|
|
61
|
+
authenticationSession.prefersEphemeralWebBrowserSession = false
|
|
62
|
+
}
|
|
63
|
+
#endif
|
|
64
|
+
|
|
65
|
+
self.session = authenticationSession
|
|
66
|
+
|
|
67
|
+
self.session?.start()
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@objc func setToken(
|
|
71
|
+
_ token: NSString,
|
|
72
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
73
|
+
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
74
|
+
) -> Void {
|
|
75
|
+
TokenCache.shared.token = token as String
|
|
76
|
+
|
|
77
|
+
resolve("token_set")
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
private func isCanceledLoginError(_ error: Error) -> Bool {
|
|
81
|
+
(error as NSError).code == ASWebAuthenticationSessionError.canceledLogin.rawValue
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
|
|
85
|
+
return UIApplication.shared.keyWindow!
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -9,7 +9,7 @@ RCT_EXTERN_METHOD(initialize:(NSString)tenantID
|
|
|
9
9
|
rejecter:(RCTPromiseRejectBlock)reject)
|
|
10
10
|
|
|
11
11
|
RCT_EXTERN_METHOD(signUp:(NSString)token
|
|
12
|
-
|
|
12
|
+
withUsername:(NSString)username
|
|
13
13
|
withDisplayName:(NSString)displayName
|
|
14
14
|
resolver:(RCTPromiseResolveBlock)resolve
|
|
15
15
|
rejecter:(RCTPromiseRejectBlock)reject)
|
|
@@ -22,8 +22,8 @@ class AuthsignalPasskeyModule: NSObject {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
@objc func signUp(
|
|
25
|
-
_ token: NSString
|
|
26
|
-
|
|
25
|
+
_ token: NSString?,
|
|
26
|
+
withUsername username: NSString?,
|
|
27
27
|
withDisplayName displayName: NSString?,
|
|
28
28
|
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
29
29
|
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
@@ -33,14 +33,16 @@ class AuthsignalPasskeyModule: NSObject {
|
|
|
33
33
|
return
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
let tokenStr = token as String
|
|
37
|
-
let
|
|
36
|
+
let tokenStr = token as String?
|
|
37
|
+
let usernameStr = username as String?
|
|
38
38
|
let displayNameStr = displayName as String?
|
|
39
39
|
|
|
40
40
|
Task.init {
|
|
41
|
-
let response = await authsignal!.signUp(token: tokenStr,
|
|
41
|
+
let response = await authsignal!.signUp(token: tokenStr, username: usernameStr, displayName: displayNameStr)
|
|
42
42
|
|
|
43
|
-
if (response.
|
|
43
|
+
if (response.errorCode == "TOKEN_NOT_SET") {
|
|
44
|
+
reject("tokenNotSetError", "TOKEN_NOT_SET", nil)
|
|
45
|
+
} else if (response.error != nil) {
|
|
44
46
|
reject("signUpError", response.error, nil)
|
|
45
47
|
} else {
|
|
46
48
|
let signUpResponse: [String: String?] = [
|
|
@@ -76,7 +78,7 @@ class AuthsignalPasskeyModule: NSObject {
|
|
|
76
78
|
preferImmediatelyAvailableCredentials: preferImmediatelyAvailableCredentials
|
|
77
79
|
)
|
|
78
80
|
|
|
79
|
-
if (response.errorCode ==
|
|
81
|
+
if (response.errorCode == "SIGN_IN_CANCELED") {
|
|
80
82
|
reject("signInCanceled", "SIGN_IN_CANCELED", nil)
|
|
81
83
|
} else if (response.error != nil) {
|
|
82
84
|
reject("signInError", response.error, nil)
|
|
@@ -86,8 +88,8 @@ class AuthsignalPasskeyModule: NSObject {
|
|
|
86
88
|
"token": response.data!.token,
|
|
87
89
|
"userId": response.data!.userId,
|
|
88
90
|
"userAuthenticatorId": response.data!.userAuthenticatorId,
|
|
89
|
-
"
|
|
90
|
-
"
|
|
91
|
+
"username": response.data!.username,
|
|
92
|
+
"displayName": response.data!.displayName,
|
|
91
93
|
]
|
|
92
94
|
|
|
93
95
|
resolve(signInResponse)
|
|
@@ -21,7 +21,7 @@ RCT_EXTERN_METHOD(removeCredential:(RCTPromiseResolveBlock)resolve
|
|
|
21
21
|
RCT_EXTERN_METHOD(getChallenge:(RCTPromiseResolveBlock)resolve
|
|
22
22
|
rejecter:(RCTPromiseRejectBlock)reject)
|
|
23
23
|
|
|
24
|
-
RCT_EXTERN_METHOD(updateChallenge:(NSString)
|
|
24
|
+
RCT_EXTERN_METHOD(updateChallenge:(NSString)challengeId
|
|
25
25
|
withApproval:(BOOL)approved
|
|
26
26
|
withVerificationCode:(NSString)verificationCode
|
|
27
27
|
resolver:(RCTPromiseResolveBlock)resolve
|
|
@@ -37,7 +37,7 @@ class AuthsignalPushModule: NSObject {
|
|
|
37
37
|
reject("getCredential error", error, nil)
|
|
38
38
|
} else if let data = response.data {
|
|
39
39
|
let credential: [String: String?] = [
|
|
40
|
-
"
|
|
40
|
+
"credentialId": response.data!.credentialId,
|
|
41
41
|
"createdAt": response.data!.createdAt,
|
|
42
42
|
"lastAuthenticatedAt": response.data!.lastAuthenticatedAt,
|
|
43
43
|
]
|
|
@@ -50,7 +50,7 @@ class AuthsignalPushModule: NSObject {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
@objc func addCredential(
|
|
53
|
-
_ token: NSString
|
|
53
|
+
_ token: NSString?,
|
|
54
54
|
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
55
55
|
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
56
56
|
) -> Void {
|
|
@@ -59,12 +59,14 @@ class AuthsignalPushModule: NSObject {
|
|
|
59
59
|
return
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
let tokenStr = token as String
|
|
62
|
+
let tokenStr = token as String?
|
|
63
63
|
|
|
64
64
|
Task.init {
|
|
65
65
|
let response = await authsignal.addCredential(token: tokenStr)
|
|
66
66
|
|
|
67
|
-
if
|
|
67
|
+
if (response.errorCode == "TOKEN_NOT_SET") {
|
|
68
|
+
reject("tokenNotSetError", "TOKEN_NOT_SET", nil)
|
|
69
|
+
} else if let error = response.error {
|
|
68
70
|
reject("addCredential error", error, nil)
|
|
69
71
|
} else {
|
|
70
72
|
resolve(response.data)
|
|
@@ -113,7 +115,7 @@ class AuthsignalPushModule: NSObject {
|
|
|
113
115
|
}
|
|
114
116
|
|
|
115
117
|
@objc func updateChallenge(
|
|
116
|
-
_
|
|
118
|
+
_ challengeId: NSString,
|
|
117
119
|
withApproval approved: Bool,
|
|
118
120
|
withVerificationCode verificationCode: NSString,
|
|
119
121
|
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
@@ -124,13 +126,13 @@ class AuthsignalPushModule: NSObject {
|
|
|
124
126
|
return
|
|
125
127
|
}
|
|
126
128
|
|
|
127
|
-
let challenge =
|
|
129
|
+
let challenge = challengeId as String
|
|
128
130
|
let approval = approved as Bool
|
|
129
131
|
let code = verificationCode as String?
|
|
130
132
|
|
|
131
133
|
Task.init {
|
|
132
134
|
let response = await authsignal.updateChallenge(
|
|
133
|
-
|
|
135
|
+
challengeId: challenge,
|
|
134
136
|
approved: approval,
|
|
135
137
|
verificationCode: code
|
|
136
138
|
)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#import <React/RCTBridgeModule.h>
|
|
2
|
+
#import <Foundation/Foundation.h>
|
|
3
|
+
|
|
4
|
+
@interface RCT_EXTERN_MODULE(AuthsignalSMSModule, NSObject)
|
|
5
|
+
|
|
6
|
+
RCT_EXTERN_METHOD(initialize:(NSString)tenantID
|
|
7
|
+
withBaseURL:(NSString)baseURL
|
|
8
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
9
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
10
|
+
|
|
11
|
+
RCT_EXTERN_METHOD(enroll:(NSString)phoneNumber
|
|
12
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
13
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
14
|
+
|
|
15
|
+
RCT_EXTERN_METHOD(challenge:(RCTPromiseResolveBlock)resolve
|
|
16
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
17
|
+
|
|
18
|
+
RCT_EXTERN_METHOD(verify:(NSString)code
|
|
19
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
20
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
21
|
+
|
|
22
|
+
@end
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import Security
|
|
2
|
+
import Foundation
|
|
3
|
+
import Authsignal
|
|
4
|
+
|
|
5
|
+
@objc(AuthsignalSMSModule)
|
|
6
|
+
class AuthsignalSMSModule: NSObject {
|
|
7
|
+
var authsignal: AuthsignalSMS?
|
|
8
|
+
|
|
9
|
+
@objc static func requiresMainQueueSetup() -> Bool {
|
|
10
|
+
return true
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
@objc func initialize(
|
|
14
|
+
_ tenantID: NSString,
|
|
15
|
+
withBaseURL baseURL: NSString,
|
|
16
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
17
|
+
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
18
|
+
) -> Void {
|
|
19
|
+
self.authsignal = AuthsignalSMS(tenantID: tenantID as String, baseURL: baseURL as String)
|
|
20
|
+
|
|
21
|
+
resolve(nil)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@objc func enroll(
|
|
25
|
+
_ phoneNumber: NSString,
|
|
26
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
27
|
+
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
28
|
+
) -> Void {
|
|
29
|
+
if (authsignal == nil) {
|
|
30
|
+
resolve(nil)
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let phoneNumberStr = phoneNumber as String
|
|
35
|
+
|
|
36
|
+
Task.init {
|
|
37
|
+
let response = await authsignal!.enroll(phoneNumber: phoneNumberStr)
|
|
38
|
+
|
|
39
|
+
if (response.errorCode == "TOKEN_NOT_SET") {
|
|
40
|
+
reject("tokenNotSetError", "TOKEN_NOT_SET", nil)
|
|
41
|
+
} else if (response.error != nil) {
|
|
42
|
+
reject("enrollError", response.error, nil)
|
|
43
|
+
} else {
|
|
44
|
+
let enrollResponse: [String: String?] = [
|
|
45
|
+
"userAuthenticatorId": response.data!.userAuthenticatorId,
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
resolve(enrollResponse)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@objc func challenge(
|
|
54
|
+
_ resolve: @escaping RCTPromiseResolveBlock,
|
|
55
|
+
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
56
|
+
) -> Void {
|
|
57
|
+
if (authsignal == nil) {
|
|
58
|
+
resolve(nil)
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
Task.init {
|
|
63
|
+
let response = await authsignal!.challenge()
|
|
64
|
+
|
|
65
|
+
if (response.errorCode == "TOKEN_NOT_SET") {
|
|
66
|
+
reject("tokenNotSetError", "TOKEN_NOT_SET", nil)
|
|
67
|
+
} else if (response.error != nil) {
|
|
68
|
+
reject("challengeError", response.error, nil)
|
|
69
|
+
} else {
|
|
70
|
+
let challengeResponse: [String: String?] = [
|
|
71
|
+
"challengeId": response.data!.challengeId,
|
|
72
|
+
]
|
|
73
|
+
|
|
74
|
+
resolve(challengeResponse)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@objc func verify(
|
|
80
|
+
_ code: NSString,
|
|
81
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
82
|
+
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
83
|
+
) -> Void {
|
|
84
|
+
if (authsignal == nil) {
|
|
85
|
+
resolve(nil)
|
|
86
|
+
return
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
let codeStr = code as String
|
|
90
|
+
|
|
91
|
+
Task.init {
|
|
92
|
+
let response = await authsignal!.verify(code: codeStr)
|
|
93
|
+
|
|
94
|
+
if (response.errorCode == "TOKEN_NOT_SET") {
|
|
95
|
+
reject("tokenNotSetError", "TOKEN_NOT_SET", nil)
|
|
96
|
+
} else if (response.error != nil) {
|
|
97
|
+
reject("verifyError", response.error, nil)
|
|
98
|
+
} else {
|
|
99
|
+
let verifyResponse: [String: Any?] = [
|
|
100
|
+
"isVerified": response.data!.isVerified,
|
|
101
|
+
"token": response.data!.token,
|
|
102
|
+
"failureReason": response.data!.failureReason,
|
|
103
|
+
]
|
|
104
|
+
|
|
105
|
+
resolve(verifyResponse)
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#import <React/RCTBridgeModule.h>
|
|
2
|
+
#import <Foundation/Foundation.h>
|
|
3
|
+
|
|
4
|
+
@interface RCT_EXTERN_MODULE(AuthsignalTOTPModule, NSObject)
|
|
5
|
+
|
|
6
|
+
RCT_EXTERN_METHOD(initialize:(NSString)tenantID
|
|
7
|
+
withBaseURL:(NSString)baseURL
|
|
8
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
9
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
10
|
+
|
|
11
|
+
RCT_EXTERN_METHOD(enroll:(RCTPromiseResolveBlock)resolve
|
|
12
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
13
|
+
|
|
14
|
+
RCT_EXTERN_METHOD(verify:(NSString)code
|
|
15
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
16
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
17
|
+
|
|
18
|
+
@end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import Security
|
|
2
|
+
import Foundation
|
|
3
|
+
import Authsignal
|
|
4
|
+
|
|
5
|
+
@objc(AuthsignalTOTPModule)
|
|
6
|
+
class AuthsignalTOTPModule: NSObject {
|
|
7
|
+
var authsignal: AuthsignalTOTP?
|
|
8
|
+
|
|
9
|
+
@objc static func requiresMainQueueSetup() -> Bool {
|
|
10
|
+
return true
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
@objc func initialize(
|
|
14
|
+
_ tenantID: NSString,
|
|
15
|
+
withBaseURL baseURL: NSString,
|
|
16
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
17
|
+
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
18
|
+
) -> Void {
|
|
19
|
+
self.authsignal = AuthsignalTOTP(tenantID: tenantID as String, baseURL: baseURL as String)
|
|
20
|
+
|
|
21
|
+
resolve(nil)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@objc func enroll(
|
|
25
|
+
_ resolve: @escaping RCTPromiseResolveBlock,
|
|
26
|
+
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
27
|
+
) -> Void {
|
|
28
|
+
if (authsignal == nil) {
|
|
29
|
+
resolve(nil)
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
Task.init {
|
|
34
|
+
let response = await authsignal!.enroll()
|
|
35
|
+
|
|
36
|
+
if (response.errorCode == "TOKEN_NOT_SET") {
|
|
37
|
+
reject("tokenNotSetError", "TOKEN_NOT_SET", nil)
|
|
38
|
+
} else if (response.error != nil) {
|
|
39
|
+
reject("enrollError", response.error, nil)
|
|
40
|
+
} else {
|
|
41
|
+
let enrollResponse: [String: String?] = [
|
|
42
|
+
"userAuthenticatorId": response.data!.userAuthenticatorId,
|
|
43
|
+
"uri": response.data!.uri,
|
|
44
|
+
"secret": response.data!.secret,
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
resolve(enrollResponse)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@objc func verify(
|
|
53
|
+
_ code: NSString,
|
|
54
|
+
resolver resolve: @escaping RCTPromiseResolveBlock,
|
|
55
|
+
rejecter reject: @escaping RCTPromiseRejectBlock
|
|
56
|
+
) -> Void {
|
|
57
|
+
if (authsignal == nil) {
|
|
58
|
+
resolve(nil)
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
let codeStr = code as String
|
|
63
|
+
|
|
64
|
+
Task.init {
|
|
65
|
+
let response = await authsignal!.verify(code: codeStr)
|
|
66
|
+
|
|
67
|
+
if (response.errorCode == "TOKEN_NOT_SET") {
|
|
68
|
+
reject("tokenNotSetError", "TOKEN_NOT_SET", nil)
|
|
69
|
+
} else if (response.error != nil) {
|
|
70
|
+
reject("verifyError", response.error, nil)
|
|
71
|
+
} else {
|
|
72
|
+
let verifyResponse: [String: Any?] = [
|
|
73
|
+
"isVerified": response.data!.isVerified,
|
|
74
|
+
"token": response.data!.token,
|
|
75
|
+
"failureReason": response.data!.failureReason,
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
resolve(verifyResponse)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|