Open bakhtizin opened 7 years ago
@sampaiodiego can you please investigate this issue?
FWIW, we don't have this issue in our iFrame integration. We are also running 0.58.2
@sampaiodiego, @danieljhochman,
hoping that it can contribute to the understanding and possible solution, following is the short technical description of the actual Rocket.Chat integration:
<iframe id="rocketChat" src="#" data-src="${requestScope.rocketChatUrl}" frameborder="0"></iframe>
a separate .js file defines initialization function and auxilary functionality as follows:
var rocketChat = {
keyName: 'rocketChatLogin',
init: function(){
var iframe = $('#rocketChat');
if($(iframe).length){
$(iframe).attr('src', $(iframe).attr('data-src'));
}
// event listener for events from rocketchat iframe
window.addEventListener('message', function(e){
console.log(e); // todo: remove
switch(e.data.eventName){
case 'startup':
//rocketChat is loaded
rocketChat.startupRocketChat();
break;
case 'unread-changed':
// new message
// {eventName: "unread-changed", data: 1}
// {eventName: "unread-changed", data: ""}
rocketChat.notificationChangedRocketChat(e.data.data);
break;
case 'notification':
break;
}
});
},
postToRocketChat: function(externalCommand, service){
$('#rocketChat')[0].contentWindow.postMessage({
externalCommand: externalCommand,
service: service
}, '*');
},
loginRocketChat: function(){
window.sessionStorage.setItem(rocketChat.keyName, 'connected'); //add key
rocketChat.postToRocketChat('call-custom-oauth-login', 'keycloak');
},
logoutRocketChat: function(redirectUrl){
window.sessionStorage.removeItem(rocketChat.keyName);
rocketChat.postToRocketChat('logout');
window.location.href = redirectUrl;
},
startupRocketChat: function(){
var isLoggedIn = window.sessionStorage.getItem(rocketChat.keyName);
if(!isLoggedIn){
// key not found
rocketChat.loginRocketChat();
}
},
notificationChangedRocketChat: function(count){
var notificationElement = $('.notification');
if(count > 0){
$(notificationElement).show().text(count);
} else {
$(notificationElement).hide().text('0');
}
},
//.....
//.....
}
@danieljhochman I didn't manage to overcome the navigation failure and curious how have you configured your system. Could you please help/shed some ligth on this issue. Many thanks.
Any update on this issue? I am also having this issue.
this issue is pretty default. When your iframe
's url changes it propagates to parent window history. If .go()
back far enough you will get to rocket.chat login page and you're already authorized, so it redirects home. You can also go
one more step back and that would be your intended back button action, but you have to know how many steps ago your iframe
have loaded and there's no way forward
. That's what I know. We are all doomed.
Is there some way to prevent meteor and flow router from changing window history?
I could for example postMessage
to my window.parent
from FlowRouter.triggers.enter([...])
and then in my app try to history.replaceState()
but that doesn't make any difference.
Would that be a good idea to conditionally modify FlowRouter
methods and call original methods from within FlowRouter.withReplaceState
when ?layout=embedded
?
The documentation about Keycloak is going to be written. Please follow https://github.com/RocketChat/docs/issues/790 and fell free to help us :)
@engelgabriel could you explain please how Keycloack is going to be helpful in this situation?
I encountered the same issue while integrating the rocketchat and following solution worked for me:
The Issue
1) when initiating the iframe either by writing explicitly in the html or appending it to the DOM through javascript , an new entry of rocketchat's url is pushed in the browser's history stack
2)If you are sending token from your parent application to the rocket chat in the iframe to login, Rocket chat will redirect if login is successful from the root_url to root_url/home creating a new entry in the browser history stack
3)Every time you click a anchor tag (enter a room etc) in the rocket chat (inside iframe) another entry is created and pushed in the browser history stack
Now when the app gets loaded the stack looks like this even if the iframe is hidden by default in the beginning
now if you press the back button the browser will go to rocketchat_url , the route will find out that a token is already present in the localstorage so it will redirect again to /home, therefore we will keep pressing the back button and it wont work
Solution
We need to avoid creating a new entry in the browser's stack for all the three points I mention above
1 & 2) Instead of giving url to the iframe in the html directly, we can add an empty iframe first, that will create a window object for that iframe , now we can access that window and use location.replace to set the url, this will replace the current entry in the browser history instead of creating a new one , this will work for the first point, for the second point we can directly give the '/home' url so that rocket chat doesnt have to redirect after login, if you are not login /home page will automatically fetch the token from your app if youre using postMessage to send the token.
$('body').append(`<iframe id="chat"></iframe>`);
$('iframe#chat')[0].contentWindow.location.replace(chat._baseUrl+'/home');
3)Adding an event listener on all the anchor tags in rocket chat that will replace the current entry in the history stack with the anchor tag's url so that when click is performed and browser tries to create new entry it finds the same entry already present on top of the stack and does not create a new entry
var anchors = document.getElementsByTagName('a');
for (var i = 0; i < anchors.length; i++) {
var anchor = anchors[i];
anchor.addEventListener('click', function (event) {
history.replaceState(null, null, anchor.href);
}, false);
}
^above code needs to be run inside the iframe window
Hope this will give you enough insight to solve the issue
var anchors = document.getElementsByTagName('a'); for (var i = 0; i < anchors.length; i++) { var anchor = anchors[i]; anchor.addEventListener('click', function (event) { history.replaceState(null, null, anchor.href); }, false); }
^above code needs to be run inside the iframe window
is that really work to someone? It doesn't work for me
Hi, Any news about this bug ? @BilalAlam173 I understand your code and it works well as a standalone, but the problem is where could we put that code in Rocker.Chat ? The problem is that with React the DOM changes regularly so we should add the event each time the user interacts with Rocket.Chat. So it isn't quite simple.
As anyone tried to plug some code, such as the one above, in the React Router ?
Hi, Here is a patch that works for me.
index cd29aaeb8a..78fe22ab7c 100644
--- a/client/startup/routes.ts
+++ b/client/startup/routes.ts
@@ -184,4 +184,19 @@ FlowRouter.notFound = {
Meteor.startup(() => {
FlowRouter.initialize();
+ FlowRouter.triggers.enter([myTrigger]);
});
+
+function myTrigger(context) {
+ window.history.replaceState({"path": context.path}, null, context.path);
+}
+
+window.pushStateOriginal = window.history.pushState.bind(window.history);
+window.history.pushState = function (state, x, path) {
+ if ((history.state !== undefined) && (history.state.path == path)) {
+ history.replaceState(state, x, path);
+ }
+ else {
+ window.pushStateOriginal(state, x, path);
+ }
+}```
Description:
I am integrating Rocket.Chat to our existing web application, which has a large user base. After successfull Rocket.Chat Keycloak integration (SSO), it was decided to inject chat to the existing application using available iframe integration since it allows sending commands for authentication and simplifies Rocket.Chat events handling.
The actual problem is the fact that, iframe integration breaks site navigation, i.e. klicking browser's back button doesn't navigate to the previous page.
Server Setup Information:
Steps to Reproduce:
Expected behavior:
Possibility to navigate back in browser
Actual behavior:
Clicking back button of the browser doesn't open previously open page