about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock11
-rw-r--r--app/lib/feed_manager.rb2
-rw-r--r--app/models/status.rb4
-rw-r--r--app/services/fan_out_on_write_service.rb17
-rw-r--r--app/workers/after_remote_follow_request_worker.rb2
-rw-r--r--app/workers/after_remote_follow_worker.rb2
-rw-r--r--app/workers/application_worker.rb5
-rw-r--r--app/workers/distribution_worker.rb4
-rw-r--r--db/migrate/20170405112956_add_index_on_mentions_status_id.rb5
-rw-r--r--db/schema.rb3
-rw-r--r--docs/Running-Mastodon/Production-guide.md16
-rw-r--r--docs/Using-Mastodon/List-of-Mastodon-instances.md10
-rw-r--r--docs/Using-Mastodon/User-guide.md6
-rw-r--r--docs/Using-the-API/API.md2
15 files changed, 57 insertions, 34 deletions
diff --git a/Gemfile b/Gemfile
index 4e7ff6621..b5705e9d1 100644
--- a/Gemfile
+++ b/Gemfile
@@ -8,8 +8,6 @@ gem 'sass-rails', '~> 5.0'
 gem 'uglifier', '>= 1.3.0'
 gem 'coffee-rails', '~> 4.1.0'
 gem 'jquery-rails'
-gem 'jbuilder', '~> 2.0'
-gem 'sdoc', '~> 0.4.0', group: :doc
 gem 'puma'
 
 gem 'hamlit-rails'
diff --git a/Gemfile.lock b/Gemfile.lock
index a774a89ba..408d85ade 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -198,9 +198,6 @@ GEM
       parser (>= 2.2.3.0)
       term-ansicolor (>= 1.3.2)
       terminal-table (>= 1.5.1)
-    jbuilder (2.6.0)
-      activesupport (>= 3.0.0, < 5.1)
-      multi_json (~> 1.2)
     jmespath (1.3.1)
     jquery-rails (4.1.1)
       rails-dom-testing (>= 1, < 3)
@@ -231,7 +228,6 @@ GEM
     mimemagic (0.3.2)
     mini_portile2 (2.1.0)
     minitest (5.10.1)
-    multi_json (1.12.1)
     net-scp (1.2.1)
       net-ssh (>= 2.6.5)
     net-ssh (4.0.1)
@@ -310,8 +306,6 @@ GEM
       thor (>= 0.18.1, < 2.0)
     rainbow (2.1.0)
     rake (12.0.0)
-    rdoc (4.2.2)
-      json (~> 1.4)
     react-rails (1.10.0)
       babel-transpiler (>= 0.7.0)
       coffee-script-source (~> 1.8)
@@ -381,9 +375,6 @@ GEM
       sprockets (>= 2.8, < 4.0)
       sprockets-rails (>= 2.0, < 4.0)
       tilt (>= 1.1, < 3)
-    sdoc (0.4.1)
-      json (~> 1.7, >= 1.7.7)
-      rdoc (~> 4.0)
     sidekiq (4.2.7)
       concurrent-ruby (~> 1.0)
       connection_pool (~> 2.2, >= 2.2.0)
@@ -483,7 +474,6 @@ DEPENDENCIES
   http
   httplog
   i18n-tasks (~> 0.9.6)
-  jbuilder (~> 2.0)
   jquery-rails
   letter_opener
   letter_opener_web
@@ -514,7 +504,6 @@ DEPENDENCIES
   rubocop
   ruby-oembed
   sass-rails (~> 5.0)
-  sdoc (~> 0.4.0)
   sidekiq
   sidekiq-unique-jobs
   simple-navigation
diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb
index 2cca1cefe..88f6f4a46 100644
--- a/app/lib/feed_manager.rb
+++ b/app/lib/feed_manager.rb
@@ -39,7 +39,7 @@ class FeedManager
 
   def broadcast(timeline_id, options = {})
     options[:queued_at] = (Time.now.to_f * 1000.0).to_i
-    ActionCable.server.broadcast("timeline:#{timeline_id}", options)
+    redis.publish("timeline:#{timeline_id}", Oj.dump(options))
   end
 
   def trim(type, account_id)
diff --git a/app/models/status.rb b/app/models/status.rb
index daf128572..6948ad77c 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -161,9 +161,9 @@ class Status < ApplicationRecord
       return where.not(visibility: [:private, :direct]) if account.nil?
 
       if target_account.blocking?(account) # get rid of blocked peeps
-        where('1 = 0')
+        none
       elsif account.id == target_account.id # author can see own stuff
