Kaynağa Gözat

Fix auth base64, fix iPhone things

Philipp Heckel 3 yıl önce
ebeveyn
işleme
160c72997f

+ 1 - 0
server/server.go

@@ -340,6 +340,7 @@ func (s *Server) handleWebConfig(w http.ResponseWriter, r *http.Request) error {
 		appRoot = "/app"
 	}
 	disallowedTopicsStr := `"` + strings.Join(disallowedTopics, `", "`) + `"`
+	w.Header().Set("Content-Type", "application/json")
 	_, err := io.WriteString(w, fmt.Sprintf(`// Generated server configuration
 var config = { 
   appRoot: "%s",

+ 11 - 0
web/package-lock.json

@@ -14,6 +14,7 @@
         "@mui/material": "latest",
         "dexie": "^3.2.1",
         "dexie-react-hooks": "^1.1.1",
+        "js-base64": "^3.7.2",
         "react": "latest",
         "react-dom": "latest",
         "react-infinite-scroll-component": "^6.1.0",
@@ -10775,6 +10776,11 @@
         "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": {
       "version": "4.0.0",
       "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": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",

+ 1 - 0
web/package.json

@@ -15,6 +15,7 @@
     "@mui/material": "latest",
     "dexie": "^3.2.1",
     "dexie-react-hooks": "^1.1.1",
+    "js-base64": "^3.7.2",
     "react": "latest",
     "react-dom": "latest",
     "react-infinite-scroll-component": "^6.1.0",

+ 12 - 1
web/src/app/Notifier.js

@@ -5,6 +5,9 @@ import logo from "../img/ntfy.png";
 
 class Notifier {
     async notify(subscriptionId, notification, onClickFallback) {
+        if (!this.supported()) {
+            return;
+        }
         const subscription = await subscriptionManager.get(subscriptionId);
         const shouldNotify = await this.shouldNotify(subscription, notification);
         if (!shouldNotify) {
@@ -38,10 +41,14 @@ class Notifier {
     }
 
     granted() {
-        return Notification.permission === 'granted';
+        return this.supported() && Notification.permission === 'granted';
     }
 
     maybeRequestPermission(cb) {
+        if (!this.supported()) {
+            cb(false);
+            return;
+        }
         if (!this.granted()) {
             Notification.requestPermission().then((permission) => {
                 const granted = permission === 'granted';
@@ -61,6 +68,10 @@ class Notifier {
         }
         return true;
     }
+
+    supported() {
+        return 'Notification' in window;
+    }
 }
 
 const notifier = new Notifier();

+ 3 - 5
web/src/app/utils.js

@@ -7,6 +7,7 @@ import dadum from "../sounds/dadum.mp3";
 import pop from "../sounds/pop.mp3";
 import popSwoosh from "../sounds/pop-swoosh.mp3";
 import config from "./config";
+import {Base64} from 'js-base64';
 
 export const topicUrl = (baseUrl, topic) => `${baseUrl}/${topic}`;
 export const topicUrlWs = (baseUrl, topic) => `${topicUrl(baseUrl, topic)}/ws`
@@ -96,14 +97,11 @@ export const basicAuth = (username, password) => {
 }
 
 export const encodeBase64 = (s) => {
-    return new Buffer(s).toString('base64');
+    return Base64.encode(s);
 }
 
 export const encodeBase64Url = (s) => {
-    return encodeBase64(s)
-        .replaceAll('+', '-')
-        .replaceAll('/', '_')
-        .replaceAll('=', '');
+    return Base64.encodeURI(s);
 }
 
 // https://jameshfisher.com/2017/10/30/web-cryptography-api-hello-world/

+ 0 - 1
web/src/components/App.js

@@ -20,7 +20,6 @@ import ErrorBoundary from "./ErrorBoundary";
 import routes from "./routes";
 import {useAutoSubscribe, useConnectionListeners} from "./hooks";
 
-// TODO iPhone blank screen
 // TODO better "send test message" (a la android app)
 // TODO docs
 // TODO screenshot on homepage

+ 20 - 4
web/src/components/Navigation.js

@@ -82,13 +82,15 @@ const NavList = (props) => {
     };
 
     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 (
         <>
             <Toolbar sx={{ display: { xs: 'none', sm: 'block' } }}/>
-            <List component="nav" sx={{ paddingTop: (showGrantPermissionsBox) ? '0' : '' }}>
-                {showGrantPermissionsBox && <PermissionAlert onRequestPermissionClick={handleRequestNotificationPermission}/>}
+            <List component="nav" sx={{ paddingTop: (showNotificationGrantBox || showNotificationNotSupportedBox) ? '0' : '' }}>
+                {showNotificationNotSupportedBox && <NotificationNotSupportedAlert/>}
+                {showNotificationGrantBox && <NotificationGrantAlert onRequestPermissionClick={handleRequestNotificationPermission}/>}
                 {!showSubscriptionsList &&
                     <ListItemButton onClick={() => navigate(routes.root)} selected={location.pathname === config.appRoot}>
                         <ListItemIcon><ChatBubble/></ListItemIcon>
@@ -167,7 +169,7 @@ const SubscriptionItem = (props) => {
     );
 };
 
-const PermissionAlert = (props) => {
+const NotificationGrantAlert = (props) => {
     return (
         <>
             <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;