From 1f7c2f8612d26febdf0042d1167b82147e887b33 Mon Sep 17 00:00:00 2001 From: Sarah Sporck Date: Thu, 16 Mar 2023 17:34:27 +0100 Subject: [PATCH] 836: send verification emails --- .../components/ApplyController.tsx | 2 +- .../{apply.graphql => addApplication.graphql} | 4 +- backend/package-lock.json | 6 +++ .../EakApplicationMutationService.kt | 54 ++++++++++++++++--- specs/backend-api.graphql | 2 +- 5 files changed, 56 insertions(+), 12 deletions(-) rename administration/src/graphql/applications/{apply.graphql => addApplication.graphql} (66%) create mode 100644 backend/package-lock.json diff --git a/administration/src/application/components/ApplyController.tsx b/administration/src/application/components/ApplyController.tsx index b59e7f433..8bbb9d46d 100644 --- a/administration/src/application/components/ApplyController.tsx +++ b/administration/src/application/components/ApplyController.tsx @@ -92,7 +92,7 @@ const ApplyController = (): React.ReactElement | null => { const [regionId, application] = validationResult.value addBlueEakApplication({ - variables: { regionId, application }, + variables: { regionId, application, project: projectId }, }) } diff --git a/administration/src/graphql/applications/apply.graphql b/administration/src/graphql/applications/addApplication.graphql similarity index 66% rename from administration/src/graphql/applications/apply.graphql rename to administration/src/graphql/applications/addApplication.graphql index ed6df963c..7c215be98 100644 --- a/administration/src/graphql/applications/apply.graphql +++ b/administration/src/graphql/applications/addApplication.graphql @@ -1,3 +1,3 @@ -mutation addEakApplication($regionId: Int!, $application: ApplicationInput!) { - result: addEakApplication(regionId: $regionId, application: $application) +mutation addEakApplication($regionId: Int!, $application: ApplicationInput!, $project: String!) { + result: addEakApplication(regionId: $regionId, application: $application, project: $project) } diff --git a/backend/package-lock.json b/backend/package-lock.json new file mode 100644 index 000000000..dfb18f115 --- /dev/null +++ b/backend/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "backend", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/backend/src/main/kotlin/app/ehrenamtskarte/backend/application/webservice/EakApplicationMutationService.kt b/backend/src/main/kotlin/app/ehrenamtskarte/backend/application/webservice/EakApplicationMutationService.kt index 27f88dde9..ce9cb39de 100644 --- a/backend/src/main/kotlin/app/ehrenamtskarte/backend/application/webservice/EakApplicationMutationService.kt +++ b/backend/src/main/kotlin/app/ehrenamtskarte/backend/application/webservice/EakApplicationMutationService.kt @@ -1,15 +1,19 @@ package app.ehrenamtskarte.backend.application.webservice import app.ehrenamtskarte.backend.application.database.ApplicationEntity +import app.ehrenamtskarte.backend.application.database.ApplicationVerificationEntity import app.ehrenamtskarte.backend.application.database.repos.ApplicationRepository import app.ehrenamtskarte.backend.application.webservice.schema.create.Application import app.ehrenamtskarte.backend.auth.database.AdministratorEntity import app.ehrenamtskarte.backend.auth.service.Authorizer.mayDeleteApplicationsInRegion import app.ehrenamtskarte.backend.common.webservice.GraphQLContext import app.ehrenamtskarte.backend.common.webservice.UnauthorizedException +import app.ehrenamtskarte.backend.mail.Mailer import com.expediagroup.graphql.generator.annotations.GraphQLDescription import graphql.schema.DataFetchingEnvironment import org.jetbrains.exposed.sql.transactions.transaction +import java.net.URLEncoder +import java.nio.charset.StandardCharsets @Suppress("unused") class EakApplicationMutationService { @@ -18,9 +22,13 @@ class EakApplicationMutationService { fun addEakApplication( regionId: Int, application: Application, + project: String, dfe: DataFetchingEnvironment, ): Boolean { val context = dfe.getContext() + val backendConfig = context.backendConfiguration + val projectConfig = backendConfig.projects.first { it.id == project } + // Validate that all files are png, jpeg or pdf files and at most 5MB. val allowedContentTypes = setOf("application/pdf", "image/png", "image/jpeg") val maxFileSizeBytes = 5 * 1000 * 1000 @@ -28,19 +36,49 @@ class EakApplicationMutationService { throw IllegalArgumentException("An uploaded file does not adhere to the file upload requirements.") } - val (applicationEntity, verificationEntities) = ApplicationRepository.persistApplication( - application.toJsonField(), - application.extractApplicationVerifications(), - regionId, - context.applicationData, - context.files, - ) + transaction { + val (applicationEntity, verificationEntities) = ApplicationRepository.persistApplication( + application.toJsonField(), + application.extractApplicationVerifications(), + regionId, + context.applicationData, + context.files, + ) - // TODO: Send mails + for (applicationVerification in verificationEntities) { + Mailer.sendMail( + backendConfig, + projectConfig.smtp, + projectConfig.administrationName, + applicationVerification.contactEmailAddress, + "Antrag Verifizieren", + generateApplicationVerificationMailMessage(projectConfig.administrationName, projectConfig.administrationBaseUrl, applicationVerification) + ) + } + } return true } + private fun generateApplicationVerificationMailMessage( + administrationName: String, + administrationBaseUrl: String, + applicationVerification: ApplicationVerificationEntity + ): String { + return """ + Guten Tag ${applicationVerification.contactName}, + + Sie wurden gebeten, die Angaben eines Antrags auf Ehrenamtskarte zu bestätigen. Die Antragsstellerin oder der + Antragssteller hat Sie als Kontaktperson der Organisation ${applicationVerification.organizationName} angegeben. + Sie können den Antrag unter folgenden Link einsehen und verifizieren oder ablehnen: + $administrationBaseUrl/antrag-verifizieren/${URLEncoder.encode(applicationVerification.accessKey, StandardCharsets.UTF_8)} + + Dies ist eine automatisierte Nachricht. Antworten Sie nicht auf diese Email. + + - $administrationName + """.trimIndent() + } + @GraphQLDescription("Deletes the application with specified id") fun deleteApplication( applicationId: Int, diff --git a/specs/backend-api.graphql b/specs/backend-api.graphql index ef2fd719a..f0bc5a65a 100644 --- a/specs/backend-api.graphql +++ b/specs/backend-api.graphql @@ -98,7 +98,7 @@ type Mutation { "Stores a batch of new digital entitlementcards" addCards(cards: [CardGenerationModelInput!]!): Boolean! "Stores a new application for an EAK" - addEakApplication(application: ApplicationInput!, regionId: Int!): Boolean! + addEakApplication(application: ApplicationInput!, project: String!, regionId: Int!): Boolean! "Changes an administrator's password" changePassword(currentPassword: String!, email: String!, newPassword: String!, project: String!): Boolean! "Creates a new administrator"