Fix an invalid SQL exception that occurs when the paginator tries to
do a COUNT(*) to calculate the page count of a relation that already
includes a GROUP BY + COUNT(*) clause. We need to nest the whole query
inside a `SELECT COUNT(*) FROM (...)` subquery so the inner COUNT(*)
doesn't mess up the outer COUNT(*).
Fixes#4285.
Calling next_page here raises an exception when calculating the page
count because it can't handle SQL containing a GROUP BY clause. Swallow
the exception as a temp fix.
Fix a couple security issues related to dmail permalinks. Dmails have a
permalink that you can give to a Mod to let them read the dmail. This is
done with a key param that grants access when the dmail is opened by
another user. The key param had several problems:
* The key contained a full copy of the message's title and body encoded in
base64. This meant that anyone given a dmail permalink could read the
full dmail just by decoding the key in the link, without even having
to open the link.
* The key was derived from the dmail's title and body. If you knew or
could guess a dmail's title and body you could open the dmail. One
case when this was possible was when sending dmails. You could send
someone a dmail, take the permalink from your sent copy of the dmail,
then increment the dmail id to open the receiver's copy of the dmail.
Since the sent copy and the received copy both had the same title and
body, they both had the same dmail key. This let you check whether a
person had read your dmail, and what time they read it at.
* The key verification was done with an insecure string comparison
rather than a secure constant-time comparison. This was potentially
vulnerable to timing attacks.
* Opening a dmail belonging to another user would mark it as read for them.
The fix to all this is to use the dmail's id as the key instead of the
dmail's title and body. This means that old permalinks no longer work.
This is unavoidable given the issues above.
Other changes:
* The name of the 'Permalink' link is now 'Share'.
* Anyone with the 'Share' link can view the dmail, not just Mods.
* Add ability to mark dmails as unread.
* Fix users.unread_dmail_count to not count deleted dmails.
* Fix show action so that API calls don't mark dmails as read.
* Don't show the unread dmail notice on the /dmails page itself.
* Stop using users.has_mail flag.
* Add unread and deleted dmail folders.
* Remove dmail_folder cookie (wasn't used).
* Default to the received folder so that we don't show sent messages by default.
Turn deletions into soft deletions (set the is_deleted flag) instead of
hard deletions (remove from database). The is_deleted flag actually
already existed, but it was never used before.
Add <link rel="prev"> and <link rel="next"> elements to most pages with
pagination. This should work on all index pages, but it won't work for
things like pool or forum topic show pages.
Also remove the <link rel="top"> element (wasn't useful, was just a link
back to the root url).
Allow all users to view and edit artist entries and wiki pages belonging
to banned artists. There was little need to hide these pages from
Members, it was mainly to appease artists who didn't like us even
linking to their sites.
These restrictions also had multiple flaws:
* Banned artist information was still visible in the API.
* It was still possible to edit banned artists using the API.
* It was still possible for unprivileged users to revert banned
artist entries or wiki pages to previous versions.
* The restrictions were inconsistent: in various places they were
either Member-only, Gold-only, or Builder-only.
Also remove options to configure names of wiki notice pages. These names
generally don't need to be changed and we already hardcode links to wiki
pages in other places anyway.
* Add ability to report dmails.
* Enable reports for comments, forum posts, and dmails.
* Allow Members to send reports.
* Don't allow users to report the same thing twice.
* Fix og:site to og:site_name.
* Fix open graph properties to use <meta property="...">, not <meta name="...">>
* Set og:type, og:site_name, twitter:site globally (not just on post pages).
* Set og:url.
* Remove unused always-resize-images, report-server <meta> tags from
post show pages.
Change the title of the post index page to look like this:
"Danbooru: Anime Image Board" (for the front page)
"Kantai Collection Art | Danbooru" (for a tag search)
Change the meta description of the front page to look like this:
Danbooru is the original anime image 'booru. Find over 3.75 million
anime pictures categorized by over 100 million tags.
Change the meta description for a tag search to look like this:
Find over 37,168 Azur Lane images on Danbooru. Azur Lane (碧蓝航线)
(벽람항로) is a Chinese shipgirl-themed side-scrolling shoot 'em up
mobile game developed by Shanghai Manjuu and Xiamen Yongshi...
Avoid doing one SQL query per topic when checking for new topics on the
forum index.
This also changes it so that forum topics aren't always marked as new
for anonymous users.
* Rarely used (only used ~15 times in total, not used at all since 2015-2016).
* Merging topics didn't properly bump the new topic.
* Merging topics didn't log a modaction when the old topic was deleted.
* Merging topics broke the old topic. Moving all the posts from one topic
to another leaves the old topic with zero posts. This normally can't
happen and it causes exceptions when you try to view the empty topic.
* It was technically possible to merge a topic with itself. This would
break the response_count.
* It was technically possible for a mod to merge a topic into an
admin-only topic.
Few people used forum subscriptions (only around 100), and even fewer
people were subscribed to active threads. Most subscriptions were for
old threads that will never be bumped again. The implementation also had
a few problems:
* Unsubscribe links in emails didn't work (they unset the user's
receive_email_notifications flag, but forum subscriptions didn't
respect this flag).
* Some users had invalid email addresses, which caused notifications to
bounce. There was no mechanism for preventing bounces.
* The implementation wasn't scalable. It involved a daily linear scan
over _all_ forum subscriptions looking for any topics that had been updated.
Few people used dmail filters (~900 users in 5 years) and even fewer
used them correctly. Most people used them to try to block dmail spam,
but usually they either blocked too much (by adding common words that
are present in nearly all dmails, causing all mails to them to be
filtered) or too little (blocking specific email addresses or urls,
which usually are never seen again after the spammer is banned).
Nowadays the spam detection system does a better job of filtering spam.
The use of any? and count was forcing new SQL requests for each statement.
Instead, present? and length were used which act on the reports once loaded.
Although unneeded, the comment and forum views were changed as well for consistency.
- Posts and topics have an added moderation_reports function
-- This is so all moderation reports can be loaded in a single query
- Those moderation reports are passed into the render functions separately
-- This is so the individual comments/posts don't have to be queried