pull/302/head
shamalka 12 months ago
commit 422790ef71

@ -113,6 +113,11 @@ public class Filter {
*/
private String favouredBy;
/**
* Checking if retired apps needs to be excluded
*/
private boolean isNotRetired;
public int getLimit() {
return limit;
}
@ -208,4 +213,12 @@ public class Filter {
public void setFavouredBy(String favouredBy) {
this.favouredBy = favouredBy;
}
public boolean isNotRetired() {
return isNotRetired;
}
public void setNotRetired(boolean notRetired) {
isNotRetired = notRetired;
}
}

@ -180,6 +180,9 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic
if (deviceTypeId != -1) {
sql += "AND AP_APP.DEVICE_TYPE_ID = ? ";
}
if (filter.isNotRetired()) {
sql += "AND AP_APP.STATUS != 'RETIRED' ";
}
sql += "GROUP BY AP_APP.ID ORDER BY AP_APP.ID ";
if (StringUtils.isNotEmpty(filter.getSortBy())) {
sql += filter.getSortBy() +" ";
@ -308,6 +311,9 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic
if (deviceTypeId != -1) {
sql += " AND AP_APP.DEVICE_TYPE_ID = ?";
}
if (filter.isNotRetired()) {
sql += " AND AP_APP.STATUS != 'RETIRED'";
}
try {
conn = this.getDBConnection();

@ -0,0 +1,60 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.device.mgt.common.invitation.mgt;
import java.util.Properties;
public class EnrollmentTypeMail {
private String template;
private String username;
private String recipient;
private Properties properties;
public String getTemplate() {
return template;
}
public void setTemplate(String template) {
this.template = template;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getRecipient() {
return recipient;
}
public void setRecipient(String recipient) {
this.recipient = recipient;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
}

@ -0,0 +1,61 @@
/*
* Copyright (c) 2018 - 2023, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
*
* Entgra (Pvt) Ltd. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package io.entgra.device.mgt.core.device.mgt.common.invitation.mgt;
public class UserMailAttributes {
private String username;
private String firstName;
private String email;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getUsernamePlaceholder() {
return "username";
}
public String getEmailPlaceholder() {
return "email";
}
public String getFirstNamePlaceholder() {
return "first-name";
}
}

@ -121,6 +121,9 @@ public final class DeviceManagementConstants {
public static final String USER_WELCOME_TEMPLATE = "user-welcome";
public static final String DEFAULT_ENROLLMENT_TEMPLATE = "default-enrollment-invitation";
public static final String ENROLLMENT_GUIDE_TEMPLATE = "enrollment-guide";
public static final String DEVICE_ENROLLMENT_MAIL_KEY = "enrollment";
public static final String TEMPLATE_NAME_PART_JOINER = "-";
public static final String ENROLLMENT_TYPE_SPLITTER = "_";
}
public static final class OperationAttributes {

@ -285,32 +285,37 @@ public class ApplicationDAOImpl implements ApplicationDAO {
"MEMORY_USAGE, " +
"IS_ACTIVE, " +
"TENANT_ID " +
"FROM DM_APPLICATION " +
"WHERE NOT EXISTS " +
"(SELECT " +
"ID " +
"FROM DM_APPLICATION A " +
"WHERE A.NAME = DM_APPLICATION.NAME " +
"AND A.ID < DM_APPLICATION.ID) " +
"AND PLATFORM = ? " +
"AND TENANT_ID = ? ";
"FROM DM_APPLICATION " +
"WHERE PLATFORM = ? AND " +
"TENANT_ID = ? AND " +
"NOT EXISTS (SELECT ID " +
"FROM DM_APPLICATION A " +
"WHERE A.NAME = DM_APPLICATION.NAME " +
"AND A.ID < DM_APPLICATION.ID AND " +
"PLATFORM = ? AND TENANT_ID = ?) ";
try {
String filter = request.getFilter();
if (filter != null) {
sql = sql + "AND NAME LIKE ? ";
}
sql = sql + "LIMIT ? OFFSET ?";
if (request != null && request.getRowCount() != -1) {
sql = sql + "LIMIT ? OFFSET ?";
}
Connection conn = this.getConnection();
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
int paramIdx = 1;
stmt.setString(paramIdx++, request.getDeviceType());
stmt.setInt(paramIdx++, tenantId);
stmt.setString(paramIdx++, request.getDeviceType());
stmt.setInt(paramIdx++, tenantId);
if (filter != null){
stmt.setString(paramIdx++, filter);
}
stmt.setInt(paramIdx++, request.getRowCount());
stmt.setInt(paramIdx, request.getStartIndex());
if (request != null && request.getRowCount() != -1) {
stmt.setInt(paramIdx++, request.getRowCount());
stmt.setInt(paramIdx, request.getStartIndex());
}
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
application = loadApplication(rs);

@ -177,12 +177,12 @@ public class SQLServerOperationDAOImpl extends GenericOperationDAOImpl {
operation = new Operation();
operation.setId(rs.getInt("ID"));
operation.setType(Operation.Type.valueOf(rs.getString("TYPE")));
operation.setCreatedTimeStamp(new Timestamp(rs.getLong("CREATED_TIMESTAMP") * 1000L).toString());
operation.setCreatedTimeStamp(new Timestamp(rs.getLong("CREATED_TIMESTAMP") * 1000L).toInstant().toString());
if (rs.getLong("UPDATED_TIMESTAMP") == 0) {
operation.setReceivedTimeStamp("");
} else {
operation.setReceivedTimeStamp(
new java.sql.Timestamp((rs.getLong("UPDATED_TIMESTAMP") * 1000)).toString());
new java.sql.Timestamp((rs.getLong("UPDATED_TIMESTAMP") * 1000)).toInstant().toString());
}
operation.setCode(rs.getString("OPERATION_CODE"));
operation.setStatus(Operation.Status.valueOf(rs.getString("STATUS")));

@ -18,20 +18,12 @@
package io.entgra.device.mgt.core.device.mgt.core.otp.mgt.service;
import com.google.gson.Gson;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.CarbonContext;
import io.entgra.device.mgt.core.device.mgt.common.configuration.mgt.ConfigurationManagementException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.BadRequestException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DBConnectionException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.DeviceManagementException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.OTPManagementException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.TransactionManagementException;
import io.entgra.device.mgt.core.device.mgt.common.exceptions.*;
import io.entgra.device.mgt.core.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitation;
import io.entgra.device.mgt.core.device.mgt.common.invitation.mgt.DeviceEnrollmentInvitationDetails;
import io.entgra.device.mgt.core.device.mgt.common.invitation.mgt.DeviceEnrollmentType;
import io.entgra.device.mgt.core.device.mgt.common.otp.mgt.OTPEmailTypes;
import io.entgra.device.mgt.core.device.mgt.common.invitation.mgt.EnrollmentTypeMail;
import io.entgra.device.mgt.core.device.mgt.common.invitation.mgt.UserMailAttributes;
import io.entgra.device.mgt.core.device.mgt.common.otp.mgt.dto.OneTimePinDTO;
import io.entgra.device.mgt.core.device.mgt.common.spi.OTPManagementService;
import io.entgra.device.mgt.core.device.mgt.core.DeviceManagementConstants;
@ -40,20 +32,16 @@ import io.entgra.device.mgt.core.device.mgt.core.otp.mgt.dao.OTPManagementDAO;
import io.entgra.device.mgt.core.device.mgt.core.otp.mgt.dao.OTPManagementDAOFactory;
import io.entgra.device.mgt.core.device.mgt.core.otp.mgt.exception.OTPManagementDAOException;
import io.entgra.device.mgt.core.device.mgt.core.otp.mgt.util.ConnectionManagerUtil;
import io.entgra.device.mgt.core.device.mgt.core.service.DeviceManagementProviderService;
import io.entgra.device.mgt.core.device.mgt.core.service.EmailMetaInfo;
import io.entgra.device.mgt.core.device.mgt.core.util.DeviceManagerUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.user.api.Tenant;
import org.wso2.carbon.user.api.UserStoreException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;
import java.util.*;
public class OTPManagementServiceImpl implements OTPManagementService {
@ -218,53 +206,12 @@ public class OTPManagementServiceImpl implements OTPManagementService {
}
}
@Override
public void sendDeviceEnrollmentInvitationMail(DeviceEnrollmentInvitation deviceEnrollmentInvitation)
throws OTPManagementException {
DeviceManagementProviderService dms = DeviceManagementDataHolder.getInstance().getDeviceManagementProvider();
StringBuilder enrollmentSteps = new StringBuilder();
DeviceEnrollmentInvitationDetails deviceEnrollmentInvitationDetails;
for (DeviceEnrollmentType deviceEnrollmentType : deviceEnrollmentInvitation.getDeviceEnrollmentTypes()) {
deviceEnrollmentInvitationDetails = dms.getDeviceEnrollmentInvitationDetails(
deviceEnrollmentType.getDeviceType());
if (deviceEnrollmentInvitationDetails != null &&
deviceEnrollmentInvitationDetails.getEnrollmentDetails() != null) {
for (String enrollmentType : deviceEnrollmentType.getEnrollmentType()) {
deviceEnrollmentInvitationDetails.getEnrollmentDetails().stream()
.filter(details -> enrollmentType.equals(details.getEnrollmentType())).findFirst()
.ifPresent(details -> enrollmentSteps.append(details.getEnrollmentSteps()));
}
}
}
Properties props = new Properties();
props.setProperty("enrollment-steps", enrollmentSteps.toString());
try {
ConnectionManagerUtil.beginDBTransaction();
for (String username : deviceEnrollmentInvitation.getUsernames()) {
String emailAddress = DeviceManagerUtil.getUserClaimValue(
username, DeviceManagementConstants.User.CLAIM_EMAIL_ADDRESS);
props.setProperty("first-name", DeviceManagerUtil.
getUserClaimValue(username, DeviceManagementConstants.User.CLAIM_FIRST_NAME));
props.setProperty("username", username);
sendMail(props, emailAddress, DeviceManagementConstants.EmailAttributes.USER_ENROLLMENT_TEMPLATE);
}
ConnectionManagerUtil.commitDBTransaction();
} catch (UserStoreException e) {
String msg = "Error occurred while getting claim values to invite user";
log.error(msg, e);
throw new OTPManagementException(msg, e);
} catch (DBConnectionException e) {
String msg = "Error occurred while getting database connection to add OPT data.";
log.error(msg, e);
throw new OTPManagementException(msg, e);
} catch (TransactionManagementException e) {
String msg = "SQL Error occurred when adding OPT data to send device enrollment Invitation.";
log.error(msg, e);
throw new OTPManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
List<EnrollmentTypeMail> enrollmentTypeMails =
getEnrollmentTypeMails(deviceEnrollmentInvitation.getDeviceEnrollmentTypes());
sendEnrollmentTypeMails(deviceEnrollmentInvitation.getUsernames(), enrollmentTypeMails);
}
/**
@ -296,7 +243,7 @@ public class OTPManagementServiceImpl implements OTPManagementService {
throw new OTPManagementException(msg, e);
} catch (OTPManagementDAOException e) {
ConnectionManagerUtil.rollbackDBTransaction();
String msg = "Error occurred while saving the OTP data for given email" ;
String msg = "Error occurred while saving the OTP data for given email";
log.error(msg, e);
throw new OTPManagementException(msg, e);
} finally {
@ -312,7 +259,7 @@ public class OTPManagementServiceImpl implements OTPManagementService {
* @return {@link OneTimePinDTO}
* @throws OTPManagementException if error occurred while getting OTP data for given OTP in DB
*/
private OneTimePinDTO getOTPDataByToken (String oneTimeToken) throws OTPManagementException {
private OneTimePinDTO getOTPDataByToken(String oneTimeToken) throws OTPManagementException {
try {
ConnectionManagerUtil.openDBConnection();
return otpManagementDAO.getOTPDataByToken(oneTimeToken);
@ -333,7 +280,7 @@ public class OTPManagementServiceImpl implements OTPManagementService {
* If OTP expired, resend the user verifying mail with renewed OTP
* @param props Mail body properties
* @param mailAddress Mail Address of the User
* @param template Mail template to be used
* @param template Mail template to be used
* @throws OTPManagementException if error occurred while resend the user verifying mail
*/
private void sendMail(Properties props, String mailAddress, String template) throws OTPManagementException {
@ -355,7 +302,7 @@ public class OTPManagementServiceImpl implements OTPManagementService {
/**
* Renew the OTP
* @param oneTimePinDTO {@link OneTimePinDTO}
* @param renewedOTP Renewed OTP
* @param renewedOTP Renewed OTP
* @throws OTPManagementException if error occurred while renew the OTP
*/
private void renewOTP(OneTimePinDTO oneTimePinDTO, String renewedOTP) throws OTPManagementException {
@ -380,4 +327,113 @@ public class OTPManagementServiceImpl implements OTPManagementService {
ConnectionManagerUtil.closeDBConnection();
}
}
/**
* Send enrollment type mails to users
* @param usernames List of usernames to send enrollment type mails
* @param enrollmentTypeMails List of enrollment types
* @throws OTPManagementException Throws when error occurred while sending emails
*/
private void sendEnrollmentTypeMails(List<String> usernames, List<EnrollmentTypeMail> enrollmentTypeMails)
throws OTPManagementException {
try {
ConnectionManagerUtil.beginDBTransaction();
for (String username : usernames) {
populateUserAttributes(getUserMailAttributes(username), enrollmentTypeMails);
for (EnrollmentTypeMail enrollmentTypeMail : enrollmentTypeMails) {
sendMail(enrollmentTypeMail);
}
}
ConnectionManagerUtil.commitDBTransaction();
} catch (UserStoreException e) {
String msg = "Error occurred while populating user attributes";
log.error(msg, e);
throw new OTPManagementException(msg, e);
} catch (DBConnectionException e) {
String msg = "Error occurred while getting database connection to add OTP data.";
log.error(msg, e);
throw new OTPManagementException(msg, e);
} catch (TransactionManagementException e) {
String msg = "SQL Error occurred when adding OPT data to send device enrollment Invitation.";
log.error(msg, e);
throw new OTPManagementException(msg, e);
} finally {
ConnectionManagerUtil.closeDBConnection();
}
}
/**
* Send enrollment type mail
* @param enrollmentTypeMail Data related to the enrollment mail
* @throws OTPManagementException Throws when error occurred while sending email
*/
private void sendMail(EnrollmentTypeMail enrollmentTypeMail) throws OTPManagementException {
sendMail(enrollmentTypeMail.getProperties(), enrollmentTypeMail.getRecipient(), enrollmentTypeMail.getTemplate());
}
/**
* Get user claims based on the username
* @param username Username
* @return {@link UserMailAttributes}
* @throws UserStoreException Throws when error occurred while retrieving user claims
*/
private UserMailAttributes getUserMailAttributes(String username) throws UserStoreException {
UserMailAttributes userMailAttributes = new UserMailAttributes();
userMailAttributes.setEmail(DeviceManagerUtil.getUserClaimValue(
username, DeviceManagementConstants.User.CLAIM_EMAIL_ADDRESS));
userMailAttributes.setFirstName(DeviceManagerUtil.
getUserClaimValue(username, DeviceManagementConstants.User.CLAIM_FIRST_NAME));
userMailAttributes.setUsername(username);
return userMailAttributes;
}
/**
* Populate enrollment type mails with provided user attributes
* @param userMailAttributes User attributes
* @param enrollmentTypeMails Enrollment type mails
*/
private void populateUserAttributes(UserMailAttributes userMailAttributes, List<EnrollmentTypeMail> enrollmentTypeMails) {
for (EnrollmentTypeMail enrollmentTypeMail : enrollmentTypeMails) {
Properties properties = new Properties();
properties.setProperty(userMailAttributes.getEmailPlaceholder(), userMailAttributes.getEmail());
properties.setProperty(userMailAttributes.getFirstNamePlaceholder(), userMailAttributes.getFirstName());
properties.setProperty(userMailAttributes.getUsernamePlaceholder(), userMailAttributes.getUsername());
enrollmentTypeMail.setProperties(properties);
enrollmentTypeMail.setUsername(userMailAttributes.getUsername());
enrollmentTypeMail.setRecipient(userMailAttributes.getEmail());
}
}
/**
* Generate enrollment type mail
* @param deviceType Device type of the enrollment type
* @param enrollmentType Enrollment type
* @return {@link EnrollmentTypeMail}
*/
private EnrollmentTypeMail getEnrollmentTypeMail(String deviceType, String enrollmentType) {
EnrollmentTypeMail enrollmentTypeMail = new EnrollmentTypeMail();
enrollmentTypeMail.setUsername(enrollmentTypeMail.getUsername());
enrollmentTypeMail.setTemplate(String.join(DeviceManagementConstants.EmailAttributes.TEMPLATE_NAME_PART_JOINER,
deviceType.toLowerCase(), enrollmentType.toLowerCase().
replace(DeviceManagementConstants.EmailAttributes.ENROLLMENT_TYPE_SPLITTER,
DeviceManagementConstants.EmailAttributes.TEMPLATE_NAME_PART_JOINER),
DeviceManagementConstants.EmailAttributes.DEVICE_ENROLLMENT_MAIL_KEY));
return enrollmentTypeMail;
}
/**
* Generate enrollment type mails from device enrollment types
* @param deviceEnrollmentTypes List of device enrollment types
* @return List of enrollment type mails
*/
private List<EnrollmentTypeMail> getEnrollmentTypeMails(List<DeviceEnrollmentType> deviceEnrollmentTypes) {
List<EnrollmentTypeMail> enrollmentTypeMails = new ArrayList<>();
for (DeviceEnrollmentType deviceEnrollmentType : deviceEnrollmentTypes) {
String deviceType = deviceEnrollmentType.getDeviceType();
for (String enrollmentType : deviceEnrollmentType.getEnrollmentType()) {
enrollmentTypeMails.add(getEnrollmentTypeMail(deviceType, enrollmentType));
}
}
return enrollmentTypeMails;
}
}

@ -19,7 +19,7 @@ CREATE TABLE IF NOT EXISTS AP_APP(
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS AP_APP_RELEASE(
ID INTEGER NOT NULL AUTO_INCREMENT,
DESCRIPTION VARCHAR(200) NOT NULL,
DESCRIPTION TEXT NOT NULL,
VERSION VARCHAR(70) NOT NULL,
TENANT_ID INTEGER NOT NULL,
UUID VARCHAR(200) NOT NULL,
@ -34,7 +34,7 @@ CREATE TABLE IF NOT EXISTS AP_APP_RELEASE(
SC_3_LOCATION VARCHAR(100) NULL DEFAULT NULL,
APP_HASH_VALUE VARCHAR(1000) NOT NULL,
SHARED_WITH_ALL_TENANTS BOOLEAN NOT NULL DEFAULT FALSE,
APP_META_INFO VARCHAR(150) NULL DEFAULT NULL,
APP_META_INFO TEXT NULL DEFAULT NULL,
SUPPORTED_OS_VERSIONS VARCHAR(45) NOT NULL,
RATING DOUBLE NULL DEFAULT NULL,
CURRENT_STATE VARCHAR(45) NOT NULL,
@ -328,4 +328,4 @@ CREATE TABLE IF NOT EXISTS AP_VPP_ASSOCIATION (
PRIMARY KEY (ID),
CONSTRAINT AP_VPP_ASSETS_fk FOREIGN KEY (ASSET_ID) REFERENCES AP_ASSETS (ID) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT AP_VPP_VPP_USER_fk FOREIGN KEY (USER_ID) REFERENCES AP_VPP_USER (ID) ON DELETE CASCADE ON UPDATE CASCADE
);
);

@ -15,56 +15,440 @@
specific language governing permissions and limitations
under the License.
*#
<EmailConfig>
<Subject>You have successfully been registered in Entgra IoT</Subject>
<Subject>You have been invited to enroll your device in Entgra UEM</Subject>
<Body>
<![CDATA[
<html>
<head>
<title>Entgra IoT Server</title>
</head>
<body style="color: #666666; background-color:#cdcdcd; padding: 0px; margin: 0px;">
<div style="background-color:#cdcdcd; font-length: 1em; font-family: Arial, Helvetica; line-height: 170%; color: #666666; padding: 20px 0px; margin: 0px;">
<div style="width: 86%; max-width: 650px; padding: 2%; background-color: #ffffff; margin: auto; border-radius: 14px;">
<div style="line-height: 0px; border-top-left-radius: 10px; border-top-right-radius: 10px; padding: 10px;">
<div style="display: inline-block; line-height: 0px;">
<img alt="entgra" src="https://storage.googleapis.com/cdn-entgra/logo.png" height="50px" width="143px" />
</div>
</div>
<div style="background-color: #ffffff; line-height: 170%; color: #666666; padding: 20px 25px;">
<p style="font-length: 1em; font-family: Arial, Helvetica; line-height: 170%; color: #666666; margin: 5px 0px 20px;">
Hi $first-name,
</p>
<p style="font-size: 1em; font-family: Arial, Helvetica; line-height: 170%; color: #666666; margin: 5px 0px;">
You have been registered in Entgra IoT and invited to enrol your device.
Click <a href="$base-url-https/endpoint-mgt/devices/enroll">here</a> to begin device enrolment.</p>
<p style="font-size: 1em; font-family: Arial, Helvetica; line-height: 170%; color: #666666; margin: 5px 0px;">
Use following credentials to log in to Entgra IoT Device Management application.
</p>
<p style="font-length: 1em; font-family: Arial, Helvetica; line-height: 170%; color: #666666; margin: 5px 0px;">
<b>Username:</b> $username
<br/>
<b>Password:</b> $password
</p>
<p style="font-length: 1em; font-family: Arial, Helvetica; line-height: 170%; color: #666666; margin: 5px 0px;">
Should you need assistance, please contact your administrator.
</p>
<p style="font-length: 1em; font-family: Arial, Helvetica; line-height: 170%; color: #666666; margin: 20px 0px 5px;">
Regards,
</p>
<p style="font-size: 1em; font-family: Arial, Helvetica; line-height: 170%; color: #666666; margin: 5px 0px;">
Entgra IoT Administrator
</p>
</div>
</div>
</div>
</body>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
<head>
<!--[if gte mso 9]>
<xml>
<o:OfficeDocumentSettings>
<o:AllowPNG>
</o:AllowPNG/>
<o:PixelsPerInch>96</o:PixelsPerInch>
</o:OfficeDocumentSettings>
</xml>
<![endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="x-apple-disable-message-reformatting" />
<!--[if !mso]><!-->
<link href="https://fonts.googleapis.com/css?family=Cabin:400,700" rel="stylesheet" type="text/css" />
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,700" rel="stylesheet" type="text/css" />
<!--<![endif]-->
<title>Entgra UEM Server</title>
<style type="text/css">
@media only screen and (min-width: 620px) {
.u-row {
width: 600px !important;
}
.u-row .u-col {
vertical-align: top;
}
.u-row .u-col-100 {
width: 600px !important;
}
}
@media (max-width: 620px) {
.u-row-container {
max-width: 100% !important;
padding-left: 0px !important;
padding-right: 0px !important;
}
.u-row .u-col {
min-width: 320px !important;
max-width: 100% !important;
display: block !important;
}
.u-row {
width: 100% !important;
}
.u-col {
width: 100% !important;
}
.u-col > div {
margin: 0 auto;
}
}
body {
margin: 0;
padding: 0;
}
table,
tr,
td {
vertical-align: top;
border-collapse: collapse;
}
p {
margin: 0;
}
.ie-container table,
.mso-container table {
table-layout: fixed;
}
* {
line-height: inherit;
}
a[x-apple-data-detectors='true'] {
color: inherit !important;
text-decoration: none !important;
}
@media (min-width: 481px) and (max-width: 768px) {
}
table, td { color: #000000; } #u_body a { color: #0000ee; text-decoration: underline; }
</style>
</head>
<body class="clean-body u_body" style="margin: 0;padding: 0;-webkit-text-size-adjust: 100%;background-color: #f9f9f9;color: #000000">
<!--[if IE]>
<div class="ie-container">
<![endif]-->
<!--[if mso]>
<div class="mso-container">
<![endif]-->
<table id="u_body" style="border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;min-width: 320px;Margin: 0 auto;background-color: #f9f9f9;width:100%" cellpadding="0" cellspacing="0">
<tbody>
<tr style="vertical-align: top">
<td style="word-break: break-word;border-collapse: collapse !important;vertical-align: top">
<!--[if (mso)|(IE)]>
<table width="100%" cellpadding="0" cellspacing="0" border="0">
<tr>
<td align="center" style="background-color: #f9f9f9;">
<![endif]-->
<div class="u-row-container" style="padding: 0px;background-color: transparent">
<div class="u-row" style="margin: 0 auto;min-width: 320px;max-width: 600px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: transparent;">
<div style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
<!--[if (mso)|(IE)]>
<table width="100%" cellpadding="0" cellspacing="0" border="0">
<tr>
<td style="padding: 0px;background-color: transparent;" align="center">
<table cellpadding="0" cellspacing="0" border="0" style="width:600px;">
<tr style="background-color: transparent;">
<![endif]-->
<!--[if (mso)|(IE)]>
<td align="center" width="600" style="width: 600px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;" valign="top">
<![endif]-->
<div class="u-col u-col-100" style="max-width: 320px;min-width: 600px;display: table-cell;vertical-align: top;">
<div style="height: 100%;width: 100% !important;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;">
<!--[if (!mso)&amp;(!IE)]><!-->
<div style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;">
<!--<![endif]-->
<table style="font-family:'Cabin',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:0px;font-family:'Cabin',sans-serif;" align="left">
<table width="100%" cellpadding="0" cellspacing="0" border="0">
<tr>
<td style="padding-right: 0px;padding-left: 0px;" align="center">
<img align="center" border="0" src="https://storage.googleapis.com/cdn-entgra/try-it/assets/imgs/uem_reg_confirm_hero.jpg" alt="" title="" style="outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;clear: both;display: inline-block !important;border: none;height: auto;float: none;width: 100%;max-width: 600px;" width="600"/>
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
<!--[if (!mso)&amp;(!IE)]><!-->
</div>
<!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]>
</td>
<![endif]-->
<!--[if (mso)|(IE)]>
</tr>
</table>
</td>
</tr>
</table>
<![endif]-->
</div>
</div>
</div>
<div class="u-row-container" style="padding: 0px;background-color: transparent">
<div class="u-row" style="margin: 0 auto;min-width: 320px;max-width: 600px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: transparent;">
<div style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
<!--[if (mso)|(IE)]>
<table width="100%" cellpadding="0" cellspacing="0" border="0">
<tr>
<td style="padding: 0px;background-color: transparent;" align="center">
<table cellpadding="0" cellspacing="0" border="0" style="width:600px;">
<tr style="background-color: transparent;">
<![endif]-->
<!--[if (mso)|(IE)]>
<td align="center" width="600" style="background-color: #ffffff;width: 600px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;" valign="top">
<![endif]-->
<div class="u-col u-col-100" style="max-width: 320px;min-width: 600px;display: table-cell;vertical-align: top;">
<div style="background-color: #ffffff;height: 100%;width: 100% !important;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;">
<!--[if (!mso)&amp;(!IE)]><!-->
<div style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;">
<!--<![endif]-->
<table style="font-family:'Cabin',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:30px;font-family:'Cabin',sans-serif;" align="left">
<div style="font-family: 'Montserrat',sans-serif; font-size: 14px; line-height: 140%; text-align: left; word-wrap: break-word;">
<p style="line-height: 140%;">Dear $first-name,</p>
<br />
<p style="line-height: 140%;">We have completed your Entgra UEM registration. You are now invited to proceed with the enrollment of your device.</p>
<br />
<br />
<p style="line-height: 140%;">Please click on the link below to initiate this process.</p>
</div>
</td>
</tr>
</tbody>
</table>
<table style="font-family:'Cabin',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding-left:30px;font-family:'Cabin',sans-serif;" align="left">
<!--[if mso]>
<style>.v-button {background: transparent !important;}</style>
<![endif]-->
<div align="left">
<!--[if mso]>
<v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="$base-url-https/endpoint-mgt/devices/enroll" style="height:37px; v-text-anchor:middle; width:156px;" arcsize="11%" stroke="f" fillcolor="#3f84bb">
<w:anchorlock/>
<center style="color:#FFFFFF;font-family: 'Montserrat',sans-serif; ">
<![endif]-->
<a href="$base-url-https/endpoint-mgt/devices/enroll" target="_blank" class="v-button" style="box-sizing: border-box;display: inline-block;text-decoration: none;-webkit-text-size-adjust: none;text-align: left;color: #FFFFFF; background-color: #3f84bb; border-radius: 4px;-webkit-border-radius: 4px; -moz-border-radius: 4px; width:auto; max-width:100%; overflow-wrap: break-word; word-break: break-word; word-wrap:break-word; mso-border-alt: none;font-family: 'Montserrat',sans-serif; font-size: 14px;">
<span style="display:block;padding:10px 20px;line-height:120%;">Start enrollment</span>
</a>
<!--[if mso]>
</center>
</v:roundrect>
<![endif]-->
</div>
</td>
</tr>
</tbody>
</table>
<table style="font-family:'Cabin',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:30px;font-family:'Cabin',sans-serif;" align="left">
<div style="font-family: 'Montserrat',sans-serif; font-size: 14px; line-height: 140%; text-align: left; word-wrap: break-word;">
<p style="line-height: 140%;">Here are your login credentials:</p>
<br />
<p style="line-height: 140%;">Username: $username</p>
<p style="line-height: 140%;">Password: $password</p>
<br />
<p style="line-height: 140%;">If you require any assistance or have questions during the enrollment process, reach out to your designated administrator via the <a rel="noopener" href="https://support.entgra.net/" target="_blank">Entgra Support Portal. </a></p>
<br />
<p style="line-height: 140%;">Thank you.</p>
<br />
<p style="line-height: 140%;">Best wishes,</p>
<p style="line-height: 140%;">Entgra team</p>
</div>
</td>
</tr>
</tbody>
</table>
<!--[if (!mso)&amp;(!IE)]><!-->
</div>
<!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]>
</td>
<![endif]-->
<!--[if (mso)|(IE)]>
</tr>
</table>
</td>
</tr>
</table>
<![endif]-->
</div>
</div>
</div>
<div class="u-row-container" style="padding: 0px;background-color: transparent">
<div class="u-row" style="margin: 0 auto;min-width: 320px;max-width: 600px;overflow-wrap: break-word;word-wrap: break-word;word-break: break-word;background-color: transparent;">
<div style="border-collapse: collapse;display: table;width: 100%;height: 100%;background-color: transparent;">
<!--[if (mso)|(IE)]>
<table width="100%" cellpadding="0" cellspacing="0" border="0">
<tr>
<td style="padding: 0px;background-color: transparent;" align="center">
<table cellpadding="0" cellspacing="0" border="0" style="width:600px;">
<tr style="background-color: transparent;">
<![endif]-->
<!--[if (mso)|(IE)]>
<td align="center" width="600" style="background-color: #ffffff;width: 600px;padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;" valign="top">
<![endif]-->
<div class="u-col u-col-100" style="max-width: 320px;min-width: 600px;display: table-cell;vertical-align: top;">
<div style="background-color: #ffffff;height: 100%;width: 100% !important;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;">
<!--[if (!mso)&amp;(!IE)]><!-->
<div style="box-sizing: border-box; height: 100%; padding: 0px;border-top: 0px solid transparent;border-left: 0px solid transparent;border-right: 0px solid transparent;border-bottom: 0px solid transparent;border-radius: 0px;-webkit-border-radius: 0px; -moz-border-radius: 0px;">
<!--<![endif]-->
<table style="font-family:'Cabin',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:10px;font-family:'Cabin',sans-serif;" align="left">
<table height="0px" align="center" border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;border-top: 1px solid #BBBBBB;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%">
<tbody>
<tr style="vertical-align: top">
<td style="word-break: break-word;border-collapse: collapse !important;vertical-align: top;font-size: 0px;line-height: 0px;mso-line-height-rule: exactly;-ms-text-size-adjust: 100%;-webkit-text-size-adjust: 100%">
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<table style="font-family:'Cabin',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:30px 10px 10px;font-family:'Cabin',sans-serif;" align="left">
<div style="font-family: 'Montserrat',sans-serif; font-size: 10px; color: #3f84bb; line-height: 140%; text-align: center; word-wrap: break-word;">
<p style="line-height: 140%;"><a rel="noopener" href="https://entgra.io/privacy-policy/" target="_blank">Privacy policy</a></p>
</div>
</td>
</tr>
</tbody>
</table>
<table style="font-family:'Cabin',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:10px;font-family:'Cabin',sans-serif;" align="left">
<div style="font-family: 'Montserrat',sans-serif; font-size: 14px; line-height: 140%; text-align: center; word-wrap: break-word;">
<p style="line-height: 140%;">Follow Entgra on social media</p>
</div>
</td>
</tr>
</tbody>
</table>
<table style="font-family:'Cabin',sans-serif;" role="presentation" cellpadding="0" cellspacing="0" width="100%" border="0">
<tbody>
<tr>
<td style="overflow-wrap:break-word;word-break:break-word;padding:10px 10px 30px;font-family:'Cabin',sans-serif;" align="left">
<div align="center">
<div style="display: table; max-width:147px;">
<!--[if (mso)|(IE)]>
<table width="147" cellpadding="0" cellspacing="0" border="0">
<tr>
<td style="border-collapse:collapse;" align="center">
<table width="100%" cellpadding="0" cellspacing="0" border="0" style="border-collapse:collapse; mso-table-lspace: 0pt;mso-table-rspace: 0pt; width:147px;">
<tr>
<![endif]-->
<!--[if (mso)|(IE)]>
<td width="32" style="width:32px; padding-right: 5px;" valign="top">
<![endif]-->
<table align="left" border="0" cellspacing="0" cellpadding="0" width="32" height="32" style="width: 32px !important;height: 32px !important;display: inline-block;border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;margin-right: 5px">
<tbody>
<tr style="vertical-align: top">
<td align="left" valign="middle" style="word-break: break-word;border-collapse: collapse !important;vertical-align: top">
<a href="https://web.facebook.com/entgra/?_rdc=1&amp;_rdr" title="Facebook" target="_blank">
<img src="https://storage.googleapis.com/cdn-entgra/try-it/assets/icons/facebook_icon.png" alt="Facebook" title="Facebook" width="32" style="outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;clear: both;display: block !important;border: none;height: auto;float: none;max-width: 32px !important" />
</a>
</td>
</tr>
</tbody>
</table>
<!--[if (mso)|(IE)]>
</td>
<![endif]-->
<!--[if (mso)|(IE)]>
<td width="32" style="width:32px; padding-right: 5px;" valign="top">
<![endif]-->
<table align="left" border="0" cellspacing="0" cellpadding="0" width="32" height="32" style="width: 32px !important;height: 32px !important;display: inline-block;border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;margin-right: 5px">
<tbody>
<tr style="vertical-align: top">
<td align="left" valign="middle" style="word-break: break-word;border-collapse: collapse !important;vertical-align: top">
<a href="https://www.linkedin.com/authwall?trk=bf&amp;trkInfo=AQF27xf5mHyOcgAAAYr7u78geOJx3p5gqeVPOR61q4iuk7LkOiZmPZf09b2dHKHzYqTIkB1D3XL9YSlCJKEj9O_xBBP9lw7zVImR04IBnmHuQ0n2cAwziOd1KwbNmOuWBtpiwCM=&amp;original_referer=&amp;sessionRedirect=https%3A%2F%2Fwww.linkedin.com%2Fcompany%2Fentgra%2Fmycompany%2F" title="LinkedIn" target="_blank">
<img src="https://storage.googleapis.com/cdn-entgra/try-it/assets/icons/linkedin_icon.png" alt="LinkedIn" title="LinkedIn" width="32" style="outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;clear: both;display: block !important;border: none;height: auto;float: none;max-width: 32px !important" />
</a>
</td>
</tr>
</tbody>
</table>
<!--[if (mso)|(IE)]>
</td>
<![endif]-->
<!--[if (mso)|(IE)]>
<td width="32" style="width:32px; padding-right: 5px;" valign="top">
<![endif]-->
<table align="left" border="0" cellspacing="0" cellpadding="0" width="32" height="32" style="width: 32px !important;height: 32px !important;display: inline-block;border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;margin-right: 5px">
<tbody>
<tr style="vertical-align: top">
<td align="left" valign="middle" style="word-break: break-word;border-collapse: collapse !important;vertical-align: top">
<a href="https://twitter.com/entgra_io" title="X" target="_blank">
<img src="https://storage.googleapis.com/cdn-entgra/try-it/assets/icons/twitter_icon.png" alt="X" title="X" width="32" style="outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;clear: both;display: block !important;border: none;height: auto;float: none;max-width: 32px !important" />
</a>
</td>
</tr>
</tbody>
</table>
<!--[if (mso)|(IE)]>
</td>
<![endif]-->
<!--[if (mso)|(IE)]>
<td width="32" style="width:32px; padding-right: 0px;" valign="top">
<![endif]-->
<table align="left" border="0" cellspacing="0" cellpadding="0" width="32" height="32" style="width: 32px !important;height: 32px !important;display: inline-block;border-collapse: collapse;table-layout: fixed;border-spacing: 0;mso-table-lspace: 0pt;mso-table-rspace: 0pt;vertical-align: top;margin-right: 0px">
<tbody>
<tr style="vertical-align: top">
<td align="left" valign="middle" style="word-break: break-word;border-collapse: collapse !important;vertical-align: top">
<a href="https://www.youtube.com/channel/UCJVV8k92SzvvyWxvv01vjPg" title="YouTube" target="_blank">
<img src="https://storage.googleapis.com/cdn-entgra/try-it/assets/icons/youtube_icon.png" alt="YouTube" title="YouTube" width="32" style="outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;clear: both;display: block !important;border: none;height: auto;float: none;max-width: 32px !important" />
</a>
</td>
</tr>
</tbody>
</table>
<!--[if (mso)|(IE)]>
</td>
<![endif]-->
<!--[if (mso)|(IE)]>
</tr>
</table>
</td>
</tr>
</table>
<![endif]-->
</div>
</div>
</td>
</tr>
</tbody>
</table>
<!--[if (!mso)&amp;(!IE)]><!-->
</div>
<!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]>
</td>
<![endif]-->
<!--[if (mso)|(IE)]>
</tr>
</table>
</td>
</tr>
</table>
<![endif]-->
</div>
</div>
</div>
<!--[if (mso)|(IE)]>
</td>
</tr>
</table>
<![endif]-->
</td>
</tr>
</tbody>
</table>
<!--[if mso]>
</div>
<![endif]-->
<!--[if IE]>
</div>
<![endif]-->
</body>
</html>
]]>
</Body>

Loading…
Cancel
Save