Login page of "subscribe dialog", still WIP, but looking nice
parent
1599793de2
commit
6d343c0f1a
|
@ -860,8 +860,9 @@ func parseSince(r *http.Request, poll bool) (sinceTime, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) handleOptions(w http.ResponseWriter, _ *http.Request) 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-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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
"@emotion/styled": "latest",
|
"@emotion/styled": "latest",
|
||||||
"@mui/icons-material": "^5.4.2",
|
"@mui/icons-material": "^5.4.2",
|
||||||
"@mui/material": "latest",
|
"@mui/material": "latest",
|
||||||
|
"@mui/styles": "^5.4.2",
|
||||||
"react": "latest",
|
"react": "latest",
|
||||||
"react-dom": "latest",
|
"react-dom": "latest",
|
||||||
"react-router-dom": "^6.2.1",
|
"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": {
|
"node_modules/@mui/system": {
|
||||||
"version": "5.4.2",
|
"version": "5.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/@mui/system/-/system-5.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/@mui/system/-/system-5.4.2.tgz",
|
||||||
|
@ -5642,6 +5683,15 @@
|
||||||
"node": ">=0.10.0"
|
"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": {
|
"node_modules/css-what": {
|
||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz",
|
"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",
|
"resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
|
||||||
"integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM="
|
"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": {
|
"node_modules/iconv-lite": {
|
||||||
"version": "0.4.24",
|
"version": "0.4.24",
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||||
|
@ -9113,6 +9168,11 @@
|
||||||
"node": ">=0.10.0"
|
"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": {
|
"node_modules/is-negative-zero": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
|
||||||
|
@ -10230,6 +10290,88 @@
|
||||||
"node": ">=0.6.0"
|
"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": {
|
"node_modules/jsx-ast-utils": {
|
||||||
"version": "2.4.1",
|
"version": "2.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.4.1.tgz",
|
"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",
|
"resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
|
||||||
"integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q="
|
"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": {
|
"node_modules/tmp": {
|
||||||
"version": "0.0.33",
|
"version": "0.0.33",
|
||||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
|
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
|
||||||
|
@ -19371,6 +19518,30 @@
|
||||||
"prop-types": "^15.7.2"
|
"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": {
|
"@mui/system": {
|
||||||
"version": "5.4.2",
|
"version": "5.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/@mui/system/-/system-5.4.2.tgz",
|
"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": {
|
"css-what": {
|
||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz",
|
"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",
|
"resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
|
||||||
"integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM="
|
"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": {
|
"iconv-lite": {
|
||||||
"version": "0.4.24",
|
"version": "0.4.24",
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||||
|
@ -24661,6 +24846,11 @@
|
||||||
"is-extglob": "^2.1.1"
|
"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": {
|
"is-negative-zero": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
|
||||||
|
@ -25539,6 +25729,84 @@
|
||||||
"verror": "1.10.0"
|
"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": {
|
"jsx-ast-utils": {
|
||||||
"version": "2.4.1",
|
"version": "2.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.4.1.tgz",
|
"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",
|
"resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
|
||||||
"integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q="
|
"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": {
|
"tmp": {
|
||||||
"version": "0.0.33",
|
"version": "0.0.33",
|
||||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
|
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
"@emotion/styled": "latest",
|
"@emotion/styled": "latest",
|
||||||
"@mui/icons-material": "^5.4.2",
|
"@mui/icons-material": "^5.4.2",
|
||||||
"@mui/material": "latest",
|
"@mui/material": "latest",
|
||||||
|
"@mui/styles": "^5.4.2",
|
||||||
"react": "latest",
|
"react": "latest",
|
||||||
"react-dom": "latest",
|
"react-dom": "latest",
|
||||||
"react-router-dom": "^6.2.1",
|
"react-router-dom": "^6.2.1",
|
||||||
|
|
|
@ -23,7 +23,10 @@ class Api {
|
||||||
async auth(baseUrl, topic, user) {
|
async auth(baseUrl, topic, user) {
|
||||||
const url = topicUrlAuth(baseUrl, topic);
|
const url = topicUrlAuth(baseUrl, topic);
|
||||||
console.log(`[Api] Checking auth for ${url}`);
|
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) {
|
if (response.status >= 200 && response.status <= 299) {
|
||||||
return true;
|
return true;
|
||||||
} else if (!user && response.status === 404) {
|
} else if (!user && response.status === 404) {
|
||||||
|
@ -33,6 +36,14 @@ class Api {
|
||||||
}
|
}
|
||||||
throw new Error(`Unexpected server response ${response.status}`);
|
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();
|
const api = new Api();
|
||||||
|
|
|
@ -4,11 +4,11 @@ import Subscriptions from "./Subscriptions";
|
||||||
export class Repository {
|
export class Repository {
|
||||||
loadSubscriptions() {
|
loadSubscriptions() {
|
||||||
console.log(`[Repository] Loading subscriptions from localStorage`);
|
console.log(`[Repository] Loading subscriptions from localStorage`);
|
||||||
|
|
||||||
const subscriptions = new Subscriptions();
|
const subscriptions = new Subscriptions();
|
||||||
const serialized = localStorage.getItem('subscriptions');
|
const serialized = localStorage.getItem('subscriptions');
|
||||||
if (serialized === null) return subscriptions;
|
if (serialized === null) {
|
||||||
|
return subscriptions;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const serializedSubscriptions = JSON.parse(serialized);
|
const serializedSubscriptions = JSON.parse(serialized);
|
||||||
serializedSubscriptions.forEach(s => {
|
serializedSubscriptions.forEach(s => {
|
||||||
|
@ -26,7 +26,6 @@ export class Repository {
|
||||||
|
|
||||||
saveSubscriptions(subscriptions) {
|
saveSubscriptions(subscriptions) {
|
||||||
console.log(`[Repository] Saving ${subscriptions.size()} subscription(s) to localStorage`);
|
console.log(`[Repository] Saving ${subscriptions.size()} subscription(s) to localStorage`);
|
||||||
|
|
||||||
const serialized = JSON.stringify(subscriptions.map( (id, subscription) => {
|
const serialized = JSON.stringify(subscriptions.map( (id, subscription) => {
|
||||||
return {
|
return {
|
||||||
baseUrl: subscription.baseUrl,
|
baseUrl: subscription.baseUrl,
|
||||||
|
@ -37,6 +36,30 @@ export class Repository {
|
||||||
}));
|
}));
|
||||||
localStorage.setItem('subscriptions', serialized);
|
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();
|
const repository = new Repository();
|
||||||
|
|
|
@ -12,6 +12,7 @@ import {useMediaQuery} from "@mui/material";
|
||||||
import theme from "./theme";
|
import theme from "./theme";
|
||||||
import api from "../app/Api";
|
import api from "../app/Api";
|
||||||
import {topicUrl} from "../app/utils";
|
import {topicUrl} from "../app/utils";
|
||||||
|
import useStyles from "./styles";
|
||||||
|
|
||||||
const defaultBaseUrl = "http://127.0.0.1"
|
const defaultBaseUrl = "http://127.0.0.1"
|
||||||
//const defaultBaseUrl = "https://ntfy.sh"
|
//const defaultBaseUrl = "https://ntfy.sh"
|
||||||
|
@ -19,6 +20,7 @@ const defaultBaseUrl = "http://127.0.0.1"
|
||||||
const SubscribeDialog = (props) => {
|
const SubscribeDialog = (props) => {
|
||||||
const [baseUrl, setBaseUrl] = useState(defaultBaseUrl); // FIXME
|
const [baseUrl, setBaseUrl] = useState(defaultBaseUrl); // FIXME
|
||||||
const [topic, setTopic] = useState("");
|
const [topic, setTopic] = useState("");
|
||||||
|
const [user, setUser] = useState(null);
|
||||||
const [showLoginPage, setShowLoginPage] = useState(false);
|
const [showLoginPage, setShowLoginPage] = useState(false);
|
||||||
const fullScreen = useMediaQuery(theme.breakpoints.down('sm'));
|
const fullScreen = useMediaQuery(theme.breakpoints.down('sm'));
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
|
@ -45,8 +47,10 @@ const SubscribeDialog = (props) => {
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
/>}
|
/>}
|
||||||
{showLoginPage && <LoginPage
|
{showLoginPage && <LoginPage
|
||||||
|
baseUrl={baseUrl}
|
||||||
topic={topic}
|
topic={topic}
|
||||||
onBack={() => setShowLoginPage(false)}
|
onBack={() => setShowLoginPage(false)}
|
||||||
|
onSubmit={handleSubmit}
|
||||||
/>}
|
/>}
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
|
@ -82,6 +86,22 @@ const SubscribePage = (props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const LoginPage = (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 (
|
return (
|
||||||
<>
|
<>
|
||||||
<DialogTitle>Login required</DialogTitle>
|
<DialogTitle>Login required</DialogTitle>
|
||||||
|
@ -95,6 +115,8 @@ const LoginPage = (props) => {
|
||||||
margin="dense"
|
margin="dense"
|
||||||
id="username"
|
id="username"
|
||||||
label="Username, e.g. phil"
|
label="Username, e.g. phil"
|
||||||
|
value={username}
|
||||||
|
onChange={ev => setUsername(ev.target.value)}
|
||||||
type="text"
|
type="text"
|
||||||
fullWidth
|
fullWidth
|
||||||
variant="standard"
|
variant="standard"
|
||||||
|
@ -104,14 +126,21 @@ const LoginPage = (props) => {
|
||||||
id="password"
|
id="password"
|
||||||
label="Password"
|
label="Password"
|
||||||
type="password"
|
type="password"
|
||||||
|
value={password}
|
||||||
|
onChange={ev => setPassword(ev.target.value)}
|
||||||
fullWidth
|
fullWidth
|
||||||
variant="standard"
|
variant="standard"
|
||||||
/>
|
/>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
<div className={styles.bottomBar}>
|
||||||
|
<DialogContentText className={styles.statusText}>
|
||||||
|
{errorText}
|
||||||
|
</DialogContentText>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<Button onClick={props.onBack}>Back</Button>
|
<Button onClick={props.onBack}>Back</Button>
|
||||||
<Button>Login</Button>
|
<Button onClick={handleLogin}>Login</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
|
@ -1,7 +1,6 @@
|
||||||
import { red } from '@mui/material/colors';
|
import { red } from '@mui/material/colors';
|
||||||
import { createTheme } from '@mui/material/styles';
|
import { createTheme } from '@mui/material/styles';
|
||||||
|
|
||||||
// A custom theme for this app
|
|
||||||
const theme = createTheme({
|
const theme = createTheme({
|
||||||
palette: {
|
palette: {
|
||||||
primary: {
|
primary: {
|
||||||
|
|
Loading…
Reference in New Issue