@stamhoofd/backend 2.121.0 → 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 +69 -52
- 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 +24 -24
- package/src/audit-logs/init.ts +8 -2
- 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 +5 -0
- package/src/crons/invoices.ts +32 -38
- package/src/crons/members-fees.ts +50 -0
- package/src/crons/mollie-chargebacks.ts +14 -15
- 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 +7 -64
- 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 +4 -6
- 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 +1 -1
- 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 +11 -11
- 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 +35 -34
- package/src/endpoints/global/registration-invitations/GetRegistrationInvitationsCountEndpoint.ts +1 -1
- package/src/endpoints/global/registration-invitations/GetRegistrationInvitationsEndpoint.test.ts +62 -63
- package/src/endpoints/global/registration-invitations/GetRegistrationInvitationsEndpoint.ts +6 -9
- package/src/endpoints/global/registration-invitations/PatchRegistrationInvitationsEndpoint.test.ts +51 -52
- package/src/endpoints/global/registration-invitations/PatchRegistrationInvitationsEndpoint.ts +6 -7
- 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 +7 -9
- package/src/endpoints/organization/dashboard/billing/ApplyRegisterCodeEndpoint.test.ts +73 -0
- package/src/endpoints/organization/dashboard/billing/ApplyRegisterCodeEndpoint.ts +89 -0
- package/src/endpoints/organization/dashboard/billing/DeactivatePackageEndpoint.ts +1 -5
- package/src/endpoints/organization/dashboard/billing/DeleteOrganizationMandateEndpoint.ts +11 -11
- package/src/endpoints/organization/dashboard/billing/GetOrganizationDetailedPayableBalanceCollectionEndpoint.ts +2 -2
- package/src/endpoints/organization/dashboard/billing/GetOrganizationDetailedPayableBalanceEndpoint.ts +8 -8
- package/src/endpoints/organization/dashboard/billing/GetOrganizationMandatesEndpoint.ts +9 -9
- 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 +4 -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 +60 -57
- package/src/endpoints/organization/dashboard/billing/PatchOrganizationMandatesEndpoint.ts +20 -20
- 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 +10 -6
- package/src/endpoints/organization/dashboard/invoices/PatchInvoicesEndpoint.ts +11 -2
- package/src/endpoints/organization/dashboard/mollie/CheckMollieEndpoint.ts +4 -5
- package/src/endpoints/organization/dashboard/mollie/ConnectMollieEndpoint.ts +5 -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 +50 -12
- 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 +21 -14
- package/src/endpoints/organization/dashboard/receivable-balances/ChargeReceivableBalancesEndpoint.ts +35 -28
- 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 +19 -18
- 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 +22 -7
- package/src/endpoints/organization/dashboard/webshops/PatchWebshopOrdersEndpoint.ts +20 -27
- 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 +2 -2
- 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 +16 -33
- 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 +50 -63
- package/src/helpers/AuthenticatedStructures.ts +69 -55
- 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 +2 -2
- 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 +105 -110
- package/src/helpers/RecordAnswerHelper.ts +7 -7
- 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 +14 -36
- 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 +7 -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/{seeds → migrations}/1750090030-records-configuration.ts +33 -32
- 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 +70 -26
- 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/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 +141 -44
- 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 +204 -251
- 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 +114 -121
- package/src/services/PaymentMandateService.ts +45 -45
- package/src/services/PaymentReallocationService.test.ts +1 -1
- package/src/services/PaymentReallocationService.ts +7 -9
- package/src/services/PaymentService.ts +444 -308
- package/src/services/PlatformMembershipService.ts +4 -8
- package/src/services/ReferralService.ts +223 -0
- package/src/services/RegistrationService.ts +63 -53
- package/src/services/SSOService.test.ts +119 -0
- package/src/services/SSOService.ts +56 -49
- package/src/services/STPackageService.ts +97 -61
- package/src/services/UniqueMemberNumberService.ts +69 -0
- package/src/services/UniqueUserService.ts +3 -6
- package/src/services/VATService.ts +85 -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 +5 -0
- 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/platform-memberships.ts +3 -3
- package/src/sql-filters/receivable-balances.ts +1 -1
- 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 +2 -2
- 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 +6 -0
- package/.nvmrc +0 -1
- 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/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}/1779121239-default-invoice-email-template.sql +0 -0
- /package/src/{seeds → migrations}/data/default-email-templates.sql +0 -0
|
@@ -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,8 +149,7 @@ 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;
|
|
@@ -159,16 +157,17 @@ export class PatchWebshopOrdersEndpoint extends Endpoint<Params, Query, Body, Re
|
|
|
159
157
|
payment.price = totalPrice;
|
|
160
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';
|
|
@@ -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
|
}
|
|
@@ -1,12 +1,13 @@
|
|
|
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 { SimpleError } from '@simonbackx/simple-errors';
|
|
6
|
-
import { Order, Ticket } from '@stamhoofd/models';
|
|
6
|
+
import { Order, Ticket, Webshop } from '@stamhoofd/models';
|
|
7
7
|
import { TicketOrder, TicketPublic } from '@stamhoofd/structures';
|
|
8
8
|
|
|
9
9
|
import { Context } from '../../../helpers/Context.js';
|
|
10
|
+
import { WebshopAuthHelper } from './WebshopAuthHelper.js';
|
|
10
11
|
type Params = { id: string };
|
|
11
12
|
|
|
12
13
|
class Query extends AutoEncoder {
|
|
@@ -45,6 +46,14 @@ export class GetTicketsEndpoint extends Endpoint<Params, Query, Body, ResponseBo
|
|
|
45
46
|
|
|
46
47
|
async handle(request: DecodedRequest<Params, Query, Body>) {
|
|
47
48
|
const organization = await Context.setOrganizationScope({ willAuthenticate: false });
|
|
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
|
+
}
|
|
48
57
|
|
|
49
58
|
if (request.query.secret) {
|
|
50
59
|
const [ticket] = await Ticket.where({
|
|
@@ -61,17 +70,20 @@ export class GetTicketsEndpoint extends Endpoint<Params, Query, Body, ResponseBo
|
|
|
61
70
|
});
|
|
62
71
|
}
|
|
63
72
|
|
|
73
|
+
const order = await Order.getByID(ticket.orderId);
|
|
74
|
+
if (!order || order.webshopId !== request.params.id || order.organizationId !== organization.id) {
|
|
75
|
+
console.error('Error: missing order ' + ticket.orderId + ' for ticket ' + ticket.id);
|
|
76
|
+
throw new SimpleError({
|
|
77
|
+
code: 'not_found',
|
|
78
|
+
message: 'Ticket not found',
|
|
79
|
+
human: $t(`%FZ`),
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
await WebshopAuthHelper.checkOrderAccess(webshop, order);
|
|
84
|
+
|
|
64
85
|
if (!request.query.orderId) {
|
|
65
86
|
// Include item data
|
|
66
|
-
const order = await Order.getByID(ticket.orderId);
|
|
67
|
-
if (!order || order.webshopId !== request.params.id) {
|
|
68
|
-
console.error('Error: missing order ' + ticket.orderId + ' for ticket ' + ticket.id);
|
|
69
|
-
throw new SimpleError({
|
|
70
|
-
code: 'not_found',
|
|
71
|
-
message: 'Ticket not found',
|
|
72
|
-
human: $t(`%FZ`),
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
87
|
|
|
76
88
|
if (ticket.itemId) {
|
|
77
89
|
const item = order.data.cart.items.find(i => i.id === ticket.itemId);
|
|
@@ -91,8 +103,7 @@ export class GetTicketsEndpoint extends Endpoint<Params, Query, Body, ResponseBo
|
|
|
91
103
|
items: [item],
|
|
92
104
|
}),
|
|
93
105
|
]);
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
106
|
+
} else {
|
|
96
107
|
return new Response([
|
|
97
108
|
TicketPublic.create({
|
|
98
109
|
...ticket,
|
|
@@ -104,8 +115,7 @@ export class GetTicketsEndpoint extends Endpoint<Params, Query, Body, ResponseBo
|
|
|
104
115
|
return new Response([
|
|
105
116
|
TicketOrder.create(ticket),
|
|
106
117
|
]);
|
|
107
|
-
}
|
|
108
|
-
else {
|
|
118
|
+
} else {
|
|
109
119
|
if (!request.query.orderId) {
|
|
110
120
|
throw new SimpleError({
|
|
111
121
|
code: 'not_found',
|
|
@@ -119,6 +129,17 @@ export class GetTicketsEndpoint extends Endpoint<Params, Query, Body, ResponseBo
|
|
|
119
129
|
organizationId: organization.id,
|
|
120
130
|
deletedAt: null,
|
|
121
131
|
});
|
|
132
|
+
|
|
133
|
+
const order = await Order.getByID(request.query.orderId);
|
|
134
|
+
if (!order || order.webshopId !== request.params.id || order.organizationId !== organization.id) {
|
|
135
|
+
throw new SimpleError({
|
|
136
|
+
code: 'not_found',
|
|
137
|
+
message: 'Ticket not found',
|
|
138
|
+
human: $t(`%FZ`),
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
await WebshopAuthHelper.checkOrderAccess(webshop, order);
|
|
122
143
|
return new Response(
|
|
123
144
|
tickets.map(ticket => TicketOrder.create(ticket)),
|
|
124
145
|
);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Request } from '@simonbackx/simple-endpoints';
|
|
2
2
|
import { OrganizationFactory, Token, UserFactory, WebshopFactory } from '@stamhoofd/models';
|
|
3
|
-
import { PermissionLevel, Permissions } from '@stamhoofd/structures';
|
|
3
|
+
import { PermissionLevel, Permissions, WebshopAuthType, WebshopMetaData } from '@stamhoofd/structures';
|
|
4
4
|
|
|
5
|
-
import { TestUtils } from '@stamhoofd/test-utils';
|
|
5
|
+
import { STExpect, TestUtils } from '@stamhoofd/test-utils';
|
|
6
6
|
import { testServer } from '../../../../tests/helpers/TestServer.js';
|
|
7
7
|
import { GetWebshopEndpoint } from './GetWebshopEndpoint.js';
|
|
8
8
|
|
|
@@ -43,6 +43,38 @@ describe('Endpoint.GetWebshop', () => {
|
|
|
43
43
|
expect((response.body as any).privateMeta).toBeUndefined();
|
|
44
44
|
});
|
|
45
45
|
|
|
46
|
+
test('Reject anonymous access for required-auth webshop', async () => {
|
|
47
|
+
const organization = await new OrganizationFactory({}).create();
|
|
48
|
+
const webshop = await new WebshopFactory({
|
|
49
|
+
organizationId: organization.id,
|
|
50
|
+
meta: WebshopMetaData.create({
|
|
51
|
+
authType: WebshopAuthType.Required,
|
|
52
|
+
}),
|
|
53
|
+
}).create();
|
|
54
|
+
|
|
55
|
+
const r = Request.buildJson('GET', '/webshop/' + webshop.id, organization.getApiHost());
|
|
56
|
+
|
|
57
|
+
await expect(testServer.test(endpoint, r)).rejects.toThrow(STExpect.errorWithCode('not_authenticated'));
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test('Allow signed in user access for required-auth webshop', async () => {
|
|
61
|
+
const organization = await new OrganizationFactory({}).create();
|
|
62
|
+
const user = await new UserFactory({ organization }).create();
|
|
63
|
+
const token = await Token.createToken(user);
|
|
64
|
+
const webshop = await new WebshopFactory({
|
|
65
|
+
organizationId: organization.id,
|
|
66
|
+
meta: WebshopMetaData.create({
|
|
67
|
+
authType: WebshopAuthType.Required,
|
|
68
|
+
}),
|
|
69
|
+
}).create();
|
|
70
|
+
|
|
71
|
+
const r = Request.buildJson('GET', '/webshop/' + webshop.id, organization.getApiHost());
|
|
72
|
+
r.headers.authorization = 'Bearer ' + token.accessToken;
|
|
73
|
+
|
|
74
|
+
const response = await testServer.test(endpoint, r);
|
|
75
|
+
expect(response.body.id).toEqual(webshop.id);
|
|
76
|
+
});
|
|
77
|
+
|
|
46
78
|
test('Get webshop as admin', async () => {
|
|
47
79
|
const organization = await new OrganizationFactory({}).create();
|
|
48
80
|
const user = await new UserFactory({
|
|
@@ -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 { Webshop } from '@stamhoofd/models';
|
|
@@ -6,6 +6,7 @@ import type { PrivateWebshop, Webshop as WebshopStruct } from '@stamhoofd/struct
|
|
|
6
6
|
|
|
7
7
|
import { AuthenticatedStructures } from '../../../helpers/AuthenticatedStructures.js';
|
|
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;
|
|
@@ -28,7 +29,6 @@ export class GetWebshopEndpoint extends Endpoint<Params, Query, Body, ResponseBo
|
|
|
28
29
|
|
|
29
30
|
async handle(request: DecodedRequest<Params, Query, Body>) {
|
|
30
31
|
await Context.setOptionalOrganizationScope(); // editing webshop from the admin panel -> no scope
|
|
31
|
-
await Context.optionalAuthenticate();
|
|
32
32
|
|
|
33
33
|
const webshop = await Webshop.getByID(request.params.id);
|
|
34
34
|
if (!webshop) {
|
|
@@ -39,6 +39,8 @@ export class GetWebshopEndpoint extends Endpoint<Params, Query, Body, ResponseBo
|
|
|
39
39
|
});
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
await WebshopAuthHelper.optionalAuthenticateForWebshop(webshop);
|
|
43
|
+
|
|
42
44
|
return new Response(
|
|
43
45
|
await AuthenticatedStructures.webshop(webshop),
|
|
44
46
|
);
|