I have a single-page react app hosted on github pages, which comes with many limitations. In order to get my "Login with Twitter" flow working, I found it was necessary to open the dynamic twitter login url in a new tab, give the Twitter API an endpoint on my backend as the callback URL, and then have my backend redirect the user to the root url of my frontend client with the generated JWT token in the URL as a query (/?token=abcd1234). I then have some code on the landing page of my client that looks like this:
useEffect(() => {
// at /?close, just close the window
if (props.location.search === '?close') {
window.close()
closeWindow()
setShowCloseMessage(true)
// at /?token, save the token to localstorage, then close the window
} else if (tokenUrlRE.test(props.location.search)) {
const token = props.location.search.match(tokenRE)[0]
localStorage.setItem('token', token)
window.close()
closeWindow()
setShowCloseMessage(true)
}
}, [])
This works fine in Chrome, but not Firefox - perhaps Firefox is more stringent about requiring that Windows only be closed by the script that opened them, and Chrome allows any script on the same domain that opened a window to close it?
Anyway, several other answers here on Stackexchange recommended the following code, which I added inside the closeWindow() function appearing in the above code:
function closeWindow() {
console.log('clicked close')
window.open('', '_parent', '')
window.close()
}
But this also did not work in Firefox.
Furthermore, this additional solution I found caused React to crash:
open(location, '_self').close()
Is there any way to accomplish what I want with Firefox? For the time being I have simply used that showClose state variable seen in the first code block to display a "Sign-in successful, please return to the previous tab" message, but this is less than ideal.
Related
I'm trying to use window.open to open an extension page, I don't care about checking if the user has the extension, I just want to open a window that starts with extension://, it's not working and says failed to load url because the scheme does not have a registered handler. My code looks like this:
const openedWindow = window.open("extension://<extension url>", "", "width=300, height=300");
openedWindow.onload = () => {
openedWindow.close();
}
this code works with normal urls, but not with ones starting with extension://. Is there any way to open a url like this?
edit: needed to use chrome-extension:// instead of just extension. Now there's a new problem, chrome is blocking the page. How do I fix this?
It's because the correct URL for a chrome extension is chrome-extension://1234
Also popups should be explicitly allowed by a user interaction on the popup permission that Chrome asks in the URL bar
The application I work on integrates with some platforms with some strict security policies when it comes to user authentication, and as such authentication from our side has to be handled a bit differently as well. The details here aren't terribly important.
I'm working on a new feature now where a user can open some items from a list, but from a UX perspective it would make the most sense to open these up in new tabs, since users will want to open a lot of them at once without having to navigate back to the list and find their place within it again.
So to get this working, our API has a redirects endpoint that handles the authentication. Implementation details aren't important, it's just important to know that this endpoint will receive a URL that should be navigated to (supplied from our UI), and it'll spit back out a redirect URL with a token.
As such, I've gone with the following function which gets called when a button is clicked by the user
async function openInNewTab() {
// $ajax is an axios instance that calls the endpoint
const { url } = await $ajax.post('/redirects', {
data: {
url: "myurl.com/route/to/go/to",
//...
}
});
window.open(url)
}
As you can see, it's very simple, it gets the redirect URL from our API and tries to open that URL in a new tab. This works in Chrome, however it doesn't work in Firefox or Safari, prompting the user that a popup was blocked.
I'm well aware that browser have a number of rules regarding popups and when they're blocked, however in this instance this action is being initiated by user interaction via a button click, the only problem being that the function getting called is asynchronous.
Is there any way to make this work in Firefox and Safari? The function simply doesn't work well enough in realistic network speeds without it being asynchronous, and with the way our application works there's no way for us to circumvent the redirect URL with something like a target="_blank" in a link, that would fail to authenticate properly.
There's 2 potential workarounds that I ended up with here.
They're both fairly similar, however from my testing it seems Safari is the strictest when it comes to parsing events as popups.
The one that works in all major browsers (Chromium-based ones, Firefox and Safari), but feels a bit hacky.
Found this here: https://stackoverflow.com/a/70463940/8610114
const { url } = await $ajax.post('/redirects', {
data: {
url: "myurl.com/route/to/go/to",
//...
}
});
setTimeout(() => {
window.open(url, "_blank");
});
And the other solution, although this one doesn't seem like it works in Safari consistently, as it gets blocked sometimes (seemingly randomly)
const newWindow = window.open('about:blank', '_blank');
const { url } = await $ajax.post('/redirects', {
data: {
url: "myurl.com/route/to/go/to",
//...
}
});
newWindow.location.href = url;
I am very new to this Ionic 2 Framework and have never worked with Cordova.
I am sending users to the payment gateway page to complete the transaction and once completed I am not able to close the window using JavaScript, due to this error:
Scripts may close only the windows that were opened by it
Have tried all possible way but none of them can be put in use.
Even closing the inAppBrowser once the user is navigated to a specific URL will work, but I am unable to find any supporting document to this and I do feel this is possible.
If you are using inAppBrowser plugin ( https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-inappbrowser/) you can add event listener and check if specific url was opened.
Example:
inAppBrowser.addEventListener("loadstop", function (event) {
if (event.url.indexOf('UrlIAmChecking') != -1) {
inAppBrowser.close();
}
}
I am trying to create a OAuth login flow. In a Cordova app (tested only on Android), I try to load a page from my server which redirects the browser to the correct OAuth page on google's side. However, this abruptly stopped working.
If you try the url in the code below in a browser, you may want to go incognito or try some other measure to avoid autologging in. (The server creates an account to an indev service if you actually log in.)
If I write the code like this (I omit the fishing of the credentials tokens from the URL, this is the simplest reproducible example.):
function onLoad(){
document.addEventListener("deviceready", onDeviceReady, false);
}
function onDeviceReady() {
var authWindow = cordova.InAppBrowser.open("https://dev.taskapp.io/googleURI", '_blank');
authWindow.addEventListener("loadstart", function(e){
alert("Loadstart fired")
}
)
}
The webview remains empty and the message Loadstart fired appears once. If I swap '_blank' to to '_self' or '_system', the pages load and the redirects work but the events never fire. This happens only with the given page.
I am at my wit's end.
Update: the same code works like a charm on iOS. On android using window.open() also fails.
Update 2: I now understand, that _system opens the os's browser, which I obviously have no control over and that _self squishes whatever was in the webview, rendering my listeners to nothingness. _blank works once from a cleanly cloned repository and then breaks on a second build (without code change).
If I substitute the url in the cordova.InAppBrowser.open(...) to the one my server redirects from, Google's tech loads. However the final login button (which would trigger the redirection to my server, one can assume.) is dead.
Does redirecting the _blank target break things? Is this a bug? Is someone else experiencing this?
I'm creating a website for iPhone and i use the native app (cliqcliq Quickpick) to upload photos. I use the script like the following to check if the application is installed. The basic idea is to send user to a custom url, if application is there it is launched, if it is not there the url should be ignored and user is taken to App Store. Below is the script:
window.launchQuickpic = function() {
var start = new Date();
setTimeout(function() {
if (new Date() - start > 2000) {
return;
}
window.location = 'http://www.cliqcliq.com/quickpic/install/';
}, 1000);
var getParams = [...];
window.location = 'vquickpic://?' + getParams.join('&');
};
If the native app is not installed I'm getting the alert box saying that Safari does not recognize the custom url. After user clicks "ok" it works as it is supposed to. But the alert is reeealy annoying.
I've tried to surround the window.location= code with try/catch. Didn't help.
If I understand correctly, you're seeing the expected behavior.
If the app isn't installed then the system has no knowledge of what it is supposed to do with a URL that starts with 'vquickpic://'. That is why you get the error message.
I presume that what you are seeing is that you first set the window.location to 'http://www.cliqcliq.com/quickpic/install/' but before that finishes loading you try to switch to window.location to 'vquickpic://'. That generates an error and the webview keeps loading the first URL when you dismiss the alert.
The main problem here is that the error is coming from the iPhone OS itself which isn't accessible from the javascript inside a webpage. A webpage can't ask the iPhone if it has a particular app installed or can carry out a particular operation.
I think the best you can do is tell the user that clicking the link will attempt to launch the native app if it is installed but if they get an error they need to dismiss it and hit another link on the page to install the app.
I have not got this to work yet but I think this is something you should investigate. It is my believe this will suppress the message .
window.onerror = function(msg, url, linenumber) { return true; }
I have also read somewhere that a user had success doing something similar to above but instead of returning true they would switch the window.location back to a valid location such as 'about:blank'. They where using a iframe in that implementation though.
OR maybe you could try Opera Mini for that matter