Firebase authentication tokens, check if valid - ios

Is it possible to check if an authentication token is invalid?
FIRAuthErrorCode.errorCodeInvalidUserToken
this is shown as a possible error but I can't figure out how to access this error besides when logging in or resetting the password like below.
FIRAuth.auth()?.sendPasswordReset(withEmail: email, completion: { (error) in
if let err = error as? NSError {
if let errorCode = FIRAuthErrorCode(rawValue: err.code){
if errorCode == FIRAuthErrorCode.errorCodeInvalidUserToken{
self.alertFunc(title: "Error", message: "invalid token")
}
}
} else{
self.alertFunc(title: "Success", message: "Password reset email has been sent")
}
If a user has a few devices logged into the same account, and reset the password on one, then the others will not be able to post to firebase due to their invalid token. I need the apps on the other devices to be able to recognize the invalid token and then prompt the user for the username and password.
Any help or links would be appreciated, thanks!

FIRAuth.auth()?.currentUser?.getTokenWithCompletion({ (string, err) in
if err != nil{
if let err = err as NSError?{
if let error = FIRAuthErrorCode(rawValue: err.code){
switch error{
case .errorCodeInvalidCredential: self.delegate.invalidToken()
case .errorCodeInvalidUserToken: self.delegate.invalidToken()
case .errorCodeUserTokenExpired: self.delegate.invalidToken()
case .errorCodeInvalidCustomToken: self.delegate.invalidToken()
case .errorCodeCustomTokenMismatch: self.delegate.invalidToken()
default: print("call default error")
}
}
}
}
})

Related

How to verify valid Token in MSAL?

I am facing one problem with the azure console when I am resetting the password from the azure console the token is not invalidating on the device/simulator.
applicationContext.acquireToken(with: parameters) { (result, error) in
if (error != nil) || result == nil {
print("Handle error")
// Handle error
} else {
print("Token valid")
// Token valid
}
}
I am using this to verify the token

AWS Cognito "confirmSignUp" is going in error code

I am using Cognito login and signup. If I am confirming OTP Code it is giving me an error.
An error occurred while registering a user AuthError: Username/client id combination not found.
Recovery suggestion: Make sure that the user is present in the backend
Caused by:
userNotFound
func confirmSignUp(for username: String, with confirmationCode: String) {
_ = Amplify.Auth.confirmSignUp(for: username, confirmationCode: confirmationCode) { result in
switch result {
case .success(_):
print("Confirm signUp succeeded")
DispatchQueue.main.async {
self.checkOTP(otp:self.storeOTP)
}
case .failure(let error):
print("An error occurred while registering a user \(error)")
DispatchQueue.main.async {
self.alert(title: "", message: "OTP not match")
}
}
}
}

Sign in with Apple - ASAuthorizationAppleIDProvider already signed in but notfound

recently I'm learning SiwA on
https://fluffy.es/sign-in-with-apple-tutorial-ios/
I tried to learn step-by step, however, I met some wired problem when I used "ASAuthorizationAppleIDProvider". I have saved the userID in local, but it returns notfound when using ASAuthorizationAppleIDProvider. I also delete the Apple ID used before in
Settings > Apple ID > Password & Security > Apps Using your Apple ID
But it stills return notfound when I re-login. Here is my code.
extension LoginViewController: ASAuthorizationControllerDelegate{
func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
print("something bad", error)
}
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential{
UserDefaults.standard.set(appleIDCredential.user, forKey: appleAccount.userID)
}
}
}
if let userID = UserDefaults.standard.string(forKey: appleAccount.userID) {
ASAuthorizationAppleIDProvider().getCredentialState(forUserID: userID, completion: {
credentialState, error in
print(userID)
switch(credentialState){
case .authorized:
print("user remain logged in, proceed to another view")
self.performSegue(withIdentifier: "LoginToUserSegue", sender: nil)
case .revoked:
print("user logged in before but revoked")
case .notFound:
print("user haven't log in before")
default:
print("unknown state")
}
})
}
It indeed print userID so userID is not nil. But seems it's not match with the Apple ID so it shows notfound? Here is the error
[core] Credential State request returned with error: Error Domain=AKAuthenticationError Code=-7073 "(null)"
The problem is caused by simulator, if we change to device, there is no such problem. See reference:
failed to get credential.state and getCredentialStateForUserID

