My Mind Login Complete

This commit is contained in:
2018-12-26 23:46:03 +00:00
parent 5dc1f7d743
commit 99bb053fb4
1111 changed files with 182978 additions and 0 deletions

View File

@@ -0,0 +1,178 @@
# v5.2.0
- Add support of Game Center sign in (#2127).
# v5.1.0
- Add support of custom FDL domain link (#2121).
# v5.0.5
- Restore SafariServices framework dependency (#2002).
# v5.0.4
- Fix analyzer issues (#1740).
# v5.0.3
- Add `FIRAuthErrorCodeMalformedJWT`, which is raised on JWT token parsing.
failures during auth operations (#1436).
- Migrate to use FirebaseAuthInterop interfaces to access FirebaseAuth (#1501).
# v5.0.2
- Fix an issue where JWT date timestamps weren't parsed correctly. (#1319)
- Fix an issue where anonymous accounts weren't correctly promoted to
non-anonymous when linked with passwordless email auth accounts. (#1383)
- Fix an exception from using an invalidated NSURLSession. (#1261)
- Fix a data race issue caught by the sanitizer. (#1446)
# v5.0.1
- Restore 4.x level of support for extensions (#1357).
# v5.0.0
- Adds APIs for phone Auth testing to bypass the verification flow (#1192).
- Changes the callback block signature for sign in and create user methods
to provide an AuthDataResult that includes the user and user info (#1123, #1186).
- Removes GoogleToolboxForMac dependency (#1175).
- Removes miscellaneous deprecated APIs (#1188, #1200).
# v4.6.1
- Fixes crash which occurred when certain Firebase IDTokens were being parsed (#1076).
# v4.6.0
- Adds `getIDTokenResultWithCompletion:` and `getIDTokenResultForcingRefresh:completion:` APIs which
call back with an AuthTokenResult object. The Auth token result object contains the ID token JWT string and other properties associated with the token including the decoded available payload claims (#1004).
- Adds the `updateCurrentUser:completion:` API which sets the currentUser on the calling Auth instance to the provided user object (#1018).
- Adds client-side validation to prevent setting `handleCodeInApp` to false when performing
email-link authentication. If `handleCodeInApp` is set to false an invalid argument exception
is thrown (#931).
- Adds support for passing the deep link (which is embedded in the sign-in link sent via email) to the
`signInWithEmail:link:completion:` and `isSignInWithEmailLink:` methods during an
email/link sign-in flow (#1023).
# v4.5.0
- Adds new API which provides a way to determine the sign-in methods associated with an
email address.
- Adds new API which allows authentication using only an email link (Passwordless Authentication
with email link).
# v4.4.4
- Addresses CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF warnings that surface in newer versions of
Xcode and CocoaPods.
- Improves FIRUser documentation with clear message explaining when Firebase Auth attempts to validate
users and what happens when an invalidated user is detected (#694) .
# v4.4.3
- Adds an explicit dependency on CoreGraphics from Firebase Auth.
# v4.4.2
- Fixes bug where the FIRAuthResult object returned following a Phone Number authentication
always contained a nil FIRAdditionalUserInfo object. Now the FIRAdditionalUserInfo object is
never nil and its newUser field is populated correctly.
# v4.4.0
- Adds new APIs which return an AuthDataResult object after successfully creating an
Email/Password user, signing in anonymously, signing in with Email/Password and signing
in with Custom Token. The AuthDataResult object contains the new user and additional
information pertaining to the new user.
# v4.3.2
- Improves error handling for the phone number sign-in reCAPTCHA flow.
- Improves error handling for phone number linking flow.
- Fixes issue where after linking an anonymous user to a phone number the user remained
anonymous.
# v4.3.1
- Internal clean up.
# v4.3.0
- Provides account creation and last sign-in dates as metadata to the user
object.
- Returns more descriptive errors for some error cases of the phone number
sign-in reCAPTCHA flow.
- Fixes an issue that invalid users were not automatically signed out earlier.
- Fixes an issue that ID token listeners were not fired in some cases.
# v4.2.1
- Fixes a threading issue in phone number auth that completion block was not
executed on the main thread in some error cases.
# v4.2.0
- Adds new phone number verification API which makes use of an intelligent reCAPTCHA to verify the application.
# v4.1.1
- Improves some method documentation in headers.
# v4.1.0
- Allows the app to handle continue URL natively, e.g., from password reset
email.
- Allows the app to set language code, e.g., for sending password reset email.
- Fixes an issue that user's phone number did not persist on client.
- Fixes an issue that recover email action code type was reported as unknown.
- Improves app start-up time by moving initialization off from the main
thread.
- Better reports missing email error when creating a new password user.
- Changes console message logging levels to be more consistent with other
Firebase products on the iOS platform.
# 2017-05-17 -- v4.0.0
- Adds Phone Number Authentication.
- Adds support for generic OAuth2 identity providers.
- Adds methods that return additional user data from identity providers if
available when authenticating users.
- Improves session management by automatically refreshing tokens if possible
and signing out users if the session is detected invalidated, for example,
after the user changed password or deleted account from another device.
- Fixes an issue that reauthentication creates new user account if the user
credential is valid but does not match the currently signed in user.
- Fixes an issue that the "password" provider is not immediately listed on the
client side after adding a password to an account.
- Changes factory methods to return non-null FIRAuth instances or raises an
exception, instead of returning nullable instances.
- Changes auth state change listener to only be triggered when the user changes.
- Adds a new listener which is triggered whenever the ID token is changed.
- Switches ERROR_EMAIL_ALREADY_IN_USE to
ERROR_ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL when the email used in the
signInWithCredential: call is already in use by another account.
- Deprecates FIREmailPasswordAuthProvider in favor of FIREmailAuthProvider.
- Deprecates getTokenWithCompletion in favor of getIDTokenWithCompletion on
FIRUser.
- Changes Swift API names to better align with Swift convention.
# 2017-02-06 -- v3.1.1
- Allows handling of additional errors when sending OOB action emails. The
server can respond with the following new error messages:
INVALID_MESSAGE_PAYLOAD,INVALID_SENDER and INVALID_RECIPIENT_EMAIL.
- Removes incorrect reference to FIRAuthErrorCodeCredentialTooOld in FIRUser.h.
- Provides additional error information from server if available.
# 2016-12-13 -- v3.1.0
- Adds FIRAuth methods that enable the app to follow up with user actions
delivered by email, such as verifying email address or reset password.
- No longer applies the keychain workaround introduced in v3.0.5 on iOS 10.2
simulator or above since the issue has been fixed.
- Fixes nullability compilation warnings when used in Swift.
- Better reports missing password error.
# 2016-10-24 -- v3.0.6
- Switches to depend on open sourced GoogleToolboxForMac and GTMSessionFetcher.
- Improves logging of keychain error when initializing.
# 2016-09-14 -- v3.0.5
- Works around a keychain issue in iOS 10 simulator.
- Reports the correct error for invalid email when signing in with email and
password.
# 2016-07-18 -- v3.0.4
- Fixes a race condition bug that could crash the app with an exception from
NSURLSession on iOS 9.
# 2016-06-20 -- v3.0.3
- Adds documentation for all possible errors returned by each method.
- Improves error handling and messages for a variety of error conditions.
- Whether or not an user is considered anonymous is now consistent with other
platforms.
- A saved signed in user is now siloed between different Firebase projects
within the same app.
# 2016-05-18 -- v3.0.2
- Initial public release.

View File

@@ -0,0 +1,17 @@
# Firebase Auth for iOS
Firebase Auth enables apps to easily support multiple authentication options
for their end users.
Please visit [our developer site](https://firebase.google.com/docs/auth/) for
integration instructions, documentation, support information, and terms of
service.
# Firebase Auth Development
Example/Auth contains a set of samples and tests that integrate with
FirebaseAuth.
The unit tests run without any additional configuration along with the rest of
Firebase. See [Example/Auth/README.md](../../Example/Auth/README.md) for
information about setting up, running, and testing the samples.

View File

@@ -0,0 +1,39 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIREmailAuthProvider.h"
#import "FIREmailPasswordAuthCredential.h"
// FIREmailPasswordAuthProviderID is defined in FIRAuthProvider.m.
@implementation FIREmailAuthProvider
- (instancetype)init {
@throw [NSException exceptionWithName:@"Attempt to call unavailable initializer."
reason:@"This class is not meant to be initialized."
userInfo:nil];
}
+ (FIRAuthCredential *)credentialWithEmail:(NSString *)email password:(NSString *)password {
return [[FIREmailPasswordAuthCredential alloc] initWithEmail:email password:password];
}
+ (FIRAuthCredential *)credentialWithEmail:(NSString *)email link:(NSString *)link {
return [[FIREmailPasswordAuthCredential alloc] initWithEmail:email link:link];
}
@end

View File

@@ -0,0 +1,61 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import "FIRAuthCredential_Internal.h"
NS_ASSUME_NONNULL_BEGIN
/** @class FIREmailPasswordAuthCredential
@brief Internal implementation of FIRAuthCredential for Email/Password credentials.
*/
@interface FIREmailPasswordAuthCredential : FIRAuthCredential
/** @property email
@brief The user's email address.
*/
@property(nonatomic, readonly) NSString *email;
/** @property password
@brief The user's password.
*/
@property(nonatomic, readonly) NSString *password;
/** @property link
@brief The email sign-in link.
*/
@property(nonatomic, readonly) NSString *link;
/** @fn initWithEmail:password:
@brief Designated initializer.
@param email The user's email address.
@param password The user's password.
*/
- (nullable instancetype)initWithEmail:(NSString *)email password:(NSString *)password
NS_DESIGNATED_INITIALIZER;
/** @fn initWithEmail:link:
@brief Designated initializer.
@param email The user's email address.
@param link The email sign-in link.
*/
- (nullable instancetype)initWithEmail:(NSString *)email link:(NSString *)link
NS_DESIGNATED_INITIALIZER;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,60 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIREmailPasswordAuthCredential.h"
#import "FIREmailAuthProvider.h"
#import "FIRAuthExceptionUtils.h"
#import "FIRVerifyAssertionRequest.h"
@interface FIREmailPasswordAuthCredential ()
- (nullable instancetype)initWithProvider:(NSString *)provider NS_UNAVAILABLE;
@end
@implementation FIREmailPasswordAuthCredential
- (nullable instancetype)initWithProvider:(NSString *)provider {
[FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason:
@"Please call the designated initializer."];
return nil;
}
- (nullable instancetype)initWithEmail:(NSString *)email password:(NSString *)password {
self = [super initWithProvider:FIREmailAuthProviderID];
if (self) {
_email = [email copy];
_password = [password copy];
}
return self;
}
- (nullable instancetype)initWithEmail:(NSString *)email link:(NSString *)link {
self = [super initWithProvider:FIREmailAuthProviderID];
if (self) {
_email = [email copy];
_link = [link copy];
}
return self;
}
- (void)prepareVerifyAssertionRequest:(FIRVerifyAssertionRequest *)request {
[FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason:
@"Attempt to call prepareVerifyAssertionRequest: on a FIREmailPasswordAuthCredential."];
}
@end

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import "FIRAuthCredential_Internal.h"
NS_ASSUME_NONNULL_BEGIN
/** @class FIRFacebookAuthCredential
@brief Internal implementation of FIRAuthCredential for the Facebook IdP.
*/
@interface FIRFacebookAuthCredential : FIRAuthCredential
/** @fn initWithAccessToken:
@brief Designated initializer.
@param accessToken The Access Token obtained from Facebook.
*/
- (nullable instancetype)initWithAccessToken:(NSString *)accessToken NS_DESIGNATED_INITIALIZER;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,51 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRFacebookAuthCredential.h"
#import "FIRFacebookAuthProvider.h"
#import "FIRAuthExceptionUtils.h"
#import "FIRVerifyAssertionRequest.h"
@interface FIRFacebookAuthCredential ()
- (nullable instancetype)initWithProvider:(NSString *)provider NS_UNAVAILABLE;
@end
@implementation FIRFacebookAuthCredential {
NSString *_accessToken;
}
- (nullable instancetype)initWithProvider:(NSString *)provider {
[FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason:
@"Please call the designated initializer."];
return nil;
}
- (nullable instancetype)initWithAccessToken:(NSString *)accessToken {
self = [super initWithProvider:FIRFacebookAuthProviderID];
if (self) {
_accessToken = [accessToken copy];
}
return self;
}
- (void)prepareVerifyAssertionRequest:(FIRVerifyAssertionRequest *)request {
request.providerAccessToken = _accessToken;
}
@end

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRFacebookAuthProvider.h"
#import "FIRFacebookAuthCredential.h"
#import "FIRAuthExceptionUtils.h"
// FIRFacebookAuthProviderID is defined in FIRAuthProvider.m.
@implementation FIRFacebookAuthProvider
- (instancetype)init {
[FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason:
@"This class is not meant to be initialized."];
return nil;
}
+ (FIRAuthCredential *)credentialWithAccessToken:(NSString *)accessToken {
return [[FIRFacebookAuthCredential alloc] initWithAccessToken:accessToken];
}
@end

View File

@@ -0,0 +1,80 @@
/*
* Copyright 2018 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import "FIRAuthCredential.h"
NS_ASSUME_NONNULL_BEGIN
/** @class FIRGameCenterAuthCredential
@brief Internal implementation of FIRAuthCredential for Game Center credentials.
*/
@interface FIRGameCenterAuthCredential : FIRAuthCredential
/** @property playerID
@brief The ID of the Game Center local player.
*/
@property(nonatomic, readonly) NSString *playerID;
/** @property publicKeyURL
@brief The URL for the public encryption key.
*/
@property(nonatomic, readonly) NSURL *publicKeyURL;
/** @property signature
@brief The verification signature data generated.
*/
@property(nonatomic, readonly) NSData *signature;
/** @property salt
@brief A random string used to compute the hash and keep it randomized.
*/
@property(nonatomic, readonly) NSData *salt;
/** @property timestamp
@brief The date and time that the signature was created.
*/
@property(nonatomic, readonly) uint64_t timestamp;
/** @property displayName
@brief The date and time that the signature was created.
*/
@property(nonatomic, readonly) NSString *displayName;
/** @fn initWithPlayerID:publicKeyURL:signature:salt:timestamp:displayName:
@brief Designated initializer.
@param publicKeyURL The URL for the public encryption key.
@param signature The verification signature generated.
@param salt A random string used to compute the hash and keep it randomized.
@param timestamp The date and time that the signature was created.
*/
- (nullable instancetype)initWithPlayerID:(NSString *)playerID
publicKeyURL:(NSURL *)publicKeyURL
signature:(NSData *)signature
salt:(NSData *)salt
timestamp:(uint64_t)timestamp
displayName:(NSString *)displayName NS_DESIGNATED_INITIALIZER;
/** @fn initWithProvider:
@brief Initializer with a provider name.
@param provider The provider name.
*/
- (nullable instancetype)initWithProvider:(NSString *)provider NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,55 @@
/*
* Copyright 2018 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRGameCenterAuthCredential.h"
#import "FIRAuthExceptionUtils.h"
#import "FIRAuthCredential_Internal.h"
#import "FIRGameCenterAuthProvider.h"
#import "FIRVerifyAssertionRequest.h"
@implementation FIRGameCenterAuthCredential
- (nullable instancetype)initWithProvider:(NSString *)provider {
[FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason:
@"Please call the designated initializer."];
return nil;
}
- (nullable instancetype)initWithPlayerID:(NSString *)playerID
publicKeyURL:(NSURL *)publicKeyURL
signature:(NSData *)signature
salt:(NSData *)salt
timestamp:(uint64_t)timestamp
displayName:(NSString *)displayName {
self = [super initWithProvider:FIRGameCenterAuthProviderID];
if (self) {
_playerID = [playerID copy];
_publicKeyURL = [publicKeyURL copy];
_signature = [signature copy];
_salt = [salt copy];
_timestamp = timestamp;
_displayName = [displayName copy];
}
return self;
}
- (void)prepareVerifyAssertionRequest:(FIRVerifyAssertionRequest *)request {
[FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason:
@"Attempt to call prepareVerifyAssertionRequest: on a FIRGameCenterAuthCredential."];
}
@end

View File

@@ -0,0 +1,69 @@
/*
* Copyright 2018 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRGameCenterAuthProvider.h"
#import <GameKit/GameKit.h>
#import "FIRAuthErrorUtils.h"
#import "FIRAuthExceptionUtils.h"
#import "FIRGameCenterAuthCredential.h"
@implementation FIRGameCenterAuthProvider
- (instancetype)init {
[FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason:
@"This class is not meant to be initialized."];
return nil;
}
+ (void)getCredentialWithCompletion:(FIRGameCenterCredentialCallback)completion {
__weak GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
if (!localPlayer.isAuthenticated) {
if (completion) {
completion(nil, [FIRAuthErrorUtils localPlayerNotAuthenticatedError]);
}
return;
}
[localPlayer generateIdentityVerificationSignatureWithCompletionHandler:
^(NSURL *publicKeyURL, NSData *signature, NSData *salt, uint64_t timestamp, NSError *error) {
if (error) {
if (completion) {
completion(nil, error);
}
} else {
if (completion) {
/**
@c `localPlayer.alias` is actually the displayname needed, instead of
`localPlayer.displayname`. For more information, check
https://developer.apple.com/documentation/gamekit/gkplayer
**/
NSString *displayName = localPlayer.alias;
FIRGameCenterAuthCredential *credential =
[[FIRGameCenterAuthCredential alloc] initWithPlayerID:localPlayer.playerID
publicKeyURL:publicKeyURL
signature:signature
salt:salt
timestamp:timestamp
displayName:displayName];
completion(credential, nil);
}
}
}];
}
@end

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import "FIRAuthCredential_Internal.h"
NS_ASSUME_NONNULL_BEGIN
/** @class FIRGitHubAuthCredential
@brief Internal implementation of FIRAuthCredential for GitHub credentials.
*/
@interface FIRGitHubAuthCredential : FIRAuthCredential
/** @property token
@brief The GitHub OAuth access token.
*/
@property(nonatomic, readonly) NSString *token;
/** @fn initWithToken:
@brief Designated initializer.
@param token The GitHub OAuth access token.
*/
- (nullable instancetype)initWithToken:(NSString *)token NS_DESIGNATED_INITIALIZER;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRGitHubAuthCredential.h"
#import "FIRGitHubAuthProvider.h"
#import "FIRAuthExceptionUtils.h"
#import "FIRVerifyAssertionRequest.h"
@interface FIRGitHubAuthCredential ()
- (nullable instancetype)initWithProvider:(NSString *)provider NS_UNAVAILABLE;
@end
@implementation FIRGitHubAuthCredential
- (nullable instancetype)initWithProvider:(NSString *)provider {
[FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason:
@"Please call the designated initializer."];
return nil;
}
- (nullable instancetype)initWithToken:(NSString *)token {
self = [super initWithProvider:FIRGitHubAuthProviderID];
if (self) {
_token = [token copy];
}
return self;
}
- (void)prepareVerifyAssertionRequest:(FIRVerifyAssertionRequest *)request {
request.providerAccessToken = _token;
}
@end

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRGitHubAuthProvider.h"
#import "FIRGitHubAuthCredential.h"
#import "FIRAuthExceptionUtils.h"
// FIRGitHubAuthProviderID is defined in FIRAuthProvider.m.
@implementation FIRGitHubAuthProvider
- (instancetype)init {
[FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason:
@"This class is not meant to be initialized."];
return nil;
}
+ (FIRAuthCredential *)credentialWithToken:(NSString *)token {
return [[FIRGitHubAuthCredential alloc] initWithToken:token];
}
@end

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import "FIRAuthCredential_Internal.h"
NS_ASSUME_NONNULL_BEGIN
/** @class FIRGoogleAuthCredential
@brief Internal implementation of FIRAuthCredential for the Google IdP.
*/
@interface FIRGoogleAuthCredential : FIRAuthCredential
/** @fn initWithIDToken:accessToken:
@brief Designated initializer.
@param IDToken The ID Token obtained from Google.
@param accessToken The Access Token obtained from Google.
*/
- (nullable instancetype)initWithIDToken:(NSString *)IDToken accessToken:(NSString *)accessToken
NS_DESIGNATED_INITIALIZER;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRGoogleAuthCredential.h"
#import "FIRGoogleAuthProvider.h"
#import "FIRAuthExceptionUtils.h"
#import "FIRVerifyAssertionRequest.h"
@interface FIRGoogleAuthCredential ()
- (nullable instancetype)initWithProvider:(NSString *)provider NS_UNAVAILABLE;
@end
@implementation FIRGoogleAuthCredential {
NSString *_IDToken;
NSString *_accessToken;
}
- (nullable instancetype)initWithProvider:(NSString *)provider {
[FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason:
@"Please call the designated initializer."];
return nil;
}
- (nullable instancetype)initWithIDToken:(NSString *)IDToken accessToken:(NSString *)accessToken {
self = [super initWithProvider:FIRGoogleAuthProviderID];
if (self) {
_IDToken = [IDToken copy];
_accessToken = [accessToken copy];
}
return self;
}
- (void)prepareVerifyAssertionRequest:(FIRVerifyAssertionRequest *)request {
request.providerIDToken = _IDToken;
request.providerAccessToken = _accessToken;
}
@end

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRGoogleAuthProvider.h"
#import "FIRGoogleAuthCredential.h"
#import "FIRAuthExceptionUtils.h"
// FIRGoogleAuthProviderID is defined in FIRAuthProvider.m.
@implementation FIRGoogleAuthProvider
- (instancetype)init {
[FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason:
@"This class is not meant to be initialized."];
return nil;
}
+ (FIRAuthCredential *)credentialWithIDToken:(NSString *)IDToken
accessToken:(NSString *)accessToken {
return [[FIRGoogleAuthCredential alloc] initWithIDToken:IDToken accessToken:accessToken];
}
@end

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import "FIRAuthCredential_Internal.h"
NS_ASSUME_NONNULL_BEGIN
/** @class FIROAuthCredential
@brief Internal implementation of FIRAuthCredential for generic credentials.
*/
@interface FIROAuthCredential : FIRAuthCredential
/** @property IDToken
@brief The ID Token associated with this credential.
*/
@property(nonatomic, readonly, nullable) NSString *IDToken;
/** @property accessToken
@brief The access token associated with this credential.
*/
@property(nonatomic, readonly, nullable) NSString *accessToken;
/** @fn initWithProviderId:IDToken:accessToken:
@brief Designated initializer.
@param providerID The provider ID associated with the credential being created.
@param IDToken The ID Token associated with the credential being created.
@param accessToken The access token associated with the credential being created.
*/
- (nullable instancetype)initWithProviderID:(NSString *)providerID
IDToken:(nullable NSString*)IDToken
accessToken:(nullable NSString *)accessToken;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIROAuthCredential.h"
#import "FIRVerifyAssertionRequest.h"
NS_ASSUME_NONNULL_BEGIN
@interface FIROAuthCredential ()
- (nullable instancetype)initWithProvider:(NSString *)provider NS_UNAVAILABLE;
@end
@implementation FIROAuthCredential
- (nullable instancetype)initWithProviderID:(NSString *)providerID
IDToken:(nullable NSString *)IDToken
accessToken:(nullable NSString *)accessToken {
self = [super initWithProvider:providerID];
if (self) {
_IDToken = IDToken;
_accessToken = accessToken;
}
return self;
}
- (void)prepareVerifyAssertionRequest:(FIRVerifyAssertionRequest *)request {
request.providerIDToken = _IDToken;
request.providerAccessToken = _accessToken;
}
NS_ASSUME_NONNULL_END
@end

View File

@@ -0,0 +1,42 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIROAuthProvider.h"
#import "FIROAuthCredential.h"
NS_ASSUME_NONNULL_BEGIN
@implementation FIROAuthProvider
+ (FIRAuthCredential *)credentialWithProviderID:(NSString *)providerID
IDToken:(NSString *)IDToken
accessToken:(nullable NSString *)accessToken {
return [[FIROAuthCredential alloc] initWithProviderID:providerID
IDToken:IDToken
accessToken:accessToken];
}
+ (FIROAuthCredential *)credentialWithProviderID:(NSString *)providerID
accessToken:(NSString *)accessToken {
return [[FIROAuthCredential alloc] initWithProviderID:providerID
IDToken:nil
accessToken:accessToken];
}
NS_ASSUME_NONNULL_END
@end

View File

@@ -0,0 +1,64 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRPhoneAuthCredential.h"
#import "FIRPhoneAuthCredential_Internal.h"
#import "FIRAuthCredential_Internal.h"
#import "FIRAuthExceptionUtils.h"
#import "FIRVerifyAssertionRequest.h"
NS_ASSUME_NONNULL_BEGIN
@interface FIRPhoneAuthCredential ()
- (nullable instancetype)initWithProvider:(NSString *)provider NS_UNAVAILABLE;
@end
@implementation FIRPhoneAuthCredential
- (instancetype)initWithTemporaryProof:(NSString *)temporaryProof
phoneNumber:(NSString *)phoneNumber
providerID:(NSString *)providerID {
self = [super initWithProvider:providerID];
if (self) {
_temporaryProof = [temporaryProof copy];
_phoneNumber = [phoneNumber copy];
}
return self;
}
- (nullable instancetype)initWithProvider:(NSString *)provider {
[FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason:
@"Please call the designated initializer."];
return nil;
}
- (instancetype)initWithProviderID:(NSString *)providerID
verificationID:(NSString *)verificationID
verificationCode:(NSString *)verificationCode {
self = [super initWithProvider:providerID];
if (self) {
_verificationID = [verificationID copy];
_verificationCode = [verificationCode copy];
}
return self;
}
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,70 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import "FIRPhoneAuthCredential.h"
NS_ASSUME_NONNULL_BEGIN
/** @extension FIRPhoneAuthCredential
@brief Internal implementation of FIRAuthCredential for Phone Auth credentials.
*/
@interface FIRPhoneAuthCredential ()
/** @var verificationID
@brief The verification ID obtained from invoking @c verifyPhoneNumber:completion:
*/
@property(nonatomic, readonly, nonnull) NSString *verificationID;
/** @var verificationCode
@brief The verification code provided by the user.
*/
@property(nonatomic, readonly, nonnull) NSString *verificationCode;
/** @var temporaryProof
@brief The a temporary proof code perftaining to this credential, returned from the backend.
*/
@property(nonatomic, readonly, nonnull) NSString *temporaryProof;
/** @var phoneNumber
@brief The a phone number pertaining to this credential, returned from the backend.
*/
@property(nonatomic, readonly, nonnull) NSString *phoneNumber;
/** @var initWithTemporaryProof:phoneNumber:
@brief Designated Initializer.
@param providerID The provider ID associated with the phone auth credential being created.
*/
- (instancetype)initWithTemporaryProof:(NSString *)temporaryProof
phoneNumber:(NSString *)phoneNumber
providerID:(NSString *)providerID NS_DESIGNATED_INITIALIZER;
/** @var initWithProviderID:verificationID:verificationCode:
@brief Designated Initializer.
@param providerID The provider ID associated with the phone auth credential being created.
@param verificationID The verification ID associated witht Phone Auth credential being created.
@param verificationCode The verification code associated witht Phone Auth credential being
created.
*/
- (instancetype)initWithProviderID:(NSString *)providerID
verificationID:(NSString *)verificationID
verificationCode:(NSString *)verificationCode NS_DESIGNATED_INITIALIZER;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,519 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRPhoneAuthProvider.h"
#import <FirebaseCore/FIRLogger.h>
#import "FIRPhoneAuthCredential_Internal.h"
#import <FirebaseCore/FIRApp.h>
#import "FIRAuthAPNSToken.h"
#import "FIRAuthAPNSTokenManager.h"
#import "FIRAuthAppCredential.h"
#import "FIRAuthAppCredentialManager.h"
#import "FIRAuthGlobalWorkQueue.h"
#import "FIRAuth_Internal.h"
#import "FIRAuthURLPresenter.h"
#import "FIRAuthNotificationManager.h"
#import "FIRAuthErrorUtils.h"
#import "FIRAuthBackend.h"
#import "FIRAuthSettings.h"
#import "FIRAuthWebUtils.h"
#import "FirebaseAuthVersion.h"
#import <FirebaseCore/FIROptions.h>
#import "FIRGetProjectConfigRequest.h"
#import "FIRGetProjectConfigResponse.h"
#import "FIRSendVerificationCodeRequest.h"
#import "FIRSendVerificationCodeResponse.h"
#import "FIRVerifyClientRequest.h"
#import "FIRVerifyClientResponse.h"
NS_ASSUME_NONNULL_BEGIN
/** @typedef FIRReCAPTCHAURLCallBack
@brief The callback invoked at the end of the flow to fetch a reCAPTCHA URL.
@param reCAPTCHAURL The reCAPTCHA URL.
@param error The error that occurred while fetching the reCAPTCHAURL, if any.
*/
typedef void (^FIRReCAPTCHAURLCallBack)(NSURL *_Nullable reCAPTCHAURL, NSError *_Nullable error);
/** @typedef FIRVerifyClientCallback
@brief The callback invoked at the end of a client verification flow.
@param appCredential credential that proves the identity of the app during a phone
authentication flow.
@param error The error that occurred while verifying the app, if any.
*/
typedef void (^FIRVerifyClientCallback)(FIRAuthAppCredential *_Nullable appCredential,
NSError *_Nullable error);
/** @typedef FIRFetchAuthDomainCallback
@brief The callback invoked at the end of the flow to fetch the Auth domain.
@param authDomain The Auth domain.
@param error The error that occurred while fetching the auth domain, if any.
*/
typedef void (^FIRFetchAuthDomainCallback)(NSString *_Nullable authDomain,
NSError *_Nullable error);
/** @var kAuthDomainSuffix
@brief The suffix of the auth domain pertiaining to a given Firebase project.
*/
static NSString *const kAuthDomainSuffix = @"firebaseapp.com";
/** @var kauthTypeVerifyApp
@brief The auth type to be specified in the app verification request.
*/
static NSString *const kAuthTypeVerifyApp = @"verifyApp";
/** @var kReCAPTCHAURLStringFormat
@brief The format of the URL used to open the reCAPTCHA page during app verification.
*/
NSString *const kReCAPTCHAURLStringFormat = @"https://%@/__/auth/handler?";
@implementation FIRPhoneAuthProvider {
/** @var _auth
@brief The auth instance used for verifying the phone number.
*/
FIRAuth *_auth;
/** @var _callbackScheme
@brief The callback URL scheme used for reCAPTCHA fallback.
*/
NSString *_callbackScheme;
}
/** @fn initWithAuth:
@brief returns an instance of @c FIRPhoneAuthProvider associated with the provided auth
instance.
@return An Instance of @c FIRPhoneAuthProvider.
*/
- (nullable instancetype)initWithAuth:(FIRAuth *)auth {
self = [super init];
if (self) {
_auth = auth;
_callbackScheme = [[[_auth.app.options.clientID componentsSeparatedByString:@"."]
reverseObjectEnumerator].allObjects componentsJoinedByString:@"."];
}
return self;
}
- (void)verifyPhoneNumber:(NSString *)phoneNumber
UIDelegate:(nullable id<FIRAuthUIDelegate>)UIDelegate
completion:(nullable FIRVerificationResultCallback)completion {
if (![self isCallbackSchemeRegistered]) {
[NSException raise:NSInternalInconsistencyException
format:@"Please register custom URL scheme '%@' in the app's Info.plist file.",
_callbackScheme];
}
dispatch_async(FIRAuthGlobalWorkQueue(), ^{
FIRVerificationResultCallback callBackOnMainThread = ^(NSString *_Nullable verificationID,
NSError *_Nullable error) {
if (completion) {
dispatch_async(dispatch_get_main_queue(), ^{
completion(verificationID, error);
});
}
};
[self internalVerifyPhoneNumber:phoneNumber completion:^(NSString *_Nullable verificationID,
NSError *_Nullable error) {
if (!error) {
callBackOnMainThread(verificationID, nil);
return;
}
NSError *underlyingError = error.userInfo[NSUnderlyingErrorKey];
BOOL isInvalidAppCredential = error.code == FIRAuthErrorCodeInternalError &&
underlyingError.code == FIRAuthErrorCodeInvalidAppCredential;
if (error.code != FIRAuthErrorCodeMissingAppToken && !isInvalidAppCredential) {
callBackOnMainThread(nil, error);
return;
}
NSMutableString *eventID = [[NSMutableString alloc] init];
for (int i=0; i<10; i++) {
[eventID appendString:
[NSString stringWithFormat:@"%c", 'a' + arc4random_uniform('z' - 'a' + 1)]];
}
[self reCAPTCHAURLWithEventID:eventID completion:^(NSURL *_Nullable reCAPTCHAURL,
NSError *_Nullable error) {
if (error) {
callBackOnMainThread(nil, error);
return;
}
FIRAuthURLCallbackMatcher callbackMatcher = ^BOOL(NSURL *_Nullable callbackURL) {
return [self isVerifyAppURL:callbackURL eventID:eventID];
};
[self->_auth.authURLPresenter presentURL:reCAPTCHAURL
UIDelegate:UIDelegate
callbackMatcher:callbackMatcher
completion:^(NSURL *_Nullable callbackURL,
NSError *_Nullable error) {
if (error) {
callBackOnMainThread(nil, error);
return;
}
NSError *reCAPTCHAError;
NSString *reCAPTCHAToken = [self reCAPTCHATokenForURL:callbackURL error:&reCAPTCHAError];
if (!reCAPTCHAToken) {
callBackOnMainThread(nil, reCAPTCHAError);
return;
}
FIRSendVerificationCodeRequest *request =
[[FIRSendVerificationCodeRequest alloc] initWithPhoneNumber:phoneNumber
appCredential:nil
reCAPTCHAToken:reCAPTCHAToken
requestConfiguration:
self->_auth.requestConfiguration];
[FIRAuthBackend sendVerificationCode:request
callback:^(FIRSendVerificationCodeResponse
*_Nullable response, NSError *_Nullable error) {
if (error) {
callBackOnMainThread(nil, error);
return;
}
callBackOnMainThread(response.verificationID, nil);
}];
}];
}];
}];
});
}
- (FIRPhoneAuthCredential *)credentialWithVerificationID:(NSString *)verificationID
verificationCode:(NSString *)verificationCode {
return [[FIRPhoneAuthCredential alloc] initWithProviderID:FIRPhoneAuthProviderID
verificationID:verificationID
verificationCode:verificationCode];
}
+ (instancetype)provider {
return [[self alloc]initWithAuth:[FIRAuth auth]];
}
+ (instancetype)providerWithAuth:(FIRAuth *)auth {
return [[self alloc]initWithAuth:auth];
}
#pragma mark - Internal Methods
/** @fn isCallbackSchemeRegistered
@brief Checks whether or not the expected callback scheme has been registered by the app.
@remarks This method is thread-safe.
*/
- (BOOL)isCallbackSchemeRegistered {
NSString *expectedCustomScheme = [_callbackScheme lowercaseString];
NSArray *urlTypes = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleURLTypes"];
for (NSDictionary *urlType in urlTypes) {
NSArray *urlTypeSchemes = urlType[@"CFBundleURLSchemes"];
for (NSString *urlTypeScheme in urlTypeSchemes) {
if ([urlTypeScheme.lowercaseString isEqualToString:expectedCustomScheme]) {
return YES;
}
}
}
return NO;
}
/** @fn reCAPTCHATokenForURL:error:
@brief Parses the reCAPTCHA URL and returns.
@param URL The url to be parsed for a reCAPTCHA token.
@param error The error that occurred if any.
@return The reCAPTCHA token if successful.
*/
- (NSString *)reCAPTCHATokenForURL:(NSURL *)URL error:(NSError **)error {
NSURLComponents *actualURLComponents = [NSURLComponents componentsWithURL:URL resolvingAgainstBaseURL:NO];
NSArray<NSURLQueryItem *> *queryItems = [actualURLComponents queryItems];
NSString *deepLinkURL = [FIRAuthWebUtils queryItemValue:@"deep_link_id" from:queryItems];
NSData *errorData;
if (deepLinkURL) {
actualURLComponents = [NSURLComponents componentsWithString:deepLinkURL];
queryItems = [actualURLComponents queryItems];
NSString *recaptchaToken = [FIRAuthWebUtils queryItemValue:@"recaptchaToken" from:queryItems];
if (recaptchaToken) {
return recaptchaToken;
}
NSString *firebaseError = [FIRAuthWebUtils queryItemValue:@"firebaseError" from:queryItems];
errorData = [firebaseError dataUsingEncoding:NSUTF8StringEncoding];
} else {
errorData = nil;
}
NSError *jsonError;
NSDictionary *errorDict = [NSJSONSerialization JSONObjectWithData:errorData
options:0
error:&jsonError];
if (jsonError) {
*error = [FIRAuthErrorUtils JSONSerializationErrorWithUnderlyingError:jsonError];
return nil;
}
*error = [FIRAuthErrorUtils URLResponseErrorWithCode:errorDict[@"code"]
message:errorDict[@"message"]];
if (!*error) {
NSString *reason;
if(errorDict[@"code"] && errorDict[@"message"]) {
reason = [NSString stringWithFormat:@"[%@] - %@",errorDict[@"code"], errorDict[@"message"]];
} else {
reason = [NSString stringWithFormat:@"An unknown error occurred with the following "
"response: %@", deepLinkURL];
}
*error = [FIRAuthErrorUtils appVerificationUserInteractionFailureWithReason:reason];
}
return nil;
}
/** @fn isVerifyAppURL:
@brief Parses a URL into all available query items.
@param URL The url to be checked against the authType string.
@return Whether or not the URL matches authType.
*/
- (BOOL)isVerifyAppURL:(nullable NSURL *)URL eventID:(NSString *)eventID {
if (!URL) {
return NO;
}
NSURLComponents *actualURLComponents =
[NSURLComponents componentsWithURL:URL resolvingAgainstBaseURL:NO];
actualURLComponents.query = nil;
actualURLComponents.fragment = nil;
NSURLComponents *expectedURLComponents = [NSURLComponents new];
expectedURLComponents.scheme = _callbackScheme;
expectedURLComponents.host = @"firebaseauth";
expectedURLComponents.path = @"/link";
if (!([[expectedURLComponents URL] isEqual:[actualURLComponents URL]])) {
return NO;
}
actualURLComponents = [NSURLComponents componentsWithURL:URL resolvingAgainstBaseURL:NO];
NSArray<NSURLQueryItem *> *queryItems = [actualURLComponents queryItems];
NSString *deepLinkURL = [FIRAuthWebUtils queryItemValue:@"deep_link_id" from:queryItems];
if (deepLinkURL == nil) {
return NO;
}
NSURLComponents *deepLinkURLComponents = [NSURLComponents componentsWithString:deepLinkURL];
NSArray<NSURLQueryItem *> *deepLinkQueryItems = [deepLinkURLComponents queryItems];
NSString *deepLinkAuthType = [FIRAuthWebUtils queryItemValue:@"authType" from:deepLinkQueryItems];
NSString *deepLinkEventID = [FIRAuthWebUtils queryItemValue:@"eventId" from:deepLinkQueryItems];
if ([deepLinkAuthType isEqualToString:kAuthTypeVerifyApp] &&
[deepLinkEventID isEqualToString:eventID]) {
return YES;
}
return NO;
}
/** @fn internalVerifyPhoneNumber:completion:
@brief Starts the phone number authentication flow by sending a verifcation code to the
specified phone number.
@param phoneNumber The phone number to be verified.
@param completion The callback to be invoked when the verification flow is finished.
*/
- (void)internalVerifyPhoneNumber:(NSString *)phoneNumber
completion:(nullable FIRVerificationResultCallback)completion {
if (!phoneNumber.length) {
completion(nil, [FIRAuthErrorUtils missingPhoneNumberErrorWithMessage:nil]);
return;
}
[_auth.notificationManager checkNotificationForwardingWithCallback:
^(BOOL isNotificationBeingForwarded) {
if (!isNotificationBeingForwarded) {
completion(nil, [FIRAuthErrorUtils notificationNotForwardedError]);
return;
}
FIRVerificationResultCallback callback = ^(NSString *_Nullable verificationID,
NSError *_Nullable error) {
if (completion) {
completion(verificationID, error);
}
};
[self verifyClientAndSendVerificationCodeToPhoneNumber:phoneNumber
retryOnInvalidAppCredential:YES
callback:callback];
}];
}
/** @fn verifyClientAndSendVerificationCodeToPhoneNumber:retryOnInvalidAppCredential:callback:
@brief Starts the flow to verify the client via silent push notification.
@param retryOnInvalidAppCredential Whether of not the flow should be retried if an
FIRAuthErrorCodeInvalidAppCredential error is returned from the backend.
@param phoneNumber The phone number to be verified.
@param callback The callback to be invoked on the global work queue when the flow is
finished.
*/
- (void)verifyClientAndSendVerificationCodeToPhoneNumber:(NSString *)phoneNumber
retryOnInvalidAppCredential:(BOOL)retryOnInvalidAppCredential
callback:(FIRVerificationResultCallback)callback {
if (_auth.settings.isAppVerificationDisabledForTesting) {
FIRSendVerificationCodeRequest *request =
[[FIRSendVerificationCodeRequest alloc] initWithPhoneNumber:phoneNumber
appCredential:nil
reCAPTCHAToken:nil
requestConfiguration:
_auth.requestConfiguration];
[FIRAuthBackend sendVerificationCode:request
callback:^(FIRSendVerificationCodeResponse *_Nullable response,
NSError *_Nullable error) {
callback(response.verificationID, error);
}];
return;
}
[self verifyClientWithCompletion:^(FIRAuthAppCredential *_Nullable appCredential,
NSError *_Nullable error) {
if (error) {
callback(nil, error);
return;
}
FIRSendVerificationCodeRequest *request =
[[FIRSendVerificationCodeRequest alloc] initWithPhoneNumber:phoneNumber
appCredential:appCredential
reCAPTCHAToken:nil
requestConfiguration:
self->_auth.requestConfiguration];
[FIRAuthBackend sendVerificationCode:request
callback:^(FIRSendVerificationCodeResponse *_Nullable response,
NSError *_Nullable error) {
if (error) {
if (error.code == FIRAuthErrorCodeInvalidAppCredential) {
if (retryOnInvalidAppCredential) {
[self->_auth.appCredentialManager clearCredential];
[self verifyClientAndSendVerificationCodeToPhoneNumber:phoneNumber
retryOnInvalidAppCredential:NO
callback:callback];
return;
}
callback(nil, [FIRAuthErrorUtils unexpectedResponseWithDeserializedResponse:nil
underlyingError:error]);
return;
}
callback(nil, error);
return;
}
callback(response.verificationID, nil);
}];
}];
}
/** @fn verifyClientWithCompletion:completion:
@brief Continues the flow to verify the client via silent push notification.
@param completion The callback to be invoked when the client verification flow is finished.
*/
- (void)verifyClientWithCompletion:(FIRVerifyClientCallback)completion {
if (_auth.appCredentialManager.credential) {
completion(_auth.appCredentialManager.credential, nil);
return;
}
[_auth.tokenManager getTokenWithCallback:^(FIRAuthAPNSToken *_Nullable token,
NSError *_Nullable error) {
if (!token) {
completion(nil, [FIRAuthErrorUtils missingAppTokenErrorWithUnderlyingError:error]);
return;
}
FIRVerifyClientRequest *request =
[[FIRVerifyClientRequest alloc] initWithAppToken:token.string
isSandbox:token.type == FIRAuthAPNSTokenTypeSandbox
requestConfiguration:self->_auth.requestConfiguration];
[FIRAuthBackend verifyClient:request callback:^(FIRVerifyClientResponse *_Nullable response,
NSError *_Nullable error) {
if (error) {
completion(nil, error);
return;
}
NSTimeInterval timeout = [response.suggestedTimeOutDate timeIntervalSinceNow];
[self->_auth.appCredentialManager
didStartVerificationWithReceipt:response.receipt
timeout:timeout
callback:^(FIRAuthAppCredential *credential) {
if (!credential.secret) {
FIRLogWarning(kFIRLoggerAuth, @"I-AUT000014",
@"Failed to receive remote notification to verify app identity within "
@"%.0f second(s)", timeout);
}
completion(credential, nil);
}];
}];
}];
}
/** @fn reCAPTCHAURLWithEventID:completion:
@brief Constructs a URL used for opening a reCAPTCHA app verification flow using a given event
ID.
@param eventID The event ID used for this purpose.
@param completion The callback invoked after the URL has been constructed or an error
has been encountered.
*/
- (void)reCAPTCHAURLWithEventID:(NSString *)eventID completion:(FIRReCAPTCHAURLCallBack)completion {
[self fetchAuthDomainWithCompletion:^(NSString *_Nullable authDomain,
NSError *_Nullable error) {
if (error) {
completion(nil, error);
return;
}
NSString *bundleID = [NSBundle mainBundle].bundleIdentifier;
NSString *clientID = self->_auth.app.options.clientID;
NSString *apiKey = self->_auth.requestConfiguration.APIKey;
NSMutableArray<NSURLQueryItem *> *queryItems = [@[
[NSURLQueryItem queryItemWithName:@"apiKey" value:apiKey],
[NSURLQueryItem queryItemWithName:@"authType" value:kAuthTypeVerifyApp],
[NSURLQueryItem queryItemWithName:@"ibi" value:bundleID ?: @""],
[NSURLQueryItem queryItemWithName:@"clientId" value:clientID],
[NSURLQueryItem queryItemWithName:@"v" value:[FIRAuthBackend authUserAgent]],
[NSURLQueryItem queryItemWithName:@"eventId" value:eventID]
] mutableCopy
];
if (self->_auth.requestConfiguration.languageCode) {
[queryItems addObject:[NSURLQueryItem queryItemWithName:@"hl"value:
self->_auth.requestConfiguration.languageCode]];
}
NSURLComponents *components = [[NSURLComponents alloc] initWithString:
[NSString stringWithFormat:kReCAPTCHAURLStringFormat, authDomain]];
[components setQueryItems:queryItems];
completion([components URL], nil);
}];
}
/** @fn fetchAuthDomainWithCompletion:completion:
@brief Fetches the auth domain associated with the Firebase Project.
@param completion The callback invoked after the auth domain has been constructed or an error
has been encountered.
*/
- (void)fetchAuthDomainWithCompletion:(FIRFetchAuthDomainCallback)completion {
FIRGetProjectConfigRequest *request =
[[FIRGetProjectConfigRequest alloc] initWithRequestConfiguration:_auth.requestConfiguration];
[FIRAuthBackend getProjectConfig:request
callback:^(FIRGetProjectConfigResponse *_Nullable response,
NSError *_Nullable error) {
if (error) {
completion(nil, error);
return;
}
NSString *authDomain;
for (NSString *domain in response.authorizedDomains) {
NSInteger index = domain.length - kAuthDomainSuffix.length;
if (index >= 2) {
if ([domain hasSuffix:kAuthDomainSuffix] && domain.length >= kAuthDomainSuffix.length + 2) {
authDomain = domain;
break;
}
}
}
if (!authDomain.length) {
completion(nil, [FIRAuthErrorUtils unexpectedErrorResponseWithDeserializedResponse:response]);
return;
}
completion(authDomain, nil);
}];
}
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import "FIRAuthCredential_Internal.h"
NS_ASSUME_NONNULL_BEGIN
/** @class FIRTwitterAuthCredential
@brief Internal implementation of FIRAuthCredential for Twitter credentials.
*/
@interface FIRTwitterAuthCredential : FIRAuthCredential
/** @property token
@brief The Twitter OAuth token.
*/
@property(nonatomic, readonly) NSString *token;
/** @property secret
@brief The Twitter OAuth secret.
*/
@property(nonatomic, readonly) NSString *secret;
/** @fn initWithToken:secret:
@brief Designated initializer.
@param token The Twitter OAuth token.
@param secret The Twitter OAuth secret.
*/
- (nullable instancetype)initWithToken:(NSString *)token secret:(NSString *)secret
NS_DESIGNATED_INITIALIZER;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,51 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRTwitterAuthCredential.h"
#import "FIRTwitterAuthProvider.h"
#import "FIRAuthExceptionUtils.h"
#import "FIRVerifyAssertionRequest.h"
@interface FIRTwitterAuthCredential ()
- (nullable instancetype)initWithProvider:(NSString *)provider NS_UNAVAILABLE;
@end
@implementation FIRTwitterAuthCredential
- (nullable instancetype)initWithProvider:(NSString *)provider {
[FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason:
@"Please call the designated initializer."];
return nil;
}
- (nullable instancetype)initWithToken:(NSString *)token secret:(NSString *)secret {
self = [super initWithProvider:FIRTwitterAuthProviderID];
if (self) {
_token = [token copy];
_secret = [secret copy];
}
return self;
}
- (void)prepareVerifyAssertionRequest:(FIRVerifyAssertionRequest *)request {
request.providerAccessToken = _token;
request.providerOAuthTokenSecret = _secret;
}
@end

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRTwitterAuthProvider.h"
#import "FIRTwitterAuthCredential.h"
#import "FIRAuthExceptionUtils.h"
// FIRTwitterAuthProviderID is defined in FIRAuthProvider.m.
@implementation FIRTwitterAuthProvider
- (instancetype)init {
[FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason:
@"This class is not meant to be initialized."];
return nil;
}
+ (FIRAuthCredential *)credentialWithToken:(NSString *)token secret:(NSString *)secret {
return [[FIRTwitterAuthCredential alloc] initWithToken:token secret:secret];
}
@end

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRActionCodeSettings.h"
NS_ASSUME_NONNULL_BEGIN
@implementation FIRActionCodeSettings
- (instancetype)init {
self = [super init];
if (self) {
_iOSBundleID = [NSBundle mainBundle].bundleIdentifier;
}
return self;
}
- (void)setIOSBundleID:(NSString *)iOSBundleID {
_iOSBundleID = [iOSBundleID copy];
}
- (void)setAndroidPackageName:(NSString *)androidPackageName
installIfNotAvailable:(BOOL)installIfNotAvailable
minimumVersion:(nullable NSString *)minimumVersion {
_androidPackageName = [androidPackageName copy];
_androidInstallIfNotAvailable = installIfNotAvailable;
_androidMinimumVersion = [minimumVersion copy];
}
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,98 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAdditionalUserInfo_Internal.h"
#import "FIRVerifyAssertionResponse.h"
NS_ASSUME_NONNULL_BEGIN
@implementation FIRAdditionalUserInfo
/** @var kProviderIDCodingKey
@brief The key used to encode the providerID property for NSSecureCoding.
*/
static NSString *const kProviderIDCodingKey = @"providerID";
/** @var kProfileCodingKey
@brief The key used to encode the profile property for NSSecureCoding.
*/
static NSString *const kProfileCodingKey = @"profile";
/** @var kUsernameCodingKey
@brief The key used to encode the username property for NSSecureCoding.
*/
static NSString *const kUsernameCodingKey = @"username";
/** @var kNewUserKey
@brief The key used to encode the newUser property for NSSecureCoding.
*/
static NSString *const kNewUserKey = @"newUser";
+ (nullable instancetype)userInfoWithVerifyAssertionResponse:
(FIRVerifyAssertionResponse *)verifyAssertionResponse {
return [[self alloc] initWithProviderID:verifyAssertionResponse.providerID
profile:verifyAssertionResponse.profile
username:verifyAssertionResponse.username
isNewUser:verifyAssertionResponse.isNewUser];
}
- (nullable instancetype)initWithProviderID:(nullable NSString *)providerID
profile:(nullable NSDictionary<NSString *, NSObject *> *)profile
username:(nullable NSString *)username
isNewUser:(BOOL)isNewUser {
self = [super init];
if (self) {
_providerID = [providerID copy];
if (profile) {
_profile = [[NSDictionary alloc] initWithDictionary:profile copyItems:YES];
}
_username = [username copy];
_newUser = isNewUser;
}
return self;
}
#pragma mark - NSSecureCoding
+ (BOOL)supportsSecureCoding {
return YES;
}
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
NSString *providerID =
[aDecoder decodeObjectOfClass:[NSString class] forKey:kProviderIDCodingKey];
NSDictionary<NSString *, NSObject *> *profile =
[aDecoder decodeObjectOfClass:[NSDictionary class] forKey:kProfileCodingKey];
NSString *username = [aDecoder decodeObjectOfClass:[NSString class] forKey:kUsernameCodingKey];
NSNumber *isNewUser = [aDecoder decodeObjectOfClass:[NSNumber class] forKey:kNewUserKey];
return [self initWithProviderID:providerID
profile:profile
username:username
isNewUser:isNewUser.boolValue];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_providerID forKey:kProviderIDCodingKey];
[aCoder encodeObject:_profile forKey:kProfileCodingKey];
[aCoder encodeObject:_username forKey:kUsernameCodingKey];
[aCoder encodeObject:[NSNumber numberWithBool:_newUser] forKey:kNewUserKey];
}
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAdditionalUserInfo.h"
NS_ASSUME_NONNULL_BEGIN
@interface FIRAdditionalUserInfo () <NSSecureCoding>
/** @fn userInfoWithVerifyAssertionResponse:
@brief A convenience factory method for constructing a @c FIRAdditionalUserInfo instance from
data returned by the verifyAssertion endpoint.
@param verifyAssertionResponse Data returned by the verifyAssertion endpoint.
@return A new instance of @c FIRAdditionalUserInfo using data from the verifyAssertion endpoint.
*/
+ (nullable instancetype)userInfoWithVerifyAssertionResponse:
(FIRVerifyAssertionResponse *)verifyAssertionResponse;
/** @fn initWithProviderID:profile:username:
@brief Designated initializer.
@param providerID The provider identifier.
@param profile Dictionary containing the additional IdP specific information.
@param username The name of the user.
@param isNewUser Indicates whether or not the current user was signed in for the first time.
*/
- (nullable instancetype)initWithProviderID:(nullable NSString *)providerID
profile:(nullable NSDictionary<NSString *, NSObject *> *)profile
username:(nullable NSString *)username
isNewUser:(BOOL)isNewUser NS_DESIGNATED_INITIALIZER;
@end
NS_ASSUME_NONNULL_END

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,59 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import "FIRAuthAPNSTokenType.h"
NS_ASSUME_NONNULL_BEGIN
/** @class FIRAuthAPNSToken
@brief A data structure for an APNs token.
*/
@interface FIRAuthAPNSToken : NSObject
/** @property data
@brief The APNs token data.
*/
@property(nonatomic, strong, readonly) NSData *data;
/** @property string
@brief The uppercase hexadecimal string form of the APNs token data.
*/
@property(nonatomic, strong, readonly) NSString *string;
/** @property type
@brief The APNs token type.
*/
@property(nonatomic, assign, readonly) FIRAuthAPNSTokenType type;
/** @fn initWithData:type:
@brief Initializes the instance.
@param data The APNs token data.
@param type The APNs token type.
@return The initialized instance.
*/
- (instancetype)initWithData:(NSData *)data type:(FIRAuthAPNSTokenType)type
NS_DESIGNATED_INITIALIZER;
/** @fn init
@brief Call @c initWithData:type: to get an instance of this class.
*/
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthAPNSToken.h"
NS_ASSUME_NONNULL_BEGIN
@implementation FIRAuthAPNSToken {
/** @var _string
@brief The lazy-initialized string form of the token data.
*/
NSString *_string;
}
- (instancetype)initWithData:(NSData *)data type:(FIRAuthAPNSTokenType)type {
self = [super init];
if (self) {
_data = [data copy];
_type = type;
}
return self;
}
- (NSString *)string {
if (!_string) {
NSUInteger capacity = _data.length * 2;
NSMutableString *tokenString = [NSMutableString stringWithCapacity:capacity];
const unsigned char *tokenData = _data.bytes;
for (int idx = 0; idx < _data.length; ++idx) {
[tokenString appendFormat:@"%02X", (int)tokenData[idx]];
}
_string = tokenString;
}
return _string;
}
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,78 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@class FIRAuthAPNSToken;
NS_ASSUME_NONNULL_BEGIN
/** @typedef FIRAuthAPNSTokenCallback
@brief The type of block to receive an APNs token.
@param token The APNs token if one is available.
@param error The error happened if any.
@remarks Both `token` and `error` being `nil` means the request timed-out.
*/
typedef void (^FIRAuthAPNSTokenCallback)(FIRAuthAPNSToken *_Nullable token,
NSError *_Nullable error);
/** @class FIRAuthAPNSTokenManager
@brief A class to manage APNs token in memory.
*/
@interface FIRAuthAPNSTokenManager : NSObject
/** @property token
@brief The APNs token, if one is available.
@remarks Setting a token with FIRAuthAPNSTokenTypeUnknown will automatically converts it to
a token with the automatically detected type.
*/
@property(nonatomic, strong, nullable) FIRAuthAPNSToken *token;
/** @property timeout
@brief The timeout for registering for remote notification.
@remarks Only tests should access this property.
*/
@property(nonatomic, assign) NSTimeInterval timeout;
/** @fn init
@brief Call @c initWithApplication: to initialize an instance of this class.
*/
- (instancetype)init NS_UNAVAILABLE;
/** @fn initWithApplication:bundle
@brief Initializes the instance.
@param application The @c UIApplication to request the token from.
@return The initialized instance.
*/
- (instancetype)initWithApplication:(UIApplication *)application NS_DESIGNATED_INITIALIZER;
/** @fn getTokenWithCallback:
@brief Attempts to get the APNs token.
@param callback The block to be called either immediately or in future, either when a token
becomes available, or when timeout occurs, whichever happens earlier.
*/
- (void)getTokenWithCallback:(FIRAuthAPNSTokenCallback)callback;
/** @fn cancelWithError:
@brief Cancels any pending `getTokenWithCallback:` request.
@param error The error to return.
*/
- (void)cancelWithError:(NSError *)error;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,247 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthAPNSTokenManager.h"
#import <FirebaseCore/FIRLogger.h>
#import <GoogleUtilities/GULAppEnvironmentUtil.h>
#import "FIRAuthAPNSToken.h"
#import "FIRAuthGlobalWorkQueue.h"
NS_ASSUME_NONNULL_BEGIN
/** @var kRegistrationTimeout
@brief Timeout for registration for remote notification.
@remarks Once we start to handle `application:didFailToRegisterForRemoteNotificationsWithError:`
we probably don't have to use timeout at all.
*/
static const NSTimeInterval kRegistrationTimeout = 5;
/** @var kLegacyRegistrationTimeout
@brief Timeout for registration for remote notification on iOS 7.
*/
static const NSTimeInterval kLegacyRegistrationTimeout = 30;
@implementation FIRAuthAPNSTokenManager {
/** @var _application
@brief The @c UIApplication to request the token from.
*/
UIApplication *_application;
/** @var _pendingCallbacks
@brief The list of all pending callbacks for the APNs token.
*/
NSMutableArray<FIRAuthAPNSTokenCallback> *_pendingCallbacks;
}
- (instancetype)initWithApplication:(UIApplication *)application {
self = [super init];
if (self) {
_application = application;
_timeout = [_application respondsToSelector:@selector(registerForRemoteNotifications)] ?
kRegistrationTimeout : kLegacyRegistrationTimeout;
}
return self;
}
- (void)getTokenWithCallback:(FIRAuthAPNSTokenCallback)callback {
if (_token) {
callback(_token, nil);
return;
}
if (_pendingCallbacks) {
[_pendingCallbacks addObject:callback];
return;
}
_pendingCallbacks =
[[NSMutableArray<FIRAuthAPNSTokenCallback> alloc] initWithObjects:callback, nil];
dispatch_async(dispatch_get_main_queue(), ^{
if ([self->_application respondsToSelector:@selector(registerForRemoteNotifications)]) {
[self->_application registerForRemoteNotifications];
} else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#if TARGET_OS_IOS
[self->_application registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert];
#endif // TARGET_OS_IOS
#pragma clang diagnostic pop
}
});
NSArray<FIRAuthAPNSTokenCallback> *applicableCallbacks = _pendingCallbacks;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_timeout * NSEC_PER_SEC)),
FIRAuthGlobalWorkQueue(), ^{
// Only cancel if the pending callbacks remain the same, i.e., not triggered yet.
if (applicableCallbacks == self->_pendingCallbacks) {
[self callBackWithToken:nil error:nil];
}
});
}
- (void)setToken:(nullable FIRAuthAPNSToken *)token {
if (!token) {
_token = nil;
return;
}
if (token.type == FIRAuthAPNSTokenTypeUnknown) {
static FIRAuthAPNSTokenType detectedTokenType = FIRAuthAPNSTokenTypeUnknown;
if (detectedTokenType == FIRAuthAPNSTokenTypeUnknown) {
detectedTokenType =
[[self class] isProductionApp] ? FIRAuthAPNSTokenTypeProd : FIRAuthAPNSTokenTypeSandbox;
}
token = [[FIRAuthAPNSToken alloc] initWithData:token.data type:detectedTokenType];
}
_token = token;
[self callBackWithToken:token error:nil];
}
- (void)cancelWithError:(NSError *)error {
[self callBackWithToken:nil error:error];
}
#pragma mark - Internal methods
/** @fn callBack
@brief Calls back all pending callbacks with APNs token or error.
@param token The APNs token if one is available.
@param error The error occurred, if any.
*/
- (void)callBackWithToken:(nullable FIRAuthAPNSToken *)token error:(nullable NSError *)error {
if (!_pendingCallbacks) {
return;
}
NSArray<FIRAuthAPNSTokenCallback> *allCallbacks = _pendingCallbacks;
_pendingCallbacks = nil;
for (FIRAuthAPNSTokenCallback callback in allCallbacks) {
callback(token, error);
}
};
/** @fn isProductionApp
@brief Whether or not the app has production (versus sandbox) provisioning profile.
@remarks This method is adapted from @c FIRInstanceID .
*/
+ (BOOL)isProductionApp {
const BOOL defaultAppTypeProd = YES;
NSError *error = nil;
if ([GULAppEnvironmentUtil isSimulator]) {
FIRLogInfo(kFIRLoggerAuth, @"I-AUT000006", @"Assuming prod APNs token type on simulator.");
return defaultAppTypeProd;
}
// Apps distributed via AppStore or TestFlight use the Production APNS certificates.
if ([GULAppEnvironmentUtil isFromAppStore]) {
return defaultAppTypeProd;
}
NSString *path = [[[NSBundle mainBundle] bundlePath]
stringByAppendingPathComponent:@"embedded.mobileprovision"];
if ([GULAppEnvironmentUtil isAppStoreReceiptSandbox] && !path.length) {
// Distributed via TestFlight
return defaultAppTypeProd;
}
NSMutableData *profileData = [NSMutableData dataWithContentsOfFile:path options:0 error:&error];
if (!profileData.length || error) {
FIRLogInfo(kFIRLoggerAuth, @"I-AUT000007",
@"Error while reading embedded mobileprovision %@", error);
return defaultAppTypeProd;
}
// The "embedded.mobileprovision" sometimes contains characters with value 0, which signals the
// end of a c-string and halts the ASCII parser, or with value > 127, which violates strict 7-bit
// ASCII. Replace any 0s or invalid characters in the input.
uint8_t *profileBytes = (uint8_t *)profileData.bytes;
for (int i = 0; i < profileData.length; i++) {
uint8_t currentByte = profileBytes[i];
if (!currentByte || currentByte > 127) {
profileBytes[i] = '.';
}
}
NSString *embeddedProfile = [[NSString alloc] initWithBytesNoCopy:profileBytes
length:profileData.length
encoding:NSASCIIStringEncoding
freeWhenDone:NO];
if (error || !embeddedProfile.length) {
FIRLogInfo(kFIRLoggerAuth, @"I-AUT000008",
@"Error while reading embedded mobileprovision %@", error);
return defaultAppTypeProd;
}
NSScanner *scanner = [NSScanner scannerWithString:embeddedProfile];
NSString *plistContents;
if ([scanner scanUpToString:@"<plist" intoString:nil]) {
if ([scanner scanUpToString:@"</plist>" intoString:&plistContents]) {
plistContents = [plistContents stringByAppendingString:@"</plist>"];
}
}
if (!plistContents.length) {
return defaultAppTypeProd;
}
NSData *data = [plistContents dataUsingEncoding:NSUTF8StringEncoding];
if (!data.length) {
FIRLogInfo(kFIRLoggerAuth, @"I-AUT000009",
@"Couldn't read plist fetched from embedded mobileprovision");
return defaultAppTypeProd;
}
NSError *plistMapError;
id plistData = [NSPropertyListSerialization propertyListWithData:data
options:NSPropertyListImmutable
format:nil
error:&plistMapError];
if (plistMapError || ![plistData isKindOfClass:[NSDictionary class]]) {
FIRLogInfo(kFIRLoggerAuth, @"I-AUT000010",
@"Error while converting assumed plist to dict %@",
plistMapError.localizedDescription);
return defaultAppTypeProd;
}
NSDictionary *plistMap = (NSDictionary *)plistData;
if ([plistMap valueForKeyPath:@"ProvisionedDevices"]) {
FIRLogInfo(kFIRLoggerAuth, @"I-AUT000011",
@"Provisioning profile has specifically provisioned devices, "
@"most likely a Dev profile.");
}
NSString *apsEnvironment = [plistMap valueForKeyPath:@"Entitlements.aps-environment"];
FIRLogDebug(kFIRLoggerAuth, @"I-AUT000012",
@"APNS Environment in profile: %@", apsEnvironment);
// No aps-environment in the profile.
if (!apsEnvironment.length) {
FIRLogInfo(kFIRLoggerAuth, @"I-AUT000013",
@"No aps-environment set. If testing on a device APNS is not "
@"correctly configured. Please recheck your provisioning profiles.");
return defaultAppTypeProd;
}
if ([apsEnvironment isEqualToString:@"development"]) {
return NO;
}
return defaultAppTypeProd;
}
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/** @class FIRAuthAppCredential
@brief A class represents a credential that proves the identity of the app.
*/
@interface FIRAuthAppCredential : NSObject <NSSecureCoding>
/** @property receipt
@brief The server acknowledgement of receiving client's claim of identity.
*/
@property(nonatomic, strong, readonly) NSString *receipt;
/** @property secret
@brief The secret that the client received from server via a trusted channel, if ever.
*/
@property(nonatomic, strong, readonly, nullable) NSString *secret;
/** @fn initWithReceipt:secret:
@brief Initializes the instance.
@param receipt The server acknowledgement of receiving client's claim of identity.
@param secret The secret that the client received from server via a trusted channel, if ever.
@return The initialized instance.
*/
- (instancetype)initWithReceipt:(NSString *)receipt secret:(nullable NSString *)secret
NS_DESIGNATED_INITIALIZER;
/** @fn init
@brief Call @c initWithReceipt:secret: to get an instance of this class.
*/
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,64 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthAppCredential.h"
NS_ASSUME_NONNULL_BEGIN
/** @var kReceiptKey
@brief The key used to encode the receipt property for NSSecureCoding.
*/
static NSString *const kReceiptKey = @"receipt";
/** @var kSecretKey
@brief The key used to encode the secret property for NSSecureCoding.
*/
static NSString *const kSecretKey = @"secret";
@implementation FIRAuthAppCredential
- (instancetype)initWithReceipt:(NSString *)receipt secret:(nullable NSString *)secret {
self = [super init];
if (self) {
_receipt = [receipt copy];
_secret = [secret copy];
}
return self;
}
#pragma mark - NSSecureCoding
+ (BOOL)supportsSecureCoding {
return YES;
}
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
NSString *receipt = [aDecoder decodeObjectOfClass:[NSString class] forKey:kReceiptKey];
if (!receipt) {
return nil;
}
NSString *secret = [aDecoder decodeObjectOfClass:[NSString class] forKey:kSecretKey];
return [self initWithReceipt:receipt secret:secret];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_receipt forKey:kReceiptKey];
[aCoder encodeObject:_secret forKey:kSecretKey];
}
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,85 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
@class FIRAuthAppCredential;
@class FIRAuthKeychain;
NS_ASSUME_NONNULL_BEGIN
/** @typedef FIRAuthAppCredentialCallback
@brief The type of block to receive an app crdential.
@param credential The best available app credential at the time.
*/
typedef void (^FIRAuthAppCredentialCallback)(FIRAuthAppCredential *credential);
/** @class FIRAuthAppCredentialManager
@brief A class to manage app credentials backed by iOS Keychain.
*/
@interface FIRAuthAppCredentialManager : NSObject
/** @property credential
@brief The full credential (which has a secret) to be used by the app, if one is available.
*/
@property(nonatomic, strong, readonly, nullable) FIRAuthAppCredential *credential;
/** @property maximumNumberOfPendingReceipts
@brief The maximum (but not necessarily the minimum) number of pending receipts to be kept.
@remarks Only tests should access this property.
*/
@property(nonatomic, assign, readonly) NSUInteger maximumNumberOfPendingReceipts;
/** @fn init
@brief Call @c initWithKeychain: to initialize an instance of this class.
*/
- (instancetype)init NS_UNAVAILABLE;
/** @fn initWithKeychain:
@brief Initializes the instance.
@param keychain The iOS Keychain storage to back up the app credential with.
@return The initialized instance.
*/
- (instancetype)initWithKeychain:(FIRAuthKeychain *)keychain NS_DESIGNATED_INITIALIZER;
/** @fn didStartVerificationWithReceipt:timeout:callback:
@brief Notifies that the app verification process has started.
@param receipt The receipt for verification.
@param timeout The timeout value for how long the callback is waited to be called.
@param callback The block to be called in future either when the verification finishes, or
when timeout occurs, whichever happens earlier.
*/
- (void)didStartVerificationWithReceipt:(NSString *)receipt
timeout:(NSTimeInterval)timeout
callback:(FIRAuthAppCredentialCallback)callback;
/** @fn canFinishVerificationWithReceipt:
@brief Attempts to finish verification.
@param receipt The receipt to match the original receipt obtained when verification started.
@param secret The secret to complete the verification.
@return Whether or not the receipt matches a pending verification, and finishes verification
if it does.
*/
- (BOOL)canFinishVerificationWithReceipt:(NSString *)receipt secret:(NSString *)secret;
/** @fn clearCredential
@brief Clears the saved credential, to be used in the case that it is rejected by the server.
*/
- (void)clearCredential;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,164 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthAppCredentialManager.h"
#import "FIRAuthAppCredential.h"
#import "FIRAuthGlobalWorkQueue.h"
#import "FIRAuthKeychain.h"
NS_ASSUME_NONNULL_BEGIN
/** @var kKeychainDataKey
@brief The keychain key for the data.
*/
static NSString *const kKeychainDataKey = @"app_credentials";
/** @var kFullCredentialKey
@brief The data key for the full app credential.
*/
static NSString *const kFullCredentialKey = @"full_credential";
/** @var kPendingReceiptsKey
@brief The data key for the array of pending receipts.
*/
static NSString *const kPendingReceiptsKey = @"pending_receipts";
/** @var kMaximumNumberOfPendingReceipts
@brief The maximum number of partial credentials kept by this class.
*/
static const NSUInteger kMaximumNumberOfPendingReceipts = 32;
@implementation FIRAuthAppCredentialManager {
/** @var _keychain
@brief The keychain for app credentials to load from and to save to.
*/
FIRAuthKeychain *_keychain;
/** @var _pendingReceipts
@brief A list of pending receipts sorted in the order they were recorded.
*/
NSMutableArray<NSString *> *_pendingReceipts;
/** @var _callbacksByReceipt
@brief A map from pending receipts to callbacks.
*/
NSMutableDictionary<NSString *, FIRAuthAppCredentialCallback> *_callbacksByReceipt;
}
- (instancetype)initWithKeychain:(FIRAuthKeychain *)keychain {
self = [super init];
if (self) {
_keychain = keychain;
// Load the credentials from keychain if possible.
NSError *error;
NSData *encodedData = [_keychain dataForKey:kKeychainDataKey error:&error];
if (!error && encodedData) {
NSKeyedUnarchiver *unarchiver =
[[NSKeyedUnarchiver alloc] initForReadingWithData:encodedData];
FIRAuthAppCredential *credential =
[unarchiver decodeObjectOfClass:[FIRAuthAppCredential class]
forKey:kFullCredentialKey];
if ([credential isKindOfClass:[FIRAuthAppCredential class]]) {
_credential = credential;
}
NSSet<Class> *allowedClasses =
[NSSet<Class> setWithObjects:[NSArray class], [NSString class], nil];
NSArray<NSString *> *pendingReceipts =
[unarchiver decodeObjectOfClasses:allowedClasses forKey:kPendingReceiptsKey];
if ([pendingReceipts isKindOfClass:[NSArray class]]) {
_pendingReceipts = [pendingReceipts mutableCopy];
}
}
if (!_pendingReceipts) {
_pendingReceipts = [[NSMutableArray<NSString *> alloc] init];
}
_callbacksByReceipt =
[[NSMutableDictionary<NSString *, FIRAuthAppCredentialCallback> alloc] init];
}
return self;
}
- (NSUInteger)maximumNumberOfPendingReceipts {
return kMaximumNumberOfPendingReceipts;
}
- (void)didStartVerificationWithReceipt:(NSString *)receipt
timeout:(NSTimeInterval)timeout
callback:(FIRAuthAppCredentialCallback)callback {
[_pendingReceipts removeObject:receipt];
if (_pendingReceipts.count >= kMaximumNumberOfPendingReceipts) {
[_pendingReceipts removeObjectAtIndex:0];
}
[_pendingReceipts addObject:receipt];
_callbacksByReceipt[receipt] = callback;
[self saveData];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeout * NSEC_PER_SEC)),
FIRAuthGlobalWorkQueue(), ^{
[self callBackWithReceipt:receipt];
});
}
- (BOOL)canFinishVerificationWithReceipt:(NSString *)receipt secret:(NSString *)secret {
if (![_pendingReceipts containsObject:receipt]) {
return NO;
}
[_pendingReceipts removeObject:receipt];
_credential = [[FIRAuthAppCredential alloc] initWithReceipt:receipt secret:secret];
[self saveData];
[self callBackWithReceipt:receipt];
return YES;
}
- (void)clearCredential {
_credential = nil;
[self saveData];
}
#pragma mark - Internal methods
/** @fn saveData
@brief Save the data in memory to the keychain ignoring any errors.
*/
- (void)saveData {
NSMutableData *archiveData = [NSMutableData data];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:archiveData];
[archiver encodeObject:_credential forKey:kFullCredentialKey];
[archiver encodeObject:_pendingReceipts forKey:kPendingReceiptsKey];
[archiver finishEncoding];
[_keychain setData:archiveData forKey:kKeychainDataKey error:NULL];
}
/** @fn callBackWithReceipt:
@brief Calls the saved callback for the specifc receipt.
@param receipt The receipt associated with the callback.
*/
- (void)callBackWithReceipt:(NSString *)receipt {
FIRAuthAppCredentialCallback callback = _callbacksByReceipt[receipt];
if (!callback) {
return;
}
[_callbacksByReceipt removeObjectForKey:receipt];
if (_credential) {
callback(_credential);
} else {
callback([[FIRAuthAppCredential alloc] initWithReceipt:receipt secret:nil]);
}
}
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,87 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
/** @protocol FIRAuthAppDelegateHandler
@brief The protocol to handle app delegate methods.
*/
@protocol FIRAuthAppDelegateHandler <NSObject>
/** @fn setAPNSToken:
@brief Sets the APNs device token.
@param token The APNs device token.
*/
- (void)setAPNSToken:(NSData *)token;
/** @fn handleAPNSTokenError:
@brief Handles APNs device token error.
@param error The APNs device token error.
*/
- (void)handleAPNSTokenError:(NSError *)error;
/** @fn canHandleNotification:
@brief Checks whether the notification can be handled by the receiver, and handles it if so.
@param notification The notification in question, which will be consumed if returns @c YES.
@return Whether the notification can be (and already has been) handled by the receiver.
*/
- (BOOL)canHandleNotification:(nonnull NSDictionary *)notification;
/** @fn canHandleURL:
@brief Checks whether the URL can be handled by the receiver, and handles it if so.
@param url The URL in question, which will be consumed if returns @c YES.
@return Whether the URL can be (and already has been) handled by the receiver.
*/
- (BOOL)canHandleURL:(nonnull NSURL *)url;
@end
/** @class FIRAuthAppDelegateProxy
@brief A manager for swizzling @c UIApplicationDelegate methods.
*/
@interface FIRAuthAppDelegateProxy : NSObject
/** @fn initWithApplication
@brief Initialize the instance with the given @c UIApplication.
@returns An initialized instance, or @c nil if a proxy cannot be established.
@remarks This method should only be called from tests if called outside of this class.
*/
- (nullable instancetype)initWithApplication:(nullable UIApplication *)application
NS_DESIGNATED_INITIALIZER;
/** @fn init
@brief Call @c sharedInstance to get an instance of this class.
*/
- (instancetype)init NS_UNAVAILABLE;
/** @fn addHandler:
@brief Adds a handler for UIApplicationDelegate methods.
@param handler The handler to be added.
*/
- (void)addHandler:(__weak id<FIRAuthAppDelegateHandler>)handler;
/** @fn sharedInstance
@brief Gets the shared instance of this class.
@returns The shared instance of this class.
*/
+ (nullable instancetype)sharedInstance;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,412 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthAppDelegateProxy.h"
#import <GoogleUtilities/GULAppEnvironmentUtil.h>
#import <objc/runtime.h>
NS_ASSUME_NONNULL_BEGIN
/** @var kProxyEnabledBundleKey
@brief The key in application's bundle plist for whether or not proxy should be enabled.
@remarks This key is a shared constant with Analytics and FCM.
*/
static NSString *const kProxyEnabledBundleKey = @"FirebaseAppDelegateProxyEnabled";
/** @fn noop
@brief A function that does nothing.
@remarks This is used as the placeholder for unimplemented UApplicationDelegate methods,
because once we added a method there is no way to remove it from the class.
*/
#if !OBJC_OLD_DISPATCH_PROTOTYPES
static void noop(void) {
}
#else
static id noop(id object, SEL cmd, ...) {
return nil;
}
#endif
/** @fn isIOS9orLater
@brief Checks whether the iOS version is 9 or later.
@returns Whether the iOS version is 9 or later.
*/
static BOOL isIOS9orLater() {
#if defined(__IPHONE_11_0) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0)
if (@available(iOS 9.0, *)) {
return YES;
}
return NO;
#else
// UIApplicationOpenURLOptionsAnnotationKey is only available on iOS 9+.
return &UIApplicationOpenURLOptionsAnnotationKey != NULL;
#endif
}
@implementation FIRAuthAppDelegateProxy {
/** @var _appDelegate
@brief The application delegate whose method is being swizzled.
*/
id<UIApplicationDelegate> _appDelegate;
/** @var _orginalImplementationsBySelector
@brief A map from selectors to original implementations that have been swizzled.
*/
NSMutableDictionary<NSValue *, NSValue *> *_originalImplementationsBySelector;
/** @var _handlers
@brief The array of weak pointers of `id<FIRAuthAppDelegateHandler>`.
*/
NSPointerArray *_handlers;
}
- (nullable instancetype)initWithApplication:(nullable UIApplication *)application {
self = [super init];
if (self) {
id proxyEnabled = [[NSBundle mainBundle] objectForInfoDictionaryKey:kProxyEnabledBundleKey];
if ([proxyEnabled isKindOfClass:[NSNumber class]] && !((NSNumber *)proxyEnabled).boolValue) {
return nil;
}
_appDelegate = application.delegate;
if (![_appDelegate conformsToProtocol:@protocol(UIApplicationDelegate)]) {
return nil;
}
_originalImplementationsBySelector = [[NSMutableDictionary<NSValue *, NSValue *> alloc] init];
_handlers = [[NSPointerArray alloc] initWithOptions:NSPointerFunctionsWeakMemory];
// Swizzle the methods.
__weak FIRAuthAppDelegateProxy *weakSelf = self;
SEL registerDeviceTokenSelector =
@selector(application:didRegisterForRemoteNotificationsWithDeviceToken:);
[self replaceSelector:registerDeviceTokenSelector
withBlock:^(id object, UIApplication* application, NSData *deviceToken) {
[weakSelf object:object
selector:registerDeviceTokenSelector
application:application
didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}];
SEL failToRegisterRemoteNotificationSelector =
@selector(application:didFailToRegisterForRemoteNotificationsWithError:);
[self replaceSelector:failToRegisterRemoteNotificationSelector
withBlock:^(id object, UIApplication* application, NSError *error) {
[weakSelf object:object
selector:failToRegisterRemoteNotificationSelector
application:application
didFailToRegisterForRemoteNotificationsWithError:error];
}];
SEL receiveNotificationSelector = @selector(application:didReceiveRemoteNotification:);
SEL receiveNotificationWithHandlerSelector =
@selector(application:didReceiveRemoteNotification:fetchCompletionHandler:);
if ([_appDelegate respondsToSelector:receiveNotificationWithHandlerSelector] ||
![_appDelegate respondsToSelector:receiveNotificationSelector]) {
// Replace the modern selector which is available on iOS 7 and above.
[self replaceSelector:receiveNotificationWithHandlerSelector
withBlock:^(id object, UIApplication *application, NSDictionary *notification,
void (^completionHandler)(UIBackgroundFetchResult)) {
[weakSelf object:object
selector:receiveNotificationWithHandlerSelector
application:application
didReceiveRemoteNotification:notification
fetchCompletionHandler:completionHandler];
}];
} else {
// Replace the deprecated selector because this is the only one that the client app uses.
[self replaceSelector:receiveNotificationSelector
withBlock:^(id object, UIApplication *application, NSDictionary *notification) {
[weakSelf object:object
selector:receiveNotificationSelector
application:application
didReceiveRemoteNotification:notification];
}];
}
SEL openURLOptionsSelector = @selector(application:openURL:options:);
SEL openURLAnnotationSelector = @selector(application:openURL:sourceApplication:annotation:);
SEL handleOpenURLSelector = @selector(application:handleOpenURL:);
if (isIOS9orLater() &&
([_appDelegate respondsToSelector:openURLOptionsSelector] ||
(![_appDelegate respondsToSelector:openURLAnnotationSelector] &&
![_appDelegate respondsToSelector:handleOpenURLSelector]))) {
// Replace the modern selector which is avaliable on iOS 9 and above because this is the one
// that the client app uses or the client app doesn't use any of them.
[self replaceSelector:openURLOptionsSelector
withBlock:^BOOL(id object, UIApplication *application, NSURL *url,
NSDictionary *options) {
return [weakSelf object:object
selector:openURLOptionsSelector
application:application
openURL:url
options:options];
}];
} else if ([_appDelegate respondsToSelector:openURLAnnotationSelector] ||
![_appDelegate respondsToSelector:handleOpenURLSelector]) {
// Replace the longer form of the deprecated selectors on iOS 8 and below because this is the
// one that the client app uses or the client app doesn't use either of the applicable ones.
[self replaceSelector:openURLAnnotationSelector
withBlock:^(id object, UIApplication *application, NSURL *url,
NSString *sourceApplication, id annotation) {
return [weakSelf object:object
selector:openURLAnnotationSelector
application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
}];
} else {
// Replace the shorter form of the deprecated selectors on iOS 8 and below because this is
// the only one that the client app uses.
[self replaceSelector:handleOpenURLSelector
withBlock:^(id object, UIApplication *application, NSURL *url) {
return [weakSelf object:object
selector:handleOpenURLSelector
application:application
handleOpenURL:url];
}];
}
// Reset the application delegate to clear the system cache that indicates whether each of the
// openURL: methods is implemented on the application delegate.
application.delegate = nil;
application.delegate = _appDelegate;
}
return self;
}
- (void)dealloc {
for (NSValue *selector in _originalImplementationsBySelector) {
IMP implementation = _originalImplementationsBySelector[selector].pointerValue;
Method method = class_getInstanceMethod([_appDelegate class], selector.pointerValue);
imp_removeBlock(method_setImplementation(method, implementation));
}
}
- (void)addHandler:(__weak id<FIRAuthAppDelegateHandler>)handler {
@synchronized (_handlers) {
[_handlers addPointer:(__bridge void *)handler];
}
}
+ (nullable instancetype)sharedInstance {
static dispatch_once_t onceToken;
static FIRAuthAppDelegateProxy *_Nullable sharedInstance;
// iOS App extensions should not call [UIApplication sharedApplication], even if UIApplication
// responds to it.
static Class applicationClass = nil;
dispatch_once(&onceToken, ^{
if (![GULAppEnvironmentUtil isAppExtension]) {
Class cls = NSClassFromString(@"UIApplication");
if (cls && [cls respondsToSelector:NSSelectorFromString(@"sharedApplication")]) {
applicationClass = cls;
}
}
UIApplication *application = [applicationClass sharedApplication];
sharedInstance = [[self alloc] initWithApplication:application];
});
return sharedInstance;
}
#pragma mark - UIApplicationDelegate proxy methods.
- (void)object:(id)object
selector:(SEL)selector
application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
if (object == _appDelegate) {
for (id<FIRAuthAppDelegateHandler> handler in [self handlers]) {
[handler setAPNSToken:deviceToken];
}
}
IMP originalImplementation = [self originalImplementationForSelector:selector];
if (originalImplementation && originalImplementation != &noop) {
typedef void (*Implmentation)(id, SEL, UIApplication*, NSData *);
((Implmentation)originalImplementation)(object, selector, application, deviceToken);
}
}
- (void)object:(id)object
selector:(SEL)selector
application:(UIApplication *)application
didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
if (object == _appDelegate) {
for (id<FIRAuthAppDelegateHandler> handler in [self handlers]) {
[handler handleAPNSTokenError:error];
}
}
IMP originalImplementation = [self originalImplementationForSelector:selector];
if (originalImplementation && originalImplementation != &noop) {
typedef void (*Implmentation)(id, SEL, UIApplication *, NSError *);
((Implmentation)originalImplementation)(object, selector, application, error);
}
}
- (void)object:(id)object
selector:(SEL)selector
application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)notification
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
if (object == _appDelegate) {
for (id<FIRAuthAppDelegateHandler> handler in [self handlers]) {
if ([handler canHandleNotification:notification]) {
completionHandler(UIBackgroundFetchResultNoData);
return;
};
}
}
IMP originalImplementation = [self originalImplementationForSelector:selector];
if (originalImplementation && originalImplementation != &noop) {
typedef void (*Implmentation)(id, SEL, UIApplication*, NSDictionary *,
void (^)(UIBackgroundFetchResult));
((Implmentation)originalImplementation)(object, selector, application, notification,
completionHandler);
}
}
- (void)object:(id)object
selector:(SEL)selector
application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)notification {
if (object == _appDelegate) {
for (id<FIRAuthAppDelegateHandler> handler in [self handlers]) {
if ([handler canHandleNotification:notification]) {
return;
};
}
}
IMP originalImplementation = [self originalImplementationForSelector:selector];
if (originalImplementation && originalImplementation != &noop) {
typedef void (*Implmentation)(id, SEL, UIApplication*, NSDictionary *);
((Implmentation)originalImplementation)(object, selector, application, notification);
}
}
- (BOOL)object:(id)object
selector:(SEL)selector
application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary *)options {
if (object == _appDelegate && [self delegateCanHandleURL:url]) {
return YES;
}
IMP originalImplementation = [self originalImplementationForSelector:selector];
if (originalImplementation && originalImplementation != &noop) {
typedef BOOL (*Implmentation)(id, SEL, UIApplication*, NSURL *, NSDictionary *);
return ((Implmentation)originalImplementation)(object, selector, application, url, options);
}
return NO;
}
- (BOOL)object:(id)object
selector:(SEL)selector
application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
if (object == _appDelegate && [self delegateCanHandleURL:url]) {
return YES;
}
IMP originalImplementation = [self originalImplementationForSelector:selector];
if (originalImplementation && originalImplementation != &noop) {
typedef BOOL (*Implmentation)(id, SEL, UIApplication*, NSURL *, NSString *, id);
return ((Implmentation)originalImplementation)(object, selector, application, url,
sourceApplication, annotation);
}
return NO;
}
- (BOOL)object:(id)object
selector:(SEL)selector
application:(UIApplication *)application
handleOpenURL:(NSURL *)url {
if (object == _appDelegate && [self delegateCanHandleURL:url]) {
return YES;
}
IMP originalImplementation = [self originalImplementationForSelector:selector];
if (originalImplementation && originalImplementation != &noop) {
typedef BOOL (*Implmentation)(id, SEL, UIApplication*, NSURL *);
return ((Implmentation)originalImplementation)(object, selector, application, url);
}
return NO;
}
#pragma mark - Internal Methods
/** @fn delegateCanHandleURL:
@brief Checks for whether any of the delegates can handle the URL.
@param url The URL in question.
@return Whether any of the delegate can handle the URL.
*/
- (BOOL)delegateCanHandleURL:(NSURL *)url {
for (id<FIRAuthAppDelegateHandler> handler in [self handlers]) {
if ([handler canHandleURL:url]) {
return YES;
};
}
return NO;
}
/** @fn handlers
@brief Gets the list of handlers from `_handlers` safely.
*/
- (NSArray<id<FIRAuthAppDelegateHandler>> *)handlers {
@synchronized (_handlers) {
NSMutableArray<id<FIRAuthAppDelegateHandler>> *liveHandlers =
[[NSMutableArray<id<FIRAuthAppDelegateHandler>> alloc] initWithCapacity:_handlers.count];
for (__weak id<FIRAuthAppDelegateHandler> handler in _handlers) {
if (handler) {
[liveHandlers addObject:handler];
}
}
if (liveHandlers.count < _handlers.count) {
[_handlers compact];
}
return liveHandlers;
}
}
/** @fn replaceSelector:withBlock:
@brief replaces the implementation for a method of `_appDelegate` specified by a selector.
@param selector The selector for the method.
@param block The block as the new implementation of the method.
*/
- (void)replaceSelector:(SEL)selector withBlock:(id)block {
Method originalMethod = class_getInstanceMethod([_appDelegate class], selector);
IMP newImplementation = imp_implementationWithBlock(block);
IMP originalImplementation;
if (originalMethod) {
originalImplementation = method_setImplementation(originalMethod, newImplementation) ?: &noop;
} else {
// The original method was not implemented in the class, add it with the new implementation.
struct objc_method_description methodDescription =
protocol_getMethodDescription(@protocol(UIApplicationDelegate), selector, NO, YES);
class_addMethod([_appDelegate class], selector, newImplementation, methodDescription.types);
originalImplementation = &noop;
}
_originalImplementationsBySelector[[NSValue valueWithPointer:selector]] =
[NSValue valueWithPointer:originalImplementation];
}
/** @fn originalImplementationForSelector:
@brief Gets the original implementation for the given selector.
@param selector The selector for the method that has been replaced.
@return The original implementation if there was one.
*/
- (IMP)originalImplementationForSelector:(SEL)selector {
return _originalImplementationsBySelector[[NSValue valueWithPointer:selector]].pointerValue;
}
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,42 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthCredential_Internal.h"
@implementation FIRAuthCredential
- (instancetype)init {
@throw [NSException exceptionWithName:@"Attempt to call unavailable initializer."
reason:@"This class is an abstract base class. It's init method "
"should not be called directly."
userInfo:nil];
}
- (nullable instancetype)initWithProvider:(NSString *)provider {
self = [super init];
if (self) {
_provider = [provider copy];
}
return self;
}
- (void)prepareVerifyAssertionRequest:(FIRVerifyAssertionRequest *)request {
@throw [NSException exceptionWithName:@"Attempt to call virtual method."
reason:@"This method must be overridden by a subclass."
userInfo:nil];
}
@end

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthCredential.h"
@class FIRVerifyAssertionRequest;
NS_ASSUME_NONNULL_BEGIN
@interface FIRAuthCredential ()
/** @fn initWithProvider:
@brief Designated initializer.
@remarks This is the designated initializer for internal/friend subclasses.
@param provider The provider name.
*/
- (nullable instancetype)initWithProvider:(NSString *)provider NS_DESIGNATED_INITIALIZER;
/** @fn prepareVerifyAssertionRequest:
@brief Called immediately before a request to the verifyAssertion endpoint is made. Implementers
should update the passed request instance with their credentials.
@param request The request to be updated with credentials.
*/
- (void)prepareVerifyAssertionRequest:(FIRVerifyAssertionRequest *)request;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,69 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthDataResult_Internal.h"
#import "FIRAdditionalUserInfo.h"
#import "FIRUser.h"
NS_ASSUME_NONNULL_BEGIN
@implementation FIRAuthDataResult
/** @var kAdditionalUserInfoCodingKey
@brief The key used to encode the additionalUserInfo property for NSSecureCoding.
*/
static NSString *const kAdditionalUserInfoCodingKey = @"additionalUserInfo";
/** @var kUserCodingKey
@brief The key used to encode the user property for NSSecureCoding.
*/
static NSString *const kUserCodingKey = @"user";
- (nullable instancetype)initWithUser:(nullable FIRUser *)user
additionalUserInfo:(nullable FIRAdditionalUserInfo *)additionalUserInfo {
self = [super init];
if (self) {
_additionalUserInfo = additionalUserInfo;
_user = user;
}
return self;
}
#pragma mark - NSSecureCoding
+ (BOOL)supportsSecureCoding {
return YES;
}
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
FIRUser *user =
[aDecoder decodeObjectOfClass:[FIRUser class] forKey:kUserCodingKey];
FIRAdditionalUserInfo *additionalUserInfo =
[aDecoder decodeObjectOfClass:[FIRAdditionalUserInfo class]
forKey:kAdditionalUserInfoCodingKey];
return [self initWithUser:user additionalUserInfo:additionalUserInfo];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_user forKey:kUserCodingKey];
[aCoder encodeObject:_additionalUserInfo forKey:kAdditionalUserInfoCodingKey];
}
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,30 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthDataResult.h"
@interface FIRAuthDataResult () <NSSecureCoding>
/** @fn initWithUser:additionalUserInfo:
@brief Designated initializer.
@param user The signed in user reference.
@param additionalUserInfo The additional user info if available.
*/
- (nullable instancetype)initWithUser:(nullable FIRUser *)user
additionalUserInfo:(nullable FIRAdditionalUserInfo *)additionalUserInfo
NS_DESIGNATED_INITIALIZER;
@end

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import "FIRAuthUIDelegate.h"
NS_ASSUME_NONNULL_BEGIN
/** @class FIRAuthDefaultUIDelegate
@brief Class responsible for providing a default FIRAuthUIDelegte.
@remarks This class should be used in the case that a UIDelegate was expected and necessary to
continue a given flow, but none was provided.
*/
@interface FIRAuthDefaultUIDelegate : NSObject <FIRAuthUIDelegate>
/** @fn defaultUIDelegate
@brief Unavailable. Please use @c +defaultUIDelegate:
*/
- (instancetype)init NS_UNAVAILABLE;
/** @fn defaultUIDelegate
@brief Returns a default FIRAuthUIDelegate object.
@return The default FIRAuthUIDelegate object.
*/
+ (id<FIRAuthUIDelegate>)defaultUIDelegate;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,92 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthDefaultUIDelegate.h"
#import <GoogleUtilities/GULAppEnvironmentUtil.h>
NS_ASSUME_NONNULL_BEGIN
@interface FIRAuthDefaultUIDelegate ()
/** @fn initWithViewController:
@brief Initializes the instance with a view controller.
@param viewController The view controller as the presenting view controller in @c
FIRAuthUIDelegate.
@return The initialized instance.
*/
- (instancetype)initWithViewController:(nullable UIViewController *)viewController NS_DESIGNATED_INITIALIZER;
@end
@implementation FIRAuthDefaultUIDelegate {
/** @var _viewController
@brief The presenting view controller.
*/
UIViewController *_viewController;
}
- (instancetype)initWithViewController:(nullable UIViewController *)viewController {
self = [super init];
if (self) {
_viewController = viewController;
}
return self;
}
- (void)presentViewController:(UIViewController *)viewControllerToPresent
animated:(BOOL)flag
completion:(nullable void (^)(void))completion {
[_viewController presentViewController:viewControllerToPresent
animated:flag
completion:completion];
}
- (void)dismissViewControllerAnimated:(BOOL)flag completion:(nullable void (^)(void))completion {
[_viewController dismissViewControllerAnimated:flag completion:completion];
}
+ (id<FIRAuthUIDelegate>)defaultUIDelegate {
// iOS App extensions should not call [UIApplication sharedApplication], even if UIApplication
// responds to it.
static Class applicationClass = nil;
if (![GULAppEnvironmentUtil isAppExtension]) {
Class cls = NSClassFromString(@"UIApplication");
if (cls && [cls respondsToSelector:NSSelectorFromString(@"sharedApplication")]) {
applicationClass = cls;
}
}
UIApplication *application = [applicationClass sharedApplication];
UIViewController *topViewController = application.keyWindow.rootViewController;
while (true){
if (topViewController.presentedViewController) {
topViewController = topViewController.presentedViewController;
} else if ([topViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController *nav = (UINavigationController *)topViewController;
topViewController = nav.topViewController;
} else if ([topViewController isKindOfClass:[UITabBarController class]]) {
UITabBarController *tab = (UITabBarController *)topViewController;
topViewController = tab.selectedViewController;
} else {
break;
}
}
return [[FIRAuthDefaultUIDelegate alloc] initWithViewController:topViewController];
}
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,63 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/** @typedef FIRAuthDispatcherImplBlock
@brief The type of block which can be set as the implementation for @c
dispatchAfterDelay:queue:callback: .
@param delay The delay in seconds after which the task will be scheduled to execute.
@param queue The dispatch queue on which the task will be submitted.
@param task The task (block) to be scheduled for future execution.
*/
typedef void(^FIRAuthDispatcherImplBlock)(NSTimeInterval delay,
dispatch_queue_t queue,
void (^task)(void));
/** @class FIRAuthDispatchAfter
@brief A utility class used to facilitate scheduling tasks to be executed in the future.
*/
@interface FIRAuthDispatcher : NSObject
/** @property dispatchAfterImplementation
@brief Allows custom implementation of dispatchAfterDelay:queue:callback:.
@remarks Set to nil to restore default implementation.
*/
@property(nonatomic, nullable, copy) FIRAuthDispatcherImplBlock dispatchAfterImplementation;
/** @fn dispatchAfterDelay:queue:callback:
@brief Schedules task in the future after a specified delay.
@param delay The delay in seconds after which the task will be scheduled to execute.
@param queue The dispatch queue on which the task will be submitted.
@param task The task (block) to be scheduled for future execution.
*/
- (void)dispatchAfterDelay:(NSTimeInterval)delay
queue:(dispatch_queue_t)queue
task:(void (^)(void))task;
/** @fn sharedInstance
@brief Gets the shared instance of this class.
@returns The shared instance of this clss
*/
+ (instancetype)sharedInstance;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthDispatcher.h"
NS_ASSUME_NONNULL_BEGIN
@implementation FIRAuthDispatcher
@synthesize dispatchAfterImplementation = _dispatchAfterImplementation;
+ (instancetype)sharedInstance {
static dispatch_once_t onceToken;
static FIRAuthDispatcher *sharedInstance;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
- (void)dispatchAfterDelay:(NSTimeInterval)delay
queue:(dispatch_queue_t)queue
task:(void (^)(void))task {
if (_dispatchAfterImplementation) {
_dispatchAfterImplementation(delay, queue, task);
return;
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delay * NSEC_PER_SEC), queue, task);
}
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,530 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
@class FIRPhoneAuthCredential;
NS_ASSUME_NONNULL_BEGIN
/** @class FIRAuthErrorUtils
@brief Utility class used to construct @c NSError instances.
*/
@interface FIRAuthErrorUtils : NSObject
/** @fn RPCRequestEncodingErrorWithUnderlyingError
@brief Constructs an @c NSError with the @c FIRAuthInternalErrorCodeRPCRequestEncodingError
code and a populated @c NSUnderlyingErrorKey in the @c NSError.userInfo dictionary.
@param underlyingError The value of the @c NSUnderlyingErrorKey key.
@remarks This error is used when an @c FIRAuthRPCRequest.unencodedHTTPRequestBodyWithError:
invocation returns an error. The error returned is wrapped in this internal error code.
*/
+ (NSError *)RPCRequestEncodingErrorWithUnderlyingError:(NSError *)underlyingError;
/** @fn JSONSerializationErrorForUnencodableType
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeJSONSerializationError code.
@remarks This error is used when an @c NSJSONSerialization.isValidJSONObject: check fails, not
for when an error is returned from @c NSJSONSerialization.dataWithJSONObject:options:error:.
*/
+ (NSError *)JSONSerializationErrorForUnencodableType;
/** @fn JSONSerializationErrorWithUnderlyingError:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeJSONSerializationError code, and the
@c underlyingError as the @c NSUnderlyingErrorKey value in the @c NSError.userInfo
dictionary.
@param underlyingError The value of the @c NSUnderlyingErrorKey key.
@remarks This error is used when an invocation of
@c NSJSONSerialization.dataWithJSONObject:options:error: returns an error.
*/
+ (NSError *)JSONSerializationErrorWithUnderlyingError:(NSError *)underlyingError;
/** @fn networkErrorWithUnderlyingError:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeNetworkError code, and the
@c underlyingError as the @c NSUnderlyingErrorKey value in the @c NSError.userInfo
dictionary.
@param underlyingError The value of the @c NSUnderlyingErrorKey key. Should be the error from
GTM.
@remarks This error is used when a network request results in an error, and no body data was
returned.
*/
+ (NSError *)networkErrorWithUnderlyingError:(NSError *)underlyingError;
/** @fn unexpectedErrorResponseWithUnderlyingError:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeNetworkError code, and the
@c underlyingError as the @c NSUnderlyingErrorKey value.
@param data The value of the @c FIRAuthErrorUserInfoDataKey key in the @c NSError.userInfo
dictionary.
@param underlyingError The value of the @c NSUnderlyingErrorKey key in the @c NSError.userInfo
dictionary.
@remarks This error is used when a network request results in an error, and unserializable body
data was returned.
*/
+ (NSError *)unexpectedErrorResponseWithData:(NSData *)data
underlyingError:(NSError *)underlyingError;
/** @fn unexpectedErrorResponseWithDeserializedResponse:
@brief Constructs an @c NSError with the @c FIRAuthInternalErrorCodeUnexpectedErrorResponse
code, and a populated @c FIRAuthErrorUserInfoDeserializedResponseKey key in the
@c NSError.userInfo dictionary.
@param deserializedResponse The value of the @c FIRAuthErrorUserInfoDeserializedResponseKey key.
@remarks This error is used when a network request results in an error, and the body data was
deserializable as JSON, but couldn't be decoded as an error.
*/
+ (NSError *)unexpectedErrorResponseWithDeserializedResponse:(id)deserializedResponse;
/** @fn malformedJWTErrorWithToken:underlyingError:
@brief Constructs an @c NSError with the code set to @c FIRAuthErrorCodeMalformedJWT and
populates the userInfo dictionary with an error message, the bad token, and an underlying
error that may have occurred when parsing.
@param token The token that failed to parse.
@param underlyingError The error that caused this error. If this parameter is nil, the
NSUnderlyingErrorKey value will not be set.
@remarks This error is returned when JWT parsing fails.
@returns An @c FIRAuthErrorCodeMalformedJWT error wrapping an underlying error, if available.
*/
+ (NSError *)malformedJWTErrorWithToken:(NSString *)token
underlyingError:(NSError *_Nullable)underlyingError;
/** @fn unexpectedResponseWithData:underlyingError:
@brief Constructs an @c NSError with the @c FIRAuthInternalErrorCodeUnexpectedResponse
code, and a populated @c FIRAuthErrorUserInfoDataKey key in the @c NSError.userInfo
dictionary.
@param data The value of the @c FIRAuthErrorUserInfoDataKey key in the @c NSError.userInfo
dictionary.
@param underlyingError The value of the @c NSUnderlyingErrorKey key in the @c NSError.userInfo
dictionary.
@remarks This error is used when a network request is apparently successful, but the body data
couldn't be deserialized as JSON.
*/
+ (NSError *)unexpectedResponseWithData:(NSData *)data
underlyingError:(NSError *)underlyingError;;
/** @fn unexpectedResponseWithDeserializedResponse:
@brief Constructs an @c NSError with the @c FIRAuthInternalErrorCodeUnexpectedResponse
code, and a populated @c FIRAuthErrorUserInfoDeserializedResponseKey key in the
@c NSError.userInfo dictionary.
@param deserializedResponse The value of the @c FIRAuthErrorUserInfoDeserializedResponseKey key.
@remarks This error is used when a network request is apparently successful, the body data was
successfully deserialized as JSON, but the JSON wasn't a dictionary.
*/
+ (NSError *)unexpectedResponseWithDeserializedResponse:(id)deserializedResponse;
/** @fn unexpectedResponseWithDeserializedResponse:underlyingError:
@brief Constructs an @c NSError with the @c FIRAuthInternalErrorCodeUnexpectedResponse
code, and populated @c FIRAuthErrorUserInfoDeserializedResponseKey and
@c NSUnderlyingErrorKey keys in the @c NSError.userInfo dictionary.
@param deserializedResponse The value of the @c FIRAuthErrorUserInfoDeserializedResponseKey key.
@param underlyingError The value of the @c NSUnderlyingErrorKey key.
@remarks This error is used when a network request was apparently successful, the body data was
successfully deserialized as JSON, but the data type of the response was unexpected.
*/
+ (NSError *)unexpectedResponseWithDeserializedResponse:(nullable id)deserializedResponse
underlyingError:(NSError *)underlyingError;
/** @fn RPCResponseDecodingErrorWithDeserializedResponse:underlyingError:
@brief Constructs an @c NSError with the @c FIRAuthInternalErrorCodeRPCResponseDecodingError
code, and populated @c FIRAuthErrorUserInfoDeserializedResponseKey and
@c NSUnderlyingErrorKey keys in the @c NSError.userInfo dictionary.
@param deserializedResponse The value of the @c FIRAuthErrorUserInfoDeserializedResponseKey key.
@param underlyingError The value of the @c NSUnderlyingErrorKey key.
@remarks This error is used when an invocation of @c FIRAuthRPCResponse.setWithDictionary:error:
resulted in an error.
*/
+ (NSError *)RPCResponseDecodingErrorWithDeserializedResponse:(id)deserializedResponse
underlyingError:(NSError *)underlyingError;
/** @fn emailAlreadyInUseErrorWithEmail:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeEmailExists code.
@param email The email address that is already in use.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)emailAlreadyInUseErrorWithEmail:(nullable NSString *)email;
/** @fn userDisabledErrorWithMessageWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeUserDisabled code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)userDisabledErrorWithMessage:(nullable NSString *)message;
/** @fn wrongPasswordErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeWrongPassword code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)wrongPasswordErrorWithMessage:(nullable NSString *)message;
/** @fn tooManyRequestsErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeTooManyRequests Code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)tooManyRequestsErrorWithMessage:(nullable NSString *)message;
/** @fn invalidCustomTokenErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeInvalidCustomToken code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)invalidCustomTokenErrorWithMessage:(nullable NSString *)message;
/** @fn customTokenMistmatchErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeCustomTokenMismatch code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)customTokenMistmatchErrorWithMessage:(nullable NSString *)message;
/** @fn invalidCredentialErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeInvalidCredential code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)invalidCredentialErrorWithMessage:(nullable NSString *)message;
/** @fn requiresRecentLoginError
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeRequiresRecentLogin code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)requiresRecentLoginErrorWithMessage:(nullable NSString *)message;
/** @fn invalidUserTokenErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeInvalidUserToken code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)invalidUserTokenErrorWithMessage:(nullable NSString *)message;
/** @fn invalidEmailErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeInvalidEmail code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)invalidEmailErrorWithMessage:(nullable NSString *)message;
/** @fn accountExistsWithDifferentCredentialErrorWithEmail:
@brief Constructs an @c NSError with the @c FIRAuthErrorAccountExistsWithDifferentCredential
code.
@param Email The email address that is already associated with an existing account
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)accountExistsWithDifferentCredentialErrorWithEmail:(nullable NSString *)Email;
/** @fn providerAlreadyLinkedErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeProviderAlreadyLinked code.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)providerAlreadyLinkedError;
/** @fn noSuchProviderError
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeNoSuchProvider code.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)noSuchProviderError;
/** @fn userTokenExpiredErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeUserTokenExpired code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)userTokenExpiredErrorWithMessage:(nullable NSString *)message;
/** @fn userNotFoundErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeUserNotFound code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)userNotFoundErrorWithMessage:(nullable NSString *)message;
/** @fn invalidLocalAPIKeyErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeInvalidAPIKey code.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)invalidAPIKeyError;
/** @fn userMismatchError
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeUserMismatch code.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)userMismatchError;
/** @fn credentialAlreadyInUseErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeCredentialAlreadyInUse code.
@param message Error message from the backend, if any.
@param credential Auth credential to be added to the Error User Info dictionary.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)credentialAlreadyInUseErrorWithMessage:(nullable NSString *)message
credential:(nullable FIRPhoneAuthCredential *)credential;
/** @fn operationNotAllowedErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeOperationNotAllowed code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)operationNotAllowedErrorWithMessage:(nullable NSString *)message;
/** @fn weakPasswordErrorWithServerResponseReason:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeWeakPassword code.
@param serverResponseReason A more detailed explanation string from server response.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)weakPasswordErrorWithServerResponseReason:(nullable NSString *)serverResponseReason;
/** @fn appNotAuthorizedError
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeAppNotAuthorized code.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)appNotAuthorizedError;
/** @fn expiredActionCodeErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeExpiredActionCode code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)expiredActionCodeErrorWithMessage:(nullable NSString *)message;
/** @fn invalidActionCodeErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeInvalidActionCode code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)invalidActionCodeErrorWithMessage:(nullable NSString *)message;
/** @fn invalidMessagePayloadError:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeInvalidMessagePayload code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)invalidMessagePayloadErrorWithMessage:(nullable NSString *)message;
/** @fn invalidSenderErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeInvalidSender code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)invalidSenderErrorWithMessage:(nullable NSString *)message;
/** @fn invalidRecipientEmailError:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeInvalidRecipientEmail code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)invalidRecipientEmailErrorWithMessage:(nullable NSString *)message;
/** @fn missingIosBundleIDErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeMissingIosBundleID code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)missingIosBundleIDErrorWithMessage:(nullable NSString *)message;
/** @fn missingAndroidPackageNameErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeMissingAndroidPackageName code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)missingAndroidPackageNameErrorWithMessage:(nullable NSString *)message;
/** @fn unauthorizedDomainErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeUnauthorizedDomain code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)unauthorizedDomainErrorWithMessage:(nullable NSString *)message;
/** @fn invalidContinueURIErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeInvalidContinueURI code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)invalidContinueURIErrorWithMessage:(nullable NSString *)message;
/** @fn missingContinueURIErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeMissingContinueURI code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)missingContinueURIErrorWithMessage:(nullable NSString *)message;
/** @fn missingEmailErrorWithMessage
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeMissingEmail code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)missingEmailErrorWithMessage:(nullable NSString *)message;
/** @fn missingPhoneNumberErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeMissingPhoneNumber code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)missingPhoneNumberErrorWithMessage:(nullable NSString *)message;
/** @fn invalidPhoneNumberErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeInvalidPhoneNumber code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)invalidPhoneNumberErrorWithMessage:(nullable NSString *)message;
/** @fn missingVerificationCodeErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeMissingVerificationCode code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)missingVerificationCodeErrorWithMessage:(nullable NSString *)message;
/** @fn invalidVerificationCodeErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeInvalidVerificationCode code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)invalidVerificationCodeErrorWithMessage:(nullable NSString *)message;
/** @fn missingVerificationIDErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeMissingVerificationID code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)missingVerificationIDErrorWithMessage:(nullable NSString *)message;
/** @fn invalidVerificationIDErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeInvalidVerificationID code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)invalidVerificationIDErrorWithMessage:(nullable NSString *)message;
/** @fn sessionExpiredErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeSessionExpired code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)sessionExpiredErrorWithMessage:(nullable NSString *)message;
/** @fn missingAppCredentialWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorMissingCredential code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)missingAppCredentialWithMessage:(nullable NSString *)message;
/** @fn invalidAppCredentialWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorInvalidCredential code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)invalidAppCredentialWithMessage:(nullable NSString *)message;
/** @fn quotaExceededErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeQuotaExceeded code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)quotaExceededErrorWithMessage:(nullable NSString *)message;
/** @fn missingAppTokenErrorWithUnderlyingError
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeMissingAppToken code.
@param underlyingError The underlying error, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)missingAppTokenErrorWithUnderlyingError:(nullable NSError *)underlyingError;
/** @fn localPlayerNotAuthenticatedError
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeLocalPlayerNotAuthenticated code.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)localPlayerNotAuthenticatedError;
/** @fn notificationNotForwardedError
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeNotificationNotForwarded code.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)notificationNotForwardedError;
/** @fn appNotVerifiedErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeAppNotVerified code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)appNotVerifiedErrorWithMessage:(nullable NSString *)message;
/** @fn captchaCheckFailedErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCaptchaCheckFailed code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)captchaCheckFailedErrorWithMessage:(nullable NSString *)message;
/** @fn webContextAlreadyPresentedErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeWebContextAlreadyPresented code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)webContextAlreadyPresentedErrorWithMessage:(nullable NSString *)message;
/** @fn webContextCancelledErrorWithMessage:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeWebContextCancelled code.
@param message Error message from the backend, if any.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)webContextCancelledErrorWithMessage:(nullable NSString *)message;
/** @fn appVerificationUserInteractionFailureWithReason:
@brief Constructs an @c NSError with the @c
FIRAuthErrorCodeAppVerificationUserInteractionFailure code.
@param reason Reason for error, returned via URL response.
@return The NSError instance associated with the given FIRAuthError.
*/
+ (NSError *)appVerificationUserInteractionFailureWithReason:(NSString *)reason;
/** @fn URLResponseErrorWithCode:message:
@brief Constructs an @c NSError with the code and message provided.
@param message Error message from the backend, if any.
@return The nullable NSError instance associated with the given error message, if one is found.
*/
+ (nullable NSError *)URLResponseErrorWithCode:(NSString *)code message:(nullable NSString *)message;
/** @fn nullUserErrorWithMessage:
@brief Constructs an @c NSError with the code and message provided.
@param message Error message from the backend, if any.
@return The nullable NSError instance associated with the given error message, if one is found.
*/
+ (NSError *)nullUserErrorWithMessage:(nullable NSString *)message;
/** @fn invalidDynamicLinkDomainErrorWithMessage:
@brief Constructs an @c NSError with the code and message provided.
@param message Error message from the backend, if any.
@return The nullable NSError instance associated with the given error message, if one is found.
*/
+ (NSError *)invalidDynamicLinkDomainErrorWithMessage:(nullable NSString *)message;
/** @fn keychainErrorWithFunction:status:
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeKeychainError code.
@param keychainFunction The keychain function which was invoked and yielded an unexpected
response. The @c NSLocalizedFailureReasonErrorKey field in the @c NSError.userInfo
dictionary will contain a string partially comprised of this value.
@param status The response status from the invoked keychain function. The
@c NSLocalizedFailureReasonErrorKey field in the @c NSError.userInfo dictionary will contain
a string partially comprised of this value.
*/
+ (NSError *)keychainErrorWithFunction:(NSString *)keychainFunction status:(OSStatus)status;
@end
NS_ASSUME_NONNULL_END

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/** @class FIRAuthExceptionUtils
@brief Utility class used to raise standardized Auth related exceptions.
*/
@interface FIRAuthExceptionUtils : NSObject
/** @fn raiseInvalidParameterExceptionWithReason:
@brief raises the "invalid parameter" exception
@param reason string will contain a description of the error.
*/
+ (void)raiseInvalidParameterExceptionWithReason:(nullable NSString *)reason;
/** @fn raiseMethodNotImplementedExceptionWithReason:
@brief raises the "method not implemented" exception
@param reason string will contain a description of the error.
@see FIRMethodNotImplementedException
*/
+ (void)raiseMethodNotImplementedExceptionWithReason:(nullable NSString *)reason;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthExceptionUtils.h"
/** @var FIRMethodNotImplementedException
@brief The name of the "Method Not Implemented" exception.
*/
static NSString *const FIRMethodNotImplementedException = @"FIRMethodNotImplementedException";
@implementation FIRAuthExceptionUtils
+ (void)raiseInvalidParameterExceptionWithReason:(NSString *)reason {
[NSException raise:NSInvalidArgumentException format:@"%@", reason];
}
+ (void)raiseMethodNotImplementedExceptionWithReason:(nullable NSString *)reason {
NSException *exception =
[NSException exceptionWithName:FIRMethodNotImplementedException reason:reason userInfo:nil];
[exception raise];
}
@end

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/** @fn FIRAuthGlobalWorkQueue
@brief Retrieves the global serial work queue for Firebase Auth.
@return The global serial dispatch queue.
@remarks To ensure thread safety, all auth code must be executed in either this global work
queue, or a serial queue that has its target queue set to this work queue. All public method
implementations that may involve contested code shall dispatch to this work queue as the
first thing they do.
*/
extern dispatch_queue_t FIRAuthGlobalWorkQueue(void);
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,26 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthGlobalWorkQueue.h"
dispatch_queue_t FIRAuthGlobalWorkQueue() {
static dispatch_once_t once;
static dispatch_queue_t queue;
dispatch_once(&once, ^{
queue = dispatch_queue_create("com.google.firebase.auth.globalWorkQueue", NULL);
});
return queue;
}

View File

@@ -0,0 +1,454 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import "FIRAuthErrors.h"
/** @var FIRAuthPublicErrorCodeFlag
@brief Bitmask value indicating the error represents a public error code when this bit is
zeroed. Error codes which don't contain this flag will be wrapped in an @c NSError whose
code is @c FIRAuthErrorCodeInternalError.
*/
static const NSInteger FIRAuthPublicErrorCodeFlag = 1 << 20;
/** @var FIRAuthInternalErrorDomain
@brief The Firebase Auth error domain for internal errors.
*/
extern NSString *const FIRAuthInternalErrorDomain;
/** @var FIRAuthErrorUserInfoDeserializedResponseKey
@brief Errors with the code @c FIRAuthErrorCodeUnexpectedResponseError,
@c FIRAuthErrorCodeUnexpectedErrorResponseError, and
@c FIRAuthInternalErrorCodeRPCResponseDecodingError may contain an @c NSError.userInfo
dictionary which contains this key. The value associated with this key is an object of
unspecified contents containing the deserialized server response.
*/
extern NSString *const FIRAuthErrorUserInfoDeserializedResponseKey;
/** @var FIRAuthErrorUserInfoDataKey
@brief Errors with the code @c FIRAuthErrorCodeUnexpectedResponseError or
@c FIRAuthErrorCodeUnexpectedErrorResponseError may contain an @c NSError.userInfo
dictionary which contains this key. The value associated with this key is an @c NSString
which represents the response from a server to an RPC which could not be deserialized.
*/
extern NSString *const FIRAuthErrorUserInfoDataKey;
/** @var FIRAuthInternalErrorCode
@brief Error codes used internally by Firebase Auth.
@remarks All errors are generated using an internal error code. These errors are automatically
converted to the appropriate public version of the @c NSError by the methods in
@c FIRAuthErrorUtils
*/
typedef NS_ENUM(NSInteger, FIRAuthInternalErrorCode) {
/** @var FIRAuthInternalErrorCodeNetworkError
@brief Indicates a network error occurred (such as a timeout, interrupted connection, or
unreachable host.)
@remarks These types of errors are often recoverable with a retry.
See the @c NSUnderlyingError value in the @c NSError.userInfo dictionary for details about
the network error which occurred.
*/
FIRAuthInternalErrorCodeNetworkError = FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeNetworkError,
/** @var FIRAuthInternalErrorCodeEmailAlreadyInUse
@brief The email used to attempt a sign-up already exists.
*/
FIRAuthInternalErrorCodeEmailAlreadyInUse =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeEmailAlreadyInUse,
/** @var FIRAuthInternalErrorCodeUserDisabled
@brief Indicates the user's account is disabled on the server side.
*/
FIRAuthInternalErrorCodeUserDisabled = FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeUserDisabled,
/** @var FIRAuthInternalErrorCodeWrongPassword
@brief Indicates the user attempted sign in with a wrong password
*/
FIRAuthInternalErrorCodeWrongPassword =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeWrongPassword,
/** @var FIRAuthInternalErrorCodeKeychainError
@brief Indicates an error occurred accessing the keychain.
@remarks The @c NSLocalizedFailureReasonErrorKey field in the @c NSError.userInfo dictionary
will contain more information about the error encountered.
*/
FIRAuthInternalErrorCodeKeychainError =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeKeychainError,
/** @var FIRAuthInternalErrorCodeInternalError
@brief An internal error occurred.
@remarks This value is here for consistency. It's also used to make the implementation of
wrapping internal errors simpler.
*/
FIRAuthInternalErrorCodeInternalError =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInternalError,
/** @var FIRAuthInternalErrorCodeTooManyRequests
@brief Indicates that too many requests were made to a server method.
*/
FIRAuthInternalErrorCodeTooManyRequests =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeTooManyRequests,
/** @var FIRAuthInternalErrorCodeInvalidCustomToken
@brief Indicates a validation error with the custom token.
*/
FIRAuthInternalErrorCodeInvalidCustomToken =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidCustomToken,
/** @var FIRAuthInternalErrorCodeCredentialMismatch
@brief Indicates the service account and the API key belong to different projects.
*/
FIRAuthInternalErrorCodeCustomTokenMismatch =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeCustomTokenMismatch,
/** @var FIRAuthInternalErrorCodeInvalidCredential
@brief Indicates the IDP token or requestUri is invalid.
*/
FIRAuthInternalErrorCodeInvalidCredential =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidCredential,
/** @var FIRAuthInternalErrorCodeRequiresRecentLogin
@brief Indicates the user has attemped to change email or password more than 5 minutes after
signing in.
*/
FIRAuthInternalErrorCodeRequiresRecentLogin =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeRequiresRecentLogin,
/** @var FIRAuthInternalErrorCodeInvalidUserToken
@brief Indicates user's saved auth credential is invalid, the user needs to sign in again.
*/
FIRAuthInternalErrorCodeInvalidUserToken =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidUserToken,
/** @var FIRAuthInternalErrorCodeInvalidEmail
@brief Indicates the email identifier is invalid.
*/
FIRAuthInternalErrorCodeInvalidEmail =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidEmail,
/** @var FIRAuthInternalErrorCodeAccountExistsWithDifferentCredential
@brief Indicates account linking is needed.
*/
FIRAuthInternalErrorCodeAccountExistsWithDifferentCredential =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeAccountExistsWithDifferentCredential,
/** @var FIRAuthInternalErrorCodeProviderAlreadyLinked
@brief Indicates an attempt to link a provider to which we are already linked.
*/
FIRAuthInternalErrorCodeProviderAlreadyLinked =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeProviderAlreadyLinked,
/** @var FIRAuthInternalErrorCodeNoSuchProvider
@brief Indicates an attempt to unlink a provider that is not is not linked.
*/
FIRAuthInternalErrorCodeNoSuchProvider =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeNoSuchProvider,
/** @var FIRAuthInternalErrorCodeUserTokenExpired
@brief Indicates the token issue time is older than account's valid_since time.
*/
FIRAuthInternalErrorCodeUserTokenExpired =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeUserTokenExpired,
/** @var FIRAuthInternalErrorCodeUserNotFound
@brief Indicates the user account was been found.
*/
FIRAuthInternalErrorCodeUserNotFound =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeUserNotFound,
/** @var FIRAuthInternalErrorCodeInvalidAPIKey
@brief Indicates an invalid API Key was supplied in the request.
*/
FIRAuthInternalErrorCodeInvalidAPIKey =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidAPIKey,
/** @var FIRAuthInternalErrorCodeOperationNotAllowed
@brief Indicates that admin disabled sign-in with the specified IDP.
*/
FIRAuthInternalErrorCodeOperationNotAllowed =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeOperationNotAllowed,
/** @var FIRAuthInternalErrorCodeUserMismatch
@brief Indicates that user attempted to reauthenticate with a user other than the current
user.
*/
FIRAuthInternalErrorCodeUserMismatch =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeUserMismatch,
/** @var FIRAuthInternalErrorCodeCredentialAlreadyInUse
@brief Indicates an attempt to link with a credential that has already been linked with a
different Firebase account.
*/
FIRAuthInternalErrorCodeCredentialAlreadyInUse =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeCredentialAlreadyInUse,
/** @var FIRAuthInternalErrorCodeWeakPassword
@brief Indicates an attempt to set a password that is considered too weak.
*/
FIRAuthInternalErrorCodeWeakPassword =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeWeakPassword,
/** @var FIRAuthInternalErrorCodeAppNotAuthorized
@brief Indicates the App is not authorized to use Firebase Authentication with the
provided API Key.
*/
FIRAuthInternalErrorCodeAppNotAuthorized =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeAppNotAuthorized,
/** @var FIRAuthInternalErrorCodeExpiredActionCode
@brief Indicates the OOB code is expired.
*/
FIRAuthInternalErrorCodeExpiredActionCode =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeExpiredActionCode,
/** @var FIRAuthInternalErrorCodeInvalidActionCode
@brief Indicates the OOB code is invalid.
*/
FIRAuthInternalErrorCodeInvalidActionCode =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidActionCode,
/** Indicates that there are invalid parameters in the payload during a "send password reset email
* " attempt.
*/
FIRAuthInternalErrorCodeInvalidMessagePayload =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidMessagePayload,
/** Indicates that the sender email is invalid during a "send password reset email" attempt.
*/
FIRAuthInternalErrorCodeInvalidSender =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidSender,
/** Indicates that the recipient email is invalid.
*/
FIRAuthInternalErrorCodeInvalidRecipientEmail =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidRecipientEmail,
/** Indicates that the iOS bundle ID is missing when a iOS App Store ID is provided.
*/
FIRAuthinternalErrorCodeMissingIosBundleID =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeMissingIosBundleID,
/** Indicates that the android package name is missing when the @c androidInstallApp flag is set
to true.
*/
FIRAuthInternalErrorCodeMissingAndroidPackageName =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeMissingAndroidPackageName,
/** Indicates that the domain specified in the continue URL is not whitelisted in the Firebase
console.
*/
FIRAuthInternalErrorCodeUnauthorizedDomain =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeUnauthorizedDomain,
/** Indicates that the domain specified in the continue URI is not valid.
*/
FIRAuthInternalErrorCodeInvalidContinueURI =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidContinueURI,
/** Indicates that a continue URI was not provided in a request to the backend which requires
one.
*/
FIRAuthInternalErrorCodeMissingContinueURI =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeMissingContinueURI,
/** Indicates that an email address was expected but one was not provided.
*/
FIRAuthInternalErrorCodeMissingEmail =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeMissingEmail,
/** Indicates that a phone number was not provided in a call to @c verifyPhoneNumber:completion:.
*/
FIRAuthInternalErrorCodeMissingPhoneNumber =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeMissingPhoneNumber,
/** Indicates that an invalid phone number was provided in a call to @c
verifyPhoneNumber:completion:.
*/
FIRAuthInternalErrorCodeInvalidPhoneNumber =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidPhoneNumber,
/** Indicates that the phone auth credential was created with an empty verification code.
*/
FIRAuthInternalErrorCodeMissingVerificationCode =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeMissingVerificationCode,
/** Indicates that an invalid verification code was used in the verifyPhoneNumber request.
*/
FIRAuthInternalErrorCodeInvalidVerificationCode =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidVerificationCode,
/** Indicates that the phone auth credential was created with an empty verification ID.
*/
FIRAuthInternalErrorCodeMissingVerificationID =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeMissingVerificationID,
/** Indicates that the APNS device token is missing in the verifyClient request.
*/
FIRAuthInternalErrorCodeMissingAppCredential =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeMissingAppCredential,
/** Indicates that an invalid APNS device token was used in the verifyClient request.
*/
FIRAuthInternalErrorCodeInvalidAppCredential =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidAppCredential,
/** Indicates that the reCAPTCHA token is not valid.
*/
FIRAuthInternalErrorCodeCaptchaCheckFailed =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeCaptchaCheckFailed,
/** Indicates that an invalid verification ID was used in the verifyPhoneNumber request.
*/
FIRAuthInternalErrorCodeInvalidVerificationID =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidVerificationID,
/** Indicates that the quota of SMS messages for a given project has been exceeded.
*/
FIRAuthInternalErrorCodeQuotaExceeded =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeQuotaExceeded,
/** Indicates that an attempt was made to present a new web context while one was already being
presented.
*/
FIRAuthInternalErrorCodeWebContextAlreadyPresented =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeWebContextAlreadyPresented,
/** Indicates that the URL presentation was cancelled prematurely by the user.
*/
FIRAuthInternalErrorCodeWebContextCancelled =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeWebContextCancelled,
/** Indicates a general failure during the app verification flow.
*/
FIRAuthInternalErrorCodeAppVerificationUserInteractionFailure =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeAppVerificationUserInteractionFailure,
/** Indicates that the clientID used to invoke a web flow is invalid.
*/
FIRAuthInternalErrorCodeInvalidClientID =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidClientID,
/** Indicates that a network request within a SFSafariViewController or UIWebview failed.
*/
FIRAuthInternalErrorCodeWebNetworkRequestFailed =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeWebNetworkRequestFailed,
/** Indicates that an internal error occurred within a SFSafariViewController or UIWebview.
*/
FIRAuthInternalErrorCodeWebInternalError =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeWebInternalError,
// The enum values between 17046 and 17051 are reserved and should NOT be used for new error
// codes.
/** Indicates that the SMS code has expired
*/
FIRAuthInternalErrorCodeSessionExpired =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeSessionExpired,
FIRAuthInternalErrorCodeMissingAppToken =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeMissingAppToken,
FIRAuthInternalErrorCodeNotificationNotForwarded =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeNotificationNotForwarded,
FIRAuthInternalErrorCodeAppNotVerified =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeAppNotVerified,
/** Indicates that the Game Center local player was not authenticated.
*/
FIRAuthInternalErrorCodeLocalPlayerNotAuthenticated =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeLocalPlayerNotAuthenticated,
/** Indicates that a non-null user was expected as an argmument to the operation but a null
user was provided.
*/
FIRAuthInternalErrorCodeNullUser =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeNullUser,
/** Indicates that the Firebase Dynamic Link domain used is either not configured or is unauthorized
for the current project.
*/
FIRAuthInternalErrorCodeInvalidDynamicLinkDomain =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidDynamicLinkDomain,
FIRAuthInternalErrorCodeMalformedJWT =
FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeMalformedJWT,
/** @var FIRAuthInternalErrorCodeRPCRequestEncodingError
@brief Indicates an error encoding the RPC request.
@remarks This is typically due to some sort of unexpected input value.
See the @c NSUnderlyingError value in the @c NSError.userInfo dictionary for details.
*/
FIRAuthInternalErrorCodeRPCRequestEncodingError = 1,
/** @var FIRAuthInternalErrorCodeJSONSerializationError
@brief Indicates an error serializing an RPC request.
@remarks This is typically due to some sort of unexpected input value.
If an @c NSJSONSerialization.isValidJSONObject: check fails, the error will contain no
@c NSUnderlyingError key in the @c NSError.userInfo dictionary. If an error was
encountered calling @c NSJSONSerialization.dataWithJSONObject:options:error:, the
resulting error will be associated with the @c NSUnderlyingError key in the
@c NSError.userInfo dictionary.
*/
FIRAuthInternalErrorCodeJSONSerializationError = 2,
/** @var FIRAuthInternalErrorCodeUnexpectedErrorResponse
@brief Indicates an HTTP error occurred and the data returned either couldn't be deserialized
or couldn't be decoded.
@remarks See the @c NSUnderlyingError value in the @c NSError.userInfo dictionary for details
about the HTTP error which occurred.
If the response could be deserialized as JSON then the @c NSError.userInfo dictionary will
contain a value for the key @c FIRAuthErrorUserInfoDeserializedResponseKey which is the
deserialized response value.
If the response could not be deserialized as JSON then the @c NSError.userInfo dictionary
will contain values for the @c NSUnderlyingErrorKey and @c FIRAuthErrorUserInfoDataKey
keys.
*/
FIRAuthInternalErrorCodeUnexpectedErrorResponse = 3,
/** @var FIRAuthInternalErrorCodeUnexpectedResponse
@brief Indicates the HTTP response indicated the request was a successes, but the response
contains something other than a JSON-encoded dictionary, or the data type of the response
indicated it is different from the type of response we expected.
@remarks See the @c NSUnderlyingError value in the @c NSError.userInfo dictionary.
If this key is present in the dictionary, it may contain an error from
@c NSJSONSerialization error (indicating the response received was of the wrong data
type).
See the @c FIRAuthErrorUserInfoDeserializedResponseKey value in the @c NSError.userInfo
dictionary. If the response could be deserialized, it's deserialized representation will
be associated with this key. If the @c NSUnderlyingError value in the @c NSError.userInfo
dictionary is @c nil, this indicates the JSON didn't represent a dictionary.
*/
FIRAuthInternalErrorCodeUnexpectedResponse = 4,
/** @var FIRAuthInternalErrorCodeRPCResponseDecodingError
@brief Indicates an error decoding the RPC response.
This is typically due to some sort of unexpected response value from the server.
@remarks See the @c NSUnderlyingError value in the @c NSError.userInfo dictionary for details.
See the @c FIRErrorUserInfoDecodedResponseKey value in the @c NSError.userInfo dictionary.
The deserialized representation of the response will be associated with this key.
*/
FIRAuthInternalErrorCodeRPCResponseDecodingError = 5,
};

View File

@@ -0,0 +1,70 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
@brief The protocol for permanant data storage.
*/
@protocol FIRAuthStorage <NSObject>
/** @fn initWithService:
@brief Initialize a @c FIRAuthStorage instance.
@param service The name of the storage service to use.
@return An initialized @c FIRAuthStorage instance for the specified service.
*/
- (id<FIRAuthStorage>)initWithService:(NSString *)service;
/** @fn dataForKey:error:
@brief Gets the data for @c key in the storage. The key is set for the attribute
@c kSecAttrAccount of a generic password query.
@param key The key to use.
@param error The address to store any error that occurs during the process, if not NULL.
If the operation was successful, its content is set to @c nil .
@return The data stored in the storage for @c key, if any.
*/
- (nullable NSData *)dataForKey:(NSString *)key error:(NSError **_Nullable)error;
/** @fn setData:forKey:error:
@brief Sets the data for @c key in the storage. The key is set for the attribute
@c kSecAttrAccount of a generic password query.
@param data The data to store.
@param key The key to use.
@param error The address to store any error that occurs during the process, if not NULL.
@return Whether the operation succeeded or not.
*/
- (BOOL)setData:(NSData *)data forKey:(NSString *)key error:(NSError **_Nullable)error;
/** @fn removeDataForKey:error:
@brief Removes the data for @c key in the storage. The key is set for the attribute
@c kSecAttrAccount of a generic password query.
@param key The key to use.
@param error The address to store any error that occurs during the process, if not NULL.
@return Whether the operation succeeded or not.
*/
- (BOOL)removeDataForKey:(NSString *)key error:(NSError **_Nullable)error;
@end
/** @class FIRAuthKeychain
@brief The utility class to manipulate data in iOS Keychain.
*/
@interface FIRAuthKeychain : NSObject <FIRAuthStorage>
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,256 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthKeychain.h"
#import <Security/Security.h>
#import "FIRAuthErrorUtils.h"
#import "FIRAuthUserDefaultsStorage.h"
#if FIRAUTH_USER_DEFAULTS_STORAGE_AVAILABLE
#import <UIKit/UIKit.h>
/** @var kOSVersionMatcherForUsingUserDefaults
@brief The regular expression to match all OS versions that @c FIRAuthUserDefaultsStorage is
used instead if available.
*/
static NSString *const kOSVersionMatcherForUsingUserDefaults = @"^10\\.[01](\\..*)?$";
#endif // FIRAUTH_USER_DEFAULTS_STORAGE_AVAILABLE
/** @var kAccountPrefix
@brief The prefix string for keychain item account attribute before the key.
@remarks A number "1" is encoded in the prefix in case we need to upgrade the scheme in future.
*/
static NSString *const kAccountPrefix = @"firebase_auth_1_";
@implementation FIRAuthKeychain {
/** @var _service
@brief The name of the keychain service.
*/
NSString *_service;
/** @var _legacyItemDeletedForKey
@brief Indicates whether or not this class knows that the legacy item for a particular key has
been deleted.
@remarks This dictionary is to avoid unecessary keychain operations against legacy items.
*/
NSMutableDictionary *_legacyEntryDeletedForKey;
}
- (id<FIRAuthStorage>)initWithService:(NSString *)service {
#if FIRAUTH_USER_DEFAULTS_STORAGE_AVAILABLE
NSString *OSVersion = [UIDevice currentDevice].systemVersion;
NSRegularExpression *regex =
[NSRegularExpression regularExpressionWithPattern:kOSVersionMatcherForUsingUserDefaults
options:0
error:NULL];
if ([regex numberOfMatchesInString:OSVersion options:0 range:NSMakeRange(0, OSVersion.length)]) {
return (id<FIRAuthStorage>)[[FIRAuthUserDefaultsStorage alloc] initWithService:service];
}
#endif // FIRAUTH_USER_DEFAULTS_STORAGE_AVAILABLE
self = [super init];
if (self) {
_service = [service copy];
_legacyEntryDeletedForKey = [[NSMutableDictionary alloc] init];
}
return self;
}
- (NSData *)dataForKey:(NSString *)key error:(NSError **_Nullable)error {
if (!key.length) {
[NSException raise:NSInvalidArgumentException
format:@"%@", @"The key cannot be nil or empty."];
return nil;
}
NSData *data = [self itemWithQuery:[self genericPasswordQueryWithKey:key] error:error];
if (error && *error) {
return nil;
}
if (data) {
return data;
}
// Check for legacy form.
if (_legacyEntryDeletedForKey[key]) {
return nil;
}
data = [self itemWithQuery:[self legacyGenericPasswordQueryWithKey:key] error:error];
if (error && *error) {
return nil;
}
if (!data) {
// Mark legacy data as non-existing so we don't have to query it again.
_legacyEntryDeletedForKey[key] = @YES;
return nil;
}
// Move the data to current form.
if (![self setData:data forKey:key error:error]) {
return nil;
}
[self deleteLegacyItemWithKey:key];
return data;
}
- (BOOL)setData:(NSData *)data forKey:(NSString *)key error:(NSError **_Nullable)error {
if (!key.length) {
[NSException raise:NSInvalidArgumentException
format:@"%@", @"The key cannot be nil or empty."];
return NO;
}
NSDictionary *attributes = @{
(__bridge id)kSecValueData : data,
(__bridge id)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly,
};
return [self setItemWithQuery:[self genericPasswordQueryWithKey:key]
attributes:attributes
error:error];
}
- (BOOL)removeDataForKey:(NSString *)key error:(NSError **_Nullable)error {
if (!key.length) {
[NSException raise:NSInvalidArgumentException
format:@"%@", @"The key cannot be nil or empty."];
return NO;
}
if (![self deleteItemWithQuery:[self genericPasswordQueryWithKey:key] error:error]) {
return NO;
}
// Legacy form item, if exists, also needs to be removed, otherwise it will be exposed when
// current form item is removed, leading to incorrect semantics.
[self deleteLegacyItemWithKey:key];
return YES;
}
#pragma mark - Private
- (NSData *)itemWithQuery:(NSDictionary *)query error:(NSError **_Nullable)error {
NSMutableDictionary *returningQuery = [query mutableCopy];
returningQuery[(__bridge id)kSecReturnData] = @YES;
returningQuery[(__bridge id)kSecReturnAttributes] = @YES;
// Using a match limit of 2 means that we can check whether there is more than one item.
// If we used a match limit of 1 we would never find out.
returningQuery[(__bridge id)kSecMatchLimit] = @2;
CFArrayRef result = NULL;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)returningQuery,
(CFTypeRef *)&result);
if (status == noErr && result != NULL) {
NSArray *items = (__bridge_transfer NSArray *)result;
if (items.count != 1) {
if (error) {
*error = [FIRAuthErrorUtils keychainErrorWithFunction:@"SecItemCopyMatching"
status:status];
}
return nil;
}
if (error) {
*error = nil;
}
NSDictionary *item = items[0];
return item[(__bridge id)kSecValueData];
}
if (status == errSecItemNotFound) {
if (error) {
*error = nil;
}
} else {
if (error) {
*error = [FIRAuthErrorUtils keychainErrorWithFunction:@"SecItemCopyMatching" status:status];
}
}
return nil;
}
- (BOOL)setItemWithQuery:(NSDictionary *)query
attributes:(NSDictionary *)attributes
error:(NSError **_Nullable)error {
NSMutableDictionary *combined = [attributes mutableCopy];
[combined addEntriesFromDictionary:query];
BOOL hasItem = NO;
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)combined, NULL);
if (status == errSecDuplicateItem) {
hasItem = YES;
status = SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)attributes);
}
if (status == noErr) {
return YES;
}
if (error) {
NSString *function = hasItem ? @"SecItemUpdate" : @"SecItemAdd";
*error = [FIRAuthErrorUtils keychainErrorWithFunction:function status:status];
}
return NO;
}
- (BOOL)deleteItemWithQuery:(NSDictionary *)query error:(NSError **_Nullable)error {
OSStatus status = SecItemDelete((__bridge CFDictionaryRef)query);
if (status == noErr || status == errSecItemNotFound) {
return YES;
}
if (error) {
*error = [FIRAuthErrorUtils keychainErrorWithFunction:@"SecItemDelete" status:status];
}
return NO;
}
/** @fn deleteLegacyItemsWithKey:
@brief Deletes legacy item from the keychain if it is not already known to be deleted.
@param key The key for the item.
*/
- (void)deleteLegacyItemWithKey:(NSString *)key {
if (_legacyEntryDeletedForKey[key]) {
return;
}
NSDictionary *query = [self legacyGenericPasswordQueryWithKey:key];
SecItemDelete((__bridge CFDictionaryRef)query);
_legacyEntryDeletedForKey[key] = @YES;
}
/** @fn genericPasswordQueryWithKey:
@brief Returns a keychain query of generic password to be used to manipulate key'ed value.
@param key The key for the value being manipulated, used as the account field in the query.
*/
- (NSDictionary *)genericPasswordQueryWithKey:(NSString *)key {
return @{
(__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrAccount : [kAccountPrefix stringByAppendingString:key],
(__bridge id)kSecAttrService : _service,
};
}
/** @fn legacyGenericPasswordQueryWithKey:
@brief Returns a keychain query of generic password without service field, which is used by
previous version of this class.
@param key The key for the value being manipulated, used as the account field in the query.
*/
- (NSDictionary *)legacyGenericPasswordQueryWithKey:(NSString *)key {
return @{
(__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrAccount : key,
};
}
@end

View File

@@ -0,0 +1,71 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@class FIRAuthAppCredentialManager;
NS_ASSUME_NONNULL_BEGIN
/** @typedef FIRAuthNotificationForwardingCallback
@brief The type of block to receive whether or not remote notifications are being forwarded.
@param isNotificationBeingForwarded Whether or not remote notifications are being forwarded.
*/
typedef void (^FIRAuthNotificationForwardingCallback)(BOOL isNotificationBeingForwarded);
/** @class FIRAuthNotificationManager
*/
@interface FIRAuthNotificationManager : NSObject
/** @property timeout
@brief The timeout for checking for notification forwarding.
@remarks Only tests should access this property.
*/
@property(nonatomic, assign) NSTimeInterval timeout;
/** @fn initWithApplication:appCredentialManager:
@brief Initializes the instance.
@param application The application.
@param appCredentialManager The object to handle app credentials delivered via notification.
@return The initialized instance.
*/
- (instancetype)initWithApplication:(UIApplication *)application
appCredentialManager:(FIRAuthAppCredentialManager *)appCredentialManager
NS_DESIGNATED_INITIALIZER;
/** @fn init
@brief please use initWithAppCredentialManager: instead.
*/
- (instancetype)init NS_UNAVAILABLE;
/** @fn checkNotificationForwardingWithCallback:
@brief Checks whether or not remote notifications are being forwarded to this class.
@param callback The block to be called either immediately or in future once a result
is available.
*/
- (void)checkNotificationForwardingWithCallback:(FIRAuthNotificationForwardingCallback)callback;
/** @fn canHandleNotification:
@brief Attempts to handle the remote notification.
@param notification The notification in question.
@return Whether or the notification has been handled.
*/
- (BOOL)canHandleNotification:(NSDictionary *)notification;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,177 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthNotificationManager.h"
#import <FirebaseCore/FIRLogger.h>
#import "FIRAuthAppCredential.h"
#import "FIRAuthAppCredentialManager.h"
#import "FIRAuthGlobalWorkQueue.h"
NS_ASSUME_NONNULL_BEGIN
/** @var kNotificationKey
@brief The key to locate payload data in the remote notification.
*/
static NSString *const kNotificationDataKey = @"com.google.firebase.auth";
/** @var kNotificationReceiptKey
@brief The key for the receipt in the remote notification payload data.
*/
static NSString *const kNotificationReceiptKey = @"receipt";
/** @var kNotificationSecretKey
@brief The key for the secret in the remote notification payload data.
*/
static NSString *const kNotificationSecretKey = @"secret";
/** @var kNotificationProberKey
@brief The key for marking the prober in the remote notification payload data.
*/
static NSString *const kNotificationProberKey = @"warning";
/** @var kProbingTimeout
@brief Timeout for probing whether the app delegate forwards the remote notification to us.
*/
static const NSTimeInterval kProbingTimeout = 1;
@implementation FIRAuthNotificationManager {
/** @var _application
@brief The application.
*/
UIApplication *_application;
/** @var _appCredentialManager
@brief The object to handle app credentials delivered via notification.
*/
FIRAuthAppCredentialManager *_appCredentialManager;
/** @var _hasCheckedNotificationForwarding
@brief Whether notification forwarding has been checked or not.
*/
BOOL _hasCheckedNotificationForwarding;
/** @var _isNotificationBeingForwarded
@brief Whether or not notification is being forwarded
*/
BOOL _isNotificationBeingForwarded;
/** @var _pendingCallbacks
@brief All pending callbacks while a check is being performed.
*/
NSMutableArray<FIRAuthNotificationForwardingCallback> *_pendingCallbacks;
}
- (instancetype)initWithApplication:(UIApplication *)application
appCredentialManager:(FIRAuthAppCredentialManager *)appCredentialManager {
self = [super init];
if (self) {
_application = application;
_appCredentialManager = appCredentialManager;
_timeout = kProbingTimeout;
}
return self;
}
- (void)checkNotificationForwardingWithCallback:(FIRAuthNotificationForwardingCallback)callback {
if (_pendingCallbacks) {
[_pendingCallbacks addObject:callback];
return;
}
if (_hasCheckedNotificationForwarding) {
callback(_isNotificationBeingForwarded);
return;
}
_hasCheckedNotificationForwarding = YES;
_pendingCallbacks =
[[NSMutableArray<FIRAuthNotificationForwardingCallback> alloc] initWithObjects:callback, nil];
dispatch_async(dispatch_get_main_queue(), ^{
NSDictionary *proberNotification = @{
kNotificationDataKey : @{
kNotificationProberKey : @"This fake notification should be forwarded to Firebase Auth."
}
};
if ([self->_application.delegate respondsToSelector:
@selector(application:didReceiveRemoteNotification:fetchCompletionHandler:)]) {
[self->_application.delegate application:self->_application
didReceiveRemoteNotification:proberNotification
fetchCompletionHandler:^(UIBackgroundFetchResult result) {}];
#if !TARGET_OS_TV
} else if ([self->_application.delegate respondsToSelector:
@selector(application:didReceiveRemoteNotification:)]) {
[self->_application.delegate application:self->_application
didReceiveRemoteNotification:proberNotification];
#endif
} else {
FIRLogWarning(kFIRLoggerAuth, @"I-AUT000015",
@"The UIApplicationDelegate must handle remote notification for phone number "
@"authentication to work.");
}
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_timeout * NSEC_PER_SEC)),
FIRAuthGlobalWorkQueue(), ^{
[self callBack];
});
}
- (BOOL)canHandleNotification:(NSDictionary *)notification {
NSDictionary *data = notification[kNotificationDataKey];
if ([data isKindOfClass:[NSString class]]) {
// Deserialize in case the data is a JSON string.
NSData *JSONData = [((NSString *)data) dataUsingEncoding:NSUTF8StringEncoding];
data = [NSJSONSerialization JSONObjectWithData:JSONData options:0 error:NULL];
}
if (![data isKindOfClass:[NSDictionary class]]) {
return NO;
}
if (data[kNotificationProberKey]) {
if (!_pendingCallbacks) {
// The prober notification probably comes from another instance, so pass it along.
return NO;
}
_isNotificationBeingForwarded = YES;
[self callBack];
return YES;
}
NSString *receipt = data[kNotificationReceiptKey];
if (![receipt isKindOfClass:[NSString class]]) {
return NO;
}
NSString *secret = data[kNotificationSecretKey];
if (![receipt isKindOfClass:[NSString class]]) {
return NO;
}
return [_appCredentialManager canFinishVerificationWithReceipt:receipt secret:secret];
}
#pragma mark - Internal methods
/** @fn callBack
@brief Calls back all pending callbacks with the result of notification forwarding check.
*/
- (void)callBack {
if (!_pendingCallbacks) {
return;
}
NSArray<FIRAuthNotificationForwardingCallback> *allCallbacks = _pendingCallbacks;
_pendingCallbacks = nil;
for (FIRAuthNotificationForwardingCallback callback in allCallbacks) {
callback(_isNotificationBeingForwarded);
}
};
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
@brief Indicates the type of operation performed for RPCs that support the operation
parameter.
*/
typedef NS_ENUM(NSInteger, FIRAuthOperationType) {
/** Indicates that the operation type is uspecified.
*/
FIRAuthOperationTypeUnspecified = 0,
/** Indicates that the operation type is sign in or sign up.
*/
FIRAuthOperationTypeSignUpOrSignIn = 1,
/** Indicates that the operation type is reauthentication.
*/
FIRAuthOperationTypeReauth = 2,
/** Indicates that the operation type is update.
*/
FIRAuthOperationTypeUpdate = 3,
/** Indicates that the operation type is link.
*/
FIRAuthOperationTypeLink = 4,
};
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,69 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#pragma mark - Provider ID constants
// Declared 'extern' in FIRGoogleAuthProvider.h
NSString *const FIRGoogleAuthProviderID = @"google.com";
// Declared 'extern' in FIRFacebookAuthProvider.h
NSString *const FIRFacebookAuthProviderID = @"facebook.com";
// Declared 'extern' in FIREmailAuthProvider.h
NSString *const FIREmailAuthProviderID = @"password";
// Declared 'extern' in FIREmailAuthProvider.h
NSString *const FIREmailPasswordAuthProviderID = @"password";
// Declared 'extern' in FIRTwitterAuthProvider.h
NSString *const FIRTwitterAuthProviderID = @"twitter.com";
// Declared 'extern' in FIRGitHubAuthProvider.h
NSString *const FIRGitHubAuthProviderID = @"github.com";
// Declared 'extern' in FIRPhoneAuthProvider.h
NSString *const FIRPhoneAuthProviderID = @"phone";
// Declared 'extern' in FIRGameCenterAuthProvider.h
NSString *const FIRGameCenterAuthProviderID = @"gc.apple.com";
#pragma mark - sign-in methods constants
// Declared 'extern' in FIRGoogleAuthProvider.h
NSString *const FIRGoogleAuthSignInMethod = @"google.com";
// Declared 'extern' in FIREmailAuthProvider.h
NSString *const FIREmailPasswordAuthSignInMethod = @"password";
// Declared 'extern' in FIREmailAuthProvider.h
NSString *const FIREmailLinkAuthSignInMethod = @"emailLink";
// Declared 'extern' in FIRTwitterAuthProvider.h
NSString *const FIRTwitterAuthSignInMethod = @"twitter.com";
// Declared 'extern' in FIRFacebookAuthProvider.h
NSString *const FIRFacebookAuthSignInMethod = @"facebook.com";
// Declared 'extern' in FIRGitHubAuthProvider.h
NSString *const FIRGitHubAuthSignInMethod = @"github.com";
// Declared 'extern' in FIRPhoneAuthProvider.h
NSString *const FIRPhoneAuthSignInMethod = @"phone";
// Declared 'extern' in FIRGameCenterAuthProvider.h
NSString *const FIRGameCenterAuthSignInMethod = @"gc.apple.com";

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/** @typedef FIRAuthSerialTaskCompletionBlock
@brief The type of method a @c FIRAuthSerialTask must call when it is complete.
*/
typedef void (^FIRAuthSerialTaskCompletionBlock)(void);
/** @typedef FIRAuthSerialTask
@brief Represents a unit of work submitted to a task queue.
@param complete The task MUST call the complete method when done.
*/
typedef void (^FIRAuthSerialTask)(FIRAuthSerialTaskCompletionBlock complete);
/** @class FIRAuthSerialTaskQueue
@brief An easy to use serial task queue which supports a callback-based completion notification
system for easy asyncronous call chaining.
*/
@interface FIRAuthSerialTaskQueue : NSObject
/** @fn enqueueTask:
@brief Enqueues a task for serial execution in the queue.
@remarks The task MUST call the complete method when done. This method is thread-safe.
The task block won't be executed concurrently with any other blocks in other task queues or
the global work queue as returned by @c FIRAuthGlobalWorkQueue , but an uncompleted task
(e.g. task block finished executation before complete method is called at a later time)
does not affect other task queues or the global work queue.
*/
- (void)enqueueTask:(FIRAuthSerialTask)task;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthSerialTaskQueue.h"
#import "FIRAuthGlobalWorkQueue.h"
@implementation FIRAuthSerialTaskQueue {
/** @var _dispatchQueue
@brief The asyncronous dispatch queue into which tasks are enqueued and processed
serially.
*/
dispatch_queue_t _dispatchQueue;
}
- (instancetype)init {
self = [super init];
if (self) {
_dispatchQueue = dispatch_queue_create("com.google.firebase.auth.serialTaskQueue", NULL);
dispatch_set_target_queue(_dispatchQueue, FIRAuthGlobalWorkQueue());
}
return self;
}
- (void)enqueueTask:(FIRAuthSerialTask)task {
// This dispatch queue will run tasks serially in FIFO order, as long as it's not suspended.
dispatch_async(self->_dispatchQueue, ^{
// But as soon as a task is started, stop other tasks from running until the task calls it's
// completion handler, which allows the queue to resume processing of tasks. This allows the
// task to perform other asyncronous actions on other dispatch queues and "get back to us" when
// all of their sub-tasks are complete.
dispatch_suspend(self->_dispatchQueue);
task(^{
dispatch_resume(self->_dispatchQueue);
});
});
}
@end

View File

@@ -0,0 +1,29 @@
/*
* Copyright 2018 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthSettings.h"
@implementation FIRAuthSettings
- (instancetype)init {
self = [super init];
if (self) {
_appVerificationDisabledForTesting = NO;
}
return self;
}
@end

View File

@@ -0,0 +1,110 @@
/*
* Copyright 2018 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthTokenResult_Internal.h"
NS_ASSUME_NONNULL_BEGIN
/** @var kExpirationDateKey
@brief The key used to encode the expirationDate property for NSSecureCoding.
*/
static NSString *const kExpirationDateKey = @"expiratinDate";
/** @var kTokenKey
@brief The key used to encode the token property for NSSecureCoding.
*/
static NSString *const kTokenKey = @"token";
/** @var kAuthDateKey
@brief The key used to encode the authDate property for NSSecureCoding.
*/
static NSString *const kAuthDateKey = @"authDate";
/** @var kIssuedDateKey
@brief The key used to encode the issuedDate property for NSSecureCoding.
*/
static NSString *const kIssuedDateKey = @"issuedDate";
/** @var kSignInProviderKey
@brief The key used to encode the signInProvider property for NSSecureCoding.
*/
static NSString *const kSignInProviderKey = @"signInProvider";
/** @var kClaimsKey
@brief The key used to encode the claims property for NSSecureCoding.
*/
static NSString *const kClaimsKey = @"claims";
@implementation FIRAuthTokenResult
- (instancetype)initWithToken:(NSString *)token
expirationDate:(NSDate *)expirationDate
authDate:(NSDate *)authDate
issuedAtDate:(NSDate *)issuedAtDate
signInProvider:(NSString *)signInProvider
claims:(NSDictionary *)claims {
self = [super init];
if (self) {
_token = token;
_expirationDate = expirationDate;
_authDate = authDate;
_issuedAtDate = issuedAtDate;
_signInProvider = signInProvider;
_claims = claims;
}
return self;
}
#pragma mark - NSSecureCoding
+ (BOOL)supportsSecureCoding {
return YES;
}
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
NSString *token =
[aDecoder decodeObjectOfClass:[NSDate class] forKey:kTokenKey];
NSDate *expirationDate =
[aDecoder decodeObjectOfClass:[NSDate class] forKey:kExpirationDateKey];
NSDate *authDate =
[aDecoder decodeObjectOfClass:[NSDate class] forKey:kAuthDateKey];
NSDate *issuedAtDate =
[aDecoder decodeObjectOfClass:[NSDate class] forKey:kAuthDateKey];
NSString *signInProvider =
[aDecoder decodeObjectOfClass:[NSString class] forKey:kSignInProviderKey];
NSDictionary<NSString *, NSString *> *claims =
[aDecoder decodeObjectOfClass:[NSDictionary<NSString *, NSString *> class] forKey:kClaimsKey];
return [self initWithToken:token
expirationDate:expirationDate
authDate:authDate
issuedAtDate:issuedAtDate
signInProvider:signInProvider
claims:claims];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_token forKey:kTokenKey];
[aCoder encodeObject:_expirationDate forKey:kExpirationDateKey];
[aCoder encodeObject:_authDate forKey:kAuthDateKey];
[aCoder encodeObject:_issuedAtDate forKey:kIssuedDateKey];
[aCoder encodeObject:_signInProvider forKey:kSignInProviderKey];
[aCoder encodeObject:_claims forKey:kClaimsKey];
}
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2018 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import "FIRAuthTokenResult.h"
NS_ASSUME_NONNULL_BEGIN
/** @extension FIRAuthAPNSTokenResult
@brief An internal class used to expose internal methods of FIRAuthAPNSTokenResult.
*/
@interface FIRAuthTokenResult () <NSSecureCoding>
- (instancetype)initWithToken:(NSString *)token
expirationDate:(NSDate *)expirationDate
authDate:(NSDate *)authDate
issuedAtDate:(NSDate *)issuedAtDate
signInProvider:(NSString *)signInProvider
claims:(NSDictionary *)claims;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,64 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@protocol FIRAuthUIDelegate;
/** @typedef FIRAuthURLPresentationCompletion
@brief The type of block invoked when the URLPresentation completes.
@param callbackURL The callback URL if the presentation ends with a matching callback.
@param error The error if the presentation fails to start or ends with an error.
*/
typedef void (^FIRAuthURLPresentationCompletion)(NSURL *_Nullable callbackURL,
NSError *_Nullable error);
/** @typedef FIRAuthCallbackMatcher
@brief The type of block invoked for checking whether a callback URL matches.
@param callbackURL The callback URL to check for match.
@return Whether or not the specific callback URL matches or not.
*/
typedef BOOL (^FIRAuthURLCallbackMatcher)(NSURL * _Nullable callbackURL);
/** @class FIRAuthURLPresenter
@brief A Class responsible for presenting URL via SFSafariViewController or UIWebView.
*/
@interface FIRAuthURLPresenter : NSObject
/** @fn presentURL:UIDelegate:callbackMatcher:completion:
@brief Presents an URL to interact with user.
@param URL The URL to present.
@param UIDelegate The UI delegate to present view controller.
@param completion A block to be called either synchronously if the presentation fails to start,
or asynchronously in future on an unspecified thread once the presentation finishes.
*/
- (void)presentURL:(NSURL *)URL
UIDelegate:(nullable id<FIRAuthUIDelegate>)UIDelegate
callbackMatcher:(FIRAuthURLCallbackMatcher)callbackMatcher
completion:(FIRAuthURLPresentationCompletion)completion;
/** @fn canHandleURL:
@brief Determines if a URL was produced by the currently presented URL.
@param URL The URL to handle.
@return Whether the URL could be handled or not.
*/
- (BOOL)canHandleURL:(NSURL *)URL;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,190 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthURLPresenter.h"
#import <SafariServices/SafariServices.h>
#import "FIRAuthDefaultUIDelegate.h"
#import "FIRAuthErrorUtils.h"
#import "FIRAuthGlobalWorkQueue.h"
#import "FIRAuthUIDelegate.h"
#import "FIRAuthWebViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface FIRAuthURLPresenter () <SFSafariViewControllerDelegate,
FIRAuthWebViewControllerDelegate>
@end
// Disable unguarded availability warnings because SFSafariViewController is been used throughout
// the code, including as an iVar, which cannot be simply excluded by @available check.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability"
@implementation FIRAuthURLPresenter {
/** @var _isPresenting
@brief Whether or not some web-based content is being presented.
*/
BOOL _isPresenting;
/** @var _callbackMatcher
@brief The callback URL matcher for the current presentation, if one is active.
*/
FIRAuthURLCallbackMatcher _Nullable _callbackMatcher;
/** @var _safariViewController
@brief The SFSafariViewController used for the current presentation, if any.
*/
SFSafariViewController *_Nullable _safariViewController;
/** @var _webViewController
@brief The FIRAuthWebViewController used for the current presentation, if any.
*/
FIRAuthWebViewController *_Nullable _webViewController;
/** @var _UIDelegate
@brief The UIDelegate used to present the SFSafariViewController.
*/
id<FIRAuthUIDelegate> _UIDelegate;
/** @var _completion
@brief The completion handler for the current presentaion, if one is active.
@remarks This variable is also used as a flag to indicate a presentation is active.
*/
FIRAuthURLPresentationCompletion _Nullable _completion;
}
- (void)presentURL:(NSURL *)URL
UIDelegate:(nullable id<FIRAuthUIDelegate>)UIDelegate
callbackMatcher:(FIRAuthURLCallbackMatcher)callbackMatcher
completion:(FIRAuthURLPresentationCompletion)completion {
if (_isPresenting) {
// Unable to start a new presentation on top of another.
_completion(nil, [FIRAuthErrorUtils webContextAlreadyPresentedErrorWithMessage:nil]);
return;
}
_isPresenting = YES;
_callbackMatcher = callbackMatcher;
_completion = completion;
dispatch_async(dispatch_get_main_queue(), ^() {
self->_UIDelegate = UIDelegate ?: [FIRAuthDefaultUIDelegate defaultUIDelegate];
if ([SFSafariViewController class]) {
self->_safariViewController = [[SFSafariViewController alloc] initWithURL:URL];
self->_safariViewController.delegate = self;
[self->_UIDelegate presentViewController:self->_safariViewController
animated:YES
completion:nil];
return;
} else {
self->_webViewController = [[FIRAuthWebViewController alloc] initWithURL:URL delegate:self];
UINavigationController *navController =
[[UINavigationController alloc] initWithRootViewController:self->_webViewController];
[self->_UIDelegate presentViewController:navController animated:YES completion:nil];
}
});
}
- (BOOL)canHandleURL:(NSURL *)URL {
if (_isPresenting && _callbackMatcher && _callbackMatcher(URL)) {
[self finishPresentationWithURL:URL error:nil];
return YES;
}
return NO;
}
#pragma mark - SFSafariViewControllerDelegate
- (void)safariViewControllerDidFinish:(SFSafariViewController *)controller {
dispatch_async(FIRAuthGlobalWorkQueue(), ^() {
if (controller == self->_safariViewController) {
self->_safariViewController = nil;
//TODO:Ensure that the SFSafariViewController is actually removed from the screen before
//invoking finishPresentationWithURL:error:
[self finishPresentationWithURL:nil
error:[FIRAuthErrorUtils webContextCancelledErrorWithMessage:nil]];
}
});
}
#pragma mark - FIRAuthwebViewControllerDelegate
- (BOOL)webViewController:(FIRAuthWebViewController *)webViewController canHandleURL:(NSURL *)URL {
__block BOOL result = NO;
dispatch_sync(FIRAuthGlobalWorkQueue(), ^() {
if (webViewController == self->_webViewController) {
result = [self canHandleURL:URL];
}
});
return result;
}
- (void)webViewControllerDidCancel:(FIRAuthWebViewController *)webViewController {
dispatch_async(FIRAuthGlobalWorkQueue(), ^() {
if (webViewController == self->_webViewController) {
[self finishPresentationWithURL:nil
error:[FIRAuthErrorUtils webContextCancelledErrorWithMessage:nil]];
}
});
}
- (void)webViewController:(FIRAuthWebViewController *)webViewController
didFailWithError:(NSError *)error {
dispatch_async(FIRAuthGlobalWorkQueue(), ^() {
if (webViewController == self->_webViewController) {
[self finishPresentationWithURL:nil error:error];
}
});
}
#pragma mark - Private methods
/** @fn finishPresentationWithURL:error:
@brief Finishes the presentation for a given URL, if any.
@param URL The URL to finish presenting.
@param error The error with which to finish presenting, if any.
*/
- (void)finishPresentationWithURL:(nullable NSURL *)URL
error:(nullable NSError *)error {
_callbackMatcher = nil;
id<FIRAuthUIDelegate> UIDelegate = _UIDelegate;
_UIDelegate = nil;
FIRAuthURLPresentationCompletion completion = _completion;
_completion = nil;
void (^finishBlock)(void) = ^() {
self->_isPresenting = NO;
completion(URL, error);
};
SFSafariViewController *safariViewController = _safariViewController;
_safariViewController = nil;
FIRAuthWebViewController *webViewController = _webViewController;
_webViewController = nil;
if (safariViewController || webViewController) {
dispatch_async(dispatch_get_main_queue(), ^() {
[UIDelegate dismissViewControllerAnimated:YES completion:^() {
dispatch_async(FIRAuthGlobalWorkQueue(), finishBlock);
}];
});
} else {
finishBlock();
}
}
#pragma clang diagnostic pop // ignored "-Wunguarded-availability"
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
// This class is only available in the simulator.
#if TARGET_OS_SIMULATOR
#ifndef FIRAUTH_USER_DEFAULTS_STORAGE_AVAILABLE
#define FIRAUTH_USER_DEFAULTS_STORAGE_AVAILABLE 1
#endif
#endif
#if FIRAUTH_USER_DEFAULTS_STORAGE_AVAILABLE
#import "FIRAuthKeychain.h"
NS_ASSUME_NONNULL_BEGIN
/** @class FIRAuthUserDefaultsStorage
@brief The utility class to storage data in NSUserDefaults.
*/
@interface FIRAuthUserDefaultsStorage : NSObject <FIRAuthStorage>
/** @fn clear
@brief Clears all data from the storage.
@remarks This method is only supposed to be called from tests.
*/
- (void)clear;
@end
NS_ASSUME_NONNULL_END
#endif // FIRAUTH_USER_DEFAULTS_STORAGE_AVAILABLE

