Read Outlook Mails via IMAP using nodejs and oauth2

saravanakumar saravanakumar 11 Reputation points
2022-06-03T06:14:42.097+00:00

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();  






 
Microsoft Entra ID
Microsoft Entra ID
A Microsoft Entra identity service that provides identity management and access control capabilities. Replaces Azure Active Directory.
19,478 questions
{count} vote

7 answers

Sort by: Most helpful
  1. Sambit Kumar Das 16 Reputation points
    2022-11-30T10:14:34.863+00:00

    HI ,

    I am facing the same issue .I have followed all the instruction above to create an Application in the Azure portal and followed the above code.
    but i am getting below error

    [connection] Connected to host
    <= '* OK The Microsoft Exchange IMAP4 service is ready. [UABOADMAUABSADAAMQBDAEEAMAAxADcAMwAuAEkATgBEAFAAUgBEADAAMQAuAFAAUgBPAEQALgBPAFUAVABMAE8ATwBLAC4AQwBPAE0A]'
    => 'A0 CAPABILITY'
    <= '* CAPABILITY IMAP4 IMAP4rev1 AUTH=PLAIN AUTH=XOAUTH2 SASL-IR UIDPLUS ID UNSELECT CHILDREN IDLE NAMESPACE LITERAL+'
    <= 'A0 OK CAPABILITY completed.'
    => 'A1 AUTHENTICATE XOAUTH2 dXNlcj1vYXRoLnZhbGlkYXRpb25AaW5vdmFhcmUuY29tXkFhdXRoPUJlYXJlciBleUowZVhBaU9pSktWMVFpTENKdWIyNWpaU0k2SWxKSFZuaExXREp1TTI5SFpDMTBkR2RXUmtOQlJVMVJMVFJ0YjJWa1NXZEhTVnAyY2t4UFltOWFZbFVpTENKaGJHY2lPaUpTVXpJMU5pSXNJbmcxZENJNklqSmFVWEJLTTFWd1ltcEJXVmhaUjJGWVJVcHNPR3hXTUZSUFNTSXNJbXRwWkNJNklqSmFVWEJLTTFWd1ltcEJXVmhaUjJGWVJVcHNPR3hXTUZSUFNTSjkuZXlKaGRXUWlPaUpvZEhSd2N6b3ZMMjkxZEd4dmIyc3ViMlptYVdObExtTnZiU0lzSW1semN5STZJbWgwZEhCek9pOHZjM1J6TG5kcGJtUnZkM011Ym1WMEx6VmpNR1V5TVRjMUxUTm1abUl0TkdVeFlpMDVORFEzTFRKaU56RTNNelU0TjJSbU5TOGlMQ0pwWVhRaU9qRTJOams0TURJME16VXNJbTVpWmlJNk1UWTJPVGd3TWpRek5Td2laWGh3SWpveE5qWTVPREEyTXpNMUxDSmhhVzhpT2lKRk1scG5XVkJvY1hCSWEzbDFjMFE0ZGxWMlJtZHdPRVp6ZWpONlFVRTlQU0lzSW1Gd2NGOWthWE53YkdGNWJtRnRaU0k2SWtWdFlXbHNUR2x6ZEdsdVpYSWlMQ0poY0hCcFpDSTZJamhpWWpjM05XSXlMVGc0WmpFdE5HSXhOQzA0TVRreExUVmtZak14TnpRNVl6bGxNaUlzSW1Gd2NHbGtZV055SWpvaU1TSXNJbWxrY0NJNkltaDBkSEJ6T2k4dmMzUnpMbmRwYm1SdmQzTXVibVYwTHpWak1HVXlNVGMxTFRObVptSXROR1V4WWkwNU5EUTNMVEppTnpFM016VTROMlJtTlM4aUxDSnZhV1FpT2lKa1l6a3pOelZoTXkxbFlqVTFMVFExTjJRdE9EWXdaUzFqWmpReE5UQTJPVFppT1RVaUxDSnlhQ0k2SWpBdVFWVnZRV1JUUlU5WVVITmZSekEyVlZKNWRIaGpNV2c1T1ZGSlFVRkJRVUZCVUVWUWVtZEJRVUZCUVVGQlFVTktRVUZCTGlJc0luSnZiR1Z6SWpwYkltWjFiR3hmWVdOalpYTnpYMkZ6WDJGd2NDSXNJbEJQVUM1QlkyTmxjM05CYzBGd2NDSXNJazFoYVd3dVVtVmhaQ0lzSWtsTlFWQXVRV05qWlhOelFYTkJjSEFpWFN3aWMybGtJam9pT1dJeVpHUTRPVFl0TkdZNE5TMDBNMlU0TFdKbE9HTXRNREEzT1dOa1ltRTNaRGRrSWl3aWMzVmlJam9pWkdNNU16YzFZVE10WldJMU5TMDBOVGRrTFRnMk1HVXRZMlkwTVRVd05qazJZamsxSWl3aWRHbGtJam9pTldNd1pUSXhOelV0TTJabVlpMDBaVEZpTFRrME5EY3RNbUkzTVRjek5UZzNaR1kxSWl3aWRYUnBJam9pT1hBMVdYcElWbEJFUlZka01FSnNlVWRTVVhoQlFTSXNJblpsY2lJNklqRXVNQ0lzSW5kcFpITWlPbHNpTURrNU4yRXhaREF0TUdReFpDMDBZV05pTFdJME1EZ3RaRFZqWVRjek1USXhaVGt3SWwxOS5hSmJ0dy1qeE12N2hVZzhEM2dfcGstRmZSSTBkOTZ6UzVpSUp6RjZ2TWVkOWZ4N1cyZW9ndlNCT3ZBV1RnOTJEUGtYZEpBdDZCV1VFdjZTRzZHa19VNllfS19fLTRxNE8ybEdRWmNCX2pUSkNJM18zNU9lbzladVluUE5HdXRvNVotbi1fYTEtNnk1eV9sLVJNbm41UDVRRUNLYTF5X3p6SFk2THBXbG9SQ2xqNHJPN2drbGxOS01xb0ZHbVY1YUV3SWpjQVNvRTlaVksxMFhwZm1LMkdJdGQ3bUZGdEV4NlE2dUhTWWRvZ1pvZkVmbk1PTUJrU3J4S3pGaERyNk5yUVhUQ3Mtc3doNmExXzAwM2pqWUt0UXhxU00zcUJOVmVjMVFUQjFvNS1ldFBGbEk3aENZanNnQzJEQkJPTEcxSHVkQkZPaUNDS0VKSkxtNlRUdWg2ekFeQV5B'
    <= 'A1 NO AUTHENTICATE failed.'
    Error: AUTHENTICATE failed.


  2. Sambit Kumar Das 16 Reputation points
    2022-11-30T10:27:55.847+00:00

    Hi All,

    I have followed all the instruction to create an application in the azure portal and go through the above code.

    But below error is coming

    <= '* OK The Microsoft Exchange IMAP4 service is ready. [UABOADMAUABSADAAMQBDAEEAMAAxADcAMwAuAEkATgBEAFAAUgBEADAAMQAuAFAAUgBPAEQALgBPAFUAVABMAE8ATwBLAC4AQwBPAE0A]'
    => 'A0 CAPABILITY'
    <= '* CAPABILITY IMAP4 IMAP4rev1 AUTH=PLAIN AUTH=XOAUTH2 SASL-IR UIDPLUS ID UNSELECT CHILDREN IDLE NAMESPACE LITERAL+'
    <= 'A0 OK CAPABILITY completed.'
    => 'A1 AUTHENTICATE XOAUTH2 dXNlcj1vYXRoLnZhbGlkYXRpb25AaW5vdmFhcmUuY29tXkFhdXRoPUJlYXJlciBleUowZVhBaU9pSktWMVFpTENKdWIyNWpaU0k2SWxKSFZuaExXREp1TTI5SFpDMTBkR2RXUmtOQlJVMVJMVFJ0YjJWa1NXZEhTVnAyY2t4UFltOWFZbFVpTENKaGJHY2lPaUpTVXpJMU5pSXNJbmcxZENJNklqSmFVWEJLTTFWd1ltcEJXVmhaUjJGWVJVcHNPR3hXTUZSUFNTSXNJbXRwWkNJNklqSmFVWEJLTTFWd1ltcEJXVmhaUjJGWVJVcHNPR3hXTUZSUFNTSjkuZXlKaGRXUWlPaUpvZEhSd2N6b3ZMMjkxZEd4dmIyc3ViMlptYVdObExtTnZiU0lzSW1semN5STZJbWgwZEhCek9pOHZjM1J6TG5kcGJtUnZkM011Ym1WMEx6VmpNR1V5TVRjMUxUTm1abUl0TkdVeFlpMDVORFEzTFRKaU56RTNNelU0TjJSbU5TOGlMQ0pwWVhRaU9qRTJOams0TURJME16VXNJbTVpWmlJNk1UWTJPVGd3TWpRek5Td2laWGh3SWpveE5qWTVPREEyTXpNMUxDSmhhVzhpT2lKRk1scG5XVkJvY1hCSWEzbDFjMFE0ZGxWMlJtZHdPRVp6ZWpONlFVRTlQU0lzSW1Gd2NGOWthWE53YkdGNWJtRnRaU0k2SWtWdFlXbHNUR2x6ZEdsdVpYSWlMQ0poY0hCcFpDSTZJamhpWWpjM05XSXlMVGc0WmpFdE5HSXhOQzA0TVRreExUVmtZak14TnpRNVl6bGxNaUlzSW1Gd2NHbGtZV055SWpvaU1TSXNJbWxrY0NJNkltaDBkSEJ6T2k4dmMzUnpMbmRwYm1SdmQzTXVibVYwTHpWak1HVXlNVGMxTFRObVptSXROR1V4WWkwNU5EUTNMVEppTnpFM016VTROMlJtTlM4aUxDSnZhV1FpT2lKa1l6a3pOelZoTXkxbFlqVTFMVFExTjJRdE9EWXdaUzFqWmpReE5UQTJPVFppT1RVaUxDSnlhQ0k2SWpBdVFWVnZRV1JUUlU5WVVITmZSekEyVlZKNWRIaGpNV2c1T1ZGSlFVRkJRVUZCVUVWUWVtZEJRVUZCUVVGQlFVTktRVUZCTGlJc0luSnZiR1Z6SWpwYkltWjFiR3hmWVdOalpYTnpYMkZ6WDJGd2NDSXNJbEJQVUM1QlkyTmxjM05CYzBGd2NDSXNJazFoYVd3dVVtVmhaQ0lzSWtsTlFWQXVRV05qWlhOelFYTkJjSEFpWFN3aWMybGtJam9pT1dJeVpHUTRPVFl0TkdZNE5TMDBNMlU0TFdKbE9HTXRNREEzT1dOa1ltRTNaRGRrSWl3aWMzVmlJam9pWkdNNU16YzFZVE10WldJMU5TMDBOVGRrTFRnMk1HVXRZMlkwTVRVd05qazJZamsxSWl3aWRHbGtJam9pTldNd1pUSXhOelV0TTJabVlpMDBaVEZpTFRrME5EY3RNbUkzTVRjek5UZzNaR1kxSWl3aWRYUnBJam9pT1hBMVdYcElWbEJFUlZka01FSnNlVWRTVVhoQlFTSXNJblpsY2lJNklqRXVNQ0lzSW5kcFpITWlPbHNpTURrNU4yRXhaREF0TUdReFpDMDBZV05pTFdJME1EZ3RaRFZqWVRjek1USXhaVGt3SWwxOS5hSmJ0dy1qeE12N2hVZzhEM2dfcGstRmZSSTBkOTZ6UzVpSUp6RjZ2TWVkOWZ4N1cyZW9ndlNCT3ZBV1RnOTJEUGtYZEpBdDZCV1VFdjZTRzZHa19VNllfS19fLTRxNE8ybEdRWmNCX2pUSkNJM18zNU9lbzladVluUE5HdXRvNVotbi1fYTEtNnk1eV9sLVJNbm41UDVRRUNLYTF5X3p6SFk2THBXbG9SQ2xqNHJPN2drbGxOS01xb0ZHbVY1YUV3SWpjQVNvRTlaVksxMFhwZm1LMkdJdGQ3bUZGdEV4NlE2dUhTWWRvZ1pvZkVmbk1PTUJrU3J4S3pGaERyNk5yUVhUQ3Mtc3doNmExXzAwM2pqWUt0UXhxU00zcUJOVmVjMVFUQjFvNS1ldFBGbEk3aENZanNnQzJEQkJPTEcxSHVkQkZPaUNDS0VKSkxtNlRUdWg2ekFeQV5B'
    <= 'A1 NO AUTHENTICATE failed.'
    Error: AUTHENTICATE failed.

    at Connection._resTagged (\node_modules\imap\lib\Connection.js:1502:11)
    at Parser.<anonymous> (\node_modules\imap\lib\Connection.js:194:10)
    at Parser.emit (events.js:400:28)
    at Parser._resTagged (\node_modules\imap\lib\Parser.js:175:10)
    at Parser._parse (\node_modules\imap\lib\Parser.js:139:16)
    at Parser._tryread (\node_modules\imap\lib\Parser.js:82:15)
    at TLSSocket.Parser._cbReadable (\node_modules\imap\lib\Parser.js:53:12)
    at TLSSocket.emit (events.js:400:28)
    at emitReadable_ (internal/streams/readable.js:555:12)
    at processTicksAndRejections (internal/process/task_queues.js:81:21) {
    type: 'no',
    textCode: undefined,
    source: 'authentication'

    }
    [connection] Ended
    [connection] Closed
    imapDisconnected

    0 comments No comments