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

GEWIS / sudosos-backend / 23944264587

03 Apr 2026 11:12AM UTC coverage: 89.102% (+0.04%) from 89.064%
23944264587

push

github

web-flow
refactor: centralize env config setup (#835)

1828 of 2248 branches covered (81.32%)

Branch coverage included in aggregate %.

242 of 252 new or added lines in 73 files covered. (96.03%)

1 existing line in 1 file now uncovered.

9414 of 10369 relevant lines covered (90.79%)

1014.39 hits per line

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

94.9
/src/database/database.ts
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
 */
20

21
/**
22
 * This is the module page of the database.
23
 *
24
 * @module internal/database
25
 */
26

27
import {
2✔
28
  DataSource,
29
} from 'typeorm';
30
import fs from 'fs';
2✔
31
import User from '../entity/user/user';
2✔
32
import Product from '../entity/product/product';
2✔
33
import SubTransaction from '../entity/transactions/sub-transaction';
2✔
34
import Transaction from '../entity/transactions/transaction';
2✔
35
import ProductCategory from '../entity/product/product-category';
2✔
36
import SubTransactionRow from '../entity/transactions/sub-transaction-row';
2✔
37
import PointOfSale from '../entity/point-of-sale/point-of-sale';
2✔
38
import Container from '../entity/container/container';
2✔
39
import VoucherGroup from '../entity/user/voucher-group';
2✔
40
import LocalUser from '../entity/user/local-user';
2✔
41
import MemberUser from '../entity/user/member-user';
2✔
42
import UserVoucherGroup from '../entity/user/user-voucher-group';
2✔
43
import EanAuthenticator from '../entity/authenticator/ean-authenticator';
2✔
44
import OrganMembership from '../entity/organ/organ-membership';
2✔
45
import NfcAuthenticator from '../entity/authenticator/nfc-authenticator';
2✔
46
import PinAuthenticator from '../entity/authenticator/pin-authenticator';
2✔
47
import Banner from '../entity/banner';
2✔
48
import Transfer from '../entity/transactions/transfer';
2✔
49
import ProductRevision from '../entity/product/product-revision';
2✔
50
import ContainerRevision from '../entity/container/container-revision';
2✔
51
import PointOfSaleRevision from '../entity/point-of-sale/point-of-sale-revision';
2✔
52
import ProductOrdering from '../entity/point-of-sale/product-ordering';
2✔
53
import Balance from '../entity/transactions/balance';
2✔
54
import InvoiceUser from '../entity/user/invoice-user';
2✔
55
import Invoice from '../entity/invoices/invoice';
2✔
56
import InvoiceStatus from '../entity/invoices/invoice-status';
2✔
57
import BaseFile from '../entity/file/base-file';
2✔
58
import ProductImage from '../entity/file/product-image';
2✔
59
import BannerImage from '../entity/file/banner-image';
2✔
60
import StripeDeposit from '../entity/stripe/stripe-deposit';
2✔
61
import StripePaymentIntentStatus from '../entity/stripe/stripe-payment-intent-status';
2✔
62
import PayoutRequest from '../entity/transactions/payout/payout-request';
2✔
63
import PayoutRequestStatus from '../entity/transactions/payout/payout-request-status';
2✔
64
import LDAPAuthenticator from '../entity/authenticator/ldap-authenticator';
2✔
65
import AssignedRole from '../entity/rbac/assigned-role';
2✔
66
import VatGroup from '../entity/vat-group';
2✔
67
import LocalAuthenticator from '../entity/authenticator/local-authenticator';
2✔
68
import ResetToken from '../entity/authenticator/reset-token';
2✔
69
import { DataSourceOptions } from 'typeorm/data-source/DataSourceOptions';
70
import KeyAuthenticator from '../entity/authenticator/key-authenticator';
2✔
71
import Fine from '../entity/fine/fine';
2✔
72
import FineHandoutEvent from '../entity/fine/fineHandoutEvent';
2✔
73
import UserFineGroup from '../entity/fine/userFineGroup';
2✔
74
import Event from '../entity/event/event';
2✔
75
import EventShiftAnswer from '../entity/event/event-shift-answer';
2✔
76
import EventShift from '../entity/event/event-shift';
2✔
77
import { TransactionSubscriber, TransferSubscriber } from '../subscriber';
2✔
78
import InvoicePdf from '../entity/file/invoice-pdf';
2✔
79
import PayoutRequestPdf from '../entity/file/payout-request-pdf';
2✔
80
import Role from '../entity/rbac/role';
2✔
81
import Permission from '../entity/rbac/permission';
2✔
82
import RoleUserType from '../entity/rbac/role-user-type';
2✔
83
import WriteOff from '../entity/transactions/write-off';
2✔
84
import ServerSetting from '../entity/server-setting';
2✔
85
import StripePaymentIntent from '../entity/stripe/stripe-payment-intent';
2✔
86
import SellerPayout from '../entity/transactions/payout/seller-payout';
2✔
87
import SellerPayoutPdf from '../entity/file/seller-payout-pdf';
2✔
88
import { InitialSQLMigration1743601882766 } from '../migrations/1743601882766-initial-database';
2✔
89
import WriteOffPdf from '../entity/file/write-off-pdf';
2✔
90
import QRAuthenticator from '../entity/authenticator/qr-authenticator';
2✔
91
import { QrAuthenticator1743601882766 } from '../migrations/1743601882766-qr-authenticator';
2✔
92
import { MemberAuthenticator1761324427011 } from '../migrations/1761324427011-member-authenticator';
2✔
93
import { AddOrganMembershipIndex1761328648026 } from '../migrations/1761328648026-add-organ-membership-index';
2✔
94
import InactiveAdministrativeCost from '../entity/transactions/inactive-administrative-cost';
2✔
95
import {
2✔
96
  UserAdministrativeCost1761845457283,
97
} from '../migrations/1761845457283-user-administrative-cost';
98
import NotificationLog from '../entity/notifications/notification-log';
2✔
99
import UserNotificationPreference from '../entity/notifications/user-notification-preference';
2✔
100
import { RenameGewisToExternal1763399087409 } from '../migrations/1763399087409-rename-gewis-to-external';
2✔
101
import { UserNotificationPreference1764615514906 } from '../migrations/1764615514906-user-notification-preference';
2✔
102
import Wrapped from '../entity/wrapped';
2✔
103
import WrappedOrganMember from '../entity/wrapped/wrapped-organ-member';
2✔
104
import { AddWrappedTable1764842063654 } from '../migrations/1764842063654-add-wrapped-table';
2✔
105
import { AddWrappedOrganMember1765826596888 } from '../migrations/1765826596888-add-wrapped-organ-member';
2✔
106
import UserSetting from '../entity/user-setting';
2✔
107
import { UserSetting1768697568707 } from '../migrations/1768697568707-user-setting';
2✔
108
import {
2✔
109
  RemoveCreditTransferFromInactiveAdministrativeCost1769005123365,
110
} from '../migrations/1769005123365-remove-credit-transfer-from-inactive-administrative-cost';
111
import { AddLastSeenToUser1769000095806 } from '../migrations/1769000095806-add-last-seen-to-user';
2✔
112
import Config from '../config';
2✔
113

114
function getDataSourceOptions(): DataSourceOptions {
115
  const config = Config.get();
124✔
116

117
  if (config.app.isTest) {
124✔
118
    console.log('TYPEORM_CONNECTION:', config.database.connection);
121✔
119
  }
120

121
  const options = {
124✔
122
    host: config.database.host,
123
    port: config.database.port,
124
    database: config.database.database,
125
    type: config.database.connection,
126
    username: config.database.username,
127
    password: config.database.password,
128
    ...(config.database.sslEnabled ? {
124!
129
      ssl: {
130
        ca: fs.readFileSync(config.database.sslCaCertsPath),
131
      },
132
    } : {}),
133
    synchronize: config.database.synchronize,
134
    logging: config.database.logging,
135
    migrations: [
136
      InitialSQLMigration1743601882766,
137
      QrAuthenticator1743601882766,
138
      MemberAuthenticator1761324427011,
139
      AddOrganMembershipIndex1761328648026,
140
      UserAdministrativeCost1761845457283,
141
      RenameGewisToExternal1763399087409,
142
      UserNotificationPreference1764615514906,
143
      AddWrappedTable1764842063654,
144
      AddWrappedOrganMember1765826596888,
145
      UserSetting1768697568707,
146
      RemoveCreditTransferFromInactiveAdministrativeCost1769005123365,
147
      AddLastSeenToUser1769000095806,
148
    ],
149
    extra: {
150
      authPlugins: {
NEW
151
        mysql_clear_password: () => () => Buffer.from(`${config.database.password ?? ''}\0`),
×
152
      },
153
    },
154
    poolSize: 4,
155
    entities: [
156
      ServerSetting,
157
      ProductCategory,
158
      VatGroup,
159
      Product,
160
      ProductRevision,
161
      Container,
162
      ContainerRevision,
163
      PointOfSale,
164
      PointOfSaleRevision,
165
      Transfer,
166
      InactiveAdministrativeCost,
167
      StripeDeposit,
168
      StripePaymentIntent,
169
      StripePaymentIntentStatus,
170
      PayoutRequest,
171
      PayoutRequestPdf,
172
      PayoutRequestStatus,
173
      SellerPayout,
174
      SellerPayoutPdf,
175
      Fine,
176
      FineHandoutEvent,
177
      UserFineGroup,
178
      Transaction,
179
      SubTransaction,
180
      SubTransactionRow,
181
      VoucherGroup,
182
      User,
183
      LocalUser,
184
      MemberUser,
185
      UserVoucherGroup,
186
      EanAuthenticator,
187
      OrganMembership,
188
      NfcAuthenticator,
189
      KeyAuthenticator,
190
      PinAuthenticator,
191
      LocalAuthenticator,
192
      LDAPAuthenticator,
193
      Banner,
194
      ProductOrdering,
195
      Balance,
196
      InvoiceUser,
197
      Invoice,
198
      InvoiceStatus,
199
      InvoicePdf,
200
      BaseFile,
201
      ProductImage,
202
      BannerImage,
203
      Role,
204
      RoleUserType,
205
      Permission,
206
      AssignedRole,
207
      ResetToken,
208
      Event,
209
      EventShift,
210
      EventShiftAnswer,
211
      Wrapped,
212
      WrappedOrganMember,
213
      WriteOff,
214
      WriteOffPdf,
215
      QRAuthenticator,
216
      NotificationLog,
217
      UserNotificationPreference,
218
      UserSetting,
219
    ],
220
    subscribers: [
221
      TransactionSubscriber,
222
      TransferSubscriber,
223
    ],
224
  };
225

226
  return options as DataSourceOptions;
124✔
227
}
228

229
function getBootstrapDataSourceOptions(): DataSourceOptions {
230
  return {
2✔
231
    type: 'sqlite',
232
    database: ':memory:',
233
    synchronize: true,
234
    logging: false,
235
    migrations: [],
236
    entities: [],
237
    subscribers: [],
238
  };
239
}
240

241
export let AppDataSource = new DataSource(getBootstrapDataSourceOptions());
2✔
242

243
const Database = {
2✔
244
  initialize: async () => {
245
    if (AppDataSource.isInitialized) return AppDataSource;
124!
246
    AppDataSource = new DataSource(getDataSourceOptions());
124✔
247
    return AppDataSource.initialize();
124✔
248
  },
249
};
250

251
export default Database;
2✔
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