Firebase send email function - firebase

I have been playing around with firebase tutorials and the new functions, and trying to implement this specific example:
https://github.com/firebase/functions-samples/tree/master/quickstarts/email-users
When I fire the trigger the mail does not get sent, and I get the following error in the log console:
Error: Invalid login: 535-5.7.8 Username and Password not accepted. Learn more at
535 5.7.8 https://support.google.com/mail/?p=BadCredentials 141sm3120746ioe.47 - gsmtp
at SMTPConnection._formatError (/user_code/node_modules/nodemailer/lib/smtp-connection/index.js:557:19)
at SMTPConnection._actionAUTHComplete (/user_code/node_modules/nodemailer/lib/smtp-connection/index.js:1248:34)
at SMTPConnection._responseActions.push.str (/user_code/node_modules/nodemailer/lib/smtp-connection/index.js:340:26)
at SMTPConnection._processResponse (/user_code/node_modules/nodemailer/lib/smtp-connection/index.js:706:20)
at SMTPConnection._onData (/user_code/node_modules/nodemailer/lib/smtp-connection/index.js:509:14)
at TLSSocket._socket.on.chunk (/user_code/node_modules/nodemailer/lib/smtp-connection/index.js:461:47)
at emitOne (events.js:96:13)
at TLSSocket.emit (events.js:188:7)
at readableAddChunk (_stream_readable.js:176:18)
at TLSSocket.Readable.push (_stream_readable.js:134:10)
What am I doing wrong? It does not say anthing about placing some authorizations on email account. Just the password. Should be simple.

If you type: firebase functions:config:get in the Terminal, you would be able to see that the gmail and password is with double quotation marks.
Mine was like this:
{
"gmail": {
"password": ""pass"",
"email": ""user#gmail.com""
}
}
So I typed in like this in the Terminal and it worked for me:
WITHOUT QUATATION MARKS
firebase functions:config:set gmail.email=user#gmail.com gmail.password=pass

not too sure if you've done the initial configuration part as listed here
For Gmail, enable these:
1. https://www.google.com/settings/security/lesssecureapps
2. https://accounts.google.com/DisplayUnlockCaptcha
If you have already done this, you can pass the email and password as a string on const gmailEmail = 'gmail.com' and const gmailPassword = 'password' to check if it's working

Related

How do you get IAM credentials using Amplify Auth?

I am trying to get IAM credentials using Amplify ^5.0.7. I am able to successfully log in and get OpenID tokens:
Auth.signIn({
username: user,
password: password
})
.then((u: CognitoUser) => {
console.log("User", u);
console.log("Credentials", Auth.Credentials);
console.log("Essential credentials", Auth.essentialCredentials(Auth.Credentials));
return Auth.currentSession();
}).then((data: CognitoUserSession) => {
console.log("Current session", data);
return Auth.essentialCredentials(Auth.currentCredentials())
}).then((c: ICredentials) => {
console.log("Credentials", c);
})
That successfully signs in, and gets a current session that has id, access, and refresh tokens. The problem is that there are no Credentials. currentCredentials() returns an ICredentials object, but its fields are all undefined. I think those should map to temporary IAM credentials.
The user I'm testing against belongs to exactly one group, and that group has an IAM role assigned to it.
Am I missing a step to request the temporary IAM credentials? I am not using amplify on the backend. I'm really using Amplify Auth because it deals with SRP for me.
I think I figured it out, and it was simpler than I thought. I want to post what I did to fix it, in case anybody else has the same problem.
What I did was basically correct, except you don't need to get the session first.
Auth.signIn({
username: userInput,
password: passwordInput
})
.then((u: CognitoUser) => {
console.log("Auth.credentials", Auth.Credentials)
return Auth.currentCredentials()
}).then((currentCredentials: ICredentials) => {
console.log("Essential credentials", Auth.essentialCredentials(currentCredentials))
})
There was not really a "code" trick to getting it to work. The real problem was that I was not careful enough about how I was setting up Cognito. To do this, you need both a user pool AND an identity pool. The identity pool points back toward the user pool. I had done that, but I wasn't setting Amplify up correctly. The way that works is:
Amplify.configure({
Auth: {
mandatorySignIn: true,
region: 'us-east-1',
userPoolId: 'us-east-1_CX1xxxxxx',
userPoolWebClientId: '5eo394ojo1gvdm6cbxxxxxxxxxs',
identityPoolId: 'us-east-1:f69259b2-ff84-4731-b80c-xf421-xxxx'
}
});
if you don't care about the IAM credentials, you don't seem to need the identity pool nor do you need to specify its ID. If you leave them out, you just get an empty Credentials back.
So Amplify does everything. I'm new to Amplify, and it's a lot less work then dealing with SRP directly.

Unity-Firebase urls to signin or signup give error with restClient

