You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
218 lines
9.3 KiB
JavaScript
218 lines
9.3 KiB
JavaScript
"use strict";
|
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
});
|
|
};
|
|
var __importStar = (this && this.__importStar) || function (mod) {
|
|
if (mod && mod.__esModule) return mod;
|
|
var result = {};
|
|
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
|
result["default"] = mod;
|
|
return result;
|
|
}
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const node_rest_client_1 = require("node-rest-client");
|
|
const settings = __importStar(require("./settings"));
|
|
const log_1 = require("./log");
|
|
exports.currentLogin = null;
|
|
/** Check for existing login */
|
|
function loggedIn() {
|
|
return (exports.currentLogin !== null);
|
|
}
|
|
exports.loggedIn = loggedIn;
|
|
/** Initialise client and configs */
|
|
exports.client = new node_rest_client_1.Client();
|
|
exports.host = settings.host;
|
|
/**
|
|
* Prepend protocol (or put back if removed from env settings for driver)
|
|
* Hard code endpoint prefix, because all syntax depends on this version
|
|
*/
|
|
exports.url = ((exports.host.indexOf('http') === -1)
|
|
? exports.host.replace(/^(\/\/)?/, 'http://')
|
|
: exports.host) + '/api/v1/';
|
|
/** Convert payload data to query string for GET requests */
|
|
function getQueryString(data) {
|
|
if (!data || typeof data !== 'object' || !Object.keys(data).length)
|
|
return '';
|
|
return '?' + Object.keys(data).map((k) => {
|
|
const value = (typeof data[k] === 'object')
|
|
? JSON.stringify(data[k])
|
|
: encodeURIComponent(data[k]);
|
|
return `${encodeURIComponent(k)}=${value}`;
|
|
}).join('&');
|
|
}
|
|
exports.getQueryString = getQueryString;
|
|
/** Setup default headers with empty auth for now */
|
|
exports.basicHeaders = { 'Content-Type': 'application/json' };
|
|
exports.authHeaders = { 'X-Auth-Token': '', 'X-User-Id': '' };
|
|
/** Populate auth headers (from response data on login) */
|
|
function setAuth(authData) {
|
|
exports.authHeaders['X-Auth-Token'] = authData.authToken;
|
|
exports.authHeaders['X-User-Id'] = authData.userId;
|
|
}
|
|
exports.setAuth = setAuth;
|
|
/** Join basic headers with auth headers if required */
|
|
function getHeaders(authRequired = false) {
|
|
if (!authRequired)
|
|
return exports.basicHeaders;
|
|
if ((!('X-Auth-Token' in exports.authHeaders) || !('X-User-Id' in exports.authHeaders)) ||
|
|
exports.authHeaders['X-Auth-Token'] === '' ||
|
|
exports.authHeaders['X-User-Id'] === '') {
|
|
throw new Error('Auth required endpoint cannot be called before login');
|
|
}
|
|
return Object.assign({}, exports.basicHeaders, exports.authHeaders);
|
|
}
|
|
exports.getHeaders = getHeaders;
|
|
/** Clear headers so they can't be used without logging in again */
|
|
function clearHeaders() {
|
|
delete exports.authHeaders['X-Auth-Token'];
|
|
delete exports.authHeaders['X-User-Id'];
|
|
}
|
|
exports.clearHeaders = clearHeaders;
|
|
/** Check result data for success, allowing override to ignore some errors */
|
|
function success(result, ignore) {
|
|
return ((typeof result.error === 'undefined' &&
|
|
typeof result.status === 'undefined' &&
|
|
typeof result.success === 'undefined') ||
|
|
(result.status && result.status === 'success') ||
|
|
(result.success && result.success === true) ||
|
|
(ignore && result.error && !ignore.test(result.error))) ? true : false;
|
|
}
|
|
exports.success = success;
|
|
/**
|
|
* Do a POST request to an API endpoint.
|
|
* If it needs a token, login first (with defaults) to set auth headers.
|
|
* @todo Look at why some errors return HTML (caught as buffer) instead of JSON
|
|
* @param endpoint The API endpoint (including version) e.g. `chat.update`
|
|
* @param data Payload for POST request to endpoint
|
|
* @param auth Require auth headers for endpoint, default true
|
|
* @param ignore Allows certain matching error messages to not count as errors
|
|
*/
|
|
function post(endpoint, data, auth = true, ignore) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
try {
|
|
log_1.logger.debug(`[API] POST: ${endpoint}`, JSON.stringify(data));
|
|
if (auth && !loggedIn())
|
|
yield login();
|
|
let headers = getHeaders(auth);
|
|
const result = yield new Promise((resolve, reject) => {
|
|
exports.client.post(exports.url + endpoint, { headers, data }, (result) => {
|
|
if (Buffer.isBuffer(result))
|
|
reject('Result was buffer (HTML, not JSON)');
|
|
else if (!success(result, ignore))
|
|
reject(result);
|
|
else
|
|
resolve(result);
|
|
}).on('error', (err) => reject(err));
|
|
});
|
|
log_1.logger.debug('[API] POST result:', result);
|
|
return result;
|
|
}
|
|
catch (err) {
|
|
console.error(err);
|
|
log_1.logger.error(`[API] POST error (${endpoint}):`, err);
|
|
}
|
|
});
|
|
}
|
|
exports.post = post;
|
|
/**
|
|
* Do a GET request to an API endpoint
|
|
* @param endpoint The API endpoint (including version) e.g. `users.info`
|
|
* @param data Object to serialise for GET request query string
|
|
* @param auth Require auth headers for endpoint, default true
|
|
* @param ignore Allows certain matching error messages to not count as errors
|
|
*/
|
|
function get(endpoint, data, auth = true, ignore) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
try {
|
|
log_1.logger.debug(`[API] GET: ${endpoint}`, data);
|
|
if (auth && !loggedIn())
|
|
yield login();
|
|
let headers = getHeaders(auth);
|
|
const query = getQueryString(data);
|
|
const result = yield new Promise((resolve, reject) => {
|
|
exports.client.get(exports.url + endpoint + query, { headers }, (result) => {
|
|
if (Buffer.isBuffer(result))
|
|
reject('Result was buffer (HTML, not JSON)');
|
|
else if (!success(result, ignore))
|
|
reject(result);
|
|
else
|
|
resolve(result);
|
|
}).on('error', (err) => reject(err));
|
|
});
|
|
log_1.logger.debug('[API] GET result:', result);
|
|
return result;
|
|
}
|
|
catch (err) {
|
|
log_1.logger.error(`[API] GET error (${endpoint}):`, err);
|
|
}
|
|
});
|
|
}
|
|
exports.get = get;
|
|
/**
|
|
* Login a user for further API calls
|
|
* Result should come back with a token, to authorise following requests.
|
|
* Use env default credentials, unless overridden by login arguments.
|
|
*/
|
|
function login(user = {
|
|
username: settings.username,
|
|
password: settings.password
|
|
}) {
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
log_1.logger.info(`[API] Logging in ${user.username}`);
|
|
if (exports.currentLogin !== null) {
|
|
log_1.logger.debug(`[API] Already logged in`);
|
|
if (exports.currentLogin.username === user.username) {
|
|
return exports.currentLogin.result;
|
|
}
|
|
else {
|
|
yield logout();
|
|
}
|
|
}
|
|
const result = yield post('login', user, false);
|
|
if (result && result.data && result.data.authToken) {
|
|
exports.currentLogin = {
|
|
result: result,
|
|
username: user.username,
|
|
authToken: result.data.authToken,
|
|
userId: result.data.userId
|
|
};
|
|
setAuth(exports.currentLogin);
|
|
log_1.logger.info(`[API] Logged in ID ${exports.currentLogin.userId}`);
|
|
return result;
|
|
}
|
|
else {
|
|
throw new Error(`[API] Login failed for ${user.username}`);
|
|
}
|
|
});
|
|
}
|
|
exports.login = login;
|
|
/** Logout a user at end of API calls */
|
|
function logout() {
|
|
if (exports.currentLogin === null) {
|
|
log_1.logger.debug(`[API] Already logged out`);
|
|
return Promise.resolve();
|
|
}
|
|
log_1.logger.info(`[API] Logging out ${exports.currentLogin.username}`);
|
|
return get('logout', null, true).then(() => {
|
|
clearHeaders();
|
|
exports.currentLogin = null;
|
|
});
|
|
}
|
|
exports.logout = logout;
|
|
/** Defaults for user queries */
|
|
exports.userFields = { name: 1, username: 1, status: 1, type: 1 };
|
|
/** Query helpers for user collection requests */
|
|
exports.users = {
|
|
all: (fields = exports.userFields) => get('users.list', { fields }).then((r) => r.users),
|
|
allNames: () => get('users.list', { fields: { 'username': 1 } }).then((r) => r.users.map((u) => u.username)),
|
|
allIDs: () => get('users.list', { fields: { '_id': 1 } }).then((r) => r.users.map((u) => u._id)),
|
|
online: (fields = exports.userFields) => get('users.list', { fields, query: { 'status': { $ne: 'offline' } } }).then((r) => r.users),
|
|
onlineNames: () => get('users.list', { fields: { 'username': 1 }, query: { 'status': { $ne: 'offline' } } }).then((r) => r.users.map((u) => u.username)),
|
|
onlineIds: () => get('users.list', { fields: { '_id': 1 }, query: { 'status': { $ne: 'offline' } } }).then((r) => r.users.map((u) => u._id))
|
|
};
|
|
//# sourceMappingURL=api.js.map
|