Tokens are now completely private

pull/20/head
pabloFuente 2017-06-02 18:58:39 +02:00
parent 5ac854cf98
commit 1a5dbaba22
9 changed files with 146 additions and 96 deletions

File diff suppressed because one or more lines are too long

View File

@ -51,10 +51,6 @@ export class Connection {
+ ", streams opts: ", this.streamsOpts ); + ", streams opts: ", this.streamsOpts );
} }
setId( newId ) {
this.connectionId = newId;
}
addStream( stream: Stream ) { addStream( stream: Stream ) {
this.streams[stream.getIdInParticipant()] = stream; this.streams[stream.getIdInParticipant()] = stream;
this.room.getStreams()[stream.getIdInParticipant()] = stream; this.room.getStreams()[stream.getIdInParticipant()] = stream;
@ -70,17 +66,13 @@ export class Connection {
} }
} }
getId() {
return this.connectionId;
}
sendIceCandidate( candidate ) { sendIceCandidate( candidate ) {
console.debug(( this.local ? "Local" : "Remote" ), "candidate for", console.debug(( this.local ? "Local" : "Remote" ), "candidate for",
this.getId(), JSON.stringify( candidate ) ); this.connectionId, JSON.stringify( candidate ) );
this.openVidu.sendRequest( "onIceCandidate", { this.openVidu.sendRequest( "onIceCandidate", {
endpointName: this.getId(), endpointName: this.connectionId,
candidate: candidate.candidate, candidate: candidate.candidate,
sdpMid: candidate.sdpMid, sdpMid: candidate.sdpMid,
sdpMLineIndex: candidate.sdpMLineIndex sdpMLineIndex: candidate.sdpMLineIndex

View File

@ -65,6 +65,10 @@ export class SessionInternal {
let exParticipants = response.value; let exParticipants = response.value;
// IMPORTANT: Update connectionId with value send by server
this.localParticipant.connectionId = response.id;
this.participants[response.id] = this.localParticipant;
let roomEvent = { let roomEvent = {
participants: new Array<Connection>(), participants: new Array<Connection>(),
streams: new Array<Stream>() streams: new Array<Stream>()
@ -77,7 +81,7 @@ export class SessionInternal {
exParticipants[i]); exParticipants[i]);
connection.creationTime = new Date().getTime(); connection.creationTime = new Date().getTime();
this.participants[connection.getId()] = connection; this.participants[connection.connectionId] = connection;
roomEvent.participants.push(connection); roomEvent.participants.push(connection);
@ -130,16 +134,12 @@ export class SessionInternal {
configure(options: SessionOptions) { configure(options: SessionOptions) {
this.options = options; this.options = options;
this.id = options.sessionId; this.id = options.sessionId;
this.subscribeToStreams = options.subscribeToStreams == null ? true : options.subscribeToStreams; this.subscribeToStreams = options.subscribeToStreams == null ? true : options.subscribeToStreams;
this.updateSpeakerInterval = options.updateSpeakerInterval || 1500; this.updateSpeakerInterval = options.updateSpeakerInterval || 1500;
this.thresholdSpeaker = options.thresholdSpeaker || -50; this.thresholdSpeaker = options.thresholdSpeaker || -50;
this.localParticipant.setId(options.participantId);
this.activateUpdateMainSpeaker(); this.activateUpdateMainSpeaker();
this.participants[options.participantId] = this.localParticipant;
} }
getId() { getId() {
@ -210,7 +210,7 @@ export class SessionInternal {
let connection = new Connection(this.openVidu, false, this, options); let connection = new Connection(this.openVidu, false, this, options);
let pid = connection.getId(); let pid = connection.connectionId;
if (!(pid in this.participants)) { if (!(pid in this.participants)) {
console.info("Publisher not found in participants list by its id", pid); console.info("Publisher not found in participants list by its id", pid);
} else { } else {
@ -240,7 +240,7 @@ export class SessionInternal {
let connection = new Connection(this.openVidu, false, this, msg); let connection = new Connection(this.openVidu, false, this, msg);
connection.creationTime = new Date().getTime(); connection.creationTime = new Date().getTime();
let pid = connection.getId(); let pid = connection.connectionId;
if (!(pid in this.participants)) { if (!(pid in this.participants)) {
console.log("New participant to participants list with id", pid); console.log("New participant to participants list with id", pid);
this.participants[pid] = connection; this.participants[pid] = connection;
@ -434,12 +434,12 @@ export class SessionInternal {
return; return;
} }
delete this.participants[connection.getId()]; delete this.participants[connection.connectionId];
connection.dispose(); connection.dispose();
if (connection === this.localParticipant) { if (connection === this.localParticipant) {
console.log("Unpublishing my media (I'm " + connection.getId() + ")"); console.log("Unpublishing my media (I'm " + connection.connectionId + ")");
delete this.localParticipant; delete this.localParticipant;
this.openVidu.sendRequest('unpublishVideo', function (error, response) { this.openVidu.sendRequest('unpublishVideo', function (error, response) {
if (error) { if (error) {
@ -464,10 +464,10 @@ export class SessionInternal {
if (connection === this.localParticipant) { if (connection === this.localParticipant) {
delete this.participants[connection.getId()]; delete this.participants[connection.connectionId];
connection.dispose(); connection.dispose();
console.log("Unpublishing my media (I'm " + connection.getId() + ")"); console.log("Unpublishing my media (I'm " + connection.connectionId + ")");
delete this.localParticipant; delete this.localParticipant;
this.openVidu.sendRequest('unpublishVideo', function (error, response) { this.openVidu.sendRequest('unpublishVideo', function (error, response) {
if (error) { if (error) {

View File

@ -323,7 +323,7 @@ export class Stream {
getId() { getId() {
if (this.connection) { if (this.connection) {
return this.connection.getId() + "_" + this.id; return this.connection.connectionId + "_" + this.id;
} else { } else {
return this.id + "_webcam"; return this.id + "_webcam";
} }

View File

@ -33,7 +33,8 @@ public class ProtocolElements {
public static final String LEAVEROOM_METHOD = "leaveRoom"; public static final String LEAVEROOM_METHOD = "leaveRoom";
public static final String JOINROOM_METHOD = "joinRoom"; public static final String JOINROOM_METHOD = "joinRoom";
public static final String JOINROOM_USER_PARAM = "token"; public static final String JOINROOM_USER_PARAM = "user";
public static final String JOINROOM_TOKEN_PARAM = "token";
public static final String JOINROOM_ROOM_PARAM = "session"; public static final String JOINROOM_ROOM_PARAM = "session";
public static final String JOINROOM_METADATA_PARAM = "metadata"; public static final String JOINROOM_METADATA_PARAM = "metadata";
public static final String JOINROOM_DATACHANNELS_PARAM = "dataChannels"; public static final String JOINROOM_DATACHANNELS_PARAM = "dataChannels";

View File

@ -75,7 +75,7 @@ public class NotificationRoomManager {
* when responding back to the client) * when responding back to the client)
* @see RoomManager#joinRoom(String, String, boolean, boolean, KurentoClientSessionInfo, String) * @see RoomManager#joinRoom(String, String, boolean, boolean, KurentoClientSessionInfo, String)
*/ */
public void joinRoom(String token, String roomId, boolean dataChannels, public void joinRoom(String userName, String roomId, boolean dataChannels,
boolean webParticipant, ParticipantRequest request) { boolean webParticipant, ParticipantRequest request) {
Set<UserParticipant> existingParticipants = null; Set<UserParticipant> existingParticipants = null;
UserParticipant newParticipant = null; UserParticipant newParticipant = null;
@ -84,13 +84,13 @@ public class NotificationRoomManager {
new DefaultKurentoClientSessionInfo(request.getParticipantId(), roomId); new DefaultKurentoClientSessionInfo(request.getParticipantId(), roomId);
JoinRoomReturnValue returnValue = internalManager JoinRoomReturnValue returnValue = internalManager
.joinRoom(token, roomId, dataChannels, webParticipant, kcSessionInfo, .joinRoom(userName, roomId, dataChannels, webParticipant, kcSessionInfo,
request.getParticipantId()); request.getParticipantId());
existingParticipants = returnValue.existingParticipants; existingParticipants = returnValue.existingParticipants;
newParticipant = returnValue.newParticipant; newParticipant = returnValue.newParticipant;
} catch (OpenViduException e) { } catch (OpenViduException e) {
log.warn("PARTICIPANT {}: Error joining/creating room {}", token, roomId, e); log.warn("PARTICIPANT {}: Error joining/creating room {}", userName, roomId, e);
notificationRoomHandler.onParticipantJoined(request, roomId, null, null, e); notificationRoomHandler.onParticipantJoined(request, roomId, null, null, e);
} }
if (existingParticipants != null) { if (existingParticipants != null) {
@ -438,4 +438,8 @@ public class NotificationRoomManager {
public String newToken(String sessionId, ParticipantRole role, String metaData){ public String newToken(String sessionId, ParticipantRole role, String metaData){
return this.internalManager.newToken(sessionId, role, metaData); return this.internalManager.newToken(sessionId, role, metaData);
} }
public String newRandomUserName(String token, String roomId){
return this.internalManager.newRandomUserName(token, roomId);
}
} }

View File

@ -83,8 +83,8 @@ public class RoomManager {
private KurentoClientProvider kcProvider; private KurentoClientProvider kcProvider;
private final ConcurrentMap<String, Room> rooms = new ConcurrentHashMap<String, Room>(); private final ConcurrentMap<String, Room> rooms = new ConcurrentHashMap<String, Room>();
private final ConcurrentMap<String, ConcurrentHashMap<String, Token>> sessionidTokenTokenobj = new ConcurrentHashMap<>();
private final ConcurrentMap<String, ConcurrentHashMap<String, Token>> sessionIdToken = new ConcurrentHashMap<>(); private final ConcurrentMap<String, ConcurrentHashMap<String, String>> sessionidUsernameToken = new ConcurrentHashMap<>();
@Value("${openvidu.security}") @Value("${openvidu.security}")
private boolean SECURITY_ENABLED; private boolean SECURITY_ENABLED;
@ -120,11 +120,11 @@ public class RoomManager {
* @return set of existing peers of type {@link UserParticipant}, can be empty if first * @return set of existing peers of type {@link UserParticipant}, can be empty if first
* @throws OpenViduException on error while joining (like the room is not found or is closing) * @throws OpenViduException on error while joining (like the room is not found or is closing)
*/ */
public JoinRoomReturnValue joinRoom(String token, String roomId, boolean dataChannels, public JoinRoomReturnValue joinRoom(String userName, String roomId, boolean dataChannels,
boolean webParticipant, KurentoClientSessionInfo kcSessionInfo, String participantId) boolean webParticipant, KurentoClientSessionInfo kcSessionInfo, String participantId)
throws OpenViduException { throws OpenViduException {
log.debug("Request [JOIN_ROOM] user={}, room={}, web={} " + "kcSessionInfo.room={} ({})", log.debug("Request [JOIN_ROOM] user={}, room={}, web={} " + "kcSessionInfo.room={} ({})",
token, roomId, webParticipant, userName, roomId, webParticipant,
kcSessionInfo != null ? kcSessionInfo.getRoomName() : null, participantId); kcSessionInfo != null ? kcSessionInfo.getRoomName() : null, participantId);
Room room = rooms.get(roomId); Room room = rooms.get(roomId);
if (room == null && kcSessionInfo != null) { if (room == null && kcSessionInfo != null) {
@ -138,12 +138,12 @@ public class RoomManager {
+ "' can join"); + "' can join");
} }
if (room.isClosed()) { if (room.isClosed()) {
log.warn("'{}' is trying to join room '{}' but it is closing", token, roomId); log.warn("'{}' is trying to join room '{}' but it is closing", userName, roomId);
throw new OpenViduException(Code.ROOM_CLOSED_ERROR_CODE, throw new OpenViduException(Code.ROOM_CLOSED_ERROR_CODE,
"'" + token + "' is trying to join room '" + roomId + "' but it is closing"); "'" + userName + "' is trying to join room '" + roomId + "' but it is closing");
} }
Set<UserParticipant> existingParticipants = getParticipants(roomId); Set<UserParticipant> existingParticipants = getParticipants(roomId);
UserParticipant newParticipant = room.join(participantId, token, getTokenClientMetadata(token, roomId), getTokenServerMetadata(token, roomId), dataChannels, webParticipant); UserParticipant newParticipant = room.join(participantId, userName, getTokenClientMetadata(userName, roomId), getTokenServerMetadata(userName, roomId), dataChannels, webParticipant);
return new JoinRoomReturnValue(newParticipant, existingParticipants); return new JoinRoomReturnValue(newParticipant, existingParticipants);
} }
@ -172,8 +172,11 @@ public class RoomManager {
} }
room.leave(participantId); room.leave(participantId);
if (this.sessionIdToken.get(roomName) != null){ if (sessionidUsernameToken.get(roomName) != null){
this.sessionIdToken.get(roomName).remove(participant.getName()); String token = sessionidUsernameToken.get(roomName).remove(participant.getName());
if (sessionidTokenTokenobj.get(roomName) != null) {
sessionidTokenTokenobj.get(roomName).remove(token);
}
} }
showMap(); showMap();
@ -190,7 +193,8 @@ public class RoomManager {
room.close(); room.close();
rooms.remove(roomName); rooms.remove(roomName);
sessionIdToken.remove(roomName); sessionidUsernameToken.remove(roomName);
sessionidTokenTokenobj.remove(roomName);
showMap(); showMap();
@ -864,7 +868,8 @@ public class RoomManager {
room.close(); room.close();
rooms.remove(roomName); rooms.remove(roomName);
sessionIdToken.remove(roomName); sessionidUsernameToken.remove(roomName);
sessionidTokenTokenobj.remove(roomName);
log.warn("Room '{}' removed and closed", roomName); log.warn("Room '{}' removed and closed", roomName);
return participants; return participants;
@ -948,7 +953,7 @@ public class RoomManager {
private void showMap(){ private void showMap(){
System.out.println("------------------------------"); System.out.println("------------------------------");
System.out.println(this.sessionIdToken.toString()); System.out.println(this.sessionidTokenTokenobj.toString());
System.out.println("------------------------------"); System.out.println("------------------------------");
} }
@ -958,28 +963,26 @@ public class RoomManager {
public boolean isParticipantInRoom(String token, String roomId) throws OpenViduException { public boolean isParticipantInRoom(String token, String roomId) throws OpenViduException {
if (SECURITY_ENABLED) { if (SECURITY_ENABLED) {
if (this.sessionIdToken.get(roomId) != null) { if (this.sessionidTokenTokenobj.get(roomId) != null) {
return this.sessionIdToken.get(roomId).containsKey(token); return this.sessionidTokenTokenobj.get(roomId).containsKey(token);
} else{ } else{
return false; return false;
} }
} else { } else {
this.sessionIdToken.putIfAbsent(roomId, new ConcurrentHashMap<>()); this.sessionidUsernameToken.putIfAbsent(roomId, new ConcurrentHashMap<>());
if (this.sessionIdToken.get(roomId).containsKey(token)){ this.sessionidTokenTokenobj.putIfAbsent(roomId, new ConcurrentHashMap<>());
// If the user already exists this.sessionidUsernameToken.get(roomId).putIfAbsent(token, token);
throw new OpenViduException(Code.EXISTING_USER_IN_ROOM_ERROR_CODE, "The user " + token + " already exists in room " + roomId); this.sessionidTokenTokenobj.get(roomId).putIfAbsent(token, new Token(token));
} else { return true;
this.sessionIdToken.get(roomId).put(token, new Token(token));
return true;
}
} }
} }
public boolean isPublisherInRoom(String token, String roomId) { public boolean isPublisherInRoom(String userName, String roomId) {
if (SECURITY_ENABLED) { if (SECURITY_ENABLED) {
if (this.sessionIdToken.get(roomId) != null){ if (this.sessionidUsernameToken.get(roomId) != null){
if (this.sessionIdToken.get(roomId).get(token) != null){ String token = this.sessionidUsernameToken.get(roomId).get(userName);
return (this.sessionIdToken.get(roomId).get(token).getRole().equals(ParticipantRole.PUBLISHER)); if (token != null){
return (this.sessionidTokenTokenobj.get(roomId).get(token).getRole().equals(ParticipantRole.PUBLISHER));
} else { } else {
return false; return false;
} }
@ -991,55 +994,61 @@ public class RoomManager {
} }
} }
public String getTokenClientMetadata(String token, String roomId) throws OpenViduException { public String getTokenClientMetadata(String userName, String roomId) throws OpenViduException {
if (this.sessionIdToken.get(roomId) != null){ if (this.sessionidUsernameToken.get(roomId) != null && this.sessionidTokenTokenobj.get(roomId) != null){
if (this.sessionIdToken.get(roomId).get(token) != null){ String token = this.sessionidUsernameToken.get(roomId).get(userName);
return this.sessionIdToken.get(roomId).get(token).getClientMetadata(); if (token != null){
return this.sessionidTokenTokenobj.get(roomId).get(token).getClientMetadata();
} else { } else {
throw new OpenViduException(Code.USER_NOT_FOUND_ERROR_CODE, roomId); throw new OpenViduException(Code.USER_NOT_FOUND_ERROR_CODE, token);
} }
} else { } else {
throw new OpenViduException(Code.ROOM_NOT_FOUND_ERROR_CODE, token); throw new OpenViduException(Code.ROOM_NOT_FOUND_ERROR_CODE, roomId);
} }
} }
public String getTokenServerMetadata(String token, String roomId) throws OpenViduException { public String getTokenServerMetadata(String userName, String roomId) throws OpenViduException {
if (this.sessionIdToken.get(roomId) != null){ if (this.sessionidUsernameToken.get(roomId) != null && this.sessionidTokenTokenobj.get(roomId) != null){
if (this.sessionIdToken.get(roomId).get(token) != null){ String token = this.sessionidUsernameToken.get(roomId).get(userName);
return this.sessionIdToken.get(roomId).get(token).getServerMetadata(); if (token != null){
return this.sessionidTokenTokenobj.get(roomId).get(token).getServerMetadata();
} else { } else {
throw new OpenViduException(Code.USER_NOT_FOUND_ERROR_CODE, roomId); throw new OpenViduException(Code.USER_NOT_FOUND_ERROR_CODE, token);
} }
} else { } else {
throw new OpenViduException(Code.ROOM_NOT_FOUND_ERROR_CODE, token); throw new OpenViduException(Code.ROOM_NOT_FOUND_ERROR_CODE, roomId);
} }
} }
public void setTokenClientMetadata(String token, String roomId, String metadata) throws OpenViduException { public void setTokenClientMetadata(String userName, String roomId, String metadata) throws OpenViduException {
if (this.sessionIdToken.get(roomId) != null){ if (this.sessionidUsernameToken.get(roomId) != null && this.sessionidTokenTokenobj.get(roomId) != null){
if (this.sessionIdToken.get(roomId).get(token) != null){ String token = this.sessionidUsernameToken.get(roomId).get(userName);
this.sessionIdToken.get(roomId).get(token).setClientMetadata(metadata); if (token != null){
this.sessionidTokenTokenobj.get(roomId).get(token).setClientMetadata(metadata);
} else { } else {
throw new OpenViduException(Code.USER_NOT_FOUND_ERROR_CODE, roomId); throw new OpenViduException(Code.USER_NOT_FOUND_ERROR_CODE, token);
} }
} else { } else {
throw new OpenViduException(Code.ROOM_NOT_FOUND_ERROR_CODE, token); throw new OpenViduException(Code.ROOM_NOT_FOUND_ERROR_CODE, roomId);
} }
} }
public String newSessionId(){ public String newSessionId(){
String sessionId = new BigInteger(130, new SecureRandom()).toString(32); String sessionId = new BigInteger(130, new SecureRandom()).toString(32);
this.sessionIdToken.put(sessionId, new ConcurrentHashMap<>());
this.sessionidTokenTokenobj.put(sessionId, new ConcurrentHashMap<>());
this.sessionidUsernameToken.put(sessionId, new ConcurrentHashMap<>());
showMap(); showMap();
return sessionId; return sessionId;
} }
public String newToken(String roomId, ParticipantRole role, String metadata){ public String newToken(String roomId, ParticipantRole role, String metadata){
if (this.sessionIdToken.get(roomId) != null) { if (this.sessionidUsernameToken.get(roomId) != null && this.sessionidTokenTokenobj.get(roomId) != null) {
if(metadataFormatCorrect(metadata)){ if(metadataFormatCorrect(metadata)){
String token = new BigInteger(130, new SecureRandom()).toString(32); String token = new BigInteger(130, new SecureRandom()).toString(32);
if (SECURITY_ENABLED) { // Store the token only if security is enabled if (SECURITY_ENABLED) { // Store the token only if security is enabled
this.sessionIdToken.get(roomId).put(token, new Token(token, role, metadata)); this.sessionidTokenTokenobj.get(roomId).put(token, new Token(token, role, metadata));
} }
showMap(); showMap();
return token; return token;
@ -1054,8 +1063,35 @@ public class RoomManager {
} }
} }
public String newRandomUserName(String token, String roomId) {
if (SECURITY_ENABLED) {
if (this.sessionidUsernameToken.get(roomId) != null && this.sessionidTokenTokenobj.get(roomId) != null) {
if (this.sessionidTokenTokenobj.get(roomId).get(token) != null) {
return this.generateAndStoreUserName(token, roomId);
} else {
throw new OpenViduException(Code.USER_NOT_FOUND_ERROR_CODE, token);
}
} else {
throw new OpenViduException(Code.ROOM_NOT_FOUND_ERROR_CODE, roomId);
}
} else {
return token;
}
}
private String generateAndStoreUserName(String token, String roomId) {
String userName = new BigInteger(130, new SecureRandom()).toString(32);
ConcurrentHashMap<String, String> usernameToken = this.sessionidUsernameToken.get(roomId);
while(usernameToken.containsKey(userName)){ // Avoid random 'userName' collisions
userName = new BigInteger(130, new SecureRandom()).toString(32);
}
this.sessionidUsernameToken.get(roomId).put(userName, token);
return userName;
}
public boolean metadataFormatCorrect(String metadata){ public boolean metadataFormatCorrect(String metadata){
// Max 1000 chars // Max 1000 chars
return (metadata.length() <= 1000); return (metadata.length() <= 1000);
} }
} }

View File

@ -53,14 +53,15 @@ public class JsonRpcUserControl {
ExecutionException, OpenViduException { ExecutionException, OpenViduException {
String roomId = getStringParam(request, ProtocolElements.JOINROOM_ROOM_PARAM); String roomId = getStringParam(request, ProtocolElements.JOINROOM_ROOM_PARAM);
String token = getStringParam(request, ProtocolElements.JOINROOM_USER_PARAM); String token = getStringParam(request, ProtocolElements.JOINROOM_TOKEN_PARAM);
String userName = roomManager.newRandomUserName(token, roomId);
String clientMetadata = getStringParam(request, ProtocolElements.JOINROOM_METADATA_PARAM); String clientMetadata = getStringParam(request, ProtocolElements.JOINROOM_METADATA_PARAM);
if(roomManager.getRoomManager().isParticipantInRoom(token, roomId)){ if(roomManager.getRoomManager().isParticipantInRoom(token, roomId)){
if(roomManager.getRoomManager().metadataFormatCorrect(clientMetadata)){ if(roomManager.getRoomManager().metadataFormatCorrect(clientMetadata)){
this.roomManager.getRoomManager().setTokenClientMetadata(token, roomId, clientMetadata); this.roomManager.getRoomManager().setTokenClientMetadata(userName, roomId, clientMetadata);
boolean dataChannels = false; boolean dataChannels = false;
if (request.getParams().has(ProtocolElements.JOINROOM_DATACHANNELS_PARAM)) { if (request.getParams().has(ProtocolElements.JOINROOM_DATACHANNELS_PARAM)) {
@ -69,11 +70,11 @@ public class JsonRpcUserControl {
} }
ParticipantSession participantSession = getParticipantSession(transaction); ParticipantSession participantSession = getParticipantSession(transaction);
participantSession.setParticipantName(token); participantSession.setParticipantName(userName);
participantSession.setRoomName(roomId); participantSession.setRoomName(roomId);
participantSession.setDataChannels(dataChannels); participantSession.setDataChannels(dataChannels);
roomManager.joinRoom(token, roomId, dataChannels, true, participantRequest); roomManager.joinRoom(userName, roomId, dataChannels, true, participantRequest);
} else { } else {
System.out.println("Error: metadata format is incorrect"); System.out.println("Error: metadata format is incorrect");
throw new OpenViduException(Code.USER_METADATA_FORMAT_INVALID_ERROR_CODE, throw new OpenViduException(Code.USER_METADATA_FORMAT_INVALID_ERROR_CODE,

21
update-plainjs.sh Executable file
View File

@ -0,0 +1,21 @@
cd openvidu-browser/src/main/resources
npm run updatetsc
npm run browserify
cd ../../../../
# openvidu-sample-basic-plainjs
cp openvidu-browser/src/main/resources/static/js/OpenVidu.js ../openvidu-sample-basic-plainjs/web/OpenVidu.js
# openvidu-sample-secure
cp openvidu-browser/src/main/resources/static/js/OpenVidu.js ../openvidu-sample-secure/src/main/resources/static/OpenVidu.js
# openvidu-sample-secure-mvc
cp openvidu-browser/src/main/resources/static/js/OpenVidu.js ../openvidu-sample-secure-mvc/demo-java-mvc-secure/src/main/resources/static/OpenVidu.js
# openvidu-sample-secure-spa-node
cp openvidu-browser/src/main/resources/static/js/OpenVidu.js ../openvidu-sample-secure-spa-node/public/OpenVidu.js
# openvidu-sample-secure-mvc-node
cp openvidu-browser/src/main/resources/static/js/OpenVidu.js ../openvidu-sample-secure-mvc-node/public/OpenVidu.js