@stamhoofd/models 2.23.0 → 2.25.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.
Files changed (38) hide show
  1. package/dist/src/helpers/EmailBuilder.d.ts.map +1 -1
  2. package/dist/src/helpers/EmailBuilder.js +18 -7
  3. package/dist/src/helpers/EmailBuilder.js.map +1 -1
  4. package/dist/src/migrations/1724929140-default-templates-verify-email.sql +5 -0
  5. package/dist/src/migrations/1724939437-default-templates-invite-admin.sql +5 -0
  6. package/dist/src/models/Email.d.ts.map +1 -1
  7. package/dist/src/models/Email.js +9 -3
  8. package/dist/src/models/Email.js.map +1 -1
  9. package/dist/src/models/EmailRecipient.d.ts.map +1 -1
  10. package/dist/src/models/EmailRecipient.js.map +1 -1
  11. package/dist/src/models/EmailVerificationCode.d.ts +1 -1
  12. package/dist/src/models/EmailVerificationCode.d.ts.map +1 -1
  13. package/dist/src/models/EmailVerificationCode.js +44 -25
  14. package/dist/src/models/EmailVerificationCode.js.map +1 -1
  15. package/dist/src/models/Member.d.ts.map +1 -1
  16. package/dist/src/models/Member.js +2 -1
  17. package/dist/src/models/Member.js.map +1 -1
  18. package/dist/src/models/MemberResponsibilityRecord.d.ts +3 -2
  19. package/dist/src/models/MemberResponsibilityRecord.d.ts.map +1 -1
  20. package/dist/src/models/MemberResponsibilityRecord.js +10 -2
  21. package/dist/src/models/MemberResponsibilityRecord.js.map +1 -1
  22. package/dist/src/models/Organization.d.ts +7 -9
  23. package/dist/src/models/Organization.d.ts.map +1 -1
  24. package/dist/src/models/Organization.js +22 -37
  25. package/dist/src/models/Organization.js.map +1 -1
  26. package/dist/src/models/OrganizationRegistrationPeriod.d.ts.map +1 -1
  27. package/dist/src/models/OrganizationRegistrationPeriod.js.map +1 -1
  28. package/package.json +2 -2
  29. package/src/helpers/EmailBuilder.ts +22 -8
  30. package/src/migrations/1724929140-default-templates-verify-email.sql +5 -0
  31. package/src/migrations/1724939437-default-templates-invite-admin.sql +5 -0
  32. package/src/models/Email.ts +9 -3
  33. package/src/models/EmailRecipient.ts +1 -0
  34. package/src/models/EmailVerificationCode.ts +46 -27
  35. package/src/models/Member.ts +2 -1
  36. package/src/models/MemberResponsibilityRecord.ts +12 -3
  37. package/src/models/Organization.ts +23 -43
  38. package/src/models/OrganizationRegistrationPeriod.ts +1 -0
