* Downcase signed_headers string before building the signed string
The HTTP Signatures draft does not mandate the “headers” field to be downcased,
but mandates the header field names to be downcased in the signed string, which
means that prior to this patch, Mastodon could fail to process signatures from
some compliant clients. It also means that it would not actually check the
Digest of non-compliant clients that wouldn't use a lowercased Digest field
name.
Thankfully, I don't know of any such client.
* Revert "Remove dead code (#8919)"
This reverts commit a00ce8c92c.
* Restore time window checking, change it to 12 hours
By checking the Date header, we can prevent replaying old vulnerable
signatures. The focus is to prevent replaying old vulnerable requests
from software that has been fixed in the meantime, so a somewhat long
window should be fine and accounts for timezone misconfiguration.
* Escape users' URLs when formatting them
Fixes possible HTML injection
* Escape all string interpolations in Formatter class
Slightly improve performance by reducing class allocations
from repeated Formatter#encode calls
* Fix code style issues
* Add conversations API
* Add web UI for conversations
* Add test for conversations API
* Add tests for ConversationAccount
* Improve web UI
* Rename ConversationAccount to AccountConversation
* Remove conversations on block and mute
* Change last_status_id to be a denormalization of status_ids
* Add optimistic locking
Conflicts:
db/migrate/20170716191202_add_hide_notifications_to_mute.rb
spec/controllers/application_controller_spec.rb
Took our version, upstream changes were only minor style linting.
* Allow min_id pagination in Feed#get
* Add min_id pagination to home and list timeline APIs
* Add min_id pagination to account statuses, public and tag APIs
* Remove unused stub in reports API
* Use min_id pagination in notifications, favourites, and fix order
* Fix HomeFeed#from_database not using paginate_by_id
* Add force_login option to OAuth authorize page
For when a user needs to sign into an app from multiple accounts
on the same server
* When logging out from modal header, redirect back after re-login
* Add animate custom emoji param to embed pages
* Rename param, use it for avatars and gifs
* Fix issues pointed by codeclimate and breaking test
* Ignore brakeman warning
* Allow moderators to disable/enable login
* Instead of rejecting login, show forbidden error when login disabled
Avoid confusion because when login is rejected, the message is that
the account is not activated, which is wrong.
* Fix tests
* Add default_settings class method to ScopedSettings
ScopedSettings was extended to use value of unscoped setting instead of
only using defaults set in config/settings.yml for selected settings.
This adds possibility for admins to set default values of users' settings,
for example default theme (as requested in #7092).
* Add ability to change an instance default theme
Closes#7092
Conflicts:
.circleci/config.yml
app/controllers/authorize_follows_controller.rb
app/javascript/packs/public.js
Moved new stuff from packs/public.js to core/public.js.
Added appropriate use_pack in new controllers.
* Add remote interaction dialog for toots
* Change AuthorizeFollow into AuthorizeInteraction, support statuses
* Update brakeman.ignore
* Adjust how interaction buttons are display on public pages
* Fix tests
Conflicts:
app/models/status.rb
db/migrate/20180528141303_fix_accounts_unique_index.rb
db/schema.rb
Resolved by taking upstream changes (no real conflicts, just glitch-soc
specific code too close to actual changes).
Conflicts:
app/controllers/accounts_controller.rb
app/javascript/mastodon/locales/pl.json
app/views/about/more.html.haml
Conflicts in `accounts_controller.rb` resolved by taking upstream's
version + our `use_pack`.
Conflicts in `pl.json` resolved by taking upstream's changes.
Conflicts in `aboute/more.html.haml` resolved by taking upstream's changes.
Manually-resolved conflicts:
.circleci/config.yml
app/controllers/accounts_controller.rb
app/controllers/auth/passwords_controller.rb
app/controllers/statuses_controller.rb
app/javascript/packs/public.js
app/models/media_attachment.rb
app/views/stream_entries/_content_spoiler.html.haml
app/views/stream_entries/_media.html.haml
config/locales/en.yml
config/locales/ja.yml
config/locales/pl.yml
lib/mastodon/version.rb
Some content from app/javascript/packs/public.js has been split to
app/javascript/core/settings.js.
Translation strings for glitch-soc's keyword mutes were dropped.
Everything else was mostly “take both”.
Conflicts:
Dockerfile
app/javascript/packs/common.js
config/webpack/loaders/sass.js
config/webpack/shared.js
db/schema.rb
package.json
yarn.lock
A lot of the conflicts come from updating webpack.
Even though upstream deleted app/javascript/packs/common.js, I kept
glitch-soc's version as it unifies JS/CSS packs behavior across flavours.
Ported glitch changes to webpack 4.x
Completely remove glitch-soc's Keyword Mutes, migrate
existing database records to CustomFilters.
Handling of client-side filters is still not implemented
in the glitch-soc front-end.
Conflicts:
README.md
app/controllers/statuses_controller.rb
app/lib/feed_manager.rb
config/navigation.rb
spec/lib/feed_manager_spec.rb
Conflicts were resolved by taking both versions for each change.
This means the two filter systems (glitch-soc's keyword mutes and tootsuite's
custom filters) are in place, which will be changed in a follow-up commit.
DELETE /api/v1/suggestions/:account_id
When blocking, remove suggestion from both sides. Muting not affected,
since muting is supposed to be invisible to the target.
* Add more granular OAuth scopes
* Add human-readable descriptions of the new scopes
* Ensure new scopes look good on the app UI
* Add tests
* Group scopes in screen and color-code dangerous ones
* Fix wrong extra scope
* Re-add follow recommendations API
GET /api/v1/suggestions
Removed in 8efa081f21 due to Neo4J
dependency. The algorithm uses triadic closures, takes into account
suspensions, blocks, mutes, domain blocks, excludes locked and moved
accounts, and prefers more recently updated accounts.
* Track interactions with people you don't follow
Replying to, favouriting and reblogging someone you're not following
will make them show up in follow recommendations. The interactions
have different weights:
- Replying is 1
- Favouriting is 10 (decidedly positive interaction, but private)
- Reblogging is 20
Following them, muting or blocking will remove them from the list,
obviously.
* Remove triadic closures, ensure potential friendships are trimmed
* Make embeds cacheable by reverse proxy
* Make follow button on embeds open remote follow modal
Instead of web+mastodon://, also, turn the button blue, and add a
sign up prompt to the remote follow modal
`@signature_verification_failure_reason` is used in most places but`@signed_verification_failure_reason` appears in two places. Likely those errors are not returned.
* Add keyword filtering
GET|POST /api/v1/filters
GET|PUT|DELETE /api/v1/filters/:id
- Irreversible filters can drop toots from home or notifications
- Other filters can hide toots through the client app
- Filters use a phrase valid in particular contexts, expiration
* Make sure expired filters don't get applied client-side
* Add missing API methods
* Remove "regex filter" from column settings
* Add tests
* Add test for FeedManager
* Add CustomFilter test
* Add UI for managing filters
* Add streaming API event to allow syncing filters
* Fix tests
Conflicts:
app/javascript/mastodon/initial_state.js
db/schema.rb
Upstream added a new field to initial_state.
Not too sure about what happened with db/schema.rb though…
* Send rejections to followers when user hides domain they're on
* Use account domain blocks for "authorized followers" action
Replace soft-blocking (block & unblock) behaviour with follow rejection
* Split sync and async work of account domain blocking
Do not create domain block when removing followers by domain, that
is probably unexpected from the user's perspective.
* Adjust confirmation message for domain block
* yarn manage:translations
* optimize direct timeline
* fix typo in class name
* change filter condition for direct timeline
* fix codestyle issue
* revoke index_accounts_not_silenced because direct timeline does not use it.
* revoke index_accounts_not_silenced because direct timeline does not use it.
* fix rspec test condition.
* fix rspec test condition.
* fix rspec test condition.
* revoke adding column and partial index
* (direct timeline) move merging logic to model
* fix pagination parameter
* add method arguments that switches return array of status or cache_ids
* fix order by
* returns ActiveRecord.Relation in default behavor
* fix codestyle issue
* Track trending tags
- Half-life of 1 day
- Historical usage in daily buckets (last 7 days stored)
- GET /api/v1/trends
Fix#271
* Add trends to web UI
* Don't render compose form on search route, adjust search results header
* Disqualify tag from trends if it's in disallowed hashtags setting
* Count distinct accounts using tag, ignore silenced accounts
Conflicts:
app/javascript/styles/mastodon-light.scss
config/locales/en.yml
config/locales/fr.yml
config/locales/simple_form.pl.yml
config/themes.yml
Conflicts resolved by deleting config/themes.yml,
marking app/javascript/styles/mastodon-light.scss as added,
and taking all new translation strings, not removing anything from
them.
* Add preference to hide following/followers lists
- Public pages
- ActivityPub collections (does not return pages but does give total)
- REST API (unless it's your own) (does not federate)
Fix#6901
* Add preference
* Add delegation
* Fix issue
* Fix issue
permitted_for scope is slow when combined with pinned status scope.
Fortunately permitted_for scope can safely be removed because a pinned
status is always public.
- POST /api/v1/push/subscription
- PUT /api/v1/push/subscription
- DELETE /api/v1/push/subscription
- New OAuth scope: "push" (required for the above methods)
* No need to re-require sidekiq plugins, they are required via Gemfile
* Add derailed_benchmarks tool, no need to require TTY gems in Gemfile
* Replace ruby-oembed with FetchOEmbedService
Reduce startup by 45382 allocated objects
* Remove preloaded JSON-LD in favour of caching HTTP responses
Reduce boot RAM by about 6 MiB
* Fix tests
* Fix test suite by stubbing out JSON-LD contexts
* Fix URL of "Show more" link in paginated threads (ancestors side)
Increase item limits in threads
Fix#7268
* Fix "Show more" link in paginated threads (descendants side)
* Use table for statuses in report
* Display reported account and reporter in the same table
* Split accounts and general report info into two tables again
* Redesign report statuses table, notes, merge notes and action log
* Remove unused translations
* Fix code style issue
* Fix code style issue
* Fix code style issue
* Added a timeline for Direct statuses
* Lists all Direct statuses you've sent and received
* Displayed in Getting Started
* Streaming server support for direct TL
* Changes to match other timelines in 2.0
Commit 519119f657 missed a change for
stream entry page. Instead of duplicating the change, redirect to account
status page. It would also help crawlers (of search engines, for example)
to understand a stream entry URL and its corresponding status URL points
to the same page.
* Add bio fields
- Fix#3211
- Fix#232
- Fix#121
* Display bio fields in web UI
* Fix output of links and missing fields
* Federate bio fields over ActivityPub as PropertyValue
* Improve how the fields are stored, add to Edit profile form
* Add rel=me to links in fields
Fix#121
This also limits the statuses returned by API, but pagination is not
implemented in Web API yet. I still expect it brings user experience
better than making a user wait to fetch all ancestor statuses and flooding
the column with them.
* Further improvements to Reports UI
- Clean up notes display
- Clean up add new note form
- Simplify controller
- Allow reopening a report with a note
- Show created at date for reports
- Fix report details table formatting
* Show history of report using Admin::ActionLog beneath the report
* Fix incorrect log message when reopening a report
* Implement fetching of all ActionLog items that could be related to the report
* Ensure adding a report_note updates the report's updated_at
* Limit Report History to actions that happened between the report being created and the report being resolved
* Fix linting issues
* Improve report history builder
Thanks @gargron for the improvements
* Admin: Show unconfirmed email address on account page
* Admin: Allow staff to change user email addresses
* ActionLog: On change_email, log current email address and new unconfirmed email address
Conflicts:
app/serializers/initial_state_serializer.rb
The glitch flavour isn't yet pulling custom emoji data on its own (see
https://github.com/tootsuite/mastodon/pull/7047). Once that gets into
the glitch flavour, we can eliminate the custom_emojis load.
* Enable updating additional account information from user preferences via rest api
Resolves#6553
* Pacify rubocop
* Decoerce incoming settings in UserSettingsDecorator
* Create user preferences hash directly from incoming credentials instead of going through ActionController::Parameters
* Clean up user preferences update
* Use ActiveModel::Type::Boolean instead of manually checking stringified number equivalence
* Fix follow/unfollow buttons on public profile
- Present non-logged users with web+mastodon:// URLs for remote accounts
- Present logged-in users with appropriate links (authorize_follows and
remote_unfollows) for remote accounts
* Do not cache rendered cards if user is logged in
Previously these returns 302 redirects instead of 403s, which meant posting links to admin pages in slack caused them to unfurl, rather than stay as a link. Additionally, require_admin! doesn't appear to be actively used, on require_staff!
* Implement Assignment of Reports (#6967)
* Change translation of admin.report.comment.label to "Report Comment" for clarity
As we'll soon add the ability for reports to have comments on them, this clarification makes sense.
* Implement notes for Reports
This enables moderators to leave comments about a report whilst they work on it
* Fix display of report moderation notes
* Allow reports to be reopened / marked as unresolved
* Redirect to reports listing upon resolution of report
* Implement "resolve with note" functionality
* Add inverse relationship for report notes
* Remove additional database querying when loading report notes
* Fix tests for reports
* Fix localisations for report notes / reports
Previously the default locale was set by Localized concern for controllers,
but it was not enforced for mailers.
config is enforced throughout the application and an appropriate place to
set the default locale.
Use Rails smart boolean cast to account for values such as "f",
"0", "false", etc. Previously, if a param was present in the request,
it would count as true.
* Fix prev/next links on public profile page
* Don't make pagination urls if no available statuses
* Fix empty check method
* Put left chevron before prev page link
* Add scope for pagination "starting at" a given id
* Status pagination try 2:
s/prev/older and s/next/newer
"older" on left, "newer" on right
Use new scope for "newer" link
Extract magic 20 page size to constant
Remove max_id from feed pagination as it's not respected
* Reinstate max_id for accounts atom stream
* normalize
* Redesign landing page (again)
* Move login form in small version to the right column
* Display closed registrations message
* Add site setting for the hero image
* Fix test
* Increase spacing, maximum width, change call to action section
* Add focus param to media API, center thumbnails on focus point
* Add UI for setting a focal point
* Improve focal point icon on upload item
* Use focal point in upload preview
* Add focalPoint property to ActivityPub
* Don't show focal point button for non-image attachments
* Fix#201: Account archive download
* Export actor and private key in the archive
* Optimize BackupService
- Add conversation to cached associations of status, because
somehow it was forgotten and is source of N+1 queries
- Explicitly call GC between batches of records being fetched
(Model class allocations are the worst offender)
- Stream media files into the tar in 1MB chunks
(Do not allocate media file (up to 8MB) as string into memory)
- Use #bytesize instead of #size to calculate file size for JSON
(Fix FileOverflow error)
- Segment media into subfolders by status ID because apparently
GIF-to-MP4 media are all named "media.mp4" for some reason
* Keep uniquely generated filename in Paperclip::GifTranscoder
* Ensure dumped files do not overwrite each other by maintaing directory partitions
* Give tar archives a good name
* Add scheduler to remove week-old backups
* Fix code style issue
* Add option to show only local toots in timeline preview
Right know, toots from all the known fediverse are shown in the main
page of an instance. That however doesn't reflect the instance itself.
With this option the admin may choose to display only local toots so
that users checking the instance get a better idea of internal
conversations.
* Fix issues pointed by codeclimate and eslint
* Add default message for community timeline
* Update pl.yml
UserTrackingConcern is circumvented by SessionsController#create
because it calls warden, which calls the User#update_tracked_fields!
method directly. Move returning user logic to that method.
* Fix regeneration marker not being removed after completion
* Return HTTP 206 from /api/v1/timelines/home if regeneration in progress
Prioritize RegenerationWorker by putting it into default queue
* Display loading indicator and poll home timeline while it regenerates
* Add graphic to regeneration message
* Make "not found" indicator consistent with home regeneration
CSRF token checking was enabled for API controllers in #6223,
producing "Can't verify CSRF token authenticity" log spam. This
disables logging of failed CSRF checks.
This also changes the protection strategy for
PushSubscriptionsController to use exceptions, making it consistent
with other controllers that use sessions.
If a flavour has only one skin, the skin selector will be omitted. This
omits the user[setting_skin] field, and because that's the only
user[...] field on the page, the entire user object will not be present
in the request handler's params object.
This commit accounts for that scenario by avoiding params.require(:user)
and instead picking out what we need from the params hash.
* Allow HTTP caching of json view of public statuses
HTML views are not cached as they can contain private statuses as well
* Disable session cookies for ActivityPub json rendering of public toots
* Add confirmation step for email changes
This adds a confirmation step for email changes of existing users.
Like the initial account confirmation, a confirmation link is sent
to the new address.
Additionally, a notification is sent to the existing address when
the change is initiated. This message includes instruction to reset
the password immediately or to contact the instance admin if the
change was not initiated by the account owner.
Fixes#3871
* Add review fixes
* Add GET /api/v1/instance/peers API to reveal known domains
* Add GET /api/v1/instance/activity API
* Make new APIs disableable, exclude private statuses from activity stats
* Fix code style issue
* Fix week timestamps
* Make host_meta/webfinger replies cacheable (fixes#6100)
Drop common code for handling users and sessions as webfinger queries
are very basic, public APIs.
Also explicitly mark results as cacheable with “expires_in”.
* Add “Vary: Accept” header for caching since content-negociation is used
Specifically, this commit:
- changes S::TFA::{Confirmations,RecoveryCodes}Controller to derive from
S::BaseController, because this gives us the necessary actions and
packs
- prepends set_pack to Auth::SessionsController's action chain so that
it takes effect in time for render :two_factor
The specs for Settings::DeletesController include an example that
sets Settings.open_deletion to false and expects the "if deletion is not
available, redirect to root" logic to run. However, this spec does not
set up a user, which means that the spec (intentionally or otherwise)
expects this redirection to work with unauthenticated access.
We should preserve that behavior. To do so, we prepend the deletion
check to the action chain set up by Settings::BaseController, so that
said check occurs before the authenticate_user! check.
* Add list of lists component to web UI
* Add list adding
* Add list removing
* List editor modal
* Add API account search limited by following=true relation
* Rework list editor modal
* Remove mandatory pagination of GET /api/v1/lists/:id/accounts
* Adjust search input placeholder
* Fix rspec (#5890)
* i18n: (zh-CN) Add missing translations for #5811 (#5891)
* i18n: (zh-CN) yarn manage:translations -- zh-CN
* i18n: (zh-CN) Add missing translations for #5811
* Fix some issues
- Display loading/missing state for list timelines
- Order lists alphabetically in overview
- Fix async list editor reset
- Redirect to /lists after deleting unpinned list
- Redirect to / after pinning a list
* Remove dead list columns when a list is deleted or fetch returns 404
* Allow hiding of reblogs from followed users
This adds a new entry to the account menu to allow users to hide
future reblogs from a user (and then if they've done that, to show
future reblogs instead).
This does not remove or add historical reblogs from/to the user's
timeline; it only affects new statuses.
The API for this operates by sending a "reblogs" key to the follow
endpoint. If this is sent when starting a new follow, it will be
respected from the beginning of the follow relationship (even if
the follow request must be approved by the followee). If this is
sent when a follow relationship already exists, it will simply
update the existing follow relationship. As with the notification
muting, this will now return an object ({reblogs: [true|false]}) or
false for each follow relationship when requesting relationship
information for an account. This should cause few issues due to an
object being truthy in many languages, but some modifications may
need to be made in pickier languages.
Database changes: adds a show_reblogs column (default true,
non-nullable) to the follows and follow_requests tables. Because
these are non-nullable, we use the existing MigrationHelpers to
perform this change without locking those tables, although the
tables are likely to be small anyway.
Tests included.
See also <https://github.com/glitch-soc/mastodon/pull/212>.
* Rubocop fixes
* Code review changes
* Test fixes
This patchset closes#648 and resolves#3271.
* Rubocop fix
* Revert reblogs defaulting in argument, fix tests
It turns out we needed this for the same reason we needed it in muting:
if nil gets passed in somehow (most usually by an API client not passing
any value), we need to detect and handle it.
We could specify a default in the parameter and then also catch nil, but
there's no great reason to duplicate the default value.
* Add consumable invites
* Add UI for generating invite codes
* Add tests
* Display max uses and expiration in invites table, delete invite
* Remove unused column and redundant validator
- Default follows not used, probably bad idea
- InviteCodeValidator is redundant because RegistrationsController
checks invite code validity
* Add admin setting to disable invites
* Add admin UI for invites, configurable role for invite creation
- Admin UI that lists everyone's invites, always available
- Admin setting min_invite_role to control who can invite people
- Non-admin invite UI only visible if users are allowed to
* Do not remove invites from database, expire them instantly
* Add structure for lists
* Add list timeline streaming API
* Add list APIs, bind list-account relation to follow relation
* Add API for adding/removing accounts from lists
* Add pagination to lists API
* Add pagination to list accounts API
* Adjust scopes for new APIs
- Creating and modifying lists merely requires "write" scope
- Fetching information about lists merely requires "read" scope
* Add test for wrong user context on list timeline
* Clean up tests
* Add a hide_notifications column to mutes
* Add muting_notifications? and a notifications argument to mute!
* block notifications in notify_service from hard muted accounts
* Add specs for how mute! interacts with muting_notifications?
* specs testing that hide_notifications in mutes actually hides notifications
* Add support for muting notifications in MuteService
* API support for muting notifications (and specs)
* Less gross passing of notifications flag
* Break out a separate mute modal with a hide-notifications checkbox.
* Convert profile header mute to use mute modal
* Satisfy eslint.
* specs for MuteService notifications params
* add trailing newlines to files for Pork :)
* Put the label for the hide notifications checkbox in a label element.
* Add a /api/v1/mutes/details route that just returns the array of mutes.
* Define a serializer for /api/v1/mutes/details
* Add more specs for the /api/v1/mutes/details endpoint
* Expose whether a mute hides notifications in the api/v1/relationships endpoint
* Show whether muted users' notifications are muted in account lists
* Allow modifying the hide_notifications of a mute with the /api/v1/accounts/:id/mute endpoint
* make the hide/unhide notifications buttons work
* satisfy eslint
* In probably dead code, replace a dispatch of muteAccount that was skipping the modal with launching the mute modal.
* fix a missing import
* add an explanatory comment to AccountInteractions
* Refactor handling of default params for muting to make code cleaner
* minor code style fixes oops
* Fixed a typo that was breaking the account mute API endpoint
* Apply white-space: nowrap to account relationships icons
* Fix code style issues
* Remove superfluous blank line
* Rename /api/v1/mutes/details -> /api/v2/mutes
* Don't serialize "account" in MuteSerializer
Doing so is somewhat unnecessary since it's always the current user's account.
* Fix wrong variable name in api/v2/mutes
* Use Toggle in place of checkbox in the mute modal.
* Make the Toggle in the mute modal look better
* Code style changes in specs and removed an extra space
* Code review suggestions from akihikodaki
Also fixed a syntax error in tests for AccountInteractions.
* Make AddHideNotificationsToMute Concurrent
It's not clear how much this will benefit instances in practice, as the
number of mutes tends to be pretty small, but this should prevent any
blocking migrations nonetheless.
* Fix up migration things
* Remove /api/v2/mutes
* Add option to block direct messages from people you don't follow
Fix#5326
* If the DM responds to a toot by recipient, allow it through
* i18n: Update Polish translation (for #5669) (#5673)
* Add moderator role and add pundit policies for admin actions
* Add rake task for turning user into mod and revoking it again
* Fix handling of unauthorized exception
* Deliver new report e-mails to staff, not just admins
* Add promote/demote to admin UI, hide some actions conditionally
* Fix unused i18n
* Show the local couterpart of emoji when it exists in admin/custom_emojis
* Fix indentation
* Fix error
* Add class table-action-link to Overwrite link
* Make it enable to overwrite emojis
* Make Code Climate happy
There are two motivations for this:
1. It looks like we're going to add other features that require
server-side storage (e.g. user notes).
2. Namespacing glitchsoc modifications is a good idea anyway: even if we
do not end up doing (1), if upstream introduces a keyword-mute feature
that also uses a "KeywordMute" model, we can avoid some merge
conflicts this way and work on the more interesting task of
choosing which implementation to use.
This should eventually be accessible via the API and the web frontend,
but I find it easier to set up an editing interface using Rails
templates and the like. We can always take it out if it turns out we
don't need it.
* Add option to reduce motion
* Use HOC to wrap all Motion calls
* fix case-sensitive issue
* Avoid updating too frequently
* Get rid of unnecessary change to _simple_status.html.haml
- For some reason, :if option on before_action did not work. It got
executed every time, returned false, and the action run anyway,
which led to the current_sign_in_at and sign_in_count being
updated on every request
- Return "do not filter" early in FeedManager#filter_from_home? if
the status is authored by receiver. Usually this method is not
called for own statuses at all, but it is called when Feed#get
uses the database
- Return early if #reload_stale_associations! has nothing to load
to save a database query with WHERE 1=0
* Use non-serial IDs
This change makes a number of nontrivial tweaks to the data model in
Mastodon:
* All IDs are now 8 byte integers (rather than mixed 4- and 8-byte)
* IDs are now assigned as:
* Top 6 bytes: millisecond-resolution time from epoch
* Bottom 2 bytes: serial (within the millisecond) sequence number
* See /lib/tasks/db.rake's `define_timestamp_id` for details, but
note that the purpose of these changes is to make it difficult to
determine the number of objects in a table from the ID of any
object.
* The Redis sorted set used for the feed will have values used to look
up toots, rather than scores. This is almost always the same as the
existing behavior, except in the case of boosted toots. This change
was made because Redis stores scores as double-precision floats,
which cannot store the new ID format exactly. Note that this doesn't
cause problems with sorting/pagination, because ZREVRANGEBYSCORE
sorts lexicographically when scores are tied. (This will still cause
sorting issues when the ID gains a new significant digit, but that's
extraordinarily uncommon.)
Note a couple of tradeoffs have been made in this commit:
* lib/tasks/db.rake is used to enforce many/most column constraints,
because this commit seems likely to take a while to bring upstream.
Enforcing a post-migrate hook is an easier way to maintain the code
in the interim.
* Boosted toots will appear in the timeline as many times as they have
been boosted. This is a tradeoff due to the way the feed is saved in
Redis at the moment, but will be handled by a future commit.
This would effectively close Mastodon's #1059, as it is a
snowflake-like system of generating IDs. However, given how involved
the changes were simply within Mastodon, it may have unexpected
interactions with some clients, if they store IDs as doubles
(or as 4-byte integers). This was a problem that Twitter ran into with
their "snowflake" transition, particularly in JavaScript clients that
treated IDs as JS integers, rather than strings. It therefore would be
useful to test these changes at least in the web interface and popular
clients before pushing them to all users.
* Fix JavaScript interface with long IDs
Somewhat predictably, the JS interface handled IDs as numbers, which in
JS are IEEE double-precision floats. This loses some precision when
working with numbers as large as those generated by the new ID scheme,
so we instead handle them here as strings. This is relatively simple,
and doesn't appear to have caused any problems, but should definitely
be tested more thoroughly than the built-in tests. Several days of use
appear to support this working properly.
BREAKING CHANGE:
The major(!) change here is that IDs are now returned as strings by the
REST endpoints, rather than as integers. In practice, relatively few
changes were required to make the existing JS UI work with this change,
but it will likely hit API clients pretty hard: it's an entirely
different type to consume. (The one API client I tested, Tusky, handles
this with no problems, however.)
Twitter ran into this issue when introducing Snowflake IDs, and decided
to instead introduce an `id_str` field in JSON responses. I have opted
to *not* do that, and instead force all IDs to 64-bit integers
represented by strings in one go. (I believe Twitter exacerbated their
problem by rolling out the changes three times: once for statuses, once
for DMs, and once for user IDs, as well as by leaving an integer ID
value in JSON. As they said, "If you’re using the `id` field with JSON
in a Javascript-related language, there is a very high likelihood that
the integers will be silently munged by Javascript interpreters. In most
cases, this will result in behavior such as being unable to load or
delete a specific direct message, because the ID you're sending to the
API is different than the actual identifier associated with the
message." [1]) However, given that this is a significant change for API
users, alternatives or a transition time may be appropriate.
1: https://blog.twitter.com/developer/en_us/a/2011/direct-messages-going-snowflake-on-sep-30-2011.html
* Restructure feed pushes/unpushes
This was necessary because the previous behavior used Redis zset scores
to identify statuses, but those are IEEE double-precision floats, so we
can't actually use them to identify all 64-bit IDs. However, it leaves
the code in a much better state for refactoring reblog handling /
coalescing.
Feed-management code has been consolidated in FeedManager, including:
* BatchedRemoveStatusService no longer directly manipulates feed zsets
* RemoveStatusService no longer directly manipulates feed zsets
* PrecomputeFeedService has moved its logic to FeedManager#populate_feed
(PrecomputeFeedService largely made lots of calls to FeedManager, but
didn't follow the normal adding-to-feed process.)
This has the effect of unifying all of the feed push/unpush logic in
FeedManager, making it much more tractable to update it in the future.
Due to some additional checks that must be made during, for example,
batch status removals, some Redis pipelining has been removed. It does
not appear that this should cause significantly increased load, but if
necessary, some optimizations are possible in batch cases. These were
omitted in the pursuit of simplicity, but a batch_push and batch_unpush
would be possible in the future.
Tests were added to verify that pushes happen under expected conditions,
and to verify reblog behavior (both on pushing and unpushing). In the
case of unpushing, this includes testing behavior that currently leads
to confusion such as Mastodon's #2817, but this codifies that the
behavior is currently expected.
* Rubocop fixes
I could swear I made these changes already, but I must have lost them
somewhere along the line.
* Address review comments
This addresses the first two comments from review of this feature:
https://github.com/tootsuite/mastodon/pull/4801#discussion_r139336735https://github.com/tootsuite/mastodon/pull/4801#discussion_r139336931
This adds an optional argument to FeedManager#key, the subtype of feed
key to generate. It also tests to ensure that FeedManager's settings are
such that reblogs won't be tracked forever.
* Hardcode IdToBigints migration columns
This addresses a comment during review:
https://github.com/tootsuite/mastodon/pull/4801#discussion_r139337452
This means we'll need to make sure that all _id columns going forward
are bigints, but that should happen automatically in most cases.
* Additional fixes for stringified IDs in JSON
These should be the last two. These were identified using eslint to try
to identify any plain casts to JavaScript numbers. (Some such casts are
legitimate, but these were not.)
Adding the following to .eslintrc.yml will identify casts to numbers:
~~~
no-restricted-syntax:
- warn
- selector: UnaryExpression[operator='+'] > :not(Literal)
message: Avoid the use of unary +
- selector: CallExpression[callee.name='Number']
message: Casting with Number() may coerce string IDs to numbers
~~~
The remaining three casts appear legitimate: two casts to array indices,
one in a server to turn an environment variable into a number.
* Only implement timestamp IDs for Status IDs
Per discussion in #4801, this is only being merged in for Status IDs at
this point. We do this in a migration, as there is no longer use for
a post-migration hook. We keep the initialization of the timestamp_id
function as a Rake task, as it is also needed after db:schema:load (as
db/schema.rb doesn't store Postgres functions).
* Change internal streaming payloads to stringified IDs as well
This is equivalent to 591a9af356faf2d5c7e66e3ec715502796c875cd from
#5019, with an extra change for the addition to FeedManager#unpush.
* Ensure we have a status_id_seq sequence
Apparently this is not a given when specifying a custom ID function,
so now we ensure it gets created. This uses the generic version of this
function to more easily support adding additional tables with timestamp
IDs in the future, although it would be possible to cut this down to a
less generic version if necessary. It is only run during db:schema:load
or the relevant migration, so the overhead is extraordinarily minimal.
* Transition reblogs to new Redis format
This provides a one-way migration to transition old Redis reblog entries
into the new format, with a separate tracking entry for reblogs.
It is not invertible because doing so could (if timestamp IDs are used)
require a database query for each status in each users' feed, which is
likely to be a significant toll on major instances.
* Address review comments from @akihikodaki
No functional changes.
* Additional review changes
* Heredoc cleanup
* Run db:schema:load hooks for test in development
This matches the behavior in Rails'
ActiveRecord::Tasks::DatabaseTasks.each_current_configuration, which
would otherwise break `rake db:setup` in development.
It also moves some functionality out to a library, which will be a good
place to put additional related functionality in the near future.
Additionally, ActivityPub::FetchRemoteStatusService no longer parses
activities.
OStatus::Activity::Creation no longer delegates to ActivityPub because
the provided ActivityPub representations are not signed while OStatus
representations are.
* Return sensible HTTP status for ActivityPub inbox processing
* Return sensible HTTP status for salmon slap processing
* Return additional information to debug signature verification failures
* Fix order of paginated accounts in FollowerDomainsController
Unordered pagination could result in unexpected behavior.
* Cover Settings::FollowerDomainsController more
If the signature could not be verified and the webfinger of the account
was last retrieved longer than the cache period, try re-resolving the
account and then attempting to verify the signature again
* Fix#117 - Add ability to specify alternative text for media attachments
- POST /api/v1/media accepts `description` straight away
- PUT /api/v1/media/:id to update `description` (only for unattached ones)
- Serialized as `name` of Document object in ActivityPub
- Uploads form adjusted for better performance and description input
* Add tests
* Change undo button blend mode to difference
* Add support for selecting a theme
* Fix codeclimate issues
* Look up site default style if current user is not available due to e.g. not being logged in
* Remove outdated comment in common.js
* Address requested changes in themes PR
* Fix codeclimate issues
* Explicitly check current_account in application controller and only check theme availability if non-nil
* codeclimate
* explicit precedence with &&
* Fix code style in application_controller according to @nightpool's suggestion, use default style in embedded.html.haml
* codeclimate: indentation + return
When a new user confirms their e-mail, bootstrap their home timeline
by automatically following a set of accounts. By default, all local
admin accounts (that are unlocked). Can be customized by new admin
setting (comma-separated usernames, local and unlocked only)
* Decouple Status#local? from uri being nil
* Replace on-the-fly URI generation with stored URIs
- Generate URI in after_save hook for local statuses
- Use static value in TagManager when available, fallback to tag format
- Make TagManager use ActivityPub::TagManager to understand new format
- Adjust tests
* Use other heuristic for locality of old statuses, do not perform long query
* Exclude tombstone stream entries from Atom feed
* Prevent nil statuses from landing in Pubsubhubbub::DistributionWorker
* Fix URI not being saved (#4818)
* Add more specs for Status
* Save generated uri immediately
and also fix method order to minimize diff.
* Fix alternate HTML URL in Atom
* Fix tests
* Remove not-null constraint from statuses migration to speed it up
* Make PreviewCard records reuseable between statuses
**Warning!** Migration truncates preview_cards tablec
* Allow a wider thumbnail for link preview, display it in horizontal layout (#4648)
* Delete preview cards files before truncating
* Rename old table instead of truncating it
* Add mastodon:maintenance:remove_deprecated_preview_cards
* Ignore deprecated_preview_cards in schema definition
* Fix null behaviour
- Use statuses controller for embeds instead of stream entries controller
- Prefer /@:username/:id/embed URL for embeds
- Use /@:username as author_url in OEmbed
- Add follow link to embeds which opens web intent in new window
- Use redis cache in development
- Cache entire embed
* Allow multiple pinned statuses to be shown and make them be ordered by pinned date
* Set timestamps NOT NULL
* Make single-line pinned_statuses
* Spec for pinned_statuses
* Remove redundant empty line
* Process Create / Announce activity in FetchRemoteStatusService
* Use activity URL in ActivityPub for reblogs
* Redirect to the original status on StatusesController#show
* Add code for creating/managing apps to settings section
* Add specs for app changes
* Fix controller spec
* Fix view file I pasted over by mistake
* Add locale strings. Add 'my apps' to nav
* Add Client ID/Secret to App page. Add some visual separation
* Fix rubocop warnings
* Fix embarrassing typo
I lost an `end` statement while fixing a merge conflict.
* Add code for creating/managing apps to settings section
- Add specs for app changes
- Add locale strings. Add 'my apps' to nav
- Add Client ID/Secret to App page. Add some visual separation
- Fix some bugs/warnings
* Update to match code standards
* Trigger notification
* Add warning about not sharing API secrets
* Tweak spec a bit
* Cleanup fixture creation by using let!
* Remove unused key
* Add foreign key for application<->user
- Tries to avoid performing HTTP request if the keyId is an actor URI
- Likewise if the URI is a fragment URI on top of actor URI
- Resolves public key, returns owner if the owner links back to the key
* ActivityPub migration procedure
Once one account is detected as going from OStatus to ActivityPub,
invalidate WebFinger cache for other accounts from the same domain
* Unsubscribe from PuSH updates once we receive an ActivityPub payload
* Re-subscribe to PuSH unless already unsubscribed, regardless of protocol
* Add ActivityPub inbox
* Handle ActivityPub deletes
* Handle ActivityPub creates
* Handle ActivityPub announces
* Stubs for handling all activities that need to be handled
* Add ActivityPub actor resolving
* Handle conversation URI passing in ActivityPub
* Handle content language in ActivityPub
* Send accept header when fetching actor, handle JSON parse errors
* Test for ActivityPub::FetchRemoteAccountService
* Handle public key and icon/image when embedded/as array/as resolvable URI
* Implement ActivityPub::FetchRemoteStatusService
* Add stubs for more interactions
* Undo activities implemented
* Handle out of order activities
* Hook up ActivityPub to ResolveRemoteAccountService, handle
Update Account activities
* Add fragment IDs to all transient activity serializers
* Add tests and fixes
* Add stubs for missing tests
* Add more tests
* Add more tests
This PR adds a new notification cleaning mode, super perfectly tuned for accessibility, and removes the previous notification cleaning functionality as it's now redundant.
* w.i.p. notif clearing mode
* Better CSS for selected notification and shorter text if Stretch is off
* wip for rebase ~
* all working in notif clearing mode, except the actual removal
* bulk delete route for piggo
* cleaning + refactor. endpoint gives 422 for some reason
* formatting
* use the right route
* fix broken destroy_multiple
* load more notifs after succ cleaning
* satisfy eslint
* Removed CSS for the old notif delete button
* Tabindex=0 is mandatory
In order to make it possible to tab to this element you must have tab index = 0. Removing this violates WCAG and makes it impossible to use the interface without good eyesight and a mouse. So nobody with certain mobility impairments, vision impairments, or brain injuries would be able to use this feature if you don't have tabindex=0
* Corrected aria-label
Previous label implied a different behavior from what actually happens
* aria role localization & made the overlay behave like a checkbox
* checkboxes css and better contrast
* color tuning for the notif overlay
* fanceh checkboxes etc and nice backgrounds
* SHUT UP TRAVIS
* Do not raise unretryable exceptions in ResolveRemoteAccountService
* Removed fatal exceptions from ResolveRemoteAccountService
Exceptions that cannot be retried should not be raised. New exception
class for those that can be retried (Mastodon::UnexpectedResponseError)
* Wrap methods of ProcessFeedService::ProcessEntry in classes
This is a change same with 425acecfdb, except
that it has the following changes:
* Revert irrelevant change in find_or_create_conversation
* Fix error handling for RemoteActivity
* Introduce Ostatus name space
* Improve webfinger templates and make tests more flexible
* Clean up AS2 representation of actor
* Refactor outbox
* Create activities representation
* Add representations of followers/following collections, do not redirect /users/:username route if format is empty
* Remove unused translations
* ActivityPub endpoint for single statuses, add ActivityPub::TagManager for better
URL/URI generation
* Add ActivityPub::TagManager#to
* Represent all attachments as Document instead of Image/Video specifically
(Because for remote ones we may not know for sure)
Add mentions and hashtags representation to AP notes
* Add AP-resolvable hashtag URIs
* Use ActiveModelSerializers for ActivityPub
* Clean up unused translations
* Separate route for object and activity
* Adjust cc/to matrices
* Add to/cc to activities, ensure announce activity embeds target status and
not the wrapper status, add "id" to all collections
* Add Request class with HTTP signature generator
Spec: https://tools.ietf.org/html/draft-cavage-http-signatures-06
* Add HTTP signature verification concern
* Add test for SignatureVerification concern
* Add basic test for Request class
* Make PuSH subscribe/unsubscribe requests use new Request class
Accidentally fix lease_seconds not being set and sent properly, and
change the new minimum subscription duration to 1 day
* Make all PuSH workers use new Request class
* Make Salmon sender use new Request class
* Make FetchLinkService use new Request class
* Make FetchAtomService use the new Request class
* Make Remotable use the new Request class
* Make ResolveRemoteAccountService use the new Request class
* Add more tests
* Allow +-30 seconds window for signed request to remain valid
* Disable time window validation for signed requests, restore 7 days
as PuSH subscription duration (which was previous default due to a bug)
* Redesign the landing page, mount public timeline on it
* Adjust the standalone mounted component to the lacking of router
* Adjust auth layout pages to new design
* Fix tests
* Standalone public timeline polling every 5 seconds
* Remove now obsolete translations
* Add responsive design for new landing page
* Address reviews
* Add floating clouds behind frontpage form
* Use access token from public page when available
* Fix mentions and hashtags links, cursor on status content in standalone mode
* Add footer link to source code
* Fix errors on pages that don't embed the component, use classnames
* Fix tests
* Change anonymous autoPlayGif default to false
* When gif autoplay is disabled, hover to play
* Add option to hide the timeline preview
* Slightly improve alt layout
* Add elephant friend to new frontpage
* Display "back to mastodon" in place of "login" when logged in on frontpage
* Change polling time to 3s
* Added a success page to remote following
Includes follow-through links to web (the old redirect target) and back to the remote user's profile
* Use Account.new in spec instead of a fake with only id
(fixes spec)
* Fabricate(:account) over Account.new
* Remove self from the success text
(and all HTML with it)
* add a system_font_ui setting on the server
* Plug the system_font_ui on the front-end
* add EN/FR locales for the new setting
* put Roboto after all other fonts
* remove trailing whitespace so CodeClimate is happy
* fix user_spec.rb
* correctly write user_spect this time
* slightly better way of adding the classes
* add comments to the system-font stack for clarification
* use .system-font for the class instead
* don't use multiple lines for comments
* remove trailing whitespace
* use the classnames module for consistency
* use `mastodon-font-sans-serif` instead of Roboto directly
* Fix#3910 - Require OTP authentication to disable 2FA. Also, remove ability
to generate new OTP backup codes *after* initial backup codes were handed
out during activation
* Restore recovery code re-generation
* Improve display of some 2FA elements
* Add overview of active sessions
* Better display of browser/platform name
* Improve how browser information is stored and displayed for sessions overview
* Fix test
* Fix#2347 - Bind web UI access token to session
When you logout, session also destroys the access token, so it's no longer
valid. If access token is destroyed some other way, the session is also
destroyed, requiring a re-login.
Fix#1681 - Add scheduler to remove revoked access tokens and grants
* Fix test
* Add overview of active sessions
* Better display of browser/platform name
* Improve how browser information is stored and displayed for sessions overview
* Fix test
* Add form for account deletion
* If avatar or header are gone from source, remove them
* Add option to have SuspendAccountService remove user record, add tests
* Exclude suspended accounts from search
* Fix#2619 - When redis feed is empty, fall back to database
* Use redis value to return feed from database only while RegenerationWorker
hasn't finished running
* Fix specs
* Replace usage of reject!
When case insensitivity is enabled via devise's `config.case_insensitive_keys` then `.find_for_authentication` method needs to be used instead of `.find_by` because second mentioned returns `nil` when valid email with different cases is passed.
More info https://github.com/plataformatec/devise/wiki/How-To:-Use-case-insensitive-emails
* Improve default language decision
This change allows to takes account of accepted language determined by
the user agent even if the custom default locale of the instance is
configured.
* Cover Localized more
* Fix code style
Each of mute, favourite, reblog has been updated to:
- Have a separate controller with just a create and destroy action
- Preserve historical route names to not break the API
- Mild refactoring to break up long methods
* Add specs for api statuses routes
* Update favourited_by and reblogged_by api routes
* Move methods into new controllers
* Use load_accounts methods to simplify index actions
* Clean up load_accounts methods
* Clean up link header generation
* Check for link headers in specs
* Remove unused actions from api/v1/statuses controller
* Remove specs for moved actions
* Move ApiController to Api/BaseController
* API controllers inherit from Api::BaseController
* Add coverage for various error cases in api/base controller
* Coverage for rate limit headers
* Move rate limit headers methods to concern
* Move throttle check to condition on before_action
* Move match_data variable into method
* Move utc timestamp to separate method
* Move header setting into smaller methods
* specs cleanup
* Redirect to streaming_api_base_url
When Rails receives a request to streaming API, it most likely
means that there is another host which is configured to respond
to it. This is to redirect clients to that host if
`STREAMING_API_BASE_URL` is set as another host.
* Use the new Ruby 1.9 hash syntax