Otp Verification in nodejs? - node.js

I want to send otp via SMS and email to the user who is signing-up to the web app to verify their email and phone no.
Is there any NPM package for sending and verifying OTP or should I write my own code?

Yes, there is a package called sendotp. This is used for sending OTP over SMS only.
In npmjs you can find different examples to achieve your task.
But my suggestion is to implement your own methodology for sending and verifying OTP is better. Because by using packages you might get extra methods that you don't want at all or there is no functionality implemented that you want.

You can use Nodemailer for email verification and twiolio for sms verification. Create a random string and send it to user via sms or email and if using mongodb you can check when otp is created and from that you can check how much time is passed after its sent but by that you can set expirey.

You can use the msg91 for sending the otp to users.
Login to msg91 and get your template_id and api_key.
using msg91 api with the axios.
const axios = require('axios');
async function sendOtpTOUser(phone) {
const template = "template _id";
const apiKey = "api_key";
const sendotp = "https://api.msg91.com/api/v5/otp?template_id="+template+"&mobile="+phone+"&authkey="+apiKey;
let request_options1 = {
method: 'get',
url: sendotp
};
let otpResponse = await axios(request_options1);
console.log(otpResponse.data)
return otpResponse.data;
}
it will return the object as
{ request_id: '3166686e7867313634383535', type: 'success' }

Related

Anchor: How to ask the Nodejs backend to co-sign a transaction from the frontend without using Serum's Multisig?

Ideally, I want my Nodejs backend (which secures a keypair) to co-sign a transaction coming from the frontend app (assuming the user will sign the transaction using his / her Solana wallet). The pubkey of the backend will be also included as a signer account to the anchor program.
I can't see any tutorial from Anchor doing this, hopefully it makes sense. I was thinking that the frontend will call a backend API passing down the serialize parameters, on which the backend will sign, and will return a signature to the frontend with its public key.
I have no idea on:
What's the correct Anchor / Solana web3 to use to sign the transaction
How can I add the returning signature (of the backend) to the transaction
I initially don't want to use Multisig with this approach as it will just overcomplicate things. Just need some confirmation from the backend before submitting the transaction.
You probably want to do something like this (backend):
// create the transaction, with user's public key as the feePayer
// Sign the transaction as the backend
// We must partial sign because the transaction still requires the user signature
transaction.partialSign(backendKeypair)
// Serialize the transaction and convert to base64 to return it
const serializedTransaction = transaction.serialize({
// We will need the buyer to sign this transaction after it's returned to them
requireAllSignatures: false
})
const base64 = serializedTransaction.toString('base64')
// return base64 to the frontend
Then from the frontend:
// make sure you're passing user's public key in this request
const response = await fetch(`/your-api/`, {
method: 'POST',
...
})
// assuming your API returns JSON
const json = await response.json()
// Deserialize the transaction from the response
const transaction = Transaction.from(Buffer.from(json.transaction, 'base64'));
// have the user sign transaction using their connected wallet

Change from address while sending email via gmail API

I want to send a mail via the gmail API. I have a function that works so far, but my problem is that I don't know how to change the from address. My mails are always send as the user I authorized the API access with.
So I want my mails sent from from.mail#example.com in the following code:
function sendSampleMail(auth, cb) {
let gmailClass = google.gmail('v1');
let emailLines = [];
emailLines.push('From: from.mail#example.vom');
emailLines.push('To: to.mail#example.com');
emailLines.push('Content-type: text/html;charset=iso-8859-1');
emailLines.push('MIME-Version: 1.0');
emailLines.push('Subject: this would be the subject');
emailLines.push('');
emailLines.push('And this would be the content.<br/>');
emailLines.push('The body is in HTML so <b>we could even use bold</b>');
const email = emailLines.join('\r\n').trim();
let base64EncodedEmail = new Buffer.from(email).toString('base64');
base64EncodedEmail = base64EncodedEmail.replace(/\+/g, '-').replace(/\//g, '_');
gmailClass.users.messages.send(
{
auth: auth,
userId: 'me',
resource: {
raw: email
}
},
cb
);
}
I don't know if it's even possible to send with different from-mails via the google API. I could not find any information about that and no solutions.
You can't send emails (or make any request) as a different user from the authenticated user because you don't have any permissions to impersonate it.
If you're a G Suite administrator, you can use a service account [1][2] with domain wide delegation [3], which will grant you access to impersonate any gmail account from your domain. You can create a service account on Cloud Platform after selecting a project, from where you'll be able to download the credentials JSON file. And use the JSON Web Tokens methods [4] to authorize your application using the service account JSON.
[1] https://cloud.google.com/iam/docs/service-accounts
[2] https://cloud.google.com/iam/docs/understanding-service-accounts
[3] https://developers.google.com/admin-sdk/directory/v1/guides/delegation
[4] https://github.com/googleapis/google-auth-library-nodejs#json-web-tokens

Verify JWT from Google Chat POST request

I have a bot in NodeJS connected to Google Chat using HTTPs endpoints. I am using express to receive requests. I need to verify that all requests come from Google, and want to do this using the Bearer Token that Google Sends with requests.
My problem is that I am struggling to find a way to verify the tokens.
I have captured the token and tried a GET reuqes to https://oauth2.googleapis.com/tokeninfo?id_token=ey... (where ey... is the token start).
Which returns:
"error": "invalid_token",
"error_description": "Invalid Value"
}
I have tried what Google recommends:
var token = req.headers.authorization.split(/[ ]+/);
client.verifyIdToken({
idToken: token[1],
audience: JSON.parse(process.env.valid_client_ids)
}).then((ticket) => {
gchatHandler.handleGChat(req.body, res);
}).catch(console.error);
And get the following error:
Error: No pem found for envelope: {"alg":"RS256","kid":"d...1","typ":"JWT"}
Any idea where I should head from here?
Edit: https://www.googleapis.com/service_accounts/v1/metadata/x509/chat#system.gserviceaccount.com found this, investigating how to use it. The kid matches the one I get.
Worked it out, eventually.
You need to hit: https://www.googleapis.com/service_accounts/v1/metadata/x509/chat#system.gserviceaccount.com to get a JSON file containing the keys linked to their KIDs.
Then when a request arrives, use jsonwebtoken (NPM) to decode the token and extract the KID from the header.
Use the KID to find the matching public key in the response from the website above, then use the verify function to make sure the token matches the public key.
You also need to pass the audience and issuer options to verify, to validate that it is your particular service account hitting the bot.
The solution above maybe the correct for Google Chat, but in my experience Google services (e.g. Google Tasks) use OIDC tokens, which can be validated with verifyIdToken function.
Adding my solution here, since your question/answer was the closest thing I was able to find to my problem
So, In case if you need to sign a request from your own code
on client, send requests with OIDC token
import {URL} from 'url';
import {GoogleAuth} from 'google-auth-library';
// will use default auth or GOOGLE_APPLICATION_CREDENTIALS path to SA file
// you must validate email of this identity on the server!
const auth = new GoogleAuth({});
export const request = async ({url, ...options}) => {
const targetAudience = new URL(url as string).origin;
const client = await auth.getIdTokenClient(targetAudience);
return await client.request({...options, url});
};
await request({ url: 'https://my-domain.com/endpoint1', method: 'POST', data: {} })
on the server, validate OIDC (Id token)
const auth = new OAuth2Client();
const audience = 'https://my-domain.com';
// to validate
const token = req.headers.authorization.split(/[ ]+/)[1];
const ticket = await auth.verifyIdToken({idToken: token, audience });
if (ticket.getPayload().email !== SA_EMAIL) {
throw new Error('request was signed with different SA');
}
// all good
Read more about Google OpenID Connect Tokens

Create and Return Firebase Email Verification Link inside a Firebase Cloud Function

I have a firebase cloud function trigger an send a Welcome email when someone signs up. I would like to include my email verification link in that same email to reduce the amount of emails users get upon signup and improve the onboarding experience (rather than sending two separate emails).
exports.sendWelcomeEmail = functions.auth.user().onCreate(event => {
// Get user that signed up
const user = event.data; // The Firebase user.
// get the email of the user that signed up
const email = user.email; // The email of the user.
// Create email verification link
var emailVerificationLink = user.createEmailVerificationLink() // NEED HELP HERE: ideally, I would like to create/call a function to create an email verification link for the user here
// send email
mailgun.messages().send({
from: 'support#example.com',
to: email,
subject: 'Welcome & Get Started',
text: 'Welcome! Here are some resources to help you get started, but first verify your email: ' + emailVerificationLink + '!',
html: // some nice formatted version of the text above
}, function (error, response) {
console.log("Email response");
console.log(response);
console.log("Email error");
console.log(error);
});
})
I have carefully looked through the documentation on custom email handlers, but it doesn't seem like they return the email verification link, so I do not see how to use that approach for my purposes here (although I hope I'm wrong).
Is there a way to create the email verification link inside a Firebase Cloud Function in such a way that I could then use resulting link as I please (like in my Welcome email)?
There is no public API to get the OOB verification code, or the link that contains that code.
But you can implement this yourself with a few steps:
Generate your own verification code, that you store somewhere securely (e.g. in a protected section of your Firebase Database).
Embed that code in your message in a link.
Create a Cloud Function at that link.
Handle the request, check the verification code in the database
Set emailVerified to true.
This isn't all that much different from what Firebase Authentication does when you call sendEmailVerification().

how to configure sendgrid 's from email in nodemail?

I am using node.js 's email module nodemail and sendgrid API to send the email to the users.
Here is my code for sending a email
SOURCE_EMAIL = ?????;
var options = {
auth: {
api_user: sendgrid.api,
api_key: sendgrid.key
}
};
transport = nodemailer.createTransport(sgTransport(options));
transport.sendMail({from: SOURCE_EMAIL, to: email, subject: subject, html: html}, function(err,data){
});
my question is when I use the sendgrid API to send email, what SOURCE_MAIL i should configure to ?
You may set SOURCE_EMAIL to anything you want.
It's best to set it to an email you own, control, and can receive email from.
However, it's entirely up to you.

Resources