mirror of
https://github.com/binwiederhier/ntfy.git
synced 2024-11-22 19:33:27 +01:00
Fix auth base64, fix iPhone things
This commit is contained in:
parent
ccb9da9333
commit
160c72997f
7 changed files with 48 additions and 11 deletions
|
@ -340,6 +340,7 @@ func (s *Server) handleWebConfig(w http.ResponseWriter, r *http.Request) error {
|
||||||
appRoot = "/app"
|
appRoot = "/app"
|
||||||
}
|
}
|
||||||
disallowedTopicsStr := `"` + strings.Join(disallowedTopics, `", "`) + `"`
|
disallowedTopicsStr := `"` + strings.Join(disallowedTopics, `", "`) + `"`
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
_, err := io.WriteString(w, fmt.Sprintf(`// Generated server configuration
|
_, err := io.WriteString(w, fmt.Sprintf(`// Generated server configuration
|
||||||
var config = {
|
var config = {
|
||||||
appRoot: "%s",
|
appRoot: "%s",
|
||||||
|
|
11
web/package-lock.json
generated
11
web/package-lock.json
generated
|
@ -14,6 +14,7 @@
|
||||||
"@mui/material": "latest",
|
"@mui/material": "latest",
|
||||||
"dexie": "^3.2.1",
|
"dexie": "^3.2.1",
|
||||||
"dexie-react-hooks": "^1.1.1",
|
"dexie-react-hooks": "^1.1.1",
|
||||||
|
"js-base64": "^3.7.2",
|
||||||
"react": "latest",
|
"react": "latest",
|
||||||
"react-dom": "latest",
|
"react-dom": "latest",
|
||||||
"react-infinite-scroll-component": "^6.1.0",
|
"react-infinite-scroll-component": "^6.1.0",
|
||||||
|
@ -10775,6 +10776,11 @@
|
||||||
"url": "https://github.com/chalk/supports-color?sponsor=1"
|
"url": "https://github.com/chalk/supports-color?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/js-base64": {
|
||||||
|
"version": "3.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.2.tgz",
|
||||||
|
"integrity": "sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ=="
|
||||||
|
},
|
||||||
"node_modules/js-tokens": {
|
"node_modules/js-tokens": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||||
|
@ -23917,6 +23923,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"js-base64": {
|
||||||
|
"version": "3.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.2.tgz",
|
||||||
|
"integrity": "sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ=="
|
||||||
|
},
|
||||||
"js-tokens": {
|
"js-tokens": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
"@mui/material": "latest",
|
"@mui/material": "latest",
|
||||||
"dexie": "^3.2.1",
|
"dexie": "^3.2.1",
|
||||||
"dexie-react-hooks": "^1.1.1",
|
"dexie-react-hooks": "^1.1.1",
|
||||||
|
"js-base64": "^3.7.2",
|
||||||
"react": "latest",
|
"react": "latest",
|
||||||
"react-dom": "latest",
|
"react-dom": "latest",
|
||||||
"react-infinite-scroll-component": "^6.1.0",
|
"react-infinite-scroll-component": "^6.1.0",
|
||||||
|
|
|
@ -5,6 +5,9 @@ import logo from "../img/ntfy.png";
|
||||||
|
|
||||||
class Notifier {
|
class Notifier {
|
||||||
async notify(subscriptionId, notification, onClickFallback) {
|
async notify(subscriptionId, notification, onClickFallback) {
|
||||||
|
if (!this.supported()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const subscription = await subscriptionManager.get(subscriptionId);
|
const subscription = await subscriptionManager.get(subscriptionId);
|
||||||
const shouldNotify = await this.shouldNotify(subscription, notification);
|
const shouldNotify = await this.shouldNotify(subscription, notification);
|
||||||
if (!shouldNotify) {
|
if (!shouldNotify) {
|
||||||
|
@ -38,10 +41,14 @@ class Notifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
granted() {
|
granted() {
|
||||||
return Notification.permission === 'granted';
|
return this.supported() && Notification.permission === 'granted';
|
||||||
}
|
}
|
||||||
|
|
||||||
maybeRequestPermission(cb) {
|
maybeRequestPermission(cb) {
|
||||||
|
if (!this.supported()) {
|
||||||
|
cb(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!this.granted()) {
|
if (!this.granted()) {
|
||||||
Notification.requestPermission().then((permission) => {
|
Notification.requestPermission().then((permission) => {
|
||||||
const granted = permission === 'granted';
|
const granted = permission === 'granted';
|
||||||
|
@ -61,6 +68,10 @@ class Notifier {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
supported() {
|
||||||
|
return 'Notification' in window;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const notifier = new Notifier();
|
const notifier = new Notifier();
|
||||||
|
|
|
@ -7,6 +7,7 @@ import dadum from "../sounds/dadum.mp3";
|
||||||
import pop from "../sounds/pop.mp3";
|
import pop from "../sounds/pop.mp3";
|
||||||
import popSwoosh from "../sounds/pop-swoosh.mp3";
|
import popSwoosh from "../sounds/pop-swoosh.mp3";
|
||||||
import config from "./config";
|
import config from "./config";
|
||||||
|
import {Base64} from 'js-base64';
|
||||||
|
|
||||||
export const topicUrl = (baseUrl, topic) => `${baseUrl}/${topic}`;
|
export const topicUrl = (baseUrl, topic) => `${baseUrl}/${topic}`;
|
||||||
export const topicUrlWs = (baseUrl, topic) => `${topicUrl(baseUrl, topic)}/ws`
|
export const topicUrlWs = (baseUrl, topic) => `${topicUrl(baseUrl, topic)}/ws`
|
||||||
|
@ -96,14 +97,11 @@ export const basicAuth = (username, password) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const encodeBase64 = (s) => {
|
export const encodeBase64 = (s) => {
|
||||||
return new Buffer(s).toString('base64');
|
return Base64.encode(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const encodeBase64Url = (s) => {
|
export const encodeBase64Url = (s) => {
|
||||||
return encodeBase64(s)
|
return Base64.encodeURI(s);
|
||||||
.replaceAll('+', '-')
|
|
||||||
.replaceAll('/', '_')
|
|
||||||
.replaceAll('=', '');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://jameshfisher.com/2017/10/30/web-cryptography-api-hello-world/
|
// https://jameshfisher.com/2017/10/30/web-cryptography-api-hello-world/
|
||||||
|
|
|
@ -20,7 +20,6 @@ import ErrorBoundary from "./ErrorBoundary";
|
||||||
import routes from "./routes";
|
import routes from "./routes";
|
||||||
import {useAutoSubscribe, useConnectionListeners} from "./hooks";
|
import {useAutoSubscribe, useConnectionListeners} from "./hooks";
|
||||||
|
|
||||||
// TODO iPhone blank screen
|
|
||||||
// TODO better "send test message" (a la android app)
|
// TODO better "send test message" (a la android app)
|
||||||
// TODO docs
|
// TODO docs
|
||||||
// TODO screenshot on homepage
|
// TODO screenshot on homepage
|
||||||
|
|
|
@ -82,13 +82,15 @@ const NavList = (props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const showSubscriptionsList = props.subscriptions?.length > 0;
|
const showSubscriptionsList = props.subscriptions?.length > 0;
|
||||||
const showGrantPermissionsBox = props.subscriptions?.length > 0 && !props.notificationsGranted;
|
const showNotificationNotSupportedBox = !notifier.supported();
|
||||||
|
const showNotificationGrantBox = notifier.supported() && props.subscriptions?.length > 0 && !props.notificationsGranted;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Toolbar sx={{ display: { xs: 'none', sm: 'block' } }}/>
|
<Toolbar sx={{ display: { xs: 'none', sm: 'block' } }}/>
|
||||||
<List component="nav" sx={{ paddingTop: (showGrantPermissionsBox) ? '0' : '' }}>
|
<List component="nav" sx={{ paddingTop: (showNotificationGrantBox || showNotificationNotSupportedBox) ? '0' : '' }}>
|
||||||
{showGrantPermissionsBox && <PermissionAlert onRequestPermissionClick={handleRequestNotificationPermission}/>}
|
{showNotificationNotSupportedBox && <NotificationNotSupportedAlert/>}
|
||||||
|
{showNotificationGrantBox && <NotificationGrantAlert onRequestPermissionClick={handleRequestNotificationPermission}/>}
|
||||||
{!showSubscriptionsList &&
|
{!showSubscriptionsList &&
|
||||||
<ListItemButton onClick={() => navigate(routes.root)} selected={location.pathname === config.appRoot}>
|
<ListItemButton onClick={() => navigate(routes.root)} selected={location.pathname === config.appRoot}>
|
||||||
<ListItemIcon><ChatBubble/></ListItemIcon>
|
<ListItemIcon><ChatBubble/></ListItemIcon>
|
||||||
|
@ -167,7 +169,7 @@ const SubscriptionItem = (props) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const PermissionAlert = (props) => {
|
const NotificationGrantAlert = (props) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Alert severity="warning" sx={{paddingTop: 2}}>
|
<Alert severity="warning" sx={{paddingTop: 2}}>
|
||||||
|
@ -189,4 +191,18 @@ const PermissionAlert = (props) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const NotificationNotSupportedAlert = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Alert severity="warning" sx={{paddingTop: 2}}>
|
||||||
|
<AlertTitle>Notifications not supported</AlertTitle>
|
||||||
|
<Typography gutterBottom>
|
||||||
|
Notifications are not supported in your browser.
|
||||||
|
</Typography>
|
||||||
|
</Alert>
|
||||||
|
<Divider/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default Navigation;
|
export default Navigation;
|
||||||
|
|
Loading…
Reference in a new issue