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")
}}
- />
+ />
+