• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

GEWIS / sudosos-backend / 25753937432

12 May 2026 09:17AM UTC coverage: 88.117% (-1.0%) from 89.089%
25753937432

push

github

web-flow
chore(deps): fix missing dependencies for running docs:dev (#911)

3925 of 4574 branches covered (85.81%)

Branch coverage included in aggregate %.

20093 of 22683 relevant lines covered (88.58%)

1125.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.42
/src/controller/user-notification-preference-controller.ts
1
/**
1✔
2
 *  SudoSOS back-end API service.
3
 *  Copyright (C) 2026 Study association GEWIS
4
 *
5
 *  This program is free software: you can redistribute it and/or modify
6
 *  it under the terms of the GNU Affero General Public License as published
7
 *  by the Free Software Foundation, either version 3 of the License, or
8
 *  (at your option) any later version.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU Affero General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU Affero General Public License
16
 *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
17
 *
18
 *  @license
19
 */
1✔
20

21
import BaseController, { BaseControllerOptions } from './base-controller';
22
import Policy from './policy';
23
import { RequestWithToken } from '../middleware/token-middleware';
24
import UserNotificationPreferenceService, {
25
  parseUserNotificationPreferenceFilters,
26
  UserNotificationPreferenceFilterParams,
27
} from '../service/user-notification-preference-service';
28
import { parseRequestPagination } from '../helpers/pagination';
29
import log4js, { Logger } from 'log4js';
30
import { Response } from 'express';
31
import UserNotificationPreference from '../entity/notifications/user-notification-preference';
32
import {
33
  UserNotificationPreferenceUpdateParams,
34
  UserNotificationPreferenceUpdateRequest,
35
} from './request/user-notification-preference-request';
36
import { asNumber } from '../helpers/validators';
37

38
/**
1✔
39
 * This is the module page of the notification-service.
40
 *
41
 * @module notifications
42
 *
43
 */
1✔
44

45
export default class UserNotificationController extends BaseController {
1✔
46
  /**
1✔
47
     * Reference to the logger instance
48
     */
1✔
49
  private logger: Logger = log4js.getLogger('UserNotificationPreferenceController');
1✔
50

51
  /**
1✔
52
     * Creates a new UserNotificationPreference controller instance
53
     * @param options - The options passed to the base controller.
54
     */
1✔
55
  public constructor(options: BaseControllerOptions) {
1✔
56
    super(options);
2✔
57
    this.configureLogger(this.logger);
2✔
58
  }
2✔
59

60
  /**
1✔
61
     * @inheritDoc
62
     */
1✔
63
  getPolicy(): Policy {
1✔
64
    return {
2✔
65
      '/': {
2✔
66
        GET: {
2✔
67
          policy: async (req) => this.roleManager.can(req.token.roles, 'get', await UserNotificationController.filterRelation(req), 'UserNotificationPreference', ['*']),
2✔
68
          handler: this.getAllUserNotificationPreferences.bind(this),
2✔
69
        },
2✔
70
      },
2✔
71
      '/:id(\\d+)': {
2✔
72
        GET: {
2✔
73
          policy: async (req) => this.roleManager.can(req.token.roles, 'get', await UserNotificationController.getRelation(req), 'UserNotificationPreference', ['*']),
2✔
74
          handler: this.getSingleUserNotificationPreference.bind(this),
2✔
75
        },
2✔
76
        PATCH: {
2✔
77
          policy: async (req) => this.roleManager.can(req.token.roles, 'update', await UserNotificationController.getRelation(req), 'UserNotificationPreference', ['*']),
2✔
78
          handler: this.updateUserNotificationPreference.bind(this),
2✔
79
        },
2✔
80
      },
2✔
81
    };
2✔
82
  }
2✔
83

84
  /**
1✔
85
     * GET /user-notification-preferences
86
     * @summary Returns all user notification preferences in the system.
87
     * @operationId getAllUserNotificationPreferences
88
     * @tags userNotificationPreferences - Operations of the user notification preference controller
89
     * @security JWT
90
     * @param {integer} userNotificationPreferenceId.query - Filter on the user notification preference id
91
     * @param {integer} userId.query - Filter on the user id
92
     * @param {string} type.query - Filter on the notification type
93
     * @param {string} channel.query - Filter on the notification channel
94
     * @param {boolean} enabled.query - Filter on enabled preferences
95
     * @return {PaginatedUserNotificationPreferenceResponse} 200 - All existing invoices
96
     * @return {string} 400 - Validation error
97
     * @return {string} 500 - Internal server error
98
     */
1✔
99
  public async getAllUserNotificationPreferences(req: RequestWithToken, res: Response): Promise<void> {
1✔
100
    const { body } = req;
3✔
101
    this.logger.trace('Get all user notification preferences', body, 'by user', req.token.user);
3✔
102

103
    let take;
3✔
104
    let skip;
3✔
105
    let filters: UserNotificationPreferenceFilterParams;
3✔
106

107
    try {
3✔
108
      const pagination = parseRequestPagination(req);
3✔
109
      filters = parseUserNotificationPreferenceFilters(req);
3✔
110
      take = pagination.take;
3✔
111
      skip = pagination.skip;
3✔
112
    } catch (e) {
3!
113
      res.status(400).send(e.message);
×
114
      return;
×
115
    }
×
116

117
    try {
3✔
118
      const userNotificationPreferences = await new UserNotificationPreferenceService().getPaginatedUserNotificationPreference(
3✔
119
        filters, { take, skip },
3✔
120
      );
121
      res.json(userNotificationPreferences);
3✔
122
    } catch (e) {
3!
123
      this.logger.error('Could not return all user notification preferences', e);
×
124
      res.status(500).json('Internal server error');
×
125
    }
×
126
  }
3✔
127

128
  /**
1✔
129
     * GET /user-notification-preferences/{id}
130
     * @summary Return a single user notification preferences in the system.
131
     * @operationId getSingleUserNotificationPreference
132
     * @tags userNotificationPreferences - Operations of the user notification preference controller
133
     * @security JWT
134
     * @param {integer} id.path.required - The id of the user notification preference
135
     * @return {BaseUserNotificationPreferenceResponse} 200 - The existing user notification preference
136
     * @return {string} 404 - User notification preference not found
137
     * @return {string} 500 - Internal server error
138
     */
1✔
139
  public async getSingleUserNotificationPreference(req: RequestWithToken, res: Response): Promise<void> {
1✔
140
    const { id } = req.params;
4✔
141
    const userNotificationPreferenceId = parseInt(id, 10);
4✔
142
    this.logger.trace('Get user notification preferences', userNotificationPreferenceId, 'by user', req.token.user);
4✔
143

144
    try {
4✔
145
      const userNotificationPreferences: UserNotificationPreference[] = await new UserNotificationPreferenceService().getUserNotificationPreferences(
4✔
146
        { userNotificationPreferenceId },
4✔
147
      );
148

149
      const userNotificationPreference = userNotificationPreferences[0];
4✔
150
      if (!userNotificationPreference) {
4✔
151
        res.status(404).send('Unknown user notification preference ID.');
1✔
152
        return;
1✔
153
      }
1✔
154

155
      const response = UserNotificationPreferenceService.asResponse(userNotificationPreference);
3✔
156

157
      res.json(response);
3✔
158
    } catch (e) {
4!
159
      this.logger.error('Could not return user notification preferences', e);
×
160
      res.status(500).json('Internal server error');
×
161
    }
×
162
  }
4✔
163

164
  /**
1✔
165
     * PATCH /user-notification-preferences/{id}
166
     * @summary Update a user notification preferences in the system.
167
     * @operationId updateUserNotificationPreference
168
     * @tags userNotificationPreferences - Operations of the user notification preference controller
169
     * @security JWT
170
     * @param {integer} id.path.required - The id of the user notification preference
171
     * @param {UserNotificationPreferenceUpdateRequest} request.body.required -
172
     * The user notification preference update to process
173
     * @return {BaseUserNotificationPreferenceResponse} 200 - The existing user notification preference
174
     * @return {string} 404 - User notification preference not found
175
     * @return {string} 500 - Internal server error
176
     */
1✔
177
  public async updateUserNotificationPreference(req: RequestWithToken, res: Response): Promise<void> {
1✔
178
    const body  = req.body as UserNotificationPreferenceUpdateRequest;
4✔
179
    const { id } = req.params;
4✔
180
    const userNotificationPreferenceId = parseInt(id, 10);
4✔
181
    this.logger.trace('Update user notification preferences', userNotificationPreferenceId, 'by user', req.token.user);
4✔
182

183
    try {
4✔
184
      const params: UserNotificationPreferenceUpdateParams = {
4✔
185
        ...body,
4✔
186
        userNotificationPreferenceId,
4✔
187
      };
4✔
188

189
      const userNotificationPreference = await new UserNotificationPreferenceService().updateUserNotificationPreference(
4✔
190
        params,
4✔
191
      );
192

193
      if (!userNotificationPreference) {
4✔
194
        res.status(404).send('Unknown user notification preference ID.');
1✔
195
        return;
1✔
196
      }
1✔
197

198
      const response = UserNotificationPreferenceService.asResponse(userNotificationPreference);
3✔
199

200
      res.json(response);
3✔
201
    } catch (e) {
4!
202
      this.logger.error('Could not update user notification preferences', e);
×
203
      res.status(500).json('Internal server error');
×
204
    }
×
205
  }
4✔
206

207
  /**
1✔
208
   * Determines the relation between the user and the notification preference.
209
   * - Returns own if user is connected to the notification preference
210
   * - Returns all otherwise.
211
   * @param req - Express request with user token and filters in query params.
212
   * @returns 'own' | 'all'
213
   */
1✔
214
  static async filterRelation(
1✔
215
    req: RequestWithToken,
3✔
216
  ): Promise<'own' | 'all'> {
3✔
217
    try {
3✔
218
      const reqUserId = req.token.user.id;
3✔
219
      const { userId } = parseUserNotificationPreferenceFilters(req);
3✔
220

221
      if (reqUserId === userId) {
3!
222
        return 'own';
×
223
      }
×
224

225
      return 'all';
3✔
226
    } catch (e) {
3!
227
      return 'all';
×
228
    }
×
229
  }
3✔
230

231
  /**
1✔
232
   * Determines which credentials are needed to get user notification preferences
233
   *    all if user is not connected to user notification preference
234
   *    own if user is connected to the notification preference
235
   * @param req - Request with notification preference id as param
236
   * @return whether notification preference is connected to user token
237
   */
1✔
238
  static async getRelation(
1✔
239
    req: RequestWithToken,
8✔
240
  ): Promise<'all' | 'own'> {
8✔
241

242
    const preference = await UserNotificationPreference.findOne({
8✔
243
      where: { id: asNumber(req.params.id) },
8✔
244
      relations: ['user'],
8✔
245
    });
8✔
246

247
    if (!preference) return 'all';
8✔
248

249
    if (preference.userId === req.token.user.id) return 'own';
8✔
250

251
    return 'all';
4✔
252
  }
4✔
253
}
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc