Add admin endpoint for API update user

This commit is contained in:
lethemanh
2025-04-03 17:25:03 +07:00
committed by Anton Shepilov
parent 9789dc24e1
commit 755c4f05e2
4 changed files with 90 additions and 52 deletions
@@ -1,9 +1,11 @@
import type { FastifyInstance, FastifyRegisterOptions } from "fastify";
import deleteUserRoutes from "./delete-user-routes";
import updateUserRoutes from "./update-user-routes";
export default (
fastify: FastifyInstance,
opts: FastifyRegisterOptions<{ prefix: string }>,
): void => {
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(
instance: User,
user: UpdateUser,
id: string,
body: UpdateUser,
context?: ExecutionContext,
): 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;
if (instance.email_canonical !== user.email) {
if (user.email_canonical !== body.email) {
isChangeEmail = true;
}
instance.email_canonical = user.email || instance.email_canonical;
instance.first_name = user.first_name || instance.first_name;
instance.last_name = user.last_name || instance.last_name;
instance.picture = user.picture || instance.picture;
instance.creation_date = !isNumber(instance.creation_date)
? Date.now()
: instance.creation_date;
user.email_canonical = body.email || user.email_canonical;
user.first_name = body.first_name || user.first_name;
user.last_name = body.last_name || user.last_name;
user.picture = body.picture || user.picture;
user.creation_date = !isNumber(user.creation_date) ? Date.now() : user.creation_date;
if (isChangeEmail) {
instance.username_canonical = formatUsername(user.email);
instance.identity_provider_id =
instance.identity_provider_id !== "null" ? user.email : "null";
user.username_canonical = formatUsername(body.email);
user.identity_provider_id = user.identity_provider_id !== "null" ? body.email : "null";
}
await this.repository.save(instance, context);
await this.repository.save(user, context);
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>> {
@@ -373,6 +373,7 @@ export class UsersCrudController
request: FastifyRequest<{ Body: UpdateUser; Params: UserParameters }>,
reply: FastifyReply,
): Promise<ResourceCreateResponse<UserObject>> {
try {
const id = request.params.id;
const context = getExecutionContext(request);
@@ -394,26 +395,15 @@ export class UsersCrudController
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;
}
}
await gr.services.users.update(user, body, context);
const user = await gr.services.users.update(id, body, context);
return {
resource: await formatUser(user),
resource: await formatUser(user.entity),
};
} catch (error) {
return error;
}
}
}