# Pushing preferences to the Hub

**URL:** https://meta.discourse.org/t/pushing-preferences-to-the-hub/15081
**Category:** Site feedback
**Tags:** discourse-hub
**Created:** [4월 26, 2014, 1:59오전 UTC](https://meta.discourse.org/t/pushing-preferences-to-the-hub/15081 "2014-04-26T01:59:59Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![riking](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/riking/32/170938_2.png) [@riking](https://meta.discourse.org/u/riking)
#### Post date: [4월 26, 2014, 1:59오전 UTC](https://meta.discourse.org/t/pushing-preferences-to-the-hub/15081/1 "2014-04-26T01:59:59Z")

</div>

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)](https://en.wikipedia.org/wiki/Web_Messaging).

The Discourse site will create a modal with an `<iframe>` in it, then execute some code that looks like this:

```js
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:

[https://github.com/riking/discourse-hub-mockup](https://github.com/riking/discourse-hub-mockup)

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:

 ![](https://global.discourse-cdn.com/meta/original/2X/d/d02b8cebf250a1501c66bd498147e2b01c6d6198.png)  
 ![](https://global.discourse-cdn.com/meta/original/2X/8/8abdc1085323ce5785a23aa7df106e56b4b44e71.png) 

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.

---

<div class="post-metadata">

### Author: ![lee-dohm](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/lee-dohm/32/113511_2.png) [@lee-dohm](https://meta.discourse.org/u/lee-dohm)
#### Post date: [4월 26, 2014, 2:17오후 UTC](https://meta.discourse.org/t/pushing-preferences-to-the-hub/15081/2 "2014-04-26T14:17:38Z")

</div>

> [@riking](#):
>
> I’m not quite sure who’s supposed to host the profile backgrounds.

I was just thinking about this with regard to custom avatars. If one of the users of my tiny gaming site created a profile and uploaded a custom avatar, it would be published to S3. Then if they pushed their settings up to the Discourse Hub and it just copied the custom avatar URL to Wildly Popular Discourse Site™, could I potentially have a boatload of S3 transfer charges? (Yes, I realize that one avatar or background image is unlikely to break the bank … but it’s the principle of the thing … work with me here ;))

---

<div class="post-metadata">

### Author: ![ArmedGuy](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/armedguy/32/107987_2.png) [@ArmedGuy](https://meta.discourse.org/u/ArmedGuy)
#### Post date: [4월 26, 2014, 3:43오후 UTC](https://meta.discourse.org/t/pushing-preferences-to-the-hub/15081/3 "2014-04-26T15:43:42Z")

</div>

> [@riking](#):
>
> and I’m not quite sure who’s supposed to host the profile backgrounds.

In my opinion each forum should host its own resources.  
Both avatars and profile backgrounds can be uploaded via URL instead of file upload, but only when using the master API key.

---

<div class="post-metadata">

### Author: ![codinghorror](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/codinghorror/32/110067_2.png) [@codinghorror](https://meta.discourse.org/u/codinghorror)
#### Post date: [4월 29, 2014, 8:34오전 UTC](https://meta.discourse.org/t/pushing-preferences-to-the-hub/15081/4 "2014-04-29T08:34:44Z")

</div>

We’d probably start with a few simple preferences first as a proof of concept before even attempting images.

---

<div class="post-metadata">

### Author: ![riking](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/riking/32/170938_2.png) [@riking](https://meta.discourse.org/u/riking)
#### Post date: [4월 29, 2014, 9:47오전 UTC](https://meta.discourse.org/t/pushing-preferences-to-the-hub/15081/5 "2014-04-29T09:47:55Z")

</div>

That’s probably a good idea. I should also set up the forum-side POC so I have example code I can copy from…

---

<div class="post-metadata">

### Author: ![neil](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/neil/32/102150_2.png) [@neil](https://meta.discourse.org/u/neil)
#### Post date: [4월 29, 2014, 3:17오후 UTC](https://meta.discourse.org/t/pushing-preferences-to-the-hub/15081/6 "2014-04-29T15:17:19Z")

</div>

I like the mockup, but I’m not sure if the green, yellow and red colors are useful, or maybe I don’t understand what they indicate.

Another option (to avoid the cross origin issue) is to allow the discourse server to do the talking with the hub instead of the browser, like we currently do when checking for available usernames.

A security concern is: are you who you say you are? If a Discourse site pushes a change for [niceguy@example.com](mailto:niceguy@example.com) to set his name to “Stinky Face”, was it really him who made that push? The simplest solution would be for the hub to send an email to Stinky Face niceguy asking him to click a link to verify the change.

---

<div class="post-metadata">

### Author: ![erlend\_sh](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/erlend_sh/32/119475_2.png) [@erlend\_sh](https://meta.discourse.org/u/erlend_sh)
#### Post date: [1월 8, 2016, 11:41오전 UTC](https://meta.discourse.org/t/pushing-preferences-to-the-hub/15081/7 "2016-01-08T11:41:57Z")

</div>

Continued here:

> [@Revitalizing the Discourse Hub](https://meta.discourse.org/t/revitalizing-the-discourse-hub/15029):
>
> The original basic idea of the Discourse Hub have a reserved @username across all Discourse instances, so when someone sees @username on any Discourse forum, they’ll know it is (probably) you! … seems like kind of a bad idea in retrospect. Why? Well, if you run your own Discourse, and your name is @david, you probably want to be called @david, even if some other David reserved the name in Feburary 2013 here on meta. It is your community, after all, who are we to tell you that you can’t use y…
