Add admin endpoint for API update user
This commit is contained in:
committed by
Anton Shepilov
parent
9789dc24e1
commit
755c4f05e2
@@ -1,9 +1,11 @@
|
|||||||
import type { FastifyInstance, FastifyRegisterOptions } from "fastify";
|
import type { FastifyInstance, FastifyRegisterOptions } from "fastify";
|
||||||
import deleteUserRoutes from "./delete-user-routes";
|
import deleteUserRoutes from "./delete-user-routes";
|
||||||
|
import updateUserRoutes from "./update-user-routes";
|
||||||
|
|
||||||
export default (
|
export default (
|
||||||
fastify: FastifyInstance,
|
fastify: FastifyInstance,
|
||||||
opts: FastifyRegisterOptions<{ prefix: string }>,
|
opts: FastifyRegisterOptions<{ prefix: string }>,
|
||||||
): void => {
|
): void => {
|
||||||
fastify.register(deleteUserRoutes, opts);
|
fastify.register(deleteUserRoutes, opts);
|
||||||
|
fastify.register(updateUserRoutes, opts);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import type { FastifyInstance, FastifyPluginCallback, FastifyReply, FastifyRequest } from "fastify";
|
||||||
|
import { getConfig } from "../../../framework/api/admin";
|
||||||
|
import gr from "../../../../../services/global-resolver";
|
||||||
|
import { CrudException } from "../../../framework/api/crud-service";
|
||||||
|
import { UpdateUser } from "../../../../../services/user/services/users/types";
|
||||||
|
|
||||||
|
const config = getConfig();
|
||||||
|
|
||||||
|
function authenticateAdminQuery(request: FastifyRequest, reply: FastifyReply) {
|
||||||
|
const secret = request.headers["secret"];
|
||||||
|
if (secret !== config.endpointSecret) {
|
||||||
|
reply.status(403).send();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const routes: FastifyPluginCallback = async (fastify: FastifyInstance, _opts, next) => {
|
||||||
|
const urlRoot = "/api/user/update";
|
||||||
|
const config = getConfig();
|
||||||
|
if (config?.endpointSecret?.length) {
|
||||||
|
fastify.put(`${urlRoot}/:id`, async (request, reply) => {
|
||||||
|
try {
|
||||||
|
if (!authenticateAdminQuery(request, reply)) {
|
||||||
|
throw CrudException.unauthorized("Not allow to update user");
|
||||||
|
}
|
||||||
|
|
||||||
|
return await gr.services.users.update(request.params["id"], request.body as UpdateUser);
|
||||||
|
} catch (error) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
|
||||||
|
export default routes;
|
||||||
@@ -110,34 +110,43 @@ export class UserServiceImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async update(
|
async update(
|
||||||
instance: User,
|
id: string,
|
||||||
user: UpdateUser,
|
body: UpdateUser,
|
||||||
context?: ExecutionContext,
|
context?: ExecutionContext,
|
||||||
): Promise<UpdateResult<User>> {
|
): Promise<UpdateResult<User>> {
|
||||||
|
const user = await gr.services.users.get({ id });
|
||||||
|
if (!user) {
|
||||||
|
throw CrudException.notFound(`User ${id} not found`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user.email_canonical !== body.email) {
|
||||||
|
const userByEmail = await gr.services.users.getByEmail(body.email, context);
|
||||||
|
if (userByEmail) {
|
||||||
|
throw CrudException.badRequest(`Email ${body.email} is existed`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let isChangeEmail = false;
|
let isChangeEmail = false;
|
||||||
if (instance.email_canonical !== user.email) {
|
if (user.email_canonical !== body.email) {
|
||||||
isChangeEmail = true;
|
isChangeEmail = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.email_canonical = user.email || instance.email_canonical;
|
user.email_canonical = body.email || user.email_canonical;
|
||||||
instance.first_name = user.first_name || instance.first_name;
|
user.first_name = body.first_name || user.first_name;
|
||||||
instance.last_name = user.last_name || instance.last_name;
|
user.last_name = body.last_name || user.last_name;
|
||||||
instance.picture = user.picture || instance.picture;
|
user.picture = body.picture || user.picture;
|
||||||
instance.creation_date = !isNumber(instance.creation_date)
|
user.creation_date = !isNumber(user.creation_date) ? Date.now() : user.creation_date;
|
||||||
? Date.now()
|
|
||||||
: instance.creation_date;
|
|
||||||
if (isChangeEmail) {
|
if (isChangeEmail) {
|
||||||
instance.username_canonical = formatUsername(user.email);
|
user.username_canonical = formatUsername(body.email);
|
||||||
instance.identity_provider_id =
|
user.identity_provider_id = user.identity_provider_id !== "null" ? body.email : "null";
|
||||||
instance.identity_provider_id !== "null" ? user.email : "null";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.repository.save(instance, context);
|
await this.repository.save(user, context);
|
||||||
if (isChangeEmail) {
|
if (isChangeEmail) {
|
||||||
await this.updateExtRepositoryInCaseChangeEmail(instance, context);
|
await this.updateExtRepositoryInCaseChangeEmail(user, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new UpdateResult("user", instance);
|
return new UpdateResult("user", user);
|
||||||
}
|
}
|
||||||
|
|
||||||
async save(user: User, context?: ExecutionContext): Promise<SaveResult<User>> {
|
async save(user: User, context?: ExecutionContext): Promise<SaveResult<User>> {
|
||||||
|
|||||||
@@ -373,47 +373,37 @@ export class UsersCrudController
|
|||||||
request: FastifyRequest<{ Body: UpdateUser; Params: UserParameters }>,
|
request: FastifyRequest<{ Body: UpdateUser; Params: UserParameters }>,
|
||||||
reply: FastifyReply,
|
reply: FastifyReply,
|
||||||
): Promise<ResourceCreateResponse<UserObject>> {
|
): Promise<ResourceCreateResponse<UserObject>> {
|
||||||
const id = request.params.id;
|
try {
|
||||||
const context = getExecutionContext(request);
|
const id = request.params.id;
|
||||||
|
const context = getExecutionContext(request);
|
||||||
|
|
||||||
const [currentUserCompanies, requestedUserCompanies] = await Promise.all(
|
const [currentUserCompanies, requestedUserCompanies] = await Promise.all(
|
||||||
[context.user.id, request.params.id].map(userId =>
|
[context.user.id, request.params.id].map(userId =>
|
||||||
gr.services.users.getUserCompanies({ id: userId }),
|
gr.services.users.getUserCompanies({ id: userId }),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
const currentUserCompaniesIds = new Set(currentUserCompanies.map(a => a.group_id));
|
const currentUserCompaniesIds = new Set(currentUserCompanies.map(a => a.group_id));
|
||||||
const sameCompanies = requestedUserCompanies.filter(a =>
|
const sameCompanies = requestedUserCompanies.filter(a =>
|
||||||
currentUserCompaniesIds.has(a.group_id),
|
currentUserCompaniesIds.has(a.group_id),
|
||||||
);
|
);
|
||||||
const roles = await Promise.all(
|
const roles = await Promise.all(
|
||||||
sameCompanies.map(a => gr.services.companies.getUserRole(a.group_id, context.user?.id)),
|
sameCompanies.map(a => gr.services.companies.getUserRole(a.group_id, context.user?.id)),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!roles.some(role => hasCompanyAdminLevel(role) === true)) {
|
if (!roles.some(role => hasCompanyAdminLevel(role) === true)) {
|
||||||
reply.unauthorized(`User ${context.user?.id} is not allowed to update user ${id}`);
|
reply.unauthorized(`User ${context.user?.id} is not allowed to update user ${id}`);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const user = await gr.services.users.get({ id });
|
|
||||||
if (!user) {
|
|
||||||
reply.notFound(`User ${id} not found`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const body = { ...request.body };
|
|
||||||
if (user.email_canonical !== body.email) {
|
|
||||||
const userByEmail = await gr.services.users.getByEmail(body.email, context);
|
|
||||||
if (userByEmail) {
|
|
||||||
reply.conflict(`Email ${body.email} is existed`);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const body = { ...request.body };
|
||||||
|
const user = await gr.services.users.update(id, body, context);
|
||||||
|
|
||||||
|
return {
|
||||||
|
resource: await formatUser(user.entity),
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
await gr.services.users.update(user, body, context);
|
|
||||||
|
|
||||||
return {
|
|
||||||
resource: await formatUser(user),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user