diff --git a/backend/schema.gql b/backend/schema.gql index e580235bd..668b6b6b0 100644 --- a/backend/schema.gql +++ b/backend/schema.gql @@ -86,6 +86,16 @@ A date-time string at UTC, such as 2019-12-03T09:54:33Z, compliant with the date """ scalar DateTime +type EditAdminMembersObj { + birthday: DateTime! + email: String! + first_name: String! + id: Int! + last_name: String! + name: String! + newsletter: Boolean! +} + type EditAdminSettingsObj { site_copyright: [TextLanguage!]! site_description: [TextLanguage!]! @@ -150,6 +160,7 @@ type Mutation { admin__core_languages__update(code: String!, file: Upload!): String! admin__core_main_settings__edit(site_copyright: [TextLanguageInput!]!, site_description: [TextLanguageInput!]!, site_name: String!, site_short_name: String!): EditAdminSettingsObj! admin__core_manifest_metadata__edit(background_color: String!, display: String!, start_url: String!, theme_color: String!): ShowAdminManifestMetadataObj! + admin__core_members__edit(birthday: DateTime!, email: String!, first_name: String!, id: Int!, last_name: String!, name: String!, newsletter: Boolean!): EditAdminMembersObj! admin__core_nav__change_position(id: Int!, index_to_move: Int!, parent_id: Int!): String! admin__core_nav__create(description: [TextLanguageInput!]!, external: Boolean!, href: String!, icon: String, name: [TextLanguageInput!]!): ShowCoreNav! admin__core_nav__delete(id: Int!): String! diff --git a/backend/src/plugins/core/admin/members/edit/dto/edit.args.ts b/backend/src/plugins/core/admin/members/edit/dto/edit.args.ts new file mode 100644 index 000000000..8faa37fcc --- /dev/null +++ b/backend/src/plugins/core/admin/members/edit/dto/edit.args.ts @@ -0,0 +1,25 @@ +import { ArgsType, Field, Int } from "@nestjs/graphql"; + +@ArgsType() +export class EditAdminMembersArgs { + @Field(() => Int) + id: number; + + @Field(() => String) + name: string; + + @Field(() => String) + email: string; + + @Field(() => Boolean) + newsletter: boolean; + + @Field(() => String) + first_name: string; + + @Field(() => String) + last_name: string; + + @Field(() => Date) + birthday: Date; +} diff --git a/backend/src/plugins/core/admin/members/edit/dto/edit.obj.ts b/backend/src/plugins/core/admin/members/edit/dto/edit.obj.ts new file mode 100644 index 000000000..bc699ff7b --- /dev/null +++ b/backend/src/plugins/core/admin/members/edit/dto/edit.obj.ts @@ -0,0 +1,25 @@ +import { ObjectType, Field, Int } from "@nestjs/graphql"; + +@ObjectType() +export class EditAdminMembersObj { + @Field(() => Int) + id: number; + + @Field(() => String) + name: string; + + @Field(() => String) + email: string; + + @Field(() => Boolean) + newsletter: boolean; + + @Field(() => String) + first_name: string; + + @Field(() => String) + last_name: string; + + @Field(() => Date) + birthday: Date; +} diff --git a/backend/src/plugins/core/admin/members/edit/edit.resolver.ts b/backend/src/plugins/core/admin/members/edit/edit.resolver.ts new file mode 100644 index 000000000..0dcf4aa01 --- /dev/null +++ b/backend/src/plugins/core/admin/members/edit/edit.resolver.ts @@ -0,0 +1,21 @@ +import { Args, Mutation, Resolver } from "@nestjs/graphql"; +import { UseGuards } from "@nestjs/common"; + +import { EditAdminMembersService } from "./edit.service"; +import { EditAdminMembersArgs } from "./dto/edit.args"; + +import { AdminAuthGuards } from "@/utils/guards/admin-auth.guard"; +import { EditAdminMembersObj } from "./dto/edit.obj"; + +@Resolver() +export class EditAdminMembersResolver { + constructor(private readonly service: EditAdminMembersService) {} + + @Mutation(() => EditAdminMembersObj) + @UseGuards(AdminAuthGuards) + async admin__core_members__edit( + @Args() args: EditAdminMembersArgs + ): Promise { + return this.service.edit(args); + } +} diff --git a/backend/src/plugins/core/admin/members/edit/edit.service.ts b/backend/src/plugins/core/admin/members/edit/edit.service.ts new file mode 100644 index 000000000..d5ab37fb6 --- /dev/null +++ b/backend/src/plugins/core/admin/members/edit/edit.service.ts @@ -0,0 +1,54 @@ +import { Injectable } from "@nestjs/common"; +import { eq } from "drizzle-orm"; + +import { EditAdminMembersArgs } from "./dto/edit.args"; + +import { core_users } from "@/plugins/core/admin/database/schema/users"; +import { DatabaseService } from "@/database/database.service"; +import { NotFoundError } from "@vitnode/backend"; +import { AccessDeniedError } from "@vitnode/backend"; +import { EditAdminMembersObj } from "./dto/edit.obj"; + +@Injectable() +export class EditAdminMembersService { + constructor(private readonly databaseService: DatabaseService) {} + + async edit({ + id, + name, + email, + newsletter, + first_name, + last_name, + birthday + }: EditAdminMembersArgs): Promise { + const user = await this.databaseService.db.query.core_users.findFirst({ + where: eq(core_users.id, id) + }); + + if (!user) throw new NotFoundError("User"); + + const admin = + await this.databaseService.db.query.core_admin_permissions.findFirst({ + where: (table, { or, eq }) => + or(eq(table.user_id, user.id), eq(table.group_id, user.group_id)) + }); + + if (!admin) throw new AccessDeniedError(); + + const update = await this.databaseService.db + .update(core_users) + .set({ + name: name, + email: email, + newsletter: newsletter, + first_name: first_name, + last_name: last_name, + birthday: birthday + }) + .where(eq(core_users.id, id)) + .returning(); + + return update[0]; + } +} diff --git a/backend/src/plugins/core/admin/members/members.module.ts b/backend/src/plugins/core/admin/members/members.module.ts index c5c0ad5f1..2d8326c8f 100644 --- a/backend/src/plugins/core/admin/members/members.module.ts +++ b/backend/src/plugins/core/admin/members/members.module.ts @@ -4,13 +4,17 @@ import { ShowAdminMembersResolver } from "./show/show.resolver"; import { ShowAdminMembersService } from "./show/show.service"; import { StatsAdminMembersResolver } from "./stats/stats.resolver"; import { StatsAdminMembersService } from "./stats/stats.service"; +import { EditAdminMembersResolver } from "./edit/edit.resolver"; +import { EditAdminMembersService } from "./edit/edit.service"; @Module({ providers: [ ShowAdminMembersResolver, ShowAdminMembersService, StatsAdminMembersResolver, - StatsAdminMembersService + StatsAdminMembersService, + EditAdminMembersResolver, + EditAdminMembersService ] }) export class AdminMembersModule {} diff --git a/backend/src/plugins/core/members/delete/delete.service.ts b/backend/src/plugins/core/members/delete/delete.service.ts index 6c8fc6c62..efbf3fa64 100644 --- a/backend/src/plugins/core/members/delete/delete.service.ts +++ b/backend/src/plugins/core/members/delete/delete.service.ts @@ -25,7 +25,7 @@ export class DeleteCoreMembersService { or(eq(table.user_id, user.id), eq(table.group_id, user.group_id)) }); - if (admin) throw new AccessDeniedError(); + if (admin) throw new AccessDeniedError(); //Protects against deletion users with admin permisssions await this.databaseService.db .delete(core_users)