I'm developing my first chrome extension and I'm stuck with a "session restore" problem. At the begging of the developement when a user log in to my extension and close the popup, when he open the plugin again he had to login again.
I've used chrome.storage.sync to be able to save the session infomation to make the user to be still logged in and if he close the plugin, and his session is still active he will be redirected to the welcome page. But how can I check at the extension's startup in what page of the plugin the user was and bring him back to that page?
For example, if a user is logged and was on the "choose a book" section, how can i make the plugin open at "choose a book" section and not in "welcome" section?
Angular 2 for client side
NodeJs for server side
Consider that the session object is something like:
{
logged: true,
last_section: 'books'
}
When the user visits the books section, save it.
// this code goes inside some listener for visiting a section
chrome.storage.sync.get('session', function (items) {
const session = items.session || {}
session.last_section = 'books'
chrome.storage.sync.set({ session })
})
At the beginning of the popup script, you can simply call chrome.storage.sync.get to get the last session object state.
chrome.storage.sync.get('session', function (items) {
const session = items.session
if (session && session.logged) {
if (session.last_section === 'books') {
// render books section
}
if (session.last_section === 'welcome') {
// render welcome section
}
}
})
Related
I use Firebase with VueJS. Sign-up, sign-in works fine so far but as soon as I reload the page with F5 or load a page with writing to the browsers address bar directly then the auth session is killed, the user isn't signed-in anymore. It works fine as long as I don't reload the page, even if I click route links or get redirected to other pages, the user session keeps alive. It doesn't matter where I reload the page btw.
My login method:
firebase.auth().signInWithEmailAndPassword(this.username, this.password).then(
(user) => {
if (user.emailVerified === false) {
firebase.auth().signOut()
} else {
// redirect to lobby page if user is verified and signed in
this.$router.push('/lobby')
}
},
function(err) {
console.log(err.message)
}
)
You need to call firebase.auth().onAuthStateChanged in order to detect whether a user is logged in.
This method gets invoked in the UI thread on changes in the authentication state:
Right after the listener has been registered
When a user is signed in
When the current user is signed out
When the current user changes
Source
Example usage can be like this:
firebase.auth().onAuthStateChanged(user => {
if (user) {
if (user.emailVerified === false) {
firebase.auth().signOut()
} else {
this.$router.push('/lobby')
}
} else {
// will get to here from a logout event
// this.$router.push('/login')
}
}
Use this in your main.js file:
firebase.auth().onAuthStateChanged(() => {
if (!app) {
app = createApp(App).use(store).use(router).mount('#app')
}})
Firebase will run before Vue app is created.
I'm using the express-socket.io-session on my app. I've integrated it and it works properly. There is only one case though.
Have a look at the following code:
io.use(...);
io.sockets.on("connection", function (socket) {
socket.onVerify = (msg, fn) => {
socket.on(msg, (data) => {
console.log(socket.handshake.session.passport);
if (typeof socket.handshake.session.passport === "undefined") {
socket.emit("auth failed emit", {
msg: "Please login via the website"
});
return false;
}
fn(data, socket.handshake.session);
});
}
socket.onVerify("chat message", function (req, session) {
Chat.publish(session.email, req.msg);
});
});
Basically, on each socket request, I verify socket.handshake.session.passport being defined, which means user is logged in.
It works in this case:
I open a browser tab, login with my credentials, get redirected to /game endpoint where my game loads and connects to socket.io
I click on "logout" button, get redirected to /game endpoint, game tells me "I need to authorize."
However, it doesn't work in this case:
I open a browser tab, login with my credentials, get redirected to /game endpoint where my game loads and connects to socket.io
I click on "logout" button ON A NEW TAB, and logout in that tab.
I switch back to main tab, and game is still online.
I added a debug in my code (console.log(socket.handshake.session.passport)) and it shows { user: 1 } although I logged out already so it must be undefined
For some reason, socket.io handshake/session doesn't recognize it, so I probably need to refresh it on certain cases.
Is there any way to do it with socket.io?
This is just a try to resolve your issue, i'm not really sure it would work. But you could try something like that :
app.get("/logout", function(req,res){
//do other logging out stuff
sockets.disconnectUser(req.session.user_id);
}
// Disconnect User function
sockets.disconnectUser = function(user_id){
sockets.socket(users[user_id]).disconnect();
}
Like described here : Destroying a handshake after logout. socket.io
In Chrome Extension Development we have Background Page Concepts. Is any thing similar available in Firefox Extension Development also. While Developing Chrome Extensions I have seen methods like
window.Bkg = chrome.extension.getBackgroundPage().Bkg;
$(function () {
var view = null;
if (Bkg.account.isLoggedIn()) {
view = new Views.Popup();
$("#content").append(view.render().el);
} else {
$("#content").append(Template('logged_out')());
Bkg.refresh();
}
}...........
Where the main logic are written in Background Page(like isLoggedIn etc) and from the Extension Popup page we are calling Background page. Here for instance the background page is always loaded which manages the session. How can we have similar functionality in Firefox Extension Development.
All communication between the background page (main.js) and content scripts (your popup script) occurs via events. You cannot call functions immediately, so you won't receive any return values, but you can send an event from a content script to the background script that sends an event back to the content script and calls a new function, like so:
main.js partial
// See docs below on how to create a panel/popup
panel.port.on('loggedIn', function(message) {
panel.port.emit('isLoggedIn', someBoolean);
});
panel.port.on('refresh', function() {
// do something to refresh the view
});
popup.js
var view = null;
addon.port.on('isLoggedIn', function(someBool) {
if (someBool) {
// Obviously not code that's going to work in FF, just want you to know how to structure
view = new Views.Popup();
$("#content").append(view.render().el);
} else {
$("#content").append(Template('logged_out')());
addon.port.emit('refresh');
}
});
addon.port.emit('loggedIn', 'This is a message. I can pass any var along with the event, but I don't have to');
You should read this stuff:
Panel
Communicating between scripts
Hi I am in need to show a popup just once during installation of the extension asking for username and a log in button.When the user first clicks on the extension icon,a pop up should appear asking for username.when the user enters his username correctly,and clicks login,the pop up should be closed and then when the user again clicks on the extension icon,it should navigate to a website.What I did is when the user enters his username,it is stored in the localStorage,Each time when the user clicks on the extension icon,it checks for whether there is username in localstorage.if yes,then it should navigate to website otherwise,it should show the popup again.How can this be done?Please help me.
Here is my background.js
chrome.browserAction.onClicked.addListener(function(tab) {
if(!localStorage.username){
chrome.browserAction.setPopup({
popup: "userinfo.html"
});
}
else{//navigate to website }
});
Here the problem is that when the user first clicks on the icon,the pop up appears and the user enters his name and login.Next time when i click it again shows the pop up only.IT is not navigating to the website.Until i reload the extension,it shows only the popup on the onclick event.Anyone please help me.
You could register a listener for the chrome.browserAction.onClicked event that checks if the username is stored in localStorage and:
if it is there navigate to the website.
if it is not there navigate to userinfo.html (either in a new tab or opening a new popu window (using chrome.windows.create()), which enables you to define its location and size).
when submitting the username and password in your userinfo.html page you can store them in localStorage and log the user in.
E.g.:
In background.js:
var myWebsite = 'https://your.domain.goes/here';
var myUserinfo = chrome.extension.getURL('userinfo.html');
chrome.browserAction.onClicked.addListener(function(tab) {
if (localStorage.username) {
/* Navigate to website */
chrome.tabs.create({ url: myWebsite });
} else {
/* Navigate to `userifo.html` */
chrome.tabs.create({ url: myUserinfo });
}
});
chrome.runtime.onMessage.addListener(function(msg, sender) {
if ((msg.action === 'saveCredentials')
&& msg.user && msg.pass) {
/* Store the credentials in localStorage */
localStorage.username = user;
localStorage.password = pass;
/* For a better user-experience, let's
* navigate the user to the website right away */
chrome.tabs.updated(sender.tab.id, { url: myWebsite });
}
});
In userinfo.html's JS:
// ...once the userinfo is "submitted"
var user = ...;
var pass = ...;
chrome.runtime.sendMessage({
action: 'saveCredentials',
user: user,
pass: pass
});
I have a own page on my server where people can download a track of my own.
My idea is to put a like button on that page to my Facebook page. People must first hit the like button, and after that they can download the track. Probably this must fix with a form with name, e-mail and the like button that they have to click! After submit, there must be something that will check if the user realy hit the like button before they get the page with the special content (download link)
So the idea is if it is possible that there's a check that the page is liked before they can submit and get the download button!
Can someone tell me if this is possible and can someone help me with the code?
I have no other Facebook social plugins! I only want to use a like button!
You can check if someone clicks the like button using the Javascript SDK
You can either use the social plugin or the XFBML button,
Implementing the XFBML button and the Javascript SDK you can find here:
https://developers.facebook.com/docs/reference/javascript/
Then you can create an event listener that listens if an user clicks the like button:
FB.Event.subscribe('edge.create',
function(response) {
alert('You liked the URL: ' + response);
}
);
https://developers.facebook.com/docs/reference/javascript/FB.Event.subscribe/
Using this you can store if someone clicked the like button then save that to either your database or in a session and let the user download their track.
Your code would be something like this
<div id="fb-root"></div>
<div class="fb-like" data-href="http://www.stackoverflow.com" data-send="false" data-width="450" data-show-faces="true"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : 'YOUR_APP_ID', // App ID
channelUrl : '//WWW.YOUR_DOMAIN.COM/channel.html', // Channel File
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
FB.Event.subscribe('edge.create',
function(response) {
alert('You liked the URL: ' + response);
}
);
};
// Load the SDK Asynchronously
(function(d){
var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
d.getElementsByTagName('head')[0].appendChild(js);
}(document));
It is possible to do what you're asking. You may find this SO question and answer useful:
How to check if a user likes my Facebook Page or URL using Facebook's API