Problem getting session/current.json


(Alessandro) #1

I’ve problem to get session/current.json from a chrome extension (chrome-discourse-notifications/Source.js at master · alepolidori/chrome-discourse-notifications · GitHub).

The response is 404 and the request is made in this manner:

this.getUserData = function (cb) {
try {
var url = [ this.url, ‘/session/current.json’ ].join(’’);

        $.ajax({
            url: url,
            type: 'GET',
            cache: false,
            dataType: 'json'

        }).done(function (data, textStatus, jqXHR) {
            try {
                if (typeof data === 'object' &&
                    typeof data.current_user === 'object' &&
                    typeof data.current_user.id === 'number' &&
                    typeof data.current_user.username === 'string' &&
                    typeof data.current_user.unread_notifications === 'number' &&
                    typeof data.current_user.unread_private_messages === 'number') {

                    that.userId = data.current_user.id;
                    that.username = data.current_user.username;
                    that.messagesUrl = [
                        that.url,
                        '/users/',
                        that.username,
                        '/messages'
                    ].join('');

                    that.counter = data.current_user.unread_notifications + data.current_user.unread_private_messages;
                    that.$dispatcher.trigger(that.EVT_NOTIFICATION_COUNTER_UPDATE);
                    cb();
                }
                else {
                    cb(new Error('malformed data'));
                }
            } catch (err) {
                console.error(err.stack);
                cb(err);
            }
        }).fail(function (jqXHR, textStatus, errorThrown) {
            try {
                cb(jqXHR.status);
            } catch (err) {
                console.error(err.stack);
                cb(err);
            }
        });
    } catch (err) {
        console.error(err.stack);
        cb(err);
    }
};

I’ve tried also adding:

xhrFields: {
‘withCredentials’: true
},

to the request as explained in other post, but the 404 remains as reponse.

p.s. I’m logged to the discourse site (https://community.nethserver.org/) from chrome itself.
I’m using this request to get the user id, username, unread_notifications and unread_private_messages.

What can I do ?

The estension can be downloaded from chrome web store Discourse Forum Notifications - Chrome Web Store


Google Chrome extension for discourse notifications
(Joffrey Jaffeux) #2

Just tried whith this and got 200 OK:

curl "https://YOUR_DISCOURSE_HOST/session/current.json?api_key=YOUR_API_KEY&api_username=YOUR_USERNAME" \
     -H "Dont-Chunk: true" \
     -H "User-Agent: DiscourseTest-joffrey" \
     -H "Content-Type: application/json"

(Alessandro) #3

Thank you @joffreyjaffeux, but what is the method to get the api_key ?
To now, the user of extension, does not need to insert his credentials but it is sufficient to login to the discourse site and after that he can see the notification of the (more) sites.


(Joffrey Jaffeux) #4

Ok sorry read too fast, if you are in the browser you should be able to access currentProp of user.

Example from the javascript console in my browser:

Discourse.User.currentProp('username')
"joffreyjaffeux"
Discourse.User.currentProp('name')
"Joffrey Jaffeux"
Discourse.User.currentProp('id')
23163
Discourse.User.currentProp('unread_notifications')
0
Discourse.User.currentProp('unread_private_messages')
0

(Alessandro) #5

Yes, but unfortunately, I’m in the chrome extension context and I can’t access the Discourse object.
Can I get it in some manner @joffreyjaffeux ?


(Alessandro) #6

Does anyone else have some other insights ?
I need to get the username, I’d, unread_notifications count and unred_privatemessage count from more than one discourse site and without being into the site itself, but from external chrome extension.

Thanks to everyone wants to contribute !


(Joffrey Jaffeux) #7

Never wrote a chrome extension, so I can’t help that much, but reading this google chrome extension - Access window variable from Content Script - Stack Overflow looks like you could access window.Discourse


(Alessandro) #8

Thank you @joffreyjaffeux, but the injection of content script implies an opened tab of discourse site.
The extension enable the notification view of more discourse sites, without open them in many tabs.
So, I think also this solution is not applicable.
Do you know if Discourse provides some sort of apis to interact with ?

(What is the requirements to get session/current.json ? Some sort of authentication ?)


Google Chrome extension for discourse notifications
(David Taylor) #9

You need to either authenticate using session cookies (as if you’re using the website directly), or you can authenticate using API keys.

For a chrome extension, you should be able to use the session cookies, as long as your extension has permission to make Cross-origin requests: Cross-Origin XMLHttpRequest - Google Chrome


(Alessandro) #10

Thanks @david, but as you can see here chrome-discourse-notifications/manifest.json at master · alepolidori/chrome-discourse-notifications · GitHub I gave the permission to the extension, but when it try to get session/current.json I receive a 404 response code. The same request from the browser obtains the correct response.
The extension seems not to set properly the cookie.


(Kane York) #11

You can insert a <script> element into the document.

/* file: content_script.js */
var script = document.createElement('script');
script.innerText = `
var port = chrome.runtime.connect("` + chrome.runtime.id + `");
port.postMessage({
  username: Discourse.User.currentProp('username'),
  name: Discourse.User.currentProp('name'),
  user_id: Discourse.User.currentProp('id'),
  /* ... */
});
port.onMessage.addEventListener(function(evt) {
  /* ... */
});
`;
document.body.appendChild(script);

(David Taylor) #12

This is just a guess, but you might be hitting issues with the CSRF protection in Discourse, even though you have the correct cookies. To avoid the CSRF checks I think you’d need to use the formal API.

Maybe someone from the team will understand how the protection works in more detail and can comment.

If you need to use the API it will make your extension a lot more complicated unfortunately - you’d need to look how the Discourse mobile app requests keys, and implement the same in your extension.


(Alessandro) #13

Yes @riking, but as I answered to @joffreyjaffeux here I thing that an opened tab to discourse site is needed to inject the code, is’n it ? The chrome extension is useful because you don’t need to open discourse sites.