diff --git a/web/package-lock.json b/web/package-lock.json index caf111eb..0d1a85c1 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -18,6 +18,7 @@ "i18next-browser-languagedetector": "^6.1.4", "i18next-http-backend": "^1.4.0", "js-base64": "^3.7.2", + "nanoid": "^4.0.0", "react": "latest", "react-dom": "latest", "react-i18next": "^11.16.2", @@ -11868,14 +11869,14 @@ } }, "node_modules/nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-4.0.0.tgz", + "integrity": "sha512-IgBP8piMxe/gf73RTQx7hmnhwz0aaEXYakvqZyE302IXW3HyVNhdNGC+O2MwMAVhLEnvXlvKtGbtJf6wvHihCg==", "bin": { - "nanoid": "bin/nanoid.cjs" + "nanoid": "bin/nanoid.js" }, "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": "^14 || ^16 || >=18" } }, "node_modules/natural-compare": { @@ -13692,6 +13693,17 @@ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, + "node_modules/postcss/node_modules/nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -25412,9 +25424,9 @@ } }, "nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-4.0.0.tgz", + "integrity": "sha512-IgBP8piMxe/gf73RTQx7hmnhwz0aaEXYakvqZyE302IXW3HyVNhdNGC+O2MwMAVhLEnvXlvKtGbtJf6wvHihCg==" }, "natural-compare": { "version": "1.4.0", @@ -25873,6 +25885,13 @@ "nanoid": "^3.3.4", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" + }, + "dependencies": { + "nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" + } } }, "postcss-attribute-case-insensitive": { diff --git a/web/package.json b/web/package.json index e97191b0..13bc146f 100644 --- a/web/package.json +++ b/web/package.json @@ -19,6 +19,7 @@ "i18next-browser-languagedetector": "^6.1.4", "i18next-http-backend": "^1.4.0", "js-base64": "^3.7.2", + "nanoid": "^4.0.0", "react": "latest", "react-dom": "latest", "react-i18next": "^11.16.2", diff --git a/web/public/static/langs/en.json b/web/public/static/langs/en.json index 4d12c072..92380c2c 100644 --- a/web/public/static/langs/en.json +++ b/web/public/static/langs/en.json @@ -129,6 +129,7 @@ "subscribe_dialog_subscribe_topic_placeholder": "Topic name, e.g. phil_alerts", "subscribe_dialog_subscribe_use_another_label": "Use another server", "subscribe_dialog_subscribe_base_url_label": "Service URL", + "subscribe_dialog_subscribe_button_generate_topic_name": "Generate topic name", "subscribe_dialog_subscribe_button_cancel": "Cancel", "subscribe_dialog_subscribe_button_subscribe": "Subscribe", "subscribe_dialog_login_title": "Login required", diff --git a/web/src/components/SubscribeDialog.js b/web/src/components/SubscribeDialog.js index 62cfeb28..1a8c1b8d 100644 --- a/web/src/components/SubscribeDialog.js +++ b/web/src/components/SubscribeDialog.js @@ -15,8 +15,10 @@ import subscriptionManager from "../app/SubscriptionManager"; import poller from "../app/Poller"; import DialogFooter from "./DialogFooter"; import {useTranslation} from "react-i18next"; +import {customAlphabet} from 'nanoid/non-secure' const publicBaseUrl = "https://ntfy.sh"; +const randomAlphanumericString = customAlphabet('abcdefghijklmnopqrstuvwxyz0123456789', 21); const SubscribeDialog = (props) => { const [baseUrl, setBaseUrl] = useState(""); @@ -77,6 +79,17 @@ const SubscribePage = (props) => { console.log(`[SubscribeDialog] Successful login to ${topicUrl(baseUrl, topic)} for user ${username}`); props.onSuccess(); }; + const generateTopicName = () => { + const entropy = randomAlphanumericString(); + let newTopic = props.topic; + if (newTopic) { + newTopic += "-" + entropy; + } else { + const sliceIndex = entropy.length / 2; + newTopic = entropy.slice(0, sliceIndex) + "-" + entropy.slice(sliceIndex); + } + props.setTopic(newTopic); + } const handleUseAnotherChanged = (e) => { props.setBaseUrl(""); setAnotherServerVisible(e.target.checked); @@ -118,7 +131,8 @@ const SubscribePage = (props) => { maxLength: 64, "aria-label": t("subscribe_dialog_subscribe_topic_placeholder") }} - /> + /> +