Google Chrome Silent Push Notifications - google-chrome

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

Related

Infinite Redirect Loop on Google One Tap Signin

I'm having trouble finding any documentation in regards to Google One Tap UX and how to persist signin state after a signin redirect. I am using the html api, check the code here:
setTimeout(function () {
let target = document.getElementById('google-signin');
target.innerHTML = '<div id="g_id_onload" data-client_id="x" data-context="signin" data-login_uri="https://x/account/google/callback" data-auto_select="true" data-itp_support="true"></div>';
var s = document.createElement("script");
s.src = 'https://accounts.google.com/gsi/client';
document.head.appendChild(s);
console.log('appended script', s);
}, 30000);
</script>
Essentially I am delaying this signin popup for 30 seconds, that part works fine but soon after this is what happens:
Sign in occurs
Redirect happens
Server redirects back to the referer page
After 30 seconds the process starts again
I would have assumed the google sdk would set a cookie or something somewhere but I guess it does not, either that I'm supposed to handle persisting signin state through my own means. I just want to know the correct approach here.
My question is: How does google know if a user has already signed in using Google One Tap UX?
Figured out a solution. Google allows you to put a property on your div tag called data-skip_prompt_cookie="yourcookie" this will skip the one tap prompt if that cookie is present with a truthy value.
What I did was on my server callback in asp.net I added a cookie to the response. This ensures the prompt is only disabled once someone actually signs in.
Response.Cookies.Append(
"yourcookie", "true");
This ensures when my server redirects back to the originating page, the cookie exists and the one tap does not show up again

Notification.requestPermission() doesn't work on 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

chrome.runtime.connect from Content Script and DevTools Page JS failing to connect

I have reviewed this question/answer as well:
Communicating between Chrome DevTools and content script in extension
It looks like they are doing something slightly different than I am trying to do, so I don't know how much it applies. Maybe I absolutely need a background.js file?
I have also reviewed this question:
extension using background, content and devtools together
Here it looks like they are not using long-lived connections as documented here (which is what I need):
https://developer.chrome.com/extensions/messaging#connect
Anyway, previous question aside here is my problem:
I have tried this a few ways over the span of a few hours so I am pretty convinced I am just missing something here to make this work.
The crux of my issue is that:
chrome.runtime.onConnect.addListener(function(){...})
the listener here will never fire.
Here's my setup:
My extension uses a Content Script and a DevTools page. From both locations, the Content Script and DevTools page, I have tried to enabling messaging though chrome.runtime. My boilerplate initialization looks like this for starting the connection:
console.log('initializing connection');
var port = chrome.runtime.connect({name: 'My Extension'});
console.log('port', port.name);
and this for waiting for onConnect:
chrome.runtime.onConnect.addListener(function(port){
console.log('got connection!!!!!!');
});
My onConnect handler will never be invoked. I have tried placing the connection code (chrome.runtime.connect({...})) in the Content Script and in the DevTools page JS while placing the handler initialization the opposite location to no avail.
In other words, if I place the connection code in the Content Script, I will place the handler initialization into the DevTools page JS. If I place the connection code into the DevTools page JS I will place the handler initialization into the Content Script.
In both cases, I receive no runtime errors, however, I also never see the console.log('got connection!!!!!!'); get called. Yes, I am looking at the DevTools page console when I have the handler initialization located in the DevTools page JS.
I simply must just be misunderstanding something or missing something in the docs. Can anyone point me in the right direction re: having DevTools Page JS communicate with a Content Script?
As per Xan comment, communication between devtools extension and content scripts should be done through the use of a background script. The process is basically:
(devtools script) - create the connection ( and sends or listens to messages through the connection port opened)
(background script) - listen for the connection to be created, receiving the port and using it to listen or broadcast messages
This is useful if you want to keep a long lived connection, so basically you will need a couple of messages to be passed back and forward for a single process. If you want simple messages to be passed from time to time, but don't need multiple messages being passed back and forth then you might implement a more simple communication:
(devtools script) - sends a message using the chrome.runtime.sendMessage
(background script) - listens for messages send by any extension associated with it using the chrome.runtime.onMessage.addListener()

Flash UrlLoader - prevent or suppress authentication dialog box

I have a rssfeed application made in Adobe AIR. It uses the UrlLoader to read the feeds. I need the application to never prompt the user to enter password for a website or accept a certificate of a website if is no longer valid. I prefer to have it fail instead.
I have setup the event listeners for IO+Error and Security_ERROR but that is not enough
Sample urls(this may not work in future)
http://www.dawnanddrew.com/rss2.xml (asks for user and pass atm)
I had another issue with a feed that even if it was a http url the website redirected the loader to https and then the certificate validation failed and the user was asked to accept the certificate. I need this to fail (I mark failed feeds and the user can check them when they want to find the issue and fix them or remove them)
Using AIR (which you are), you can actually tell the application to NOT handle authentication.
var request:URLRequest =new URLRequest("http://www.dawnanddrew.com/rss2.xml");
request.authenticate = false; //default is true, so you need to tell your request to not handle authentication
Then it will fail with an IO error instead of prompting for credentials.
Documentation
Note however, this will only work in AIR and is not a supported property for flash player.
You cannot do it this way. Now, the server returns specific status and the browser reacts to it by showing you a login dialog box. You cannot do this directly in flash and you cannot get default login button. You need to implement this by your own. The perfect way to do so is to check (server side) if the user is logged in and if not - return status ok (200) with an error message (let's say JSON). This specific message would be read by the flash client and a login screen would be shown (custom made). You will also need to implement the login feature by yourself :)
Sorry for the bad news, but this is the way it is with flash.

Is it possible to know whether Windows widget totally covered by other windows?

We want to create a Windows desktop version of our weather widget
There are 2 special things about the widget.
It consumes a lot of processor time
while active - it displays an
animated picture (Flash without GPU acceleration, unfortunately).
It updates the weather from our
server (frequent server requests from all widget users).
When the user does not look at the widget there is no need for animation and weather loading.
So I have an idea of putting my widget to sleep when it is not visible and hense not used.
Is it possible to detect whether the widget is used or not.
Speaking precisely I need to know whether the widget is covered by other windows?
I mostly interested in Vista/7 gadgets engine, however I also would like to know if this problem is solved in these widget engines
Yahoo widgets
Google desktop
Hope to find some desktop widget guru here.
Pasha
If you InvalidateRect and don't get a subsequent WM_PAINT message, than your window is hidden. You can call UpdateWindow after InvalidateRect to force the WM_PAINT message to happen (or not happen) right away.
So you could do something like this
request server data (and cancel request timer if any)
when data arrives InvalidateRect
when WM_PAINT message arrives, draw the data and set a timer for next request
when timer arrives, goto 1
When you stop getting WM_PAINT messages, you stop re-setting your timer, and you therefor stop requesting updates from the server. When the WM_PAINT message happens (because you are no longer covered). You start requesting data again.