mirror of
https://repository.entgra.net/community/device-mgt-plugins.git
synced 2025-09-16 23:42:15 +00:00
Merge pull request #321 from rasika/master
Migrating emm-web-agent app into UUFv0.2
This commit is contained in:
commit
b38d75f32a
@ -29,7 +29,12 @@
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>${basedir}/src/main/resources/jaggeryapps/devicemgt</directory>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<outputDirectory>/devicemgt</outputDirectory>
|
||||
<useDefaultExcludes>true</useDefaultExcludes>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>${basedir}/src/main/resources/jaggeryapps/emm-web-agent</directory>
|
||||
<outputDirectory>/emm-web-agent</outputDirectory>
|
||||
<useDefaultExcludes>true</useDefaultExcludes>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
|
||||
@ -0,0 +1,104 @@
|
||||
<%
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
var log = new Log("api/invoker-api.jag");
|
||||
|
||||
var uri = request.getRequestURI();
|
||||
var uriMatcher = new URIMatcher(String(uri));
|
||||
|
||||
var constants = require("/app/modules/constants.js");
|
||||
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"];
|
||||
|
||||
if (uriMatcher.match("/{context}/api/invoker/execute/")) {
|
||||
var restAPIRequestDetails = request.getContent();
|
||||
|
||||
var requestMethod = restAPIRequestDetails["requestMethod"];
|
||||
var requestURL = restAPIRequestDetails["requestURL"];
|
||||
var requestPayload = restAPIRequestDetails["requestPayload"];
|
||||
|
||||
if (!requestMethod) {
|
||||
requestMethod = parse(restAPIRequestDetails)["requestMethod"];
|
||||
}
|
||||
|
||||
if (!requestURL) {
|
||||
requestURL = parse(restAPIRequestDetails)["requestURL"];
|
||||
}
|
||||
|
||||
if (!requestPayload) {
|
||||
requestPayload = parse(restAPIRequestDetails)["requestPayload"];
|
||||
}
|
||||
|
||||
var restAPIEndpoint = devicemgtProps["httpsURL"] + requestURL;
|
||||
|
||||
try {
|
||||
switch (requestMethod) {
|
||||
case constants["HTTP_GET"]:
|
||||
serviceInvokers.XMLHttp.get(
|
||||
restAPIEndpoint,
|
||||
function (restAPIResponse) {
|
||||
response["status"] = restAPIResponse["status"];
|
||||
if (restAPIResponse["responseText"]) {
|
||||
response["content"] = restAPIResponse["responseText"];
|
||||
}
|
||||
}
|
||||
);
|
||||
break;
|
||||
case constants["HTTP_POST"]:
|
||||
serviceInvokers.XMLHttp.post(
|
||||
restAPIEndpoint,
|
||||
requestPayload,
|
||||
function (restAPIResponse) {
|
||||
response["status"] = restAPIResponse["status"];
|
||||
if (restAPIResponse["responseText"]) {
|
||||
response["content"] = restAPIResponse["responseText"];
|
||||
}
|
||||
}
|
||||
);
|
||||
break;
|
||||
case constants["HTTP_PUT"]:
|
||||
serviceInvokers.XMLHttp.put(
|
||||
restAPIEndpoint,
|
||||
requestPayload,
|
||||
function (restAPIResponse) {
|
||||
response["status"] = restAPIResponse["status"];
|
||||
if (restAPIResponse["responseText"]) {
|
||||
response["content"] = restAPIResponse["responseText"];
|
||||
}
|
||||
}
|
||||
);
|
||||
break;
|
||||
case constants["HTTP_DELETE"]:
|
||||
serviceInvokers.XMLHttp.delete(
|
||||
restAPIEndpoint,
|
||||
function (restAPIResponse) {
|
||||
response["status"] = restAPIResponse["status"];
|
||||
if (restAPIResponse["responseText"]) {
|
||||
response["content"] = restAPIResponse["responseText"];
|
||||
}
|
||||
}
|
||||
);
|
||||
break;
|
||||
}
|
||||
} catch (e) {
|
||||
throw new Error("Exception occurred while trying to access " +
|
||||
"backend REST API services from Jaggery API invoker layer", e);
|
||||
}
|
||||
}
|
||||
%>
|
||||
@ -0,0 +1,185 @@
|
||||
<%
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
var uri = request.getRequestURI();
|
||||
var uriMatcher = new URIMatcher(String(uri));
|
||||
|
||||
var log = new Log("api/user-api.jag");
|
||||
|
||||
var constants = require("/app/modules/constants.js");
|
||||
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
|
||||
var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"];
|
||||
var utility = require("/app/modules/utility.js").utility;
|
||||
var apiWrapperUtil = require("/app/modules/oauth/token-handlers.js")["handlers"];
|
||||
var util = require("/app/modules/oauth/token-handler-utils.js")["utils"];
|
||||
|
||||
var responseProcessor = require('utils').response;
|
||||
|
||||
var result;
|
||||
|
||||
if (uriMatcher.match("/{context}/api/user/authenticate")) {
|
||||
var username = request.getParameter("username");
|
||||
var password = request.getParameter("password");
|
||||
//Check if a username and password is provided
|
||||
if ((!username) || (!password)) {
|
||||
response = responseProcessor.buildErrorResponse(response, 400, 'Username and Password must be provided');
|
||||
} else {
|
||||
try {
|
||||
userModule.login(username, password, function (user) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("User Logged In : " + user);
|
||||
}
|
||||
apiWrapperUtil.setupTokenPairByPasswordGrantType(username, password);
|
||||
}, function () {
|
||||
response = responseProcessor.buildSuccessResponse(response, 200, {'sessionId': session.getId()});
|
||||
});
|
||||
} catch (e) {
|
||||
log.error("Exception occurred while a user tried to login to MDM", e);
|
||||
response = responseProcessor.buildErrorResponse(response, 401, 'username/password is incorrect');
|
||||
}
|
||||
}
|
||||
} else if (uriMatcher.match("/{context}/api/user/login/")) {
|
||||
username = request.getParameter("username");
|
||||
password = request.getParameter("password");
|
||||
username = util.decode(username);
|
||||
password = util.decode(password);
|
||||
try {
|
||||
userModule.login(username, password, function (user) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("User Logged In : " + user);
|
||||
}
|
||||
|
||||
apiWrapperUtil.setupTokenPairByPasswordGrantType(username, password);
|
||||
var permissions = userModule.getUIPermissions();
|
||||
if (permissions.VIEW_DASHBOARD) {
|
||||
response.sendRedirect(constants.WEB_APP_CONTEXT);
|
||||
} else {
|
||||
response.sendRedirect(constants.WEB_APP_CONTEXT + "/devices");
|
||||
}
|
||||
}, function () {
|
||||
response.sendRedirect(devicemgtProps.appContext + "login?#auth-failed");
|
||||
});
|
||||
} catch (e) {
|
||||
log.error("Exception occurred while a user tried to login to MDM", e);
|
||||
response.sendRedirect(devicemgtProps.appContext + "login?#error");
|
||||
}
|
||||
} else if (uriMatcher.match("/{context}/api/user/logout/")) {
|
||||
userModule.logout(function () {
|
||||
response.sendRedirect(devicemgtProps.appContext + "login");
|
||||
});
|
||||
} else if (uriMatcher.match("/{context}/api/user/devices/")) {
|
||||
/*
|
||||
@Deprecated
|
||||
*/
|
||||
if (userModule.isAuthorized("/permission/admin/device-mgt/user/devices/list")) {
|
||||
carbonUser = session.get(constants.USER_SESSION_KEY);
|
||||
result = deviceModule.listDevicesForUser(carbonUser.username);
|
||||
} else {
|
||||
response.sendError(403);
|
||||
}
|
||||
} else if (uriMatcher.match("/{context}/api/user/{username}/invite")) {
|
||||
/*
|
||||
@Deprecated
|
||||
*/
|
||||
if (userModule.isAuthorized("/permission/admin/device-mgt/admin/user/invite")) {
|
||||
elements = uriMatcher.elements();
|
||||
username = elements.username;
|
||||
userModule.inviteUser(username);
|
||||
} else {
|
||||
response.sendError(403);
|
||||
}
|
||||
} else if (uriMatcher.match("/{context}/api/user/add")) {
|
||||
/*
|
||||
@Deprecated
|
||||
*/
|
||||
if (userModule.isAuthorized("/permission/admin/device-mgt/admin/user/add")) {
|
||||
addUserFormData = request.getContent();
|
||||
username = addUserFormData.username;
|
||||
firstname = addUserFormData.firstname;
|
||||
lastname = addUserFormData.lastname;
|
||||
emailAddress = addUserFormData.emailAddress;
|
||||
|
||||
if (!addUserFormData.userRoles) {
|
||||
userRoles = null;
|
||||
} else {
|
||||
userRoles = String(addUserFormData.userRoles).split(",");
|
||||
}
|
||||
if (username.length < devicemgtProps.usernameLength) {
|
||||
log.error("Username Must be between 1 and " + devicemgtProps.usernameLength + " characters long");
|
||||
result = "Username Must be between 1 and " + devicemgtProps.usernameLength + " characters long";
|
||||
} else {
|
||||
try {
|
||||
result = userModule.addUser(username, firstname, lastname, emailAddress, userRoles);
|
||||
} catch (e) {
|
||||
log.error("Exception occurred while trying to add a user to MDM User Store", e);
|
||||
// http status code 400 refers to - Bad request.
|
||||
result = 400;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// http status code 403 refers to - forbidden.
|
||||
result = 403;
|
||||
}
|
||||
} else if (uriMatcher.match("/{context}/api/user/register")) {
|
||||
|
||||
addUserFormData = request.getContent();
|
||||
username = addUserFormData.username;
|
||||
firstname = addUserFormData.firstname;
|
||||
lastname = addUserFormData.lastname;
|
||||
emailAddress = addUserFormData.emailAddress;
|
||||
password = addUserFormData.password;
|
||||
userRoles = ["internal/devicemgt-user"];
|
||||
|
||||
try {
|
||||
result = userModule.registerUser(username, firstname, lastname, emailAddress, password,
|
||||
userRoles);
|
||||
} catch (e) {
|
||||
log.error("Exception occurred while trying to registering a new user to DC User Store", e);
|
||||
// http status code 400 refers to - Bad request.
|
||||
result = 400;
|
||||
}
|
||||
|
||||
} else if (uriMatcher.match("/{context}/api/user/{username}/remove")) {
|
||||
/*
|
||||
@Deprecated
|
||||
*/
|
||||
if (userModule.isAuthorized("/permission/admin/device-mgt/admin/user/remove")) {
|
||||
elements = uriMatcher.elements();
|
||||
username = elements.username;
|
||||
try {
|
||||
result = userModule.removeUser(username);
|
||||
} catch (e) {
|
||||
log.error("Exception occurred while trying to remove a user from MDM User Store", e);
|
||||
// http status code 400 refers to - Bad request.
|
||||
result = 400;
|
||||
}
|
||||
} else {
|
||||
// http status code 403 refers to - forbidden.
|
||||
result = 403;
|
||||
}
|
||||
} else if (uriMatcher.match("/{context}/api/user/all")) {
|
||||
result = userModule.getUsers();
|
||||
}
|
||||
|
||||
// returning the result.
|
||||
if (result) {
|
||||
print(result);
|
||||
}
|
||||
%>
|
||||
@ -0,0 +1,52 @@
|
||||
{
|
||||
"appName": "WSO2 Enterprise Mobility Manager",
|
||||
"cachingEnabled": true,
|
||||
"debuggingEnabled": false,
|
||||
"permissionRoot": "/",
|
||||
"loginPage": "cdmf.page.sign-in",
|
||||
"adminServicesUrl": "https://${server.ip}:${server.https_port}/admin/services/",
|
||||
"authModule": {
|
||||
"enabled": true,
|
||||
"login": {
|
||||
"onSuccess": {
|
||||
"script": "/app/modules/login.js",
|
||||
"page": "mdm.page.dashboard"
|
||||
},
|
||||
"onFail": {
|
||||
"script": "/app/modules/login.js",
|
||||
"page": "cdmf.page.sign-in"
|
||||
}
|
||||
},
|
||||
"logout": {
|
||||
"onSuccess": {
|
||||
"page": "cdmf.page.sign-in"
|
||||
},
|
||||
"onFail": {
|
||||
"page": "mdm.page.dashboard"
|
||||
}
|
||||
},
|
||||
"sso": {
|
||||
"enabled": false,
|
||||
"issuer" : "emm",
|
||||
"appName" : "emm",
|
||||
"identityProviderUrl" : "https://localhost:9443/samlsso",
|
||||
"acs": "https://localhost:9443/emm/uuf/sso/acs",
|
||||
"identityAlias": "wso2carbon",
|
||||
"responseSigningEnabled" : "true",
|
||||
"useTenantKey": false
|
||||
}
|
||||
},
|
||||
"generalConfig" : {
|
||||
"host" : "https://localhost:9443",
|
||||
"companyName" : "WSO2 Enterprise Mobility Manager",
|
||||
"browserTitle" : "WSO2 EMM",
|
||||
"copyrightPrefix" : "\u00A9 %date-year%, ",
|
||||
"copyrightOwner" : "WSO2 Inc.",
|
||||
"copyrightOwnersSite" : "http://www.wso2.org",
|
||||
"copyrightSuffix" : ""
|
||||
},
|
||||
"errorPages": {
|
||||
"404": "mdm.page.error",
|
||||
"default": "uuf.page.error"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,108 @@
|
||||
{
|
||||
"appContext" : "/emm-web-agent/",
|
||||
"apiContext" : "api",
|
||||
"httpsURL" : "%https.ip%",
|
||||
"httpURL" : "%http.ip%",
|
||||
"enrollmentDir": "/emm-web-agent/enrollment",
|
||||
"iOSConfigRoot" : "%https.ip%/ios-enrollment/",
|
||||
"iOSAPIRoot" : "%https.ip%/ios/",
|
||||
"dynamicClientRegistrationEndPoint" : "%https.ip%/dynamic-client-web/register/",
|
||||
"adminService":"%https.ip%",
|
||||
"idPServer":"%https.ip%",
|
||||
"callBackUrl":"%https.ip%/mdm-admin",
|
||||
"oauthProvider": {
|
||||
"appRegistration": {
|
||||
"appType": "webapp",
|
||||
"clientName": "emm-web-agent",
|
||||
"owner": "admin@carbon.super",
|
||||
"dynamicClientAppRegistrationServiceURL": "%https.ip%/dynamic-client-web/register",
|
||||
"apiManagerClientAppRegistrationServiceURL": "%https.ip%/api-application-registration/register/tenants",
|
||||
"grantType": "password refresh_token urn:ietf:params:oauth:grant-type:saml2-bearer",
|
||||
"tokenScope": "admin",
|
||||
"callbackUrl": "%https.ip%/api/device-mgt/v1.0"
|
||||
},
|
||||
"tokenServiceURL": "%https.ip%/oauth2/token"
|
||||
},
|
||||
"adminUser":"admin",
|
||||
"usernameLength":30,
|
||||
"device" : {
|
||||
"ios" : {
|
||||
"location" : "%http.ip%/emm-web-agent/public/mdm.page.enrollments.ios.download-agent/asset/ios-agent.ipa",
|
||||
"bundleID" : "org.wso2.carbon.emm.iOSMDMAgent",
|
||||
"version" : "1.0",
|
||||
"appName" : "EMM iOS Agent"
|
||||
}
|
||||
},
|
||||
"androidAgentApp" : "android-agent.apk",
|
||||
"windowsConfigRoot" : "%http.ip%/api/device-mgt/windows/v1.0/services/federated/bst/authentication",
|
||||
"ssoConfiguration" : {
|
||||
"enabled" : false,
|
||||
"issuer" : "mdm",
|
||||
"appName" : "admin_emm-web-agent",
|
||||
"identityProviderURL" : "%https.ip%/sso/samlsso.jag",
|
||||
"responseSigningEnabled" : "true",
|
||||
"keyStorePassword" : "wso2carbon",
|
||||
"identityAlias" : "wso2carbon",
|
||||
"keyStoreName" : "/repository/resources/security/wso2carbon.jks"
|
||||
},
|
||||
"generalConfig" : {
|
||||
"host" : "%https.ip%",
|
||||
"companyName" : "WSO2 Enterprise Mobility Manager",
|
||||
"browserTitle" : "WSO2 EMM",
|
||||
"copyrightText" : "\u00A9 %date-year%, WSO2 Inc. (http://www.wso2.org) All Rights Reserved."
|
||||
},
|
||||
"isOAuthEnabled" : true,
|
||||
"scopes" : ["activity:view",
|
||||
"application:install",
|
||||
"application:uninstall",
|
||||
"device:view",
|
||||
"user:modify",
|
||||
"configuration:view",
|
||||
"configuration:modify",
|
||||
"device:list",
|
||||
"device:search",
|
||||
"notification:view",
|
||||
"policy:list",
|
||||
"policy:add",
|
||||
"polciy:modify",
|
||||
"policy:view",
|
||||
"role:list",
|
||||
"role:add",
|
||||
"role:view",
|
||||
"role:modify",
|
||||
"user:list",
|
||||
"user:add",
|
||||
"user:view",
|
||||
"certificate:view",
|
||||
"certificate:add",
|
||||
"certificate:modify",
|
||||
"device:android:get-applications",
|
||||
"device:android:blacklist-applications",
|
||||
"device:android:change-lock-code",
|
||||
"device:android:clear-password",
|
||||
"device:android:vpn",
|
||||
"device:android:wifi",
|
||||
"device:android:camera",
|
||||
"device:android:encrypt",
|
||||
"device:android:enterprise-wipe",
|
||||
"device:android:info",
|
||||
"device:android:install-application",
|
||||
"device:android:location",
|
||||
"device:android:lock",
|
||||
"device:android:mute",
|
||||
"device:android:reboot",
|
||||
"device:android:ring",
|
||||
"device:android:send-notification",
|
||||
"device:android:set-password-policy",
|
||||
"device:android:webclip",
|
||||
"device:android:uninstall-application",
|
||||
"device:android:unlock",
|
||||
"device:android:update-application",
|
||||
"device:android:upgrade-firmware",
|
||||
"device:android:wipe",
|
||||
"device:configuration:view",
|
||||
"device:android:configuration:modify",
|
||||
"device:android:enroll",
|
||||
"device:android:event:publish",
|
||||
"device:android:event:view"]
|
||||
}
|
||||
@ -0,0 +1,67 @@
|
||||
{{!-- Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
|
||||
WSO2 Inc. 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. --}}
|
||||
|
||||
{{!-- Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
|
||||
WSO2 Inc. 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. --}}
|
||||
{{~defineZone "accessControl"~}}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
{{defineZone "favicon"}}
|
||||
<title>
|
||||
{{defineZone "title"}}
|
||||
</title>
|
||||
{{defineZone "topCss"}}
|
||||
{{defineZone "topJs"}}
|
||||
</head>
|
||||
<body>
|
||||
<div class="container col-lg-12 col-md-12 col-sm-12">
|
||||
<header>
|
||||
<div class="row wr-global-header">
|
||||
<div class="col-sm-8 app-logo">
|
||||
{{defineZone "brand"}}
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container c-both">
|
||||
<div class="wr-head">
|
||||
<h2>{{defineZone "headerTitle"}}</h2>
|
||||
<hr>
|
||||
</div>
|
||||
<!-- start: zone-content-->
|
||||
{{defineZone "content"}}
|
||||
<!-- end: zone-content-->
|
||||
</div>
|
||||
{{!-- {{ defineZone "footer"}} --}}
|
||||
</div>
|
||||
{{defineZone "bottomJs" }}
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,348 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
var deviceModule;
|
||||
deviceModule = function () {
|
||||
var log = new Log("/app/modules/business-controllers/device.js");
|
||||
|
||||
var utility = require('/app/modules/utility.js').utility;
|
||||
var constants = require('/app/modules/constants.js');
|
||||
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"];
|
||||
|
||||
// var ArrayList = Packages.java.util.ArrayList;
|
||||
// var Properties = Packages.java.util.Properties;
|
||||
// var DeviceIdentifier = Packages.org.wso2.carbon.device.mgt.common.DeviceIdentifier;
|
||||
// var DeviceManagerUtil = Packages.org.wso2.carbon.device.mgt.core.util.DeviceManagerUtil;
|
||||
// var SimpleOperation = Packages.org.wso2.carbon.device.mgt.core.operation.mgt.SimpleOperation;
|
||||
// var ConfigOperation = Packages.org.wso2.carbon.device.mgt.core.operation.mgt.ConfigOperation;
|
||||
// var CommandOperation = Packages.org.wso2.carbon.device.mgt.core.operation.mgt.CommandOperation;
|
||||
|
||||
var publicMethods = {};
|
||||
var privateMethods = {};
|
||||
|
||||
// var deviceCloudService = devicemgtProps["httpsURL"] + "/common/device_manager";
|
||||
|
||||
privateMethods.validateAndReturn = function (value) {
|
||||
return (value == undefined || value == null) ? constants.UNSPECIFIED : value;
|
||||
};
|
||||
|
||||
/*
|
||||
@Deprecated
|
||||
*/
|
||||
// publicMethods.listDevices = function () {
|
||||
// var carbonUser = session.get(constants.USER_SESSION_KEY);
|
||||
// var utility = require('/app/modules/utility.js').utility;
|
||||
// if (!carbonUser) {
|
||||
// log.error("User object was not found in the session");
|
||||
// throw constants.ERRORS.USER_NOT_FOUND;
|
||||
// }
|
||||
// try {
|
||||
// utility.startTenantFlow(carbonUser);
|
||||
// var deviceManagementService = utility.getDeviceManagementService();
|
||||
// var devices = deviceManagementService.getAllDevices();
|
||||
// var deviceList = [];
|
||||
// var i, device, propertiesList, deviceObject;
|
||||
// for (i = 0; i < devices.size(); i++) {
|
||||
// device = devices.get(i);
|
||||
// propertiesList = DeviceManagerUtil.convertDevicePropertiesToMap(device.getProperties());
|
||||
//
|
||||
// deviceObject = {};
|
||||
// deviceObject[constants.DEVICE_IDENTIFIER] =
|
||||
// privateMethods.validateAndReturn(device.getDeviceIdentifier());
|
||||
// deviceObject[constants.DEVICE_NAME] =
|
||||
// privateMethods.validateAndReturn(device.getName());
|
||||
// deviceObject[constants.DEVICE_OWNERSHIP] =
|
||||
// privateMethods.validateAndReturn(device.getEnrolmentInfo().getOwnership());
|
||||
// deviceObject[constants.DEVICE_OWNER] =
|
||||
// privateMethods.validateAndReturn(device.getEnrolmentInfo().getOwner());
|
||||
// deviceObject[constants.DEVICE_TYPE] =
|
||||
// privateMethods.validateAndReturn(device.getType());
|
||||
// deviceObject[constants.DEVICE_PROPERTIES] = {};
|
||||
// if (device.getType() == constants.PLATFORM_IOS) {
|
||||
// deviceObject[constants.DEVICE_PROPERTIES][constants.DEVICE_MODEL] =
|
||||
// privateMethods.validateAndReturn(propertiesList.get(constants.DEVICE_PRODUCT));
|
||||
// deviceObject[constants.DEVICE_PROPERTIES][constants.DEVICE_VENDOR] = constants.VENDOR_APPLE;
|
||||
// } else {
|
||||
// deviceObject[constants.DEVICE_PROPERTIES][constants.DEVICE_MODEL] =
|
||||
// privateMethods.validateAndReturn(propertiesList.get(constants.DEVICE_MODEL));
|
||||
// deviceObject[constants.DEVICE_PROPERTIES][constants.DEVICE_VENDOR] =
|
||||
// privateMethods.validateAndReturn(propertiesList.get(constants.DEVICE_VENDOR));
|
||||
// }
|
||||
// deviceObject[constants.DEVICE_PROPERTIES][constants.DEVICE_OS_VERSION] =
|
||||
// privateMethods.validateAndReturn(propertiesList.get(constants.DEVICE_OS_VERSION));
|
||||
//
|
||||
// deviceList.push(deviceObject);
|
||||
// }
|
||||
// return deviceList;
|
||||
// } catch (e) {
|
||||
// throw e;
|
||||
// } finally {
|
||||
// utility.endTenantFlow();
|
||||
// }
|
||||
// };
|
||||
|
||||
/*
|
||||
@Deprecated
|
||||
*/
|
||||
/*
|
||||
Get the supported features by the device type
|
||||
*/
|
||||
// publicMethods.getFeatures = function (deviceType) {
|
||||
// var carbonUser = session.get(constants.USER_SESSION_KEY);
|
||||
// var utility = require('/app/modules/utility.js').utility;
|
||||
// if (!carbonUser) {
|
||||
// log.error("User object was not found in the session");
|
||||
// throw constants.ERRORS.USER_NOT_FOUND;
|
||||
// }
|
||||
// try {
|
||||
// utility.startTenantFlow(carbonUser);
|
||||
// var deviceManagementService = utility.getDeviceManagementService();
|
||||
// var features = deviceManagementService.getFeatureManager(deviceType).getFeatures();
|
||||
// var featuresConverted = {};
|
||||
// if (features) {
|
||||
// var i, feature, featureObject;
|
||||
// for (i = 0; i < features.size(); i++) {
|
||||
// feature = features.get(i);
|
||||
// featureObject = {};
|
||||
// featureObject[constants.FEATURE_NAME] = feature.getName();
|
||||
// featureObject[constants.FEATURE_DESCRIPTION] = feature.getDescription();
|
||||
// featuresConverted[feature.getName()] = featureObject;
|
||||
// }
|
||||
// }
|
||||
// return featuresConverted;
|
||||
// } catch (e) {
|
||||
// throw e;
|
||||
// } finally {
|
||||
// utility.endTenantFlow();
|
||||
// }
|
||||
// };
|
||||
|
||||
/*
|
||||
@Deprecated
|
||||
*/
|
||||
// publicMethods.performOperation = function (devices, operation) {
|
||||
// var carbonUser = session.get(constants.USER_SESSION_KEY);
|
||||
// var utility = require('/app/modules/utility.js').utility;
|
||||
// if (!carbonUser) {
|
||||
// log.error("User object was not found in the session");
|
||||
// throw constants.ERRORS.USER_NOT_FOUND;
|
||||
// }
|
||||
// try {
|
||||
// utility.startTenantFlow(carbonUser);
|
||||
// var deviceManagementService = utility.getDeviceManagementService();
|
||||
// var operationInstance;
|
||||
// if (operation.type == "COMMAND") {
|
||||
// operationInstance = new CommandOperation();
|
||||
// } else if (operation.type == "CONFIG") {
|
||||
// operationInstance = new ConfigOperation();
|
||||
// } else {
|
||||
// operationInstance = new SimpleOperation();
|
||||
// }
|
||||
// operationInstance.setCode(operation.featureName);
|
||||
// var props = new Properties();
|
||||
// var i, object;
|
||||
// for (i = 0; i < operation.properties.length; i++) {
|
||||
// object = properties[i];
|
||||
// props.setProperty(object.key, object.value);
|
||||
// }
|
||||
// operationInstance.setProperties(props);
|
||||
// var deviceList = new ArrayList();
|
||||
// var j, device, deviceIdentifier;
|
||||
// for (j = 0; j < devices.length; i++) {
|
||||
// device = devices[j];
|
||||
// deviceIdentifier = new DeviceIdentifier();
|
||||
// deviceIdentifier.setId(device.id);
|
||||
// deviceIdentifier.setType(device.type);
|
||||
// deviceList.add(deviceIdentifier);
|
||||
// }
|
||||
// deviceManagementService.addOperation(operationInstance, deviceList);
|
||||
// } catch (e) {
|
||||
// throw e;
|
||||
// } finally {
|
||||
// utility.endTenantFlow();
|
||||
// }
|
||||
// };
|
||||
|
||||
/*
|
||||
@Deprecated
|
||||
*/
|
||||
// privateMethods.getDevice = function (type, deviceId) {
|
||||
// var carbonUser = session.get(constants.USER_SESSION_KEY);
|
||||
// var utility = require('/app/modules/utility.js').utility;
|
||||
// if (!carbonUser) {
|
||||
// log.error("User object was not found in the session");
|
||||
// throw constants.ERRORS.USER_NOT_FOUND;
|
||||
// }
|
||||
// try {
|
||||
// utility.startTenantFlow(carbonUser);
|
||||
// var deviceManagementService = utility.getDeviceManagementService();
|
||||
// var deviceIdentifier = new DeviceIdentifier();
|
||||
// deviceIdentifier.setType(type);
|
||||
// deviceIdentifier.setId(deviceId);
|
||||
// return deviceManagementService.getDevice(deviceIdentifier);
|
||||
// } catch (e) {
|
||||
// throw e;
|
||||
// } finally {
|
||||
// utility.endTenantFlow();
|
||||
// }
|
||||
// };
|
||||
|
||||
/*
|
||||
@Updated
|
||||
*/
|
||||
publicMethods.viewDevice = function (deviceType, deviceId) {
|
||||
var carbonUser = session.get(constants["USER_SESSION_KEY"]);
|
||||
if (!carbonUser) {
|
||||
log.error("User object was not found in the session");
|
||||
throw constants["ERRORS"]["USER_NOT_FOUND"];
|
||||
}
|
||||
var utility = require('/app/modules/utility.js')["utility"];
|
||||
try {
|
||||
utility.startTenantFlow(carbonUser);
|
||||
|
||||
var url = devicemgtProps["httpsURL"] + constants.ADMIN_SERVICE_CONTEXT + "/devices/view?type=" + deviceType
|
||||
+ "&id=" + deviceId;
|
||||
return serviceInvokers.XMLHttp.get(
|
||||
url, function (responsePayload) {
|
||||
var device = responsePayload.responseContent;
|
||||
if (device) {
|
||||
var propertiesList = device["properties"];
|
||||
var properties = {};
|
||||
if (propertiesList) {
|
||||
for (var i = 0; i < propertiesList.length; i++) {
|
||||
properties[propertiesList[i]["name"]] = propertiesList[i]["value"];
|
||||
}
|
||||
}
|
||||
var deviceObject = {};
|
||||
deviceObject[constants["DEVICE_IDENTIFIER"]] = device["deviceIdentifier"];
|
||||
deviceObject[constants["DEVICE_NAME"]] = device["name"];
|
||||
deviceObject[constants["DEVICE_OWNERSHIP"]] = device["enrolmentInfo"]["ownership"];
|
||||
deviceObject[constants["DEVICE_OWNER"]] = device["enrolmentInfo"]["owner"];
|
||||
deviceObject[constants["DEVICE_STATUS"]] = device["enrolmentInfo"]["status"];
|
||||
deviceObject[constants["DEVICE_TYPE"]] = device["type"];
|
||||
if (device["type"] == constants["PLATFORM_IOS"]) {
|
||||
properties[constants["DEVICE_MODEL"]] = properties[constants["DEVICE_PRODUCT"]];
|
||||
delete properties[constants["DEVICE_PRODUCT"]];
|
||||
properties[constants["DEVICE_VENDOR"]] = constants["VENDOR_APPLE"];
|
||||
}
|
||||
deviceObject[constants["DEVICE_PROPERTIES"]] = properties;
|
||||
return deviceObject;
|
||||
}
|
||||
},
|
||||
function (responsePayload) {
|
||||
var response = {};
|
||||
response["status"] = "error";
|
||||
return response;
|
||||
}
|
||||
);
|
||||
} catch (e) {
|
||||
throw e;
|
||||
} finally {
|
||||
utility.endTenantFlow();
|
||||
}
|
||||
};
|
||||
|
||||
// Refactored methods
|
||||
publicMethods.getDevicesCount = function () {
|
||||
var carbonUser = session.get(constants.USER_SESSION_KEY);
|
||||
if (carbonUser) {
|
||||
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
|
||||
var uiPermissions = userModule.getUIPermissions();
|
||||
var url;
|
||||
if (uiPermissions.LIST_DEVICES) {
|
||||
url = devicemgtProps["httpsURL"] + constants.ADMIN_SERVICE_CONTEXT + "/devices/count";
|
||||
} else if (uiPermissions.LIST_OWN_DEVICES) {
|
||||
url = devicemgtProps["httpsURL"] + constants.ADMIN_SERVICE_CONTEXT + "/devices/user/"
|
||||
+ carbonUser.username
|
||||
+ "/count";
|
||||
} else {
|
||||
log.error("Access denied for user: " + carbonUser.username);
|
||||
return -1;
|
||||
}
|
||||
return serviceInvokers.XMLHttp.get(
|
||||
url, function (responsePayload) {
|
||||
return responsePayload;
|
||||
},
|
||||
function (responsePayload) {
|
||||
log.error(responsePayload);
|
||||
return -1;
|
||||
}
|
||||
);
|
||||
} else {
|
||||
log.error("User object was not found in the session");
|
||||
throw constants["ERRORS"]["USER_NOT_FOUND"];
|
||||
}
|
||||
};
|
||||
|
||||
publicMethods.getDeviceTypes = function () {
|
||||
var url = devicemgtProps["httpsURL"] + constants.ADMIN_SERVICE_CONTEXT + "/devices/types";
|
||||
return serviceInvokers.XMLHttp.get(
|
||||
url, function (responsePayload) {
|
||||
return responsePayload;
|
||||
},
|
||||
function (responsePayload) {
|
||||
log.error(responsePayload);
|
||||
return -1;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
//Old methods
|
||||
//TODO: make sure these methods are updated
|
||||
/*
|
||||
@Updated
|
||||
*/
|
||||
publicMethods.getLicense = function (deviceType) {
|
||||
var url;
|
||||
var license;
|
||||
if (deviceType == "windows") {
|
||||
url = devicemgtProps["httpURL"] + "/mdm-windows-agent/services/device/license";
|
||||
} else if (deviceType == "ios") {
|
||||
url = devicemgtProps["httpsURL"] + "/ios-enrollment/license/";
|
||||
}
|
||||
if (url != null && url != undefined) {
|
||||
return serviceInvokers.XMLHttp.get(
|
||||
url, function (responsePayload) {
|
||||
return "" + parse(responsePayload.responseText).text;
|
||||
},
|
||||
function (responsePayload) {
|
||||
return null;
|
||||
}
|
||||
);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
publicMethods.getDevices = function (userName) {
|
||||
var url = devicemgtProps["httpsURL"] + constants.ADMIN_SERVICE_CONTEXT + "/devices/user/" + userName;
|
||||
return serviceInvokers.XMLHttp.get(
|
||||
url, function (responsePayload) {
|
||||
for (var i = 0; i < responsePayload.length; i++) {
|
||||
responsePayload[i].thumb = utility.getDeviceThumb(responsePayload[i].type);
|
||||
}
|
||||
return responsePayload;
|
||||
},
|
||||
function (responsePayload) {
|
||||
log.error(responsePayload);
|
||||
return -1;
|
||||
}
|
||||
);
|
||||
};
|
||||
return publicMethods;
|
||||
}();
|
||||
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
var groupModule = {};
|
||||
(function (groupModule) {
|
||||
var log = new Log("/app/modules/business-controllers/group.js");
|
||||
|
||||
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
|
||||
var constants = require('/app/modules/constants.js');
|
||||
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
var utility = require("/app/modules/utility.js").utility;
|
||||
var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"];
|
||||
|
||||
var groupServiceEndpoint = devicemgtProps["httpsURL"] + constants.ADMIN_SERVICE_CONTEXT + "/groups";
|
||||
|
||||
var user = session.get(constants.USER_SESSION_KEY);
|
||||
|
||||
var endPoint;
|
||||
|
||||
groupModule.getGroupCount = function () {
|
||||
var permissions = userModule.getUIPermissions();
|
||||
if (permissions.LIST_ALL_GROUPS) {
|
||||
endPoint = groupServiceEndpoint + "/count";
|
||||
} else if (permissions.LIST_GROUPS) {
|
||||
endPoint = groupServiceEndpoint + "/user/" + user.username + "/count";
|
||||
} else {
|
||||
log.error("Access denied for user: " + carbonUser.username);
|
||||
return -1;
|
||||
}
|
||||
return serviceInvokers.XMLHttp.get(
|
||||
endPoint, function (responsePayload) {
|
||||
return responsePayload;
|
||||
},
|
||||
function (responsePayload) {
|
||||
log.error(responsePayload);
|
||||
return -1;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
groupModule.getGroupDeviceCount = function (groupName, owner) {
|
||||
endPoint = groupServiceEndpoint + "/owner/" + owner + "/name/" + groupName + "/devices/count";
|
||||
return serviceInvokers.XMLHttp.get(
|
||||
endPoint, function (responsePayload) {
|
||||
return responsePayload;
|
||||
},
|
||||
function (responsePayload) {
|
||||
log.error(responsePayload);
|
||||
return -1;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
groupModule.getGroupDevices = function (groupName, owner) {
|
||||
endPoint = groupServiceEndpoint + "/owner/" + owner + "/name/" + groupName + "/devices";
|
||||
return serviceInvokers.XMLHttp.get(
|
||||
endPoint, function (responsePayload) {
|
||||
return responsePayload;
|
||||
},
|
||||
function (responsePayload) {
|
||||
log.error(responsePayload);
|
||||
return responsePayload;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
}(groupModule));
|
||||
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
var operationModule = function () {
|
||||
var log = new Log("/app/modules/business-controllers/operation.js");
|
||||
var utility = require('/app/modules/utility.js').utility;
|
||||
var constants = require('/app/modules/constants.js');
|
||||
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"];
|
||||
|
||||
var publicMethods = {};
|
||||
var privateMethods = {};
|
||||
|
||||
/**
|
||||
* This method reads the token from the Token client and return the access token.
|
||||
* If the token pair s not set in the session this will send a redirect to the login page.
|
||||
*/
|
||||
function getAccessToken(deviceType, owner, deviceId) {
|
||||
var TokenClient = Packages.org.wso2.carbon.device.mgt.iot.apimgt.TokenClient;
|
||||
var accessTokenClient = new TokenClient(deviceType);
|
||||
var accessTokenInfo = accessTokenClient.getAccessToken(owner, deviceId);
|
||||
return accessTokenInfo.getAccess_token();
|
||||
}
|
||||
|
||||
privateMethods.getOperationsFromFeatures = function (deviceType, operationType) {
|
||||
var url = devicemgtProps["httpsURL"] + constants.ADMIN_SERVICE_CONTEXT + "/features/" + deviceType;
|
||||
var featuresList = serviceInvokers.XMLHttp.get(url, function (responsePayload) {
|
||||
var features = responsePayload;
|
||||
var featureList = [];
|
||||
var feature;
|
||||
for (var i = 0; i < features.length; i++) {
|
||||
feature = {};
|
||||
var analyticStreams = utility.getDeviceTypeConfig(deviceType)["analyticStreams"];
|
||||
if (analyticStreams) {
|
||||
for (var stream in analyticStreams) {
|
||||
if (analyticStreams[stream].name == features[i].name) {
|
||||
feature.ui_unit = analyticStreams[stream].ui_unit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
feature["operation"] = features[i].code;
|
||||
feature["name"] = features[i].name;
|
||||
feature["description"] = features[i].description;
|
||||
feature["deviceType"] = deviceType;
|
||||
feature["params"] = [];
|
||||
var metaData = features[i].metadataEntries;
|
||||
if (metaData) {
|
||||
for (var j = 0; j < metaData.length; j++) {
|
||||
feature["params"].push(metaData[j].value);
|
||||
}
|
||||
featureList.push(feature);
|
||||
}
|
||||
}
|
||||
return featureList;
|
||||
}, function (responsePayload) {
|
||||
var response = {};
|
||||
response["status"] = "error";
|
||||
return response;
|
||||
}
|
||||
);
|
||||
return featuresList;
|
||||
};
|
||||
|
||||
publicMethods.getControlOperations = function (deviceType) {
|
||||
var operations = privateMethods.getOperationsFromFeatures(deviceType, "operation");
|
||||
for (var op in operations) {
|
||||
var iconPath = utility.getOperationIcon(deviceType, operations[op].operation);
|
||||
if (iconPath) {
|
||||
operations[op]["icon"] = iconPath;
|
||||
}
|
||||
}
|
||||
return operations;
|
||||
};
|
||||
|
||||
publicMethods.getMonitorOperations = function (deviceType) {
|
||||
return privateMethods.getOperationsFromFeatures(deviceType, "monitor");
|
||||
};
|
||||
|
||||
publicMethods.handlePOSTOperation = function (deviceType, operation, deviceId, params) {
|
||||
var user = session.get(constants.USER_SESSION_KEY);
|
||||
var endPoint = devicemgtProps["httpsURL"] + '/' + deviceType + "/controller/" + operation;
|
||||
var header = '{"owner":"' + user.username + '","deviceId":"' + deviceId +
|
||||
'","protocol":"mqtt", "sessionId":"' + session.getId() + '", "' +
|
||||
constants.AUTHORIZATION_HEADER + '":"' + constants.BEARER_PREFIX +
|
||||
getAccessToken(deviceType, user.username, deviceId) + '"}';
|
||||
return post(endPoint, params, JSON.parse(header), "json");
|
||||
};
|
||||
|
||||
publicMethods.handleGETOperation = function (deviceType, operation, operationName, deviceId) {
|
||||
var user = session.get(constants.USER_SESSION_KEY);
|
||||
var endPoint = devicemgtProps["httpsURL"] + '/' + deviceType + "/controller/" + operation;
|
||||
var header = '{"owner":"' + user.username + '","deviceId":"' + deviceId +
|
||||
'","protocol":"mqtt", "' + constants.AUTHORIZATION_HEADER + '":"' +
|
||||
constants.BEARER_PREFIX + getAccessToken(deviceType, user.username, deviceId) +
|
||||
'"}';
|
||||
var result = get(endPoint, {}, JSON.parse(header), "json");
|
||||
if (result.data) {
|
||||
var values = result.data.sensorValue.split(',');
|
||||
if (operationName == 'gps') {
|
||||
result.data.map = {
|
||||
lat: parseFloat(values[0]),
|
||||
lng: parseFloat(values[1])
|
||||
}
|
||||
} else {
|
||||
var sqSum = 0;
|
||||
for (var v in values) {
|
||||
sqSum += Math.pow(values[v], 2);
|
||||
}
|
||||
result.data[operationName] = Math.sqrt(sqSum);
|
||||
}
|
||||
delete result.data['sensorValue'];
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
return publicMethods;
|
||||
}();
|
||||
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
var policyModule;
|
||||
policyModule = function () {
|
||||
var log = new Log("/app/modules/business-controllers/policy.js");
|
||||
|
||||
var constants = require('/app/modules/constants.js');
|
||||
var utility = require("/app/modules/utility.js")["utility"];
|
||||
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"];
|
||||
|
||||
var publicMethods = {};
|
||||
var privateMethods = {};
|
||||
|
||||
privateMethods.handleGetAllPoliciesResponse = function (backendResponse) {
|
||||
var response = {};
|
||||
if (backendResponse.status == 200 && backendResponse.responseText) {
|
||||
var isUpdated = false;
|
||||
var policyListFromRestEndpoint = parse(backendResponse.responseText)["policies"];
|
||||
|
||||
var policyListToView = [];
|
||||
var i, policyObjectFromRestEndpoint, policyObjectToView;
|
||||
for (i = 0; i < policyListFromRestEndpoint.length; i++) {
|
||||
// get list object
|
||||
policyObjectFromRestEndpoint = policyListFromRestEndpoint[i];
|
||||
// populate list object values to view-object
|
||||
policyObjectToView = {};
|
||||
policyObjectToView["id"] = policyObjectFromRestEndpoint["id"];
|
||||
policyObjectToView["priorityId"] = policyObjectFromRestEndpoint["priorityId"];
|
||||
policyObjectToView["name"] = policyObjectFromRestEndpoint["policyName"];
|
||||
policyObjectToView["platform"] = policyObjectFromRestEndpoint["profile"]["deviceType"];
|
||||
policyObjectToView["icon"] = utility.getDeviceThumb(policyObjectToView["platform"]);
|
||||
policyObjectToView["ownershipType"] = policyObjectFromRestEndpoint["ownershipType"];
|
||||
|
||||
var assignedRoleCount = policyObjectFromRestEndpoint["roles"].length;
|
||||
var assignedUserCount = policyObjectFromRestEndpoint["users"].length;
|
||||
|
||||
if (assignedRoleCount == 0) {
|
||||
policyObjectToView["roles"] = "None";
|
||||
} else if (assignedRoleCount == 1) {
|
||||
policyObjectToView["roles"] = policyObjectFromRestEndpoint["roles"][0];
|
||||
} else if (assignedRoleCount > 1) {
|
||||
policyObjectToView["roles"] = policyObjectFromRestEndpoint["roles"][0] + ", ...";
|
||||
}
|
||||
|
||||
if (assignedUserCount == 0) {
|
||||
policyObjectToView["users"] = "None";
|
||||
} else if (assignedUserCount == 1) {
|
||||
policyObjectToView["users"] = policyObjectFromRestEndpoint["users"][0];
|
||||
} else if (assignedUserCount > 1) {
|
||||
policyObjectToView["users"] = policyObjectFromRestEndpoint["users"][0] + ", ...";
|
||||
}
|
||||
|
||||
policyObjectToView["compliance"] = policyObjectFromRestEndpoint["compliance"];
|
||||
|
||||
if (policyObjectFromRestEndpoint["active"] == true &&
|
||||
policyObjectFromRestEndpoint["updated"] == true) {
|
||||
policyObjectToView["status"] = "Active/Updated";
|
||||
isUpdated = true;
|
||||
} else if (policyObjectFromRestEndpoint["active"] == true &&
|
||||
policyObjectFromRestEndpoint["updated"] == false) {
|
||||
policyObjectToView["status"] = "Active";
|
||||
} else if (policyObjectFromRestEndpoint["active"] == false &&
|
||||
policyObjectFromRestEndpoint["updated"] == true) {
|
||||
policyObjectToView["status"] = "Inactive/Updated";
|
||||
isUpdated = true;
|
||||
} else if (policyObjectFromRestEndpoint["active"] == false &&
|
||||
policyObjectFromRestEndpoint["updated"] == false) {
|
||||
policyObjectToView["status"] = "Inactive";
|
||||
}
|
||||
// push view-objects to list
|
||||
policyListToView.push(policyObjectToView);
|
||||
}
|
||||
// generate response
|
||||
response.updated = isUpdated;
|
||||
response.status = "success";
|
||||
response.content = policyListToView;
|
||||
|
||||
return response;
|
||||
} else {
|
||||
response.status = "error";
|
||||
/* backendResponse.responseText == "Scope validation failed"
|
||||
Here the response.context("Scope validation failed") is used other then response.status(401).
|
||||
Reason for this is IDP return 401 as the status in 4 different situations such as,
|
||||
1. UnAuthorized.
|
||||
2. Scope Validation Failed.
|
||||
3. Permission Denied.
|
||||
4. Access Token Expired.
|
||||
5. Access Token Invalid.
|
||||
In these cases in order to identify the correct situation we have to compare the unique value from status and
|
||||
context which is context.
|
||||
*/
|
||||
if (backendResponse.responseText == "Scope validation failed") {
|
||||
response.content = "Permission Denied";
|
||||
} else {
|
||||
response.content = backendResponse.responseText;
|
||||
}
|
||||
return response;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@Updated
|
||||
*/
|
||||
publicMethods.getAllPolicies = function () {
|
||||
var carbonUser = session.get(constants["USER_SESSION_KEY"]);
|
||||
if (!carbonUser) {
|
||||
log.error("User object was not found in the session");
|
||||
throw constants["ERRORS"]["USER_NOT_FOUND"];
|
||||
}
|
||||
try {
|
||||
var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] +
|
||||
"/policies?offset=0&limit=100";
|
||||
return serviceInvokers.XMLHttp.get(url, privateMethods.handleGetAllPoliciesResponse);
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@Updated - used by getAllPolicies
|
||||
*/
|
||||
privateMethods.getElementsInAString = function (elementList) {
|
||||
var i, elementsInAString = "";
|
||||
for (i = 0; i < elementList.length; i++) {
|
||||
if (i == elementList.length - 1) {
|
||||
elementsInAString += elementList[i];
|
||||
} else {
|
||||
elementsInAString += elementList[i] + ", ";
|
||||
}
|
||||
}
|
||||
return elementsInAString;
|
||||
};
|
||||
|
||||
return publicMethods;
|
||||
}();
|
||||
@ -0,0 +1,540 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This module contains user and roles related functionality.
|
||||
*/
|
||||
var userModule = function () {
|
||||
var log = new Log("/app/modules/business-controllers/user.js");
|
||||
|
||||
var constants = require("/app/modules/constants.js");
|
||||
var utility = require("/app/modules/utility.js")["utility"];
|
||||
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"];
|
||||
|
||||
/* Initializing user manager */
|
||||
var carbon = require("carbon");
|
||||
var url = carbon.server.address("https") + "/admin/services";
|
||||
var server = new carbon.server.Server(url);
|
||||
|
||||
var publicMethods = {};
|
||||
var privateMethods = {};
|
||||
|
||||
/**
|
||||
* Get the carbon user object from the session. If not found - it will throw a user not found error.
|
||||
* @returns {object} carbon user object
|
||||
*/
|
||||
privateMethods.getCarbonUser = function () {
|
||||
var carbon = require("carbon");
|
||||
var carbonUser = session.get(constants["USER_SESSION_KEY"]);
|
||||
var utility = require("/modules/utility.js")["utility"];
|
||||
if (!carbonUser) {
|
||||
log.error("User object was not found in the session");
|
||||
throw constants["ERRORS"]["USER_NOT_FOUND"];
|
||||
}
|
||||
return carbonUser;
|
||||
};
|
||||
|
||||
/**
|
||||
* Only GET method is implemented for now since there are no other type of methods used this method.
|
||||
* @param url - URL to call the backend without the host
|
||||
* @param method - HTTP Method (GET, POST)
|
||||
* @returns An object with 'status': 'success'|'error', 'content': {}
|
||||
*/
|
||||
privateMethods.callBackend = function (url, method) {
|
||||
if (constants["HTTP_GET"] == method) {
|
||||
return serviceInvokers.XMLHttp.get(url,
|
||||
function (backendResponse) {
|
||||
var response = {};
|
||||
response.content = backendResponse.responseText;
|
||||
if (backendResponse.status == 200) {
|
||||
response.status = "success";
|
||||
} else if (backendResponse.status == 400 || backendResponse.status == 401 ||
|
||||
backendResponse.status == 404 || backendResponse.status == 500) {
|
||||
response.status = "error";
|
||||
}
|
||||
return response;
|
||||
}
|
||||
);
|
||||
} else {
|
||||
log.error("Runtime error : This method only support HTTP GET requests.");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Register user to dc-user-store.
|
||||
*
|
||||
* @param username Username of the user
|
||||
* @param firstname First name of the user
|
||||
* @param lastname Last name of the user
|
||||
* @param emailAddress Email address of the user
|
||||
* @param password Password of the user
|
||||
* @param userRoles Roles assigned to the user
|
||||
*
|
||||
* @returns {number} HTTP Status code 201 if succeeded, 409 if user already exists
|
||||
*/
|
||||
publicMethods.registerUser = function (username, firstname, lastname, emailAddress, password, userRoles) {
|
||||
var carbon = require('carbon');
|
||||
var tenantId = carbon.server.tenantId();
|
||||
var url = carbon.server.address('https') + "/admin/services";
|
||||
var server = new carbon.server.Server(url);
|
||||
var userManager = new carbon.user.UserManager(server, tenantId);
|
||||
|
||||
try {
|
||||
if (userManager.userExists(username)) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("A user with name '" + username + "' already exists.");
|
||||
}
|
||||
// http status code 409 refers to - conflict.
|
||||
return constants.HTTP_CONFLICT;
|
||||
} else {
|
||||
var defaultUserClaims = privateMethods.buildDefaultUserClaims(firstname, lastname, emailAddress);
|
||||
userManager.addUser(username, password, userRoles, defaultUserClaims, "default");
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("A new user with name '" + username + "' was created.");
|
||||
}
|
||||
// http status code 201 refers to - created.
|
||||
return constants.HTTP_CREATED;
|
||||
}
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@Updated
|
||||
*/
|
||||
publicMethods.getUsers = function () {
|
||||
var carbonUser = session.get(constants["USER_SESSION_KEY"]);
|
||||
var utility = require("/app/modules/utility.js")["utility"];
|
||||
if (!carbonUser) {
|
||||
log.error("User object was not found in the session");
|
||||
throw constants["ERRORS"]["USER_NOT_FOUND"];
|
||||
}
|
||||
try {
|
||||
utility.startTenantFlow(carbonUser);
|
||||
var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/users?offset=0&limit=100";
|
||||
var response = privateMethods.callBackend(url, constants["HTTP_GET"]);
|
||||
if (response.status == "success") {
|
||||
response.content = parse(response.content).users;
|
||||
}
|
||||
return response;
|
||||
} catch (e) {
|
||||
throw e;
|
||||
} finally {
|
||||
utility.endTenantFlow();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return a User object from the backend by calling the JAX-RS
|
||||
* @param username
|
||||
* @returns {object} a response object with status and content on success.
|
||||
*/
|
||||
publicMethods.getUser = function (username) {
|
||||
var carbonUser = privateMethods.getCarbonUser();
|
||||
try {
|
||||
utility.startTenantFlow(carbonUser);
|
||||
var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/users/" +
|
||||
encodeURIComponent(username);
|
||||
var response = privateMethods.callBackend(url, constants["HTTP_GET"]);
|
||||
response["content"] = parse(response.content);
|
||||
response["userDomain"] = carbonUser.domain;
|
||||
return response;
|
||||
} catch (e) {
|
||||
throw e;
|
||||
} finally {
|
||||
utility.endTenantFlow();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a set of roles assigned to a particular user
|
||||
* @param username
|
||||
* @returns {object} a response object with status and content on success.
|
||||
*/
|
||||
publicMethods.getRolesByUsername = function (username) {
|
||||
var carbonUser = privateMethods.getCarbonUser();
|
||||
try {
|
||||
utility.startTenantFlow(carbonUser);
|
||||
var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/users/" +
|
||||
encodeURIComponent(username) + "/roles";
|
||||
return privateMethods.callBackend(url, constants["HTTP_GET"]);
|
||||
} catch (e) {
|
||||
throw e;
|
||||
} finally {
|
||||
utility.endTenantFlow();
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@NewlyAdded
|
||||
*/
|
||||
publicMethods.getUsersByUsername = function () {
|
||||
var carbonUser = session.get(constants["USER_SESSION_KEY"]);
|
||||
var utility = require("/app/modules/utility.js")["utility"];
|
||||
if (!carbonUser) {
|
||||
log.error("User object was not found in the session");
|
||||
throw constants["ERRORS"]["USER_NOT_FOUND"];
|
||||
}
|
||||
try {
|
||||
utility.startTenantFlow(carbonUser);
|
||||
var url = devicemgtProps["httpsURL"] + "/mdm-admin/users/users-by-username";
|
||||
return privateMethods.callBackend(url, constants["HTTP_GET"]);
|
||||
} catch (e) {
|
||||
throw e;
|
||||
} finally {
|
||||
utility.endTenantFlow();
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@Updated
|
||||
*/
|
||||
/**
|
||||
* Get User Roles from user store (Internal roles not included).
|
||||
*/
|
||||
publicMethods.getRoles = function () {
|
||||
var carbonUser = session.get(constants["USER_SESSION_KEY"]);
|
||||
var utility = require("/app/modules/utility.js")["utility"];
|
||||
if (!carbonUser) {
|
||||
log.error("User object was not found in the session");
|
||||
throw constants["ERRORS"]["USER_NOT_FOUND"];
|
||||
}
|
||||
try {
|
||||
utility.startTenantFlow(carbonUser);
|
||||
var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] +
|
||||
"/roles?offset=0&limit=100";
|
||||
var response = privateMethods.callBackend(url, constants["HTTP_GET"]);
|
||||
if (response.status == "success") {
|
||||
response.content = parse(response.content).roles;
|
||||
}
|
||||
return response;
|
||||
} catch (e) {
|
||||
throw e;
|
||||
} finally {
|
||||
utility.endTenantFlow();
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@Updated
|
||||
*/
|
||||
/**
|
||||
* Get User Roles from user store (Internal roles not included).
|
||||
* @returns {object} a response object with status and content on success.
|
||||
*/
|
||||
publicMethods.getRolesByUserStore = function () {
|
||||
var ROLE_LIMIT = devicemgtProps["pageSize"];
|
||||
var carbonUser = session.get(constants["USER_SESSION_KEY"]);
|
||||
var utility = require("/app/modules/utility.js")["utility"];
|
||||
if (!carbonUser) {
|
||||
log.error("User object was not found in the session");
|
||||
throw constants["ERRORS"]["USER_NOT_FOUND"];
|
||||
}
|
||||
try {
|
||||
utility.startTenantFlow(carbonUser);
|
||||
var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/roles?limit=" + ROLE_LIMIT;
|
||||
var response = privateMethods.callBackend(url, constants["HTTP_GET"]);
|
||||
if (response.status == "success") {
|
||||
response.content = parse(response.content).roles;
|
||||
}
|
||||
return response;
|
||||
} catch (e) {
|
||||
throw e;
|
||||
} finally {
|
||||
utility.endTenantFlow();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get Platforms.
|
||||
*/
|
||||
//TODO Move this piece of logic out of user.js to somewhere else appropriate.
|
||||
publicMethods.getPlatforms = function () {
|
||||
var carbonUser = session.get(constants["USER_SESSION_KEY"]);
|
||||
var utility = require("/app/modules/utility.js")["utility"];
|
||||
if (!carbonUser) {
|
||||
log.error("User object was not found in the session");
|
||||
throw constants["ERRORS"]["USER_NOT_FOUND"];
|
||||
}
|
||||
try {
|
||||
utility.startTenantFlow(carbonUser);
|
||||
var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] + "/admin/device-types";
|
||||
var response = privateMethods.callBackend(url, constants["HTTP_GET"]);
|
||||
if (response.status == "success") {
|
||||
response.content = parse(response.content);
|
||||
}
|
||||
return response;
|
||||
} catch (e) {
|
||||
throw e;
|
||||
} finally {
|
||||
utility.endTenantFlow();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get role
|
||||
*/
|
||||
publicMethods.getRole = function (roleName) {
|
||||
var carbonUser = session.get(constants["USER_SESSION_KEY"]);
|
||||
var utility = require("/app/modules/utility.js")["utility"];
|
||||
if (!carbonUser) {
|
||||
log.error("User object was not found in the session");
|
||||
throw constants["ERRORS"]["USER_NOT_FOUND"];
|
||||
}
|
||||
try {
|
||||
utility.startTenantFlow(carbonUser);
|
||||
var url = devicemgtProps["httpsURL"] + devicemgtProps["backendRestEndpoints"]["deviceMgt"] +
|
||||
"/roles/" + encodeURIComponent(roleName);
|
||||
var response = privateMethods.callBackend(url, constants["HTTP_GET"]);
|
||||
response.content = parse(response.content);
|
||||
return response;
|
||||
} catch (e) {
|
||||
throw e;
|
||||
} finally {
|
||||
utility.endTenantFlow();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Authenticate a user when he or she attempts to login to MDM.
|
||||
*
|
||||
* @param username Username of the user
|
||||
* @param password Password of the user
|
||||
* @param successCallback Function to be called at the event of successful authentication
|
||||
* @param failureCallback Function to be called at the event of failed authentication
|
||||
*/
|
||||
publicMethods.login = function (username, password, successCallback, failureCallback) {
|
||||
var carbonModule = require("carbon");
|
||||
var carbonServer = application.get("carbonServer");
|
||||
try {
|
||||
// check if the user is an authenticated user.
|
||||
var isAuthenticated = carbonServer.authenticate(username, password);
|
||||
if (!isAuthenticated) {
|
||||
failureCallback("authentication");
|
||||
return;
|
||||
}
|
||||
var tenantUser = carbonModule.server.tenantUser(username);
|
||||
var isAuthorizedToLogin = privateMethods.isAuthorizedToLogin(tenantUser);
|
||||
if (!isAuthorizedToLogin) {
|
||||
failureCallback("authorization");
|
||||
return;
|
||||
}
|
||||
session.put(constants.USER_SESSION_KEY, tenantUser);
|
||||
successCallback(tenantUser);
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
|
||||
publicMethods.logout = function (successCallback) {
|
||||
session.invalidate();
|
||||
successCallback();
|
||||
};
|
||||
|
||||
publicMethods.isAuthorized = function (permission) {
|
||||
var carbon = require("carbon");
|
||||
var carbonServer = application.get("carbonServer");
|
||||
var carbonUser = session.get(constants.USER_SESSION_KEY);
|
||||
var utility = require('/app/modules/utility.js').utility;
|
||||
if (!carbonUser) {
|
||||
log.error("User object was not found in the session");
|
||||
response.sendError(401, constants.ERRORS.USER_NOT_FOUND);
|
||||
exit();
|
||||
}
|
||||
|
||||
try {
|
||||
utility.startTenantFlow(carbonUser);
|
||||
var tenantId = carbon.server.tenantId();
|
||||
var userManager = new carbon.user.UserManager(server, tenantId);
|
||||
var user = new carbon.user.User(userManager, carbonUser.username);
|
||||
return user.isAuthorized(permission, "ui.execute");
|
||||
} catch (e) {
|
||||
throw e;
|
||||
} finally {
|
||||
utility.endTenantFlow();
|
||||
}
|
||||
};
|
||||
|
||||
privateMethods.isAuthorizedToLogin = function(carbonUser) {
|
||||
var utility = require('/app/modules/utility.js').utility;
|
||||
try {
|
||||
utility.startTenantFlow(carbonUser);
|
||||
var tenantId = carbon.server.tenantId();
|
||||
var userManager = new carbon.user.UserManager(server, tenantId);
|
||||
var user = new carbon.user.User(userManager, carbonUser.username);
|
||||
return user.isAuthorized("/permission/admin/login", "ui.execute");
|
||||
} catch (e) {
|
||||
throw e;
|
||||
} finally {
|
||||
utility.endTenantFlow();
|
||||
}
|
||||
};
|
||||
|
||||
publicMethods.getUIPermissions = function () {
|
||||
var permissions = {};
|
||||
if (publicMethods.isAuthorized("/permission/admin/device-mgt/admin/devices/list")) {
|
||||
permissions["LIST_DEVICES"] = true;
|
||||
}
|
||||
if (publicMethods.isAuthorized("/permission/admin/device-mgt/user/devices/list")) {
|
||||
permissions["LIST_OWN_DEVICES"] = true;
|
||||
}
|
||||
if (publicMethods.isAuthorized("/permission/admin/device-mgt/admin/groups/list")) {
|
||||
permissions["LIST_ALL_GROUPS"] = true;
|
||||
}
|
||||
if (publicMethods.isAuthorized("/permission/admin/device-mgt/user/groups/list")) {
|
||||
permissions["LIST_GROUPS"] = true;
|
||||
}
|
||||
if (publicMethods.isAuthorized("/permission/admin/device-mgt/admin/users/list")) {
|
||||
permissions["LIST_USERS"] = true;
|
||||
}
|
||||
if (publicMethods.isAuthorized("/permission/admin/device-mgt/admin/roles/list")) {
|
||||
permissions["LIST_ROLES"] = true;
|
||||
}
|
||||
if (publicMethods.isAuthorized("/permission/admin/device-mgt/admin/policies/list")) {
|
||||
permissions["LIST_ALL_POLICIES"] = true;
|
||||
}
|
||||
if (publicMethods.isAuthorized("/permission/admin/device-mgt/user/policies/list")) {
|
||||
permissions["LIST_POLICIES"] = true;
|
||||
}
|
||||
if (publicMethods.isAuthorized("/permission/admin/device-mgt/user/devices/add")) {
|
||||
permissions["ADD_DEVICE"] = true;
|
||||
}
|
||||
if (publicMethods.isAuthorized("/permission/admin/device-mgt/user/groups/add")) {
|
||||
permissions["ADD_GROUP"] = true;
|
||||
}
|
||||
if (publicMethods.isAuthorized("/permission/admin/device-mgt/admin/users/add")) {
|
||||
permissions["ADD_USER"] = true;
|
||||
}
|
||||
if (publicMethods.isAuthorized("/permission/admin/device-mgt/admin/users/remove")) {
|
||||
permissions["REMOVE_USER"] = true;
|
||||
}
|
||||
if (publicMethods.isAuthorized("/permission/admin/device-mgt/admin/roles/add")) {
|
||||
permissions["ADD_ROLE"] = true;
|
||||
}
|
||||
if (publicMethods.isAuthorized("/permission/admin/device-mgt/admin/policies/add")) {
|
||||
permissions["ADD_ADMIN_POLICY"] = true;
|
||||
}
|
||||
if (publicMethods.isAuthorized("/permission/admin/device-mgt/user/policies/add")) {
|
||||
permissions["ADD_POLICY"] = true;
|
||||
}
|
||||
if (publicMethods.isAuthorized("/permission/admin/device-mgt/admin/policies/priority")) {
|
||||
permissions["CHANGE_POLICY_PRIORITY"] = true;
|
||||
}
|
||||
if (publicMethods.isAuthorized("/permission/admin/device-mgt/admin/dashboard/view")) {
|
||||
permissions["VIEW_DASHBOARD"] = true;
|
||||
}
|
||||
if (publicMethods.isAuthorized("/permission/admin/device-mgt/admin/platform-configs/view")) {
|
||||
permissions["TENANT_CONFIGURATION"] = true;
|
||||
}
|
||||
|
||||
return permissions;
|
||||
};
|
||||
|
||||
publicMethods.addPermissions = function (permissionList, path, init) {
|
||||
var registry, carbon = require("carbon");
|
||||
var carbonServer = application.get("carbonServer");
|
||||
var utility = require('/app/modules/utility.js').utility;
|
||||
var options = {system: true};
|
||||
if (init == "login") {
|
||||
try {
|
||||
var carbonUser = session.get(constants.USER_SESSION_KEY);
|
||||
if (!carbonUser) {
|
||||
log.error("User object was not found in the session");
|
||||
throw constants.ERRORS.USER_NOT_FOUND;
|
||||
}
|
||||
utility.startTenantFlow(carbonUser);
|
||||
var tenantId = carbon.server.tenantId();
|
||||
if (carbonUser) {
|
||||
options.tenantId = tenantId;
|
||||
}
|
||||
registry = new carbon.registry.Registry(carbonServer, options);
|
||||
var i, permission, resource;
|
||||
for (i = 0; i < permissionList.length; i++) {
|
||||
permission = permissionList[i];
|
||||
resource = {
|
||||
collection: true,
|
||||
name: permission.name,
|
||||
properties: {
|
||||
name: permission.name
|
||||
}
|
||||
};
|
||||
if (path != "") {
|
||||
registry.put("/_system/governance/permission/admin/" + path + "/" + permission.key, resource);
|
||||
} else {
|
||||
registry.put("/_system/governance/permission/admin/" + permission.key, resource);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
throw e;
|
||||
} finally {
|
||||
utility.endTenantFlow();
|
||||
}
|
||||
} else {
|
||||
registry = new carbon.registry.Registry(carbonServer, options);
|
||||
var i, permission, resource;
|
||||
for (i = 0; i < permissionList.length; i++) {
|
||||
permission = permissionList[i];
|
||||
resource = {
|
||||
collection: true,
|
||||
name: permission.name,
|
||||
properties: {
|
||||
name: permission.name
|
||||
}
|
||||
};
|
||||
if (path != "") {
|
||||
registry.put("/_system/governance/permission/admin/" + path + "/" + permission.key, resource);
|
||||
} else {
|
||||
registry.put("/_system/governance/permission/admin/" + permission.key, resource);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Private method to be used by addUser() to
|
||||
* retrieve secondary user stores.
|
||||
* This needs Authentication since the method access admin services.
|
||||
*
|
||||
* @returns Array of secondary user stores.
|
||||
*/
|
||||
publicMethods.getSecondaryUserStores = function () {
|
||||
var returnVal = [];
|
||||
var endpoint = devicemgtProps["adminService"] + constants["USER_STORE_CONFIG_ADMIN_SERVICE_END_POINT"];
|
||||
var wsPayload = "<xsd:getSecondaryRealmConfigurations xmlns:xsd='http://org.apache.axis2/xsd'/>";
|
||||
serviceInvokers.WS.soapRequest(
|
||||
"urn:getSecondaryRealmConfigurations",
|
||||
wsPayload,
|
||||
endpoint,
|
||||
function (wsResponse) {
|
||||
var domainIDs = stringify(wsResponse.*::['return']. *::domainId.text());
|
||||
if (domainIDs != "\"\"") {
|
||||
var regExpForSearch = new RegExp(constants["USER_STORES_NOISY_CHAR"], "g");
|
||||
domainIDs = domainIDs.replace(regExpForSearch, "");
|
||||
returnVal = domainIDs.split(constants["USER_STORES_SPLITTING_CHAR"]);
|
||||
}
|
||||
}, function (e) {
|
||||
log.error("Error retrieving secondary user stores", e);
|
||||
},
|
||||
constants["SOAP_VERSION"]);
|
||||
return returnVal;
|
||||
};
|
||||
|
||||
return publicMethods;
|
||||
}();
|
||||
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
var conf = function () {
|
||||
var conf = application.get("CONF");
|
||||
if (!conf) {
|
||||
conf = require("/app/conf/config.json");
|
||||
var pinch = require("/app/modules/conf-reader/pinch.min.js")["pinch"];
|
||||
var server = require("carbon")["server"];
|
||||
pinch(conf, /^/,
|
||||
function (path, key, value) {
|
||||
if ((typeof value === "string") && value.indexOf("%https.ip%") > -1) {
|
||||
//noinspection JSUnresolvedFunction
|
||||
return value.replace("%https.ip%", server.address("https"));
|
||||
} else if ((typeof value === "string") && value.indexOf("%http.ip%") > -1) {
|
||||
//noinspection JSUnresolvedFunction
|
||||
return value.replace("%http.ip%", server.address("http"));
|
||||
} else if ((typeof value === "string") && value.indexOf("%date-year%") > -1) {
|
||||
var year = new Date().getFullYear();
|
||||
return value.replace("%date-year%", year);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
);
|
||||
application.put("CONF", conf);
|
||||
}
|
||||
return conf;
|
||||
}();
|
||||
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2011 František Hába <hello@frantisekhaba.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the 'Software'), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
|
||||
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Reference:- https://github.com/Baggz/Pinch
|
||||
* */
|
||||
(function(){var k=function(a,c){return a.length!==c.length?!1:a.every(function(a,b){return c[b]===a})},j=function(a,c,d){var b,e;if("[object Array]"===Object.prototype.toString.call(a)){b=0;for(e=a.length;b<e;b++)c.apply(d,[b,a[b],a])}else for(b in a)a.hasOwnProperty(b)&&c.apply(d,[b,a[b],a])},h=function(a){for(var c=[],d=!1,b=0,e=a.length,f="",g=function(){f&&(c.push(f),f="")};b<e;b++)a[b].match(/\[|\]/)?(g(),d="]"===a[b]?!1:!0):'"'!==a[b]&&"'"!==a[b]&&("."===a[b]&&!d?g():f+=a[b]),b===e-1&&g();return c},
|
||||
g=function(a,c,d){var b=-1!==["string","object"].indexOf(typeof a),e="string"===typeof c||c&&c.test&&c.exec,f=-1!==["string","object","function"].indexOf(typeof d);b&&e&&f&&("string"===typeof a?(this.instance=JSON.parse(a),this.json=!0):this.instance=a,this.pattern="string"===typeof c?c.replace(/'/g,'"'):c,this.replacement=d,this.createIndex(this.instance))};g.prototype.createIndex=function(a,c){var d=this;this.index=this.index||[];c=c||"";j(a,function(a,e){var f,a=a+"";f=a.match(/^[a-zA-Z]+$/)?c?
|
||||
c+"."+a:a:a.match(/\d+/)?c+"["+a+"]":c+'["'+a+'"]';d.index.push(f);"object"===typeof e&&d.createIndex(e,f)})};g.prototype.replace=function(){var a=this;j(this.index,function(c,d){if(a.pattern&&a.pattern.test&&a.pattern.exec&&d.match(a.pattern))return a.replaceValue(d);if("string"===typeof a.pattern){var b=h(d),e=h(a.pattern);if(k(b,e))return a.replaceValue(d)}});return this.json?JSON.stringify(this.instance):this.instance};g.prototype.replaceValue=function(a){var c=this,d=h(a);d.reduce(function(b,
|
||||
e,f){if(f===d.length-1)f="function"===typeof c.replacement?c.replacement(a,e,b[e]):c.replacement,b[e]=f;else return b[e]},this.instance)};var i=function(a,c,d,b){a=(new g(a,c,d)).replace();return"function"===typeof b?b(null,a):a};"undefined"!==typeof module&&module.exports?module.exports=i:"undefined"!==typeof define?define(function(){return i}):this.pinch=i})();
|
||||
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
var WEB_APP_TITLE = "WSO2 CDM";
|
||||
var WEB_APP_CONTEXT = "/devicemgt";
|
||||
var ADMIN_SERVICE_CONTEXT = "/devicemgt_admin";
|
||||
var USER_SESSION_KEY = "_UUF_USER";
|
||||
var UNSPECIFIED = "Unspecified";
|
||||
var httpURL = "httpURL";
|
||||
var httpsURL = "httpsURL";
|
||||
|
||||
var DEVICE_IDENTIFIER = "deviceIdentifier";
|
||||
var DEVICE_NAME = "name";
|
||||
var DEVICE_OWNERSHIP = "ownership";
|
||||
var DEVICE_OWNER = "owner";
|
||||
var DEVICE_TYPE = "type";
|
||||
var DEVICE_VENDOR = "vendor";
|
||||
var DEVICE_MODEL = "model";
|
||||
var DEVICE_PRODUCT = "PRODUCT";
|
||||
var DEVICE_OS_VERSION = "osVersion";
|
||||
var DEVICE_OS_BUILD_DATE = "osBuildDate";
|
||||
var DEVICE_PROPERTIES = "properties";
|
||||
var DEVICE_ENROLLMENT_INFO = "enrolmentInfo";
|
||||
var DEVICE_STATUS = "status";
|
||||
|
||||
var FEATURE_NAME = "featureName";
|
||||
var FEATURE_DESCRIPTION = "featureDescription";
|
||||
|
||||
var PLATFORM_ANDROID = "android";
|
||||
var PLATFORM_WINDOWS = "windows";
|
||||
var PLATFORM_IOS = "ios";
|
||||
|
||||
var LANGUAGE_US = "en_US";
|
||||
|
||||
var VENDOR_APPLE = "Apple";
|
||||
var ERRORS = {
|
||||
"USER_NOT_FOUND": "USER_NOT_FOUND"
|
||||
};
|
||||
|
||||
var USER_STORES_NOISY_CHAR = "\"";
|
||||
var USER_STORES_SPLITTING_CHAR = "\\n";
|
||||
var USER_STORE_CONFIG_ADMIN_SERVICE_END_POINT =
|
||||
"/services/UserStoreConfigAdminService.UserStoreConfigAdminServiceHttpsSoap12Endpoint/";
|
||||
|
||||
var SOAP_VERSION = 1.2;
|
||||
var WEB_SERVICE_ADDRESSING_VERSION = 1.0;
|
||||
var TOKEN_PAIR = "tokenPair";
|
||||
var ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS = "encodedTenantBasedClientAppCredentials";
|
||||
var CONTENT_TYPE_IDENTIFIER = "Content-Type";
|
||||
var CONTENT_DISPOSITION_IDENTIFIER = "Content-Disposition";
|
||||
var APPLICATION_JSON = "application/json";
|
||||
var APPLICATION_ZIP = "application/zip";
|
||||
var ACCEPT_IDENTIFIER = "Accept";
|
||||
var AUTHORIZATION_HEADER= "Authorization";
|
||||
var BEARER_PREFIX = "Bearer ";
|
||||
var HTTP_GET = "GET";
|
||||
var HTTP_POST = "POST";
|
||||
var HTTP_PUT = "PUT";
|
||||
var HTTP_DELETE = "DELETE";
|
||||
var REFERER = "referer";
|
||||
|
||||
var HTTP_CONFLICT = 409;
|
||||
var HTTP_CREATED = 201;
|
||||
|
||||
var CACHED_CREDENTIALS = "tenantBasedCredentials";
|
||||
var ALLOWED_SCOPES = "scopes";
|
||||
@ -0,0 +1,63 @@
|
||||
<%
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
var log = new Log("/modules/enrollments/ios/agent-check.jag");
|
||||
|
||||
var mdmProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
var UAParser = require("/app/modules/ua-parser.min.js")["UAParser"];
|
||||
|
||||
var parser = new UAParser();
|
||||
var userAgent = request.getHeader("User-Agent");
|
||||
parser.setUA(userAgent);
|
||||
parser.getResult();
|
||||
var os = parser.getOS();
|
||||
var platform = os.name;
|
||||
|
||||
if (platform != "iOS") {
|
||||
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
|
||||
} else if (session.get("lastAccessedPage") != "license-agent") {
|
||||
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
|
||||
} else {
|
||||
var enrolledUser = session.get("enrolledUser");
|
||||
if (!enrolledUser) {
|
||||
response["status"] = 200;
|
||||
response["content"] = {"deviceID" : null};
|
||||
} else {
|
||||
var deviceCheckURL = mdmProps["iOSAPIRoot"] + "device/deviceid";
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", deviceCheckURL);
|
||||
var challengeToken = session.get("iOSChallengeToken");
|
||||
var inputs = {"challengeToken" : challengeToken};
|
||||
xhr.setRequestHeader("Content-Type", "application/json");
|
||||
xhr.setRequestHeader("Accept", "application/json");
|
||||
xhr.send(stringify(inputs));
|
||||
|
||||
if (xhr.status == 200) {
|
||||
var responseObject = parse(xhr["responseText"]);
|
||||
response["status"] = 200;
|
||||
response["content"] = responseObject;
|
||||
} else {
|
||||
// server only returns 400 in case of bad request
|
||||
response["status"] = 200;
|
||||
response["content"] = {"deviceID" : null};
|
||||
}
|
||||
}
|
||||
}
|
||||
%>
|
||||
@ -0,0 +1,80 @@
|
||||
<%
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
var log = new Log("/modules/enrollments/ios/agent-controller.jag");
|
||||
|
||||
var mdmProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
var UAParser = require("/app/modules/ua-parser.min.js")["UAParser"];
|
||||
var tokenUtil = require("/app/modules/oauth/token-handlers.js")["handlers"];
|
||||
var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"];
|
||||
var constants = require("/app/modules/constants.js");
|
||||
|
||||
var parser = new UAParser();
|
||||
var userAgent = request.getHeader("User-Agent");
|
||||
parser.setUA(userAgent);
|
||||
parser.getResult();
|
||||
var os = parser.getOS();
|
||||
var platform = os.name;
|
||||
|
||||
if (platform != "iOS") {
|
||||
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
|
||||
} else if (session.get("lastAccessedPage") != "login-agent") {
|
||||
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
|
||||
} else {
|
||||
var username = request.getParameter("username");
|
||||
var password = request.getParameter("password");
|
||||
var ownership = request.getParameter("ownership");
|
||||
var domain = request.getParameter("domain");
|
||||
if (!username || !password || !ownership) {
|
||||
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
|
||||
} else {
|
||||
var fullyQualifiedUsername = username;
|
||||
if(domain != null && domain != ''){
|
||||
fullyQualifiedUsername = username + "@" + domain;
|
||||
}
|
||||
tokenUtil.setupTokenPairByPasswordGrantType(fullyQualifiedUsername, password);
|
||||
var authUrl = mdmProps["iOSConfigRoot"] + "authenticate";
|
||||
var payload = {
|
||||
"username": username, "password": password, "ownership": ownership,
|
||||
"tenantDomain": domain
|
||||
};
|
||||
serviceInvokers.XMLHttp.post(
|
||||
authUrl,
|
||||
stringify(payload),
|
||||
function (restAPIResponse) {
|
||||
var status = restAPIResponse["status"];
|
||||
if (status == 200) {
|
||||
var responseContent = parse(restAPIResponse.responseText);
|
||||
session.put("authenticatedUser", username);
|
||||
session.put("authenticatedUserPassword", password);
|
||||
session.put("authenticatedUserDeviceOwnership", ownership);
|
||||
session.put("authenticatedUserDomain", domain);
|
||||
session.put("iOSChallengeToken", responseContent["challengeToken"]);
|
||||
response.sendRedirect(mdmProps["appContext"] + "enrollments/ios/license-agent");
|
||||
} else if (status == 403) {
|
||||
response.sendRedirect(mdmProps["appContext"] + "enrollments/ios/login-agent?error=auth-failed");
|
||||
} else {
|
||||
// one visible possibility would be server sending 500
|
||||
response.sendRedirect(mdmProps["appContext"] + "enrollments/ios/login-agent?error=unexpected");
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
%>
|
||||
@ -0,0 +1,85 @@
|
||||
<%
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
var log = new Log("/app/modules/enrollments/ios/agent-enroll.jag");
|
||||
|
||||
var mdmProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
var UAParser = require("/app/modules/ua-parser.min.js")["UAParser"];
|
||||
|
||||
var parser = new UAParser();
|
||||
var userAgent = request.getHeader("User-Agent");
|
||||
parser.setUA(userAgent);
|
||||
parser.getResult();
|
||||
var os = parser.getOS();
|
||||
var platform = os.name;
|
||||
|
||||
if (platform != "iOS") {
|
||||
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
|
||||
} else if (session.get("lastAccessedPage") != "license-agent") {
|
||||
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
|
||||
} else {
|
||||
var authenticatedUser = session.get("authenticatedUser");
|
||||
if (!authenticatedUser) {
|
||||
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
|
||||
} else {
|
||||
var HttpClient = Packages.org.apache.commons.httpclient.HttpClient;
|
||||
var PostMethod = Packages.org.apache.commons.httpclient.methods.PostMethod;
|
||||
var Header = Packages.org.apache.commons.httpclient.Header;
|
||||
var StringRequestEntity = Packages.org.apache.commons.httpclient.methods.StringRequestEntity;
|
||||
var ByteArrayInputStream = Packages.java.io.ByteArrayInputStream;
|
||||
|
||||
var client = new HttpClient();
|
||||
var enrollUrl = mdmProps["iOSConfigRoot"] + "enroll";
|
||||
var method = new PostMethod(enrollUrl);
|
||||
var header = new Header();
|
||||
|
||||
header.setName("Content-Type");
|
||||
header.setValue("application/json");
|
||||
method.addRequestHeader(header);
|
||||
|
||||
var username = authenticatedUser;
|
||||
var password = session.get("authenticatedUserPassword");
|
||||
var tenantDomain = session.get("authenticatedUserDomain");
|
||||
var challengeToken = session.get("iOSChallengeToken");
|
||||
|
||||
var inputs = {"username": username, "password": password, "challengeToken": challengeToken, "tenantDomain": tenantDomain};
|
||||
var stringRequestEntity = new StringRequestEntity(stringify(inputs));
|
||||
method.setRequestEntity(stringRequestEntity);
|
||||
try {
|
||||
client.executeMethod(method);
|
||||
var status = method.getStatusCode();
|
||||
if (status == 200) {
|
||||
session.put("enrolledUser", authenticatedUser);
|
||||
var stream = method.getResponseBody();
|
||||
var byteArrayInputStream = new ByteArrayInputStream(stream);
|
||||
response.contentType = "application/x-apple-aspen-config";
|
||||
print(new Stream(byteArrayInputStream));
|
||||
} else {
|
||||
// two visible possibilities would be server sending 401 and 500
|
||||
response.sendRedirect(mdmProps["appContext"] + "enrollments/ios/login-agent?error=unexpected");
|
||||
}
|
||||
} catch (e) {
|
||||
log.error("Error occurred in enrolling ios device", e);
|
||||
response.sendRedirect(mdmProps["appContext"] + "enrollments/ios/login-agent?error=unexpected");
|
||||
} finally {
|
||||
method.releaseConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
%>
|
||||
@ -0,0 +1,47 @@
|
||||
<%
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
var log = new Log("/app/modules/enrollments/ios/agent.jag");
|
||||
|
||||
var mdmProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
|
||||
var userAgent = request.getHeader("User-Agent");
|
||||
var userAgentIsiPhone = (userAgent.indexOf("iPhone") > -1);
|
||||
var userAgentIsiPad = (userAgent.indexOf("iPad") > -1);
|
||||
var userAgentIsiPodTouch = (userAgent.indexOf("iPod Touch") > -1);
|
||||
|
||||
if (!userAgentIsiPhone && !userAgentIsiPad && !userAgentIsiPodTouch) {
|
||||
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
|
||||
} else {
|
||||
var enrollmentUtils = require("/app/modules/enrollments/util/utils.js")["methods"];
|
||||
var Handlebars = require("/lib/modules/handlebars/handlebars-v2.0.0.js")["Handlebars"];
|
||||
var template = Handlebars.compile(enrollmentUtils.
|
||||
getResource("/app/modules/enrollments/ios/config/ios-manifest-template.hbs"));
|
||||
|
||||
var iOSManifest = template({
|
||||
"url" : mdmProps["device"]["ios"]["location"],
|
||||
"bundleID" : mdmProps["device"]["ios"]["bundleID"],
|
||||
"bundleVersion" : mdmProps["device"]["ios"]["version"],
|
||||
"appName" : mdmProps["device"]["ios"]["appName"]
|
||||
});
|
||||
|
||||
response.contentType = "application/xml";
|
||||
response.content = iOSManifest;
|
||||
}
|
||||
%>
|
||||
@ -0,0 +1,26 @@
|
||||
<%
|
||||
var HttpClient = Packages.org.apache.commons.httpclient.HttpClient;
|
||||
var GetMethod = Packages.org.apache.commons.httpclient.methods.GetMethod;
|
||||
var StringRequestEntity = Packages.org.apache.commons.httpclient.methods.StringRequestEntity;
|
||||
|
||||
var mdmProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
var caURL = mdmProps["iOSConfigRoot"] + 'ca';
|
||||
var client = new HttpClient();
|
||||
var method = new GetMethod(caURL);
|
||||
|
||||
try {
|
||||
client.executeMethod(method);
|
||||
var status = method.getStatusCode();
|
||||
|
||||
if (status == 200) {
|
||||
var stream = method.getResponseBody();
|
||||
response.contentType = "application/x-x509-ca-cert";
|
||||
var byteArrayInputStream = new Packages.java.io.ByteArrayInputStream(stream);
|
||||
print(new Stream(byteArrayInputStream));
|
||||
} else {
|
||||
response.sendRedirect("/errorpage");
|
||||
}
|
||||
} catch (e) {
|
||||
log.error("Error occurred when downloading CA " + e);
|
||||
}
|
||||
%>
|
||||
@ -0,0 +1,31 @@
|
||||
<?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>items</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>assets</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>kind</key>
|
||||
<string>software-package</string>
|
||||
<key>url</key>
|
||||
<string>{{url}}</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>metadata</key>
|
||||
<dict>
|
||||
<key>bundle-identifier</key>
|
||||
<string>{{bundleID}}</string>
|
||||
<key>bundle-version</key>
|
||||
<string>{{bundleVersion}}</string>
|
||||
<key>kind</key>
|
||||
<string>software</string>
|
||||
<key>title</key>
|
||||
<string>{{appName}}</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
var methods;
|
||||
methods = function () {
|
||||
var log = new Log("modules/enrollments/util/utils.js");
|
||||
|
||||
var publicMethods = {};
|
||||
|
||||
publicMethods.getResource = function (resourcePath) {
|
||||
var file = new File(resourcePath);
|
||||
var resource = null;
|
||||
try {
|
||||
file.open("r");
|
||||
resource = file.readAll();
|
||||
} catch (e) {
|
||||
log.error("Error in reading resource");
|
||||
} finally {
|
||||
file.close();
|
||||
}
|
||||
return resource;
|
||||
};
|
||||
|
||||
return publicMethods;
|
||||
}();
|
||||
@ -0,0 +1,96 @@
|
||||
<%
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
var log = new Log("/app/modules/enrollments/windows/agent-controller.jag");
|
||||
|
||||
var mdmProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
var UAParser = require("/app/modules/ua-parser.min.js")["UAParser"];
|
||||
var tokenUtil = require("/app/modules/oauth/token-handlers.js")["handlers"];
|
||||
var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"];
|
||||
var constants = require("/app/modules/constants.js");
|
||||
|
||||
var parser = new UAParser();
|
||||
var userAgent = request.getHeader("User-Agent");
|
||||
parser.setUA(userAgent);
|
||||
parser.getResult();
|
||||
var os = parser.getOS();
|
||||
var platform = os.name;
|
||||
|
||||
if (platform != "Windows Phone") {
|
||||
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
|
||||
} else if (session.get("lastAccessedPage") != "login-agent") {
|
||||
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
|
||||
} else {
|
||||
var username = request.getParameter("username");
|
||||
var email = session.get("email");
|
||||
var password = request.getParameter("password");
|
||||
var domain = request.getParameter("domain");
|
||||
if (!username || !email || !password) {
|
||||
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
|
||||
} else {
|
||||
var authUrl = mdmProps["windowsConfigRoot"];
|
||||
var fullyQualifiedUsername = username;
|
||||
if(domain != null && domain != ''){
|
||||
fullyQualifiedUsername = username + "@" + domain;
|
||||
}
|
||||
tokenUtil.setupTokenPairByPasswordGrantType(fullyQualifiedUsername, password);
|
||||
var payload = {
|
||||
"credentials": {
|
||||
"username": username, "email": email,
|
||||
"password": password, "token": getAccessToken()
|
||||
}
|
||||
};
|
||||
serviceInvokers.XMLHttp.post(
|
||||
authUrl,
|
||||
stringify(payload),
|
||||
function (restAPIResponse) {
|
||||
var status = restAPIResponse["status"];
|
||||
if (status == 200) {
|
||||
session.put("authenticatedUser", username);
|
||||
session.put("windowsBinaryToken", parse(xmlHttpRequest["responseText"]).UserToken);
|
||||
response.sendRedirect(mdmProps["appContext"] + "enrollments/windows/license-agent");
|
||||
} else if (status == 403) {
|
||||
response.sendRedirect(mdmProps["appContext"] + "enrollments/windows/login-agent?error=auth-failed");
|
||||
} else if (status == 409) {
|
||||
response.sendRedirect(mdmProps["appContext"] + "enrollments/windows/login-agent?" +
|
||||
"error=auth-failed&message=Provided Workplace email does not match with username. Please check.");
|
||||
} else {
|
||||
// one visible possibility would be server sending 500
|
||||
response.sendRedirect(mdmProps["appContext"] + "enrollments/windows/login-agent?error=unexpected");
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method reads the token pair from the session and return the access token.
|
||||
* If the token pair is not set in the session, this will return null.
|
||||
*/
|
||||
function getAccessToken() {
|
||||
var tokenPair = parse(session.get(constants["TOKEN_PAIR"]));
|
||||
if (tokenPair) {
|
||||
return tokenPair["accessToken"];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
%>
|
||||
@ -0,0 +1,55 @@
|
||||
<%
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
var log = new Log("/app/modules/enrollments/windows/agent-enroll.jag");
|
||||
|
||||
var UAParser = require("/app/modules/ua-parser.min.js")["UAParser"];
|
||||
var parser = new UAParser();
|
||||
var userAgent = request.getHeader("User-Agent");
|
||||
parser.setUA(userAgent);
|
||||
parser.getResult();
|
||||
var os = parser.getOS();
|
||||
var platform = os.name;
|
||||
|
||||
if (platform != "Windows Phone") {
|
||||
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
|
||||
} else if (session.get("lastAccessedPage") != "license-agent") {
|
||||
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
|
||||
} else {
|
||||
var authenticatedUser = session.get("authenticatedUser");
|
||||
if (!authenticatedUser) {
|
||||
response.sendRedirect(mdmProps["appContext"] + "enrollments/error/unintentional-request");
|
||||
} else {
|
||||
var enrollmentUtils = require("/modules/enrollments/util/utils.js")["methods"];
|
||||
var Handlebars = require("/lib/handlebars-v2.0.0.js")["Handlebars"];
|
||||
var template = Handlebars.compile(enrollmentUtils.
|
||||
getResource("/modules/enrollments/windows/config/workplace-switch-request-template.hbs"));
|
||||
|
||||
var windowsWorkplaceAppID = session.get("windowsWorkplaceAppID");
|
||||
var windowsBinaryToken = session.get("windowsBinaryToken");
|
||||
var workplaceSwitchRequest = template({
|
||||
"windowsWorkplaceAppID" : windowsWorkplaceAppID,
|
||||
"windowsBinaryToken" : windowsBinaryToken
|
||||
});
|
||||
|
||||
response.contentType = "text/html";
|
||||
response.content = workplaceSwitchRequest;
|
||||
}
|
||||
}
|
||||
%>
|
||||
@ -0,0 +1,20 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
Working...
|
||||
</title>
|
||||
<script>
|
||||
function formSubmit() {
|
||||
document.forms[0].submit();
|
||||
}
|
||||
window.onload=formSubmit;
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<form method="post" action="{{windowsWorkplaceAppID}}">
|
||||
<p><input type="hidden" name="wresult" value="{{windowsBinaryToken}}"/></p>
|
||||
<input type="submit"/>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
var carbonModule = require("carbon");
|
||||
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
var carbonServer = new carbonModule.server.Server({
|
||||
tenanted: true,
|
||||
url: devicemgtProps["httpsURL"] + "/admin"
|
||||
});
|
||||
application.put("carbonServer", carbonServer);
|
||||
|
||||
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
|
||||
var utility = require("/app/modules/utility.js")["utility"];
|
||||
|
||||
var permissions = {
|
||||
'/permission/admin/device-mgt/user': ['ui.execute'],
|
||||
'/permission/admin/manage/api/subscribe': ['ui.execute']
|
||||
};
|
||||
//userModule.addRole("internal/devicemgt-user", ["admin"], permissions);
|
||||
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
var onSuccess;
|
||||
var onFail;
|
||||
|
||||
(function () {
|
||||
var log = new Log("/app/modules/login.js");
|
||||
var constants = require("/app/modules/constants.js");
|
||||
onSuccess = function (context) {
|
||||
var utility = require("/app/modules/utility.js").utility;
|
||||
var apiWrapperUtil = require("/app/modules/oauth/token-handlers.js")["handlers"];
|
||||
if (context.input.samlToken) {
|
||||
apiWrapperUtil.setupTokenPairBySamlGrantType(context.input.username, context.input.samlToken);
|
||||
} else {
|
||||
apiWrapperUtil.setupTokenPairByPasswordGrantType(context.input.username, context.input.password);
|
||||
}
|
||||
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
var carbonServer = require("carbon").server;
|
||||
(new carbonServer.Server({url: devicemgtProps["adminService"]}))
|
||||
.login(context.input.username, context.input.password);
|
||||
};
|
||||
|
||||
onFail = function (error) {
|
||||
log.error(error.message);
|
||||
}
|
||||
})();
|
||||
@ -0,0 +1,295 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
var utils = function () {
|
||||
var log = new Log("/app/modules/oauth/token-handler-utils.js");
|
||||
|
||||
var deviceMgtProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
var constants = require("/app/modules/constants.js");
|
||||
var carbon = require("carbon");
|
||||
|
||||
//noinspection JSUnresolvedVariable
|
||||
var Base64 = Packages.org.apache.commons.codec.binary.Base64;
|
||||
//noinspection JSUnresolvedVariable
|
||||
var String = Packages.java.lang.String;
|
||||
|
||||
var publicMethods = {};
|
||||
var privateMethods = {};
|
||||
|
||||
publicMethods["encode"] = function (payload) {
|
||||
//noinspection JSUnresolvedFunction
|
||||
return String(Base64.encodeBase64(String(payload).getBytes()));
|
||||
};
|
||||
|
||||
publicMethods["decode"] = function (payload) {
|
||||
//noinspection JSUnresolvedFunction
|
||||
return String(Base64.decodeBase64(String(payload).getBytes()));
|
||||
};
|
||||
|
||||
publicMethods["getDynamicClientAppCredentials"] = function () {
|
||||
// setting up dynamic client application properties
|
||||
var dcAppProperties = {
|
||||
"applicationType": deviceMgtProps["oauthProvider"]["appRegistration"]["appType"],
|
||||
"clientName": deviceMgtProps["oauthProvider"]["appRegistration"]["clientName"],
|
||||
"owner": deviceMgtProps["oauthProvider"]["appRegistration"]["owner"],
|
||||
"tokenScope": deviceMgtProps["oauthProvider"]["appRegistration"]["tokenScope"],
|
||||
"grantType": deviceMgtProps["oauthProvider"]["appRegistration"]["grantType"],
|
||||
"callbackUrl": deviceMgtProps["oauthProvider"]["appRegistration"]["callbackUrl"],
|
||||
"saasApp" : true
|
||||
};
|
||||
// calling dynamic client app registration service endpoint
|
||||
var requestURL = deviceMgtProps["oauthProvider"]["appRegistration"]
|
||||
["dynamicClientAppRegistrationServiceURL"];
|
||||
var requestPayload = dcAppProperties;
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", requestURL, false);
|
||||
xhr.setRequestHeader("Content-Type", "application/json");
|
||||
xhr.send(stringify(requestPayload));
|
||||
|
||||
var dynamicClientAppCredentials = {};
|
||||
if (xhr["status"] == 201 && xhr["responseText"]) {
|
||||
var responsePayload = parse(xhr["responseText"]);
|
||||
dynamicClientAppCredentials["clientId"] = responsePayload["client_id"];
|
||||
dynamicClientAppCredentials["clientSecret"] = responsePayload["client_secret"];
|
||||
} else if (xhr["status"] == 400) {
|
||||
log.error("{/app/modules/oauth/token-handler-utils.js - getDynamicClientAppCredentials()} " +
|
||||
"Bad request. Invalid data provided as dynamic client application properties.");
|
||||
dynamicClientAppCredentials = null;
|
||||
} else {
|
||||
log.error("{/app/modules/oauth/token-handler-utils.js - getDynamicClientAppCredentials()} " +
|
||||
"Error in retrieving dynamic client credentials.");
|
||||
dynamicClientAppCredentials = null;
|
||||
}
|
||||
// returning dynamic client credentials
|
||||
return dynamicClientAppCredentials;
|
||||
};
|
||||
|
||||
publicMethods["getTenantBasedClientAppCredentials"] = function (username, jwtToken) {
|
||||
if (!username || !jwtToken) {
|
||||
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving tenant " +
|
||||
"based client app credentials. No username or jwt token is found " +
|
||||
"as input - getTenantBasedClientAppCredentials(x, y)");
|
||||
return null;
|
||||
} else {
|
||||
//noinspection JSUnresolvedFunction, JSUnresolvedVariable
|
||||
var tenantDomain = carbon.server.tenantDomain({username: username});
|
||||
if (!tenantDomain) {
|
||||
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving tenant " +
|
||||
"based client application credentials. Unable to obtain a valid tenant domain for provided " +
|
||||
"username - getTenantBasedClientAppCredentials(x, y)");
|
||||
return null;
|
||||
} else {
|
||||
var cachedTenantBasedClientAppCredentials = privateMethods.
|
||||
getCachedTenantBasedClientAppCredentials(tenantDomain);
|
||||
if (cachedTenantBasedClientAppCredentials) {
|
||||
return cachedTenantBasedClientAppCredentials;
|
||||
} else {
|
||||
// register a tenant based client app at API Manager
|
||||
var applicationName = "webapp_" + tenantDomain;
|
||||
var requestURL = deviceMgtProps["oauthProvider"]["appRegistration"]
|
||||
["apiManagerClientAppRegistrationServiceURL"] +
|
||||
"?tenantDomain=" + tenantDomain + "&applicationName=" + applicationName;
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", requestURL, false);
|
||||
xhr.setRequestHeader("Content-Type", "application/json");
|
||||
xhr.setRequestHeader("Authorization", "Bearer " + jwtToken);
|
||||
xhr.send();
|
||||
|
||||
if (xhr["status"] == 201 && xhr["responseText"]) {
|
||||
var responsePayload = parse(xhr["responseText"]);
|
||||
var tenantBasedClientAppCredentials = {};
|
||||
tenantBasedClientAppCredentials["clientId"] = responsePayload["client_id"];
|
||||
tenantBasedClientAppCredentials["clientSecret"] = responsePayload["client_secret"];
|
||||
privateMethods.
|
||||
setCachedTenantBasedClientAppCredentials(tenantDomain, tenantBasedClientAppCredentials);
|
||||
return tenantBasedClientAppCredentials;
|
||||
} else {
|
||||
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving tenant " +
|
||||
"based client application credentials from API " +
|
||||
"Manager - getTenantBasedClientAppCredentials(x, y)");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
privateMethods["setCachedTenantBasedClientAppCredentials"] = function (tenantDomain, clientAppCredentials) {
|
||||
var cachedTenantBasedClientAppCredentialsMap = application.get(constants["CACHED_CREDENTIALS"]);
|
||||
if (!cachedTenantBasedClientAppCredentialsMap) {
|
||||
cachedTenantBasedClientAppCredentialsMap = {};
|
||||
cachedTenantBasedClientAppCredentialsMap[tenantDomain] = clientAppCredentials;
|
||||
application.put(constants["CACHED_CREDENTIALS"], cachedTenantBasedClientAppCredentialsMap);
|
||||
} else if (!cachedTenantBasedClientAppCredentialsMap[tenantDomain]) {
|
||||
cachedTenantBasedClientAppCredentialsMap[tenantDomain] = clientAppCredentials;
|
||||
}
|
||||
};
|
||||
|
||||
privateMethods["getCachedTenantBasedClientAppCredentials"] = function (tenantDomain) {
|
||||
var cachedTenantBasedClientAppCredentialsMap = application.get(constants["CACHED_CREDENTIALS"]);
|
||||
if (!cachedTenantBasedClientAppCredentialsMap ||
|
||||
!cachedTenantBasedClientAppCredentialsMap[tenantDomain]) {
|
||||
return null;
|
||||
} else {
|
||||
return cachedTenantBasedClientAppCredentialsMap[tenantDomain];
|
||||
}
|
||||
};
|
||||
|
||||
publicMethods["getTokenPairByPasswordGrantType"] = function (username, password, encodedClientAppCredentials, scopes) {
|
||||
if (!username || !password || !encodedClientAppCredentials || !scopes) {
|
||||
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving access token by password " +
|
||||
"grant type. No username, password, encoded client app credentials or scopes are " +
|
||||
"found - getTokenPairByPasswordGrantType(a, b, c, d)");
|
||||
return null;
|
||||
} else {
|
||||
// calling oauth provider token service endpoint
|
||||
var requestURL = deviceMgtProps["oauthProvider"]["tokenServiceURL"];
|
||||
var requestPayload = "grant_type=password&username=" +
|
||||
username + "&password=" + password + "&scope=" + scopes;
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", requestURL, false);
|
||||
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||
xhr.setRequestHeader("Authorization", "Basic " + encodedClientAppCredentials);
|
||||
xhr.send(requestPayload);
|
||||
|
||||
if (xhr["status"] == 200 && xhr["responseText"]) {
|
||||
var responsePayload = parse(xhr["responseText"]);
|
||||
var tokenData = {};
|
||||
tokenData["accessToken"] = responsePayload["access_token"];
|
||||
tokenData["refreshToken"] = responsePayload["refresh_token"];
|
||||
tokenData["scopes"] = responsePayload["scope"];
|
||||
return tokenData;
|
||||
} else {
|
||||
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving access token " +
|
||||
"by password grant type - getTokenPairByPasswordGrantType(a, b, c, d)");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
publicMethods["getTokenPairBySAMLGrantType"] = function (assertion, encodedClientAppCredentials, scopes) {
|
||||
if (!assertion || !encodedClientAppCredentials || !scopes) {
|
||||
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving access token by saml " +
|
||||
"grant type. No assertion, encoded client app credentials or scopes are " +
|
||||
"found - getTokenPairBySAMLGrantType(x, y, z)");
|
||||
return null;
|
||||
} else {
|
||||
var assertionXML = publicMethods.decode(assertion);
|
||||
/*
|
||||
TODO: make assertion extraction with proper parsing.
|
||||
Since Jaggery XML parser seem to add formatting which causes signature verification to fail.
|
||||
*/
|
||||
var assertionStartMarker = "<saml2:Assertion";
|
||||
var assertionEndMarker = "<\/saml2:Assertion>";
|
||||
var assertionStartIndex = assertionXML.indexOf(assertionStartMarker);
|
||||
var assertionEndIndex = assertionXML.indexOf(assertionEndMarker);
|
||||
|
||||
var extractedAssertion;
|
||||
if (assertionStartIndex == -1 || assertionEndIndex == -1) {
|
||||
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving access " +
|
||||
"token by saml grant type. Issue in assertion format - getTokenPairBySAMLGrantType(x, y, z)");
|
||||
return null;
|
||||
} else {
|
||||
extractedAssertion = assertionXML.
|
||||
substring(assertionStartIndex, assertionEndIndex) + assertionEndMarker;
|
||||
var encodedAssertion = publicMethods.encode(extractedAssertion);
|
||||
|
||||
// calling oauth provider token service endpoint
|
||||
var requestURL = deviceMgtProps["oauthProvider"]["tokenServiceURL"];
|
||||
var requestPayload = "grant_type=urn:ietf:params:oauth:grant-type:saml2-bearer&" +
|
||||
"assertion=" + encodeURIComponent(encodedAssertion) + "&scope=" + scopes;
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", requestURL, false);
|
||||
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||
xhr.setRequestHeader("Authorization", "Basic " + encodedClientAppCredentials);
|
||||
xhr.send(requestPayload);
|
||||
|
||||
if (xhr["status"] == 200 && xhr["responseText"]) {
|
||||
var responsePayload = parse(xhr["responseText"]);
|
||||
var tokenData = {};
|
||||
tokenData["accessToken"] = responsePayload["access_token"];
|
||||
tokenData["refreshToken"] = responsePayload["refresh_token"];
|
||||
tokenData["scopes"] = responsePayload["scope"];
|
||||
return tokenData;
|
||||
} else {
|
||||
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving access token " +
|
||||
"by password grant type - getTokenPairBySAMLGrantType(x, y, z)");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
publicMethods["getNewTokenPairByRefreshToken"] = function (refreshToken, encodedClientAppCredentials, scopes) {
|
||||
if (!refreshToken || !encodedClientAppCredentials) {
|
||||
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving new access token " +
|
||||
"by current refresh token. No refresh token or encoded client app credentials are " +
|
||||
"found - getNewTokenPairByRefreshToken(x, y, z)");
|
||||
return null;
|
||||
} else {
|
||||
var requestURL = deviceMgtProps["oauthProvider"]["tokenServiceURL"];
|
||||
var requestPayload = "grant_type=refresh_token&refresh_token=" + refreshToken;
|
||||
if (scopes) {
|
||||
requestPayload = requestPayload + "&scope=" + scopes;
|
||||
}
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", requestURL, false);
|
||||
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||
xhr.setRequestHeader("Authorization", "Basic " + encodedClientAppCredentials);
|
||||
xhr.send(requestPayload);
|
||||
|
||||
if (xhr["status"] == 200 && xhr["responseText"]) {
|
||||
var responsePayload = parse(xhr["responseText"]);
|
||||
var tokenPair = {};
|
||||
tokenPair["accessToken"] = responsePayload["access_token"];
|
||||
tokenPair["refreshToken"] = responsePayload["refresh_token"];
|
||||
return tokenPair;
|
||||
} else {
|
||||
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving new access token by " +
|
||||
"current refresh token - getNewTokenPairByRefreshToken(x, y, z)");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
publicMethods["getAccessTokenByJWTGrantType"] = function (clientAppCredentials) {
|
||||
if (!clientAppCredentials) {
|
||||
log.error("{/app/modules/oauth/token-handler-utils.js} Error in retrieving new access token " +
|
||||
"by current refresh token. No client app credentials are found " +
|
||||
"as input - getAccessTokenByJWTGrantType(x)");
|
||||
return null;
|
||||
} else {
|
||||
var JWTClientManagerServicePackagePath =
|
||||
"org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService";
|
||||
//noinspection JSUnresolvedFunction, JSUnresolvedVariable
|
||||
var JWTClientManagerService = carbon.server.osgiService(JWTClientManagerServicePackagePath);
|
||||
//noinspection JSUnresolvedFunction
|
||||
var jwtClient = JWTClientManagerService.getJWTClient();
|
||||
// returning access token by JWT grant type
|
||||
return jwtClient.getAccessToken(clientAppCredentials["clientId"], clientAppCredentials["clientSecret"],
|
||||
deviceMgtProps["oauthProvider"]["appRegistration"]["owner"], null)["accessToken"];
|
||||
}
|
||||
};
|
||||
|
||||
return publicMethods;
|
||||
}();
|
||||
@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* -----------------------------------------------------
|
||||
* Following module includes handlers
|
||||
* at Jaggery Layer for handling OAuth tokens.
|
||||
* -----------------------------------------------------
|
||||
*/
|
||||
var handlers = function () {
|
||||
var log = new Log("/app/modules/oauth/token-handlers.js");
|
||||
|
||||
var tokenUtil = require("/app/modules/oauth/token-handler-utils.js")["utils"];
|
||||
var constants = require("/app/modules/constants.js");
|
||||
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
|
||||
var publicMethods = {};
|
||||
var privateMethods = {};
|
||||
|
||||
publicMethods["setupTokenPairByPasswordGrantType"] = function (username, password) {
|
||||
if (!username || !password) {
|
||||
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up access token pair by " +
|
||||
"password grant type. Either username of logged in user, password or both are missing " +
|
||||
"as input - setupTokenPairByPasswordGrantType(x, y)");
|
||||
} else {
|
||||
privateMethods.setUpEncodedTenantBasedClientAppCredentials(username);
|
||||
var encodedClientAppCredentials = session.get(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS"]);
|
||||
if (!encodedClientAppCredentials) {
|
||||
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up access token pair by " +
|
||||
"password grant type. Encoded client credentials are " +
|
||||
"missing - setupTokenPairByPasswordGrantType(x, y)");
|
||||
} else {
|
||||
var tokenData;
|
||||
// tokenPair will include current access token as well as current refresh token
|
||||
var arrayOfScopes = devicemgtProps["scopes"];
|
||||
var stringOfScopes = "";
|
||||
arrayOfScopes.forEach(function (entry) {
|
||||
stringOfScopes += entry + " ";
|
||||
});
|
||||
tokenData = tokenUtil.
|
||||
getTokenPairByPasswordGrantType(username,
|
||||
encodeURIComponent(password), encodedClientAppCredentials, stringOfScopes);
|
||||
if (!tokenData) {
|
||||
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up " +
|
||||
"token pair by password grant type. Error in token " +
|
||||
"retrieval - setupTokenPairByPasswordGrantType(x, y)");
|
||||
} else {
|
||||
var tokenPair = {};
|
||||
tokenPair["accessToken"] = tokenData["accessToken"];
|
||||
tokenPair["refreshToken"] = tokenData["refreshToken"];
|
||||
// setting up token pair into session context as a string
|
||||
session.put(constants["TOKEN_PAIR"], stringify(tokenPair));
|
||||
|
||||
var scopes = tokenData.scopes.split(" ");
|
||||
// adding allowed scopes to the session
|
||||
session.put(constants["ALLOWED_SCOPES"], scopes);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
publicMethods["setupTokenPairBySamlGrantType"] = function (username, samlToken) {
|
||||
if (!username || !samlToken) {
|
||||
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up access token pair by " +
|
||||
"saml grant type. Either username of logged in user, samlToken or both are missing " +
|
||||
"as input - setupTokenPairByPasswordGrantType(x, y)");
|
||||
} else {
|
||||
privateMethods.setUpEncodedTenantBasedClientAppCredentials(username);
|
||||
var encodedClientAppCredentials = session.get(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS"]);
|
||||
if (!encodedClientAppCredentials) {
|
||||
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up access token pair " +
|
||||
"by saml grant type. Encoded client credentials are " +
|
||||
"missing - setupTokenPairByPasswordGrantType(x, y)");
|
||||
} else {
|
||||
var tokenData;
|
||||
// accessTokenPair will include current access token as well as current refresh token
|
||||
tokenData = tokenUtil.
|
||||
getTokenPairBySAMLGrantType(samlToken, encodedClientAppCredentials, "PRODUCTION");
|
||||
if (!tokenData) {
|
||||
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up token " +
|
||||
"pair by password grant type. Error in token " +
|
||||
"retrieval - setupTokenPairByPasswordGrantType(x, y)");
|
||||
} else {
|
||||
var tokenPair = {};
|
||||
tokenPair["accessToken"] = tokenData["accessToken"];
|
||||
tokenPair["refreshToken"] = tokenData["refreshToken"];
|
||||
// setting up access token pair into session context as a string
|
||||
session.put(constants["TOKEN_PAIR"], stringify(tokenPair));
|
||||
|
||||
var scopes = tokenData.scopes.split(" ");
|
||||
// adding allowed scopes to the session
|
||||
session.put(constants["ALLOWED_SCOPES"], scopes);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
publicMethods["refreshTokenPair"] = function () {
|
||||
var currentTokenPair = parse(session.get(constants["TOKEN_PAIR"]));
|
||||
// currentTokenPair includes current access token as well as current refresh token
|
||||
var encodedClientAppCredentials = session.get(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS"]);
|
||||
if (!currentTokenPair || !encodedClientAppCredentials) {
|
||||
throw new Error("{/app/modules/oauth/token-handlers.js} Error in refreshing tokens. Either the " +
|
||||
"token pair, encoded client app credentials or both input are not found under " +
|
||||
"session context - refreshTokenPair()");
|
||||
} else {
|
||||
var newTokenPair = tokenUtil.
|
||||
getNewTokenPairByRefreshToken(currentTokenPair["refreshToken"], encodedClientAppCredentials);
|
||||
if (!newTokenPair) {
|
||||
log.error("{/app/modules/oauth/token-handlers.js} Error in refreshing token pair. " +
|
||||
"Unable to update session context with new access token pair - refreshTokenPair()");
|
||||
} else {
|
||||
session.put(constants["TOKEN_PAIR"], stringify(newTokenPair));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
privateMethods["setUpEncodedTenantBasedClientAppCredentials"] = function (username) {
|
||||
if (!username) {
|
||||
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up encoded tenant based " +
|
||||
"client credentials to session context. No username of logged in user is found as " +
|
||||
"input - setUpEncodedTenantBasedClientAppCredentials(x)");
|
||||
} else {
|
||||
var dynamicClientAppCredentials = tokenUtil.getDynamicClientAppCredentials();
|
||||
if (!dynamicClientAppCredentials) {
|
||||
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up encoded tenant based " +
|
||||
"client credentials to session context as the server is unable to obtain " +
|
||||
"dynamic client credentials - setUpEncodedTenantBasedClientAppCredentials(x)");
|
||||
} else {
|
||||
var jwtToken = tokenUtil.getAccessTokenByJWTGrantType(dynamicClientAppCredentials);
|
||||
if (!jwtToken) {
|
||||
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up encoded tenant based " +
|
||||
"client credentials to session context as the server is unable to obtain " +
|
||||
"a jwt token - setUpEncodedTenantBasedClientAppCredentials(x)");
|
||||
} else {
|
||||
var tenantBasedClientAppCredentials = tokenUtil.
|
||||
getTenantBasedClientAppCredentials(username, jwtToken);
|
||||
if (!tenantBasedClientAppCredentials) {
|
||||
throw new Error("{/app/modules/oauth/token-handlers.js} Could not set up encoded tenant " +
|
||||
"based client credentials to session context as the server is unable " +
|
||||
"to obtain such credentials - setUpEncodedTenantBasedClientAppCredentials(x)");
|
||||
} else {
|
||||
var encodedTenantBasedClientAppCredentials =
|
||||
tokenUtil.encode(tenantBasedClientAppCredentials["clientId"] + ":" +
|
||||
tenantBasedClientAppCredentials["clientSecret"]);
|
||||
// setting up encoded tenant based client credentials to session context.
|
||||
session.put(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS"],
|
||||
encodedTenantBasedClientAppCredentials);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return publicMethods;
|
||||
}();
|
||||
@ -0,0 +1,376 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* ----------------------------------------------------------------------------
|
||||
* Following module includes invokers
|
||||
* at Jaggery Layer for calling Backend Services, protected by OAuth Tokens.
|
||||
* These Services include both REST and SOAP Services.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
var invokers = function () {
|
||||
var log = new Log("/app/modules/oauth/token-protected-service-invokers.js");
|
||||
|
||||
var publicXMLHTTPInvokers = {};
|
||||
var publicHTTPClientInvokers = {};
|
||||
|
||||
var privateMethods = {};
|
||||
var publicWSInvokers = {};
|
||||
|
||||
var TOKEN_EXPIRED = "Access token expired";
|
||||
var TOKEN_INVALID = "Invalid input. Access token validation failed";
|
||||
|
||||
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
var constants = require("/app/modules/constants.js");
|
||||
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
|
||||
var tokenUtil = require("/app/modules/oauth/token-handlers.js")["handlers"];
|
||||
|
||||
/**
|
||||
* This method reads the token pair from the session and return the access token.
|
||||
* If the token pair is not set in the session, this will return null.
|
||||
*/
|
||||
privateMethods.getAccessToken = function () {
|
||||
var tokenPair = parse(session.get(constants["TOKEN_PAIR"]));
|
||||
if (tokenPair) {
|
||||
return tokenPair["accessToken"];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* ---------------------------------------------------------------------------
|
||||
* Start of XML-HTTP-REQUEST based Interceptor implementations
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* This method add Oauth authentication header to outgoing XML-HTTP Requests if Oauth authentication is enabled.
|
||||
* @param httpMethod HTTP request type.
|
||||
* @param requestPayload payload/data if exists which is needed to be send.
|
||||
* @param endpoint Backend REST API url.
|
||||
* @param responseCallback a function to be called with response retrieved.
|
||||
* @param count a counter which hold the number of recursive execution
|
||||
*/
|
||||
privateMethods["execute"] = function (httpMethod, requestPayload, endpoint, responseCallback, count) {
|
||||
var xmlHttpRequest = new XMLHttpRequest();
|
||||
|
||||
xmlHttpRequest.open(httpMethod, endpoint);
|
||||
xmlHttpRequest.setRequestHeader(constants["CONTENT_TYPE_IDENTIFIER"], constants["APPLICATION_JSON"]);
|
||||
xmlHttpRequest.setRequestHeader(constants["ACCEPT_IDENTIFIER"], constants["APPLICATION_JSON"]);
|
||||
|
||||
if (devicemgtProps["isOAuthEnabled"]) {
|
||||
var accessToken = privateMethods.getAccessToken();
|
||||
if (!accessToken) {
|
||||
userModule.logout(function () {
|
||||
response.sendRedirect(devicemgtProps["appContext"] + "login");
|
||||
});
|
||||
} else {
|
||||
xmlHttpRequest.setRequestHeader(constants["AUTHORIZATION_HEADER"],
|
||||
constants["BEARER_PREFIX"] + accessToken);
|
||||
}
|
||||
}
|
||||
|
||||
if (requestPayload) {
|
||||
xmlHttpRequest.send(requestPayload);
|
||||
} else {
|
||||
xmlHttpRequest.send();
|
||||
}
|
||||
|
||||
log.debug("Request : " + httpMethod + " " + endpoint);
|
||||
log.debug("Request payload if any : " + stringify(requestPayload));
|
||||
log.debug("Response status : " + xmlHttpRequest.status);
|
||||
log.debug("Response payload if any : " + xmlHttpRequest.responseText);
|
||||
|
||||
if (xmlHttpRequest.status == 401 && (xmlHttpRequest.responseText == TOKEN_EXPIRED ||
|
||||
xmlHttpRequest.responseText == TOKEN_INVALID ) && count < 5) {
|
||||
tokenUtil.refreshTokenPair();
|
||||
return privateMethods.execute(httpMethod, requestPayload, endpoint, responseCallback, ++count);
|
||||
} else {
|
||||
return responseCallback(xmlHttpRequest);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This method add Oauth authentication header to outgoing XML-HTTP Requests if Oauth authentication is enabled.
|
||||
* @param httpMethod HTTP request type.
|
||||
* @param requestPayload payload/data if exists which is needed to be send.
|
||||
* @param endpoint Backend REST API url.
|
||||
* @param responseCallback a function to be called with response retrieved.
|
||||
*/
|
||||
privateMethods["initiateXMLHTTPRequest"] = function (httpMethod, requestPayload, endpoint, responseCallback) {
|
||||
return privateMethods.execute(httpMethod, requestPayload, endpoint, responseCallback, 0);
|
||||
};
|
||||
|
||||
/**
|
||||
* This method invokes return initiateXMLHttpRequest for get calls.
|
||||
* @param endpoint Backend REST API url.
|
||||
* @param responseCallback a function to be called with response retrieved.
|
||||
*/
|
||||
publicXMLHTTPInvokers["get"] = function (endpoint, responseCallback) {
|
||||
var requestPayload = null;
|
||||
return privateMethods.initiateXMLHTTPRequest(constants["HTTP_GET"], requestPayload, endpoint, responseCallback);
|
||||
};
|
||||
|
||||
/**
|
||||
* This method invokes return initiateXMLHttpRequest for post calls.
|
||||
* @param endpoint Backend REST API url.
|
||||
* @param requestPayload payload/data if exists which is needed to be send.
|
||||
* @param responseCallback a function to be called with response retrieved.
|
||||
*/
|
||||
publicXMLHTTPInvokers["post"] = function (endpoint, requestPayload, responseCallback) {
|
||||
return privateMethods.initiateXMLHTTPRequest(constants["HTTP_POST"], requestPayload, endpoint, responseCallback);
|
||||
};
|
||||
|
||||
/**
|
||||
* This method invokes return initiateXMLHttpRequest for put calls.
|
||||
* @param endpoint Backend REST API url.
|
||||
* @param requestPayload payload/data if exists which is needed to be send.
|
||||
* @param responseCallback a function to be called with response retrieved.
|
||||
*/
|
||||
publicXMLHTTPInvokers["put"] = function (endpoint, requestPayload, responseCallback) {
|
||||
return privateMethods.initiateXMLHTTPRequest(constants["HTTP_PUT"], requestPayload, endpoint, responseCallback);
|
||||
};
|
||||
|
||||
/**
|
||||
* This method invokes return initiateXMLHttpRequest for delete calls.
|
||||
* @param endpoint Backend REST API url.
|
||||
* @param responseCallback a function to be called with response retrieved.
|
||||
*/
|
||||
publicXMLHTTPInvokers["delete"] = function (endpoint, responseCallback) {
|
||||
var requestPayload = null;
|
||||
return privateMethods.initiateXMLHTTPRequest(constants["HTTP_DELETE"], requestPayload, endpoint, responseCallback);
|
||||
};
|
||||
|
||||
/**
|
||||
* ---------------------------------------------------------------------------
|
||||
* Start of WS-REQUEST based Interceptor implementations
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* This method add Oauth authentication header to outgoing WS Requests if Oauth authentication is enabled.
|
||||
* @param action
|
||||
* @param endpoint service end point to be triggered.
|
||||
* @param payload soap payload which need to be send.
|
||||
* @param successCallback a function to be called if the respond if successful.
|
||||
* @param errorCallback a function to be called if en error is reserved.
|
||||
* @param soapVersion soapVersion which need to used.
|
||||
*/
|
||||
privateMethods["initiateWSRequest"] = function (action, endpoint, successCallback,
|
||||
errorCallback, soapVersion, payload) {
|
||||
var ws = require("ws");
|
||||
//noinspection JSUnresolvedFunction
|
||||
var wsRequest = new ws.WSRequest();
|
||||
var options = [];
|
||||
if (devicemgtProps["isOAuthEnabled"]) {
|
||||
var accessToken = privateMethods.getAccessToken();
|
||||
if (accessToken) {
|
||||
var authenticationHeaderName = String(constants["AUTHORIZATION_HEADER"]);
|
||||
var authenticationHeaderValue = String(constants["BEARER_PREFIX"] + accessToken);
|
||||
var headers = [];
|
||||
var oAuthAuthenticationData = {};
|
||||
oAuthAuthenticationData.name = authenticationHeaderName;
|
||||
oAuthAuthenticationData.value = authenticationHeaderValue;
|
||||
headers.push(oAuthAuthenticationData);
|
||||
options.HTTPHeaders = headers;
|
||||
} else {
|
||||
response.sendRedirect(devicemgtProps["appContext"] + "login");
|
||||
}
|
||||
}
|
||||
options.useSOAP = soapVersion;
|
||||
options.useWSA = constants["WEB_SERVICE_ADDRESSING_VERSION"];
|
||||
options.action = action;
|
||||
var wsResponse;
|
||||
try {
|
||||
wsRequest.open(options, endpoint, false);
|
||||
if (payload) {
|
||||
wsRequest.send(payload);
|
||||
} else {
|
||||
wsRequest.send();
|
||||
}
|
||||
wsResponse = wsRequest.responseE4X;
|
||||
} catch (e) {
|
||||
return errorCallback(e);
|
||||
}
|
||||
return successCallback(wsResponse);
|
||||
};
|
||||
|
||||
/**
|
||||
* This method invokes return initiateWSRequest for soap calls.
|
||||
* @param action describes particular soap action.
|
||||
* @param requestPayload SOAP request payload which is needed to be send.
|
||||
* @param endpoint service end point to be triggered.
|
||||
* @param successCallback a function to be called if the respond if successful.
|
||||
* @param errorCallback a function to be called if en error is reserved.
|
||||
* @param soapVersion soapVersion which need to used.
|
||||
*/
|
||||
publicWSInvokers["soapRequest"] = function (action, requestPayload, endpoint,
|
||||
successCallback, errorCallback, soapVersion) {
|
||||
return privateMethods.initiateWSRequest(action, endpoint, successCallback,
|
||||
errorCallback, soapVersion, requestPayload);
|
||||
};
|
||||
|
||||
/**
|
||||
* ---------------------------------------------------------------------------
|
||||
* Start of HTTP-CLIENT-REQUEST based Interceptor implementations
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* This method add Oauth authentication header to outgoing HTTPClient Requests if Oauth authentication is enabled.
|
||||
* @param method HTTP request type.
|
||||
* @param url target url.
|
||||
* @param payload payload/data which need to be send.
|
||||
* @param successCallback a function to be called if the respond if successful.
|
||||
* @param errorCallback a function to be called if en error is reserved.
|
||||
*/
|
||||
privateMethods["initiateHTTPClientRequest"] = function (method, url, successCallback, errorCallback, payload) {
|
||||
//noinspection JSUnresolvedVariable
|
||||
var HttpClient = Packages.org.apache.commons.httpclient.HttpClient;
|
||||
var httpMethodObject;
|
||||
switch (method) {
|
||||
case constants["HTTP_GET"]:
|
||||
//noinspection JSUnresolvedVariable
|
||||
var GetMethod = Packages.org.apache.commons.httpclient.methods.GetMethod;
|
||||
httpMethodObject = new GetMethod(url);
|
||||
break;
|
||||
case constants["HTTP_POST"]:
|
||||
//noinspection JSUnresolvedVariable
|
||||
var PostMethod = Packages.org.apache.commons.httpclient.methods.PostMethod;
|
||||
httpMethodObject = new PostMethod(url);
|
||||
break;
|
||||
case constants["HTTP_PUT"]:
|
||||
//noinspection JSUnresolvedVariable
|
||||
var PutMethod = Packages.org.apache.commons.httpclient.methods.PutMethod;
|
||||
httpMethodObject = new PutMethod(url);
|
||||
break;
|
||||
case constants["HTTP_DELETE"]:
|
||||
//noinspection JSUnresolvedVariable
|
||||
var DeleteMethod = Packages.org.apache.commons.httpclient.methods.DeleteMethod;
|
||||
httpMethodObject = new DeleteMethod(url);
|
||||
break;
|
||||
default:
|
||||
//noinspection JSUnresolvedFunction
|
||||
throw new IllegalArgumentException("Invalid HTTP request method: " + method);
|
||||
}
|
||||
//noinspection JSUnresolvedVariable
|
||||
var Header = Packages.org.apache.commons.httpclient.Header;
|
||||
var header = new Header();
|
||||
header.setName(constants["CONTENT_TYPE_IDENTIFIER"]);
|
||||
header.setValue(constants["APPLICATION_JSON"]);
|
||||
//noinspection JSUnresolvedFunction
|
||||
httpMethodObject.addRequestHeader(header);
|
||||
header = new Header();
|
||||
header.setName(constants["ACCEPT_IDENTIFIER"]);
|
||||
header.setValue(constants["APPLICATION_JSON"]);
|
||||
//noinspection JSUnresolvedFunction
|
||||
httpMethodObject.addRequestHeader(header);
|
||||
|
||||
if (devicemgtProps["isOAuthEnabled"]) {
|
||||
var accessToken = privateMethods.getAccessToken();
|
||||
if (accessToken) {
|
||||
header = new Header();
|
||||
header.setName(constants["AUTHORIZATION_HEADER"]);
|
||||
header.setValue(constants["BEARER_PREFIX"] + accessToken);
|
||||
//noinspection JSUnresolvedFunction
|
||||
httpMethodObject.addRequestHeader(header);
|
||||
} else {
|
||||
response.sendRedirect(devicemgtProps["appContext"] + "login");
|
||||
}
|
||||
}
|
||||
//noinspection JSUnresolvedFunction
|
||||
var stringRequestEntity = new StringRequestEntity(stringify(payload));
|
||||
//noinspection JSUnresolvedFunction
|
||||
httpMethodObject.setRequestEntity(stringRequestEntity);
|
||||
var client = new HttpClient();
|
||||
try {
|
||||
//noinspection JSUnresolvedFunction
|
||||
client.executeMethod(httpMethodObject);
|
||||
//noinspection JSUnresolvedFunction
|
||||
var status = httpMethodObject.getStatusCode();
|
||||
if (status == 200) {
|
||||
//noinspection JSUnresolvedFunction
|
||||
return successCallback(httpMethodObject.getResponseBody());
|
||||
} else {
|
||||
//noinspection JSUnresolvedFunction
|
||||
return errorCallback(httpMethodObject.getResponseBody());
|
||||
}
|
||||
} catch (e) {
|
||||
return errorCallback(response);
|
||||
} finally {
|
||||
//noinspection JSUnresolvedFunction
|
||||
method.releaseConnection();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This method invokes return initiateHTTPClientRequest for get calls.
|
||||
* @param url target url.
|
||||
* @param successCallback a function to be called if the respond if successful.
|
||||
* @param errorCallback a function to be called if en error is reserved.
|
||||
*/
|
||||
publicHTTPClientInvokers["get"] = function (url, successCallback, errorCallback) {
|
||||
var requestPayload = null;
|
||||
return privateMethods.
|
||||
initiateHTTPClientRequest(constants["HTTP_GET"], url, successCallback, errorCallback, requestPayload);
|
||||
};
|
||||
|
||||
/**
|
||||
* This method invokes return initiateHTTPClientRequest for post calls.
|
||||
* @param url target url.
|
||||
* @param payload payload/data which need to be send.
|
||||
* @param successCallback a function to be called if the respond if successful.
|
||||
* @param errorCallback a function to be called if en error is reserved.
|
||||
*/
|
||||
publicHTTPClientInvokers["post"] = function (url, payload, successCallback, errorCallback) {
|
||||
return privateMethods.
|
||||
initiateHTTPClientRequest(constants["HTTP_POST"], url, successCallback, errorCallback, payload);
|
||||
};
|
||||
|
||||
/**
|
||||
* This method invokes return initiateHTTPClientRequest for put calls.
|
||||
* @param url target url.
|
||||
* @param payload payload/data which need to be send.
|
||||
* @param successCallback a function to be called if the respond if successful.
|
||||
* @param errorCallback a function to be called if en error is reserved.
|
||||
*/
|
||||
publicHTTPClientInvokers["put"] = function (url, payload, successCallback, errorCallback) {
|
||||
return privateMethods.
|
||||
initiateHTTPClientRequest(constants["HTTP_PUT"], url, successCallback, errorCallback, payload);
|
||||
};
|
||||
|
||||
/**
|
||||
* This method invokes return initiateHTTPClientRequest for delete calls.
|
||||
* @param url target url.
|
||||
* @param successCallback a function to be called if the respond if successful.
|
||||
* @param errorCallback a function to be called if en error is reserved.
|
||||
*/
|
||||
publicHTTPClientInvokers["delete"] = function (url, successCallback, errorCallback) {
|
||||
var requestPayload = null;
|
||||
return privateMethods.
|
||||
initiateHTTPClientRequest(constants["HTTP_DELETE"], url, successCallback, errorCallback, requestPayload);
|
||||
};
|
||||
|
||||
var publicMethods = {};
|
||||
publicMethods.XMLHttp = publicXMLHTTPInvokers;
|
||||
publicMethods.WS = publicWSInvokers;
|
||||
publicMethods.HttpClient = publicHTTPClientInvokers;
|
||||
|
||||
return publicMethods;
|
||||
}();
|
||||
File diff suppressed because one or more lines are too long
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
var utility;
|
||||
utility = function () {
|
||||
|
||||
var constants = require('/app/modules/constants.js');
|
||||
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
var log = new Log("/app/modules/utility.js");
|
||||
var JavaClass = Packages.java.lang.Class;
|
||||
var PrivilegedCarbonContext = Packages.org.wso2.carbon.context.PrivilegedCarbonContext;
|
||||
|
||||
var getOsgiService = function (className) {
|
||||
return PrivilegedCarbonContext.getThreadLocalCarbonContext().getOSGiService(JavaClass.forName(className));
|
||||
};
|
||||
|
||||
var deviceTypeConfigMap = {};
|
||||
|
||||
var publicMethods = {};
|
||||
|
||||
publicMethods.startTenantFlow = function (userInfo) {
|
||||
var context, carbon = require('carbon');
|
||||
PrivilegedCarbonContext.startTenantFlow();
|
||||
context = PrivilegedCarbonContext.getThreadLocalCarbonContext();
|
||||
context.setTenantDomain(carbon.server.tenantDomain({
|
||||
tenantId: userInfo.tenantId
|
||||
}));
|
||||
context.setTenantId(userInfo.tenantId);
|
||||
context.setUsername(userInfo.username || null);
|
||||
};
|
||||
|
||||
publicMethods.endTenantFlow = function () {
|
||||
PrivilegedCarbonContext.endTenantFlow();
|
||||
};
|
||||
|
||||
publicMethods.getDeviceManagementService = function () {
|
||||
return getOsgiService('org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService');
|
||||
};
|
||||
|
||||
publicMethods.getUserManagementService = function () {
|
||||
return getOsgiService("org.wso2.carbon.device.mgt.user.core.UserManager");
|
||||
};
|
||||
|
||||
publicMethods.getPolicyManagementService = function () {
|
||||
return getOsgiService("org.wso2.carbon.policy.mgt.core.PolicyManagerService");
|
||||
};
|
||||
|
||||
publicMethods.getIoTServerConfig = function (configName) {
|
||||
var path = "/config/iot-config.json";
|
||||
var file = new File(path);
|
||||
try {
|
||||
file.open("r");
|
||||
var content = file.readAll();
|
||||
} catch (err) {
|
||||
log.error("Error while reading IoT server config file `" + path + "`: " + err);
|
||||
} finally {
|
||||
file.close();
|
||||
}
|
||||
var json = parse(content);
|
||||
return json[configName];
|
||||
};
|
||||
|
||||
publicMethods.getDeviceTypeConfig = function (deviceType) {
|
||||
var unitName = publicMethods.getTenantedDeviceUnitName(deviceType, "type-view");
|
||||
|
||||
if (deviceType in deviceTypeConfigMap) {
|
||||
return deviceTypeConfigMap[deviceType];
|
||||
}
|
||||
var deviceTypeConfig;
|
||||
var deviceTypeConfigFile = new File("/app/units/" + unitName + "/private/config.json");
|
||||
if (deviceTypeConfigFile.isExists()) {
|
||||
try {
|
||||
deviceTypeConfigFile.open("r");
|
||||
deviceTypeConfig = parse(deviceTypeConfigFile.readAll());
|
||||
} catch (err) {
|
||||
log.error("Error while reading device config file for `" + deviceType + "`: " + err);
|
||||
} finally {
|
||||
deviceTypeConfigFile.close();
|
||||
}
|
||||
}
|
||||
deviceTypeConfigMap[deviceType] = deviceTypeConfig;
|
||||
return deviceTypeConfig;
|
||||
};
|
||||
|
||||
publicMethods.getOperationIcon = function (deviceType, operation) {
|
||||
var unitName = publicMethods.getTenantedDeviceUnitName(deviceType, "type-view");
|
||||
var iconPath = "/app/units/" + unitName + "/public/images/operations/" + operation + ".png";
|
||||
var icon = new File(iconPath);
|
||||
if (icon.isExists()) {
|
||||
return devicemgtProps["appContext"] + "public/" + unitName + "/images/operations/" + operation + ".png";
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
publicMethods.getDeviceThumb = function (deviceType) {
|
||||
var unitName = publicMethods.getTenantedDeviceUnitName(deviceType, "type-view");
|
||||
var iconPath = "/app/units/" + unitName + "/public/images/thumb.png";
|
||||
var icon = new File(iconPath);
|
||||
if (icon.isExists()) {
|
||||
return devicemgtProps["appContext"] + "public/" + unitName + "/images/thumb.png";
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
publicMethods.getTenantedDeviceUnitName = function (deviceType, unitPostfix) {
|
||||
var user = session.get(constants.USER_SESSION_KEY);
|
||||
if (!user) {
|
||||
log.error("User object was not found in the session");
|
||||
throw constants.ERRORS.USER_NOT_FOUND;
|
||||
}
|
||||
var unitName = user.domain + ".cdmf.unit.device.type." + deviceType + "." + unitPostfix;
|
||||
if (new File("/app/units/" + unitName).isExists()) {
|
||||
return unitName;
|
||||
}
|
||||
unitName = "cdmf.unit.device.type." + deviceType + "." + unitPostfix;
|
||||
if (new File("/app/units/" + unitName).isExists()) {
|
||||
return unitName;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
return publicMethods;
|
||||
}();
|
||||
@ -0,0 +1,47 @@
|
||||
{{!-- Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
|
||||
WSO2 Inc. 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. --}}
|
||||
|
||||
{{!-- defining controlled access parameters --}}
|
||||
{{#zone "accessControl"}}
|
||||
{{
|
||||
unit "mdm.unit.enrollments.access-control"
|
||||
allowedPlatform = "Android"
|
||||
currentPage = "download-agent"
|
||||
}}
|
||||
{{/zone}}
|
||||
{{!-- Inputting content into defined zones in enrollment layout --}}
|
||||
{{unit "mdm.unit.ui.title" pageTitle = "Android Enrollment | Download and Install Agent"}}
|
||||
{{#zone "headerTitle"}}
|
||||
Android Enrollment
|
||||
{{/zone}}
|
||||
|
||||
{{#zone "content"}}
|
||||
{{
|
||||
unit "mdm.unit.wizard-stepper"
|
||||
steps = "Download and Install Agent"
|
||||
currentStep = "Download and Install Agent"
|
||||
currentStepIndex = 0
|
||||
}}
|
||||
<div class="row">
|
||||
<div class="container col-md-4 wr-text">
|
||||
If you have not already enrolled this device with {{companyName}},
|
||||
Download and install following EMM Agent to continue.
|
||||
<div class="wr-buttons">
|
||||
<a href="{{agentDownloadURL}}" class="btn-download-agent">Download EMM Agent</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/zone}}
|
||||
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
function onRequest(context) {
|
||||
var log = new Log("mdm.page.enrollments.android.agent.download");
|
||||
|
||||
var mdmProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
var viewModel = {};
|
||||
|
||||
// setting android agent download URL
|
||||
viewModel.agentDownloadURL = context.page.publicUri + "/asset/" + mdmProps["androidAgentApp"];
|
||||
var companyProps = session.get("COMPANY_DETAILS");
|
||||
if (!companyProps) {
|
||||
viewModel.companyName = mdmProps.generalConfig.companyName;
|
||||
} else {
|
||||
viewModel.companyName = companyProps.companyName;
|
||||
}
|
||||
return viewModel;
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"uri": "/enrollments/android/download-agent",
|
||||
"layout": "mdm.layout.enrollment",
|
||||
"isAnonymous": true
|
||||
}
|
||||
Binary file not shown.
@ -0,0 +1,17 @@
|
||||
{{!-- Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
|
||||
WSO2 Inc. 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. --}}
|
||||
|
||||
{{!-- This page will route into relevant download url based on User-Agent --}}
|
||||
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
function onRequest(context) {
|
||||
var log = new Log("mdm.page.enrollments.default");
|
||||
var UAParser = require("/app/modules/ua-parser.min.js")["UAParser"];
|
||||
|
||||
var parser = new UAParser();
|
||||
var userAgent = request.getHeader("User-Agent");
|
||||
parser.setUA(userAgent);
|
||||
parser.getResult();
|
||||
var os = parser.getOS();
|
||||
var platform = os.name;
|
||||
|
||||
if (platform == "Android") {
|
||||
response.sendRedirect(context.app.context + "/enrollments/android/download-agent");
|
||||
} else if (platform == "iOS") {
|
||||
response.sendRedirect(context.app.context + "/enrollments/ios/download-agent");
|
||||
} else if (platform == "Windows Phone") {
|
||||
response.sendRedirect(context.app.context + "/enrollments/windows/invoke-agent");
|
||||
} else {
|
||||
response.sendRedirect(context.app.context + "/enrollments/error/unintentional-request");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"uri": "/enrollment",
|
||||
"layout": "mdm.layout.enrollment",
|
||||
"isAnonymous": true
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
{{!-- Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
|
||||
WSO2 Inc. 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. --}}
|
||||
|
||||
{{!-- Inputting content into defined zones in enrollment layout --}}
|
||||
{{unit "mdm.unit.ui.title" pageTitle="Device Enrollment"}}
|
||||
{{#zone "headerTitle"}}
|
||||
Unintentional Request
|
||||
{{/zone}}
|
||||
{{#zone "content"}}
|
||||
<div class="wr-head">
|
||||
<h3>Possible Causes :</h3>
|
||||
</div>
|
||||
[1] You have tried making a request call intended to be made by a different Platform. <br />
|
||||
[2] You have tried accessing enrollment steps out of order. <br />
|
||||
<div class="row">
|
||||
<div class="container col-md-4 wr-buttons">
|
||||
<a href="{{@app.context}}/enrollment" class="btn-download-agent">Redirect</a>
|
||||
</div>
|
||||
</div>
|
||||
{{/zone}}
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"uri": "/enrollments/error/unintentional-request",
|
||||
"layout": "mdm.layout.enrollment",
|
||||
"isAnonymous": true
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
{{!-- Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
|
||||
WSO2 Inc. 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. --}}
|
||||
|
||||
{{!-- Inputting content into defined zones in enrollment layout --}}
|
||||
{{unit "mdm.unit.ui.title" pageTitle="iOS Enrollment | Certificate Download Failure"}}
|
||||
{{#zone "headerTitle"}}
|
||||
iOS Certificate Download Failure
|
||||
{{/zone}}
|
||||
{{#zone "content"}}
|
||||
<div class="wr-head">
|
||||
<h3>Possible Causes :</h3>
|
||||
</div>
|
||||
[1] Network Issue. <br/>
|
||||
[2] Bad Request Call to Server. <br/>
|
||||
[3] Internal Server Error. <br/>
|
||||
<div class="row">
|
||||
<div class="container col-md-4 wr-buttons">
|
||||
<a href="{{@app.context}}/enrollment" class="btn-download-agent">Redirect</a>
|
||||
</div>
|
||||
</div>
|
||||
{{/zone}}
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"uri": "/enrollments/error/ios/certificate-download-failure",
|
||||
"layout": "mdm.layout.enrollment",
|
||||
"isAnonymous": true
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
{{!-- Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
|
||||
WSO2 Inc. 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. --}}
|
||||
|
||||
{{!-- defining controlled access parameters --}}
|
||||
{{#zone "accessControl"}}
|
||||
{{
|
||||
unit "mdm.unit.enrollments.access-control"
|
||||
allowedPlatform = "iOS"
|
||||
currentPage = "download-agent"
|
||||
nextPage = "login-agent"
|
||||
}}
|
||||
{{/zone}}
|
||||
{{!-- Inputting content into defined zones in enrollment layout --}}
|
||||
{{unit "mdm.unit.ui.title" pageTitle="iOS Enrollment | Install Certificate and Agent"}}
|
||||
{{#zone "headerTitle"}}
|
||||
iOS Enrollment
|
||||
{{/zone}}
|
||||
{{#zone "content"}}
|
||||
{{
|
||||
unit "mdm.unit.wizard-stepper"
|
||||
steps = "Install Certificate and Agent,
|
||||
Login to Enterprise Mobility Manager,
|
||||
Accept End User License Agreement"
|
||||
currentStep = "Install Certificate and Agent"
|
||||
currentStepIndex = 0
|
||||
}}
|
||||
<div class="row">
|
||||
<div class="container col-md-4 wr-text">
|
||||
If you have not already enrolled this device with {{companyName}},
|
||||
Install following EMM Certificate and Agent to continue.
|
||||
<div class="wr-buttons">
|
||||
<a href="{{emmCertificateDownloadURL}}" class="btn-download-agent">Install EMM Certificate</a>
|
||||
</div>
|
||||
<br class="c-both" />
|
||||
Also note : EMM certificate should be first installed on the device for a
|
||||
successful installation of the agent.
|
||||
<div class="wr-buttons">
|
||||
<a href="{{agentDownloadURL}}" class="btn-download-agent">Install EMM Agent</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/zone}}
|
||||
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
function onRequest(context) {
|
||||
var log = new Log("asset-download-agent-ios-unit");
|
||||
log.debug("calling asset-download-agent-ios-unit backend js");
|
||||
|
||||
var mdmProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
var viewModel = {};
|
||||
// setting iOS certificate download URL
|
||||
viewModel.emmCertificateDownloadURL = context.app.context + "/enrollment/ios/download-certificate";
|
||||
// setting iOS agent download URL
|
||||
viewModel.agentDownloadURL = "itms-services://?action=download-manifest&url=" +
|
||||
mdmProps["httpsURL"] + context.app.context + "/enrollment/ios/download-agent";
|
||||
var companyProps = session.get("COMPANY_DETAILS");
|
||||
if (!companyProps) {
|
||||
viewModel.companyName = mdmProps.generalConfig.companyName;
|
||||
} else {
|
||||
viewModel.companyName = companyProps.companyName;
|
||||
}
|
||||
return viewModel;
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"uri": "/enrollments/ios/download-agent",
|
||||
"layout": "mdm.layout.enrollment",
|
||||
"isAnonymous": true
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
Add the iOS-agent with the name "ios-agent.ipa" into this folder.
|
||||
@ -0,0 +1,59 @@
|
||||
{{!-- Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
|
||||
WSO2 Inc. 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. --}}
|
||||
|
||||
{{!-- defining controlled access parameters --}}
|
||||
{{#zone "accessControl"}}
|
||||
{{
|
||||
unit "mdm.unit.enrollments.access-control"
|
||||
allowedPlatform = "iOS"
|
||||
currentPage = "license-agent"
|
||||
lastPage = "login-agent"
|
||||
nextPage = "thank-you-agent"
|
||||
}}
|
||||
{{/zone}}
|
||||
{{!-- Inputting content into defined zones in enrollment layout --}}
|
||||
{{unit "mdm.unit.ui.title" pageTitle="iOS Enrollment | Accept End User License Agreement"}}
|
||||
|
||||
{{#zone "headerTitle"}}
|
||||
iOS Enrollment
|
||||
{{/zone}}
|
||||
|
||||
{{#zone "content"}}
|
||||
{{
|
||||
unit "mdm.unit.wizard-stepper"
|
||||
steps = "Install Certificate and Agent,
|
||||
Login to Enterprise Mobility Manager,
|
||||
Accept End User License Agreement"
|
||||
currentStep = "Accept End User License Agreement"
|
||||
currentStepIndex = 2
|
||||
}}
|
||||
{{
|
||||
unit "mdm.unit.enrollments.license-box"
|
||||
platform = "ios"
|
||||
languageCode = "en_US"
|
||||
licenseAcceptActionURL = iosLicenseAcceptURL
|
||||
}}
|
||||
{{/zone}}
|
||||
|
||||
{{#zone "topJs"}}
|
||||
<script type="text/javascript">
|
||||
var contextPath = "{{@app.context}}";
|
||||
</script>
|
||||
{{/zone}}
|
||||
|
||||
{{#zone "bottomJs"}}
|
||||
{{js "/js/enrollment-completion-checker-ios.js"}}
|
||||
{{/zone}}
|
||||
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
function onRequest(context) {
|
||||
var viewModel = {};
|
||||
// setting iOS license download URL
|
||||
viewModel.iosLicenseAcceptURL = context.app.context + "/enrollment/ios/enroll";
|
||||
return viewModel;
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"uri": "/enrollments/ios/license-agent",
|
||||
"layout": "mdm.layout.enrollment",
|
||||
"isAnonymous": true
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
$(document).ready(function () {
|
||||
var iOSCheckUrl = contextPath + "/enrollment/ios/check";
|
||||
setInterval(function () {
|
||||
$.post(iOSCheckUrl, function (data, status) {
|
||||
var parsedData = JSON.parse(data);
|
||||
var deviceId = parsedData["deviceID"];
|
||||
var refreshToken = parsedData["refreshToken"];
|
||||
var accessToken = parsedData["accessToken"];
|
||||
var clientCredentials = parsedData["clientCredentials"];
|
||||
if (deviceId) {
|
||||
window.location = contextPath + "/enrollments/ios/thank-you-agent?device-id=" + encodeURI(deviceId) +
|
||||
"&accessToken=" + encodeURI(accessToken) + "&refreshToken=" + encodeURI(refreshToken)
|
||||
+ "&clientCredentials=" + encodeURI(clientCredentials);
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
});
|
||||
@ -0,0 +1,45 @@
|
||||
{{!-- Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
|
||||
WSO2 Inc. 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. --}}
|
||||
|
||||
{{!-- defining controlled access parameters --}}
|
||||
{{#zone "accessControl"}}
|
||||
{{
|
||||
unit "mdm.unit.enrollments.access-control"
|
||||
allowedPlatform = "iOS"
|
||||
currentPage = "login-agent"
|
||||
lastPage = "download-agent"
|
||||
nextPage = "license-agent"
|
||||
}}
|
||||
{{/zone}}
|
||||
{{!-- Inputting content into defined zones in enrollment layout --}}
|
||||
{{unit "mdm.unit.ui.title" pageTitle="iOS Enrollment | Login to Enterprise Mobility Manager"}}
|
||||
{{#zone "headerTitle"}}
|
||||
iOS Enrollment
|
||||
{{/zone}}
|
||||
{{#zone "content"}}
|
||||
{{
|
||||
unit "mdm.unit.wizard-stepper"
|
||||
steps = "Install Certificate and Agent,
|
||||
Login to Enterprise Mobility Manager,
|
||||
Accept End User License Agreement"
|
||||
currentStep = "Login to Enterprise Mobility Manager"
|
||||
currentStepIndex = 1
|
||||
}}
|
||||
{{
|
||||
unit "mdm.unit.enrollments.login-box"
|
||||
loginActionURL = iosLoginActionURL
|
||||
}}
|
||||
{{/zone}}
|
||||
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
function onRequest(context) {
|
||||
var viewModel = {};
|
||||
// setting iOS login URL
|
||||
viewModel.iosLoginActionURL = context.app.context + "/enrollment/ios/login";
|
||||
return viewModel;
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"uri": "/enrollments/ios/login-agent",
|
||||
"layout": "mdm.layout.enrollment",
|
||||
"isAnonymous": true
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
var getParameterByName = function (name) {
|
||||
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
|
||||
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), results = regex.exec(location.search);
|
||||
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
|
||||
};
|
||||
|
||||
$(document).ready(function () {
|
||||
setTimeout(function () {
|
||||
var deviceID = getParameterByName("device-id");
|
||||
var accessToken = getParameterByName("accessToken");
|
||||
var refreshToken = getParameterByName("refreshToken");
|
||||
var clientCredentials = getParameterByName("clientCredentials");
|
||||
// window.location.href = "wso2agent://" + deviceID;
|
||||
window.location.href = "wso2agent://" + deviceID + "?accessToken=" +
|
||||
accessToken +"&refreshToken=" + refreshToken + "&clientCredentials=" + clientCredentials;
|
||||
}, 1000);
|
||||
});
|
||||
@ -0,0 +1,52 @@
|
||||
{{!-- Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
|
||||
WSO2 Inc. 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. --}}
|
||||
|
||||
{{!-- defining controlled access parameters --}}
|
||||
{{#zone "accessControl"}}
|
||||
{{
|
||||
unit "mdm.unit.enrollments.access-control"
|
||||
allowedPlatform = "iOS"
|
||||
currentPage = "thank-you-agent"
|
||||
lastPage = "license-agent"
|
||||
}}
|
||||
{{/zone}}
|
||||
{{!-- Inputting content into defined zones in enrollment layout --}}
|
||||
{{unit "mdm.unit.ui.title" pageTitle="iOS Enrollment | Success Note"}}
|
||||
{{#zone "headerTitle"}}
|
||||
iOS Enrollment
|
||||
{{/zone}}
|
||||
{{#zone "content"}}
|
||||
<div class="wr-head">
|
||||
<h3>DEVICE ADDED</h3>
|
||||
</div>
|
||||
You have successfully enrolled your iOS device with {{companyName}}.
|
||||
<br class="c-both" />
|
||||
<br class="c-both" />
|
||||
Device Owner : {{deviceOwner}}
|
||||
<br class="c-both" />
|
||||
<br class="c-both" />
|
||||
Changes related to your company device policy will usually be applied
|
||||
on your phone with in the next couple of minutes.
|
||||
<br class="c-both" />
|
||||
<br class="c-both" />
|
||||
Thank You.
|
||||
<br class="c-both" />
|
||||
<a href="{{serverURL}}">{{companyName}}</a>
|
||||
{{/zone}}
|
||||
|
||||
{{#zone "bottomJs"}}
|
||||
{{js "/js/enrollment-success-note-ios.js"}}
|
||||
{{/zone}}
|
||||
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
function onRequest (context) {
|
||||
var viewModel = {};
|
||||
var mdmProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
viewModel.deviceOwner = session.get("enrolledUser");
|
||||
viewModel.serverURL = mdmProps["httpsURL"] + context.app.context;
|
||||
var companyProps = session.get("COMPANY_DETAILS");
|
||||
if (!companyProps) {
|
||||
viewModel.companyName = mdmProps.generalConfig.companyName;
|
||||
} else {
|
||||
viewModel.companyName = companyProps.companyName;
|
||||
}
|
||||
return viewModel;
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"uri": "/enrollments/ios/thank-you-agent",
|
||||
"layout": "mdm.layout.enrollment",
|
||||
"isAnonymous": true
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
{{!-- Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
|
||||
WSO2 Inc. 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. --}}
|
||||
|
||||
{{!-- defining controlled access parameters --}}
|
||||
{{#zone "accessControl"}}
|
||||
{{
|
||||
unit "mdm.unit.enrollments.access-control"
|
||||
allowedPlatform = "Windows Phone"
|
||||
currentPage = "invoke-agent"
|
||||
nextPage = "login-agent"
|
||||
}}
|
||||
{{/zone}}
|
||||
{{!-- Inputting content into defined zones in enrollment layout --}}
|
||||
{{unit "mdm.unit.ui.title" pageTitle="Windows Phone Enrollment | Start Workplace"}}
|
||||
{{#zone "headerTitle"}}
|
||||
Windows Phone Enrollment
|
||||
{{/zone}}
|
||||
{{#zone "content"}}
|
||||
{{
|
||||
unit "mdm.unit.wizard-stepper"
|
||||
steps = "Start Workplace,
|
||||
Login to Enterprise Mobility Manager,
|
||||
Accept End User License Agreement"
|
||||
currentStep = "Start Workplace"
|
||||
currentStepIndex = 0
|
||||
}}
|
||||
Start the Workplace app to continue device enrollment.
|
||||
<br class="c-both" />
|
||||
<br class="c-both" />
|
||||
Setting up a Workplace account with WSO2 Enterprise Mobility Manager
|
||||
will offer you company policies, certificates and apps that help you connect
|
||||
to your business.
|
||||
<br class="c-both" />
|
||||
<br class="c-both" />
|
||||
<div class="row">
|
||||
<div class="container col-md-4 wr-buttons">
|
||||
<a href="ms-settings-workplace://" class="btn-download-agent">Start Workplace</a>
|
||||
</div>
|
||||
</div>
|
||||
{{/zone}}
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"uri": "/enrollments/windows/invoke-agent",
|
||||
"layout": "mdm.layout.enrollment",
|
||||
"isAnonymous": true
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
{{!-- Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
|
||||
WSO2 Inc. 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. --}}
|
||||
|
||||
{{!-- defining controlled access parameters --}}
|
||||
{{#zone "accessControl"}}
|
||||
{{
|
||||
unit "mdm.unit.enrollments.access-control"
|
||||
allowedPlatform = "Windows Phone"
|
||||
currentPage = "license-agent"
|
||||
lastPage = "login-agent"
|
||||
}}
|
||||
{{/zone}}
|
||||
{{!-- Inputting content into defined zones in enrollment layout --}}
|
||||
{{unit "mdm.unit.ui.title" pageTitle="Windows Phone Enrollment | Accept End User License Agreement"}}
|
||||
{{#zone "headerTitle"}}
|
||||
Windows Phone Enrollment
|
||||
{{/zone}}
|
||||
{{#zone "content"}}
|
||||
{{
|
||||
unit "mdm.unit.wizard-stepper"
|
||||
steps = "Start Workplace,
|
||||
Login to Enterprise Mobility Manager,
|
||||
Accept End User License Agreement"
|
||||
currentStep = "Accept End User License Agreement"
|
||||
currentStepIndex = 2
|
||||
}}
|
||||
{{
|
||||
unit "mdm.unit.enrollments.license-box"
|
||||
platform = "windows"
|
||||
languageCode = "en_US"
|
||||
licenseAcceptActionURL = windowsLicenseAcceptURL
|
||||
}}
|
||||
{{/zone}}
|
||||
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
function onRequest(context) {
|
||||
var viewModel = {};
|
||||
// setting iOS license download URL
|
||||
viewModel.windowsLicenseAcceptURL = context.app.context + "/enrollment/windows/enroll";
|
||||
return viewModel;
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"uri": "/enrollments/windows/license-agent",
|
||||
"layout": "mdm.layout.enrollment",
|
||||
"isAnonymous": true
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
{{!-- Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
|
||||
WSO2 Inc. 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. --}}
|
||||
|
||||
{{!-- defining controlled access parameters --}}
|
||||
{{#zone "accessControl"}}
|
||||
{{
|
||||
unit "mdm.unit.enrollments.access-control"
|
||||
allowedPlatform = "Windows Phone"
|
||||
currentPage = "login-agent"
|
||||
lastPage = "invoke-agent"
|
||||
nextPage = "license-agent"
|
||||
}}
|
||||
{{/zone}}
|
||||
{{!-- Inputting content into defined zones in enrollment layout --}}
|
||||
{{unit "mdm.unit.ui.title" pageTitle="Windows Phone Enrollment | Login to Enterprise Mobility Manager"}}
|
||||
{{#zone "headerTitle"}}
|
||||
Windows Phone Enrollment
|
||||
{{/zone}}
|
||||
{{#zone "content"}}
|
||||
{{
|
||||
unit "mdm.unit.wizard-stepper"
|
||||
steps = "Start Workplace,
|
||||
Login to Enterprise Mobility Manager,
|
||||
Accept End User License Agreement"
|
||||
currentStep = "Login to Enterprise Mobility Manager"
|
||||
currentStepIndex = 1
|
||||
}}
|
||||
{{
|
||||
unit "mdm.unit.enrollments.login-box"
|
||||
loginActionURL = windowsLoginActionURL
|
||||
}}
|
||||
{{/zone}}
|
||||
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
function onRequest(context) {
|
||||
var log = new Log("agent-to-web-context-mapper-windows-unit backend js");
|
||||
log.debug("calling agent-to-web-context-mapper-windows-unit");
|
||||
|
||||
var viewModel = {};
|
||||
if (!(session.get("email") && session.get("windowsWorkplaceAppID"))) {
|
||||
// if both email and windowsWorkplaceAppID session values are not set
|
||||
// this means either shifting to the page from agent or directly accessing the page out-of-order
|
||||
|
||||
// checking if user is actually shifting to the page from agent
|
||||
// login_hint passes the user email value entered in Windows workplace app
|
||||
var userEmail = request.getParameter("login_hint");
|
||||
// appru passes app ID of the Windows workplace app
|
||||
var windowsWorkplaceAppID = request.getParameter("appru");
|
||||
if (!userEmail || !windowsWorkplaceAppID) {
|
||||
response.sendRedirect(context.app.context + "/enrollments/error/unintentional-request");
|
||||
} else {
|
||||
/* allowing to skip first step of windows enrollment by
|
||||
setting session.put("lastAccessedPage", "invoke-agent")...
|
||||
This update was proposed to overcome following problem:
|
||||
First step of enrollment and second step of enrollment being linked with two sessions as
|
||||
first step is initiated by Internet explorer and the second by an internal web-view */
|
||||
session.put("lastAccessedPage", "invoke-agent");
|
||||
session.put("email", userEmail);
|
||||
session.put("windowsWorkplaceAppID", windowsWorkplaceAppID);
|
||||
}
|
||||
}
|
||||
|
||||
// setting windows login URL
|
||||
viewModel.windowsLoginActionURL = context.app.context + "/enrollment/windows/login";
|
||||
return viewModel;
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"uri": "/enrollments/windows/login-agent",
|
||||
"layout": "mdm.layout.enrollment",
|
||||
"isAnonymous": true
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
{{!-- Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
|
||||
WSO2 Inc. 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. --}}
|
||||
|
||||
{{!-- Inputting content into defined zones in enrollment layout --}}
|
||||
{{unit "mdm.unit.ui.title" pageTitle="Page Error"}}
|
||||
{{#zone "headerTitle"}}
|
||||
404 - Resource Not Found
|
||||
{{/zone}}
|
||||
{{#zone "content"}}
|
||||
<div class="wr-head">
|
||||
<h3>Possible Causes :</h3>
|
||||
</div>
|
||||
You are seen this page since the resource you are trying to access is not available.<br/>
|
||||
<div class="row">
|
||||
<div class="container col-md-4 wr-buttons">
|
||||
<a href="{{@app.context}}/enrollment" class="btn-download-agent">Goto Enroll Page</a>
|
||||
</div>
|
||||
</div>
|
||||
{{/zone}}
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"uri": "/error/404",
|
||||
"layout": "mdm.layout.enrollment",
|
||||
"isAnonymous": true
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"uri": "/",
|
||||
"isAnonymous": true,
|
||||
"extends": "mdm.page.error"
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
{{!-- Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
|
||||
WSO2 Inc. 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. --}}
|
||||
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
function onRequest(context) {
|
||||
var log = new Log("enrollment-access-control-unit backend js");
|
||||
log.debug("calling enrollment-access-control-unit");
|
||||
|
||||
var mdmProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
var UAParser = require("/app/modules/ua-parser.min.js")["UAParser"];
|
||||
|
||||
var parser = new UAParser();
|
||||
var userAgent = request.getHeader("User-Agent");
|
||||
parser.setUA(userAgent);
|
||||
parser.getResult();
|
||||
var userAgentPlatform = parser.getOS()["name"];
|
||||
|
||||
if (userAgentPlatform != context.unit.params["allowedPlatform"]) {
|
||||
// if userAgentPlatform is not allowed
|
||||
log.error("platform not allowed");
|
||||
response.sendRedirect(context.app.context + "/enrollments/error/unintentional-request");
|
||||
} else {
|
||||
var lastPage = context.unit.params["lastPage"];
|
||||
var nextPage = context.unit.params["nextPage"];
|
||||
var currentPage = context.unit.params["currentPage"];
|
||||
// if userAgentPlatform is allowed,
|
||||
// restricting unordered intermediate page access
|
||||
if (lastPage && currentPage && nextPage) {
|
||||
// meaning it's not first page, but a middle page
|
||||
if (!session.get("lastAccessedPage")) {
|
||||
// meaning a middle page is accessed at first
|
||||
response.sendRedirect(context.app.context + "/enrollments/error/unintentional-request");
|
||||
} else if (!(session.get("lastAccessedPage") == currentPage) &&
|
||||
!(session.get("lastAccessedPage") == lastPage) &&
|
||||
!(session.get("lastAccessedPage") == nextPage)) {
|
||||
response.sendRedirect(context.app.context + "/enrollments/error/unintentional-request");
|
||||
} else if (currentPage) {
|
||||
// if currentPage is set, update lastAccessedPage as currentPage
|
||||
session.put("lastAccessedPage", currentPage);
|
||||
}
|
||||
} else if (lastPage && currentPage && !nextPage) {
|
||||
// meaning it's not first page, not a middle page, but the last page in wizard
|
||||
if (!session.get("lastAccessedPage")) {
|
||||
// this means the last page is accessed at first
|
||||
response.sendRedirect(context.app.context + "/enrollments/error/unintentional-request");
|
||||
} else if (!(session.get("lastAccessedPage") == currentPage) &&
|
||||
!(session.get("lastAccessedPage") == lastPage)) {
|
||||
response.sendRedirect(context.app.context + "/enrollments/error/unintentional-request");
|
||||
} else if (currentPage) {
|
||||
// if currentPage is set, update lastAccessedPage as currentPage
|
||||
session.put("lastAccessedPage", currentPage);
|
||||
}
|
||||
} else if (currentPage) {
|
||||
// meaning it's the first page
|
||||
// if currentPage is set, update lastAccessedPage as currentPage
|
||||
session.put("lastAccessedPage", currentPage);
|
||||
}
|
||||
}
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("last-accessed-page = " + session.get("lastAccessedPage") +
|
||||
" : " + "session-id = " + session.getId());
|
||||
}
|
||||
return context;
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"isAnonymous": true
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
{{!-- Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
|
||||
WSO2 Inc. 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. --}}
|
||||
|
||||
<div>
|
||||
<div class="row">
|
||||
<div class="container col-md-8 wr-text">
|
||||
Please read the following end user license agreement carefully.
|
||||
In order to complete device enrollment, you must accept these terms.
|
||||
<br /><br />
|
||||
<div class="wr-agreement">
|
||||
<h4>{{companyName}} License Agreement</h4>
|
||||
<p id="license-text">{{license}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="container col-md-4 wr-buttons">
|
||||
<a href="{{@unit.params.licenseAcceptActionURL}}" class="btn-download-agent">I accept the terms</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{#zone "bottomJs"}}
|
||||
{{js "/js/license-box.js"}}
|
||||
{{/zone}}
|
||||
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
function onRequest(context) {
|
||||
var log = new Log("license-box-agent-unit");
|
||||
log.debug("calling license-box-agent-unit backend js");
|
||||
|
||||
var viewModel = {};
|
||||
var deviceModule = require("/app/modules/business-controllers/device.js")["deviceModule"];
|
||||
var mdmProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
|
||||
var license = deviceModule.getLicense(context.unit.params["platform"], context.unit.params["languageCode"]);
|
||||
if (license) {
|
||||
viewModel.license = license;
|
||||
} else {
|
||||
viewModel.license = "ERROR: Unable to retrieve License Text.";
|
||||
}
|
||||
|
||||
var companyProps = session.get("COMPANY_DETAILS");
|
||||
if (!companyProps) {
|
||||
viewModel.companyName = mdmProps.generalConfig.companyName;
|
||||
} else {
|
||||
viewModel.companyName = companyProps.companyName;
|
||||
}
|
||||
return viewModel;
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"version" : "1.0.0",
|
||||
"isAnonymous" : true
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
$(document).ready(function () {
|
||||
var license = $("#license-text").text();
|
||||
$("#license-text").html(license);
|
||||
});
|
||||
@ -0,0 +1,74 @@
|
||||
{{!-- Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
|
||||
WSO2 Inc. 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. --}}
|
||||
|
||||
<form class="form-login-box" action="{{@unit.params.loginActionURL}}" method="POST" onsubmit="return validate();">
|
||||
<div class="row">
|
||||
<div class="container col-md-8 wr-text">
|
||||
<!-- start of validation -->
|
||||
<div id="enrollment-error-msg" class="alert alert-danger hidden" role="alert">
|
||||
<span></span>
|
||||
</div>
|
||||
<!-- end of validation -->
|
||||
{{#excludes @unit.params.loginActionURL "windows"}}
|
||||
<div class="wr-input-control">
|
||||
<label class="input-label" for="domain">
|
||||
Domain *
|
||||
</label>
|
||||
<input id="domain" name="domain" type="text" class="form-control" maxlength="30"
|
||||
placeholder="Enter your tenant domain here" />
|
||||
</div>
|
||||
{{/excludes}}
|
||||
<div class="wr-input-control">
|
||||
<label class="input-label" for="username">
|
||||
Username *
|
||||
</label>
|
||||
<input id="username" name="username" type="text" class="form-control" maxlength="30"
|
||||
placeholder="Enter your username here" />
|
||||
</div>
|
||||
<br class="c-both" />
|
||||
<div class="wr-input-control">
|
||||
<label class="input-label" for="password">
|
||||
Password *
|
||||
</label>
|
||||
<input id="password" name="password" type="password" class="form-control" maxlength="30"
|
||||
placeholder="Enter your password here" />
|
||||
</div>
|
||||
<br class="c-both" />
|
||||
<div id="ownership-content" style="visibility:hidden; position:absolute">
|
||||
<div class="radio">
|
||||
<label class="input-label">
|
||||
<input type="radio" name="ownership" value="BYOD" checked>
|
||||
BYOD (This is my own device)
|
||||
</label>
|
||||
</div>
|
||||
<div class="radio">
|
||||
<label class="input-label">
|
||||
<input type="radio" name="ownership" value="COPE">
|
||||
COPE (This is a corporate device)
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="container col-md-4 wr-buttons">
|
||||
<a href="#" class="btn-download-agent">Login</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{{#zone "bottomJs"}}
|
||||
{{js "/js/login-box.js"}}
|
||||
{{/zone}}
|
||||
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
function onRequest(context) {
|
||||
context.handlebars.registerHelper("excludes", function (lvalue, rvalue, options) {
|
||||
if (arguments.length < 3) {
|
||||
throw new Error("Handlebars Helper equal needs 2 parameters");
|
||||
}
|
||||
if (lvalue.indexOf(rvalue) > -1) {
|
||||
return options.inverse(this);
|
||||
} else {
|
||||
return options.fn(this);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"version" : "1.0.0",
|
||||
"isAnonymous" : true
|
||||
}
|
||||
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This method will return query parameter value given its name
|
||||
* @param name Query parameter name
|
||||
* @returns {string} Query parameter value
|
||||
*/
|
||||
var getParameterByName = function (name) {
|
||||
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
|
||||
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
|
||||
results = regex.exec(location.search);
|
||||
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
|
||||
};
|
||||
|
||||
var errorMsgWrapper = "#enrollment-error-msg";
|
||||
var errorMsg = errorMsgWrapper + " span";
|
||||
|
||||
/**
|
||||
* This method will execute on login form submission and validate input.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
var validate = function () {
|
||||
var username = $("input#username").val();
|
||||
var password = $("input#password").val();
|
||||
|
||||
if (!username && !password) {
|
||||
$(errorMsg).text("Both username and password are empty. You cannot proceed.");
|
||||
if ($(errorMsgWrapper).hasClass("hidden")) {
|
||||
$(errorMsgWrapper).removeClass("hidden");
|
||||
}
|
||||
return false;
|
||||
} else if (!username && password) {
|
||||
$(errorMsg).text("Username should not be empty.");
|
||||
if ($(errorMsgWrapper).hasClass("hidden")) {
|
||||
$(errorMsgWrapper).removeClass("hidden");
|
||||
}
|
||||
return false;
|
||||
} else if (username && !password) {
|
||||
$(errorMsg).text("Password should not be empty.");
|
||||
if ($(errorMsgWrapper).hasClass("hidden")) {
|
||||
$(errorMsgWrapper).removeClass("hidden");
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
$(document).ready(function () {
|
||||
var error = getParameterByName("error");
|
||||
if (error == "auth-failed") {
|
||||
var defaultMessage = "Please provide a correct username and password to continue.";
|
||||
var customMessage = getParameterByName("message");
|
||||
if (customMessage) {
|
||||
$(errorMsg).text("Authentication failed. " + customMessage);
|
||||
} else {
|
||||
$(errorMsg).text("Authentication failed. " + defaultMessage);
|
||||
}
|
||||
$(errorMsgWrapper).removeClass("hidden");
|
||||
} else if (error == "unexpected") {
|
||||
$(errorMsg).text("An unexpected error occured. Please try again.");
|
||||
$(errorMsgWrapper).removeClass("hidden");
|
||||
}
|
||||
});
|
||||
|
||||
$(".btn-download-agent").click(function () {
|
||||
$(".form-login-box").submit();
|
||||
});
|
||||
|
||||
|
||||
@ -0,0 +1,24 @@
|
||||
{{!
|
||||
Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
|
||||
WSO2 Inc. 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.
|
||||
}}
|
||||
{{#zone "contentTitle"}}
|
||||
<div class="row wr-device-board">
|
||||
<div class="col-lg-12 wr-secondary-bar">
|
||||
<span class="page-sub-title">{{@unit.params.pageHeader}}</span>
|
||||
</div>
|
||||
</div>
|
||||
{{/zone}}
|
||||
@ -0,0 +1,3 @@
|
||||
{
|
||||
"version": "1.0.0"
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
{{!
|
||||
Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
|
||||
WSO2 Inc. 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.
|
||||
}}
|
||||
{{#zone "brand"}}
|
||||
<a href="{{@app.context}}/">
|
||||
<img src="{{@unit.publicUri}}/img/logo.png" alt="Enterprise Mobility Manager"
|
||||
title="Enterprise Mobility Manager" class="logo" />
|
||||
<h2 class="app-title"><span>Enterprise Mobility Manager</span></h2>
|
||||
</a>
|
||||
{{/zone}}
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"extends": "uuf.unit.header.logo"
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
{{!
|
||||
Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
|
||||
WSO2 Inc. 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.
|
||||
}}
|
||||
{{#zone "userMenu-items"}}
|
||||
<li>
|
||||
<a href="{{@app.context}}/logout">Logout</a>
|
||||
</li>
|
||||
{{/zone}}
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"extends" : "uuf.unit.header.user-menu"
|
||||
}
|
||||
@ -0,0 +1,117 @@
|
||||
{{!
|
||||
Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
|
||||
WSO2 Inc. 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.
|
||||
}}
|
||||
{{#zone "navMenu-icon"}}
|
||||
<span class="icon fw-stack">
|
||||
<i class="fw fw-tiles fw-stack-1x toggle-icon-up"></i>
|
||||
</span>
|
||||
{{/zone}}
|
||||
|
||||
{{#zone "navMenu-items"}}
|
||||
{{#if permissions.VIEW_DASHBOARD}}
|
||||
<li>
|
||||
<a href="{{@app.context}}">
|
||||
<i class="fw fw-dashboard"></i>
|
||||
Admin Dashboard
|
||||
</a>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#if permissions.LIST_DEVICES_ADMIN}}
|
||||
<li>
|
||||
<a href="{{@app.context}}/devices">
|
||||
<i class="fw fw-mobile"></i>
|
||||
Device Management
|
||||
</a>
|
||||
</li>
|
||||
{{else}}
|
||||
{{#if permissions.LIST_OWN_DEVICES}}
|
||||
<li>
|
||||
<a href="{{@app.context}}/devices">
|
||||
<i class="fw fw-mobile"></i>
|
||||
Device Management
|
||||
</a>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{#if permissions.LIST_GROUPS}}
|
||||
<li>
|
||||
<a href="{{@app.context}}/groups">
|
||||
<i class="fw fw-grouping"></i>
|
||||
Group Management
|
||||
</a>
|
||||
</li>
|
||||
{{/if}}
|
||||
<li><a><i class="fw fw-user"></i>User Management</a>
|
||||
<ul>
|
||||
{{#if permissions.LIST_USERS}}
|
||||
<li><a href="{{@app.context}}/users"><i class="fw fw-user"></i>Users</a></li>
|
||||
{{/if}}
|
||||
|
||||
{{#if permissions.LIST_ROLES}}
|
||||
<li><a href="{{@app.context}}/roles"><i class="fw fw-bookmark"></i>Roles</a></li>
|
||||
{{/if}}
|
||||
</ul>
|
||||
</li>
|
||||
{{#if permissions.LIST_POLICIES}}
|
||||
<li><a href="{{@app.context}}/policies"><i class="fw fw-policy"></i>Policy Management</a></li>
|
||||
{{/if}}
|
||||
<li><a><i class="fw fw-settings"></i>Configuration Management</a>
|
||||
<ul>
|
||||
{{#if permissions.TENANT_CONFIGURATION}}
|
||||
<li><a href="{{@app.context}}/platform-configuration"><i class="fw fw-service"></i>Platform Configurations</a>
|
||||
</li>
|
||||
{{/if}}
|
||||
<!-- todo change the permission and get the related permission -->
|
||||
{{#if permissions.TENANT_CONFIGURATION}}
|
||||
<li><a href="{{@app.context}}/certificates"><i class="fw fw-security-policy"></i>Certificate Configurations</a>
|
||||
</li>
|
||||
{{/if}}
|
||||
</ul>
|
||||
</li>
|
||||
{{/zone}}
|
||||
|
||||
{{#zone "navbarCollapsableRightItems"}}
|
||||
<ul id="notification-bubble-wrapper" class="nav navbar-nav navbar-right">
|
||||
<li class="visible-inline-block">
|
||||
<!--<a href="{{appContext}}notification-listing" title="Failures of operations on the device side will be listed here">-->
|
||||
<a data-toggle="sidebar" data-target="#right-sidebar" data-container=".page-content"
|
||||
aria-expanded="false" rel="notifications-sidebar">
|
||||
<span class="icon fw-stack">
|
||||
<i class="fw fw-notification fw-stack-1x"></i>
|
||||
</span>
|
||||
<span class="hidden-xs">Notifications</span>
|
||||
<span class="badge notifications" id="notification-bubble"></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
{{/zone}}
|
||||
{{#zone "sidePanes"}}
|
||||
<div class="sidebar-wrapper" id="right-sidebar" is-authorized="{{isAuthorizedForNotifications}}"
|
||||
data-side="right" data-width="320" data-sidebar-fixed="true" data-fixed-offset="50" data-spy="affix"
|
||||
data-offset-top="80">
|
||||
<ul class="sidebar-messages">
|
||||
</ul>
|
||||
<h4 class="text-center"><a href="{{appContext}}notification-listing" class="text-center">Show all notifications</a>
|
||||
</h4>
|
||||
</div>
|
||||
{{/zone}}
|
||||
{{#zone "bottomJs"}}
|
||||
<script id="notifications" data-current-user="{{currentUser.username}}"
|
||||
data-image-resource="{{self.publicURL}}/images/" src="{{self.publicURL}}/templates/notifications.hbs"
|
||||
type="text/x-handlebars-template"></script>
|
||||
{{js "js/nav-menu.js"}}
|
||||
{{/zone}}
|
||||
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
function onRequest(context) {
|
||||
context.handlebars.registerHelper('equal', function (lvalue, rvalue, options) {
|
||||
if (arguments.length < 3) {
|
||||
throw new Error("Handlebars Helper equal needs 2 parameters");
|
||||
}
|
||||
if (lvalue != rvalue) {
|
||||
return options.inverse(this);
|
||||
} else {
|
||||
return options.fn(this);
|
||||
}
|
||||
});
|
||||
var userModule = require("/app/modules/business-controllers/user.js")["userModule"];
|
||||
var mdmProps = require("/app/modules/conf-reader/main.js")["conf"];
|
||||
var constants = require("/app/modules/constants.js");
|
||||
var uiPermissions = userModule.getUIPermissions();
|
||||
context["permissions"] = uiPermissions;
|
||||
|
||||
var links = {
|
||||
"user-mgt": [],
|
||||
"role-mgt": [],
|
||||
"policy-mgt": [],
|
||||
"device-mgt": []
|
||||
};
|
||||
|
||||
// following context.link value comes here based on the value passed at the point
|
||||
// where units are attached to a page zone.
|
||||
// eg: {{unit "appbar" pageLink="users" title="User Management"}}
|
||||
context["currentActions"] = links[context["pageLink"]];
|
||||
context["enrollmentURL"] = mdmProps["generalConfig"]["host"] + mdmProps["enrollmentDir"];
|
||||
var isAuthorizedForNotifications =
|
||||
userModule.isAuthorized("/permission/admin/device-mgt/emm-admin/notifications/view");
|
||||
var currentUser = session.get(constants["USER_SESSION_KEY"]);
|
||||
context["isAuthorizedForNotifications"] = isAuthorizedForNotifications;
|
||||
context["currentUser"] = currentUser;
|
||||
context["appContext"] = context.app.context;
|
||||
|
||||
return context;
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"index": 30,
|
||||
"pushedUris": [
|
||||
"/",
|
||||
"/{+any}"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
//---------------------------------------------------------------------
|
||||
// QRCode for JavaScript
|
||||
//
|
||||
// Copyright (c) 2009 Kazuhiko Arase
|
||||
//
|
||||
// URL: http://www.d-project.com/
|
||||
//
|
||||
// Licensed under the MIT license:
|
||||
// http://www.opensource.org/licenses/mit-license.php
|
||||
//
|
||||
// The word "QR Code" is registered trademark of
|
||||
// DENSO WAVE INCORPORATED
|
||||
// http://www.denso-wave.com/qrcode/faqpatent-e.html
|
||||
//
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// QR8bitByte
|
||||
//---------------------------------------------------------------------
|
||||
(function(r){r.fn.qrcode=function(h){var s;function u(a){this.mode=s;this.data=a}function o(a,c){this.typeNumber=a;this.errorCorrectLevel=c;this.modules=null;this.moduleCount=0;this.dataCache=null;this.dataList=[]}function q(a,c){if(void 0==a.length)throw Error(a.length+"/"+c);for(var d=0;d<a.length&&0==a[d];)d++;this.num=Array(a.length-d+c);for(var b=0;b<a.length-d;b++)this.num[b]=a[b+d]}function p(a,c){this.totalCount=a;this.dataCount=c}function t(){this.buffer=[];this.length=0}u.prototype={getLength:function(){return this.data.length},
|
||||
write:function(a){for(var c=0;c<this.data.length;c++)a.put(this.data.charCodeAt(c),8)}};o.prototype={addData:function(a){this.dataList.push(new u(a));this.dataCache=null},isDark:function(a,c){if(0>a||this.moduleCount<=a||0>c||this.moduleCount<=c)throw Error(a+","+c);return this.modules[a][c]},getModuleCount:function(){return this.moduleCount},make:function(){if(1>this.typeNumber){for(var a=1,a=1;40>a;a++){for(var c=p.getRSBlocks(a,this.errorCorrectLevel),d=new t,b=0,e=0;e<c.length;e++)b+=c[e].dataCount;
|
||||
for(e=0;e<this.dataList.length;e++)c=this.dataList[e],d.put(c.mode,4),d.put(c.getLength(),j.getLengthInBits(c.mode,a)),c.write(d);if(d.getLengthInBits()<=8*b)break}this.typeNumber=a}this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(a,c){this.moduleCount=4*this.typeNumber+17;this.modules=Array(this.moduleCount);for(var d=0;d<this.moduleCount;d++){this.modules[d]=Array(this.moduleCount);for(var b=0;b<this.moduleCount;b++)this.modules[d][b]=null}this.setupPositionProbePattern(0,0);this.setupPositionProbePattern(this.moduleCount-
|
||||
7,0);this.setupPositionProbePattern(0,this.moduleCount-7);this.setupPositionAdjustPattern();this.setupTimingPattern();this.setupTypeInfo(a,c);7<=this.typeNumber&&this.setupTypeNumber(a);null==this.dataCache&&(this.dataCache=o.createData(this.typeNumber,this.errorCorrectLevel,this.dataList));this.mapData(this.dataCache,c)},setupPositionProbePattern:function(a,c){for(var d=-1;7>=d;d++)if(!(-1>=a+d||this.moduleCount<=a+d))for(var b=-1;7>=b;b++)-1>=c+b||this.moduleCount<=c+b||(this.modules[a+d][c+b]=
|
||||
0<=d&&6>=d&&(0==b||6==b)||0<=b&&6>=b&&(0==d||6==d)||2<=d&&4>=d&&2<=b&&4>=b?!0:!1)},getBestMaskPattern:function(){for(var a=0,c=0,d=0;8>d;d++){this.makeImpl(!0,d);var b=j.getLostPoint(this);if(0==d||a>b)a=b,c=d}return c},createMovieClip:function(a,c,d){a=a.createEmptyMovieClip(c,d);this.make();for(c=0;c<this.modules.length;c++)for(var d=1*c,b=0;b<this.modules[c].length;b++){var e=1*b;this.modules[c][b]&&(a.beginFill(0,100),a.moveTo(e,d),a.lineTo(e+1,d),a.lineTo(e+1,d+1),a.lineTo(e,d+1),a.endFill())}return a},
|
||||
setupTimingPattern:function(){for(var a=8;a<this.moduleCount-8;a++)null==this.modules[a][6]&&(this.modules[a][6]=0==a%2);for(a=8;a<this.moduleCount-8;a++)null==this.modules[6][a]&&(this.modules[6][a]=0==a%2)},setupPositionAdjustPattern:function(){for(var a=j.getPatternPosition(this.typeNumber),c=0;c<a.length;c++)for(var d=0;d<a.length;d++){var b=a[c],e=a[d];if(null==this.modules[b][e])for(var f=-2;2>=f;f++)for(var i=-2;2>=i;i++)this.modules[b+f][e+i]=-2==f||2==f||-2==i||2==i||0==f&&0==i?!0:!1}},setupTypeNumber:function(a){for(var c=
|
||||
j.getBCHTypeNumber(this.typeNumber),d=0;18>d;d++){var b=!a&&1==(c>>d&1);this.modules[Math.floor(d/3)][d%3+this.moduleCount-8-3]=b}for(d=0;18>d;d++)b=!a&&1==(c>>d&1),this.modules[d%3+this.moduleCount-8-3][Math.floor(d/3)]=b},setupTypeInfo:function(a,c){for(var d=j.getBCHTypeInfo(this.errorCorrectLevel<<3|c),b=0;15>b;b++){var e=!a&&1==(d>>b&1);6>b?this.modules[b][8]=e:8>b?this.modules[b+1][8]=e:this.modules[this.moduleCount-15+b][8]=e}for(b=0;15>b;b++)e=!a&&1==(d>>b&1),8>b?this.modules[8][this.moduleCount-
|
||||
b-1]=e:9>b?this.modules[8][15-b-1+1]=e:this.modules[8][15-b-1]=e;this.modules[this.moduleCount-8][8]=!a},mapData:function(a,c){for(var d=-1,b=this.moduleCount-1,e=7,f=0,i=this.moduleCount-1;0<i;i-=2)for(6==i&&i--;;){for(var g=0;2>g;g++)if(null==this.modules[b][i-g]){var n=!1;f<a.length&&(n=1==(a[f]>>>e&1));j.getMask(c,b,i-g)&&(n=!n);this.modules[b][i-g]=n;e--; -1==e&&(f++,e=7)}b+=d;if(0>b||this.moduleCount<=b){b-=d;d=-d;break}}}};o.PAD0=236;o.PAD1=17;o.createData=function(a,c,d){for(var c=p.getRSBlocks(a,
|
||||
c),b=new t,e=0;e<d.length;e++){var f=d[e];b.put(f.mode,4);b.put(f.getLength(),j.getLengthInBits(f.mode,a));f.write(b)}for(e=a=0;e<c.length;e++)a+=c[e].dataCount;if(b.getLengthInBits()>8*a)throw Error("code length overflow. ("+b.getLengthInBits()+">"+8*a+")");for(b.getLengthInBits()+4<=8*a&&b.put(0,4);0!=b.getLengthInBits()%8;)b.putBit(!1);for(;!(b.getLengthInBits()>=8*a);){b.put(o.PAD0,8);if(b.getLengthInBits()>=8*a)break;b.put(o.PAD1,8)}return o.createBytes(b,c)};o.createBytes=function(a,c){for(var d=
|
||||
0,b=0,e=0,f=Array(c.length),i=Array(c.length),g=0;g<c.length;g++){var n=c[g].dataCount,h=c[g].totalCount-n,b=Math.max(b,n),e=Math.max(e,h);f[g]=Array(n);for(var k=0;k<f[g].length;k++)f[g][k]=255&a.buffer[k+d];d+=n;k=j.getErrorCorrectPolynomial(h);n=(new q(f[g],k.getLength()-1)).mod(k);i[g]=Array(k.getLength()-1);for(k=0;k<i[g].length;k++)h=k+n.getLength()-i[g].length,i[g][k]=0<=h?n.get(h):0}for(k=g=0;k<c.length;k++)g+=c[k].totalCount;d=Array(g);for(k=n=0;k<b;k++)for(g=0;g<c.length;g++)k<f[g].length&&
|
||||
(d[n++]=f[g][k]);for(k=0;k<e;k++)for(g=0;g<c.length;g++)k<i[g].length&&(d[n++]=i[g][k]);return d};s=4;for(var j={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,
|
||||
78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:1335,G18:7973,G15_MASK:21522,getBCHTypeInfo:function(a){for(var c=a<<10;0<=j.getBCHDigit(c)-j.getBCHDigit(j.G15);)c^=j.G15<<j.getBCHDigit(c)-j.getBCHDigit(j.G15);return(a<<10|c)^j.G15_MASK},getBCHTypeNumber:function(a){for(var c=a<<12;0<=j.getBCHDigit(c)-
|
||||
j.getBCHDigit(j.G18);)c^=j.G18<<j.getBCHDigit(c)-j.getBCHDigit(j.G18);return a<<12|c},getBCHDigit:function(a){for(var c=0;0!=a;)c++,a>>>=1;return c},getPatternPosition:function(a){return j.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,c,d){switch(a){case 0:return 0==(c+d)%2;case 1:return 0==c%2;case 2:return 0==d%3;case 3:return 0==(c+d)%3;case 4:return 0==(Math.floor(c/2)+Math.floor(d/3))%2;case 5:return 0==c*d%2+c*d%3;case 6:return 0==(c*d%2+c*d%3)%2;case 7:return 0==(c*d%3+(c+d)%2)%2;default:throw Error("bad maskPattern:"+
|
||||
a);}},getErrorCorrectPolynomial:function(a){for(var c=new q([1],0),d=0;d<a;d++)c=c.multiply(new q([1,l.gexp(d)],0));return c},getLengthInBits:function(a,c){if(1<=c&&10>c)switch(a){case 1:return 10;case 2:return 9;case s:return 8;case 8:return 8;default:throw Error("mode:"+a);}else if(27>c)switch(a){case 1:return 12;case 2:return 11;case s:return 16;case 8:return 10;default:throw Error("mode:"+a);}else if(41>c)switch(a){case 1:return 14;case 2:return 13;case s:return 16;case 8:return 12;default:throw Error("mode:"+
|
||||
a);}else throw Error("type:"+c);},getLostPoint:function(a){for(var c=a.getModuleCount(),d=0,b=0;b<c;b++)for(var e=0;e<c;e++){for(var f=0,i=a.isDark(b,e),g=-1;1>=g;g++)if(!(0>b+g||c<=b+g))for(var h=-1;1>=h;h++)0>e+h||c<=e+h||0==g&&0==h||i==a.isDark(b+g,e+h)&&f++;5<f&&(d+=3+f-5)}for(b=0;b<c-1;b++)for(e=0;e<c-1;e++)if(f=0,a.isDark(b,e)&&f++,a.isDark(b+1,e)&&f++,a.isDark(b,e+1)&&f++,a.isDark(b+1,e+1)&&f++,0==f||4==f)d+=3;for(b=0;b<c;b++)for(e=0;e<c-6;e++)a.isDark(b,e)&&!a.isDark(b,e+1)&&a.isDark(b,e+
|
||||
2)&&a.isDark(b,e+3)&&a.isDark(b,e+4)&&!a.isDark(b,e+5)&&a.isDark(b,e+6)&&(d+=40);for(e=0;e<c;e++)for(b=0;b<c-6;b++)a.isDark(b,e)&&!a.isDark(b+1,e)&&a.isDark(b+2,e)&&a.isDark(b+3,e)&&a.isDark(b+4,e)&&!a.isDark(b+5,e)&&a.isDark(b+6,e)&&(d+=40);for(e=f=0;e<c;e++)for(b=0;b<c;b++)a.isDark(b,e)&&f++;a=Math.abs(100*f/c/c-50)/5;return d+10*a}},l={glog:function(a){if(1>a)throw Error("glog("+a+")");return l.LOG_TABLE[a]},gexp:function(a){for(;0>a;)a+=255;for(;256<=a;)a-=255;return l.EXP_TABLE[a]},EXP_TABLE:Array(256),
|
||||
LOG_TABLE:Array(256)},m=0;8>m;m++)l.EXP_TABLE[m]=1<<m;for(m=8;256>m;m++)l.EXP_TABLE[m]=l.EXP_TABLE[m-4]^l.EXP_TABLE[m-5]^l.EXP_TABLE[m-6]^l.EXP_TABLE[m-8];for(m=0;255>m;m++)l.LOG_TABLE[l.EXP_TABLE[m]]=m;q.prototype={get:function(a){return this.num[a]},getLength:function(){return this.num.length},multiply:function(a){for(var c=Array(this.getLength()+a.getLength()-1),d=0;d<this.getLength();d++)for(var b=0;b<a.getLength();b++)c[d+b]^=l.gexp(l.glog(this.get(d))+l.glog(a.get(b)));return new q(c,0)},mod:function(a){if(0>
|
||||
this.getLength()-a.getLength())return this;for(var c=l.glog(this.get(0))-l.glog(a.get(0)),d=Array(this.getLength()),b=0;b<this.getLength();b++)d[b]=this.get(b);for(b=0;b<a.getLength();b++)d[b]^=l.gexp(l.glog(a.get(b))+c);return(new q(d,0)).mod(a)}};p.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],
|
||||
[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,
|
||||
116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,
|
||||
43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,
|
||||
3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,
|
||||
55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,
|
||||
45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]];p.getRSBlocks=function(a,c){var d=p.getRsBlockTable(a,c);if(void 0==d)throw Error("bad rs block @ typeNumber:"+a+"/errorCorrectLevel:"+c);for(var b=d.length/3,e=[],f=0;f<b;f++)for(var h=d[3*f+0],g=d[3*f+1],j=d[3*f+2],l=0;l<h;l++)e.push(new p(g,j));return e};p.getRsBlockTable=function(a,c){switch(c){case 1:return p.RS_BLOCK_TABLE[4*(a-1)+0];case 0:return p.RS_BLOCK_TABLE[4*(a-1)+1];case 3:return p.RS_BLOCK_TABLE[4*
|
||||
(a-1)+2];case 2:return p.RS_BLOCK_TABLE[4*(a-1)+3]}};t.prototype={get:function(a){return 1==(this.buffer[Math.floor(a/8)]>>>7-a%8&1)},put:function(a,c){for(var d=0;d<c;d++)this.putBit(1==(a>>>c-d-1&1))},getLengthInBits:function(){return this.length},putBit:function(a){var c=Math.floor(this.length/8);this.buffer.length<=c&&this.buffer.push(0);a&&(this.buffer[c]|=128>>>this.length%8);this.length++}};"string"===typeof h&&(h={text:h});h=r.extend({},{render:"canvas",width:256,height:256,typeNumber:-1,
|
||||
correctLevel:2,background:"#ffffff",foreground:"#000000"},h);return this.each(function(){var a;if("canvas"==h.render){a=new o(h.typeNumber,h.correctLevel);a.addData(h.text);a.make();var c=document.createElement("canvas");c.width=h.width;c.height=h.height;for(var d=c.getContext("2d"),b=h.width/a.getModuleCount(),e=h.height/a.getModuleCount(),f=0;f<a.getModuleCount();f++)for(var i=0;i<a.getModuleCount();i++){d.fillStyle=a.isDark(f,i)?h.foreground:h.background;var g=Math.ceil((i+1)*b)-Math.floor(i*b),
|
||||
j=Math.ceil((f+1)*b)-Math.floor(f*b);d.fillRect(Math.round(i*b),Math.round(f*e),g,j)}}else{a=new o(h.typeNumber,h.correctLevel);a.addData(h.text);a.make();c=r("<table></table>").css("width",h.width+"px").css("height",h.height+"px").css("border","0px").css("border-collapse","collapse").css("background-color",h.background);d=h.width/a.getModuleCount();b=h.height/a.getModuleCount();for(e=0;e<a.getModuleCount();e++){f=r("<tr></tr>").css("height",b+"px").appendTo(c);for(i=0;i<a.getModuleCount();i++)r("<td></td>").css("width",
|
||||
d+"px").css("background-color",a.isDark(e,i)?h.foreground:h.background).appendTo(f)}}a=c;jQuery(a).appendTo(this)})}})(jQuery);
|
||||
@ -0,0 +1,351 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. 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.
|
||||
*/
|
||||
|
||||
var modalPopup = ".wr-modalpopup",
|
||||
modalPopupContainer = modalPopup + " .modalpopup-container",
|
||||
modalPopupContent = modalPopup + " .modalpopup-content";
|
||||
|
||||
var emmAdminBasePath = "/api/device-mgt/v1.0";
|
||||
|
||||
/*
|
||||
* set popup maximum height function.
|
||||
*/
|
||||
function setPopupMaxHeight() {
|
||||
var maxHeight = "max-height";
|
||||
var marginTop = "margin-top";
|
||||
var body = "body";
|
||||
$(modalPopupContent).css(maxHeight, ($(body).height() - ($(body).height() / 100 * 30)));
|
||||
$(modalPopupContainer).css(marginTop, (-($(modalPopupContainer).height() / 2)));
|
||||
}
|
||||
|
||||
/*
|
||||
* show popup function.
|
||||
*/
|
||||
function showPopup() {
|
||||
$(modalPopup).show();
|
||||
setPopupMaxHeight();
|
||||
}
|
||||
|
||||
/*
|
||||
* hide popup function.
|
||||
*/
|
||||
function hidePopup() {
|
||||
$(modalPopupContent).html("");
|
||||
$(modalPopupContent).removeClass("operation-data");
|
||||
$(modalPopup).hide();
|
||||
}
|
||||
|
||||
var updateNotificationCount = function (data, textStatus, jqXHR) {
|
||||
if (jqXHR.status == 200 && data) {
|
||||
var responsePayload = JSON.parse(data);
|
||||
var newNotificationsCount = responsePayload.count;
|
||||
if (newNotificationsCount > 0) {
|
||||
$("#notification-bubble").html(newNotificationsCount);
|
||||
}
|
||||
// } else {
|
||||
// $("#notification-bubble").html("Error");
|
||||
// }
|
||||
}
|
||||
};
|
||||
|
||||
function loadNotificationsPanel() {
|
||||
if ("true" == $("#right-sidebar").attr("is-authorized")) {
|
||||
var serviceURL = emmAdminBasePath + "/notifications?status=NEW";
|
||||
invokerUtil.get(serviceURL, updateNotificationCount, hideNotificationCount);
|
||||
loadNewNotifications();
|
||||
} else {
|
||||
$("#notification-bubble-wrapper").remove();
|
||||
}
|
||||
}
|
||||
|
||||
function hideNotificationCount(jqXHR) {
|
||||
if (jqXHR.status == 404) {
|
||||
// this means "no new notifications to show"
|
||||
$("#notification-bubble").hide();
|
||||
} else {
|
||||
$("#notification-bubble").html("Error");
|
||||
}
|
||||
}
|
||||
|
||||
function loadNewNotifications() {
|
||||
var messageSideBar = ".sidebar-messages";
|
||||
if ($("#right-sidebar").attr("is-authorized") == "true") {
|
||||
var notifications = $("#notifications");
|
||||
var currentUser = notifications.data("currentUser");
|
||||
|
||||
$.template("notification-listing", notifications.attr("src"), function (template) {
|
||||
var serviceURL = emmAdminBasePath + "/notifications?status=NEW";
|
||||
|
||||
var successCallback = function (data, textStatus, jqXHR) {
|
||||
if (jqXHR.status == 200 && data) {
|
||||
var viewModel = {};
|
||||
var responsePayload = JSON.parse(data);
|
||||
|
||||
if (responsePayload.notifications) {
|
||||
viewModel.notifications = responsePayload.notifications;
|
||||
if (responsePayload.count > 0) {
|
||||
$(messageSideBar).html(template(viewModel));
|
||||
} else {
|
||||
$(messageSideBar).html("<h4 class='text-center'>No new notifications found...</h4>");
|
||||
}
|
||||
} else {
|
||||
$(messageSideBar).html("<h4 class ='message-danger'>Unexpected error occurred while loading new notifications.</h4>");
|
||||
}
|
||||
}
|
||||
};
|
||||
var errorCallback = function (jqXHR) {
|
||||
if (jqXHR.status = 500) {
|
||||
$(messageSideBar).html("<h4 class ='message-danger'>Unexpected error occurred while trying " +
|
||||
"to retrieve any new notifications.</h4>");
|
||||
}
|
||||
};
|
||||
invokerUtil.get(serviceURL, successCallback, errorCallback);
|
||||
});
|
||||
} else {
|
||||
$(messageSideBar).html("<h4 class ='message-danger'>You are not authorized to view notifications</h4>");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle function for
|
||||
* notification listing sidebar.
|
||||
* @return {Null}
|
||||
*/
|
||||
$.sidebar_toggle = function (action, target, container) {
|
||||
var elem = '[data-toggle=sidebar]',
|
||||
button,
|
||||
containerOffsetLeft,
|
||||
containerOffsetRight,
|
||||
targetOffsetLeft,
|
||||
targetOffsetRight,
|
||||
targetWidth,
|
||||
targetSide,
|
||||
relationship,
|
||||
pushType,
|
||||
buttonParent;
|
||||
|
||||
var sidebar_window = {
|
||||
update: function (target, container, button) {
|
||||
containerOffsetLeft = $(container).data('offset-left') ? $(container).data('offset-left') : 0;
|
||||
containerOffsetRight = $(container).data('offset-right') ? $(container).data('offset-right') : 0;
|
||||
targetOffsetLeft = $(target).data('offset-left') ? $(target).data('offset-left') : 0;
|
||||
targetOffsetRight = $(target).data('offset-right') ? $(target).data('offset-right') : 0;
|
||||
targetWidth = $(target).data('width');
|
||||
targetSide = $(target).data("side");
|
||||
pushType = $(container).parent().is('body') == true ? 'padding' : 'margin';
|
||||
|
||||
if (button !== undefined) {
|
||||
relationship = button.attr('rel') ? button.attr('rel') : '';
|
||||
buttonParent = $(button).parent();
|
||||
}
|
||||
},
|
||||
|
||||
show: function () {
|
||||
if ($(target).data('sidebar-fixed') == true) {
|
||||
$(target).height($(window).height() - $(target).data('fixed-offset'));
|
||||
}
|
||||
$(target).trigger('show.sidebar');
|
||||
if (targetWidth !== undefined) {
|
||||
$(target).css('width', targetWidth);
|
||||
}
|
||||
$(target).addClass('toggled');
|
||||
if (button !== undefined) {
|
||||
if (relationship !== '') {
|
||||
// Removing active class from all relative buttons
|
||||
$(elem + '[rel=' + relationship + ']:not([data-handle=close])').removeClass("active");
|
||||
$(elem + '[rel=' + relationship + ']:not([data-handle=close])').attr('aria-expanded', 'false');
|
||||
}
|
||||
// Adding active class to button
|
||||
if (button.attr('data-handle') !== 'close') {
|
||||
button.addClass("active");
|
||||
button.attr('aria-expanded', 'true');
|
||||
}
|
||||
if (buttonParent.is('li')) {
|
||||
if (relationship !== '') {
|
||||
$(elem + '[rel=' + relationship + ']:not([data-handle=close])').parent().removeClass("active");
|
||||
$(elem + '[rel=' + relationship + ']:not([data-handle=close])').parent().
|
||||
attr('aria-expanded', 'false');
|
||||
}
|
||||
buttonParent.addClass("active");
|
||||
buttonParent.attr('aria-expanded', 'true');
|
||||
}
|
||||
}
|
||||
// Sidebar open function
|
||||
if (targetSide == 'left') {
|
||||
if ((button !== undefined) && (button.attr('data-container-divide'))) {
|
||||
$(container).css(pushType + '-' + targetSide, targetWidth + targetOffsetLeft);
|
||||
}
|
||||
$(target).css(targetSide, targetOffsetLeft);
|
||||
} else if (targetSide == 'right') {
|
||||
if ((button !== undefined) && (button.attr('data-container-divide'))) {
|
||||
$(container).css(pushType + '-' + targetSide, targetWidth + targetOffsetRight);
|
||||
}
|
||||
$(target).css(targetSide, targetOffsetRight);
|
||||
}
|
||||
$(target).trigger('shown.sidebar');
|
||||
},
|
||||
|
||||
hide: function () {
|
||||
$(target).trigger('hide.sidebar');
|
||||
$(target).removeClass('toggled');
|
||||
if (button !== undefined) {
|
||||
if (relationship !== '') {
|
||||
// Removing active class from all relative buttons
|
||||
$(elem + '[rel=' + relationship + ']:not([data-handle=close])').removeClass("active");
|
||||
$(elem + '[rel=' + relationship + ']:not([data-handle=close])').attr('aria-expanded', 'false');
|
||||
}
|
||||
// Removing active class from button
|
||||
if (button.attr('data-handle') !== 'close') {
|
||||
button.removeClass("active");
|
||||
button.attr('aria-expanded', 'false');
|
||||
}
|
||||
if ($(button).parent().is('li')) {
|
||||
if (relationship !== '') {
|
||||
$(elem + '[rel=' + relationship + ']:not([data-handle=close])').parent().removeClass("active");
|
||||
$(elem + '[rel=' + relationship + ']:not([data-handle=close])').parent().
|
||||
attr('aria-expanded', 'false');
|
||||
}
|
||||
}
|
||||
}
|
||||
// Sidebar close function
|
||||
if (targetSide == 'left') {
|
||||
if ((button !== undefined) && (button.attr('data-container-divide'))) {
|
||||
$(container).css(pushType + '-' + targetSide, targetOffsetLeft);
|
||||
}
|
||||
$(target).css(targetSide, -Math.abs(targetWidth + targetOffsetLeft));
|
||||
} else if (targetSide == 'right') {
|
||||
if ((button !== undefined) && (button.attr('data-container-divide'))) {
|
||||
$(container).css(pushType + '-' + targetSide, targetOffsetRight);
|
||||
}
|
||||
$(target).css(targetSide, -Math.abs(targetWidth + targetOffsetRight));
|
||||
}
|
||||
$(target).trigger('hidden.sidebar');
|
||||
}
|
||||
};
|
||||
if (action === 'show') {
|
||||
sidebar_window.update(target, container);
|
||||
sidebar_window.show();
|
||||
}
|
||||
if (action === 'hide') {
|
||||
sidebar_window.update(target, container);
|
||||
sidebar_window.hide();
|
||||
}
|
||||
// binding click function
|
||||
var body = 'body';
|
||||
$(body).off('click', elem);
|
||||
$(body).on('click', elem, function (e) {
|
||||
e.preventDefault();
|
||||
button = $(this);
|
||||
container = button.data('container');
|
||||
target = button.data('target');
|
||||
sidebar_window.update(target, container, button);
|
||||
/**
|
||||
* Sidebar function on data container divide
|
||||
* @return {Null}
|
||||
*/
|
||||
if (button.attr('aria-expanded') == 'false') {
|
||||
sidebar_window.show();
|
||||
} else if (button.attr('aria-expanded') == 'true') {
|
||||
sidebar_window.hide();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.collapse_nav_sub = function () {
|
||||
var navSelector = 'ul.nav';
|
||||
|
||||
if (!$(navSelector).hasClass('collapse-nav-sub')) {
|
||||
$(navSelector + ' > li', this).each(function () {
|
||||
var position = $(this).offset().left - $(this).parent().scrollLeft();
|
||||
$(this).attr('data-absolute-position', (position + 5));
|
||||
});
|
||||
|
||||
$(navSelector + ' li', this).each(function () {
|
||||
if ($('ul', this).length !== 0) {
|
||||
$(this).addClass('has-sub');
|
||||
}
|
||||
});
|
||||
|
||||
$(navSelector + ' > li', this).each(function () {
|
||||
$(this).css({
|
||||
'left': $(this).data('absolute-position'),
|
||||
'position': 'absolute'
|
||||
});
|
||||
});
|
||||
|
||||
$(navSelector + ' li.has-sub', this).on('click', function () {
|
||||
var elem = $(this);
|
||||
if (elem.attr('aria-expanded') !== 'true') {
|
||||
elem.siblings().fadeOut(100, function () {
|
||||
elem.animate({'left': '15'}, 200, function () {
|
||||
$(elem).first().children('ul').fadeIn(200);
|
||||
});
|
||||
});
|
||||
elem.siblings().attr('aria-expanded', 'false');
|
||||
elem.attr('aria-expanded', 'true');
|
||||
} else {
|
||||
$(elem).first().children('ul').fadeOut(100, function () {
|
||||
elem.animate({'left': $(elem).data('absolute-position')}, 200, function () {
|
||||
elem.siblings().fadeIn(100);
|
||||
});
|
||||
});
|
||||
elem.siblings().attr('aria-expanded', 'false');
|
||||
elem.attr('aria-expanded', 'false');
|
||||
}
|
||||
});
|
||||
|
||||
$(navSelector + ' > li.has-sub ul', this).on('click', function (e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
$(navSelector).addClass('collapse-nav-sub');
|
||||
}
|
||||
};
|
||||
|
||||
$(document).ready(function () {
|
||||
loadNotificationsPanel();
|
||||
$.sidebar_toggle();
|
||||
|
||||
$("#right-sidebar").on("click", ".new-notification", function () {
|
||||
var notificationId = $(this).data("id");
|
||||
var redirectUrl = $(this).data("url");
|
||||
var markAsReadNotificationsAPI = "/mdm-admin/notifications/" + notificationId + "/CHECKED";
|
||||
var messageSideBar = ".sidebar-messages";
|
||||
|
||||
invokerUtil.put(
|
||||
markAsReadNotificationsAPI,
|
||||
null,
|
||||
function (data) {
|
||||
data = JSON.parse(data);
|
||||
if (data.statusCode == responseCodes["ACCEPTED"]) {
|
||||
location.href = redirectUrl;
|
||||
}
|
||||
}, function () {
|
||||
var content = "<li class='message message-danger'><h4><i class='icon fw fw-error'></i>Warning</h4>" +
|
||||
"<p>Unexpected error occurred while loading notification. Please refresh the page and" +
|
||||
" try again</p></li>";
|
||||
$(messageSideBar).html(content);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
if (typeof $.fn.collapse == 'function') {
|
||||
$('.navbar-collapse.tiles').on('shown.bs.collapse', function () {
|
||||
$(this).collapse_nav_sub();
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,14 @@
|
||||
{{#each notifications}}
|
||||
<li class="message message-info" data-type="selectable" >
|
||||
<h4>
|
||||
<i class="icon fw fw-info"></i>
|
||||
<a href="device?type={{deviceIdentifier.type}}&id={{deviceIdentifier.id}}"
|
||||
data-id="{{notificationId}}"
|
||||
data-url="device?type={{deviceIdentifier.type}}&id={{deviceIdentifier.id}}"
|
||||
class="new-notification" data-click-event="remove-form">
|
||||
Device Type : {{deviceIdentifier.type}}
|
||||
</a>
|
||||
</h4>
|
||||
<p>{{description}}</p>
|
||||
</li>
|
||||
{{/each}}
|
||||
@ -0,0 +1,5 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"extends": "uuf.unit.navbar.notifications",
|
||||
"disabled": true
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"extends": "uuf.unit.navbar.popover",
|
||||
"disabled": true
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"extends": "uuf.unit.navbar.toggle-menu.left",
|
||||
"disabled": true
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"extends": "uuf.unit.navbar.toggle-menu.right",
|
||||
"disabled": true
|
||||
}
|
||||
@ -0,0 +1,369 @@
|
||||
|
||||
/* Regular */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
|
||||
src: url('../fonts/OpenSans-Regular-webfont.eot');
|
||||
src: url('../fonts/OpenSans-Regular-webfont.eot?#iefix') format('embedded-opentype'),
|
||||
url('../fonts/OpenSans-Regular-webfont.woff') format('woff'),
|
||||
url('../fonts/OpenSans-Regular-webfont.ttf') format('truetype'),
|
||||
url('../fonts/OpenSans-Regular-webfont.svg#OpenSansRegular') format('svg');
|
||||
font-weight: normal;
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
|
||||
}
|
||||
|
||||
/* Italic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src: url('../fonts/OpenSans-Italic-webfont.eot');
|
||||
src: url('../fonts/OpenSans-Italic-webfont.eot?#iefix') format('embedded-opentype'),
|
||||
url('../fonts/OpenSans-Italic-webfont.woff') format('woff'),
|
||||
url('../fonts/OpenSans-Italic-webfont.ttf') format('truetype'),
|
||||
url('../fonts/OpenSans-Italic-webfont.svg#OpenSansItalic') format('svg');
|
||||
font-weight: normal;
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
|
||||
}
|
||||
|
||||
/* Light */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src: url('../fonts/OpenSans-Light-webfont.eot');
|
||||
src: url('../fonts/OpenSans-Light-webfont.eot?#iefix') format('embedded-opentype'),
|
||||
url('../fonts/OpenSans-Light-webfont.woff') format('woff'),
|
||||
url('../fonts/OpenSans-Light-webfont.ttf') format('truetype'),
|
||||
url('../fonts/OpenSans-Light-webfont.svg#OpenSansLight') format('svg');
|
||||
font-weight: 200;
|
||||
font-style: normal;
|
||||
|
||||
}
|
||||
|
||||
/* Light Italic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src: url('../fonts/OpenSans-LightItalic-webfont.eot');
|
||||
src: url('../fonts/OpenSans-LightItalic-webfont.eot?#iefix') format('embedded-opentype'),
|
||||
url('../fonts/OpenSans-LightItalic-webfont.woff') format('woff'),
|
||||
url('../fonts/OpenSans-LightItalic-webfont.ttf') format('truetype'),
|
||||
url('../fonts/OpenSans-LightItalic-webfont.svg#OpenSansLightItalic') format('svg');
|
||||
font-weight: 200;
|
||||
font-style: italic;
|
||||
|
||||
}
|
||||
|
||||
/* Semibold */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src: url('../fonts/OpenSans-Semibold-webfont.eot');
|
||||
src: url('../fonts/OpenSans-Semibold-webfont.eot?#iefix') format('embedded-opentype'),
|
||||
url('../fonts/OpenSans-Semibold-webfont.woff') format('woff'),
|
||||
url('../fonts/OpenSans-Semibold-webfont.ttf') format('truetype'),
|
||||
url('../fonts/OpenSans-Semibold-webfont.svg#OpenSansSemibold') format('svg');
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
|
||||
}
|
||||
|
||||
/* Semibold Italic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src: url('../fonts/OpenSans-SemiboldItalic-webfont.eot');
|
||||
src: url('../fonts/OpenSans-SemiboldItalic-webfont.eot?#iefix') format('embedded-opentype'),
|
||||
url('../fonts/OpenSans-SemiboldItalic-webfont.woff') format('woff'),
|
||||
url('../fonts/OpenSans-SemiboldItalic-webfont.ttf') format('truetype'),
|
||||
url('../fonts/OpenSans-SemiboldItalic-webfont.svg#OpenSansSemiboldItalic') format('svg');
|
||||
font-weight: 500;
|
||||
font-style: italic;
|
||||
|
||||
}
|
||||
|
||||
/* Bold */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src: url('../fonts/OpenSans-Bold-webfont.eot');
|
||||
src: url('../fonts/OpenSans-Bold-webfont.eot?#iefix') format('embedded-opentype'),
|
||||
url('../fonts/OpenSans-Bold-webfont.woff') format('woff'),
|
||||
url('../fonts/OpenSans-Bold-webfont.ttf') format('truetype'),
|
||||
url('../fonts/OpenSans-Bold-webfont.svg#OpenSansBold') format('svg');
|
||||
font-weight: bold;
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
|
||||
}
|
||||
|
||||
/* Bold Italic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src: url('../fonts/OpenSans-BoldItalic-webfont.eot');
|
||||
src: url('../fonts/OpenSans-BoldItalic-webfont.eot?#iefix') format('embedded-opentype'),
|
||||
url('../fonts/OpenSans-BoldItalic-webfont.woff') format('woff'),
|
||||
url('../fonts/OpenSans-BoldItalic-webfont.ttf') format('truetype'),
|
||||
url('../fonts/OpenSans-BoldItalic-webfont.svg#OpenSansBoldItalic') format('svg');
|
||||
font-weight: bold;
|
||||
font-weight: 700;
|
||||
font-style: italic;
|
||||
|
||||
}
|
||||
|
||||
/* Extra Bold */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src: url('../fonts/OpenSans-ExtraBold-webfont.eot');
|
||||
src: url('../fonts/OpenSans-ExtraBold-webfont.eot?#iefix') format('embedded-opentype'),
|
||||
url('../fonts/OpenSans-ExtraBold-webfont.woff') format('woff'),
|
||||
url('../fonts/OpenSans-ExtraBold-webfont.ttf') format('truetype'),
|
||||
url('../fonts/OpenSans-ExtraBold-webfont.svg#OpenSansExtrabold') format('svg');
|
||||
font-weight: 900;
|
||||
font-style: normal;
|
||||
|
||||
}
|
||||
|
||||
/* Extra Bold Italic */
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src: url('../fonts/OpenSans-ExtraBoldItalic-webfont.eot');
|
||||
src: url('../fonts/OpenSans-ExtraBoldItalic-webfont.eot?#iefix') format('embedded-opentype'),
|
||||
url('../fonts/OpenSans-ExtraBoldItalic-webfont.woff') format('woff'),
|
||||
url('../fonts/OpenSans-ExtraBoldItalic-webfont.ttf') format('truetype'),
|
||||
url('../fonts/OpenSans-ExtraBoldItalic-webfont.svg#OpenSansExtraboldItalic') format('svg');
|
||||
font-weight: 900;
|
||||
font-style: italic;
|
||||
|
||||
}
|
||||
|
||||
html {
|
||||
position: relative;
|
||||
min-height: 100%;
|
||||
margin:0;
|
||||
padding:0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family:'Open Sans';
|
||||
background:#fff;
|
||||
font-weight: 100;
|
||||
color: #444444;
|
||||
font-size: 14px;
|
||||
margin:0;
|
||||
padding:0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.container {
|
||||
position: relative;
|
||||
padding-bottom: 20px;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
.wr-content {
|
||||
padding-left:33px;
|
||||
padding-right:33px;
|
||||
}
|
||||
|
||||
/* application top level header */
|
||||
h2.app-title {
|
||||
font-weight:400;
|
||||
font-size:17px;
|
||||
margin:0;
|
||||
padding:3px 0 0 0;
|
||||
color:#fafafa;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.wr-global-header {
|
||||
background:#11375B;
|
||||
}
|
||||
|
||||
.app-logo {
|
||||
height:50px;
|
||||
padding:12px 10px;
|
||||
}
|
||||
|
||||
.app-logo a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.app-logo img {
|
||||
float:left;
|
||||
margin-right:10px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.app-logo {
|
||||
padding: 16px 10px;
|
||||
}
|
||||
.app-logo img {
|
||||
width: 50px;
|
||||
height: auto;
|
||||
margin-right:10px;
|
||||
}
|
||||
h2.app-title {
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 570px) {
|
||||
h2.app-title:after {
|
||||
content: "EMM";
|
||||
}
|
||||
h2.app-title span {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.wr-app-bar {
|
||||
background:#526A84;
|
||||
height:53px;
|
||||
}
|
||||
|
||||
header {
|
||||
height:50px;
|
||||
}
|
||||
|
||||
#nav.affix {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
z-index:100000;
|
||||
}
|
||||
|
||||
.auth-user {
|
||||
display:none;
|
||||
}
|
||||
|
||||
.wr-auth-container {
|
||||
padding-right:0;
|
||||
}
|
||||
|
||||
.auth-img {
|
||||
float: left;
|
||||
display:inline-block;
|
||||
height:50px;
|
||||
padding:8px 10px;
|
||||
font-size: 14px;
|
||||
color:#fff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.auth-img:hover {
|
||||
background:#526A84;
|
||||
}
|
||||
|
||||
.wr-auth.open .auth-img {
|
||||
background: #526A84;
|
||||
}
|
||||
|
||||
|
||||
/* sticky footer styles */
|
||||
.footer {
|
||||
height: 40px;
|
||||
background-color: #222;
|
||||
padding-top:5px;
|
||||
color:#fff;
|
||||
font-weight: 500;
|
||||
padding-left:20px;
|
||||
font-size:12px;
|
||||
letter-spacing: 1px;
|
||||
position:absolute;
|
||||
width: 100%;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.footer p {
|
||||
padding-top: 5px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* misc */
|
||||
br.c-both {
|
||||
clear:both;
|
||||
}
|
||||
|
||||
.wr-input-control .helper {
|
||||
font-weight:100;
|
||||
}
|
||||
|
||||
.wr-input-control .cus-col-25 {
|
||||
float:left;
|
||||
width:25%;
|
||||
}
|
||||
|
||||
.wr-input-control .cus-col-50 {
|
||||
float:left;
|
||||
width:60%;
|
||||
}
|
||||
|
||||
.wr-input-control .cus-col-70 {
|
||||
float:left;
|
||||
width:70%;
|
||||
}
|
||||
|
||||
.wr-input-control .cus-col-50 input {
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.wr-input-control .cus-col-70 input {
|
||||
width:95%;
|
||||
}
|
||||
|
||||
.wr-input-control .cus-col-25 input {
|
||||
width:65%;
|
||||
}
|
||||
|
||||
/*.wr-input-control .cus-col-50 span, .wr-input-control .cus-col-25 span {*/
|
||||
/*padding-left:20px;*/
|
||||
/*}*/
|
||||
|
||||
/* wizard */
|
||||
.wr-wizard {
|
||||
|
||||
}
|
||||
|
||||
.itm-wiz-current .wiz-no {
|
||||
border:1px solid #444;
|
||||
color:#fff;
|
||||
background:#444;
|
||||
}
|
||||
|
||||
.itm-wiz {
|
||||
font-weight:100;
|
||||
}
|
||||
|
||||
.itm-wiz div {
|
||||
display:inline-block;
|
||||
float:left;
|
||||
}
|
||||
|
||||
.wiz-no {
|
||||
width:50px;
|
||||
height:50px;
|
||||
font-size:33px;
|
||||
font-weight: 100;
|
||||
border-radius: 80px;
|
||||
border:1px solid #ccc;
|
||||
color:#fff;
|
||||
padding:0 12px 10px;
|
||||
display:inline-block;
|
||||
text-align: center;
|
||||
background:#ccc;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.wiz-lbl {
|
||||
width:190px;
|
||||
font-size:17px;
|
||||
}
|
||||
|
||||
.wiz-lbl > span {
|
||||
padding-top:0;
|
||||
display:inline-block;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,137 @@
|
||||
/* forms */
|
||||
.input-control {
|
||||
margin-bottom:20px;
|
||||
}
|
||||
|
||||
.input-control input, .input-control textarea {
|
||||
border: 1px #999 solid;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 6px 10px;
|
||||
z-index: 1;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
.input-control input:focus, .input-control textarea:focus {
|
||||
border-color: #555;
|
||||
box-shadow: 0 0px 0px rgba(229, 103, 23, 0.075) inset, 0 0 0px rgba(229, 103, 23, 0.6);
|
||||
outline: 0 none
|
||||
}
|
||||
|
||||
.input-control file {
|
||||
border: 1px #d9d9d9 solid !important;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 8px 15px;
|
||||
z-index: 1;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
.input-label {
|
||||
font-weight:100;
|
||||
font-size:18px;
|
||||
color:#555;
|
||||
}
|
||||
|
||||
.input-label {
|
||||
font-weight:400;
|
||||
font-size:14px;
|
||||
color:#555;
|
||||
}
|
||||
|
||||
.help-tip {
|
||||
font-size:14px;
|
||||
padding:0px 10px;
|
||||
color:#666;
|
||||
}
|
||||
|
||||
.wr-notification {
|
||||
background:#ff5353;
|
||||
padding:10px 20px;
|
||||
}
|
||||
|
||||
.form-val-error {
|
||||
font-size:13px;
|
||||
color:#ff2353;
|
||||
font-weight:400;
|
||||
display:inline-block;
|
||||
padding-top:3px;
|
||||
}
|
||||
|
||||
.wr-validation-summary {
|
||||
padding: 15px 0px 10px 0;
|
||||
border-top: 1px solid #ffe8e8;
|
||||
border-bottom: 1px solid #ffe8e8;
|
||||
background: #fff4f4;
|
||||
text-align: center;
|
||||
display:block;
|
||||
margin-bottom:15px;
|
||||
}
|
||||
|
||||
span.wr-validation-summary p {
|
||||
font-size:17px;
|
||||
font-weight:400;
|
||||
}
|
||||
|
||||
/* button group */
|
||||
.wr-buttons {
|
||||
margin-top:20px;
|
||||
}
|
||||
|
||||
/* text content */
|
||||
.wr-head h2 {
|
||||
font-weight:400;
|
||||
margin-bottom:20px;
|
||||
}
|
||||
|
||||
.wr-text p {
|
||||
font-size:24px;
|
||||
font-weight:100;
|
||||
color:#555;
|
||||
}
|
||||
|
||||
a.btn-download-agent {
|
||||
display:block;
|
||||
padding:15px 20px;
|
||||
background:#11375B;
|
||||
color:#fff;
|
||||
font-size:18px;
|
||||
font-weight:100;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a.btn-download-agent:hover {
|
||||
background:#16436D;
|
||||
}
|
||||
|
||||
.wr-agreement {
|
||||
padding:15px;
|
||||
border:1px solid #f0f0f0;
|
||||
background:#fafafa;
|
||||
height:320px;
|
||||
overflow-y:auto;
|
||||
}
|
||||
|
||||
.wr-agreement p {
|
||||
font-weight:400;
|
||||
margin-bottom:20px;
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-weight:400;
|
||||
margin-bottom:20px;
|
||||
font-size:18px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-weight:700;
|
||||
margin-bottom:20px;
|
||||
font-size:15px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.itm-wiz {
|
||||
margin-top: 20px;
|
||||
}
|
||||
@ -0,0 +1,567 @@
|
||||
body {
|
||||
overflow-x: hidden;
|
||||
-ms-overflow-x: hidden;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #526A84;
|
||||
}
|
||||
|
||||
textarea { width: 100%; }
|
||||
|
||||
h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
h1, .h1 {
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.well {
|
||||
border-radius: 0;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/* asset type switcher */
|
||||
.wr-asset-type-switcher .popover {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 1060;
|
||||
display: none;
|
||||
max-width: 451px;
|
||||
padding: 1px;
|
||||
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 1.42857143;
|
||||
text-align: left;
|
||||
white-space: normal;
|
||||
background-color: #232323;
|
||||
-webkit-background-clip: padding-box;
|
||||
background-clip: padding-box;
|
||||
border: 0 solid #232323;
|
||||
border: 0 solid rgba(0,0,0,.2);
|
||||
border-radius: 0;
|
||||
-webkit-box-shadow: 0 0 0 rgba(0,0,0,.2);
|
||||
box-shadow: 0 0 0 rgba(0,0,0,.2);
|
||||
padding-bottom:8px;
|
||||
}
|
||||
|
||||
.wr-asset-type-switcher .popover.bottom>.arrow {
|
||||
top: -11px;
|
||||
left: 50%;
|
||||
margin-left: -11px;
|
||||
border-top-width: 0;
|
||||
border-bottom-color: #232323;
|
||||
}
|
||||
|
||||
.wr-asset-type-switcher .popover>.arrow {
|
||||
border-width: 11px;
|
||||
}
|
||||
|
||||
.wr-asset-type-switcher .popover.bottom>.arrow:after {
|
||||
top: 1px;
|
||||
margin-left: -10px;
|
||||
content: " ";
|
||||
border-top-width: 0;
|
||||
border-bottom-color: #232323;
|
||||
}
|
||||
|
||||
.wr-asset-type-switcher .popover>.arrow, .popover>.arrow:after {
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-color: transparent;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.wr-asset-type-switcher .popover-content {
|
||||
padding: 6px 6px;
|
||||
}
|
||||
|
||||
.wr-asset-type-switcher .arrow {
|
||||
left:25px !important;
|
||||
}
|
||||
|
||||
.wr-asset-type-switcher .popover {
|
||||
left:10px !important;
|
||||
}
|
||||
|
||||
|
||||
/* sorting */
|
||||
.dropdown-menu {
|
||||
position: absolute;
|
||||
top: 40px;
|
||||
left: 0;
|
||||
z-index: 1000;
|
||||
display: none;
|
||||
float: left;
|
||||
min-width: 160px;
|
||||
padding: 5px 0;
|
||||
margin: 2px 10px 0;
|
||||
font-size: 14px;
|
||||
text-align: left;
|
||||
list-style: none;
|
||||
background-color: transparent;
|
||||
-webkit-background-clip: padding-box;
|
||||
background-clip: padding-box;
|
||||
border: 0 solid #ccc;
|
||||
border: 0 solid rgba(0,0,0,.15);
|
||||
border-radius: 0;
|
||||
-webkit-box-shadow: 0 0 0 rgba(0,0,0,.175);
|
||||
box-shadow: 0 0 0 rgba(0,0,0,.175);
|
||||
|
||||
}
|
||||
|
||||
.dropdown-menu-content {
|
||||
background-color: #e4e4e4;
|
||||
padding:10px 20px;
|
||||
color:#fff;
|
||||
}
|
||||
|
||||
.dropdown-menu-content a {
|
||||
color:#333;
|
||||
cursor:pointer;
|
||||
display:block;
|
||||
}
|
||||
|
||||
.wr-auth .cu-arrow {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 8px solid transparent;
|
||||
border-right: 8px solid transparent;
|
||||
border-bottom: 8px solid #e4e4e4;
|
||||
left:87%;
|
||||
position:relative;
|
||||
}
|
||||
|
||||
/* filter */
|
||||
.dropdown-menu {
|
||||
position: absolute;
|
||||
top: 40px;
|
||||
left: 0;
|
||||
z-index: 1000;
|
||||
display: none;
|
||||
float: left;
|
||||
min-width: 160px;
|
||||
padding: 5px 0;
|
||||
margin: 2px 5px 0;
|
||||
font-size: 14px;
|
||||
text-align: left;
|
||||
list-style: none;
|
||||
background-color: transparent;
|
||||
-webkit-background-clip: padding-box;
|
||||
background-clip: padding-box;
|
||||
border: 0 solid #ccc;
|
||||
border: 0 solid rgba(0,0,0,.15);
|
||||
border-radius: 0;
|
||||
-webkit-box-shadow: 0 0px 0px rgba(0,0,0,.175);
|
||||
box-shadow: 0 0 0 rgba(0,0,0,.175);
|
||||
|
||||
}
|
||||
|
||||
.dropdown-menu-content {
|
||||
background-color: #e4e4e4;
|
||||
padding:5px;
|
||||
color:#fff;
|
||||
}
|
||||
|
||||
.dropdown-menu-content a {
|
||||
color: #11375B;
|
||||
padding: 8px 10px;
|
||||
cursor:pointer;
|
||||
display:block;
|
||||
}
|
||||
|
||||
.dropdown-menu-content a:hover {
|
||||
color:#fff;
|
||||
background: #11375B;
|
||||
}
|
||||
|
||||
|
||||
/* category selection */
|
||||
a.ctrl-filter-category {
|
||||
display:inline-block;
|
||||
background:#237bd5;
|
||||
border:1px solid #237bd5;
|
||||
color:#fff;
|
||||
text-decoration:none;
|
||||
padding:7px 10px 7px 20px;
|
||||
width:230px;
|
||||
font-size:18px;
|
||||
font-weight:100;
|
||||
}
|
||||
|
||||
a.ctrl-filter-category:hover {
|
||||
background:#666;
|
||||
color:#e4e4e4;
|
||||
text-decoration: none;
|
||||
border:1px solid #666;
|
||||
}
|
||||
|
||||
.wr-filter-category .dropdown-menu {
|
||||
border:0px solid #237bd5;
|
||||
background:#237bd5;
|
||||
top:53px;
|
||||
left:20px;
|
||||
width:230px;
|
||||
padding-top:0;
|
||||
padding-bottom:0;
|
||||
color:#fff;
|
||||
font-size:17px;
|
||||
}
|
||||
|
||||
.wr-filter-category .dropdown-menu li a {
|
||||
padding-top:7px;
|
||||
padding-bottom:7px;
|
||||
font-weight:100;
|
||||
color:#fff;
|
||||
}
|
||||
|
||||
.wr-filter-category .dropdown-menu li a:hover {
|
||||
background:#61a3e6;
|
||||
}
|
||||
|
||||
.ctrl-filter-category .glyphicon {
|
||||
font-size:13px;
|
||||
font-weight:100;
|
||||
margin-left:33px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* panel */
|
||||
.panel-group .panel {
|
||||
margin-bottom: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.panel {
|
||||
margin-bottom: 0;
|
||||
background-color: transparent;
|
||||
border: 0 solid #e4e4e4;
|
||||
border-radius: 0;
|
||||
-webkit-box-shadow: 0 0 0 rgba(0, 0, 0, .05);
|
||||
box-shadow: 0 0 0 rgba(0, 0, 0, .05);
|
||||
}
|
||||
|
||||
.panel-default > .panel-heading {
|
||||
background-color: #999;
|
||||
border-color: #e4e4e4;
|
||||
}
|
||||
|
||||
.cu-acc-head-title {
|
||||
font-weight:400;
|
||||
font-size:22px;
|
||||
}
|
||||
|
||||
.cu-acc-head-title:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.panel-title a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.panel-heading {
|
||||
padding: 0 0 0 15px;
|
||||
border-bottom: 0 solid transparent;
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
|
||||
.panel-title table, .panel-body table {
|
||||
width:100%;
|
||||
border: 1px solid #c8c8c8;
|
||||
}
|
||||
|
||||
.panel-title a {
|
||||
color:#fff;
|
||||
}
|
||||
|
||||
.cu-acc-head-created {
|
||||
font-weight:200;
|
||||
font-size:16px;
|
||||
}
|
||||
|
||||
.cu-acc-head-workflow {
|
||||
font-weight:200;
|
||||
font-size:16px;
|
||||
}
|
||||
|
||||
.panel-group .panel-heading + .panel-collapse > .panel-body, .panel-group .panel-heading + .panel-collapse > .list-group {
|
||||
border-top: 0 solid #e4e4e4;
|
||||
}
|
||||
|
||||
.panel-body {
|
||||
padding: 10px;
|
||||
background:#f9f9f9;
|
||||
}
|
||||
|
||||
/* input */
|
||||
.form-control {
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
background-image: none;
|
||||
border: 1px solid #999;
|
||||
border-radius: 0;
|
||||
-webkit-box-shadow: inset 0 0 0 rgba(0, 0, 0, .075);
|
||||
box-shadow: inset 0 0 0 rgba(0, 0, 0, .075);
|
||||
-webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
|
||||
-o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
||||
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
border-color: #555;
|
||||
outline: 0;
|
||||
-webkit-box-shadow: inset 0 0 0 rgba(0,0,0,.075), 0 0 0 rgba(102, 175, 233, .6);
|
||||
box-shadow: inset 0 0 0 rgba(0,0,0,.075), 0 0 0 rgba(102, 175, 233, .6);
|
||||
}
|
||||
|
||||
.form-control.modal-input, .form-control.modal-input:focus {
|
||||
border: 1px solid #fff;
|
||||
}
|
||||
|
||||
|
||||
/* progress bar */
|
||||
.progress {
|
||||
height: 20px;
|
||||
margin-bottom: 20px;
|
||||
overflow: hidden;
|
||||
background-color: #e4e4e4;
|
||||
border-radius: 0;
|
||||
-webkit-box-shadow: inset 0 0 0 rgba(0, 0, 0, .1);
|
||||
box-shadow: inset 0 0 0 rgba(0, 0, 0, .1);
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
background-color: #6c5c76;
|
||||
}
|
||||
|
||||
.t-data-file {
|
||||
padding-right:20px;
|
||||
}
|
||||
|
||||
/* tabs */
|
||||
.nav-tabs {
|
||||
border-bottom: 1px solid #6c5c76;
|
||||
}
|
||||
|
||||
.nav-tabs > li > a {
|
||||
margin-right: 2px;
|
||||
line-height: 1.42857143;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 0;
|
||||
color:#6c5c76;
|
||||
}
|
||||
|
||||
.nav-tabs > li.active > a, .nav-tabs > li.active > a:hover, .nav-tabs > li.active > a:focus {
|
||||
color: #555;
|
||||
cursor: default;
|
||||
background-color: #fff;
|
||||
border: 1px solid #6c5c76;
|
||||
border-top:1px solid #6c5c76;
|
||||
border-bottom-color: transparent;
|
||||
}
|
||||
|
||||
.nav-tabs > li > a:hover {
|
||||
border-color: #6c5c76 #6c5c76 #6c5c76;
|
||||
}
|
||||
.nav > li > a:hover, .nav > li > a:focus {
|
||||
text-decoration: none;
|
||||
background-color: #6c5c76;
|
||||
color:#fff;
|
||||
}
|
||||
|
||||
/* nav pills */
|
||||
.wr-tabs-grphs .nav-pills > li.active > a, .wr-tabs-grphs .nav-pills > li.active > a:hover, .wr-tabs-grphs .nav-pills > li.active > a:focus {
|
||||
color: #fff;
|
||||
background-color: #888;
|
||||
}
|
||||
|
||||
.wr-tabs-grphs .nav-pills > li > a {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.wr-tabs-grphs {
|
||||
border-bottom:1px solid #e4e4e4;
|
||||
padding-bottom:10px;
|
||||
}
|
||||
|
||||
/* buttons */
|
||||
.btn-group {
|
||||
margin: 30px 0;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
color: #fff;
|
||||
background-color: #11375b;
|
||||
border-color: #11375b;
|
||||
}
|
||||
|
||||
.btn-primary:hover, .btn-primary:focus, .btn-primary.focus, .btn-primary:active, .btn-primary.active, .open > .dropdown-toggle.btn-primary {
|
||||
color: #fff;
|
||||
background-color: #526A84;
|
||||
border-color: #526A84;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: inline-block;
|
||||
padding: 8px 20px;
|
||||
margin-bottom: 0;
|
||||
font-size: 16px;
|
||||
font-weight: normal;
|
||||
line-height: 1.42857143;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
-ms-touch-action: manipulation;
|
||||
touch-action: manipulation;
|
||||
cursor: pointer;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
background-image: none;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 0;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
|
||||
.col-centered {
|
||||
float: none;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
b, strong {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.form-horizontal .control-label {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.form-horizontal .control-value {
|
||||
padding-top: 7px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.panel-group .panel-heading + .panel-collapse > .panel-body, .panel-group .panel-heading + .panel-collapse > .list-group {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.panel-default > .panel-heading {
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.panel-title a {
|
||||
color: #333333;
|
||||
padding:15px 0;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.panel-body {
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.list-group-item:first-child, .list-group-item:last-child { border-radius: 0; }
|
||||
|
||||
.row.no-gutter {
|
||||
margin-right: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.row.no-gutter > [class*='col-']:not(:first-child), .row.no-gutter > [class*='col-']:not(:last-child) {
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.table tr.row.no-gutter > td {
|
||||
border-top: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.table thead th {
|
||||
font-weight: 200;
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
select.select2 {
|
||||
height:0 !important;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.select2-container {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.select2-container--default .select2-selection--multiple, .select2-container--default .select2-selection--single {
|
||||
border-radius: 0;
|
||||
height: 34px;
|
||||
border: 1px solid #999;
|
||||
}
|
||||
|
||||
.select2-container .select2-search--inline .select2-search__field {
|
||||
margin-top: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.select2-container--default .select2-selection--multiple .select2-selection__rendered {
|
||||
padding: 5px 8px;
|
||||
}
|
||||
|
||||
.select2-container--default .select2-selection--single .select2-selection__rendered {
|
||||
line-height: 34px;
|
||||
}
|
||||
|
||||
.select2-container--default .select2-selection--multiple .select2-selection__choice {
|
||||
margin-bottom: 0;
|
||||
margin-top: 0;
|
||||
color: #ffffff;
|
||||
background: #526A84;
|
||||
font-size: 11px;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
padding: 3px 6px;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
|
||||
color: #ffffff;
|
||||
font-weight: 500;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {
|
||||
color: #ffffff;
|
||||
}
|
||||
.select2-container--default .select2-results__option--highlighted[aria-selected] {
|
||||
background-color: #526A84;
|
||||
}
|
||||
|
||||
.select2-dropdown {
|
||||
z-index: 10000;
|
||||
}
|
||||
|
||||
.ui-autocomplete {
|
||||
max-height: 400px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
* html .ui-autocomplete {
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
.qr-code canvas{
|
||||
border: 2px solid white;
|
||||
}
|
||||
Binary file not shown.
@ -0,0 +1,251 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata>
|
||||
This is a custom SVG webfont generated by Font Squirrel.
|
||||
Copyright : Digitized data copyright 20102011 Google Corporation
|
||||
Foundry : Ascender Corporation
|
||||
Foundry URL : httpwwwascendercorpcom
|
||||
</metadata>
|
||||
<defs>
|
||||
<font id="OpenSansBold" horiz-adv-x="1169" >
|
||||
<font-face units-per-em="2048" ascent="1638" descent="-410" />
|
||||
<missing-glyph horiz-adv-x="532" />
|
||||
<glyph unicode=" " horiz-adv-x="532" />
|
||||
<glyph unicode="	" horiz-adv-x="532" />
|
||||
<glyph unicode=" " horiz-adv-x="532" />
|
||||
<glyph unicode="!" horiz-adv-x="586" d="M117 143q0 84 45 127t131 43q83 0 128.5 -44t45.5 -126q0 -79 -46 -124.5t-128 -45.5q-84 0 -130 44.5t-46 125.5zM121 1462h346l-51 -977h-244z" />
|
||||
<glyph unicode=""" horiz-adv-x="967" d="M133 1462h279l-41 -528h-197zM555 1462h279l-41 -528h-197z" />
|
||||
<glyph unicode="#" horiz-adv-x="1323" d="M45 406v206h277l47 232h-252v209h289l77 407h219l-77 -407h198l78 407h215l-78 -407h240v-209h-279l-47 -232h258v-206h-297l-77 -406h-220l78 406h-194l-76 -406h-215l74 406h-238zM539 612h196l47 232h-196z" />
|
||||
<glyph unicode="$" d="M88 1049q0 145 113.5 238.5t316.5 113.5v153h137v-149q229 -10 414 -92l-94 -234q-156 64 -320 78v-295q195 -75 277.5 -130t121 -121t38.5 -154q0 -159 -115 -255.5t-322 -115.5v-205h-137v201q-244 5 -428 86v264q87 -43 209.5 -76t218.5 -39v310l-67 26 q-198 78 -280.5 169.5t-82.5 226.5zM389 1049q0 -44 30.5 -72.5t98.5 -58.5v235q-129 -19 -129 -104zM655 324q136 23 136 118q0 42 -34 71t-102 60v-249z" />
|
||||
<glyph unicode="%" horiz-adv-x="1845" d="M63 1026q0 457 345 457q169 0 259.5 -118.5t90.5 -338.5q0 -230 -89 -345.5t-261 -115.5q-165 0 -255 118.5t-90 342.5zM315 1024q0 -127 22.5 -189.5t72.5 -62.5q96 0 96 252q0 250 -96 250q-50 0 -72.5 -61.5t-22.5 -188.5zM395 0l811 1462h240l-811 -1462h-240z M1087 442q0 457 345 457q169 0 259.5 -118.5t90.5 -338.5q0 -229 -89 -344.5t-261 -115.5q-165 0 -255 118.5t-90 341.5zM1339 440q0 -127 22.5 -189.5t72.5 -62.5q96 0 96 252q0 250 -96 250q-50 0 -72.5 -61.5t-22.5 -188.5z" />
|
||||
<glyph unicode="&" horiz-adv-x="1536" d="M82 395q0 137 60.5 233.5t207.5 180.5q-75 86 -109 164.5t-34 171.5q0 152 116.5 245t311.5 93q186 0 297.5 -86.5t111.5 -231.5q0 -119 -69 -217.5t-223 -187.5l284 -277q71 117 123 301h318q-36 -135 -99 -263.5t-143 -227.5l301 -293h-377l-115 113 q-191 -133 -432 -133q-244 0 -387 112t-143 303zM403 424q0 -86 64.5 -137t165.5 -51q126 0 227 61l-332 330q-58 -44 -91.5 -92t-33.5 -111zM489 1124q0 -88 95 -194q86 48 132 94.5t46 108.5q0 53 -36 83.5t-93 30.5q-67 0 -105.5 -32t-38.5 -91z" />
|
||||
<glyph unicode="'" horiz-adv-x="545" d="M133 1462h279l-41 -528h-197z" />
|
||||
<glyph unicode="(" horiz-adv-x="694" d="M82 561q0 265 77.5 496t223.5 405h250q-141 -193 -213 -424t-72 -475q0 -245 73.5 -473.5t209.5 -413.5h-248q-147 170 -224 397t-77 488z" />
|
||||
<glyph unicode=")" horiz-adv-x="694" d="M61 1462h250q147 -175 224 -406.5t77 -494.5t-77.5 -490t-223.5 -395h-248q135 184 209 412.5t74 474.5q0 244 -72 475t-213 424z" />
|
||||
<glyph unicode="*" horiz-adv-x="1116" d="M63 1042l39 250l365 -104l-41 368h262l-41 -368l373 104l33 -252l-340 -24l223 -297l-227 -121l-156 313l-137 -311l-236 119l221 297z" />
|
||||
<glyph unicode="+" d="M88 612v219h387v390h219v-390h387v-219h-387v-385h-219v385h-387z" />
|
||||
<glyph unicode="," horiz-adv-x="594" d="M63 -264q65 266 101 502h280l15 -23q-52 -202 -176 -479h-220z" />
|
||||
<glyph unicode="-" horiz-adv-x="659" d="M61 424v250h537v-250h-537z" />
|
||||
<glyph unicode="." horiz-adv-x="584" d="M117 143q0 84 45 127t131 43q83 0 128.5 -44t45.5 -126q0 -79 -46 -124.5t-128 -45.5q-84 0 -130 44.5t-46 125.5z" />
|
||||
<glyph unicode="/" horiz-adv-x="846" d="M14 0l545 1462h277l-545 -1462h-277z" />
|
||||
<glyph unicode="0" d="M74 731q0 387 125 570.5t385 183.5q253 0 382.5 -192t129.5 -562q0 -383 -125.5 -567t-386.5 -184q-253 0 -381.5 190t-128.5 561zM381 731q0 -269 46.5 -385.5t156.5 -116.5q108 0 156 118t48 384q0 269 -48.5 386.5t-155.5 117.5q-109 0 -156 -117.5t-47 -386.5z" />
|
||||
<glyph unicode="1" d="M121 1087l471 375h254v-1462h-309v846l3 139l5 152q-77 -77 -107 -101l-168 -135z" />
|
||||
<glyph unicode="2" d="M78 1274q108 92 179 130t155 58.5t188 20.5q137 0 242 -50t163 -140t58 -206q0 -101 -35.5 -189.5t-110 -181.5t-262.5 -265l-188 -177v-14h637v-260h-1022v215l367 371q163 167 213 231.5t72 119.5t22 114q0 88 -48.5 131t-129.5 43q-85 0 -165 -39t-167 -111z" />
|
||||
<glyph unicode="3" d="M78 59v263q85 -43 187 -70t202 -27q153 0 226 52t73 167q0 103 -84 146t-268 43h-111v237h113q170 0 248.5 44.5t78.5 152.5q0 166 -208 166q-72 0 -146.5 -24t-165.5 -83l-143 213q200 144 477 144q227 0 358.5 -92t131.5 -256q0 -137 -83 -233t-233 -132v-6 q177 -22 268 -107.5t91 -230.5q0 -211 -153 -328.5t-437 -117.5q-238 0 -422 79z" />
|
||||
<glyph unicode="4" d="M35 303v215l641 944h285v-919h176v-240h-176v-303h-302v303h-624zM307 543h352v248q0 62 5 180t8 137h-8q-37 -82 -89 -160z" />
|
||||
<glyph unicode="5" d="M100 59v267q79 -42 184 -68.5t199 -26.5q283 0 283 232q0 221 -293 221q-53 0 -117 -10.5t-104 -22.5l-123 66l55 745h793v-262h-522l-27 -287l35 7q61 14 151 14q212 0 337.5 -119t125.5 -326q0 -245 -151 -377t-432 -132q-244 0 -394 79z" />
|
||||
<glyph unicode="6" d="M72 621q0 434 183.5 646t549.5 212q125 0 196 -15v-247q-89 20 -176 20q-159 0 -259.5 -48t-150.5 -142t-59 -267h13q99 170 317 170q196 0 307 -123t111 -340q0 -234 -132 -370.5t-366 -136.5q-162 0 -282.5 75t-186 219t-65.5 347zM379 510q0 -119 62.5 -201t158.5 -82 q99 0 152 66.5t53 189.5q0 107 -49.5 168.5t-149.5 61.5q-94 0 -160.5 -61t-66.5 -142z" />
|
||||
<glyph unicode="7" d="M55 1200v260h1049v-194l-553 -1266h-324l549 1200h-721z" />
|
||||
<glyph unicode="8" d="M72 371q0 125 66.5 222t213.5 171q-125 79 -180 169t-55 197q0 157 130 254t339 97q210 0 338.5 -95.5t128.5 -257.5q0 -112 -62 -199.5t-200 -156.5q164 -88 235.5 -183.5t71.5 -209.5q0 -180 -141 -289.5t-371 -109.5q-240 0 -377 102t-137 289zM358 389q0 -86 60 -134 t164 -48q115 0 172 49.5t57 130.5q0 67 -56.5 125.5t-183.5 124.5q-213 -98 -213 -248zM408 1106q0 -60 38.5 -107.5t139.5 -97.5q98 46 137 94t39 111q0 69 -50 109t-128 40q-79 0 -127.5 -40.5t-48.5 -108.5z" />
|
||||
<glyph unicode="9" d="M66 971q0 235 133.5 371.5t363.5 136.5q162 0 283.5 -76t186.5 -220.5t65 -344.5q0 -432 -182 -645t-551 -213q-130 0 -197 14v248q84 -21 176 -21q155 0 255 45.5t153 143t61 268.5h-12q-58 -94 -134 -132t-190 -38q-191 0 -301 122.5t-110 340.5zM365 975 q0 -106 49 -168t149 -62q94 0 161 61.5t67 141.5q0 119 -62.5 201t-159.5 82q-96 0 -150 -66t-54 -190z" />
|
||||
<glyph unicode=":" horiz-adv-x="584" d="M117 143q0 84 45 127t131 43q83 0 128.5 -44t45.5 -126q0 -79 -46 -124.5t-128 -45.5q-84 0 -130 44.5t-46 125.5zM117 969q0 84 45 127t131 43q83 0 128.5 -44t45.5 -126q0 -81 -46.5 -125.5t-127.5 -44.5q-84 0 -130 44t-46 126z" />
|
||||
<glyph unicode=";" horiz-adv-x="594" d="M63 -264q65 266 101 502h280l15 -23q-52 -202 -176 -479h-220zM117 969q0 84 45 127t131 43q83 0 128.5 -44t45.5 -126q0 -81 -46.5 -125.5t-127.5 -44.5q-84 0 -130 44t-46 126z" />
|
||||
<glyph unicode="<" d="M88 641v143l993 496v-240l-684 -317l684 -281v-239z" />
|
||||
<glyph unicode="=" d="M88 418v219h993v-219h-993zM88 805v219h993v-219h-993z" />
|
||||
<glyph unicode=">" d="M88 203v239l684 281l-684 317v240l993 -496v-143z" />
|
||||
<glyph unicode="?" horiz-adv-x="977" d="M6 1358q223 125 473 125q206 0 327.5 -99t121.5 -264q0 -110 -50 -190t-190 -180q-96 -71 -121.5 -108t-25.5 -97v-60h-265v74q0 96 41 167t150 151q105 75 138.5 122t33.5 105q0 65 -48 99t-134 34q-150 0 -342 -98zM244 143q0 84 45 127t131 43q83 0 128.5 -44 t45.5 -126q0 -79 -46 -124.5t-128 -45.5q-84 0 -130 44.5t-46 125.5z" />
|
||||
<glyph unicode="@" horiz-adv-x="1837" d="M102 602q0 247 108.5 448.5t309 316t461.5 114.5q220 0 393 -90t267 -256t94 -383q0 -144 -46 -263.5t-130 -187.5t-195 -68q-74 0 -131 35.5t-82 93.5h-16q-108 -129 -275 -129q-177 0 -279 106.5t-102 291.5q0 211 134 340t350 129q86 0 189.5 -16.5t170.5 -39.5 l-23 -489q0 -139 76 -139q64 0 102 93.5t38 244.5q0 161 -67 284.5t-188.5 188.5t-277.5 65q-202 0 -351 -83t-228.5 -239.5t-79.5 -361.5q0 -276 147.5 -423.5t427.5 -147.5q106 0 233 23.5t250 68.5v-192q-214 -91 -475 -91q-380 0 -592.5 200t-212.5 556zM711 627 q0 -211 172 -211q90 0 137 63.5t57 206.5l13 221q-51 11 -115 11q-125 0 -194.5 -78t-69.5 -213z" />
|
||||
<glyph unicode="A" horiz-adv-x="1413" d="M0 0l516 1468h379l518 -1468h-334l-106 348h-533l-106 -348h-334zM518 608h381q-147 473 -165.5 535t-26.5 98q-33 -128 -189 -633z" />
|
||||
<glyph unicode="B" horiz-adv-x="1376" d="M184 0v1462h455q311 0 451.5 -88.5t140.5 -281.5q0 -131 -61.5 -215t-163.5 -101v-10q139 -31 200.5 -116t61.5 -226q0 -200 -144.5 -312t-392.5 -112h-547zM494 256h202q128 0 189 49t61 150q0 182 -260 182h-192v-381zM494 883h180q126 0 182.5 39t56.5 129 q0 84 -61.5 120.5t-194.5 36.5h-163v-325z" />
|
||||
<glyph unicode="C" horiz-adv-x="1305" d="M119 729q0 228 83 399.5t238.5 263t364.5 91.5q213 0 428 -103l-100 -252q-82 39 -165 68t-163 29q-175 0 -271 -131.5t-96 -366.5q0 -489 367 -489q154 0 373 77v-260q-180 -75 -402 -75q-319 0 -488 193.5t-169 555.5z" />
|
||||
<glyph unicode="D" horiz-adv-x="1516" d="M184 0v1462h459q358 0 556 -189t198 -528q0 -361 -205.5 -553t-593.5 -192h-414zM494 256h133q448 0 448 481q0 471 -416 471h-165v-952z" />
|
||||
<glyph unicode="E" horiz-adv-x="1147" d="M184 0v1462h842v-254h-532v-321h495v-254h-495v-377h532v-256h-842z" />
|
||||
<glyph unicode="F" horiz-adv-x="1124" d="M184 0v1462h838v-254h-533v-377h496v-253h-496v-578h-305z" />
|
||||
<glyph unicode="G" horiz-adv-x="1483" d="M119 733q0 354 202.5 552t561.5 198q225 0 434 -90l-103 -248q-160 80 -333 80q-201 0 -322 -135t-121 -363q0 -238 97.5 -363.5t283.5 -125.5q97 0 197 20v305h-277v258h580v-758q-141 -46 -265.5 -64.5t-254.5 -18.5q-331 0 -505.5 194.5t-174.5 558.5z" />
|
||||
<glyph unicode="H" horiz-adv-x="1567" d="M184 0v1462h310v-573h579v573h309v-1462h-309v631h-579v-631h-310z" />
|
||||
<glyph unicode="I" horiz-adv-x="678" d="M184 0v1462h310v-1462h-310z" />
|
||||
<glyph unicode="J" horiz-adv-x="678" d="M-152 -150q80 -20 146 -20q102 0 146 63.5t44 198.5v1370h310v-1368q0 -256 -117 -390t-346 -134q-105 0 -183 22v258z" />
|
||||
<glyph unicode="K" horiz-adv-x="1360" d="M184 0v1462h310v-669l122 172l396 497h344l-510 -647l514 -815h-352l-383 616l-131 -94v-522h-310z" />
|
||||
<glyph unicode="L" horiz-adv-x="1157" d="M184 0v1462h310v-1206h593v-256h-903z" />
|
||||
<glyph unicode="M" horiz-adv-x="1931" d="M184 0v1462h422l346 -1118h6l367 1118h422v-1462h-289v692q0 49 1.5 113t13.5 340h-9l-377 -1145h-284l-352 1147h-9q19 -350 19 -467v-680h-277z" />
|
||||
<glyph unicode="N" horiz-adv-x="1665" d="M184 0v1462h391l635 -1095h7q-15 285 -15 403v692h279v-1462h-394l-636 1106h-9q19 -293 19 -418v-688h-277z" />
|
||||
<glyph unicode="O" horiz-adv-x="1630" d="M119 735q0 365 180.5 557.5t517.5 192.5t515.5 -194t178.5 -558q0 -363 -180 -558t-516 -195t-516 195t-180 560zM444 733q0 -245 93 -369t278 -124q371 0 371 493q0 494 -369 494q-185 0 -279 -124.5t-94 -369.5z" />
|
||||
<glyph unicode="P" horiz-adv-x="1286" d="M184 0v1462h467q266 0 404.5 -114.5t138.5 -341.5q0 -236 -147.5 -361t-419.5 -125h-133v-520h-310zM494 774h102q143 0 214 56.5t71 164.5q0 109 -59.5 161t-186.5 52h-141v-434z" />
|
||||
<glyph unicode="Q" horiz-adv-x="1630" d="M119 735q0 365 180.5 557.5t517.5 192.5t515.5 -194t178.5 -558q0 -258 -91.5 -432.5t-268.5 -255.5l352 -393h-397l-268 328h-23q-336 0 -516 195t-180 560zM444 733q0 -245 93 -369t278 -124q371 0 371 493q0 494 -369 494q-185 0 -279 -124.5t-94 -369.5z" />
|
||||
<glyph unicode="R" horiz-adv-x="1352" d="M184 0v1462h426q298 0 441 -108.5t143 -329.5q0 -129 -71 -229.5t-201 -157.5q330 -493 430 -637h-344l-349 561h-165v-561h-310zM494 813h100q147 0 217 49t70 154q0 104 -71.5 148t-221.5 44h-94v-395z" />
|
||||
<glyph unicode="S" horiz-adv-x="1128" d="M94 68v288q148 -66 250.5 -93t187.5 -27q102 0 156.5 39t54.5 116q0 43 -24 76.5t-70.5 64.5t-189.5 99q-134 63 -201 121t-107 135t-40 180q0 194 131.5 305t363.5 111q114 0 217.5 -27t216.5 -76l-100 -241q-117 48 -193.5 67t-150.5 19q-88 0 -135 -41t-47 -107 q0 -41 19 -71.5t60.5 -59t196.5 -102.5q205 -98 281 -196.5t76 -241.5q0 -198 -142.5 -312t-396.5 -114q-234 0 -414 88z" />
|
||||
<glyph unicode="T" horiz-adv-x="1186" d="M41 1204v258h1104v-258h-397v-1204h-310v1204h-397z" />
|
||||
<glyph unicode="U" horiz-adv-x="1548" d="M174 520v942h309v-895q0 -169 68 -248t225 -79q152 0 220.5 79.5t68.5 249.5v893h309v-946q0 -162 -72.5 -284t-209.5 -187t-324 -65q-282 0 -438 144.5t-156 395.5z" />
|
||||
<glyph unicode="V" horiz-adv-x="1331" d="M0 1462h313l275 -870q23 -77 47.5 -179.5t30.5 -142.5q11 92 75 322l277 870h313l-497 -1462h-338z" />
|
||||
<glyph unicode="W" horiz-adv-x="1980" d="M0 1462h305l187 -798q49 -221 71 -383q6 57 27.5 176.5t40.5 185.5l213 819h293l213 -819q14 -55 35 -168t32 -194q10 78 32 194.5t40 188.5l186 798h305l-372 -1462h-353l-198 768q-11 41 -37.5 169.5t-30.5 172.5q-6 -54 -30 -173.5t-37 -170.5l-197 -766h-352z" />
|
||||
<glyph unicode="X" horiz-adv-x="1366" d="M0 0l485 754l-454 708h342l315 -526l309 526h334l-459 -725l494 -737h-354l-340 553l-340 -553h-332z" />
|
||||
<glyph unicode="Y" horiz-adv-x="1278" d="M0 1462h336l303 -602l305 602h334l-485 -893v-569h-308v559z" />
|
||||
<glyph unicode="Z" horiz-adv-x="1186" d="M49 0v201l701 1005h-682v256h1050v-200l-700 -1006h719v-256h-1088z" />
|
||||
<glyph unicode="[" horiz-adv-x="678" d="M143 -324v1786h484v-211h-224v-1364h224v-211h-484z" />
|
||||
<glyph unicode="\" horiz-adv-x="846" d="M12 1462h277l545 -1462h-277z" />
|
||||
<glyph unicode="]" horiz-adv-x="678" d="M51 -113h223v1364h-223v211h484v-1786h-484v211z" />
|
||||
<glyph unicode="^" horiz-adv-x="1090" d="M8 520l438 950h144l495 -950h-239l-322 643l-280 -643h-236z" />
|
||||
<glyph unicode="_" horiz-adv-x="842" d="M-4 -184h850v-140h-850v140z" />
|
||||
<glyph unicode="`" horiz-adv-x="1243" d="M332 1548v21h342q63 -101 235 -301v-27h-202q-63 44 -185 142.5t-190 164.5z" />
|
||||
<glyph unicode="a" horiz-adv-x="1237" d="M86 334q0 178 124.5 262.5t375.5 93.5l194 6v49q0 170 -174 170q-134 0 -315 -81l-101 206q193 101 428 101q225 0 345 -98t120 -298v-745h-213l-59 152h-8q-77 -97 -158.5 -134.5t-212.5 -37.5q-161 0 -253.5 92t-92.5 262zM399 332q0 -129 148 -129q106 0 169.5 61 t63.5 162v92l-118 -4q-133 -4 -198 -48t-65 -134z" />
|
||||
<glyph unicode="b" horiz-adv-x="1296" d="M160 0v1556h305v-362q0 -69 -12 -221h12q107 166 317 166q198 0 310 -154.5t112 -423.5q0 -277 -115.5 -429t-314.5 -152q-197 0 -309 143h-21l-51 -123h-233zM465 563q0 -180 53.5 -258t169.5 -78q94 0 149.5 86.5t55.5 251.5t-56 247.5t-153 82.5q-113 0 -165 -69.5 t-54 -229.5v-33z" />
|
||||
<glyph unicode="c" horiz-adv-x="1053" d="M92 553q0 285 142 435.5t407 150.5q194 0 348 -76l-90 -236q-72 29 -134 47.5t-124 18.5q-238 0 -238 -338q0 -328 238 -328q88 0 163 23.5t150 73.5v-261q-74 -47 -149.5 -65t-190.5 -18q-522 0 -522 573z" />
|
||||
<glyph unicode="d" horiz-adv-x="1296" d="M92 557q0 275 114.5 428.5t315.5 153.5q211 0 322 -164h10q-23 125 -23 223v358h306v-1556h-234l-59 145h-13q-104 -165 -317 -165q-197 0 -309.5 153t-112.5 424zM401 553q0 -165 57 -247.5t163 -82.5q117 0 171.5 68t59.5 231v33q0 180 -55.5 258t-180.5 78 q-102 0 -158.5 -86.5t-56.5 -251.5z" />
|
||||
<glyph unicode="e" horiz-adv-x="1210" d="M92 551q0 281 140.5 434.5t388.5 153.5q237 0 369 -135t132 -373v-148h-721q5 -130 77 -203t202 -73q101 0 191 21t188 67v-236q-80 -40 -171 -59.5t-222 -19.5q-270 0 -422 149t-152 422zM408 686h428q-2 113 -59 174.5t-154 61.5t-152 -61.5t-63 -174.5z" />
|
||||
<glyph unicode="f" horiz-adv-x="793" d="M41 889v147l168 82v82q0 191 94 279t301 88q158 0 281 -47l-78 -224q-92 29 -170 29q-65 0 -94 -38.5t-29 -98.5v-70h264v-229h-264v-889h-305v889h-168z" />
|
||||
<glyph unicode="g" horiz-adv-x="1157" d="M6 -182q0 101 63 169t185 97q-47 20 -82 65.5t-35 96.5q0 64 37 106.5t107 83.5q-88 38 -139.5 122t-51.5 198q0 183 119 283t340 100q47 0 111.5 -8.5t82.5 -12.5h390v-155l-175 -45q48 -75 48 -168q0 -180 -125.5 -280.5t-348.5 -100.5l-55 3l-45 5q-47 -36 -47 -80 q0 -66 168 -66h190q184 0 280.5 -79t96.5 -232q0 -196 -163.5 -304t-469.5 -108q-234 0 -357.5 81.5t-123.5 228.5zM270 -158q0 -63 60.5 -99t169.5 -36q164 0 257 45t93 123q0 63 -55 87t-170 24h-158q-84 0 -140.5 -39.5t-56.5 -104.5zM381 752q0 -91 41.5 -144t126.5 -53 q86 0 126 53t40 144q0 202 -166 202q-168 0 -168 -202z" />
|
||||
<glyph unicode="h" horiz-adv-x="1346" d="M160 0v1556h305v-317q0 -37 -7 -174l-7 -90h16q102 164 324 164q197 0 299 -106t102 -304v-729h-305v653q0 242 -180 242q-128 0 -185 -87t-57 -282v-526h-305z" />
|
||||
<glyph unicode="i" horiz-adv-x="625" d="M147 1407q0 149 166 149t166 -149q0 -71 -41.5 -110.5t-124.5 -39.5q-166 0 -166 150zM160 0v1118h305v-1118h-305z" />
|
||||
<glyph unicode="j" horiz-adv-x="625" d="M-131 -227q70 -19 143 -19q77 0 112.5 43t35.5 127v1194h305v-1239q0 -178 -103 -274.5t-292 -96.5q-117 0 -201 25v240zM147 1407q0 149 166 149t166 -149q0 -71 -41.5 -110.5t-124.5 -39.5q-166 0 -166 150z" />
|
||||
<glyph unicode="k" horiz-adv-x="1270" d="M160 0v1556h305v-694l-16 -254h4l133 170l313 340h344l-444 -485l471 -633h-352l-322 453l-131 -105v-348h-305z" />
|
||||
<glyph unicode="l" horiz-adv-x="625" d="M160 0v1556h305v-1556h-305z" />
|
||||
<glyph unicode="m" horiz-adv-x="2011" d="M160 0v1118h233l41 -143h17q45 77 130 120.5t195 43.5q251 0 340 -164h27q45 78 132.5 121t197.5 43q190 0 287.5 -97.5t97.5 -312.5v-729h-306v653q0 121 -40.5 181.5t-127.5 60.5q-112 0 -167.5 -80t-55.5 -254v-561h-305v653q0 121 -40.5 181.5t-127.5 60.5 q-117 0 -170 -86t-53 -283v-526h-305z" />
|
||||
<glyph unicode="n" horiz-adv-x="1346" d="M160 0v1118h233l41 -143h17q51 81 140.5 122.5t203.5 41.5q195 0 296 -105.5t101 -304.5v-729h-305v653q0 121 -43 181.5t-137 60.5q-128 0 -185 -85.5t-57 -283.5v-526h-305z" />
|
||||
<glyph unicode="o" horiz-adv-x="1268" d="M92 561q0 274 143 426t402 152q161 0 284 -70t189 -201t66 -307q0 -273 -144 -427t-401 -154q-161 0 -284 70.5t-189 202.5t-66 308zM403 561q0 -166 54.5 -251t177.5 -85q122 0 175.5 84.5t53.5 251.5q0 166 -54 249t-177 83q-122 0 -176 -82.5t-54 -249.5z" />
|
||||
<glyph unicode="p" horiz-adv-x="1296" d="M160 -492v1610h248l43 -145h14q107 166 317 166q198 0 310 -153t112 -425q0 -179 -52.5 -311t-149.5 -201t-228 -69q-197 0 -309 143h-16q16 -140 16 -162v-453h-305zM465 563q0 -180 53.5 -258t169.5 -78q205 0 205 338q0 165 -50.5 247.5t-158.5 82.5 q-113 0 -165 -69.5t-54 -229.5v-33z" />
|
||||
<glyph unicode="q" horiz-adv-x="1296" d="M92 557q0 274 114.5 428t313.5 154q106 0 185 -40t139 -124h8l27 143h258v-1610h-306v469q0 61 13 168h-13q-49 -81 -130 -123t-187 -42q-198 0 -310 152.5t-112 424.5zM403 553q0 -168 53.5 -251t166.5 -83q116 0 170 66.5t59 232.5v37q0 180 -55.5 258t-178.5 78 q-215 0 -215 -338z" />
|
||||
<glyph unicode="r" horiz-adv-x="930" d="M160 0v1118h231l45 -188h15q52 94 140.5 151.5t192.5 57.5q62 0 103 -9l-23 -286q-37 10 -90 10q-146 0 -227.5 -75t-81.5 -210v-569h-305z" />
|
||||
<glyph unicode="s" horiz-adv-x="1018" d="M92 827q0 149 115.5 230.5t327.5 81.5q202 0 393 -88l-92 -220q-84 36 -157 59t-149 23q-135 0 -135 -73q0 -41 43.5 -71t190.5 -89q131 -53 192 -99t90 -106t29 -143q0 -172 -119.5 -262t-357.5 -90q-122 0 -208 16.5t-161 48.5v252q85 -40 191.5 -67t187.5 -27 q166 0 166 96q0 36 -22 58.5t-76 51t-144 66.5q-129 54 -189.5 100t-88 105.5t-27.5 146.5z" />
|
||||
<glyph unicode="t" horiz-adv-x="889" d="M47 889v129l168 102l88 236h195v-238h313v-229h-313v-539q0 -65 36.5 -96t96.5 -31q80 0 192 35v-227q-114 -51 -280 -51q-183 0 -266.5 92.5t-83.5 277.5v539h-146z" />
|
||||
<glyph unicode="u" horiz-adv-x="1346" d="M154 389v729h305v-653q0 -121 43 -181.5t137 -60.5q128 0 185 85.5t57 283.5v526h305v-1118h-234l-41 143h-16q-49 -78 -139 -120.5t-205 -42.5q-197 0 -297 105.5t-100 303.5z" />
|
||||
<glyph unicode="v" horiz-adv-x="1165" d="M0 1118h319l216 -637q36 -121 45 -229h6q5 96 45 229l215 637h319l-426 -1118h-313z" />
|
||||
<glyph unicode="w" horiz-adv-x="1753" d="M20 1118h304l129 -495q31 -133 63 -367h6q4 76 35 241l16 85l138 536h336l131 -536q4 -22 12.5 -65t16.5 -91.5t14.5 -95t7.5 -74.5h6q9 72 32 197.5t33 169.5l134 495h299l-322 -1118h-332l-86 391l-116 494h-7l-204 -885h-328z" />
|
||||
<glyph unicode="x" horiz-adv-x="1184" d="M10 0l379 571l-360 547h346l217 -356l219 356h346l-364 -547l381 -571h-347l-235 383l-236 -383h-346z" />
|
||||
<glyph unicode="y" horiz-adv-x="1165" d="M0 1118h334l211 -629q27 -82 37 -194h6q11 103 43 194l207 629h327l-473 -1261q-65 -175 -185.5 -262t-281.5 -87q-79 0 -155 17v242q55 -13 120 -13q81 0 141.5 49.5t94.5 149.5l18 55z" />
|
||||
<glyph unicode="z" horiz-adv-x="999" d="M55 0v180l518 705h-487v233h834v-198l-504 -687h522v-233h-883z" />
|
||||
<glyph unicode="{" horiz-adv-x="807" d="M31 449v239q126 0 191 44t65 126v8v318q0 153 97 215.5t341 62.5v-225q-99 -3 -136.5 -38t-37.5 -103v-299q-6 -188 -234 -222v-12q234 -35 234 -212v-9v-299q0 -68 37 -103t137 -38v-226q-244 0 -341 62.5t-97 216.5v315q0 87 -65.5 133t-190.5 46z" />
|
||||
<glyph unicode="|" horiz-adv-x="1128" d="M455 -465v2015h219v-2015h-219z" />
|
||||
<glyph unicode="}" horiz-adv-x="807" d="M82 -98q99 2 136.5 36t37.5 105v299v11q0 86 59 139.5t174 70.5v12q-227 34 -233 222v299q0 70 -37 104t-137 37v225q167 0 262 -26.5t135.5 -84t40.5 -167.5v-318v-10q0 -84 61.5 -126t194.5 -42v-239q-125 0 -190.5 -41t-65.5 -138v-315q0 -112 -41 -169t-135.5 -83.5 t-261.5 -26.5v226z" />
|
||||
<glyph unicode="~" d="M88 551v231q103 109 256 109q73 0 137.5 -16t139.5 -48q129 -55 227 -55q53 0 116 32t117 89v-231q-101 -109 -256 -109q-66 0 -126 13t-150 50q-131 56 -227 56q-55 0 -117.5 -33.5t-116.5 -87.5z" />
|
||||
<glyph unicode="¡" horiz-adv-x="586" d="M117 -369l51 975h244l51 -975h-346zM117 948q0 81 46.5 125.5t127.5 44.5q84 0 130 -44t46 -126q0 -84 -45 -127t-131 -43q-83 0 -128.5 44t-45.5 126z" />
|
||||
<glyph unicode="¢" d="M143 741q0 261 104.5 403t315.5 173v166h178v-158q166 -9 299 -74l-90 -235q-72 29 -134 47t-124 18q-121 0 -179 -83.5t-58 -254.5q0 -327 237 -327q82 0 148 15.5t166 60.5v-254q-127 -61 -265 -70v-188h-178v196q-420 59 -420 565z" />
|
||||
<glyph unicode="£" d="M82 0v248q103 44 141.5 101t38.5 157v145h-178v219h178v195q0 201 114.5 309.5t323.5 108.5q195 0 390 -82l-93 -230q-157 64 -272 64q-78 0 -120 -44.5t-42 -127.5v-193h375v-219h-375v-143q0 -170 -151 -248h718v-260h-1048z" />
|
||||
<glyph unicode="¤" d="M113 1047l147 147l127 -127q91 53 197 53q105 0 196 -55l127 129l150 -143l-129 -129q53 -89 53 -199q0 -107 -53 -199l125 -125l-146 -145l-127 125q-95 -51 -196 -51q-115 0 -199 51l-125 -123l-145 145l127 125q-54 93 -54 197q0 102 54 197zM395 723 q0 -77 54.5 -132.5t134.5 -55.5q81 0 136.5 55t55.5 133q0 80 -56.5 135t-135.5 55q-78 0 -133.5 -56t-55.5 -134z" />
|
||||
<glyph unicode="¥" d="M6 1462h316l262 -602l264 602h313l-383 -747h195v-178h-246v-138h246v-178h-246v-221h-287v221h-247v178h247v138h-247v178h190z" />
|
||||
<glyph unicode="¦" horiz-adv-x="1128" d="M455 350h219v-815h-219v815zM455 735v815h219v-815h-219z" />
|
||||
<glyph unicode="§" horiz-adv-x="995" d="M106 59v207q81 -41 180 -69.5t169 -28.5q194 0 194 117q0 39 -18.5 63t-63.5 49.5t-125 59.5q-183 74 -252 152.5t-69 195.5q0 79 36 144.5t97 105.5q-133 84 -133 233q0 131 111.5 210t293.5 79q170 0 363 -84l-82 -190q-68 32 -138.5 57.5t-148.5 25.5q-81 0 -118 -23 t-37 -71q0 -49 49.5 -86t163.5 -82q163 -64 240 -148.5t77 -193.5q0 -177 -125 -260q62 -40 93.5 -92.5t31.5 -126.5q0 -148 -119.5 -235.5t-320.5 -87.5q-203 0 -349 79zM344 827q0 -67 65 -119t181 -98q78 57 78 146q0 68 -50.5 115t-183.5 96q-37 -14 -63.5 -53.5 t-26.5 -86.5z" />
|
||||
<glyph unicode="¨" horiz-adv-x="1243" d="M279 1405q0 65 37.5 100t101.5 35q66 0 103.5 -37t37.5 -98q0 -60 -38 -96.5t-103 -36.5q-64 0 -101.5 35t-37.5 98zM682 1405q0 70 40.5 102.5t100.5 32.5q65 0 103.5 -36t38.5 -99q0 -61 -39 -97t-103 -36q-60 0 -100.5 32.5t-40.5 100.5z" />
|
||||
<glyph unicode="©" horiz-adv-x="1704" d="M100 731q0 200 100 375t275 276t377 101q200 0 375 -100t276 -275t101 -377q0 -197 -97 -370t-272 -277t-383 -104q-207 0 -382 103.5t-272.5 276.5t-97.5 371zM242 731q0 -164 82 -305.5t224 -223t304 -81.5q164 0 305.5 82t223 224t81.5 304q0 164 -82 305.5t-224 223 t-304 81.5q-164 0 -305.5 -82t-223 -224t-81.5 -304zM461 733q0 220 110.5 342.5t309.5 122.5q149 0 305 -78l-74 -168q-113 58 -217 58q-97 0 -150 -74t-53 -205q0 -280 203 -280q57 0 123 15t123 44v-191q-120 -57 -252 -57q-204 0 -316 125t-112 346z" />
|
||||
<glyph unicode="ª" horiz-adv-x="784" d="M47 975q0 109 82.5 163.5t267.5 63.5l99 4q0 117 -127 117q-81 0 -217 -61l-66 135q66 32 145.5 57t178.5 25q137 0 211.5 -71t74.5 -202v-442h-135l-31 110q-43 -58 -105 -90t-136 -32q-117 0 -179.5 58.5t-62.5 164.5zM252 977q0 -38 23 -56t55 -18q77 0 121.5 41.5 t44.5 106.5v36l-99 -6q-145 -10 -145 -104z" />
|
||||
<glyph unicode="«" horiz-adv-x="1260" d="M82 547v26l371 455l219 -119l-279 -348l279 -348l-219 -119zM588 547v26l370 455l220 -119l-279 -348l279 -348l-220 -119z" />
|
||||
<glyph unicode="¬" d="M88 612v219h993v-583h-219v364h-774z" />
|
||||
<glyph unicode="­" horiz-adv-x="659" d="M61 424v250h537v-250h-537z" />
|
||||
<glyph unicode="®" horiz-adv-x="1704" d="M100 731q0 200 100 375t275 276t377 101q200 0 375 -100t276 -275t101 -377q0 -197 -97 -370t-272 -277t-383 -104q-207 0 -382 103.5t-272.5 276.5t-97.5 371zM242 731q0 -164 82 -305.5t224 -223t304 -81.5q164 0 305.5 82t223 224t81.5 304q0 164 -82 305.5t-224 223 t-304 81.5q-164 0 -305.5 -82t-223 -224t-81.5 -304zM543 272v916h264q181 0 265.5 -70t84.5 -213q0 -170 -143 -233l237 -400h-254l-178 338h-47v-338h-229zM772 778h31q66 0 94.5 28.5t28.5 94.5q0 65 -28 92t-97 27h-29v-242z" />
|
||||
<glyph unicode="¯" horiz-adv-x="1024" d="M-6 1556v201h1036v-201h-1036z" />
|
||||
<glyph unicode="°" horiz-adv-x="877" d="M92 1137q0 92 46 172t126 127t174 47q92 0 172.5 -46t127 -127t46.5 -173q0 -93 -46.5 -173.5t-126.5 -125.5t-173 -45q-145 0 -245.5 99.5t-100.5 244.5zM283 1137q0 -64 44.5 -109t110.5 -45t111 46t45 108q0 63 -45.5 110t-110.5 47q-64 0 -109.5 -46t-45.5 -111z" />
|
||||
<glyph unicode="±" d="M88 0v219h993v-219h-993zM88 674v219h387v389h219v-389h387v-219h-387v-385h-219v385h-387z" />
|
||||
<glyph unicode="²" horiz-adv-x="776" d="M47 1354q147 129 336 129q137 0 216 -66.5t79 -183.5q0 -85 -47 -160t-176 -192l-105 -95h352v-200h-647v168l224 219q102 100 130.5 144.5t28.5 94.5q0 38 -24 58t-64 20q-81 0 -180 -88z" />
|
||||
<glyph unicode="³" horiz-adv-x="776" d="M59 639v190q148 -90 271 -90q143 0 143 107q0 53 -44 79.5t-122 26.5h-112v160h92q83 0 123.5 26t40.5 83q0 38 -25 63t-76 25q-47 0 -89 -19t-99 -59l-101 141q62 47 137.5 78t178.5 31q127 0 208 -64t81 -168q0 -143 -170 -198v-13q94 -20 146 -75t52 -134 q0 -121 -88 -190.5t-274 -69.5q-143 0 -273 70z" />
|
||||
<glyph unicode="´" horiz-adv-x="1243" d="M332 1241v27q172 200 235 301h342v-21q-52 -52 -177.5 -154.5t-196.5 -152.5h-203z" />
|
||||
<glyph unicode="µ" horiz-adv-x="1352" d="M160 -492v1610h305v-653q0 -121 44 -181.5t138 -60.5q126 0 183 86.5t57 282.5v526h305v-1118h-231l-43 150h-15q-42 -85 -102 -127.5t-148 -42.5q-62 0 -114 23t-84 67l5 -85l5 -157v-320h-305z" />
|
||||
<glyph unicode="¶" horiz-adv-x="1341" d="M113 1042q0 260 109 387t341 127h604v-1816h-161v1616h-166v-1616h-162v819q-62 -18 -146 -18q-216 0 -317.5 125t-101.5 376z" />
|
||||
<glyph unicode="·" horiz-adv-x="584" d="M117 723q0 84 45 127t131 43q83 0 128.5 -44t45.5 -126q0 -81 -46.5 -125.5t-127.5 -44.5q-84 0 -130 44t-46 126z" />
|
||||
<glyph unicode="¸" horiz-adv-x="420" d="M-37 -303q27 -7 72.5 -14t70.5 -7q72 0 72 62q0 83 -166 108l78 154h193l-27 -61q74 -24 118 -74.5t44 -114.5q0 -128 -75.5 -185t-233.5 -57q-78 0 -146 21v168z" />
|
||||
<glyph unicode="¹" horiz-adv-x="776" d="M92 1227l301 235h191v-876h-238v446l3 112l5 95q-27 -36 -75 -78l-78 -61z" />
|
||||
<glyph unicode="º" horiz-adv-x="795" d="M57 1116q0 169 89.5 266t252.5 97q152 0 245 -98.5t93 -264.5q0 -171 -91.5 -267.5t-250.5 -96.5q-153 0 -245.5 98.5t-92.5 265.5zM260 1116q0 -100 32.5 -150.5t104.5 -50.5t103.5 50.5t31.5 150.5t-31.5 149.5t-103.5 49.5t-104.5 -49.5t-32.5 -149.5z" />
|
||||
<glyph unicode="»" horiz-adv-x="1260" d="M82 213l278 348l-278 348l219 119l371 -455v-26l-371 -453zM588 213l278 348l-278 348l219 119l371 -455v-26l-371 -453z" />
|
||||
<glyph unicode="¼" horiz-adv-x="1804" d="M46 1227l301 235h191v-876h-238v446l3 112l5 95q-27 -36 -75 -78l-78 -61zM320 0l811 1462h239l-811 -1462h-239zM936 152v154l385 577h236v-563h125v-168h-125v-151h-238v151h-383zM1121 320h198v164q0 86 6 184q-9 -26 -35.5 -80t-41.5 -77z" />
|
||||
<glyph unicode="½" horiz-adv-x="1804" d="M46 1227l301 235h191v-876h-238v446l3 112l5 95q-27 -36 -75 -78l-78 -61zM320 0l811 1462h239l-811 -1462h-239zM1061 769q147 129 336 129q137 0 216 -66.5t79 -183.5q0 -85 -47 -160t-176 -192l-105 -95h352v-200h-647v168l224 219q102 100 130.5 144.5t28.5 94.5 q0 38 -24 58t-64 20q-81 0 -180 -88z" />
|
||||
<glyph unicode="¾" horiz-adv-x="1804" d="M90 639v190q148 -90 271 -90q143 0 143 107q0 53 -44 79.5t-122 26.5h-112v160h92q83 0 123.5 26t40.5 83q0 38 -25 63t-76 25q-47 0 -89 -19t-99 -59l-101 141q62 47 137.5 78t178.5 31q127 0 208 -64t81 -168q0 -143 -170 -198v-13q94 -20 146 -75t52 -134 q0 -121 -88 -190.5t-274 -69.5q-143 0 -273 70zM391 0l811 1462h239l-811 -1462h-239zM966 152v154l385 577h236v-563h125v-168h-125v-151h-238v151h-383zM1151 320h198v164q0 86 6 184q-9 -26 -35.5 -80t-41.5 -77z" />
|
||||
<glyph unicode="¿" horiz-adv-x="977" d="M61 -29q0 108 48.5 187t191.5 184q95 70 121.5 107t26.5 98v59h264v-74q0 -98 -44.5 -169t-152.5 -148q-109 -78 -137.5 -122t-28.5 -107q0 -57 43.5 -94t132.5 -37q79 0 169 29t186 71l102 -221q-98 -56 -221.5 -90.5t-229.5 -34.5q-220 0 -345.5 96.5t-125.5 265.5z M395 948q0 81 46.5 125.5t127.5 44.5q84 0 130 -44t46 -126q0 -84 -45 -127t-131 -43q-83 0 -128.5 44t-45.5 126z" />
|
||||
<glyph unicode="À" horiz-adv-x="1413" d="M0 0l516 1468h379l518 -1468h-334l-106 348h-533l-106 -348h-334zM518 608h381q-147 473 -165.5 535t-26.5 98q-33 -128 -189 -633zM338 1886v21h342q63 -101 235 -301v-27h-202q-63 44 -185 142.5t-190 164.5z" />
|
||||
<glyph unicode="Á" horiz-adv-x="1413" d="M0 0l516 1468h379l518 -1468h-334l-106 348h-533l-106 -348h-334zM518 608h381q-147 473 -165.5 535t-26.5 98q-33 -128 -189 -633zM541 1579v27q172 200 235 301h342v-21q-52 -52 -177.5 -154.5t-196.5 -152.5h-203z" />
|
||||
<glyph unicode="Â" horiz-adv-x="1413" d="M0 0l516 1468h379l518 -1468h-334l-106 348h-533l-106 -348h-334zM518 608h381q-147 473 -165.5 535t-26.5 98q-33 -128 -189 -633zM272 1579v27q189 189 256 301h357q31 -52 107.5 -141.5t148.5 -159.5v-27h-203q-157 93 -234 176q-78 -81 -229 -176h-203z" />
|
||||
<glyph unicode="Ã" horiz-adv-x="1413" d="M0 0l516 1468h379l518 -1468h-334l-106 348h-533l-106 -348h-334zM518 608h381q-147 473 -165.5 535t-26.5 98q-33 -128 -189 -633zM293 1577q11 145 82.5 227t189.5 82q41 0 80.5 -16.5t78 -36t75.5 -35.5t73 -16q31 0 59.5 26t41.5 80h149q-11 -145 -83.5 -227 t-188.5 -82q-41 0 -80.5 16.5t-78 36t-75.5 36t-73 16.5q-31 0 -59.5 -26.5t-41.5 -80.5h-149z" />
|
||||
<glyph unicode="Ä" horiz-adv-x="1413" d="M0 0l516 1468h379l518 -1468h-334l-106 348h-533l-106 -348h-334zM518 608h381q-147 473 -165.5 535t-26.5 98q-33 -128 -189 -633zM365 1743q0 65 37.5 100t101.5 35q66 0 103.5 -37t37.5 -98q0 -60 -38 -96.5t-103 -36.5q-64 0 -101.5 35t-37.5 98zM768 1743 q0 70 40.5 102.5t100.5 32.5q65 0 103.5 -36t38.5 -99q0 -61 -39 -97t-103 -36q-60 0 -100.5 32.5t-40.5 100.5z" />
|
||||
<glyph unicode="Å" horiz-adv-x="1413" d="M0 0l516 1468h379l518 -1468h-334l-106 348h-533l-106 -348h-334zM518 608h381q-147 473 -165.5 535t-26.5 98q-33 -128 -189 -633zM457 1565q0 108 67.5 172.5t180.5 64.5q110 0 182 -66t72 -169q0 -108 -71 -174t-183 -66t-180 64t-68 174zM609 1565q0 -45 24 -71 t72 -26q42 0 69 26t27 71t-27 70.5t-69 25.5t-69 -25.5t-27 -70.5z" />
|
||||
<glyph unicode="Æ" horiz-adv-x="1950" d="M0 0l655 1462h1174v-254h-563v-321h526v-254h-526v-377h563v-256h-873v348h-491l-150 -348h-315zM578 608h378v590h-127z" />
|
||||
<glyph unicode="Ç" horiz-adv-x="1305" d="M119 729q0 228 83 399.5t238.5 263t364.5 91.5q213 0 428 -103l-100 -252q-82 39 -165 68t-163 29q-175 0 -271 -131.5t-96 -366.5q0 -489 367 -489q154 0 373 77v-260q-180 -75 -402 -75q-319 0 -488 193.5t-169 555.5zM504 -303q27 -7 72.5 -14t70.5 -7q72 0 72 62 q0 83 -166 108l78 154h193l-27 -61q74 -24 118 -74.5t44 -114.5q0 -128 -75.5 -185t-233.5 -57q-78 0 -146 21v168z" />
|
||||
<glyph unicode="È" horiz-adv-x="1147" d="M184 0v1462h842v-254h-532v-321h495v-254h-495v-377h532v-256h-842zM259 1886v21h342q63 -101 235 -301v-27h-202q-63 44 -185 142.5t-190 164.5z" />
|
||||
<glyph unicode="É" horiz-adv-x="1147" d="M184 0v1462h842v-254h-532v-321h495v-254h-495v-377h532v-256h-842zM424 1579v27q172 200 235 301h342v-21q-52 -52 -177.5 -154.5t-196.5 -152.5h-203z" />
|
||||
<glyph unicode="Ê" horiz-adv-x="1147" d="M184 0v1462h842v-254h-532v-321h495v-254h-495v-377h532v-256h-842zM175 1579v27q189 189 256 301h357q31 -52 107.5 -141.5t148.5 -159.5v-27h-203q-157 93 -234 176q-78 -81 -229 -176h-203z" />
|
||||
<glyph unicode="Ë" horiz-adv-x="1147" d="M184 0v1462h842v-254h-532v-321h495v-254h-495v-377h532v-256h-842zM272 1743q0 65 37.5 100t101.5 35q66 0 103.5 -37t37.5 -98q0 -60 -38 -96.5t-103 -36.5q-64 0 -101.5 35t-37.5 98zM675 1743q0 70 40.5 102.5t100.5 32.5q65 0 103.5 -36t38.5 -99q0 -61 -39 -97 t-103 -36q-60 0 -100.5 32.5t-40.5 100.5z" />
|
||||
<glyph unicode="Ì" horiz-adv-x="678" d="M184 0v1462h310v-1462h-310zM-58 1886v21h342q63 -101 235 -301v-27h-202q-63 44 -185 142.5t-190 164.5z" />
|
||||
<glyph unicode="Í" horiz-adv-x="678" d="M184 0v1462h310v-1462h-310zM167 1579v27q172 200 235 301h342v-21q-52 -52 -177.5 -154.5t-196.5 -152.5h-203z" />
|
||||
<glyph unicode="Î" horiz-adv-x="678" d="M184 0v1462h310v-1462h-310zM-96 1579v27q189 189 256 301h357q31 -52 107.5 -141.5t148.5 -159.5v-27h-203q-157 93 -234 176q-78 -81 -229 -176h-203z" />
|
||||
<glyph unicode="Ï" horiz-adv-x="678" d="M184 0v1462h310v-1462h-310zM-3 1743q0 65 37.5 100t101.5 35q66 0 103.5 -37t37.5 -98q0 -60 -38 -96.5t-103 -36.5q-64 0 -101.5 35t-37.5 98zM400 1743q0 70 40.5 102.5t100.5 32.5q65 0 103.5 -36t38.5 -99q0 -61 -39 -97t-103 -36q-60 0 -100.5 32.5t-40.5 100.5z " />
|
||||
<glyph unicode="Ð" horiz-adv-x="1516" d="M47 596v254h137v612h459q358 0 556 -189t198 -528q0 -361 -205.5 -553t-593.5 -192h-414v596h-137zM494 256h131q450 0 450 481q0 232 -104 351.5t-314 119.5h-163v-358h237v-254h-237v-340z" />
|
||||
<glyph unicode="Ñ" horiz-adv-x="1665" d="M184 0v1462h391l635 -1095h7q-15 285 -15 403v692h279v-1462h-394l-636 1106h-9q19 -293 19 -418v-688h-277zM418 1577q11 145 82.5 227t189.5 82q41 0 80.5 -16.5t78 -36t75.5 -35.5t73 -16q31 0 59.5 26t41.5 80h149q-11 -145 -83.5 -227t-188.5 -82q-41 0 -80.5 16.5 t-78 36t-75.5 36t-73 16.5q-31 0 -59.5 -26.5t-41.5 -80.5h-149z" />
|
||||
<glyph unicode="Ò" horiz-adv-x="1630" d="M119 735q0 365 180.5 557.5t517.5 192.5t515.5 -194t178.5 -558q0 -363 -180 -558t-516 -195t-516 195t-180 560zM444 733q0 -245 93 -369t278 -124q371 0 371 493q0 494 -369 494q-185 0 -279 -124.5t-94 -369.5zM449 1886v21h342q63 -101 235 -301v-27h-202 q-63 44 -185 142.5t-190 164.5z" />
|
||||
<glyph unicode="Ó" horiz-adv-x="1630" d="M119 735q0 365 180.5 557.5t517.5 192.5t515.5 -194t178.5 -558q0 -363 -180 -558t-516 -195t-516 195t-180 560zM444 733q0 -245 93 -369t278 -124q371 0 371 493q0 494 -369 494q-185 0 -279 -124.5t-94 -369.5zM658 1579v27q172 200 235 301h342v-21 q-52 -52 -177.5 -154.5t-196.5 -152.5h-203z" />
|
||||
<glyph unicode="Ô" horiz-adv-x="1630" d="M119 735q0 365 180.5 557.5t517.5 192.5t515.5 -194t178.5 -558q0 -363 -180 -558t-516 -195t-516 195t-180 560zM444 733q0 -245 93 -369t278 -124q371 0 371 493q0 494 -369 494q-185 0 -279 -124.5t-94 -369.5zM381 1579v27q189 189 256 301h357q31 -52 107.5 -141.5 t148.5 -159.5v-27h-203q-157 93 -234 176q-78 -81 -229 -176h-203z" />
|
||||
<glyph unicode="Õ" horiz-adv-x="1630" d="M119 735q0 365 180.5 557.5t517.5 192.5t515.5 -194t178.5 -558q0 -363 -180 -558t-516 -195t-516 195t-180 560zM444 733q0 -245 93 -369t278 -124q371 0 371 493q0 494 -369 494q-185 0 -279 -124.5t-94 -369.5zM402 1577q11 145 82.5 227t189.5 82q41 0 80.5 -16.5 t78 -36t75.5 -35.5t73 -16q31 0 59.5 26t41.5 80h149q-11 -145 -83.5 -227t-188.5 -82q-41 0 -80.5 16.5t-78 36t-75.5 36t-73 16.5q-31 0 -59.5 -26.5t-41.5 -80.5h-149z" />
|
||||
<glyph unicode="Ö" horiz-adv-x="1630" d="M119 735q0 365 180.5 557.5t517.5 192.5t515.5 -194t178.5 -558q0 -363 -180 -558t-516 -195t-516 195t-180 560zM444 733q0 -245 93 -369t278 -124q371 0 371 493q0 494 -369 494q-185 0 -279 -124.5t-94 -369.5zM474 1743q0 65 37.5 100t101.5 35q66 0 103.5 -37 t37.5 -98q0 -60 -38 -96.5t-103 -36.5q-64 0 -101.5 35t-37.5 98zM877 1743q0 70 40.5 102.5t100.5 32.5q65 0 103.5 -36t38.5 -99q0 -61 -39 -97t-103 -36q-60 0 -100.5 32.5t-40.5 100.5z" />
|
||||
<glyph unicode="×" d="M129 1024l152 154l301 -299l305 299l153 -150l-305 -305l301 -303l-149 -152l-305 301l-301 -299l-150 152l297 301z" />
|
||||
<glyph unicode="Ø" horiz-adv-x="1630" d="M119 735q0 365 180.5 557.5t517.5 192.5q198 0 344 -70l84 125l160 -104l-88 -131q194 -194 194 -572q0 -363 -180 -558t-516 -195q-197 0 -336 65l-90 -135l-162 108l90 136q-198 194 -198 581zM444 733q0 -191 56 -307l506 756q-84 45 -189 45q-185 0 -279 -124.5 t-94 -369.5zM635 279q76 -39 180 -39q371 0 371 493q0 180 -51 297z" />
|
||||
<glyph unicode="Ù" horiz-adv-x="1548" d="M174 520v942h309v-895q0 -169 68 -248t225 -79q152 0 220.5 79.5t68.5 249.5v893h309v-946q0 -162 -72.5 -284t-209.5 -187t-324 -65q-282 0 -438 144.5t-156 395.5zM375 1886v21h342q63 -101 235 -301v-27h-202q-63 44 -185 142.5t-190 164.5z" />
|
||||
<glyph unicode="Ú" horiz-adv-x="1548" d="M174 520v942h309v-895q0 -169 68 -248t225 -79q152 0 220.5 79.5t68.5 249.5v893h309v-946q0 -162 -72.5 -284t-209.5 -187t-324 -65q-282 0 -438 144.5t-156 395.5zM602 1579v27q172 200 235 301h342v-21q-52 -52 -177.5 -154.5t-196.5 -152.5h-203z" />
|
||||
<glyph unicode="Û" horiz-adv-x="1548" d="M174 520v942h309v-895q0 -169 68 -248t225 -79q152 0 220.5 79.5t68.5 249.5v893h309v-946q0 -162 -72.5 -284t-209.5 -187t-324 -65q-282 0 -438 144.5t-156 395.5zM340 1579v27q189 189 256 301h357q31 -52 107.5 -141.5t148.5 -159.5v-27h-203q-157 93 -234 176 q-78 -81 -229 -176h-203z" />
|
||||
<glyph unicode="Ü" horiz-adv-x="1548" d="M174 520v942h309v-895q0 -169 68 -248t225 -79q152 0 220.5 79.5t68.5 249.5v893h309v-946q0 -162 -72.5 -284t-209.5 -187t-324 -65q-282 0 -438 144.5t-156 395.5zM433 1743q0 65 37.5 100t101.5 35q66 0 103.5 -37t37.5 -98q0 -60 -38 -96.5t-103 -36.5 q-64 0 -101.5 35t-37.5 98zM836 1743q0 70 40.5 102.5t100.5 32.5q65 0 103.5 -36t38.5 -99q0 -61 -39 -97t-103 -36q-60 0 -100.5 32.5t-40.5 100.5z" />
|
||||
<glyph unicode="Ý" horiz-adv-x="1278" d="M0 1462h336l303 -602l305 602h334l-485 -893v-569h-308v559zM461 1579v27q172 200 235 301h342v-21q-52 -52 -177.5 -154.5t-196.5 -152.5h-203z" />
|
||||
<glyph unicode="Þ" horiz-adv-x="1286" d="M184 0v1462h310v-229h178q254 0 388 -119t134 -344q0 -229 -142.5 -353t-404.5 -124h-153v-293h-310zM494 543h100q145 0 216 52.5t71 174.5q0 107 -63.5 159t-199.5 52h-124v-438z" />
|
||||
<glyph unicode="ß" horiz-adv-x="1456" d="M160 0v1139q0 201 146.5 314.5t404.5 113.5q244 0 391 -88.5t147 -237.5q0 -64 -21 -112.5t-53 -86.5t-69 -67t-69 -53t-53 -45t-21 -43q0 -27 26.5 -53t92.5 -66q146 -91 198.5 -140t78 -110t25.5 -139q0 -172 -116.5 -259t-343.5 -87q-99 0 -171 14.5t-132 48.5v242 q53 -36 135.5 -61t146.5 -25q168 0 168 123q0 41 -16 66.5t-57 55.5t-115 72q-126 72 -175 131.5t-49 140.5q0 64 35 117t105 102q77 55 108 95t31 86q0 60 -63.5 100.5t-163.5 40.5q-116 0 -181 -52.5t-65 -148.5v-1128h-305z" />
|
||||
<glyph unicode="à" horiz-adv-x="1237" d="M86 334q0 178 124.5 262.5t375.5 93.5l194 6v49q0 170 -174 170q-134 0 -315 -81l-101 206q193 101 428 101q225 0 345 -98t120 -298v-745h-213l-59 152h-8q-77 -97 -158.5 -134.5t-212.5 -37.5q-161 0 -253.5 92t-92.5 262zM399 332q0 -129 148 -129q106 0 169.5 61 t63.5 162v92l-118 -4q-133 -4 -198 -48t-65 -134zM239 1548v21h342q63 -101 235 -301v-27h-202q-63 44 -185 142.5t-190 164.5z" />
|
||||
<glyph unicode="á" horiz-adv-x="1237" d="M86 334q0 178 124.5 262.5t375.5 93.5l194 6v49q0 170 -174 170q-134 0 -315 -81l-101 206q193 101 428 101q225 0 345 -98t120 -298v-745h-213l-59 152h-8q-77 -97 -158.5 -134.5t-212.5 -37.5q-161 0 -253.5 92t-92.5 262zM399 332q0 -129 148 -129q106 0 169.5 61 t63.5 162v92l-118 -4q-133 -4 -198 -48t-65 -134zM441 1241v27q172 200 235 301h342v-21q-52 -52 -177.5 -154.5t-196.5 -152.5h-203z" />
|
||||
<glyph unicode="â" horiz-adv-x="1237" d="M86 334q0 178 124.5 262.5t375.5 93.5l194 6v49q0 170 -174 170q-134 0 -315 -81l-101 206q193 101 428 101q225 0 345 -98t120 -298v-745h-213l-59 152h-8q-77 -97 -158.5 -134.5t-212.5 -37.5q-161 0 -253.5 92t-92.5 262zM399 332q0 -129 148 -129q106 0 169.5 61 t63.5 162v92l-118 -4q-133 -4 -198 -48t-65 -134zM177 1240v27q189 189 256 301h357q31 -52 107.5 -141.5t148.5 -159.5v-27h-203q-157 93 -234 176q-78 -81 -229 -176h-203z" />
|
||||
<glyph unicode="ã" horiz-adv-x="1237" d="M86 334q0 178 124.5 262.5t375.5 93.5l194 6v49q0 170 -174 170q-134 0 -315 -81l-101 206q193 101 428 101q225 0 345 -98t120 -298v-745h-213l-59 152h-8q-77 -97 -158.5 -134.5t-212.5 -37.5q-161 0 -253.5 92t-92.5 262zM399 332q0 -129 148 -129q106 0 169.5 61 t63.5 162v92l-118 -4q-133 -4 -198 -48t-65 -134zM217 1239q11 145 82.5 227t189.5 82q41 0 80.5 -16.5t78 -36t75.5 -35.5t73 -16q31 0 59.5 26t41.5 80h149q-11 -145 -83.5 -227t-188.5 -82q-41 0 -80.5 16.5t-78 36t-75.5 36t-73 16.5q-31 0 -59.5 -26.5t-41.5 -80.5 h-149z" />
|
||||
<glyph unicode="ä" horiz-adv-x="1237" d="M86 334q0 178 124.5 262.5t375.5 93.5l194 6v49q0 170 -174 170q-134 0 -315 -81l-101 206q193 101 428 101q225 0 345 -98t120 -298v-745h-213l-59 152h-8q-77 -97 -158.5 -134.5t-212.5 -37.5q-161 0 -253.5 92t-92.5 262zM399 332q0 -129 148 -129q106 0 169.5 61 t63.5 162v92l-118 -4q-133 -4 -198 -48t-65 -134zM285 1405q0 65 37.5 100t101.5 35q66 0 103.5 -37t37.5 -98q0 -60 -38 -96.5t-103 -36.5q-64 0 -101.5 35t-37.5 98zM688 1405q0 70 40.5 102.5t100.5 32.5q65 0 103.5 -36t38.5 -99q0 -61 -39 -97t-103 -36 q-60 0 -100.5 32.5t-40.5 100.5z" />
|
||||
<glyph unicode="å" horiz-adv-x="1237" d="M86 334q0 178 124.5 262.5t375.5 93.5l194 6v49q0 170 -174 170q-134 0 -315 -81l-101 206q193 101 428 101q225 0 345 -98t120 -298v-745h-213l-59 152h-8q-77 -97 -158.5 -134.5t-212.5 -37.5q-161 0 -253.5 92t-92.5 262zM399 332q0 -129 148 -129q106 0 169.5 61 t63.5 162v92l-118 -4q-133 -4 -198 -48t-65 -134zM381 1477q0 108 67.5 172.5t180.5 64.5q110 0 182 -66t72 -169q0 -108 -71 -174t-183 -66t-180 64t-68 174zM533 1477q0 -45 24 -71t72 -26q42 0 69 26t27 71t-27 70.5t-69 25.5t-69 -25.5t-27 -70.5z" />
|
||||
<glyph unicode="æ" horiz-adv-x="1878" d="M86 334q0 178 121 262.5t362 93.5l191 6v84q0 69 -44.5 102t-121.5 33q-140 0 -305 -77l-99 202q189 101 422 101q227 0 342 -131q66 64 152.5 96.5t206.5 32.5q221 0 349 -137.5t128 -370.5v-148h-723q5 -130 77 -203t202 -73q196 0 380 88v-236q-79 -39 -171 -59 t-226 -20q-137 0 -249.5 50.5t-184.5 155.5q-98 -117 -196.5 -161.5t-256.5 -44.5q-161 0 -258.5 94.5t-97.5 259.5zM399 332q0 -129 140 -129q101 0 161 61t60 162v92l-113 -4q-124 -4 -186 -47.5t-62 -134.5zM1073 686h430q-2 112 -55 174t-141 62q-217 0 -234 -236z" />
|
||||
<glyph unicode="ç" horiz-adv-x="1053" d="M92 553q0 285 142 435.5t407 150.5q194 0 348 -76l-90 -236q-72 29 -134 47.5t-124 18.5q-238 0 -238 -338q0 -328 238 -328q88 0 163 23.5t150 73.5v-261q-74 -47 -149.5 -65t-190.5 -18q-522 0 -522 573zM350 -303q27 -7 72.5 -14t70.5 -7q72 0 72 62q0 83 -166 108 l78 154h193l-27 -61q74 -24 118 -74.5t44 -114.5q0 -128 -75.5 -185t-233.5 -57q-78 0 -146 21v168z" />
|
||||
<glyph unicode="è" horiz-adv-x="1210" d="M92 551q0 281 140.5 434.5t388.5 153.5q237 0 369 -135t132 -373v-148h-721q5 -130 77 -203t202 -73q101 0 191 21t188 67v-236q-80 -40 -171 -59.5t-222 -19.5q-270 0 -422 149t-152 422zM408 686h428q-2 113 -59 174.5t-154 61.5t-152 -61.5t-63 -174.5zM245 1548v21 h342q63 -101 235 -301v-27h-202q-63 44 -185 142.5t-190 164.5z" />
|
||||
<glyph unicode="é" horiz-adv-x="1210" d="M92 551q0 281 140.5 434.5t388.5 153.5q237 0 369 -135t132 -373v-148h-721q5 -130 77 -203t202 -73q101 0 191 21t188 67v-236q-80 -40 -171 -59.5t-222 -19.5q-270 0 -422 149t-152 422zM408 686h428q-2 113 -59 174.5t-154 61.5t-152 -61.5t-63 -174.5zM447 1241v27 q172 200 235 301h342v-21q-52 -52 -177.5 -154.5t-196.5 -152.5h-203z" />
|
||||
<glyph unicode="ê" horiz-adv-x="1210" d="M92 551q0 281 140.5 434.5t388.5 153.5q237 0 369 -135t132 -373v-148h-721q5 -130 77 -203t202 -73q101 0 191 21t188 67v-236q-80 -40 -171 -59.5t-222 -19.5q-270 0 -422 149t-152 422zM408 686h428q-2 113 -59 174.5t-154 61.5t-152 -61.5t-63 -174.5zM194 1241v27 q189 189 256 301h357q31 -52 107.5 -141.5t148.5 -159.5v-27h-203q-157 93 -234 176q-78 -81 -229 -176h-203z" />
|
||||
<glyph unicode="ë" horiz-adv-x="1210" d="M92 551q0 281 140.5 434.5t388.5 153.5q237 0 369 -135t132 -373v-148h-721q5 -130 77 -203t202 -73q101 0 191 21t188 67v-236q-80 -40 -171 -59.5t-222 -19.5q-270 0 -422 149t-152 422zM408 686h428q-2 113 -59 174.5t-154 61.5t-152 -61.5t-63 -174.5zM297 1405 q0 65 37.5 100t101.5 35q66 0 103.5 -37t37.5 -98q0 -60 -38 -96.5t-103 -36.5q-64 0 -101.5 35t-37.5 98zM700 1405q0 70 40.5 102.5t100.5 32.5q65 0 103.5 -36t38.5 -99q0 -61 -39 -97t-103 -36q-60 0 -100.5 32.5t-40.5 100.5z" />
|
||||
<glyph unicode="ì" horiz-adv-x="625" d="M160 0v1118h305v-1118h-305zM-101 1548v21h342q63 -101 235 -301v-27h-202q-63 44 -185 142.5t-190 164.5z" />
|
||||
<glyph unicode="í" horiz-adv-x="625" d="M160 0v1118h305v-1118h-305zM145 1241v27q172 200 235 301h342v-21q-52 -52 -177.5 -154.5t-196.5 -152.5h-203z" />
|
||||
<glyph unicode="î" horiz-adv-x="625" d="M160 0v1118h305v-1118h-305zM-122 1241v27q189 189 256 301h357q31 -52 107.5 -141.5t148.5 -159.5v-27h-203q-157 93 -234 176q-78 -81 -229 -176h-203z" />
|
||||
<glyph unicode="ï" horiz-adv-x="625" d="M160 0v1118h305v-1118h-305zM-29 1405q0 65 37.5 100t101.5 35q66 0 103.5 -37t37.5 -98q0 -60 -38 -96.5t-103 -36.5q-64 0 -101.5 35t-37.5 98zM374 1405q0 70 40.5 102.5t100.5 32.5q65 0 103.5 -36t38.5 -99q0 -61 -39 -97t-103 -36q-60 0 -100.5 32.5t-40.5 100.5z " />
|
||||
<glyph unicode="ð" horiz-adv-x="1268" d="M92 489q0 233 130 369.5t351 136.5q205 0 275 -98l8 4q-67 162 -192 281l-230 -142l-100 156l176 107q-80 53 -152 92l101 176q144 -65 258 -141l225 139l100 -154l-170 -104q156 -143 230 -324.5t74 -413.5q0 -280 -145 -436.5t-400 -156.5q-245 0 -392 137t-147 372z M403 487q0 -140 60 -211t172 -71q123 0 176 82t53 245q0 108 -61 173t-168 65q-121 0 -176.5 -68.5t-55.5 -214.5z" />
|
||||
<glyph unicode="ñ" horiz-adv-x="1346" d="M160 0v1118h233l41 -143h17q51 81 140.5 122.5t203.5 41.5q195 0 296 -105.5t101 -304.5v-729h-305v653q0 121 -43 181.5t-137 60.5q-128 0 -185 -85.5t-57 -283.5v-526h-305zM258 1239q11 145 82.5 227t189.5 82q41 0 80.5 -16.5t78 -36t75.5 -35.5t73 -16q31 0 59.5 26 t41.5 80h149q-11 -145 -83.5 -227t-188.5 -82q-41 0 -80.5 16.5t-78 36t-75.5 36t-73 16.5q-31 0 -59.5 -26.5t-41.5 -80.5h-149z" />
|
||||
<glyph unicode="ò" horiz-adv-x="1268" d="M92 561q0 274 143 426t402 152q161 0 284 -70t189 -201t66 -307q0 -273 -144 -427t-401 -154q-161 0 -284 70.5t-189 202.5t-66 308zM403 561q0 -166 54.5 -251t177.5 -85q122 0 175.5 84.5t53.5 251.5q0 166 -54 249t-177 83q-122 0 -176 -82.5t-54 -249.5zM237 1548v21 h342q63 -101 235 -301v-27h-202q-63 44 -185 142.5t-190 164.5z" />
|
||||
<glyph unicode="ó" horiz-adv-x="1268" d="M92 561q0 274 143 426t402 152q161 0 284 -70t189 -201t66 -307q0 -273 -144 -427t-401 -154q-161 0 -284 70.5t-189 202.5t-66 308zM403 561q0 -166 54.5 -251t177.5 -85q122 0 175.5 84.5t53.5 251.5q0 166 -54 249t-177 83q-122 0 -176 -82.5t-54 -249.5zM467 1241v27 q172 200 235 301h342v-21q-52 -52 -177.5 -154.5t-196.5 -152.5h-203z" />
|
||||
<glyph unicode="ô" horiz-adv-x="1268" d="M92 561q0 274 143 426t402 152q161 0 284 -70t189 -201t66 -307q0 -273 -144 -427t-401 -154q-161 0 -284 70.5t-189 202.5t-66 308zM403 561q0 -166 54.5 -251t177.5 -85q122 0 175.5 84.5t53.5 251.5q0 166 -54 249t-177 83q-122 0 -176 -82.5t-54 -249.5zM198 1241v27 q189 189 256 301h357q31 -52 107.5 -141.5t148.5 -159.5v-27h-203q-157 93 -234 176q-78 -81 -229 -176h-203z" />
|
||||
<glyph unicode="õ" horiz-adv-x="1268" d="M92 561q0 274 143 426t402 152q161 0 284 -70t189 -201t66 -307q0 -273 -144 -427t-401 -154q-161 0 -284 70.5t-189 202.5t-66 308zM403 561q0 -166 54.5 -251t177.5 -85q122 0 175.5 84.5t53.5 251.5q0 166 -54 249t-177 83q-122 0 -176 -82.5t-54 -249.5zM219 1239 q11 145 82.5 227t189.5 82q41 0 80.5 -16.5t78 -36t75.5 -35.5t73 -16q31 0 59.5 26t41.5 80h149q-11 -145 -83.5 -227t-188.5 -82q-41 0 -80.5 16.5t-78 36t-75.5 36t-73 16.5q-31 0 -59.5 -26.5t-41.5 -80.5h-149z" />
|
||||
<glyph unicode="ö" horiz-adv-x="1268" d="M92 561q0 274 143 426t402 152q161 0 284 -70t189 -201t66 -307q0 -273 -144 -427t-401 -154q-161 0 -284 70.5t-189 202.5t-66 308zM403 561q0 -166 54.5 -251t177.5 -85q122 0 175.5 84.5t53.5 251.5q0 166 -54 249t-177 83q-122 0 -176 -82.5t-54 -249.5zM291 1405 q0 65 37.5 100t101.5 35q66 0 103.5 -37t37.5 -98q0 -60 -38 -96.5t-103 -36.5q-64 0 -101.5 35t-37.5 98zM694 1405q0 70 40.5 102.5t100.5 32.5q65 0 103.5 -36t38.5 -99q0 -61 -39 -97t-103 -36q-60 0 -100.5 32.5t-40.5 100.5z" />
|
||||
<glyph unicode="÷" d="M88 612v219h993v-219h-993zM444 373q0 76 37 113.5t103 37.5t102.5 -39t36.5 -112q0 -70 -37 -111t-102 -41t-102.5 39t-37.5 113zM444 1071q0 75 37 113.5t103 38.5q67 0 103 -40.5t36 -111.5q0 -70 -37 -110.5t-102 -40.5t-102.5 39t-37.5 112z" />
|
||||
<glyph unicode="ø" horiz-adv-x="1268" d="M92 561q0 274 143 426t402 152q132 0 248 -52l55 82l152 -108l-58 -84q142 -155 142 -416q0 -273 -144 -427t-401 -154q-126 0 -234 45l-67 -101l-154 105l68 100q-152 156 -152 432zM403 561q0 -94 19 -166l317 475q-43 23 -106 23q-122 0 -176 -82.5t-54 -249.5z M543 240q38 -15 92 -15q122 0 175.5 84.5t53.5 251.5q0 81 -12 141z" />
|
||||
<glyph unicode="ù" horiz-adv-x="1346" d="M154 389v729h305v-653q0 -121 43 -181.5t137 -60.5q128 0 185 85.5t57 283.5v526h305v-1118h-234l-41 143h-16q-49 -78 -139 -120.5t-205 -42.5q-197 0 -297 105.5t-100 303.5zM245 1548v21h342q63 -101 235 -301v-27h-202q-63 44 -185 142.5t-190 164.5z" />
|
||||
<glyph unicode="ú" horiz-adv-x="1346" d="M154 389v729h305v-653q0 -121 43 -181.5t137 -60.5q128 0 185 85.5t57 283.5v526h305v-1118h-234l-41 143h-16q-49 -78 -139 -120.5t-205 -42.5q-197 0 -297 105.5t-100 303.5zM498 1241v27q172 200 235 301h342v-21q-52 -52 -177.5 -154.5t-196.5 -152.5h-203z" />
|
||||
<glyph unicode="û" horiz-adv-x="1346" d="M154 389v729h305v-653q0 -121 43 -181.5t137 -60.5q128 0 185 85.5t57 283.5v526h305v-1118h-234l-41 143h-16q-49 -78 -139 -120.5t-205 -42.5q-197 0 -297 105.5t-100 303.5zM235 1241v27q189 189 256 301h357q31 -52 107.5 -141.5t148.5 -159.5v-27h-203 q-157 93 -234 176q-78 -81 -229 -176h-203z" />
|
||||
<glyph unicode="ü" horiz-adv-x="1346" d="M154 389v729h305v-653q0 -121 43 -181.5t137 -60.5q128 0 185 85.5t57 283.5v526h305v-1118h-234l-41 143h-16q-49 -78 -139 -120.5t-205 -42.5q-197 0 -297 105.5t-100 303.5zM326 1405q0 65 37.5 100t101.5 35q66 0 103.5 -37t37.5 -98q0 -60 -38 -96.5t-103 -36.5 q-64 0 -101.5 35t-37.5 98zM729 1405q0 70 40.5 102.5t100.5 32.5q65 0 103.5 -36t38.5 -99q0 -61 -39 -97t-103 -36q-60 0 -100.5 32.5t-40.5 100.5z" />
|
||||
<glyph unicode="ý" horiz-adv-x="1165" d="M0 1118h334l211 -629q27 -82 37 -194h6q11 103 43 194l207 629h327l-473 -1261q-65 -175 -185.5 -262t-281.5 -87q-79 0 -155 17v242q55 -13 120 -13q81 0 141.5 49.5t94.5 149.5l18 55zM393 1241v27q172 200 235 301h342v-21q-52 -52 -177.5 -154.5t-196.5 -152.5h-203z " />
|
||||
<glyph unicode="þ" horiz-adv-x="1296" d="M160 -492v2048h305v-391l-7 -120l-7 -72h14q50 81 131 123.5t186 42.5q198 0 310 -154.5t112 -423.5q0 -273 -111.5 -427t-310.5 -154q-213 0 -317 137h-14l7 -62l7 -94v-453h-305zM465 563q0 -180 53.5 -258t169.5 -78q205 0 205 338q0 165 -50.5 247.5t-158.5 82.5 q-113 0 -165 -69.5t-54 -229.5v-33z" />
|
||||
<glyph unicode="ÿ" horiz-adv-x="1165" d="M0 1118h334l211 -629q27 -82 37 -194h6q11 103 43 194l207 629h327l-473 -1261q-65 -175 -185.5 -262t-281.5 -87q-79 0 -155 17v242q55 -13 120 -13q81 0 141.5 49.5t94.5 149.5l18 55zM243 1405q0 65 37.5 100t101.5 35q66 0 103.5 -37t37.5 -98q0 -60 -38 -96.5 t-103 -36.5q-64 0 -101.5 35t-37.5 98zM646 1405q0 70 40.5 102.5t100.5 32.5q65 0 103.5 -36t38.5 -99q0 -61 -39 -97t-103 -36q-60 0 -100.5 32.5t-40.5 100.5z" />
|
||||
<glyph unicode="ı" horiz-adv-x="625" d="M160 0v1118h305v-1118h-305z" />
|
||||
<glyph unicode="Œ" horiz-adv-x="1993" d="M119 735q0 363 169.5 556.5t487.5 193.5q61 0 127 -7t101 -16h868v-254h-563v-321h526v-254h-526v-377h563v-256h-873q-38 -9 -109 -14.5t-116 -5.5q-319 0 -487 197t-168 558zM438 733q0 -244 86 -368.5t250 -124.5q65 0 126 10.5t99 28.5v907q-35 19 -101.5 30 t-121.5 11q-166 0 -252 -125.5t-86 -368.5z" />
|
||||
<glyph unicode="œ" horiz-adv-x="2003" d="M92 561q0 277 141.5 427.5t399.5 150.5q112 0 212 -39.5t171 -116.5q144 156 383 156q244 0 380 -135t136 -373v-148h-746v-8q7 -127 81.5 -197.5t207.5 -70.5q107 0 200 21t193 67v-236q-81 -39 -175.5 -59t-229.5 -20q-271 0 -420 155q-141 -155 -391 -155 q-162 0 -286 70t-190.5 202t-66.5 309zM403 561q0 -166 54.5 -251t177.5 -85q122 0 175.5 84.5t53.5 251.5q0 166 -54 249t-177 83q-122 0 -176 -82.5t-54 -249.5zM1178 686h450q-2 111 -60.5 173.5t-162.5 62.5q-94 0 -156 -57.5t-71 -178.5z" />
|
||||
<glyph unicode="Ÿ" horiz-adv-x="1278" d="M0 1462h336l303 -602l305 602h334l-485 -893v-569h-308v559zM297 1743q0 65 37.5 100t101.5 35q66 0 103.5 -37t37.5 -98q0 -60 -38 -96.5t-103 -36.5q-64 0 -101.5 35t-37.5 98zM700 1743q0 70 40.5 102.5t100.5 32.5q65 0 103.5 -36t38.5 -99q0 -61 -39 -97t-103 -36 q-60 0 -100.5 32.5t-40.5 100.5z" />
|
||||
<glyph unicode="ˆ" horiz-adv-x="1243" d="M186 1241v27q189 189 256 301h357q31 -52 107.5 -141.5t148.5 -159.5v-27h-203q-157 93 -234 176q-78 -81 -229 -176h-203z" />
|
||||
<glyph unicode="˚" horiz-adv-x="1182" d="M340 1477q0 108 67.5 172.5t180.5 64.5q110 0 182 -66t72 -169q0 -108 -71 -174t-183 -66t-180 64t-68 174zM492 1477q0 -45 24 -71t72 -26q42 0 69 26t27 71t-27 70.5t-69 25.5t-69 -25.5t-27 -70.5z" />
|
||||
<glyph unicode="˜" horiz-adv-x="1243" d="M207 1239q11 145 82.5 227t189.5 82q41 0 80.5 -16.5t78 -36t75.5 -35.5t73 -16q31 0 59.5 26t41.5 80h149q-11 -145 -83.5 -227t-188.5 -82q-41 0 -80.5 16.5t-78 36t-75.5 36t-73 16.5q-31 0 -59.5 -26.5t-41.5 -80.5h-149z" />
|
||||
<glyph unicode=" " horiz-adv-x="953" />
|
||||
<glyph unicode=" " horiz-adv-x="1907" />
|
||||
<glyph unicode=" " horiz-adv-x="953" />
|
||||
<glyph unicode=" " horiz-adv-x="1907" />
|
||||
<glyph unicode=" " horiz-adv-x="635" />
|
||||
<glyph unicode=" " horiz-adv-x="476" />
|
||||
<glyph unicode=" " horiz-adv-x="317" />
|
||||
<glyph unicode=" " horiz-adv-x="317" />
|
||||
<glyph unicode=" " horiz-adv-x="238" />
|
||||
<glyph unicode=" " horiz-adv-x="381" />
|
||||
<glyph unicode=" " horiz-adv-x="105" />
|
||||
<glyph unicode="‐" horiz-adv-x="659" d="M61 424v250h537v-250h-537z" />
|
||||
<glyph unicode="‑" horiz-adv-x="659" d="M61 424v250h537v-250h-537z" />
|
||||
<glyph unicode="‒" horiz-adv-x="659" d="M61 424v250h537v-250h-537z" />
|
||||
<glyph unicode="–" horiz-adv-x="1024" d="M82 436v230h860v-230h-860z" />
|
||||
<glyph unicode="—" horiz-adv-x="2048" d="M82 436v230h1884v-230h-1884z" />
|
||||
<glyph unicode="‘" horiz-adv-x="444" d="M25 983q22 91 72.5 228.5t103.5 250.5h219q-66 -267 -101 -501h-280z" />
|
||||
<glyph unicode="’" horiz-adv-x="444" d="M25 961q69 296 100 501h281l14 -22q-50 -197 -176 -479h-219z" />
|
||||
<glyph unicode="‚" horiz-adv-x="596" d="M63 -264q65 266 101 502h280l15 -23q-52 -202 -176 -479h-220z" />
|
||||
<glyph unicode="“" horiz-adv-x="911" d="M25 983q22 91 72.5 228.5t103.5 250.5h219q-66 -267 -101 -501h-280zM492 983q22 91 72.5 228.5t103.5 250.5h219q-66 -267 -101 -501h-280z" />
|
||||
<glyph unicode="”" horiz-adv-x="911" d="M25 961q69 296 100 501h281l14 -22q-50 -197 -176 -479h-219zM492 961q69 296 100 501h280l15 -22q-50 -197 -176 -479h-219z" />
|
||||
<glyph unicode="„" horiz-adv-x="1061" d="M63 -264q65 266 101 502h280l15 -23q-52 -202 -176 -479h-220zM530 -264q65 266 101 502h280l15 -23q-52 -202 -176 -479h-220z" />
|
||||
<glyph unicode="•" horiz-adv-x="770" d="M98 748q0 154 74 235.5t213 81.5q137 0 212 -82t75 -235q0 -152 -75.5 -235t-211.5 -83q-138 0 -212.5 83t-74.5 235z" />
|
||||
<glyph unicode="…" horiz-adv-x="1751" d="M117 143q0 84 45 127t131 43q83 0 128.5 -44t45.5 -126q0 -79 -46 -124.5t-128 -45.5q-84 0 -130 44.5t-46 125.5zM700 143q0 84 45 127t132 43q83 0 128.5 -44t45.5 -126q0 -79 -46 -124.5t-128 -45.5q-85 0 -131 44.5t-46 125.5zM1284 143q0 84 45 127t131 43 q83 0 128.5 -44t45.5 -126q0 -79 -46 -124.5t-128 -45.5q-84 0 -130 44.5t-46 125.5z" />
|
||||
<glyph unicode=" " horiz-adv-x="381" />
|
||||
<glyph unicode="‹" horiz-adv-x="754" d="M82 547v26l371 455l219 -119l-279 -348l279 -348l-219 -119z" />
|
||||
<glyph unicode="›" horiz-adv-x="754" d="M82 213l278 348l-278 348l219 119l371 -455v-26l-371 -453z" />
|
||||
<glyph unicode="⁄" horiz-adv-x="266" d="M-393 0l811 1462h239l-811 -1462h-239z" />
|
||||
<glyph unicode=" " horiz-adv-x="476" />
|
||||
<glyph unicode="⁴" horiz-adv-x="776" d="M12 737v154l385 577h236v-563h125v-168h-125v-151h-238v151h-383zM197 905h198v164q0 86 6 184q-9 -26 -35.5 -80t-41.5 -77z" />
|
||||
<glyph unicode="€" d="M66 481v178h118q-4 23 -4 62l2 53h-116v176h133q37 242 199 382.5t405 140.5q188 0 352 -82l-98 -232q-69 31 -129 48.5t-125 17.5q-122 0 -201 -70.5t-102 -204.5h403v-176h-418l-2 -35v-47l2 -33h355v-178h-338q51 -243 321 -243q143 0 275 57v-256q-116 -59 -293 -59 q-245 0 -403 133t-199 368h-137z" />
|
||||
<glyph unicode="™" horiz-adv-x="1534" d="M16 1313v149h564v-149h-199v-572h-168v572h-197zM625 741v721h247l160 -510l170 510h240v-721h-168v408l4 121h-6l-174 -529h-142l-165 529h-7l4 -111v-418h-163z" />
|
||||
<glyph unicode="" horiz-adv-x="1120" d="M0 1120h1120v-1120h-1120v1120z" />
|
||||
<glyph unicode="fi" horiz-adv-x="1417" d="M41 889v147l168 82v82q0 191 94 279t301 88q158 0 281 -47l-78 -224q-92 29 -170 29q-65 0 -94 -38.5t-29 -98.5v-70h264v-229h-264v-889h-305v889h-168zM940 1407q0 149 166 149t166 -149q0 -71 -41.5 -110.5t-124.5 -39.5q-166 0 -166 150zM953 0v1118h305v-1118h-305z " />
|
||||
<glyph unicode="fl" horiz-adv-x="1417" d="M41 889v147l168 82v82q0 191 94 279t301 88q158 0 281 -47l-78 -224q-92 29 -170 29q-65 0 -94 -38.5t-29 -98.5v-70h264v-229h-264v-889h-305v889h-168zM953 0v1556h305v-1556h-305z" />
|
||||
<glyph unicode="ffi" horiz-adv-x="2208" d="M41 889v147l168 82v82q0 191 94 279t301 88q158 0 281 -47l-78 -224q-92 29 -170 29q-65 0 -94 -38.5t-29 -98.5v-70h264v-229h-264v-889h-305v889h-168zM834 889v147l168 82v82q0 191 94 279t301 88q158 0 281 -47l-78 -224q-92 29 -170 29q-65 0 -94 -38.5t-29 -98.5 v-70h264v-229h-264v-889h-305v889h-168zM1730 1407q0 149 166 149t166 -149q0 -71 -41.5 -110.5t-124.5 -39.5q-166 0 -166 150zM1743 0v1118h305v-1118h-305z" />
|
||||
<glyph unicode="ffl" horiz-adv-x="2208" d="M41 889v147l168 82v82q0 191 94 279t301 88q158 0 281 -47l-78 -224q-92 29 -170 29q-65 0 -94 -38.5t-29 -98.5v-70h264v-229h-264v-889h-305v889h-168zM834 889v147l168 82v82q0 191 94 279t301 88q158 0 281 -47l-78 -224q-92 29 -170 29q-65 0 -94 -38.5t-29 -98.5 v-70h264v-229h-264v-889h-305v889h-168zM1743 0v1556h305v-1556h-305z" />
|
||||
</font>
|
||||
</defs></svg>
|
||||
|
After Width: | Height: | Size: 56 KiB |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user