mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-07-01 00:38:03 +02:00
User Email and email validation API (#10160)
* feat: wip user emails api * fix: allow admins with manage-users access to email confirmation api as well * fix: wrong route path * docs: openapi spec
This commit is contained in:
@@ -78,6 +78,12 @@ paths:
|
||||
$ref: 'write/users/uid/invites.yaml'
|
||||
/users/{uid}/invites/groups:
|
||||
$ref: 'write/users/uid/invites/groups.yaml'
|
||||
/users/{uid}/emails:
|
||||
$ref: 'write/users/uid/emails.yaml'
|
||||
/users/{uid}/emails/{email}:
|
||||
$ref: 'write/users/uid/emails/email.yaml'
|
||||
/users/{uid}/emails/{email}/confirm:
|
||||
$ref: 'write/users/uid/emails/email/confirm.yaml'
|
||||
/groups/:
|
||||
$ref: 'write/groups.yaml'
|
||||
/groups/{slug}:
|
||||
|
||||
33
public/openapi/write/users/uid/emails.yaml
Normal file
33
public/openapi/write/users/uid/emails.yaml
Normal file
@@ -0,0 +1,33 @@
|
||||
get:
|
||||
tags:
|
||||
- users
|
||||
summary: get user emails
|
||||
description: |
|
||||
This operation lists all emails associated with the user.
|
||||
This route is accessible to all users if the target user has elected to show their email publicly. Otherwise, it is only accessible to privileged users, or if the calling user is the same as the target user.
|
||||
parameters:
|
||||
- in: path
|
||||
required: true
|
||||
name: uid
|
||||
schema:
|
||||
type: number
|
||||
description: A valid user id
|
||||
example: 1
|
||||
responses:
|
||||
'200':
|
||||
description: user emails successfully listed
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
status:
|
||||
$ref: ../../../components/schemas/Status.yaml#/Status
|
||||
response:
|
||||
type: object
|
||||
properties:
|
||||
emails:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: An email address
|
||||
25
public/openapi/write/users/uid/emails/email.yaml
Normal file
25
public/openapi/write/users/uid/emails/email.yaml
Normal file
@@ -0,0 +1,25 @@
|
||||
get:
|
||||
tags:
|
||||
- users
|
||||
summary: get user's email data
|
||||
description: |
|
||||
This operation lists the data associated with a single email.
|
||||
This route is accessible to all users if the target user has elected to show their email publicly. Otherwise, it is only accessible to privileged users, or if the calling user is the same as the target user.
|
||||
parameters:
|
||||
- in: path
|
||||
required: true
|
||||
name: uid
|
||||
schema:
|
||||
type: number
|
||||
description: A valid user id
|
||||
example: 1
|
||||
- in: path
|
||||
required: true
|
||||
name: email
|
||||
schema:
|
||||
type: string
|
||||
description: A valid email address
|
||||
example: test@example.org
|
||||
responses:
|
||||
'204':
|
||||
description: user's email data successfully retrieved
|
||||
34
public/openapi/write/users/uid/emails/email/confirm.yaml
Normal file
34
public/openapi/write/users/uid/emails/email/confirm.yaml
Normal file
@@ -0,0 +1,34 @@
|
||||
post:
|
||||
tags:
|
||||
- users
|
||||
summary: validate a user's email address
|
||||
description: |
|
||||
Marks the passed-in user's email as confirmed.
|
||||
This route is only accessible to administrators with the `admin:users` privilege (or superadmins)
|
||||
parameters:
|
||||
- in: path
|
||||
required: true
|
||||
name: uid
|
||||
schema:
|
||||
type: number
|
||||
description: A valid user id
|
||||
example: 1
|
||||
- in: path
|
||||
required: true
|
||||
name: email
|
||||
schema:
|
||||
type: string
|
||||
description: A valid email address
|
||||
example: test@example.org
|
||||
responses:
|
||||
'200':
|
||||
description: successfully confirmed a user email
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
status:
|
||||
$ref: ../../../../../components/schemas/Status.yaml#/Status
|
||||
response:
|
||||
type: object
|
||||
@@ -233,3 +233,51 @@ Users.getInviteGroups = async function (req, res) {
|
||||
const userInviteGroups = await groups.getUserInviteGroups(req.params.uid);
|
||||
return helpers.formatApiResponse(200, res, userInviteGroups);
|
||||
};
|
||||
|
||||
Users.listEmails = async (req, res) => {
|
||||
const [isPrivileged, { showemail }] = await Promise.all([
|
||||
user.isPrivileged(req.uid),
|
||||
user.getSettings(req.params.uid),
|
||||
]);
|
||||
const isSelf = req.uid === parseInt(req.params.uid, 10);
|
||||
|
||||
if (isSelf || isPrivileged || showemail) {
|
||||
const emails = await db.getSortedSetRangeByScore('email:uid', 0, 500, req.params.uid, req.params.uid);
|
||||
helpers.formatApiResponse(200, res, { emails });
|
||||
} else {
|
||||
helpers.formatApiResponse(204, res);
|
||||
}
|
||||
};
|
||||
|
||||
Users.getEmail = async (req, res) => {
|
||||
const [isPrivileged, { showemail }, exists] = await Promise.all([
|
||||
user.isPrivileged(req.uid),
|
||||
user.getSettings(req.params.uid),
|
||||
db.isSortedSetMember('email:uid', req.params.email.toLowerCase()),
|
||||
]);
|
||||
const isSelf = req.uid === parseInt(req.params.uid, 10);
|
||||
|
||||
if (exists && (isSelf || isPrivileged || showemail)) {
|
||||
helpers.formatApiResponse(204, res);
|
||||
} else {
|
||||
helpers.formatApiResponse(404, res);
|
||||
}
|
||||
};
|
||||
|
||||
Users.confirmEmail = async (req, res) => {
|
||||
const [exists, canManage] = await Promise.all([
|
||||
db.isSortedSetMember('email:uid', req.params.email.toLowerCase()),
|
||||
privileges.admin.can('admin:users', req.uid),
|
||||
]);
|
||||
|
||||
if (!canManage) {
|
||||
helpers.notAllowed(req, res);
|
||||
}
|
||||
|
||||
if (exists) {
|
||||
await user.email.confirmByUid(req.params.uid);
|
||||
helpers.formatApiResponse(200, res);
|
||||
} else {
|
||||
helpers.formatApiResponse(404, res);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -44,6 +44,10 @@ function authenticatedRoutes() {
|
||||
setupApiRoute(router, 'post', '/:uid/invites', middlewares, controllers.write.users.invite);
|
||||
setupApiRoute(router, 'get', '/:uid/invites/groups', [...middlewares, middleware.assert.user], controllers.write.users.getInviteGroups);
|
||||
|
||||
setupApiRoute(router, 'get', '/:uid/emails', [...middlewares, middleware.assert.user], controllers.write.users.listEmails);
|
||||
setupApiRoute(router, 'get', '/:uid/emails/:email', [...middlewares, middleware.assert.user], controllers.write.users.getEmail);
|
||||
setupApiRoute(router, 'post', '/:uid/emails/:email/confirm', [...middlewares, middleware.assert.user], controllers.write.users.confirmEmail);
|
||||
|
||||
// Shorthand route to access user routes by userslug
|
||||
router.all('/+bySlug/:userslug*?', [], controllers.write.users.redirectBySlug);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user