Passed
Push — development ( dc54c5...2ef559 )
by Vad
09:16 queued 13s
created

UsersController.softDeleteUser   A

Complexity

Conditions 1

Size

Total Lines 19
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1.125

Importance

Changes 0
Metric Value
cc 1
eloc 16
dl 0
loc 19
ccs 1
cts 2
cp 0.5
crap 1.125
rs 9.6
c 0
b 0
f 0
1 5
import { BadRequestException, Controller, Param, ForbiddenException } from '@nestjs/common';
2 5
import { UsersService } from './users.service';
3 5
import { Patch, Get, Body, Req, Post, UseGuards, Request } from '@nestjs/common';
0 ignored issues
show
introduced by
'@nestjs/common' import is duplicated.
Loading history...
introduced by
'Post' is defined but never used.
Loading history...
4 5
import { UpdateTermsDto } from './dto/update-terms.dto/update-terms.dto';
5 5
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
6 5
import { ApiBearerAuth, ApiBody, ApiOperation, ApiParam, ApiResponse } from '@nestjs/swagger';
7 5
import { UpdateUserDto } from './dto/update-user.dto/update-user.dto';
8 5
import { AdjustFundsDto } from './dto/update-user.dto/adjust-funds.dto';
9 5
import { AdminGuard } from '../auth/guards/admin.guard';
10
11
@Controller({ path: 'users', version: '1' })
12 5
export class UsersController {
13 7
  constructor(private readonly usersService: UsersService) {}
14
15
  @Patch('terms')
16
  @UseGuards(JwtAuthGuard)
17
  @ApiBearerAuth()
18
  @ApiOperation({ summary: 'Update terms acceptance status' })
19
  @ApiBody({
20
    description: 'The body containing the updated terms acceptance status',
21
    type: UpdateTermsDto,
22
  })
23
  @ApiResponse({
24
    status: 200,
25
    description: 'Terms acceptance status updated successfully',
26
    examples: {
27
      'application/json': {
28
        summary: 'Example of a successful terms update',
29
        value: {
30
          githubId: '12345',
31
          hasAcceptedTerms: true,
32
        },
33
      },
34
    },
35
  })
36
  @ApiResponse({
37
    status: 400,
38
    description: 'Invalid input',
39
  })
40
  @ApiResponse({
41
    status: 401,
42
    description: 'Unauthorized. Authentication required',
0 ignored issues
show
introduced by
Define a constant instead of duplicating this literal 4 times.
Loading history...
43
  })
44 5
  async updateTerms(@Req() req, @Body() updateTermsDto: UpdateTermsDto) {
45 6
    if (typeof updateTermsDto.hasAcceptedTerms !== 'boolean') {
46 2
      throw new BadRequestException('Invalid input');
47
    }
48 4
    return await this.usersService.updateTerms(req.user.githubId, updateTermsDto.hasAcceptedTerms);
49
  }
50
  // Fetch all customers
51
  @Get()
52
  @UseGuards(JwtAuthGuard, AdminGuard)
53
  @ApiBearerAuth()
54
  @ApiOperation({ summary: 'Get all customers (Only for admin)' })
55
  @ApiResponse({
56
    status: 200,
57
    description: 'List of customers',
58
    examples: {
59
      'application/json': {
60
        summary: 'Example of a list of customers',
61
        value: [
62
          {
63
            githubId: '169550',
64
            username: 'three-musketeers',
0 ignored issues
show
introduced by
Define a constant instead of duplicating this literal 3 times.
Loading history...
65
            email: 'dasthreemusketö[email protected]',
0 ignored issues
show
introduced by
Define a constant instead of duplicating this literal 3 times.
Loading history...
66
            roles: ['user'],
67
            hasAcceptedTerms: false,
68
            avatarUrl: 'https://avatars.githubusercontent.com/u/169550?v=4',
0 ignored issues
show
introduced by
Define a constant instead of duplicating this literal 3 times.
Loading history...
69
            createdAt: '2024-12-01T05:01:01.000Z',
0 ignored issues
show
introduced by
Define a constant instead of duplicating this literal 3 times.
Loading history...
70
            updatedAt: '2024-12-07T18:30:30.000Z',
0 ignored issues
show
introduced by
Define a constant instead of duplicating this literal 3 times.
Loading history...
71
          },
72
          {
73
            githubId: '169550',
74
            username: 'three-musketeers',
75
            email: 'dasthreemusketö[email protected]',
76
            roles: ['user'],
77
            hasAcceptedTerms: false,
78
            avatarUrl: 'https://avatars.githubusercontent.com/u/169550?v=4',
79
            createdAt: '2024-12-01T05:01:01.000Z',
80
            updatedAt: '2024-12-07T18:30:30.000Z',
81
          },
82
        ],
83
      },
84
    },
85
  })
86
  @ApiResponse({
87
    status: 401,
88
    description: 'Unauthorized. Authentication required',
89
  })
90
  @ApiResponse({
91
    status: 403,
92
    description: 'Forbidden. Admin access required',
0 ignored issues
show
introduced by
Define a constant instead of duplicating this literal 4 times.
Loading history...
93
  })
94 5
  async getAllCustomers() {
95
    // return {userid: "hej1"};
96
    return await this.usersService.findAll();
97
  }
98
  // Fetch a customer by ID
99
  @Get(':githubId')
100
  @UseGuards(JwtAuthGuard, AdminGuard)
101
  @ApiBearerAuth()
102
  @ApiOperation({ summary: 'Get customer by id (Only for admin)' })
103
  @ApiResponse({
104
    status: 200,
105
    description: 'Customer details returned by id',
106
    examples: {
107
      'application/json': {
108
        summary: 'Example of a customer',
109
        value: {
110
          githubId: '169550',
111
          username: 'three-musketeers',
112
          email: 'dasthreemusketö[email protected]',
113
          roles: ['user'],
114
          hasAcceptedTerms: false,
115
          avatarUrl: 'https://avatars.githubusercontent.com/u/169550?v=4',
116
          createdAt: '2024-12-01T05:01:01.000Z',
117
          updatedAt: '2024-12-07T18:30:30.000Z',
118
        },
119
      },
120
    },
121
  })
122
  @ApiResponse({
123
    status: 404,
124
    description: 'Customer not found',
125
  })
126
  @ApiResponse({
127
    status: 401,
128
    description: 'Unauthorized. Authentication required',
129
  })
130
  @ApiResponse({
131
    status: 403,
132
    description: 'Forbidden. Admin access required',
133
  })
134 5
  async getCustomerById(@Param('githubId') githubId: string) {
135
    return await this.usersService.findById(githubId);
136
  }
137
  // Update a customer by ID
138
  @Patch(':githubId')
139
  @UseGuards(JwtAuthGuard, AdminGuard)
140
  @ApiBearerAuth()
141
  @ApiOperation({ summary: 'Update customer by githubId (Only for admin)' })
142
  @ApiParam({
143
    name: 'githubId',
144
    description: 'The GitHub ID of the user',
145
    example: '12345',
146
  })
147
  @ApiBody({
148
    description: 'The body containing the updated user details',
149
    type: UpdateUserDto,
150
  })
151
  @ApiResponse({
152
    status: 200,
153
    description: 'Customer updated successfully',
154
    examples: {
155
      'application/json': {
156
        summary: 'Example of a successful customer update',
157
        value: {
158
          githubId: '12345',
159
          email: '[email protected]',
160
          roles: ['admin'],
161
          hasAcceptedTerms: true,
162
        },
163
      },
164
    },
165
  })
166
  @ApiResponse({
167
    status: 400,
168
    description: 'Invalid input with error message',
169
  })
170
  @ApiResponse({
171
    status: 404,
172
    description: 'Customer not found',
173
  })
174
  @ApiResponse({
175
    status: 401,
176
    description: 'Unauthorized. Authentication required',
177
  })
178
  @ApiResponse({
179
    status: 403,
180
    description: 'Forbidden. Admin access required',
181
  })
182 5
  async updateCustomer(@Param('githubId') githubId: string, @Body() updateUserDto: UpdateUserDto) {
183
    return this.usersService.update(githubId, updateUserDto);
184
  }
185
186
  @Get(':githubId/account')
187
  @UseGuards(JwtAuthGuard)
188
  @ApiBearerAuth()
189
  @ApiOperation({
190
    summary: 'Get account balance and accumulated cost',
191
    description: 'Returns the users balance and accumulated monthly payment cost.',
192
  })
193
  @ApiResponse({
194
    status: 200,
195
    description: 'Account details retrieved successfully.',
196
  })
197 5
  async getAccountDetails(@Param('githubId') githubId: string, @Request() req: any,) {
0 ignored issues
show
introduced by
Delete ,
Loading history...
198
    const user = await this.usersService.findById(githubId);
199
    const authenticatedUser = req.user;
200
201
    // Only allow if the user is an admin or viewing their own account
202 3
    if (authenticatedUser.githubId !== githubId && !authenticatedUser.roles.includes('admin')) {
203
      throw new ForbiddenException("You are not allowed to view other users' accounts.");
204
    }
205
206
    return {
207
      balance: user.balance,
208
      accumulatedCost: user.accumulatedCost,
209
      isMonthlyPayment: user.isMonthlyPayment,
210
    };
211
  }
212
  @Patch(':githubId/adjust-funds')
213
  @UseGuards(JwtAuthGuard)
214
  @ApiBearerAuth()
215
  @ApiOperation({
216
    summary: 'Adjust user balance and payment mode',
217
    description: 'Set a new balance for the user and optionally toggle monthly payment mode.',
218
  })
219
  @ApiResponse({
220
    status: 200,
221
    description: 'User balance adjusted successfully',
222
  })
223
  @ApiResponse({
224
    status: 404,
225
    description: 'User not found',
226
  })
227
  @ApiResponse({
228
    status: 403,
229
    description: 'Forbidden. You cannot adjust other users unless you are an admin.',
230
  })
231 5
  async adjustFunds(
232
    @Param('githubId') githubId: string,
233
    @Body() adjustFundsDto: AdjustFundsDto,
234
    @Request() req: any,
235
  ) {
236
    const authenticatedUser = req.user;
237
238
    // Only allow if the user is an admin or adjusting their own account
239 3
    if (authenticatedUser.githubId !== githubId && !authenticatedUser.roles.includes('admin')) {
240
      throw new ForbiddenException("You are not allowed to adjust other users' accounts.");
241
    }
242
243
    return await this.usersService.adjustFunds(githubId, adjustFundsDto);
244
  }
245
246
  @Patch(':githubId/soft-delete')
247
  @UseGuards(JwtAuthGuard, AdminGuard)
248
  @ApiBearerAuth()
249
  @ApiOperation({ summary: 'Soft delete a user (Only for admin - set user role to inactive)' })
250
  @ApiResponse({
251
    status: 200,
252
    description: 'User soft-deleted successfully',
253
  })
254
  @ApiResponse({
255
    status: 404,
256
    description: 'User not found',
257
  })
258
  @ApiResponse({
259
    status: 403,
260
    description: 'Forbidden. Admin access required',
261
  })
262 5
  async softDeleteUser(@Param('githubId') githubId: string) {
263
    return await this.usersService.softDeleteUser(githubId);
264
  }
0 ignored issues
show
introduced by
Delete
Loading history...
265
266
}
267