mirror of
https://github.com/fleetdm/fleet
synced 2026-04-21 13:37:30 +00:00
813 lines
24 KiB
HTML
813 lines
24 KiB
HTML
<html>
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<meta name="robots" content="noindex" />
|
|
<link rel="shortcut icon" href="{{.URLPrefix}}/assets/favicon.ico" />
|
|
<title>Fleet</title>
|
|
<style nonce="{{.CSPNonce}}">
|
|
@font-face {
|
|
font-family: "Inter";
|
|
font-weight: 400;
|
|
src: url("../assets/fonts/inter/Inter-Regular.woff2") format("woff2"),
|
|
url("../assets/fonts/inter/Inter-Regular.woff") format("woff");
|
|
}
|
|
@font-face {
|
|
font-family: "Inter";
|
|
font-weight: 600;
|
|
src: url("../assets/fonts/inter/Inter-Semibold.woff2") format("woff2"),
|
|
url("../assets/fonts/inter/Inter-Semibold.woff") format("woff");
|
|
}
|
|
|
|
html {
|
|
box-sizing: border-box;
|
|
font-family: "Inter", sans-serif;
|
|
color: #515774;
|
|
line-height: 1.5;
|
|
font-size: 1.25rem;
|
|
}
|
|
|
|
*,
|
|
*:before,
|
|
*:after {
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
body,
|
|
h1,
|
|
p {
|
|
margin: 0;
|
|
}
|
|
|
|
.download-link,
|
|
.enroll-link {
|
|
display: inline-block;
|
|
color: #fff;
|
|
background-color: #009a7d;
|
|
padding: 8px 16px;
|
|
border-radius: 4px;
|
|
text-decoration: none;
|
|
font-weight: 600;
|
|
font-size: 14px;
|
|
line-height: 21px;
|
|
text-align: center;
|
|
}
|
|
|
|
header {
|
|
padding: 13px 20px;
|
|
border-bottom: 1px solid #e2e4ea;
|
|
}
|
|
|
|
p {
|
|
font-size: 14px;
|
|
}
|
|
|
|
a {
|
|
color: #515774;
|
|
text-decoration: none;
|
|
font-weight: 600;
|
|
border-bottom: 1px solid #e2e4ea;
|
|
}
|
|
|
|
ol {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 48px;
|
|
list-style: none;
|
|
padding: 0;
|
|
margin: 0;
|
|
}
|
|
|
|
li {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 20px;
|
|
align-items: flex-start;
|
|
}
|
|
|
|
.android-content {
|
|
margin-top: 48px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: flex-start;
|
|
gap: 20px;
|
|
}
|
|
|
|
.switch-browser-content {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: flex-start;
|
|
gap: 20px;
|
|
}
|
|
|
|
.page-description {
|
|
font-size: 16px;
|
|
margin-bottom: 48px;
|
|
}
|
|
|
|
.profile-downloaded-container,
|
|
.install-profile-container {
|
|
width: 100%;
|
|
background-color: #f9fafc;
|
|
text-align: center;
|
|
}
|
|
|
|
.profile-downloaded-img,
|
|
.install-profile-img {
|
|
max-width: 100%;
|
|
}
|
|
|
|
.profile-downloaded-img {
|
|
max-height: 150px;
|
|
}
|
|
|
|
.install-profile-img {
|
|
max-height: 118px;
|
|
}
|
|
|
|
#main-content {
|
|
margin: 0 auto;
|
|
padding: 48px 24px;
|
|
max-width: 1000px;
|
|
}
|
|
|
|
.device-instructions-content {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 48px;
|
|
}
|
|
|
|
.content-with-sidebar {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
gap: 64px;
|
|
}
|
|
|
|
.mobile-enroll-sidebar p {
|
|
max-width: 208px;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.qr-container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 24px;
|
|
background-color: #f9fafc;
|
|
padding: 24px;
|
|
border: 1px solid #e2e4ea;
|
|
border-radius: 8px;
|
|
}
|
|
|
|
.fully-managed-instructions .qr-container {
|
|
padding: 8px;
|
|
border-radius: 4px;
|
|
background-color: #fff;
|
|
}
|
|
|
|
.device-enroll-message {
|
|
margin-top: 48px;
|
|
display: flex;
|
|
gap: 8px;
|
|
}
|
|
|
|
.error-header {
|
|
display: flex;
|
|
gap: 8px;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin-bottom: 24px;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.error-description {
|
|
text-align: center;
|
|
}
|
|
|
|
@media screen and (max-width: 1344px) {
|
|
.device-instructions-content {
|
|
gap: 24px;
|
|
}
|
|
|
|
.enroll-link {
|
|
width: 100%;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<!-- unsupported platform content, not macos, ios, ipados, or android -->
|
|
<template id="unsupported-template">
|
|
<div class="content-with-sidebar">
|
|
<section class="device-instructions-content">
|
|
<h1>How to enroll your device to Fleet</h1>
|
|
<p class="page-description">
|
|
To enroll your Mac, please open this page on your device.
|
|
</p>
|
|
</section>
|
|
<section class="mobile-enroll-sidebar">
|
|
<div class="qr-container">
|
|
<p>Trying to enroll your mobile device?</p>
|
|
<canvas class="qr-code"></canvas>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</template>
|
|
|
|
<!-- android content when not fully managed-->
|
|
<template id="android-template">
|
|
<section class="device-instructions-content">
|
|
<h1>How to enroll your Android device to Fleet</h1>
|
|
<div class="android-content">
|
|
<p>Select <b>Enroll</b> and follow the steps.</p>
|
|
<a class="enroll-link" href="" target="_blank">Enroll</a>
|
|
<p>Already finished? You can close this tab.</p>
|
|
</div>
|
|
</section>
|
|
</template>
|
|
|
|
<!-- content when full managed is enabled. This will show for any platform, despite the copy referencing Android -->
|
|
<template id="fully-managed-template">
|
|
<section class="device-instructions-content">
|
|
<h1>How to enroll your Android device to Fleet</h1>
|
|
<ol class="fully-managed-instructions">
|
|
<li>
|
|
<p>
|
|
<span>1.</span>
|
|
<span>
|
|
Turn on your new device or
|
|
<a
|
|
target="_blank"
|
|
href="https://support.google.com/android/answer/6088915?hl=en"
|
|
>
|
|
factory reset it
|
|
<svg
|
|
width="9"
|
|
height="9"
|
|
viewBox="0 0 9 9"
|
|
fill="none"
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
>
|
|
<rect
|
|
x="0.5"
|
|
y="0.5"
|
|
width="8"
|
|
height="8"
|
|
rx="2"
|
|
stroke="#515774"
|
|
/>
|
|
<path
|
|
d="M3.49992 2.83325H6.16659M6.16659 2.83325V5.49992M6.16659 2.83325L2.83325 6.16659"
|
|
stroke="#515774"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
/>
|
|
</svg>
|
|
</a>
|
|
</span>
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
<span>2.</span>
|
|
<span>
|
|
On the very first screen, tap the screen six times in a blank
|
|
area.
|
|
</span>
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
<span>3.</span>
|
|
<span>Scan QR code below with the QR reader that shows up.</span>
|
|
</p>
|
|
<div class="qr-container">
|
|
<canvas class="qr-code"></canvas>
|
|
</div>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
<span>4.</span>
|
|
<span>
|
|
Connect to Wi-Fi and follow the instructions on the screen.
|
|
</span>
|
|
</p>
|
|
</li>
|
|
</ol>
|
|
<p>QR code invalid? Refresh the page.</p>
|
|
</section>
|
|
</template>
|
|
|
|
<!-- ios, ipados content -->
|
|
<template id="ios-ipad-template">
|
|
<section class="device-instructions-content">
|
|
<h1>
|
|
How to enroll your
|
|
<span data-attribute="dynamic-device-type">iPhone or iPad</span> to
|
|
Fleet
|
|
</h1>
|
|
<ol>
|
|
<li>
|
|
<p>
|
|
<span>1.</span>
|
|
<span>
|
|
Tap the button below to download the Fleet profile. When
|
|
prompted, tap <b>Allow</b>.
|
|
</span>
|
|
</p>
|
|
<a class="download-link" href="{{.EnrollURL}}">Download</a>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
<span>2.</span>
|
|
<span>Go to <b>Settings > Profile Downloaded</b>.</span>
|
|
</p>
|
|
<div class="profile-downloaded-container">
|
|
<img
|
|
class="profile-downloaded-img"
|
|
src=""
|
|
alt="select profile downloaded in settings"
|
|
/>
|
|
</div>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
<span>3.</span>
|
|
<span>
|
|
Tap <b>Install</b>. You'll see a few warnings, which is
|
|
expected. Tap <b>Install</b> again when prompted.
|
|
</span>
|
|
</p>
|
|
<div class="install-profile-container">
|
|
<img class="install-profile-img" src="" alt="select install" />
|
|
</div>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
<span>4.</span>
|
|
<span>
|
|
When you see the <b>Remote Management</b> screen, tap
|
|
<b>Trust</b>.
|
|
</span>
|
|
</p>
|
|
</li>
|
|
</ol>
|
|
<p>Done! You can close this tab.</p>
|
|
</section>
|
|
</template>
|
|
|
|
<!-- macos content -->
|
|
<template id="macos-template">
|
|
<div class="content-with-sidebar">
|
|
<section class="device-instructions-content">
|
|
<h1>How to turn on MDM on your Mac</h1>
|
|
<ol>
|
|
<li>
|
|
<p>
|
|
<span>1.</span>
|
|
<span>
|
|
Tap the button below to download the Fleet profile. Open it.
|
|
You'll see a warning, which is expected.
|
|
</span>
|
|
</p>
|
|
<a class="download-link" href="{{.EnrollURL}}">Download</a>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
<span>2.</span>
|
|
<span>
|
|
Go to the Apple menu in the top left corner of your screen.
|
|
Select
|
|
<b>System Settings</b>.
|
|
</span>
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
<span>3.</span>
|
|
<span>
|
|
Go to <b>Profile Downloaded</b>. Double-click the
|
|
<b>[Organization name] enrollment</b> profile.
|
|
</span>
|
|
</p>
|
|
</li>
|
|
<li>
|
|
<p>
|
|
<span>4.</span>
|
|
<span>Select <b>Install</b>. Enter your password.</span>
|
|
</p>
|
|
</li>
|
|
</ol>
|
|
<p>Done! You can close this tab.</p>
|
|
</section>
|
|
<section class="mobile-enroll-sidebar">
|
|
<div class="qr-container">
|
|
<p>Trying to enroll your mobile device?</p>
|
|
<canvas class="qr-code"></canvas>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</template>
|
|
|
|
<!-- Open in Safari content (iOS/iPadOS only) -->
|
|
<template id="open-in-safari-template">
|
|
<section class="device-instructions-content">
|
|
<h1>Please open in Safari</h1>
|
|
<div class="switch-browser-content">
|
|
<p>
|
|
To enroll your device, this page needs to be opened in
|
|
<b>Safari</b>.
|
|
</p>
|
|
<button class="enroll-link open-safari-btn">Open in Safari</button>
|
|
<p class="safari-fallback-msg" style="display: none">
|
|
URL copied to clipboard. Please open <b>Safari</b> and paste the
|
|
URL.
|
|
</p>
|
|
</div>
|
|
</section>
|
|
</template>
|
|
|
|
<!-- Error content -->
|
|
<template id="error-template">
|
|
<h1 class="error-header">
|
|
<svg
|
|
width="16"
|
|
height="17"
|
|
viewBox="0 0 16 17"
|
|
fill="none"
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
>
|
|
<path
|
|
fill-rule="evenodd"
|
|
clip-rule="evenodd"
|
|
d="M8 0.5C3.58 0.5 0 4.08 0 8.5C0 12.92 3.58 16.5 8 16.5C12.42 16.5 16 12.92 16 8.5C16 4.08 12.42 0.5 8 0.5ZM8 3.75C8.41421 3.75 8.75 4.08579 8.75 4.5V9.5C8.75 9.91421 8.41421 10.25 8 10.25C7.58579 10.25 7.25 9.91421 7.25 9.5V4.5C7.25 4.08579 7.58579 3.75 8 3.75ZM8 13.5C8.55229 13.5 9 13.0523 9 12.5C9 11.9477 8.55229 11.5 8 11.5C7.44772 11.5 7 11.9477 7 12.5C7 13.0523 7.44772 13.5 8 13.5Z"
|
|
fill="#D66C7B"
|
|
/>
|
|
</svg>
|
|
<p class="error-title"></p>
|
|
</h1>
|
|
<p class="error-description"></p>
|
|
</template>
|
|
|
|
<header>
|
|
<img src="{{.URLPrefix}}/assets/images/fleet-logo.svg" />
|
|
</header>
|
|
|
|
<!-- container for the dynamic content -->
|
|
<section id="main-content"></section>
|
|
|
|
<!-- using qrcode library to generate QR codes -->
|
|
<script
|
|
src="https://cdnjs.cloudflare.com/ajax/libs/qrcode/1.5.1/qrcode.min.js"
|
|
integrity="sha512-PEhlWBZBrQL7flpJPY8lXx8tIN7HWX912GzGhFTDqA3iWFrakVH3lVHomCoU9BhfKzgxfEk6EG2C3xej+9srOQ=="
|
|
crossorigin="anonymous"
|
|
referrerpolicy="no-referrer"
|
|
defer
|
|
nonce="{{.CSPNonce}}"
|
|
></script>
|
|
|
|
<script nonce="{{.CSPNonce}}">
|
|
const ANDROID_GET_TOKEN_URL =
|
|
"{{.URLPrefix}}/api/v1/fleet/android_enterprise/enrollment_token";
|
|
// using string comparison to satisfy the linter.
|
|
const ANDROID_MDM_ENABLED = "{{.AndroidMDMEnabled}}" === "true";
|
|
const MAC_MDM_ENABLED = "{{.MacMDMEnabled}}" == "true";
|
|
const ERROR_MESSAGE = "{{.ErrorMessage}}";
|
|
const isFullyManaged = new URLSearchParams(window.location.search).has(
|
|
"fully_managed",
|
|
true
|
|
);
|
|
|
|
const getPlatform = () => {
|
|
const userAgent = navigator.userAgent;
|
|
const isIPhone = /iPhone/i.test(userAgent);
|
|
const isIPad =
|
|
/iPad/i.test(userAgent) ||
|
|
(/Macintosh/i.test(userAgent) &&
|
|
navigator.maxTouchPoints !== undefined &&
|
|
navigator.maxTouchPoints > 1);
|
|
const isAndroid = /Android/i.test(userAgent);
|
|
const isMac =
|
|
(/Macintosh/i.test(userAgent) && !isIPad) ||
|
|
/Mac OS X/i.test(userAgent);
|
|
|
|
switch (true) {
|
|
case isAndroid:
|
|
return "android";
|
|
case isIPhone:
|
|
return "ios";
|
|
case isIPad:
|
|
return "ipad";
|
|
case isMac:
|
|
return "macos";
|
|
default:
|
|
return "unsupported";
|
|
}
|
|
};
|
|
|
|
// Detects if the browser is Safari on iOS/iPadOS
|
|
// Other browsers on iOS: CriOS (Chrome), FxiOS (Firefox), EdgiOS (Edge), OPiOS or OPT (Opera)
|
|
// Brave (Brave)
|
|
const isSafariBrowser = () => {
|
|
const ua = navigator.userAgent;
|
|
return (
|
|
/Safari/i.test(ua) &&
|
|
!/CriOS/i.test(ua) &&
|
|
!/FxiOS/i.test(ua) &&
|
|
!/EdgiOS/i.test(ua) &&
|
|
!/OPiOS/i.test(ua) &&
|
|
!/OPT/i.test(ua) &&
|
|
!/Brave/i.test(ua)
|
|
);
|
|
};
|
|
|
|
// Attempts to open the current URL in Safari, falls back to clipboard copy
|
|
const openInSafari = async () => {
|
|
const currentUrl = window.location.href;
|
|
const safariUrl = currentUrl.replace(
|
|
/^https?:\/\//,
|
|
"x-safari-https://"
|
|
);
|
|
|
|
// Track if the page loses focus (indicates Safari opened)
|
|
let didNavigate = false;
|
|
const handleBlur = () => {
|
|
didNavigate = true;
|
|
};
|
|
window.addEventListener("blur", handleBlur);
|
|
|
|
// Try to open Safari via URL scheme
|
|
window.location.href = safariUrl;
|
|
|
|
// Wait a moment to see if navigation occurred
|
|
setTimeout(async () => {
|
|
window.removeEventListener("blur", handleBlur);
|
|
|
|
if (!didNavigate) {
|
|
// URL scheme didn't work, fall back to clipboard
|
|
try {
|
|
await navigator.clipboard.writeText(currentUrl);
|
|
const fallbackMsg = document.querySelector(
|
|
".safari-fallback-msg"
|
|
);
|
|
const openBtn = document.querySelector(".open-safari-btn");
|
|
if (fallbackMsg) {
|
|
fallbackMsg.style.display = "block";
|
|
}
|
|
if (openBtn) {
|
|
openBtn.textContent = "URL Copied";
|
|
openBtn.disabled = true;
|
|
openBtn.style.backgroundColor = "#6A6A6A";
|
|
}
|
|
} catch (err) {
|
|
console.error("Failed to copy URL to clipboard", err);
|
|
}
|
|
}
|
|
}, 500);
|
|
};
|
|
|
|
/**
|
|
* Renders a QR code for the given text into the specified element.
|
|
* @param {string} text - The text to encode in the QR code.
|
|
* @param {HTMLElement} element - The HTML element where the QR code will be rendered.
|
|
* @param {Object} [options] - Optional configuration for the QR code (e.g., width, margin,
|
|
* color). valid options can be found here:
|
|
* https://github.com/soldair/node-qrcode?tab=readme-ov-file#options-9
|
|
*/
|
|
const renderQRCode = (text, element, options) => {
|
|
let QROptions = {
|
|
width: 208,
|
|
margin: 0,
|
|
color: { dark: "#515774", light: "#F9FAFC" },
|
|
};
|
|
|
|
if (options) {
|
|
QROptions = { ...QROptions, ...options };
|
|
}
|
|
QRCode.toCanvas(element, text, QROptions, function (error) {
|
|
if (error) console.error("problem with rendering QR code", error);
|
|
});
|
|
};
|
|
|
|
const getTemplateIdFromPlatform = (platform) => {
|
|
switch (true) {
|
|
case platform === "android":
|
|
return "android-template";
|
|
case platform === "ios" || platform === "ipad":
|
|
return "ios-ipad-template";
|
|
case platform === "macos":
|
|
return "macos-template";
|
|
default:
|
|
return "unsupported-template";
|
|
}
|
|
};
|
|
|
|
// renders the content based on the template id
|
|
const renderContent = (templateId) => {
|
|
const template = document.getElementById(templateId);
|
|
if (template) {
|
|
document
|
|
.getElementById("main-content")
|
|
.appendChild(template.content.cloneNode(true));
|
|
}
|
|
};
|
|
|
|
const setEnrollTokenUrl = (url) => {
|
|
document.querySelector(".enroll-link").setAttribute("href", url);
|
|
};
|
|
|
|
// dynmaic content rendering for ios and ipad only
|
|
const setIosIpadContent = (platform) => {
|
|
if (platform === "ios") {
|
|
deviceType = "iPhone";
|
|
} else if (platform === "ipad") {
|
|
deviceType = "iPad";
|
|
}
|
|
|
|
document
|
|
.querySelectorAll('[data-attribute="dynamic-device-type"]')
|
|
.forEach((el) => {
|
|
el.textContent = deviceType;
|
|
});
|
|
|
|
// update image src based on OS
|
|
const osImagePrefix = platform === "ios" ? "ios" : "iPadOS";
|
|
document.querySelector(
|
|
".profile-downloaded-img"
|
|
).src = `{{.URLPrefix}}/assets/images/${osImagePrefix}-profile-downloaded.png`;
|
|
document.querySelector(
|
|
".install-profile-img"
|
|
).src = `{{.URLPrefix}}/assets/images/${osImagePrefix}-install-profile.png`;
|
|
};
|
|
|
|
const renderError = (title, description) => {
|
|
const template = document.getElementById("error-template");
|
|
if (template) {
|
|
const clone = template.content.cloneNode(true);
|
|
clone.querySelector(".error-title").textContent = title;
|
|
clone.querySelector(".error-description").textContent = description;
|
|
document.getElementById("main-content").appendChild(clone);
|
|
}
|
|
};
|
|
|
|
const getEnrollmentSecret = () => {
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
return urlParams.get("enroll_secret");
|
|
};
|
|
|
|
const getEnrollmentToken = async (fullyManaged) => {
|
|
const enrollSecret = getEnrollmentSecret();
|
|
|
|
let url = `${ANDROID_GET_TOKEN_URL}?enroll_secret=${encodeURIComponent(
|
|
enrollSecret
|
|
)}`;
|
|
|
|
if (fullyManaged) {
|
|
url = url.concat("&fully_managed=true");
|
|
}
|
|
|
|
const response = await fetch(url, {
|
|
method: "GET",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
});
|
|
if (!response.ok) {
|
|
throw new Error("Failed to get enrollment token");
|
|
}
|
|
return await response.json();
|
|
};
|
|
|
|
// here we render the page content
|
|
document.addEventListener("DOMContentLoaded", async function () {
|
|
// if there is an error message, render it
|
|
if (ERROR_MESSAGE) {
|
|
// format of error message is expected to use colon as separator character, e.g., "An error occurred. : Failed to parse original URL."
|
|
const [title, description] = ERROR_MESSAGE.split(":");
|
|
renderError(title.trim(), description.trim());
|
|
return;
|
|
}
|
|
|
|
// check if there is an enrollment secret
|
|
if (!getEnrollmentSecret()) {
|
|
renderError(
|
|
"This URL is invalid.",
|
|
"Enroll secret is missing. Please contact your IT admin."
|
|
);
|
|
return;
|
|
}
|
|
|
|
const platform = getPlatform();
|
|
|
|
if (isFullyManaged) {
|
|
if (platform === "android" && !ANDROID_MDM_ENABLED) {
|
|
renderError(
|
|
"Android MDM is turned off.",
|
|
"To enroll your Android device please contact your IT admin."
|
|
);
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const data = await getEnrollmentToken(true);
|
|
if (!data.android_enrollment_qr_code) {
|
|
throw new Error("Failed to get QR code");
|
|
}
|
|
renderContent("fully-managed-template");
|
|
renderQRCode(
|
|
data.android_enrollment_qr_code,
|
|
document.querySelector(".qr-code"),
|
|
{ width: 245, color: { dark: "#515774", light: "#fff" } }
|
|
);
|
|
} catch (error) {
|
|
renderError(
|
|
"Couldn't get Android enrollment token.",
|
|
"Please refresh the page. If the issue continues, contact your IT admin."
|
|
);
|
|
return;
|
|
}
|
|
return;
|
|
}
|
|
|
|
// render unsupported platform content. Unsupported means not macos, ios, ipad, or android
|
|
if (platform === "unsupported") {
|
|
renderContent("unsupported-template");
|
|
renderQRCode(
|
|
window.location.href,
|
|
document.querySelector(".qr-code")
|
|
);
|
|
return;
|
|
}
|
|
|
|
let templateId = getTemplateIdFromPlatform(platform);
|
|
|
|
// handle android rendering
|
|
if (platform === "android") {
|
|
if (!ANDROID_MDM_ENABLED) {
|
|
renderError(
|
|
"Android MDM is turned off.",
|
|
"To enroll your Android device please contact your IT admin."
|
|
);
|
|
return;
|
|
}
|
|
|
|
// we need to get the token and then place it in the enroll link
|
|
try {
|
|
const data = await getEnrollmentToken();
|
|
renderContent(templateId);
|
|
if (!data.android_enrollment_url) {
|
|
throw new Error("Failed to get enrollment token");
|
|
}
|
|
setEnrollTokenUrl(data.android_enrollment_url);
|
|
} catch (error) {
|
|
renderError(
|
|
"Couldn't get Android enrollment token.",
|
|
"Please refresh the page. If the issue continues, contact your IT admin."
|
|
);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// handle rendering for macos
|
|
if (platform === "macos") {
|
|
if (!MAC_MDM_ENABLED) {
|
|
renderError(
|
|
"Apple MDM is turned off.",
|
|
"To enroll your Mac device please contact your IT admin."
|
|
);
|
|
return;
|
|
}
|
|
renderContent(templateId);
|
|
renderQRCode(
|
|
window.location.href,
|
|
document.querySelector(".qr-code")
|
|
);
|
|
}
|
|
|
|
// handle rendering for ios and ipad
|
|
if (platform === "ios" || platform === "ipad") {
|
|
if (!MAC_MDM_ENABLED) {
|
|
const description = `To enroll your ${
|
|
platform === "ios" ? "iPhone" : "iPad"
|
|
} please contact your IT admin.`;
|
|
renderError("Apple MDM is turned off.", description);
|
|
return;
|
|
}
|
|
|
|
// Check if user is NOT in Safari - redirect them to Safari
|
|
if (!isSafariBrowser()) {
|
|
renderContent("open-in-safari-template");
|
|
const openBtn = document.querySelector(".open-safari-btn");
|
|
if (openBtn) {
|
|
openBtn.addEventListener("click", openInSafari);
|
|
}
|
|
return;
|
|
}
|
|
|
|
renderContent(templateId);
|
|
setIosIpadContent(platform);
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|