There are a few security/design problems with getting your preferences to the Discourse Hub. You can’t have the server make the request, because pushing should only happen at the request of the user. Using a GET redirect is bad, because you shouldn’t be modifying data on a GET. And due to Cross-Origin rules, it’s hard to get data from one domain to another.
But not impossible, thanks to Cross-Document Messaging (wikipedia).
The Discourse site will create a modal with an <iframe>
in it, then execute some code that looks like this:
var user = Discourse.User.current();
// Build data
var preferences = {
"email": user.get('email'),
"full_name": user.get('name'),
"bio": user.get('bio_raw'), // don't pass bio_cooked - shouldn't be trusted
"website": user.get('website'),
"email_digest_days": user.get('digest_after_days'),
"email_quotes_replies_mentions": user.get('email_direct'),
// ...
"use_custom_avatar": user.get('use_uploaded_avatar'),
"custom_avatar_url": absoluteUrl(user.get('avatar_template')),
"profile_background_url": absoluteUrl(user.get('profile_background')),
"dynamic_favicon": user.get('dynamic_favicon'),
"last_pushed_from": Discourse.SiteSettings.title,
"prefs_protocol_version": 1
};
// Get element
var hubFrame = document.getElementById('hub-iframe');
// Send message
hubFrame.contentWindow.postMessage(JSON.stringify(preferences), "https://hub.discourse.org");
The magic line is that last one: hubFrame.contentWindow.postMessage(JSON.stringify(preferences), "https://hub.discourse.org");
We get to pass JSON into the iframe, and we’re assured that it’s actually the hub (because of the other-origin check on the second parameter).
I’ve already written a tentative implementation of the reciever:
Here’s what it looks like with one of my example data sets right now, first the whole page when you load it, and second after clicking one of the -
buttons:
I kinda skimmed over a few things - it doesn’t treat Gravatar correctly, and I’m not quite sure who’s supposed to host the profile backgrounds.
The code also doesn’t look too great.