Update Email using Phone Auth Credential iOS

I am creating an application which authenticate user using PhoneAuth. In my application I have a function which let user add Email to his account But not meant that I authenticate user using Email and Password, I just want to add email to his/her account (auth.auth().currentUser).
Initially, I let user to add his/her email in textfield and then I start to logout user from his/her device in order to reauthentication otherwise, I cannot update user's email using auth.updateEmail(). But sadly, the credential always expired after I called func updateEmail().
This is how I signIn user and update Email
let credential = PhoneAuthProvider.provider().credential(withVerificationID: verficationID, verificationCode: code)
Auth.auth().signInAndRetrieveData(with: credential) { (result, error) in
guard let result = result else {
completion(false)
return
}
if error == nil {
guard let user = Auth.auth().currentUser else {
return
}
if UserDefaults.standard.getUserUpdatedEmail() {
user.reauthenticate(with: credential, completion: { (error) in
if error == nil {
user.updateEmail(to: newEmail, completion: { (error) in
if error == nil {
UserDefaults.standard.setUserUpdatedEmail(value: false)
completion(true)
//return true
} else {
completion(false)
//return false
print("Error validate email ",error?.localizedDescription ?? "")
}
})
} else {
completion(false)
// return false
print("Error reauthntication email ",error?.localizedDescription ?? "")
}
})
} else {
print("User is signed in \(result.user)")
print("This is userID \(result.user.uid)")
completion(true)
}
} else {
if let error = error {
print("Error during verification \(error.localizedDescription)")
}
completion(false)
}
}
I don't why the credential is expired too fast? I cannot figure it out how to update user email using PhoneAuthCredential. Is there any other techniques to do it?
You are trying to re-use the same phone credential (you used it first to sign-in). The phone credential is one time use only. If you want to update email immediately after sign-in, re-auth is not needed. However, if you try to update email after some time, you will need to send a new SMS code to re-authenticate.

iOS link two firebase accounts error

I'm trying to link two firebase accounts
a phone account ( signed in ) to Anonymous account ( prevUser )
this is my code
func verifyCode() {
let credential = PhoneAuthProvider.provider().credential(
withVerificationID: self.verificationID,
verificationCode: phoneCode.text!)
let prevUser = Auth.auth().currentUser!
Auth.auth().signIn(with: credential) { (user, error) in
if let error = error {
print("1 something went wrong : ", error.localizedDescription)
return
}
print("the user ID is : " , user!.uid)
prevUser.link(with: credential, completion: { (user, error) in
if let error = error {
print("something went wrong : ", error.localizedDescription)
return
}
})
}
}
I keep getting the same error always
something went wrong : The SMS code has expired. Please re-send the verification
code to try again.
thanks in advance
There are 2 issues here:
You are signing in with the phone auth credential first and then linking to the same credential which contains the same underlying SMS code which is a one time code. This will always fail with the error you are getting since the Firebase Auth backend can only use the code once (it immediately expires the first time it is used).
Even if the code is usable more than once, you can't have more than one user with the same phone credential. You first sign in one user with that credential and then try to link it to another user. This will always fail with an error that the credential already exists on another account.
Step 1: You can verify the phone number by providing phone number string and in completion you will be returned a verificationID and error if any.
func verifyPhoneNumber(withPhoneNo phoneNo:String, completion: #escaping (_ error: Error?, _ verificationID: String?)->Void) {
PhoneAuthProvider.provider().verifyPhoneNumber(phoneNo) { (verificationID, error) in
if let error = error {
print(error.localizedDescription)
completion(error, verificationID)
} else {
print(verificationID ?? "no id provided")
completion(nil, verificationID)
}
}
}
Step 2: Linking Phone Number to the current User by providing the current user, 6digit verification code, verificationID obtained from the previous function.
In completion you will be returned with an error if any.
func linkPhoneNumber(withUser user: User, verificationCode: String, verificationID id: String, completion: #escaping (_ error: Error?)-> Void) {
let credential = PhoneAuthProvider.provider().credential(withVerificationID: id, verificationCode: verificationCode)
user.link(with: credential) { (user, error) in
if let error = error {
print(error.localizedDescription)
completion(error)
} else {
print(user!.uid)
completion(nil)
}
}
}

Resources