I have email verification/password-reset with parse-server-simple-mailgun-adapter that works. However, now, whenever a saveInBackground() function is called on a puffer, an email-verification email is sent out again with the user's emailVerified field in the database reset to false. Here is the code I have in my index.js pertaining to email:
// Enable email verification
verifyUserEmails: true,
emailVerifyTokenValidityDuration: 3 * 60 * 60, // in seconds (2 hours = 7200 seconds)
// set preventLoginWithUnverifiedEmail to false to allow user to login without verifying their email
// set preventLoginWithUnverifiedEmail to true to prevent user from login if their email is not verified
preventLoginWithUnverifiedEmail: true,
Related
I am trying to make a loggin system that allows to signIn/signUp (with google or facebook) and then add a verified phone number, and vice versa. If I enter the email first and then the phone number I have no problems since the email is verified. but in the opposite case, first I enter the phone number and then I update the email, but this time I enter the values (mail and displayname) through a TexFormField. Because of this the emailVerified parameter always starts at false. I tried to use the sendEmailVerification method but according to the documentation, the verification email is only sent for users created with the createUserWithEmailAndPassword method. Which does not help me since I do not want to start with email and password but with phone number, I only want email (verified) and displayName for reference.
I use the following code (firebaseAuth = FirebaseAuth.Instace):
I get the verification sms
await firebaseAuth.verifyPhoneNumber(
phoneNumber: phoneNumber,
timeout: const Duration(seconds: Constants.timeOut),
verificationCompleted: (_) {
...
},
verificationFailed: (firebaseExcep) {
...
},
codeSent: (verificationId, _) { <--------- here
setVerificationId(verifycationId);
completer.complete('ok');
},
codeAutoRetrievalTimeout: (_) {
...
},
);
After receiving the sms I start the session with that phone number
final credential = PhoneAuthProvider.credential(verificationId: verifycationId, smsCode: smsCode);
await firebaseAuth.signInWithCredential(credential);
Then I enter email and displayName and update the previously created user:
await firebaseAuth.currentUser!.updateEmail(email);
await firebaseAuth.currentUser!.updateDisplayName(name);
--- Up to this point I have in firebase a user with phone number, email and displayName. But emailVerified is false
Finally, I try to send the verification email but I never receive anything
firebaseAuth.currentUser!.sendEmailVerification()
--- According to the documentation it is because this user was not created with createUserWithEmailAndPassword. Is there any other way to check the email?
I was literally writing a multi-step signup page passwordlessly. I have looked up and I don't think sendVerificationEmail would work.
I have code which has remained essentially unchanged for months. The code extracted an email address and email password from an .env file and was used for a few difference cases. Whenever a single user signs up, they would receive an email; and whenever an owner signs many employees up, each of them would receive and email.
The email account we used to send these emails was a Gmail, and was created before the May 30th update and allowed less secure apps access. This allowed it to work sending an individual an email when they signed up, and provided there was a 1 second delay between each employee signed up, it was able to handle the en masse emailing as well.
The email account we use has since been changed, this new email was created after the May 30th update. I jumped through all of the extra hoops to enable less secured apps on this new account, so it sends individual sign up emails with no issue. However, as soon as I attempt to execute the en masse emails (even with the one second delay) I get the following error:
Error: Invalid login: 535-5.7.8 Username and Password not accepted.
Now, this really makes no sense because it is a copy and paste job of the email syntax that DOES work meaning this code below works...
try{
// Creates the Transporter
const transporter = nodemailer.createTransport({
service: "Gmail",
auth: {
user: `${process.env.SIGNUP_EMAIL}`,
pass: `${process.env.SIGNUP_PASS}`
}
})
// Creates the Mail Object
const mailOptions = {
from: `${process.env.SIGNUP_EMAIL}`,
to: `${actualEmail}`,
subject: `Thank you for joining the TOM Team!`,
text: `We have recieved your Account Signup and are please to welcome you to the TOM Experience!`
}
// Sends the mail
transporter.sendMail(mailOptions, (error, response) => {
if (error){
throw new Error('Something went wrong, please try again \n' + error)
}
})
} catch(error){
console.log(error)
}
But this code DOES NOT (breaks on the first attempt no matter how many others there are after)
try{
const transporter = nodemailer.createTransport({
service: "Gmail",
auth: {
user: `${process.env.SIGNUP_EMAIL}`,
pass: `${process.env.SIGNUP_PASS}`
}
})
// Creates the Mail Object
const mailOptions = {
from: `${process.env.SIGNUP_EMAIL}`,
to: `${actualEmail}`,
subject: `Thank you for joining the TOM Team!`,
text: `We have recieved your Account Signup and are please to welcome you to the TOM Experience! \nUpon recieving this email, you will have a new TOM Account for the mobile app. Please use this email, and the password "${passwordToUse}" to login and get started!`
}
// Sends the mail
transporter.sendMail(mailOptions, (error, response) => {
if (error){
console.log(error)
throw new Error('Something went wrong, please try again \n' + error)
}
})
}
catch(err){
console.log(err)
throw new Error(`Something went wrong emailing ${actualEmail}. Please check this is the proper address.`)
}
Is it just impossible to send gmails en masse now? Even with a 1 second delay? Even if not, why is the very first email failing? I truly have no idea why I'm facing these errors
I'm not sure why this is, but increasing the wait time from 1000 milliseconds to 1500, and then back to 1000 did the trick.
I'm not sure, maybe the new email just needed to get baby-stepped into sending multiple at a time.
My question is an extension of this fantastic solution but am hoping to take it one step further. Whenever a user other than me marks the checkbox as TRUE, the sender of the email is always me, since:
Installable triggers always run under the account of the person who created them
Is it possible to capture the user currently logged in and make them the sender, and if so, what am I missing in my code to make that happen?
What I've tried
I believed I had found my answer, but no such luck. This still posts the timestamp to the sheet successfully, but the email sender still shows as me. Any help would be greatly appreciated.
Edit(s):
I noticed in the above solution if (activeUser === effectiveUser) { only "worked" if typed as if (activeUser !== effectiveUser) {. In my attempts at making it work, I made that edit and forgot to revert it.
function sendEmail(e){
var sheet = e.source.getActiveSheet();
var cell = e.range;
var activeUser = Session.getActiveUser().getEmail();
var effectiveUser = Session.getEffectiveUser().getEmail();
if (activeUser !== effectiveUser) {
Logger.log(cell.getColumn());
Logger.log(cell.isChecked());
//Check if the checkbox in column G(index 7) was checked
if(sheet.getName() == "actionItems" && cell.getColumn() == 7 && cell.isChecked()){
//get current row values from column A to column F
var values = sheet.getRange(cell.getRow(),1,1,6).getDisplayValues().flat();
Logger.log(values);
var transmittalNumber = values[0];
var email = values[5];
var query = values[1];
//create and update the email's hmtl body
var templ = HtmlService.createTemplateFromFile('html_template');
templ.query = query;
var message = templ.evaluate().getContent();
//Send email
MailApp.sendEmail({
to: email,
subject: "Oatsies Action Item: "+transmittalNumber,
htmlBody: message
});
//Add timestamp at column H(index 8)
var timeZone = "GMT-7";
var date = Utilities.formatDate(new Date(),timeZone, "yyyy-MM-dd HH:mm");
sheet.getRange(cell.getRow(),8).setValue(date);
}
}
}
From the question
Is it possible to capture the user currently logged in and make them the sender?
If you are using a free Google account (usually gmail.com account) it might be possible if you use the Gmail API and set a way for active users to authorize the access to their Gmail account to send emails. Also it might be possible if you and the user are using a Google Workspace accounts and if you are able to take advantage of company-wide delegation of authority (also might be possible if you are able to configure the user's email addresses as emails aliases of your account).
Regarding the use of Session.getActiveUser().getEmail() it will return the active user email based on a complex rules i.e. your account and active user belongs to the same Google Workspace domains.
Related
Session.getActiveUser().getEmail() results are inconsistent
Domain-wide delegation
getActiveUser() doesn't return the user?
I am experimenting on botpress slots . There is the new option called as slot which will validate the user input . However I am not able to find resources which will validate the user input.
The bot must validate the use input as a phone number using slot feature or any other without use of external api ?
Is this possible ?
for example:
If the user inputs a valide phone number the flow will proceed.
else if use enters invalid phone number the flow will ask to re enter a valid phone number.
I have tried multiple things but had no luck finding the proper documentation/ tutorial regarding it.
I think you can use a custom action to achieve this. A custom action for validating mobile number may look like:
const baseMessage = {
type: 'text',
markdown: false
}
/**
* check if phone number is valid
* #title validate phone number
* #category Validation
* #author Your name
* #param {string} phone - phone number
*/
const validateNumber = async phone => {
var phoneRegex = /^\d{10}$/
if (phone.match(phoneRegex)) {
temp.phone_validation = 'success'
} else {
temp.phone_validation = 'error'
}
}
return validateNumber(args.phone)
You can call the custom action in your validation flow and redirect user accordingly
In my routing file I have the following down.
Router.route('/user/:createdBy', {
name: 'user',
/*onBeforeAction: function () {
AccountsEntry.signInRequired(this);
},*/
fastRender: true,
data: function () {
paramId = this.params.createdBy;
// Still have to find a way how to get data
// Function below is only for signed in users
return Meteor.users.findOne(paramId);
}
});
In my user template I want to display the email. I have it like this {{emails.[0].address}} and as {{users.emails.[0].address}} but the email doesn't show up. It only shows up if the user is logged in. I however have the users Id as my param. (This is for testing purposes guys!).
If you want to use the logged off user information, you could try this:
// in your router.js
// callback would be called when login is successful
Meteor.onLogin(function(){
Session.set('login user', Meteor.user());
})
// in your template, or other functions
// the Session would be update only if a user login successfully
var userId = Session.get('login user')._id;
Click here for more details.
I wish it could help :-)