Skip to content

Comments

fix: handle ntfy access token auth, and handle @ in credentials#424

Open
w33ble wants to merge 1 commit intoFinsys:mainfrom
w33ble:fix/ntfy-token-auth
Open

fix: handle ntfy access token auth, and handle @ in credentials#424
w33ble wants to merge 1 commit intoFinsys:mainfrom
w33ble:fix/ntfy-token-auth

Conversation

@w33ble
Copy link

@w33ble w33ble commented Jan 31, 2026

Closes #398
Also addresses some of the comments in #15

Fixes the ntfy Apprise URL parsing. It works when an @ is used in the credentials and also adds support for using an access token as a Bearer token in the header.

Support for both is accomplished by using URL.parse, which will URL encode the @ character in the credentials. And because that method separates the username and password, we can assume that when a password is not provided that it is actualyl an access token, and pass it as a Bearer token in the header directly.

Testing

I threw together a local test setup to help iterate and also to show that the original code didn't do what was needed. These tests provide the appriseUrl and payload as well as the url and headers they should produce.

const payload: NotificationPayload = {
    title: 'title 1',
    message: 'hello world',
    type: 'info'
}

const tests = [
    { appriseUrl: 'ntfy://topic', url: 'https://ntfy.sh/topic', headers: { "Priority": "3", "Tags": "info", "Title": "title 1" } },
    { appriseUrl: 'ntfy://ntfy.domain.com/topic', url: 'http://ntfy.domain.com/topic', headers: { "Priority": "3", "Tags": "info", "Title": "title 1" } },
    { appriseUrl: 'ntfy://user:password@ntfy.domain.com/topic', url: 'http://ntfy.domain.com/topic', headers: { "Priority": "3", "Tags": "info", "Title": "title 1", "Authorization": "Basic dXNlcjpwYXNzd29yZA==" } },
    { appriseUrl: 'ntfy://user:p@ssword@ntfy.domain.com/topic', url: 'http://ntfy.domain.com/topic', headers: { "Priority": "3", "Tags": "info", "Title": "title 1", "Authorization": "Basic dXNlcjpwQHNzd29yZA==" } },
    { appriseUrl: 'ntfy://tk_token1234@ntfy.domain.com/topic', url: 'http://ntfy.domain.com/topic', headers: { "Priority": "3", "Tags": "info", "Title": "title 1", "Authorization": "Bearer tk_token1234" } },
    { appriseUrl: 'ntfys://topic', url: 'https://ntfy.sh/topic', headers: { "Priority": "3", "Tags": "info", "Title": "title 1" } },
    { appriseUrl: 'ntfys://ntfy.domain.com/topic', url: 'https://ntfy.domain.com/topic', headers: { "Priority": "3", "Tags": "info", "Title": "title 1" } },
    { appriseUrl: 'ntfys://user:password@ntfy.domain.com/topic', url: 'https://ntfy.domain.com/topic', headers: { "Priority": "3", "Tags": "info", "Title": "title 1", "Authorization": "Basic dXNlcjpwYXNzd29yZA==" } },
    { appriseUrl: 'ntfys://user:p@ssword@ntfy.domain.com/topic', url: 'https://ntfy.domain.com/topic', headers: { "Priority": "3", "Tags": "info", "Title": "title 1", "Authorization": "Basic dXNlcjpwQHNzd29yZA==" } },
    { appriseUrl: 'ntfys://tk_token1234@ntfy.domain.com/topic', url: 'https://ntfy.domain.com/topic', headers: { "Priority": "3", "Tags": "info", "Title": "title 1", "Authorization": "Bearer tk_token1234" } },
]

The original code failed when the credentials contain a @ character, or used an access token:

ntfy://topic PASS ✅
ntfy://ntfy.domain.com/topic PASS ✅
ntfy://user:password@ntfy.domain.com/topic PASS ✅
ntfy://user:p@ssword@ntfy.domain.com/topic FAIL ❌
ntfy://tk_token1234@ntfy.domain.com/topic FAIL ❌
ntfys://topic PASS ✅
ntfys://ntfy.domain.com/topic PASS ✅
ntfys://user:password@ntfy.domain.com/topic PASS ✅
ntfys://user:p@ssword@ntfy.domain.com/topic FAIL ❌
ntfys://tk_token1234@ntfy.domain.com/topic FAIL ❌

The changes in this PR pass in all cases:

ntfy://topic PASS ✅
ntfy://ntfy.domain.com/topic PASS ✅
ntfy://user:password@ntfy.domain.com/topic PASS ✅
ntfy://user:p@ssword@ntfy.domain.com/topic PASS ✅
ntfy://tk_token1234@ntfy.domain.com/topic PASS ✅
ntfys://topic PASS ✅
ntfys://ntfy.domain.com/topic PASS ✅
ntfys://user:password@ntfy.domain.com/topic PASS ✅
ntfys://user:p@ssword@ntfy.domain.com/topic PASS ✅
ntfys://tk_token1234@ntfy.domain.com/topic PASS ✅

I also tested these changes with my own private ntfy instance. And when run with an access token or with an @ in the credentials, it worked as expected.

@CLAassistant
Copy link

CLAassistant commented Jan 31, 2026

CLA assistant check
All committers have signed the CLA.

@w33ble w33ble force-pushed the fix/ntfy-token-auth branch from a7c1289 to 1dea242 Compare January 31, 2026 23:11
@tsposato
Copy link

tsposato commented Feb 3, 2026

I can confirm ntfy notifications currently don't work using token auth.

@bestplay9384
Copy link

bestplay9384 commented Feb 7, 2026

they work for me, however in other form - not present in dockhand docs, but in ntfy/apprise docs:

ntfys://ntfy.domain.com/topic?auth=[base64enc("Bearer tk_token1234")]

@lgwapnitsky
Copy link

Just started testing this, and I am not working either

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Token support for NTFY

5 participants