UNPKG

node-red-contrib-viseo-ms-graph

Version:

VISEO Bot Maker - Microsoft Graph

296 lines (254 loc) 9.52 kB
const helper = require('node-red-viseo-helper'); const request = require('request-promise'); const uuidv4 = require('uuid/v4'); // -------------------------------------------------------------------------- // NODE-RED // -------------------------------------------------------------------------- module.exports = function (RED) { const register = function (config) { RED.nodes.createNode(this, config); config.redirect = this.credentials.redirect; config.username = this.credentials.username; config.password = this.credentials.password; config.config = RED.nodes.getCredentials(config.config); let node = this; this.on('input', (data) => { input(RED, node, data, config) }); } RED.nodes.registerType("ms-graph", register, { credentials : { redirect: { type: "text" }, username: { type: "text" }, password: { type: "text" } } }); } async function input(RED, node, data, config) { // Log activity try { setTimeout(function() { helper.trackActivities(node)},0); } catch(err) { console.log(err); } let action = config.action; let output = config.output || "payload"; let redirect = helper.getContextValue(RED, node, data, config.redirect, config.redirectType); let state = helper.getContextValue(RED, node, data, config.state, config.stateType); let scope = helper.getContextValue(RED, node, data, config.scope, config.scopeType); let authority = helper.getContextValue(RED, node, data, config.authority, config.authorityType); scope = scope || 'User.Read'; scope = scope.toLowerCase().replace(/,/g,' '); let credentials = { 'authority': authority || 'https://login.microsoftonline.com/viseo.com', 'authorize_endpoint': '/oauth2/v2.0/authorize', 'end_session': '/oauth2/v2.0/logout', 'token_endpoint': '/oauth2/v2.0/token', 'client_id': config.config.clientid, 'client_secret': config.config.clientsecret, 'redirect_uri': redirect, 'scope': scope, 'state': state } if (action === "auth") { let url = getAuthUrl(credentials); if (!url) node.error("Information missing"); helper.setContextValue(RED, node, data, output, url, config.outputType); return node.send(data); } if (action === "unauth") { let url = getUnauthUrl(credentials); if (!url) node.error("Information missing"); helper.setContextValue(RED, node, data, output, url, config.outputType); return node.send(data); } if (action === "token-code") { let code = helper.getContextValue(RED, node, data, config.code, config.codeType); if (!code) return node.error("Code missing"); try { let json = await getTokenFromCode(credentials, code); helper.setContextValue(RED, node, data, output, JSON.parse(json), config.outputType); return node.send(data); } catch (err) { node.error(err); helper.setContextValue(RED, node, data, output, "ERROR", config.outputType); return node.send(data); } } if (action === "token-password") { let username = helper.getContextValue(RED, node, data, config.username, config.usernameType); let password = helper.getContextValue(RED, node, data, config.password, config.passwordType); if (!username || !password) return node.error("Credentials missing"); try { let json = await getTokenFromPass(credentials, username, password); helper.setContextValue(RED, node, data, output, JSON.parse(json), config.outputType); return node.send(data); } catch (err) { node.error(err); helper.setContextValue(RED, node, data, output, "ERROR", config.outputType); return node.send(data); } } if (action === "token-code-refresh") { let refresh = helper.getContextValue(RED, node, data, config.refresh, config.refreshType); if (!refresh) node.error("Refresh missing"); try { let json = await getTokenFromRefresh(credentials, refresh); helper.setContextValue(RED, node, data, output, JSON.parse(json), config.outputType); return node.send(data); } catch (err) { node.error(err); } } if (action === "user") { let token = helper.getContextValue(RED, node, data, config.token, config.tokenType); if (!token) return node.error("Token missing"); try { let json = await getUser(token); helper.setContextValue(RED, node, data, output, JSON.parse(json), config.outputType); return node.send(data); } catch (err) { node.error(err); helper.setContextValue(RED, node, data, output, "ERROR", config.outputType); return node.send(data); } } if (action === "photo") { let token = config.token; if (config.tokenType !== 'str') { let loc = (config.tokenType === 'global') ? node.context().global : data; token = helper.getByString(loc, token); } if (!token) return node.error("Token missing"); try { let picture = await getUserPhoto(token); helper.setByString(outLoc, output, picture); return node.send(data); } catch (err) { node.error(err); helper.setByString(outLoc, output, "ERROR"); return node.send(data); } } if (action === "rooms") { let token = helper.getContextValue(RED, node, data, config.token, config.tokenType); if (!token) return node.error("Token missing"); try { let json = await getRooms(token); helper.setContextValue(RED, node, data, output, JSON.parse(json), config.outputType); return node.send(data); } catch (err) { node.error(err); helper.setContextValue(RED, node, data, output, "ERROR", config.outputType); return node.send(data); } } } // -------------------------------------------------------------------------- // LIBRARY // -------------------------------------------------------------------------- const getAuthUrl = (CREDENTIALS) => { if (!CREDENTIALS.client_id || !CREDENTIALS.redirect_uri || !CREDENTIALS.scope) return ""; let url = CREDENTIALS.authority + CREDENTIALS.authorize_endpoint + '?client_id=' + CREDENTIALS.client_id + '&response_type=code'; url += '&redirect_uri=' + CREDENTIALS.redirect_uri + '&scope=' + CREDENTIALS.scope + '&response_mode=query&state=' + CREDENTIALS.state; url += '&nonce=' + uuidv4(); return url; } const getUnauthUrl = (CREDENTIALS) => { let url = CREDENTIALS.authority + CREDENTIALS.end_session + '?state=' + CREDENTIALS.state; url += '&post_logout_redirect_uri=' + CREDENTIALS.redirect_uri; return url; } async function getTokenFromCode(CREDENTIALS, code) { let req = { method: "POST", uri: CREDENTIALS.authority + CREDENTIALS.token_endpoint, formData: { grant_type: 'authorization_code', client_id: CREDENTIALS.client_id, client_secret: CREDENTIALS.client_secret, scope: CREDENTIALS.scope, code: code, redirect_uri: CREDENTIALS.redirect_uri } }; return request(req); } async function getTokenFromPass(CREDENTIALS, username, password) { let req = { method: "POST", uri: CREDENTIALS.authority + CREDENTIALS.token_endpoint, formData: { grant_type: 'password', client_id: CREDENTIALS.client_id, client_secret: CREDENTIALS.client_secret, scope: CREDENTIALS.scope, username: username, password: password } }; return request(req) } async function getTokenFromRefresh(CREDENTIALS, refresh) { let req = { method: "POST", uri: CREDENTIALS.authority + CREDENTIALS.token_endpoint, formData: { grant_type: 'refresh_token', client_id: CREDENTIALS.client_id, client_secret: CREDENTIALS.client_secret, scope: CREDENTIALS.scope, refresh_token: refresh, redirect_uri: CREDENTIALS.redirect_uri } }; return request(req); } async function getUser(access) { let req = { method: "GET", uri: "https://graph.microsoft.com/v1.0/me/", headers: { "Authorization": "Bearer " + access, "Content-Type": "application/json" } }; return request(req); } async function getUserPhoto(access) { let result = {}; let buffer = { method: "GET", encoding: null, uri: "https://graph.microsoft.com/v1.0/me/photo/$value", headers: { "Authorization": "Bearer " + access, "Content-Type": "application/json" } }; let metadata = { method: "GET", uri: "https://graph.microsoft.com/v1.0/me/photo", headers: { "Authorization": "Bearer " + access, "Content-Type": "application/json" } }; result.buffer = await request(buffer); result.buffer = Buffer.from(result.buffer); result.metadata = await request(metadata); result.metadata = JSON.parse(result.metadata); return result; } async function getRooms(access) { let req = { method: "GET", uri: "https://graph.microsoft.com/beta/me/findRooms", headers: { "Authorization": "Bearer " + access, "Content-Type": "application/json" } }; return request(req); }