You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by so...@apache.org on 2018/11/08 14:51:23 UTC

[openmeetings] branch master updated: [OPENMEETINGS-1352] initial commit on Chrome support

This is an automated email from the ASF dual-hosted git repository.

solomax pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openmeetings.git


The following commit(s) were added to refs/heads/master by this push:
     new a02eaf1  [OPENMEETINGS-1352] initial commit on Chrome support
a02eaf1 is described below

commit a02eaf10248174472dd60ceca01b1d98e27c4225
Author: Maxim Solodovnik <so...@gmail.com>
AuthorDate: Thu Nov 8 21:51:11 2018 +0700

    [OPENMEETINGS-1352] initial commit on Chrome support
---
 .../java/org/apache/openmeetings/IApplication.java |   2 -
 .../db/dao/basic/ConfigurationDao.java             |  46 +++--
 .../installation/ImportInitvalues.java             |   9 +-
 .../openmeetings/util/OpenmeetingsVariables.java   |  33 +++-
 openmeetings-web/pom.xml                           |   1 +
 .../apache/openmeetings/web/app/Application.java   |  28 +--
 .../apache/openmeetings/web/room/RoomPanel.java    |   5 +-
 .../apache/openmeetings/web/room/getScreenId.js    | 209 +++++++++++++++++++++
 pom.xml                                            |   2 +-
 9 files changed, 288 insertions(+), 47 deletions(-)

diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java b/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java
index b54f8f7..0b6a15d 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java
@@ -40,8 +40,6 @@ public interface IApplication {
 	String getOmContactsLink();
 	String getOmInvitationLink(Invitation i);
 	String urlForActivatePage(PageParameters pp);
-	void setXFrameOptions(String xFrameOptions);
-	void setContentSecurityPolicy(String contentSecurityPolicy);
 
 	String getServerId();
 
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/basic/ConfigurationDao.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/basic/ConfigurationDao.java
index 8ca1d42..93531c1 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/basic/ConfigurationDao.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/basic/ConfigurationDao.java
@@ -24,7 +24,9 @@ import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_APPLICAT
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_APPLICATION_NAME;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_CAM_FPS;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_CHAT_SEND_ON_ENTER;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_CHROME_EXT_URL;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_CRYPT;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_CSP_XFRAME;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DEFAULT_GROUP_ID;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DEFAULT_LANG;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DEFAULT_TIMEZONE;
@@ -34,7 +36,6 @@ import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_EXT_PROC
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_FNAME_MIN_LENGTH;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_GOOGLE_ANALYTICS_CODE;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_HEADER_CSP;
-import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_HEADER_XFRAME;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_KEYCODE_ARRANGE;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_KEYCODE_EXCLUSIVE;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_KEYCODE_MUTE;
@@ -56,12 +57,14 @@ import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_SIP_ENAB
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_SIP_EXTEN_CONTEXT;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.DEFAULT_APP_NAME;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.DEFAULT_BASE_URL;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.DEFAULT_CHROME_EXT_URL;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.DEFAULT_MAX_UPLOAD_SIZE;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.DEFAULT_SIP_CONTEXT;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.HEADER_CSP_SELF;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.HEADER_XFRAME_SELF;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.USER_LOGIN_MINIMUM_LENGTH;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.USER_PASSWORD_MINIMUM_LENGTH;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.getRoomSettings;
-import static org.apache.openmeetings.util.OpenmeetingsVariables.getWicketApplicationName;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.setAllowRegisterFrontend;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.setAllowRegisterOauth;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.setAllowRegisterSoap;
@@ -70,6 +73,8 @@ import static org.apache.openmeetings.util.OpenmeetingsVariables.setAudioBitrate
 import static org.apache.openmeetings.util.OpenmeetingsVariables.setAudioRate;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.setBaseUrl;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.setChatSenndOnEnter;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.setChromeExtensionUrl;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.setContentSecurityPolicy;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.setCryptClassName;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.setDefaultGroup;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.setDefaultLang;
@@ -87,6 +92,7 @@ import static org.apache.openmeetings.util.OpenmeetingsVariables.setSendVerifica
 import static org.apache.openmeetings.util.OpenmeetingsVariables.setSipContext;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.setSipEnabled;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.setVideoPreset;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.setxFrameOptions;
 
 import java.net.UnknownHostException;
 import java.util.ArrayList;
@@ -104,14 +110,12 @@ import org.apache.openjpa.event.RemoteCommitProvider;
 import org.apache.openjpa.event.TCPRemoteCommitProvider;
 import org.apache.openjpa.persistence.OpenJPAEntityManagerSPI;
 import org.apache.openjpa.persistence.OpenJPAPersistence;
-import org.apache.openmeetings.IApplication;
 import org.apache.openmeetings.db.dao.IDataProviderDao;
 import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.entity.basic.Configuration;
 import org.apache.openmeetings.db.util.DaoHelper;
 import org.apache.openmeetings.util.OpenmeetingsVariables;
 import org.apache.openmeetings.util.crypt.CryptProvider;
-import org.apache.wicket.Application;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -319,21 +323,11 @@ public class ConfigurationDao implements IDataProviderDao<Configuration> {
 			case CONFIG_GOOGLE_ANALYTICS_CODE:
 				reloadGaCode();
 				break;
-			case CONFIG_HEADER_XFRAME:
-			{
-				IApplication iapp = (IApplication)Application.get(getWicketApplicationName());
-				if (iapp != null) {
-					iapp.setXFrameOptions(value);
-				}
-			}
+			case CONFIG_CSP_XFRAME:
+				reloadXFrameOptions();
 				break;
 			case CONFIG_HEADER_CSP:
-			{
-				IApplication iapp = (IApplication)Application.get(getWicketApplicationName());
-				if (iapp != null) {
-					iapp.setContentSecurityPolicy(value);
-				}
-			}
+				reloadContentSecurityPolicy();
 				break;
 			case CONFIG_EXT_PROCESS_TTL:
 				setExtProcessTtl(toInt(value));
@@ -392,6 +386,9 @@ public class ConfigurationDao implements IDataProviderDao<Configuration> {
 			case CONFIG_EMAIL_AT_REGISTER:
 				reloadSendRegisterEmail();
 				break;
+			case CONFIG_CHROME_EXT_URL:
+				reloadChromeExtensionUrl();
+				break;
 		}
 		return entity;
 	}
@@ -515,6 +512,18 @@ public class ConfigurationDao implements IDataProviderDao<Configuration> {
 		setSendRegisterEmail(getBool(CONFIG_EMAIL_AT_REGISTER, false));
 	}
 
+	private void reloadChromeExtensionUrl() {
+		setChromeExtensionUrl(getString(CONFIG_CHROME_EXT_URL, DEFAULT_CHROME_EXT_URL));
+	}
+
+	private void reloadXFrameOptions() {
+		setxFrameOptions(getString(CONFIG_CSP_XFRAME, HEADER_XFRAME_SELF));
+	}
+
+	private void reloadContentSecurityPolicy() {
+		setContentSecurityPolicy(getString(CONFIG_HEADER_CSP, HEADER_CSP_SELF));
+	}
+
 	public void reinit() {
 		reloadMaxUpload();
 		reloadCrypt();
@@ -541,6 +550,9 @@ public class ConfigurationDao implements IDataProviderDao<Configuration> {
 		reloadAllowRegisterOauth();
 		reloadSendVerificationEmail();
 		reloadSendRegisterEmail();
+		reloadXFrameOptions();
+		reloadContentSecurityPolicy();
+		reloadChromeExtensionUrl();
 	}
 
 	private JSONObject reloadRoomSettings() {
diff --git a/openmeetings-install/src/main/java/org/apache/openmeetings/installation/ImportInitvalues.java b/openmeetings-install/src/main/java/org/apache/openmeetings/installation/ImportInitvalues.java
index 7860301..7dc266a 100644
--- a/openmeetings-install/src/main/java/org/apache/openmeetings/installation/ImportInitvalues.java
+++ b/openmeetings-install/src/main/java/org/apache/openmeetings/installation/ImportInitvalues.java
@@ -25,7 +25,9 @@ import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_APPOINTM
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_CALENDAR_ROOM_CAPACITY;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_CAM_FPS;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_CHAT_SEND_ON_ENTER;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_CHROME_EXT_URL;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_CRYPT;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_CSP_XFRAME;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DASHBOARD_RSS_FEED1;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DASHBOARD_RSS_FEED2;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DASHBOARD_SHOW_CHAT;
@@ -44,7 +46,6 @@ import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_EXT_PROC
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_FNAME_MIN_LENGTH;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_GOOGLE_ANALYTICS_CODE;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_HEADER_CSP;
-import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_HEADER_XFRAME;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_IGNORE_BAD_SSL;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_KEYCODE_ARRANGE;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_KEYCODE_EXCLUSIVE;
@@ -87,9 +88,10 @@ import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_SMTP_TIM
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_SMTP_TLS;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_SMTP_USER;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.DEFAULT_APP_NAME;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.DEFAULT_CHROME_EXT_URL;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.DEFAULT_MAX_UPLOAD_SIZE;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.HEADER_CSP_SELF;
-import static org.apache.openmeetings.util.OpenmeetingsVariables.HEADER_XFRAME_SAMEORIGIN;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.HEADER_XFRAME_SELF;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.USER_LOGIN_MINIMUM_LENGTH;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.USER_PASSWORD_MINIMUM_LENGTH;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.getAudioBitrate;
@@ -323,7 +325,6 @@ public class ImportInitvalues {
 		addCfg(list, CONFIG_REDIRECT_URL_FOR_EXTERNAL, "", Configuration.Type.string,
 				"Users entered the room via invitationHash or secureHash will be redirected to this URL on connection lost", VER_3_0);
 		addCfg(list, CONFIG_GOOGLE_ANALYTICS_CODE, null, Configuration.Type.string, "Code for Google Analytics", "3.1.0");
-		addCfg(list, CONFIG_HEADER_XFRAME, HEADER_XFRAME_SAMEORIGIN, Configuration.Type.string, "Value for 'X-Frame-Options' header (default: DENY), more info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options", VER_3_3_0);
 		addCfg(list, CONFIG_HEADER_CSP, HEADER_CSP_SELF, Configuration.Type.string, String.format("Value for 'Content-Security-Policy' header (default: %s), have to be modified to enable Google analytics site: https://content-security-policy.com/", HEADER_CSP_SELF), VER_3_3_0);
 		addCfg(list, CONFIG_EXT_PROCESS_TTL, String.valueOf(getExtProcessTtl()), Configuration.Type.number, String.format("Time to live in minutes for external processes such as conversion via ffmpeg (default %s minutes)", getExtProcessTtl()), VER_3_3_0);
 		addCfg(list, CONFIG_MYROOMS_ENABLED, String.valueOf(true), Configuration.Type.bool, "Users are allowed to create personal rooms", "3.3.2");
@@ -344,6 +345,8 @@ public class ImportInitvalues {
 		addCfg(list, CONFIG_MIC_RATE, "22", Configuration.Type.number, "The rate at which the microphone should capture sound, in kHz. The default value is 22 kHz.", VER_5_0_0);
 		addCfg(list, CONFIG_MIC_ECHO, String.valueOf(true), Configuration.Type.bool, "Whether or not echo cancellation is preferred and/or required.", VER_5_0_0);
 		addCfg(list, CONFIG_MIC_NOISE, String.valueOf(true), Configuration.Type.bool, "Whether noise suppression is preferred and/or required.", VER_5_0_0);
+		addCfg(list, CONFIG_CSP_XFRAME, HEADER_XFRAME_SELF, Configuration.Type.string, String.format("Value for 'frame-src' directive of 'Content-Security-Policy' header (default: %s), more info: https://w3c.github.io/webappsec-csp/", HEADER_XFRAME_SELF), VER_5_0_0);
+		addCfg(list, CONFIG_CHROME_EXT_URL, DEFAULT_CHROME_EXT_URL, Configuration.Type.string, String.format("URL to custom page with Chrome Extension logic (default %s).", DEFAULT_CHROME_EXT_URL), VER_5_0_0);
 		return list;
 	}
 	public void loadConfiguration(InstallationConfig cfg) {
diff --git a/openmeetings-util/src/main/java/org/apache/openmeetings/util/OpenmeetingsVariables.java b/openmeetings-util/src/main/java/org/apache/openmeetings/util/OpenmeetingsVariables.java
index 47179aa..bd6e401 100644
--- a/openmeetings-util/src/main/java/org/apache/openmeetings/util/OpenmeetingsVariables.java
+++ b/openmeetings-util/src/main/java/org/apache/openmeetings/util/OpenmeetingsVariables.java
@@ -75,7 +75,8 @@ public class OpenmeetingsVariables {
 	public static final String CONFIG_MIC_RATE = "mic.rate";
 	public static final String CONFIG_MIC_ECHO = "mic.echo.cancellation";
 	public static final String CONFIG_MIC_NOISE = "mic.noise.suppression";
-	public static final String CONFIG_HEADER_XFRAME = "header.x.frame.options";
+	public static final String CONFIG_CHROME_EXT_URL = "chrome.sharing.ext.url";
+	public static final String CONFIG_CSP_XFRAME = "header.csp.frame.options";
 	public static final String CONFIG_EXT_PROCESS_TTL = "external.process.ttl";
 	public static final String CONFIG_HEADER_CSP = "header.content.security.policy";
 	public static final String CONFIG_EMAIL_AT_REGISTER = "send.email.at.register";
@@ -95,7 +96,7 @@ public class OpenmeetingsVariables {
 	public static final String CONFIG_LNAME_MIN_LENGTH = "user.lname.minimum.length";
 	public static final String CONFIG_CHAT_SEND_ON_ENTER = "chat.send.on.enter";
 
-	public static final String HEADER_XFRAME_SAMEORIGIN = "SAMEORIGIN";
+	public static final String HEADER_XFRAME_SELF = "'self'";
 	public static final String HEADER_CSP_SELF = "default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self' data:; media-src 'self' blob:;";
 	public static final int RECENT_ROOMS_COUNT = 5;
 	public static final int USER_LOGIN_MINIMUM_LENGTH = 4;
@@ -116,6 +117,7 @@ public class OpenmeetingsVariables {
 	public static final int DEFAULT_MINUTES_REMINDER_SEND = 15;
 	public static final String DEFAULT_BASE_URL = "http://localhost:5080/openmeetings/";
 	public static final String DEFAULT_SIP_CONTEXT = "rooms";
+	public static final String DEFAULT_CHROME_EXT_URL = "https://www.webrtc-experiment.com/getSourceId/";
 
 	private static String cryptClassName = null;
 	private static String wicketApplicationName = null;
@@ -146,6 +148,9 @@ public class OpenmeetingsVariables {
 	private static boolean allowRegisterOauth = false;
 	private static boolean sendVerificationEmail = false;
 	private static boolean sendRegisterEmail = false;
+	private static String contentSecurityPolicy = HEADER_CSP_SELF;
+	private static String xFrameOptions = HEADER_XFRAME_SELF;
+	private static String chromeExtensionUrl = DEFAULT_CHROME_EXT_URL;
 
 	private OpenmeetingsVariables() {}
 
@@ -384,4 +389,28 @@ public class OpenmeetingsVariables {
 	public static void setSendRegisterEmail(boolean send) {
 		sendRegisterEmail = send;
 	}
+
+	public static String getxFrameOptions() {
+		return xFrameOptions;
+	}
+
+	public static void setxFrameOptions(String options) {
+		xFrameOptions = options;
+	}
+
+	public static String getContentSecurityPolicy() {
+		return contentSecurityPolicy;
+	}
+
+	public static void setContentSecurityPolicy(String policy) {
+		contentSecurityPolicy = policy;
+	}
+
+	public static String getChromeExtensionUrl() {
+		return chromeExtensionUrl;
+	}
+
+	public static void setChromeExtensionUrl(String url) {
+		chromeExtensionUrl = url;
+	}
 }
diff --git a/openmeetings-web/pom.xml b/openmeetings-web/pom.xml
index 6185131..cdffadf 100644
--- a/openmeetings-web/pom.xml
+++ b/openmeetings-web/pom.xml
@@ -212,6 +212,7 @@
 								<jsSourceFile>jquery.dialogextend.js</jsSourceFile>
 								<jsSourceFile>raw-video.js</jsSourceFile>
 								<jsSourceFile>raw-video-manager.js</jsSourceFile>
+								<jsSourceFile>getScreenId.js</jsSourceFile>
 								<jsSourceFile>raw-sharer.js</jsSourceFile>
 								<jsSourceFile>raw-room.js</jsSourceFile>
 							</jsSourceFiles>
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
index 5c6eeee..c21ce2b 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
@@ -19,14 +19,13 @@
 package org.apache.openmeetings.web.app;
 
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_EXT_PROCESS_TTL;
-import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_HEADER_CSP;
-import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_HEADER_XFRAME;
-import static org.apache.openmeetings.util.OpenmeetingsVariables.HEADER_CSP_SELF;
-import static org.apache.openmeetings.util.OpenmeetingsVariables.HEADER_XFRAME_SAMEORIGIN;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.getApplicationName;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.getBaseUrl;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.getChromeExtensionUrl;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.getContentSecurityPolicy;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.getExtProcessTtl;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.getWicketApplicationName;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.getxFrameOptions;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.isInitComplete;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.setExtProcessTtl;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.setInitComplete;
@@ -67,7 +66,6 @@ import org.apache.openmeetings.db.entity.user.User.Type;
 import org.apache.openmeetings.db.util.ws.RoomMessage;
 import org.apache.openmeetings.db.util.ws.TextRoomMessage;
 import org.apache.openmeetings.util.OmFileHelper;
-import org.apache.openmeetings.util.OpenmeetingsVariables;
 import org.apache.openmeetings.util.Version;
 import org.apache.openmeetings.util.ws.IClusterWsMessage;
 import org.apache.openmeetings.web.pages.AccessDeniedPage;
@@ -159,8 +157,6 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 	public static final String SIGNIN_MAPPING = "/signin";
 	public static final String NOTINIT_MAPPING = "/notinited";
 	final HazelcastInstance hazelcast = Hazelcast.getOrCreateHazelcastInstance(new XmlConfigBuilder().build());
-	private String xFrameOptions = HEADER_XFRAME_SAMEORIGIN;
-	private String contentSecurityPolicy = OpenmeetingsVariables.HEADER_CSP_SELF;
 	private ITopic<IClusterWsMessage> hazelWsTopic;
 
 	@Autowired
@@ -245,10 +241,12 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 					wresp.setHeader("X-XSS-Protection", "1; mode=block");
 					wresp.setHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload");
 					wresp.setHeader("X-Content-Type-Options", "nosniff");
-					wresp.setHeader("X-Frame-Options", xFrameOptions);
 					Url reqUrl = cycle.getRequest().getUrl();
 					wresp.setHeader("Content-Security-Policy"
-							, String.format("%s; connect-src 'self' %s;", contentSecurityPolicy, getWsUrl(reqUrl)));
+							, String.format("%s; connect-src 'self' %s; frame-src %s %s;"
+									, getContentSecurityPolicy(), getWsUrl(reqUrl)
+									, getxFrameOptions(), getChromeExtensionUrl()
+							));
 				}
 			}
 		});
@@ -299,8 +297,6 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 			cfgDao.reinit();
 
 			// Init properties
-			setXFrameOptions(cfgDao.getString(CONFIG_HEADER_XFRAME, HEADER_XFRAME_SAMEORIGIN));
-			setContentSecurityPolicy(cfgDao.getString(CONFIG_HEADER_CSP, HEADER_CSP_SELF));
 			updateJpaAddresses();
 			setExtProcessTtl(cfgDao.getInt(CONFIG_EXT_PROCESS_TTL, getExtProcessTtl()));
 			Version.logOMStarted();
@@ -558,16 +554,6 @@ public class Application extends AuthenticatedWebApplication implements IApplica
 	}
 
 	@Override
-	public void setXFrameOptions(String xFrameOptions) {
-		this.xFrameOptions = xFrameOptions;
-	}
-
-	@Override
-	public void setContentSecurityPolicy(String contentSecurityPolicy) {
-		this.contentSecurityPolicy = contentSecurityPolicy;
-	}
-
-	@Override
 	public String getServerId() {
 		return hazelcast.getName();
 	}
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
index 6280061..e8d6ae0 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
@@ -19,6 +19,7 @@
 package org.apache.openmeetings.web.room;
 
 import static org.apache.openmeetings.util.OpenmeetingsVariables.ATTR_CLASS;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.getChromeExtensionUrl;
 import static org.apache.openmeetings.web.app.WebSession.getDateFormat;
 import static org.apache.openmeetings.web.app.WebSession.getUserId;
 import static org.apache.openmeetings.web.room.wb.InterviewWbPanel.INTERVIEWWB_JS_REFERENCE;
@@ -141,7 +142,9 @@ public class RoomPanel extends BasePanel {
 			if (!Strings.isEmpty(r.getRedirectURL()) && (ws.getSoapLogin() != null || ws.getInvitation() != null)) {
 				options.put("reloadUrl", r.getRedirectURL());
 			}
-			StringBuilder sb = new StringBuilder("Room.init(").append(options.toString(new NullStringer())).append(");")
+			StringBuilder sb = new StringBuilder()
+					.append("MuazKhan.init('").append(getChromeExtensionUrl()).append("');")
+					.append("Room.init(").append(options.toString(new NullStringer())).append(");")
 					.append(wb.getInitScript())
 					.append("Room.setSize();")
 					.append(getQuickPollJs());
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/getScreenId.js b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/getScreenId.js
new file mode 100644
index 0000000..ea96a98
--- /dev/null
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/getScreenId.js
@@ -0,0 +1,209 @@
+// Licensed MIT
+// Last time updated on June 08, 2018
+
+// Latest file can be found here: https://cdn.webrtc-experiment.com/getScreenId.js
+
+// Muaz Khan         - www.MuazKhan.com
+// MIT License       - www.WebRTC-Experiment.com/licence
+// Documentation     - https://github.com/muaz-khan/getScreenId.
+
+// ______________
+// getScreenId.js
+
+/*
+getScreenId(function (error, sourceId, screen_constraints) {
+    // error    == null || 'permission-denied' || 'not-installed' || 'installed-disabled' || 'not-chrome'
+    // sourceId == null || 'string' || 'firefox'
+    
+    if(microsoftEdge) {
+        navigator.getDisplayMedia(screen_constraints).then(onSuccess, onFailure);
+    }
+    else {
+        navigator.mediaDevices.getUserMedia(screen_constraints).then(onSuccess)catch(onFailure);
+    }
+
+}, 'pass second parameter only if you want system audio');
+*/
+
+var MuazKhan = (function() {
+	const self = {};
+	let frameUrl = 'https://www.webrtc-experiment.com/getSourceId/';
+
+	self.init = function(url) {
+		frameUrl = url;
+	}
+	self.getScreenId = function(callback, custom_parameter) {
+        window.addEventListener('message', onIFrameCallback);
+
+        function onIFrameCallback(event) {
+            if (!event.data) return;
+
+            if (event.data.chromeMediaSourceId) {
+                if (event.data.chromeMediaSourceId === 'PermissionDeniedError') {
+                    callback('permission-denied');
+                } else {
+                    callback(null, event.data.chromeMediaSourceId, getScreenConstraints(null, event.data.chromeMediaSourceId, event.data.canRequestAudioTrack));
+                }
+
+                // this event listener is no more needed
+                window.removeEventListener('message', onIFrameCallback);
+            }
+
+            if (event.data.chromeExtensionStatus) {
+                callback(event.data.chromeExtensionStatus, null, getScreenConstraints(event.data.chromeExtensionStatus));
+
+                // this event listener is no more needed
+                window.removeEventListener('message', onIFrameCallback);
+            }
+        }
+
+        if(!custom_parameter) {
+            setTimeout(postGetSourceIdMessage, 100);
+        }
+        else {
+            setTimeout(function() {
+                postGetSourceIdMessage(custom_parameter);
+            }, 100);
+        }
+    };
+
+    function getScreenConstraints(error, sourceId, canRequestAudioTrack) {
+        var screen_constraints = {
+            audio: false,
+            video: {
+                mandatory: {
+                    chromeMediaSource: error ? 'screen' : 'desktop',
+                    maxWidth: window.screen.width > 1920 ? window.screen.width : 1920,
+                    maxHeight: window.screen.height > 1080 ? window.screen.height : 1080
+                },
+                optional: []
+            }
+        };
+
+        if(!!canRequestAudioTrack) {
+            screen_constraints.audio = {
+                mandatory: {
+                    chromeMediaSource: error ? 'screen' : 'desktop',
+                    // echoCancellation: true
+                },
+                optional: []
+            };
+        }
+
+        if (sourceId) {
+            screen_constraints.video.mandatory.chromeMediaSourceId = sourceId;
+
+            if(screen_constraints.audio && screen_constraints.audio.mandatory) {
+                screen_constraints.audio.mandatory.chromeMediaSourceId = sourceId;
+            }
+        }
+
+        return screen_constraints;
+    }
+
+    function postGetSourceIdMessage(custom_parameter) {
+        if (!iframe) {
+            loadIFrame(function() {
+                postGetSourceIdMessage(custom_parameter);
+            });
+            return;
+        }
+
+        if (!iframe.isLoaded) {
+            setTimeout(function() {
+                postGetSourceIdMessage(custom_parameter);
+            }, 100);
+            return;
+        }
+
+        if(!custom_parameter) {
+            iframe.contentWindow.postMessage({
+                captureSourceId: true
+            }, '*');
+        }
+        else if(!!custom_parameter.forEach) {
+            iframe.contentWindow.postMessage({
+                captureCustomSourceId: custom_parameter
+            }, '*');
+        }
+        else {
+            iframe.contentWindow.postMessage({
+                captureSourceIdWithAudio: true
+            }, '*');
+        }
+    }
+
+    var iframe;
+
+    // this function is used in RTCMultiConnection v3
+    self.getScreenConstraints = function(callback) {
+        loadIFrame(function() {
+            self.getScreenId(function(error, sourceId, screen_constraints) {
+                if(!screen_constraints) {
+                    screen_constraints = {
+                        video: true
+                    };
+                }
+
+                callback(error, screen_constraints.video);
+            });
+        });
+    };
+
+    function loadIFrame(loadCallback) {
+        if (iframe) {
+            loadCallback();
+            return;
+        }
+
+        iframe = document.createElement('iframe');
+        iframe.onload = function() {
+            iframe.isLoaded = true;
+
+            loadCallback();
+        };
+        iframe.src = frameUrl;
+        iframe.style.display = 'none';
+        (document.body || document.documentElement).appendChild(iframe);
+    }
+
+    self.getChromeExtensionStatus = function(callback) {
+        // for Firefox:
+        if (!!navigator.mozGetUserMedia) {
+            callback('installed-enabled');
+            return;
+        }
+
+        window.addEventListener('message', onIFrameCallback);
+
+        function onIFrameCallback(event) {
+            if (!event.data) return;
+
+            if (event.data.chromeExtensionStatus) {
+                callback(event.data.chromeExtensionStatus);
+
+                // this event listener is no more needed
+                window.removeEventListener('message', onIFrameCallback);
+            }
+        }
+
+        setTimeout(postGetChromeExtensionStatusMessage, 100);
+    };
+
+    function postGetChromeExtensionStatusMessage() {
+        if (!iframe) {
+            loadIFrame(postGetChromeExtensionStatusMessage);
+            return;
+        }
+
+        if (!iframe.isLoaded) {
+            setTimeout(postGetChromeExtensionStatusMessage, 100);
+            return;
+        }
+
+        iframe.contentWindow.postMessage({
+            getChromeExtensionStatus: true
+        }, '*');
+    }
+    return self;
+})();
diff --git a/pom.xml b/pom.xml
index 64fa4cb..091a209 100644
--- a/pom.xml
+++ b/pom.xml
@@ -114,7 +114,7 @@
 		<!--  URL of the ASF SonarQube server  -->
 		<sonar.host.url>https://builds.apache.org/analysis</sonar.host.url>
 		<!--  Exclude all generated code  -->
-		<sonar.exclusions>file:**/generated-sources/**, file:**/fabric.js, file:**/cssemoticons.js, file:**/kurento-utils.js, file:**/fileinput*.js, file:**/MathJax.js, file:**/network.js, file:**/jquery.dialogextend.js</sonar.exclusions>
+		<sonar.exclusions>file:**/generated-sources/**, file:**/fabric.js, file:**/cssemoticons.js, file:**/kurento-utils.js, file:**/getScreenId.js, file:**/fileinput*.js, file:**/MathJax.js, file:**/network.js, file:**/jquery.dialogextend.js</sonar.exclusions>
 		<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
 		<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
 		<sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>