[feature] Admin accounts endpoints; approve/reject sign-ups (#2826)

* update settings panels, add pending overview + approve/deny functions

* add admin accounts get, approve, reject

* send approved/rejected emails

* use signup URL

* docs!

* email

* swagger

* web linting

* fix email tests

* wee lil fixerinos

* use new paging logic for GetAccounts() series of admin endpoints, small changes to query building

* shuffle useAccountIDIn check *before* adding to query

* fix parse from toot react error

* use `netip.Addr`

* put valid slices in globals

* optimistic updates for account state

---------

Co-authored-by: kim <grufwub@gmail.com>
This commit is contained in:
tobi
2024-04-13 13:25:10 +02:00
committed by GitHub
parent 1439042104
commit 89e0cfd874
74 changed files with 4102 additions and 545 deletions

59
docs/admin/signups.md Normal file
View File

@ -0,0 +1,59 @@
# New Account Sign-Ups
If you want to allow more people than just you to have an account on your instance, you can open your instance to new account sign-ups / registrations.
Be wary that as instance admin, like it or not, you are responsible for what people post on your instance. If users on your instance harass or annoy other people on the fediverse, you may find your instance gets a bad reputation and becomes blocked by others. Moderating a space properly takes work. As such, you should carefully consider whether or not you are willing and able to do moderation, and consider accepting sign-ups on your instance only from friends and people that you really trust.
!!! warning
For the sign-up flow to work as intended, your instance [should be configured to send emails](../configuration/smtp.md).
As mentioned below, several emails are sent during the sign-up flow, both to you (as admin/moderator) and to the applicant, including an email asking them to confirm their email address.
If they cannot receive this email (because your instance is not configured to send emails), you will have to manually confirm the account by [using the CLI tool](../admin/cli.md#gotosocial-admin-account-confirm).
## Opening Sign-Ups
You can open new account sign-ups for your instance by changing the variable `accounts-registration-open` to `true` in your [configuration](../configuration/accounts.md), and restarting your GoToSocial instance.
A sign-up form for your instance will be available at the `/signup` endpoint. For example, `https://your-instance.example.org/signup`.
![Sign-up form, showing email, password, username, and reason fields.](../assets/signup-form.png)
Also, your instance homepage and "about" pages will be updated to reflect that registrations are open.
When someone submits a new sign-up, they'll receive an email at the provided email address, giving them a link to confirm that the address really belongs to them.
In the meantime, admins and moderators on your instance will receive an email and a notification that a new sign-up has been submitted.
## Handling Sign-Ups
Instance admins and moderators can handle a new sign-up by either approving or rejecting it via the "accounts" -> "pending" section in the admin panel.
![Admin settings panel open to "accounts" -> "pending", showing one account in a list.](../assets/signup-pending.png)
If you have no sign-ups, the list pictured above will be empty. If you have a pending account sign-up, however, you can click on it to open that account in the account details screen:
![Details of a new pending account, giving options to approve or reject the sign-up.](../assets/signup-account.png)
At the bottom, you will find actions that let you approve or reject the sign-up.
If you **approve** the sign-up, the account will be marked as "approved", and an email will be sent to the applicant informing them their sign-up has been approved, and reminding them to confirm their email address if they haven't already done so. If they have already confirmed their email address, they will be able to log in and start using their account.
If you **reject** the sign-up, you may wish to inform the applicant that their sign-up has been rejected, which you can do by ticking the "send email" checkbox. This will send a short email to the applicant informing them of the rejection. If you wish, you can add a custom message, which will be added at the bottom of the email. You can also add a private note that will be visible to other admins only.
!!! warning
You may want to hold off on approving a sign-up until they have confirmed their email address, in case the applicant made a typo when submitting, or the email address they provided does not actually belong to them. If they cannot confirm their email address, they will not be able to log in and use their account.
## Sign-Up Limits
To avoid sign-up backlogs overwhelming admins and moderators, GoToSocial limits the sign-up pending backlog to 20 accounts. Once there are 20 accounts pending in the backlog waiting to be handled by an admin or moderator, new sign-ups will not be accepted via the form.
New sign-ups will also not be accepted via the form if 10 or more new account sign-ups have been approved in the last 24 hours, to avoid instances rapidly expanding beyond the capabilities of moderators.
In both cases, applicants will be shown an error message explaining why they could not submit the form, and inviting them to try again later.
To combat spam accounts, GoToSocial account sign-ups **always** require manual approval by an administrator, and applicants must **always** confirm their email address before they are able to log in and post.
## Sign-Up Via Invite
NOT IMPLEMENTED YET: in a future update, admins and moderators will be able to create and send invites that allow accounts to be created even when public sign-up is closed, and to pre-approve accounts created via invitation, and/or allow them to override the sign-up limits described above.

View File

@ -3680,6 +3680,166 @@ paths:
summary: Verify a token by returning account details pertaining to it.
tags:
- accounts
/api/v1/admin/accounts:
get:
description: |-
The next and previous queries can be parsed from the returned Link header.
Example:
```
<https://example.org/api/v1/admin/accounts?limit=80&max_id=01FC0SKA48HNSVR6YKZCQGS2V8>; rel="next", <https://example.org/api/v1/admin/accounts?limit=80&min_id=01FC0SKW5JK2Q4EVAV2B462YY0>; rel="prev"
````
operationId: adminAccountsGetV1
parameters:
- default: false
description: Filter for local accounts.
in: query
name: local
type: boolean
- default: false
description: Filter for remote accounts.
in: query
name: remote
type: boolean
- default: false
description: Filter for currently active accounts.
in: query
name: active
type: boolean
- default: false
description: Filter for currently pending accounts.
in: query
name: pending
type: boolean
- default: false
description: Filter for currently disabled accounts.
in: query
name: disabled
type: boolean
- default: false
description: Filter for currently silenced accounts.
in: query
name: silenced
type: boolean
- default: false
description: Filter for currently suspended accounts.
in: query
name: suspended
type: boolean
- default: false
description: Filter for accounts force-marked as sensitive.
in: query
name: sensitized
type: boolean
- description: Search for the given username.
in: query
name: username
type: string
- description: Search for the given display name.
in: query
name: display_name
type: string
- description: Filter by the given domain.
in: query
name: by_domain
type: string
- description: Lookup a user with this email.
in: query
name: email
type: string
- description: Lookup users with this IP address.
in: query
name: ip
type: string
- default: false
description: Filter for staff accounts.
in: query
name: staff
type: boolean
- description: All results returned will be older than the item with this ID.
in: query
name: max_id
type: string
- description: All results returned will be newer than the item with this ID.
in: query
name: since_id
type: string
- description: Returns results immediately newer than the item with this ID.
in: query
name: min_id
type: string
- default: 100
description: Maximum number of results to return.
in: query
maximum: 200
minimum: 1
name: limit
type: integer
produces:
- application/json
responses:
"200":
description: ""
headers:
Link:
description: Links to the next and previous queries.
type: string
schema:
items:
$ref: '#/definitions/adminAccountInfo'
type: array
"400":
description: bad request
"401":
description: unauthorized
"403":
description: forbidden
"404":
description: not found
"406":
description: not acceptable
"500":
description: internal server error
security:
- OAuth2 Bearer:
- admin
summary: View + page through known accounts according to given filters.
tags:
- admin
/api/v1/admin/accounts/{id}:
get:
operationId: adminAccountGet
parameters:
- description: ID of the account.
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/adminAccountInfo'
"400":
description: bad request
"401":
description: unauthorized
"403":
description: forbidden
"404":
description: not found
"406":
description: not acceptable
"500":
description: internal server error
security:
- OAuth2 Bearer:
- admin
summary: View one account.
tags:
- admin
/api/v1/admin/accounts/{id}/action:
post:
consumes:
@ -3725,6 +3885,86 @@ paths:
summary: Perform an admin action on an account.
tags:
- admin
/api/v1/admin/accounts/{id}/approve:
post:
operationId: adminAccountApprove
parameters:
- description: ID of the account.
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: The now-approved account.
schema:
$ref: '#/definitions/adminAccountInfo'
"400":
description: bad request
"401":
description: unauthorized
"403":
description: forbidden
"404":
description: not found
"406":
description: not acceptable
"500":
description: internal server error
security:
- OAuth2 Bearer:
- admin
summary: Approve pending account.
tags:
- admin
/api/v1/admin/accounts/{id}/reject:
post:
operationId: adminAccountReject
parameters:
- description: ID of the account.
in: path
name: id
required: true
type: string
- description: Comment to leave on why the account was denied. The comment will be visible to admins only.
in: formData
name: private_comment
type: string
- description: Message to include in email to applicant. Will be included only if send_email is true.
in: formData
name: message
type: string
- description: Send an email to the applicant informing them that their sign-up has been rejected.
in: formData
name: send_email
type: boolean
produces:
- application/json
responses:
"200":
description: The now-rejected account.
schema:
$ref: '#/definitions/adminAccountInfo'
"400":
description: bad request
"401":
description: unauthorized
"403":
description: forbidden
"404":
description: not found
"406":
description: not acceptable
"500":
description: internal server error
security:
- OAuth2 Bearer:
- admin
summary: Reject pending account.
tags:
- admin
/api/v1/admin/custom_emojis:
get:
description: |-
@ -7934,6 +8174,109 @@ paths:
summary: Change the password of authenticated user.
tags:
- user
/api/v2/admin/accounts:
get:
description: |-
The next and previous queries can be parsed from the returned Link header.
Example:
```
<https://example.org/api/v2/admin/accounts?limit=80&max_id=01FC0SKA48HNSVR6YKZCQGS2V8>; rel="next", <https://example.org/api/v2/admin/accounts?limit=80&min_id=01FC0SKW5JK2Q4EVAV2B462YY0>; rel="prev"
````
operationId: adminAccountsGetV2
parameters:
- description: Filter for `local` or `remote` accounts.
in: query
name: origin
type: string
- description: Filter for `active`, `pending`, `disabled`, `silenced`, or `suspended` accounts.
in: query
name: status
type: string
- description: Filter for accounts with staff permissions (users that can manage reports).
in: query
name: permissions
type: string
- description: Filter for users with these roles.
in: query
items:
type: string
name: role_ids[]
type: array
- description: Lookup users invited by the account with this ID.
in: query
name: invited_by
type: string
- description: Search for the given username.
in: query
name: username
type: string
- description: Search for the given display name.
in: query
name: display_name
type: string
- description: Filter by the given domain.
in: query
name: by_domain
type: string
- description: Lookup a user with this email.
in: query
name: email
type: string
- description: Lookup users with this IP address.
in: query
name: ip
type: string
- description: All results returned will be older than the item with this ID.
in: query
name: max_id
type: string
- description: All results returned will be newer than the item with this ID.
in: query
name: since_id
type: string
- description: Returns results immediately newer than the item with this ID.
in: query
name: min_id
type: string
- default: 100
description: Maximum number of results to return.
in: query
maximum: 200
minimum: 1
name: limit
type: integer
produces:
- application/json
responses:
"200":
description: ""
headers:
Link:
description: Links to the next and previous queries.
type: string
schema:
items:
$ref: '#/definitions/adminAccountInfo'
type: array
"400":
description: bad request
"401":
description: unauthorized
"403":
description: forbidden
"404":
description: not found
"406":
description: not acceptable
"500":
description: internal server error
security:
- OAuth2 Bearer:
- admin
summary: View + page through known accounts according to given filters.
tags:
- admin
/api/v2/instance:
get:
operationId: instanceGetV2

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

BIN
docs/assets/signup-form.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB