Search code examples
node.jsoauth-2.0outlook

Read Outlook inbox with oauth2 authentication - error NO AUTHENTICATE failed


I'm trying to connect with node imap library to a Outlook email inbox.

Outlook need oauth2 authentication, this is my code that try to connect to IMAP server with oauth2 token retrieved by msal library.

I followed this guide: https://learn.microsoft.com/en-us/exchange/client-developer/legacy-protocols/how-to-authenticate-an-imap-pop-smtp-application-by-using-oauth

async function getMSToken(){

  let msalConfig = {
    auth: {
      clientId: "1cf7d7ff-*****************",
      authority: "https://login.microsoftonline.com/880c05e3-*****************",
      clientSecret: "azQ8Q~eU.*****************",
    }
  };

  const cca = new msal.ConfidentialClientApplication(msalConfig);

  let tokenRequest = {
    scopes: [ "https://graph.microsoft.com/.default" ],
  };

  let { accessToken } = await cca.acquireTokenByClientCredential(tokenRequest);
  console.log("accessToken", accessToken);

  let user = "*****************@*****************";

  return btoa('user=' + user + '^Aauth=Bearer ' + accessToken + '^A^A');

}

async function connect(){

  let token = await getMSToken();
  console.log("tokenConverted", token);

  imap = new Imap({
    xoauth2: token,
    host: 'outlook.office365.com',
    port: 993,
    tls: true,
    debug: console.log
  });

  imap.once("ready", () => {

    console.log("connected");

  });

  imap.once("error", function(err) {
    console.error("Error connecting", err);
  });

  console.log("connecting...");
  imap.connect();

}

The msal library return me an access token but when i tried to connect to IMAP server, this is the log of connection:

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

And these are the permissions on tenant:

enter image description here

If I try the scope https://outlook.office365.com/IMAP.AccessAsUser.All the response from msal library it's:

1002012 - [2022-10-24 14:46:27Z]: AADSTS1002012: The provided value for scope https://outlook.office365.com/IMAP.AccessAsUser.All is not valid. Client credential flows must have a scope value with /.default suffixed to the resource identifier (application ID URI).\r\n

What can I try? Thank you!


Solution

  • I have gone through the above code . And I fixed the problem in the following process.

    you can encode username, access token together in the following format and It will work.

     let base64Encoded =  Buffer.from([`user=${mailId}`, `auth=Bearer ${token}`, '', ''].join('\x01'), 'utf-8').toString('base64');
    
    var imap = new Imap({
           xoauth2: base64Encoded ,
           host: 'outlook.office365.com',
           port: 993,
           tls: true,
           debug: console.log,
           authTimeout: 25000,
           connTimeout: 30000,
           tlsOptions: {
             rejectUnauthorized: false,
             servername: 'outlook.office365.com'
          }
        });
    
    
    in this process I have fixed This above problem.
     and scope should be
    
    scopes:["https://outlook.office365.com/.default"]