Spent quite a while looking into the best solution here and ended up going with three separate classes. Thanks to @Luceos for the PR that got this rolling (#518). My reasoning is:
- The task of routing and URL generation is independent for each section of the app. Take Flarum\Api\Users\IndexAction for example. I don't want to generate a URL to a Flarum route... I specifically want to generate a URL to an API route. So there should be a class with that specific responsibility.
- In fact, each URL generator is slightly different, because we need to add a certain prefix to the start (e.g. /api)
- This also allows us to get rid of the "flarum.api" prefix on each route's name.
- It's still DRY, because they all extend a base class.
At the same time, I could see no reason this needed to be "interfaced", so all of the classes are concrete.
Goes a long way to fixing #123 - still just a few places left remaining with hardcoded URLs.
Previously, clicking the "mark all notifications as read" button would individually mark each of the visible notifications as read. Since we now always show a badge with the number of unread notifications, we need to make sure that all notifications (not just the visible ones) can be marked as read. Otherwise it would be possible to get stuck with an unread badge there.
This commit adds a new API endpoint which marks *all* of a user's notifications as read. The JSON-API spec doesn't cover this kind of thing (updating all instances of a certain resource type), so I'm a bit unsure regarding what the endpoint should actually be. For now I've gone with POST /notifications/read, but I'm open to suggestions.
ref #500
Some providers (e.g. Twitter) don't expose user email addresses, so it
turns out we can't use that as the sole form of identification/account
matching.
This commit introduces a new `auth_tokens` table which stores arbitrary
attributes during the sign up process. For example, when Twitter is
authenticated, a new auth token containing the user's Twitter ID will
be created. When sign up is completed with this token, that Twitter ID
will be set as an attribute on the user's account.
Anti-spam extensions may automatically hide the first post in a
discussion, and thus we had to implement smarter permissions so
discussions with zero posts wouldn't be visible to users other than the
author/mods. This change allows those hidden posts to be restored again.
- Allow users to see their own posts, even if they have been hidden by
someone else
- Don't require hiding a post to be necessarily attributed to a user
- Hide discussions with zero posts, unless the user can edit posts, or
they are the discussion author
We can't do this using the ValidatesBeforeSave trait because the
password has been hashed by then. Instead, we must validate the
original password as it comes in.