My requirement is very simple.
I have a node server, which doesnt have login page, there is no interactivity login page(dont want to redirect using express.js). I want to connect my mailbox id and read all unread emails from nodejs using oauth2 access token, thats it enough. As i am new to Azure, i followed some steps from azure portal for app registrations set permissions to scopes ["Mail.ReadWrite", "User.Read", "Mail.ReadWrite.Shared", "offline_access"].
Anyone who knows, nodejs and Azure could help me out from this pathetic path. I was tried most of the way to websites, but no luck. I dont know, whether issue is in my code or in the azure app registration. I appreciate godfather of Azure and Nodejs developer, who can help in this issue. I am okay to have a call if possible through zoom:
Followed Website for Development:
https://learn.microsoft.com/en-us/exchange/client-developer/legacy-protocols/how-to-authenticate-an-imap-pop-smtp-application-by-using-oauth
To get oauth2 access token, followed the below code:
const msal = require('@azure/msal-node');
/**
* Configuration object to be passed to MSAL instance on creation.
* For a full list of MSAL Node configuration parameters, visit:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-node/docs/configuration.md
*/
const msalConfig = {
auth: {
clientId: "*******************-589b9fbd51d3",
authority: "https://login.microsoftonline.com/*********************-d2c178decee1",
clientSecret: "***********************iqDQNl48FGc63"
}
};
const tokenRequest = {
scopes: ["https://graph.microsoft.com/.default"]
// scopes: ["https://outlook.office.com/IMAP.AccessAsUser.All"],
};
/**
* Initialize a confidential client application. For more info, visit:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-node/docs/initialize-confidential-client-application.md
*/
/**
* Acquires token with client credentials.
* @param {object} tokenRequest
*/
async function getToken(tokenRequest) {
const cca = new msal.ConfidentialClientApplication(msalConfig);
const msalTokenCache = cca.getTokenCache();
return await cca.acquireTokenByClientCredential(tokenRequest);
}
async function main() {
try {
const authResponse = await getToken(tokenRequest);
console.log(authResponse.accessToken);
} catch (error) {
console.log(error);
}
};
main();
My index.js for reading mails and using the above access token in the below code, for now i am manually copy and paste the token, later will merge these two code files for dynamic fetch.
Followed code was taken from here: https://www.npmjs.com/package/node-imap
var Imap = require('node-imap'),
inspect = require('util').inspect;
const mailId = 'sstest**@******.com';
const token =
'eyJ0eXAiOiJKV1QiLCJub25jZSI6ImRvd3R0S2draG1fVGN1T1g3S1p................';
const auth2 = btoa('user=' + mailId + '^Aauth=Bearer ' + token + '^A^A');
var imap = new Imap({
xoauth2: auth2,
host: 'outlook.office365.com',
port: 993,
tls: true,
debug: console.log,
authTimeout: 25000,
connTimeout: 30000,
tlsOptions: {
rejectUnauthorized: false,
servername: 'outlook.office365.com'
}
});
function openInbox(cb) {
imap.openBox('INBOX', true, cb);
}
imap.once('ready', function () {
openInbox(function (err, box) {
if (err) throw err;
var f = imap.seq.fetch('1:3', {
bodies: 'HEADER.FIELDS (FROM TO SUBJECT DATE)',
struct: true
});
f.on('message', function (msg, seqno) {
console.log('Message #%d', seqno);
var prefix = '(#' + seqno + ') ';
msg.on('body', function (stream, info) {
var buffer = '';
stream.on('data', function (chunk) {
buffer += chunk.toString('utf8');
});
stream.once('end', function () {
console.log(
prefix + 'Parsed header: %s',
inspect(Imap.parseHeader(buffer))
);
});
});
msg.once('attributes', function (attrs) {
console.log(prefix + 'Attributes: %s', inspect(attrs, false, 8));
});
msg.once('end', function () {
console.log(prefix + 'Finished');
});
});
f.once('error', function (err) {
console.log('Fetch error: ' + err);
});
f.once('end', function () {
console.log('Done fetching all messages!');
imap.end();
});
});
});
imap.once('error', function (err) {
console.log(err);
});
imap.once('end', function () {
console.log('Connection ended');
});
imap.connect();