Design Doc 014: Merchant backoffice UI ###################################### Motivation ========== The merchant should have a user-friendly way to manage the merchant backend, which can currently only be done via a HTTP+JSON RESTful API (:doc:`../core/api-merchant`). Security Architecture ===================== Either (simple deployment): Internal auth (via API key, user directly downloads SPA, asked to enter API key). See: https://bugs.gnunet.org/view.php?id=6731 API token/key is persisted (by SPA) in local storage of browser until you explicitly logout. Or (large company with existing authentication infrastructure): External auth: 1. Login flow via reverse proxy for authentication: BROWSER -> AUTH-PROXY -> (likely) redirect to login server 2. AUTH-PROXY may redirect to login server, passes authentication token via URL param when redirecting back to the AUTH-PROXY for the SPA download BROWSER -> AUTH-PROXY -> SPA (download HTML/JS from backend) 3. Running SPA: SPA-in-BROWSER -> AUTH-PROXY -> BACKEND https://backend/instance/foo/ - Browser shows login dialog (401 Unauthorized, say). - AUTH-PROXY is happy, allows download of HTML. - All requests from SPA are then automatically auth'ed because the browser KNOWS already how to bypass the auth-proxy (token validation, etc). User stories ============ Story #1: Login --------------- 1. User loads SPA at say https://backend/instance/$FOO/ 2. SPA asks for authorization IF an API key is specified/required by the merchant backend for the respective instance. Note: we have several authorization methods: - HTTP ``Authorize`` header with pre-shared key - (maybe?) username / password - (maybe?) theoretically: TLS client certificates (maybe much later) Additionally, the user may specify which instance to log into, as different instances may use different credentials. So the SPA needs to fetch the list of instances. 3. Special case: If there are no instances, the ``default`` instance MUST be used, and the login should immediately move on to the ``setup`` (default) instance dialog, forcing the user to setup the default instance upon first login. 4. After login, we (somehow) need to persist the login data in the SPA. Local storage or just global variable in the JS? Local storage may be better to survive page reload, right? Q: How does the SPA know about the base URL? In the LibEuFin UI, it's part of the login page. A: Just use relative URLs to its own location? => Possible, but might now always be the case => Could use relative URL by default, maybe have a field to allow user to override? => Makes sense. 5. LOGOUT button to reset state and go back to login page. 6. "Change instance" drop-down, to change instance without having to log in again IF the credentials are the same? Story #2: Manage instances -------------------------- This involves only the ``default`` instance owner. Management operations include: - creating an instance (including in particular merchant bank accounts) - deleting an instance (with extra confirmation) - updating an instance (change in bank accounts) Q: Do we have some separate "admin login" to manage instances? Who is actually allowed to manage instances? LibEuFin has some permissions system for this. A: Default instance owner can manage instances. But, there is a complication: *credentials* for all instances are managed in nginx configuration, NOT via the REST API. So default instance owner can create new instances, but access control MUST be configured by the sysadmin. Story #3: View orders and their status, grant refunds ----------------------------------------------------- - list all orders (by date, by payment status, etc.) - for paid orders, view details (show contract, show already granted refunds, trigger refund) Story #4: Manage inventory -------------------------- - add product to inventory - update stock (increase available stock) - change product description / price / etc. - delete products from inventory Story #5: Manage tipping ------------------------ - set up tipping reserve - check tipping reserve status