From 6d343c0f1a0c277b48da8b3da76d9ec3ee4d647b Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Fri, 25 Feb 2022 16:07:25 -0500 Subject: [PATCH] Login page of "subscribe dialog", still WIP, but looking nice --- server/server.go | 3 +- web/package-lock.json | 273 ++++++++++++++++++++++++++ web/package.json | 1 + web/src/app/Api.js | 13 +- web/src/app/Repository.js | 31 ++- web/src/components/SubscribeDialog.js | 37 +++- web/src/components/styles.js | 18 ++ web/src/components/theme.js | 1 - 8 files changed, 366 insertions(+), 11 deletions(-) create mode 100644 web/src/components/styles.js diff --git a/server/server.go b/server/server.go index 5dd4bfce..b54a9d87 100644 --- a/server/server.go +++ b/server/server.go @@ -860,8 +860,9 @@ func parseSince(r *http.Request, poll bool) (sinceTime, error) { } func (s *Server) handleOptions(w http.ResponseWriter, _ *http.Request) error { - w.Header().Set("Access-Control-Allow-Origin", "*") // CORS, allow cross-origin requests w.Header().Set("Access-Control-Allow-Methods", "GET, PUT, POST") + w.Header().Set("Access-Control-Allow-Origin", "*") // CORS, allow cross-origin requests + w.Header().Set("Access-Control-Allow-Headers", "Authorization") // CORS, allow auth return nil } diff --git a/web/package-lock.json b/web/package-lock.json index 067a0fac..8bdd9b6e 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -11,6 +11,7 @@ "@emotion/styled": "latest", "@mui/icons-material": "^5.4.2", "@mui/material": "latest", + "@mui/styles": "^5.4.2", "react": "latest", "react-dom": "latest", "react-router-dom": "^6.2.1", @@ -2363,6 +2364,46 @@ } } }, + "node_modules/@mui/styles": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/@mui/styles/-/styles-5.4.2.tgz", + "integrity": "sha512-BX75fNHmRF51yove9dBkH28gpSFjClOPDEnUwLTghPYN913OsqViS/iuCd61dxzygtEEmmeYuWfQjxu/F6vF5g==", + "dependencies": { + "@babel/runtime": "^7.17.0", + "@emotion/hash": "^0.8.0", + "@mui/private-theming": "^5.4.2", + "@mui/types": "^7.1.2", + "@mui/utils": "^5.4.2", + "clsx": "^1.1.1", + "csstype": "^3.0.10", + "hoist-non-react-statics": "^3.3.2", + "jss": "^10.8.2", + "jss-plugin-camel-case": "^10.8.2", + "jss-plugin-default-unit": "^10.8.2", + "jss-plugin-global": "^10.8.2", + "jss-plugin-nested": "^10.8.2", + "jss-plugin-props-sort": "^10.8.2", + "jss-plugin-rule-value-function": "^10.8.2", + "jss-plugin-vendor-prefixer": "^10.8.2", + "prop-types": "^15.7.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@types/react": "^16.8.6 || ^17.0.0", + "react": "^17.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@mui/system": { "version": "5.4.2", "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.4.2.tgz", @@ -5642,6 +5683,15 @@ "node": ">=0.10.0" } }, + "node_modules/css-vendor": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz", + "integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==", + "dependencies": { + "@babel/runtime": "^7.8.3", + "is-in-browser": "^1.0.2" + } + }, "node_modules/css-what": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz", @@ -8521,6 +8571,11 @@ "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" }, + "node_modules/hyphenate-style-name": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz", + "integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==" + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -9113,6 +9168,11 @@ "node": ">=0.10.0" } }, + "node_modules/is-in-browser": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz", + "integrity": "sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU=" + }, "node_modules/is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -10230,6 +10290,88 @@ "node": ">=0.6.0" } }, + "node_modules/jss": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/jss/-/jss-10.9.0.tgz", + "integrity": "sha512-YpzpreB6kUunQBbrlArlsMpXYyndt9JATbt95tajx0t4MTJJcCJdd4hdNpHmOIDiUJrF/oX5wtVFrS3uofWfGw==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "csstype": "^3.0.2", + "is-in-browser": "^1.1.3", + "tiny-warning": "^1.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/jss" + } + }, + "node_modules/jss-plugin-camel-case": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.9.0.tgz", + "integrity": "sha512-UH6uPpnDk413/r/2Olmw4+y54yEF2lRIV8XIZyuYpgPYTITLlPOsq6XB9qeqv+75SQSg3KLocq5jUBXW8qWWww==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "hyphenate-style-name": "^1.0.3", + "jss": "10.9.0" + } + }, + "node_modules/jss-plugin-default-unit": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.9.0.tgz", + "integrity": "sha512-7Ju4Q9wJ/MZPsxfu4T84mzdn7pLHWeqoGd/D8O3eDNNJ93Xc8PxnLmV8s8ZPNRYkLdxZqKtm1nPQ0BM4JRlq2w==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.9.0" + } + }, + "node_modules/jss-plugin-global": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.9.0.tgz", + "integrity": "sha512-4G8PHNJ0x6nwAFsEzcuVDiBlyMsj2y3VjmFAx/uHk/R/gzJV+yRHICjT4MKGGu1cJq2hfowFWCyrr/Gg37FbgQ==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.9.0" + } + }, + "node_modules/jss-plugin-nested": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.9.0.tgz", + "integrity": "sha512-2UJnDrfCZpMYcpPYR16oZB7VAC6b/1QLsRiAutOt7wJaaqwCBvNsosLEu/fUyKNQNGdvg2PPJFDO5AX7dwxtoA==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.9.0", + "tiny-warning": "^1.0.2" + } + }, + "node_modules/jss-plugin-props-sort": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.9.0.tgz", + "integrity": "sha512-7A76HI8bzwqrsMOJTWKx/uD5v+U8piLnp5bvru7g/3ZEQOu1+PjHvv7bFdNO3DwNPC9oM0a//KwIJsIcDCjDzw==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.9.0" + } + }, + "node_modules/jss-plugin-rule-value-function": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.9.0.tgz", + "integrity": "sha512-IHJv6YrEf8pRzkY207cPmdbBstBaE+z8pazhPShfz0tZSDtRdQua5jjg6NMz3IbTasVx9FdnmptxPqSWL5tyJg==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.9.0", + "tiny-warning": "^1.0.2" + } + }, + "node_modules/jss-plugin-vendor-prefixer": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.9.0.tgz", + "integrity": "sha512-MbvsaXP7iiVdYVSEoi+blrW+AYnTDvHTW6I6zqi7JcwXdc6I9Kbm234nEblayhF38EftoenbM+5218pidmC5gA==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "css-vendor": "^2.0.8", + "jss": "10.9.0" + } + }, "node_modules/jsx-ast-utils": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.4.1.tgz", @@ -16215,6 +16357,11 @@ "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -19371,6 +19518,30 @@ "prop-types": "^15.7.2" } }, + "@mui/styles": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/@mui/styles/-/styles-5.4.2.tgz", + "integrity": "sha512-BX75fNHmRF51yove9dBkH28gpSFjClOPDEnUwLTghPYN913OsqViS/iuCd61dxzygtEEmmeYuWfQjxu/F6vF5g==", + "requires": { + "@babel/runtime": "^7.17.0", + "@emotion/hash": "^0.8.0", + "@mui/private-theming": "^5.4.2", + "@mui/types": "^7.1.2", + "@mui/utils": "^5.4.2", + "clsx": "^1.1.1", + "csstype": "^3.0.10", + "hoist-non-react-statics": "^3.3.2", + "jss": "^10.8.2", + "jss-plugin-camel-case": "^10.8.2", + "jss-plugin-default-unit": "^10.8.2", + "jss-plugin-global": "^10.8.2", + "jss-plugin-nested": "^10.8.2", + "jss-plugin-props-sort": "^10.8.2", + "jss-plugin-rule-value-function": "^10.8.2", + "jss-plugin-vendor-prefixer": "^10.8.2", + "prop-types": "^15.7.2" + } + }, "@mui/system": { "version": "5.4.2", "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.4.2.tgz", @@ -21984,6 +22155,15 @@ } } }, + "css-vendor": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz", + "integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==", + "requires": { + "@babel/runtime": "^7.8.3", + "is-in-browser": "^1.0.2" + } + }, "css-what": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz", @@ -24238,6 +24418,11 @@ "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" }, + "hyphenate-style-name": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz", + "integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==" + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -24661,6 +24846,11 @@ "is-extglob": "^2.1.1" } }, + "is-in-browser": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz", + "integrity": "sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU=" + }, "is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -25539,6 +25729,84 @@ "verror": "1.10.0" } }, + "jss": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/jss/-/jss-10.9.0.tgz", + "integrity": "sha512-YpzpreB6kUunQBbrlArlsMpXYyndt9JATbt95tajx0t4MTJJcCJdd4hdNpHmOIDiUJrF/oX5wtVFrS3uofWfGw==", + "requires": { + "@babel/runtime": "^7.3.1", + "csstype": "^3.0.2", + "is-in-browser": "^1.1.3", + "tiny-warning": "^1.0.2" + } + }, + "jss-plugin-camel-case": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.9.0.tgz", + "integrity": "sha512-UH6uPpnDk413/r/2Olmw4+y54yEF2lRIV8XIZyuYpgPYTITLlPOsq6XB9qeqv+75SQSg3KLocq5jUBXW8qWWww==", + "requires": { + "@babel/runtime": "^7.3.1", + "hyphenate-style-name": "^1.0.3", + "jss": "10.9.0" + } + }, + "jss-plugin-default-unit": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.9.0.tgz", + "integrity": "sha512-7Ju4Q9wJ/MZPsxfu4T84mzdn7pLHWeqoGd/D8O3eDNNJ93Xc8PxnLmV8s8ZPNRYkLdxZqKtm1nPQ0BM4JRlq2w==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.9.0" + } + }, + "jss-plugin-global": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.9.0.tgz", + "integrity": "sha512-4G8PHNJ0x6nwAFsEzcuVDiBlyMsj2y3VjmFAx/uHk/R/gzJV+yRHICjT4MKGGu1cJq2hfowFWCyrr/Gg37FbgQ==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.9.0" + } + }, + "jss-plugin-nested": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.9.0.tgz", + "integrity": "sha512-2UJnDrfCZpMYcpPYR16oZB7VAC6b/1QLsRiAutOt7wJaaqwCBvNsosLEu/fUyKNQNGdvg2PPJFDO5AX7dwxtoA==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.9.0", + "tiny-warning": "^1.0.2" + } + }, + "jss-plugin-props-sort": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.9.0.tgz", + "integrity": "sha512-7A76HI8bzwqrsMOJTWKx/uD5v+U8piLnp5bvru7g/3ZEQOu1+PjHvv7bFdNO3DwNPC9oM0a//KwIJsIcDCjDzw==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.9.0" + } + }, + "jss-plugin-rule-value-function": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.9.0.tgz", + "integrity": "sha512-IHJv6YrEf8pRzkY207cPmdbBstBaE+z8pazhPShfz0tZSDtRdQua5jjg6NMz3IbTasVx9FdnmptxPqSWL5tyJg==", + "requires": { + "@babel/runtime": "^7.3.1", + "jss": "10.9.0", + "tiny-warning": "^1.0.2" + } + }, + "jss-plugin-vendor-prefixer": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.9.0.tgz", + "integrity": "sha512-MbvsaXP7iiVdYVSEoi+blrW+AYnTDvHTW6I6zqi7JcwXdc6I9Kbm234nEblayhF38EftoenbM+5218pidmC5gA==", + "requires": { + "@babel/runtime": "^7.3.1", + "css-vendor": "^2.0.8", + "jss": "10.9.0" + } + }, "jsx-ast-utils": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.4.1.tgz", @@ -30352,6 +30620,11 @@ "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" }, + "tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", diff --git a/web/package.json b/web/package.json index d81b9a98..735efcda 100644 --- a/web/package.json +++ b/web/package.json @@ -12,6 +12,7 @@ "@emotion/styled": "latest", "@mui/icons-material": "^5.4.2", "@mui/material": "latest", + "@mui/styles": "^5.4.2", "react": "latest", "react-dom": "latest", "react-router-dom": "^6.2.1", diff --git a/web/src/app/Api.js b/web/src/app/Api.js index 471b4103..dc43a296 100644 --- a/web/src/app/Api.js +++ b/web/src/app/Api.js @@ -23,7 +23,10 @@ class Api { async auth(baseUrl, topic, user) { const url = topicUrlAuth(baseUrl, topic); console.log(`[Api] Checking auth for ${url}`); - const response = await fetch(url); + const headers = this.maybeAddAuthorization({}, user); + const response = await fetch(url, { + headers: headers + }); if (response.status >= 200 && response.status <= 299) { return true; } else if (!user && response.status === 404) { @@ -33,6 +36,14 @@ class Api { } throw new Error(`Unexpected server response ${response.status}`); } + + maybeAddAuthorization(headers, user) { + if (user) { + const encoded = new Buffer(`${user.username}:${user.password}`).toString('base64'); + headers['Authorization'] = `Basic ${encoded}`; + } + return headers; + } } const api = new Api(); diff --git a/web/src/app/Repository.js b/web/src/app/Repository.js index 6651c039..541e651d 100644 --- a/web/src/app/Repository.js +++ b/web/src/app/Repository.js @@ -4,11 +4,11 @@ import Subscriptions from "./Subscriptions"; export class Repository { loadSubscriptions() { console.log(`[Repository] Loading subscriptions from localStorage`); - const subscriptions = new Subscriptions(); const serialized = localStorage.getItem('subscriptions'); - if (serialized === null) return subscriptions; - + if (serialized === null) { + return subscriptions; + } try { const serializedSubscriptions = JSON.parse(serialized); serializedSubscriptions.forEach(s => { @@ -26,7 +26,6 @@ export class Repository { saveSubscriptions(subscriptions) { console.log(`[Repository] Saving ${subscriptions.size()} subscription(s) to localStorage`); - const serialized = JSON.stringify(subscriptions.map( (id, subscription) => { return { baseUrl: subscription.baseUrl, @@ -37,6 +36,30 @@ export class Repository { })); localStorage.setItem('subscriptions', serialized); } + + loadUsers() { + console.log(`[Repository] Loading users from localStorage`); + const serialized = localStorage.getItem('users'); + if (serialized === null) { + return {}; + } + try { + return JSON.parse(serialized); + } catch (e) { + console.log(`[Repository] Unable to deserialize users: ${e.message}`); + return {}; + } + } + + saveUser(baseUrl, username, password) { + console.log(`[Repository] Saving users to localStorage`); + const users = this.loadUsers(); + users[baseUrl] = { + username: username, + password: password + }; + localStorage.setItem('users', users); + } } const repository = new Repository(); diff --git a/web/src/components/SubscribeDialog.js b/web/src/components/SubscribeDialog.js index 55240c73..20b3b0fd 100644 --- a/web/src/components/SubscribeDialog.js +++ b/web/src/components/SubscribeDialog.js @@ -12,6 +12,7 @@ import {useMediaQuery} from "@mui/material"; import theme from "./theme"; import api from "../app/Api"; import {topicUrl} from "../app/utils"; +import useStyles from "./styles"; const defaultBaseUrl = "http://127.0.0.1" //const defaultBaseUrl = "https://ntfy.sh" @@ -19,6 +20,7 @@ const defaultBaseUrl = "http://127.0.0.1" const SubscribeDialog = (props) => { const [baseUrl, setBaseUrl] = useState(defaultBaseUrl); // FIXME const [topic, setTopic] = useState(""); + const [user, setUser] = useState(null); const [showLoginPage, setShowLoginPage] = useState(false); const fullScreen = useMediaQuery(theme.breakpoints.down('sm')); const handleCancel = () => { @@ -45,8 +47,10 @@ const SubscribeDialog = (props) => { onSubmit={handleSubmit} />} {showLoginPage && setShowLoginPage(false)} + onSubmit={handleSubmit} />} ); @@ -82,6 +86,22 @@ const SubscribePage = (props) => { }; const LoginPage = (props) => { + const styles = useStyles(); + const [username, setUsername] = useState(""); + const [password, setPassword] = useState(""); + const [errorText, setErrorText] = useState(""); + const baseUrl = props.baseUrl; + const topic = props.topic; + const handleLogin = async () => { + const user = {username: username, password: password}; + const success = await api.auth(baseUrl, topic, user); + if (!success) { + console.log(`[SubscribeDialog] Login to ${topicUrl(baseUrl, topic)} failed for user ${username}`); + setErrorText(`User ${username} not authorized`); + return; + } + console.log(`[SubscribeDialog] Login to ${topicUrl(baseUrl, topic)} successful for user ${username}`); + }; return ( <> Login required @@ -95,6 +115,8 @@ const LoginPage = (props) => { margin="dense" id="username" label="Username, e.g. phil" + value={username} + onChange={ev => setUsername(ev.target.value)} type="text" fullWidth variant="standard" @@ -104,14 +126,21 @@ const LoginPage = (props) => { id="password" label="Password" type="password" + value={password} + onChange={ev => setPassword(ev.target.value)} fullWidth variant="standard" /> - - - - +
+ + {errorText} + + + + + +
); }; diff --git a/web/src/components/styles.js b/web/src/components/styles.js new file mode 100644 index 00000000..5c47e4a6 --- /dev/null +++ b/web/src/components/styles.js @@ -0,0 +1,18 @@ +import {makeStyles} from "@mui/styles"; + +const useStyles = makeStyles(theme => ({ + bottomBar: { + display: 'flex', + flexDirection: 'row', + justifyContent: 'space-between', + paddingLeft: '24px', + paddingTop: '8px 24px', + paddingBottom: '8px 24px', + }, + statusText: { + margin: '0px', + paddingTop: '8px', + } +})); + +export default useStyles; diff --git a/web/src/components/theme.js b/web/src/components/theme.js index d8565316..28fa1bce 100644 --- a/web/src/components/theme.js +++ b/web/src/components/theme.js @@ -1,7 +1,6 @@ import { red } from '@mui/material/colors'; import { createTheme } from '@mui/material/styles'; -// A custom theme for this app const theme = createTheme({ palette: { primary: {