UNPKG

urban-rivals-oauth

Version:

Module making connection with the Urban Rivals OAuth API.

254 lines (227 loc) 7.84 kB
import { URL } from 'url' import { OAuth } from 'oauth' /** * Token info * @typedef {Object} Token Token info * @property {string} token Token public * @property {string} secret Token secret */ /** * Query result * @typedef {Object} QueryResult Query result * @property {Object<String,*>} context reply context * @property {Object<String,*>} [items] reply items */ /** * This object allows to call API with javascript functions instead of passing call name as string. * For example, instead of doing `urOAuth.query('collections.getCollectionPage', { deckOnly: true })`, you can do `urOAuth.proxyClient.collections.getCollectionPage({ deckOnly: true })` * The parameters are the same as query parameters following the call name since the function uses proxies and bind. * The function still returns a promise. Please note as well that since proxies are used, you need to have an environment * which supports it. For node.js, you need node.js 6+. If you use it with a previous version, even with babel, it will likely fail. * @typedef {Object} UROAuthProxyClient Object allowing to directly call the API * @property {ApiCaller} characters Characters API * @property {ApiCaller} collections Collections API * @property {ApiCaller} forums Forums API * @property {ApiCaller} general General API * @property {ApiCaller} guilds Guilds API * @property {ApiCaller} market Market API * @property {ApiCaller} missions Missions API * @property {ApiCaller} players Players API */ /** * Object from proxyClient which allows direct API calls * @typedef {Object<string, ApiCallerFunction>} ApiCaller Object from proxyClient which allows direct API calls */ /** * @typedef {Function} ApiCallerFunction * @param {Object<String,*>} [params={}] Call params * @param {APIFilter} [filters={}] All filters you want on your query result * @param {Array<String>} [filters.itemsFilter=[]] Filter on items sent by the server * @param {Array<String>} [filters.contextFilter=[]] Filter on context sent by the server * @returns {Promise<QueryResult>} The query result */ /** * API Filters * @typedef {Object} APIFilter API Filters * @property {Array<String>} itemsFilter Filter on items sent by the server * @property {Array<String>} contextFilter Filter on context sent by the server */ /** * The Urban Rivals API * @type {UROAuth} * @extends {OAuth} */ class UROAuth extends OAuth { /** * query URL * @type {String} * @readonly */ static API_URL = 'https://www.urban-rivals.com/api' /** * Authorization URL * @type {String} * @readonly */ static AUTHORIZE_URL = `${this.API_URL}/auth/authorize.php` /** * * @param {Object} options API options * @param {String} options.key Application key * @param {String} options.secret Application secret * @param {String} [options.algorithm='HMAC-SHA1'] Signing method * @param {Function} [options.authorizeCallback=null] Callback called when authorized */ constructor({ key, secret, algorithm = 'HMAC-SHA1', authorizeCallback = null, }) { super( 'https://www.urban-rivals.com/api/auth/request_token.php', 'https://www.urban-rivals.com/api/auth/access_token.php', key, secret, '1.0', authorizeCallback, algorithm, ) /** * Request token * @type {Token} */ this.requestToken = {} /** * Access token * @type {Token} */ this.accessToken = {} } /** * Get request token * @return {Promise<Token>} */ getRequestToken() { return new Promise((resolve, reject) => { this.getOAuthRequestToken((err, token, token_secret) => { if (err) { reject(err) } else { const tokenObject = { token: token, secret: token_secret, } this.requestToken = tokenObject resolve(tokenObject) } }) }) } /** * Get access token from request token * @param {Token} [requestToken] Request token * @return {Promise<Token>} */ getAccessToken(requestToken = this.requestToken) { if (typeof requestToken === 'object' && requestToken.hasOwnProperty('requestToken')) { requestToken = requestToken.requestToken } return new Promise((resolve, reject) => { this.getOAuthAccessToken(requestToken.token, requestToken.secret, (err, accessToken, accessSecret, results) => { if(err) reject(err) else { this.accessToken = { token: accessToken, secret: accessSecret, } resolve(this.token) } }) }) } /** * Do one or more queries on the UR API * @param {Object} queries All queries to do * @param {String} queries.call Call name * @param {Object} [queries.params={}] params of the query * @param {Array} [queries.contextFilter=[]] filter on the received context attributes * @param {Array} [queries.itemsFilter=[]] filter on the received items attributes * @returns {Promise<Object<String,QueryResult>>} The queries results, indexed by the call name */ multipleQueries(...queries) { const queriesToDo = queries.map(({call, params = {}, contextFilter = [], itemsFilter = []}) => ({ call, params, contextFilter, itemsFilter, })) const jsonEncodedQuery = JSON.stringify(queriesToDo); return new Promise((resolve, reject) => { this.post(this.constructor.API_URL, this.accessToken.token, this.accessToken.secret, { request: jsonEncodedQuery, }, 'application/x-www-form-urlencoded', (err, response, result) => { if (err) { reject(err) } else { resolve(JSON.parse(response)) } }) }) } /** * Do one query * @param {String} call Call name * @param {Object<String,*>} [params={}] Call params * @param {APIFilter} [filters={}] All filters you want on your query result * @param {Array<String>} [filters.itemsFilter=[]] Filter on items sent by the server * @param {Array<String>} [filters.contextFilter=[]] Filter on context sent by the server * @returns {Promise<QueryResult>} The query result */ async query(call, params = {}, { itemsFilter = [], contextFilter = [] } = {}) { return (await this.multipleQueries({ call, params, itemsFilter, contextFilter, }))[call] } /** * Get the authorization URL for the player * @param [callbackUrl] The callback url for the query * @returns {string} The authorize URL */ getAuthorizeUrl(callbackUrl = '') { const authorizeUrl = new URL(this.constructor.AUTHORIZE_URL) authorizeUrl.searchParams.set('oauth_token', this.requestToken.token) if (callbackUrl) { authorizeUrl.searchParams.set('oauth_callback', callbackUrl) } return authorizeUrl.toString() } /** * Creates a proxy client to call API with syntaxic sugar * @returns {UROAuthProxyClient} The UROAuth proxy client */ get proxyClient() { return new Proxy({}, { get: (target, callGroup) => new Proxy({}, { get: (target, callName) => this.query.bind(this, `${callGroup}.${callName}`), set: () => false, deleteProperty: () => false, ownKeys: () => [], has: () => true, defineProperty: () => false, }), set: () => false, deleteProperty: () => false, ownKeys: () => [], has: () => true, defineProperty: () => false, }) } } export default UROAuth