mirror of
https://github.com/mjl-/mox.git
synced 2024-12-26 08:23:48 +03:00
include all email addresses of an account in the mobileconfig profile for apple devices
after feedback from x8x, pointing out the support, thanks! for issue #65
This commit is contained in:
parent
f1f3135135
commit
d19c75559b
3 changed files with 33 additions and 15 deletions
|
@ -328,15 +328,23 @@ func mobileconfigHandle(w http.ResponseWriter, r *http.Request) {
|
|||
http.Error(w, "405 - method not allowed - get required", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
address := r.FormValue("address")
|
||||
addresses := r.FormValue("addresses")
|
||||
fullName := r.FormValue("name")
|
||||
buf, err := MobileConfig(address, fullName)
|
||||
var buf []byte
|
||||
var err error
|
||||
if addresses == "" {
|
||||
err = fmt.Errorf("missing/empty field addresses")
|
||||
}
|
||||
l := strings.Split(addresses, ",")
|
||||
if err == nil {
|
||||
buf, err = MobileConfig(l, fullName)
|
||||
}
|
||||
if err != nil {
|
||||
http.Error(w, "400 - bad request - "+err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
h := w.Header()
|
||||
filename := address
|
||||
filename := l[0]
|
||||
filename = strings.ReplaceAll(filename, ".", "-")
|
||||
filename = strings.ReplaceAll(filename, "@", "-at-")
|
||||
filename = "email-account-" + filename + ".mobileconfig"
|
||||
|
|
|
@ -109,9 +109,15 @@ func (m dict) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
|||
// password because sending opaque files containing passwords around to users seems
|
||||
// like bad security practice.
|
||||
//
|
||||
// Multiple addresses can be passed, the first is used for IMAP/submission login,
|
||||
// and likely seen as primary account by Apple software.
|
||||
//
|
||||
// The config is not signed, so users must ignore warnings about unsigned profiles.
|
||||
func MobileConfig(address, fullName string) ([]byte, error) {
|
||||
addr, err := smtp.ParseAddress(address)
|
||||
func MobileConfig(addresses []string, fullName string) ([]byte, error) {
|
||||
if len(addresses) == 0 {
|
||||
return nil, fmt.Errorf("need at least 1 address")
|
||||
}
|
||||
addr, err := smtp.ParseAddress(addresses[0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parsing address: %v", err)
|
||||
}
|
||||
|
@ -131,7 +137,7 @@ func MobileConfig(address, fullName string) ([]byte, error) {
|
|||
const key = "mox0"
|
||||
uuid := func(prefix string) string {
|
||||
mac := hmac.New(sha256.New, []byte(key))
|
||||
mac.Write([]byte(prefix + "\n" + "\n" + address))
|
||||
mac.Write([]byte(prefix + "\n" + "\n" + strings.Join(addresses, ",")))
|
||||
sum := mac.Sum(nil)
|
||||
uuid := fmt.Sprintf("%x-%x-%x-%x-%x", sum[0:4], sum[4:6], sum[6:8], sum[8:10], sum[10:16])
|
||||
return uuid
|
||||
|
@ -152,26 +158,28 @@ func MobileConfig(address, fullName string) ([]byte, error) {
|
|||
p := deviceManagementProfile{
|
||||
Version: "1.0",
|
||||
Dict: dict(map[string]any{
|
||||
"PayloadDisplayName": fmt.Sprintf("%s email account", address),
|
||||
"PayloadDisplayName": fmt.Sprintf("%s email account", addresses[0]),
|
||||
"PayloadIdentifier": reverseAddr + ".email",
|
||||
"PayloadType": "Configuration",
|
||||
"PayloadUUID": uuidConfig,
|
||||
"PayloadVersion": 1,
|
||||
"PayloadContent": array{
|
||||
dict(map[string]any{
|
||||
"EmailAccountDescription": address,
|
||||
"EmailAccountName": fullName,
|
||||
"EmailAccountType": "EmailTypeIMAP",
|
||||
"EmailAddress": address,
|
||||
"EmailAccountDescription": addresses[0],
|
||||
"EmailAccountName": fullName,
|
||||
"EmailAccountType": "EmailTypeIMAP",
|
||||
// Comma-separated multiple addresses are not documented at Apple, but seem to
|
||||
// work.
|
||||
"EmailAddress": strings.Join(addresses, ","),
|
||||
"IncomingMailServerAuthentication": "EmailAuthCRAMMD5", // SCRAM not an option at time of writing..
|
||||
"IncomingMailServerUsername": address,
|
||||
"IncomingMailServerUsername": addresses[0],
|
||||
"IncomingMailServerHostName": config.IMAP.Host.ASCII,
|
||||
"IncomingMailServerPortNumber": config.IMAP.Port,
|
||||
"IncomingMailServerUseSSL": config.IMAP.TLSMode == mox.TLSModeImmediate,
|
||||
"OutgoingMailServerAuthentication": "EmailAuthCRAMMD5", // SCRAM not an option at time of writing...
|
||||
"OutgoingMailServerHostName": config.Submission.Host.ASCII,
|
||||
"OutgoingMailServerPortNumber": config.Submission.Port,
|
||||
"OutgoingMailServerUsername": address,
|
||||
"OutgoingMailServerUsername": addresses[0],
|
||||
"OutgoingMailServerUseSSL": config.Submission.TLSMode == mox.TLSModeImmediate,
|
||||
"OutgoingPasswordSameAsIncomingPassword": true,
|
||||
"PayloadIdentifier": reverseAddr + ".email.account",
|
||||
|
|
|
@ -601,6 +601,8 @@ const destination = async (name) => {
|
|||
let fullName
|
||||
let saveButton
|
||||
|
||||
const addresses = [name, ...Object.keys(destinations).filter(a => !a.startsWith('@') && a !== name)]
|
||||
|
||||
const page = document.getElementById('page')
|
||||
dom._kids(page,
|
||||
crumbs(
|
||||
|
@ -685,9 +687,9 @@ const destination = async (name) => {
|
|||
dom.br(),
|
||||
dom.p("Apple's mail applications don't do account autoconfiguration, and when adding an account it can choose defaults that don't work with modern email servers. Adding an account through a \"mobileconfig\" profile file can be more convenient: It contains the IMAP/SMTP settings such as host name, port, TLS, authentication mechanism and user name. This profile does not contain a login password. Opening the profile adds it under Profiles in System Preferences (macOS) or Settings (iOS), where you can install it. These profiles are not signed, so users will have to ignore the warnings about them being unsigned. ",
|
||||
dom.br(),
|
||||
dom.a(attr({href: 'https://autoconfig.'+domainName(domain)+'/profile.mobileconfig?address='+encodeURIComponent(name)+'&name='+encodeURIComponent(dest.FullName), download: ''}), 'Download .mobileconfig email account profile'),
|
||||
dom.a(attr({href: 'https://autoconfig.'+domainName(domain)+'/profile.mobileconfig?addresses='+encodeURIComponent(addresses.join(','))+'&name='+encodeURIComponent(dest.FullName), download: ''}), 'Download .mobileconfig email account profile'),
|
||||
dom.br(),
|
||||
dom.a(attr({href: 'https://autoconfig.'+domainName(domain)+'/profile.mobileconfig.qrcode.png?address='+encodeURIComponent(name)+'&name='+encodeURIComponent(dest.FullName), download: ''}), 'Open QR-code with link to .mobileconfig profile'),
|
||||
dom.a(attr({href: 'https://autoconfig.'+domainName(domain)+'/profile.mobileconfig.qrcode.png?addresses='+encodeURIComponent(addresses.join(','))+'&name='+encodeURIComponent(dest.FullName), download: ''}), 'Open QR-code with link to .mobileconfig profile'),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue