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

GEWIS / sudosos-backend / 15861584900

24 Jun 2025 09:10PM UTC coverage: 85.087% (-0.007%) from 85.094%
15861584900

Pull #471

github

web-flow
Merge bb6d18828 into 26e0bdf71
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%)

12 existing lines in 2 files now uncovered.

6929 of 8084 relevant lines covered (85.71%)

1081.36 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
 * @module Authentication
23
 */
24

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

38
/**
39
 * The authentication secure controller handles all requests related to authentication that require the user to be authenticated.
40
 *
41
 * Mostly used for refreshing tokens and authenticating Point of Sales.
42
 */
43
export default class AuthenticationSecureController extends BaseController {
2✔
44
  private logger: Logger = log4js.getLogger('AuthenticationController');
2✔
45

46
  /**
47
   * Reference to the token handler of the application.
48
   */
49
  protected tokenHandler: TokenHandler;
50

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

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

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

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

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

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

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