@stamhoofd/backend 2.39.1 → 2.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/eslint.config.mjs +5 -0
- package/index.ts +81 -74
- package/jest.config.cjs +10 -0
- package/migrations.ts +16 -14
- package/package.json +11 -11
- package/src/crons/clear-excel-cache.test.ts +48 -50
- package/src/crons/clear-excel-cache.ts +18 -18
- package/src/crons/setup-steps.ts +2 -2
- package/src/crons.ts +325 -306
- package/src/decoders/StringArrayDecoder.ts +7 -7
- package/src/decoders/StringNullableDecoder.ts +1 -2
- package/src/email-recipient-loaders/members.ts +22 -22
- package/src/endpoints/admin/memberships/ChargeMembershipsEndpoint.ts +8 -9
- package/src/endpoints/admin/memberships/GetChargeMembershipsSummaryEndpoint.ts +39 -40
- package/src/endpoints/admin/organizations/GetOrganizationsCountEndpoint.ts +8 -8
- package/src/endpoints/admin/organizations/GetOrganizationsEndpoint.ts +44 -45
- package/src/endpoints/admin/organizations/PatchOrganizationsEndpoint.ts +58 -57
- package/src/endpoints/auth/CreateAdminEndpoint.ts +48 -45
- package/src/endpoints/auth/CreateTokenEndpoint.test.ts +31 -31
- package/src/endpoints/auth/CreateTokenEndpoint.ts +146 -147
- package/src/endpoints/auth/DeleteTokenEndpoint.ts +7 -7
- package/src/endpoints/auth/DeleteUserEndpoint.ts +15 -15
- package/src/endpoints/auth/ForgotPasswordEndpoint.ts +17 -18
- package/src/endpoints/auth/GetOtherUserEndpoint.ts +9 -10
- package/src/endpoints/auth/GetUserEndpoint.test.ts +32 -35
- package/src/endpoints/auth/GetUserEndpoint.ts +5 -6
- package/src/endpoints/auth/PatchApiUserEndpoint.ts +35 -33
- package/src/endpoints/auth/PatchUserEndpoint.ts +55 -52
- package/src/endpoints/auth/PollEmailVerificationEndpoint.ts +9 -9
- package/src/endpoints/auth/RetryEmailVerificationEndpoint.ts +8 -8
- package/src/endpoints/auth/SignupEndpoint.ts +37 -36
- package/src/endpoints/auth/VerifyEmailEndpoint.ts +29 -28
- package/src/endpoints/global/addresses/SearchRegionsEndpoint.ts +33 -33
- package/src/endpoints/global/addresses/ValidateAddressEndpoint.ts +7 -7
- package/src/endpoints/global/caddy/CheckDomainCertEndpoint.ts +37 -37
- package/src/endpoints/global/email/CreateEmailEndpoint.ts +30 -30
- package/src/endpoints/global/email/GetEmailAddressEndpoint.ts +13 -13
- package/src/endpoints/global/email/GetEmailEndpoint.ts +13 -13
- package/src/endpoints/global/email/ManageEmailAddressEndpoint.ts +16 -16
- package/src/endpoints/global/email/PatchEmailEndpoint.ts +25 -25
- package/src/endpoints/global/events/GetEventsEndpoint.ts +43 -44
- package/src/endpoints/global/events/PatchEventsEndpoint.ts +127 -172
- package/src/endpoints/global/files/ExportToExcelEndpoint.ts +49 -50
- package/src/endpoints/global/files/GetFileCache.ts +13 -13
- package/src/endpoints/global/files/UploadFile.ts +51 -54
- package/src/endpoints/global/files/UploadImage.ts +53 -53
- package/src/endpoints/global/groups/GetGroupsEndpoint.ts +25 -25
- package/src/endpoints/global/members/GetMemberFamilyEndpoint.ts +24 -23
- package/src/endpoints/global/members/GetMembersCountEndpoint.ts +8 -8
- package/src/endpoints/global/members/GetMembersEndpoint.ts +105 -102
- package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.ts +240 -239
- package/src/endpoints/global/organizations/CheckRegisterCodeEndpoint.ts +12 -14
- package/src/endpoints/global/organizations/CreateOrganizationEndpoint.test.ts +32 -33
- package/src/endpoints/global/organizations/CreateOrganizationEndpoint.ts +48 -57
- package/src/endpoints/global/organizations/GetOrganizationFromDomainEndpoint.test.ts +21 -22
- package/src/endpoints/global/organizations/GetOrganizationFromDomainEndpoint.ts +28 -28
- package/src/endpoints/global/organizations/GetOrganizationFromUriEndpoint.ts +18 -18
- package/src/endpoints/global/organizations/SearchOrganizationEndpoint.test.ts +20 -20
- package/src/endpoints/global/organizations/SearchOrganizationEndpoint.ts +17 -17
- package/src/endpoints/global/payments/StripeWebhookEndpoint.ts +81 -75
- package/src/endpoints/global/platform/GetPlatformAdminsEndpoint.ts +14 -14
- package/src/endpoints/global/platform/GetPlatformEnpoint.ts +11 -11
- package/src/endpoints/global/platform/PatchPlatformEnpoint.ts +71 -68
- package/src/endpoints/global/registration/GetPaymentRegistrations.ts +27 -27
- package/src/endpoints/global/registration/GetUserBillingStatusEndpoint.ts +30 -30
- package/src/endpoints/global/registration/GetUserDetailedBillingStatusEndpoint.ts +34 -34
- package/src/endpoints/global/registration/GetUserDocumentsEndpoint.ts +26 -26
- package/src/endpoints/global/registration/GetUserMembersEndpoint.ts +12 -12
- package/src/endpoints/global/registration/PatchUserMembersEndpoint.ts +90 -90
- package/src/endpoints/global/registration/RegisterMembersEndpoint.test.ts +118 -121
- package/src/endpoints/global/registration/RegisterMembersEndpoint.ts +362 -350
- package/src/endpoints/global/registration-periods/GetRegistrationPeriodsEndpoint.ts +8 -9
- package/src/endpoints/global/registration-periods/PatchRegistrationPeriodsEndpoint.ts +21 -21
- package/src/endpoints/global/webshops/GetWebshopFromDomainEndpoint.ts +65 -65
- package/src/endpoints/organization/dashboard/billing/GetOrganizationBillingStatusEndpoint.ts +9 -9
- package/src/endpoints/organization/dashboard/billing/GetOrganizationDetailedBillingStatusEndpoint.ts +14 -14
- package/src/endpoints/organization/dashboard/documents/GetDocumentTemplateXML.ts +17 -17
- package/src/endpoints/organization/dashboard/documents/GetDocumentTemplatesEndpoint.ts +21 -21
- package/src/endpoints/organization/dashboard/documents/GetDocumentsEndpoint.ts +15 -15
- package/src/endpoints/organization/dashboard/documents/PatchDocumentEndpoint.ts +52 -52
- package/src/endpoints/organization/dashboard/documents/PatchDocumentTemplateEndpoint.ts +37 -37
- package/src/endpoints/organization/dashboard/email/CheckEmailBouncesEndpoint.ts +14 -14
- package/src/endpoints/organization/dashboard/email/EmailEndpoint.ts +113 -112
- package/src/endpoints/organization/dashboard/email-templates/GetEmailTemplatesEndpoint.ts +29 -29
- package/src/endpoints/organization/dashboard/email-templates/PatchEmailTemplatesEndpoint.ts +48 -47
- package/src/endpoints/organization/dashboard/mollie/CheckMollieEndpoint.ts +22 -21
- package/src/endpoints/organization/dashboard/mollie/ConnectMollieEndpoint.ts +13 -14
- package/src/endpoints/organization/dashboard/mollie/DisconnectMollieEndpoint.ts +12 -13
- package/src/endpoints/organization/dashboard/mollie/GetMollieDashboardEndpoint.ts +24 -24
- package/src/endpoints/organization/dashboard/nolt/CreateNoltTokenEndpoint.ts +10 -12
- package/src/endpoints/organization/dashboard/organization/GetOrganizationArchivedGroups.ts +14 -14
- package/src/endpoints/organization/dashboard/organization/GetOrganizationDeletedGroups.ts +13 -13
- package/src/endpoints/organization/dashboard/organization/GetOrganizationSSOEndpoint.ts +12 -12
- package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.test.ts +120 -124
- package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.ts +172 -173
- package/src/endpoints/organization/dashboard/organization/SetOrganizationDomainEndpoint.ts +88 -89
- package/src/endpoints/organization/dashboard/organization/SetOrganizationSSOEndpoint.ts +12 -12
- package/src/endpoints/organization/dashboard/payments/GetMemberBalanceEndpoint.ts +17 -17
- package/src/endpoints/organization/dashboard/payments/GetPaymentsCountEndpoint.ts +8 -8
- package/src/endpoints/organization/dashboard/payments/GetPaymentsEndpoint.ts +66 -67
- package/src/endpoints/organization/dashboard/payments/PatchBalanceItemsEndpoint.ts +47 -47
- package/src/endpoints/organization/dashboard/payments/PatchPaymentsEndpoint.ts +93 -91
- package/src/endpoints/organization/dashboard/registration-periods/GetOrganizationRegistrationPeriodsEndpoint.ts +16 -17
- package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.ts +170 -167
- package/src/endpoints/organization/dashboard/registration-periods/SetupStepReviewEndpoint.ts +25 -24
- package/src/endpoints/organization/dashboard/stripe/ConnectStripeEndpoint.ts +22 -23
- package/src/endpoints/organization/dashboard/stripe/DeleteStripeAccountEndpoint.ts +22 -22
- package/src/endpoints/organization/dashboard/stripe/GetStripeAccountLinkEndpoint.ts +17 -18
- package/src/endpoints/organization/dashboard/stripe/GetStripeAccountsEndpoint.ts +8 -9
- package/src/endpoints/organization/dashboard/stripe/GetStripeLoginLinkEndpoint.ts +17 -18
- package/src/endpoints/organization/dashboard/stripe/UpdateStripeAccountEndpoint.ts +14 -15
- package/src/endpoints/organization/dashboard/users/CreateApiUserEndpoint.ts +19 -19
- package/src/endpoints/organization/dashboard/users/DeleteUserEndpoint.ts +19 -19
- package/src/endpoints/organization/dashboard/users/GetApiUsersEndpoint.ts +14 -14
- package/src/endpoints/organization/dashboard/users/GetOrganizationAdminsEndpoint.ts +12 -12
- package/src/endpoints/organization/dashboard/webshops/CreateWebshopEndpoint.ts +103 -100
- package/src/endpoints/organization/dashboard/webshops/DeleteWebshopEndpoint.ts +11 -12
- package/src/endpoints/organization/dashboard/webshops/GetDiscountCodesEndpoint.ts +15 -15
- package/src/endpoints/organization/dashboard/webshops/GetWebshopOrdersEndpoint.ts +14 -14
- package/src/endpoints/organization/dashboard/webshops/GetWebshopTicketsEndpoint.ts +14 -14
- package/src/endpoints/organization/dashboard/webshops/GetWebshopUriAvailabilityEndpoint.ts +23 -23
- package/src/endpoints/organization/dashboard/webshops/PatchDiscountCodesEndpoint.ts +54 -52
- package/src/endpoints/organization/dashboard/webshops/PatchWebshopEndpoint.ts +84 -81
- package/src/endpoints/organization/dashboard/webshops/PatchWebshopOrdersEndpoint.ts +120 -111
- package/src/endpoints/organization/dashboard/webshops/PatchWebshopTicketsEndpoint.ts +24 -24
- package/src/endpoints/organization/dashboard/webshops/VerifyWebshopDomainEndpoint.ts +18 -18
- package/src/endpoints/organization/shared/ExchangePaymentEndpoint.ts +141 -130
- package/src/endpoints/organization/shared/GetDocumentHtml.ts +25 -25
- package/src/endpoints/organization/shared/GetPaymentEndpoint.ts +18 -18
- package/src/endpoints/organization/shared/auth/GetOrganizationEndpoint.test.ts +36 -37
- package/src/endpoints/organization/shared/auth/GetOrganizationEndpoint.ts +9 -9
- package/src/endpoints/organization/shared/auth/OpenIDConnectCallbackEndpoint.ts +11 -11
- package/src/endpoints/organization/shared/auth/OpenIDConnectStartEndpoint.ts +28 -27
- package/src/endpoints/organization/webshops/CheckWebshopDiscountCodesEndpoint.ts +20 -20
- package/src/endpoints/organization/webshops/GetOrderByPaymentEndpoint.ts +22 -22
- package/src/endpoints/organization/webshops/GetOrderEndpoint.ts +14 -14
- package/src/endpoints/organization/webshops/GetTicketsEndpoint.ts +57 -56
- package/src/endpoints/organization/webshops/GetWebshopEndpoint.test.ts +65 -66
- package/src/endpoints/organization/webshops/GetWebshopEndpoint.ts +18 -17
- package/src/endpoints/organization/webshops/PlaceOrderEndpoint.test.ts +124 -128
- package/src/endpoints/organization/webshops/PlaceOrderEndpoint.ts +154 -145
- package/src/excel-loaders/members.ts +102 -103
- package/src/excel-loaders/payments.ts +155 -156
- package/src/helpers/AddressValidator.test.ts +32 -32
- package/src/helpers/AddressValidator.ts +128 -122
- package/src/helpers/AdminPermissionChecker.ts +339 -236
- package/src/helpers/AuthenticatedStructures.ts +233 -134
- package/src/helpers/BuckarooHelper.ts +134 -134
- package/src/helpers/CheckSettlements.ts +94 -88
- package/src/helpers/Context.ts +87 -86
- package/src/helpers/CookieHelper.ts +23 -22
- package/src/helpers/EmailResumer.ts +10 -10
- package/src/helpers/FileCache.ts +62 -62
- package/src/helpers/ForwardHandler.test.ts +122 -124
- package/src/helpers/ForwardHandler.ts +76 -70
- package/src/helpers/MemberUserSyncer.ts +101 -96
- package/src/helpers/MembershipCharger.ts +69 -69
- package/src/helpers/MembershipHelper.ts +11 -12
- package/src/helpers/OpenIDConnectHelper.ts +85 -82
- package/src/helpers/PeriodHelper.ts +65 -70
- package/src/helpers/StripeHelper.ts +146 -137
- package/src/helpers/StripePayoutChecker.ts +51 -52
- package/src/helpers/ViesHelper.ts +46 -44
- package/src/helpers/fetchToAsyncIterator.ts +14 -14
- package/src/helpers/xlsxAddressTransformerColumnFactory.ts +50 -52
- package/src/middleware/ContextMiddleware.ts +5 -5
- package/src/migrations/1646578856-validate-addresses.ts +6 -9
- package/src/seeds/0000000000-example.ts +3 -5
- package/src/seeds/1715028563-user-permissions.ts +16 -18
- package/src/seeds/1722256498-group-update-occupancy.ts +12 -12
- package/src/seeds/1722344162-sync-member-users.ts +14 -15
- package/src/seeds/1722344162-update-membership.ts +6 -6
- package/src/seeds/1726055544-balance-item-paid.ts +4 -4
- package/src/seeds/1726055545-balance-item-pending.ts +4 -4
- package/src/seeds/1726494419-update-cached-outstanding-balance.ts +16 -16
- package/src/seeds/1726494420-update-cached-outstanding-balance-from-items.ts +12 -12
- package/src/seeds/1726572303-schedule-stock-updates.ts +12 -12
- package/src/seeds/1726847064-setup-steps.ts +16 -0
- package/src/sql-filters/balance-item-payments.ts +7 -7
- package/src/sql-filters/events.ts +14 -14
- package/src/sql-filters/members.ts +96 -96
- package/src/sql-filters/organizations.ts +139 -75
- package/src/sql-filters/payments.ts +28 -28
- package/src/sql-filters/registrations.ts +14 -14
- package/src/sql-sorters/events.ts +25 -25
- package/src/sql-sorters/members.ts +26 -26
- package/src/sql-sorters/organizations.ts +36 -36
- package/src/sql-sorters/payments.ts +26 -26
- package/tests/e2e/stock.test.ts +616 -621
- package/tests/e2e/tickets.test.ts +255 -260
- package/tests/helpers/StripeMocker.ts +177 -179
- package/tests/helpers/TestServer.ts +9 -9
- package/tests/jest.global.setup.ts +14 -13
- package/tests/jest.setup.ts +33 -32
- package/.eslintrc.js +0 -61
- package/jest.config.js +0 -11
- package/src/helpers/SetupStepsUpdater.ts +0 -359
- package/src/seeds/1724076679-setup-steps.ts +0 -16
|
@@ -1,45 +1,46 @@
|
|
|
1
|
-
import { DecodedRequest, Response } from
|
|
1
|
+
import { DecodedRequest, Response } from '@simonbackx/simple-endpoints';
|
|
2
2
|
import cookie from 'cookie';
|
|
3
3
|
|
|
4
|
-
type DecodedRequestWithCookies = DecodedRequest<any, any, any> & { cookies?: Record<string, string>}
|
|
4
|
+
type DecodedRequestWithCookies = DecodedRequest<any, any, any> & { cookies?: Record<string, string> };
|
|
5
5
|
|
|
6
6
|
export class CookieHelper {
|
|
7
7
|
static getCookies(request: DecodedRequest<any, any, any>): Record<string, string> {
|
|
8
|
-
const r = request as DecodedRequestWithCookies
|
|
8
|
+
const r = request as DecodedRequestWithCookies;
|
|
9
9
|
if (r.cookies) {
|
|
10
|
-
return r.cookies
|
|
10
|
+
return r.cookies;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
const header = r.headers.cookie
|
|
13
|
+
const header = r.headers.cookie;
|
|
14
14
|
if (!header) {
|
|
15
|
-
r.cookies = {}
|
|
16
|
-
return r.cookies
|
|
15
|
+
r.cookies = {};
|
|
16
|
+
return r.cookies;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
// Parse
|
|
20
|
-
r.cookies = cookie.parse(header)
|
|
21
|
-
return r.cookies
|
|
20
|
+
r.cookies = cookie.parse(header);
|
|
21
|
+
return r.cookies;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
static getCookie(request: DecodedRequest<any, any, any>, name: string): string | undefined {
|
|
25
|
-
const cookies = this.getCookies(request)
|
|
26
|
-
return cookies[name]
|
|
25
|
+
const cookies = this.getCookies(request);
|
|
26
|
+
return cookies[name];
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
static setCookie(response: Response<any>, name: string, value: string, options?: cookie.CookieSerializeOptions
|
|
30
|
-
const cookies = cookie.serialize(name, value, options)
|
|
31
|
-
let currentCookies = response.headers['set-cookie']
|
|
29
|
+
static setCookie(response: Response<any>, name: string, value: string, options?: cookie.CookieSerializeOptions) {
|
|
30
|
+
const cookies = cookie.serialize(name, value, options);
|
|
31
|
+
let currentCookies = response.headers['set-cookie'];
|
|
32
32
|
if (!currentCookies) {
|
|
33
33
|
response.headers['set-cookie'] = [
|
|
34
|
-
cookies
|
|
35
|
-
]
|
|
36
|
-
}
|
|
34
|
+
cookies,
|
|
35
|
+
];
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
37
38
|
if (!Array.isArray(currentCookies)) {
|
|
38
|
-
currentCookies = [currentCookies.toString()]
|
|
39
|
-
response.headers['set-cookie'] = currentCookies
|
|
39
|
+
currentCookies = [currentCookies.toString()];
|
|
40
|
+
response.headers['set-cookie'] = currentCookies;
|
|
40
41
|
}
|
|
41
|
-
|
|
42
|
-
(currentCookies
|
|
42
|
+
|
|
43
|
+
(currentCookies).push(cookies);
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
|
-
}
|
|
46
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Email, Organization, User } from
|
|
2
|
-
import { SQL } from
|
|
3
|
-
import { EmailStatus } from
|
|
4
|
-
import { ContextInstance } from
|
|
1
|
+
import { Email, Organization, User } from '@stamhoofd/models';
|
|
2
|
+
import { SQL } from '@stamhoofd/sql';
|
|
3
|
+
import { EmailStatus } from '@stamhoofd/structures';
|
|
4
|
+
import { ContextInstance } from './Context';
|
|
5
5
|
|
|
6
6
|
export async function resumeEmails() {
|
|
7
7
|
const query = SQL.select()
|
|
@@ -13,25 +13,25 @@ export async function resumeEmails() {
|
|
|
13
13
|
|
|
14
14
|
for (const email of emails) {
|
|
15
15
|
if (!email.userId) {
|
|
16
|
-
console.warn('Cannot retry sending email because userId is not set - which is required for setting the scope', email.id)
|
|
16
|
+
console.warn('Cannot retry sending email because userId is not set - which is required for setting the scope', email.id);
|
|
17
17
|
continue;
|
|
18
18
|
}
|
|
19
19
|
console.log('Resuming email that has sending status on boot', email.id);
|
|
20
20
|
|
|
21
21
|
const user = await User.getByID(email.userId);
|
|
22
22
|
if (!user) {
|
|
23
|
-
console.warn('Cannot retry sending email because user not found', email.id)
|
|
23
|
+
console.warn('Cannot retry sending email because user not found', email.id);
|
|
24
24
|
continue;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
const organization = email.organizationId ? (await Organization.getByID(email.organizationId)) : null;
|
|
28
28
|
if (organization === undefined) {
|
|
29
|
-
console.warn('Cannot retry sending email because organization not found', email.id)
|
|
29
|
+
console.warn('Cannot retry sending email because organization not found', email.id);
|
|
30
30
|
continue;
|
|
31
31
|
}
|
|
32
|
-
|
|
32
|
+
|
|
33
33
|
await ContextInstance.startForUser(user, organization, async () => {
|
|
34
|
-
await email.send()
|
|
35
|
-
})
|
|
34
|
+
await email.send();
|
|
35
|
+
});
|
|
36
36
|
}
|
|
37
37
|
}
|
package/src/helpers/FileCache.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { SimpleError } from '@simonbackx/simple-errors';
|
|
2
2
|
import { Formatter } from '@stamhoofd/utility';
|
|
3
|
-
import basex from
|
|
4
|
-
import crypto from
|
|
3
|
+
import basex from 'base-x';
|
|
4
|
+
import crypto from 'crypto';
|
|
5
5
|
import fs from 'node:fs';
|
|
6
6
|
import { Writable } from 'node:stream';
|
|
7
7
|
import { Readable } from 'stream';
|
|
8
8
|
|
|
9
|
-
const ALPHABET = '0123456789abcdefghijklmnopqrstuvwxyz'
|
|
10
|
-
const baseEncoder = basex(ALPHABET)
|
|
9
|
+
const ALPHABET = '0123456789abcdefghijklmnopqrstuvwxyz';
|
|
10
|
+
const baseEncoder = basex(ALPHABET);
|
|
11
11
|
|
|
12
12
|
async function randomBytes(size: number): Promise<Buffer> {
|
|
13
13
|
return new Promise((resolve, reject) => {
|
|
@@ -21,18 +21,17 @@ async function randomBytes(size: number): Promise<Buffer> {
|
|
|
21
21
|
});
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
|
|
25
24
|
export class FileCache {
|
|
26
25
|
static async getWriteStream(extension: '.xlsx'): Promise<{
|
|
27
|
-
file: string
|
|
28
|
-
stream: WritableStream
|
|
26
|
+
file: string;
|
|
27
|
+
stream: WritableStream;
|
|
29
28
|
}> {
|
|
30
29
|
if (!STAMHOOFD.CACHE_PATH) {
|
|
31
30
|
throw new SimpleError({
|
|
32
|
-
code:
|
|
33
|
-
message:
|
|
34
|
-
statusCode: 500
|
|
35
|
-
})
|
|
31
|
+
code: 'not_configured',
|
|
32
|
+
message: 'CACHE_PATH environment variable is not configured',
|
|
33
|
+
statusCode: 500,
|
|
34
|
+
});
|
|
36
35
|
}
|
|
37
36
|
|
|
38
37
|
// Generate a long and unguessable filename
|
|
@@ -41,42 +40,42 @@ export class FileCache {
|
|
|
41
40
|
|
|
42
41
|
// Save in folder with the current day
|
|
43
42
|
// Since this contains the day, we can easily restrict access to files after 1 day
|
|
44
|
-
const folder = STAMHOOFD.CACHE_PATH +
|
|
45
|
-
await fs.promises.mkdir(folder, { recursive: true })
|
|
43
|
+
const folder = STAMHOOFD.CACHE_PATH + '/' + path;
|
|
44
|
+
await fs.promises.mkdir(folder, { recursive: true });
|
|
46
45
|
|
|
47
46
|
const s = fs.createWriteStream(folder + '/' + fileName, 'binary');
|
|
48
47
|
|
|
49
48
|
s.on('close', () => {
|
|
50
|
-
console.log('FileCache closed file: File written to disk', folder + '/' + fileName)
|
|
49
|
+
console.log('FileCache closed file: File written to disk', folder + '/' + fileName);
|
|
51
50
|
});
|
|
52
51
|
|
|
53
52
|
return {
|
|
54
53
|
file: path + '/' + fileName,
|
|
55
|
-
stream: Writable.toWeb(s)
|
|
56
|
-
}
|
|
54
|
+
stream: Writable.toWeb(s),
|
|
55
|
+
};
|
|
57
56
|
}
|
|
58
57
|
|
|
59
|
-
static async read(file: string, dayTimeout = 1): Promise<{stream: Readable
|
|
60
|
-
const splitted = file.split(
|
|
61
|
-
if (splitted.length
|
|
58
|
+
static async read(file: string, dayTimeout = 1): Promise<{ stream: Readable; contentLength: number; extension: string }> {
|
|
59
|
+
const splitted = file.split('/');
|
|
60
|
+
if (splitted.length !== 2) {
|
|
62
61
|
throw new SimpleError({
|
|
63
|
-
code:
|
|
64
|
-
message:
|
|
65
|
-
human:
|
|
66
|
-
statusCode: 400
|
|
67
|
-
})
|
|
62
|
+
code: 'invalid_file',
|
|
63
|
+
message: 'Invalid file',
|
|
64
|
+
human: 'Ongeldig bestand',
|
|
65
|
+
statusCode: 400,
|
|
66
|
+
});
|
|
68
67
|
}
|
|
69
68
|
|
|
70
69
|
const fileName = splitted[1];
|
|
71
70
|
|
|
72
71
|
const extension = fileName.substring(fileName.length - 5);
|
|
73
|
-
if (extension
|
|
72
|
+
if (extension !== '.xlsx') {
|
|
74
73
|
throw new SimpleError({
|
|
75
|
-
code:
|
|
76
|
-
message:
|
|
77
|
-
human:
|
|
78
|
-
statusCode: 400
|
|
79
|
-
})
|
|
74
|
+
code: 'invalid_file',
|
|
75
|
+
message: 'Invalid file',
|
|
76
|
+
human: 'Ongeldig bestand',
|
|
77
|
+
statusCode: 400,
|
|
78
|
+
});
|
|
80
79
|
}
|
|
81
80
|
|
|
82
81
|
const fileNameWithoutExtension = fileName.substring(0, fileName.length - 5);
|
|
@@ -85,66 +84,67 @@ export class FileCache {
|
|
|
85
84
|
for (const char of fileNameWithoutExtension) {
|
|
86
85
|
if (!ALPHABET.includes(char)) {
|
|
87
86
|
throw new SimpleError({
|
|
88
|
-
code:
|
|
89
|
-
message:
|
|
90
|
-
human:
|
|
91
|
-
statusCode: 400
|
|
92
|
-
})
|
|
87
|
+
code: 'invalid_file',
|
|
88
|
+
message: 'Invalid file',
|
|
89
|
+
human: 'Onbekend karakters in bestandsnaam',
|
|
90
|
+
statusCode: 400,
|
|
91
|
+
});
|
|
93
92
|
}
|
|
94
93
|
}
|
|
95
94
|
|
|
96
95
|
const path = splitted[0];
|
|
97
96
|
|
|
98
97
|
// Verify date
|
|
99
|
-
if (path.length
|
|
98
|
+
if (path.length !== 10) {
|
|
100
99
|
throw new SimpleError({
|
|
101
|
-
code:
|
|
102
|
-
message:
|
|
103
|
-
human:
|
|
104
|
-
statusCode: 400
|
|
105
|
-
})
|
|
100
|
+
code: 'invalid_file',
|
|
101
|
+
message: 'Invalid file',
|
|
102
|
+
human: 'Ongelidge datum',
|
|
103
|
+
statusCode: 400,
|
|
104
|
+
});
|
|
106
105
|
}
|
|
107
106
|
const year = parseInt(path.substring(0, 4));
|
|
108
|
-
const month = parseInt(path.substring(5,
|
|
107
|
+
const month = parseInt(path.substring(5, 5 + 2));
|
|
109
108
|
const day = parseInt(path.substring(8, 8 + 2));
|
|
110
109
|
|
|
111
110
|
if (isNaN(year) || isNaN(month) || isNaN(day)) {
|
|
112
111
|
throw new SimpleError({
|
|
113
|
-
code:
|
|
114
|
-
message:
|
|
115
|
-
human:
|
|
116
|
-
statusCode: 400
|
|
117
|
-
})
|
|
112
|
+
code: 'invalid_file',
|
|
113
|
+
message: 'Invalid file',
|
|
114
|
+
human: 'Ongeldige datum',
|
|
115
|
+
statusCode: 400,
|
|
116
|
+
});
|
|
118
117
|
}
|
|
119
118
|
|
|
120
119
|
const date = new Date(year, month - 1, day, 0, 0, 0);
|
|
121
120
|
const now = new Date();
|
|
122
121
|
now.setHours(0, 0, 0, 0);
|
|
123
122
|
|
|
124
|
-
const diff = now.getTime() - date.getTime()
|
|
123
|
+
const diff = now.getTime() - date.getTime();
|
|
125
124
|
|
|
126
125
|
if (date > now || diff > dayTimeout * 24 * 60 * 60 * 1000) {
|
|
127
126
|
throw new SimpleError({
|
|
128
|
-
code:
|
|
129
|
-
message:
|
|
130
|
-
human:
|
|
131
|
-
statusCode: 404
|
|
132
|
-
})
|
|
127
|
+
code: 'file_expired',
|
|
128
|
+
message: 'File expired',
|
|
129
|
+
human: 'Het bestand is verlopen',
|
|
130
|
+
statusCode: 404,
|
|
131
|
+
});
|
|
133
132
|
}
|
|
134
133
|
|
|
135
|
-
const filePath = STAMHOOFD.CACHE_PATH +
|
|
134
|
+
const filePath = STAMHOOFD.CACHE_PATH + '/' + Formatter.dateIso(date) + '/' + fileName;
|
|
136
135
|
|
|
137
136
|
let stat: fs.Stats;
|
|
138
137
|
try {
|
|
139
138
|
stat = await fs.promises.stat(filePath);
|
|
140
|
-
}
|
|
139
|
+
}
|
|
140
|
+
catch (e) {
|
|
141
141
|
if (e.code == 'ENOENT') {
|
|
142
142
|
throw new SimpleError({
|
|
143
|
-
code:
|
|
144
|
-
message:
|
|
145
|
-
human:
|
|
146
|
-
statusCode: 404
|
|
147
|
-
})
|
|
143
|
+
code: 'file_expired',
|
|
144
|
+
message: 'File expired',
|
|
145
|
+
human: 'Het bestand bestaat niet',
|
|
146
|
+
statusCode: 404,
|
|
147
|
+
});
|
|
148
148
|
}
|
|
149
149
|
throw e;
|
|
150
150
|
}
|
|
@@ -152,7 +152,7 @@ export class FileCache {
|
|
|
152
152
|
return {
|
|
153
153
|
stream: fs.createReadStream(filePath),
|
|
154
154
|
contentLength: stat.size,
|
|
155
|
-
extension
|
|
156
|
-
}
|
|
155
|
+
extension,
|
|
156
|
+
};
|
|
157
157
|
}
|
|
158
158
|
}
|