aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2021-04-22 23:34:11 +0200
committerChristian Grothoff <christian@grothoff.org>2021-04-22 23:34:11 +0200
commit5f914a980ce398be8c28708b6910944e2beb74c1 (patch)
tree2a1b3c58448c73070a21ef6704151fcb796b4531
parent873f0ac8448a7f4d2efaef4e9ab9840e90a3b867 (diff)
integrate SPA
-rw-r--r--.gitmodules3
-rw-r--r--ChangeLog3
-rwxr-xr-xbootstrap12
-rw-r--r--contrib/.gitignore1
-rw-r--r--contrib/Makefile.am7
m---------contrib/merchant-backoffice0
-rw-r--r--src/backend/Makefile.am2
-rw-r--r--src/backend/taler-merchant-httpd.c16
-rw-r--r--src/backend/taler-merchant-httpd_spa.c197
-rw-r--r--src/backend/taler-merchant-httpd_spa.h47
10 files changed, 283 insertions, 5 deletions
diff --git a/.gitmodules b/.gitmodules
index 91e0186e..396c1367 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -2,3 +2,6 @@
path = doc/prebuilt
url = git://git.taler.net/docs.git
branch = prebuilt
+[submodule "contrib/merchant-backoffice"]
+ path = contrib/merchant-backoffice
+ url = git://git.taler.net/merchant-backoffice
diff --git a/ChangeLog b/ChangeLog
index c339bc3b..e39b21f5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+Thu 22 Apr 2021 11:30:13 PM CEST
+ Integrate new single-page app. -CG/SM
+
Tue 10 Nov 2020 01:08:46 PM CET
Major revamp of the entire API (now 1:0:0), changing the names of
many endpoints for better consistency.
diff --git a/bootstrap b/bootstrap
index 5fbaf9b7..23e2cbce 100755
--- a/bootstrap
+++ b/bootstrap
@@ -1,5 +1,7 @@
#!/bin/sh
+set -eu
+
if ! git --version >/dev/null; then
echo "git not installed"
exit 1
@@ -29,3 +31,13 @@ fi
echo "$0: Running autoreconf"
autoreconf -if
+
+echo "Building single-page app (from external Git repository)"
+cd contrib/merchant-backoffice
+./bootstrap
+./configure
+make build-single
+cp packages/frontend/single/index.html ../spa.html
+cd ../..
+
+exit 0
diff --git a/contrib/.gitignore b/contrib/.gitignore
new file mode 100644
index 00000000..863e327b
--- /dev/null
+++ b/contrib/.gitignore
@@ -0,0 +1 @@
+spa.html
diff --git a/contrib/Makefile.am b/contrib/Makefile.am
index 14826f9e..fa11ebb4 100644
--- a/contrib/Makefile.am
+++ b/contrib/Makefile.am
@@ -1,5 +1,6 @@
tmplpkgdatadir = $(prefix)/share/taler/merchant/templates/
staticpkgdatadir = $(prefix)/share/taler/merchant/static/
+spapkgdatadir = $(prefix)/share/taler/merchant/spa/
dist_tmplpkgdata_DATA = \
depleted_tip.en.must \
@@ -11,3 +12,9 @@ dist_tmplpkgdata_DATA = \
# Note: if you update pure-min.css, you must also update the MUST templates above!
dist_staticpkgdata_DATA = \
pure-min.css
+
+
+# spa.html is the single-page-app generated from the merchant-backoffice.git,
+# 'make build-single', during 'bootstrap!'
+dist_spapkgdata_DATA = \
+ spa.html
diff --git a/contrib/merchant-backoffice b/contrib/merchant-backoffice
new file mode 160000
+Subproject 4320467db1392e5f48a4acd079f7e2a253cf998
diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am
index 3dd126a6..93a069af 100644
--- a/src/backend/Makefile.am
+++ b/src/backend/Makefile.am
@@ -98,6 +98,8 @@ taler_merchant_httpd_SOURCES = \
taler-merchant-httpd_qr.h \
taler-merchant-httpd_reserves.c \
taler-merchant-httpd_reserves.h \
+ taler-merchant-httpd_spa.c \
+ taler-merchant-httpd_spa.h \
taler-merchant-httpd_statics.c \
taler-merchant-httpd_statics.h \
taler-merchant-httpd_templating.c \
diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c
index b331bef5..5cfec854 100644
--- a/src/backend/taler-merchant-httpd.c
+++ b/src/backend/taler-merchant-httpd.c
@@ -64,6 +64,7 @@
#include "taler-merchant-httpd_post-orders-ID-refund.h"
#include "taler-merchant-httpd_post-tips-ID-pickup.h"
#include "taler-merchant-httpd_reserves.h"
+#include "taler-merchant-httpd_spa.h"
#include "taler-merchant-httpd_statics.h"
#include "taler-merchant-httpd_templating.h"
@@ -1417,12 +1418,9 @@ url_handler (void *cls,
{
.url_prefix = "/",
.method = MHD_HTTP_METHOD_GET,
- .mime_type = "text/plain",
+ .mime_type = "text/html",
.skip_instance = true,
- .data = "This is a GNU Taler merchant backend. See https://taler.net/.\n",
- .data_size = strlen (
- "This is a GNU Taler merchant backend. See https://taler.net/.\n"),
- .handler = &TMH_MHD_handler_static_response,
+ .handler = &TMH_return_spa,
.response_code = MHD_HTTP_OK
},
{
@@ -2096,6 +2094,14 @@ run (void *cls,
"FORCE_AUDIT"))
TMH_force_audit = GNUNET_YES;
TMH_templating_init ();
+ if (GNUNET_OK !=
+ TMH_spa_init ())
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to load single page app\n");
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
TMH_statics_init ();
elen = TMH_EXCHANGES_init (config);
if (GNUNET_SYSERR == elen)
diff --git a/src/backend/taler-merchant-httpd_spa.c b/src/backend/taler-merchant-httpd_spa.c
new file mode 100644
index 00000000..0e15ad4c
--- /dev/null
+++ b/src/backend/taler-merchant-httpd_spa.c
@@ -0,0 +1,197 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2020 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file taler-merchant-httpd_spa.c
+ * @brief logic to load the single page app (/)
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <gnunet/gnunet_util_lib.h>
+#include <taler/taler_util.h>
+#include <taler/taler_mhd_lib.h>
+#include "taler-merchant-httpd_statics.h"
+#include <gnunet/gnunet_mhd_compat.h>
+
+
+/**
+ * SPA, compressed.
+ */
+static struct MHD_Response *zspa;
+
+/**
+ * SPA, vanilla.
+ */
+static struct MHD_Response *spa;
+
+
+MHD_RESULT
+TMH_return_spa (const struct TMH_RequestHandler *rh,
+ struct MHD_Connection *connection,
+ struct TMH_HandlerContext *hc)
+{
+ if ( (MHD_YES ==
+ TALER_MHD_can_compress (connection)) &&
+ (NULL != zspa) )
+ return MHD_queue_response (connection,
+ MHD_HTTP_OK,
+ zspa);
+ return MHD_queue_response (connection,
+ MHD_HTTP_OK,
+ spa);
+}
+
+
+int
+TMH_spa_init ()
+{
+ char *dn;
+ int fd;
+ struct stat sb;
+
+ {
+ char *path;
+
+ path = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR);
+ if (NULL == path)
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ GNUNET_asprintf (&dn,
+ "%s/merchant/spa/spa.html",
+ path);
+ GNUNET_free (path);
+ }
+
+ /* finally open template */
+ fd = open (dn,
+ O_RDONLY);
+ if (-1 == fd)
+ {
+ GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
+ "open",
+ dn);
+ GNUNET_free (dn);
+ return GNUNET_SYSERR;
+ }
+ if (0 !=
+ fstat (fd,
+ &sb))
+ {
+ GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
+ "open",
+ dn);
+ GNUNET_break (0 == close (fd));
+ GNUNET_free (dn);
+ return GNUNET_SYSERR;
+ }
+
+ {
+ void *in;
+ ssize_t r;
+ size_t csize;
+
+ in = GNUNET_malloc_large (sb.st_size);
+ if (NULL == in)
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+ "malloc");
+ GNUNET_break (0 == close (fd));
+ GNUNET_free (dn);
+ return GNUNET_SYSERR;
+ }
+ r = read (fd,
+ in,
+ sb.st_size);
+ if ( (-1 == r) ||
+ (sb.st_size != (size_t) r) )
+ {
+ GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
+ "read",
+ dn);
+ GNUNET_free (in);
+ GNUNET_break (0 == close (fd));
+ GNUNET_free (dn);
+ return GNUNET_SYSERR;
+ }
+ csize = (size_t) r;
+ if (MHD_YES ==
+ TALER_MHD_body_compress (&in,
+ &csize))
+ {
+ zspa = MHD_create_response_from_buffer (csize,
+ in,
+ MHD_RESPMEM_MUST_FREE);
+ if (NULL != zspa)
+ {
+ if (MHD_NO ==
+ MHD_add_response_header (zspa,
+ MHD_HTTP_HEADER_CONTENT_ENCODING,
+ "deflate"))
+ {
+ GNUNET_break (0);
+ MHD_destroy_response (zspa);
+ zspa = NULL;
+ }
+ GNUNET_break (MHD_YES ==
+ MHD_add_response_header (zspa,
+ MHD_HTTP_HEADER_CONTENT_TYPE,
+ "text/html"));
+ }
+ }
+ }
+
+ spa = MHD_create_response_from_fd (sb.st_size,
+ fd);
+ if (NULL == spa)
+ {
+ GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
+ "open",
+ dn);
+ GNUNET_break (0 == close (fd));
+ GNUNET_free (dn);
+ if (NULL != zspa)
+ {
+ MHD_destroy_response (zspa);
+ zspa = NULL;
+ }
+ return GNUNET_SYSERR;
+ }
+ GNUNET_break (MHD_YES ==
+ MHD_add_response_header (spa,
+ MHD_HTTP_HEADER_CONTENT_TYPE,
+ "text/html"));
+ return GNUNET_OK;
+}
+
+
+/**
+ * Nicely shut down.
+ */
+void __attribute__ ((destructor))
+get_spa_fini ()
+{
+ if (NULL != spa)
+ {
+ MHD_destroy_response (spa);
+ spa = NULL;
+ }
+ if (NULL != zspa)
+ {
+ MHD_destroy_response (zspa);
+ zspa = NULL;
+ }
+}
diff --git a/src/backend/taler-merchant-httpd_spa.h b/src/backend/taler-merchant-httpd_spa.h
new file mode 100644
index 00000000..8a998c38
--- /dev/null
+++ b/src/backend/taler-merchant-httpd_spa.h
@@ -0,0 +1,47 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2021 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file taler-merchant-httpd_spa.h
+ * @brief logic to preload and serve static files
+ * @author Christian Grothoff
+ */
+#ifndef TALER_MERCHANT_HTTPD_SPA_H
+#define TALER_MERCHANT_HTTPD_SPA_H
+
+#include <microhttpd.h>
+#include "taler-merchant-httpd.h"
+
+/**
+ * Return our single-page-app user interface (see contrib/spa.html).
+ *
+ * @param rh request handler
+ * @param connection the connection we act upon
+ * @param hc handler context
+ * @return #MHD_YES on success (reply queued), #MHD_NO on error (close connection)
+ */
+MHD_RESULT
+TMH_return_spa (const struct TMH_RequestHandler *rh,
+ struct MHD_Connection *connection,
+ struct TMH_HandlerContext *hc);
+
+/**
+ * Preload and compress SPA file.
+ */
+int
+TMH_spa_init (void);
+
+
+#endif