Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions app/assets/javascripts/discourse/controllers/user.js.es6
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,6 @@ export default ObjectController.extend(CanCheckEmails, {

collapsedInfo: Em.computed.not('indexStream'),

websiteName: function() {
var website = this.get('model.website');
if (Em.isEmpty(website)) { return; }
return website.split("/")[2];
}.property('model.website'),

linkWebsite: Em.computed.not('model.isBasic'),

removeNoFollow: function() {
Expand Down
2 changes: 1 addition & 1 deletion app/assets/javascripts/discourse/models/user.js.es6
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const User = RestModel.extend({
/**
This user's profile background(in CSS).

@property websiteName
@property profileBackground
@type {String}
**/
profileBackground: function() {
Expand Down
6 changes: 3 additions & 3 deletions app/assets/javascripts/discourse/templates/user/user.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,12 @@
{{/if}}
<h3>
{{#if model.location}}{{fa-icon "map-marker"}} {{model.location}}{{/if}}
{{#if websiteName}}
{{#if model.website_name}}
{{fa-icon "globe"}}
{{#if linkWebsite}}
<a href={{model.website}} rel={{unless removeNoFollow 'nofollow'}} target="_blank">{{websiteName}}</a>
<a href={{model.website}} rel={{unless removeNoFollow 'nofollow'}} target="_blank">{{model.website_name}}</a>
{{else}}
<span title={{model.website}}>{{websiteName}}</span>
<span title={{model.website}}>{{model.website_name}}</span>
{{/if}}
{{/if}}
</h3>
Expand Down
21 changes: 21 additions & 0 deletions app/serializers/user_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ def self.untrusted_attributes(*attrs)
:bio_cooked,
:created_at,
:website,
:website_name,
:profile_background,
:card_background,
:location,
Expand Down Expand Up @@ -133,6 +134,26 @@ def website
object.user_profile.website
end

def website_name
website_host = URI(website.to_s).host rescue nil
discourse_host = Discourse.current_hostname
return if website_host.nil?
if website_host == discourse_host
# example.com == example.com
website_host + URI(website.to_s).path
elsif (website_host.split('.').length == discourse_host.split('.').length) && discourse_host.split('.').length > 2
# www.example.com == forum.example.com
website_host.split('.')[1..-1].join('.') == discourse_host.split('.')[1..-1].join('.') ? website_host + URI(website.to_s).path : website_host
else
# example.com == forum.example.com
discourse_host.ends_with?("." << website_host) ? website_host + URI(website.to_s).path : website_host
end
end

def include_website_name
website.present?
Comment on lines +153 to +154

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Gate website_name with untrusted field rules

include_website_name only checks website.present?, so for TL0 users viewed by anonymous (where restrict_user_fields? hides website via untrusted_attributes), website_name is still serialized and the profile template will render it. That leaks the website host/path that the privacy filter is meant to suppress. Consider applying the same restrict_user_fields? check (or reusing the include_website? logic) so website_name is omitted whenever website is omitted.

Useful? React with 👍 / 👎.

end

def card_image_badge_id
object.user_profile.card_image_badge.try(:id)
end
Expand Down
21 changes: 19 additions & 2 deletions spec/serializers/user_serializer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,28 @@

context "with filled out website" do
before do
user.user_profile.website = 'http://example.com'
user.user_profile.website = 'http://example.com/user'
end

it "has a website" do
expect(json[:website]).to eq 'http://example.com'
expect(json[:website]).to eq 'http://example.com/user'
end

context "has a website name" do
it "returns website host name when instance domain is not same as website domain" do
Discourse.stubs(:current_hostname).returns('discourse.org')
expect(json[:website_name]).to eq 'example.com'
end

it "returns complete website path when instance domain is same as website domain" do
Discourse.stubs(:current_hostname).returns('example.com')
expect(json[:website_name]).to eq 'example.com/user'
end

it "returns complete website path when website domain is parent of instance domain" do
Discourse.stubs(:current_hostname).returns('forums.example.com')
expect(json[:website_name]).to eq 'example.com/user'
end
end
end

Expand Down