From a9851c0d8b75f3b8044d441d50211b1e2900701a Mon Sep 17 00:00:00 2001 From: Jonathan Druart Date: Tue, 13 Feb 2024 15:08:25 +0100 Subject: [PATCH] Bug 36084: Bring fetch for everywhere We are retrieving the awesome fetch modules from Vue, so that it can be used in other areas. Here we will use it to inject the CSRF token to the header of every POST request. Signed-off-by: Jonathan Druart --- .../intranet-tmpl/prog/js/fetch/api-client.js | 5 ++ .../js/fetch/article-request-api-client.js | 53 ++++++++++++ .../prog/js/fetch/http-client.js | 82 +++++++++++++++++++ 3 files changed, 140 insertions(+) create mode 100644 koha-tmpl/intranet-tmpl/prog/js/fetch/api-client.js create mode 100644 koha-tmpl/intranet-tmpl/prog/js/fetch/article-request-api-client.js create mode 100644 koha-tmpl/intranet-tmpl/prog/js/fetch/http-client.js diff --git a/koha-tmpl/intranet-tmpl/prog/js/fetch/api-client.js b/koha-tmpl/intranet-tmpl/prog/js/fetch/api-client.js new file mode 100644 index 0000000000..ed27a7c36c --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/js/fetch/api-client.js @@ -0,0 +1,5 @@ +import ArticleRequestAPIClient from "./article-request-api-client.js"; + +export const APIClient = { + article_request: new ArticleRequestAPIClient(), +}; diff --git a/koha-tmpl/intranet-tmpl/prog/js/fetch/article-request-api-client.js b/koha-tmpl/intranet-tmpl/prog/js/fetch/article-request-api-client.js new file mode 100644 index 0000000000..59e984b122 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/js/fetch/article-request-api-client.js @@ -0,0 +1,53 @@ +import HttpClient from "./http-client.js"; + +export class ArticleRequestAPIClient extends HttpClient { + constructor() { + super({ + baseURL: "/cgi-bin/koha/svc/article_request", + headers: { + "Content-Type": + "application/x-www-form-urlencoded;charset=utf-8", + }, + }); + } + + get articleRequests() { + return { + process: id => + this.post({ + endpoint: "", + body: "id=%s&op=%s".format(id, "cud-process"), + }), + complete: id => + this.post({ + endpoint: "", + body: "id=%s&op=%s".format(id, "cud-complete"), + }), + pending: id => + this.post({ + endpoint: "", + body: "id=%s&op=%s".format(id, "cud-pending"), + }), + update_urls: (id, urls) => + this.post({ + endpoint: "", + body: "id=%s&urls=%s&op=%s".format( + id, + urls, + "cud-update_urls" + ), + }), + update_library_id: (id, library_id) => + this.post({ + endpoint: "", + body: "id=%s&library_id=%s&op=%s".format( + id, + library_id, + "cud-update_library_id" + ), + }), + }; + } +} + +export default ArticleRequestAPIClient; diff --git a/koha-tmpl/intranet-tmpl/prog/js/fetch/http-client.js b/koha-tmpl/intranet-tmpl/prog/js/fetch/http-client.js new file mode 100644 index 0000000000..1da2b563ca --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/js/fetch/http-client.js @@ -0,0 +1,82 @@ +//import { setError, submitting, submitted } from "../messages"; + +class HttpClient { + constructor(options = {}) { + this._baseURL = options.baseURL || ""; + this._headers = options.headers || { + "Content-Type": "application/json;charset=utf-8", + }; + this.csrf_token = $('meta[name="csrf-token"]').attr("content"); + } + + async _fetchJSON( + endpoint, + headers = {}, + options = {}, + return_response = false, + mark_submitting = false + ) { + let res, error; + //if (mark_submitting) submitting(); + await fetch(this._baseURL + endpoint, { + ...options, + headers: { ...this._headers, ...headers }, + }) + .then(response => { + if (!response.ok) { + return response.text().then(text => { + let message; + if (text) { + let json = JSON.parse(text); + message = + json.error || + json.errors.map(e => e.message).join("\n") || + json; + } else { + message = response.statusText; + } + throw new Error(message); + }); + } + return return_response ? response : response.json(); + }) + .then(result => { + res = result; + }) + .catch(err => { + error = err; + //setError(err); + console.error(err); + }) + .then(() => { + //if (mark_submitting) submitted(); + }); + + if (error) throw Error(error); + + return res; + } + + post(params = {}) { + const body = params.body + ? typeof params.body === "string" + ? params.body + : JSON.stringify(params.body) + : params.data || undefined; + let csrf_token = { csrf_token: this.csrf_token }; + let headers = { ...csrf_token, ...params.headers }; + return this._fetchJSON( + params.endpoint, + headers, + { + ...params.options, + body, + method: "POST", + }, + false, + true + ); + } +} + +export default HttpClient; -- 2.39.5