binwiederhier 3 лет назад
Родитель
Сommit
5724bdf436

+ 1 - 0
server/server.go

@@ -34,6 +34,7 @@ import (
 
 /*
 
+- MEDIUM fail2ban to work with ntfy log not nginx log
 - HIGH Docs
   - tiers
   - api

+ 1 - 1
web/src/components/ActionBar.js

@@ -26,7 +26,7 @@ import {Logout, Person, Settings} from "@mui/icons-material";
 import ListItemIcon from "@mui/material/ListItemIcon";
 import accountApi from "../app/AccountApi";
 import PopupMenu from "./PopupMenu";
-import SubscriptionPopup from "./SubscriptionPopup";
+import { SubscriptionPopup } from "./SubscriptionPopup";
 
 const ActionBar = (props) => {
     const { t } = useTranslation();

+ 3 - 15
web/src/components/Navigation.js

@@ -11,9 +11,8 @@ import Divider from "@mui/material/Divider";
 import List from "@mui/material/List";
 import SettingsIcon from "@mui/icons-material/Settings";
 import AddIcon from "@mui/icons-material/Add";
-import VisibilityIcon from '@mui/icons-material/Visibility';
 import SubscribeDialog from "./SubscribeDialog";
-import {Alert, AlertTitle, Badge, CircularProgress, Link, ListSubheader, Menu, Portal, Tooltip} from "@mui/material";
+import {Alert, AlertTitle, Badge, CircularProgress, Link, ListSubheader, Portal, Tooltip} from "@mui/material";
 import Button from "@mui/material/Button";
 import Typography from "@mui/material/Typography";
 import {openUrl, topicDisplayName, topicUrl} from "../app/utils";
@@ -21,16 +20,7 @@ import routes from "./routes";
 import {ConnectionState} from "../app/Connection";
 import {useLocation, useNavigate} from "react-router-dom";
 import subscriptionManager from "../app/SubscriptionManager";
-import {
-    ChatBubble,
-    Lock, Logout,
-    MoreHoriz, MoreVert,
-    NotificationsOffOutlined,
-    Public,
-    PublicOff,
-    Send,
-    Settings
-} from "@mui/icons-material";
+import {ChatBubble, MoreVert, NotificationsOffOutlined, Send} from "@mui/icons-material";
 import Box from "@mui/material/Box";
 import notifier from "../app/Notifier";
 import config from "../app/config";
@@ -43,9 +33,7 @@ import UpgradeDialog from "./UpgradeDialog";
 import {AccountContext} from "./App";
 import {PermissionDenyAll, PermissionRead, PermissionReadWrite, PermissionWrite} from "./ReserveIcons";
 import IconButton from "@mui/material/IconButton";
-import MenuItem from "@mui/material/MenuItem";
-import PopupMenu from "./PopupMenu";
-import SubscriptionPopup from "./SubscriptionPopup";
+import { SubscriptionPopup } from "./SubscriptionPopup";
 
 const navWidth = 280;
 

+ 6 - 4
web/src/components/SubscribeDialog.js

@@ -6,7 +6,7 @@ import Dialog from '@mui/material/Dialog';
 import DialogContent from '@mui/material/DialogContent';
 import DialogContentText from '@mui/material/DialogContentText';
 import DialogTitle from '@mui/material/DialogTitle';
-import {Autocomplete, Checkbox, Chip, FormControlLabel, FormGroup, useMediaQuery} from "@mui/material";
+import {Autocomplete, Checkbox, FormControlLabel, FormGroup, useMediaQuery} from "@mui/material";
 import theme from "./theme";
 import api from "../app/Api";
 import {randomAlphanumericString, topicUrl, validTopic, validUrl} from "../app/utils";
@@ -21,6 +21,7 @@ import accountApi, {Role} from "../app/AccountApi";
 import ReserveTopicSelect from "./ReserveTopicSelect";
 import {AccountContext} from "./App";
 import {TopicReservedError, UnauthorizedError} from "../app/errors";
+import {ReserveLimitChip} from "./SubscriptionPopup";
 
 const publicBaseUrl = "https://ntfy.sh";
 
@@ -33,7 +34,7 @@ const SubscribeDialog = (props) => {
     const handleSuccess = async () => {
         console.log(`[SubscribeDialog] Subscribing to topic ${topic}`);
         const actualBaseUrl = (baseUrl) ? baseUrl : config.base_url;
-        const subscription = subscribeTopic(actualBaseUrl, topic);
+        const subscription = await subscribeTopic(actualBaseUrl, topic);
         poller.pollInBackground(subscription); // Dangle!
         props.onSuccess(subscription);
     }
@@ -73,6 +74,7 @@ const SubscribePage = (props) => {
     const existingBaseUrls = Array
         .from(new Set([publicBaseUrl, ...props.subscriptions.map(s => s.baseUrl)]))
         .filter(s => s !== config.base_url);
+    const showReserveTopicCheckbox = config.enable_reservations && session.exists() && !anotherServerVisible;
     const reserveTopicEnabled = session.exists() && account?.role === Role.USER && (account?.stats.reservations_remaining || 0) > 0;
 
     const handleSubscribe = async () => {
@@ -163,7 +165,7 @@ const SubscribePage = (props) => {
                         {t("subscribe_dialog_subscribe_button_generate_topic_name")}
                     </Button>
                 </div>
-                {config.enable_reservations && session.exists() && !anotherServerVisible &&
+                {showReserveTopicCheckbox &&
                     <FormGroup>
                         <FormControlLabel
                             variant="standard"
@@ -181,7 +183,7 @@ const SubscribePage = (props) => {
                             label={
                                 <>
                                     {t("reserve_dialog_checkbox_label")}
-                                    <Chip label={t("action_bar_reservation_limit_reached")} variant="outlined" color="primary" sx={{ opacity: 0.8, borderWidth: "2px", height: "24px", marginLeft: "5px" }}/>
+                                    <ReserveLimitChip/>
                                 </>
                             }
                         />

+ 43 - 8
web/src/components/SubscriptionPopup.js

@@ -24,9 +24,8 @@ import {Clear} from "@mui/icons-material";
 import {AccountContext} from "./App";
 import {ReserveAddDialog, ReserveDeleteDialog, ReserveEditDialog} from "./ReserveDialogs";
 import {UnauthorizedError} from "../app/errors";
-import Box from "@mui/material/Box";
 
-const SubscriptionPopup = (props) => {
+export const SubscriptionPopup = (props) => {
     const { t } = useTranslation();
     const { account } = useContext(AccountContext);
     const navigate = useNavigate();
@@ -39,10 +38,10 @@ const SubscriptionPopup = (props) => {
     const placement = props.placement ?? "left";
     const reservations = account?.reservations || [];
 
-    const showReservationAdd = !subscription?.reservation && account?.stats.reservations_remaining > 0;
-    const showReservationAddDisabled = !subscription?.reservation && account?.stats.reservations_remaining === 0;
-    const showReservationEdit = !!subscription?.reservation;
-    const showReservationDelete = !!subscription?.reservation;
+    const showReservationAdd = config.enable_reservations && !subscription?.reservation && account?.stats.reservations_remaining > 0;
+    const showReservationAddDisabled = config.enable_reservations && !subscription?.reservation && (config.enable_payments || account?.stats.reservations_remaining === 0);
+    const showReservationEdit = config.enable_reservations && !!subscription?.reservation;
+    const showReservationDelete = config.enable_reservations && !!subscription?.reservation;
 
     const handleChangeDisplayName = async () => {
         setDisplayNameDialogOpen(true);
@@ -141,7 +140,7 @@ const SubscriptionPopup = (props) => {
                 {showReservationAddDisabled &&
                     <MenuItem sx={{ cursor: "default" }}>
                         <span style={{ opacity: 0.3 }}>{t("action_bar_reservation_add")}</span>
-                        <Chip label={t("action_bar_reservation_limit_reached")} variant="outlined" color="primary" sx={{ opacity: 0.8, borderWidth: "2px", height: "24px", marginLeft: "5px" }}/>
+                        <ReserveLimitChip/>
                     </MenuItem>
                 }
                 {showReservationEdit && <MenuItem onClick={handleReserveEdit}>{t("action_bar_reservation_edit")}</MenuItem>}
@@ -254,4 +253,40 @@ const DisplayNameDialog = (props) => {
     );
 };
 
-export default SubscriptionPopup;
+export const ReserveLimitChip = () => {
+    const { account } = useContext(AccountContext);
+    if (account?.stats.reservations_remaining > 0) {
+        return <></>;
+    } else if (config.enable_payments) {
+        return <ProChip/>;
+    } else if (account) {
+        return <LimitReachedChip/>;
+    }
+    return <></>;
+};
+
+const LimitReachedChip = () => {
+    const { t } = useTranslation();
+    return (
+        <Chip
+            label={t("action_bar_reservation_limit_reached")}
+            variant="outlined"
+            color="primary"
+            sx={{ opacity: 0.8, borderWidth: "2px", height: "24px", marginLeft: "5px" }}
+        />
+    );
+};
+
+const ProChip = () => {
+    const { t } = useTranslation();
+    return (
+        <Chip
+            label={"ntfy Pro"}
+            variant="outlined"
+            color="primary"
+            sx={{ opacity: 0.8, borderWidth: "2px", height: "24px", marginLeft: "5px" }}
+        />
+    );
+};
+
+