-        where('1 = 1')
+        all
       elsif account.following?(target_account) # followers can see followers-only stuff, but also things they are mentioned in
         joins('LEFT OUTER JOIN mentions ON statuses.id = mentions.status_id AND mentions.account_id = ' + account.id.to_s)
           .where('statuses.visibility != ? OR mentions.id IS NOT NULL', Status.visibilities[:direct])
diff --git a/app/services/fan_out_on_write_service.rb b/app/services/fan_out_on_write_service.rb
index 42222c25b..106d257ba 100644
--- a/app/services/fan_out_on_write_service.rb
+++ b/app/services/fan_out_on_write_service.rb
@@ -16,6 +16,7 @@ class FanOutOnWriteService < BaseService
 
     return if status.account.silenced? || !status.public_visibility? || status.reblog?
 
+    render_anonymous_payload(status)
     deliver_to_hashtags(status)
 
     return if status.reply? && status.in_reply_to_account_id != status.account_id
@@ -48,23 +49,23 @@ class FanOutOnWriteService < BaseService
     end
   end
 
+  def render_anonymous_payload(status)
+    @payload = FeedManager.instance.inline_render(nil, 'api/v1/statuses/show', status)
+  end
+
   def deliver_to_hashtags(status)
     Rails.logger.debug "Delivering status #{status.id} to hashtags"
 
-    payload = FeedManager.instance.inline_render(nil, 'api/v1/statuses/show', status)
-
     status.tags.pluck(:name).each do |hashtag|
-      FeedManager.instance.broadcast("hashtag:#{hashtag}", event: 'update', payload: payload)
-      FeedManager.instance.broadcast("hashtag:#{hashtag}:local", event: 'update', payload: payload) if status.account.local?
+      FeedManager.instance.broadcast("hashtag:#{hashtag}", event: 'update', payload: @payload)
+      FeedManager.instance.broadcast("hashtag:#{hashtag}:local", event: 'update', payload: @payload) if status.account.local?
     end
   end
 
   def deliver_to_public(status)
     Rails.logger.debug "Delivering status #{status.id} to public timeline"
 
-    payload = FeedManager.instance.inline_render(nil, 'api/v1/statuses/show', status)
-
-    FeedManager.instance.broadcast(:public, event: 'update', payload: payload)
-    FeedManager.instance.broadcast('public:local', event: 'update', payload: payload) if status.account.local?
+    FeedManager.instance.broadcast(:public, event: 'update', payload: @payload)
+    FeedManager.instance.broadcast('public:local', event: 'update', payload: @payload) if status.account.local?
   end
 end
diff --git a/app/workers/after_remote_follow_request_worker.rb b/app/workers/after_remote_follow_request_worker.rb
index 1f2db3061..928069211 100644
--- a/app/workers/after_remote_follow_request_worker.rb
+++ b/app/workers/after_remote_follow_request_worker.rb
@@ -13,5 +13,7 @@ class AfterRemoteFollowRequestWorker
 
     follow_request.destroy
     FollowService.new.call(follow_request.account, updated_account.acct)
+  rescue ActiveRecord::RecordNotFound
+    true
   end
 end
diff --git a/app/workers/after_remote_follow_worker.rb b/app/workers/after_remote_follow_worker.rb
index bdd2c2a91..d12fa3454 100644
--- a/app/workers/after_remote_follow_worker.rb
+++ b/app/workers/after_remote_follow_worker.rb
@@ -13,5 +13,7 @@ class AfterRemoteFollowWorker
 
     follow.destroy
     FollowService.new.call(follow.account, updated_account.acct)
+  rescue ActiveRecord::RecordNotFound
+    true
   end
 end
diff --git a/app/workers/application_worker.rb b/app/workers/application_worker.rb
new file mode 100644
index 000000000..f2d7c1062
--- /dev/null
+++ b/app/workers/application_worker.rb
@@ -0,0 +1,5 @@
+class ApplicationWorker
+  def info(message)
+    Rails.logger.info("#{self.class.name} - #{message}")
+  end
+end
diff --git a/app/workers/distribution_worker.rb b/app/workers/distribution_worker.rb
index f4e738d80..9a2867ea6 100644
--- a/app/workers/distribution_worker.rb
+++ b/app/workers/distribution_worker.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-class DistributionWorker
+class DistributionWorker < ApplicationWorker
   include Sidekiq::Worker
 
   def perform(status_id)
@@ -9,6 +9,6 @@ class DistributionWorker
     FanOutOnWriteService.new.call(status)
     WarmCacheService.new.call(status)
   rescue ActiveRecord::RecordNotFound
-    true
+    info("Couldn't find the status")
   end
 end