Im learning Firebase with Unity and using the RestClient and while it worked well with just reading and writing to the database, in the authentication part Im stuck, I have only tested the signup part so far but it gives me error http unknown, I got the url from the reference docs in firebase site, here is the function that throws the error in case it helps but I assume I got the url wrong or something, Im open to any solution you give, thanks =) :
void signUpUser(string nombreusuario,string email, string password)
{
string datosusuario="{\"email\":\""+email+"\",\"password\":\""+password+"\",\"returnSecureToken\":true}";
RestClient.Post<signresponse>("https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=" + AuthKey, datosusuario).Then( ResponseHelper=>
{
localId = ResponseHelper.localId;
idToken = ResponseHelper.idToken;
nombre = nombreusuario;
enviaBaseDatos(true);
}).Catch(error=>
{
Debug.Log(error);
});
}
So I've been digging and I think that documentation is partially wrong as it says that the endpoint is
https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=[API_KEY]
But It also says
You can create a new email and password user by issuing an
HTTP POST request to the Auth signupNewUser endpoint.
So the real endpoint is signUpNewUser instead of simply signUp!
https://identitytoolkit.googleapis.com/v1/accounts: signUpNewUser?key=[API_KEY]
If this new endpoint does not work, try the version 3 of the endpoint:
https://www.googleapis.com/identitytoolkit/v3/relyingparty/signUpNewUser?key=[API_KEY]

Find whether email and username already exist in Firebase Auth in Flutter App

I am using sign up with email in my Flutter app and using Firebase Authentication for the same. How do I show on the sign up page whether the entered email and username already exist in the database?
firebase will return that info as an error message:
FirebaseAuth.instance.createUserWithEmailAndPassword(email: _email, password: _password).then((user) {
// do whatever you want to do with new user object
}).catchError((e) {
print(e.details); // code, message, details
});
if the email exists it'll trigger the catchError. it's worth noting that 'details' is the human readable error getter. 'code' and 'message' are useless to an end user, but those are the only two documented on firebase_auth.

Importing users into firebase using sha-1 hashed passwords

In the simple case outlined below, the user will successfully import but I receive an INVALID_PASSWORD when I try to authenticate.
The salt and passwordHash where pulled from an LDAP user directory (apacheds) using the {SSHA} auth schema. When I run the following JS I receive the passwordHash I'm expecting:
var sha1Hex = require('sha1-hex');
var saltHex = Buffer.from("ktuF+dzYMQU=", 'base64').toString('hex');
var passwordHex = Buffer.from("demo", 'utf-8').toString('hex');
var hash = sha1Hex(Buffer.from(passwordHex + saltHex, 'hex'));
var hashBase64 = Buffer.from(hash, 'hex').toString('base64');
console.log(hashBase64);
firebase CLM import command:
firebase auth:import users.json --hash-algo=SHA1 --rounds=80
users.json file:
{
"users": [
{
"localId": "3c872eee-e86c-4b44-9840-bcebaac18f2c",
"email": "test#example.com",
"salt": "ktuF+dzYMQU=",
"passwordHash": "BuapoGGKIdfGprfMFjj3N9I7Ljg=",
"displayName": "Demo User",
}
]
}
Credentials that should work with imported user:
Username: test#example.com
Password: demo
Firebase web api login command (returns INVALID_PASSWORD):
firebase.auth().signInWithEmailAndPassword('test#example.com', demo);
I'm not confident about the --rounds=80 parameter, seems weird that needs to be specified at all when using sha1. I've also tried with --rounds=0.
After trying this out with Java MessageDigest SHA-1 to verify the password hash, one of our uber auth experts said that it looks like you're doing passwordHash = SHA1(plainPassword + salt)
However, the Firebase Auth system uses passwordHash = SHA1(salt + plainPassword).
So I think if you switch that around, it should produce better results.
You can configure the order of the password and hash.
The hash-input-order accept two values: SALT_FIRST or PASSWORD_FIRST.
In your case you want to do:
firebase auth:import users.json --hash-algo=SHA1 --rounds=80 --hash-input-order=PASSWORD_FIRST
For anyone like me that went hours finding a solution for this issue, please refer to this.
Basically, passwordHash should be in Base64 encoding from un-hex-ed SHA1 hash. And --rounds=1 works fine.

User Not Found when trying to reset password

I have a user who forgot their password. Using the Accounts package the user tried to get their password reset with the "Reset password" function. When they enter their email address it states "User Not Found".
What is causing this? More importantly how do I fix it? I've been beating my head into a wall trying to find a solution so any help would be great. I've tried to duplicate but my test accounts don't have the same issue.
My build is Meteor 1.2 with the accounts-password and accounts-base packages. My setup is:
passwordSignupFields: "USERNAME_AND_EMAIL"
When resetting the user's password, Meteor tries to look up the user by the provided e-mail. If it cannot find the user using the e-mail - it throws the "User not found" - link to code here
Meteor.methods({forgotPassword: function (options) {
check(options, {email: String});
var user = Accounts.findUserByEmail(options.email);
if (!user)
throw new Meteor.Error(403, "User not found");
const emails = _.pluck(user.emails || [], 'address');
const caseSensitiveEmail = _.find(emails, email => {
return email.toLowerCase() === options.email.toLowerCase();
});
Accounts.sendResetPasswordEmail(user._id, caseSensitiveEmail);
}});
Is the user providing the correct e-mail? Check that the e-mail being provided actually exists in the DB in the Meteor.users collection

Resources