Created
December 18, 2017 09:47
-
-
Save mkhahani/4b351f552349e64fd66455448a762697 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Nuve client API | |
* | |
* @author aalonsog@dit.upm.es | |
* @author prodriguez@dit.upm.es | |
* @author jcervino@dit.upm.es | |
*/ | |
const crypto = require('crypto'); | |
const XHR = require('./xmlhttprequest'); | |
const N = { | |
version: 0.1, | |
}; | |
N.API = (function nuveApi(N) { | |
const params = { | |
service: undefined, | |
key: undefined, | |
url: undefined, | |
}; | |
const init = (service, key, url) => { | |
N.API.params.service = service; | |
N.API.params.key = key; | |
N.API.params.url = url; | |
}; | |
const getRooms = params => send( | |
'GET', | |
undefined, | |
'rooms', | |
params | |
); | |
const getRoom = (room, params) => send( | |
'GET', | |
undefined, | |
`rooms/${room}`, | |
params | |
); | |
const createRoom = async (name, options, params) => { | |
if (!options) { | |
options = {}; | |
} | |
const room = await send( | |
'POST', | |
{ name, options }, | |
'rooms', | |
params | |
); | |
return JSON.parse(room); | |
}; | |
const updateRoom = (room, name, options, params) => send( | |
'PUT', | |
{ name, options }, | |
`rooms/${room}`, | |
params | |
); | |
const patchRoom = (room, name, options, params) => send( | |
'PATCH', | |
{ name, options }, | |
`rooms/${room}`, | |
params | |
); | |
const deleteRoom = (room, params) => send( | |
'DELETE', | |
undefined, | |
`rooms/${room}`, | |
params | |
); | |
const createToken = (room, username, role, params) => send( | |
'POST', | |
undefined, | |
`rooms/${room}/tokens`, | |
params, | |
username, | |
role | |
); | |
const createService = (name, key, params) => send( | |
'POST', | |
{ name, key }, | |
'services/', | |
params | |
); | |
const getServices = params => send( | |
'GET', | |
undefined, | |
'services/', | |
params | |
); | |
const getService = (service, params) => send( | |
'GET', | |
undefined, | |
`services/${service}`, | |
params | |
); | |
const deleteService = (service, params) => send( | |
'DELETE', | |
undefined, | |
`services/${service}`, | |
params | |
); | |
const getUsers = (room, params) => send( | |
'GET', | |
undefined, | |
`rooms/${room}/users/`, | |
params | |
); | |
const getUser = (room, user, params) => send( | |
'GET', | |
undefined, | |
`rooms/${room}/users/${user}`, | |
params | |
); | |
const deleteUser = (room, user, params) => send( | |
'DELETE', | |
undefined, | |
`rooms/${room}/users/${user}`, | |
params | |
); | |
const send = (method, body, url, params, username, role) => { | |
let service; | |
let key; | |
if (params === undefined) { | |
service = N.API.params.service; | |
key = N.API.params.key; | |
url = N.API.params.url + url; | |
} else { | |
service = params.service; | |
key = params.key; | |
url = params.url + url; | |
} | |
let header = 'MAuth realm=http://marte3.dit.upm.es,mauth_signature_method=HMAC_SHA1'; | |
const req = new XHR(); | |
const promise = new Promise((resolve, reject) => { | |
if (service === '' || key === '') { | |
console.log('ServiceID and Key are required!!'); | |
return; | |
} | |
const timestamp = new Date().getTime(); | |
const cnounce = Math.floor(Math.random() * 99999); | |
let toSign = `${timestamp},${cnounce}`; | |
if (username && role) { | |
username = formatString(username); | |
header += ',mauth_username='; | |
header += username; | |
header += ',mauth_role='; | |
header += role; | |
toSign += `,${username},${role}`; | |
} | |
const signed = calculateSignature(toSign, key); | |
header += ',mauth_serviceid='; | |
header += service; | |
header += ',mauth_cnonce='; | |
header += cnounce; | |
header += ',mauth_timestamp='; | |
header += timestamp; | |
header += ',mauth_signature='; | |
header += signed; | |
req.onreadystatechange = () => { | |
if (req.readyState === 4) { | |
switch (req.status) { | |
case 100: | |
case 200: | |
case 201: | |
case 202: | |
case 203: | |
case 204: | |
case 205: | |
resolve(req.responseText); | |
break; | |
default: | |
reject(new Error(`${req.status} Error${req.responseText}`)); | |
} | |
} | |
}; | |
}); | |
req.open(method, url, true); | |
req.setRequestHeader('Authorization', header); | |
if (body !== undefined) { | |
req.setRequestHeader('Content-Type', 'application/json'); | |
req.send(JSON.stringify(body)); | |
} else { | |
req.send(); | |
} | |
return promise; | |
}; | |
const calculateSignature = (toSign, key) => { | |
const hex = crypto.createHmac('sha1', key) | |
.update(toSign) | |
.digest('hex'); | |
return Buffer.from(hex).toString('base64'); | |
}; | |
const formatString = (s) => { | |
let r = s.toLowerCase(); | |
const nonAsciis = { | |
a: '[àáâãäå]', | |
ae: 'æ', | |
c: 'ç', | |
e: '[èéêë]', | |
i: '[ìíîï]', | |
n: 'ñ', | |
o: '[òóôõö]', | |
oe: 'œ', | |
u: '[ùúûűü]', | |
y: '[ýÿ]', | |
}; | |
for (const i in nonAsciis) { | |
if (nonAsciis.hasOwnProperty(i)) { | |
r = r.replace(new RegExp(nonAsciis[i], 'g'), i); | |
} | |
} | |
return r; | |
}; | |
return { | |
params, | |
init, | |
getRooms, | |
getRoom, | |
createRoom, | |
updateRoom, | |
patchRoom, | |
deleteRoom, | |
createToken, | |
createService, | |
getServices, | |
getService, | |
deleteService, | |
getUsers, | |
getUser, | |
deleteUser, | |
}; | |
}(N)); | |
module.exports = N; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment