XOAUTH2 IMAP

Minor UI changes. Exposing only XOAuth2. Picks up raw access token from input message specified.

Only works for IMAP
Token formatted by node for Exchange and GMail, won't work on other providers.
Only works on trigger, not timer

TODO:
Add POP XOAUTH2 capability
Add SMTP XOAUTH2 capability
Add option to pass SASL XAOUTH2 token rather than raw OAUTH2 token
This commit is contained in:
wooferguy 2023-02-09 14:58:25 +13:00
parent 92578322d6
commit de40c4b817
2 changed files with 87 additions and 17 deletions

View File

@ -146,7 +146,6 @@
<label for="node-input-authtype"><i class="fa fa-tasks"></i> <span data-i18n="email.label.authtype"></span></label>
<select type="text" id="node-input-authtype">
<option value="BASIC">Basic</option>
<option value="OAUTH">OAuth</option>
<option value="XOAUTH2">XOAuth2</option>
</select>
</div>
@ -160,7 +159,7 @@
</div>
<div class="form-row node-input-token" style="display: none;">
<label for="node-input-token"><i class="fa fa-lock"></i> <span data-i18n="email.label.token"></span></label>
<input type="text" id="node-input-token">
<input type="text" id="node-input-token" placeholder="oauth2Response.access_token">
</div>
<div class="form-row node-input-box">
<label for="node-input-box"><i class="fa fa-inbox"></i> <span data-i18n="email.label.folder"></span></label>
@ -260,7 +259,8 @@
useSSL: {value: true},
autotls: {value: "never"},
port: {value:"993",required:true},
authentication: {value: "BASIC", required:true},
authtype: {value: "BASIC"},
token: {value: "oauth2Response.access_token"},
box: {value:"INBOX"}, // For IMAP, The mailbox to process
disposition: { value: "Read" }, // For IMAP, the disposition of the read email
criteria: {value: "UNSEEN"},
@ -271,7 +271,6 @@
credentials: {
userid: {type:"text"},
password: {type: "password"},
token: {type:"text"},
global: { type:"boolean"}
},
inputs: 0,
@ -322,6 +321,10 @@
$("#node-input-fetch").change();
}
});
$("#node-input-token").typedInput({
type:'msg',
types:['msg']
});
}
});
})();

View File

@ -197,9 +197,11 @@ module.exports = function(RED) {
this.box = n.box || "INBOX";
this.useSSL= n.useSSL;
this.autotls= n.autotls;
this.token = n.token || "oAuth2Response.access_token";
this.protocol = n.protocol || "IMAP";
this.disposition = n.disposition || "None"; // "None", "Delete", "Read"
this.criteria = n.criteria || "UNSEEN"; // "ALL", "ANSWERED", "FLAGGED", "SEEN", "UNANSWERED", "UNFLAGGED", "UNSEEN"
this.authtype = n.authtype || "BASIC";
var flag = false;
@ -367,6 +369,45 @@ module.exports = function(RED) {
var s = false;
var ss = false;
function checkIMAP(msg,send,done) {
var tout = (node.repeat > 0) ? node.repeat - 500 : 15000;
var saslxoauth2 = "";
if(node.authtype == "XOAUTH2") {
var value = RED.util.getMessageProperty(msg,node.token);
if (value !== undefined) {
//Make base64 string for access - compatible with outlook365 and gmail
saslxoauth2 = Buffer.from("user="+node.userid+"\x01auth=Bearer "+value+"\x01\x01").toString('base64');
}
imap = new Imap({
xoauth2: saslxoauth2,
host: node.inserver,
port: node.inport,
tls: node.useSSL,
autotls: node.autotls,
tlsOptions: { rejectUnauthorized: false },
connTimeout: tout,
authTimeout: tout
});
} else {
imap = new Imap({
user: node.userid,
password: node.password,
host: node.inserver,
port: node.inport,
tls: node.useSSL,
autotls: node.autotls,
tlsOptions: { rejectUnauthorized: false },
connTimeout: tout,
authTimeout: tout
});
}
imap.on('error', function(err) {
if (err.errno !== "ECONNRESET") {
s = false;
node.error(err.message,err);
node.status({fill:"red",shape:"ring",text:"email.status.connecterror"});
}
setInputRepeatTimeout();
});
//console.log("Checking IMAP for new messages");
// We get back a 'ready' event once we have connected to imap
s = true;
@ -521,19 +562,45 @@ module.exports = function(RED) {
}
} // End of checkEmail
if (node.protocol === "IMAP") {
/* if (node.protocol === "IMAP") {
var tout = (node.repeat > 0) ? node.repeat - 500 : 15000;
imap = new Imap({
user: node.userid,
password: node.password,
host: node.inserver,
port: node.inport,
tls: node.useSSL,
autotls: node.autotls,
tlsOptions: { rejectUnauthorized: false },
connTimeout: tout,
authTimeout: tout
});
if(node.authentication == "OAUTH") {
imap = new Imap({
user: node.userid,
oauth: node.token,
host: node.inserver,
port: node.inport,
tls: node.useSSL,
autotls: node.autotls,
tlsOptions: { rejectUnauthorized: false },
connTimeout: tout,
authTimeout: tout
});
} else if(node.authentication == "XOAUTH2") {
imap = new Imap({
user: node.userid,
xoauth2: node.token,
host: node.inserver,
port: node.inport,
tls: node.useSSL,
autotls: node.autotls,
tlsOptions: { rejectUnauthorized: false },
connTimeout: tout,
authTimeout: tout
});
} else {
imap = new Imap({
user: node.userid,
password: node.password,
host: node.inserver,
port: node.inport,
tls: node.useSSL,
autotls: node.autotls,
tlsOptions: { rejectUnauthorized: false },
connTimeout: tout,
authTimeout: tout
});
}
imap.on('error', function(err) {
if (err.errno !== "ECONNRESET") {
s = false;
@ -542,7 +609,7 @@ module.exports = function(RED) {
}
setInputRepeatTimeout();
});
}
}*/
node.on("input", function(msg, send, done) {
send = send || function() { node.send.apply(node,arguments) };