From f7ad02cd4b81ee69b66f00371e188e95bd4254f3 Mon Sep 17 00:00:00 2001 From: Andre Date: Wed, 12 Jun 2024 10:48:53 +0200 Subject: [PATCH 1/6] feat: Edit users --- backend/schema.gql | 1 + .../core/admin/members/edit/dto/edit.args.ts | 25 +++++++++ .../core/admin/members/edit/edit.resolver.ts | 20 +++++++ .../core/admin/members/edit/edit.service.ts | 52 +++++++++++++++++++ .../core/admin/members/members.module.ts | 6 ++- .../core/members/delete/delete.service.ts | 2 +- 6 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 backend/src/plugins/core/admin/members/edit/dto/edit.args.ts create mode 100644 backend/src/plugins/core/admin/members/edit/edit.resolver.ts create mode 100644 backend/src/plugins/core/admin/members/edit/edit.service.ts diff --git a/backend/schema.gql b/backend/schema.gql index e580235bd..63101c1d3 100644 --- a/backend/schema.gql +++ b/backend/schema.gql @@ -150,6 +150,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!): String! 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/edit.resolver.ts b/backend/src/plugins/core/admin/members/edit/edit.resolver.ts new file mode 100644 index 000000000..1904b69d2 --- /dev/null +++ b/backend/src/plugins/core/admin/members/edit/edit.resolver.ts @@ -0,0 +1,20 @@ +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"; + +@Resolver() +export class EditAdminMembersResolver { + constructor(private readonly service: EditAdminMembersService) {} + + @Mutation(() => String) + @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..63b2a9216 --- /dev/null +++ b/backend/src/plugins/core/admin/members/edit/edit.service.ts @@ -0,0 +1,52 @@ +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 "@/utils/errors/not-found-error"; +import { AccessDeniedError } from "@/utils/errors/access-denied-error"; + +@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(); + + 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)); + + return "Success!"; + } +} 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) From 9156eb313809e448a8baa9194ae39982617c76c3 Mon Sep 17 00:00:00 2001 From: Andre Date: Wed, 12 Jun 2024 12:59:28 +0200 Subject: [PATCH 2/6] fix: Applied suggestions from review --- .../core/admin/members/edit/dto/edit.obj.ts | 46 +++++++++++++++++++ .../core/admin/members/edit/edit.service.ts | 11 +++-- 2 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 backend/src/plugins/core/admin/members/edit/dto/edit.obj.ts 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..5f91838ac --- /dev/null +++ b/backend/src/plugins/core/admin/members/edit/dto/edit.obj.ts @@ -0,0 +1,46 @@ +import { ObjectType, Field, Int } from "@nestjs/graphql"; + +@ObjectType() +export class EditAdminMembersObj { + @Field(() => Int) + id: number; + + @Field(() => String) + name_seo: string; + + @Field(() => String) + name: string; + + @Field(() => String) + email: string; + + @Field(() => String) + password: string; + + @Field(() => Date) + joined: Date; + + @Field(() => Int) + posts: number; + + @Field(() => Boolean) + newsletter: boolean; + + @Field(() => String) + avatar_color: string; + + @Field(() => Int) + group_id: number; + + @Field(() => String) + first_name: string; + + @Field(() => String) + last_name: string; + + @Field(() => Date) + birthday: Date; + + @Field(() => String) + ip_address: string; +} diff --git a/backend/src/plugins/core/admin/members/edit/edit.service.ts b/backend/src/plugins/core/admin/members/edit/edit.service.ts index 63b2a9216..1556e2d02 100644 --- a/backend/src/plugins/core/admin/members/edit/edit.service.ts +++ b/backend/src/plugins/core/admin/members/edit/edit.service.ts @@ -1,5 +1,5 @@ import { Injectable } from "@nestjs/common"; -import { eq } from "drizzle-orm"; +import { eq, return } from "drizzle-orm"; import { EditAdminMembersArgs } from "./dto/edit.args"; @@ -7,6 +7,7 @@ import { core_users } from "@/plugins/core/admin/database/schema/users"; import { DatabaseService } from "@/database/database.service"; import { NotFoundError } from "@/utils/errors/not-found-error"; import { AccessDeniedError } from "@/utils/errors/access-denied-error"; +import { EditAdminMembersObj } from "./dto/edit.obj"; @Injectable() export class EditAdminMembersService { @@ -20,7 +21,7 @@ export class EditAdminMembersService { first_name, last_name, birthday - }: EditAdminMembersArgs): Promise { + }: EditAdminMembersArgs): Promise { const user = await this.databaseService.db.query.core_users.findFirst({ where: eq(core_users.id, id) }); @@ -35,7 +36,7 @@ export class EditAdminMembersService { if (!admin) throw new AccessDeniedError(); - await this.databaseService.db + const update = await this.databaseService.db .update(core_users) .set({ name: name, @@ -45,8 +46,8 @@ export class EditAdminMembersService { last_name: last_name, birthday: birthday }) - .where(eq(core_users.id, id)); + .where(eq(core_users.id, id)).returning(); - return "Success!"; + return update[0]; } } From 55d05b295d1bc9cae54524de72e4557d1560d50d Mon Sep 17 00:00:00 2001 From: Andre Date: Thu, 13 Jun 2024 08:32:14 +0200 Subject: [PATCH 3/6] fix: Fixed typing for data retrieved from database --- .../core/admin/members/edit/dto/edit.obj.ts | 21 ------------------- .../core/admin/members/edit/edit.service.ts | 5 +++-- 2 files changed, 3 insertions(+), 23 deletions(-) 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 index 5f91838ac..bc699ff7b 100644 --- a/backend/src/plugins/core/admin/members/edit/dto/edit.obj.ts +++ b/backend/src/plugins/core/admin/members/edit/dto/edit.obj.ts @@ -5,33 +5,15 @@ export class EditAdminMembersObj { @Field(() => Int) id: number; - @Field(() => String) - name_seo: string; - @Field(() => String) name: string; @Field(() => String) email: string; - @Field(() => String) - password: string; - - @Field(() => Date) - joined: Date; - - @Field(() => Int) - posts: number; - @Field(() => Boolean) newsletter: boolean; - @Field(() => String) - avatar_color: string; - - @Field(() => Int) - group_id: number; - @Field(() => String) first_name: string; @@ -40,7 +22,4 @@ export class EditAdminMembersObj { @Field(() => Date) birthday: Date; - - @Field(() => String) - ip_address: string; } diff --git a/backend/src/plugins/core/admin/members/edit/edit.service.ts b/backend/src/plugins/core/admin/members/edit/edit.service.ts index 1556e2d02..4ed3d1a8e 100644 --- a/backend/src/plugins/core/admin/members/edit/edit.service.ts +++ b/backend/src/plugins/core/admin/members/edit/edit.service.ts @@ -1,5 +1,5 @@ import { Injectable } from "@nestjs/common"; -import { eq, return } from "drizzle-orm"; +import { eq } from "drizzle-orm"; import { EditAdminMembersArgs } from "./dto/edit.args"; @@ -46,7 +46,8 @@ export class EditAdminMembersService { last_name: last_name, birthday: birthday }) - .where(eq(core_users.id, id)).returning(); + .where(eq(core_users.id, id)) + .returning(); return update[0]; } From dc44990332d3c3be1033804836d30ec7974d72b7 Mon Sep 17 00:00:00 2001 From: Andre Date: Thu, 13 Jun 2024 08:37:16 +0200 Subject: [PATCH 4/6] fix: Fixed typing in resolver --- backend/src/plugins/core/admin/members/edit/edit.resolver.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/src/plugins/core/admin/members/edit/edit.resolver.ts b/backend/src/plugins/core/admin/members/edit/edit.resolver.ts index 1904b69d2..66a19c70e 100644 --- a/backend/src/plugins/core/admin/members/edit/edit.resolver.ts +++ b/backend/src/plugins/core/admin/members/edit/edit.resolver.ts @@ -5,6 +5,7 @@ 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 { @@ -14,7 +15,7 @@ export class EditAdminMembersResolver { @UseGuards(AdminAuthGuards) async admin__core_members__edit( @Args() args: EditAdminMembersArgs - ): Promise { + ): Promise { return this.service.edit(args); } } From 6d1fd2a0ef4b3e2c820cb587d3c24d468806c061 Mon Sep 17 00:00:00 2001 From: Andre Date: Thu, 13 Jun 2024 10:14:46 +0200 Subject: [PATCH 5/6] fix: Fixed typing in resolver --- backend/schema.gql | 12 +++++++++++- .../plugins/core/admin/members/edit/edit.resolver.ts | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/backend/schema.gql b/backend/schema.gql index 63101c1d3..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,7 +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!): String! + 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/edit.resolver.ts b/backend/src/plugins/core/admin/members/edit/edit.resolver.ts index 66a19c70e..0dcf4aa01 100644 --- a/backend/src/plugins/core/admin/members/edit/edit.resolver.ts +++ b/backend/src/plugins/core/admin/members/edit/edit.resolver.ts @@ -11,7 +11,7 @@ import { EditAdminMembersObj } from "./dto/edit.obj"; export class EditAdminMembersResolver { constructor(private readonly service: EditAdminMembersService) {} - @Mutation(() => String) + @Mutation(() => EditAdminMembersObj) @UseGuards(AdminAuthGuards) async admin__core_members__edit( @Args() args: EditAdminMembersArgs From 475592e3ce0ec6334931a09f24166e9ea7b05dc3 Mon Sep 17 00:00:00 2001 From: Andre Date: Thu, 13 Jun 2024 14:48:04 +0200 Subject: [PATCH 6/6] fix: Fixed exception imports --- backend/src/plugins/core/admin/members/edit/edit.service.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/plugins/core/admin/members/edit/edit.service.ts b/backend/src/plugins/core/admin/members/edit/edit.service.ts index 4ed3d1a8e..d5ab37fb6 100644 --- a/backend/src/plugins/core/admin/members/edit/edit.service.ts +++ b/backend/src/plugins/core/admin/members/edit/edit.service.ts @@ -5,8 +5,8 @@ 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 "@/utils/errors/not-found-error"; -import { AccessDeniedError } from "@/utils/errors/access-denied-error"; +import { NotFoundError } from "@vitnode/backend"; +import { AccessDeniedError } from "@vitnode/backend"; import { EditAdminMembersObj } from "./dto/edit.obj"; @Injectable()