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

GEWIS / sudosos-backend / 15664172639

15 Jun 2025 02:23PM UTC coverage: 85.087% (-0.007%) from 85.094%
15664172639

Pull #471

github

web-flow
Merge 2cfe2a825 into 5d7267112
Pull Request #471: Add `authentication` docs

1281 of 1565 branches covered (81.85%)

Branch coverage included in aggregate %.

1 of 2 new or added lines in 1 file covered. (50.0%)

33 existing lines in 3 files now uncovered.

6929 of 8084 relevant lines covered (85.71%)

1081.38 hits per line

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

88.57
/src/controller/authentication-secure-controller.ts
1
/**
2
 *  SudoSOS back-end API service.
3
 *  Copyright (C) 2024  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
 */
20

21
/**
22
 * This is the module page of authentication-secure-controller.
23
 *
24
 * @module authentication
25
 */
26

27
import { Response } from 'express';
28
import log4js, { Logger } from 'log4js';
2✔
29
import BaseController, { BaseControllerOptions } from './base-controller';
2✔
30
import Policy from './policy';
31
import { RequestWithToken } from '../middleware/token-middleware';
32
import AuthenticationService from '../service/authentication-service';
2✔
33
import TokenHandler from '../authentication/token-handler';
34
import User from '../entity/user/user';
2✔
35
import PointOfSaleController from './point-of-sale-controller';
2✔
36
import PointOfSale from '../entity/point-of-sale/point-of-sale';
2✔
37
import ServerSettingsStore from '../server-settings/server-settings-store';
2✔
38
import { ISettings } from '../entity/server-setting';
39

40
export default class AuthenticationSecureController extends BaseController {
2✔
41
  private logger: Logger = log4js.getLogger('AuthenticationController');
2✔
42

43
  /**
44
   * Reference to the token handler of the application.
45
   */
46
  protected tokenHandler: TokenHandler;
47

48
  /**
49
   * Creates a new banner controller instance.
50
   * @param options - The options passed to the base controller.
51
   * @param tokenHandler - The token handler for creating signed tokens.
52
   */
53
  public constructor(options: BaseControllerOptions, tokenHandler: TokenHandler) {
54
    super(options);
2✔
55
    this.logger.level = process.env.LOG_LEVEL;
2✔
56
    this.tokenHandler = tokenHandler;
2✔
57
  }
58

59
  /**
60
   * @inheritdoc
61
   */
62
  public getPolicy(): Policy {
63
    return {
2✔
64
      '/refreshToken': {
65
        GET: {
66
          policy: async () => Promise.resolve(true),
1✔
67
          handler: this.refreshToken.bind(this),
68
          restrictions: { lesser: true, acceptedTOS: false },
69
        },
70
      },
71
      '/pointofsale/:id(\\d+)': {
72
        GET: {
73
          policy: async (req) => this.roleManager.can(req.token.roles, 'authenticate', await PointOfSaleController.getRelation(req), 'User', ['pointOfSale']),
6✔
74
          handler: this.authenticatePointOfSale.bind(this),
75
        },
76
      },
77
    };
78
  }
79

80
  /**
81
   * GET /authentication/refreshToken
82
   * @summary Get a new JWT token, lesser if the existing token is also lesser
83
   * @operationId refreshToken
84
   * @tags authenticate - Operations of the authentication controller
85
   * @security JWT
86
   * @return {AuthenticationResponse} 200 - The created json web token.
87
   */
88
  private async refreshToken(req: RequestWithToken, res: Response): Promise<void> {
89
    this.logger.trace('Refresh token for user', req.token.user.id);
1✔
90

91
    try {
1✔
92
      const user = await User.findOne({ where: { id: req.token.user.id } });
1✔
93
      const token = await new AuthenticationService().getSaltedToken(user, {
1✔
94
        roleManager: this.roleManager,
95
        tokenHandler: this.tokenHandler,
96
      }, req.token.lesser);
97
      res.json(token);
1✔
98
    } catch (error) {
UNCOV
99
      this.logger.error('Could not create token:', error);
×
UNCOV
100
      res.status(500).json('Internal server error.');
×
101
    }
102
  }
103

104
  /**
105
   * GET /authentication/pointofsale/{id}
106
   * @summary Get a JWT token for the given POS
107
   * @operationId authenticatePointOfSale
108
   * @tags authenticate - Operations of the authentication controller
109
   * @security JWT
110
   * @param {integer} id.path.required - The id of the user
111
   * @return {AuthenticationResponse} 200 - The created json web token.
112
   * @return {string} 404 - Point of sale not found
113
   * @return {string} 500 - Internal server error
114
   */
115
  private async authenticatePointOfSale(req: RequestWithToken, res: Response): Promise<void> {
116
    this.logger.trace('Authenticate point of sale', req.params.id, 'by user', req.token.user.id);
5✔
117

118
    try {
5✔
119
      const pointOfSaleId = Number(req.params.id);
5✔
120
      const pointOfSale = await PointOfSale.findOne({ where: { id: pointOfSaleId }, relations: { user: true } });
5✔
121
      if (!pointOfSale) {
5✔
122
        res.status(404).json('Point of sale not found.');
2✔
123
        return;
2✔
124
      }
125

126
      const expiry = ServerSettingsStore.getInstance().getSetting('jwtExpiryPointOfSale') as ISettings['jwtExpiryPointOfSale'];
3✔
127
      const token = await new AuthenticationService().getSaltedToken(pointOfSale.user, {
3✔
128
        roleManager: this.roleManager,
129
        tokenHandler: this.tokenHandler,
130
      }, false, undefined, expiry);
131
      res.json(token);
3✔
132
    } catch (error) {
UNCOV
133
      this.logger.error('Could not create token:', error);
×
UNCOV
134
      res.status(500).json('Internal server error.');
×
135
    }
136
  }
137
}
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