View File

@@ -0,0 +1,78 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthUserDefaultsStorage.h"
#if FIRAUTH_USER_DEFAULTS_STORAGE_AVAILABLE
NS_ASSUME_NONNULL_BEGIN
static NSString *const kPersistentDomainNamePrefix = @"com.google.Firebase.Auth.";
@implementation FIRAuthUserDefaultsStorage {
/** @var _persistentDomainName
@brief The name of the persistent domain in user defaults.
*/
NSString *_persistentDomainName;
/** @var _storage
@brief The backing NSUserDefaults storage for this instance.
*/
NSUserDefaults *_storage;
}
- (id<FIRAuthStorage>)initWithService:(NSString *)service {
self = [super init];
if (self) {
_persistentDomainName = [kPersistentDomainNamePrefix stringByAppendingString:service];
_storage = [[NSUserDefaults alloc] init];
}
return self;
}
- (nullable NSData *)dataForKey:(NSString *)key error:(NSError **_Nullable)error {
if (error) {
*error = nil;
}
NSDictionary<NSString *, id> *allData = [_storage persistentDomainForName:_persistentDomainName];
return allData[key];
}
- (BOOL)setData:(NSData *)data forKey:(NSString *)key error:(NSError **_Nullable)error {
NSMutableDictionary<NSString *, id> *allData =
[([_storage persistentDomainForName:_persistentDomainName] ?: @{}) mutableCopy];
allData[key] = data;
[_storage setPersistentDomain:allData forName:_persistentDomainName];
return YES;
}
- (BOOL)removeDataForKey:(NSString *)key error:(NSError **_Nullable)error {
NSMutableDictionary<NSString *, id> *allData =
[[_storage persistentDomainForName:_persistentDomainName] mutableCopy];
[allData removeObjectForKey:key];
[_storage setPersistentDomain:allData forName:_persistentDomainName];
return YES;
}
- (void)clear {
[_storage setPersistentDomain:@{} forName:_persistentDomainName];
}
@end
NS_ASSUME_NONNULL_END
#endif // FIRAUTH_USER_DEFAULTS_STORAGE_AVAILABLE

