Fixes#6630 (partial — deletion causing broken PAT)
If a user deletes the OAuth client that serves as the personal access
client, all PAT creation breaks for the entire instance with a 500 error.
Changes:
- Add custom OAuthClientController@destroy that checks if the client
has the personal_access grant type before allowing deletion
- Returns 403 with a clear error message if deletion is blocked
- Add confirmation dialog before client deletion in the frontend
- Add error handling to show server error messages to the user
This prevents accidental destruction of the PAT infrastructure.
Fixes#6630 (partial — PAT 500 error)
Previously, POST /oauth/personal-access-tokens would throw an unhandled
RuntimeException (HTTP 500) when:
- OAUTH_PAT_ENABLED is false (the default), or
- No personal access client exists in the database
Now the endpoint:
1. Returns 403 with a clear message if PAT is disabled in config
2. Catches RuntimeException from the token factory and returns 500
with an actionable error message instead of a stack trace
Fixes#6630 (partial — client secret issue)
In Passport v13, client secrets are hashed at the model level and only
available as plain_secret on the response from the creation endpoint.
The previous code immediately re-fetched the client list after creation,
losing the plain secret since it's not stored or returned on GET.
Changes:
- Capture plain_secret from the POST response
- Show a dedicated modal with the client ID and secret after creation
- Warn users to copy the secret immediately (it won't be shown again)
- Add a Copy button for convenience
- Show 'Hidden (only shown at creation)' in the table for existing clients
Fixes#6643
The POST /api/v1/accounts/{id}/remove_from_followers endpoint was missing
the token existence check (! $request->user()->token()). While the
tokenCan('follow') scope check was already present, the missing token
guard meant unauthenticated token-less requests could potentially bypass
the scope enforcement.
Added the standard guard pattern consistent with accountFollowById and
accountUnfollowById endpoints.
Also adds tests verifying:
- Read-only tokens are denied (403)
- Follow-scoped tokens succeed (200)
- Unauthenticated requests are denied (403)
Fixes#6657
When media uploads fail with a 422 validation error (e.g. file too large),
the error dialog now shows the actual validation message including the
filename, instead of the generic 'An unexpected error occurred.'
Example: 'DSCF0273.JPG: The file may not be greater than 15000 kilobytes'
Also improved the default error case to surface server-provided messages
when available. Applied to both ComposeModal and ComposeClassic components.
Fixes#6695
When no pagination params are provided, the default min_id was set to 1
and the query used 'id > 1', which excluded the very first follower row
(id=1) on fresh instances.
Changed default min_id from 1 to 0 and switched the direction check from
truthy evaluation to !== null, so the query becomes 'id > 0' which
correctly includes all records.
PHP 5.5.9 adds the new static `class` property which provides the fully qualified class name. This is preferred over using strings for class names since the `class` property references are checked by PHP.