@stamhoofd/backend 2.120.6 → 2.122.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/output-2.txt +1 -0
- package/output.txt +1 -0
- package/package.json +70 -53
- package/src/audit-logs/EventNotificationLogger.ts +40 -0
- package/src/audit-logs/ModelLogger.ts +19 -15
- package/src/audit-logs/OrganizationLogger.ts +1 -1
- package/src/audit-logs/RegistrationInvitationLogger.ts +46 -0
- package/src/audit-logs/init.ts +9 -1
- package/src/boot.ts +19 -18
- package/src/crons/amazon-ses.ts +13 -26
- package/src/crons/balance-emails.ts +3 -5
- package/src/crons/clearExcelCache.test.ts +1 -1
- package/src/crons/clearExcelCache.ts +1 -2
- package/src/crons/drip-emails.ts +42 -0
- package/src/crons/endFunctionsOfUsersWithoutRegistration.ts +4 -0
- package/src/crons/helpers/isOutside.ts +11 -0
- package/src/crons/helpers/useSavedIterator.ts +32 -0
- package/src/crons/index.ts +7 -0
- package/src/crons/invoices.ts +160 -0
- package/src/crons/members-fees.ts +50 -0
- package/src/crons/mollie-chargebacks.ts +86 -0
- package/src/crons/service-fees.ts +152 -0
- package/src/crons/stripe-invoices.ts +48 -0
- package/src/crons/transfer-fees.ts +176 -0
- package/src/crons/update-cached-balances.ts +4 -4
- package/src/crons.ts +54 -74
- package/src/debug.ts +4 -2
- package/src/email-recipient-loaders/documents.ts +1 -1
- package/src/email-recipient-loaders/members.ts +1 -1
- package/src/email-recipient-loaders/payments.ts +87 -46
- package/src/email-recipient-loaders/registrations.ts +1 -1
- package/src/email-replacements/getEmailReplacementsForPayment.ts +5 -9
- package/src/endpoints/admin/members/ChargeMembersEndpoint.ts +1 -1
- package/src/endpoints/admin/memberships/ChargeMembershipsEndpoint.ts +1 -1
- package/src/endpoints/admin/memberships/GetChargeMembershipsSummaryEndpoint.ts +3 -5
- package/src/endpoints/admin/organizations/ChargeOrganizationsEndpoint.ts +1 -1
- package/src/endpoints/admin/organizations/GetOrganizationsCountEndpoint.ts +1 -1
- package/src/endpoints/admin/organizations/GetOrganizationsEndpoint.ts +13 -7
- package/src/endpoints/admin/organizations/PatchOrganizationsEndpoint.ts +4 -6
- package/src/endpoints/admin/organizations/PatchPackagesEndpoint.test.ts +10 -6
- package/src/endpoints/admin/organizations/PatchPackagesEndpoint.ts +39 -21
- package/src/endpoints/admin/registrations/ChargeRegistrationsEndpoint.ts +1 -1
- package/src/endpoints/auth/CreateAdminEndpoint.ts +23 -5
- package/src/endpoints/auth/CreateTokenEndpoint.ts +2 -2
- package/src/endpoints/auth/DeleteTokenEndpoint.ts +1 -1
- package/src/endpoints/auth/DeleteUserEndpoint.ts +3 -3
- package/src/endpoints/auth/ForgotPasswordEndpoint.ts +1 -1
- package/src/endpoints/auth/GetOtherUserEndpoint.ts +1 -1
- package/src/endpoints/auth/GetUserEndpoint.ts +1 -1
- package/src/endpoints/auth/OpenIDConnectAuthTokenEndpoint.ts +1 -1
- package/src/endpoints/auth/OpenIDConnectStartEndpoint.ts +1 -1
- package/src/endpoints/auth/PatchUserEndpoint.ts +5 -8
- package/src/endpoints/auth/PollEmailVerificationEndpoint.ts +1 -1
- package/src/endpoints/auth/RetryEmailVerificationEndpoint.ts +1 -1
- package/src/endpoints/auth/SignupEndpoint.ts +2 -3
- package/src/endpoints/auth/VerifyEmailEndpoint.ts +20 -3
- package/src/endpoints/frontend/FrontendEnvironmentEndpoint.ts +2 -1
- package/src/endpoints/global/addresses/SearchRegionsEndpoint.ts +2 -4
- package/src/endpoints/global/addresses/ValidateAddressEndpoint.ts +1 -1
- package/src/endpoints/global/audit-logs/GetAuditLogsEndpoint.ts +5 -7
- package/src/endpoints/global/caddy/CheckDomainCertEndpoint.ts +2 -2
- package/src/endpoints/global/email/CreateEmailEndpoint.ts +3 -4
- package/src/endpoints/global/email/GetAdminEmailsEndpoint.test.ts +1 -1
- package/src/endpoints/global/email/GetAdminEmailsEndpoint.ts +1 -2
- package/src/endpoints/global/email/GetEmailAddressEndpoint.ts +4 -6
- package/src/endpoints/global/email/GetEmailEndpoint.ts +1 -1
- package/src/endpoints/global/email/GetUserEmailsEndpoint.test.ts +1 -1
- package/src/endpoints/global/email/GetUserEmailsEndpoint.ts +1 -1
- package/src/endpoints/global/email/ManageEmailAddressEndpoint.ts +6 -10
- package/src/endpoints/global/email/PatchEmailEndpoint.test.ts +4 -7
- package/src/endpoints/global/email/PatchEmailEndpoint.ts +6 -9
- package/src/endpoints/global/email-recipients/GetEmailRecipientsCountEndpoint.ts +1 -1
- package/src/endpoints/global/email-recipients/GetEmailRecipientsEndpoint.test.ts +1 -1
- package/src/endpoints/global/email-recipients/GetEmailRecipientsEndpoint.ts +1 -1
- package/src/endpoints/global/email-recipients/RetryEmailRecipientEndpoint.ts +2 -2
- package/src/endpoints/global/events/GetEventNotificationsCountEndpoint.ts +1 -1
- package/src/endpoints/global/events/GetEventNotificationsEndpoint.ts +3 -3
- package/src/endpoints/global/events/GetEventsEndpoint.ts +3 -3
- package/src/endpoints/global/events/PatchEventNotificationsEndpoint.test.ts +49 -4
- package/src/endpoints/global/events/PatchEventNotificationsEndpoint.ts +5 -8
- package/src/endpoints/global/events/PatchEventsEndpoint.test.ts +12 -44
- package/src/endpoints/global/events/PatchEventsEndpoint.ts +128 -127
- package/src/endpoints/global/files/ExportToExcelEndpoint.ts +9 -9
- package/src/endpoints/global/files/GetFileCache.ts +3 -4
- package/src/endpoints/global/files/UploadFile.ts +3 -4
- package/src/endpoints/global/files/UploadImage.ts +3 -4
- package/src/endpoints/global/groups/GetGroupsCountEndpoint.ts +51 -0
- package/src/endpoints/global/groups/GetGroupsEndpoint.test.ts +1 -1
- package/src/endpoints/global/groups/GetGroupsEndpoint.ts +4 -2
- package/src/endpoints/global/members/GetMemberFamilyEndpoint.ts +2 -3
- package/src/endpoints/global/members/GetMembersCountEndpoint.ts +1 -1
- package/src/endpoints/global/members/GetMembersEndpoint.test.ts +2 -2
- package/src/endpoints/global/members/GetMembersEndpoint.ts +10 -12
- package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.test.ts +195 -12
- package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.ts +16 -22
- package/src/endpoints/global/members/helpers/validateGroupFilter.ts +6 -30
- package/src/endpoints/global/members/shouldCheckIfMemberIsDuplicate.ts +1 -1
- package/src/endpoints/global/organizations/CheckRegisterCodeEndpoint.ts +1 -1
- package/src/endpoints/global/organizations/CreateOrganizationEndpoint.ts +40 -8
- package/src/endpoints/global/organizations/GetOrganizationFromDomainEndpoint.ts +2 -2
- package/src/endpoints/global/organizations/GetOrganizationFromUriEndpoint.ts +2 -2
- package/src/endpoints/global/organizations/SearchOrganizationEndpoint.test.ts +4 -1
- package/src/endpoints/global/organizations/SearchOrganizationEndpoint.ts +4 -5
- package/src/endpoints/global/payments/StripeWebhookEndpoint.ts +9 -16
- package/src/endpoints/global/platform/GetPlatformAdminsEndpoint.ts +1 -1
- package/src/endpoints/global/platform/GetPlatformEndpoint.ts +1 -1
- package/src/endpoints/global/platform/PatchPlatformEnpoint.test.ts +1 -1
- package/src/endpoints/global/platform/PatchPlatformEnpoint.ts +32 -13
- package/src/endpoints/global/platform-memberships/GetPlatformMembershipsCountEndpoint.ts +31 -31
- package/src/endpoints/global/platform-memberships/GetPlatformMembershipsEndpoint.ts +18 -20
- package/src/endpoints/global/registration/GetRegistrationsCountEndpoint.ts +1 -1
- package/src/endpoints/global/registration/GetRegistrationsEndpoint.test.ts +1 -1
- package/src/endpoints/global/registration/GetRegistrationsEndpoint.ts +6 -10
- package/src/endpoints/global/registration/GetUserDetailedPayableBalanceEndpoint.ts +35 -6
- package/src/endpoints/global/registration/GetUserDocumentsEndpoint.ts +2 -2
- package/src/endpoints/global/registration/GetUserMembersEndpoint.ts +1 -1
- package/src/endpoints/global/registration/GetUserPayableBalanceEndpoint.ts +1 -1
- package/src/endpoints/global/registration/PatchUserMembersEndpoint.test.ts +2 -2
- package/src/endpoints/global/registration/PatchUserMembersEndpoint.ts +3 -3
- package/src/endpoints/global/registration/RegisterMembersEndpoint.test.ts +90 -6
- package/src/endpoints/global/registration/RegisterMembersEndpoint.ts +38 -33
- package/src/endpoints/global/registration-invitations/GetRegistrationInvitationsCountEndpoint.ts +45 -0
- package/src/endpoints/global/registration-invitations/GetRegistrationInvitationsEndpoint.test.ts +494 -0
- package/src/endpoints/global/registration-invitations/GetRegistrationInvitationsEndpoint.ts +213 -0
- package/src/endpoints/global/registration-invitations/PatchRegistrationInvitationsEndpoint.test.ts +404 -0
- package/src/endpoints/global/registration-invitations/PatchRegistrationInvitationsEndpoint.ts +167 -0
- package/src/endpoints/global/registration-periods/GetRegistrationPeriodsCountEndpoint.ts +43 -0
- package/src/endpoints/global/registration-periods/GetRegistrationPeriodsEndpoint.ts +1 -1
- package/src/endpoints/global/registration-periods/PatchRegistrationPeriodsEndpoint.ts +13 -5
- package/src/endpoints/global/sso/GetSSOEndpoint.ts +2 -3
- package/src/endpoints/global/sso/SetSSOEndpoint.ts +1 -1
- package/src/endpoints/global/webshops/GetWebshopFromDomainEndpoint.ts +2 -2
- package/src/endpoints/global/webshops/GetWebshopsEndpoint.test.ts +1 -2
- package/src/endpoints/global/webshops/GetWebshopsEndpoint.ts +2 -4
- package/src/endpoints/organization/dashboard/balance-items/GetBalanceItemEndpoint.ts +2 -2
- package/src/endpoints/organization/dashboard/balance-items/GetBalanceItemsCountEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/balance-items/GetBalanceItemsEndpoint.ts +3 -4
- package/src/endpoints/organization/dashboard/balance-items/PatchBalanceItemsEndpoint.ts +19 -6
- package/src/endpoints/organization/dashboard/billing/ApplyRegisterCodeEndpoint.test.ts +73 -0
- package/src/endpoints/organization/dashboard/billing/ApplyRegisterCodeEndpoint.ts +89 -0
- package/src/endpoints/{global → organization/dashboard}/billing/DeactivatePackageEndpoint.ts +4 -9
- package/src/endpoints/organization/dashboard/billing/DeleteOrganizationMandateEndpoint.ts +62 -0
- package/src/endpoints/organization/dashboard/billing/GetOrganizationDetailedPayableBalanceCollectionEndpoint.ts +56 -0
- package/src/endpoints/organization/dashboard/billing/GetOrganizationDetailedPayableBalanceEndpoint.ts +41 -18
- package/src/endpoints/organization/dashboard/billing/GetOrganizationMandatesEndpoint.ts +64 -0
- package/src/endpoints/organization/dashboard/billing/GetOrganizationPayableBalanceEndpoint.ts +2 -2
- package/src/endpoints/organization/dashboard/billing/GetOrganizationPayableInvoicesEndpoint.ts +68 -0
- package/src/endpoints/organization/dashboard/billing/GetPackagesEndpoint.ts +12 -4
- package/src/endpoints/organization/dashboard/billing/GetRegisterCodeEndpoint.ts +66 -0
- package/src/endpoints/organization/dashboard/billing/OrganizationCheckoutEndpoint.test.ts +949 -0
- package/src/endpoints/organization/dashboard/billing/OrganizationCheckoutEndpoint.ts +311 -0
- package/src/endpoints/organization/dashboard/billing/PatchOrganizationMandatesEndpoint.ts +94 -0
- package/src/endpoints/organization/dashboard/documents/GetDocumentTemplateXML.ts +1 -1
- package/src/endpoints/organization/dashboard/documents/GetDocumentTemplatesCountEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/documents/GetDocumentTemplatesEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/documents/GetDocumentsCountEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/documents/GetDocumentsEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/documents/PatchDocumentEndpoint.ts +10 -2
- package/src/endpoints/organization/dashboard/documents/PatchDocumentTemplatesEndpoint.test.ts +2 -2
- package/src/endpoints/organization/dashboard/documents/PatchDocumentTemplatesEndpoint.ts +2 -2
- package/src/endpoints/organization/dashboard/email/CheckEmailBouncesEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/email-templates/GetEmailTemplatesEndpoint.test.ts +1 -1
- package/src/endpoints/organization/dashboard/email-templates/GetEmailTemplatesEndpoint.ts +10 -8
- package/src/endpoints/organization/dashboard/email-templates/PatchEmailTemplatesEndpoint.test.ts +1 -1
- package/src/endpoints/organization/dashboard/email-templates/PatchEmailTemplatesEndpoint.ts +5 -6
- package/src/endpoints/organization/dashboard/invoices/GetInvoicesCountEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/invoices/GetInvoicesEndpoint.ts +15 -4
- package/src/endpoints/organization/dashboard/invoices/PatchInvoicesEndpoint.ts +11 -2
- package/src/endpoints/organization/dashboard/mollie/CheckMollieEndpoint.ts +8 -8
- package/src/endpoints/organization/dashboard/mollie/ConnectMollieEndpoint.ts +10 -5
- package/src/endpoints/organization/dashboard/mollie/DisconnectMollieEndpoint.ts +2 -2
- package/src/endpoints/organization/dashboard/mollie/GetMollieDashboardEndpoint.ts +7 -7
- package/src/endpoints/organization/dashboard/nolt/CreateNoltTokenEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/organization/GetOrganizationArchivedGroups.ts +2 -2
- package/src/endpoints/organization/dashboard/organization/GetOrganizationDeletedGroups.ts +1 -1
- package/src/endpoints/organization/dashboard/organization/GetUitpasClientIdEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.test.ts +2 -2
- package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.ts +67 -20
- package/src/endpoints/organization/dashboard/organization/SearchUitpasOrganizersEndpoint.ts +2 -2
- package/src/endpoints/organization/dashboard/organization/SetOrganizationDomainEndpoint.ts +5 -10
- package/src/endpoints/organization/dashboard/organization/SetUitpasClientCredentialsEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/payments/GetPaymentsCountEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/payments/GetPaymentsEndpoint.ts +3 -4
- package/src/endpoints/organization/dashboard/payments/PatchPaymentsEndpoint.ts +24 -17
- package/src/endpoints/organization/dashboard/receivable-balances/ChargeReceivableBalancesEndpoint.ts +134 -0
- package/src/endpoints/organization/dashboard/receivable-balances/GetReceivableBalanceEndpoint.ts +2 -3
- package/src/endpoints/organization/dashboard/receivable-balances/GetReceivableBalancesCountEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/receivable-balances/GetReceivableBalancesEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/registration-periods/GetOrganizationRegistrationPeriodsEndpoint.test.ts +1 -1
- package/src/endpoints/organization/dashboard/registration-periods/GetOrganizationRegistrationPeriodsEndpoint.ts +2 -3
- package/src/endpoints/organization/dashboard/registration-periods/MoveRegistrationPeriods.test.ts +1 -1
- package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.test.ts +1 -1
- package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.ts +32 -22
- package/src/endpoints/organization/dashboard/registration-periods/SetupStepReviewEndpoint.ts +4 -5
- package/src/endpoints/organization/dashboard/stripe/ConnectStripeEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/stripe/DeleteStripeAccountEndpoint.ts +2 -3
- package/src/endpoints/organization/dashboard/stripe/GetStripeAccountLinkEndpoint.ts +2 -2
- package/src/endpoints/organization/dashboard/stripe/GetStripeAccountsEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/stripe/GetStripeLoginLinkEndpoint.ts +2 -2
- package/src/endpoints/organization/dashboard/stripe/UpdateStripeAccountEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/users/CreateApiUserEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/users/DeleteUserEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/users/GetApiUsersEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/users/GetOrganizationAdminsEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/users/PatchApiUserEndpoint.ts +4 -6
- package/src/endpoints/organization/dashboard/webshops/CreateWebshopEndpoint.ts +10 -15
- package/src/endpoints/organization/dashboard/webshops/DeleteWebshopEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/webshops/GetDiscountCodesEndpoint.ts +2 -2
- package/src/endpoints/organization/dashboard/webshops/GetWebshopOrdersCountEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/webshops/GetWebshopOrdersEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/webshops/GetWebshopTicketsEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/webshops/GetWebshopUriAvailabilityEndpoint.ts +11 -2
- package/src/endpoints/organization/dashboard/webshops/PatchDiscountCodesEndpoint.ts +4 -6
- package/src/endpoints/organization/dashboard/webshops/PatchWebshopEndpoint.ts +29 -8
- package/src/endpoints/organization/dashboard/webshops/PatchWebshopOrdersEndpoint.ts +21 -28
- package/src/endpoints/organization/dashboard/webshops/PatchWebshopTicketsEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/webshops/SearchUitpasEventsEndpoint.ts +2 -2
- package/src/endpoints/organization/dashboard/webshops/VerifyWebshopDomainEndpoint.ts +2 -3
- package/src/endpoints/organization/dashboard/webshops/WebshopReservedPathSegments.test.ts +95 -0
- package/src/endpoints/organization/shared/ExchangePaymentEndpoint.ts +15 -13
- package/src/endpoints/organization/shared/GetDocumentHtml.ts +1 -1
- package/src/endpoints/organization/shared/GetPaymentEndpoint.ts +1 -1
- package/src/endpoints/organization/shared/GetUitpasNumberDetailsEndpoint.ts +3 -5
- package/src/endpoints/organization/shared/auth/GetOrganizationEndpoint.ts +1 -1
- package/src/endpoints/organization/webshops/CheckWebshopDiscountCodesEndpoint.ts +4 -1
- package/src/endpoints/organization/webshops/GetOrderByPaymentEndpoint.ts +14 -3
- package/src/endpoints/organization/webshops/GetOrderEndpoint.ts +14 -2
- package/src/endpoints/organization/webshops/GetTicketsEndpoint.ts +37 -16
- package/src/endpoints/organization/webshops/GetWebshopEndpoint.test.ts +34 -2
- package/src/endpoints/organization/webshops/GetWebshopEndpoint.ts +4 -2
- package/src/endpoints/organization/webshops/PlaceOrderEndpoint.test.ts +74 -3
- package/src/endpoints/organization/webshops/PlaceOrderEndpoint.ts +28 -50
- package/src/endpoints/organization/webshops/RetrieveUitpasSocialTariffPriceEndpoint.ts +3 -5
- package/src/endpoints/organization/webshops/WebshopAuthHelper.ts +36 -0
- package/src/endpoints/system/HealthEndpoint.ts +1 -1
- package/src/excel-loaders/balance-items.ts +1 -1
- package/src/excel-loaders/event-notifications.ts +1 -1
- package/src/excel-loaders/members.ts +1 -1
- package/src/excel-loaders/organizations.ts +3 -3
- package/src/excel-loaders/payments.ts +31 -1
- package/src/excel-loaders/platform-memberships.ts +13 -14
- package/src/excel-loaders/receivable-balances.ts +2 -2
- package/src/excel-loaders/registrations.ts +2 -3
- package/src/helpers/AddressValidator.ts +7 -14
- package/src/helpers/AdminPermissionChecker.ts +60 -65
- package/src/helpers/AuthenticatedStructures.ts +153 -51
- package/src/helpers/BalanceItemRelationsBackfiller.test.ts +174 -0
- package/src/helpers/BalanceItemRelationsBackfiller.ts +163 -0
- package/src/helpers/BuckarooHelper.ts +2 -4
- package/src/helpers/CheckSettlements.ts +12 -24
- package/src/helpers/Context.ts +15 -10
- package/src/helpers/CookieHelper.ts +1 -2
- package/src/helpers/EmailResumer.ts +1 -2
- package/src/helpers/FileCache.ts +2 -3
- package/src/helpers/FinancialSupportHelper.ts +21 -0
- package/src/helpers/FlagMomentCleanup.ts +1 -2
- package/src/helpers/ForwardHandler.ts +5 -10
- package/src/helpers/GlobalHelper.ts +3 -3
- package/src/helpers/LegacyBillingConverter.ts +787 -0
- package/src/helpers/MemberMerger.test.ts +782 -0
- package/src/helpers/MemberMerger.ts +600 -0
- package/src/helpers/MemberUserSyncer.ts +6 -12
- package/src/helpers/MembershipCharger.ts +2 -4
- package/src/helpers/PaymentCustomerResolver.test.ts +203 -0
- package/src/helpers/PaymentCustomerResolver.ts +144 -0
- package/src/helpers/PeriodHelper.ts +2 -3
- package/src/helpers/RecordAnswerHelper.test.ts +741 -0
- package/src/helpers/RecordAnswerHelper.ts +116 -0
- package/src/helpers/SeedTools.ts +106 -0
- package/src/helpers/ServiceFeeHelper.ts +125 -15
- package/src/helpers/SetupStepUpdater.ts +38 -32
- package/src/helpers/StamhoofdFilterAccessHelper.ts +52 -0
- package/src/helpers/StripeHelper.ts +15 -38
- package/src/helpers/StripeInvoicer.ts +419 -0
- package/src/helpers/StripePayoutChecker.ts +5 -10
- package/src/helpers/TagHelper.ts +7 -8
- package/src/helpers/TemporaryMemberAccess.ts +1 -2
- package/src/helpers/ThrottledQueue.ts +1 -2
- package/src/helpers/UitpasTokenRepository.ts +1 -2
- package/src/helpers/ViesHelper.ts +11 -11
- package/src/helpers/XlsxTransformerColumnHelper.ts +1 -1
- package/src/helpers/outstandingBalanceJoin.ts +2 -2
- package/src/helpers/updateMemberDetailsUitpasNumber.ts +3 -5
- package/src/migrate.ts +12 -5
- package/src/{seeds → migrations}/0000000004-single-organization.ts +10 -1
- package/src/migrations/0000000006-default-organization.ts +139 -0
- package/src/{seeds → migrations}/1715028563-user-permissions.ts +17 -27
- package/src/{seeds/1765896674-document-update-year.test.ts → migrations/1750090029-document-update-year.test.ts} +27 -26
- package/src/migrations/1750090029-document-update-year.ts +103 -0
- package/src/migrations/1750090030-records-configuration.ts +92 -0
- package/src/migrations/1750090031-records-configuration-webshops.ts +36 -0
- package/src/migrations/1752848540-national-numbers.ts +585 -0
- package/src/migrations/1752848550-records-configuration-group-filter.ts +1064 -0
- package/src/{seeds → migrations}/1752848561-groups-registration-periods.ts +95 -27
- package/src/{seeds → migrations}/1754560914-groups-prices.test.ts +1 -1
- package/src/{seeds → migrations}/1754560914-groups-prices.ts +9 -15
- package/src/{seeds → migrations}/1756293699-fill-previous-next-period-id.ts +1 -2
- package/src/migrations/1761665607-sync-member-users.ts +40 -0
- package/src/migrations/1779121239-default-invoice-email-template.sql +3 -0
- package/src/migrations/1779121240-invoice-email-template.sql +6 -0
- package/src/migrations/1779986893-default-payment-failed-email-templates.sql +4 -0
- package/src/migrations/1780578166-convert-legacy-billing.ts +13 -0
- package/src/{seeds/1755876819-remove-duplicate-members.ts → migrations/1780665426-remove-duplicate-members.ts} +23 -4
- package/src/migrations/1780933598-document-groups.ts +88 -0
- package/src/migrations/1781692342-balance-item-relations.ts +13 -0
- package/src/migrations/1781857866-platform-admins.ts +103 -0
- package/src/migrations/1781857867-rm-old-platform-admins.ts +25 -0
- package/src/seeds/0000000001-throw.ts +5 -0
- package/src/seeds/1760702452-update-balance-price-paid.ts +19 -0
- package/src/seeds/1760702453-update-balance-invoiced.ts +19 -0
- package/src/seeds/1760702454-update-cached-outstanding-balance-from-items.ts +51 -14
- package/src/seeds/1773754928-force-save-members.ts +41 -8
- package/src/seeds/1780665427-schedule-stock-updates.ts +45 -0
- package/src/seeds/1780665428-group-update-occupancy.ts +31 -0
- package/src/seeds/1780915001-fill-payment-customer.ts +70 -0
- package/src/seeds/1780915002-update-orders.ts +39 -0
- package/src/seeds/1782047708-organization-company-address.ts +44 -0
- package/src/seeds-temporary/1769088653-uitpas-status.ts +1 -2
- package/src/seeds-temporary/1780416000-migrate-audit-log-legacy-enums.test.ts +69 -0
- package/src/seeds-temporary/1780416000-migrate-audit-log-legacy-enums.ts +85 -0
- package/src/services/AuditLogService.test.ts +51 -0
- package/src/services/AuditLogService.ts +45 -0
- package/src/services/BalanceItemService.ts +148 -55
- package/src/services/CpuService.ts +3 -6
- package/src/services/DatabaseCollationService.test.ts +1 -2
- package/src/services/DocumentService.ts +1 -2
- package/src/services/EventNotificationService.ts +1 -1
- package/src/services/FileSignService.ts +2 -4
- package/src/services/InvoicePdfService.ts +286 -0
- package/src/services/InvoiceService.ts +330 -77
- package/src/services/InvoiceXMLService.ts +424 -0
- package/src/services/MemberNumberService.ts +6 -11
- package/src/services/MemberRecordStore.ts +8 -10
- package/src/services/MollieService.ts +530 -0
- package/src/services/PaymentMandateService.ts +214 -0
- package/src/services/PaymentReallocationService.test.ts +1 -1
- package/src/services/PaymentReallocationService.ts +7 -9
- package/src/services/PaymentService.ts +820 -328
- package/src/services/PlatformMembershipService.ts +5 -9
- package/src/services/ReferralService.ts +223 -0
- package/src/services/RegistrationService.ts +125 -54
- package/src/services/SSOService.test.ts +119 -0
- package/src/services/SSOService.ts +56 -49
- package/src/services/STPackageService.ts +97 -68
- package/src/services/UniqueMemberNumberService.ts +69 -0
- package/src/services/UniqueUserService.ts +3 -6
- package/src/services/VATService.ts +85 -0
- package/src/services/data/invoice.hbs.html +686 -0
- package/src/services/uitpas/PassholderEndpoints.ts +3 -6
- package/src/services/uitpas/UitpasService.ts +6 -10
- package/src/services/uitpas/checkUitpasNumbers.ts +2 -4
- package/src/services/uitpas/getSocialTariffForUitpasNumbers.ts +3 -6
- package/src/services/uitpas/searchUitpasEvents.ts +1 -2
- package/src/sql-filters/audit-logs.ts +1 -1
- package/src/sql-filters/balance-item-payments.ts +1 -1
- package/src/sql-filters/balance-items.ts +1 -1
- package/src/sql-filters/base-registration-filter-compilers.ts +5 -33
- package/src/sql-filters/document-templates.ts +1 -1
- package/src/sql-filters/documents.ts +1 -1
- package/src/sql-filters/email-recipients.ts +1 -1
- package/src/sql-filters/emails.ts +1 -1
- package/src/sql-filters/event-notifications.ts +1 -1
- package/src/sql-filters/events.ts +6 -1
- package/src/sql-filters/groups.ts +16 -1
- package/src/sql-filters/invoiced-balance-items.ts +1 -1
- package/src/sql-filters/invoices.ts +1 -1
- package/src/sql-filters/member-responsibility-records.ts +1 -1
- package/src/sql-filters/members.ts +1 -1
- package/src/sql-filters/orders.ts +4 -4
- package/src/sql-filters/organization-registration-periods.ts +1 -1
- package/src/sql-filters/organizations.ts +1 -1
- package/src/sql-filters/payments.ts +5 -0
- package/src/sql-filters/platform-memberships.ts +3 -3
- package/src/sql-filters/receivable-balances.ts +1 -1
- package/src/sql-filters/registration-invitations.ts +90 -0
- package/src/sql-filters/registration-periods.ts +1 -1
- package/src/sql-filters/registrations.ts +1 -1
- package/src/sql-filters/tickets.ts +1 -1
- package/src/sql-filters/users.ts +1 -1
- package/src/sql-sorters/groups.ts +23 -0
- package/src/sql-sorters/platform-memberships.ts +16 -16
- package/src/sql-sorters/registration-invitations.ts +36 -0
- package/tests/actions/patchOrganizationMember.ts +1 -1
- package/tests/actions/patchUserMember.ts +1 -1
- package/tests/assertions/assertBalances.ts +6 -12
- package/tests/e2e/api-rate-limits.test.ts +12 -24
- package/tests/e2e/bundle-discounts.test.ts +4 -1
- package/tests/e2e/charge-members.test.ts +13 -11
- package/tests/e2e/documents.test.ts +4 -1
- package/tests/e2e/register.test.ts +7 -9
- package/tests/e2e/stock.test.ts +4 -3
- package/tests/e2e/tickets.test.ts +1 -1
- package/tests/helpers/MollieMocker.ts +462 -0
- package/tests/helpers/PayconiqMocker.ts +138 -45
- package/tests/helpers/StripeMocker.ts +9 -6
- package/tests/helpers/index.ts +4 -0
- package/tests/init/initAdmin.ts +2 -2
- package/tests/init/initBundleDiscount.ts +1 -1
- package/tests/init/initMembershipOrganization.ts +13 -0
- package/tests/init/initPermissionRole.ts +3 -4
- package/tests/vitest.global.setup.ts +1 -1
- package/vitest.config.js +7 -0
- package/.nvmrc +0 -1
- package/src/endpoints/global/billing/ActivatePackagesEndpoint.ts +0 -216
- package/src/helpers/GroupBuilder.ts +0 -418
- package/src/seeds/0000000000-example.ts +0 -11
- package/src/seeds/1722256498-group-update-occupancy.ts +0 -52
- package/src/seeds/1726572303-schedule-stock-updates.ts +0 -52
- package/src/seeds/1726847064-setup-steps.ts +0 -16
- package/src/seeds/1728928974-update-cached-outstanding-balance-from-items.ts +0 -31
- package/src/seeds/1729253172-update-orders.ts +0 -21
- package/src/seeds/1733319079-fill-paying-organization-ids.ts +0 -68
- package/src/seeds/1733748412-update-deleted-order-numbers.ts +0 -109
- package/src/seeds/1733994455-balance-item-status-open.ts +0 -30
- package/src/seeds/1740046783-update-membership.ts +0 -17
- package/src/seeds/1741008870-fix-auditlog-description.ts +0 -50
- package/src/seeds/1741011468-fix-auditlog-description-uft16.ts +0 -88
- package/src/seeds/1741268179-fix-group-dates-of-events.ts +0 -32
- package/src/seeds/1750090030-records-configuration.ts +0 -26
- package/src/seeds/1751445358-upload-email-attachments.ts +0 -106
- package/src/seeds/1755532883-update-email-sender-ids.ts +0 -47
- package/src/seeds/1755790070-fill-email-recipient-errors.ts +0 -96
- package/src/seeds/1756115432-remove-old-drafts.ts +0 -16
- package/src/seeds/1756115433-fill-email-recipient-organization-id.ts +0 -30
- package/src/seeds/1756303697-update-email-counts.ts +0 -76
- package/src/seeds/1761665607-sync-member-users.ts +0 -59
- package/src/seeds/1765896674-document-update-year.ts +0 -66
- /package/src/{seeds → migrations}/0000000001-development-user.ts +0 -0
- /package/src/{seeds → migrations}/0000000002-clear-stamhoofd-email-templates.ts +0 -0
- /package/src/{seeds → migrations}/0000000003-default-email-templates.ts +0 -0
- /package/src/{seeds → migrations}/1752848561-groups-registration-periods.test.ts +0 -0
- /package/src/{seeds → migrations}/1766150402-document-published-at.test.ts +0 -0
- /package/src/{seeds → migrations}/1766150402-document-published-at.ts +0 -0
- /package/src/{seeds → migrations}/data/default-email-templates.sql +0 -0
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import type { Decoder} from '@simonbackx/simple-encoding';
|
|
1
|
+
import type { Decoder } from '@simonbackx/simple-encoding';
|
|
2
2
|
import { AutoEncoder, field, StringDecoder } from '@simonbackx/simple-encoding';
|
|
3
|
-
import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
|
|
3
|
+
import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
|
|
4
4
|
import { Endpoint, Response } from '@simonbackx/simple-endpoints';
|
|
5
5
|
import { Webshop } from '@stamhoofd/models';
|
|
6
6
|
import { PermissionLevel, WebshopUriAvailabilityResponse } from '@stamhoofd/structures';
|
|
7
|
+
import { isReservedWebshopPathSegment } from '@stamhoofd/utility';
|
|
7
8
|
|
|
8
9
|
import { Context } from '../../../../helpers/Context.js';
|
|
9
10
|
|
|
@@ -49,6 +50,14 @@ export class GetWebshopUriAvailabilityEndpoint extends Endpoint<Params, Query, B
|
|
|
49
50
|
throw Context.auth.notFoundOrNoAccess();
|
|
50
51
|
}
|
|
51
52
|
|
|
53
|
+
if (isReservedWebshopPathSegment(request.query.uri)) {
|
|
54
|
+
return new Response(
|
|
55
|
+
WebshopUriAvailabilityResponse.create({
|
|
56
|
+
available: false,
|
|
57
|
+
}),
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
52
61
|
const q = await Webshop.where({
|
|
53
62
|
uri: request.query.uri,
|
|
54
63
|
id: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { AutoEncoderPatchType, Decoder, PatchableArrayAutoEncoder} from '@simonbackx/simple-encoding';
|
|
1
|
+
import type { AutoEncoderPatchType, Decoder, PatchableArrayAutoEncoder } from '@simonbackx/simple-encoding';
|
|
2
2
|
import { PatchableArrayDecoder, patchObject, StringDecoder } from '@simonbackx/simple-encoding';
|
|
3
|
-
import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
|
|
3
|
+
import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
|
|
4
4
|
import { Endpoint, Response } from '@simonbackx/simple-endpoints';
|
|
5
5
|
import { SimpleError } from '@simonbackx/simple-errors';
|
|
6
6
|
import { Webshop, WebshopDiscountCode } from '@stamhoofd/models';
|
|
@@ -61,8 +61,7 @@ export class PatchWebshopDiscountCodesEndpoint extends Endpoint<Params, Query, B
|
|
|
61
61
|
|
|
62
62
|
try {
|
|
63
63
|
await model.save();
|
|
64
|
-
}
|
|
65
|
-
catch (e) {
|
|
64
|
+
} catch (e) {
|
|
66
65
|
// Duplicate key probably
|
|
67
66
|
if (e.code && e.code == 'ER_DUP_ENTRY') {
|
|
68
67
|
throw new SimpleError({
|
|
@@ -93,8 +92,7 @@ export class PatchWebshopDiscountCodesEndpoint extends Endpoint<Params, Query, B
|
|
|
93
92
|
|
|
94
93
|
try {
|
|
95
94
|
await model.save();
|
|
96
|
-
}
|
|
97
|
-
catch (e) {
|
|
95
|
+
} catch (e) {
|
|
98
96
|
// Duplicate key probably
|
|
99
97
|
if (e.code && e.code == 'ER_DUP_ENTRY') {
|
|
100
98
|
throw new SimpleError({
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import type { AutoEncoderPatchType, Decoder } from '@simonbackx/simple-encoding';
|
|
2
|
-
import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
|
|
2
|
+
import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
|
|
3
3
|
import { Endpoint, Response } from '@simonbackx/simple-endpoints';
|
|
4
4
|
import { SimpleError } from '@simonbackx/simple-errors';
|
|
5
5
|
import { Webshop } from '@stamhoofd/models';
|
|
6
6
|
import { QueueHandler } from '@stamhoofd/queues';
|
|
7
7
|
import { PermissionLevel, PrivateWebshop, WebshopPrivateMetaData } from '@stamhoofd/structures';
|
|
8
|
-
import { Formatter } from '@stamhoofd/utility';
|
|
8
|
+
import { Formatter, isReservedWebshopPathSegment } from '@stamhoofd/utility';
|
|
9
9
|
|
|
10
10
|
import { Context } from '../../../../helpers/Context.js';
|
|
11
|
+
import { RecordAnswerHelper } from '../../../../helpers/RecordAnswerHelper.js';
|
|
11
12
|
|
|
12
13
|
type Params = { id: string };
|
|
13
14
|
type Query = undefined;
|
|
@@ -56,6 +57,11 @@ export class PatchWebshopEndpoint extends Endpoint<Params, Query, Body, Response
|
|
|
56
57
|
if (request.body.meta.customCode !== undefined && !await Context.auth.hasFullAccess(organization.id)) {
|
|
57
58
|
throw Context.auth.error($t('%15n'));
|
|
58
59
|
}
|
|
60
|
+
|
|
61
|
+
if (request.body.meta.recordCategories) {
|
|
62
|
+
RecordAnswerHelper.throwIfPatchOrPutIsInvalid(webshop.meta.recordCategories, request.body.meta.recordCategories);
|
|
63
|
+
}
|
|
64
|
+
|
|
59
65
|
webshop.meta.patchOrPut(request.body.meta);
|
|
60
66
|
}
|
|
61
67
|
|
|
@@ -116,8 +122,7 @@ export class PatchWebshopEndpoint extends Endpoint<Params, Query, Body, Response
|
|
|
116
122
|
});
|
|
117
123
|
}
|
|
118
124
|
}
|
|
119
|
-
}
|
|
120
|
-
else {
|
|
125
|
+
} else {
|
|
121
126
|
webshop.domain = null;
|
|
122
127
|
webshop.privateMeta.dnsRecords = [];
|
|
123
128
|
webshop.meta.domainActive = false;
|
|
@@ -137,6 +142,15 @@ export class PatchWebshopEndpoint extends Endpoint<Params, Query, Body, Response
|
|
|
137
142
|
});
|
|
138
143
|
}
|
|
139
144
|
|
|
145
|
+
if (webshop.domainUri && isReservedWebshopPathSegment(webshop.domainUri)) {
|
|
146
|
+
throw new SimpleError({
|
|
147
|
+
code: 'invalid_field',
|
|
148
|
+
message: 'domainUri is reserved for internal webshop routes',
|
|
149
|
+
human: $t("%1a4"),
|
|
150
|
+
field: 'customUrl',
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
140
154
|
// Check exists
|
|
141
155
|
const existing = await Webshop.getByDomain(webshop.domain, webshop.domainUri);
|
|
142
156
|
if (existing !== undefined) {
|
|
@@ -146,8 +160,7 @@ export class PatchWebshopEndpoint extends Endpoint<Params, Query, Body, Response
|
|
|
146
160
|
human: $t(`%FP`) + ' ' + existing.meta.name + $t(`%FQ`),
|
|
147
161
|
});
|
|
148
162
|
}
|
|
149
|
-
}
|
|
150
|
-
else {
|
|
163
|
+
} else {
|
|
151
164
|
webshop.domainUri = null;
|
|
152
165
|
}
|
|
153
166
|
}
|
|
@@ -177,6 +190,15 @@ export class PatchWebshopEndpoint extends Endpoint<Params, Query, Body, Response
|
|
|
177
190
|
});
|
|
178
191
|
}
|
|
179
192
|
|
|
193
|
+
if (isReservedWebshopPathSegment(request.body.uri)) {
|
|
194
|
+
throw new SimpleError({
|
|
195
|
+
code: 'invalid_field',
|
|
196
|
+
message: 'Uri is reserved for internal webshop routes',
|
|
197
|
+
human: $t("%1a4"),
|
|
198
|
+
field: 'uri',
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
180
202
|
webshop.uri = request.body.uri;
|
|
181
203
|
}
|
|
182
204
|
|
|
@@ -191,8 +213,7 @@ export class PatchWebshopEndpoint extends Endpoint<Params, Query, Body, Response
|
|
|
191
213
|
|
|
192
214
|
try {
|
|
193
215
|
await webshop.save();
|
|
194
|
-
}
|
|
195
|
-
catch (e) {
|
|
216
|
+
} catch (e) {
|
|
196
217
|
// Duplicate key probably
|
|
197
218
|
if (e.code && e.code == 'ER_DUP_ENTRY') {
|
|
198
219
|
throw new SimpleError({
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { AutoEncoderPatchType, Data, Decoder, PatchableArrayAutoEncoder} from '@simonbackx/simple-encoding';
|
|
1
|
+
import type { AutoEncoderPatchType, Data, Decoder, PatchableArrayAutoEncoder } from '@simonbackx/simple-encoding';
|
|
2
2
|
import { ArrayDecoder, PatchableArray, PatchableArrayDecoder, StringDecoder } from '@simonbackx/simple-encoding';
|
|
3
|
-
import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
|
|
3
|
+
import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
|
|
4
4
|
import { Endpoint, Response } from '@simonbackx/simple-endpoints';
|
|
5
5
|
import { SimpleError } from '@simonbackx/simple-errors';
|
|
6
6
|
import { BalanceItem, BalanceItemPayment, Order, Payment, Webshop, WebshopCounter } from '@stamhoofd/models';
|
|
@@ -65,7 +65,7 @@ export class PatchWebshopOrdersEndpoint extends Endpoint<Params, Query, Body, Re
|
|
|
65
65
|
|
|
66
66
|
async handle(request: DecodedRequest<Params, Query, Body>) {
|
|
67
67
|
const organization = await Context.setOrganizationScope();
|
|
68
|
-
await Context.authenticate();
|
|
68
|
+
const { user } = await Context.authenticate();
|
|
69
69
|
|
|
70
70
|
// Fast throw first (more in depth checking for patches later)
|
|
71
71
|
if (!await Context.auth.hasSomeAccess(organization.id)) {
|
|
@@ -79,8 +79,7 @@ export class PatchWebshopOrdersEndpoint extends Endpoint<Params, Query, Body, Re
|
|
|
79
79
|
for (const p of request.body) {
|
|
80
80
|
body.addPatch(p);
|
|
81
81
|
}
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
82
|
+
} else {
|
|
84
83
|
body = request.body;
|
|
85
84
|
}
|
|
86
85
|
|
|
@@ -99,12 +98,12 @@ export class PatchWebshopOrdersEndpoint extends Endpoint<Params, Query, Body, Re
|
|
|
99
98
|
|
|
100
99
|
const orders = body.getPatches().length > 0
|
|
101
100
|
? await Order.where({
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
101
|
+
webshopId: webshop.id,
|
|
102
|
+
id: {
|
|
103
|
+
sign: 'IN',
|
|
104
|
+
value: body.getPatches().map(o => o.id),
|
|
105
|
+
},
|
|
106
|
+
})
|
|
108
107
|
: [];
|
|
109
108
|
|
|
110
109
|
// We use a getter because we need to have an up to date webshop struct
|
|
@@ -150,25 +149,25 @@ export class PatchWebshopOrdersEndpoint extends Endpoint<Params, Query, Body, Re
|
|
|
150
149
|
// Mark this order as paid
|
|
151
150
|
await order.markPaid(null, organization, webshop);
|
|
152
151
|
await order.save();
|
|
153
|
-
}
|
|
154
|
-
else {
|
|
152
|
+
} else {
|
|
155
153
|
const payment = new Payment();
|
|
156
154
|
payment.organizationId = organization.id;
|
|
157
155
|
payment.method = struct.data.paymentMethod;
|
|
158
156
|
payment.status = PaymentStatus.Created;
|
|
159
157
|
payment.price = totalPrice;
|
|
160
|
-
PaymentService.
|
|
158
|
+
PaymentService.roundPayment(payment);
|
|
161
159
|
payment.paidAt = null;
|
|
160
|
+
payment.adminUserId = user.id;
|
|
162
161
|
|
|
163
162
|
// Determine the payment provider (always null because no online payments here)
|
|
164
163
|
payment.provider = null;
|
|
165
|
-
ServiceFeeHelper.setServiceFee(
|
|
164
|
+
await ServiceFeeHelper.setServiceFee(
|
|
166
165
|
payment,
|
|
167
166
|
organization,
|
|
168
167
|
webshop.meta.ticketType === WebshopTicketType.None ? 'webshop' : 'tickets',
|
|
169
168
|
order.data.cart.items.flatMap(i => i.calculatedPrices.map(p => p.discountedPrice)),
|
|
170
169
|
);
|
|
171
|
-
|
|
170
|
+
await ServiceFeeHelper.setTransferFee({ payment, organization, stripeAccount: null });
|
|
172
171
|
await payment.save();
|
|
173
172
|
|
|
174
173
|
order.paymentId = payment.id;
|
|
@@ -209,22 +208,19 @@ export class PatchWebshopOrdersEndpoint extends Endpoint<Params, Query, Body, Re
|
|
|
209
208
|
await order.markValid(payment, []);
|
|
210
209
|
await payment.save();
|
|
211
210
|
await order.save();
|
|
212
|
-
}
|
|
213
|
-
else if (payment.method === PaymentMethod.PointOfSale) {
|
|
211
|
+
} else if (payment.method === PaymentMethod.PointOfSale) {
|
|
214
212
|
// Not really paid, but needed to create the tickets if needed
|
|
215
213
|
await order.markPaid(payment, organization, webshop);
|
|
216
214
|
await payment.save();
|
|
217
215
|
await order.save();
|
|
218
|
-
}
|
|
219
|
-
else {
|
|
216
|
+
} else {
|
|
220
217
|
throw new Error('Unsupported payment method');
|
|
221
218
|
}
|
|
222
219
|
|
|
223
220
|
balanceItem.description = order.generateBalanceDescription(webshop);
|
|
224
221
|
await balanceItem.save();
|
|
225
222
|
}
|
|
226
|
-
}
|
|
227
|
-
catch (e) {
|
|
223
|
+
} catch (e) {
|
|
228
224
|
await order.deleteOrderBecauseOfCreationError();
|
|
229
225
|
throw e;
|
|
230
226
|
}
|
|
@@ -278,8 +274,7 @@ export class PatchWebshopOrdersEndpoint extends Endpoint<Params, Query, Body, Re
|
|
|
278
274
|
model.markUpdated();
|
|
279
275
|
// Cancel payment if still pending
|
|
280
276
|
await BalanceItem.deleteForDeletedOrders([model.id]);
|
|
281
|
-
}
|
|
282
|
-
else {
|
|
277
|
+
} else {
|
|
283
278
|
if (previousStatus === OrderStatus.Canceled || previousStatus === OrderStatus.Deleted) {
|
|
284
279
|
model.markUpdated();
|
|
285
280
|
// Undo deletion
|
|
@@ -300,8 +295,7 @@ export class PatchWebshopOrdersEndpoint extends Endpoint<Params, Query, Body, Re
|
|
|
300
295
|
|
|
301
296
|
if (model.isDue) {
|
|
302
297
|
paidItem.status = BalanceItemStatus.Due;
|
|
303
|
-
}
|
|
304
|
-
else {
|
|
298
|
+
} else {
|
|
305
299
|
paidItem.status = BalanceItemStatus.Canceled;
|
|
306
300
|
}
|
|
307
301
|
paidItem.description = model.generateBalanceDescription(webshop);
|
|
@@ -310,8 +304,7 @@ export class PatchWebshopOrdersEndpoint extends Endpoint<Params, Query, Body, Re
|
|
|
310
304
|
// Zero out the other items
|
|
311
305
|
const otherItems = items.filter(i => i.id !== paidItem.id);
|
|
312
306
|
await BalanceItem.deleteItems(otherItems);
|
|
313
|
-
}
|
|
314
|
-
else if (items.length === 0
|
|
307
|
+
} else if (items.length === 0
|
|
315
308
|
&& model.totalToPay > 0) {
|
|
316
309
|
model.markUpdated();
|
|
317
310
|
const balanceItem = new BalanceItem();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AutoEncoderPatchType, Decoder } from '@simonbackx/simple-encoding';
|
|
2
2
|
import { ArrayDecoder } from '@simonbackx/simple-encoding';
|
|
3
|
-
import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
|
|
3
|
+
import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
|
|
4
4
|
import { Endpoint, Response } from '@simonbackx/simple-endpoints';
|
|
5
5
|
import { SimpleError, SimpleErrors } from '@simonbackx/simple-errors';
|
|
6
6
|
import { Ticket, Token, Webshop } from '@stamhoofd/models';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
|
|
1
|
+
import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
|
|
2
2
|
import { Endpoint, Response } from '@simonbackx/simple-endpoints';
|
|
3
3
|
import { UitpasService } from '../../../../services/uitpas/UitpasService.js';
|
|
4
|
-
import type { Decoder} from '@simonbackx/simple-encoding';
|
|
4
|
+
import type { Decoder } from '@simonbackx/simple-encoding';
|
|
5
5
|
import { AutoEncoder, field, StringDecoder } from '@simonbackx/simple-encoding';
|
|
6
6
|
import { Context } from '../../../../helpers/Context.js';
|
|
7
7
|
import type { UitpasEventsResponse } from '@stamhoofd/structures';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
|
|
1
|
+
import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
|
|
2
2
|
import { Endpoint, Response } from '@simonbackx/simple-endpoints';
|
|
3
3
|
import { SimpleError } from '@simonbackx/simple-errors';
|
|
4
4
|
import { Token, Webshop } from '@stamhoofd/models';
|
|
@@ -48,8 +48,7 @@ export class VerifyWebshopDomainEndpoint extends Endpoint<Params, Query, Body, R
|
|
|
48
48
|
if (webshop.domain !== null) {
|
|
49
49
|
webshop.privateMeta.dnsRecords = WebshopPrivateMetaData.buildDNSRecords(webshop.domain);
|
|
50
50
|
await webshop.updateDNSRecords();
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
51
|
+
} else {
|
|
53
52
|
webshop.privateMeta.dnsRecords = [];
|
|
54
53
|
webshop.meta.domainActive = false;
|
|
55
54
|
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { Request } from '@simonbackx/simple-endpoints';
|
|
2
|
+
import { OrganizationFactory, Token, UserFactory, Webshop, WebshopFactory } from '@stamhoofd/models';
|
|
3
|
+
import { Permissions, PermissionLevel, PrivateWebshop, WebshopMetaData } from '@stamhoofd/structures';
|
|
4
|
+
import { STExpect, TestUtils } from '@stamhoofd/test-utils';
|
|
5
|
+
|
|
6
|
+
import { testServer } from '../../../../../tests/helpers/TestServer.js';
|
|
7
|
+
import { CreateWebshopEndpoint } from './CreateWebshopEndpoint.js';
|
|
8
|
+
import { GetWebshopUriAvailabilityEndpoint } from './GetWebshopUriAvailabilityEndpoint.js';
|
|
9
|
+
import { PatchWebshopEndpoint } from './PatchWebshopEndpoint.js';
|
|
10
|
+
|
|
11
|
+
describe('Endpoint.WebshopReservedPathSegments', () => {
|
|
12
|
+
const checkUriEndpoint = new GetWebshopUriAvailabilityEndpoint();
|
|
13
|
+
const patchEndpoint = new PatchWebshopEndpoint();
|
|
14
|
+
const createEndpoint = new CreateWebshopEndpoint();
|
|
15
|
+
|
|
16
|
+
beforeEach(async () => {
|
|
17
|
+
TestUtils.setEnvironment('userMode', 'platform');
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
async function createAdminContext() {
|
|
21
|
+
const organization = await new OrganizationFactory({}).create();
|
|
22
|
+
const user = await new UserFactory({
|
|
23
|
+
organization,
|
|
24
|
+
permissions: Permissions.create({
|
|
25
|
+
level: PermissionLevel.Full,
|
|
26
|
+
}),
|
|
27
|
+
}).create();
|
|
28
|
+
const token = await Token.createToken(user);
|
|
29
|
+
|
|
30
|
+
return { organization, token };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
test('reserved webshop paths are not available as default URI', async () => {
|
|
34
|
+
const { organization, token } = await createAdminContext();
|
|
35
|
+
const webshop = await new WebshopFactory({ organizationId: organization.id }).create();
|
|
36
|
+
|
|
37
|
+
const request = Request.get({
|
|
38
|
+
path: '/webshop/' + webshop.id + '/check-uri',
|
|
39
|
+
host: organization.getApiHost(),
|
|
40
|
+
query: {
|
|
41
|
+
uri: 'tickets',
|
|
42
|
+
},
|
|
43
|
+
headers: { authorization: 'Bearer ' + token.accessToken },
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const response = await testServer.test(checkUriEndpoint, request);
|
|
47
|
+
|
|
48
|
+
expect(response.body.available).toBe(false);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test('reserved webshop paths cannot be saved as default URI', async () => {
|
|
52
|
+
const { organization, token } = await createAdminContext();
|
|
53
|
+
const webshop = await new WebshopFactory({ organizationId: organization.id }).create();
|
|
54
|
+
const patch = PrivateWebshop.patch({ uri: 'tickets' });
|
|
55
|
+
const request = Request.buildJson('PATCH', '/webshop/' + webshop.id, organization.getApiHost(), patch);
|
|
56
|
+
request.headers.authorization = 'Bearer ' + token.accessToken;
|
|
57
|
+
|
|
58
|
+
await expect(testServer.test(patchEndpoint, request)).rejects.toThrow(
|
|
59
|
+
STExpect.simpleError({ code: 'invalid_field', field: 'uri' }),
|
|
60
|
+
);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test('reserved webshop paths cannot be saved as custom domain URI', async () => {
|
|
64
|
+
const { organization, token } = await createAdminContext();
|
|
65
|
+
const webshop = await new WebshopFactory({ organizationId: organization.id }).create();
|
|
66
|
+
webshop.domain = 'shop.example.com';
|
|
67
|
+
webshop.domainUri = 'valid';
|
|
68
|
+
await webshop.save();
|
|
69
|
+
|
|
70
|
+
const patch = PrivateWebshop.patch({ domainUri: 'tickets' });
|
|
71
|
+
const request = Request.buildJson('PATCH', '/webshop/' + webshop.id, organization.getApiHost(), patch);
|
|
72
|
+
request.headers.authorization = 'Bearer ' + token.accessToken;
|
|
73
|
+
|
|
74
|
+
await expect(testServer.test(patchEndpoint, request)).rejects.toThrow(
|
|
75
|
+
STExpect.simpleError({ code: 'invalid_field', field: 'customUrl' }),
|
|
76
|
+
);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test('generated webshop URIs skip reserved webshop paths', async () => {
|
|
80
|
+
const { organization, token } = await createAdminContext();
|
|
81
|
+
const body = PrivateWebshop.create({
|
|
82
|
+
meta: WebshopMetaData.create({
|
|
83
|
+
name: 'Tickets',
|
|
84
|
+
}),
|
|
85
|
+
});
|
|
86
|
+
const request = Request.buildJson('POST', '/webshop', organization.getApiHost(), body);
|
|
87
|
+
request.headers.authorization = 'Bearer ' + token.accessToken;
|
|
88
|
+
|
|
89
|
+
const response = await testServer.test(createEndpoint, request);
|
|
90
|
+
const webshop = await Webshop.getByID(response.body.id);
|
|
91
|
+
|
|
92
|
+
expect(response.body.uri).not.toBe('tickets');
|
|
93
|
+
expect(webshop?.uri).not.toBe('tickets');
|
|
94
|
+
});
|
|
95
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Decoder} from '@simonbackx/simple-encoding';
|
|
1
|
+
import type { Decoder } from '@simonbackx/simple-encoding';
|
|
2
2
|
import { AutoEncoder, BooleanDecoder, field } from '@simonbackx/simple-encoding';
|
|
3
|
-
import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
|
|
3
|
+
import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
|
|
4
4
|
import { Endpoint, Response } from '@simonbackx/simple-endpoints';
|
|
5
5
|
import { SimpleError } from '@simonbackx/simple-errors';
|
|
6
6
|
import { Order } from '@stamhoofd/models';
|
|
@@ -45,10 +45,8 @@ export class ExchangePaymentEndpoint extends Endpoint<Params, Query, Body, Respo
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
async handle(request: DecodedRequest<Params, Query, Body>) {
|
|
48
|
-
const organization = await Context.setOptionalOrganizationScope({ willAuthenticate:
|
|
49
|
-
|
|
50
|
-
await Context.optionalAuthenticate();
|
|
51
|
-
}
|
|
48
|
+
const organization = await Context.setOptionalOrganizationScope({ willAuthenticate: true }); // will authentiate set to true because we allow exchanges for inactive organizations
|
|
49
|
+
await Context.optionalAuthenticate();
|
|
52
50
|
|
|
53
51
|
// Not method on payment because circular references (not supprted in ts)
|
|
54
52
|
const payment = await PaymentService.pollStatus(request.params.id, organization, request.query.cancel);
|
|
@@ -63,19 +61,23 @@ export class ExchangePaymentEndpoint extends Endpoint<Params, Query, Body, Respo
|
|
|
63
61
|
return new Response(undefined);
|
|
64
62
|
}
|
|
65
63
|
|
|
66
|
-
//
|
|
64
|
+
// Skip check permissions if order and created less than hour ago
|
|
67
65
|
let checkPermissions = true;
|
|
68
66
|
const hourAgo = new Date();
|
|
69
|
-
hourAgo.setHours(-
|
|
67
|
+
hourAgo.setHours(-2);
|
|
70
68
|
|
|
71
69
|
if (payment.createdAt > hourAgo) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
70
|
+
if (payment.payingOrganizationId) {
|
|
71
|
+
// B2B payments always required
|
|
72
|
+
checkPermissions = true;
|
|
73
|
+
} else {
|
|
74
|
+
const orders = await Order.where({ paymentId: payment.id }, { limit: 1 });
|
|
75
|
+
const isOrder = orders[0] !== undefined;
|
|
76
|
+
if (isOrder) {
|
|
77
|
+
checkPermissions = false;
|
|
78
|
+
}
|
|
76
79
|
}
|
|
77
80
|
}
|
|
78
|
-
// #endregion
|
|
79
81
|
|
|
80
82
|
return new Response(
|
|
81
83
|
await AuthenticatedStructures.paymentGeneral(payment, checkPermissions),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
|
|
1
|
+
import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
|
|
2
2
|
import { Endpoint, Response } from '@simonbackx/simple-endpoints';
|
|
3
3
|
import { SimpleError } from '@simonbackx/simple-errors';
|
|
4
4
|
import { signInternal } from '@stamhoofd/backend-env';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
|
|
1
|
+
import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
|
|
2
2
|
import { Endpoint, Response } from '@simonbackx/simple-endpoints';
|
|
3
3
|
import { SimpleError } from '@simonbackx/simple-errors';
|
|
4
4
|
import { Payment } from '@stamhoofd/models';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
|
|
1
|
+
import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
|
|
2
2
|
import { Endpoint, Response } from '@simonbackx/simple-endpoints';
|
|
3
3
|
import { UitpasNumberDetails, UitpasNumbersGetDetailsRequest } from '@stamhoofd/structures';
|
|
4
4
|
|
|
@@ -53,14 +53,12 @@ export class GetUitpasNumberDetailsEndpoint extends Endpoint<Params, Query, Body
|
|
|
53
53
|
uitpasNumber,
|
|
54
54
|
socialTariff,
|
|
55
55
|
}));
|
|
56
|
-
}
|
|
57
|
-
catch (error) {
|
|
56
|
+
} catch (error) {
|
|
58
57
|
if (isSimpleError(error) || isSimpleErrors(error)) {
|
|
59
58
|
error.addNamespace(i.toString());
|
|
60
59
|
error.addNamespace('uitpasNumbers');
|
|
61
60
|
simpleErrors.addError(error);
|
|
62
|
-
}
|
|
63
|
-
else {
|
|
61
|
+
} else {
|
|
64
62
|
throw error;
|
|
65
63
|
}
|
|
66
64
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
|
|
1
|
+
import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
|
|
2
2
|
import { Endpoint, Response } from '@simonbackx/simple-endpoints';
|
|
3
3
|
import type { Organization as OrganizationStruct } from '@stamhoofd/structures';
|
|
4
4
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { ArrayDecoder, StringDecoder } from '@simonbackx/simple-encoding';
|
|
2
|
-
import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
|
|
2
|
+
import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
|
|
3
3
|
import { Endpoint, Response } from '@simonbackx/simple-endpoints';
|
|
4
4
|
import { SimpleError } from '@simonbackx/simple-errors';
|
|
5
5
|
import { Webshop, WebshopDiscountCode } from '@stamhoofd/models';
|
|
6
6
|
import type { DiscountCode } from '@stamhoofd/structures';
|
|
7
7
|
|
|
8
8
|
import { Context } from '../../../helpers/Context.js';
|
|
9
|
+
import { WebshopAuthHelper } from './WebshopAuthHelper.js';
|
|
9
10
|
|
|
10
11
|
type Params = { id: string };
|
|
11
12
|
type Query = undefined;
|
|
@@ -39,6 +40,8 @@ export class CheckWebshopDiscountCodesEndpoint extends Endpoint<Params, Query, B
|
|
|
39
40
|
});
|
|
40
41
|
}
|
|
41
42
|
|
|
43
|
+
await WebshopAuthHelper.optionalAuthenticateForWebshop(webshop);
|
|
44
|
+
|
|
42
45
|
if (request.body.length > 10) {
|
|
43
46
|
// Auto limit
|
|
44
47
|
request.body = request.body.slice(0, 10);
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
|
|
1
|
+
import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
|
|
3
2
|
import { Endpoint, Response } from '@simonbackx/simple-endpoints';
|
|
4
3
|
import { SimpleError } from '@simonbackx/simple-errors';
|
|
5
|
-
import { Order } from '@stamhoofd/models';
|
|
4
|
+
import { Order, Webshop } from '@stamhoofd/models';
|
|
6
5
|
import { Payment } from '@stamhoofd/models';
|
|
7
6
|
import type { Order as OrderStruct } from '@stamhoofd/structures';
|
|
8
7
|
|
|
9
8
|
import { Context } from '../../../helpers/Context.js';
|
|
9
|
+
import { WebshopAuthHelper } from './WebshopAuthHelper.js';
|
|
10
10
|
type Params = { id: string; paymentId: string };
|
|
11
11
|
type Query = undefined;
|
|
12
12
|
type Body = undefined;
|
|
@@ -46,6 +46,17 @@ export class GetOrderByPaymentEndpoint extends Endpoint<Params, Query, Body, Res
|
|
|
46
46
|
});
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
const webshop = await Webshop.getByID(request.params.id);
|
|
50
|
+
if (!webshop || webshop.organizationId !== organization.id) {
|
|
51
|
+
throw new SimpleError({
|
|
52
|
+
code: 'not_found',
|
|
53
|
+
message: 'Webshop not found',
|
|
54
|
+
human: $t(`%FX`),
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
await WebshopAuthHelper.checkOrderAccess(webshop, order);
|
|
59
|
+
|
|
49
60
|
order.setRelation(Order.payment, payment);
|
|
50
61
|
return new Response(await order.getStructure());
|
|
51
62
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
|
|
1
|
+
import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
|
|
2
2
|
import { Endpoint, Response } from '@simonbackx/simple-endpoints';
|
|
3
3
|
import { SimpleError } from '@simonbackx/simple-errors';
|
|
4
|
-
import { Order } from '@stamhoofd/models';
|
|
4
|
+
import { Order, Webshop } from '@stamhoofd/models';
|
|
5
5
|
import type { Order as OrderStruct } from '@stamhoofd/structures';
|
|
6
6
|
|
|
7
7
|
import { Context } from '../../../helpers/Context.js';
|
|
8
|
+
import { WebshopAuthHelper } from './WebshopAuthHelper.js';
|
|
8
9
|
type Params = { id: string; orderId: string };
|
|
9
10
|
type Query = undefined;
|
|
10
11
|
type Body = undefined;
|
|
@@ -36,6 +37,17 @@ export class GetOrderEndpoint extends Endpoint<Params, Query, Body, ResponseBody
|
|
|
36
37
|
});
|
|
37
38
|
}
|
|
38
39
|
|
|
40
|
+
const webshop = await Webshop.getByID(request.params.id);
|
|
41
|
+
if (!webshop || webshop.organizationId !== organization.id) {
|
|
42
|
+
throw new SimpleError({
|
|
43
|
+
code: 'not_found',
|
|
44
|
+
message: 'Webshop not found',
|
|
45
|
+
human: $t(`%FX`),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
await WebshopAuthHelper.checkOrderAccess(webshop, order);
|
|
50
|
+
|
|
39
51
|
return new Response(await order.getStructure());
|
|
40
52
|
}
|
|
41
53
|
}
|