Notification.requestPermission() doesn't work on Chrome - google-chrome

I'm having a problem with push notifications on Chrome. On certain pcs in my network, websites normally requesting permissions to post push notifications, don't request them. That functionality works on some browsers in my network, but doesn't on others. Chrome version is 68.0.3440.106 on all the machines.
To investigate the case, I run a simple script in the console, that should trigger the browser request:
Notification.requestPermission().then(function(result) {
if (result === 'denied') {
console.log('denied');
return;
}
if (result === 'default') {
console.log('default');
return;
}
console.log(result);
return;
});
On the machines where push is working as expected, this promise resolves, whereas on the "faulty" ones, it doesn't resolve. I don't have my browser configured to either allow or deny the notifications (I've never clicked the "allow" or "deny" on the request, as it has never appeared). I don't know where to go from here, here's what I've tried so far:
I don't have the browser notification behaviour set to either allow or deny.
Chrome://flags shows "default" for all entries concerning push notifications.
Console doesn't print any errors/warnings
running chrome with --enable-logging --v=1 doesn't show anything suspicious when running the script. Here's an excerpt:
[7772:21772:0828/101500.364:VERBOSE1:thread_state.cc(1024)] [state:00007FFB173B67A0] PostSweep: collection_rate: 0.00067%
[7772:21772:0828/101500.421:VERBOSE1:thread_state.cc(1024)] [state:00007FFB173B67A0] PostSweep: collection_rate: 0%
[7772:21772:0828/101500.422:VERBOSE1:thread_state.cc(1430)] [state:00007FFB173B67A0] CollectGarbage: time: 15ms stack: HeapPointersOnStack marking: AtomicMarking sweeping: EagerSweeping reason: ForcedGC
[7772:21772:0828/101500.427:VERBOSE1:thread_state.cc(1430)] [state:00007FFB173B67A0] CollectGarbage: time: 4.9ms stack: NoHeapPointersOnStack marking: AtomicMarking sweeping: LazySweeping reason: PreciseGC
I'd really appreciate it if someone could tell me what else to check, I'm really lost with this one. Thanks in advance!
Edit: Apparently this is some weird screen offset issue. The request shows just fine, when I have two instances of chrome running. However, when I have the request showing in one window, snapping it back to the other instance makes the request disappear. It reappears after resising the window to anything but fullscreen, or undocking the tab. Has nobody encountered this problem? This occurs among multiple machines in my workplace

Related

Access-Control-Request-Private-Network header issues

Today we updated the last version of google chrome browser (Version 102.0.5005.61). We have an aplication that runs into a vpn. And since then we start getting this errors on the console:
As you can see we get a timed out error on the preflight and then the xhr request fails.
We noticed that on this version of chorme they add the new header: Access-Control-Request-Private-Network. An that is what I see on the preflight headers:
Serching on what could be wrong, since this is happening only when we update the chrome version and in other browsers the site works perfectly; Ive found this:
https://developer.chrome.com/blog/private-network-access-preflight/
On the article is explained what to do and how to handle this.
And show kind of what is happening to me:
If your request would have triggered a regular CORS preflight without
Private Network Access rules, then two preflights may appear in the
network panel, with the first one always appearing to have failed.
This is a known bug, and you can safely ignore it.
Based on that I added the new header support on my API that is made on JAVA with spring boot.
response.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS");
response.setHeader("Access-Control-Allow-Headers", "content-type");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Max-Age", "180");
response.setHeader("Access-Control-Allow-Private-Network", "true");
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
As you can see just added the header and return 200 for the option request
if ("OPTIONS".equals(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
return;
}
The site is running, meaning it get served and is loaded on chrome browser but all the API calls from the site get that error. (See screen shoots avobe).
But still after that have the same issues. Any one had the same issue and was able to solve?
Any help will be appreciated!
Thanks!
EDIT:
We just add the headers on the preflight response:
Access-Control-Request-Private-Network: true
Access-Control-Allow-Private-Network: true
Then we go to the google flags configuration and disable this:
Now Im not sure why google thinks that my requests are insecure.
This issue is coming for Private and Public combination, like our web is deployed as CloudFront Public URL and backend is Private api hosting, so we are also facing this issue, currently only disabling "Send Private Network Access preflights" property of chrome is working (its only enough).
We have tried setting "preflight request will carry a new header, Access-Control-Request-Private-Network: true, and the response to it must carry a corresponding header, Access-Control-Allow-Private-Network: true" but no luck till now.
Our another web application on which FE/BE both are private hosting is working fine.

Chrome xhr call stays in pending status even though server sent a response back

I have a page where it has 2 different endpoint calls to 2 different routes around the same time. The second one returns successfully, however, the first one stays in pending status.
I have checked the server logs and the request is received by the server and a response is sent back.
For some reason, the status code of the pending one is 200 even though it says pending.
I tried to replicate this problem in multiple machines but failed. However, in the users' machine, it can be replicated every single time.
The user does not have any browser extensions. (Tried on incognito and problem still occurs)
All calls are in https
The page which does the requests generally has ~100% CPU for a few seconds.
After waiting for a while the user gets the Page unresponsive tab.
Users Chrome version: 81.0.4044.26 / macOS Mojave. I also tested with the same versions and couldn't replicate.
I'm using axios and the following code to fetch data.
const fetchData = async () => {
try {
const result = await axios(url);
..
} catch (error) {
..
}
};
I couldn't figure out why this was happening and how to fix it. Would appriciate help.
Thanks
Related Topic: What does "pending" mean for request in Chrome Developer Window?

Permission issue for appium chrome borwser

I am implementing an appium test on remote android driver, with chrome browser for loading urls.
Some of the Urls are pdfs, and chrome asks to store those files. and appears that chrome doesnt have access to filesystem to store those files, which results in a dialog like below.
Please help me pass that dialog without any manual inputs.
Upon clicking continue, it will load actual permissions dialog from Android.
Here is my code initialize appium capabilities
DesiredCapabilities caps = DesiredCapabilities.android();
caps.setCapability("appiumVersion", "1.9.1");
caps.setCapability("deviceName","Samsung Galaxy S9 Plus HD GoogleAPI Emulator");
caps.setCapability("deviceOrientation", "portrait");
caps.setCapability("browserName", "Chrome");
caps.setCapability("platformVersion", "8.1");
caps.setCapability("platformName","Android");
caps.setCapability("autoAcceptAlerts", true);
caps.setCapability("autoGrantPermissions", true);
caps.setCapability("chromedriverArgs", "--allow-file-access-from-files");
caps.setCapability("maxDuration", 10000);
and this is the snippet I use to load a Url
driver.navigate().to("http://kmmc.in/wp-content/uploads/2014/01/lesson2.pdf");
autoGrantPermission also doesnt work in this case because chrome is already installed. Appium team has already rejected this issue -
https://github.com/appium/appium/issues/10008
Please help!
Indeed I had very hard time finding out the solution, but eventually I found a workaround.
The best workaround would have been reinstalling the chrome package. I tried that, but I could not start chrome after reinstalling it, as I had no access to shell, and chromedriver complained. So I left that track.
I tried getting hold of adb command or mobile:changePermissions but for that you need to use server flag --relaxed-security while starting the server, and saucelabs doesnt provide any handy interface to start the server with this flag.
The last resort, I found a solution here - https://stackoverflow.com/a/51241899/4675277 . But just that was not sufficient, because it helped me fix chrome alert, but later on it popped up with another alert with allow and deny, for which another solution in the same question helped me. So this is the code I eventually used -
driver.navigate().to("http://kmmc.in/wp-content/uploads/2014/01/lesson2.pdf");
String webContext = ((AndroidDriver)driver).getContext();
Set<String> contexts = ((AndroidDriver)driver).getContextHandles();
for (String context: contexts){
if (context.contains("NATIVE_APP")){
((AndroidDriver)driver).context(context);
break;
}
}
driver.findElement(By.id("android:id/button1")).click();
contexts = ((AndroidDriver)driver).getContextHandles();
for (String context: contexts){
if (context.contains("NATIVE_APP")){
((AndroidDriver)driver).context(context);
break;
}
}
driver.findElement(By.id("com.android.packageinstaller:id/permission_allow_button")).click();
((AndroidDriver)driver).context(webContext);
This helps allow all permissions required.

Google Chrome not showing microphone permission prompt

I have a web application that uses the microphone for WebRTC through getUserMedia. I currently have this application running on multiple subdomains, like test.example.com, staging.example.com, production.example.com, etc.
On most of them, it works properly.
On one of the domains (test), I am unable to use the microphone. My code calls getUserMedia with a callback, but the callback is never executed, and the browser's permission prompt is never shown.
I have also reproduced this behavior using the Developer Tools console using the new Promise-based API:
navigator.mediaDevices.getUserMedia({audio: true, video: false}).then(console.log).catch(console.log)
(Yes, I know it does the same thing for then and catch, but it doesn't matter for this case.)
On the working site (stage, for example) here is the result in the console:
Promise {<pending>}
MediaStream {id: "RANDOM_CHARS", active: true, onaddtrack: null, onremovetrack: null, onactive: null, …}
On the non-working site, it only shows Promise {<pending>}, but the neither then nor catch logs anything because it never resolves either way.
I have found that if I go into the site settings (chrome://settings/content/siteDetails?site=https%3A%2F%2Ftest.example.com) and change Microphone to Allow, then I can refresh the page and it works properly. If I change it back to Ask, I get the same behavior again - that it doesn't ask.
This behavior is true about any site and any permission that I have tested - changing an Allowed permission back to Ask doesn't ask. However, on this particular test site, I had never before today tried to use it, so there's no reason it would have been set to Allow and then back to Ask to trigger that behavior.
In all these cases, navigator.permissions.query({name: "microphone"}).then(console.log) returns PermissionStatus {state: "prompt", onchange: null} as expected.
How can I get Chrome to prompt for microphone permission again?
You need a valid domain using https protocol in order to get Chrome to prompt for permissions.

Google Chrome Silent Push Notifications

I've been reading through the docs for Chrome's implementation of the Web Push API here, and I noticed the API says "you promise to show a notification whenever you receive a push" and under limitations it's stated "you have to show a notification when you receive a push message".
After implementing the example on my localhost, I used cURL to send a push notification successfully. I was curious, so I commented out the lines that actually call the showNotification function, and put in a console.log instead and found that I could, in fact, send, receive, and totally ignore a push notification. I even tried using an if-statement to control whether or not to show them based on global boolean that I controlled from my main page, and that worked. So I was wondering if anyone knew what they meant by saying you need to show a notification, and that silent push notifications weren't available?
This wasn't just for the heck of it, I legitimately may need to control whether or not to show these notifications in my web app, so it would be great if this were actually possible. Code below in case you're curious.
self.addEventListener('push', function(event) {
var title = 'New Message';
var body = 'You have received a new message!';
var icon = '/img/favicon.png';
var tag = 'well-notification';
console.log("DID RECEIVE NOTIFICATION")
if(settingsShowNotification) {
event.waitUntil(
self.registration.showNotification(title, {
body: body,
icon: icon,
tag: tag
})
);
}
});
EDIT: On Chrome 47, if it's relevant.
UPDATE: After further experimenting, I found the obvious issue that I can't update the original global variable once the user navigates away and then re-navigates to the same page. However, I was able to circumvent this using a variable on the serviceworker itself and sending a message to the service worker using the API described here to toggle the showNotifications boolean.
You do have to show a notification, and if you don't show a notification you get a forced notification from the browser saying "This site has been updated in the background". But the requirements that show the scary message have been relaxed slightly:
As of Jan. '16, it seems like up to the last 10 notifications are checked for whether each showed a notification or not. If one notification in the last ten notifications did not show a notification, that's considered an accident and the browser won't show the scary "This site has been updated in the background". You have to miss two notifications in the last ten for the scary message to appear.
Note: If the URL in the address bar of the active browser tab matches the origin of your page, and the browser is not minimized, you are not required to show a notification. This is probably why your tests succeeded, if you were on the page itself while running your tests.
Chromium bug that tracks the implementation: https://code.google.com/p/chromium/issues/detail?id=437277
Relevant lines of source code: https://code.google.com/p/chromium/codesearch#chromium/src/chrome/browser/push_messaging/push_messaging_notification_manager.cc&l=249