samschott / desktop-notifier

Python library for cross-platform desktop notifications
https://desktop-notifier.readthedocs.io
MIT License
81 stars 8 forks source link

Deleted my app from macOS system settings "Notifications" panels to test requesting permissions and now it's gone forever #136

Closed michelcrypt4d4mus closed 3 weeks ago

michelcrypt4d4mus commented 3 weeks ago

Description

First off i will just state that i highly doubt this situation is any fault of desktop-notifier. I'm mostly just asking here because I figured someone here might now how to remedy this situation. What happened was:

  1. I set up this package to send notifications from a signed and notarized macOS application. worked like a charm! thanks for the great package.
  2. But then I wanted to test the initial first notification / user permissions flow again... so i right clicked my app from System Settings->Notifications panel and clicked Reset Notifications. According to the apple docs this should get my app back to an initial "hasn't asked for notifications permissions yet" state.
  3. But... now when i try to send notifications i am told by a call to notifier.has_authorisation() that this app is no longer authorized to send notifications (i never even disabled it, i just tried to reset it).

I have tried the following:

  1. reboot
  2. reboot in safe mode
  3. delete my app from the sqlite DB at $(getconf DARWIN_USER_DIR)/com.apple.notificationcenter/db2 and then killall NotificationCenter && killall usernoted
  4. move ~/Library/Preferences/com.apple.ncprefs.plist out of the way and then killall NotificationCenter && killall usernoted

i figured the developer(s) of this package might know a thing or two about where macos is hiding the per-app notification settings... either way feel free to close this as i don't think it's a bug in the package, i think it's a bug in macOS.

samschott commented 3 weeks ago

I've just tried this myself and indeed, notifier.has_authorisation() will return False after resetting notification settings for an app. This is technically correct, you are no longer authorized after resetting.

There are two ways to trigger a new permission flow:

  1. Call notifier.request_authorisation().
  2. Try to actually send another notification. DesktopNotifier will then call notifier.request_authorisation() on your behalf if notifier.has_authorisation() is false.

Both should trigger a new permission flow if the settings were reset. If the user explicitly rejected permissions and those settings are still active, either will just return False without prompting the user again.

michelcrypt4d4mus commented 3 weeks ago

Unfortunately I tried that approach before I took all the other extreme measures I listed... Or at least I can confirm I tried the 2nd one, sending another notification. request_authorisation() always returns False and there is no prompt.

The user (me) never explicitly rejected permissions. I just tried to reset the permissions in the macOS notifications System Settings the way Apple instructs you to do (right click on app name in Notifications settings, choose "Reset")

michelcrypt4d4mus commented 3 weeks ago

I checked into the response codes request_authorisation() is getting and here i'm getting:

was granted? False, error: Notifications are not allowed for this application

despite the fact that my app no longer appears in the Notifications systems settings at all. again i don't think this is a desktop-notifier problem, i think this is a macos problem - somewhere in some weird macos configuration file or something somehow my signed app has been marked as having been disallowed any notifications even though what i actually did was attempt to reset the notifications status for the bundle as per the official docs.

any advice as to places macos might be hiding this info appreciated.

samschott commented 3 weeks ago

any advice as to places macos might be hiding this info appreciated.

Unfortunately, I don't have any good advice here. The steps from https://github.com/samschott/desktop-notifier/issues/136#issuecomment-2161552677 work to re-trigger the permission flow, both for my own app that uses desktop_notifier and for other macOS apps.

Try to actually send another notification. DesktopNotifier will then call notifier.request_authorisation() on your behalf if notifier.has_authorisation() is false.

That part is not exactly true actually. desktop-notifier will only request authorization again after a restart of the app. Otherwise, it caches previous requests:

https://github.com/samschott/desktop-notifier/blob/988fc339f12d6c7139f1466a5228675187dba7e3/src/desktop_notifier/main.py#L205-L206

Maybe that is actually worth changing, as long as we can make sure that the user is not spammed with permission requests.

michelcrypt4d4mus commented 3 weeks ago

desktop-notifier will only request authorization again after a restart of the app.

right sorry that was implicit - i have restarted the app many times.

one hunch i had was that perhaps there were still notifications in the queue somewhere that were causing macOS to think the app's notification preferences weren't actually in an initial empty state so i tried clearing anything out with DekstopNotifier.clear_all() and unfortunately that didn't help either.

oh well. worst case i can change my bundle identifier before release. thanks for the thoughts and maybe the future will bring some answers from someone googling a similar issue. in the meantime i'm closing this because i highly doubt it's an issue with this package.

michelcrypt4d4mus commented 1 day ago

fwiw if this happens to anyone else: in the end i was only able to fix this by changing the app's bundle identifier to something else at which point it worked great. my conclusions are that one of two things happened:

  1. somewhere in the macOS system prefs there is a stuck cache or preference setting that can be improperly reset when manually deleting the app through the System Settings. a number of posts on the apple forums and stackoverflow support this hypothesis.
  2. there were settings in my somewhat complicated multi-executable .app bundle that required me to use the alternate bundle ID. i bundled the app with briefcase which is a bit quirky in that it appends the app name to the string you specify as the bundle ID... so what it actually code signs with is a bundle ID a bit longer than the one you thought you chose.

    specifically what was happening was that the configured bundle ID without the app name at the end (e.g. my.illmatic.app) stopped working when i deleted it from notification center but once i manually signed the briefcase build w/a bundle ID with the app name at the end (e.g. my.illmatic.app.ill_client) things were OK.

i lean much more towards reason 1 because it worked fine for a significant time and only failed when i manually removed the authorization from notification center but reason 2 can't be entirely ruled out, especially because it could be a combination of both reasons given that some of apple's docs imply that permissions for apps that share a bundle ID substring are related.

samschott commented 1 day ago

Thanks for providing all the detail! While its hard to track the actual cause, it's definitely a good reference to have for others.