How can I programmatically log out of Forge? - autodesk-forge

I followed this guide from the Forge Community Blog.
The blog suggests loading an iFrame with the src attribute set to https://accounts.autodesk.com/Authentication/LogOut
<iframe src="https://accounts.autodesk.com/Authentication/LogOut" />
Though the iFrame loads properly, the user does not get logged out of the Forge platform.
This method worked well until sometime this past week or so. Now, the user remains logged in.
However, manually opening a new window and navigating to the LogOut URL does log the user out.
This appears to be a new change but I cannot find any documentation for it.

I used this in the past and so far I have not encountered any issue, basically goes to the Nodejs SDK to use the endpoint for sign out.
// prepare sign out
$('#signOut').click(function () {
$('#hiddenFrame').on('load', function (event) {
location.href = '/api/forge/oauth/signout';
});
$('#hiddenFrame').attr('src', 'https://accounts.autodesk.com/Authentication/LogOut');
// learn more about this signout iframe at
// https://forge.autodesk.com/blog/log-out-forge
})

To solve this, I decided to open a temporary new window for the logout url. I'm not happy with the solution, but it functions.
const newWindow = open('https://accounts.autodesk.com/Authentication/LogOut');
setTimeout(() => newWindow.close(), 500);

Related

Custom HTML Dialog in Electron

How (or is it even possible) to use custom HTML dialogs in Electron? I know that Electron provides certain dialogs (showMessageDialog, showErrorDialog) but these do not seem to allow custom HTML.
I do not wish to use native HTML dialogs (dialog) tag as it does not 'blend in' with the user interface.
Any help would be much appreciated. Thanks!
You can create a BrowserWindow that's modal and, if you like, frameless. See http://electron.atom.io/docs/api/browser-window/.
Yes.
On your parent you should have:
const { remote } = require('electron');
const { BrowserWindow } = require('electron').remote;
and then:
let child = new BrowserWindow({
parent: remote.getCurrentWindow(),
modal: true,
width:300, height:300,
webPreferences: {
enableRemoteModule: true,
nodeIntegration: true
}
});
child.loadFile('myCustomModal.html');
On myCustomModal.html remeber to include a way to close the modal!
like:
<button id="cancel-btn">Cancel</button>
<script>
const remote = require('electron').remote;
document.getElementById("cancel-btn").addEventListener("click", function (e) {
var window = remote.getCurrentWindow();
window.close();
});
</script>
As Marc Rochkind said in a previous answer, you can use modal windows in Electron.
However, I have found a small bug with modal windows which causes the parent window to flicker for a very short duration when its .show() function is called. After quite some time on Google, I found an open issue on GitHub about the same problem. After reading the comment section in the issue, and stumbling across some code snippets, I shared a hacky solution in the issue's comment section.
It does take some work to set up, but once it's done, it's really easy to port to other child windows.

How to make screen blink when there is an unread email

I am looking for any way to make the entire screen blink red, or whatever color, when there is an unread email. It could be for any email client. I have done a lot of googling and can't find anything. There is an add-on to thunderbird that creates a little blinking notification, but it only appears very small in the lower right hand corner of the screen.
I was thinking of maybe some add-on to Firefox or Chrome that would allow me to write custom css and javascript that would run on Gmail and make the blinking happen.
Any ideas are greatly appreciated.
I know this is not you regular SO question, but y'all are great and I don't know where else to turn. If there is a better forum out there for this type of question, you could also inform me of it.
Thanks!
I have found this program while searching, haven't tried it. But it says it can execute an external program when email arrives. So seems like you can write a little C# application that can perform the task you want and execute when new email arrives.
http://www.jsonline.nl/Content/Poppy/Poppy.htm
Instead of making a Chrome plugin, I would either make the window title blink or use HTML5 Notifications. Create a simple page which polls your IMAP Gmail for new messages, and include gmail in a large iFrame. If a new message is found, your outer window can issue the notification.
HTML5 Notifications: http://www.html5rocks.com/en/tutorials/notifications/quick/
Blinking Title (adopted from this):
var newMailBlinker = (function () {
var oldTitle = document.title,
msg = 'New Mail!',
timeoutId,
blink = function() {
document.title = document.title == msg ? ' ' : msg;
},
clear = function() {
clearInterval(timeoutId);
document.title = oldTitle;
window.onmousemove = null;
timeoutId = null;
};
return function () {
if (!timeoutId) {
timeoutId = setInterval(blink, 1000);
window.onmousemove = clear;
}
};
}());
PHP Poll Gmail IMAP (adopted from this):
$t1=time();//mark time in
$tt=$t1+(60*1);//total time = t1 + n seconds
do{
if(isset($t2)) unset($t2);//clean it at every loop cicle
$t2=time();//mark time
if(imap_num_msg($imap)!=0){//if there is any message (in the inbox)
$mc=imap_check($imap);//messages check
//var_dump($mc); die;//vardump it to see all the data it is possible to get with imap_check() and them customize it for yourself
echo 'New messages available';
}else echo 'No new messagens';
sleep(rand(7,13));//Give Google server a breack
if(!#imap_ping($imap)){//if the connection is not up
//start the imap connection the normal way like you did at first
}
}while($tt>$t2);//if the total time was not achivied yet, get back to the beginning of the loop
jQuery AJAX Polling to your IMAP script (adopted from this):
// make the AJAX request
function ajax_request() {
$.ajax({
url: '/path/to/gmail/imap/checkMessages.php',
dataType: 'json',
error: function(xhr_data) {
// terminate the script
},
success: function(xhr_data) {
console.log(xhr_data);
if (xhr_data.status == 'No new messages') {
setTimeout(function() { ajax_request(); }, 15000); // wait 15 seconds than call ajax request again
} else {
newMailBlinker(); // blink the title here for new messages
}
}
contentType: 'application/json'
});
}
Obviously you wouldn't use jQuery AND PHP to poll. Pick one to do the polling. I'd recommend have the client do the polling and have PHP check IMAP once per connection. That being said, these snippets should get you started :)
Grab the current google mail checker extension sample (https://developer.chrome.com/extensions/samples.html). Convert it to a packaged app (grab the pieces you want), open a very large window and close it quickly. That should do the trick. Sadly Fullscreen doesnt seem to be possible. But i dont know if thats a problem.
Assuming your dad has the client page always opened, you could just write an extension and manipulate the screen with JS.
You could for example:
Use the gmail client in chrome
Write a chrome extension that checks for new e-mails that come in. You could achieve this by identifying new e-mails. I believe gmail uses a specific css class for new e-mails. So your JS just needs to check for that class.
Have the extension change the page from white to red and back to white a few times (or till the e-mail is read).
You could also possibly have the chrome extension play a sound when a new email arrives?
I found chrome extensions a lot easier to use than FF, especially if you're just going to use JS.

Modify url location in chrome extensions & stop the initial request

I've made an extension who's purpose is to redirect urls.
I.e: www.google.com becomes: www.mysite.com/?url=www.google.com
I came across this post:
How to modify current url location in chrome via extensions
The problem I'm having is that the url's are both processed. The tab initially loads up google.com and only after it's finished my request is shown ( www.mysite.com/?url=www.google.com).
Is there any way to stop the initial request from being processed?
Something like:
chrome.tabs.onUpdated.addListener(function(tabId,obj,tab){
update.stop() // ??????????? Here I'm missing...
chrome.tabs.update(tabId,{url:....}, function callback); // My update stuff..
});
Thoughts?
thank you all.
You're looking for the webNavigation API.
You can register listeners to handle user navigation by modifying or blocking the request on the fly.
In the example below, when a user navigate to www.google.com, before the page even start loading onBeforeNavigate is fired and you can redirect the user to the CSS validation page for that URL:
chrome.webNavigation.onBeforeNavigate.addListener((details) => {
if(details.url.indexOf("www.google.com") !== -1)) {
chrome.tabs.update(details.tabId, {
url: "https://jigsaw.w3.org/css-validator/validator?uri=" + details.url
});
}
});
Remember to add the "webNavigation" permission to your extension manifest to get this functionality enabled.
chrome.tabs.onUpdated is fired two times per tab load - once a tab starts loading, and another time when it finishes loading. If you attach your update to the tab start loading event then it should work relatively quickly. You will still see original url being loaded for a brief moment, but it won't wait until it finishes, as you are describing.
chrome.tabs.onUpdated.addListener(function(tabId,obj,tab){
if(obj.status == "loading") {
chrome.tabs.update(tabId,{url:....}, function callback);
}
});
I don't think there is a more efficient solution at the moment.

How to use google analytics with HTML 5 History?

