mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
feat: openapi schema for user admin (#4146)
This commit is contained in:
parent
5dc560f911
commit
79b34121a4
@ -16,7 +16,7 @@ class BadDataError extends UnleashError {
|
||||
errors?: [ValidationErrorDescription, ...ValidationErrorDescription[]],
|
||||
) {
|
||||
const topLevelMessage =
|
||||
'Request validation failed: your request body contains invalid data' +
|
||||
'Request validation failed: your request body or params contain invalid data' +
|
||||
(errors
|
||||
? '. Refer to the `details` list for more information.'
|
||||
: `: ${message}`);
|
||||
|
@ -133,6 +133,7 @@ import {
|
||||
userSchema,
|
||||
usersGroupsBaseSchema,
|
||||
usersSchema,
|
||||
createUserResponseSchema,
|
||||
usersSearchSchema,
|
||||
validatedEdgeTokensSchema,
|
||||
validatePasswordSchema,
|
||||
@ -327,6 +328,7 @@ export const schemas: UnleashSchemas = {
|
||||
createStrategySchema,
|
||||
updateStrategySchema,
|
||||
userSchema,
|
||||
createUserResponseSchema,
|
||||
usersGroupsBaseSchema,
|
||||
usersSchema,
|
||||
usersSearchSchema,
|
||||
|
@ -96,7 +96,6 @@ const metaRules: Rule[] = [
|
||||
'createApiTokenSchema',
|
||||
'createFeatureSchema',
|
||||
'createInvitedUserSchema',
|
||||
'createUserSchema',
|
||||
'environmentsSchema',
|
||||
'environmentsProjectSchema',
|
||||
'eventSchema',
|
||||
@ -113,11 +112,9 @@ const metaRules: Rule[] = [
|
||||
'groupSchema',
|
||||
'groupsSchema',
|
||||
'groupUserModelSchema',
|
||||
'idSchema',
|
||||
'maintenanceSchema',
|
||||
'toggleMaintenanceSchema',
|
||||
'meSchema',
|
||||
'passwordSchema',
|
||||
'patchSchema',
|
||||
'permissionSchema',
|
||||
'profileSchema',
|
||||
@ -143,11 +140,9 @@ const metaRules: Rule[] = [
|
||||
'updateFeatureSchema',
|
||||
'updateFeatureStrategySchema',
|
||||
'updateTagTypeSchema',
|
||||
'updateUserSchema',
|
||||
'upsertContextFieldSchema',
|
||||
'upsertStrategySchema',
|
||||
'usersGroupsBaseSchema',
|
||||
'usersSchema',
|
||||
'validateEdgeTokensSchema',
|
||||
'validateTagTypeSchema',
|
||||
'variantFlagSchema',
|
||||
@ -175,7 +170,6 @@ const metaRules: Rule[] = [
|
||||
'createFeatureSchema',
|
||||
'createFeatureStrategySchema',
|
||||
'createInvitedUserSchema',
|
||||
'createUserSchema',
|
||||
'dateSchema',
|
||||
'environmentsSchema',
|
||||
'eventSchema',
|
||||
@ -191,12 +185,10 @@ const metaRules: Rule[] = [
|
||||
'groupSchema',
|
||||
'groupsSchema',
|
||||
'groupUserModelSchema',
|
||||
'idSchema',
|
||||
'maintenanceSchema',
|
||||
'toggleMaintenanceSchema',
|
||||
'meSchema',
|
||||
'parametersSchema',
|
||||
'passwordSchema',
|
||||
'patchesSchema',
|
||||
'patchSchema',
|
||||
'permissionSchema',
|
||||
@ -223,11 +215,9 @@ const metaRules: Rule[] = [
|
||||
'updateFeatureSchema',
|
||||
'updateFeatureStrategySchema',
|
||||
'updateTagTypeSchema',
|
||||
'updateUserSchema',
|
||||
'upsertContextFieldSchema',
|
||||
'upsertStrategySchema',
|
||||
'usersGroupsBaseSchema',
|
||||
'usersSchema',
|
||||
'usersSearchSchema',
|
||||
'validateEdgeTokensSchema',
|
||||
'validateTagTypeSchema',
|
||||
|
34
src/lib/openapi/spec/create-user-response-schema.ts
Normal file
34
src/lib/openapi/spec/create-user-response-schema.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { FromSchema } from 'json-schema-to-ts';
|
||||
import { userSchema } from './user-schema';
|
||||
|
||||
export const createUserResponseSchema = {
|
||||
$id: '#/components/schemas/createUserResponseSchema',
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
description: 'An Unleash user after creation',
|
||||
required: ['id'],
|
||||
properties: {
|
||||
...userSchema.properties,
|
||||
rootRole: {
|
||||
description:
|
||||
'Which [root role](https://docs.getunleash.io/reference/rbac#standard-roles) this user is assigned. Usually a numeric role ID, but can be a string when returning newly created user with an explicit string role.',
|
||||
oneOf: [
|
||||
{
|
||||
type: 'integer',
|
||||
example: 1,
|
||||
minimum: 0,
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
example: 'Admin',
|
||||
enum: ['Admin', 'Editor', 'Viewer', 'Owner', 'Member'],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
components: {},
|
||||
} as const;
|
||||
|
||||
export type CreateUserResponseSchema = FromSchema<
|
||||
typeof createUserResponseSchema
|
||||
>;
|
@ -5,24 +5,52 @@ export const createUserSchema = {
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
required: ['rootRole'],
|
||||
description:
|
||||
'The payload must contain at least one of the name and email properties, though which one is up to you. For the user to be able to log in to the system, the user must have an email.',
|
||||
properties: {
|
||||
username: {
|
||||
description:
|
||||
"The user's username. Must be provided if email is not provided.",
|
||||
type: 'string',
|
||||
example: 'hunter',
|
||||
},
|
||||
email: {
|
||||
description:
|
||||
"The user's email address. Must be provided if username is not provided.",
|
||||
type: 'string',
|
||||
example: 'user@example.com',
|
||||
},
|
||||
name: {
|
||||
description: "The user's name (not the user's username).",
|
||||
type: 'string',
|
||||
example: 'Sam Seawright',
|
||||
},
|
||||
password: {
|
||||
type: 'string',
|
||||
example: 'k!5As3HquUrQ',
|
||||
description: 'Password for the user',
|
||||
},
|
||||
rootRole: {
|
||||
type: 'number',
|
||||
description:
|
||||
"The role to assign to the user. Can be either the role's ID or its unique name.",
|
||||
oneOf: [
|
||||
{
|
||||
type: 'integer',
|
||||
example: 1,
|
||||
minimum: 0,
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
example: 'Admin',
|
||||
enum: ['Admin', 'Editor', 'Viewer', 'Owner', 'Member'],
|
||||
},
|
||||
],
|
||||
},
|
||||
sendEmail: {
|
||||
type: 'boolean',
|
||||
example: false,
|
||||
description:
|
||||
'Whether to send a welcome email with a login link to the user or not. Defaults to `true`.',
|
||||
},
|
||||
},
|
||||
components: {},
|
||||
|
@ -4,10 +4,13 @@ export const idSchema = {
|
||||
$id: '#/components/schemas/idSchema',
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
description: 'Email id used for password reset',
|
||||
required: ['id'],
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
description: 'User email',
|
||||
example: 'user@example.com',
|
||||
},
|
||||
},
|
||||
components: {},
|
||||
|
@ -8,6 +8,7 @@ export * from './pats-schema';
|
||||
export * from './role-schema';
|
||||
export * from './tags-schema';
|
||||
export * from './user-schema';
|
||||
export * from './create-user-response-schema';
|
||||
export * from './addon-schema';
|
||||
export * from './addon-create-update-schema';
|
||||
export * from './email-schema';
|
||||
|
@ -5,15 +5,24 @@ export const passwordSchema = {
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
required: ['password'],
|
||||
description: 'Fields used to create new password or update old password',
|
||||
properties: {
|
||||
password: {
|
||||
type: 'string',
|
||||
example: 'k!5As3HquUrQ',
|
||||
description: 'The new password to change or validate.',
|
||||
},
|
||||
oldPassword: {
|
||||
type: 'string',
|
||||
example: 'Oldk!5As3HquUrQ',
|
||||
description:
|
||||
'The old password the user is changing. This field is for the non-admin users changing their own password.',
|
||||
},
|
||||
confirmPassword: {
|
||||
type: 'string',
|
||||
example: 'k!5As3HquUrQ',
|
||||
description:
|
||||
'The confirmation of the new password. This field is for the non-admin users changing their own password.',
|
||||
},
|
||||
},
|
||||
components: {},
|
||||
|
@ -4,15 +4,34 @@ export const updateUserSchema = {
|
||||
$id: '#/components/schemas/updateUserSchema',
|
||||
type: 'object',
|
||||
additionalProperties: true,
|
||||
description: 'All fields that can be directly changed for the user',
|
||||
properties: {
|
||||
email: {
|
||||
description:
|
||||
"The user's email address. Must be provided if username is not provided.",
|
||||
type: 'string',
|
||||
example: 'user@example.com',
|
||||
},
|
||||
name: {
|
||||
description: "The user's name (not the user's username).",
|
||||
type: 'string',
|
||||
example: 'Sam Seawright',
|
||||
},
|
||||
rootRole: {
|
||||
type: 'number',
|
||||
description:
|
||||
"The role to assign to the user. Can be either the role's ID or its unique name.",
|
||||
oneOf: [
|
||||
{
|
||||
type: 'integer',
|
||||
example: 1,
|
||||
minimum: 0,
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
example: 'Admin',
|
||||
enum: ['Admin', 'Editor', 'Viewer', 'Owner', 'Member'],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
components: {},
|
||||
|
@ -84,6 +84,13 @@ export const userSchema = {
|
||||
enum: AccountTypes,
|
||||
example: 'User',
|
||||
},
|
||||
permissions: {
|
||||
description: 'Deprecated',
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
components: {},
|
||||
} as const;
|
||||
|
@ -6,16 +6,20 @@ export const usersSchema = {
|
||||
$id: '#/components/schemas/usersSchema',
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
description: 'Users and root roles',
|
||||
required: ['users'],
|
||||
properties: {
|
||||
users: {
|
||||
type: 'array',
|
||||
description: 'A list of users in the Unleash instance.',
|
||||
items: {
|
||||
$ref: '#/components/schemas/userSchema',
|
||||
},
|
||||
},
|
||||
rootRoles: {
|
||||
type: 'array',
|
||||
description:
|
||||
'A list of [root roles](https://docs.getunleash.io/reference/rbac#standard-roles) in the Unleash instance.',
|
||||
items: {
|
||||
$ref: '#/components/schemas/roleSchema',
|
||||
},
|
||||
|
@ -5,7 +5,7 @@ import UserService from '../../services/user-service';
|
||||
import { AccountService } from '../../services/account-service';
|
||||
import { AccessService } from '../../services/access-service';
|
||||
import { Logger } from '../../logger';
|
||||
import { IUnleashConfig, IUnleashServices } from '../../types';
|
||||
import { IUnleashConfig, IUnleashServices, RoleName } from '../../types';
|
||||
import { EmailService } from '../../services/email-service';
|
||||
import ResetTokenService from '../../services/reset-token-service';
|
||||
import { IAuthRequest } from '../unleash-types';
|
||||
@ -15,7 +15,10 @@ import { simpleAuthSettingsKey } from '../../types/settings/simple-auth-settings
|
||||
import { anonymise } from '../../util/anonymise';
|
||||
import { OpenApiService } from '../../services/openapi-service';
|
||||
import { createRequestSchema } from '../../openapi/util/create-request-schema';
|
||||
import { createResponseSchema } from '../../openapi/util/create-response-schema';
|
||||
import {
|
||||
createResponseSchema,
|
||||
resourceCreatedResponseSchema,
|
||||
} from '../../openapi/util/create-response-schema';
|
||||
import { userSchema, UserSchema } from '../../openapi/spec/user-schema';
|
||||
import { serializeDates } from '../../types/serialize-dates';
|
||||
import { usersSchema, UsersSchema } from '../../openapi/spec/users-schema';
|
||||
@ -31,7 +34,10 @@ import {
|
||||
resetPasswordSchema,
|
||||
ResetPasswordSchema,
|
||||
} from '../../openapi/spec/reset-password-schema';
|
||||
import { emptyResponse } from '../../openapi/util/standard-responses';
|
||||
import {
|
||||
emptyResponse,
|
||||
getStandardResponses,
|
||||
} from '../../openapi/util/standard-responses';
|
||||
import { GroupService } from '../../services/group-service';
|
||||
import {
|
||||
UsersGroupsBaseSchema,
|
||||
@ -45,6 +51,11 @@ import {
|
||||
AdminCountSchema,
|
||||
adminCountSchema,
|
||||
} from '../../openapi/spec/admin-count-schema';
|
||||
import { BadDataError } from '../../error';
|
||||
import {
|
||||
createUserResponseSchema,
|
||||
CreateUserResponseSchema,
|
||||
} from '../../openapi/spec/create-user-response-schema';
|
||||
|
||||
export default class UserAdminController extends Controller {
|
||||
private flagResolver: IFlagResolver;
|
||||
@ -114,8 +125,14 @@ export default class UserAdminController extends Controller {
|
||||
openApiService.validPath({
|
||||
tags: ['Users'],
|
||||
operationId: 'validateUserPassword',
|
||||
summary: 'Validate password for a user',
|
||||
description:
|
||||
'Validate the password strength. Minimum 10 characters, uppercase letter, number, special character.',
|
||||
requestBody: createRequestSchema('passwordSchema'),
|
||||
responses: { 200: emptyResponse },
|
||||
responses: {
|
||||
200: emptyResponse,
|
||||
...getStandardResponses(400, 401, 415),
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
@ -129,8 +146,13 @@ export default class UserAdminController extends Controller {
|
||||
openApiService.validPath({
|
||||
tags: ['Users'],
|
||||
operationId: 'changeUserPassword',
|
||||
summary: 'Change password for a user',
|
||||
description: 'Change password for a user as an admin',
|
||||
requestBody: createRequestSchema('passwordSchema'),
|
||||
responses: { 200: emptyResponse },
|
||||
responses: {
|
||||
200: emptyResponse,
|
||||
...getStandardResponses(400, 401, 403),
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
@ -144,9 +166,12 @@ export default class UserAdminController extends Controller {
|
||||
openApiService.validPath({
|
||||
tags: ['Users'],
|
||||
operationId: 'resetUserPassword',
|
||||
summary: 'Reset user password',
|
||||
description: 'Reset user password as an admin',
|
||||
requestBody: createRequestSchema('idSchema'),
|
||||
responses: {
|
||||
200: createResponseSchema('resetPasswordSchema'),
|
||||
...getStandardResponses(400, 401, 403, 404),
|
||||
},
|
||||
}),
|
||||
],
|
||||
@ -161,7 +186,14 @@ export default class UserAdminController extends Controller {
|
||||
openApiService.validPath({
|
||||
tags: ['Users'],
|
||||
operationId: 'getUsers',
|
||||
responses: { 200: createResponseSchema('usersSchema') },
|
||||
summary:
|
||||
'Get all users and [root roles](https://docs.getunleash.io/reference/rbac#standard-roles)',
|
||||
description:
|
||||
'Will return all users and all available root roles for the Unleash instance.',
|
||||
responses: {
|
||||
200: createResponseSchema('usersSchema'),
|
||||
...getStandardResponses(401, 403),
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
@ -175,7 +207,22 @@ export default class UserAdminController extends Controller {
|
||||
openApiService.validPath({
|
||||
tags: ['Users'],
|
||||
operationId: 'searchUsers',
|
||||
responses: { 200: createResponseSchema('usersSchema') },
|
||||
summary: 'Search users',
|
||||
description:
|
||||
' It will preform a simple search based on name and email matching the given query. Requires minimum 2 characters',
|
||||
parameters: [
|
||||
{
|
||||
name: 'q',
|
||||
description:
|
||||
'The pattern to search in the username or email',
|
||||
schema: { type: 'string' },
|
||||
in: 'query',
|
||||
},
|
||||
],
|
||||
responses: {
|
||||
200: createResponseSchema('usersSchema'),
|
||||
...getStandardResponses(401),
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
@ -189,8 +236,12 @@ export default class UserAdminController extends Controller {
|
||||
openApiService.validPath({
|
||||
tags: ['Users'],
|
||||
operationId: 'getBaseUsersAndGroups',
|
||||
summary: 'Get basic user and group information',
|
||||
description:
|
||||
'Get a subset of user and group information eligible even for non-admin users',
|
||||
responses: {
|
||||
200: createResponseSchema('usersGroupsBaseSchema'),
|
||||
...getStandardResponses(401),
|
||||
},
|
||||
}),
|
||||
],
|
||||
@ -205,8 +256,12 @@ export default class UserAdminController extends Controller {
|
||||
openApiService.validPath({
|
||||
tags: ['Users'],
|
||||
operationId: 'getAdminCount',
|
||||
summary: 'Get total count of admin accounts',
|
||||
description:
|
||||
'Get a total count of admins with password, without password and admin service accounts',
|
||||
responses: {
|
||||
200: createResponseSchema('adminCountSchema'),
|
||||
...getStandardResponses(401, 403),
|
||||
},
|
||||
}),
|
||||
],
|
||||
@ -221,8 +276,15 @@ export default class UserAdminController extends Controller {
|
||||
openApiService.validPath({
|
||||
tags: ['Users'],
|
||||
operationId: 'createUser',
|
||||
summary: 'Create a new user',
|
||||
description: 'Creates a new user with the given root role.',
|
||||
requestBody: createRequestSchema('createUserSchema'),
|
||||
responses: { 200: createResponseSchema('userSchema') },
|
||||
responses: {
|
||||
201: resourceCreatedResponseSchema(
|
||||
'createUserResponseSchema',
|
||||
),
|
||||
...getStandardResponses(400, 401, 403),
|
||||
},
|
||||
}),
|
||||
rateLimit({
|
||||
windowMs: minutesToMilliseconds(1),
|
||||
@ -242,7 +304,12 @@ export default class UserAdminController extends Controller {
|
||||
openApiService.validPath({
|
||||
tags: ['Users'],
|
||||
operationId: 'getUser',
|
||||
responses: { 200: createResponseSchema('userSchema') },
|
||||
summary: 'Get user',
|
||||
description: 'Will return a single user by id',
|
||||
responses: {
|
||||
200: createResponseSchema('userSchema'),
|
||||
...getStandardResponses(400, 401, 404),
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
@ -256,8 +323,14 @@ export default class UserAdminController extends Controller {
|
||||
openApiService.validPath({
|
||||
tags: ['Users'],
|
||||
operationId: 'updateUser',
|
||||
summary: 'Update a user',
|
||||
description:
|
||||
'Only the explicitly specified fields get updated.',
|
||||
requestBody: createRequestSchema('updateUserSchema'),
|
||||
responses: { 200: createResponseSchema('userSchema') },
|
||||
responses: {
|
||||
200: createResponseSchema('createUserResponseSchema'),
|
||||
...getStandardResponses(400, 401, 403, 404),
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
@ -272,7 +345,12 @@ export default class UserAdminController extends Controller {
|
||||
openApiService.validPath({
|
||||
tags: ['Users'],
|
||||
operationId: 'deleteUser',
|
||||
responses: { 200: emptyResponse },
|
||||
summary: 'Delete a user',
|
||||
description: 'Deletes the user with the given userId',
|
||||
responses: {
|
||||
200: emptyResponse,
|
||||
...getStandardResponses(401, 403, 404),
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
@ -382,6 +460,9 @@ export default class UserAdminController extends Controller {
|
||||
|
||||
async getUser(req: Request, res: Response<UserSchema>): Promise<void> {
|
||||
const { id } = req.params;
|
||||
if (!Number.isInteger(Number(id))) {
|
||||
throw new BadDataError('User id should be an integer');
|
||||
}
|
||||
const user = await this.userService.getUser(Number(id));
|
||||
|
||||
this.openApiService.respondWithValidation(
|
||||
@ -394,11 +475,14 @@ export default class UserAdminController extends Controller {
|
||||
|
||||
async createUser(
|
||||
req: IAuthRequest<unknown, unknown, CreateUserSchema>,
|
||||
res: Response<UserSchema>,
|
||||
res: Response<CreateUserResponseSchema>,
|
||||
): Promise<void> {
|
||||
const { username, email, name, rootRole, sendEmail, password } =
|
||||
req.body;
|
||||
const { user } = req;
|
||||
const normalizedRootRole = Number.isInteger(Number(rootRole))
|
||||
? Number(rootRole)
|
||||
: (rootRole as RoleName);
|
||||
|
||||
const createdUser = await this.userService.createUser(
|
||||
{
|
||||
@ -406,7 +490,7 @@ export default class UserAdminController extends Controller {
|
||||
email,
|
||||
name,
|
||||
password,
|
||||
rootRole,
|
||||
rootRole: normalizedRootRole,
|
||||
},
|
||||
user,
|
||||
);
|
||||
@ -451,48 +535,67 @@ export default class UserAdminController extends Controller {
|
||||
);
|
||||
}
|
||||
|
||||
const responseData: UserSchema = {
|
||||
const responseData: CreateUserResponseSchema = {
|
||||
...serializeDates(createdUser),
|
||||
inviteLink: inviteLink || this.unleashUrl,
|
||||
emailSent,
|
||||
rootRole,
|
||||
rootRole: normalizedRootRole,
|
||||
};
|
||||
|
||||
this.openApiService.respondWithValidation(
|
||||
201,
|
||||
res,
|
||||
userSchema.$id,
|
||||
createUserResponseSchema.$id,
|
||||
responseData,
|
||||
{ location: `${responseData.id}` },
|
||||
);
|
||||
}
|
||||
|
||||
async updateUser(
|
||||
req: IAuthRequest<{ id: string }, UserSchema, UpdateUserSchema>,
|
||||
res: Response<UserSchema>,
|
||||
req: IAuthRequest<
|
||||
{ id: string },
|
||||
CreateUserResponseSchema,
|
||||
UpdateUserSchema
|
||||
>,
|
||||
res: Response<CreateUserResponseSchema>,
|
||||
): Promise<void> {
|
||||
const { user, params, body } = req;
|
||||
const { id } = params;
|
||||
const { name, email, rootRole } = body;
|
||||
if (!Number.isInteger(Number(id))) {
|
||||
throw new BadDataError('User id should be an integer');
|
||||
}
|
||||
const normalizedRootRole = Number.isInteger(Number(rootRole))
|
||||
? Number(rootRole)
|
||||
: (rootRole as RoleName);
|
||||
|
||||
const updateUser = await this.userService.updateUser(
|
||||
{
|
||||
id: Number(id),
|
||||
name,
|
||||
email,
|
||||
rootRole,
|
||||
rootRole: normalizedRootRole,
|
||||
},
|
||||
user,
|
||||
);
|
||||
|
||||
this.openApiService.respondWithValidation(200, res, userSchema.$id, {
|
||||
...serializeDates(updateUser),
|
||||
rootRole,
|
||||
});
|
||||
this.openApiService.respondWithValidation(
|
||||
200,
|
||||
res,
|
||||
createUserResponseSchema.$id,
|
||||
{
|
||||
...serializeDates(updateUser),
|
||||
rootRole: normalizedRootRole,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
async deleteUser(req: IAuthRequest, res: Response): Promise<void> {
|
||||
const { user, params } = req;
|
||||
const { id } = params;
|
||||
if (!Number.isInteger(Number(id))) {
|
||||
throw new BadDataError('User id should be an integer');
|
||||
}
|
||||
|
||||
await this.userService.deleteUser(+id, user);
|
||||
res.status(200).send();
|
||||
|
@ -192,7 +192,7 @@ class UserService {
|
||||
|
||||
const exists = await this.store.hasUser({ username, email });
|
||||
if (exists) {
|
||||
throw new Error('User already exists');
|
||||
throw new BadDataError('User already exists');
|
||||
}
|
||||
|
||||
const user = await this.store.insert({
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { setupApp, setupAppWithCustomConfig } from '../../helpers/test-helper';
|
||||
import { setupAppWithCustomConfig } from '../../helpers/test-helper';
|
||||
import dbInit from '../../helpers/database-init';
|
||||
import getLogger from '../../../fixtures/no-logger';
|
||||
import {
|
||||
@ -29,7 +29,13 @@ let adminRole: IRole;
|
||||
beforeAll(async () => {
|
||||
db = await dbInit('user_admin_api_serial', getLogger);
|
||||
stores = db.stores;
|
||||
app = await setupApp(stores);
|
||||
app = await setupAppWithCustomConfig(stores, {
|
||||
experimental: {
|
||||
flags: {
|
||||
strictSchemaValidation: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
userStore = stores.userStore;
|
||||
eventStore = stores.eventStore;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -186,7 +186,7 @@ The payload **must** contain **at least one of** the `name` and `email` properti
|
||||
|
||||
`PUT https://unleash.host.com/api/admin/user-admin/:userId`
|
||||
|
||||
Updates use with new fields
|
||||
Updates user with new fields
|
||||
|
||||
**Body**
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user