Dependency bumps

This commit is contained in:
binwiederhier
2026-06-24 04:17:59 -04:00
parent e6a201bc11
commit 4b070546b5
16 changed files with 1196 additions and 1057 deletions
+1
View File
@@ -1971,6 +1971,7 @@ since I do have to reset emails on a regular basis.
* Grant users full access to their own sync topic (`st_...`) so cross-device subscription sync works under `auth-default-access: deny-all` ([#733](https://github.com/binwiederhier/ntfy/issues/733), [#1795](https://github.com/binwiederhier/ntfy/pull/1795), thanks to [@lmorchard](https://github.com/lmorchard) for the contribution)
* Support HTTP (non-TLS) S3-compatible endpoints by preserving the endpoint scheme, e.g. for a local MinIO instance ([#1794](https://github.com/binwiederhier/ntfy/pull/1794), [#1734](https://github.com/binwiederhier/ntfy/issues/1734), thanks to [@sskender](https://github.com/sskender) for the contribution, and [@Kernald](https://github.com/Kernald) for reporting)
* Stop silently stripping spaces from passwords while typing in the web app's login, signup, and password-reset forms ([#1246](https://github.com/binwiederhier/ntfy/issues/1246), thanks to [@aldem](https://github.com/aldem) for reporting)
* Update web app dependencies, including major-version upgrades to Vite (6 -> 8, now Rolldown-based), Material UI (5 -> 9), and Dexie (3 -> 4) ([#1800](https://github.com/binwiederhier/ntfy/pull/1800), [#1764](https://github.com/binwiederhier/ntfy/pull/1764), [#1767](https://github.com/binwiederhier/ntfy/pull/1767), [#1762](https://github.com/binwiederhier/ntfy/pull/1762), [#1766](https://github.com/binwiederhier/ntfy/pull/1766), [#1765](https://github.com/binwiederhier/ntfy/pull/1765), thanks Dependabot)
### ntfy Android v1.25.x (UNRELEASED)
+1003 -913
View File
File diff suppressed because it is too large Load Diff
+7 -7
View File
@@ -14,24 +14,24 @@
"@emotion/cache": "^11.11.0",
"@emotion/react": "^11.11.0",
"@emotion/styled": "^11.11.0",
"@mui/icons-material": "^5.4.2",
"@mui/icons-material": "^9.1.1",
"@mui/material": "latest",
"dexie": "^3.2.1",
"dexie-react-hooks": "^1.1.1",
"dexie": "^4.4.4",
"dexie-react-hooks": "^4.4.0",
"i18next": "^21.6.14",
"i18next-browser-languagedetector": "^6.1.4",
"i18next-http-backend": "^3.0.5",
"i18next-http-backend": "^4.0.0",
"react": "latest",
"react-dom": "latest",
"react-i18next": "^11.16.2",
"react-infinite-scroll-component": "^6.1.0",
"react-infinite-scroll-component": "^7.2.1",
"react-remark": "^2.1.0",
"react-router-dom": "^6.30.4",
"stylis": "^4.3.0",
"stylis-plugin-rtl": "^2.1.1"
},
"devDependencies": {
"@vitejs/plugin-react": "^4.0.0",
"@vitejs/plugin-react": "^6.0.3",
"eslint": "^8.41.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-prettier": "^8.8.0",
@@ -40,7 +40,7 @@
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"prettier": "^2.8.8",
"vite": "^6.4.2",
"vite": "^8.0.16",
"vite-plugin-pwa": "^1.0.0"
},
"browserslist": {
+3 -3
View File
@@ -41,7 +41,7 @@ import {
} from "@mui/material";
import EditIcon from "@mui/icons-material/Edit";
import { Trans, useTranslation } from "react-i18next";
import DeleteOutlineIcon from "@mui/icons-material/DeleteOutline";
import DeleteOutlineIcon from "@mui/icons-material/DeleteOutlineOutlined";
import StarIcon from "@mui/icons-material/Star";
import StarBorderIcon from "@mui/icons-material/StarBorder";
import RefreshIcon from "@mui/icons-material/Refresh";
@@ -787,7 +787,7 @@ const AddPhoneNumberDialog = (props) => {
type="tel"
value={phoneNumber}
onChange={(ev) => setPhoneNumber(ev.target.value)}
inputProps={{ inputMode: "tel", pattern: "+[0-9]*" }}
slotProps={{ htmlInput: { inputMode: "tel", pattern: "+[0-9]*" } }}
variant="standard"
sx={{ flexGrow: 1 }}
/>
@@ -818,7 +818,7 @@ const AddPhoneNumberDialog = (props) => {
value={code}
onChange={(ev) => setCode(ev.target.value)}
fullWidth
inputProps={{ inputMode: "numeric", pattern: "[0-9]*" }}
slotProps={{ htmlInput: { inputMode: "numeric", pattern: "[0-9]*" } }}
variant="standard"
/>
)}
+2 -2
View File
@@ -1,8 +1,8 @@
import * as React from "react";
import { useEffect, useRef, useState } from "react";
import { Typography, Button, Box, CircularProgress } from "@mui/material";
import CheckCircleOutlineIcon from "@mui/icons-material/CheckCircleOutline";
import ErrorOutlineIcon from "@mui/icons-material/ErrorOutline";
import CheckCircleOutlineIcon from "@mui/icons-material/CheckCircleOutlineOutlined";
import ErrorOutlineIcon from "@mui/icons-material/ErrorOutlineOutlined";
import { useParams, useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next";
import accountApi from "../app/AccountApi";
+14 -12
View File
@@ -71,18 +71,20 @@ const EmojiPicker = (props) => {
variant="standard"
fullWidth
sx={{ marginTop: 0, marginBottom: "12px", paddingRight: 2 }}
inputProps={{
role: "searchbox",
"aria-label": t("emoji_picker_search_placeholder"),
}}
InputProps={{
endAdornment: (
<InputAdornment position="end" sx={{ display: search ? "" : "none" }}>
<IconButton size="small" onClick={handleSearchClear} edge="end" aria-label={t("emoji_picker_search_clear")}>
<Close />
</IconButton>
</InputAdornment>
),
slotProps={{
htmlInput: {
role: "searchbox",
"aria-label": t("emoji_picker_search_placeholder"),
},
input: {
endAdornment: (
<InputAdornment position="end" sx={{ display: search ? "" : "none" }}>
<IconButton size="small" onClick={handleSearchClear} edge="end" aria-label={t("emoji_picker_search_clear")}>
<Close />
</IconButton>
</InputAdornment>
),
},
}}
/>
<Box
+15 -13
View File
@@ -68,19 +68,21 @@ const Login = () => {
value={password}
onChange={(ev) => setPassword(ev.target.value)}
autoComplete="current-password"
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton
aria-label={t("signup_form_toggle_password_visibility")}
onClick={() => setShowPassword(!showPassword)}
onMouseDown={(ev) => ev.preventDefault()}
edge="end"
>
{showPassword ? <VisibilityOff /> : <Visibility />}
</IconButton>
</InputAdornment>
),
slotProps={{
input: {
endAdornment: (
<InputAdornment position="end">
<IconButton
aria-label={t("signup_form_toggle_password_visibility")}
onClick={() => setShowPassword(!showPassword)}
onMouseDown={(ev) => ev.preventDefault()}
edge="end"
>
{showPassword ? <VisibilityOff /> : <Visibility />}
</IconButton>
</InputAdornment>
),
},
}}
/>
<Button type="submit" fullWidth variant="contained" disabled={username === "" || password === ""} sx={{ mt: 2, mb: 2 }}>
+1 -1
View File
@@ -22,7 +22,7 @@ import {
} from "@mui/material";
import * as React from "react";
import { useContext, useState } from "react";
import ChatBubbleOutlineIcon from "@mui/icons-material/ChatBubbleOutline";
import ChatBubbleOutlineIcon from "@mui/icons-material/ChatBubbleOutlineOutlined";
import Person from "@mui/icons-material/Person";
import SettingsIcon from "@mui/icons-material/Settings";
import AddIcon from "@mui/icons-material/Add";
+1 -1
View File
@@ -462,7 +462,7 @@ const Image = (props) => {
cursor: "pointer",
}}
/>
<Modal open={open} onClose={() => setOpen(false)} BackdropComponent={LightboxBackdrop}>
<Modal open={open} onClose={() => setOpen(false)} slots={{ backdrop: LightboxBackdrop }}>
<Fade in={open}>
<Box
component="img"
+1 -1
View File
@@ -2,7 +2,7 @@ import * as React from "react";
import { useEffect, useRef, useState } from "react";
import { Typography, TextField, Button, Box } from "@mui/material";
import WarningAmberIcon from "@mui/icons-material/WarningAmber";
import CheckCircleOutlineIcon from "@mui/icons-material/CheckCircleOutline";
import CheckCircleOutlineIcon from "@mui/icons-material/CheckCircleOutlineOutlined";
import { useParams, useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next";
import accountApi from "../app/AccountApi";
+1 -1
View File
@@ -1,7 +1,7 @@
import * as React from "react";
import { useState } from "react";
import { TextField, Button, Box, Typography } from "@mui/material";
import CheckCircleOutlineIcon from "@mui/icons-material/CheckCircleOutline";
import CheckCircleOutlineIcon from "@mui/icons-material/CheckCircleOutlineOutlined";
import { NavLink } from "react-router-dom";
import { useTranslation } from "react-i18next";
import accountApi from "../app/AccountApi";
+26 -24
View File
@@ -10,30 +10,32 @@ const PopupMenu = (props) => {
open={props.open}
onClose={props.onClose}
onClick={props.onClose}
TransitionComponent={Fade}
PaperProps={{
elevation: 0,
sx: {
overflow: "visible",
filter: "drop-shadow(0px 2px 8px rgba(0,0,0,0.32))",
mt: 1.5,
"& .MuiAvatar-root": {
width: 32,
height: 32,
ml: -0.5,
mr: 1,
},
"&:before": {
content: '""',
display: "block",
position: "absolute",
top: 0,
width: 10,
height: 10,
bgcolor: "background.paper",
transform: "translateY(-50%) rotate(45deg)",
zIndex: 0,
...arrow,
slots={{ transition: Fade }}
slotProps={{
paper: {
elevation: 0,
sx: {
overflow: "visible",
filter: "drop-shadow(0px 2px 8px rgba(0,0,0,0.32))",
mt: 1.5,
"& .MuiAvatar-root": {
width: 32,
height: 32,
ml: -0.5,
mr: 1,
},
"&:before": {
content: '""',
display: "block",
position: "absolute",
top: 0,
width: 10,
height: 10,
bgcolor: "background.paper",
transform: "translateY(-50%) rotate(45deg)",
zIndex: 0,
...arrow,
},
},
},
}}
+56 -30
View File
@@ -320,8 +320,10 @@ const PublishDialog = (props) => {
type="url"
variant="standard"
sx={{ flexGrow: 1, marginRight: 1 }}
inputProps={{
"aria-label": t("publish_dialog_base_url_label"),
slotProps={{
htmlInput: {
"aria-label": t("publish_dialog_base_url_label"),
},
}}
/>
<TextField
@@ -335,8 +337,10 @@ const PublishDialog = (props) => {
variant="standard"
autoFocus={!messageFocused}
sx={{ flexGrow: 1 }}
inputProps={{
"aria-label": t("publish_dialog_topic_label"),
slotProps={{
htmlInput: {
"aria-label": t("publish_dialog_topic_label"),
},
}}
/>
</ClosableRow>
@@ -351,8 +355,10 @@ const PublishDialog = (props) => {
type="text"
fullWidth
variant="standard"
inputProps={{
"aria-label": t("publish_dialog_title_label"),
slotProps={{
htmlInput: {
"aria-label": t("publish_dialog_title_label"),
},
}}
/>
<TextField
@@ -368,8 +374,10 @@ const PublishDialog = (props) => {
autoFocus={messageFocused}
fullWidth
multiline
inputProps={{
"aria-label": t("publish_dialog_message_label"),
slotProps={{
htmlInput: {
"aria-label": t("publish_dialog_message_label"),
},
}}
onPaste={handlePaste}
/>
@@ -381,8 +389,10 @@ const PublishDialog = (props) => {
size="small"
checked={markdownEnabled}
onChange={(ev) => setMarkdownEnabled(ev.target.checked)}
inputProps={{
"aria-label": t("publish_dialog_checkbox_markdown"),
slotProps={{
input: {
"aria-label": t("publish_dialog_checkbox_markdown"),
},
}}
/>
}
@@ -402,8 +412,10 @@ const PublishDialog = (props) => {
type="text"
variant="standard"
sx={{ flexGrow: 1, marginRight: 1 }}
inputProps={{
"aria-label": t("publish_dialog_tags_label"),
slotProps={{
htmlInput: {
"aria-label": t("publish_dialog_tags_label"),
},
}}
/>
<FormControl variant="standard" margin="dense" sx={{ minWidth: 170, maxWidth: 300, flexGrow: 1 }}>
@@ -460,8 +472,10 @@ const PublishDialog = (props) => {
type="url"
fullWidth
variant="standard"
inputProps={{
"aria-label": t("publish_dialog_click_label"),
slotProps={{
htmlInput: {
"aria-label": t("publish_dialog_click_label"),
},
}}
/>
</ClosableRow>
@@ -485,8 +499,10 @@ const PublishDialog = (props) => {
type="email"
variant="standard"
fullWidth
inputProps={{
"aria-label": t("publish_dialog_email_label"),
slotProps={{
htmlInput: {
"aria-label": t("publish_dialog_email_label"),
},
}}
/>
</ClosableRow>
@@ -556,8 +572,10 @@ const PublishDialog = (props) => {
type="url"
variant="standard"
sx={{ flexGrow: 5, marginRight: 1 }}
inputProps={{
"aria-label": t("publish_dialog_attach_label"),
slotProps={{
htmlInput: {
"aria-label": t("publish_dialog_attach_label"),
},
}}
/>
<TextField
@@ -573,8 +591,10 @@ const PublishDialog = (props) => {
type="text"
variant="standard"
sx={{ flexGrow: 1 }}
inputProps={{
"aria-label": t("publish_dialog_filename_label"),
slotProps={{
htmlInput: {
"aria-label": t("publish_dialog_filename_label"),
},
}}
/>
</ClosableRow>
@@ -617,8 +637,10 @@ const PublishDialog = (props) => {
type="text"
variant="standard"
fullWidth
inputProps={{
"aria-label": t("publish_dialog_delay_label"),
slotProps={{
htmlInput: {
"aria-label": t("publish_dialog_delay_label"),
},
}}
/>
</ClosableRow>
@@ -735,8 +757,10 @@ const PublishDialog = (props) => {
size="small"
checked={publishAnother}
onChange={(ev) => setPublishAnother(ev.target.checked)}
inputProps={{
"aria-label": t("publish_dialog_checkbox_publish_another"),
slotProps={{
input: {
"aria-label": t("publish_dialog_checkbox_publish_another"),
},
}}
/>
}
@@ -867,12 +891,14 @@ const ExpandingTextField = (props) => {
type="text"
variant="standard"
sx={{ width: `${textWidth}px`, borderBottom: "none" }}
InputProps={{
style: { fontSize: theme.typography[props.variant].fontSize },
}}
inputProps={{
style: { paddingBottom: 0, paddingTop: 0 },
"aria-label": props.placeholder,
slotProps={{
input: {
style: { fontSize: theme.typography[props.variant].fontSize },
},
htmlInput: {
style: { paddingBottom: 0, paddingTop: 0 },
"aria-label": props.placeholder,
},
}}
disabled={props.disabled}
/>
+30 -26
View File
@@ -88,19 +88,21 @@ const Signup = () => {
autoComplete="new-password"
value={password}
onChange={(ev) => setPassword(ev.target.value)}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton
aria-label={t("signup_form_toggle_password_visibility")}
onClick={() => setShowPassword(!showPassword)}
onMouseDown={(ev) => ev.preventDefault()}
edge="end"
>
{showPassword ? <VisibilityOff /> : <Visibility />}
</IconButton>
</InputAdornment>
),
slotProps={{
input: {
endAdornment: (
<InputAdornment position="end">
<IconButton
aria-label={t("signup_form_toggle_password_visibility")}
onClick={() => setShowPassword(!showPassword)}
onMouseDown={(ev) => ev.preventDefault()}
edge="end"
>
{showPassword ? <VisibilityOff /> : <Visibility />}
</IconButton>
</InputAdornment>
),
},
}}
/>
<TextField
@@ -114,19 +116,21 @@ const Signup = () => {
autoComplete="new-password"
value={confirm}
onChange={(ev) => setConfirm(ev.target.value)}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton
aria-label={t("signup_form_toggle_password_visibility")}
onClick={() => setShowConfirm(!showConfirm)}
onMouseDown={(ev) => ev.preventDefault()}
edge="end"
>
{showConfirm ? <VisibilityOff /> : <Visibility />}
</IconButton>
</InputAdornment>
),
slotProps={{
input: {
endAdornment: (
<InputAdornment position="end">
<IconButton
aria-label={t("signup_form_toggle_password_visibility")}
onClick={() => setShowConfirm(!showConfirm)}
onMouseDown={(ev) => ev.preventDefault()}
edge="end"
>
{showConfirm ? <VisibilityOff /> : <Visibility />}
</IconButton>
</InputAdornment>
),
},
}}
/>
<Button
+21 -11
View File
@@ -179,9 +179,11 @@ const SubscribePage = (props) => {
type="text"
fullWidth
variant="standard"
inputProps={{
maxLength: 64,
"aria-label": t("subscribe_dialog_subscribe_topic_placeholder"),
slotProps={{
htmlInput: {
maxLength: 64,
"aria-label": t("subscribe_dialog_subscribe_topic_placeholder"),
},
}}
/>
<Button
@@ -202,8 +204,10 @@ const SubscribePage = (props) => {
disabled={!reserveTopicEnabled}
checked={reserveTopicVisible}
onChange={(ev) => setReserveTopicVisible(ev.target.checked)}
inputProps={{
"aria-label": t("reserve_dialog_checkbox_label"),
slotProps={{
input: {
"aria-label": t("reserve_dialog_checkbox_label"),
},
}}
/>
}
@@ -224,8 +228,10 @@ const SubscribePage = (props) => {
<Switch
onChange={handleUseAnotherChanged}
checked={anotherServerVisible}
inputProps={{
"aria-label": t("subscribe_dialog_subscribe_use_another_label"),
slotProps={{
input: {
"aria-label": t("subscribe_dialog_subscribe_use_another_label"),
},
}}
/>
}
@@ -303,8 +309,10 @@ const LoginPage = (props) => {
type="text"
fullWidth
variant="standard"
inputProps={{
"aria-label": t("subscribe_dialog_login_username_label"),
slotProps={{
htmlInput: {
"aria-label": t("subscribe_dialog_login_username_label"),
},
}}
/>
<TextField
@@ -316,8 +324,10 @@ const LoginPage = (props) => {
onChange={(ev) => setPassword(ev.target.value)}
fullWidth
variant="standard"
inputProps={{
"aria-label": t("subscribe_dialog_login_password_label"),
slotProps={{
htmlInput: {
"aria-label": t("subscribe_dialog_login_password_label"),
},
}}
/>
</DialogContent>
+14 -12
View File
@@ -326,18 +326,20 @@ const DisplayNameDialog = (props) => {
type="text"
fullWidth
variant="standard"
inputProps={{
maxLength: 64,
"aria-label": t("display_name_dialog_placeholder"),
}}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton onClick={() => setDisplayName("")} edge="end">
<Clear />
</IconButton>
</InputAdornment>
),
slotProps={{
htmlInput: {
maxLength: 64,
"aria-label": t("display_name_dialog_placeholder"),
},
input: {
endAdornment: (
<InputAdornment position="end">
<IconButton onClick={() => setDisplayName("")} edge="end">
<Clear />
</IconButton>
</InputAdornment>
),
},
}}
/>
</DialogContent>