node-red-contrib-monzo
Version:
This is a wrapper that will allow a connection to the monzo bank API for use within node-red
275 lines (231 loc) • 12.2 kB
HTML
<script data-template-name="monzo-credentials" type="text/x-red">
<div class="form-row">
<label style="margin-left: 20px;" for="node-config-input-client_id"><span>Client ID</span></label>
<input type="text" id="node-config-input-client_id">
</div>
<div class="form-row">
<label style="margin-left: 20px;" for="node-config-input-secret"><span>Secret</span></label>
<input type="text" id="node-config-input-secret">
</div>
<div class="form-row" id="node-config-monzo-row"></div>
<div class="form-row" id="node-config-monzo-result-row"></div>
<div class="form-row">
<label style="margin-left: 20px;" for="node-config-input-token"><span>Access Token</span></label>
<input type="text" id="node-config-input-token">
</div>
<div class="form-row" id="node-config-monzo-refresh-type"></div>
</script>
<script data-help-name="monzo-credentials" type="text/x-red">
<p><h3>Path A</h3>For instant testing you will find a temporary access token when logged into the monzo developer website on the playground page. you can enter this directly into the access token field.<br><a href="https://developers.monzo.com/api/playground" target="_blank">https://developers.monzo.com/api/playground</a><br><br><h3>Path B</h3>To set up permanent access you must create a Monzo API client at<br><a href="https://developers.monzo.com/apps/home" target="_blank">https://developers.monzo.com/apps/home</a><br> so that you can get a Client ID and a API Secret.<br>Please note you *MUST* set the redirect url to <br><b>protocol+"//"+hostname+":"+port+"/monzo-creds</b><br><br>For Example: http://localhost:1880/monzo-creds<br><br>If you do not do this, you will <b>Not</b> be able to authenticate with your client.</p>
</script>
<script type="text/javascript">
(function() {
RED.nodes.registerType('monzo-credentials',{
category: 'config',
defaults: {
},
credentials: {
client_id: {type:"text"},
secret: {type:"password"},
token: {type:"text"}
},
label: function() {
return "Monzo: "+this.id
},
exportable: false,
oneditprepare: function() {
var monzoConfigNodeId = this.id;
function showMonzoAuthStart() {
/*
Checking if refresh token exists.
*/
var headers_dat = "";
if (localStorage.getItem("auth-tokens") !== null) {
// we have auth we need to set this on the poll request
tokens = JSON.parse(localStorage.getItem("auth-tokens"))
headers_dat = "Bearer "+tokens.access_token
}
$.ajax({
url: '/credentials/monzo-credentials/'+monzoConfigNodeId,
beforeSend: function(request) {
if(headers_dat != ""){
request.setRequestHeader("Authorization", headers_dat);
}
},
error: function() {
console.log("error");
},
success: function(data) {
if(data.token){
if (data.refreshtoken) {
$('#node-config-monzo-refresh-type').html("<center>(Token Refresh ON)</center><br><center>*This access token will refresh, only if node-red stays running*</center>")
} else {
$('#node-config-monzo-refresh-type').html("<center>(Token Refresh OFF)</center><br><center>*This access token will not automatically refresh*</center>")
}
}
},
type: 'GET'
});
/*
Setting ports to take into account all variations
*/
var portstring = "";
if(location.port == "80" || location.port == undefined || location.port == "443" || location.port == ""){
portstring = "";
} else {
portstring = ":"+location.port;
}
var callback = encodeURIComponent(location.protocol+"//"+location.hostname+portstring+"/monzo-creds");
var token = $('#node-config-input-token').val();
var button_txt = "";
if(token){
button_txt = "Re-Authorise With Monzo";
} else {
button_txt = "Authorise With Monzo";
}
$("#node-config-monzo-row").html('<div style="text-align: center; margin-top: 20px; "><span class="editor-button" id="node-config-monzo-start" >'+button_txt+'</span></div>');
/*
Capturing click event on the start button to initialise authentication process
*/
$("#node-config-monzo-start").click(function() {
var token = $('#node-config-input-token').val();
if(token){
$('#node-config-input-token').val("");
}
var client_id = $('#node-config-input-client_id').val();
var secret = $('#node-config-input-secret').val();
if(client_id != "" && secret != ""){
/*
In order to have correct clientid and secret upon return, we must set them in advance.
*/
var dataa = {"nodeid":monzoConfigNodeId,"clientid":client_id,"secret":secret, "redirect":(location.protocol+"//"+location.hostname+portstring+"/monzo-creds")};
//work around to stop popup blockage! open blank page first, then set url upon data set, seems to fool browsers.
window.open("about:blank", "loginpage");
$.ajax({
url: "/monzo-creds-set",
data: dataa,
error: function() {
console.log("error");
},
success: function(data) {
if(data == "success"){
/*
If set credentials succesfully, now open popup window with Oauth process
*/
window.open('https://auth.monzo.com/?client_id='+client_id+'&redirect_uri='+callback+'&response_type=code&state='+monzoConfigNodeId+'', 'loginpage');
$("#node-config-dialog-ok").button("disable");
monzoConfigNodeIntervalId = window.setTimeout(pollMonzoCredentials,2000);
}
},
type: 'GET'
});
} else {
//If no client or secret do not run auth proccess, display they need to fill it out.
$("#node-config-monzo-result-row").html('Please enter in your "clientid" and "secret"');
}
});
}
function updateMonzoToken(token, refresh_token) {
$("#node-config-input-token").val(token);
if(token){
$("#node-config-monzo-result-row").html('<span style="color:green">Successfully retrieved access token.</span>');
}
if(token && refresh_token){
$("#node-config-monzo-result-row").html('<span style="color:green">Successfully retrieved access token and refresh token</span>');
}
}
function pollMonzoCredentials(e) {
var headers_dat = "";
if (localStorage.getItem("auth-tokens") !== null) {
// we have auth we need to set this on the poll request
tokens = JSON.parse(localStorage.getItem("auth-tokens"))
headers_dat = "Bearer "+tokens.access_token
}
$.ajax({
url: '/credentials/monzo-credentials/'+monzoConfigNodeId,
beforeSend: function(request) {
if(headers_dat != ""){
request.setRequestHeader("Authorization", headers_dat);
}
},
error: function() {
console.log("error");
},
success: function(data) {
if (data.token) {
updateMonzoToken(data.token, data.refreshtoken);
monzoConfigNodeIntervalId = null;
$("#node-config-dialog-ok").button("enable");
} else {
monzoConfigNodeIntervalId = window.setTimeout(pollMonzoCredentials,2000);
}
},
type: 'GET'
});
}
/*
initialise auth start for credential node
*/
showMonzoAuthStart();
}
});
})();
</script>
<script type="text/javascript">
RED.nodes.registerType('monzo-in',{
category: 'banking',
color: '#F3AAA9',
defaults: {
name:{value:""},
monzocreds: {type:"monzo-credentials",required:true},
requesttype:{value:"accounts"},
responsetype:{value:"stream"}
},
inputs:1,
outputs:1,
icon: "monzo.png",
label: function() {
return this.name||"monzo in";
},
paletteLabel:function(){
return "monzo in";
},
oneditprepare: function() {
$('#node-input-requesttype').on("change", function(e){
$('.responsetype-row').hide();
var val = $(this).val();
if(val == "pots" ){
$('.responsetype-row').show();
}
});
}
});
</script>
<script data-template-name="monzo-in" type="text/x-red">
<div class="form-row">
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Node Name">
</div>
<div class="form-row">
<label for="node-input-monzocreds"><i class="fa fa-user" style="width:14px"></i> <span > Auth</span></label>
<input type="text" id="node-input-monzocreds">
</div>
<div class="form-row">
<label for="node-input-requesttype"><i class="icon-tag"></i> Request</label>
<select id="node-input-requesttype">
<option value="accounts">all accounts</>
<option value="balances">all balances</>
<option value="pots">all pots</>
</select>
</div>
<div class="form-row responsetype-row" style="display:none">
<label for="node-input-responsetype"><i class="icon-tag"></i> Output As</label>
<select id="node-input-responsetype">
<option value="stream" selected>stream of responses</>
<option value="single">single response</>
</select>
</div>
</script>
<script data-help-name="monzo-in" type="text/x-red">
<p>This is a monzo input node that will allow a connection to the monzo bank API to retrieve information.</p>
</script>