I am using the JavaScript Google Data API and having issues getting the AuthSub script to work correctly. This is my script currently:
google.load('gdata', '1');
function getCookie(c_name){
if(document.cookie.length>0){
c_start=document.cookie.indexOf(c_name + "=");
if(c_start!=-1){
c_start=c_start + c_name.length+1;
c_end=document.cookie.indexOf(";",c_start);
if(c_end==-1) c_end=document.cookie.length;
return unescape(document.cookie.substring(c_start, c_end));
}
}
return "";
}
function main(){
var scope = 'http://www.google.com/calendar/feeds/';
if(!google.accounts.user.checkLogin(scope)){
google.accounts.user.login();
} else {
/*
* Retrieve all calendars
*/
// Create the calendar service object
var calendarService = new google.gdata.calendar.CalendarService('GoogleInc-jsguide-1.0');
// The default "allcalendars" feed is used to retrieve a list of all
// calendars (primary, secondary and subscribed) of the logged-in user
var feedUri = 'http://www.google.com/calendar/feeds/default/allcalendars/full';
// The callback method that will be called when getAllCalendarsFeed() returns feed data
var callback = function(result) {
// Obtain the array of CalendarEntry
var entries = result.feed.entry;
//for (var i = 0; i < entries.length; i++) {
var calendarEntry = entries[0];
var calendarTitle = calendarEntry.getTitle().getText();
alert('Calendar title = ' + calendarTitle);
//}
}
// Error handler to be invoked when getAllCalendarsFeed() produces an error
var handleError = function(error) {
alert(error);
}
// Submit the request using the calendar service object
calendarService.getAllCalendarsFeed(feedUri, callback, handleError);
}
}
google.setOnLoadCallback(main);
However when I run this the page redirects me to the authentication page. After I authenticate it send me back to my page and then quickly sends me back to the authenticate page again. I've included alerts to check if the token is being set and it doesn't seem to be working. Has anyone has this problem?
I was having the same problem so I built this function
function login() {
var scope = "http://www.google.com/calendar/feeds/";
if(!google.accounts.user.checkLogin(scope)) {
if(google.accounts.user.getStatus() == 0) {
var token = google.accounts.user.login();
}
}
}
I added the check to google.accounts.user.getStatus() if it's 1 that means the application is in the process of logging in and if it is 2 that means the applications is logged in. You can also pass a scope to the getStatus method.
the problem is that setting the cookie takes a little while when google redirects back to your site. However, the callback runs immediately, and there is no cookie by that time to verify authentication, so it again redirects back to google. Try using setTimeout or something to run the authentication check after a second or so to be sure.
You should pass the scope to the login method too.
Sometimes you can end up with an orphaned cookie in your browser - which will keep getting fed back to Google.
What I'm doing now, is doing a checkLogin before I perform my login call, and if it returns true I explicitly call logOut().
The logOut call will remove any cookies which Google had rejected but left in your browser. The reason it seems to keep going in a loop is because the cookie is there, but even on reauth, it doesn't produce a new one because you already have one. But unfortunately for our sake, the one that's there is invalid.
Related
I've got an Outlook Add In that was developed using the Office Javascript API.
It looks at the new email being composed & does things based on who it's going to: https://learn.microsoft.com/en-us/office/dev/add-ins/reference/objectmodel/requirement-set-1.3/office.context.mailbox.item
The code correctly returns the TO email when you 'select' the email from the suggested email list... screenshots shown # bottom of this thread
To debug the Javascript, I use C:\Windows\SysWOW64\F12\IEChooser.exe
It was working fine until last week. Is it possible a Windows update broke functionality?
I'm the only person with access to the code. It hadn't been modified for months.
When debugger is running, getAsync correctly returns the 'TO' value. I needed to write the response to a global variable to prove the values were 'undefined' while not in debug.
var resultObjects;
var resultObjects2;
var strMessages = '';
var strTo = '';
var mailbox;
var mailitem;
(function () {
"use strict";
// The Office initialize function must be run each time a new page is loaded.
Office.initialize = function (reason) {
$(document).ready(function () {
mailbox = Office.context.mailbox;
mailitem = mailbox.item;
mailitem.to.getAsync(function (result) {
if (result.status === 'failed') {
strMessages = 'FAILED';
} else {
strMessages = 'SUCCESS';
strTo = result.value[0];
resultObjects = result;
resultObjects2 = result.value;
}
});
loadApp();
});
};
})();
Here are the values of the variables, when the app is loaded & debugger is not running
EDIT
If you 'select' the TO email so that it is bolded... the code works correctly. If you leave the typed-in-text field without selecting the suggested email, it does not work. The same behavior is true for both the Outlook Web Application (# https://outlook.office.com) and the desktop outlook application.
Does not work
Does Work
The Office.context.mailbox.item.to.getAsync API will only return resolved recipients. If the TO email address is not resolved (as in the first screenshot titled "Does not Work"), then API will not return the email address until it is resolved (in both desktop and OWA).
You can use the RecipientsChanged Event, to get newly resolved recipients after you have queried for to.getAsync. This event would fire when a recipient is newly resolved.
Suppose I have an instance of an indexedDB object. Is there a simple way of detecting if the object is currently in the 'open' state?
I've tried database.closePending and looking at other properties but do not see a simple property that tells me the state of the database.
I am looking to do this synchronously.
Doing something like attempting open a transaction on a database and checking if an exception occurs is not a reasonable solution for me.
I don't want to maintain an extra variable associated with the database instance.
Perhaps I am missing some simple function in the api? Is there some observable feature of the instance variable that I can quickly and easily query to determine state?
Stated a different way, can you improve upon the following implementation?
function isOpen(db) {
if(db && Object.prototype.toString.call(db) === '[object IDBDatabase]') {
var names = db.objectStoreNames();
if(names && names.length) {
try {
var transaction = db.transaction(names[0]);
transaction.abort();
return true;
} catch(error) {
}
}
}
}
Or this method?
var opened = false;
var db;
var request = indexedDB.open(...);
request.onsuccess = function() {
db = request.result;
opened = true;
};
function isOpen(db) {
return opened;
}
db.close();
opened = false;
Or this method?
var db;
var request = indexedDB.open(...);
request.onsuccess = function() {
db = request.result;
db.onclose = function() {
db._secret_did_close = true;
};
};
function isOpen(db) {
return db instanceof IDBDatabase && !db.hasOwnProperty('_secret_did_close');
}
There's nothing else in the API that tells you if a connection is closed. Your enumeration of possibilities is what is available.
Also note that there is no closePending property in the API. The specification text uses a close pending flag to represent internal state, but this is not exposed to script.
Doing something like attempting open a transaction on a database and checking if an exception occurs is not a reasonable solution for me.
Why? This is the most reliable approach. Maintaining extra state would not account for unexpected closure (e.g. the user has deleted browsing data, forcing the connection to close) although that's what the onclose handler would account for - you'd need to combine your 2nd and 3rd approaches. (close is not fired if close() is called by script)
You should create a request by using indexedDB.open and if the connection is open you will jump onsuccess method.
request = indexedDB.open('html5',1);
request.onsuccess = function() {
console.log('Database connected');
};
Example :
https://codepen.io/headmax/pen/BmaOMR?editors=1111
About how to close or how to known if the indexedDB is still open : I guess you need to implement all events on every transaction : for example to take the control you can take the events : transaction.onerror, transaction.onabort ... If you need some example explanation i guess you have to create a new post ;).
https://developer.mozilla.org/en-US/docs/Web/API/IDBTransaction
I am using symfony2 to build some app. In that app I have chat app. I am using attached session in chat.
1) On login I fire up event listener to catch user/pass from login, connect to openfire server and get sid and rid.
2) After that i am storing that data in session so I can use them later on every page where I have chat.
Problem occurs when page is reloaded/refreshed.
My guess this is because ajax request to url:7070/httpd-bind is canceled strophe sends terminate to openfire server. Bu I can not find anywhere terminate stanza.
I am have patched strophe.js to use sync on page unload but again that is not working.
Chat.connection.flush();
Chat.connection.sync = true; // Switch to using synchronous requests since this is typically called onUnload.
Chat.connection.disconnect();
Please suggest solution for this, I am on 10 hour coding and I have no idea how to solve this.
I can sotre user/pass in session but that is just stupid. Why attached session exists if I have to do that.
UPDATE
After trying to figure about this rid plus+1 etc I noticed that rid is changing on presence, on message on message sent on roster on roster change so I made a XMLHttpRequest on each to remember new rid in session. For some reason localstorage is sometimes working sometimes not.
Now i have rid up to date all the time.
I think I got this. Problem was in rid and presence.
1) First you have to figure out from your logs if your rid is increasing or decreasing.
My was decreasing by one. So I substract -1 from my Chat.connection.rid
2) In my openfire logs I figured out that I was sending unavailable status on page refresh
so I changed my window.unload function to send presence to online. N
Now I am refreshing page million times and i never got disconnected.
Now I just have to figure out how to remember connection.rid to localStorage for non HTML browsers.
To start openfire in debug mode you just add ./openfire.sh -debug. Then you will be able to se everything in debug.log
This did trick for me. If this is doing trick for you please +1 and accept answer.
Do not forget to terminate session on logout :)
UPDATE
This is my on window.onunload function
window.onunload = function(ev){
var initialPresence = $pres().c('show').t("cao").up().c('status').t("sad");
Chat.connection.send(initialPresence);
store.set('session_rid', parseInt(Chat.connection.rid)-1);
//save rooster contacts state
var contacts = document.getElementById('records').getElementsByTagName('li');
var id_value;
var class_value;
var status;
var el;
for(i= 0; i < contacts.length; i++){
el = contacts[i].getElementsByClassName("mood")[0];
status = el.textContent || el.innerText;
Array.prototype.slice.call(contacts[i].attributes).forEach(function(item) {
if(item.name == "id"){
id_value = item.value;
}
if(item.name == "class"){
class_value = item.value;
}
store.set('user'+i, { id: id_value, class_name: class_value, status : status });
});
}
Chat.disconnect();
}
This is my on window.onload function
window.onload = function(){
if(store.get("session_rid")){
var obj;
var id;
var class_name;
var status;
store.forEach(function(val, key) {
if(val !== "session_rid"){
setTimeout(function(){
obj = eval(key);
id = obj.id;
class_name = obj.class_name;
status = obj.status;
if(document.getElementById(id)){
document.getElementById(id).className = class_name;
document.getElementById(id).getElementsByClassName("mood")[0].innerHTML = "<span>"+status+"</span>";
}
}, 1000);
}
})
}
}
This is working for me. I used store.js to store data so it can work on IE.
I used attached sessions.
//json is from ajax call on some php script that has started attached session on user login
var obj = JSON.parse(json);
connection = new Strophe.Connection(BOSH_SERVICE);
connection.attach(obj.fulljid,
obj.sid,
(store.get("session_rid") ? store.get("session_rid"):obj.rid),
justDoIt);
full_jid = obj.fulljid;
I am using an authentication cookie passed between websites on the same domain. The cookie contains some user info and page info (the accession number). The design goal is for the user to click a button on the referring website, and it will launch a second website, authenticate based on the cookie, and do some useful stuff with the accession number. I got most of this built, including getting the authentication passed and properly parsed out on the receiving system.
The problem I am having is that I can't get the data within the cookie into the javascript on the page. It seems when i launch website2 from website1, $(document).ready() is not fired after the page_load event (which handles the cookie parsing). Also I tried using a literal to post the javascript code, it's never fired (seemingly it places it after the client side stuff is executed.
What I really want to do is call a javascript function getResults(accnum) using this data.
I have this code on the page_load event:
if (userdata != null)
{
accnum = userdata[4];
}
if (accnum != String.Empty)
{
//HttpCookie accnumcookie = new HttpCookie("accnum", accnum);
//this.Context.Response.Cookies.Set(accnumcookie);
}
}
When I run the .Set function, I'm not really sure of the innards and details, but long story short, the cookie is set but does nothing.
This is the document.ready.
$(document).ready(function () {
var accnum = new String();
accnum = GetCookie('accnum');
if (accnum != null) {
document.cookie = 'test=testz';
var srch = document.getElementById('crit');
srch.style.display = 'none';
getResults('', 'accnum', accnum);
}
I'm developing an add-on for the first time. It puts a little widget in the status bar that displays the number of unread Google Reader items. To accommodate this, the add-on process queries the Google Reader API every minute and passes the response to the widget. When I run cfx test I get this error:
Error: The page has been destroyed and can no longer be used.
I made sure to catch the widget's detach event and stop the refresh timer in response, but I'm still seeing the error. What am I doing wrong? Here's the relevant code:
// main.js - Main entry point
const tabs = require('tabs');
const widgets = require('widget');
const data = require('self').data;
const timers = require("timers");
const Request = require("request").Request;
function refreshUnreadCount() {
// Put in Google Reader API request
Request({
url: "https://www.google.com/reader/api/0/unread-count?output=json",
onComplete: function(response) {
// Ignore response if we encountered a 404 (e.g. user isn't logged in)
// or a different HTTP error.
// TODO: Can I make this work when third-party cookies are disabled?
if (response.status == 200) {
monitorWidget.postMessage(response.json);
} else {
monitorWidget.postMessage(null);
}
}
}).get();
}
var monitorWidget = widgets.Widget({
// Mandatory widget ID string
id: "greader-monitor",
// A required string description of the widget used for
// accessibility, title bars, and error reporting.
label: "GReader Monitor",
contentURL: data.url("widget.html"),
contentScriptFile: [data.url("jquery-1.7.2.min.js"), data.url("widget.js")],
onClick: function() {
// Open Google Reader when the widget is clicked.
tabs.open("https://www.google.com/reader/view/");
},
onAttach: function(worker) {
// If the widget's inner width changes, reflect that in the GUI
worker.port.on("widthReported", function(newWidth) {
worker.width = newWidth;
});
var refreshTimer = timers.setInterval(refreshUnreadCount, 60000);
// If the monitor widget is destroyed, make sure the timer gets cancelled.
worker.on("detach", function() {
timers.clearInterval(refreshTimer);
});
refreshUnreadCount();
}
});
// widget.js - Status bar widget script
// Every so often, we'll receive the updated item feed. It's our job
// to parse it.
self.on("message", function(json) {
if (json == null) {
$("span#counter").attr("class", "");
$("span#counter").text("N/A");
} else {
var newTotal = 0;
for (var item in json.unreadcounts) {
newTotal += json.unreadcounts[item].count;
}
// Since the cumulative reading list count is a separate part of the
// unread count info, we have to divide the total by 2.
newTotal /= 2;
$("span#counter").text(newTotal);
// Update style
if (newTotal > 0)
$("span#counter").attr("class", "newitems");
else
$("span#counter").attr("class", "");
}
// Reports the current width of the widget
self.port.emit("widthReported", $("div#widget").width());
});
Edit: I've uploaded the project in its entirety to this GitHub repository.
I think if you use the method monitorWidget.port.emit("widthReported", response.json); you can fire the event. It the second way to communicate with the content script and the add-on script.
Reference for the port communication
Reference for the communication with postMessage
I guess that this message comes up when you call monitorWidget.postMessage() in refreshUnreadCount(). The obvious cause for it would be: while you make sure to call refreshUnreadCount() only when the worker is still active, this function will do an asynchronous request which might take a while. So by the time this request completes the worker might be destroyed already.
One solution would be to pass the worker as a parameter to refreshUnreadCount(). It could then add its own detach listener (remove it when the request is done) and ignore the response if the worker was detached while the request was performed.
function refreshUnreadCount(worker) {
var detached = false;
function onDetach()
{
detached = true;
}
worker.on("detach", onDetach);
Request({
...
onComplete: function(response) {
worker.removeListener("detach", onDetach);
if (detached)
return; // Nothing to update with out data
...
}
}).get();
}
Then again, using try..catch to detect this situation and suppress the error would probably be simpler - but not exactly a clean solution.
I've just seen your message on irc, thanks for reporting your issues.
You are facing some internal bug in the SDK. I've opened a bug about that here.
You should definitely keep the first version of your code, where you send messages to the widget, i.e. widget.postMessage (instead of worker.postMessage). Then we will have to fix the bug I linked to in order to just make your code work!!
Then I suggest you to move the setInterval to the toplevel, otherwise you will fire multiple interval and request, one per window. This attach event is fired for each new firefox window.