diff --git a/db/migrate/20170405112956_add_index_on_mentions_status_id.rb b/db/migrate/20170405112956_add_index_on_mentions_status_id.rb
new file mode 100644
index 000000000..3ed1a20cf
--- /dev/null
+++ b/db/migrate/20170405112956_add_index_on_mentions_status_id.rb
@@ -0,0 +1,5 @@
+class AddIndexOnMentionsStatusId < ActiveRecord::Migration[5.0]
+  def change
+    add_index :mentions, :status_id
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 3aaa3e3ad..b5d55fa16 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema.define(version: 20170403172249) do
+ActiveRecord::Schema.define(version: 20170405112956) do
 
   # These are extensions that must be enabled in order to support this database
   enable_extension "plpgsql"
@@ -127,6 +127,7 @@ ActiveRecord::Schema.define(version: 20170403172249) do
     t.datetime "created_at", null: false
     t.datetime "updated_at", null: false
     t.index ["account_id", "status_id"], name: "index_mentions_on_account_id_and_status_id", unique: true, using: :btree
+    t.index ["status_id"], name: "index_mentions_on_status_id", using: :btree
   end
 
   create_table "mutes", force: :cascade do |t|
diff --git a/docs/Running-Mastodon/Production-guide.md b/docs/Running-Mastodon/Production-guide.md
index b1f7bd35b..90e9c0dea 100644
--- a/docs/Running-Mastodon/Production-guide.md
+++ b/docs/Running-Mastodon/Production-guide.md
@@ -12,9 +12,22 @@ map $http_upgrade $connection_upgrade {
 }
 
 server {
+  listen 80;
+  listen [::]:80;
+  server_name example.com;
+  return 301 https://$host$request_uri;
+}
+
+server {
   listen 443 ssl;
   server_name example.com;
 
+  ssl_protocols TLSv1.2;
+  ssl_ciphers EECDH+AESGCM:EECDH+AES;
+  ssl_ecdh_curve secp384r1;
+  ssl_prefer_server_ciphers on;
+  ssl_session_cache shared:SSL:10m;
+
   ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
   ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
 
@@ -75,8 +88,9 @@ It is recommended to create a special user for mastodon on the server (you could
 
 ## General dependencies
 
+    sudo apt-get install imagemagick ffmpeg libpq-dev libxml2-dev libxslt1-dev nodejs file git curl
     curl -sL https://deb.nodesource.com/setup_4.x | sudo bash -
-    sudo apt-get install imagemagick ffmpeg libpq-dev libxml2-dev libxslt1-dev nodejs file
+    apt-get intall nodejs
     sudo npm install -g yarn
 
 ## Redis
diff --git a/docs/Using-Mastodon/List-of-Mastodon-instances.md b/docs/Using-Mastodon/List-of-Mastodon-instances.md
index 0cd3f18d6..a14836b80 100644
--- a/docs/Using-Mastodon/List-of-Mastodon-instances.md
+++ b/docs/Using-Mastodon/List-of-Mastodon-instances.md
@@ -5,7 +5,10 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz)
 
 | Name | Theme/Notes, if applicable | Open Registrations | IPv6 |
 | -------------|-------------|---|---|
-| [mastodon.social](https://mastodon.social) |Flagship, quick updates|Yes|No|
+| [mastodon.social](https://mastodon.social) |Flagship, quick updates|No|No|
+| [securitymastod.one](https://securitymastod.one/) |Information security enthusiasts and pros|Yes|Yes|
+| [mastodon.cx](https://mastodon.cx/) |Alternative Mastodon instance hosted in France|Yes|Yes|
+| [mastodon.network](https://mastodon.network) |N/A|Yes|Yes|
 | [awoo.space](https://awoo.space) |Intentionally moderated, only federates with mastodon.social|Yes|No|
 | [animalliberation.social](https://animalliberation.social) |Animal Rights|Yes|No|
 | [socially.constructed.space](https://socially.constructed.space) |Single user|No|No|
@@ -17,10 +20,12 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz)
 | [social.diskseven.com](https://social.diskseven.com) |Single user|No|Yes|
 | [social.gestaltzerfall.net](https://social.gestaltzerfall.net) |Single user|No|No|
 | [mastodon.xyz](https://mastodon.xyz) |N/A|Yes|Yes|
+| [mastodon.partipirate.org](https://mastodon.partipirate.org) |French Pirate Party Instance - Politics and stuff|Yes|No|
 | [social.targaryen.house](https://social.targaryen.house) |Federates everywhere, quick updates.|Yes|Yes|
 | [masto.themimitoof.fr](https://masto.themimitoof.fr) |N/A|Yes|Yes|
+| [mstdn.io](https://mstdn.io) |N/A|Yes|Yes|
 | [social.imirhil.fr](https://social.imirhil.fr) |N/A|No|Yes|
-| [social.wxcafe.net](https://social.wxcafe.net) |Open registrations, federates everywhere, no moderation yet|Yes|Yes|
+| [social.wxcafe.net](https://social.wxcafe.net) |Open registrations, queer people, activists, safe as much as possible |Yes|Yes|
 | [octodon.social](https://octodon.social) |Open registrations, federates everywhere, cutest instance yet|Yes|Yes|
 | [mastodon.club](https://mastodon.club)|Open Registration, Open Federation, Mostly Canadians|Yes|No|
 | [hostux.social](https://hostux.social) |N/A|Yes|Yes|
@@ -40,5 +45,6 @@ There is also a list at [instances.mastodon.xyz](https://instances.mastodon.xyz)
 | [social.nasqueron.org](https://social.nasqueron.org) |Dreamers, open source developers, free culture|Yes|Yes|
 | [status.dissidence.ovh](https://status.dissidence.ovh)|N/A|Yes|Yes|
 | [mastodon.cc](https://mastodon.cc)|Art|Yes|No|
+| [mastodon.technology](https://mastodon.technology)|Open registrations, federates everywhere, for tech folks|Yes|No|
 
 Let me know if you start running one so I can add it to the list! (Alternatively, add it yourself as a pull request).
diff --git a/docs/Using-Mastodon/User-guide.md b/docs/Using-Mastodon/User-guide.md
index f8018909a..acd02f24e 100644
--- a/docs/Using-Mastodon/User-guide.md
+++ b/docs/Using-Mastodon/User-guide.md
@@ -160,13 +160,13 @@ Toot privacy is handled independently of account privacy, and individually for e
 
 **Unlisted** toots are toggled with the "Do not display in public timeline" option in the Compose pane. They are visible to anyone following you and appear on your profile page to the public even without a Mastodon login, but do *not* appear to anyone viewing the Public Timeline while logged into Mastodon.
 
-**Private** toots, finally, are toggled with the "Mark as private" switch. Private toots do not appear in the public timeline nor on your profile page to anyone viewing it unless they are on your Followers list. This means the option is of very limited use if your account is not also set to be private (as anyone can follow you without confirmation and thus see your private toots). However the separation of this means that if you *do* set your entire account to private, you can switch this option off on a toot to make unlisted or even public toots from your otherwise private account.
+**Private** toots, finally, are toggled with the "Mark as private" switch. Private toots do not appear in the public timeline nor on your profile page to anyone viewing it unless they are on your Followers list. This means the option is of very limited use if your account is not also set to be private (as anyone can follow you without confirmation and thus see your private toots). However the separation of this means that if you *do* set your entire account to private, you can switch this option off on a toot to make unlisted or even public toots from your otherwise private account. Private posts are not encrypted. Make sure you trust your instance admin not to just read your private posts on the back-end.
 
 Private toots do not federate to other instances, unless you @mention a remote user. In this case, they will federate to their instance *and may appear there PUBLICLY*. A warning will be displayed if you're composing a private toot that will federate to another instance.
 
 Private toots cannot be boosted. If someone you follow makes a private toot, it will appear in your timeline with a padlock icon in place of the Boost icon. **NOTE** that remote instances may not respect this.
 
-**Direct** messages are only visible to users you have @mentioned in them. This does *not* federate to protect your privacy (as other instances may ignore the "Direct" status and display the messages as public if they were to receive them), even if you have @mentioned a remote user.
+**Direct** posts are only visible to users you have @mentioned in them and cannot be boosted. Like with private posts, you should be mindful that the remote instance may not respect this protocol. If you are discussing a sensitive matter you should move the conversation off of Mastodon. 
 
 To summarise:
 
@@ -175,7 +175,7 @@ Toot Privacy | Visible on Profile | Visible on Public Timeline | Federates to ot
 Public | Anyone incl. anonymous viewers | Yes | Yes
 Unlisted | Anyone incl. anonymous viewers | No | Yes
 Private | Followers only | No | Only remote @mentions
-Direct | No | No | No
+Direct | No | No | Only remote @mentions
 
 #### Blocking
 
diff --git a/docs/Using-the-API/API.md b/docs/Using-the-API/API.md
index bc5ca3de4..e09d8ac9c 100644
--- a/docs/Using-the-API/API.md
+++ b/docs/Using-the-API/API.md
@@ -310,7 +310,7 @@ Returns a [Status](#status).
 
 #### Getting status context:
 
-    GET /api/v1/statuses/:id/contexts
+    GET /api/v1/statuses/:id/context
 
 Returns a [Context](#context).