Get it working with vue js
This commit is contained in:
parent
9d67216a6d
commit
2944056fc0
3 changed files with 204 additions and 161 deletions
|
@ -0,0 +1,6 @@
|
|||
body {
|
||||
font-family: "JetBrains Mono", "Roboto Mono", "Menlo", monospace;
|
||||
}
|
||||
#profile {
|
||||
white-space: pre-wrap;
|
||||
}
|
112
index.html
112
index.html
|
@ -6,16 +6,116 @@
|
|||
<title></title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="css/main.css">
|
||||
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<form id="profile-form">
|
||||
<button type="button" onclick="generateProfile()">Generate</button>
|
||||
<p>
|
||||
<label for="profile">Generated profile</label>
|
||||
<textarea name="profile" id="profile" cols="80" rows="15"></textarea>
|
||||
<div id="app">
|
||||
<h1>1. Fill in the forms for your email configuration profile</h1>
|
||||
<p>Documentation can be found
|
||||
<a href="https://developer.apple.com/documentation/devicemanagement/configuring_multiple_devices_using_profiles">here</a>
|
||||
for common fields and
|
||||
<a href="https://developer.apple.com/documentation/devicemanagement/mail">here</a>
|
||||
for email specific fields.
|
||||
</p>
|
||||
</form>
|
||||
<div id="profile">
|
||||
<?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'>
|
||||
<dict>
|
||||
<key>PayloadContent</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>EmailAccountType</key>
|
||||
<string><select v-model="payload.EmailAccountType">
|
||||
<option value="" disabled>Select...</option>
|
||||
<option>EmailTypeIMAP</option>
|
||||
<option>EmailTypePOP</option>
|
||||
</select></string>
|
||||
<key>EmailAddress</key>
|
||||
<string><input type="email" v-model="payload.EmailAddress" v-bind:placeholder="payloadPlaceholders.EmailAddress"></string>
|
||||
<key>EmailAccountDescription</key>
|
||||
<string><input type="text" v-model="payload.EmailAccountDescription" v-bind:placeholder="payloadPlaceholders.EmailAccountDescription"></string>
|
||||
|
||||
<!-- Incoming -->
|
||||
<key>IncomingMailServerAuthentication</key>
|
||||
<string><select v-model="payload.IncomingMailServerAuthentication">
|
||||
<option value="" disabled>Select...</option>
|
||||
<option>EmailAuthNone</option>
|
||||
<option>EmailAuthPassword</option>
|
||||
<option>EmailAuthCRAMMD5</option>
|
||||
<option>EmailAuthNTLM</option>
|
||||
<option>EmailAuthHTTPMD5</option>
|
||||
</select></string>
|
||||
<key>IncomingMailServerHostName</key>
|
||||
<string><input type="text" v-model="payload.IncomingMailServerHostName" v-bind:placeholder="payloadPlaceholders.IncomingMailServerHostName"></string>
|
||||
<key>IncomingMailServerPortNumber</key>
|
||||
<integer><input type="number" v-model="payload.IncomingMailServerPortNumber" v-bind:placeholder="payloadPlaceholders.IncomingMailServerPortNumber"></integer>
|
||||
<key>IncomingMailServerUsername</key>
|
||||
<string><input type="text" v-model="payload.IncomingMailServerUsername" v-bind:placeholder="payloadPlaceholders.IncomingMailServerUsername"></string>
|
||||
<key>IncomingMailServerUseSSL</key>
|
||||
<<input type="checkbox" v-model="payload.IncomingMailServerUseSSL">/>
|
||||
|
||||
<!-- Outgoing -->
|
||||
<key>OutgoingMailServerAuthentication</key>
|
||||
<string><select v-model="payload.OutgoingMailServerAuthentication">
|
||||
<option value="" disabled>Select...</option>
|
||||
<option>EmailAuthNone</option>
|
||||
<option>EmailAuthPassword</option>
|
||||
<option>EmailAuthCRAMMD5</option>
|
||||
<option>EmailAuthNTLM</option>
|
||||
<option>EmailAuthHTTPMD5</option>
|
||||
</select></string>
|
||||
<key>OutgoingMailServerHostName</key>
|
||||
<string><input type="text" v-model="payload.OutgoingMailServerHostName" v-bind:placeholder="payloadPlaceholders.OutgoingMailServerHostName"></string>
|
||||
<key>OutgoingMailServerPortNumber</key>
|
||||
<integer><input type="number" v-model="payload.OutgoingMailServerPortNumber" v-bind:placeholder="payloadPlaceholders.OutgoingMailServerPortNumber"></integer>
|
||||
<key>OutgoingMailServerUsername</key>
|
||||
<string><input type="text" v-model="payload.OutgoingMailServerUsername" v-bind:placeholder="payloadPlaceholders.OutgoingMailServerUsername"></string>
|
||||
<key>OutgoingMailServerUseSSL</key>
|
||||
<<input type="checkbox" v-model="payload.OutgoingMailServerUseSSL">/>
|
||||
<key>OutgoingPasswordSameAsIncomingPassword</key>
|
||||
<<input type="checkbox" v-model="payload.OutgoingPasswordSameAsIncomingPassword">/>
|
||||
|
||||
<!-- Common keys -->
|
||||
<key>PayloadDisplayName</key>
|
||||
<string><input type="text" v-model="payload.PayloadDisplayName" v-bind:placeholder="payloadPlaceholders.PayloadDisplayName"></string>
|
||||
<key>PayloadDescription</key>
|
||||
<string><input type="text" v-model="payload.PayloadDescription" v-bind:placeholder="payloadPlaceholders.PayloadDescription"></string>
|
||||
<key>PayloadIdentifier</key>
|
||||
<string><input type="text" v-model="payload.PayloadIdentifier" v-bind:placeholder="payloadPlaceholders.PayloadIdentifier"></string>
|
||||
<key>PayloadType</key>
|
||||
<string>{{ payload.PayloadType }}</string>
|
||||
<key>PayloadUUID</key>
|
||||
<string>{{ payload.PayloadUUID() }}</string>
|
||||
<key>PayloadVersion</key>
|
||||
<integer>{{ payload.PayloadVersion }}</integer>
|
||||
</dict>
|
||||
</array>
|
||||
|
||||
<!-- Common keys -->
|
||||
<key>PayloadDisplayName</key>
|
||||
<string><input type="text" v-model="container.PayloadDisplayName" v-bind:placeholder="containerPlaceholders.PayloadDisplayName"></string>
|
||||
<key>PayloadDescription</key>
|
||||
<string><input type="text" v-model="container.PayloadDescription" v-bind:placeholder="containerPlaceholders.PayloadDescription"></string>
|
||||
<key>PayloadIdentifier</key>
|
||||
<string><input type="text" v-model="container.PayloadIdentifier" v-bind:placeholder="containerPlaceholders.PayloadIdentifier"></string>
|
||||
<key>PayloadType</key>
|
||||
<string>{{ container.PayloadType }}</string>
|
||||
<key>PayloadUUID</key>
|
||||
<string>{{ container.PayloadUUID() }}</string>
|
||||
<key>PayloadVersion</key>
|
||||
<integer>{{ container.PayloadVersion }}</integer>
|
||||
</dict>
|
||||
</plist>
|
||||
</div>
|
||||
|
||||
<h1>2. Download your profile</h1>
|
||||
<a v-bind:href="generatedProfileLink" v-bind:download="downloadFileName">Download</a>
|
||||
|
||||
<h1>3. Or copy/paste</h1>
|
||||
<textarea rows="30" cols="80">{{ generatedProfile }}</textarea>
|
||||
</div>
|
||||
<script src="js/main.js"></script>
|
||||
</body>
|
||||
|
||||
|
|
247
js/main.js
247
js/main.js
|
@ -1,41 +1,61 @@
|
|||
"use strict";
|
||||
|
||||
const data = {
|
||||
payload: {
|
||||
EmailAccountType: "",
|
||||
EmailAddress: "",
|
||||
EmailAccountDescription: "",
|
||||
|
||||
IncomingMailServerAuthentication: "",
|
||||
IncomingMailServerHostName: "",
|
||||
IncomingMailServerPortNumber: null,
|
||||
IncomingMailServerUsername: "",
|
||||
IncomingMailServerUseSSL: null,
|
||||
|
||||
OutgoingMailServerAuthentication: "",
|
||||
OutgoingMailServerHostName: "",
|
||||
OutgoingMailServerPortNumber: null,
|
||||
OutgoingMailServerUsername: "",
|
||||
OutgoingMailServerUseSSL: null,
|
||||
OutgoingPasswordSameAsIncomingPassword: null,
|
||||
|
||||
let payloadForm = {
|
||||
EmailAccountType: {type: "string", choices: ["EmailTypeIMAP"]},
|
||||
EmailAddress: {type: "string"},
|
||||
EmailAccountDescription: {type: "string"},
|
||||
PayloadDescription: "",
|
||||
PayloadDisplayName: "",
|
||||
PayloadIdentifier: "",
|
||||
PayloadType: "com.apple.mail.managed",
|
||||
PayloadUUID: generateUUID,
|
||||
PayloadVersion: 1,
|
||||
},
|
||||
payloadPlaceholders: {
|
||||
EmailAddress: "john@example.com",
|
||||
EmailAccountDescription: "Example email account",
|
||||
|
||||
IncomingMailServerAuthentication: {type: "string", choices: ["EmailAuthPassword"]},
|
||||
IncomingMailServerHostName: {type: "string"},
|
||||
IncomingMailServerPortNumber: {type: "number"},
|
||||
IncomingMailServerUsername: {type: "string"},
|
||||
IncomingMailServerUseSSL: {type: "boolean"},
|
||||
IncomingMailServerHostName: "imap.example.com",
|
||||
IncomingMailServerPortNumber: 993,
|
||||
IncomingMailServerUsername: "john@example.com",
|
||||
|
||||
OutgoingMailServerAuthentication: {type: "string", choices: ["EmailAuthPassword"]},
|
||||
OutgoingMailServerHostName: {type: "string"},
|
||||
OutgoingMailServerPortNumber: {type: "number"},
|
||||
OutgoingMailServerUsername: {type: "string"},
|
||||
OutgoingMailServerUseSSL: {type: "boolean"},
|
||||
OutgoingPasswordSameAsIncomingPassword: {type: "boolean"},
|
||||
OutgoingMailServerHostName: "smtp.example.com",
|
||||
OutgoingMailServerPortNumber: 465,
|
||||
OutgoingMailServerUsername: "john@example.com",
|
||||
|
||||
PayloadDescription: {type: "string"},
|
||||
PayloadDisplayName: {type: "string"},
|
||||
PayloadIdentifier: {type: "string"},
|
||||
PayloadType: {type: "string", constant: true, value: "com.apple.mail.managed"},
|
||||
PayloadUUID: {type: "function", constant: true, value: generateUUID},
|
||||
PayloadVersion: {type: "number", constant: true, value: 1},
|
||||
}
|
||||
|
||||
let containerForm = {
|
||||
PayloadDescription: {type: "string"},
|
||||
PayloadDisplayName: {type: "string"},
|
||||
PayloadIdentifier: {type: "string"},
|
||||
PayloadType: {type: "string", constant: true, value: "Configuration"},
|
||||
PayloadUUID: {type: "function", constant: true, value: generateUUID},
|
||||
PayloadVersion: {type: "number", constant: true, value: 1},
|
||||
PayloadDescription: "Email configuration profile",
|
||||
PayloadDisplayName: "Display name",
|
||||
PayloadIdentifier: "com.apple.dns.reverse",
|
||||
},
|
||||
container: {
|
||||
PayloadDescription: "",
|
||||
PayloadDisplayName: "",
|
||||
PayloadIdentifier: "",
|
||||
PayloadType: "Configuration",
|
||||
PayloadUUID: generateUUID,
|
||||
PayloadVersion: 1,
|
||||
},
|
||||
containerPlaceholders: {
|
||||
PayloadDescription: "Email configuration profile",
|
||||
PayloadDisplayName: "Display name",
|
||||
PayloadIdentifier: "com.apple.dns.reverse",
|
||||
},
|
||||
generated: false,
|
||||
}
|
||||
|
||||
function generateUUID() {
|
||||
|
@ -45,7 +65,7 @@ function generateUUID() {
|
|||
}
|
||||
|
||||
function convertKeyValueToXml(xmlDoc, key, value) {
|
||||
let keyElement = xmlDoc.createElement("key");
|
||||
const keyElement = xmlDoc.createElement("key");
|
||||
keyElement.innerHTML = key;
|
||||
|
||||
let valueElementTag = null;
|
||||
|
@ -64,138 +84,55 @@ function convertKeyValueToXml(xmlDoc, key, value) {
|
|||
if (valueElementTag === null) {
|
||||
throw Error("Value type not recognized")
|
||||
}
|
||||
let valueElement = xmlDoc.createElement(valueElementTag);
|
||||
const valueElement = xmlDoc.createElement(valueElementTag);
|
||||
if (typeof value === "number" || typeof value === "string"){
|
||||
valueElement.innerHTML = value;
|
||||
}
|
||||
return [keyElement, valueElement];
|
||||
}
|
||||
|
||||
function generateProfile(event) {
|
||||
let payload = {
|
||||
EmailAccountType: "EmailTypeIMAP",
|
||||
EmailAddress: "gabriel@augendre.info",
|
||||
EmailAccountDescription: "Migadu",
|
||||
const app = new Vue({
|
||||
el: '#app',
|
||||
data: data,
|
||||
computed: {
|
||||
generatedProfile: function () {
|
||||
const template = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" +
|
||||
"<plist version='1.0'><dict></dict></plist>"
|
||||
const parser = new DOMParser();
|
||||
const xmlDoc = parser.parseFromString(template, "application/xml");
|
||||
const dict = xmlDoc.getElementsByTagName("dict")[0];
|
||||
|
||||
IncomingMailServerAuthentication: "EmailAuthPassword",
|
||||
IncomingMailServerHostName: "imap.migadu.com",
|
||||
IncomingMailServerPortNumber: 993,
|
||||
IncomingMailServerUsername: "gabriel@augendre.info",
|
||||
IncomingMailServerUseSSL: true,
|
||||
const contentElement = xmlDoc.createElement("key");
|
||||
contentElement.innerHTML = "PayloadContent";
|
||||
dict.appendChild(contentElement);
|
||||
const arrayElement = xmlDoc.createElement("array");
|
||||
dict.appendChild(arrayElement);
|
||||
const contentDict = xmlDoc.createElement("dict");
|
||||
arrayElement.appendChild(contentDict);
|
||||
|
||||
OutgoingMailServerAuthentication: "EmailAuthPassword",
|
||||
OutgoingMailServerHostName: "smtp.migadu.com",
|
||||
OutgoingMailServerPortNumber: 465,
|
||||
OutgoingMailServerUsername: "gabriel@augendre.info",
|
||||
OutgoingMailServerUseSSL: true,
|
||||
OutgoingPasswordSameAsIncomingPassword: true,
|
||||
for (const [key, value] of Object.entries(this.payload)) {
|
||||
const [keyElement, valueElement] = convertKeyValueToXml(xmlDoc, key, value);
|
||||
contentDict.appendChild(keyElement);
|
||||
contentDict.appendChild(valueElement);
|
||||
}
|
||||
|
||||
PayloadDisplayName: "Migadu",
|
||||
PayloadIdentifier: "info.augendre.mail.config.migadu",
|
||||
PayloadType: "com.apple.mail.managed",
|
||||
PayloadUUID: generateUUID,
|
||||
PayloadVersion: 1,
|
||||
for (const [key, value] of Object.entries(this.container)) {
|
||||
const [keyElement, valueElement] = convertKeyValueToXml(xmlDoc, key, value);
|
||||
dict.appendChild(keyElement);
|
||||
dict.appendChild(valueElement);
|
||||
}
|
||||
|
||||
const serializer = new XMLSerializer();
|
||||
return serializer.serializeToString(xmlDoc);
|
||||
},
|
||||
generatedProfileLink: function () {
|
||||
const xmlString = this.generatedProfile;
|
||||
return 'data:application/xml;charset=utf-8,' + encodeURIComponent(xmlString);
|
||||
},
|
||||
downloadFileName: function() {
|
||||
return `${this.payload.EmailAddress}.mobileconfig`;
|
||||
},
|
||||
}
|
||||
|
||||
let container = {
|
||||
PayloadDescription: "Migadu email configuration profile",
|
||||
PayloadDisplayName: "Migadu",
|
||||
PayloadIdentifier: "info.augendre.mail.config.migadu",
|
||||
PayloadType: "Configuration",
|
||||
PayloadUUID: generateUUID,
|
||||
PayloadVersion: 1,
|
||||
}
|
||||
let downloadLink = document.getElementById("download-link");
|
||||
if (downloadLink) {
|
||||
document.body.removeChild(downloadLink);
|
||||
}
|
||||
|
||||
let template = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" +
|
||||
"<plist version='1.0'><dict></dict></plist>"
|
||||
let parser = new DOMParser();
|
||||
let xmlDoc = parser.parseFromString(template, "application/xml");
|
||||
let dict = xmlDoc.getElementsByTagName("dict")[0];
|
||||
|
||||
let contentElement = xmlDoc.createElement("key");
|
||||
contentElement.innerHTML = "PayloadContent";
|
||||
dict.appendChild(contentElement);
|
||||
let arrayElement = xmlDoc.createElement("array");
|
||||
dict.appendChild(arrayElement);
|
||||
let contentDict = xmlDoc.createElement("dict");
|
||||
arrayElement.appendChild(contentDict);
|
||||
|
||||
for (let [key, value] of Object.entries(payload)) {
|
||||
let [keyElement, valueElement] = convertKeyValueToXml(xmlDoc, key, value);
|
||||
contentDict.appendChild(keyElement);
|
||||
contentDict.appendChild(valueElement);
|
||||
}
|
||||
|
||||
for (let [key, value] of Object.entries(container)) {
|
||||
let [keyElement, valueElement] = convertKeyValueToXml(xmlDoc, key, value);
|
||||
dict.appendChild(keyElement);
|
||||
dict.appendChild(valueElement);
|
||||
}
|
||||
|
||||
|
||||
var serializer = new XMLSerializer();
|
||||
var xmlString = serializer.serializeToString(xmlDoc);
|
||||
|
||||
let area = document.getElementById("profile");
|
||||
area.value = xmlString;
|
||||
|
||||
let link = document.createElement('a');
|
||||
link.setAttribute("id", "download-link")
|
||||
link.setAttribute('href', 'data:application/xml;charset=utf-8,' + encodeURIComponent(xmlString));
|
||||
link.setAttribute('download', `${payload.EmailAddress}.mobileconfig`);
|
||||
link.innerHTML = "Download profile";
|
||||
document.body.appendChild(link);
|
||||
}
|
||||
|
||||
function getElemFromConfig(key, value, prefix) {
|
||||
const identifier = `${prefix}-${key}`;
|
||||
let input = document.createElement("input");
|
||||
input.setAttribute("type", value.type);
|
||||
input.setAttribute("id", identifier);
|
||||
input.setAttribute("name", identifier);
|
||||
|
||||
let defaultValue = value.value;
|
||||
if (typeof defaultValue === "function") {
|
||||
defaultValue = defaultValue();
|
||||
}
|
||||
if (defaultValue) {
|
||||
input.value = defaultValue;
|
||||
}
|
||||
if (value.constant) {
|
||||
input.setAttribute("disabled", "disabled");
|
||||
}
|
||||
|
||||
let label = document.createElement("label");
|
||||
label.setAttribute("for", identifier);
|
||||
label.innerHTML = key;
|
||||
|
||||
const p = document.createElement("p");
|
||||
p.appendChild(label);
|
||||
p.appendChild(input);
|
||||
return p;
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function(){
|
||||
let form = document.getElementById("profile-form");
|
||||
let button = document.querySelector("form#profile-form button[type='button']");
|
||||
let title = document.createElement("h2");
|
||||
title.innerHTML = "Container"
|
||||
form.insertBefore(title, button);
|
||||
for (let [key, value] of Object.entries(containerForm)) {
|
||||
let line = getElemFromConfig(key, value, "container");
|
||||
form.insertBefore(line, button);
|
||||
}
|
||||
title = document.createElement("h2");
|
||||
title.innerHTML = "Payload"
|
||||
form.insertBefore(title, button);
|
||||
for (let [key, value] of Object.entries(payloadForm)) {
|
||||
let line = getElemFromConfig(key, value, "payload");
|
||||
form.insertBefore(line, button);
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
|
|
Loading…
Reference in a new issue