-
-
Notifications
You must be signed in to change notification settings - Fork 268
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat: Add support for XAPPLEPUSHSERVICE
#711
Comments
XAPPLEPUSHSERVICE aps-version 2 aps-account-id 0715A26B-CA09-4730-A419-793000CA982E aps-device-token 2918390218931890821908309283098109381029309829018310983092892829 aps-subtopic com.apple.mobilemail mailboxes (INBOX Notes)
So we need to parse and validate these parameters, and then push the values to a daemon/runner/API that will then record the mapping between the account and the client. We could copy the validation from https://github.com/freswa/dovecot-xaps-plugin/blob/197d68e9d0f4f802aff06f90ffd2c1957394a380/xaps-imap-plugin.c#L64-L107. (e.g. |
I agree this would be very nice to have! May not be that easy, as there's no publically available official spec. |
It looks like the only requirement is that you need to be registered iOS developer, so you can download macOS server.
As per https://github.com/freswa/dovecot-xaps-daemon?tab=readme-ov-file#what-is-this. |
@louis-lau I'm digging in, there are two repos we can get inspiration from, both https://github.com/freswa/dovecot-xaps-plugin/tree/master and https://github.com/freswa/dovecot-xaps-daemon. |
Nice! The fact that people have reverse engineered this before should make things easier. Looking into this was on my list somewhere, but there's about 999 things above it haha. Good luck! |
I can’t contribute anything technically, but I would love to see this implemented. Major quality of life win for iOS users. |
We'll see what we can do, we have a lot going on at https://forwardemail.net - but this is highly requested of course for our IMAP users 😄 |
There's apparently a way to notify too for non-INBOX as per comment here: https://github.com/Rjevski/apache-james-xapsd-registration-extension/blob/f694b993c08966485e9ad185c31fe038d42c4962/README.md?plain=1#L55C1-L55C115 |
A few additional notes:
When creating a certificate, the request body to Apple looks like https://github.com/freswa/dovecot-xaps-daemon/blob/abce2f14cf1b5afa56329ebb4d923c9c2aebdfe3/pkg/apple_xserver_certs/request.go#L118-L139: {
PushCertCertificateChainPushCertCertificateChain: Buffer, // signing certificate chain
PushCertRequestPlist: Buffer, // push certificate request plist
PushCertSignature: Buffer, // new push certificate signature using push certificate request plist and signing key
PushCertSignedRequest: Buffer
} The signing key is derived from x509 parsed PKCS1PrivateKey Cert renewals are sent as HTTP POST request to Headers for this request are as follows:
|
Looks like vendor certs are used, which is derived from this repo https://github.com/scintill/macos-server-apns-certs?tab=readme-ov-file#download-and-configure. This repo has a great guide for creating a certificate. |
Basically the way that this whole thing works with adding |
The vendor certificates we need to include (and randomly pick one it seems) are here https://github.com/freswa/dovecot-xaps-daemon/blob/1e589be2e2f54fc94189b03e3db274f86bb7357c/pkg/apple_xserver_certs/request.go#L21-L116. You can see the signing cert is randomly selected via |
The value for var plist = require('plist');
var json = [
"metadata",
{
"bundle-identifier": "com.company.app",
"bundle-version": "0.1.1",
"kind": "software",
"title": "AppName"
}
];
console.log(plist.build(json));
// <?xml version="1.0" encoding="UTF-8"?>
// <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
// <plist version="1.0">
// <key>metadata</key>
// <dict>
// <key>bundle-identifier</key>
// <string>com.company.app</string>
// <key>bundle-version</key>
// <string>0.1.1</string>
// <key>kind</key>
// <string>software</string>
// <key>title</key>
// <string>AppName</string>
// </dict>
// </plist> And we need to use Looks like they have max line length of 64 and indentation using two spaces, and no escaping. So I'm assuming there are two var plist = require('plist');
var json = [
"Header",
{
ClientApplicationCredential: "1",
ClientApplicationName: "XServer",
ClientIPAddress: "1",
ClientOSName: "MAC OSX",
ClientOSVersion: "2.1",
LanguagePreference: "1",
TransactionId: "1",
Version: "1",
},
"Request",
{
ProfileType: "Production",
RequesterType: "XServer",
"User",
{
AccountName: username,
PasswordHash: passwordhash
}
"CertRequestList",
... values here ....
}
]; For |
Now we just need to figure out how to make it so we take action based off provided values from the command, e.g. ( |
It looks like Dovecot takes the This is done here https://github.com/freswa/dovecot-xaps-daemon/blob/abce2f14cf1b5afa56329ebb4d923c9c2aebdfe3/internal/socket.go#L68-L104 So that's how they register it internally. Now how do they send the actual notifications via Apple Push Notifications is what we need to figure out next. |
Searching for They use the Go package Now in Node.js land, we can do it with So basically whenever new mail is received, we'd simply call that, which will then trigger INBOX to fetch new messages. |
@louis-lau @andris9 can you please review and merge this PR, and release with #705 merged as well under #689 for WildDuck v1.43.4 to npm so that we can test and then follow-up with how to implement here in production? PR to add XAPPLEPUSHSERVICE support is at: #712 Many thanks 🙏 |
See forwardemail/forwardemail.net@6398425 for example integration. We are testing it out now. |
Got it working!!!! 🎉 This PR is ready for merge, please review and merge, thank you! ✅ If you'd like to see the working implementation, see these files:
Feel free to try it out on https://forwardemail.net with your iOS device (setup an IMAP account) PUSH now supported on iOS!!!! ⚡ (our alternative since IDLE not supported on iOS Mail) |
* feat: added XAPPLEPUSHSERVICE support (per #711) * fix: added missing XAPPLEPUSHSERVICE capability advertisement * fix: fixed parsing of attributes * fix: invoke `this.send` with successful registration response to `XAPPLEPUSHSERVICE` command We were missing sending a response with the version and sub topic as seen in these references: <https://opensource.apple.com/source/dovecot/dovecot-293/dovecot/src/imap/cmd-x-apple-push-service.c.auto.html> <https://github.com/st3fan/dovecot-xaps-plugin/blob/3d1c71e0c78cc35ca6ead21f49a8e0e35e948a7c/xaps-imap-plugin.c#L158-L166>
We're debugging a few issues, and it's not actually working (yet). After fixing an issue with |
Additionally it appears we can't just set Looks like we do indeed need to spoof mac OSX Server. |
Almost done here, figured out 90% of it just parsing the body and adding caching. That was a headache indeed. |
Folks, it's finally WORKING! I will clean up my commits (and push once ready) and share more here once done and deployed. This was very, very painful to get working, and we still need to test it more thoroughly, but we were able to generate all the certs, verify them, and send a successful APN payload to the device token and account id. |
Okay so despite it working and the APN being successfully delivered – it doesn't appear that APPL is actually delivering it to the device/account pair. I've reached out to folks at APPL, Linux (maintainers of that Dovecot project), and the team at Fastmail. Hoping we can figure out if this is possible still or not, and if not, what are the alternatives. It seems that Yahoo and Fastmail can only do this approach because of a custom licensing that permits them for |
Mailbox.org is another one that has managed to make push email work on iOS. They’re another one to reach out to.
Zoho Mail rely on ActiveSync to do push on iOS.
|
Thank you @JDENredden, we've pinged Mailbox.org folks too. |
We figured out what was wrong, and are fixing it now. |
Special thanks to @freswa per freswa/dovecot-xaps-daemon#39 (comment) (PR at #719). We finally got to the bottom of this and will be testing in production shortly, and will follow up here once done. |
… issue > use row instead, added QR code download for iOS/Android mobile configs, password generate modal hides after 10m not 30s, fixed update alias api issue, fixed FAQ onboard rendering issue with <code>, ignore max length for alias recipient emails, added list of best security audit companies, sync locales
@andris9 Here is our implementation:
There are still some future TODO's – see the TODO's in the codebase at those links, e.g. cert renewals; right now they expire after 360d in redis cache). We are still testing stuff, so await our final confirmation before this is smooth implementation. P.S. @andris9 awesome work with |
Works great! Had to make a few more updates to the above linked files in #711 (comment) and now it's good to go! |
Feel free to try it out, use coupon code Once you sign up and add your domain, simply follow these instructions: https://forwardemail.net/faq#do-you-support-receiving-email-with-imap |
Ref: https://docker-mailserver.github.io/docker-mailserver/latest/examples/use-cases/ios-mail-push-support/
The text was updated successfully, but these errors were encountered: