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

GEWIS / sudosos-backend / 27712399675

17 Jun 2026 06:54PM UTC coverage: 91.227% (-0.8%) from 92.023%
27712399675

Pull #735

github

web-flow
Merge e1b5512d3 into 29d0df55c
Pull Request #735: feat: enhance product/banner image validation (#14)

4171 of 4767 branches covered (87.5%)

Branch coverage included in aggregate %.

65 of 72 new or added lines in 4 files covered. (90.28%)

227 existing lines in 4 files now uncovered.

21555 of 23433 relevant lines covered (91.99%)

837.52 hits per line

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

27.12
/src/controller/stripe-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
/**
1✔
22
 * This is the module page of the stripe-controller.
23
 *
24
 * @module stripe
25
 */
1✔
26

27
import log4js, { Logger } from 'log4js';
28
import { Response } from 'express';
29
import Dinero from 'dinero.js';
30
import BaseController, { BaseControllerOptions } from './base-controller';
31
import Policy from './policy';
32
import { RequestWithToken } from '../middleware/token-middleware';
33
import StripeService from '../service/stripe-service';
34
import { StripeRequest } from './request/stripe-request';
35
import BalanceService from '../service/balance-service';
36

37
export default class StripeController extends BaseController {
1✔
38
  private logger: Logger = log4js.getLogger('StripeController');
1✔
39

40
  private stripeService: StripeService;
41

42
  /**
1✔
43
   * Create a new stripe controller instance
44
   * @param options
45
   */
1✔
46
  public constructor(options: BaseControllerOptions) {
1✔
UNCOV
47
    super(options);
×
UNCOV
48
    this.configureLogger(this.logger);
×
UNCOV
49
    this.stripeService = new StripeService();
×
UNCOV
50
  }
×
51

52
  /**
1✔
53
   * @inheritDoc
54
   */
1✔
55
  public getPolicy(): Policy {
1✔
UNCOV
56
    return {
×
UNCOV
57
      '/deposit': {
×
UNCOV
58
        POST: {
×
UNCOV
59
          policy: async (req) => this.roleManager.can(
×
UNCOV
60
            req.token.roles, 'create', 'all', 'StripeDeposit', ['*'],
×
61
          ),
UNCOV
62
          handler: this.createStripeDeposit.bind(this),
×
UNCOV
63
          body: { modelName: 'StripeRequest' },
×
UNCOV
64
        },
×
UNCOV
65
      },
×
UNCOV
66
    };
×
UNCOV
67
  }
×
68

69
  /**
1✔
70
   * POST /stripe/deposit
71
   * @summary Start the stripe deposit flow
72
   * @operationId deposit
73
   * @tags stripe - Operations of the stripe controller
74
   * @param {StripeRequest} request.body.required - The deposit that should be created
75
   * @return {StripePaymentIntentResponse} 200 - Payment Intent information
76
   * @return {string} 500 - Internal server error
77
   * @security JWT
78
   */
1✔
79
  public async createStripeDeposit(req: RequestWithToken, res: Response): Promise<void> {
1✔
UNCOV
80
    this.logger.trace('Create a new stripe deposit by user', req.token.user);
×
UNCOV
81
    const request = req.body as StripeRequest;
×
82

UNCOV
83
    try {
×
UNCOV
84
      const amount = Dinero(request.amount);
×
UNCOV
85
      const balance = await new BalanceService().getBalance(req.token.user.id);
×
86

UNCOV
87
      // Check if top-up satisfies minimum in accordance with TOS.
×
UNCOV
88
      if (!StripeService.validateStripeRequestMinimumAmount(balance, request)) {
×
UNCOV
89
        res.status(422).json({ error: 'Top-up amount is too low' });
×
UNCOV
90
        return;
×
UNCOV
91
      }
×
92

UNCOV
93
      // Check if top-up satisfies maximum in accordance with TOS.
×
UNCOV
94
      if (!StripeService.validateStripeRequestMaximumAmount(balance, request)) {
×
UNCOV
95
        res.status(422).json({ error: 'Top-up amount is too high' });
×
UNCOV
96
        return;
×
UNCOV
97
      }
×
98

UNCOV
99
      const { deposit, clientSecret } = await this.stripeService.createStripePaymentIntent(req.token.user, amount);
×
UNCOV
100
      res.status(200).json({
×
UNCOV
101
        id: deposit.id,
×
UNCOV
102
        createdAt: deposit.createdAt.toISOString(),
×
UNCOV
103
        updatedAt: deposit.updatedAt.toISOString(),
×
UNCOV
104
        stripeId: deposit.stripePaymentIntent.stripeId,
×
UNCOV
105
        clientSecret,
×
UNCOV
106
      });
×
UNCOV
107
    } catch (error) {
×
108
      this.logger.error('Could not create Stripe payment intent:', error);
×
109
      res.status(500).send('Internal server error.');
×
110
    }
×
UNCOV
111
  }
×
112
}
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