@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,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"environment": "development",
|
|
3
|
+
"domains": {
|
|
4
|
+
"dashboard": "dashboard.stamhoofd",
|
|
5
|
+
"registration": {
|
|
6
|
+
"": "be.stamhoofd",
|
|
7
|
+
"BE": "be.stamhoofd",
|
|
8
|
+
"NL": "nl.stamhoofd"
|
|
9
|
+
},
|
|
10
|
+
"marketing": {
|
|
11
|
+
"": "www.be.stamhoofd",
|
|
12
|
+
"BE": "www.be.stamhoofd",
|
|
13
|
+
"NL": "www.nl.stamhoofd"
|
|
14
|
+
},
|
|
15
|
+
"webshop": {
|
|
16
|
+
"": "shop.be.stamhoofd",
|
|
17
|
+
"BE": "shop.be.stamhoofd",
|
|
18
|
+
"NL": "shop.nl.stamhoofd"
|
|
19
|
+
},
|
|
20
|
+
"legacyWebshop": "shop.stamhoofd",
|
|
21
|
+
"api": "api.stamhoofd",
|
|
22
|
+
"rendererApi": "renderer.stamhoofd"
|
|
23
|
+
},
|
|
24
|
+
"translationNamespace": "stamhoofd",
|
|
25
|
+
"userMode": "organization",
|
|
26
|
+
|
|
27
|
+
"PORT": 9091,
|
|
28
|
+
"DB_HOST": "127.0.0.1",
|
|
29
|
+
"DB_USER": "",
|
|
30
|
+
"DB_PASS": "",
|
|
31
|
+
"DB_DATABASE": "",
|
|
32
|
+
|
|
33
|
+
"SMTP_HOST": "0.0.0.0",
|
|
34
|
+
"SMTP_USERNAME": "username",
|
|
35
|
+
"SMTP_PASSWORD": "password",
|
|
36
|
+
"SMTP_PORT": 1025,
|
|
37
|
+
|
|
38
|
+
"TRANSACTIONAL_SMTP_HOST": "0.0.0.0",
|
|
39
|
+
"TRANSACTIONAL_SMTP_USERNAME": "username",
|
|
40
|
+
"TRANSACTIONAL_SMTP_PASSWORD": "password",
|
|
41
|
+
"TRANSACTIONAL_SMTP_PORT": 1025,
|
|
42
|
+
|
|
43
|
+
"AWS_ACCESS_KEY_ID": "",
|
|
44
|
+
"AWS_SECRET_ACCESS_KEY": "",
|
|
45
|
+
"AWS_REGION": "",
|
|
46
|
+
|
|
47
|
+
"SPACES_ENDPOINT": "",
|
|
48
|
+
"SPACES_BUCKET": "",
|
|
49
|
+
"SPACES_KEY": "",
|
|
50
|
+
"SPACES_SECRET": "",
|
|
51
|
+
|
|
52
|
+
"MOLLIE_CLIENT_ID": "",
|
|
53
|
+
"MOLLIE_SECRET": "",
|
|
54
|
+
"MOLLIE_API_KEY": "",
|
|
55
|
+
"MOLLIE_ORGANIZATION_TOKEN": "",
|
|
56
|
+
|
|
57
|
+
"LATEST_IOS_VERSION": 0,
|
|
58
|
+
"LATEST_ANDROID_VERSION": 0,
|
|
59
|
+
|
|
60
|
+
"NOLT_SSO_SECRET_KEY": "",
|
|
61
|
+
"INTERNAL_SECRET_KEY": "",
|
|
62
|
+
"CRONS_DISABLED": false
|
|
63
|
+
}
|
package/.eslintrc.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
root: true,
|
|
3
|
+
ignorePatterns: ["dist/", "node_modules/"],
|
|
4
|
+
parserOptions: {
|
|
5
|
+
"ecmaVersion": 2017
|
|
6
|
+
},
|
|
7
|
+
env: {
|
|
8
|
+
"es6": true,
|
|
9
|
+
"node": true,
|
|
10
|
+
},
|
|
11
|
+
extends: [
|
|
12
|
+
"eslint:recommended",
|
|
13
|
+
],
|
|
14
|
+
plugins: [],
|
|
15
|
+
rules: {
|
|
16
|
+
"no-console": "off",
|
|
17
|
+
"no-debugger": process.env.NODE_ENV === "production" ? "error" : "off",
|
|
18
|
+
"sort-imports": "off",
|
|
19
|
+
"import/order": "off"
|
|
20
|
+
},
|
|
21
|
+
overrides: [
|
|
22
|
+
{
|
|
23
|
+
// Rules for TypeScript and vue
|
|
24
|
+
files: ["*.ts"],
|
|
25
|
+
parser: "@typescript-eslint/parser",
|
|
26
|
+
parserOptions: {
|
|
27
|
+
project: ["./tsconfig.json"]
|
|
28
|
+
},
|
|
29
|
+
plugins: ["@typescript-eslint", "jest"],
|
|
30
|
+
extends: [
|
|
31
|
+
"eslint:recommended",
|
|
32
|
+
"plugin:@typescript-eslint/eslint-recommended",
|
|
33
|
+
"plugin:@typescript-eslint/recommended",
|
|
34
|
+
"plugin:@typescript-eslint/recommended-requiring-type-checking",
|
|
35
|
+
"plugin:jest/recommended",
|
|
36
|
+
],
|
|
37
|
+
rules: {
|
|
38
|
+
"no-console": "off",
|
|
39
|
+
"no-debugger": process.env.NODE_ENV === "production" ? "error" : "off",
|
|
40
|
+
"sort-imports": "off",
|
|
41
|
+
"import/order": "off",
|
|
42
|
+
"@typescript-eslint/explicit-function-return-type": "off",
|
|
43
|
+
"@typescript-eslint/no-explicit-any": "off",
|
|
44
|
+
"@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_" }],
|
|
45
|
+
"@typescript-eslint/no-namespace": "off",
|
|
46
|
+
"@typescript-eslint/no-floating-promises": "error",
|
|
47
|
+
"@typescript-eslint/no-misused-promises": "error",
|
|
48
|
+
"@typescript-eslint/prefer-for-of": "warn",
|
|
49
|
+
"@typescript-eslint/no-empty-interface": "off", // It is convenient to have placeholder interfaces
|
|
50
|
+
"@typescript-eslint/no-this-alias": "off", // No idea why we need this. This breaks code that is just fine. Prohibit the use of function() instead of this rule
|
|
51
|
+
"@typescript-eslint/unbound-method": "off", // Methods are automatically bound in vue, it would break removeEventListeners if we bound it every time unless we save every method in variables again...
|
|
52
|
+
"@typescript-eslint/no-unsafe-assignment": "off", // This is impossible to use with dependencies that don't have types yet, such as tiptap
|
|
53
|
+
"@typescript-eslint/no-unsafe-return": "off", // This is impossible to use with dependencies that don't have types yet, such as tiptap
|
|
54
|
+
"@typescript-eslint/no-unsafe-call": "off", // This is impossible to use with dependencies that don't have types yet, such as tiptap
|
|
55
|
+
"@typescript-eslint/no-unsafe-member-access": "off", // This is impossible to use with dependencies that don't have types yet, such as tiptap
|
|
56
|
+
"@typescript-eslint/restrict-plus-operands": "off", // bullshit one
|
|
57
|
+
"@typescript-eslint/explicit-module-boundary-types": "off",
|
|
58
|
+
},
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
};
|
package/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Stamhoofd backend application
|
|
2
|
+
|
|
3
|
+
To run, make sure you set your environment variables.
|
|
4
|
+
|
|
5
|
+
You can create a `.env` file:
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
# Database
|
|
9
|
+
DB_HOST=localhost
|
|
10
|
+
DB_USER=root
|
|
11
|
+
DB_PASS=root
|
|
12
|
+
DB_DATABASE=stamhoofd
|
|
13
|
+
|
|
14
|
+
# SMTP server (for sending emails)
|
|
15
|
+
SMTP_HOST=email-smtp.eu-west-1.amazonaws.com
|
|
16
|
+
SMTP_USERNAME=xxxx
|
|
17
|
+
SMTP_PASSWORD=xxxx
|
|
18
|
+
SMTP_PORT=xxxx
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Setup
|
|
22
|
+
|
|
23
|
+
Install dependencies and run the migrations to setup the database.
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
yarn install
|
|
27
|
+
yarn migrations
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Running
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
yarn start
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Testing
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
yarn test
|
|
40
|
+
```
|
package/index.ts
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
require('@stamhoofd/backend-env').load()
|
|
2
|
+
import { Column, Database, Migration } from "@simonbackx/simple-database";
|
|
3
|
+
import { CORSPreflightEndpoint, Router, RouterServer } from "@simonbackx/simple-endpoints";
|
|
4
|
+
import { I18n } from "@stamhoofd/backend-i18n";
|
|
5
|
+
import { CORSMiddleware, LogMiddleware, VersionMiddleware } from "@stamhoofd/backend-middleware";
|
|
6
|
+
import { Email } from "@stamhoofd/email";
|
|
7
|
+
import { loadLogger } from "@stamhoofd/logging";
|
|
8
|
+
import { Version } from '@stamhoofd/structures';
|
|
9
|
+
import { sleep } from "@stamhoofd/utility";
|
|
10
|
+
|
|
11
|
+
import { areCronsRunning, crons, stopCronScheduling } from './src/crons';
|
|
12
|
+
import { ContextMiddleware } from "./src/middleware/ContextMiddleware";
|
|
13
|
+
|
|
14
|
+
process.on("unhandledRejection", (error: Error) => {
|
|
15
|
+
console.error("unhandledRejection");
|
|
16
|
+
console.error(error.message, error.stack);
|
|
17
|
+
process.exit(1);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// Set version of saved structures
|
|
21
|
+
Column.setJSONVersion(Version);
|
|
22
|
+
|
|
23
|
+
// Set timezone!
|
|
24
|
+
process.env.TZ = "UTC";
|
|
25
|
+
|
|
26
|
+
// Quick check
|
|
27
|
+
if (new Date().getTimezoneOffset() != 0) {
|
|
28
|
+
throw new Error("Process should always run in UTC timezone");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const seeds = async () => {
|
|
32
|
+
try {
|
|
33
|
+
// Internal
|
|
34
|
+
await Migration.runAll(__dirname + "/src/seeds");
|
|
35
|
+
} catch (e) {
|
|
36
|
+
console.error("Failed to run seeds:")
|
|
37
|
+
console.error(e)
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const start = async () => {
|
|
42
|
+
console.log('Running server at v' + Version)
|
|
43
|
+
loadLogger();
|
|
44
|
+
await I18n.load()
|
|
45
|
+
const router = new Router();
|
|
46
|
+
await router.loadAllEndpoints(__dirname + "/src/endpoints/global/*");
|
|
47
|
+
await router.loadAllEndpoints(__dirname + "/src/endpoints/admin/*");
|
|
48
|
+
await router.loadAllEndpoints(__dirname + "/src/endpoints/auth");
|
|
49
|
+
await router.loadAllEndpoints(__dirname + "/src/endpoints/organization/dashboard/*");
|
|
50
|
+
await router.loadAllEndpoints(__dirname + "/src/endpoints/organization/registration");
|
|
51
|
+
await router.loadAllEndpoints(__dirname + "/src/endpoints/organization/webshops");
|
|
52
|
+
await router.loadAllEndpoints(__dirname + "/src/endpoints/organization/shared");
|
|
53
|
+
await router.loadAllEndpoints(__dirname + "/src/endpoints/organization/shared/*");
|
|
54
|
+
|
|
55
|
+
router.endpoints.push(new CORSPreflightEndpoint())
|
|
56
|
+
|
|
57
|
+
const routerServer = new RouterServer(router);
|
|
58
|
+
routerServer.verbose = false
|
|
59
|
+
|
|
60
|
+
// Log requests and errors
|
|
61
|
+
routerServer.addRequestMiddleware(LogMiddleware)
|
|
62
|
+
routerServer.addResponseMiddleware(LogMiddleware)
|
|
63
|
+
|
|
64
|
+
// Contexts
|
|
65
|
+
routerServer.addRequestMiddleware(ContextMiddleware)
|
|
66
|
+
|
|
67
|
+
// Add version headers and minimum version
|
|
68
|
+
const versionMiddleware = new VersionMiddleware({
|
|
69
|
+
latestVersions: {
|
|
70
|
+
android: STAMHOOFD.LATEST_ANDROID_VERSION,
|
|
71
|
+
ios: STAMHOOFD.LATEST_IOS_VERSION,
|
|
72
|
+
web: Version
|
|
73
|
+
},
|
|
74
|
+
minimumVersion: 168
|
|
75
|
+
})
|
|
76
|
+
routerServer.addRequestMiddleware(versionMiddleware)
|
|
77
|
+
routerServer.addResponseMiddleware(versionMiddleware)
|
|
78
|
+
|
|
79
|
+
// Add CORS headers
|
|
80
|
+
routerServer.addResponseMiddleware(CORSMiddleware)
|
|
81
|
+
|
|
82
|
+
routerServer.listen(STAMHOOFD.PORT ?? 9090);
|
|
83
|
+
|
|
84
|
+
if (routerServer.server) {
|
|
85
|
+
// Default timeout is a bit too short
|
|
86
|
+
routerServer.server.timeout = 61000;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
let shuttingDown = false;
|
|
90
|
+
const shutdown = async () => {
|
|
91
|
+
if (shuttingDown) {
|
|
92
|
+
return
|
|
93
|
+
}
|
|
94
|
+
shuttingDown = true
|
|
95
|
+
console.log("Shutting down...")
|
|
96
|
+
// Disable keep alive
|
|
97
|
+
routerServer.defaultHeaders = Object.assign(routerServer.defaultHeaders, { 'Connection': 'close' })
|
|
98
|
+
if (routerServer.server) {
|
|
99
|
+
routerServer.server.headersTimeout = 5000;
|
|
100
|
+
routerServer.server.keepAliveTimeout = 1;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
stopCronScheduling();
|
|
104
|
+
clearInterval(cronInterval)
|
|
105
|
+
|
|
106
|
+
try {
|
|
107
|
+
await routerServer.close()
|
|
108
|
+
console.log("HTTP server stopped");
|
|
109
|
+
} catch (err) {
|
|
110
|
+
console.error("Failed to stop HTTP server:");
|
|
111
|
+
console.error(err);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
try {
|
|
115
|
+
while (areCronsRunning()) {
|
|
116
|
+
console.log("Crons are still running. Waiting 2 seconds...")
|
|
117
|
+
await sleep(2000)
|
|
118
|
+
}
|
|
119
|
+
} catch (err) {
|
|
120
|
+
console.error("Failed to wait for crons to finish:");
|
|
121
|
+
console.error(err);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
try {
|
|
125
|
+
while (Email.currentQueue.length > 0) {
|
|
126
|
+
console.log("Emails still in queue. Waiting 2 seconds...")
|
|
127
|
+
await sleep(2000)
|
|
128
|
+
}
|
|
129
|
+
} catch (err) {
|
|
130
|
+
console.error("Failed to wait for emails to finish:");
|
|
131
|
+
console.error(err);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
try {
|
|
135
|
+
await Database.end()
|
|
136
|
+
console.log("MySQL connections closed");
|
|
137
|
+
} catch (err) {
|
|
138
|
+
console.error("Failed to close MySQL connection:")
|
|
139
|
+
console.error(err);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Should not be needed, but added for security as sometimes a promise hangs somewhere
|
|
143
|
+
process.exit(0);
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
process.on("SIGTERM", () => {
|
|
147
|
+
console.info("SIGTERM signal received.");
|
|
148
|
+
shutdown().catch((e) => {
|
|
149
|
+
console.error(e)
|
|
150
|
+
process.exit(1);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
process.on("SIGINT", () => {
|
|
155
|
+
console.info("SIGINT signal received.");
|
|
156
|
+
shutdown().catch((e) => {
|
|
157
|
+
console.error(e)
|
|
158
|
+
process.exit(1);
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
const cronInterval = setInterval(() => {
|
|
163
|
+
crons().catch(console.error)
|
|
164
|
+
}, 5 * 60 * 1000);
|
|
165
|
+
crons().catch(console.error)
|
|
166
|
+
seeds().catch(console.error);
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
start().catch(error => {
|
|
170
|
+
console.error("unhandledRejection", error);
|
|
171
|
+
process.exit(1);
|
|
172
|
+
});
|
package/jest.config.js
ADDED
package/migrations.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require('@stamhoofd/backend-env').load()
|
|
2
|
+
import { Column, Migration } from "@simonbackx/simple-database";
|
|
3
|
+
import { Version } from "@stamhoofd/structures";
|
|
4
|
+
import path from "path";
|
|
5
|
+
|
|
6
|
+
Column.setJSONVersion(Version);
|
|
7
|
+
process.env.TZ = "UTC";
|
|
8
|
+
|
|
9
|
+
const emailPath = require.resolve("@stamhoofd/email")
|
|
10
|
+
const modelsPath = require.resolve("@stamhoofd/models")
|
|
11
|
+
|
|
12
|
+
// Validate UTC timezone
|
|
13
|
+
if (new Date().getTimezoneOffset() != 0) {
|
|
14
|
+
throw new Error("Process should always run in UTC timezone");
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const start = async () => {
|
|
18
|
+
// External migrations
|
|
19
|
+
await Migration.runAll(path.dirname(modelsPath) + "/migrations");
|
|
20
|
+
await Migration.runAll(path.dirname(emailPath) + "/migrations");
|
|
21
|
+
|
|
22
|
+
// Internal
|
|
23
|
+
await Migration.runAll(__dirname + "/src/migrations");
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
start()
|
|
27
|
+
.catch(error => {
|
|
28
|
+
console.error("unhandledRejection", error);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
})
|
|
31
|
+
.finally(() => {
|
|
32
|
+
process.exit();
|
|
33
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@stamhoofd/backend",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"main": "index.ts",
|
|
5
|
+
"license": "UNLICENCED",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "concurrently -r \"rm -rf ./dist && wait-on ./dist/index.js && nodemon --quiet --inspect=5858 --watch dist --delay 200ms --exec node --enable-source-maps ./dist/index.js --signal SIGTERM\" 'yarn build --watch --preserveWatchOutput'",
|
|
8
|
+
"dev:backend": "yarn dev",
|
|
9
|
+
"build": "rm -rf ./dist/src/migrations && rm -rf ./dist/src/seeds && tsc -b",
|
|
10
|
+
"build:full": "yarn clear && yarn build",
|
|
11
|
+
"clear": "rm -rf ./dist",
|
|
12
|
+
"start": "yarn build && node --enable-source-maps ./dist/index.js",
|
|
13
|
+
"test": "jest --runInBand",
|
|
14
|
+
"test:reset": "yarn build:full && jest --runInBand",
|
|
15
|
+
"migrations": "yarn build:full && node ./dist/migrations.js",
|
|
16
|
+
"lint": "eslint . --ext .js,.jsx,.ts,.tsx"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@types/cookie": "^0.5.1",
|
|
20
|
+
"@types/luxon": "^2.0.8",
|
|
21
|
+
"@types/mailparser": "3.4.4",
|
|
22
|
+
"@types/mysql": "^2.15.20",
|
|
23
|
+
"@types/node": "^18.11.17",
|
|
24
|
+
"nock": "^13.5.1",
|
|
25
|
+
"qs": "^6.11.2",
|
|
26
|
+
"sinon": "^17.0.1"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@mollie/api-client": "3.7.0",
|
|
30
|
+
"@simonbackx/simple-database": "1.24.0",
|
|
31
|
+
"@simonbackx/simple-endpoints": "1.13.0",
|
|
32
|
+
"@simonbackx/simple-logging": "^1.0.1",
|
|
33
|
+
"aws-sdk": "^2.885.0",
|
|
34
|
+
"axios": "1.6.8",
|
|
35
|
+
"cookie": "^0.5.0",
|
|
36
|
+
"formidable": "3.5.1",
|
|
37
|
+
"handlebars": "^4.7.7",
|
|
38
|
+
"jsonwebtoken": "9.0.0",
|
|
39
|
+
"luxon": "^2.2.0",
|
|
40
|
+
"mailparser": "3.7.0",
|
|
41
|
+
"mockdate": "^3.0.2",
|
|
42
|
+
"mysql": "^2.18.1",
|
|
43
|
+
"node-rsa": "1.1.1",
|
|
44
|
+
"openid-client": "^5.4.0",
|
|
45
|
+
"postmark": "4.0.2",
|
|
46
|
+
"stripe": "^11.5.0"
|
|
47
|
+
}
|
|
48
|
+
}
|