View File

@@ -0,0 +1,67 @@
/*
* Copyright 2018 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
@class FIRAuthRequestConfiguration;
NS_ASSUME_NONNULL_BEGIN
/** @typedef FIRFetchAuthDomainCallback
@brief The callback invoked at the end of the flow to fetch the Auth domain.
@param authDomain The Auth domain.
@param error The error that occurred while fetching the auth domain, if any.
*/
typedef void (^FIRFetchAuthDomainCallback)(NSString *_Nullable authDomain,
NSError *_Nullable error);
/** @class FIRAuthURLUtils
@brief A utility class used to facilitate the creation of auth related URLs.
*/
@interface FIRAuthWebUtils : NSObject
/** @fn randomStringWithLength:
@brief Generates a random string of a specified length.
*/
+ (NSString *)randomStringWithLength:(NSUInteger)length;
/** @fn isCallbackSchemeRegisteredForCustomURLScheme:
@brief Checks whether or not the provided custom URL scheme has been registered by the app.
@param URLScheme The custom URL scheme to be checked against all custom URL schemes registered by the app.
@return whether or not the provided custom URL scheme has been registered by the app.
*/
+ (BOOL)isCallbackSchemeRegisteredForCustomURLScheme:(NSString *)URLScheme;
/** @fn fetchAuthDomainWithCompletion:completion:
@brief Fetches the auth domain associated with the Firebase Project.
@param completion The callback invoked after the auth domain has been constructed or an error
has been encountered.
*/
+ (void)fetchAuthDomainWithRequestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration
completion:(FIRFetchAuthDomainCallback)completion;
/** @fn queryItemValue:from:
@brief Utility function to get a value from a NSURLQueryItem array.
@param name The key.
@param queryList The NSURLQueryItem array.
@return The value for the key.
*/
+ (nullable NSString *)queryItemValue:(NSString *)name from:(NSArray<NSURLQueryItem *> *)queryList;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,100 @@
/*
* Copyright 2018 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthWebUtils.h"
#import "FIRAuthBackend.h"
#import "FIRAuthErrorUtils.h"
#import "FIRGetProjectConfigRequest.h"
#import "FIRGetProjectConfigResponse.h"
/** @var kAuthDomainSuffix
@brief The suffix of the auth domain pertiaining to a given Firebase project.
*/
static NSString *const kAuthDomainSuffix = @"firebaseapp.com";
@implementation FIRAuthWebUtils
+ (NSString *)randomStringWithLength:(NSUInteger)length {
NSMutableString *randomString = [[NSMutableString alloc] init];
for (int i=0; i < length; i++) {
[randomString appendString:
[NSString stringWithFormat:@"%c", 'a' + arc4random_uniform('z' - 'a' + 1)]];
}
return randomString;
}
+ (BOOL)isCallbackSchemeRegisteredForCustomURLScheme:(NSString *)URLScheme {
NSString *expectedCustomScheme = [URLScheme lowercaseString];
NSArray *urlTypes = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleURLTypes"];
for (NSDictionary *urlType in urlTypes) {
NSArray *urlTypeSchemes = urlType[@"CFBundleURLSchemes"];
for (NSString *urlTypeScheme in urlTypeSchemes) {
if ([urlTypeScheme.lowercaseString isEqualToString:expectedCustomScheme]) {
return YES;
}
}
}
return NO;
}
+ (void)fetchAuthDomainWithRequestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration
completion:(FIRFetchAuthDomainCallback)completion {
FIRGetProjectConfigRequest *request =
[[FIRGetProjectConfigRequest alloc] initWithRequestConfiguration:requestConfiguration];
[FIRAuthBackend getProjectConfig:request
callback:^(FIRGetProjectConfigResponse *_Nullable response,
NSError *_Nullable error) {
if (error) {
completion(nil, error);
return;
}
NSString *authDomain;
for (NSString *domain in response.authorizedDomains) {
NSInteger index = domain.length - kAuthDomainSuffix.length;
if (index >= 2) {
if ([domain hasSuffix:kAuthDomainSuffix] && domain.length >= kAuthDomainSuffix.length + 2) {
authDomain = domain;
break;
}
}
}
if (!authDomain.length) {
completion(nil, [FIRAuthErrorUtils unexpectedErrorResponseWithDeserializedResponse:response]);
return;
}
completion(authDomain, nil);
}];
}
/** @fn queryItemValue:from:
@brief Utility function to get a value from a NSURLQueryItem array.
@param name The key.
@param queryList The NSURLQueryItem array.
@return The value for the key.
*/
+ (nullable NSString *)queryItemValue:(NSString *)name from:(NSArray<NSURLQueryItem *> *)queryList {
for (NSURLQueryItem *item in queryList) {
if ([item.name isEqualToString:name]) {
return item.value;
}
}
return nil;
}
@end

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
/** @class FIRAuthWebView
@brief A class reponsible for creating a UIWebview for use within Firebase Auth.
*/
@interface FIRAuthWebView : UIView
/** @property webView
* @brief The web view.
*/
@property(nonatomic, weak) UIWebView *webView;
/** @property spinner
* @brief The spinner that indicates web view loading.
*/
@property(nonatomic, weak) UIActivityIndicatorView *spinner;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,86 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthWebView.h"
NS_ASSUME_NONNULL_BEGIN
@implementation FIRAuthWebView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor whiteColor];
[self initializeSubviews];
}
return self;
}
/** @fn initializeSubviews
@brief Initializes the subviews of this view.
*/
- (void)initializeSubviews {
UIWebView *webView = [self createWebView];
UIActivityIndicatorView *spinner = [self createSpinner];
// The order of the following controls z-order.
[self addSubview:webView];
[self addSubview:spinner];
[self layoutSubviews];
_webView = webView;
_spinner = spinner;
}
- (void)layoutSubviews {
CGFloat height = self.bounds.size.height;
CGFloat width = self.bounds.size.width;
_webView.frame = CGRectMake(0, 0, width, height);
_spinner.center = _webView.center;
}
/** @fn createWebView
@brief Creates a web view to be used by this view.
@return The newly created web view.
*/
- (UIWebView *)createWebView {
UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectZero];
// Trickery to make the web view not do weird things (like showing a black background when
// the prompt in the navigation bar animates changes.)
webView.opaque = NO;
webView.backgroundColor = [UIColor clearColor];
webView.scrollView.opaque = NO;
webView.scrollView.backgroundColor = [UIColor clearColor];
webView.scrollView.bounces = NO;
webView.scrollView.alwaysBounceVertical = NO;
webView.scrollView.alwaysBounceHorizontal = NO;
return webView;
}
/** @fn createSpinner
@brief Creates a spinner to be used by this view.
@return The newly created spinner.
*/
- (UIActivityIndicatorView *)createSpinner {
UIActivityIndicatorViewStyle spinnerStyle = UIActivityIndicatorViewStyleGray;
UIActivityIndicatorView *spinner =
[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:spinnerStyle];
return spinner;
}
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,73 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <UIKit/UIKit.h>
@class FIRAuthWebViewController;
NS_ASSUME_NONNULL_BEGIN
/** @protocol FIRAuthWebViewControllerDelegate
@brief Defines a delegate for FIRAuthWebViewController
*/
@protocol FIRAuthWebViewControllerDelegate <NSObject>
/** @fn webViewController:canHandleURL:
@brief Determines if a URL should be handled by the delegate.
@param URL The URL to handle.
@return Whether the URL could be handled or not.
*/
- (BOOL)webViewController:(FIRAuthWebViewController *)webViewController canHandleURL:(NSURL *)URL;
/** @fn webViewControllerDidCancel:
@brief Notifies the delegate that the web view controller is being cancelled by the user.
@param webViewController The web view controller in question.
*/
- (void)webViewControllerDidCancel:(FIRAuthWebViewController *)webViewController;
/** @fn webViewController:didFailWithError:
@brief Notifies the delegate that the web view controller failed to load a page.
@param webViewController The web view controller in question.
@param error The error that has occurred.
*/
- (void)webViewController:(FIRAuthWebViewController *)webViewController
didFailWithError:(NSError *)error;
@end
/** @class FIRAuthWebViewController
@brief Reponsible for creating a UIViewController for presenting a FIRAutWebView.
*/
@interface FIRAuthWebViewController : UIViewController
/** @fn initWithNibName:bundle:
* @brief Please call initWithURL:delegate:
*/
- (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil
bundle:(nullable NSBundle *)nibBundleOrNil NS_UNAVAILABLE;
/** @fn initWithCoder:
* @brief Please call initWithURL:delegate:
*/
- (instancetype)initWithCoder:(NSCoder *)aDecoder NS_UNAVAILABLE;
- (instancetype)initWithURL:(NSURL *)URL
delegate:(__weak id<FIRAuthWebViewControllerDelegate>)delegate
NS_DESIGNATED_INITIALIZER;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,111 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthWebViewController.h"
#import "FIRAuthWebView.h"
NS_ASSUME_NONNULL_BEGIN
@interface FIRAuthWebViewController () <UIWebViewDelegate>
@end
@implementation FIRAuthWebViewController {
/** @var _URL
@brief The initial URL to display.
*/
NSURL *_URL;
/** @var _delegate
@brief The delegate to call.
*/
__weak id<FIRAuthWebViewControllerDelegate> _delegate;
/** @var _webView;
@brief The web view instance for easier access.
*/
__weak FIRAuthWebView *_webView;
}
- (instancetype)initWithURL:(NSURL *)URL
delegate:(__weak id<FIRAuthWebViewControllerDelegate>)delegate {
self = [super initWithNibName:nil bundle:nil];
if (self) {
_URL = URL;
_delegate = delegate;
}
return self;
}
#pragma mark - Lifecycle
- (void)loadView {
FIRAuthWebView *webView = [[FIRAuthWebView alloc] initWithFrame:[UIScreen mainScreen].bounds];
webView.webView.delegate = self;
self.view = webView;
_webView = webView;
self.navigationItem.leftBarButtonItem =
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
target:self
action:@selector(cancel)];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// Loads the requested URL in the web view.
[_webView.webView loadRequest:[NSURLRequest requestWithURL:_URL]];
}
#pragma mark - UI Targets
- (void)cancel {
[_delegate webViewControllerDidCancel:self];
}
#pragma mark - UIWebViewDelegate
- (BOOL)webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType {
return ![_delegate webViewController:self canHandleURL:request.URL];
}
- (void)webViewDidStartLoad:(UIWebView *)webView {
// Show & animate the activity indicator.
_webView.spinner.hidden = NO;
[_webView.spinner startAnimating];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
// Hide & stop the activity indicator.
_webView.spinner.hidden = YES;
[_webView.spinner stopAnimating];
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
if ([error.domain isEqualToString:NSURLErrorDomain] && error.code == NSURLErrorCancelled) {
// It's okay for the page to be redirected before it is completely loaded. See b/32028062 .
return;
}
// Forward notification to our delegate.
[self webViewDidFinishLoad:webView];
[_delegate webViewController:self didFailWithError:error];
}
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,122 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import "FIRAuth.h"
#import <FirebaseAuthInterop/FIRAuthInterop.h>
@class FIRAuthRequestConfiguration;
#if TARGET_OS_IOS
@class FIRAuthAPNSTokenManager;
@class FIRAuthAppCredentialManager;
@class FIRAuthNotificationManager;
@class FIRAuthURLPresenter;
#endif
NS_ASSUME_NONNULL_BEGIN
@interface FIRAuth () <FIRAuthInterop>
/** @property requestConfiguration
@brief The configuration object comprising of paramters needed to make a request to Firebase
Auth's backend.
*/
@property(nonatomic, copy, readonly) FIRAuthRequestConfiguration *requestConfiguration;
#if TARGET_OS_IOS
/** @property tokenManager
@brief The manager for APNs tokens used by phone number auth.
*/
@property(nonatomic, strong, readonly) FIRAuthAPNSTokenManager *tokenManager;
/** @property appCredentailManager
@brief The manager for app credentials used by phone number auth.
*/
@property(nonatomic, strong, readonly) FIRAuthAppCredentialManager *appCredentialManager;
/** @property notificationManager
@brief The manager for remote notifications used by phone number auth.
*/
@property(nonatomic, strong, readonly) FIRAuthNotificationManager *notificationManager;
/** @property authURLPresenter
@brief An object that takes care of presenting URLs via the auth instance.
*/
@property(nonatomic, strong, readonly) FIRAuthURLPresenter *authURLPresenter;
#endif // TARGET_OS_IOS
/** @fn initWithAPIKey:appName:
@brief Designated initializer.
@param APIKey The Google Developers Console API key for making requests from your app.
@param appName The name property of the previously created @c FIRApp instance.
*/
- (nullable instancetype)initWithAPIKey:(NSString *)APIKey
appName:(NSString *)appName NS_DESIGNATED_INITIALIZER;
/** @fn getUserID
@brief Gets the identifier of the current user, if any.
@return The identifier of the current user, or nil if there is no current user.
*/
- (nullable NSString *)getUserID;
/** @fn updateKeychainWithUser:error:
@brief Updates the keychain for the given user.
@param user The user to be updated.
@param error The error caused the method to fail if the method returns NO.
@return Whether updating keychain has succeeded or not.
@remarks Called by @c FIRUser when user info or token changes occur.
*/
- (BOOL)updateKeychainWithUser:(FIRUser *)user error:(NSError *_Nullable *_Nullable)error;
/** @fn internalSignInWithCredential:callback:
@brief Convenience method for @c internalSignInAndRetrieveDataWithCredential:callback:
This method doesn't return additional identity provider data.
*/
- (void)internalSignInWithCredential:(FIRAuthCredential *)credential
callback:(FIRAuthResultCallback)callback;
/** @fn internalSignInAndRetrieveDataWithCredential:callback:
@brief Asynchronously signs in Firebase with the given 3rd party credentials (e.g. a Facebook
login Access Token, a Google ID Token/Access Token pair, etc.) and returns additional
identity provider data.
@param credential The credential supplied by the IdP.
@param isReauthentication Indicates whether or not the current invocation originated from an
attempt to reauthenticate.
@param callback A block which is invoked when the sign in finishes (or is cancelled.) Invoked
asynchronously on the auth global work queue in the future.
@remarks This is the internal counterpart of this method, which uses a callback that does not
update the current user.
*/
- (void)internalSignInAndRetrieveDataWithCredential:(FIRAuthCredential *)credential
isReauthentication:(BOOL)isReauthentication
callback:(nullable FIRAuthDataResultCallback)callback;
/** @fn signOutByForceWithUserID:error:
@brief Signs out the current user.
@param userID The ID of the user to force sign out.
@param error An optional out parameter for error results.
@return @YES when the sign out request was successful. @NO otherwise.
*/
- (BOOL)signOutByForceWithUserID:(NSString *)userID error:(NSError *_Nullable *_Nullable)error;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,99 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
@class FIRAuthRequestConfiguration;
NS_ASSUME_NONNULL_BEGIN
/** @typedef FIRFetchAccessTokenCallback
@brief The callback used to return the value of attempting to fetch an access token.
In the event the operation was successful @c token will be set and @c error will be @c nil.
In the event of failure @c token will be @c nil and @c error will be set.
@c tokenUpdated indicates whether either the access or the refresh token has been updated.
The token returned should be considered ephemeral and not cached. It should be used immediately
and discarded. All operations that need this token should call fetchAccessToken and do their
work from the callback.
*/
typedef void(^FIRFetchAccessTokenCallback)(NSString *_Nullable token,
NSError *_Nullable error,
BOOL tokenUpdated);
/** @class FIRSecureTokenService
@brief Provides services for token exchanges and refreshes.
*/
@interface FIRSecureTokenService : NSObject <NSSecureCoding>
/** @property requestConfiguration
@brief The configuration for making requests to server.
*/
@property(nonatomic, strong) FIRAuthRequestConfiguration *requestConfiguration;
/** @property rawAccessToken
@brief The cached access token.
@remarks This method is specifically for providing the access token to internal clients during
deserialization and sign-in events, and should not be used to retrieve the access token by
anyone else.
*/
@property(nonatomic, copy, readonly) NSString *rawAccessToken;
/** @property refreshToken
@brief The refresh token for the user, or @c nil if the user has yet completed sign-in flow.
@remarks This property needs to be set manually after the instance is decoded from archive.
*/
@property(nonatomic, copy, readonly, nullable) NSString *refreshToken;
/** @property accessTokenExpirationDate
@brief The expiration date of the cached access token.
*/
@property(nonatomic, copy, readonly, nullable) NSDate *accessTokenExpirationDate;
/** @fn initWithRequestConfiguration:authorizationCode:
@brief Creates a @c FIRSecureTokenService with an authroization code.
@param requestConfiguration The configuration for making requests to server.
@param authorizationCode An authorization code which needs to be exchanged for STS tokens.
*/
- (instancetype)initWithRequestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration
authorizationCode:(NSString *)authorizationCode;
/** @fn initWithRequestConfiguration:accessToken:accessTokenExpirationDate:refreshToken
@brief Creates a @c FIRSecureTokenService with access and refresh tokens.
@param requestConfiguration The configuration for making requests to server.
@param accessToken The STS access token.
@param accessTokenExpirationDate The approximate expiration date of the access token.
@param refreshToken The STS refresh token.
*/
- (instancetype)initWithRequestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration
accessToken:(nullable NSString *)accessToken
accessTokenExpirationDate:(nullable NSDate *)accessTokenExpirationDate
refreshToken:(NSString *)refreshToken;
/** @fn fetchAccessTokenForcingRefresh:callback:
@brief Fetch a fresh ephemeral access token for the ID associated with this instance. The token
received in the callback should be considered short lived and not cached.
@param forceRefresh Forces the token to be refreshed.
@param callback Callback block that will be called to return either the token or an error.
Invoked asyncronously on the auth global work queue in the future.
*/
- (void)fetchAccessTokenForcingRefresh:(BOOL)forceRefresh
callback:(FIRFetchAccessTokenCallback)callback;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,206 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRSecureTokenService.h"
#import "FIRAuth.h"
#import "FIRAuthKeychain.h"
#import "FIRAuthSerialTaskQueue.h"
#import "FIRAuthBackend.h"
#import "FIRAuthRequestConfiguration.h"
#import "FIRSecureTokenRequest.h"
#import "FIRSecureTokenResponse.h"
/** @var kAPIKeyCodingKey
@brief The key used to encode the APIKey for NSSecureCoding.
*/
static NSString *const kAPIKeyCodingKey = @"APIKey";
/** @var kRefreshTokenKey
@brief The key used to encode the refresh token for NSSecureCoding.
*/
static NSString *const kRefreshTokenKey = @"refreshToken";
/** @var kAccessTokenKey
@brief The key used to encode the access token for NSSecureCoding.
*/
static NSString *const kAccessTokenKey = @"accessToken";
/** @var kAccessTokenExpirationDateKey
@brief The key used to encode the access token expiration date for NSSecureCoding.
*/
static NSString *const kAccessTokenExpirationDateKey = @"accessTokenExpirationDate";
/** @var kFiveMinutes
@brief Five minutes (in seconds.)
*/
static const NSTimeInterval kFiveMinutes = 5 * 60;
@interface FIRSecureTokenService ()
- (instancetype)init NS_DESIGNATED_INITIALIZER;
@end
@implementation FIRSecureTokenService {
/** @var _taskQueue
@brief Used to serialize all requests for access tokens.
*/
FIRAuthSerialTaskQueue *_taskQueue;
/** @var _authorizationCode
@brief An authorization code which needs to be exchanged for Secure Token Service tokens.
*/
NSString *_Nullable _authorizationCode;
/** @var _accessToken
@brief The currently cached access token. Or |nil| if no token is currently cached.
*/
NSString *_Nullable _accessToken;
}
- (instancetype)init {
self = [super init];
if (self) {
_taskQueue = [[FIRAuthSerialTaskQueue alloc] init];
}
return self;
}
- (instancetype)initWithRequestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration
authorizationCode:(NSString *)authorizationCode {
self = [self init];
if (self) {
_requestConfiguration = requestConfiguration;
_authorizationCode = [authorizationCode copy];
}
return self;
}
- (instancetype)initWithRequestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration
accessToken:(nullable NSString *)accessToken
accessTokenExpirationDate:(nullable NSDate *)accessTokenExpirationDate
refreshToken:(NSString *)refreshToken {
self = [self init];
if (self) {
_requestConfiguration = requestConfiguration;
_accessToken = [accessToken copy];
_accessTokenExpirationDate = [accessTokenExpirationDate copy];
_refreshToken = [refreshToken copy];
}
return self;
}
- (void)fetchAccessTokenForcingRefresh:(BOOL)forceRefresh
callback:(FIRFetchAccessTokenCallback)callback {
[_taskQueue enqueueTask:^(FIRAuthSerialTaskCompletionBlock complete) {
if (!forceRefresh && [self hasValidAccessToken]) {
complete();
callback(self->_accessToken, nil, NO);
} else {
[self requestAccessToken:^(NSString *_Nullable token,
NSError *_Nullable error,
BOOL tokenUpdated) {
complete();
callback(token, error, tokenUpdated);
}];
}
}];
}
- (NSString *)rawAccessToken {
return _accessToken;
}
#pragma mark - NSSecureCoding
+ (BOOL)supportsSecureCoding {
return YES;
}
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
NSString *refreshToken = [aDecoder decodeObjectOfClass:[NSString class] forKey:kRefreshTokenKey];
NSString *accessToken = [aDecoder decodeObjectOfClass:[NSString class] forKey:kAccessTokenKey];
NSDate *accessTokenExpirationDate =
[aDecoder decodeObjectOfClass:[NSDate class] forKey:kAccessTokenExpirationDateKey];
if (!refreshToken) {
return nil;
}
self = [self init];
if (self) {
_refreshToken = refreshToken;
_accessToken = accessToken;
_accessTokenExpirationDate = accessTokenExpirationDate;
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
// The API key is encoded even it is not used in decoding to be compatible with previous versions
// of the library.
[aCoder encodeObject:_requestConfiguration.APIKey forKey:kAPIKeyCodingKey];
// Authorization code is not encoded because it is not long-lived.
[aCoder encodeObject:_refreshToken forKey:kRefreshTokenKey];
[aCoder encodeObject:_accessToken forKey:kAccessTokenKey];
[aCoder encodeObject:_accessTokenExpirationDate forKey:kAccessTokenExpirationDateKey];
}
#pragma mark - Private methods
/** @fn requestAccessToken:
@brief Makes a request to STS for an access token.
@details This handles both the case that the token has not been granted yet and that it just
needs to be refreshed. The caller is responsible for making sure that this is occurring in
a @c _taskQueue task.
@param callback Called when the fetch is complete. Invoked asynchronously on the main thread in
the future.
@remarks Because this method is guaranteed to only be called from tasks enqueued in
@c _taskQueue, we do not need any @synchronized guards around access to _accessToken/etc.
since only one of those tasks is ever running at a time, and those tasks are the only
access to and mutation of these instance variables.
*/
- (void)requestAccessToken:(FIRFetchAccessTokenCallback)callback {
FIRSecureTokenRequest *request;
if (_refreshToken.length) {
request = [FIRSecureTokenRequest refreshRequestWithRefreshToken:_refreshToken
requestConfiguration:_requestConfiguration];
} else {
request = [FIRSecureTokenRequest authCodeRequestWithCode:_authorizationCode
requestConfiguration:_requestConfiguration];
}
[FIRAuthBackend secureToken:request
callback:^(FIRSecureTokenResponse *_Nullable response,
NSError *_Nullable error) {
BOOL tokenUpdated = NO;
NSString *newAccessToken = response.accessToken;
if (newAccessToken.length && ![newAccessToken isEqualToString:self->_accessToken]) {
self->_accessToken = [newAccessToken copy];
self->_accessTokenExpirationDate = response.approximateExpirationDate;
tokenUpdated = YES;
}
NSString *newRefreshToken = response.refreshToken;
if (newRefreshToken.length &&
![newRefreshToken isEqualToString:self->_refreshToken]) {
self->_refreshToken = [newRefreshToken copy];
tokenUpdated = YES;
}
callback(newAccessToken, error, tokenUpdated);
}];
}
- (BOOL)hasValidAccessToken {
return _accessToken && [_accessTokenExpirationDate timeIntervalSinceNow] > kFiveMinutes;
}
@end

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,61 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import "FIRUserInfo.h"
@class FIRGetAccountInfoResponseProviderUserInfo;
NS_ASSUME_NONNULL_BEGIN
@interface FIRUserInfoImpl : NSObject <FIRUserInfo, NSSecureCoding>
/** @fn userInfoWithGetAccountInfoResponseProviderUserInfo:
@brief A convenience factory method for constructing a @c FIRUserInfo instance from data
returned by the getAccountInfo endpoint.
@param providerUserInfo Data returned by the getAccountInfo endpoint.
@return A new instance of @c FIRUserInfo using data from the getAccountInfo endpoint.
*/
+ (nullable instancetype)userInfoWithGetAccountInfoResponseProviderUserInfo:
(FIRGetAccountInfoResponseProviderUserInfo *)providerUserInfo;
/** @fn init
@brief This class should not be initialized manually.
@see FIRUser.providerData
*/
- (instancetype)init NS_UNAVAILABLE;
/** @fn initWithProviderID:userID:displayName:photoURL:email:
@brief Designated initializer.
@param providerID The provider identifier.
@param userID The unique user ID for the user (the value of the @c uid field in the token.)
@param displayName The name of the user.
@param photoURL The URL of the user's profile photo.
@param email The user's email address.
@param phoneNumber The user's phone number.
*/
- (nullable instancetype)initWithProviderID:(NSString *)providerID
userID:(NSString *)userID
displayName:(nullable NSString *)displayName
photoURL:(nullable NSURL *)photoURL
email:(nullable NSString *)email
phoneNumber:(nullable NSString *)phoneNumber
NS_DESIGNATED_INITIALIZER;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,127 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRUserInfoImpl.h"
#import "FIRGetAccountInfoResponse.h"
/** @var kProviderIDCodingKey
@brief The key used to encode the providerID property for NSSecureCoding.
*/
static NSString *const kProviderIDCodingKey = @"providerID";
/** @var kUserIDCodingKey
@brief The key used to encode the userID property for NSSecureCoding.
*/
static NSString *const kUserIDCodingKey = @"userID";
/** @var kDisplayNameCodingKey
@brief The key used to encode the displayName property for NSSecureCoding.
*/
static NSString *const kDisplayNameCodingKey = @"displayName";
/** @var kProfileURLCodingKey
@brief The key used to encode the profileURL property for NSSecureCoding.
*/
static NSString *const kProfileURLCodingKey = @"profileURL";
/** @var kPhotoURLCodingKey
@brief The key used to encode the photoURL property for NSSecureCoding.
*/
static NSString *const kPhotoURLCodingKey = @"photoURL";
/** @var kEmailCodingKey
@brief The key used to encode the email property for NSSecureCoding.
*/
static NSString *const kEmailCodingKey = @"email";
/** @var kPhoneNumberCodingKey
@brief The key used to encode the phoneNumber property for NSSecureCoding.
*/
static NSString *const kPhoneNumberCodingKey = @"phoneNumber";
@implementation FIRUserInfoImpl
@synthesize providerID = _providerID;
@synthesize uid = _userID;
@synthesize displayName = _displayName;
@synthesize photoURL = _photoURL;
@synthesize email = _email;
@synthesize phoneNumber = _phoneNumber;
+ (nullable instancetype)userInfoWithGetAccountInfoResponseProviderUserInfo:
(FIRGetAccountInfoResponseProviderUserInfo *)providerUserInfo {
return [[self alloc] initWithProviderID:providerUserInfo.providerID
userID:providerUserInfo.federatedID
displayName:providerUserInfo.displayName
photoURL:providerUserInfo.photoURL
email:providerUserInfo.email
phoneNumber:providerUserInfo.phoneNumber];
}
- (nullable instancetype)initWithProviderID:(NSString *)providerID
userID:(NSString *)userID
displayName:(nullable NSString *)displayName
photoURL:(nullable NSURL *)photoURL
email:(nullable NSString *)email
phoneNumber:(nullable NSString *)phoneNumber {
self = [super init];
if (self) {
_providerID = [providerID copy];
_userID = [userID copy];
_displayName = [displayName copy];
_photoURL = [photoURL copy];
_email = [email copy];
_phoneNumber = [phoneNumber copy];
}
return self;
}
#pragma mark - NSSecureCoding
+ (BOOL)supportsSecureCoding {
return YES;
}
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
NSString *providerID =
[aDecoder decodeObjectOfClass:[NSString class] forKey:kProviderIDCodingKey];
NSString *userID = [aDecoder decodeObjectOfClass:[NSString class] forKey:kUserIDCodingKey];
NSString *displayName =
[aDecoder decodeObjectOfClass:[NSString class] forKey:kDisplayNameCodingKey];
NSURL *photoURL = [aDecoder decodeObjectOfClass:[NSURL class] forKey:kPhotoURLCodingKey];
NSString *email = [aDecoder decodeObjectOfClass:[NSString class] forKey:kEmailCodingKey];
NSString *phoneNumber =
[aDecoder decodeObjectOfClass:[NSString class] forKey:kPhoneNumberCodingKey];
return [self initWithProviderID:providerID
userID:userID
displayName:displayName
photoURL:photoURL
email:email
phoneNumber:phoneNumber];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_providerID forKey:kProviderIDCodingKey];
[aCoder encodeObject:_userID forKey:kUserIDCodingKey];
[aCoder encodeObject:_displayName forKey:kDisplayNameCodingKey];
[aCoder encodeObject:_photoURL forKey:kPhotoURLCodingKey];
[aCoder encodeObject:_email forKey:kEmailCodingKey];
[aCoder encodeObject:_phoneNumber forKey:kPhoneNumberCodingKey];
}
@end

