diff --git a/packages/hoppscotch-backend/src/admin/admin.module.ts b/packages/hoppscotch-backend/src/admin/admin.module.ts index f81f54245..68e4848c1 100644 --- a/packages/hoppscotch-backend/src/admin/admin.module.ts +++ b/packages/hoppscotch-backend/src/admin/admin.module.ts @@ -10,6 +10,7 @@ import { TeamInvitationModule } from '../team-invitation/team-invitation.module' import { TeamEnvironmentsModule } from '../team-environments/team-environments.module'; import { TeamCollectionModule } from '../team-collection/team-collection.module'; import { TeamRequestModule } from '../team-request/team-request.module'; +import { InfraResolver } from './infra.resolver'; @Module({ imports: [ @@ -23,7 +24,7 @@ import { TeamRequestModule } from '../team-request/team-request.module'; TeamCollectionModule, TeamRequestModule, ], - providers: [AdminResolver, AdminService], + providers: [InfraResolver, AdminResolver, AdminService], exports: [AdminService], }) export class AdminModule {} diff --git a/packages/hoppscotch-backend/src/admin/admin.resolver.ts b/packages/hoppscotch-backend/src/admin/admin.resolver.ts index e0a29274e..35a93cde0 100644 --- a/packages/hoppscotch-backend/src/admin/admin.resolver.ts +++ b/packages/hoppscotch-backend/src/admin/admin.resolver.ts @@ -1,15 +1,5 @@ -import { - Args, - ID, - Mutation, - Parent, - Query, - ResolveField, - Resolver, - Subscription, -} from '@nestjs/graphql'; +import { Args, ID, Mutation, Resolver, Subscription } from '@nestjs/graphql'; import { Admin } from './admin.model'; -import { Infra } from './infra.model'; import { UseGuards } from '@nestjs/common'; import { GqlAuthGuard } from '../guards/gql-auth.guard'; import { GqlAdminGuard } from './guards/gql-admin.guard'; @@ -22,9 +12,6 @@ import { InvitedUser } from './invited-user.model'; import { GqlUser } from '../decorators/gql-user.decorator'; import { PubSubService } from '../pubsub/pubsub.service'; import { Team, TeamMember } from '../team/team.model'; -import { User } from '../user/user.model'; -import { TeamInvitation } from '../team-invitation/team-invitation.model'; -import { PaginationArgs } from '../types/input-types.args'; import { AddUserToTeamArgs, ChangeUserRoleInTeamArgs, @@ -33,7 +20,7 @@ import { GqlThrottlerGuard } from 'src/guards/gql-throttler.guard'; import { SkipThrottle } from '@nestjs/throttler'; @UseGuards(GqlThrottlerGuard) -@Resolver(() => Infra) +@Resolver(() => Admin) export class AdminResolver { constructor( private adminService: AdminService, @@ -42,195 +29,13 @@ export class AdminResolver { /* Query */ - @Query(() => Infra, { - description: 'Gives details of the admin executing this query', - }) - @UseGuards(GqlAuthGuard, GqlAdminGuard) - infra(@GqlAdmin() admin: Admin) { - return admin; - } - - @ResolveField(() => [User], { - description: 'Returns a list of all admin users in infra', - }) - @UseGuards(GqlAuthGuard, GqlAdminGuard) - async admins() { - const admins = await this.adminService.fetchAdmins(); - return admins; - } - @ResolveField(() => User, { - description: 'Returns a user info by UID', - }) - @UseGuards(GqlAuthGuard, GqlAdminGuard) - async userInfo( - @Args({ - name: 'userUid', - type: () => ID, - description: 'The user UID', - }) - userUid: string, - ): Promise { - const user = await this.adminService.fetchUserInfo(userUid); - if (E.isLeft(user)) throwErr(user.left); - return user.right; - } - - @ResolveField(() => [User], { - description: 'Returns a list of all the users in infra', - }) - @UseGuards(GqlAuthGuard, GqlAdminGuard) - async allUsers( - @Parent() admin: Admin, - @Args() args: PaginationArgs, - ): Promise { - const users = await this.adminService.fetchUsers(args.cursor, args.take); - return users; - } - - @ResolveField(() => [InvitedUser], { - description: 'Returns a list of all the invited users', - }) - async invitedUsers(@Parent() admin: Admin): Promise { - const users = await this.adminService.fetchInvitedUsers(); - return users; - } - - @ResolveField(() => [Team], { - description: 'Returns a list of all the teams in the infra', - }) - async allTeams( - @Parent() admin: Admin, - @Args() args: PaginationArgs, - ): Promise { - const teams = await this.adminService.fetchAllTeams(args.cursor, args.take); - return teams; - } - @ResolveField(() => Team, { - description: 'Returns a team info by ID when requested by Admin', - }) - async teamInfo( - @Parent() admin: Admin, - @Args({ - name: 'teamID', - type: () => ID, - description: 'Team ID for which info to fetch', - }) - teamID: string, - ): Promise { - const team = await this.adminService.getTeamInfo(teamID); - if (E.isLeft(team)) throwErr(team.left); - return team.right; - } - - @ResolveField(() => Number, { - description: 'Return count of all the members in a team', - }) - async membersCountInTeam( - @Parent() admin: Admin, - @Args({ - name: 'teamID', - type: () => ID, - description: 'Team ID for which team members to fetch', - nullable: false, - }) - teamID: string, - ): Promise { - const teamMembersCount = await this.adminService.membersCountInTeam(teamID); - return teamMembersCount; - } - - @ResolveField(() => Number, { - description: 'Return count of all the stored collections in a team', - }) - async collectionCountInTeam( - @Parent() admin: Admin, - @Args({ - name: 'teamID', - type: () => ID, - description: 'Team ID for which team members to fetch', - }) - teamID: string, - ): Promise { - const teamCollCount = await this.adminService.collectionCountInTeam(teamID); - return teamCollCount; - } - @ResolveField(() => Number, { - description: 'Return count of all the stored requests in a team', - }) - async requestCountInTeam( - @Parent() admin: Admin, - @Args({ - name: 'teamID', - type: () => ID, - description: 'Team ID for which team members to fetch', - }) - teamID: string, - ): Promise { - const teamReqCount = await this.adminService.requestCountInTeam(teamID); - return teamReqCount; - } - - @ResolveField(() => Number, { - description: 'Return count of all the stored environments in a team', - }) - async environmentCountInTeam( - @Parent() admin: Admin, - @Args({ - name: 'teamID', - type: () => ID, - description: 'Team ID for which team members to fetch', - }) - teamID: string, - ): Promise { - const envsCount = await this.adminService.environmentCountInTeam(teamID); - return envsCount; - } - - @ResolveField(() => [TeamInvitation], { - description: 'Return all the pending invitations in a team', - }) - async pendingInvitationCountInTeam( - @Parent() admin: Admin, - @Args({ - name: 'teamID', - type: () => ID, - description: 'Team ID for which team members to fetch', - }) - teamID: string, - ) { - const invitations = await this.adminService.pendingInvitationCountInTeam( - teamID, - ); - return invitations; - } - - @ResolveField(() => Number, { - description: 'Return total number of Users in organization', - }) - async usersCount() { - return this.adminService.getUsersCount(); - } - - @ResolveField(() => Number, { - description: 'Return total number of Teams in organization', - }) - async teamsCount() { - return this.adminService.getTeamsCount(); - } - - @ResolveField(() => Number, { - description: 'Return total number of Team Collections in organization', - }) - async teamCollectionsCount() { - return this.adminService.getTeamCollectionsCount(); - } - - @ResolveField(() => Number, { - description: 'Return total number of Team Requests in organization', - }) - async teamRequestsCount() { - return this.adminService.getTeamRequestsCount(); - } + // @Query(() => Admin, { + // description: 'Gives details of the admin executing this query', + // }) + // @UseGuards(GqlAuthGuard, GqlAdminGuard) + // admin(@GqlAdmin() admin: Admin) { + // return admin; + // } /* Mutations */ diff --git a/packages/hoppscotch-backend/src/admin/infra.resolver.ts b/packages/hoppscotch-backend/src/admin/infra.resolver.ts new file mode 100644 index 000000000..155c34322 --- /dev/null +++ b/packages/hoppscotch-backend/src/admin/infra.resolver.ts @@ -0,0 +1,223 @@ +import { UseGuards } from '@nestjs/common'; +import { + Args, + ID, + Parent, + Query, + ResolveField, + Resolver, +} from '@nestjs/graphql'; +import { GqlThrottlerGuard } from 'src/guards/gql-throttler.guard'; +import { Infra } from './infra.model'; +import { AdminService } from './admin.service'; +import { GqlAuthGuard } from 'src/guards/gql-auth.guard'; +import { GqlAdminGuard } from './guards/gql-admin.guard'; +import { User } from 'src/user/user.model'; +import { AuthUser } from 'src/types/AuthUser'; +import { throwErr } from 'src/utils'; +import * as E from 'fp-ts/Either'; +import { Admin } from './admin.model'; +import { PaginationArgs } from 'src/types/input-types.args'; +import { InvitedUser } from './invited-user.model'; +import { Team } from 'src/team/team.model'; +import { TeamInvitation } from 'src/team-invitation/team-invitation.model'; +import { GqlAdmin } from './decorators/gql-admin.decorator'; + +@UseGuards(GqlThrottlerGuard) +@Resolver(() => Infra) +export class InfraResolver { + constructor(private adminService: AdminService) {} + + @Query(() => Infra, { + description: 'Gives details of the admin executing this query', + }) + @UseGuards(GqlAuthGuard, GqlAdminGuard) + infra(@GqlAdmin() admin: Admin) { + return admin; + } + + @ResolveField(() => [User], { + description: 'Returns a list of all admin users in infra', + }) + @UseGuards(GqlAuthGuard, GqlAdminGuard) + async admins() { + const admins = await this.adminService.fetchAdmins(); + return admins; + } + + @ResolveField(() => User, { + description: 'Returns a user info by UID', + }) + @UseGuards(GqlAuthGuard, GqlAdminGuard) + async userInfo( + @Args({ + name: 'userUid', + type: () => ID, + description: 'The user UID', + }) + userUid: string, + ): Promise { + const user = await this.adminService.fetchUserInfo(userUid); + if (E.isLeft(user)) throwErr(user.left); + return user.right; + } + + @ResolveField(() => [User], { + description: 'Returns a list of all the users in infra', + }) + @UseGuards(GqlAuthGuard, GqlAdminGuard) + async allUsers( + @Parent() infra: Infra, + @Args() args: PaginationArgs, + ): Promise { + const users = await this.adminService.fetchUsers(args.cursor, args.take); + return users; + } + + @ResolveField(() => [InvitedUser], { + description: 'Returns a list of all the invited users', + }) + async invitedUsers(@Parent() infra: Infra): Promise { + const users = await this.adminService.fetchInvitedUsers(); + return users; + } + + @ResolveField(() => [Team], { + description: 'Returns a list of all the teams in the infra', + }) + async allTeams( + @Parent() infra: Infra, + @Args() args: PaginationArgs, + ): Promise { + const teams = await this.adminService.fetchAllTeams(args.cursor, args.take); + return teams; + } + + @ResolveField(() => Team, { + description: 'Returns a team info by ID when requested by Admin', + }) + async teamInfo( + @Parent() infra: Infra, + @Args({ + name: 'teamID', + type: () => ID, + description: 'Team ID for which info to fetch', + }) + teamID: string, + ): Promise { + const team = await this.adminService.getTeamInfo(teamID); + if (E.isLeft(team)) throwErr(team.left); + return team.right; + } + + @ResolveField(() => Number, { + description: 'Return count of all the members in a team', + }) + async membersCountInTeam( + @Parent() infra: Infra, + @Args({ + name: 'teamID', + type: () => ID, + description: 'Team ID for which team members to fetch', + nullable: false, + }) + teamID: string, + ): Promise { + const teamMembersCount = await this.adminService.membersCountInTeam(teamID); + return teamMembersCount; + } + + @ResolveField(() => Number, { + description: 'Return count of all the stored collections in a team', + }) + async collectionCountInTeam( + @Parent() infra: Infra, + @Args({ + name: 'teamID', + type: () => ID, + description: 'Team ID for which team members to fetch', + }) + teamID: string, + ): Promise { + const teamCollCount = await this.adminService.collectionCountInTeam(teamID); + return teamCollCount; + } + + @ResolveField(() => Number, { + description: 'Return count of all the stored requests in a team', + }) + async requestCountInTeam( + @Parent() infra: Infra, + @Args({ + name: 'teamID', + type: () => ID, + description: 'Team ID for which team members to fetch', + }) + teamID: string, + ): Promise { + const teamReqCount = await this.adminService.requestCountInTeam(teamID); + return teamReqCount; + } + + @ResolveField(() => Number, { + description: 'Return count of all the stored environments in a team', + }) + async environmentCountInTeam( + @Parent() infra: Infra, + @Args({ + name: 'teamID', + type: () => ID, + description: 'Team ID for which team members to fetch', + }) + teamID: string, + ): Promise { + const envsCount = await this.adminService.environmentCountInTeam(teamID); + return envsCount; + } + + @ResolveField(() => [TeamInvitation], { + description: 'Return all the pending invitations in a team', + }) + async pendingInvitationCountInTeam( + @Parent() infra: Infra, + @Args({ + name: 'teamID', + type: () => ID, + description: 'Team ID for which team members to fetch', + }) + teamID: string, + ) { + const invitations = await this.adminService.pendingInvitationCountInTeam( + teamID, + ); + return invitations; + } + + @ResolveField(() => Number, { + description: 'Return total number of Users in organization', + }) + async usersCount() { + return this.adminService.getUsersCount(); + } + + @ResolveField(() => Number, { + description: 'Return total number of Teams in organization', + }) + async teamsCount() { + return this.adminService.getTeamsCount(); + } + + @ResolveField(() => Number, { + description: 'Return total number of Team Collections in organization', + }) + async teamCollectionsCount() { + return this.adminService.getTeamCollectionsCount(); + } + + @ResolveField(() => Number, { + description: 'Return total number of Team Requests in organization', + }) + async teamRequestsCount() { + return this.adminService.getTeamRequestsCount(); + } +} diff --git a/packages/hoppscotch-backend/src/gql-schema.ts b/packages/hoppscotch-backend/src/gql-schema.ts index 0fedcd7f6..bd2434e2f 100644 --- a/packages/hoppscotch-backend/src/gql-schema.ts +++ b/packages/hoppscotch-backend/src/gql-schema.ts @@ -27,6 +27,7 @@ import { UserRequestUserCollectionResolver } from './user-request/resolvers/user import { UserEnvsUserResolver } from './user-environment/user.resolver'; import { UserHistoryUserResolver } from './user-history/user.resolver'; import { UserSettingsUserResolver } from './user-settings/user.resolver'; +import { InfraResolver } from './admin/infra.resolver'; /** * All the resolvers present in the application. @@ -34,6 +35,7 @@ import { UserSettingsUserResolver } from './user-settings/user.resolver'; * NOTE: This needs to be KEPT UP-TO-DATE to keep the schema accurate */ const RESOLVERS = [ + InfraResolver, AdminResolver, ShortcodeResolver, TeamResolver,