@stamhoofd/backend 1.0.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/.env.template.json +63 -0
- package/.eslintrc.js +61 -0
- package/README.md +40 -0
- package/index.ts +172 -0
- package/jest.config.js +11 -0
- package/migrations.ts +33 -0
- package/package.json +48 -0
- package/src/crons.ts +845 -0
- package/src/endpoints/admin/organizations/GetOrganizationsCountEndpoint.ts +42 -0
- package/src/endpoints/admin/organizations/GetOrganizationsEndpoint.ts +320 -0
- package/src/endpoints/admin/organizations/PatchOrganizationsEndpoint.ts +171 -0
- package/src/endpoints/auth/CreateAdminEndpoint.ts +137 -0
- package/src/endpoints/auth/CreateTokenEndpoint.test.ts +68 -0
- package/src/endpoints/auth/CreateTokenEndpoint.ts +200 -0
- package/src/endpoints/auth/DeleteTokenEndpoint.ts +31 -0
- package/src/endpoints/auth/ForgotPasswordEndpoint.ts +70 -0
- package/src/endpoints/auth/GetUserEndpoint.test.ts +64 -0
- package/src/endpoints/auth/GetUserEndpoint.ts +57 -0
- package/src/endpoints/auth/PatchApiUserEndpoint.ts +90 -0
- package/src/endpoints/auth/PatchUserEndpoint.ts +122 -0
- package/src/endpoints/auth/PollEmailVerificationEndpoint.ts +37 -0
- package/src/endpoints/auth/RetryEmailVerificationEndpoint.ts +41 -0
- package/src/endpoints/auth/SignupEndpoint.ts +107 -0
- package/src/endpoints/auth/VerifyEmailEndpoint.ts +89 -0
- package/src/endpoints/global/addresses/SearchRegionsEndpoint.ts +95 -0
- package/src/endpoints/global/addresses/ValidateAddressEndpoint.ts +31 -0
- package/src/endpoints/global/caddy/CheckDomainCertEndpoint.ts +101 -0
- package/src/endpoints/global/email/GetEmailAddressEndpoint.ts +53 -0
- package/src/endpoints/global/email/ManageEmailAddressEndpoint.ts +57 -0
- package/src/endpoints/global/files/UploadFile.ts +147 -0
- package/src/endpoints/global/files/UploadImage.ts +119 -0
- package/src/endpoints/global/members/GetMemberFamilyEndpoint.ts +76 -0
- package/src/endpoints/global/members/GetMembersCountEndpoint.ts +43 -0
- package/src/endpoints/global/members/GetMembersEndpoint.ts +429 -0
- package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.ts +734 -0
- package/src/endpoints/global/organizations/CheckRegisterCodeEndpoint.ts +45 -0
- package/src/endpoints/global/organizations/CreateOrganizationEndpoint.test.ts +105 -0
- package/src/endpoints/global/organizations/CreateOrganizationEndpoint.ts +146 -0
- package/src/endpoints/global/organizations/GetOrganizationFromDomainEndpoint.test.ts +52 -0
- package/src/endpoints/global/organizations/GetOrganizationFromDomainEndpoint.ts +80 -0
- package/src/endpoints/global/organizations/GetOrganizationFromUriEndpoint.ts +49 -0
- package/src/endpoints/global/organizations/SearchOrganizationEndpoint.test.ts +58 -0
- package/src/endpoints/global/organizations/SearchOrganizationEndpoint.ts +62 -0
- package/src/endpoints/global/payments/ExchangeSTPaymentEndpoint.ts +153 -0
- package/src/endpoints/global/payments/StripeWebhookEndpoint.ts +134 -0
- package/src/endpoints/global/platform/GetPlatformAdminsEndpoint.ts +44 -0
- package/src/endpoints/global/platform/GetPlatformEnpoint.ts +39 -0
- package/src/endpoints/global/platform/PatchPlatformEnpoint.ts +63 -0
- package/src/endpoints/global/registration/GetPaymentRegistrations.ts +68 -0
- package/src/endpoints/global/registration/GetUserBalanceEndpoint.ts +39 -0
- package/src/endpoints/global/registration/GetUserDocumentsEndpoint.ts +80 -0
- package/src/endpoints/global/registration/GetUserMembersEndpoint.ts +41 -0
- package/src/endpoints/global/registration/PatchUserMembersEndpoint.ts +134 -0
- package/src/endpoints/global/registration/RegisterMembersEndpoint.ts +521 -0
- package/src/endpoints/global/registration-periods/GetRegistrationPeriodsEndpoint.ts +37 -0
- package/src/endpoints/global/registration-periods/PatchRegistrationPeriodsEndpoint.ts +115 -0
- package/src/endpoints/global/webshops/GetWebshopFromDomainEndpoint.ts +187 -0
- package/src/endpoints/organization/dashboard/billing/ActivatePackagesEndpoint.ts +424 -0
- package/src/endpoints/organization/dashboard/billing/DeactivatePackageEndpoint.ts +67 -0
- package/src/endpoints/organization/dashboard/billing/GetBillingStatusEndpoint.ts +39 -0
- package/src/endpoints/organization/dashboard/documents/GetDocumentTemplateXML.ts +57 -0
- package/src/endpoints/organization/dashboard/documents/GetDocumentTemplatesEndpoint.ts +50 -0
- package/src/endpoints/organization/dashboard/documents/GetDocumentsEndpoint.ts +50 -0
- package/src/endpoints/organization/dashboard/documents/PatchDocumentEndpoint.ts +129 -0
- package/src/endpoints/organization/dashboard/documents/PatchDocumentTemplateEndpoint.ts +114 -0
- package/src/endpoints/organization/dashboard/email/CheckEmailBouncesEndpoint.ts +50 -0
- package/src/endpoints/organization/dashboard/email/EmailEndpoint.ts +234 -0
- package/src/endpoints/organization/dashboard/email-templates/GetEmailTemplatesEndpoint.ts +62 -0
- package/src/endpoints/organization/dashboard/email-templates/PatchEmailTemplatesEndpoint.ts +85 -0
- package/src/endpoints/organization/dashboard/mollie/CheckMollieEndpoint.ts +80 -0
- package/src/endpoints/organization/dashboard/mollie/ConnectMollieEndpoint.ts +54 -0
- package/src/endpoints/organization/dashboard/mollie/DisconnectMollieEndpoint.ts +49 -0
- package/src/endpoints/organization/dashboard/mollie/GetMollieDashboardEndpoint.ts +63 -0
- package/src/endpoints/organization/dashboard/nolt/CreateNoltTokenEndpoint.ts +61 -0
- package/src/endpoints/organization/dashboard/organization/ApplyRegisterCodeEndpoint.test.ts +64 -0
- package/src/endpoints/organization/dashboard/organization/ApplyRegisterCodeEndpoint.ts +84 -0
- package/src/endpoints/organization/dashboard/organization/GetOrganizationArchivedGroups.ts +43 -0
- package/src/endpoints/organization/dashboard/organization/GetOrganizationDeletedGroups.ts +42 -0
- package/src/endpoints/organization/dashboard/organization/GetOrganizationSSOEndpoint.ts +43 -0
- package/src/endpoints/organization/dashboard/organization/GetRegisterCodeEndpoint.ts +65 -0
- package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.test.ts +281 -0
- package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.ts +338 -0
- package/src/endpoints/organization/dashboard/organization/SetOrganizationDomainEndpoint.ts +196 -0
- package/src/endpoints/organization/dashboard/organization/SetOrganizationSSOEndpoint.ts +50 -0
- package/src/endpoints/organization/dashboard/payments/GetMemberBalanceEndpoint.ts +48 -0
- package/src/endpoints/organization/dashboard/payments/GetPaymentsEndpoint.ts +207 -0
- package/src/endpoints/organization/dashboard/payments/PatchBalanceItemsEndpoint.ts +202 -0
- package/src/endpoints/organization/dashboard/payments/PatchPaymentsEndpoint.ts +233 -0
- package/src/endpoints/organization/dashboard/registration-periods/GetOrganizationRegistrationPeriodsEndpoint.ts +66 -0
- package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.ts +210 -0
- package/src/endpoints/organization/dashboard/stripe/ConnectStripeEndpoint.ts +93 -0
- package/src/endpoints/organization/dashboard/stripe/DeleteStripeAccountEndpoint.ts +59 -0
- package/src/endpoints/organization/dashboard/stripe/GetStripeAccountLinkEndpoint.ts +78 -0
- package/src/endpoints/organization/dashboard/stripe/GetStripeAccountsEndpoint.ts +40 -0
- package/src/endpoints/organization/dashboard/stripe/GetStripeLoginLinkEndpoint.ts +69 -0
- package/src/endpoints/organization/dashboard/stripe/UpdateStripeAccountEndpoint.ts +52 -0
- package/src/endpoints/organization/dashboard/users/CreateApiUserEndpoint.ts +73 -0
- package/src/endpoints/organization/dashboard/users/DeleteUserEndpoint.ts +60 -0
- package/src/endpoints/organization/dashboard/users/GetApiUsersEndpoint.ts +47 -0
- package/src/endpoints/organization/dashboard/users/GetOrganizationAdminsEndpoint.ts +41 -0
- package/src/endpoints/organization/dashboard/webshops/CreateWebshopEndpoint.ts +217 -0
- package/src/endpoints/organization/dashboard/webshops/DeleteWebshopEndpoint.ts +51 -0
- package/src/endpoints/organization/dashboard/webshops/GetDiscountCodesEndpoint.ts +47 -0
- package/src/endpoints/organization/dashboard/webshops/GetWebshopOrdersEndpoint.ts +83 -0
- package/src/endpoints/organization/dashboard/webshops/GetWebshopTicketsEndpoint.ts +68 -0
- package/src/endpoints/organization/dashboard/webshops/GetWebshopUriAvailabilityEndpoint.ts +69 -0
- package/src/endpoints/organization/dashboard/webshops/PatchDiscountCodesEndpoint.ts +125 -0
- package/src/endpoints/organization/dashboard/webshops/PatchWebshopEndpoint.ts +204 -0
- package/src/endpoints/organization/dashboard/webshops/PatchWebshopOrdersEndpoint.ts +278 -0
- package/src/endpoints/organization/dashboard/webshops/PatchWebshopTicketsEndpoint.ts +80 -0
- package/src/endpoints/organization/dashboard/webshops/VerifyWebshopDomainEndpoint.ts +60 -0
- package/src/endpoints/organization/shared/ExchangePaymentEndpoint.ts +379 -0
- package/src/endpoints/organization/shared/GetDocumentHtml.ts +54 -0
- package/src/endpoints/organization/shared/GetPaymentEndpoint.ts +45 -0
- package/src/endpoints/organization/shared/auth/GetOrganizationEndpoint.test.ts +78 -0
- package/src/endpoints/organization/shared/auth/GetOrganizationEndpoint.ts +34 -0
- package/src/endpoints/organization/shared/auth/OpenIDConnectCallbackEndpoint.ts +44 -0
- package/src/endpoints/organization/shared/auth/OpenIDConnectStartEndpoint.ts +82 -0
- package/src/endpoints/organization/webshops/CheckWebshopDiscountCodesEndpoint.ts +59 -0
- package/src/endpoints/organization/webshops/GetOrderByPaymentEndpoint.ts +51 -0
- package/src/endpoints/organization/webshops/GetOrderEndpoint.ts +40 -0
- package/src/endpoints/organization/webshops/GetTicketsEndpoint.ts +124 -0
- package/src/endpoints/organization/webshops/GetWebshopEndpoint.test.ts +130 -0
- package/src/endpoints/organization/webshops/GetWebshopEndpoint.ts +50 -0
- package/src/endpoints/organization/webshops/PlaceOrderEndpoint.test.ts +450 -0
- package/src/endpoints/organization/webshops/PlaceOrderEndpoint.ts +335 -0
- package/src/helpers/AddressValidator.test.ts +40 -0
- package/src/helpers/AddressValidator.ts +256 -0
- package/src/helpers/AdminPermissionChecker.ts +1031 -0
- package/src/helpers/AuthenticatedStructures.ts +158 -0
- package/src/helpers/BuckarooHelper.ts +279 -0
- package/src/helpers/CheckSettlements.ts +215 -0
- package/src/helpers/Context.ts +202 -0
- package/src/helpers/CookieHelper.ts +45 -0
- package/src/helpers/ForwardHandler.test.ts +216 -0
- package/src/helpers/ForwardHandler.ts +140 -0
- package/src/helpers/OpenIDConnectHelper.ts +284 -0
- package/src/helpers/StripeHelper.ts +293 -0
- package/src/helpers/StripePayoutChecker.ts +188 -0
- package/src/middleware/ContextMiddleware.ts +16 -0
- package/src/migrations/1646578856-validate-addresses.ts +60 -0
- package/src/seeds/0000000000-example.ts +13 -0
- package/src/seeds/1715028563-user-permissions.ts +52 -0
- package/tests/e2e/stock.test.ts +2120 -0
- package/tests/e2e/tickets.test.ts +926 -0
- package/tests/helpers/StripeMocker.ts +362 -0
- package/tests/helpers/TestServer.ts +21 -0
- package/tests/jest.global.setup.ts +29 -0
- package/tests/jest.setup.ts +59 -0
- package/tsconfig.json +42 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import {Order, Payment, StripeCheckoutSession, StripePaymentIntent} from "@stamhoofd/models";
|
|
2
|
+
import { Settlement } from "@stamhoofd/structures";
|
|
3
|
+
import Stripe from "stripe";
|
|
4
|
+
|
|
5
|
+
export class StripePayoutChecker {
|
|
6
|
+
private stripe: Stripe;
|
|
7
|
+
private stripePlatform: Stripe;
|
|
8
|
+
|
|
9
|
+
constructor({secretKey, stripeAccount}: { secretKey: string, stripeAccount?: string}) {
|
|
10
|
+
this.stripe = new Stripe(
|
|
11
|
+
secretKey, {
|
|
12
|
+
apiVersion: '2022-11-15',
|
|
13
|
+
typescript: true,
|
|
14
|
+
maxNetworkRetries: 1,
|
|
15
|
+
timeout: 10000,
|
|
16
|
+
stripeAccount
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
this.stripePlatform = new Stripe(
|
|
20
|
+
secretKey, {
|
|
21
|
+
apiVersion: '2022-11-15',
|
|
22
|
+
typescript: true,
|
|
23
|
+
maxNetworkRetries: 1,
|
|
24
|
+
timeout: 10000
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async checkSettlements(checkAll = false) {
|
|
30
|
+
// Check last 2 weeks + 3 day margin, unless we check them all
|
|
31
|
+
const d = new Date()
|
|
32
|
+
d.setDate(d.getDate() - 17)
|
|
33
|
+
|
|
34
|
+
if (checkAll) {
|
|
35
|
+
d.setFullYear(2022, 11, 1)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Loop all payouts
|
|
39
|
+
try {
|
|
40
|
+
// Fetch all payouts that are paid out
|
|
41
|
+
for await (const payout of this.stripe.payouts.list({
|
|
42
|
+
status: 'paid',
|
|
43
|
+
arrival_date: {
|
|
44
|
+
gte: Math.floor(d.getTime() / 1000)
|
|
45
|
+
}
|
|
46
|
+
})) {
|
|
47
|
+
// Get all payments for this payout
|
|
48
|
+
await this.fetchBalanceItems(payout);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
} catch (e) {
|
|
52
|
+
console.error(e)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
private async fetchBalanceItems(payout: Stripe.Payout) {
|
|
57
|
+
// For the given payout, fetch all balance items
|
|
58
|
+
const params = {
|
|
59
|
+
payout: payout.id,
|
|
60
|
+
// Via the Application Fee object, we can get the original payment metadata
|
|
61
|
+
expand: ['data.source', 'data.source.application_fee', 'data.source.application_fee.originating_transaction'],
|
|
62
|
+
// TODO: ALSO DO CARDS! (type: 'charge')
|
|
63
|
+
//type: 'payment'
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
for await (const balanceItem of this.stripe.balanceTransactions.list(params)) {
|
|
67
|
+
// TODO
|
|
68
|
+
|
|
69
|
+
if (balanceItem.type === 'charge' || balanceItem.type === 'payment') {
|
|
70
|
+
await this.handleBalanceItem(payout, balanceItem);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
private async handleBalanceItem(payout: Stripe.Payout, balanceItem: Stripe.BalanceTransaction) {
|
|
78
|
+
if (!balanceItem.source || typeof balanceItem.source === 'string') {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (balanceItem.source.object !== 'charge') {
|
|
82
|
+
console.log("No payment id set for charge " + balanceItem.source.id)
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
let paymentId = balanceItem.source.metadata.payment;
|
|
87
|
+
|
|
88
|
+
if (!paymentId) {
|
|
89
|
+
// Search in the metadata of the application fee, originating transaction
|
|
90
|
+
if (typeof balanceItem.source.application_fee !== 'string' && balanceItem.source.application_fee) {
|
|
91
|
+
const applicationFee = balanceItem.source.application_fee;
|
|
92
|
+
|
|
93
|
+
if (applicationFee.originating_transaction !== 'string' && applicationFee.originating_transaction) {
|
|
94
|
+
const originatingTransaction = applicationFee.originating_transaction as Stripe.Charge;
|
|
95
|
+
paymentId = originatingTransaction.metadata.payment;
|
|
96
|
+
|
|
97
|
+
if (!paymentId) {
|
|
98
|
+
// Historical bug where we didn't save payment in metadata
|
|
99
|
+
// Try to look it up by payment intent id
|
|
100
|
+
|
|
101
|
+
if (originatingTransaction.payment_intent) {
|
|
102
|
+
const paymentIntentId = typeof originatingTransaction.payment_intent === 'string' ? originatingTransaction.payment_intent : originatingTransaction.payment_intent.id
|
|
103
|
+
const stripePayments = await StripePaymentIntent.where({
|
|
104
|
+
stripeIntentId: paymentIntentId
|
|
105
|
+
}, {limit: 1});
|
|
106
|
+
|
|
107
|
+
if (stripePayments.length === 1) {
|
|
108
|
+
paymentId = stripePayments[0].paymentId;
|
|
109
|
+
console.log("Found missing payment metadata for payment intent "+originatingTransaction.payment_intent, paymentId)
|
|
110
|
+
} else {
|
|
111
|
+
// Probably a card payment
|
|
112
|
+
// Search for the checkout session
|
|
113
|
+
const checkoutSession = await this.stripePlatform.checkout.sessions.list({
|
|
114
|
+
payment_intent: paymentIntentId
|
|
115
|
+
})
|
|
116
|
+
if (checkoutSession.data.length === 1) {
|
|
117
|
+
const session = checkoutSession.data[0];
|
|
118
|
+
console.log("Found checkout session for payment intent ", paymentIntentId, session)
|
|
119
|
+
|
|
120
|
+
// Search
|
|
121
|
+
const stripeCheckoutSessions = await StripeCheckoutSession.where({
|
|
122
|
+
stripeSessionId: session.id
|
|
123
|
+
}, {limit: 1});
|
|
124
|
+
|
|
125
|
+
if (stripeCheckoutSessions.length === 1) {
|
|
126
|
+
paymentId = stripeCheckoutSessions[0].paymentId;
|
|
127
|
+
console.log("Found missing payment metadata for payment intent "+originatingTransaction.payment_intent, paymentId)
|
|
128
|
+
} else {
|
|
129
|
+
console.log("No payment found for checkout session "+session.id)
|
|
130
|
+
}
|
|
131
|
+
} else {
|
|
132
|
+
console.log("No Stripe Checkout Sessions found for payment intent "+paymentIntentId)
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (!paymentId) {
|
|
144
|
+
console.log(balanceItem)
|
|
145
|
+
console.log("No payment id set for charge " + balanceItem.source.id)
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const applicationFee = balanceItem.source.application_fee_amount;
|
|
150
|
+
|
|
151
|
+
// Cool, we can store this in the database now.
|
|
152
|
+
|
|
153
|
+
const payment = await Payment.getByID(paymentId);
|
|
154
|
+
if (!payment) {
|
|
155
|
+
console.log("Invalid payment id set for charge " + balanceItem.source.id+': '+paymentId)
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (payment.price !== balanceItem.amount) {
|
|
160
|
+
console.log("Amount mismatch for payment " + payment.id+': '+payment.price+' !== '+balanceItem.amount)
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const settlement = Settlement.create({
|
|
165
|
+
id: payout.id,
|
|
166
|
+
reference: payout.statement_descriptor ?? '',
|
|
167
|
+
settledAt: new Date(payout.arrival_date * 1000),
|
|
168
|
+
amount: payout.amount,
|
|
169
|
+
// Set only if application fee is witheld
|
|
170
|
+
fee: applicationFee ?? 0
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
payment.settlement = settlement;
|
|
174
|
+
payment.transferFee = applicationFee ?? 0;
|
|
175
|
+
|
|
176
|
+
// Force an updatedAt timestamp of the related order
|
|
177
|
+
// Mark order as 'updated', or the frontend won't pull in the updates
|
|
178
|
+
const order = await Order.getForPayment(null, payment.id)
|
|
179
|
+
if (order) {
|
|
180
|
+
order.updatedAt = new Date();
|
|
181
|
+
order.forceSaveProperty('updatedAt');
|
|
182
|
+
await order.save();
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
await payment.save();
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Request, RequestMiddleware } from "@simonbackx/simple-endpoints"
|
|
2
|
+
|
|
3
|
+
import { ContextInstance } from "../helpers/Context"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* This attaches a context to each request for authentication and authorization
|
|
7
|
+
*/
|
|
8
|
+
export const ContextMiddleware: RequestMiddleware = {
|
|
9
|
+
wrapRun<T>(run: () => Promise<T>, request: Request) {
|
|
10
|
+
return ContextInstance.start(request, run)
|
|
11
|
+
},
|
|
12
|
+
|
|
13
|
+
handleRequest: function (request: Request) {
|
|
14
|
+
// Noop
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Migration } from '@simonbackx/simple-database';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
export default new Migration(async () => {
|
|
5
|
+
if (STAMHOOFD.environment == "test") {
|
|
6
|
+
console.log("skipped in tests")
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
return Promise.resolve()
|
|
11
|
+
|
|
12
|
+
/*let lastId = ""
|
|
13
|
+
|
|
14
|
+
while(true) {
|
|
15
|
+
const members = await Member.where({
|
|
16
|
+
id: {
|
|
17
|
+
sign: ">",
|
|
18
|
+
value: lastId
|
|
19
|
+
},
|
|
20
|
+
}, {
|
|
21
|
+
limit: 100,
|
|
22
|
+
sort: ["id"]
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
if (members.length == 0) {
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
lastId = members[members.length - 1].id
|
|
30
|
+
|
|
31
|
+
for (const member of members) {
|
|
32
|
+
if (member.details) {
|
|
33
|
+
const addresses = [member.details.address, ...member.details.parents.map(p => p.address)].filter(a => a !== null) as Address[]
|
|
34
|
+
|
|
35
|
+
for (const address of addresses) {
|
|
36
|
+
try {
|
|
37
|
+
const validatedAddress = await AddressValidator.validate(address)
|
|
38
|
+
const s = address.toString()
|
|
39
|
+
const e = validatedAddress.toString()
|
|
40
|
+
if (s != e) {
|
|
41
|
+
if (StringCompare.typoCount(address.street, validatedAddress.street) > 4) {
|
|
42
|
+
console.log("Updated street: " + s + " => " + e)
|
|
43
|
+
}
|
|
44
|
+
if (StringCompare.typoCount(address.city, validatedAddress.city) > 4) {
|
|
45
|
+
//console.log("Updated city: " + s + " => " + e)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
} catch (e) {
|
|
49
|
+
console.error("Invalid address: " + address.toString()+" — "+e.message)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
throw new Error("WIP")*/
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Migration } from '@simonbackx/simple-database';
|
|
2
|
+
|
|
3
|
+
export default new Migration(async () => {
|
|
4
|
+
if (STAMHOOFD.environment == "test") {
|
|
5
|
+
console.log("skipped in tests")
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// Do something here
|
|
10
|
+
return Promise.resolve()
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Migration } from '@simonbackx/simple-database';
|
|
2
|
+
import { User } from '@stamhoofd/models';
|
|
3
|
+
import { UserPermissions } from '@stamhoofd/structures';
|
|
4
|
+
|
|
5
|
+
export default new Migration(async () => {
|
|
6
|
+
if (STAMHOOFD.environment == "test") {
|
|
7
|
+
console.log("skipped in tests")
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
process.stdout.write('\n');
|
|
11
|
+
let c = 0;
|
|
12
|
+
while(true) {
|
|
13
|
+
const admins = await User.where({
|
|
14
|
+
organizationPermissions: {
|
|
15
|
+
value: null,
|
|
16
|
+
sign: '!='
|
|
17
|
+
},
|
|
18
|
+
organizationId: {
|
|
19
|
+
value: null,
|
|
20
|
+
sign: '!='
|
|
21
|
+
}
|
|
22
|
+
}, {limit: 100})
|
|
23
|
+
|
|
24
|
+
for (const admin of admins) {
|
|
25
|
+
if (!admin.organizationPermissions || !admin.organizationId) {
|
|
26
|
+
continue
|
|
27
|
+
}
|
|
28
|
+
const p = UserPermissions.create({})
|
|
29
|
+
p.organizationPermissions.set(admin.organizationId, admin.organizationPermissions)
|
|
30
|
+
admin.permissions = UserPermissions.limitedAdd(admin.permissions, p, admin.organizationId)
|
|
31
|
+
admin.organizationPermissions = null
|
|
32
|
+
await admin.save()
|
|
33
|
+
c++;
|
|
34
|
+
|
|
35
|
+
if (c%1000 === 0) {
|
|
36
|
+
process.stdout.write('.');
|
|
37
|
+
}
|
|
38
|
+
if (c%10000 === 0) {
|
|
39
|
+
process.stdout.write('\n');
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (admins.length === 0) {
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Do something here
|
|
49
|
+
return Promise.resolve()
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
|