View File

@@ -0,0 +1,64 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRUserMetadata_Internal.h"
NS_ASSUME_NONNULL_BEGIN
@implementation FIRUserMetadata
/** @var kCreationDateCodingKey
@brief The key used to encode the creationDate property for NSSecureCoding.
*/
static NSString *const kCreationDateCodingKey = @"creationDate";
/** @var kLastSignInDateCodingKey
@brief The key used to encode the lastSignInDate property for NSSecureCoding.
*/
static NSString *const kLastSignInDateCodingKey = @"lastSignInDate";
- (instancetype)initWithCreationDate:(nullable NSDate *)creationDate
lastSignInDate:(nullable NSDate *)lastSignInDate {
self = [super init];
if (self) {
_creationDate = [creationDate copy];
_lastSignInDate = [lastSignInDate copy];
}
return self;
}
#pragma mark - NSSecureCoding
+ (BOOL)supportsSecureCoding {
return YES;
}
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
NSDate *creationDate =
[aDecoder decodeObjectOfClass:[NSDate class] forKey:kCreationDateCodingKey];
NSDate *lastSignInDate =
[aDecoder decodeObjectOfClass:[NSDate class] forKey:kLastSignInDateCodingKey];
return [self initWithCreationDate:creationDate lastSignInDate:lastSignInDate];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_creationDate forKey:kCreationDateCodingKey];
[aCoder encodeObject:_lastSignInDate forKey:kLastSignInDateCodingKey];
}
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import "FIRUserMetadata.h"
NS_ASSUME_NONNULL_BEGIN
/** @extension FIRUserMetadata
@brief An internal class used to expose internal methods of FIRUserMetadata.
*/
@interface FIRUserMetadata () <NSSecureCoding>
/** @fn initWithCreationDate:lastSignInDate:
@brief Designated initializer.
@param creationDate The creation date of the corresponding user.
@param lastSignInDate The date of the last recorded sign-in of the corresponding user.
*/
- (instancetype)initWithCreationDate:(nullable NSDate *)creationDate
lastSignInDate:(nullable NSDate *)lastSignInDate NS_DESIGNATED_INITIALIZER;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,86 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRUser.h"
@class FIRAuth;
@class FIRAuthRequestConfiguration;
NS_ASSUME_NONNULL_BEGIN
/** @typedef FIRRetrieveUserCallback
@brief The type of block that is invoked when the construction of a user succeeds or fails.
@param user The user that was constructed, or nil if user construction failed.
@param error The error which occurred, or nil if the request was successful.
*/
typedef void(^FIRRetrieveUserCallback)(FIRUser *_Nullable user, NSError *_Nullable error);
@interface FIRUser () <NSSecureCoding>
/** @property rawAccessToken
@brief The cached access token.
@remarks This method is specifically for providing the access token to internal clients during
deserialization and sign-in events, and should not be used to retrieve the access token by
anyone else.
*/
@property(nonatomic, copy, readonly) NSString *rawAccessToken;
/** @property auth
@brief A weak reference to a FIRAuth instance associated with this instance.
*/
@property(nonatomic, weak) FIRAuth *auth;
/** @property auth
@brief A strong reference to a requestConfiguration instance associated with this user instance.
*/
@property(nonatomic, strong) FIRAuthRequestConfiguration *requestConfiguration;
/** @var accessTokenExpirationDate
@brief The expiration date of the cached access token.
*/
@property(nonatomic, copy, readonly) NSDate *accessTokenExpirationDate;
/** @fn retrieveUserWithAuth:accessToken:accessTokenExpirationDate:refreshToken:callback:
@brief Constructs a user with Secure Token Service tokens, and obtains user details from the
getAccountInfo endpoint.
@param auth The associated FIRAuth instance.
@param accessToken The Secure Token Service access token.
@param accessTokenExpirationDate The approximate expiration date of the access token.
@param refreshToken The Secure Token Service refresh token.
@param anonymous Whether or not the user is anonymous.
@param callback A block which is invoked when the construction succeeds or fails. Invoked
asynchronously on the auth global work queue in the future.
*/
+ (void)retrieveUserWithAuth:(FIRAuth *)auth
accessToken:(nullable NSString *)accessToken
accessTokenExpirationDate:(nullable NSDate *)accessTokenExpirationDate
refreshToken:(nullable NSString *)refreshToken
anonymous:(BOOL)anonymous
callback:(FIRRetrieveUserCallback)callback;
/** @fn internalGetTokenForcingRefresh:callback:
@brief Retrieves the Firebase authentication token, possibly refreshing it if it has expired.
@param forceRefresh Forces a token refresh. Useful if the token becomes invalid for some reason
other than an expiration.
@param callback The block to invoke when the token is available. Invoked asynchronously on the
global work thread in the future.
*/
- (void)internalGetTokenForcingRefresh:(BOOL)forceRefresh
callback:(nonnull FIRAuthTokenCallback)callback;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,26 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FirebaseAuthVersion.h"
// Convert the macro to a string
#define STR(x) STR_EXPAND(x)
#define STR_EXPAND(x) #x
const double FirebaseAuthVersionNum = FIRAuth_MINOR_VERSION;
const unsigned char *const FirebaseAuthVersionStr =
(const unsigned char *const)STR(FIRAuth_VERSION);

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2018 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSData (FIRBase64)
/** @fn fir_base64URLEncodedStringWithOptions:
@brief Get a web safe base64 encoded string
@param options The base64 encoding options
*/
- (NSString *)fir_base64URLEncodedStringWithOptions:(NSDataBase64EncodingOptions)options;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,29 @@
/*
* Copyright 2018 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "NSData+FIRBase64.h"
@implementation NSData (FIRBase64)
- (NSString *)fir_base64URLEncodedStringWithOptions:(NSDataBase64EncodingOptions)options {
NSString *string = [self base64EncodedStringWithOptions:options];
string = [string stringByReplacingOccurrencesOfString:@"/" withString:@"_"];
string = [string stringByReplacingOccurrencesOfString:@"+" withString:@"-"];
string = [string stringByReplacingOccurrencesOfString:@"=" withString:@""];
return string;
}
@end

View File

@@ -0,0 +1,89 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/** @class FIRActionCodeSettings
@brief Used to set and retrieve settings related to handling action codes.
*/
NS_SWIFT_NAME(ActionCodeSettings)
@interface FIRActionCodeSettings : NSObject
/** @property URL
@brief This URL represents the state/Continue URL in the form of a universal link.
@remarks This URL can should be contructed as a universal link that would either directly open
the app where the action code would be handled or continue to the app after the action code
is handled by Firebase.
*/
@property(nonatomic, copy, nullable) NSURL *URL;
/** @property handleCodeInApp
@brief Indicates whether the action code link will open the app directly or after being
redirected from a Firebase owned web widget.
*/
@property(assign, nonatomic) BOOL handleCodeInApp;
/** @property iOSBundleID
@brief The iOS bundle ID, if available. The default value is the current app's bundle ID.
*/
@property(copy, nonatomic, readonly, nullable) NSString *iOSBundleID;
/** @property androidPackageName
@brief The Android package name, if available.
*/
@property(nonatomic, copy, readonly, nullable) NSString *androidPackageName;
/** @property androidMinimumVersion
@brief The minimum Android version supported, if available.
*/
@property(nonatomic, copy, readonly, nullable) NSString *androidMinimumVersion;
/** @property androidInstallIfNotAvailable
@brief Indicates whether the Android app should be installed on a device where it is not
available.
*/
@property(nonatomic, assign, readonly) BOOL androidInstallIfNotAvailable;
/** @property dynamicLinkDomain
@brief The Firebase Dynamic Link domain used for out of band code flow.
*/
@property (copy, nonatomic, nullable) NSString *dynamicLinkDomain;
/** @fn setIOSBundleID
@brief Sets the iOS bundle Id.
@param iOSBundleID The iOS bundle ID.
*/
- (void)setIOSBundleID:(NSString *)iOSBundleID;
/** @fn setAndroidPackageName:installIfNotAvailable:minimumVersion:
@brief Sets the Android package name, the flag to indicate whether or not to install the app and
the minimum Android version supported.
@param androidPackageName The Android package name.
@param installIfNotAvailable Indicates whether or not the app should be installed if not
available.
@param minimumVersion The minimum version of Android supported.
@remarks If installIfNotAvailable is set to YES and the link is opened on an android device, it
will try to install the app if not already available. Otherwise the web URL is used.
*/
- (void)setAndroidPackageName:(NSString *)androidPackageName
installIfNotAvailable:(BOOL)installIfNotAvailable
minimumVersion:(nullable NSString *)minimumVersion;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,57 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
@class FIRVerifyAssertionResponse;
NS_ASSUME_NONNULL_BEGIN
/** @class FIRAdditionalUserInfo
@brief Represents additional user data returned from an identity provider.
*/
NS_SWIFT_NAME(AdditionalUserInfo)
@interface FIRAdditionalUserInfo : NSObject
/** @fn init
@brief This class should not be initialized manually. `FIRAdditionalUserInfo` can be retrieved
from from an instance of `FIRAuthDataResult`.
*/
- (instancetype)init NS_UNAVAILABLE;
/** @property providerID
@brief The provider identifier.
*/
@property(nonatomic, readonly) NSString *providerID;
/** @property profile
@brief Dictionary containing the additional IdP specific information.
*/
@property(nonatomic, readonly, nullable) NSDictionary<NSString *, NSObject *> *profile;
/** @property username
@brief username The name of the user.
*/
@property(nonatomic, readonly, nullable) NSString *username;
/** @property newUser
@brief Indicates whether or not the current user was signed in for the first time.
*/
@property(nonatomic, readonly, getter=isNewUser) BOOL newUser;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,864 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <AvailabilityMacros.h>
#import <Foundation/Foundation.h>
#import "FIRAuthErrors.h"
#if TARGET_OS_IOS
#import "FIRAuthAPNSTokenType.h"
#endif
@class FIRActionCodeSettings;
@class FIRApp;
@class FIRAuth;
@class FIRAuthCredential;
@class FIRAuthDataResult;
@class FIRAuthSettings;
@class FIRUser;
@protocol FIRAuthStateListener;
NS_ASSUME_NONNULL_BEGIN
/** @typedef FIRUserUpdateCallback
@brief The type of block invoked when a request to update the current user is completed.
*/
typedef void (^FIRUserUpdateCallback)(NSError *_Nullable error) NS_SWIFT_NAME(UserUpdateCallback);
/** @typedef FIRAuthStateDidChangeListenerHandle
@brief The type of handle returned by `FIRAuth.addAuthStateDidChangeListener:`.
*/
typedef id<NSObject> FIRAuthStateDidChangeListenerHandle
NS_SWIFT_NAME(AuthStateDidChangeListenerHandle);
/** @typedef FIRAuthStateDidChangeListenerBlock
@brief The type of block which can be registered as a listener for auth state did change events.
@param auth The FIRAuth object on which state changes occurred.
@param user Optionally; the current signed in user, if any.
*/
typedef void(^FIRAuthStateDidChangeListenerBlock)(FIRAuth *auth, FIRUser *_Nullable user)
NS_SWIFT_NAME(AuthStateDidChangeListenerBlock);
/** @typedef FIRIDTokenDidChangeListenerHandle
@brief The type of handle returned by `FIRAuth.addIDTokenDidChangeListener:`.
*/
typedef id<NSObject> FIRIDTokenDidChangeListenerHandle
NS_SWIFT_NAME(IDTokenDidChangeListenerHandle);
/** @typedef FIRIDTokenDidChangeListenerBlock
@brief The type of block which can be registered as a listener for ID token did change events.
@param auth The FIRAuth object on which ID token changes occurred.
@param user Optionally; the current signed in user, if any.
*/
typedef void(^FIRIDTokenDidChangeListenerBlock)(FIRAuth *auth, FIRUser *_Nullable user)
NS_SWIFT_NAME(IDTokenDidChangeListenerBlock);
/** @typedef FIRAuthDataResultCallback
@brief The type of block invoked when sign-in related events complete.
@param authResult Optionally; Result of sign-in request containing both the user and
the additional user info associated with the user.
@param error Optionally; the error which occurred - or nil if the request was successful.
*/
typedef void (^FIRAuthDataResultCallback)(FIRAuthDataResult *_Nullable authResult,
NSError *_Nullable error)
NS_SWIFT_NAME(AuthDataResultCallback);
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
/**
@brief The name of the `NSNotificationCenter` notification which is posted when the auth state
changes (for example, a new token has been produced, a user signs in or signs out). The
object parameter of the notification is the sender `FIRAuth` instance.
*/
extern const NSNotificationName FIRAuthStateDidChangeNotification
NS_SWIFT_NAME(AuthStateDidChange);
#else
/**
@brief The name of the `NSNotificationCenter` notification which is posted when the auth state
changes (for example, a new token has been produced, a user signs in or signs out). The
object parameter of the notification is the sender `FIRAuth` instance.
*/
extern NSString *const FIRAuthStateDidChangeNotification
NS_SWIFT_NAME(AuthStateDidChangeNotification);
#endif // defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
/** @typedef FIRAuthResultCallback
@brief The type of block invoked when sign-in related events complete.
@param user Optionally; the signed in user, if any.
@param error Optionally; if an error occurs, this is the NSError object that describes the
problem. Set to nil otherwise.
*/
typedef void (^FIRAuthResultCallback)(FIRUser *_Nullable user, NSError *_Nullable error)
NS_SWIFT_NAME(AuthResultCallback);
/** @typedef FIRProviderQueryCallback
@brief The type of block invoked when a list of identity providers for a given email address is
requested.
@param providers Optionally; a list of provider identifiers, if any.
@see FIRGoogleAuthProviderID etc.
@param error Optionally; if an error occurs, this is the NSError object that describes the
problem. Set to nil otherwise.
*/
typedef void (^FIRProviderQueryCallback)(NSArray<NSString *> *_Nullable providers,
NSError *_Nullable error)
NS_SWIFT_NAME(ProviderQueryCallback);
/** @typedef FIRSignInMethodQueryCallback
@brief The type of block invoked when a list of sign-in methods for a given email address is
requested.
*/
typedef void (^FIRSignInMethodQueryCallback)(NSArray<NSString *> *_Nullable,
NSError *_Nullable)
NS_SWIFT_NAME(SignInMethodQueryCallback);
/** @typedef FIRSendPasswordResetCallback
@brief The type of block invoked when sending a password reset email.
@param error Optionally; if an error occurs, this is the NSError object that describes the
problem. Set to nil otherwise.
*/
typedef void (^FIRSendPasswordResetCallback)(NSError *_Nullable error)
NS_SWIFT_NAME(SendPasswordResetCallback);
/** @typedef FIRSendSignInLinkToEmailCallback
@brief The type of block invoked when sending an email sign-in link email.
*/
typedef void (^FIRSendSignInLinkToEmailCallback)(NSError *_Nullable error)
NS_SWIFT_NAME(SendSignInLinkToEmailCallback);
/** @typedef FIRConfirmPasswordResetCallback
@brief The type of block invoked when performing a password reset.
@param error Optionally; if an error occurs, this is the NSError object that describes the
problem. Set to nil otherwise.
*/
typedef void (^FIRConfirmPasswordResetCallback)(NSError *_Nullable error)
NS_SWIFT_NAME(ConfirmPasswordResetCallback);
/** @typedef FIRVerifyPasswordResetCodeCallback
@brief The type of block invoked when verifying that an out of band code should be used to
perform password reset.
@param email Optionally; the email address of the user for which the out of band code applies.
@param error Optionally; if an error occurs, this is the NSError object that describes the
problem. Set to nil otherwise.
*/
typedef void (^FIRVerifyPasswordResetCodeCallback)(NSString *_Nullable email,
NSError *_Nullable error)
NS_SWIFT_NAME(VerifyPasswordResetCodeCallback);
/** @typedef FIRApplyActionCodeCallback
@brief The type of block invoked when applying an action code.
@param error Optionally; if an error occurs, this is the NSError object that describes the
problem. Set to nil otherwise.
*/
typedef void (^FIRApplyActionCodeCallback)(NSError *_Nullable error)
NS_SWIFT_NAME(ApplyActionCodeCallback);
/**
@brief Keys used to retrieve operation data from a `FIRActionCodeInfo` object by the
`dataForKey` method.
*/
typedef NS_ENUM(NSInteger, FIRActionDataKey) {
/**
* The email address to which the code was sent.
* For FIRActionCodeOperationRecoverEmail, the new email address for the account.
*/
FIRActionCodeEmailKey = 0,
/** For FIRActionCodeOperationRecoverEmail, the current email address for the account. */
FIRActionCodeFromEmailKey = 1
} NS_SWIFT_NAME(ActionDataKey);
/** @class FIRActionCodeInfo
@brief Manages information regarding action codes.
*/
NS_SWIFT_NAME(ActionCodeInfo)
@interface FIRActionCodeInfo : NSObject
/**
@brief Operations which can be performed with action codes.
*/
typedef NS_ENUM(NSInteger, FIRActionCodeOperation) {
/** Action code for unknown operation. */
FIRActionCodeOperationUnknown = 0,
/** Action code for password reset operation. */
FIRActionCodeOperationPasswordReset = 1,
/** Action code for verify email operation. */
FIRActionCodeOperationVerifyEmail = 2,
/** Action code for recover email operation. */
FIRActionCodeOperationRecoverEmail = 3,
/** Action code for email link operation. */
FIRActionCodeOperationEmailLink = 4,
} NS_SWIFT_NAME(ActionCodeOperation);
/**
@brief The operation being performed.
*/
@property(nonatomic, readonly) FIRActionCodeOperation operation;
/** @fn dataForKey:
@brief The operation being performed.
@param key The FIRActionDataKey value used to retrieve the operation data.
@return The operation data pertaining to the provided action code key.
*/
- (NSString *)dataForKey:(FIRActionDataKey)key;
/** @fn init
@brief please use initWithOperation: instead.
*/
- (instancetype)init NS_UNAVAILABLE;
@end
/** @typedef FIRCheckActionCodeCallBack
@brief The type of block invoked when performing a check action code operation.
@param info Metadata corresponding to the action code.
@param error Optionally; if an error occurs, this is the NSError object that describes the
problem. Set to nil otherwise.
*/
typedef void (^FIRCheckActionCodeCallBack)(FIRActionCodeInfo *_Nullable info,
NSError *_Nullable error)
NS_SWIFT_NAME(CheckActionCodeCallback);
/** @class FIRAuth
@brief Manages authentication for Firebase apps.
@remarks This class is thread-safe.
*/
NS_SWIFT_NAME(Auth)
@interface FIRAuth : NSObject
/** @fn auth
@brief Gets the auth object for the default Firebase app.
@remarks The default Firebase app must have already been configured or an exception will be
raised.
*/
+ (FIRAuth *)auth NS_SWIFT_NAME(auth());
/** @fn authWithApp:
@brief Gets the auth object for a `FIRApp`.
@param app The FIRApp for which to retrieve the associated FIRAuth instance.
@return The FIRAuth instance associated with the given FIRApp.
*/
+ (FIRAuth *)authWithApp:(FIRApp *)app NS_SWIFT_NAME(auth(app:));
/** @property app
@brief Gets the `FIRApp` object that this auth object is connected to.
*/
@property(nonatomic, weak, readonly, nullable) FIRApp *app;
/** @property currentUser
@brief Synchronously gets the cached current user, or null if there is none.
*/
@property(nonatomic, strong, readonly, nullable) FIRUser *currentUser;
/** @property languageCode
@brief The current user language code. This property can be set to the app's current language by
calling `useAppLanguage`.
@remarks The string used to set this property must be a language code that follows BCP 47.
*/
@property (nonatomic, copy, nullable) NSString *languageCode;
/** @property settings
@brief Contains settings related to the auth object.
*/
@property (nonatomic, copy, nullable) FIRAuthSettings *settings;
#if TARGET_OS_IOS
/** @property APNSToken
@brief The APNs token used for phone number authentication. The type of the token (production
or sandbox) will be attempted to be automatcially detected.
@remarks If swizzling is disabled, the APNs Token must be set for phone number auth to work,
by either setting this property or by calling `setAPNSToken:type:`
*/
@property(nonatomic, strong, nullable) NSData *APNSToken;
#endif
/** @fn init
@brief Please access auth instances using `FIRAuth.auth` and `FIRAuth.authForApp:`.
*/
- (instancetype)init NS_UNAVAILABLE;
/** @fn updateCurrentUser:completion:
@brief Sets the currentUser on the calling Auth instance to the provided user object.
@param user The user object to be set as the current user of the calling Auth instance.
@param completion Optionally; a block invoked after the user of the calling Auth instance has
been updated or an error was encountered.
*/
- (void)updateCurrentUser:(FIRUser *)user completion:(nullable FIRUserUpdateCallback)completion;
/** @fn fetchProvidersForEmail:completion:
@brief Fetches the list of IdPs that can be used for signing in with the provided email address.
Useful for an "identifier-first" sign-in flow.
@param email The email address for which to obtain a list of identity providers.
@param completion Optionally; a block which is invoked when the list of providers for the
specified email address is ready or an error was encountered. Invoked asynchronously on the
main thread in the future.
@remarks Possible error codes:
+ `FIRAuthErrorCodeInvalidEmail` - Indicates the email address is malformed.
@remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods.
*/
- (void)fetchProvidersForEmail:(NSString *)email
completion:(nullable FIRProviderQueryCallback)completion;
/** @fn fetchSignInMethodsForEmail:completion:
@brief Fetches the list of all sign-in methods previously used for the provided email address.
@param email The email address for which to obtain a list of sign-in methods.
@param completion Optionally; a block which is invoked when the list of sign in methods for the
specified email address is ready or an error was encountered. Invoked asynchronously on the
main thread in the future.
@remarks Possible error codes:
+ `FIRAuthErrorCodeInvalidEmail` - Indicates the email address is malformed.
@remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods.
*/
- (void)fetchSignInMethodsForEmail:(NSString *)email
completion:(nullable FIRSignInMethodQueryCallback)completion;
/** @fn signInWithEmail:password:completion:
@brief Signs in using an email address and password.
@param email The user's email address.
@param password The user's password.
@param completion Optionally; a block which is invoked when the sign in flow finishes, or is
canceled. Invoked asynchronously on the main thread in the future.
@remarks Possible error codes:
+ `FIRAuthErrorCodeOperationNotAllowed` - Indicates that email and password
accounts are not enabled. Enable them in the Auth section of the
Firebase console.
+ `FIRAuthErrorCodeUserDisabled` - Indicates the user's account is disabled.
+ `FIRAuthErrorCodeWrongPassword` - Indicates the user attempted
sign in with an incorrect password.
+ `FIRAuthErrorCodeInvalidEmail` - Indicates the email address is malformed.
@remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods.
*/
- (void)signInWithEmail:(NSString *)email
password:(NSString *)password
completion:(nullable FIRAuthDataResultCallback)completion;
/** @fn signInWithEmail:link:completion:
@brief Signs in using an email address and email sign-in link.
@param email The user's email address.
@param link The email sign-in link.
@param completion Optionally; a block which is invoked when the sign in flow finishes, or is
canceled. Invoked asynchronously on the main thread in the future.
@remarks Possible error codes:
+ `FIRAuthErrorCodeOperationNotAllowed` - Indicates that email and email sign-in link
accounts are not enabled. Enable them in the Auth section of the
Firebase console.
+ `FIRAuthErrorCodeUserDisabled` - Indicates the user's account is disabled.
+ `FIRAuthErrorCodeInvalidEmail` - Indicates the email address is invalid.
@remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods.
*/
- (void)signInWithEmail:(NSString *)email
link:(NSString *)link
completion:(nullable FIRAuthDataResultCallback)completion;
/** @fn signInAndRetrieveDataWithEmail:password:completion:
@brief Please use `signInWithEmail:password:completion:` for Objective-C or
`signIn(withEmail:password:completion:)` for Swift instead.
@param email The user's email address.
@param password The user's password.
@param completion Optionally; a block which is invoked when the sign in flow finishes, or is
canceled. Invoked asynchronously on the main thread in the future.
*/
- (void)signInAndRetrieveDataWithEmail:(NSString *)email
password:(NSString *)password
completion:(nullable FIRAuthDataResultCallback)completion
DEPRECATED_MSG_ATTRIBUTE(
"Please use signInWithEmail:password:completion: for"
" Objective-C or signIn(withEmail:password:completion:) for"
" Swift instead.");
/** @fn signInWithCredential:completion:
@brief Please use `signInAndRetrieveDataWithCredential:completion:` for Objective-C or
`signInAndRetrieveData(with:completion:)` for swift instead
@param credential The credential supplied by the IdP.
@param completion Optionally; a block which is invoked when the sign in flow finishes, or is
canceled. Invoked asynchronously on the main thread in the future.
@remarks Possible error codes:
+ `FIRAuthErrorCodeInvalidCredential` - Indicates the supplied credential is invalid.
This could happen if it has expired or it is malformed.
+ `FIRAuthErrorCodeOperationNotAllowed` - Indicates that accounts
with the identity provider represented by the credential are not enabled.
Enable them in the Auth section of the Firebase console.
+ `FIRAuthErrorCodeAccountExistsWithDifferentCredential` - Indicates the email asserted
by the credential (e.g. the email in a Facebook access token) is already in use by an
existing account, that cannot be authenticated with this sign-in method. Call
fetchProvidersForEmail for this users email and then prompt them to sign in with any of
the sign-in providers returned. This error will only be thrown if the "One account per
email address" setting is enabled in the Firebase console, under Auth settings.
+ `FIRAuthErrorCodeUserDisabled` - Indicates the user's account is disabled.
+ `FIRAuthErrorCodeWrongPassword` - Indicates the user attempted sign in with an
incorrect password, if credential is of the type EmailPasswordAuthCredential.
+ `FIRAuthErrorCodeInvalidEmail` - Indicates the email address is malformed.
+ `FIRAuthErrorCodeMissingVerificationID` - Indicates that the phone auth credential was
created with an empty verification ID.
+ `FIRAuthErrorCodeMissingVerificationCode` - Indicates that the phone auth credential
was created with an empty verification code.
+ `FIRAuthErrorCodeInvalidVerificationCode` - Indicates that the phone auth credential
was created with an invalid verification Code.
+ `FIRAuthErrorCodeInvalidVerificationID` - Indicates that the phone auth credential was
created with an invalid verification ID.
+ `FIRAuthErrorCodeSessionExpired` - Indicates that the SMS code has expired.
@remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods
*/
- (void)signInWithCredential:(FIRAuthCredential *)credential
completion:(nullable FIRAuthResultCallback)completion DEPRECATED_MSG_ATTRIBUTE(
"Please use signInAndRetrieveDataWithCredential:completion:"
" for Objective-C or signInAndRetrieveData(with:completion:)"
" for Swift instead.");
/** @fn signInAndRetrieveDataWithCredential:completion:
@brief Asynchronously signs in to Firebase with the given 3rd-party credentials (e.g. a Facebook
login Access Token, a Google ID Token/Access Token pair, etc.) and returns additional
identity provider data.
@param credential The credential supplied by the IdP.
@param completion Optionally; a block which is invoked when the sign in flow finishes, or is
canceled. Invoked asynchronously on the main thread in the future.
@remarks Possible error codes:
+ `FIRAuthErrorCodeInvalidCredential` - Indicates the supplied credential is invalid.
This could happen if it has expired or it is malformed.
+ `FIRAuthErrorCodeOperationNotAllowed` - Indicates that accounts
with the identity provider represented by the credential are not enabled.
Enable them in the Auth section of the Firebase console.
+ `FIRAuthErrorCodeAccountExistsWithDifferentCredential` - Indicates the email asserted
by the credential (e.g. the email in a Facebook access token) is already in use by an
existing account, that cannot be authenticated with this sign-in method. Call
fetchProvidersForEmail for this users email and then prompt them to sign in with any of
the sign-in providers returned. This error will only be thrown if the "One account per
email address" setting is enabled in the Firebase console, under Auth settings.
+ `FIRAuthErrorCodeUserDisabled` - Indicates the user's account is disabled.
+ `FIRAuthErrorCodeWrongPassword` - Indicates the user attempted sign in with an
incorrect password, if credential is of the type EmailPasswordAuthCredential.
+ `FIRAuthErrorCodeInvalidEmail` - Indicates the email address is malformed.
+ `FIRAuthErrorCodeMissingVerificationID` - Indicates that the phone auth credential was
created with an empty verification ID.
+ `FIRAuthErrorCodeMissingVerificationCode` - Indicates that the phone auth credential
was created with an empty verification code.
+ `FIRAuthErrorCodeInvalidVerificationCode` - Indicates that the phone auth credential
was created with an invalid verification Code.
+ `FIRAuthErrorCodeInvalidVerificationID` - Indicates that the phone auth credential was
created with an invalid verification ID.
+ `FIRAuthErrorCodeSessionExpired` - Indicates that the SMS code has expired.
@remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods
*/
- (void)signInAndRetrieveDataWithCredential:(FIRAuthCredential *)credential
completion:(nullable FIRAuthDataResultCallback)completion;
/** @fn signInAnonymouslyWithCompletion:
@brief Asynchronously creates and becomes an anonymous user.
@param completion Optionally; a block which is invoked when the sign in finishes, or is
canceled. Invoked asynchronously on the main thread in the future.
@remarks If there is already an anonymous user signed in, that user will be returned instead.
If there is any other existing user signed in, that user will be signed out.
@remarks Possible error codes:
+ `FIRAuthErrorCodeOperationNotAllowed` - Indicates that anonymous accounts are
not enabled. Enable them in the Auth section of the Firebase console.
@remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods.
*/
- (void)signInAnonymouslyWithCompletion:(nullable FIRAuthDataResultCallback)completion;
/** @fn signInAnonymouslyAndRetrieveDataWithCompletion:
@brief `Please use sign `signInAnonymouslyWithCompletion:` for Objective-C or
`signInAnonymously(Completion:)` for Swift instead.
@param completion Optionally; a block which is invoked when the sign in finishes, or is
canceled. Invoked asynchronously on the main thread in the future.
*/
- (void)signInAnonymouslyAndRetrieveDataWithCompletion:
(nullable FIRAuthDataResultCallback)completion
DEPRECATED_MSG_ATTRIBUTE("Please use signInAnonymouslyWithCompletion: for Objective-C or"
" signInAnonymously(Completion:) for swift instead.");
/** @fn signInWithCustomToken:completion:
@brief Asynchronously signs in to Firebase with the given Auth token.
@param token A self-signed custom auth token.
@param completion Optionally; a block which is invoked when the sign in finishes, or is
canceled. Invoked asynchronously on the main thread in the future.
@remarks Possible error codes:
+ `FIRAuthErrorCodeInvalidCustomToken` - Indicates a validation error with
the custom token.
+ `FIRAuthErrorCodeCustomTokenMismatch` - Indicates the service account and the API key
belong to different projects.
@remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods.
*/
- (void)signInWithCustomToken:(NSString *)token
completion:(nullable FIRAuthDataResultCallback)completion;
/** @fn signInAndRetrieveDataWithCustomToken:completion:
@brief Please use `signInWithCustomToken:completion:` or `signIn(withCustomToken:completion:)`
for Swift instead.
@param token A self-signed custom auth token.
@param completion Optionally; a block which is invoked when the sign in finishes, or is
canceled. Invoked asynchronously on the main thread in the future.
*/
- (void)signInAndRetrieveDataWithCustomToken:(NSString *)token
completion:(nullable FIRAuthDataResultCallback)completion
DEPRECATED_MSG_ATTRIBUTE(
"Please use signInWithCustomToken:completion:"
"for Objective-C or signIn(withCustomToken:completion:) for"
" Swift instead.");
/** @fn createUserWithEmail:password:completion:
@brief Creates and, on success, signs in a user with the given email address and password.
@param email The user's email address.
@param password The user's desired password.
@param completion Optionally; a block which is invoked when the sign up flow finishes, or is
canceled. Invoked asynchronously on the main thread in the future.
@remarks Possible error codes:
+ `FIRAuthErrorCodeInvalidEmail` - Indicates the email address is malformed.
+ `FIRAuthErrorCodeEmailAlreadyInUse` - Indicates the email used to attempt sign up
already exists. Call fetchProvidersForEmail to check which sign-in mechanisms the user
used, and prompt the user to sign in with one of those.
+ `FIRAuthErrorCodeOperationNotAllowed` - Indicates that email and password accounts
are not enabled. Enable them in the Auth section of the Firebase console.
+ `FIRAuthErrorCodeWeakPassword` - Indicates an attempt to set a password that is
considered too weak. The NSLocalizedFailureReasonErrorKey field in the NSError.userInfo
dictionary object will contain more detailed explanation that can be shown to the user.
@remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods.
*/
- (void)createUserWithEmail:(NSString *)email
password:(NSString *)password
completion:(nullable FIRAuthDataResultCallback)completion;
/** @fn createUserAndRetrieveDataWithEmail:password:completion:
@brief Please use `createUserAndRetrieveDataWithEmail:password:completion:` or
`createUser(withEmail:password:completion:)` for Swift instead.
@param email The user's email address.
@param password The user's desired password.
@param completion Optionally; a block which is invoked when the sign up flow finishes, or is
canceled. Invoked asynchronously on the main thread in the future.
*/
- (void)createUserAndRetrieveDataWithEmail:(NSString *)email
password:(NSString *)password
completion:(nullable FIRAuthDataResultCallback)completion
DEPRECATED_MSG_ATTRIBUTE(
"Please use createUserWithEmail:password:completion: for"
" Objective-C or createUser(withEmail:password:completion:)"
" for Swift instead.");
/** @fn confirmPasswordResetWithCode:newPassword:completion:
@brief Resets the password given a code sent to the user outside of the app and a new password
for the user.
@param newPassword The new password.
@param completion Optionally; a block which is invoked when the request finishes. Invoked
asynchronously on the main thread in the future.
@remarks Possible error codes:
+ `FIRAuthErrorCodeWeakPassword` - Indicates an attempt to set a password that is
considered too weak.
+ `FIRAuthErrorCodeOperationNotAllowed` - Indicates the administrator disabled sign
in with the specified identity provider.
+ `FIRAuthErrorCodeExpiredActionCode` - Indicates the OOB code is expired.
+ `FIRAuthErrorCodeInvalidActionCode` - Indicates the OOB code is invalid.
@remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods.
*/
- (void)confirmPasswordResetWithCode:(NSString *)code
newPassword:(NSString *)newPassword
completion:(FIRConfirmPasswordResetCallback)completion;
/** @fn checkActionCode:completion:
@brief Checks the validity of an out of band code.
@param code The out of band code to check validity.
@param completion Optionally; a block which is invoked when the request finishes. Invoked
asynchronously on the main thread in the future.
*/
- (void)checkActionCode:(NSString *)code completion:(FIRCheckActionCodeCallBack)completion;
/** @fn verifyPasswordResetCode:completion:
@brief Checks the validity of a verify password reset code.
@param code The password reset code to be verified.
@param completion Optionally; a block which is invoked when the request finishes. Invoked
asynchronously on the main thread in the future.
*/
- (void)verifyPasswordResetCode:(NSString *)code
completion:(FIRVerifyPasswordResetCodeCallback)completion;
/** @fn applyActionCode:completion:
@brief Applies out of band code.
@param code The out of band code to be applied.
@param completion Optionally; a block which is invoked when the request finishes. Invoked
asynchronously on the main thread in the future.
@remarks This method will not work for out of band codes which require an additional parameter,
such as password reset code.
*/
- (void)applyActionCode:(NSString *)code
completion:(FIRApplyActionCodeCallback)completion;
/** @fn sendPasswordResetWithEmail:completion:
@brief Initiates a password reset for the given email address.
@param email The email address of the user.
@param completion Optionally; a block which is invoked when the request finishes. Invoked
asynchronously on the main thread in the future.
@remarks Possible error codes:
+ `FIRAuthErrorCodeInvalidRecipientEmail` - Indicates an invalid recipient email was
sent in the request.
+ `FIRAuthErrorCodeInvalidSender` - Indicates an invalid sender email is set in
the console for this action.
+ `FIRAuthErrorCodeInvalidMessagePayload` - Indicates an invalid email template for
sending update email.
*/
- (void)sendPasswordResetWithEmail:(NSString *)email
completion:(nullable FIRSendPasswordResetCallback)completion;
/** @fn sendPasswordResetWithEmail:actionCodeSetting:completion:
@brief Initiates a password reset for the given email address and @FIRActionCodeSettings object.
@param email The email address of the user.
@param actionCodeSettings An `FIRActionCodeSettings` object containing settings related to
handling action codes.
@param completion Optionally; a block which is invoked when the request finishes. Invoked
asynchronously on the main thread in the future.
@remarks Possible error codes:
+ `FIRAuthErrorCodeInvalidRecipientEmail` - Indicates an invalid recipient email was
sent in the request.
+ `FIRAuthErrorCodeInvalidSender` - Indicates an invalid sender email is set in
the console for this action.
+ `FIRAuthErrorCodeInvalidMessagePayload` - Indicates an invalid email template for
sending update email.
+ `FIRAuthErrorCodeMissingIosBundleID` - Indicates that the iOS bundle ID is missing when
`handleCodeInApp` is set to YES.
+ `FIRAuthErrorCodeMissingAndroidPackageName` - Indicates that the android package name
is missing when the `androidInstallApp` flag is set to true.
+ `FIRAuthErrorCodeUnauthorizedDomain` - Indicates that the domain specified in the
continue URL is not whitelisted in the Firebase console.
+ `FIRAuthErrorCodeInvalidContinueURI` - Indicates that the domain specified in the
continue URI is not valid.
*/
- (void)sendPasswordResetWithEmail:(NSString *)email
actionCodeSettings:(FIRActionCodeSettings *)actionCodeSettings
completion:(nullable FIRSendPasswordResetCallback)completion;
/** @fn sendSignInLinkToEmail:actionCodeSettings:completion:
@brief Sends a sign in with email link to provided email address.
@param email The email address of the user.
@param actionCodeSettings An `FIRActionCodeSettings` object containing settings related to
handling action codes.
@param completion Optionally; a block which is invoked when the request finishes. Invoked
asynchronously on the main thread in the future.
*/
- (void)sendSignInLinkToEmail:(NSString *)email
actionCodeSettings:(FIRActionCodeSettings *)actionCodeSettings
completion:(nullable FIRSendSignInLinkToEmailCallback)completion;
/** @fn signOut:
@brief Signs out the current user.
@param error Optionally; if an error occurs, upon return contains an NSError object that
describes the problem; is nil otherwise.
@return @YES when the sign out request was successful. @NO otherwise.
@remarks Possible error codes:
+ `FIRAuthErrorCodeKeychainError` - Indicates an error occurred when accessing the
keychain. The `NSLocalizedFailureReasonErrorKey` field in the `NSError.userInfo`
dictionary will contain more information about the error encountered.
*/
- (BOOL)signOut:(NSError *_Nullable *_Nullable)error;
/** @fn isSignInWithEmailLink
@brief Checks if link is an email sign-in link.
@param link The email sign-in link.
@return @YES when the link passed matches the expected format of an email sign-in link.
*/
- (BOOL)isSignInWithEmailLink:(NSString *)link;
/** @fn addAuthStateDidChangeListener:
@brief Registers a block as an "auth state did change" listener. To be invoked when:
+ The block is registered as a listener,
+ A user with a different UID from the current user has signed in, or
+ The current user has signed out.
@param listener The block to be invoked. The block is always invoked asynchronously on the main
thread, even for it's initial invocation after having been added as a listener.
@remarks The block is invoked immediately after adding it according to it's standard invocation
semantics, asynchronously on the main thread. Users should pay special attention to
making sure the block does not inadvertently retain objects which should not be retained by
the long-lived block. The block itself will be retained by `FIRAuth` until it is
unregistered or until the `FIRAuth` instance is otherwise deallocated.
@return A handle useful for manually unregistering the block as a listener.
*/
- (FIRAuthStateDidChangeListenerHandle)addAuthStateDidChangeListener:
(FIRAuthStateDidChangeListenerBlock)listener;
/** @fn removeAuthStateDidChangeListener:
@brief Unregisters a block as an "auth state did change" listener.
@param listenerHandle The handle for the listener.
*/
- (void)removeAuthStateDidChangeListener:(FIRAuthStateDidChangeListenerHandle)listenerHandle;
/** @fn addIDTokenDidChangeListener:
@brief Registers a block as an "ID token did change" listener. To be invoked when:
+ The block is registered as a listener,
+ A user with a different UID from the current user has signed in,
+ The ID token of the current user has been refreshed, or
+ The current user has signed out.
@param listener The block to be invoked. The block is always invoked asynchronously on the main
thread, even for it's initial invocation after having been added as a listener.
@remarks The block is invoked immediately after adding it according to it's standard invocation
semantics, asynchronously on the main thread. Users should pay special attention to
making sure the block does not inadvertently retain objects which should not be retained by
the long-lived block. The block itself will be retained by `FIRAuth` until it is
unregistered or until the `FIRAuth` instance is otherwise deallocated.
@return A handle useful for manually unregistering the block as a listener.
*/
- (FIRIDTokenDidChangeListenerHandle)addIDTokenDidChangeListener:
(FIRIDTokenDidChangeListenerBlock)listener;
/** @fn removeIDTokenDidChangeListener:
@brief Unregisters a block as an "ID token did change" listener.
@param listenerHandle The handle for the listener.
*/
- (void)removeIDTokenDidChangeListener:(FIRIDTokenDidChangeListenerHandle)listenerHandle;
/** @fn useAppLanguage
@brief Sets `languageCode` to the app's current language.
*/
- (void)useAppLanguage;
#if TARGET_OS_IOS
/** @fn canHandleURL:
@brief Whether the specific URL is handled by `FIRAuth` .
@param URL The URL received by the application delegate from any of the openURL method.
@return Whether or the URL is handled. YES means the URL is for Firebase Auth
so the caller should ignore the URL from further processing, and NO means the
the URL is for the app (or another libaray) so the caller should continue handling
this URL as usual.
@remarks If swizzling is disabled, URLs received by the application delegate must be forwarded
to this method for phone number auth to work.
*/
- (BOOL)canHandleURL:(nonnull NSURL *)URL;
/** @fn setAPNSToken:type:
@brief Sets the APNs token along with its type.
@remarks If swizzling is disabled, the APNs Token must be set for phone number auth to work,
by either setting calling this method or by setting the `APNSToken` property.
*/
- (void)setAPNSToken:(NSData *)token type:(FIRAuthAPNSTokenType)type;
/** @fn canHandleNotification:
@brief Whether the specific remote notification is handled by `FIRAuth` .
@param userInfo A dictionary that contains information related to the
notification in question.
@return Whether or the notification is handled. YES means the notification is for Firebase Auth
so the caller should ignore the notification from further processing, and NO means the
the notification is for the app (or another libaray) so the caller should continue handling
this notification as usual.
@remarks If swizzling is disabled, related remote notifications must be forwarded to this method
for phone number auth to work.
*/
- (BOOL)canHandleNotification:(NSDictionary *)userInfo;
#endif // TARGET_OS_IOS
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,40 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
* @brief The APNs token type for the app.
*/
typedef NS_ENUM(NSInteger, FIRAuthAPNSTokenType) {
/** Unknown token type.
The actual token type will be detected from the provisioning profile in the app's bundle.
*/
FIRAuthAPNSTokenTypeUnknown,
/** Sandbox token type.
*/
FIRAuthAPNSTokenTypeSandbox,
/** Production token type.
*/
FIRAuthAPNSTokenTypeProd,
} NS_SWIFT_NAME(AuthAPNSTokenType);
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/** @class FIRAuthCredential
@brief Represents a credential.
*/
NS_SWIFT_NAME(AuthCredential)
@interface FIRAuthCredential : NSObject
/** @property provider
@brief Gets the name of the identity provider for the credential.
*/
@property(nonatomic, copy, readonly) NSString *provider;
/** @fn init
@brief This is an abstract base class. Concrete instances should be created via factory
methods available in the various authentication provider libraries (like the Facebook
provider or the Google provider libraries.)
*/
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
@class FIRAdditionalUserInfo;
@class FIRUser;
NS_ASSUME_NONNULL_BEGIN
/** @class FIRAuthDataResult
@brief Helper object that contains the result of a successful sign-in, link and reauthenticate
action. It contains references to a FIRUser instance and a FIRAdditionalUserInfo instance.
*/
NS_SWIFT_NAME(AuthDataResult)
@interface FIRAuthDataResult : NSObject
/** @fn init
@brief This class should not be initialized manually. `FIRAuthDataResult` instance is
returned as part of `FIRAuthDataResultCallback`.
*/
- (instancetype)init NS_UNAVAILABLE;
/** @property user
@brief The signed in user.
*/
@property(nonatomic, readonly) FIRUser *user;
/** @property additionalUserInfo
@brief If available contains the additional IdP specific information about signed in user.
*/
@property(nonatomic, readonly, nullable) FIRAdditionalUserInfo *additionalUserInfo;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,330 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
/** @class FIRAuthErrors
@remarks Error Codes common to all API Methods:
+ `FIRAuthErrorCodeNetworkError`
+ `FIRAuthErrorCodeUserNotFound`
+ `FIRAuthErrorCodeUserTokenExpired`
+ `FIRAuthErrorCodeTooManyRequests`
+ `FIRAuthErrorCodeInvalidAPIKey`
+ `FIRAuthErrorCodeAppNotAuthorized`
+ `FIRAuthErrorCodeKeychainError`
+ `FIRAuthErrorCodeInternalError`
@remarks Common error codes for `FIRUser` operations:
+ `FIRAuthErrorCodeInvalidUserToken`
+ `FIRAuthErrorCodeUserDisabled`
*/
NS_SWIFT_NAME(AuthErrors)
@interface FIRAuthErrors
/**
@brief The Firebase Auth error domain.
*/
extern NSString *const FIRAuthErrorDomain NS_SWIFT_NAME(AuthErrorDomain);
/**
@brief The key used to read the updated credential from the userinfo dictionary of the NSError
object returned in the case that the credential being linked in already in use.
*/
extern NSString *const FIRAuthUpdatedCredentialKey NS_SWIFT_NAME(AuthUpdatedCredentialKey);
/**
@brief The name of the key for the "error_name" string in the NSError userinfo dictionary.
*/
extern NSString *const FIRAuthErrorNameKey NS_SWIFT_NAME(AuthErrorNameKey);
/**
@brief Errors with the code `FIRAuthErrorCodeAccountExistsWithDifferentCredential` may contain
an `NSError.userInfo` dictinary object which contains this key. The value associated with
this key is an NSString of the email address of the account that already exists.
*/
extern NSString *const FIRAuthErrorUserInfoEmailKey NS_SWIFT_NAME(AuthErrorUserInfoEmailKey);
/**
@brief Error codes used by Firebase Auth.
*/
typedef NS_ENUM(NSInteger, FIRAuthErrorCode) {
/** Indicates a validation error with the custom token.
*/
FIRAuthErrorCodeInvalidCustomToken = 17000,
/** Indicates the service account and the API key belong to different projects.
*/
FIRAuthErrorCodeCustomTokenMismatch = 17002,
/** Indicates the IDP token or requestUri is invalid.
*/
FIRAuthErrorCodeInvalidCredential = 17004,
/** Indicates the user's account is disabled on the server.
*/
FIRAuthErrorCodeUserDisabled = 17005,
/** Indicates the administrator disabled sign in with the specified identity provider.
*/
FIRAuthErrorCodeOperationNotAllowed = 17006,
/** Indicates the email used to attempt a sign up is already in use.
*/
FIRAuthErrorCodeEmailAlreadyInUse = 17007,
/** Indicates the email is invalid.
*/
FIRAuthErrorCodeInvalidEmail = 17008,
/** Indicates the user attempted sign in with a wrong password.
*/
FIRAuthErrorCodeWrongPassword = 17009,
/** Indicates that too many requests were made to a server method.
*/
FIRAuthErrorCodeTooManyRequests = 17010,
/** Indicates the user account was not found.
*/
FIRAuthErrorCodeUserNotFound = 17011,
/** Indicates account linking is required.
*/
FIRAuthErrorCodeAccountExistsWithDifferentCredential = 17012,
/** Indicates the user has attemped to change email or password more than 5 minutes after
signing in.
*/
FIRAuthErrorCodeRequiresRecentLogin = 17014,
/** Indicates an attempt to link a provider to which the account is already linked.
*/
FIRAuthErrorCodeProviderAlreadyLinked = 17015,
/** Indicates an attempt to unlink a provider that is not linked.
*/
FIRAuthErrorCodeNoSuchProvider = 17016,
/** Indicates user's saved auth credential is invalid, the user needs to sign in again.
*/
FIRAuthErrorCodeInvalidUserToken = 17017,
/** Indicates a network error occurred (such as a timeout, interrupted connection, or
unreachable host). These types of errors are often recoverable with a retry. The
`NSUnderlyingError` field in the `NSError.userInfo` dictionary will contain the error
encountered.
*/
FIRAuthErrorCodeNetworkError = 17020,
/** Indicates the saved token has expired, for example, the user may have changed account
password on another device. The user needs to sign in again on the device that made this
request.
*/
FIRAuthErrorCodeUserTokenExpired = 17021,
/** Indicates an invalid API key was supplied in the request.
*/
FIRAuthErrorCodeInvalidAPIKey = 17023,
/** Indicates that an attempt was made to reauthenticate with a user which is not the current
user.
*/
FIRAuthErrorCodeUserMismatch = 17024,
/** Indicates an attempt to link with a credential that has already been linked with a
different Firebase account
*/
FIRAuthErrorCodeCredentialAlreadyInUse = 17025,
/** Indicates an attempt to set a password that is considered too weak.
*/
FIRAuthErrorCodeWeakPassword = 17026,
/** Indicates the App is not authorized to use Firebase Authentication with the
provided API Key.
*/
FIRAuthErrorCodeAppNotAuthorized = 17028,
/** Indicates the OOB code is expired.
*/
FIRAuthErrorCodeExpiredActionCode = 17029,
/** Indicates the OOB code is invalid.
*/
FIRAuthErrorCodeInvalidActionCode = 17030,
/** Indicates that there are invalid parameters in the payload during a "send password reset
* email" attempt.
*/
FIRAuthErrorCodeInvalidMessagePayload = 17031,
/** Indicates that the sender email is invalid during a "send password reset email" attempt.
*/
FIRAuthErrorCodeInvalidSender = 17032,
/** Indicates that the recipient email is invalid.
*/
FIRAuthErrorCodeInvalidRecipientEmail = 17033,
/** Indicates that an email address was expected but one was not provided.
*/
FIRAuthErrorCodeMissingEmail = 17034,
// The enum values 17035 is reserved and should NOT be used for new error codes.
/** Indicates that the iOS bundle ID is missing when a iOS App Store ID is provided.
*/
FIRAuthErrorCodeMissingIosBundleID = 17036,
/** Indicates that the android package name is missing when the `androidInstallApp` flag is set
to true.
*/
FIRAuthErrorCodeMissingAndroidPackageName = 17037,
/** Indicates that the domain specified in the continue URL is not whitelisted in the Firebase
console.
*/
FIRAuthErrorCodeUnauthorizedDomain = 17038,
/** Indicates that the domain specified in the continue URI is not valid.
*/
FIRAuthErrorCodeInvalidContinueURI = 17039,
/** Indicates that a continue URI was not provided in a request to the backend which requires
one.
*/
FIRAuthErrorCodeMissingContinueURI = 17040,
/** Indicates that a phone number was not provided in a call to
`verifyPhoneNumber:completion:`.
*/
FIRAuthErrorCodeMissingPhoneNumber = 17041,
/** Indicates that an invalid phone number was provided in a call to
`verifyPhoneNumber:completion:`.
*/
FIRAuthErrorCodeInvalidPhoneNumber = 17042,
/** Indicates that the phone auth credential was created with an empty verification code.
*/
FIRAuthErrorCodeMissingVerificationCode = 17043,
/** Indicates that an invalid verification code was used in the verifyPhoneNumber request.
*/
FIRAuthErrorCodeInvalidVerificationCode = 17044,
/** Indicates that the phone auth credential was created with an empty verification ID.
*/
FIRAuthErrorCodeMissingVerificationID = 17045,
/** Indicates that an invalid verification ID was used in the verifyPhoneNumber request.
*/
FIRAuthErrorCodeInvalidVerificationID = 17046,
/** Indicates that the APNS device token is missing in the verifyClient request.
*/
FIRAuthErrorCodeMissingAppCredential = 17047,
/** Indicates that an invalid APNS device token was used in the verifyClient request.
*/
FIRAuthErrorCodeInvalidAppCredential = 17048,
// The enum values between 17048 and 17051 are reserved and should NOT be used for new error
// codes.
/** Indicates that the SMS code has expired.
*/
FIRAuthErrorCodeSessionExpired = 17051,
/** Indicates that the quota of SMS messages for a given project has been exceeded.
*/
FIRAuthErrorCodeQuotaExceeded = 17052,
/** Indicates that the APNs device token could not be obtained. The app may not have set up
remote notification correctly, or may fail to forward the APNs device token to FIRAuth
if app delegate swizzling is disabled.
*/
FIRAuthErrorCodeMissingAppToken = 17053,
/** Indicates that the app fails to forward remote notification to FIRAuth.
*/
FIRAuthErrorCodeNotificationNotForwarded = 17054,
/** Indicates that the app could not be verified by Firebase during phone number authentication.
*/
FIRAuthErrorCodeAppNotVerified = 17055,
/** Indicates that the reCAPTCHA token is not valid.
*/
FIRAuthErrorCodeCaptchaCheckFailed = 17056,
/** Indicates that an attempt was made to present a new web context while one was already being
presented.
*/
FIRAuthErrorCodeWebContextAlreadyPresented = 17057,
/** Indicates that the URL presentation was cancelled prematurely by the user.
*/
FIRAuthErrorCodeWebContextCancelled = 17058,
/** Indicates a general failure during the app verification flow.
*/
FIRAuthErrorCodeAppVerificationUserInteractionFailure = 17059,
/** Indicates that the clientID used to invoke a web flow is invalid.
*/
FIRAuthErrorCodeInvalidClientID = 17060,
/** Indicates that a network request within a SFSafariViewController or UIWebview failed.
*/
FIRAuthErrorCodeWebNetworkRequestFailed = 17061,
/** Indicates that an internal error occurred within a SFSafariViewController or UIWebview.
*/
FIRAuthErrorCodeWebInternalError = 17062,
/** Indicates that the local player was not authenticated prior to attempting Game Center signin.
*/
FIRAuthErrorCodeLocalPlayerNotAuthenticated = 17066,
/** Indicates that a non-null user was expected as an argmument to the operation but a null
user was provided.
*/
FIRAuthErrorCodeNullUser = 17067,
/** Indicates that the Firebase Dynamic Link domain used is either not configured or is unauthorized
for the current project.
*/
FIRAuthErrorCodeInvalidDynamicLinkDomain = 17074,
/** Indicates an error occurred while attempting to access the keychain.
*/
FIRAuthErrorCodeKeychainError = 17995,
/** Indicates an internal error occurred.
*/
FIRAuthErrorCodeInternalError = 17999,
/** Raised when a JWT fails to parse correctly. May be accompanied by an underlying error
describing which step of the JWT parsing process failed.
*/
FIRAuthErrorCodeMalformedJWT = 18000,
} NS_SWIFT_NAME(AuthErrorCode);
@end

