//** REQUEST TYPES **// export const REQUEST_TYPE_POST = "POST"; export const REQUEST_TYPE_GET = "GET"; export const REQUEST_TYPE_PUT = "PUT"; export const REQUEST_TYPE_DELETE = "DELETE"; //** POST CONTENT TYPES **// export const CONTENT_TYPE_JSON = "json"; export const CONTENT_TYPE_FORM = "x-www-form-urlencoded"; //** API URLS **// export const API_STATUS = "/api/v1/status"; export const API_GET_NAV = "/api/settings/nav"; export const API_NEW_PAGE = "/api/v1/page/create"; export const API_EDIT_PAGE = "/api/v1/page/write"; export const API_DELETE_PAGE = "/api/v1/page/delete"; export const API_SETTINGS_SYNC = "/api/v1/settings/sync"; export const API_PUBLISH_PAGES = "/api/v1/settings/publish"; export const API_NAV_SYNC = "/api/v1/settings/nav-sync"; export const API_REINDEX_PAGES = "/api/v1/settings/reindex"; export const API_SEND_MAIL = "/api/v1/mailer"; export const API_LOGIN = "/api/v1/login"; //** API TASKS **// export const AUTH_STATUS = "getAuthStatus"; export const TASK_SETTINGS_WRITE = "writeSettings"; export const TASK_PUBLISH_SITE = "publishSite"; export const TASK_PAGE_CREATE = "createNewPage"; export const TASK_PAGE_EDIT = "editPage"; export const TASK_PAGE_DELETE = "deletePage"; export const TASK_SEND_MAIL = "sendMail"; export const TASK_REINDEX_PAGE = "reIndexPages"; //** API STATUS **// export const API_ACCESS_GOOD = "apiUseAuthorized"; export const API_ACCESS_BAD = "apiUseNotAuthorized"; /** * A can of methods used to edit install settings, navigation pages. */ class FipamoAdminAPI { /** * @constructor * @param {string} baseURL - url of site; uses local when empty * @param {string} key - user api key */ constructor(baseURL = null, key = null) { this.percentComplete = 0; //for later this.token = null; this.baseURL = null; this.key = null; if (key) this.key = key; if (baseURL) this.baseURL = baseURL; //if key is valid, checks to see if a session is active and returns this._request( this.baseURL ? this.baseURL + API_STATUS + "?key=" + this.key : API_STATUS + "?key=" + this.key ).then((response) => { if (response.type === API_ACCESS_GOOD) { this.token = response.token; } else { //don't set token //console.log("NO TOKEN"); } }); } /** * Promise method for checking credentials. Must login to use Admin API. * @param {object} data - json object that contains data for set up * @property {string} handle - handle for site user * @property {string} password - password for site user */ login(data) { return new Promise((resolve, reject) => { this.baseURL ? (data.remote = true) : (data.remote = false); this.key ? (data.key = this.key) : (data.key = null); this._request( this.baseURL ? this.baseURL + API_LOGIN : API_LOGIN, AUTH_STATUS, REQUEST_TYPE_POST, CONTENT_TYPE_JSON, data ) .then((result) => { resolve(result); }) .catch((err) => { reject(err); }); }); } /** * Method for saving settings * @param {object} data - json object that contains settings data set on the front-end * @property {string} global.base_url - base url for site * @property {string} global.title - site title * @property {string} global.descriptions - brief site summary * @property {string} global.background - url for site feature image for header * @property {boolean} global.private - privacy state for site [disabled] * @property {boolean} global.renderOnSave - property for publishing site when page saved [disabled] * @property {string} global.theme - current theme for site * @property {boolean} global.externalAPI - toggle for external API access * @property {string} member.handle - current member handle * @property {string} member.email - current member email * @property {string} email.active - current email protocol being used * @property {string} email.smtp.domain - url of smtp service being * @property {string} email.smtp.email - email account of smtp service * @property {string} email.smtp.password - password for email of smtp service * @property {string} email.mailgun.domain - mailgun domain url * @property {string} email.mailgun.key - mailgun key */ syncSettings(data) { return new Promise((resolve, reject) => { this._request( this.baseURL ? this.baseURL + API_SETTINGS_SYNC + "?key=" + this.key : API_SETTINGS_SYNC + "?key=" + this.key, TASK_SETTINGS_WRITE, REQUEST_TYPE_POST, CONTENT_TYPE_JSON, data ) .then((result) => { resolve(result); }) .catch((err) => { reject(err); }); }); } /** * Method for retrieving user authorizing user login * @param {object} data - json object that contains task * @property {string} task - publishing task [deprecated] */ publishSite(data) { return new Promise((resolve, reject) => { this._request( //API_PUBLISH_PAGES, this.baseURL ? this.baseURL + API_PUBLISH_PAGES : API_PUBLISH_PAGES, TASK_PUBLISH_SITE, REQUEST_TYPE_POST, CONTENT_TYPE_JSON, data ) .then((result) => { resolve(result); }) .catch((err) => { reject(err); }); }); } /** * Method for handling page creating and editing * @param {string} task - current page action * @param {object} data - form object that contains info for current page being edited/created * @property {string} id - sequence id for page * @property {string} uuid - unique identifier for page * @property {string} layout - current page layout * @property {string} current_title - saved url save title for persistence when changing title * @property {string} content - markdown body of page * @property {string} title - current title of page * @property {string} created - date page was created * @property {string} slug - url safe string of page title * @property {string} tags - comma separated list of tags * @property {boolean} menu - property that indicates page is included in site menu * @property {boolean} featured - property that indicates page is featured * @property {boolean} published - property that indicates page is public * @property {input} feature_image - main image for page */ pageActions(task, data) { let url, event, content; switch (task) { case TASK_PAGE_CREATE: url = API_NEW_PAGE; event = TASK_PAGE_CREATE; content = CONTENT_TYPE_FORM; break; case TASK_PAGE_EDIT: url = API_EDIT_PAGE; event = TASK_PAGE_EDIT; content = CONTENT_TYPE_FORM; break; case TASK_PAGE_DELETE: url = API_DELETE_PAGE; event = TASK_PAGE_DELETE; content = CONTENT_TYPE_JSON; break; default: break; } if (this.baseURL) { data.key = this.key; data.remote = true; } else { data.remote = false; } return new Promise((resolve, reject) => { this._request( this.baseURL ? this.baseURL + url : url, event, REQUEST_TYPE_POST, content, data ) .then((result) => { resolve(result); }) .catch((err) => { reject(err); }); }); } /** * Method for saving pages to be included in main site navigation * @param {object} data - json object that contains items to be included in main site navigation * @property {string} item.title - page title * @property {string} item.slug - url safe title * @property {string} item.uuid - unique identifier * @property {string} item.path - directory path to associated markdown file */ syncNav(data) { return new Promise((resolve, reject) => { this._request( this.baseURL ? this.baseURL + API_NAV_SYNC : API_NAV_SYNC, TASK_SETTINGS_WRITE, REQUEST_TYPE_POST, CONTENT_TYPE_JSON, data ) .then((result) => { resolve(result); }) .catch((err) => { reject(err); }); }); } /** * Method for sending mail * @param {object} message - json object that contains items to be included in main site navigation * @property {string} content - message to send */ sendMail(message) { return new Promise((resolve, reject) => { this._request( this.baseURL ? this.baseURL + API_SEND_MAIL : API_SEND_MAIL, TASK_SEND_MAIL, REQUEST_TYPE_POST, CONTENT_TYPE_JSON, message ) .then((result) => { resolve(result); }) .catch((err) => { reject(err); }); }); } /** * Maintenance method to clean up page sequencing [disabled] * @param {object} data - json object that contains items to be included in main site navigation */ reindexPages(data) { return new Promise((resolve, reject) => { this._request( this.baseURL ? this.baseURL + API_REINDEX_PAGES : API_REINDEX_PAGES, TASK_REINDEX_PAGE, REQUEST_TYPE_POST, CONTENT_TYPE_JSON, data ) .then((result) => { resolve(result); }) .catch((err) => { reject(err); }); }); } //-------------------------- // private //-------------------------- _request( requestURL, eventType, requestType = REQUEST_TYPE_GET, contentType = CONTENT_TYPE_JSON, requestData = null ) { var self = this; return new Promise(function (resolve, reject) { var request = new XMLHttpRequest(); request.upload.onprogress = self.handleLoadProgress; request.open(requestType, requestURL, true); request.onload = () => { if (request.status == 200) { let response = JSON.parse(request["response"]); resolve(response); } else { let error = JSON.parse(request["response"]); reject(error); } }; if (requestType == REQUEST_TYPE_PUT || requestType == REQUEST_TYPE_POST) { if ( eventType === TASK_SETTINGS_WRITE || eventType === TASK_PAGE_EDIT || eventType === TASK_PAGE_CREATE || eventType === TASK_PAGE_DELETE || eventType === TASK_PUBLISH_SITE || eventType === TASK_REINDEX_PAGE ) request.setRequestHeader("fipamo-access-token", self.token); switch (contentType) { case CONTENT_TYPE_JSON: request.setRequestHeader( "Content-type", "application/" + contentType ); request.send(JSON.stringify(requestData)); break; case CONTENT_TYPE_FORM: request.send(requestData); break; } } else { request.send(); } }); } //-------------------------- // event handlers //-------------------------- handleLoadProgress(e) { this.percentComplete = Math.ceil((e.loaded / e.total) * 100); //pass element to display request progress } } export { FipamoAdminAPI as default };