diff --git a/server/src/main/java/invite/mail/MailBox.java b/server/src/main/java/invite/mail/MailBox.java index 1e0bda77..3b7c940a 100644 --- a/server/src/main/java/invite/mail/MailBox.java +++ b/server/src/main/java/invite/mail/MailBox.java @@ -1,6 +1,7 @@ package invite.mail; import invite.cron.IdPMetaDataResolver; +import invite.cron.IdentityProvider; import invite.model.*; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; @@ -69,12 +70,17 @@ public void sendInviteMail(Provisionable provisionable, Invitation invitation, variables.put("groupedProviders", groupedProviders); variables.put("title", title); if (provisionable instanceof User user) { - variables.put("institutionName", idPMetaDataResolver - .getIdentityProvider(user.getSchacHomeOrganization()) + Optional identityProvider = idPMetaDataResolver + .getIdentityProvider(user.getSchacHomeOrganization()); + variables.put("institutionName", identityProvider .map(idp -> idp.getName()) .orElse(user.getSchacHomeOrganization())); + variables.put("institutionLogoUrl", identityProvider + .map(idp -> idp.getLogoUrl()) + .orElse(null)); } else { variables.put("institutionName", "SURF"); + variables.put("isInstitutionSurf", true); } optionalIdpName.ifPresent(idpName -> variables.put("idpName", idpName)); variables.put("roles", splitListSemantically(invitation.getRoles().stream() diff --git a/server/src/main/resources/templates/eduID-logo-square.svg b/server/src/main/resources/templates/eduID-logo-square.svg new file mode 100644 index 00000000..c5930564 --- /dev/null +++ b/server/src/main/resources/templates/eduID-logo-square.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/server/src/main/resources/templates/invitation_en.html b/server/src/main/resources/templates/invitation_en.html index 13f8d389..12958632 100644 --- a/server/src/main/resources/templates/invitation_en.html +++ b/server/src/main/resources/templates/invitation_en.html @@ -4,88 +4,84 @@ {{title}} -
-
- {{> logo-surf.svg}} - Welcome +
+
+ {{#institutionLogoUrl}} + logo + {{/institutionLogoUrl}} + {{#isInstitutionSurf}} + logo + {{/isInstitutionSurf}}
-
+
{{#environment}} -

+

This mail is from the {{environment}} environment

{{/environment}} -

Hello,

- {{#invitation.institutionAdminInvitation}} -

{{displaySenderName}} (from {{institutionName}}) has invited you to become +

{{displaySenderName}} (from {{institutionName}}) has invited you to become an institution admin for institution {{idpName}} to manage the applications of this institution.

{{/invitation.institutionAdminInvitation}} {{#invitation.anyRoles}} -

{{displaySenderName}} (from {{institutionName}}) has invited you for one or - more - applications or systems that they use.

- -

You have been invited for:

- +

{{displaySenderName}} (from {{institutionName}}) would you like to grant access to:

    {{#groupedProviders}} -
  • {{name}} ({{organisation}}) - as - {{rolesDisplay}}
  • +
  • {{name}} - as {{rolesDisplay}}
  • {{/groupedProviders}}
{{/invitation.anyRoles}} {{#message}} -

Personal message from {{displaySenderName}}

-
+

{{{message}}}

{{/message}} {{#useEduID}} -

For access to these applications eduID is used. Do you not have an eduID account yet? - No worries, you can create one in less than 30 seconds.

+

You accept the role(s) by logging in with eduID. If you don’t have one yet, you can create it right away.

+

or copy this link into your browser: {{{ url }}}

{{/useEduID}} {{^useEduID}} -

For access to these applications we use SURFconext.

+

You accept the role(s) by logging in with SURFconext.

+

or copy this link into your browser: {{{ url }}}

{{/useEduID}}
- {{#useEduID}} -
-

Why do I need an eduID account?

-

An eduID is an account for users within the Dutch educational and research community. It is yours and exists - independent of an educational institution. - With eduID you can log in to various applications. Even if you don't have an institutional account. You can - use - eduID for example - if you want to follow courses with different institutions. Or if you want to follow a course after you have - graduated.

-

- Request eduID -

-

Requesting an eduID is free, and you can do it now. All you need is an - emailaddress.

+ - {{/useEduID}} - - {{> footer_en.html}} -
+ diff --git a/server/src/main/resources/templates/invitation_nl.html b/server/src/main/resources/templates/invitation_nl.html index c02cd223..33efc568 100644 --- a/server/src/main/resources/templates/invitation_nl.html +++ b/server/src/main/resources/templates/invitation_nl.html @@ -4,89 +4,84 @@ {{title}} -
-
- {{> logo-surf.svg}} - Welkom +
+
+ {{#institutionLogoUrl}} + logo + {{/institutionLogoUrl}} + {{#isInstitutionSurf}} + logo + {{/isInstitutionSurf}}
-
+
{{#environment}} -

+

Deze mail is van de {{environment}}-omgeving

{{/environment}} -

Hallo,

- {{#invitation.institutionAdminInvitation}} -

{{displaySenderName}} (van {{institutionName}}) heeft je uitgenodigd om +

{{displaySenderName}} (van {{institutionName}}) heeft je uitgenodigd om een instellings-admin te worden van instelling {{idpName}} om de applicaties van deze instelling te beheren.

{{/invitation.institutionAdminInvitation}} {{#invitation.anyRoles}} -

{{displaySenderName}} (van {{institutionName}}) heeft je uitgenodigd voor - één of meer - applicaties en systemen die zij gebruiken.

- -

Je bent uitgenodigd voor:

- +

{{displaySenderName}} (van {{institutionName}}) wil je toegang geven tot:

    {{#groupedProviders}} -
  • {{name}} ({{organisation}}) - als - {{rolesDisplay}}
  • +
  • {{name}} - als {{rolesDisplay}}
  • {{/groupedProviders}}
{{/invitation.anyRoles}} {{#message}} -

Persoonlijk bericht van {{displaySenderName}}

-
+

{{{message}}}

{{/message}} {{#useEduID}} -

Voor de toegang tot deze applicatie(s) wordt gebruik gemaakt van eduID. Heb je nog geen eduID account? Geen - probleem, - een eduID account aanmaken kost minder dan 30 seconden.

+

De rol(len) accepteer je door in te loggen met eduID. Als je deze nog niet hebt, kun je hem gelijk aanmaken.

+

of kopieer deze link in je browser: {{{ url }}}

{{/useEduID}} {{^useEduID}} -

Voor de toegang tot deze applicaties wordt gebruik gemaakt van SURFconext.

+

De rol(len) accepteer je door in te loggen met SURFconext.

+

of kopieer deze link in je browser: {{{ url }}}

{{/useEduID}}
- {{#useEduID}} -
-

Waarom heb ik een eduID account nodig?

-

- Een eduID is een account voor gebruikers binnen het Nederlandse onderwijs en onderzoek. Het - is van jou, en bestaat onafhankelijk van een onderwijsinstelling. Met eduID kan je inloggen op - verschillende applicaties. Ook als je geen account van je instelling hebt, kan je met eduID inloggen. - Je kunt eduID bijvoorbeeld gebruiken als je bij meerdere instellingen tegelijk onnderwijs wilt volgen. - Of na je studie als je naast je werk een opleiding of cursus wilt volgen. -

-

- Aanvragen eduID -

-

Het aanvragen van een eduID is kosteloos en kan direct. Je hebt alleen een - e-mailadres nodig.

+ - {{/useEduID}} - - {{> footer_nl.html}} -
+ diff --git a/server/src/main/resources/templates/logo-surf-black.svg b/server/src/main/resources/templates/logo-surf-black.svg new file mode 100644 index 00000000..0fdba176 --- /dev/null +++ b/server/src/main/resources/templates/logo-surf-black.svg @@ -0,0 +1,4 @@ + + + + diff --git a/server/src/test/java/invite/api/InvitationControllerTest.java b/server/src/test/java/invite/api/InvitationControllerTest.java index 312da87b..dd6446db 100644 --- a/server/src/test/java/invite/api/InvitationControllerTest.java +++ b/server/src/test/java/invite/api/InvitationControllerTest.java @@ -107,6 +107,47 @@ void newInvitation() throws Exception { assertEquals(2, ((List) results.get("recipientInvitationURLs")).size()); } + @Test + void newInvitationNL() throws Exception { + //Because the user is changed and provisionings are queried + stubForManageProvisioning(List.of()); + AccessCookieFilter accessCookieFilter = openIDConnectFlow("/api/v1/users/login", MANAGE_SUB); + + stubForManageProviderById(EntityType.SAML20_SP, "1"); + + List roleIdentifiers = roleRepository.findByApplicationUsagesApplicationManageId("1").stream() + .map(Role::getId) + .toList(); + InvitationRequest invitationRequest = new InvitationRequest( + Authority.GUEST, + "Message", + Language.nl, + true, + false, + null, + false, + false, + List.of("new@new.nl"), + List.of(new Invite("new2@new.nl", "placeholder-1")), + roleIdentifiers, + null, + Instant.now().plus(365, ChronoUnit.DAYS), + Instant.now().plus(12, ChronoUnit.DAYS)); + + Map results = given() + .when() + .filter(accessCookieFilter.cookieFilter()) + .accept(ContentType.JSON) + .header(accessCookieFilter.csrfToken().getHeaderName(), accessCookieFilter.csrfToken().getToken()) + .contentType(ContentType.JSON) + .body(invitationRequest) + .post("/api/v1/invitations") + .as(new TypeRef<>() { + }); + assertEquals(201, results.get("status")); + assertEquals(2, ((List) results.get("recipientInvitationURLs")).size()); + } + @Test void newInvitationEmptyRoles() throws Exception { //Because the user is changed and provisionings are queried diff --git a/server/src/test/java/invite/api/InvitationMailControllerTest.java b/server/src/test/java/invite/api/InvitationMailControllerTest.java index 17424954..85090b74 100644 --- a/server/src/test/java/invite/api/InvitationMailControllerTest.java +++ b/server/src/test/java/invite/api/InvitationMailControllerTest.java @@ -34,7 +34,6 @@ void resendInviteMail() throws Exception { .statusCode(201); String htmlContent = super.mailMessage().getHtmlContent(); assertTrue(htmlContent.contains("Calendar EN")); - assertTrue(htmlContent.contains("SURF bv")); assertTrue(htmlContent.contains("Mail")); } diff --git a/server/src/test/java/invite/internal/InternalInviteControllerTest.java b/server/src/test/java/invite/internal/InternalInviteControllerTest.java index 933ab702..737a9437 100644 --- a/server/src/test/java/invite/internal/InternalInviteControllerTest.java +++ b/server/src/test/java/invite/internal/InternalInviteControllerTest.java @@ -157,6 +157,39 @@ void newInvitation() { assertEquals(201, results.get("status")); assertEquals(1, ((List) results.get("recipientInvitationURLs")).size()); } + @Test + void newInvitationNL() { + stubForManageProviderById(EntityType.SAML20_SP, "4"); + List roleIdentifiers = List.of(roleRepository.findByName("Research").get().getId()); + + InvitationRequest invitationRequest = new InvitationRequest( + Authority.GUEST, + "Message", + Language.nl, + true, + true, + null, + false, + false, + List.of("new@new.nl"), + List.of(), + roleIdentifiers, + null, + Instant.now().plus(365, ChronoUnit.DAYS), + Instant.now().plus(12, ChronoUnit.DAYS)); + + Map results = given() + .when() + .auth().preemptive().basic("sp_dashboard", "secret") + .accept(ContentType.JSON) + .contentType(ContentType.JSON) + .body(invitationRequest) + .post("/api/internal/invite/invitations") + .as(new TypeRef>() { + }); + assertEquals(201, results.get("status")); + assertEquals(1, ((List) results.get("recipientInvitationURLs")).size()); + } @Test void resendInvitation() { diff --git a/server/src/test/java/invite/mail/MailBoxTest.java b/server/src/test/java/invite/mail/MailBoxTest.java index b35258c3..6e232280 100644 --- a/server/src/test/java/invite/mail/MailBoxTest.java +++ b/server/src/test/java/invite/mail/MailBoxTest.java @@ -26,9 +26,8 @@ void sendInviteMail() { String htmlContent = doSendInviteMail(true, Authority.INVITER); assertTrue(htmlContent.contains("Wiki EN")); - assertTrue(htmlContent.contains("SURF bv")); - assertTrue(htmlContent.contains("For access to these applications we use SURFconext")); - assertFalse(htmlContent.contains("For access to these applications eduID is used")); + assertTrue(htmlContent.contains("You accept the role(s) by logging in with SURFconext.")); + assertFalse(htmlContent.contains("You accept the role(s) by logging in with eduID")); } @Test @@ -36,9 +35,8 @@ void sendInviteMailForEduIDOnly() { String htmlContent = doSendInviteMail(true, Authority.GUEST); assertTrue(htmlContent.contains("Wiki EN")); - assertTrue(htmlContent.contains("SURF bv")); - assertFalse(htmlContent.contains("For access to these applications we use SURFconext")); - assertTrue(htmlContent.contains("For access to these applications eduID is used")); + assertFalse(htmlContent.contains("You accept the role(s) by logging in with SURFconext")); + assertTrue(htmlContent.contains("You accept the role(s) by logging in with eduID")); } private String doSendInviteMail(boolean eduIDOnly, Authority intendedAuthority) {