View File

@@ -0,0 +1,30 @@
/*
* Copyright 2018 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
/** @class FIRAuthSettings
@brief Determines settings related to an auth object.
*/
@interface FIRAuthSettings : NSObject
/** @property appVerificationDisabledForTesting
@brief Flag to determine whether app verification should be disabled for testing or not.
*/
@property (nonatomic, assign, getter=isAppVerificationDisabledForTesting) BOOL
appVerificationDisabledForTesting;
@end

View File

@@ -0,0 +1,66 @@
/*
* Copyright 2018 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/** @class FIRAuthTokenResult
@brief A data class containing the ID token JWT string and other properties associated with the
token including the decoded payload claims.
*/
NS_SWIFT_NAME(AuthTokenResult)
@interface FIRAuthTokenResult : NSObject
/** @property token
@brief Stores the JWT string of the ID token.
*/
@property (nonatomic, readonly) NSString *token;
/** @property expirationDate
@brief Stores the ID token's expiration date.
*/
@property (nonatomic, readonly) NSDate *expirationDate;
/** @property authDate
@brief Stores the ID token's authentication date.
@remarks This is the date the user was signed in and NOT the date the token was refreshed.
*/
@property (nonatomic, readonly) NSDate *authDate;
/** @property issuedAtDate
@brief Stores the date that the ID token was issued.
@remarks This is the date last refreshed and NOT the last authentication date.
*/
@property (nonatomic, readonly) NSDate *issuedAtDate;
/** @property signInProvider
@brief Stores sign-in provider through which the token was obtained.
@remarks This does not necesssarily map to provider IDs.
*/
@property (nonatomic, readonly) NSString *signInProvider;
/** @property claims
@brief Stores the entire payload of claims found on the ID token. This includes the standard
reserved claims as well as custom claims set by the developer via the Admin SDK.
*/
@property (nonatomic, readonly) NSDictionary<NSString *, id> *claims;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
/** @protocol FIRAuthUIDelegate
@brief A protocol to handle user interface interactions for Firebase Auth.
*/
NS_SWIFT_NAME(AuthUIDelegate)
@protocol FIRAuthUIDelegate <NSObject>
/** @fn presentViewController:animated:completion:
@brief If implemented, this method will be invoked when Firebase Auth needs to display a view
controller.
@param viewControllerToPresent The view controller to be presented.
@param flag Decides whether the view controller presentation should be animated or not.
@param completion The block to execute after the presentation finishes. This block has no return
value and takes no parameters.
*/
- (void)presentViewController:(UIViewController *)viewControllerToPresent
animated:(BOOL)flag
completion:(void (^ _Nullable)(void))completion;
/** @fn dismissViewControllerAnimated:completion:
@brief If implemented, this method will be invoked when Firebase Auth needs to display a view
controller.
@param flag Decides whether removing the view controller should be animated or not.
@param completion The block to execute after the presentation finishes. This block has no return
value and takes no parameters.
*/
- (void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^ _Nullable)(void))completion
NS_SWIFT_NAME(dismiss(animated:completion:));
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,81 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
@class FIRAuthCredential;
NS_ASSUME_NONNULL_BEGIN
/**
@brief A string constant identifying the email & password identity provider.
*/
extern NSString *const FIREmailAuthProviderID NS_SWIFT_NAME(EmailAuthProviderID);
/**
@brief A string constant identifying the email-link sign-in method.
*/
extern NSString *const FIREmailLinkAuthSignInMethod NS_SWIFT_NAME(EmailLinkAuthSignInMethod);
/**
@brief A string constant identifying the email & password sign-in method.
*/
extern NSString *const FIREmailPasswordAuthSignInMethod
NS_SWIFT_NAME(EmailPasswordAuthSignInMethod);
/**
@brief Please use `FIREmailAuthProviderID` for Objective-C or `EmailAuthProviderID` for Swift instead.
*/
extern NSString *const FIREmailPasswordAuthProviderID __attribute__((deprecated));
/** @class FIREmailAuthProvider
@brief A concrete implementation of `FIRAuthProvider` for Email & Password Sign In.
*/
NS_SWIFT_NAME(EmailAuthProvider)
@interface FIREmailAuthProvider : NSObject
/** @typedef FIREmailPasswordAuthProvider
@brief Please use `FIREmailAuthProvider` instead.
*/
typedef FIREmailAuthProvider FIREmailPasswordAuthProvider __attribute__((deprecated));
/** @fn credentialWithEmail:password:
@brief Creates an `FIRAuthCredential` for an email & password sign in.
@param email The user's email address.
@param password The user's password.
@return A FIRAuthCredential containing the email & password credential.
*/
+ (FIRAuthCredential *)credentialWithEmail:(NSString *)email password:(NSString *)password;
/** @fn credentialWithEmail:Link:
@brief Creates an `FIRAuthCredential` for an email & link sign in.
@param email The user's email address.
@param link The email sign-in link.
@return A FIRAuthCredential containing the email & link credential.
*/
+ (FIRAuthCredential *)credentialWithEmail:(NSString *)email link:(NSString *)link;
/** @fn init
@brief This class is not meant to be initialized.
*/
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
@class FIRAuthCredential;
NS_ASSUME_NONNULL_BEGIN
/**
@brief A string constant identifying the Facebook identity provider.
*/
extern NSString *const FIRFacebookAuthProviderID NS_SWIFT_NAME(FacebookAuthProviderID);
/**
@brief A string constant identifying the Facebook sign-in method.
*/
extern NSString *const _Nonnull FIRFacebookAuthSignInMethod NS_SWIFT_NAME(FacebookAuthSignInMethod);
/** @class FIRFacebookAuthProvider
@brief Utility class for constructing Facebook credentials.
*/
NS_SWIFT_NAME(FacebookAuthProvider)
@interface FIRFacebookAuthProvider : NSObject
/** @fn credentialWithAccessToken:
@brief Creates an `FIRAuthCredential` for a Facebook sign in.
@param accessToken The Access Token from Facebook.
@return A FIRAuthCredential containing the Facebook credentials.
*/
+ (FIRAuthCredential *)credentialWithAccessToken:(NSString *)accessToken;
/** @fn init
@brief This class should not be initialized.
*/
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

Some files were not shown because too many files have changed in this diff Show More