I'm using HTML 5 history for my site, so, for users whose browsers support it, clicking on a link doesn't reload the whole page, but just the main area.
Google analytics doesn't track these partial page loads. How can I get it to track it just like it does for users that don't have HTML 5 history support?
You just need to register the additional pageviews by calling the _trackPageview function again each time your new content loads. This is called a 'Virtual Pageview' but is registered in Google Analytics in the same way as a real one. To set the path of the page you need to add an additional parameter to the function:
_gaq.push(['_setAccount', 'UA-XXXXXXX-X']);
_gaq.push(['_trackPageview', '/new/content']);
This is for the newest Universal Tracking Code.
So recently, I had to revisit my own answer for a new project. I noticed some issues that I should clean up.
To send a pageview programmatically, you want to send only the Path and the Query eg. for http://example.com/path/to/resource?param=1 we will send /path/to/resource?param=1.
Some SPAs use HashBangs (#!) for their urls. So we need to send anything after the Hashbang. e.g. http://example.com#!path/to/resource we will send /path/to/resource?param=1.
The earlier version of my solution was erroneous and would fail for all urls which had a hash in the url. Also, as I was using jQuery + History.js plugin my solution was along of listening to statechange came from there.
Use this new code to send a pageview. It is more resilient and caters for both hashbangs and history.
var loc = window.location,
hashbang = "#!",
bangIndex = location.href.indexOf(hashbang),
page = bangIndex != -1 ? loc.href.substring(bangIndex).replace(hashbang, "/") : loc.pathname + loc.search;
ga('send', 'pageview', page);
If you don't use Hashbangs specifically, simply change hashbang = "#!", to match e.g. hashbang = "##",
The second part of this is detecting when the url changes. For this, you will need to find out from the docs of whatever library you are using.
For jQuery + History.js plugin, the code below works
$(window).on('statechange', function() {
//put code here
});
More information can be found at https://developers.google.com/analytics/devguides/collection/analyticsjs/single-page-applications
$(window).on('statechange', function() {
var loc = window.location,
page = loc.hash ? loc.hash.substring(1) : loc.pathname + loc.search;
ga('send', 'pageview', page);
});
As Ewan already stated, you should send the pageview to analytics in the window.popstate event.
So, in plain javascript, if you have called:
history.pushState({'statedata':''}, 'title', '/new/page/url');
you should simply add:
window.addEventListener('popstate', function(event) {
ga('send', 'pageview');
});
Actually the new Universal Tracking Code automatically gets the current URL, so you don't really need to pass the extra parameter.

How do I access the popup page DOM from bg page in Chrome extension?

In Google Chrome's extension developer section, it says
The HTML pages inside an extension
have complete access to each other's
DOMs, and they can invoke functions on
each other. ... The popup's contents
are a web page defined by an HTML file
(popup.html). The popup doesn't need
to duplicate code that's in the
background page (background.html)
because the popup can invoke functions
on the background page
I've loaded and tested jQuery, and can access DOM elements in background.html with jQuery, but I cannot figure out how to get access to DOM elements in popup.html from background.html.
can you discuss why you would want to do that? A background page is a page that lives forever for the life time of your extension. While the popup page only lives when you click on the popup.
In my opinion, it should be refactored the other way around, your popup should request something from the background page. You just do this in the popup to access the background page:
chrome.extension.getBackgroundPage()
But if you insist, you can use simple communication with extension pages with sendRequest() and onRequest. Perhaps you can use chrome.extension.getViews
I understand why you want to do this as I have run into the problem myself.
The easiest thing I could think of was using Google's method of a callback - the sendRequest and onRequest methods work as well, but I find them to be clunky and less straightforward.
Popup.js
chrome.extension.getBackgroundPage().doMethod(function(params)
{
// Work with modified params
// Use local variables
});
Background.html
function doMethod(callback)
{
if(callback)
{
// Create/modify params if needed
var params;
// Invoke the callback
callback(params);
}
}
As other answers mention, you can call background.js functions from popup.js like so:
var _background = chrome.extension.getBackgroundPage();
_background.backgroundJsFunction();
But to access popup.js or popup.html from background.js, you're supposed to use the messages architecture like so:
// in background.js
chrome.runtime.sendMessage( { property: value } );
// in popup.js
chrome.runtime.onMessage.addListener(handleBackgroundMessages);
function handleBackgroundMessages(message)
{
if (message.property === value)
// do stuff
}
However, it seems that you can synchronously access popup.js from background.js, just like you can synchronously access the other way around. chrome.extension.getViews can get you the popup window object, and you can use that to call functions, access variables, and access the DOM.
var _popup = chrome.extension.getViews( { type: 'popup' } )[0];
_popup.popupJsFunction();
_popup.document.getElementById('element');
_popup.document.title = 'poop'
Note that getViews() will return [] if the popup is not open, so you have to handle that.
I'm not sure why no one else mentioned this. Perhaps there's some pitfalls or bad practices to this that I've overlooked? But in my limited testing in my own extension, it seems to work.