@@ -0,0 +1,5 @@
1
+ INSERT INTO `email_templates` (`id`, `subject`, `groupId`, `webshopId`, `organizationId`, `type`, `text`, `html`, `json`, `updatedAt`, `createdAt`) VALUES
2
+ ('1b26c047-94b8-4b7c-9124-292d38da5c06', '[{{organizationName}}] Verifieer jouw e-mailadres', NULL, NULL, NULL, 'VerifyEmailWithoutCode', '{{greeting}}Verifieer jouw e-mailadres om te kunnen inloggen bij {{organizationName}}. Klik op de onderstaande link om jouw e-mailadres te bevestigen.\n\n \n \n \n \n Bevestig e-mailadres\n \n \n \n \n\nDit is een automatische e-mail. Gelieve niet op dit e-mailadres te reageren.{{organizationName}}', '<!DOCTYPE html>\n<html>\n\n<head>\n<meta charset=\"utf-8\" />\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\" />\n<title>[{{organizationName}}] Verifieer jouw e-mailadres</title>\n<style type=\"text/css\">body {\n color: #000716;\n color: var(--color-dark, #000716);\n font-family: -apple-system-body, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n font-size: 12pt;\n line-height: 1.4;\n}\n\np {\n margin: 0;\n padding: 0;\n line-height: 1.4;\n}\n\np.description {\n color: var(--color-gray-4, #5e5e5e);\n}\np.description a, p.description a:link, p.description a:visited, p.description a:active, p.description a:hover {\n text-decoration: underline;\n color: var(--color-gray-4, #5e5e5e);\n}\n\nstrong {\n font-weight: bold;\n}\n\nem {\n font-style: italic;\n}\n\nh1 {\n font-size: 30px;\n font-weight: bold;\n line-height: 1.2;\n margin: 0;\n padding: 0;\n}\n@media (max-width: 350px) {\n h1 {\n font-size: 24px;\n }\n}\n\nh2 {\n font-size: 20px;\n line-height: 1.2;\n font-weight: bold;\n margin: 0;\n padding: 0;\n}\n\nh3 {\n font-size: 16px;\n line-height: 1.2;\n font-weight: bold;\n margin: 0;\n padding: 0;\n}\n\nh4 {\n line-height: 1.2;\n font-weight: 500;\n margin: 0;\n padding: 0;\n}\n\nol, ul {\n list-style-position: outside;\n padding-left: 30px;\n}\n\nhr {\n height: 1px;\n background: var(--color-border, var(--color-gray-2, #dcdcdc));\n border-radius: 1px;\n padding: 0;\n margin: 20px 0;\n outline: none;\n border: 0;\n}\n\n.button {\n touch-action: inherit;\n user-select: auto;\n cursor: pointer;\n display: inline-block !important;\n line-height: 42px;\n font-size: 16px;\n font-weight: bold;\n}\n.button:active {\n transform: none;\n}\n\nimg {\n max-width: 100%;\n height: auto;\n}\n\na, a:link, a:visited, a:active, a:hover {\n text-decoration: underline;\n color: blue;\n}\n\n.email-data-table {\n width: 100%;\n border-collapse: collapse;\n}\n.email-data-table th, .email-data-table td {\n text-align: left;\n padding: 10px 10px 10px 0;\n border-bottom: 1px solid var(--color-border, var(--color-gray-2, #dcdcdc));\n vertical-align: middle;\n}\n.email-data-table th:last-child, .email-data-table td:last-child {\n text-align: right;\n padding-right: 0;\n}\n.email-data-table thead {\n font-weight: bold;\n}\n.email-data-table thead th {\n font-size: 10pt;\n}\n.email-data-table h4 ~ p {\n padding-top: 3px;\n opacity: 0.8;\n font-size: 11pt;\n} hr {height: 2px;background: #e7e7e7; border-radius: 1px; padding: 0; margin: 20px 0; outline: none; border: 0;} .button.primary { margin: 0; text-decoration: none; font-size: 16px; font-weight: bold; color: {{primaryColorContrast}}; padding: 0 27px; line-height: 42px; background: {{primaryColor}}; text-align: center; border-radius: 7px; touch-action: manipulation; display: inline-block; transition: 0.2s transform, 0.2s opacity; } .button.primary:active { transform: scale(0.95, 0.95); } .inline-link, .inline-link:link, .inline-link:visited, .inline-link:active, .inline-link:hover { margin: 0; text-decoration: underline; font-size: inherit; font-weight: inherit; color: inherit; touch-action: manipulation; } .inline-link:active { opacity: 0.5; } .description { color: #5e5e5e; } </style>\n</head>\n\n<body>\n<p style=\"margin: 0; padding: 0; line-height: 1.4;\">{{greeting}}</p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\">Verifieer jouw e-mailadres om te kunnen inloggen bij {{organizationName}}. Klik op de onderstaande link om jouw e-mailadres te bevestigen.</p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><div data-type=\"smartButton\" data-id=\"confirmEmailUrl\"><table width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" style=\"margin: 5px 0;\">\n<tbody><tr>\n <td>\n <table cellspacing=\"0\" cellpadding=\"0\">\n <tbody><tr>\n <td style=\"border-radius: 7px;\" bgcolor=\"{{primaryColor}}\">\n <a class=\"button primary\" href=\"{{confirmEmailUrl}}\" target=\"\" style=\"margin: 0; text-decoration: none; font-size: 16px; font-weight: bold; color: {{primaryColorContrast}}; padding: 0 27px; line-height: 42px; background: {{primaryColor}}; text-align: center; border-radius: 7px; touch-action: manipulation; display: inline-block; transition: 0.2s transform, 0.2s opacity;\">Bevestig e-mailadres</a>\n </td>\n </tr>\n </tbody></table>\n </td>\n</tr>\n</tbody></table></div><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\">Dit is een automatische e-mail. Gelieve niet op dit e-mailadres te reageren.</p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\">{{organizationName}}</p>\n</body>\n\n</html>', '{\"value\": {\"type\": \"doc\", \"content\": [{\"type\": \"paragraph\", \"content\": [{\"type\": \"smartVariable\", \"attrs\": {\"id\": \"greeting\"}}]}, {\"type\": \"paragraph\"}, {\"type\": \"paragraph\", \"content\": [{\"text\": \"Verifieer jouw e-mailadres om te kunnen inloggen bij \", \"type\": \"text\"}, {\"type\": \"smartVariable\", \"attrs\": {\"id\": \"organizationName\"}}, {\"text\": \". Klik op de onderstaande link om jouw e-mailadres te bevestigen.\", \"type\": \"text\"}]}, {\"type\": \"paragraph\"}, {\"type\": \"smartButton\", \"attrs\": {\"id\": \"confirmEmailUrl\"}, \"content\": [{\"text\": \"Bevestig e-mailadres\", \"type\": \"text\"}]}, {\"type\": \"paragraph\"}, {\"type\": \"paragraph\", \"content\": [{\"text\": \"Dit is een automatische e-mail. Gelieve niet op dit e-mailadres te reageren.\", \"type\": \"text\"}]}, {\"type\": \"paragraph\"}, {\"type\": \"paragraph\", \"content\": [{\"type\": \"smartVariable\", \"attrs\": {\"id\": \"organizationName\"}}]}]}, \"version\": 328}', '2024-08-29 13:29:26', '2024-08-29 13:29:26');
3
+
4
+ INSERT INTO `email_templates` (`id`, `subject`, `groupId`, `webshopId`, `organizationId`, `type`, `text`, `html`, `json`, `updatedAt`, `createdAt`) VALUES
5
+ ('6594a28e-a204-401c-9bca-6d88141b07dd', '[{{organizationName}}] Verifieer jouw e-mailadres', NULL, NULL, NULL, 'VerifyEmail', '{{greeting}}Verifieer jouw e-mailadres om te kunnen inloggen bij {{organizationName}}.Vul de onderstaande code in op de website:{{confirmEmailCode}}Of klik op onderstaande link:\n\n \n \n \n \n bevestig e-mailadres\n \n \n \n \n\nDit is een automatische e-mail. Gelieve niet op dit e-mailadres te reageren.{{organizationName}}', '<!DOCTYPE html>\n<html>\n\n<head>\n<meta charset=\"utf-8\" />\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\" />\n<title>[{{organizationName}}] Verifieer jouw e-mailadres</title>\n<style type=\"text/css\">body {\n color: #000716;\n color: var(--color-dark, #000716);\n font-family: -apple-system-body, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n font-size: 12pt;\n line-height: 1.4;\n}\n\np {\n margin: 0;\n padding: 0;\n line-height: 1.4;\n}\n\np.description {\n color: var(--color-gray-4, #5e5e5e);\n}\np.description a, p.description a:link, p.description a:visited, p.description a:active, p.description a:hover {\n text-decoration: underline;\n color: var(--color-gray-4, #5e5e5e);\n}\n\nstrong {\n font-weight: bold;\n}\n\nem {\n font-style: italic;\n}\n\nh1 {\n font-size: 30px;\n font-weight: bold;\n line-height: 1.2;\n margin: 0;\n padding: 0;\n}\n@media (max-width: 350px) {\n h1 {\n font-size: 24px;\n }\n}\n\nh2 {\n font-size: 20px;\n line-height: 1.2;\n font-weight: bold;\n margin: 0;\n padding: 0;\n}\n\nh3 {\n font-size: 16px;\n line-height: 1.2;\n font-weight: bold;\n margin: 0;\n padding: 0;\n}\n\nh4 {\n line-height: 1.2;\n font-weight: 500;\n margin: 0;\n padding: 0;\n}\n\nol, ul {\n list-style-position: outside;\n padding-left: 30px;\n}\n\nhr {\n height: 1px;\n background: var(--color-border, var(--color-gray-2, #dcdcdc));\n border-radius: 1px;\n padding: 0;\n margin: 20px 0;\n outline: none;\n border: 0;\n}\n\n.button {\n touch-action: inherit;\n user-select: auto;\n cursor: pointer;\n display: inline-block !important;\n line-height: 42px;\n font-size: 16px;\n font-weight: bold;\n}\n.button:active {\n transform: none;\n}\n\nimg {\n max-width: 100%;\n height: auto;\n}\n\na, a:link, a:visited, a:active, a:hover {\n text-decoration: underline;\n color: blue;\n}\n\n.email-data-table {\n width: 100%;\n border-collapse: collapse;\n}\n.email-data-table th, .email-data-table td {\n text-align: left;\n padding: 10px 10px 10px 0;\n border-bottom: 1px solid var(--color-border, var(--color-gray-2, #dcdcdc));\n vertical-align: middle;\n}\n.email-data-table th:last-child, .email-data-table td:last-child {\n text-align: right;\n padding-right: 0;\n}\n.email-data-table thead {\n font-weight: bold;\n}\n.email-data-table thead th {\n font-size: 10pt;\n}\n.email-data-table h4 ~ p {\n padding-top: 3px;\n opacity: 0.8;\n font-size: 11pt;\n} hr {height: 2px;background: #e7e7e7; border-radius: 1px; padding: 0; margin: 20px 0; outline: none; border: 0;} .button.primary { margin: 0; text-decoration: none; font-size: 16px; font-weight: bold; color: {{primaryColorContrast}}; padding: 0 27px; line-height: 42px; background: {{primaryColor}}; text-align: center; border-radius: 7px; touch-action: manipulation; display: inline-block; transition: 0.2s transform, 0.2s opacity; } .button.primary:active { transform: scale(0.95, 0.95); } .inline-link, .inline-link:link, .inline-link:visited, .inline-link:active, .inline-link:hover { margin: 0; text-decoration: underline; font-size: inherit; font-weight: inherit; color: inherit; touch-action: manipulation; } .inline-link:active { opacity: 0.5; } .description { color: #5e5e5e; } </style>\n</head>\n\n<body>\n<p style=\"margin: 0; padding: 0; line-height: 1.4;\">{{greeting}}</p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\">Verifieer jouw e-mailadres om te kunnen inloggen bij {{organizationName}}.</p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\">Vul de onderstaande code in op de website:</p><h1 style=\"margin: 0; padding: 0;\">{{confirmEmailCode}}</h1><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\">Of klik op onderstaande link:</p><div data-type=\"smartButton\" data-id=\"confirmEmailUrl\"><table width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" style=\"margin: 5px 0;\">\n<tbody><tr>\n <td>\n <table cellspacing=\"0\" cellpadding=\"0\">\n <tbody><tr>\n <td style=\"border-radius: 7px;\" bgcolor=\"{{primaryColor}}\">\n <a class=\"button primary\" href=\"{{confirmEmailUrl}}\" target=\"\" style=\"margin: 0; text-decoration: none; font-size: 16px; font-weight: bold; color: {{primaryColorContrast}}; padding: 0 27px; line-height: 42px; background: {{primaryColor}}; text-align: center; border-radius: 7px; touch-action: manipulation; display: inline-block; transition: 0.2s transform, 0.2s opacity;\">bevestig e-mailadres</a>\n </td>\n </tr>\n </tbody></table>\n </td>\n</tr>\n</tbody></table></div><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\">Dit is een automatische e-mail. Gelieve niet op dit e-mailadres te reageren.</p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\">{{organizationName}}</p>\n</body>\n\n</html>', '{\"value\": {\"type\": \"doc\", \"content\": [{\"type\": \"paragraph\", \"content\": [{\"type\": \"smartVariable\", \"attrs\": {\"id\": \"greeting\"}}]}, {\"type\": \"paragraph\"}, {\"type\": \"paragraph\", \"content\": [{\"text\": \"Verifieer jouw e-mailadres om te kunnen inloggen bij \", \"type\": \"text\"}, {\"type\": \"smartVariable\", \"attrs\": {\"id\": \"organizationName\"}}, {\"text\": \".\", \"type\": \"text\"}]}, {\"type\": \"paragraph\"}, {\"type\": \"paragraph\", \"content\": [{\"text\": \"Vul de onderstaande code in op de website:\", \"type\": \"text\"}]}, {\"type\": \"heading\", \"attrs\": {\"level\": 1}, \"content\": [{\"type\": \"smartVariable\", \"attrs\": {\"id\": \"confirmEmailCode\"}}]}, {\"type\": \"paragraph\"}, {\"type\": \"paragraph\", \"content\": [{\"text\": \"Of klik op onderstaande link:\", \"type\": \"text\"}]}, {\"type\": \"smartButton\", \"attrs\": {\"id\": \"confirmEmailUrl\"}, \"content\": [{\"text\": \"bevestig e-mailadres\", \"type\": \"text\"}]}, {\"type\": \"paragraph\"}, {\"type\": \"paragraph\", \"content\": [{\"text\": \"Dit is een automatische e-mail. Gelieve niet op dit e-mailadres te reageren.\", \"type\": \"text\"}]}, {\"type\": \"paragraph\"}, {\"type\": \"paragraph\", \"content\": [{\"type\": \"smartVariable\", \"attrs\": {\"id\": \"organizationName\"}}]}]}, \"version\": 328}', '2024-08-29 13:28:44', '2024-08-29 13:28:44');
@@ -0,0 +1,5 @@
1
+ INSERT INTO `email_templates` (`id`, `subject`, `groupId`, `webshopId`, `organizationId`, `type`, `text`, `html`, `json`, `updatedAt`, `createdAt`) VALUES
2
+ ('548ae096-d5db-4115-af44-4155ba50b30d', '✉️ Beheerder van {{platformOrOrganizationName}}', NULL, NULL, NULL, 'AdminInvitation', '{{greeting}}{{inviterName}} heeft je toegevoegd als beheerder van {{platformOrOrganizationName}}. Je kan inloggen met je bestaande account {{email}}. Daar kan je jouw vereniging zoeken en aanklikken.\n\n \n \n \n \n Log in\n \n \n \n \n\nWeet je jouw wachtwoord niet meer? Dan kan je een nieuw wachtwoord instellen via de onderstaande link:{{resetUrl}}Deze link is geldig tot {{validUntil}}.Ken je deze vereniging niet? Dan kan je deze e-mail veilig negeren.', '<!DOCTYPE html>\n<html>\n\n<head>\n<meta charset=\"utf-8\" />\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\" />\n<title>✉️ Beheerder van {{platformOrOrganizationName}}</title>\n<style type=\"text/css\">body {\n color: #000716;\n color: var(--color-dark, #000716);\n font-family: -apple-system-body, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n font-size: 12pt;\n line-height: 1.4;\n}\n\np {\n margin: 0;\n padding: 0;\n line-height: 1.4;\n}\n\np.description {\n color: var(--color-gray-4, #5e5e5e);\n}\np.description a, p.description a:link, p.description a:visited, p.description a:active, p.description a:hover {\n text-decoration: underline;\n color: var(--color-gray-4, #5e5e5e);\n}\n\nstrong {\n font-weight: bold;\n}\n\nem {\n font-style: italic;\n}\n\nh1 {\n font-size: 30px;\n font-weight: bold;\n line-height: 1.2;\n margin: 0;\n padding: 0;\n}\n@media (max-width: 350px) {\n h1 {\n font-size: 24px;\n }\n}\n\nh2 {\n font-size: 20px;\n line-height: 1.2;\n font-weight: bold;\n margin: 0;\n padding: 0;\n}\n\nh3 {\n font-size: 16px;\n line-height: 1.2;\n font-weight: bold;\n margin: 0;\n padding: 0;\n}\n\nh4 {\n line-height: 1.2;\n font-weight: 500;\n margin: 0;\n padding: 0;\n}\n\nol, ul {\n list-style-position: outside;\n padding-left: 30px;\n}\n\nhr {\n height: 1px;\n background: var(--color-border, var(--color-gray-2, #dcdcdc));\n border-radius: 1px;\n padding: 0;\n margin: 20px 0;\n outline: none;\n border: 0;\n}\n\n.button {\n touch-action: inherit;\n user-select: auto;\n cursor: pointer;\n display: inline-block !important;\n line-height: 42px;\n font-size: 16px;\n font-weight: bold;\n}\n.button:active {\n transform: none;\n}\n\nimg {\n max-width: 100%;\n height: auto;\n}\n\na, a:link, a:visited, a:active, a:hover {\n text-decoration: underline;\n color: blue;\n}\n\n.email-data-table {\n width: 100%;\n border-collapse: collapse;\n}\n.email-data-table th, .email-data-table td {\n text-align: left;\n padding: 10px 10px 10px 0;\n border-bottom: 1px solid var(--color-border, var(--color-gray-2, #dcdcdc));\n vertical-align: middle;\n}\n.email-data-table th:last-child, .email-data-table td:last-child {\n text-align: right;\n padding-right: 0;\n}\n.email-data-table thead {\n font-weight: bold;\n}\n.email-data-table thead th {\n font-size: 10pt;\n}\n.email-data-table h4 ~ p {\n padding-top: 3px;\n opacity: 0.8;\n font-size: 11pt;\n} hr {height: 2px;background: #e7e7e7; border-radius: 1px; padding: 0; margin: 20px 0; outline: none; border: 0;} .button.primary { margin: 0; text-decoration: none; font-size: 16px; font-weight: bold; color: {{primaryColorContrast}}; padding: 0 27px; line-height: 42px; background: {{primaryColor}}; text-align: center; border-radius: 7px; touch-action: manipulation; display: inline-block; transition: 0.2s transform, 0.2s opacity; } .button.primary:active { transform: scale(0.95, 0.95); } .inline-link, .inline-link:link, .inline-link:visited, .inline-link:active, .inline-link:hover { margin: 0; text-decoration: underline; font-size: inherit; font-weight: inherit; color: inherit; touch-action: manipulation; } .inline-link:active { opacity: 0.5; } .description { color: #5e5e5e; } </style>\n</head>\n\n<body>\n<p style=\"margin: 0; padding: 0; line-height: 1.4;\">{{greeting}}</p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\">{{inviterName}} <code>heeft je toegevoegd als beheerder van </code>{{platformOrOrganizationName}}<code>. Je kan inloggen met je bestaande account </code>{{email}}<code>. Daar kan je jouw vereniging zoeken en aanklikken.</code></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><div data-type=\"smartButton\" data-id=\"signInUrl\"><table width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" style=\"margin: 5px 0;\">\n<tbody><tr>\n <td>\n <table cellspacing=\"0\" cellpadding=\"0\">\n <tbody><tr>\n <td style=\"border-radius: 7px;\" bgcolor=\"{{primaryColor}}\">\n <a class=\"button primary\" href=\"{{signInUrl}}\" target=\"\" style=\"margin: 0; text-decoration: none; font-size: 16px; font-weight: bold; color: {{primaryColorContrast}}; padding: 0 27px; line-height: 42px; background: {{primaryColor}}; text-align: center; border-radius: 7px; touch-action: manipulation; display: inline-block; transition: 0.2s transform, 0.2s opacity;\">Log in</a>\n </td>\n </tr>\n </tbody></table>\n </td>\n</tr>\n</tbody></table></div><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p class=\"description\" style=\"color: #5e5e5e;\"><code>Weet je jouw wachtwoord niet meer? Dan kan je een nieuw wachtwoord instellen via de onderstaande link:</code></p><p class=\"description\" style=\"color: #5e5e5e;\">{{resetUrl}}</p><p class=\"description\" style=\"color: #5e5e5e;\"><br></p><p class=\"description\" style=\"color: #5e5e5e;\">Deze link is geldig tot {{validUntil}}.</p><p class=\"description\" style=\"color: #5e5e5e;\"><br></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\">Ken je deze vereniging niet? Dan kan je deze e-mail veilig negeren.</p>\n</body>\n\n</html>', '{\"value\": {\"type\": \"doc\", \"content\": [{\"type\": \"paragraph\", \"content\": [{\"type\": \"smartVariable\", \"attrs\": {\"id\": \"greeting\"}}]}, {\"type\": \"paragraph\"}, {\"type\": \"paragraph\", \"content\": [{\"type\": \"smartVariable\", \"attrs\": {\"id\": \"inviterName\"}}, {\"text\": \" \", \"type\": \"text\"}, {\"text\": \"heeft je toegevoegd als beheerder van \", \"type\": \"text\", \"marks\": [{\"type\": \"code\"}]}, {\"type\": \"smartVariable\", \"attrs\": {\"id\": \"platformOrOrganizationName\"}}, {\"text\": \". Je kan inloggen met je bestaande account \", \"type\": \"text\", \"marks\": [{\"type\": \"code\"}]}, {\"type\": \"smartVariable\", \"attrs\": {\"id\": \"email\"}}, {\"text\": \". Daar kan je jouw vereniging zoeken en aanklikken.\", \"type\": \"text\", \"marks\": [{\"type\": \"code\"}]}]}, {\"type\": \"paragraph\"}, {\"type\": \"smartButton\", \"attrs\": {\"id\": \"signInUrl\"}, \"content\": [{\"text\": \"Log in\", \"type\": \"text\"}]}, {\"type\": \"paragraph\"}, {\"type\": \"descriptiveText\", \"content\": [{\"text\": \"Weet je jouw wachtwoord niet meer? Dan kan je een nieuw wachtwoord instellen via de onderstaande link:\", \"type\": \"text\", \"marks\": [{\"type\": \"code\"}]}]}, {\"type\": \"descriptiveText\", \"content\": [{\"type\": \"smartVariable\", \"attrs\": {\"id\": \"resetUrl\"}}]}, {\"type\": \"descriptiveText\"}, {\"type\": \"descriptiveText\", \"content\": [{\"text\": \"Deze link is geldig tot \", \"type\": \"text\"}, {\"type\": \"smartVariable\", \"attrs\": {\"id\": \"validUntil\"}}, {\"text\": \".\", \"type\": \"text\"}]}, {\"type\": \"descriptiveText\"}, {\"type\": \"paragraph\", \"content\": [{\"text\": \"Ken je deze vereniging niet? Dan kan je deze e-mail veilig negeren.\", \"type\": \"text\"}]}]}, \"version\": 328}', '2024-08-29 13:41:58', '2024-08-29 13:41:58');
3
+
4
+ INSERT INTO `email_templates` (`id`, `subject`, `groupId`, `webshopId`, `organizationId`, `type`, `text`, `html`, `json`, `updatedAt`, `createdAt`) VALUES
5
+ ('daf7152c-a58c-4c60-811f-4f7d5d4026cc', '✉️ Beheerder van {{platformOrOrganizationName}}', NULL, NULL, NULL, 'AdminInvitationNewUser', '{{greeting}}{{inviterName}} heeft je uitgenodigd om beheerder te worden van {{platformOrOrganizationName}}.\n\n \n \n \n \n Account aanmaken\n \n \n \n \n\nDeze link is geldig tot {{validUntil}}.Ken je deze vereniging niet? Dan kan je deze e-mail veilig negeren.', '<!DOCTYPE html>\n<html>\n\n<head>\n<meta charset=\"utf-8\" />\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\" />\n<title>✉️ Beheerder van {{platformOrOrganizationName}}</title>\n<style type=\"text/css\">body {\n color: #000716;\n color: var(--color-dark, #000716);\n font-family: -apple-system-body, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n font-size: 12pt;\n line-height: 1.4;\n}\n\np {\n margin: 0;\n padding: 0;\n line-height: 1.4;\n}\n\np.description {\n color: var(--color-gray-4, #5e5e5e);\n}\np.description a, p.description a:link, p.description a:visited, p.description a:active, p.description a:hover {\n text-decoration: underline;\n color: var(--color-gray-4, #5e5e5e);\n}\n\nstrong {\n font-weight: bold;\n}\n\nem {\n font-style: italic;\n}\n\nh1 {\n font-size: 30px;\n font-weight: bold;\n line-height: 1.2;\n margin: 0;\n padding: 0;\n}\n@media (max-width: 350px) {\n h1 {\n font-size: 24px;\n }\n}\n\nh2 {\n font-size: 20px;\n line-height: 1.2;\n font-weight: bold;\n margin: 0;\n padding: 0;\n}\n\nh3 {\n font-size: 16px;\n line-height: 1.2;\n font-weight: bold;\n margin: 0;\n padding: 0;\n}\n\nh4 {\n line-height: 1.2;\n font-weight: 500;\n margin: 0;\n padding: 0;\n}\n\nol, ul {\n list-style-position: outside;\n padding-left: 30px;\n}\n\nhr {\n height: 1px;\n background: var(--color-border, var(--color-gray-2, #dcdcdc));\n border-radius: 1px;\n padding: 0;\n margin: 20px 0;\n outline: none;\n border: 0;\n}\n\n.button {\n touch-action: inherit;\n user-select: auto;\n cursor: pointer;\n display: inline-block !important;\n line-height: 42px;\n font-size: 16px;\n font-weight: bold;\n}\n.button:active {\n transform: none;\n}\n\nimg {\n max-width: 100%;\n height: auto;\n}\n\na, a:link, a:visited, a:active, a:hover {\n text-decoration: underline;\n color: blue;\n}\n\n.email-data-table {\n width: 100%;\n border-collapse: collapse;\n}\n.email-data-table th, .email-data-table td {\n text-align: left;\n padding: 10px 10px 10px 0;\n border-bottom: 1px solid var(--color-border, var(--color-gray-2, #dcdcdc));\n vertical-align: middle;\n}\n.email-data-table th:last-child, .email-data-table td:last-child {\n text-align: right;\n padding-right: 0;\n}\n.email-data-table thead {\n font-weight: bold;\n}\n.email-data-table thead th {\n font-size: 10pt;\n}\n.email-data-table h4 ~ p {\n padding-top: 3px;\n opacity: 0.8;\n font-size: 11pt;\n} hr {height: 2px;background: #e7e7e7; border-radius: 1px; padding: 0; margin: 20px 0; outline: none; border: 0;} .button.primary { margin: 0; text-decoration: none; font-size: 16px; font-weight: bold; color: {{primaryColorContrast}}; padding: 0 27px; line-height: 42px; background: {{primaryColor}}; text-align: center; border-radius: 7px; touch-action: manipulation; display: inline-block; transition: 0.2s transform, 0.2s opacity; } .button.primary:active { transform: scale(0.95, 0.95); } .inline-link, .inline-link:link, .inline-link:visited, .inline-link:active, .inline-link:hover { margin: 0; text-decoration: underline; font-size: inherit; font-weight: inherit; color: inherit; touch-action: manipulation; } .inline-link:active { opacity: 0.5; } .description { color: #5e5e5e; } </style>\n</head>\n\n<body>\n<p style=\"margin: 0; padding: 0; line-height: 1.4;\">{{greeting}}</p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\">{{inviterName}} <code>heeft je uitgenodigd om beheerder te worden van </code>{{platformOrOrganizationName}}<code>.</code></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><div data-type=\"smartButton\" data-id=\"resetUrl\"><table width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" style=\"margin: 5px 0;\">\n<tbody><tr>\n <td>\n <table cellspacing=\"0\" cellpadding=\"0\">\n <tbody><tr>\n <td style=\"border-radius: 7px;\" bgcolor=\"{{primaryColor}}\">\n <a class=\"button primary\" href=\"{{resetUrl}}\" target=\"\" style=\"margin: 0; text-decoration: none; font-size: 16px; font-weight: bold; color: {{primaryColorContrast}}; padding: 0 27px; line-height: 42px; background: {{primaryColor}}; text-align: center; border-radius: 7px; touch-action: manipulation; display: inline-block; transition: 0.2s transform, 0.2s opacity;\">Account aanmaken</a>\n </td>\n </tr>\n </tbody></table>\n </td>\n</tr>\n</tbody></table></div><p class=\"description\" style=\"color: #5e5e5e;\">Deze link is geldig tot {{validUntil}}.</p><p style=\"margin: 0; padding: 0; line-height: 1.4;\"><br></p><p style=\"margin: 0; padding: 0; line-height: 1.4;\">Ken je deze vereniging niet? Dan kan je deze e-mail veilig negeren.</p>\n</body>\n\n</html>', '{\"value\": {\"type\": \"doc\", \"content\": [{\"type\": \"paragraph\", \"content\": [{\"type\": \"smartVariable\", \"attrs\": {\"id\": \"greeting\"}}]}, {\"type\": \"paragraph\"}, {\"type\": \"paragraph\", \"content\": [{\"type\": \"smartVariable\", \"attrs\": {\"id\": \"inviterName\"}}, {\"text\": \" \", \"type\": \"text\"}, {\"text\": \"heeft je uitgenodigd om beheerder te worden van \", \"type\": \"text\", \"marks\": [{\"type\": \"code\"}]}, {\"type\": \"smartVariable\", \"attrs\": {\"id\": \"platformOrOrganizationName\"}}, {\"text\": \".\", \"type\": \"text\", \"marks\": [{\"type\": \"code\"}]}]}, {\"type\": \"paragraph\"}, {\"type\": \"smartButton\", \"attrs\": {\"id\": \"resetUrl\"}, \"content\": [{\"text\": \"Account aanmaken\", \"type\": \"text\"}]}, {\"type\": \"descriptiveText\", \"content\": [{\"text\": \"Deze link is geldig tot \", \"type\": \"text\"}, {\"type\": \"smartVariable\", \"attrs\": {\"id\": \"validUntil\"}}, {\"text\": \".\", \"type\": \"text\"}]}, {\"type\": \"paragraph\"}, {\"type\": \"paragraph\", \"content\": [{\"text\": \"Ken je deze vereniging niet? Dan kan je deze e-mail veilig negeren.\", \"type\": \"text\"}]}]}, \"version\": 328}', '2024-08-29 13:41:58', '2024-08-29 13:41:58');
@@ -11,6 +11,7 @@ import { Formatter } from '@stamhoofd/utility';
11
11
  import { getEmailBuilder } from '../helpers/EmailBuilder';
12
12
  import { EmailRecipient } from './EmailRecipient';
13
13
  import { Organization } from './Organization';
14
+ import { I18n } from '@stamhoofd/backend-i18n';
14
15
 
15
16
  export class Email extends Model {
16
17
  static table = "emails";
@@ -139,10 +140,11 @@ export class Email extends Model {
139
140
  }
140
141
 
141
142
  getDefaultFromAddress(organization?: Organization|null): string {
142
- let address = "noreply@stamhoofd.email";
143
+ const i18n = new I18n("nl", "BE")
144
+ let address = "noreply@" + i18n.localizedDomains.defaultBroadcastEmail()
143
145
 
144
146
  if (organization) {
145
- address = organization.uri+"@stamhoofd.email";
147
+ address = organization.getDefaultFrom(organization.i18n, false, 'broadcast');
146
148
  }
147
149
 
148
150
  if (!this.fromName) {
@@ -198,7 +200,11 @@ export class Email extends Model {
198
200
  }
199
201
  } else {
200
202
  // Platform
201
- const domains = Object.values(STAMHOOFD.domains.marketing)
203
+ // Is the platform allowed to send from the provided email address?
204
+ const domains = [
205
+ ...Object.values(STAMHOOFD.domains.defaultTransactionalEmail ?? {}),
206
+ ...Object.values(STAMHOOFD.domains.defaultBroadcastEmail ?? {})
207
+ ]
202
208
 
203
209
  for (const domain of domains) {
204
210
  if (upToDate.fromAddress!.endsWith("@"+domain)) {
@@ -78,4 +78,5 @@ export class EmailRecipient extends Model {
78
78
  getStructure() {
79
79
  return EmailRecipientStruct.create(this)
80
80
  }
81
+
81
82
  }
@@ -1,10 +1,12 @@
1
1
  import { column, Model } from "@simonbackx/simple-database";
2
2
  import { SimpleError } from "@simonbackx/simple-errors";
3
3
  import { I18n } from "@stamhoofd/backend-i18n";
4
- import { Email } from "@stamhoofd/email";
4
+ import { EmailTemplateType, Recipient, Replacement } from "@stamhoofd/structures";
5
5
  import basex from "base-x";
6
6
  import crypto from "crypto";
7
7
  import { v4 as uuidv4 } from "uuid";
8
+ import { sendEmailTemplate } from "../helpers/EmailBuilder";
9
+ import { Platform } from "./Platform";
8
10
 
9
11
  const ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
10
12
  const bs58 = basex(ALPHABET)
@@ -241,38 +243,55 @@ export class EmailVerificationCode extends Model {
241
243
  }
242
244
  }
243
245
 
244
- send(user: import('./User').User, organization: import('./Organization').Organization|null, i18n: I18n, withCode = true) {
245
- const { from, replyTo } = {
246
- from: (user.organizationPermissions || !organization ? Email.getInternalEmailFor(i18n) : organization.getStrongEmail(i18n)),
247
- replyTo: undefined // Don't use replyTo because it affects deliverability rates due to spam filters
248
- }
249
-
250
- const url = this.getEmailVerificationUrl(user, organization, i18n)
246
+ async send(user: import('./User').User, organization: import('./Organization').Organization|null, i18n: I18n, withCode = true) {
247
+ const url = this.getEmailVerificationUrl(user, organization, i18n);
251
248
 
252
- const footer = (!user.organizationPermissions && organization ? "\n\n—\n\nOnze ledenadministratie werkt via het Stamhoofd platform, op maat van verenigingen. Probeer het ook via https://"+i18n.$t("shared.domains.marketing")+"/ledenadministratie\n\n" : '')
253
- const footerHTML = (!user.organizationPermissions && organization ? "<br><br>—<br><br>Onze ledenadministratie werkt via het Stamhoofd platform, op maat van verenigingen. Probeer het ook via <a href=\"https://"+i18n.$t("shared.domains.marketing")+"/ledenadministratie\">Stamhoofd</a><br><br>" : '')
249
+ const name = organization?.name ?? (await Platform.getSharedPrivateStruct()).config.name;
254
250
 
255
- const name = organization?.name ?? 'Stamhoofd'
251
+ const replacements: Replacement[] = [
252
+ Replacement.create({
253
+ token: 'organizationName',
254
+ value: name
255
+ }),
256
+ Replacement.create({
257
+ token: 'confirmEmailUrl',
258
+ value: url
259
+ })
260
+ ]
256
261
 
257
262
  if (withCode) {
258
263
  const formattedCode = this.code.substr(0, 3)+" "+this.code.substr(3)
259
- Email.send({
260
- from,
261
- replyTo,
262
- to: this.email,
263
- subject: `[${user.organizationPermissions ? "Stamhoofd" : name}] Verifieer jouw e-mailadres`,
264
- type: "transactional",
265
- text: `Hallo${user.firstName ? (" "+user.firstName) : ""}!\n\nVerifieer jouw e-mailadres om te kunnen inloggen bij ${name}. Vul de code "${formattedCode}" in op de website of klik op de onderstaande link om jouw e-mailadres te bevestigen.\n${url}\n\nDit is een automatische e-mail. Gelieve niet op dit e-mailadres te reageren.\n\n${user.organizationPermissions ? "Stamhoofd" : name}`+footer,
266
- html: `Hallo${user.firstName ? (" "+user.firstName) : ""}!<br><br>Verifieer jouw e-mailadres om te kunnen inloggen bij ${name}. Vul de onderstaande code in op de website<br><br><strong style="font-size: 30px; font-weight: bold;">${formattedCode}</strong><br><br>Of klik op de onderstaande link om jouw e-mailadres te bevestigen:<br>${url}<br><br>Dit is een automatische e-mail. Gelieve niet op dit e-mailadres te reageren.<br><br>${user.organizationPermissions ? "Stamhoofd" : name}`+footerHTML
264
+
265
+ await sendEmailTemplate(organization, {
266
+ recipients: [
267
+ Recipient.create({
268
+ email: this.email,
269
+ replacements: [
270
+ ...replacements,
271
+ Replacement.create({
272
+ token: 'confirmEmailCode',
273
+ value: formattedCode
274
+ })
275
+ ]
276
+ })
277
+ ],
278
+ template: {
279
+ type: EmailTemplateType.VerifyEmail,
280
+ },
281
+ type: 'transactional'
267
282
  })
268
283
  } else {
269
- Email.send({
270
- from,
271
- replyTo,
272
- to: this.email,
273
- type: "transactional",
274
- subject: `[${user.organizationPermissions ? "Stamhoofd" : name}] Verifieer jouw e-mailadres`,
275
- text: `Hallo${user.firstName ? (" "+user.firstName) : ""}!\n\nVerifieer jouw e-mailadres om te kunnen inloggen bij ${name}. Klik op de onderstaande link om jouw e-mailadres te bevestigen.\n${url}\n\nDit is een automatische e-mail. Gelieve niet op dit e-mailadres te reageren.\n\n${user.organizationPermissions ? "Stamhoofd" : name}`+footer
284
+ await sendEmailTemplate(organization, {
285
+ recipients: [
286
+ Recipient.create({
287
+ email: this.email,
288
+ replacements
289
+ })
290
+ ],
291
+ template: {
292
+ type: EmailTemplateType.VerifyEmailWithoutCode,
293
+ },
294
+ type: 'transactional'
276
295
  })
277
296
  }
278
297
  }
@@ -305,7 +324,7 @@ export class EmailVerificationCode extends Model {
305
324
  if (!user) {
306
325
  return
307
326
  }
308
- verificationCode.send(user, organization, i18n)
327
+ await verificationCode.send(user, organization, i18n)
309
328
  }
310
329
 
311
330
  /**
@@ -511,7 +511,8 @@ export class Member extends Model {
511
511
 
512
512
  const periodConfig = cheapestMembership.membership.periods.get(platform.periodId)
513
513
  if (!periodConfig) {
514
- throw new Error("Period config not found")
514
+ console.error("Missing membership prices for membership type "+cheapestMembership.membership.id+" and period " + platform.periodId)
515
+ return;
515
516
  }
516
517
 
517
518
  // Can we revive an earlier deleted membership?
@@ -1,6 +1,6 @@
1
1
  import { column, Model, SQLResultNamespacedRow } from '@simonbackx/simple-database';
2
2
  import { SQL, SQLSelect } from '@stamhoofd/sql';
3
- import { MemberResponsibilityRecord as MemberResponsibilityRecordStruct } from '@stamhoofd/structures';
3
+ import { Group as GroupStruct, MemberResponsibilityRecordBase, MemberResponsibilityRecord as MemberResponsibilityRecordStruct } from '@stamhoofd/structures';
4
4
  import { v4 as uuidv4 } from "uuid";
5
5
 
6
6
  export class MemberResponsibilityRecord extends Model {
@@ -41,8 +41,17 @@ export class MemberResponsibilityRecord extends Model {
41
41
  @column({ type: "datetime", nullable: true })
42
42
  endDate: Date | null = null
43
43
 
44
- getStructure() {
45
- return MemberResponsibilityRecordStruct.create(this)
44
+ getBaseStructure() {
45
+ return MemberResponsibilityRecordBase.create({
46
+ ...this
47
+ })
48
+ }
49
+
50
+ getStructure(group: GroupStruct|null) {
51
+ return MemberResponsibilityRecordStruct.create({
52
+ ...this,
53
+ group
54
+ })
46
55
  }
47
56
 
48
57
  /**
@@ -130,27 +130,19 @@ export class Organization extends Model {
130
130
 
131
131
  // Methods
132
132
  static async getByEmail(email: string): Promise<Organization | undefined> {
133
- if (["hallo@stamhoofd.be", "hallo@stamhoofd.nl"].includes(email)) {
134
- return
135
- }
136
133
  if (email.startsWith('noreply-')) {
137
134
  // Trim
138
135
  email = email.substring("noreply-".length)
139
136
  }
140
137
 
141
- if (email.endsWith("@stamhoofd.email")) {
142
- const uri = email.substring(0, email.length - "@stamhoofd.email".length)
143
- return await Organization.getByURI(uri)
144
- }
145
-
146
- if (email.endsWith("@stamhoofd.be")) {
147
- const uri = email.substring(0, email.length - "@stamhoofd.be".length)
148
- return await Organization.getByURI(uri)
149
- }
150
-
151
- if (email.endsWith("@stamhoofd.nl")) {
152
- const uri = email.substring(0, email.length - "@stamhoofd.nl".length)
153
- return await Organization.getByURI(uri)
138
+ for (const domain of [
139
+ ...Object.values(STAMHOOFD.domains.defaultBroadcastEmail ?? {}),
140
+ ...Object.values(STAMHOOFD.domains.defaultTransactionalEmail ?? {}),
141
+ ]) {
142
+ if (email.endsWith("@" + domain)) {
143
+ const uri = email.substring(0, email.length - ("@" + domain).length)
144
+ return await Organization.getByURI(uri)
145
+ }
154
146
  }
155
147
 
156
148
  const at = email.indexOf("@");
@@ -448,8 +440,8 @@ export class Organization extends Model {
448
440
 
449
441
  const replaceAll = [
450
442
  {
451
- from: defaultI18n.$t("shared.domains.marketing"),
452
- to: i18n.$t("shared.domains.marketing")
443
+ from: defaultI18n.localizedDomains.marketing(),
444
+ to: i18n.localizedDomains.marketing()
453
445
  },
454
446
  {
455
447
  from: defaultI18n.$t("shared.emails.general"),
@@ -872,38 +864,27 @@ export class Organization extends Model {
872
864
  }
873
865
 
874
866
  /**
875
- * These email addresess are private
867
+ * Return default e-mail address if no email addresses are set.
876
868
  */
877
- async getInvoicingToEmails() {
878
- // Circular reference fix
879
- const User = (await import('./User')).User;
880
- const admins = await User.where({ organizationId: this.id, permissions: { sign: "!=", value: null }})
881
- const filtered = admins.filter(a => a.permissions?.forOrganization(this)?.hasAccessRight(AccessRight.OrganizationFinanceDirector))
882
-
883
- if (filtered.length > 0) {
884
- return filtered.map(f => f.getEmailTo() ).join(", ")
885
- }
869
+ getDefaultFrom(i18n: I18n, withName = true, type: 'transactional' | 'broadcast' = 'broadcast') {
870
+ const domain = type === 'transactional' ? i18n.localizedDomains.defaultTransactionalEmail() : i18n.localizedDomains.defaultBroadcastEmail()
886
871
 
887
- return undefined
888
- }
889
-
890
- /**
891
- * Return default e-mail address for important e-mails that should have the highest deliverability
892
- */
893
- getStrongEmail(i18n: I18n, withName = true) {
894
872
  if (!withName) {
895
- return ('noreply-' + this.uri+"@"+i18n.$t("shared.domains.email"));
873
+ return ('noreply-' + this.uri+"@"+domain);
896
874
  }
897
- return '"'+this.name.replaceAll("\"", "\\\"")+'" <'+ ('noreply-' + this.uri+"@"+i18n.$t("shared.domains.email")) +'>'
875
+ return '"'+this.name.replaceAll("\"", "\\\"")+'" <'+ ('noreply-' + this.uri+"@"+domain) +'>'
898
876
  }
899
877
 
878
+ /**
879
+ * @deprecated Switch to EmailBuilder.sendEmailTemplate
880
+ */
900
881
  getEmail(id: string | null, strongDefault = false): { from: string; replyTo: string | undefined } {
901
882
  if (id === null) {
902
883
  return this.getDefaultEmail(strongDefault)
903
884
  }
904
885
 
905
886
  // Send confirmation e-mail
906
- let from = strongDefault ? this.getStrongEmail(this.i18n, false) : this.uri+"@stamhoofd.email";
887
+ let from = this.getDefaultFrom(this.i18n, false, strongDefault ? 'transactional' : 'broadcast')
907
888
  const sender: OrganizationEmail | undefined = this.privateMeta.emails.find(e => e.id === id)
908
889
  let replyTo: string | undefined = undefined
909
890
 
@@ -935,13 +916,12 @@ export class Organization extends Model {
935
916
  return this.getDefaultEmail(strongDefault)
936
917
  }
937
918
 
938
- getGroupEmail(group: Group) {
939
- return this.getEmail(group.privateSettings.defaultEmailId)
940
- }
941
-
919
+ /**
920
+ * @deprecated Switch to EmailBuilder.sendEmailTemplate
921
+ */
942
922
  getDefaultEmail(strongDefault = false): { from: string; replyTo: string | undefined } {
943
923
  // Send confirmation e-mail
944
- let from = strongDefault ? this.getStrongEmail(this.i18n, false) : this.uri+"@stamhoofd.email";
924
+ let from = strongDefault ? this.getDefaultFrom(this.i18n, false) : this.uri+"@stamhoofd.email";
945
925
  const sender: OrganizationEmail | undefined = this.privateMeta.emails.find(e => e.default) ?? this.privateMeta.emails[0];
946
926
  let replyTo: string | undefined = undefined
947
927
 
@@ -122,4 +122,5 @@ export class OrganizationRegistrationPeriod extends Model {
122
122
  }
123
123
  }
124
124
  }
125
+
125
126
  }