├── .clas ├── IRIS Gateway-Entity.pdf └── IRIS Gateway-Individual.pdf ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ └── release.md ├── dependabot.yml └── workflows │ ├── app-eps_develop.yml │ ├── bff_develop.yml │ ├── codeql-analysis.yml │ ├── fe-e2e-test.yml │ ├── fe_develop.yml │ ├── iris-client-eps_develop.yml │ ├── iris-client-proxy_develop.yml │ ├── nginx_develop.yml │ ├── publish-test-results.yml │ ├── release-gitflow.yml │ ├── reuse-check.yml │ ├── trivy-config-scan.yml │ ├── trivy-container-scan.yml │ └── trivy-repo-scan.yml ├── .gitignore ├── .prepare-release.sh ├── .releaserc ├── .reuse └── dep5 ├── .setup_dct.sh ├── .trivyignore ├── AUTHORS.md ├── BFF-THIRD-PARTY-LICENSES.md ├── CHANGELOG.md ├── FE-THIRD-PARTY-LICENSES-DEV.md ├── FE-THIRD-PARTY-LICENSES-PROD.md ├── LICENSE ├── LICENSES ├── AGPL-3.0-or-later.txt └── Apache-2.0.txt ├── README.adoc ├── SECURITY.md ├── doc └── adr │ ├── 0001-record-architecture-decisions.md │ ├── 0002-use-fix-version-tags-for-base-images.md │ ├── 0003-coherent-use-of-the-configuration-cascade-for-spring.md │ ├── 0004-coherent-use-of-the-configuration-cascade-for-eps.md │ └── README.txt ├── infrastructure ├── deployment │ ├── .env.sample │ ├── Installation.md │ ├── certs │ │ ├── eps │ │ │ └── .keep │ │ └── nginx │ │ │ └── .keep │ ├── docker-compose-ext-postgres.yml │ ├── docker-compose.yml │ ├── docs │ │ ├── Architektur.md │ │ ├── Architektur.pdf │ │ ├── Beispiel-Bonn.png │ │ ├── Certificate-Process-Staging.md │ │ ├── Certificate-Process_Prod_organizational.md │ │ ├── Certificate-Process_Prod_technical.md │ │ ├── Installation-Docker-Compose.md │ │ ├── Installation.md │ │ ├── Smoketest.md │ │ ├── Upgrade-Guides.md │ │ ├── examples │ │ │ ├── Bonn-example-proxy.txt │ │ │ ├── Bonn-example.txt │ │ │ ├── Koeln-example-proxy.txt │ │ │ └── Koeln-example.txt │ │ ├── images │ │ │ ├── IRIS-C2-with-EPS.jpg │ │ │ ├── IRIS-Production-Certs-v2.jpg │ │ │ ├── IRIS-Production-Certs.jpg │ │ │ ├── certificate_service_manager │ │ │ │ ├── mycsm_Anmeldung.png │ │ │ │ ├── mycsm_Neues_Zertifikat.png │ │ │ │ ├── mycsm_Produkt_auswählen.png │ │ │ │ ├── mycsm_Produkt_auswählen_advanced_ssl.png │ │ │ │ ├── mycsm_Produkt_auswählen_advanced_ssl_webform.png │ │ │ │ ├── mycsm_Zertifikate.png │ │ │ │ ├── mycsm_Zertifikatsverwaltung.png │ │ │ │ ├── mycsm_basic_device_id_webform.png │ │ │ │ └── mycsm_Übersicht.png │ │ │ ├── smoketest │ │ │ │ ├── EventRequest.png │ │ │ │ ├── EventResponse.png │ │ │ │ ├── Login.png │ │ │ │ ├── NewEvent.png │ │ │ │ └── SearchResult.png │ │ │ └── support-information.png │ │ ├── iris-docker-installation.jpg │ │ ├── iris-local-installation.jpg │ │ └── sanitized-rki-name.md │ └── scripts │ │ ├── live │ │ ├── create-eps-cert.sh │ │ ├── create-fingerprint-from-cert.sh │ │ ├── create-proxy-eps-cert.sh │ │ ├── generate-rsa-key-pair.bat │ │ ├── generate-rsa-key-pair.sh │ │ └── generate-signature-key-pair.sh │ │ └── staging │ │ ├── create-csr-for-eps.sh │ │ └── create-csr-for-proxy.sh ├── dev │ ├── .env │ ├── docker-compose-watchtower.yml │ ├── docker-compose.yml │ ├── nginx │ │ └── iris-client.conf.template │ └── settings │ │ └── roles │ │ ├── ga-gotham │ │ └── settings.yml │ │ ├── hd-1 │ │ └── settings.yml │ │ ├── private-proxy-1 │ │ └── settings.yml │ │ ├── private-proxy-eps-1 │ │ └── settings.yml │ │ ├── private-proxy-eps-gotham │ │ └── settings.yml │ │ └── private-proxy-gotham │ │ └── settings.yml ├── docker │ ├── .gitignore │ ├── app-eps │ │ ├── .gitignore │ │ ├── Dockerfile │ │ ├── Readme.md │ │ ├── ca │ │ │ ├── prod │ │ │ │ ├── D-TRUST_Limited_Basic_Combined.pem │ │ │ │ ├── inter-r1.crt │ │ │ │ ├── inter-r2.crt │ │ │ │ ├── root-x1.crt │ │ │ │ └── root-x2.crt │ │ │ └── test │ │ │ │ ├── D-TRUST_Limited_Basic_Test_Combined.pem │ │ │ │ └── IRIS-CA-Staging.crt │ │ └── conf │ │ │ └── roles │ │ │ ├── prod │ │ │ └── app │ │ │ │ └── settings.yml │ │ │ └── test │ │ │ └── app │ │ │ └── settings.yml │ ├── iris-client-eps │ │ ├── Dockerfile │ │ ├── ca │ │ │ ├── live │ │ │ │ ├── D-TRUST_Limited_Basic_Combined.pem │ │ │ │ ├── inter-r1.crt │ │ │ │ ├── inter-r2.crt │ │ │ │ ├── root-x1.crt │ │ │ │ └── root-x2.crt │ │ │ └── staging │ │ │ │ ├── D-TRUST_Limited_Basic_Test_Combined.pem │ │ │ │ └── IRIS-CA-Staging.crt │ │ └── conf │ │ │ └── roles │ │ │ ├── live │ │ │ ├── hd │ │ │ │ └── 001_default.yml │ │ │ └── private-proxy-eps │ │ │ │ └── 001_default.yml │ │ │ └── staging │ │ │ ├── hd │ │ │ └── 001_default.yml │ │ │ └── private-proxy-eps │ │ │ └── 001_default.yml │ ├── iris-client-proxy │ │ ├── Dockerfile │ │ ├── ca │ │ │ ├── live │ │ │ │ ├── D-TRUST_Limited_Basic_Combined.pem │ │ │ │ ├── inter-r1.crt │ │ │ │ ├── inter-r2.crt │ │ │ │ ├── root-x1.crt │ │ │ │ └── root-x2.crt │ │ │ └── staging │ │ │ │ ├── D-TRUST_Limited_Basic_Test_Combined.pem │ │ │ │ └── IRIS-CA-Staging.crt │ │ └── conf │ │ │ └── roles │ │ │ ├── live │ │ │ └── private-proxy │ │ │ │ └── 001_default.yml │ │ │ └── staging │ │ │ └── private-proxy │ │ │ └── 001_default.yml │ └── nginx │ │ ├── Dockerfile │ │ └── config │ │ └── templates │ │ └── iris-client.conf.template ├── ide │ ├── eclipse-code-formatter.xml │ └── eclipse.importorder └── stand-alone-deployment │ ├── .env.sample │ ├── .gitignore │ ├── README.md │ ├── bin │ └── .keep │ ├── ca │ ├── live │ │ ├── D-TRUST_Limited_Basic_Combined.pem │ │ ├── inter-r1.crt │ │ ├── inter-r2.crt │ │ ├── root-x1.crt │ │ └── root-x2.crt │ └── staging │ │ ├── D-TRUST_Limited_Basic_Test_Combined.pem │ │ └── IRIS-CA-Staging.crt │ ├── conf │ ├── eps │ │ ├── certs │ │ │ └── .keep │ │ └── roles │ │ │ ├── live │ │ │ ├── hd │ │ │ │ └── 001_default.yml │ │ │ └── private-proxy-eps │ │ │ │ └── 001_default.yml │ │ │ └── staging │ │ │ ├── hd │ │ │ └── 001_default.yml │ │ │ └── private-proxy-eps │ │ │ └── 001_default.yml │ ├── nginx │ │ ├── .keep │ │ ├── mime.types │ │ └── nginx.conf │ └── proxy │ │ ├── certs │ │ └── .keep │ │ └── roles │ │ ├── live │ │ └── private-proxy │ │ │ └── 001_default.yml │ │ └── staging │ │ └── private-proxy │ │ └── 001_default.yml │ ├── db │ └── .keep │ ├── public │ └── .keep │ └── scripts │ ├── import-root-cert.sh │ ├── start-eps.sh │ ├── start-iris-client-bff.sh │ ├── start-private-proxy-eps.sh │ └── start-private-proxy.sh ├── iris-client-bff ├── .mvn │ └── wrapper │ │ ├── MavenWrapperDownloader.java │ │ └── maven-wrapper.properties ├── Readme.md ├── bindings │ └── ca-certificates │ │ ├── D-TRUST_Limited_Basic_Intermediate.pem │ │ ├── D-TRUST_Limited_Basic_Root.pem │ │ ├── D-TRUST_Limited_Basic_Test_Intermediate.pem │ │ ├── D-TRUST_Limited_Basic_Test_Root.pem │ │ ├── IRIS-CA-Staging.crt │ │ ├── inter-r1.crt │ │ ├── inter-r2.crt │ │ ├── root-x1.crt │ │ ├── root-x2.crt │ │ └── type ├── lombok.config ├── mvnw ├── mvnw.cmd ├── pom.xml ├── postman │ ├── IRIS Client BFF.postman_collection.json │ └── IRIS localhost.postman_environment.json └── src │ ├── main │ ├── java │ │ └── iris │ │ │ ├── client_bff │ │ │ ├── IrisClientBffApplication.java │ │ │ ├── auth │ │ │ │ └── db │ │ │ │ │ ├── AuthenticationStatus.java │ │ │ │ │ ├── DbAuthSecurityConfig.java │ │ │ │ │ ├── InitialAdminLoader.java │ │ │ │ │ ├── JwtAuthenticationToken.java │ │ │ │ │ ├── MfAuthenticationProperties.java │ │ │ │ │ ├── OtpAuthenticationProvider.java │ │ │ │ │ ├── OtpAuthenticationToken.java │ │ │ │ │ ├── RefreshTokenException.java │ │ │ │ │ ├── UserEventListener.java │ │ │ │ │ ├── jwt │ │ │ │ │ ├── AllowedToken.java │ │ │ │ │ ├── AllowedTokenRepository.java │ │ │ │ │ ├── JWTService.java │ │ │ │ │ ├── JWTWhitelistCleanup.java │ │ │ │ │ └── JwtConstants.java │ │ │ │ │ ├── login_attempts │ │ │ │ │ ├── AuthenticationFailureListener.java │ │ │ │ │ ├── AuthenticationSuccessEventListener.java │ │ │ │ │ ├── LoginAttempts.java │ │ │ │ │ ├── LoginAttemptsRepository.java │ │ │ │ │ └── LoginAttemptsService.java │ │ │ │ │ └── web │ │ │ │ │ ├── AuthenticationController.java │ │ │ │ │ └── MfAuthenticationConfigController.java │ │ │ ├── cases │ │ │ │ ├── CaseDataRequest.java │ │ │ │ ├── CaseDataRequestRepository.java │ │ │ │ ├── CaseDataRequestService.java │ │ │ │ ├── CaseDataSubmissionMapper.java │ │ │ │ ├── CaseDataSubmissionRepository.java │ │ │ │ ├── CaseDataSubmissionService.java │ │ │ │ ├── CaseDeleteJob.java │ │ │ │ ├── CaseEmail.java │ │ │ │ ├── CaseEmailProvider.java │ │ │ │ ├── CaseToUserReferenceChecker.java │ │ │ │ ├── eps │ │ │ │ │ ├── CaseDataController.java │ │ │ │ │ ├── CaseDataControllerImpl.java │ │ │ │ │ └── dto │ │ │ │ │ │ ├── CaseDataProvider.java │ │ │ │ │ │ ├── ContactCategory.java │ │ │ │ │ │ ├── ContactInformation.java │ │ │ │ │ │ ├── ContactPerson.java │ │ │ │ │ │ ├── Contacts.java │ │ │ │ │ │ ├── Event.java │ │ │ │ │ │ ├── Events.java │ │ │ │ │ │ └── WorkPlace.java │ │ │ │ ├── model │ │ │ │ │ ├── CaseDataProvider.java │ │ │ │ │ ├── CaseDataSubmission.java │ │ │ │ │ ├── CaseEvent.java │ │ │ │ │ └── Contact.java │ │ │ │ └── web │ │ │ │ │ ├── CaseDataRequestController.java │ │ │ │ │ ├── IndexCaseMapper.java │ │ │ │ │ ├── request_dto │ │ │ │ │ ├── IndexCaseDTO.java │ │ │ │ │ ├── IndexCaseDetailsDTO.java │ │ │ │ │ ├── IndexCaseInsertDTO.java │ │ │ │ │ ├── IndexCaseStatusDTO.java │ │ │ │ │ └── IndexCaseUpdateDTO.java │ │ │ │ │ └── submission_dto │ │ │ │ │ ├── ContactCategory.java │ │ │ │ │ ├── ContactPerson.java │ │ │ │ │ ├── ContactPersonAllOfContactInformation.java │ │ │ │ │ ├── ContactPersonAllOfWorkPlace.java │ │ │ │ │ ├── ContactPersonList.java │ │ │ │ │ ├── ContactsAndEvents.java │ │ │ │ │ ├── ContactsAndEventsDataProvider.java │ │ │ │ │ ├── Event.java │ │ │ │ │ └── EventList.java │ │ │ ├── config │ │ │ │ ├── BackendServiceProperties.java │ │ │ │ ├── BaseConfig.java │ │ │ │ ├── CORSConfig.java │ │ │ │ ├── CentralConfigurationService.java │ │ │ │ ├── DataSubmissionConfig.java │ │ │ │ ├── DictionaryProperties.java │ │ │ │ ├── EmailConfig.java │ │ │ │ ├── FlywayConfig.java │ │ │ │ ├── HibernateSearchConfig.java │ │ │ │ ├── HttpTraceConfig.java │ │ │ │ ├── I18nProperties.java │ │ │ │ ├── JacksonConfig.java │ │ │ │ ├── LocaleConfig.java │ │ │ │ ├── MapStructCentralConfig.java │ │ │ │ ├── MethodSecurityConfig.java │ │ │ │ ├── ProxyServiceProperties.java │ │ │ │ ├── RPCClientConfig.java │ │ │ │ ├── RPCClientProperties.java │ │ │ │ ├── SchedulingConfig.java │ │ │ │ ├── SecurityConfig.java │ │ │ │ ├── SpringAsyncConfig.java │ │ │ │ ├── SuspiciouslyCaseRequestProperties.java │ │ │ │ ├── SuspiciouslyEventRequestProperties.java │ │ │ │ └── ValidationConfig.java │ │ │ ├── core │ │ │ │ ├── alert │ │ │ │ │ ├── AlertDto.java │ │ │ │ │ ├── AlertListDto.java │ │ │ │ │ └── AlertService.java │ │ │ │ ├── api │ │ │ │ │ ├── dto │ │ │ │ │ │ ├── Address.java │ │ │ │ │ │ ├── AddressWithDefuseData.java │ │ │ │ │ │ ├── Person.java │ │ │ │ │ │ └── PersonWithDefuseData.java │ │ │ │ │ ├── filter │ │ │ │ │ │ ├── ApplicationRequestSizeLimitFilter.java │ │ │ │ │ │ └── SuspiciouslyRequestProperties.java │ │ │ │ │ └── web │ │ │ │ │ │ └── error │ │ │ │ │ │ ├── GlobalControllerExceptionHandler.java │ │ │ │ │ │ ├── GlobalFilterExceptionHandler.java │ │ │ │ │ │ └── IrisErrorAttributes.java │ │ │ │ ├── converters │ │ │ │ │ ├── IdWithUuidToPrimitivesConverter.java │ │ │ │ │ └── PrimitivesToIdWithUuidConverter.java │ │ │ │ ├── database │ │ │ │ │ ├── HibernateSearcher.java │ │ │ │ │ └── IrisDateTimeProvider.java │ │ │ │ ├── health │ │ │ │ │ ├── LocationServiceHealthIndicator.java │ │ │ │ │ └── StatusDeserializer.java │ │ │ │ ├── log │ │ │ │ │ ├── LogHelper.java │ │ │ │ │ └── RequestResponseLoggingInterceptor.java │ │ │ │ ├── mail │ │ │ │ │ ├── EmailProvider.java │ │ │ │ │ ├── EmailSender.java │ │ │ │ │ ├── EmailSenderDummy.java │ │ │ │ │ ├── EmailSenderReal.java │ │ │ │ │ ├── EmailTemplates.java │ │ │ │ │ └── support │ │ │ │ │ │ ├── GreenMailEmailServer.java │ │ │ │ │ │ └── GreenMailSSLSocketFactory.java │ │ │ │ ├── mappers │ │ │ │ │ └── MetadataMapper.java │ │ │ │ ├── messages │ │ │ │ │ └── ErrorMessages.java │ │ │ │ ├── model │ │ │ │ │ ├── Address.java │ │ │ │ │ ├── Aggregate.java │ │ │ │ │ ├── AggregateRepository.java │ │ │ │ │ ├── EmailAddress.java │ │ │ │ │ ├── Id.java │ │ │ │ │ ├── IdWithUuid.java │ │ │ │ │ ├── Metadata.java │ │ │ │ │ ├── PhoneNumber.java │ │ │ │ │ ├── Sex.java │ │ │ │ │ └── package-info.java │ │ │ │ ├── serialization │ │ │ │ │ ├── DefuseJsonString.java │ │ │ │ │ └── FlexibleEnum.java │ │ │ │ ├── setting │ │ │ │ │ ├── Setting.java │ │ │ │ │ └── SettingsRepository.java │ │ │ │ ├── sync │ │ │ │ │ ├── SyncTimes.java │ │ │ │ │ └── SyncTimesRepository.java │ │ │ │ ├── token │ │ │ │ │ ├── Dictionary.java │ │ │ │ │ ├── IdentifierToken.java │ │ │ │ │ └── TokenGenerator.java │ │ │ │ └── validation │ │ │ │ │ ├── AttackDetector.java │ │ │ │ │ ├── Base64.java │ │ │ │ │ ├── NoSignOfAttack.java │ │ │ │ │ ├── PhoneNumber.java │ │ │ │ │ ├── ValidPassword.java │ │ │ │ │ └── ValidatedProperties.java │ │ │ ├── events │ │ │ │ ├── EventDataRequest.java │ │ │ │ ├── EventDataRequestRepository.java │ │ │ │ ├── EventDataRequestService.java │ │ │ │ ├── EventDataSubmissionRepository.java │ │ │ │ ├── EventDataSubmissionService.java │ │ │ │ ├── EventDeleteJob.java │ │ │ │ ├── EventEmail.java │ │ │ │ ├── EventEmailProvider.java │ │ │ │ ├── EventMapper.java │ │ │ │ ├── EventToUserReferenceChecker.java │ │ │ │ ├── LocationMapper.java │ │ │ │ ├── eps │ │ │ │ │ ├── DataProviderClient.java │ │ │ │ │ ├── EPSDataProviderClient.java │ │ │ │ │ ├── EventDataController.java │ │ │ │ │ ├── EventDataControllerImpl.java │ │ │ │ │ └── JsonRpcClientDto.java │ │ │ │ ├── exceptions │ │ │ │ │ └── IRISDataRequestException.java │ │ │ │ ├── message │ │ │ │ │ ├── EventMessageDataBuilder.java │ │ │ │ │ ├── EventMessageDataPayload.java │ │ │ │ │ ├── EventMessageDataProcessor.java │ │ │ │ │ └── dto │ │ │ │ │ │ ├── ExportSelectionDto.java │ │ │ │ │ │ ├── ImportSelectionDto.java │ │ │ │ │ │ └── ImportSelectionViewPayloadDto.java │ │ │ │ ├── model │ │ │ │ │ ├── AttendanceInformation.java │ │ │ │ │ ├── EventDataSubmission.java │ │ │ │ │ ├── Guest.java │ │ │ │ │ ├── GuestListDataProvider.java │ │ │ │ │ └── Location.java │ │ │ │ └── web │ │ │ │ │ ├── EventDataRequestController.java │ │ │ │ │ └── dto │ │ │ │ │ ├── DataRequestClient.java │ │ │ │ │ ├── DataRequestDetails.java │ │ │ │ │ ├── EventStatusDTO.java │ │ │ │ │ ├── EventUpdateDTO.java │ │ │ │ │ ├── ExistingDataRequestClientWithLocation.java │ │ │ │ │ ├── ExistingDataRequestClientWithLocationList.java │ │ │ │ │ ├── Guest.java │ │ │ │ │ ├── GuestAttendanceInformation.java │ │ │ │ │ ├── GuestList.java │ │ │ │ │ ├── GuestListDataProvider.java │ │ │ │ │ ├── LocationAddress.java │ │ │ │ │ ├── LocationContact.java │ │ │ │ │ ├── LocationContext.java │ │ │ │ │ └── LocationInformation.java │ │ │ ├── feedback │ │ │ │ ├── FeedbackEndpointConnector.java │ │ │ │ ├── FeedbackOutputDto.java │ │ │ │ ├── FeedbackResponseDto.java │ │ │ │ ├── FeedbackSendingException.java │ │ │ │ └── web │ │ │ │ │ ├── FeedbackInputDto.java │ │ │ │ │ └── FeedbackRestAPI.java │ │ │ ├── hd_search │ │ │ │ ├── HdSearchException.java │ │ │ │ ├── HealthDepartment.java │ │ │ │ └── eps │ │ │ │ │ └── EPSHdSearchClient.java │ │ │ ├── iris_messages │ │ │ │ ├── IrisMessage.java │ │ │ │ ├── IrisMessageContext.java │ │ │ │ ├── IrisMessageData.java │ │ │ │ ├── IrisMessageDataProcessor.java │ │ │ │ ├── IrisMessageDataProcessors.java │ │ │ │ ├── IrisMessageDataRepository.java │ │ │ │ ├── IrisMessageDataService.java │ │ │ │ ├── IrisMessageDeleteJob.java │ │ │ │ ├── IrisMessageFolder.java │ │ │ │ ├── IrisMessageFolderInitializer.java │ │ │ │ ├── IrisMessageFolderRepository.java │ │ │ │ ├── IrisMessageHdContact.java │ │ │ │ ├── IrisMessageRepository.java │ │ │ │ ├── IrisMessageService.java │ │ │ │ ├── IrisMessageToUserReferenceChecker.java │ │ │ │ ├── eps │ │ │ │ │ ├── EPSIrisMessageClient.java │ │ │ │ │ ├── IrisMessageBuilderEps.java │ │ │ │ │ ├── IrisMessageDataController.java │ │ │ │ │ ├── IrisMessageDataControllerImpl.java │ │ │ │ │ └── IrisMessageTransferDto.java │ │ │ │ ├── exceptions │ │ │ │ │ ├── IrisMessageDataException.java │ │ │ │ │ └── IrisMessageException.java │ │ │ │ ├── utils │ │ │ │ │ ├── IrisMessageDataUtils.java │ │ │ │ │ └── RawJsonDeserializer.java │ │ │ │ └── web │ │ │ │ │ ├── IrisMessageBuilderWeb.java │ │ │ │ │ ├── IrisMessageController.java │ │ │ │ │ ├── IrisMessageDataAttachmentCountDto.java │ │ │ │ │ ├── IrisMessageDataController.java │ │ │ │ │ ├── IrisMessageDataViewDataDto.java │ │ │ │ │ ├── IrisMessageDataViewProvider.java │ │ │ │ │ ├── IrisMessageDetailsDto.java │ │ │ │ │ ├── IrisMessageFolderDto.java │ │ │ │ │ ├── IrisMessageInsertDto.java │ │ │ │ │ ├── IrisMessageListItemDto.java │ │ │ │ │ └── IrisMessageUpdateDto.java │ │ │ ├── proxy │ │ │ │ ├── EPSProxyServiceServiceClient.java │ │ │ │ ├── IRISAnnouncementException.java │ │ │ │ └── ProxyServiceClient.java │ │ │ ├── search_client │ │ │ │ ├── SearchClient.java │ │ │ │ ├── eps │ │ │ │ │ ├── EPSSearchClient.java │ │ │ │ │ └── dto │ │ │ │ │ │ ├── IdSearch.java │ │ │ │ │ │ ├── KeywordSearch.java │ │ │ │ │ │ └── PageableDto.java │ │ │ │ ├── exceptions │ │ │ │ │ └── IRISSearchException.java │ │ │ │ └── web │ │ │ │ │ ├── LocationSearchController.java │ │ │ │ │ └── dto │ │ │ │ │ ├── LocationAddress.java │ │ │ │ │ ├── LocationContact.java │ │ │ │ │ ├── LocationContext.java │ │ │ │ │ ├── LocationInformation.java │ │ │ │ │ └── LocationQueryResult.java │ │ │ ├── statistics │ │ │ │ └── web │ │ │ │ │ ├── StatisticsController.java │ │ │ │ │ └── dto │ │ │ │ │ └── StatisticsDTO.java │ │ │ ├── status │ │ │ │ ├── AppInfo.java │ │ │ │ ├── AppStatus.java │ │ │ │ ├── AppStatusException.java │ │ │ │ ├── AppStatusInternalException.java │ │ │ │ ├── Apps.java │ │ │ │ ├── EpsConnectionException.java │ │ │ │ ├── StatusService.java │ │ │ │ ├── eps │ │ │ │ │ └── EPSStatusClient.java │ │ │ │ └── web │ │ │ │ │ └── AppStatusController.java │ │ │ ├── users │ │ │ │ ├── AuthenticatedUserAware.java │ │ │ │ ├── IrisAuditorAware.java │ │ │ │ ├── UserAccount.java │ │ │ │ ├── UserAccountsRepository.java │ │ │ │ ├── UserAnonymizationJob.java │ │ │ │ ├── UserAnonymizationReferenceChecker.java │ │ │ │ ├── UserRole.java │ │ │ │ ├── UserService.java │ │ │ │ ├── package-info.java │ │ │ │ └── web │ │ │ │ │ ├── UserController.java │ │ │ │ │ ├── UserDtos.java │ │ │ │ │ ├── UserMapper.java │ │ │ │ │ └── UserProfileController.java │ │ │ └── vaccination_info │ │ │ │ ├── EncryptionService.java │ │ │ │ ├── VaccinationInfo.java │ │ │ │ ├── VaccinationInfoAnnouncement.java │ │ │ │ ├── VaccinationInfoAnnouncementDeleteJob.java │ │ │ │ ├── VaccinationInfoAnnouncementException.java │ │ │ │ ├── VaccinationInfoAnnouncementRepository.java │ │ │ │ ├── VaccinationInfoDeleteJob.java │ │ │ │ ├── VaccinationInfoRepository.java │ │ │ │ ├── VaccinationInfoService.java │ │ │ │ ├── VaccinationInfoToUserReferenceChecker.java │ │ │ │ ├── VaccinationStatus.java │ │ │ │ ├── VaccinationType.java │ │ │ │ ├── eps │ │ │ │ ├── InvalidPublicKeyException.java │ │ │ │ ├── VaccinationInfoController.java │ │ │ │ └── VaccinationInfoControllerImpl.java │ │ │ │ ├── message │ │ │ │ ├── VaccinationMessageDataMapper.java │ │ │ │ ├── VaccinationMessageDataPayload.java │ │ │ │ ├── VaccinationMessageDataProcessor.java │ │ │ │ └── dto │ │ │ │ │ ├── ExportSelectionDto.java │ │ │ │ │ ├── ImportSelectionDto.java │ │ │ │ │ └── ImportSelectionViewPayloadDto.java │ │ │ │ └── web │ │ │ │ ├── VaccinationInfoController.java │ │ │ │ └── VaccinationInfoDto.java │ │ │ └── tools │ │ │ └── HealthChecker.java │ └── resources │ │ ├── .gitignore │ │ ├── META-INF │ │ └── spring-devtools.properties │ │ ├── application-dev_auth.properties │ │ ├── application-dev_env.properties │ │ ├── application-h2_db.properties │ │ ├── application-mariadb.properties │ │ ├── application-mssql.properties │ │ ├── application-mysql.properties │ │ ├── application-prod_auth.properties │ │ ├── application-prod_db.properties │ │ ├── application-prod_env.properties │ │ ├── application-psql_compose_db.properties │ │ ├── application-stage_live.properties │ │ ├── application-stage_staging.properties │ │ ├── application.properties │ │ ├── db │ │ ├── migration │ │ │ ├── V1001__Initial_schema.sql │ │ │ ├── V1002__introduce_announcements.sql │ │ │ ├── V1003__introduce_allowed_tokens.sql │ │ │ ├── V1004__add_cases.sql │ │ │ ├── V1005__add_login_attempts.sql │ │ │ ├── V1006__login_attempts_rename_column.sql │ │ │ ├── V1007__readable_token_for_cases.sql │ │ │ ├── V1008__add_audit_metadata.sql │ │ │ ├── V1009__add_iris_messages.sql │ │ │ ├── V1010__add_vaccination_info_announcement.sql │ │ │ ├── V1011__add_vaccination_info.sql │ │ │ ├── V1012__add_iris_message_data.sql │ │ │ ├── V1013__extends_user_account.sql │ │ │ ├── V1014__add_settings.sql │ │ │ └── V1015__add_mfa.sql │ │ ├── migration_mssql │ │ │ ├── V1001__Initial_schema.sql │ │ │ ├── V1002__introduce_announcements.sql │ │ │ ├── V1003__introduce_allowed_tokens.sql │ │ │ ├── V1004__add_cases.sql │ │ │ ├── V1005__add_login_attempts.sql │ │ │ ├── V1007__readable_token_for_cases.sql │ │ │ ├── V1008__add_audit_metadata.sql │ │ │ ├── V1009__add_iris_messages.sql │ │ │ ├── V1010__add_vaccination_info_announcement.sql │ │ │ ├── V1011__add_vaccination_info.sql │ │ │ ├── V1012__add_iris_message_data.sql │ │ │ ├── V1013__extends_user_account.sql │ │ │ ├── V1014__add_settings.sql │ │ │ └── V1015__add_mfa.sql │ │ └── migration_mysql │ │ │ ├── V1001__Initial_schema.sql │ │ │ ├── V1002__introduce_announcements.sql │ │ │ ├── V1003__introduce_allowed_tokens.sql │ │ │ ├── V1004__add_cases.sql │ │ │ ├── V1005__add_login_attempts.sql │ │ │ ├── V1007__readable_token_for_cases.sql │ │ │ ├── V1008__add_audit_metadata.sql │ │ │ ├── V1009__add_iris_messages.sql │ │ │ ├── V1010__add_vaccination_info_announcement.sql │ │ │ ├── V1011__add_vaccination_info.sql │ │ │ ├── V1012__add_iris_message_data.sql │ │ │ ├── V1013__extends_user_account.sql │ │ │ ├── V1014__add_settings.sql │ │ │ └── V1015__add_mfa.sql │ │ ├── dict │ │ └── deutsch.txt │ │ ├── iris-banner.txt │ │ ├── logback-spring.xml │ │ ├── mail-templates │ │ ├── case-data-received-mail.ftlh │ │ ├── case-data-received-mail_de.ftlh │ │ ├── case-data-received-mail_en.ftlh │ │ ├── event-data-received-mail.ftlh │ │ ├── event-data-received-mail_de.ftlh │ │ └── event-data-received-mail_en.ftlh │ │ ├── messages.properties │ │ ├── messages_de.properties │ │ └── messages_en.properties │ └── test │ ├── java │ └── iris │ │ └── client_bff │ │ ├── DataInitializer.java │ │ ├── DataInitializerInvoker.java │ │ ├── FakerConfig.java │ │ ├── IrisMapperTest.java │ │ ├── IrisWebIntegrationTest.java │ │ ├── IrisWireMockTest.java │ │ ├── MemoryAppender.java │ │ ├── RestResponsePage.java │ │ ├── WithMockAdmin.java │ │ ├── WithMockIrisUser.java │ │ ├── auth │ │ └── db │ │ │ ├── CsrfConfigIntegrationTest.java │ │ │ ├── InitialAdminLoaderTest.java │ │ │ ├── LoginAttemptsTests.java │ │ │ ├── MfAuthenticationIntegrationTest.java │ │ │ └── RefreshTokenIntegrationTest.java │ │ ├── cases │ │ ├── CaseDataRequestDataInitializer.java │ │ ├── CaseDataRequestServiceTest.java │ │ ├── CaseDataSubmissionsDataInitializer.java │ │ ├── CaseDeleteJobIntegrationTests.java │ │ ├── CaseEmailProviderTest.java │ │ ├── DtoSupplier.java │ │ ├── rpc │ │ │ └── CaseDataControllerIntegrationTest.java │ │ └── web │ │ │ ├── IndexCaseControllerTest.java │ │ │ └── IndexCaseMapperTest.java │ │ ├── config │ │ ├── EmailConfigTests.java │ │ └── JacksonIntegrationTests.java │ │ ├── core │ │ ├── DummyJsonRpcClient.java │ │ ├── alert │ │ │ └── AlertServiceTests.java │ │ ├── api │ │ │ └── web │ │ │ │ └── error │ │ │ │ ├── GlobalControllerExceptionHandlerIntegrationTest.java │ │ │ │ └── TestController.java │ │ ├── converters │ │ │ └── IdWithUuidPrimitivesConverterIntegrationTests.java │ │ ├── extensions │ │ │ └── ValidatorExtension.java │ │ ├── mail │ │ │ ├── EmailSenderIntegrationTests.java │ │ │ └── TestEmailServer.java │ │ ├── model │ │ │ └── MetadataUtil.java │ │ └── validation │ │ │ ├── Base64Tests.java │ │ │ ├── NoSignOfAttackTests.java │ │ │ ├── PhoneNumberTests.java │ │ │ └── ValidPasswordTests.java │ │ ├── dbms │ │ ├── DatabasesystemIT.java │ │ ├── MSSQLServerIT.java │ │ ├── MariaDBIT.java │ │ ├── MySQLIT.java │ │ └── PostgresIT.java │ │ ├── events │ │ ├── EventDataRequestServiceTest.java │ │ ├── EventDataRequestsDataInitializer.java │ │ ├── EventDataSubmissionsDataInitializer.java │ │ ├── EventDeleteJobIntegrationTests.java │ │ ├── EventEmailProviderTest.java │ │ ├── LocationRepository.java │ │ ├── message │ │ │ ├── EventMessageDataProcessorTest.java │ │ │ └── EventMessageTestData.java │ │ ├── rpc │ │ │ └── EventDataControllerIntegrationTest.java │ │ └── web │ │ │ ├── EventDataRequestControllerTest.java │ │ │ └── TestData.java │ │ ├── iris_messages │ │ ├── IrisMessageDataInitializer.java │ │ ├── IrisMessageDataServiceTest.java │ │ ├── IrisMessageDataTestData.java │ │ ├── IrisMessageDeleteJobIntegrationTests.java │ │ ├── IrisMessageServiceTest.java │ │ ├── IrisMessageTestData.java │ │ ├── eps │ │ │ ├── IrisMessageBuilderEpsTest.java │ │ │ └── IrisMessageDataControllerTest.java │ │ └── web │ │ │ ├── IrisMessageBuilderWebTest.java │ │ │ ├── IrisMessageControllerIntegrationTest.java │ │ │ ├── IrisMessageControllerTest.java │ │ │ ├── IrisMessageDataControllerTest.java │ │ │ └── IrisMessageDataViewProviderTest.java │ │ ├── matchers │ │ ├── IrisMatchers.java │ │ └── IsUuid.java │ │ ├── search_client │ │ ├── eps │ │ │ └── EPSSearchClientTests.java │ │ └── web │ │ │ └── LocationSearchControllerTests.java │ │ ├── statistics │ │ └── web │ │ │ └── StatisticsControllerTest.java │ │ ├── status │ │ └── web │ │ │ └── AppStatusControllerTest.java │ │ ├── users │ │ ├── UserAccountsRepositoryForTests.java │ │ ├── UserAnonymizationJobIntegrationTests.java │ │ ├── UserAnonymizationJobTestBase.java │ │ ├── UserAnonymizationJobTimeBasedIntegrationTests.java │ │ ├── UserServiceTests.java │ │ └── web │ │ │ ├── UserControllerIntegrationTests.java │ │ │ ├── UserControllerTests.java │ │ │ ├── UserDtoMappingTests.java │ │ │ └── UsersTestData.java │ │ ├── vaccination_info │ │ ├── EncryptionServiceTests.java │ │ ├── VaccinationInfoAnnouncementDeleteJobIntegrationTests.java │ │ ├── VaccinationInfoDataInitializer.java │ │ ├── VaccinationInfoDeleteJobIntegrationTests.java │ │ ├── eps │ │ │ ├── VaccinationInfoAnnouncmentTestData.java │ │ │ ├── VaccinationInfoControllerImplIntegrationTests.java │ │ │ └── VaccinationInfoSubmissionTestData.java │ │ ├── message │ │ │ ├── VaccinationMessageDataProcessorTest.java │ │ │ └── VaccinationMessageTestData.java │ │ └── web │ │ │ └── VaccinationInfoControllerIntegrationTest.java │ │ └── web │ │ └── filter │ │ └── ApplicationRequestSizeLimitFilterTests.java │ └── resources │ ├── container-license-acceptance.txt │ ├── mail-templates │ ├── test-html-mail_de.ftlh │ ├── test-mail.ftl │ └── test-mail_de.ftl │ ├── messages.properties │ └── messages_de_DE_test.properties ├── iris-client-eps └── README.md ├── iris-client-fe ├── .browserslistrc ├── .env.bff_local ├── .env.development ├── .env.e2e_test ├── .env.e2e_test_local.dist ├── .env.integration ├── .env.production ├── .eslintrc.js ├── .gitignore ├── .nvmrc ├── Caddyfile ├── Dockerfile ├── README.md ├── autosave.json ├── babel.config.js ├── cypress.config.ts ├── cypress.env.json.dist ├── docs │ └── RESOURCES.md ├── jest.config.js ├── package-lock.json ├── package.json ├── public │ ├── android-chrome-96x96.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── favicon.svg │ ├── index.html │ ├── mstile-150x150.png │ └── robots.txt ├── src │ ├── App.vue │ ├── api-client.ts │ ├── api │ │ ├── api.ts │ │ ├── base.ts │ │ ├── common.ts │ │ └── index.ts │ ├── assets │ │ ├── images │ │ │ ├── sketch_file_analysis.svg │ │ │ ├── sketch_group.svg │ │ │ ├── sketch_group2.svg │ │ │ ├── sketch_medicine.svg │ │ │ └── sketch_reviewed_docs.svg │ │ ├── logo-bss.svg │ │ ├── logo-inoeg.svg │ │ ├── logo-iris-connect.png │ │ └── scss │ │ │ ├── base │ │ │ └── _global.scss │ │ │ ├── modules │ │ │ ├── _card.scss │ │ │ ├── _stepper.scss │ │ │ ├── _table.scss │ │ │ └── _tabs.scss │ │ │ ├── theme.scss │ │ │ └── utilities │ │ │ ├── _mixins.scss │ │ │ └── _variables.scss │ ├── common │ │ ├── messages.ts │ │ ├── normalizer.ts │ │ └── validation-rules.ts │ ├── components │ │ ├── alerts │ │ │ └── alert-component.vue │ │ ├── app-settings-menu.vue │ │ ├── btn-toggle-select.vue │ │ ├── confirm-dialog.vue │ │ ├── dashboard │ │ │ ├── cases-bar-chart.vue │ │ │ ├── cases-pie-chart.vue │ │ │ └── counter-widget.vue │ │ ├── data-export │ │ │ ├── data-export-dialog.vue │ │ │ └── data-export-label.vue │ │ ├── data-table-item-status.vue │ │ ├── data-table-select-all.vue │ │ ├── data-tree │ │ │ └── data-tree.vue │ │ ├── entry-meta-data.vue │ │ ├── error-message-alert.vue │ │ ├── event-list.vue │ │ ├── expandable-data-table.vue │ │ ├── expanded-data-table-item.vue │ │ ├── form │ │ │ ├── date-input-field.vue │ │ │ ├── date-time-input-field.vue │ │ │ ├── editable-field.vue │ │ │ ├── password-input-field.vue │ │ │ ├── stepper-input-field.vue │ │ │ └── time-input-field.vue │ │ ├── info-grid.vue │ │ ├── iris-data-table.vue │ │ ├── pageable │ │ │ ├── data-query-handler.vue │ │ │ ├── search-field.vue │ │ │ └── status-select.vue │ │ ├── sortable-data-table.vue │ │ ├── stepper │ │ │ ├── vertical-stepper-step.vue │ │ │ └── vertical-stepper.vue │ │ └── vue-chart.vue │ ├── config.ts │ ├── constants │ │ ├── ContactCategories.ts │ │ ├── Discriminators.ts │ │ ├── Genders.ts │ │ ├── StatusColors.ts │ │ ├── StatusMessages.ts │ │ └── StatusTestLabel.ts │ ├── main.ts │ ├── mixins │ │ └── HistoryBack.ts │ ├── modules │ │ ├── e2e-tests │ │ │ └── e2e-tests.store.ts │ │ ├── event-tracking │ │ │ ├── modules │ │ │ │ └── message-data │ │ │ │ │ ├── components │ │ │ │ │ ├── select-event.vue │ │ │ │ │ ├── select-guests-data-table.vue │ │ │ │ │ └── select-guests.vue │ │ │ │ │ ├── event-tracking-message-data.export.vue │ │ │ │ │ ├── event-tracking-message-data.import.vue │ │ │ │ │ ├── event-tracking-message-data.preview.vue │ │ │ │ │ └── services │ │ │ │ │ ├── config.ts │ │ │ │ │ └── normalizer.ts │ │ │ └── services │ │ │ │ └── api.ts │ │ ├── iris-message │ │ │ ├── modules │ │ │ │ └── message-data │ │ │ │ │ └── components │ │ │ │ │ ├── iris-message-data-component.vue │ │ │ │ │ ├── iris-message-data-view.vue │ │ │ │ │ ├── multi-select-data-table.vue │ │ │ │ │ └── single-select-query-data-table.vue │ │ │ └── services │ │ │ │ └── api.ts │ │ ├── mfa │ │ │ ├── components │ │ │ │ ├── mfa-admin-user-fieldset.vue │ │ │ │ ├── mfa-admin-user-secret-reset.vue │ │ │ │ ├── mfa-enrollment.vue │ │ │ │ └── mfa-otp-form.vue │ │ │ └── services │ │ │ │ ├── api.ts │ │ │ │ └── normalizer.ts │ │ ├── mock-api │ │ │ └── mock-api.store.ts │ │ └── vaccination-report │ │ │ ├── components │ │ │ └── vaccination-status-chip.vue │ │ │ ├── modules │ │ │ └── message-data │ │ │ │ ├── components │ │ │ │ ├── select-employees-data-table.vue │ │ │ │ ├── select-employees.vue │ │ │ │ └── select-report.vue │ │ │ │ ├── services │ │ │ │ ├── normalizer.ts │ │ │ │ └── utils.ts │ │ │ │ ├── vaccination-report-message-data.export.vue │ │ │ │ ├── vaccination-report-message-data.import.vue │ │ │ │ └── vaccination-report-message-data.preview.vue │ │ │ ├── services │ │ │ ├── api.ts │ │ │ ├── constants.ts │ │ │ ├── mappedData.ts │ │ │ └── normalizer.ts │ │ │ └── views │ │ │ ├── details │ │ │ ├── components │ │ │ │ ├── vaccination-report-details.component.vue │ │ │ │ └── vaccination-report-facility-info.vue │ │ │ ├── modules │ │ │ │ └── data-export │ │ │ │ │ ├── components │ │ │ │ │ └── vaccination-report-data-export.vue │ │ │ │ │ └── services │ │ │ │ │ └── exportStandard.ts │ │ │ └── vaccination-report-details.view.vue │ │ │ └── list │ │ │ └── vaccination-report-list.view.vue │ ├── plugins │ │ └── vuetify.ts │ ├── router │ │ └── index.ts │ ├── server │ │ ├── data │ │ │ ├── data-requests-cases.ts │ │ │ ├── data-requests.ts │ │ │ ├── dummy-iris-messages.ts │ │ │ ├── dummy-locations.ts │ │ │ ├── dummy-userlist.ts │ │ │ ├── status-checkin-apps.ts │ │ │ └── vaccination-reports.ts │ │ ├── mockAPIServer.ts │ │ └── utils │ │ │ ├── date.ts │ │ │ └── pagination.ts │ ├── shims-config.d.ts │ ├── shims-tsx.d.ts │ ├── shims-vue.d.ts │ ├── shims-vuetify.d.ts │ ├── store │ │ ├── index.ts │ │ ├── store.config.ts │ │ └── types.ts │ ├── styles │ │ ├── theme.scss │ │ └── variables.scss │ ├── utils │ │ ├── address.ts │ │ ├── api.ts │ │ ├── appContext.ts │ │ ├── asyncAction.ts │ │ ├── axios.ts │ │ ├── data-export │ │ │ ├── common.ts │ │ │ ├── data-export.ts │ │ │ └── sanitization.ts │ │ ├── data.ts │ │ ├── date.ts │ │ ├── fileDownload.ts │ │ ├── misc.ts │ │ └── pagination.ts │ └── views │ │ ├── about │ │ └── about.view.vue │ │ ├── admin-user-create │ │ ├── admin-user-create.store.ts │ │ └── admin-user-create.view.vue │ │ ├── admin-user-edit │ │ ├── admin-user-edit.store.ts │ │ ├── admin-user-edit.view.vue │ │ └── components │ │ │ └── conditional-field.vue │ │ ├── admin-user-list │ │ ├── admin-user-list.data.ts │ │ ├── admin-user-list.store.ts │ │ ├── admin-user-list.view.vue │ │ └── components │ │ │ └── user-delete-button.vue │ │ ├── app-settings │ │ ├── chunk-loader.store.ts │ │ ├── index-tracking-settings.store.ts │ │ └── normalize-settings.store.ts │ │ ├── checkin-app-status-list │ │ ├── checkin-app-status-list.data.ts │ │ ├── checkin-app-status-list.store.ts │ │ ├── checkin-app-status-list.view.vue │ │ └── components │ │ │ └── checkin-app-status-indicator.vue │ │ ├── event-tracking-details │ │ ├── components │ │ │ ├── data-export │ │ │ │ ├── event-tracking-details-data-export.vue │ │ │ │ └── utils │ │ │ │ │ ├── exportOctoware.ts │ │ │ │ │ ├── exportSormasContactPersons.ts │ │ │ │ │ ├── exportSormasEventParticipants.ts │ │ │ │ │ └── exportStandard.ts │ │ │ ├── event-tracking-details-location-info.vue │ │ │ ├── event-tracking-details.component.vue │ │ │ └── event-tracking-status-change.vue │ │ ├── event-tracking-details.data.ts │ │ ├── event-tracking-details.view.vue │ │ └── utils │ │ │ └── mappedData.ts │ │ ├── event-tracking-form │ │ ├── components │ │ │ ├── data-provider-status-info.vue │ │ │ ├── event-tracking-form-location-info.vue │ │ │ └── location-select-dialog.vue │ │ ├── event-tracking-form.data.ts │ │ ├── event-tracking-form.store.ts │ │ └── event-tracking-form.view.vue │ │ ├── event-tracking-list │ │ ├── event-tracking-list.data.ts │ │ ├── event-tracking-list.view.vue │ │ └── utils │ │ │ └── mappeData.ts │ │ ├── home │ │ ├── Home.vue │ │ ├── home.data.ts │ │ └── home.store.ts │ │ ├── index-tracking-details │ │ ├── components │ │ │ ├── data-export │ │ │ │ └── utils │ │ │ │ │ ├── exportStandardContacts.ts │ │ │ │ │ └── exportStandardEvents.ts │ │ │ ├── index-tracking-submission-url-copy.vue │ │ │ └── index-tracking-submission-url.vue │ │ ├── index-tracking-details.data.ts │ │ ├── index-tracking-details.store.ts │ │ └── index-tracking-details.view.vue │ │ ├── index-tracking-form │ │ ├── index-tracking-form.data.ts │ │ ├── index-tracking-form.store.ts │ │ └── index-tracking-form.view.vue │ │ ├── index-tracking-list │ │ ├── index-tracking-list.data.ts │ │ ├── index-tracking-list.store.ts │ │ └── index-tracking-list.view.vue │ │ ├── iris-message-create │ │ ├── components │ │ │ ├── iris-message-data-export-dialog.vue │ │ │ ├── iris-message-data-select-dialog.vue │ │ │ └── iris-message-data-select-form.vue │ │ ├── iris-message-create.data.ts │ │ ├── iris-message-create.store.ts │ │ └── iris-message-create.view.vue │ │ ├── iris-message-details │ │ ├── components │ │ │ ├── iris-message-data-attachments.vue │ │ │ ├── iris-message-data-import-dialog.vue │ │ │ ├── iris-message-data-import-form.vue │ │ │ ├── iris-message-data-import-menu.vue │ │ │ └── iris-message-data-preview-dialog.vue │ │ ├── iris-message-details.data.ts │ │ └── iris-message-details.view.vue │ │ ├── iris-message-list │ │ ├── components │ │ │ ├── iris-message-data-table.vue │ │ │ ├── iris-message-folders-data-tree.vue │ │ │ └── iris-message-list-nav-link.vue │ │ ├── iris-message-list.data.ts │ │ └── iris-message-list.view.vue │ │ └── user-login │ │ ├── components │ │ ├── user-login-error.vue │ │ ├── user-login-form.vue │ │ └── user-menu.vue │ │ ├── user-login.data.ts │ │ ├── user-login.store.ts │ │ ├── user-login.view.vue │ │ └── utils │ │ └── store.ts ├── tests │ └── e2e │ │ ├── .eslintrc.js │ │ ├── specs │ │ ├── 000_prepare.js │ │ ├── 100_about.js │ │ ├── 101_app-bar.js │ │ ├── 102_checkin-apps-status.js │ │ ├── 103_dashboard.js │ │ ├── 104_events.js │ │ ├── 105_index-cases.js │ │ ├── 106_iris-messages.js │ │ ├── 107_login.js │ │ ├── 108_logout.js │ │ ├── 109_users.js │ │ ├── 110_vaccination-report.js │ │ ├── 111_iris-message-data.js │ │ ├── 999_cleanup.js │ │ └── all.cy.ts │ │ ├── support │ │ ├── commands.js │ │ ├── index.d.ts │ │ └── index.js │ │ └── tsconfig.json ├── tsconfig.json └── vue.config.js └── pom.xml /.clas/IRIS Gateway-Entity.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/.clas/IRIS Gateway-Entity.pdf -------------------------------------------------------------------------------- /.clas/IRIS Gateway-Individual.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/.clas/IRIS Gateway-Individual.pdf -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve IRIS 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Additional context** 27 | Add any other context about the problem here. 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for IRIS 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/publish-test-results.yml: -------------------------------------------------------------------------------- 1 | name: Publish Test Results 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | artifact: 7 | description: 'Name of the artifact' 8 | required: false 9 | type: string 10 | default: 'test-reports' 11 | 12 | jobs: 13 | publish-test-results: 14 | name: Download and Publish 15 | runs-on: ubuntu-latest 16 | 17 | # the previous job might be skipped, we don't need to run this job then 18 | if: success() || failure() 19 | 20 | steps: 21 | - name: Download Artifact 22 | uses: actions/download-artifact@v3 23 | with: 24 | name: ${{inputs.artifact}} 25 | path: reports 26 | 27 | - name: Publish Test Results 28 | uses: EnricoMi/publish-unit-test-result-action@v2 29 | with: 30 | files: reports/**/*.xml 31 | report_individual_runs: true 32 | check_run_annotations_branch: "*" -------------------------------------------------------------------------------- /.github/workflows/reuse-check.yml: -------------------------------------------------------------------------------- 1 | name: License analysis with REUSE 2 | 3 | on: 4 | push: 5 | branches: [ release ] 6 | pull_request: 7 | branches: [ main, release ] 8 | 9 | jobs: 10 | license-analysis: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout code 14 | uses: actions/checkout@v3 15 | 16 | - name: REUSE Compliance Check 17 | uses: fsfe/reuse-action@v1.1 -------------------------------------------------------------------------------- /.reuse/dep5: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: iris-client 3 | Upstream-Contact: IRIS Connect Team 4 | Source: https://github.com/iris-connect/iris-client 5 | 6 | Files: * 7 | # Copyright: $YEAR $NAME <$CONTACT> 8 | Copyright: 2021-present The IRIS Client Authors (see AUTHORS.md) 9 | License: AGPL-3.0-or-later 10 | 11 | # File from SORMAS with own license 12 | #Files: iris-client-bff/src/main/java/iris/client_bff/core/Base32.java 13 | #Copyright: Copyright © 2016-2018 Helmholtz-Zentrum für Infektionsforschung GmbH (HZI) 14 | #License: GPL-3.0-or-later 15 | 16 | # Files from Maven Wrapper with own license 17 | Files: **/MavenWrapperDownloader.java 18 | Copyright: Copyright 2007-present the original author or authors. 19 | License: Apache-2.0 20 | 21 | # From Swagger generated Code 22 | #Files: iris-sormas-api-client/** 23 | #Copyright: No Copyright 24 | #License: CC0-1.0 25 | -------------------------------------------------------------------------------- /.setup_dct.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # exit when any command fails 4 | set -e 5 | 6 | DCT_PATH=~/.docker/trust/private/ 7 | 8 | DCT_KEY_FILE="$DCT_PATH$DCT_PRIVATE_KEY_IDENTIFIER.key" 9 | 10 | mkdir -p "$DCT_PATH" 11 | 12 | echo "$DCT_PRIVATE_KEY" > "$DCT_KEY_FILE" 13 | 14 | chmod 600 "$DCT_KEY_FILE" 15 | 16 | export DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE="$DCT_PRIVATE_KEY_PASSPHRASE" 17 | export DOCKER_CONTENT_TRUST=1 18 | docker trust key load "$DCT_KEY_FILE" 19 | 20 | -------------------------------------------------------------------------------- /.trivyignore: -------------------------------------------------------------------------------- 1 | # EPS images must start with root to change the owner of the certificate files. The images switch to non-root at startup. 2 | DS002 3 | 4 | # Since Trivy 0.22.0 and the POM scan, an outdated version of junit:junit is regularly, but not always, flagged. It is unclear where this comes from. 5 | CVE-2020-15250 6 | -------------------------------------------------------------------------------- /AUTHORS.md: -------------------------------------------------------------------------------- 1 | # Authors 2 | 3 | This file lists all individual authors that have contributed significant code to this project. This does not necessarly list minor contributors, please refert to the git commit log for a full list of these. 4 | 5 | * Jens Kutzsche 6 | * Claudio Bianucci 7 | * Andreas Finke 8 | * Sebastian Wegener 9 | * Andreas Kausler 10 | * Nadine Schwingler 11 | * Tim Lusa 12 | * Fabio Aversente 13 | * Timo Bögner 14 | -------------------------------------------------------------------------------- /doc/adr/0001-record-architecture-decisions.md: -------------------------------------------------------------------------------- 1 | # 1. Record architecture decisions 2 | 3 | Date: 2022-01-05 4 | 5 | ## Status 6 | 7 | Accepted 8 | 9 | ## Context 10 | 11 | We need to record the architectural decisions made on this project and its subprojects. 12 | 13 | ## Decision 14 | 15 | We will use Architecture Decision Records, as [described by Michael Nygard](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions). 16 | 17 | ## Consequences 18 | 19 | See Michael Nygard's article, linked above. For a lightweight ADR toolset, see Nat Pryce's [adr-tools](https://github.com/npryce/adr-tools). 20 | -------------------------------------------------------------------------------- /doc/adr/README.txt: -------------------------------------------------------------------------------- 1 | German Artikle about ADR: https://www.heise.de/hintergrund/Gut-dokumentiert-Architecture-Decision-Records-4664988.html 2 | ADR-Tools: https://github.com/npryce/adr-tools 3 | -------------------------------------------------------------------------------- /infrastructure/deployment/Installation.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | *Das entsprechende Dokument wurde verschoben, dieses hier Dokument existiert nur, um entsprechende Verlinkungen aufrecht zu erhalten.* 3 | Änderungen bitte nur in den entsprechenden Dokumenten vornehmen. 4 | 5 | Hier geht es weiter zur [Installations-Anleitung](./docs/Installation.md). 6 | 7 | -------------------------------------------------------------------------------- /infrastructure/deployment/certs/eps/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/deployment/certs/eps/.keep -------------------------------------------------------------------------------- /infrastructure/deployment/certs/nginx/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/deployment/certs/nginx/.keep -------------------------------------------------------------------------------- /infrastructure/deployment/docs/Architektur.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/deployment/docs/Architektur.pdf -------------------------------------------------------------------------------- /infrastructure/deployment/docs/Beispiel-Bonn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/deployment/docs/Beispiel-Bonn.png -------------------------------------------------------------------------------- /infrastructure/deployment/docs/examples/Bonn-example-proxy.txt: -------------------------------------------------------------------------------- 1 | sh create-csr-for-proxy.sh "Engeltalstr. 6" "53111 Bonn" "ga-stadt-bonn-proxy" 2 | -------------------------------------------------------------------------------- /infrastructure/deployment/docs/examples/Bonn-example.txt: -------------------------------------------------------------------------------- 1 | sh create-csr-for-eps.sh "Engeltalstr. 6" "53111 Bonn" "ga-stadt-bonn" 2 | -------------------------------------------------------------------------------- /infrastructure/deployment/docs/examples/Koeln-example-proxy.txt: -------------------------------------------------------------------------------- 1 | sh create-csr-for-proxy.sh "Neumarkt 15-21" "50667 Köln" "ga-stadt-koeln-proxy" 2 | -------------------------------------------------------------------------------- /infrastructure/deployment/docs/examples/Koeln-example.txt: -------------------------------------------------------------------------------- 1 | sh create-csr-for-eps.sh "Neumarkt 15-21" "50667 Köln" "ga-stadt-koeln" 2 | -------------------------------------------------------------------------------- /infrastructure/deployment/docs/images/IRIS-C2-with-EPS.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/deployment/docs/images/IRIS-C2-with-EPS.jpg -------------------------------------------------------------------------------- /infrastructure/deployment/docs/images/IRIS-Production-Certs-v2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/deployment/docs/images/IRIS-Production-Certs-v2.jpg -------------------------------------------------------------------------------- /infrastructure/deployment/docs/images/IRIS-Production-Certs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/deployment/docs/images/IRIS-Production-Certs.jpg -------------------------------------------------------------------------------- /infrastructure/deployment/docs/images/certificate_service_manager/mycsm_Anmeldung.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/deployment/docs/images/certificate_service_manager/mycsm_Anmeldung.png -------------------------------------------------------------------------------- /infrastructure/deployment/docs/images/certificate_service_manager/mycsm_Neues_Zertifikat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/deployment/docs/images/certificate_service_manager/mycsm_Neues_Zertifikat.png -------------------------------------------------------------------------------- /infrastructure/deployment/docs/images/certificate_service_manager/mycsm_Produkt_auswählen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/deployment/docs/images/certificate_service_manager/mycsm_Produkt_auswählen.png -------------------------------------------------------------------------------- /infrastructure/deployment/docs/images/certificate_service_manager/mycsm_Produkt_auswählen_advanced_ssl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/deployment/docs/images/certificate_service_manager/mycsm_Produkt_auswählen_advanced_ssl.png -------------------------------------------------------------------------------- /infrastructure/deployment/docs/images/certificate_service_manager/mycsm_Produkt_auswählen_advanced_ssl_webform.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/deployment/docs/images/certificate_service_manager/mycsm_Produkt_auswählen_advanced_ssl_webform.png -------------------------------------------------------------------------------- /infrastructure/deployment/docs/images/certificate_service_manager/mycsm_Zertifikate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/deployment/docs/images/certificate_service_manager/mycsm_Zertifikate.png -------------------------------------------------------------------------------- /infrastructure/deployment/docs/images/certificate_service_manager/mycsm_Zertifikatsverwaltung.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/deployment/docs/images/certificate_service_manager/mycsm_Zertifikatsverwaltung.png -------------------------------------------------------------------------------- /infrastructure/deployment/docs/images/certificate_service_manager/mycsm_basic_device_id_webform.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/deployment/docs/images/certificate_service_manager/mycsm_basic_device_id_webform.png -------------------------------------------------------------------------------- /infrastructure/deployment/docs/images/certificate_service_manager/mycsm_Übersicht.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/deployment/docs/images/certificate_service_manager/mycsm_Übersicht.png -------------------------------------------------------------------------------- /infrastructure/deployment/docs/images/smoketest/EventRequest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/deployment/docs/images/smoketest/EventRequest.png -------------------------------------------------------------------------------- /infrastructure/deployment/docs/images/smoketest/EventResponse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/deployment/docs/images/smoketest/EventResponse.png -------------------------------------------------------------------------------- /infrastructure/deployment/docs/images/smoketest/Login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/deployment/docs/images/smoketest/Login.png -------------------------------------------------------------------------------- /infrastructure/deployment/docs/images/smoketest/NewEvent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/deployment/docs/images/smoketest/NewEvent.png -------------------------------------------------------------------------------- /infrastructure/deployment/docs/images/smoketest/SearchResult.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/deployment/docs/images/smoketest/SearchResult.png -------------------------------------------------------------------------------- /infrastructure/deployment/docs/images/support-information.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/deployment/docs/images/support-information.png -------------------------------------------------------------------------------- /infrastructure/deployment/docs/iris-docker-installation.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/deployment/docs/iris-docker-installation.jpg -------------------------------------------------------------------------------- /infrastructure/deployment/docs/iris-local-installation.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/deployment/docs/iris-local-installation.jpg -------------------------------------------------------------------------------- /infrastructure/deployment/docs/sanitized-rki-name.md: -------------------------------------------------------------------------------- 1 | # Bestimmung vom IRIS Identifier Ihres Gesundheitsamtes 2 | 3 | Der `IRIS Identifier` an einigen Stellen benutzt, um ein Gesundheitsamt eindeutig zu identifizieren. 4 | 5 | ## 1) Bestimmung vom offiziellen RKI Namen 6 | 7 | Bestimmen Sie zunächst den offiziellen RKI Namen Ihres Gesundheitsamtes. Gehen Sie dafür auf https://tools.rki.de/PLZTool und suchen Sie nach Ihrem GA. Der offizielle Name ist die obere Zeit im Adressfeld ([Beispiel Bonn](./Beispiel-Bonn.png)). 8 | 9 | ## 2) Bestimmung vom IRIS Identifier Ihres Gesundheitsamtes 10 | 11 | ``` 12 | Der allgemeine Aufbau vom IRIS Identifier ist: ga-${sanitized_name(Offizieller RKI Name)} 13 | 14 | sanitized_name bedeutet folgendes: Ersetzung aller Umlaute (z.B. ö -> oe). Sonderzeichen und Leerzeichen (auch aufeinanderfolgend) werden durch ein '-' ersetzt. Alles Lower Case. 15 | 16 | # Beispiel Bonn 17 | Offizieller RKI Name: Stadt Bonn 18 | sanitized_name: stadt-bonn 19 | IRIS Identifier: ga-stadt-bonn 20 | ``` -------------------------------------------------------------------------------- /infrastructure/deployment/scripts/live/create-eps-cert.sh: -------------------------------------------------------------------------------- 1 | # Usage: create-eps-cert.sh [your signature cert private key] [your signature cert] [common name] 2 | 3 | key=$1 4 | sign_cert=$2 5 | cn=$3 6 | 7 | extFile=extFile.txt 8 | 9 | openssl req -new -sha256 -key "${key}" -subj "/CN=${cn}" -addext "keyUsage=digitalSignature" -addext "subjectAltName = URI:iris-name://${cn}" -out "${cn}-sign.csr"; 10 | 11 | echo "[SANKey]\nsubjectAltName = URI:iris-name://${cn},URI:iris-group://health-departments,DNS:${cn},DNS:*.${cn}.local\nkeyUsage = digitalSignature" > $extFile 12 | 13 | openssl x509 -req -in "${cn}-sign.csr" -CA $sign_cert -CAkey $key -CAcreateserial -out "${cn}.crt" -days 365 -sha256 -extensions SANKey -extfile $extFile; 14 | 15 | FINGERPRINT=$(openssl x509 -noout -fingerprint -sha256 -inform pem -in ${cn}.crt | sed -e 's/://g' | sed -r 's/.*=(.*)$/\1/g' | awk '{print tolower($0)}') 16 | 17 | echo "# Information needed for IRIS Team" 18 | echo "CN: $cn" 19 | echo "Certificate Fingerprint: $FINGERPRINT" 20 | 21 | rm $extFile 22 | 23 | -------------------------------------------------------------------------------- /infrastructure/deployment/scripts/live/create-fingerprint-from-cert.sh: -------------------------------------------------------------------------------- 1 | # Usage: create-fingerprint-from-cert.sh < Zertifikate #3 - mTLS-Zertifikat - EPS > 2 | 3 | cert=$1 4 | 5 | export CN=`openssl x509 -noout -subject -in $cert | sed -n '/^subject/s/^.*CN = //p'|tr -d '\n'` 6 | export FINGERPRINT=$(openssl x509 -noout -fingerprint -sha256 -inform pem -in $cert | sed -e 's/://g' | sed -r 's/.*=(.*)$/\1/g' | awk '{print tolower($0)}') 7 | 8 | echo "# Information needed for IRIS Team" 9 | echo "CN: $CN" 10 | echo "Certificate Fingerprint: $FINGERPRINT" -------------------------------------------------------------------------------- /infrastructure/deployment/scripts/live/create-proxy-eps-cert.sh: -------------------------------------------------------------------------------- 1 | # Usage: create-eps-proxy-cert.sh [your signature cert private key] [your signature cert] [common name] 2 | 3 | key=$1 4 | sign_cert=$2 5 | cn=$3 6 | 7 | extFile=extFile.txt 8 | 9 | openssl req -new -sha256 -key "${key}" -subj "/CN=${cn}" -addext "keyUsage=digitalSignature" -addext "subjectAltName = URI:iris-name://${cn}" -out "${cn}-sign.csr"; 10 | 11 | echo "[SANKey]\nsubjectAltName = URI:iris-name://${cn},URI:iris-group://private-proxies,DNS:${cn},DNS:*.${cn}.local" > $extFile 12 | 13 | openssl x509 -req -in "${cn}-sign.csr" -CA $sign_cert -CAkey $key -CAcreateserial -out "${cn}.crt" -days 365 -sha256 -extensions SANKey -extfile $extFile; 14 | 15 | FINGERPRINT=$(openssl x509 -noout -fingerprint -sha256 -inform pem -in ${cn}.crt | sed -e 's/://g' | sed -r 's/.*=(.*)$/\1/g' | awk '{print tolower($0)}') 16 | 17 | echo "# Information needed for IRIS Team" 18 | echo "CN: $cn" 19 | echo "Certificate Fingerprint: $FINGERPRINT" 20 | 21 | rm $extFile -------------------------------------------------------------------------------- /infrastructure/deployment/scripts/live/generate-rsa-key-pair.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | openssl genrsa -out "%1.key" 4096 3 | openssl rsa -in "%1.key" -pubout -out "%1.pub" -------------------------------------------------------------------------------- /infrastructure/deployment/scripts/live/generate-rsa-key-pair.sh: -------------------------------------------------------------------------------- 1 | # Skript zur Erstellung eines RSA Schluesselpaares zur Beantragung des TLS Zertifikates bei D-TRUST 2 | # Benutzung: generate-rsa-key-pair.sh 3 | 4 | NAME=$1 5 | LEN="4096" 6 | 7 | openssl genrsa -out "${NAME}.key" ${LEN}; 8 | openssl rsa -in "${NAME}.key" -pubout -out "${NAME}.pub"; 9 | -------------------------------------------------------------------------------- /infrastructure/deployment/scripts/live/generate-signature-key-pair.sh: -------------------------------------------------------------------------------- 1 | # # Skript zur Erstellung eines Signature Schluesselpaares zur Beantragung des Signatur Zertifikates bei D-TRUST 2 | NAME=$1 3 | PRIV_KEY=$NAME-priv-key 4 | PUB_KEY=$NAME-pub-key 5 | 6 | openssl ecparam -name secp256r1 -genkey -noout -out "${PRIV_KEY}.pem" 7 | openssl ec -in "${PRIV_KEY}.pem" -pubout > "${PUB_KEY}.pem" 8 | 9 | -------------------------------------------------------------------------------- /infrastructure/deployment/scripts/staging/create-csr-for-eps.sh: -------------------------------------------------------------------------------- 1 | ST=$1 2 | L=$2 3 | CN=$3 4 | 5 | O="Gesundheitsamt" 6 | ST=$1 7 | L=$2 8 | C="DE" 9 | OU="IT" 10 | CN=$3 11 | LEN="4096" 12 | 13 | openssl genrsa -out "${CN}.key" ${LEN}; 14 | openssl rsa -in "${CN}.key" -pubout -out "${CN}.pub"; 15 | 16 | openssl req -new -sha256 -key "${CN}.key" -subj "/C=${C}/ST=${ST}/L=${L}/O=${O}/OU=${OU}/CN=${CN}" -addext "keyUsage=digitalSignature" -addext "subjectAltName = URI:iris-name://${CN},URI:iris-group://health-departments,DNS:${CN},DNS:*.${CN}.local" -out "${CN}.csr"; -------------------------------------------------------------------------------- /infrastructure/deployment/scripts/staging/create-csr-for-proxy.sh: -------------------------------------------------------------------------------- 1 | ST=$1 2 | L=$2 3 | CN=$3 4 | 5 | O="Gesundheitsamt" 6 | ST=$1 7 | L=$2 8 | C="DE" 9 | OU="IT" 10 | CN=$3 11 | LEN="4096" 12 | 13 | openssl genrsa -out "${CN}.key" ${LEN}; 14 | openssl rsa -in "${CN}.key" -pubout -out "${CN}.pub"; 15 | 16 | openssl req -new -sha256 -key "${CN}.key" -subj "/C=${C}/ST=${ST}/L=${L}/O=${O}/OU=${OU}/CN=${CN}" -addext "keyUsage=digitalSignature" -addext "subjectAltName = URI:iris-name://${CN},URI:iris-group://private-proxies,DNS:${CN},DNS:*.${CN}.local" -out "${CN}.csr"; 17 | -------------------------------------------------------------------------------- /infrastructure/dev/docker-compose-watchtower.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | # Watchtower managing auto-updates (polling all 60s) 4 | watchtower: 5 | image: containrrr/watchtower 6 | volumes: 7 | - /var/run/docker.sock:/var/run/docker.sock 8 | environment: 9 | TZ: Europe/Berlin 10 | WATCHTOWER_LABEL_ENABLE: "true" 11 | WATCHTOWER_POLL_INTERVAL: 60 12 | -------------------------------------------------------------------------------- /infrastructure/docker/.gitignore: -------------------------------------------------------------------------------- 1 | !**/ca/** -------------------------------------------------------------------------------- /infrastructure/docker/app-eps/.gitignore: -------------------------------------------------------------------------------- 1 | !* 2 | -------------------------------------------------------------------------------- /infrastructure/docker/app-eps/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM inoeg/eps:v0.2.7 2 | 3 | COPY conf /app/settings 4 | COPY ca /app/settings/ca 5 | 6 | ENV EPS_SETTINGS "settings/roles/test/app" 7 | 8 | CMD ["--level", "trace", "server", "run"] 9 | -------------------------------------------------------------------------------- /infrastructure/docker/iris-client-eps/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM inoeg/eps:v0.2.7 2 | 3 | COPY conf /app/settings 4 | COPY ca /app/settings/ca 5 | 6 | CMD ["--level", "trace", "server", "run"] 7 | -------------------------------------------------------------------------------- /infrastructure/docker/iris-client-proxy/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM inoeg/proxy:v0.2.7 2 | 3 | COPY conf /app/settings 4 | COPY ca /app/settings/ca 5 | 6 | CMD ["--level", "trace", "run", "private"] 7 | -------------------------------------------------------------------------------- /infrastructure/docker/nginx/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx:1.23.1-alpine 2 | RUN echo 'server_tokens off;' > /etc/nginx/conf.d/server_tokens.conf 3 | COPY config/templates/ /etc/nginx/templates/ 4 | -------------------------------------------------------------------------------- /infrastructure/ide/eclipse.importorder: -------------------------------------------------------------------------------- 1 | #Organize Import Order 2 | #Tue Aug 18 16:51:09 CEST 2020 3 | 0= 4 | 1=java 5 | 2=javax 6 | 3=org 7 | 4=com 8 | -------------------------------------------------------------------------------- /infrastructure/stand-alone-deployment/.gitignore: -------------------------------------------------------------------------------- 1 | *.db 2 | public/** 3 | !public/.keep 4 | !ca/** 5 | -------------------------------------------------------------------------------- /infrastructure/stand-alone-deployment/bin/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/stand-alone-deployment/bin/.keep -------------------------------------------------------------------------------- /infrastructure/stand-alone-deployment/conf/eps/certs/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/stand-alone-deployment/conf/eps/certs/.keep -------------------------------------------------------------------------------- /infrastructure/stand-alone-deployment/conf/nginx/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/stand-alone-deployment/conf/nginx/.keep -------------------------------------------------------------------------------- /infrastructure/stand-alone-deployment/conf/proxy/certs/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/stand-alone-deployment/conf/proxy/certs/.keep -------------------------------------------------------------------------------- /infrastructure/stand-alone-deployment/db/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/stand-alone-deployment/db/.keep -------------------------------------------------------------------------------- /infrastructure/stand-alone-deployment/public/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/infrastructure/stand-alone-deployment/public/.keep -------------------------------------------------------------------------------- /infrastructure/stand-alone-deployment/scripts/start-eps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source .env 4 | 5 | ## Variables depending on .env 6 | export EPS_SETTINGS=conf/eps/roles/$IRIS_ENV/hd 7 | export EPS_OP=$EPS_OP 8 | export EPS_CLIENT_CERT=$EPS_CLIENT_CERT 9 | export EPS_CLIENT_CERT_KEY=$EPS_CLIENT_CERT_KEY 10 | export PROXY_URL=$PROXY_URL 11 | 12 | ## Fixed Variables 13 | export IRIS_CLIENT_BFF_ENDPOINT=http://localhost:8092/data-submission-rpc 14 | 15 | ## Run application ( requires eps to be in PATH ) 16 | eps -level trace server run 17 | -------------------------------------------------------------------------------- /infrastructure/stand-alone-deployment/scripts/start-private-proxy-eps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source .env 4 | 5 | ## Variables depending on .env 6 | export EPS_SETTINGS=conf/eps/roles/$IRIS_ENV/private-proxy-eps 7 | export PROXY_OP=$PROXY_OP 8 | export PROXY_CLIENT_CERT=$PROXY_CLIENT_CERT 9 | export PROXY_CLIENT_CERT_KEY=$PROXY_CLIENT_CERT_KEY 10 | export PROXY_URL=$PROXY_URL 11 | 12 | ## Fixed Variables 13 | export PRIVATE_PROXY_ENDPOINT=http://localhost:8877/jsonrpc 14 | 15 | ## Run application ( requires eps to be in PATH ) 16 | eps -level trace server run 17 | -------------------------------------------------------------------------------- /infrastructure/stand-alone-deployment/scripts/start-private-proxy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source .env 4 | 5 | ## Variables depending on .env 6 | export PROXY_SETTINGS=conf/proxy/roles/$IRIS_ENV/private-proxy 7 | export PROXY_OP=$PROXY_OP 8 | export PROXY_DOMAIN=$PROXY_SUBDOMAIN 9 | export PROXY_TLS_CERT=$PROXY_TLS_CERT 10 | export PROXY_TLS_CERT_KEY=$PROXY_TLS_CERT_KEY 11 | export PROXY_CLIENT_CERT=$PROXY_CLIENT_CERT 12 | export PROXY_CLIENT_CERT_KEY=$PROXY_CLIENT_CERT_KEY 13 | export PROXY_URL=$PROXY_URL 14 | export ANNOUNCEMENT_DB_FOLDER=${ANNOUNCEMENT_DB_FOLDER:-./db} 15 | 16 | ## Fixed Variables 17 | export IRIS_CLIENT_BFF_ENDPOINT=http://localhost:8092/data-submission-rpc 18 | export PRIVATE_PROXY_EPS_ENDPOINT=https://localhost:7766/jsonrpc 19 | 20 | ## Run application ( requires proxy to be in PATH ) 21 | proxy -level trace run private -------------------------------------------------------------------------------- /iris-client-bff/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar 3 | -------------------------------------------------------------------------------- /iris-client-bff/Readme.md: -------------------------------------------------------------------------------- 1 | # IRIS Client BFF 2 | 3 | "Backend for frontend" service for [IRIS client frontend](https://github.com/iris-connect/iris-client/tree/develop/iris-client-fe). 4 | 5 | ## Authentication 6 | 7 | At the moment you can configure DB authentication. 8 | 9 | ### DB Authentication 10 | 11 | In this setting the local database is used to store authentication information. You need to set the following property in Spring configuration. 12 | 13 | ```bash 14 | security.auth=db # Activates the DB auth 15 | security.auth.db.admin-user-name=admin # Creates an initial admin user if it does not exist. 16 | security.auth.db.admin-user-password=admin # Set the initial admin user password. 17 | ``` 18 | 19 | Using this setting, the authentication is activated for all calls towards the client need to be authorized. 20 | -------------------------------------------------------------------------------- /iris-client-bff/bindings/ca-certificates/type: -------------------------------------------------------------------------------- 1 | ca-certificates -------------------------------------------------------------------------------- /iris-client-bff/lombok.config: -------------------------------------------------------------------------------- 1 | lombok.accessors.chain=true 2 | lombok.addNullAnnotations=spring 3 | lombok.var.flagUsage=error 4 | lombok.nonNull.exceptionType=IllegalArgumentException 5 | lombok.addLombokGeneratedAnnotation = true 6 | # lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier -------------------------------------------------------------------------------- /iris-client-bff/postman/IRIS localhost.postman_environment.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "bca51237-0c51-42bb-9883-026cdcfc02e0", 3 | "name": "IRIS localhost", 4 | "values": [ 5 | { 6 | "key": "base_url_search", 7 | "value": "http://localhost:8080", 8 | "enabled": true 9 | }, 10 | { 11 | "key": "base_url_iris_bff", 12 | "value": "http://localhost:8092", 13 | "enabled": true 14 | } 15 | ], 16 | "_postman_variable_scope": "environment", 17 | "_postman_exported_at": "2021-05-07T05:34:37.692Z", 18 | "_postman_exported_using": "Postman/8.3.0" 19 | } -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/auth/db/AuthenticationStatus.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.auth.db; 2 | 3 | public enum AuthenticationStatus { 4 | AUTHENTICATED, PRE_AUTHENTICATED_MFA_REQUIRED, PRE_AUTHENTICATED_ENROLLMENT_REQUIRED 5 | } 6 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/auth/db/MfAuthenticationProperties.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.auth.db; 2 | 3 | import static iris.client_bff.auth.db.MfAuthenticationProperties.MfAuthenticationOptions.*; 4 | 5 | import lombok.Value; 6 | 7 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 8 | import org.springframework.boot.context.properties.ConfigurationProperties; 9 | import org.springframework.boot.context.properties.ConstructorBinding; 10 | 11 | @ConfigurationProperties(prefix = "security.auth.db.mfa") 12 | @ConstructorBinding 13 | @ConditionalOnProperty( 14 | value = "security.auth", 15 | havingValue = "db") 16 | @Value 17 | public class MfAuthenticationProperties { 18 | 19 | private MfAuthenticationOptions option; 20 | 21 | public boolean isMfaEnabled() { 22 | return option != DISABLED; 23 | } 24 | 25 | public enum MfAuthenticationOptions { 26 | ALWAYS, OPTIONAL_DEFAULT_TRUE, OPTIONAL_DEFAULT_FALSE, DISABLED 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/auth/db/OtpAuthenticationToken.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.auth.db; 2 | 3 | import lombok.EqualsAndHashCode; 4 | import lombok.Value; 5 | 6 | import org.springframework.security.authentication.AbstractAuthenticationToken; 7 | import org.springframework.security.core.SpringSecurityCoreVersion; 8 | 9 | /** 10 | * @author Jens Kutzsche 11 | */ 12 | @Value 13 | @EqualsAndHashCode(callSuper = false) 14 | public class OtpAuthenticationToken extends AbstractAuthenticationToken { 15 | 16 | private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID; 17 | 18 | private Object principal; 19 | private Object credentials; 20 | 21 | public OtpAuthenticationToken(Object principal, Object credentials) { 22 | 23 | super(null); 24 | 25 | this.principal = principal; 26 | this.credentials = credentials; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/auth/db/RefreshTokenException.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.auth.db; 2 | 3 | import org.springframework.security.core.AuthenticationException; 4 | 5 | /** 6 | * @author Jens Kutzsche 7 | */ 8 | public class RefreshTokenException extends AuthenticationException { 9 | 10 | private static final long serialVersionUID = 6158791145978867925L; 11 | 12 | /** 13 | * @param msg 14 | */ 15 | public RefreshTokenException(String msg) { 16 | super(msg); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/auth/db/jwt/AllowedToken.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.auth.db.jwt; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.NoArgsConstructor; 5 | import lombok.RequiredArgsConstructor; 6 | import lombok.Value; 7 | 8 | import java.io.Serializable; 9 | import java.time.Instant; 10 | 11 | import javax.persistence.Column; 12 | import javax.persistence.Entity; 13 | import javax.persistence.Id; 14 | import javax.persistence.Table; 15 | 16 | @Entity 17 | @Table(name = "allowed_tokens") 18 | @Value 19 | @RequiredArgsConstructor(staticName = "of") 20 | @NoArgsConstructor(force = true, access = AccessLevel.PRIVATE) 21 | class AllowedToken implements Serializable { 22 | 23 | @Id 24 | private String jwtTokenDigest; 25 | 26 | @Column(nullable = false) 27 | private String userName; 28 | 29 | @Column(nullable = false) 30 | private Instant expirationTime; 31 | 32 | @Column(nullable = false) 33 | private Instant created; 34 | } 35 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/auth/db/jwt/AllowedTokenRepository.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.auth.db.jwt; 2 | 3 | import java.time.Instant; 4 | import java.util.Optional; 5 | 6 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 7 | import org.springframework.data.jpa.repository.JpaRepository; 8 | import org.springframework.transaction.annotation.Transactional; 9 | 10 | @ConditionalOnProperty( 11 | value = "security.auth", 12 | havingValue = "db") 13 | interface AllowedTokenRepository extends JpaRepository { 14 | 15 | Optional findByJwtTokenDigest(String token); 16 | 17 | @Transactional 18 | void deleteByUserName(String userName); 19 | 20 | @Transactional 21 | void deleteByExpirationTimeBefore(Instant expirationTime); 22 | } 23 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/auth/db/jwt/JWTWhitelistCleanup.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.auth.db.jwt; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 6 | import org.springframework.scheduling.annotation.Scheduled; 7 | import org.springframework.stereotype.Component; 8 | 9 | @Component 10 | @ConditionalOnProperty( 11 | value = "security.auth", 12 | havingValue = "db") 13 | @RequiredArgsConstructor 14 | class JWTWhitelistCleanup { 15 | 16 | private static final long DELETION_RATE = 30 * 60 * 1000l; // 30 minutes 17 | 18 | private final JWTService jwtService; 19 | 20 | @Scheduled(fixedDelay = DELETION_RATE) 21 | public void clean() { 22 | jwtService.removeExpiredTokens(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/auth/db/jwt/JwtConstants.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.auth.db.jwt; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.NoArgsConstructor; 5 | 6 | @NoArgsConstructor(access = AccessLevel.PRIVATE) 7 | public class JwtConstants { 8 | 9 | public static final String JWT_CLAIM_AUTH_STATUS = "AUTH_STATUS"; 10 | } 11 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/auth/db/login_attempts/AuthenticationFailureListener.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.auth.db.login_attempts; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 6 | import org.springframework.context.ApplicationListener; 7 | import org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent; 8 | import org.springframework.stereotype.Component; 9 | 10 | @Component 11 | @ConditionalOnProperty( 12 | value = "security.auth", 13 | havingValue = "db") 14 | @RequiredArgsConstructor 15 | class AuthenticationFailureListener implements ApplicationListener { 16 | 17 | private final LoginAttemptsService loginAttemptService; 18 | 19 | @Override 20 | public void onApplicationEvent(AuthenticationFailureBadCredentialsEvent e) { 21 | loginAttemptService.loginFailed(e.getAuthentication().getName()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/auth/db/login_attempts/AuthenticationSuccessEventListener.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.auth.db.login_attempts; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 6 | import org.springframework.context.ApplicationListener; 7 | import org.springframework.security.authentication.event.AuthenticationSuccessEvent; 8 | import org.springframework.stereotype.Component; 9 | 10 | @Component 11 | @ConditionalOnProperty( 12 | value = "security.auth", 13 | havingValue = "db") 14 | @RequiredArgsConstructor 15 | class AuthenticationSuccessEventListener implements ApplicationListener { 16 | 17 | private final LoginAttemptsService loginAttemptService; 18 | 19 | @Override 20 | public void onApplicationEvent(final AuthenticationSuccessEvent e) { 21 | loginAttemptService.loginSucceeded(e.getAuthentication().getName()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/auth/db/login_attempts/LoginAttemptsRepository.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.auth.db.login_attempts; 2 | 3 | import java.time.Instant; 4 | 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 6 | import org.springframework.data.repository.CrudRepository; 7 | import org.springframework.transaction.annotation.Transactional; 8 | 9 | /** 10 | * @author Jens Kutzsche 11 | */ 12 | @ConditionalOnProperty( 13 | value = "security.auth", 14 | havingValue = "db") 15 | interface LoginAttemptsRepository extends CrudRepository { 16 | 17 | @Transactional 18 | void deleteBylastModifiedBefore(Instant time); 19 | } 20 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/cases/CaseDataSubmissionRepository.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.cases; 2 | 3 | import iris.client_bff.cases.model.CaseDataSubmission; 4 | import iris.client_bff.cases.model.CaseDataSubmission.DataSubmissionIdentifier; 5 | import iris.client_bff.core.model.AggregateRepository; 6 | 7 | import javax.transaction.Transactional; 8 | 9 | import org.springframework.data.util.Streamable; 10 | 11 | public interface CaseDataSubmissionRepository 12 | extends AggregateRepository { 13 | 14 | @Transactional 15 | Streamable findAllByRequest(CaseDataRequest request); 16 | 17 | @Transactional 18 | void deleteAllByRequestIn(Iterable requests); 19 | } 20 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/cases/CaseEmail.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.cases; 2 | 3 | import iris.client_bff.core.mail.EmailSender.AbstractTemplatedEmail; 4 | import iris.client_bff.core.mail.EmailTemplates; 5 | 6 | import java.util.Map; 7 | 8 | class CaseEmail extends AbstractTemplatedEmail { 9 | 10 | CaseEmail(Recipient recipient, String subject, EmailTemplates.Key template, 11 | Map placeholders) { 12 | 13 | super(recipient, subject, template, placeholders, null); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/cases/CaseToUserReferenceChecker.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.cases; 2 | 3 | import iris.client_bff.users.UserAccount; 4 | import iris.client_bff.users.UserAnonymizationReferenceChecker; 5 | import lombok.RequiredArgsConstructor; 6 | 7 | import org.springframework.stereotype.Component; 8 | 9 | /** 10 | * @author Jens Kutzsche 11 | */ 12 | @Component 13 | @RequiredArgsConstructor 14 | class CaseToUserReferenceChecker implements UserAnonymizationReferenceChecker { 15 | 16 | private final CaseDataRequestRepository caseRepo; 17 | private final CaseDataSubmissionRepository submissionRepo; 18 | 19 | @Override 20 | public boolean canUserBeAnonymized(UserAccount user) { 21 | return !caseRepo.isReferencedToUser(user.getId().toUuid()) 22 | && !submissionRepo.isReferencedToUser(user.getId().toUuid()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/cases/eps/CaseDataController.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.cases.eps; 2 | 3 | import iris.client_bff.cases.eps.dto.CaseDataProvider; 4 | import iris.client_bff.cases.eps.dto.Contacts; 5 | import iris.client_bff.cases.eps.dto.Events; 6 | 7 | import javax.validation.constraints.NotNull; 8 | 9 | import org.springframework.validation.annotation.Validated; 10 | 11 | import com.googlecode.jsonrpc4j.JsonRpcParam; 12 | 13 | @Validated 14 | public interface CaseDataController { 15 | String submitContactAndEventData( 16 | @JsonRpcParam(value = "dataAuthorizationToken") String dataAuthorizationToken, 17 | @JsonRpcParam(value = "contacts") @NotNull Contacts contacts, 18 | @JsonRpcParam(value = "events") @NotNull Events events, 19 | @JsonRpcParam(value = "dataProvider") @NotNull CaseDataProvider dataProvider); 20 | } 21 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/cases/eps/dto/CaseDataProvider.java: -------------------------------------------------------------------------------- 1 | 2 | package iris.client_bff.cases.eps.dto; 3 | 4 | import static lombok.AccessLevel.*; 5 | 6 | import iris.client_bff.core.serialization.DefuseJsonString; 7 | import lombok.AllArgsConstructor; 8 | import lombok.Builder; 9 | import lombok.Data; 10 | import lombok.NoArgsConstructor; 11 | 12 | @Data 13 | @Builder 14 | @NoArgsConstructor(access = PRIVATE) 15 | @AllArgsConstructor(access = PRIVATE) 16 | public class CaseDataProvider { 17 | 18 | @DefuseJsonString(maxLength = 256) 19 | String firstName; 20 | 21 | @DefuseJsonString(maxLength = 256) 22 | String lastName; 23 | } 24 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/cases/eps/dto/ContactCategory.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.cases.eps.dto; 2 | 3 | public enum ContactCategory { 4 | HIGH_RISK, HIGH_RISK_MED, MEDIUM_RISK_MED, LOW_RISK, NO_RISK 5 | } 6 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/cases/eps/dto/ContactInformation.java: -------------------------------------------------------------------------------- 1 | 2 | package iris.client_bff.cases.eps.dto; 3 | 4 | import static lombok.AccessLevel.*; 5 | 6 | import iris.client_bff.core.serialization.DefuseJsonString; 7 | import lombok.AllArgsConstructor; 8 | import lombok.Builder; 9 | import lombok.Data; 10 | import lombok.NoArgsConstructor; 11 | 12 | import java.time.Instant; 13 | 14 | @Data 15 | @Builder 16 | @NoArgsConstructor(access = PRIVATE) 17 | @AllArgsConstructor(access = PRIVATE) 18 | public class ContactInformation { 19 | 20 | Instant firstContactDate; 21 | Instant lastContactDate; 22 | ContactCategory contactCategory; 23 | 24 | @DefuseJsonString(maxLength = 256) 25 | String basicConditions; 26 | } 27 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/cases/eps/dto/ContactPerson.java: -------------------------------------------------------------------------------- 1 | 2 | package iris.client_bff.cases.eps.dto; 3 | 4 | import static lombok.AccessLevel.*; 5 | 6 | import iris.client_bff.core.api.dto.PersonWithDefuseData; 7 | import lombok.AllArgsConstructor; 8 | import lombok.Data; 9 | import lombok.EqualsAndHashCode; 10 | import lombok.NoArgsConstructor; 11 | import lombok.experimental.SuperBuilder; 12 | 13 | @Data 14 | @EqualsAndHashCode(callSuper = true) 15 | @SuperBuilder 16 | @NoArgsConstructor(access = PRIVATE) 17 | @AllArgsConstructor(access = PRIVATE) 18 | public class ContactPerson extends PersonWithDefuseData { 19 | 20 | WorkPlace workPlace; 21 | ContactInformation contactInformation; 22 | } 23 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/cases/eps/dto/Contacts.java: -------------------------------------------------------------------------------- 1 | 2 | package iris.client_bff.cases.eps.dto; 3 | 4 | import static lombok.AccessLevel.*; 5 | 6 | import lombok.AllArgsConstructor; 7 | import lombok.Builder; 8 | import lombok.Data; 9 | import lombok.NoArgsConstructor; 10 | 11 | import java.time.Instant; 12 | import java.util.List; 13 | 14 | @Data 15 | @Builder 16 | @NoArgsConstructor(access = PRIVATE) 17 | @AllArgsConstructor(access = PRIVATE) 18 | public class Contacts { 19 | 20 | List contactPersons; 21 | Instant startDate; 22 | Instant endDate; 23 | } 24 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/cases/eps/dto/Event.java: -------------------------------------------------------------------------------- 1 | 2 | package iris.client_bff.cases.eps.dto; 3 | 4 | import static lombok.AccessLevel.*; 5 | 6 | import iris.client_bff.core.api.dto.AddressWithDefuseData; 7 | import iris.client_bff.core.serialization.DefuseJsonString; 8 | import iris.client_bff.core.validation.AttackDetector.Phone; 9 | import lombok.AllArgsConstructor; 10 | import lombok.Builder; 11 | import lombok.Data; 12 | import lombok.NoArgsConstructor; 13 | 14 | @Data 15 | @Builder 16 | @NoArgsConstructor(access = PRIVATE) 17 | @AllArgsConstructor(access = PRIVATE) 18 | public class Event { 19 | 20 | @DefuseJsonString(maxLength = 256) 21 | String name; 22 | 23 | @DefuseJsonString(maxLength = 100, payload = Phone.class) 24 | String phone; 25 | 26 | AddressWithDefuseData address; 27 | 28 | @DefuseJsonString(maxLength = 256) 29 | String additionalInformation; 30 | } 31 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/cases/eps/dto/Events.java: -------------------------------------------------------------------------------- 1 | 2 | package iris.client_bff.cases.eps.dto; 3 | 4 | import static lombok.AccessLevel.*; 5 | 6 | import lombok.AllArgsConstructor; 7 | import lombok.Builder; 8 | import lombok.Data; 9 | import lombok.NoArgsConstructor; 10 | 11 | import java.time.Instant; 12 | import java.util.List; 13 | 14 | @Data 15 | @Builder 16 | @NoArgsConstructor(access = PRIVATE) 17 | @AllArgsConstructor(access = PRIVATE) 18 | public class Events { 19 | 20 | List events; 21 | Instant startDate; 22 | Instant endDate; 23 | } 24 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/cases/eps/dto/WorkPlace.java: -------------------------------------------------------------------------------- 1 | 2 | package iris.client_bff.cases.eps.dto; 3 | 4 | import static lombok.AccessLevel.*; 5 | 6 | import iris.client_bff.core.api.dto.AddressWithDefuseData; 7 | import iris.client_bff.core.serialization.DefuseJsonString; 8 | import iris.client_bff.core.validation.AttackDetector.Phone; 9 | import lombok.AllArgsConstructor; 10 | import lombok.Builder; 11 | import lombok.Data; 12 | import lombok.NoArgsConstructor; 13 | 14 | @Data 15 | @Builder 16 | @NoArgsConstructor(access = PRIVATE) 17 | @AllArgsConstructor(access = PRIVATE) 18 | public class WorkPlace { 19 | 20 | @DefuseJsonString(maxLength = 256) 21 | String name; 22 | 23 | @DefuseJsonString(maxLength = 256) 24 | String pointOfContact; 25 | 26 | @DefuseJsonString(maxLength = 100, payload = Phone.class) 27 | String phone; 28 | 29 | AddressWithDefuseData address; 30 | } 31 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/cases/model/CaseDataProvider.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.cases.model; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | 9 | import java.time.LocalDate; 10 | 11 | import javax.persistence.Embeddable; 12 | 13 | @Embeddable 14 | @Data 15 | @EqualsAndHashCode 16 | @AllArgsConstructor 17 | @NoArgsConstructor(force = true, access = AccessLevel.PRIVATE) 18 | public class CaseDataProvider { 19 | 20 | private String firstName; 21 | private String lastName; 22 | private LocalDate dateOfBirth; 23 | } 24 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/cases/model/CaseEvent.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.cases.model; 2 | 3 | import iris.client_bff.core.model.Address; 4 | import lombok.AccessLevel; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Data; 7 | import lombok.EqualsAndHashCode; 8 | import lombok.NoArgsConstructor; 9 | 10 | import java.util.UUID; 11 | 12 | import javax.persistence.Embedded; 13 | import javax.persistence.Entity; 14 | import javax.persistence.Id; 15 | import javax.persistence.JoinColumn; 16 | import javax.persistence.ManyToOne; 17 | 18 | @Entity 19 | @Data 20 | @EqualsAndHashCode 21 | @AllArgsConstructor 22 | @NoArgsConstructor(force = true, access = AccessLevel.PRIVATE) 23 | public class CaseEvent { 24 | 25 | @Id 26 | private final UUID eventId = UUID.randomUUID(); 27 | 28 | @ManyToOne // 29 | @JoinColumn(name = "submission_id") 30 | private CaseDataSubmission submission; 31 | 32 | private String name; 33 | private String phone; 34 | 35 | @Embedded 36 | private Address address; 37 | 38 | private String additionalInformation; 39 | } 40 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/cases/web/request_dto/IndexCaseDTO.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.cases.web.request_dto; 2 | 3 | import static lombok.AccessLevel.*; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | import lombok.ToString; 10 | 11 | import java.time.Instant; 12 | 13 | @Data 14 | @Builder 15 | @ToString 16 | @NoArgsConstructor(access = PRIVATE) 17 | @AllArgsConstructor(access = PRIVATE) 18 | public class IndexCaseDTO { 19 | private String caseId; 20 | private String comment; 21 | private String externalCaseId; 22 | private String name; 23 | private Instant start; 24 | private Instant end; 25 | private IndexCaseStatusDTO status; 26 | } 27 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/cases/web/request_dto/IndexCaseDetailsDTO.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.cases.web.request_dto; 2 | 3 | import static lombok.AccessLevel.*; 4 | 5 | import iris.client_bff.cases.web.submission_dto.ContactsAndEvents; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Builder; 8 | import lombok.Data; 9 | import lombok.NoArgsConstructor; 10 | import lombok.ToString; 11 | 12 | import java.time.Instant; 13 | 14 | @Data 15 | @Builder 16 | @ToString 17 | @NoArgsConstructor(access = PRIVATE) 18 | @AllArgsConstructor(access = PRIVATE) 19 | public class IndexCaseDetailsDTO { 20 | private String caseId; 21 | private String comment; 22 | private String externalCaseId; 23 | private String name; 24 | private Instant start; 25 | private Instant end; 26 | private IndexCaseStatusDTO status; 27 | private ContactsAndEvents submissionData; 28 | private String readableToken; 29 | private Instant createdAt; 30 | private Instant lastModifiedAt; 31 | private String createdBy; 32 | private String lastModifiedBy; 33 | } 34 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/cases/web/request_dto/IndexCaseInsertDTO.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.cases.web.request_dto; 2 | 3 | import static lombok.AccessLevel.*; 4 | 5 | import iris.client_bff.core.validation.NoSignOfAttack; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Builder; 8 | import lombok.Data; 9 | import lombok.NoArgsConstructor; 10 | import lombok.ToString; 11 | 12 | import java.time.Instant; 13 | 14 | import javax.validation.constraints.NotNull; 15 | 16 | @Data 17 | @Builder 18 | @ToString 19 | @NoArgsConstructor(access = PRIVATE) 20 | @AllArgsConstructor(access = PRIVATE) 21 | public class IndexCaseInsertDTO { 22 | 23 | @NoSignOfAttack 24 | private String comment; 25 | 26 | @NoSignOfAttack 27 | private String externalCaseId; 28 | 29 | @NoSignOfAttack 30 | private String name; 31 | 32 | @NotNull 33 | private Instant start; 34 | 35 | private Instant end; 36 | } 37 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/cases/web/request_dto/IndexCaseStatusDTO.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.cases.web.request_dto; 2 | 3 | public enum IndexCaseStatusDTO { 4 | DATA_REQUESTED, DATA_RECEIVED, ABORTED, CLOSED; 5 | } 6 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/cases/web/request_dto/IndexCaseUpdateDTO.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.cases.web.request_dto; 2 | 3 | import static lombok.AccessLevel.*; 4 | 5 | import iris.client_bff.core.validation.NoSignOfAttack; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Builder; 8 | import lombok.Data; 9 | import lombok.NoArgsConstructor; 10 | import lombok.ToString; 11 | 12 | @Data 13 | @Builder 14 | @ToString 15 | @NoArgsConstructor(access = PRIVATE) 16 | @AllArgsConstructor(access = PRIVATE) 17 | public class IndexCaseUpdateDTO { 18 | 19 | @NoSignOfAttack 20 | private String comment; 21 | 22 | @NoSignOfAttack 23 | private String externalCaseId; 24 | 25 | @NoSignOfAttack 26 | private String name; 27 | 28 | private IndexCaseStatusDTO status; 29 | } 30 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/cases/web/submission_dto/ContactCategory.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.cases.web.submission_dto; 2 | 3 | /** 4 | * Category of contact that describes the intensity and thus the risk of infection of the contact. 5 | */ 6 | public enum ContactCategory { 7 | 8 | HIGH_RISK, HIGH_RISK_MED, MEDIUM_RISK_MED, LOW_RISK, NO_RISK; 9 | } 10 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/cases/web/submission_dto/ContactPersonAllOfContactInformation.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.cases.web.submission_dto; 2 | 3 | import static lombok.AccessLevel.*; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | import lombok.ToString; 10 | 11 | import java.time.Instant; 12 | 13 | @Data 14 | @Builder 15 | @ToString 16 | @NoArgsConstructor(access = PRIVATE) 17 | @AllArgsConstructor(access = PRIVATE) 18 | public class ContactPersonAllOfContactInformation { 19 | 20 | private Instant firstContactDate; 21 | private Instant lastContactDate; 22 | private ContactCategory contactCategory; 23 | private String basicConditions; 24 | } 25 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/cases/web/submission_dto/ContactPersonAllOfWorkPlace.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.cases.web.submission_dto; 2 | 3 | import static lombok.AccessLevel.*; 4 | 5 | import iris.client_bff.core.api.dto.Address; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Builder; 8 | import lombok.Data; 9 | import lombok.NoArgsConstructor; 10 | import lombok.ToString; 11 | 12 | @Data 13 | @Builder 14 | @ToString 15 | @NoArgsConstructor(access = PRIVATE) 16 | @AllArgsConstructor(access = PRIVATE) 17 | public class ContactPersonAllOfWorkPlace { 18 | 19 | private String name; 20 | private String pointOfContact; 21 | private String phone; 22 | private Address address; 23 | } 24 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/cases/web/submission_dto/ContactPersonList.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.cases.web.submission_dto; 2 | 3 | import static lombok.AccessLevel.*; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | import lombok.ToString; 10 | 11 | import java.time.LocalDate; 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | @Data 16 | @Builder 17 | @ToString 18 | @NoArgsConstructor(access = PRIVATE) 19 | @AllArgsConstructor(access = PRIVATE) 20 | public class ContactPersonList { 21 | 22 | @Builder.Default 23 | private List contactPersons = new ArrayList<>(); 24 | private LocalDate startDate; 25 | private LocalDate endDate; 26 | } 27 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/cases/web/submission_dto/ContactsAndEvents.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.cases.web.submission_dto; 2 | 3 | import static lombok.AccessLevel.*; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | import lombok.ToString; 10 | 11 | @Data 12 | @Builder 13 | @ToString 14 | @NoArgsConstructor(access = PRIVATE) 15 | @AllArgsConstructor(access = PRIVATE) 16 | public class ContactsAndEvents { 17 | 18 | private ContactPersonList contacts; 19 | private EventList events; 20 | private ContactsAndEventsDataProvider dataProvider; 21 | } 22 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/cases/web/submission_dto/ContactsAndEventsDataProvider.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.cases.web.submission_dto; 2 | 3 | import static lombok.AccessLevel.*; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | import lombok.ToString; 10 | 11 | import java.time.LocalDate; 12 | 13 | @Data 14 | @Builder 15 | @ToString 16 | @NoArgsConstructor(access = PRIVATE) 17 | @AllArgsConstructor(access = PRIVATE) 18 | public class ContactsAndEventsDataProvider { 19 | 20 | private String firstName; 21 | private String lastName; 22 | private LocalDate dateOfBirth; 23 | } 24 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/cases/web/submission_dto/Event.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.cases.web.submission_dto; 2 | 3 | import static lombok.AccessLevel.*; 4 | 5 | import iris.client_bff.core.api.dto.Address; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Builder; 8 | import lombok.Data; 9 | import lombok.NoArgsConstructor; 10 | import lombok.ToString; 11 | 12 | @Data 13 | @Builder 14 | @ToString 15 | @NoArgsConstructor(access = PRIVATE) 16 | @AllArgsConstructor(access = PRIVATE) 17 | public class Event { 18 | 19 | private String name; 20 | private String phone; 21 | private Address address; 22 | private String additionalInformation; 23 | } 24 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/cases/web/submission_dto/EventList.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.cases.web.submission_dto; 2 | 3 | import static lombok.AccessLevel.*; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | import lombok.ToString; 10 | 11 | import java.time.LocalDate; 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | @Data 16 | @Builder 17 | @ToString 18 | @NoArgsConstructor(access = PRIVATE) 19 | @AllArgsConstructor(access = PRIVATE) 20 | public class EventList { 21 | 22 | @Builder.Default 23 | private List events = new ArrayList<>(); 24 | private LocalDate startDate; 25 | private LocalDate endDate; 26 | } 27 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/config/BaseConfig.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.data.jpa.repository.config.EnableJpaAuditing; 5 | 6 | /** 7 | * @author Jens Kutzsche 8 | */ 9 | @Configuration 10 | @EnableJpaAuditing(dateTimeProviderRef = "irisDateTimeProvider") 11 | public class BaseConfig { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/config/DictionaryProperties.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.config; 2 | 3 | import lombok.Value; 4 | 5 | import org.springframework.boot.context.properties.ConfigurationProperties; 6 | import org.springframework.boot.context.properties.ConstructorBinding; 7 | import org.springframework.boot.context.properties.bind.DefaultValue; 8 | import org.springframework.validation.annotation.Validated; 9 | 10 | /** 11 | * @author Jens Kutzsche 12 | */ 13 | @ConfigurationProperties("dictionary") 14 | @ConstructorBinding 15 | @Value 16 | @Validated 17 | public class DictionaryProperties { 18 | 19 | int size; 20 | 21 | DictionaryProperties(@DefaultValue("20000") int size) { 22 | 23 | this.size = size; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/config/MethodSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.config; 2 | 3 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 4 | import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; 5 | 6 | /** 7 | * @author Jens Kutzsche 8 | */ 9 | @EnableGlobalMethodSecurity(prePostEnabled = true) 10 | public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {} 11 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/config/ProxyServiceProperties.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.config; 2 | 3 | import lombok.Value; 4 | 5 | import javax.validation.constraints.NotBlank; 6 | 7 | import org.springframework.boot.context.properties.ConfigurationProperties; 8 | import org.springframework.boot.context.properties.ConstructorBinding; 9 | import org.springframework.validation.annotation.Validated; 10 | 11 | @ConfigurationProperties("proxy-service") 12 | @ConstructorBinding 13 | @Value 14 | @Validated 15 | public class ProxyServiceProperties { 16 | 17 | @NotBlank 18 | private final String epsName; 19 | 20 | @NotBlank 21 | private final String targetProxy; 22 | 23 | @NotBlank 24 | private final String targetSubdomain; 25 | } 26 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/config/RPCClientProperties.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.config; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.Getter; 5 | import lombok.Value; 6 | 7 | import javax.validation.constraints.NotEmpty; 8 | 9 | import org.springframework.boot.context.properties.ConfigurationProperties; 10 | import org.springframework.boot.context.properties.ConstructorBinding; 11 | import org.springframework.validation.annotation.Validated; 12 | 13 | /** 14 | * @author Jens Kutzsche 15 | */ 16 | @ConfigurationProperties("eps-client") 17 | @ConstructorBinding 18 | @Validated 19 | @Value 20 | public class RPCClientProperties { 21 | 22 | private final @NotEmpty @Getter(value = AccessLevel.PACKAGE) String epsClientUrl; 23 | 24 | private final @NotEmpty @Getter(value = AccessLevel.PACKAGE) String proxyClientUrl; 25 | 26 | private final @NotEmpty String ownEndpoint; 27 | } 28 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/config/SchedulingConfig.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.context.annotation.Profile; 5 | import org.springframework.scheduling.annotation.EnableScheduling; 6 | 7 | /** 8 | * @author Jens Kutzsche 9 | */ 10 | @Configuration 11 | @EnableScheduling 12 | @Profile({ "!test", "!inttest" }) 13 | public class SchedulingConfig {} 14 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/config/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.config; 2 | 3 | import java.security.Security; 4 | 5 | import javax.annotation.PostConstruct; 6 | 7 | import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 11 | 12 | @Configuration 13 | public class SecurityConfig { 14 | 15 | @Bean 16 | public BCryptPasswordEncoder bCryptPasswordEncoder() { 17 | return new BCryptPasswordEncoder(); 18 | } 19 | 20 | @PostConstruct 21 | public void initBouncyCastle() { 22 | 23 | Security.addProvider(new BouncyCastleFipsProvider()); 24 | Security.setProperty("crypto.policy", "unlimited"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/config/SpringAsyncConfig.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.scheduling.annotation.EnableAsync; 5 | 6 | @Configuration 7 | @EnableAsync 8 | public class SpringAsyncConfig { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/config/SuspiciouslyCaseRequestProperties.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.config; 2 | 3 | import lombok.Value; 4 | 5 | import javax.validation.constraints.Positive; 6 | 7 | import org.springframework.boot.context.properties.ConfigurationProperties; 8 | import org.springframework.boot.context.properties.ConstructorBinding; 9 | import org.springframework.validation.annotation.Validated; 10 | 11 | /** 12 | * @author Jens Kutzsche 13 | */ 14 | @ConfigurationProperties(prefix = "iris.suspiciously.request.case") 15 | @ConstructorBinding 16 | @Validated 17 | @Value 18 | public class SuspiciouslyCaseRequestProperties { 19 | 20 | @Positive 21 | long dataWarningThreshold; 22 | 23 | @Positive 24 | long dataBlockingThreshold; 25 | } 26 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/config/SuspiciouslyEventRequestProperties.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.config; 2 | 3 | import lombok.Value; 4 | 5 | import javax.validation.constraints.Positive; 6 | 7 | import org.springframework.boot.context.properties.ConfigurationProperties; 8 | import org.springframework.boot.context.properties.ConstructorBinding; 9 | import org.springframework.validation.annotation.Validated; 10 | 11 | /** 12 | * @author Jens Kutzsche 13 | */ 14 | @ConfigurationProperties(prefix = "iris.suspiciously.request.event") 15 | @ConstructorBinding 16 | @Validated 17 | @Value 18 | public class SuspiciouslyEventRequestProperties { 19 | 20 | @Positive 21 | long dataWarningThreshold; 22 | 23 | @Positive 24 | long dataBlockingThreshold; 25 | } 26 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/core/alert/AlertDto.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.core.alert; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Getter; 6 | import lombok.NoArgsConstructor; 7 | 8 | import org.springframework.validation.annotation.Validated; 9 | 10 | /** 11 | * @author Jens Kutzsche 12 | */ 13 | @Validated 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | @Builder 17 | @Getter 18 | public class AlertDto { 19 | 20 | String title; 21 | String text; 22 | String sourceApp; 23 | String appVersion; 24 | AlertType alertType; 25 | 26 | public enum AlertType { 27 | TICKET, MESSAGE 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/core/alert/AlertListDto.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.core.alert; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Getter; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.util.List; 9 | 10 | @NoArgsConstructor 11 | @AllArgsConstructor 12 | @Builder 13 | @Getter 14 | public class AlertListDto { 15 | List alertList; 16 | } 17 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/core/api/dto/Address.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.core.api.dto; 2 | 3 | import static lombok.AccessLevel.*; 4 | 5 | import iris.client_bff.core.validation.NoSignOfAttack; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Builder; 8 | import lombok.Data; 9 | import lombok.NoArgsConstructor; 10 | 11 | import javax.validation.constraints.NotBlank; 12 | 13 | @Data 14 | @Builder 15 | @NoArgsConstructor(access = PRIVATE) 16 | @AllArgsConstructor(access = PRIVATE) 17 | public class Address { 18 | 19 | private @NotBlank @NoSignOfAttack String street; 20 | private @NotBlank @NoSignOfAttack String houseNumber; 21 | private @NotBlank @NoSignOfAttack String zipCode; 22 | private @NotBlank @NoSignOfAttack String city; 23 | } 24 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/core/api/dto/AddressWithDefuseData.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.core.api.dto; 2 | 3 | import static lombok.AccessLevel.*; 4 | 5 | import iris.client_bff.core.serialization.DefuseJsonString; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Builder; 8 | import lombok.Data; 9 | import lombok.NoArgsConstructor; 10 | 11 | import javax.validation.constraints.NotBlank; 12 | 13 | @Data 14 | @Builder 15 | @NoArgsConstructor(access = PRIVATE) 16 | @AllArgsConstructor(access = PRIVATE) 17 | public class AddressWithDefuseData { 18 | 19 | @NotBlank 20 | @DefuseJsonString(maxLength = 256) 21 | private String street; 22 | 23 | @NotBlank 24 | @DefuseJsonString(maxLength = 256) 25 | private String houseNumber; 26 | 27 | @NotBlank 28 | @DefuseJsonString(maxLength = 10) 29 | private String zipCode; 30 | 31 | @NotBlank 32 | @DefuseJsonString(maxLength = 256) 33 | private String city; 34 | } 35 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/core/api/dto/Person.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.core.api.dto; 2 | 3 | import static lombok.AccessLevel.*; 4 | 5 | import iris.client_bff.core.model.Sex; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Builder; 8 | import lombok.Data; 9 | import lombok.NoArgsConstructor; 10 | import lombok.experimental.SuperBuilder; 11 | 12 | import java.time.LocalDate; 13 | 14 | /** 15 | * A person base class. 16 | */ 17 | @Data 18 | @SuperBuilder 19 | @NoArgsConstructor(access = PROTECTED) 20 | @AllArgsConstructor(access = PROTECTED) 21 | public class Person { 22 | 23 | private String firstName; 24 | private String lastName; 25 | private LocalDate dateOfBirth; 26 | @Builder.Default 27 | private Sex sex = Sex.UNKNOWN; 28 | private String email; 29 | private String phone; 30 | private String mobilePhone; 31 | private Address address; 32 | } 33 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/core/mail/EmailSenderDummy.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.core.mail; 2 | 3 | import io.vavr.control.Try; 4 | import lombok.extern.slf4j.Slf4j; 5 | 6 | import javax.annotation.PostConstruct; 7 | 8 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 9 | import org.springframework.stereotype.Service; 10 | 11 | /** 12 | * @author Jens Kutzsche 13 | */ 14 | @Service 15 | @ConditionalOnProperty(name = "iris.client.mailing.active", havingValue = "false", matchIfMissing = true) 16 | @Slf4j 17 | public class EmailSenderDummy implements EmailSender { 18 | 19 | @Override 20 | public Try testConnection() { 21 | return Try.success("Dummy Sender"); 22 | } 23 | 24 | @Override 25 | public Try sendMail(TemplatedEmail email) { 26 | return Try.success(null); 27 | } 28 | 29 | @PostConstruct 30 | void postConstruct() { 31 | log.info("Email sender dummy is used."); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/core/messages/ErrorMessages.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.core.messages; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.NoArgsConstructor; 5 | 6 | @NoArgsConstructor(access = AccessLevel.PRIVATE) 7 | public class ErrorMessages { 8 | 9 | public static final String REQUEST_TOO_LARGE = "Request content length exceeded limit!"; 10 | public static final String EVENT_DATA_REQUEST_CREATION = "Fehler: Ereignisnachverfolgung konnte nicht angelegt werden."; 11 | public static final String LOCATION_SEARCH = "Fehler: Ereignisortsuche fehlgeschlagen."; 12 | public static final String CASE_DATA_REQUEST_CREATION = "Indexfall-Datenanforderung konnte nicht angelegt werden."; 13 | public static final String INVALID_INPUT = "Eingabedaten sind ungültig"; 14 | public static final String USER_NOT_FOUND = "User: %s, not found"; 15 | } 16 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/core/model/Address.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.core.model; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.EqualsAndHashCode; 8 | import lombok.NoArgsConstructor; 9 | 10 | import javax.persistence.Embeddable; 11 | 12 | import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField; 13 | import org.hibernate.search.mapper.pojo.mapping.definition.annotation.GenericField; 14 | import org.hibernate.search.mapper.pojo.mapping.definition.annotation.KeywordField; 15 | 16 | @Embeddable 17 | @Data 18 | @Builder 19 | @EqualsAndHashCode 20 | @AllArgsConstructor 21 | @NoArgsConstructor(force = true, access = AccessLevel.PRIVATE) 22 | public class Address { 23 | 24 | @FullTextField(analyzer = "german") 25 | private String street; 26 | private String houseNumber; 27 | 28 | @GenericField 29 | private String zipCode; 30 | 31 | @KeywordField(normalizer = "german") 32 | private String city; 33 | } 34 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/core/model/AggregateRepository.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.core.model; 2 | 3 | import java.time.Instant; 4 | import java.util.UUID; 5 | 6 | import org.springframework.data.jpa.repository.JpaRepository; 7 | import org.springframework.data.repository.NoRepositoryBean; 8 | import org.springframework.data.util.Streamable; 9 | 10 | /** 11 | * @author Jens Kutzsche 12 | */ 13 | @NoRepositoryBean 14 | public interface AggregateRepository, ID extends Id> extends JpaRepository { 15 | 16 | /** 17 | * Returns the {@link Aggregate}s of type {@link T} created before the given {@link Instant}. 18 | * 19 | * @param refDate must not be {@literal null}. 20 | * @return 21 | */ 22 | Streamable findByMetadataCreatedIsBefore(Instant refDate); 23 | 24 | boolean existsByMetadataCreatedByIsOrMetadataLastModifiedByIs(UUID userId, UUID userId2); 25 | 26 | default boolean isReferencedToUser(UUID userId) { 27 | return existsByMetadataCreatedByIsOrMetadataLastModifiedByIs(userId, userId); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/core/model/Id.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.core.model; 2 | 3 | import java.io.Serializable; 4 | 5 | import javax.persistence.Embeddable; 6 | 7 | /** 8 | * @author Jens Kutzsche 9 | */ 10 | @Embeddable 11 | public interface Id extends Serializable {} 12 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/core/model/IdWithUuid.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.core.model; 2 | 3 | import java.util.UUID; 4 | 5 | /** 6 | * @author Jens Kutzsche 7 | */ 8 | public abstract class IdWithUuid implements Id { 9 | 10 | private static final long serialVersionUID = 1932442646942290069L; 11 | 12 | protected abstract UUID getBasicId(); 13 | 14 | @Override 15 | public String toString() { 16 | return getBasicId().toString(); 17 | } 18 | 19 | public UUID toUuid() { 20 | return getBasicId(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/core/model/Sex.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.core.model; 2 | 3 | public enum Sex { 4 | MALE, FEMALE, OTHER, UNKNOWN; 5 | } 6 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/core/model/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Contains base and common classes of the domain model, i.e. entities and value objects. 3 | * 4 | * @author Jens Kutzsche 5 | */ 6 | package iris.client_bff.core.model; 7 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/core/serialization/FlexibleEnum.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.core.serialization; 2 | 3 | import static org.apache.commons.lang3.StringUtils.*; 4 | 5 | /** 6 | * @author Jens Kutzsche 7 | */ 8 | public interface FlexibleEnum { 9 | 10 | static String cleanStringForEnum(String string) { 11 | 12 | var cleanString = replaceChars(string, '-', '_'); 13 | cleanString = camelToSnake(cleanString); 14 | 15 | return cleanString.toUpperCase(); 16 | } 17 | 18 | static String camelToSnake(String str) { 19 | return str.replaceAll("([a-z])([A-Z]+)", "$1_$2").toLowerCase(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/core/setting/Setting.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.core.setting; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.time.LocalDate; 8 | 9 | import javax.persistence.Column; 10 | import javax.persistence.Entity; 11 | import javax.persistence.EnumType; 12 | import javax.persistence.Enumerated; 13 | import javax.persistence.Id; 14 | import javax.persistence.Table; 15 | import javax.validation.constraints.Size; 16 | 17 | /** 18 | * @author Jens Kutzsche 19 | */ 20 | @Entity 21 | @Table(name = "settings") 22 | @Data 23 | @AllArgsConstructor 24 | @NoArgsConstructor 25 | public class Setting { 26 | 27 | @Id 28 | @Enumerated(EnumType.STRING) 29 | @Column(nullable = false) 30 | private Name name; 31 | 32 | @Size(max = 1000) 33 | private String storedValue; // value is a keyword for DBMS 34 | 35 | private LocalDate savedAt = LocalDate.now(); 36 | 37 | public enum Name { 38 | JWT_SECRET, REFRESH_SECRET; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/core/setting/SettingsRepository.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.core.setting; 2 | 3 | import org.springframework.data.jpa.repository.JpaRepository; 4 | 5 | public interface SettingsRepository extends JpaRepository {} 6 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/core/sync/SyncTimesRepository.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.core.sync; 2 | 3 | import iris.client_bff.core.sync.SyncTimes.DataTypes; 4 | 5 | import org.springframework.data.repository.CrudRepository; 6 | 7 | public interface SyncTimesRepository extends CrudRepository {} 8 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/core/token/IdentifierToken.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.core.token; 2 | 3 | import iris.client_bff.core.log.LogHelper; 4 | import lombok.Builder; 5 | 6 | @Builder 7 | public record IdentifierToken(String readableToken, 8 | String connectionAuthorizationToken, 9 | String dataAuthorizationToken) { 10 | 11 | public String toStringWithObfuscation() { 12 | return String.format("readable token: %s, dataAuthorizationToken: %s, connectionAuthorizationToken: %s", 13 | LogHelper.obfuscateAtStart16(readableToken), 14 | LogHelper.obfuscateAtStart16(dataAuthorizationToken), 15 | LogHelper.obfuscateAtStart16(connectionAuthorizationToken)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/events/EventDataRequestRepository.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.events; 2 | 3 | import iris.client_bff.core.model.AggregateRepository; 4 | import iris.client_bff.events.EventDataRequest.DataRequestIdentifier; 5 | import iris.client_bff.events.EventDataRequest.Status; 6 | 7 | import java.time.Instant; 8 | 9 | import org.springframework.data.domain.Page; 10 | import org.springframework.data.domain.Pageable; 11 | import org.springframework.data.jpa.repository.Query; 12 | 13 | /** 14 | * @author Jens Kutzsche 15 | */ 16 | public interface EventDataRequestRepository extends AggregateRepository { 17 | 18 | @Query("select count(r) from EventDataRequest r where r.metadata.created >= :date") 19 | int getCountSinceDate(Instant date); 20 | 21 | @Query("select count(r) from EventDataRequest r where r.status = :status") 22 | int getCountWithStatus(Status status); 23 | 24 | Page findByStatus(Status status, Pageable pageable); 25 | } 26 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/events/EventDataSubmissionRepository.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.events; 2 | 3 | import iris.client_bff.core.model.AggregateRepository; 4 | import iris.client_bff.events.model.EventDataSubmission; 5 | import iris.client_bff.events.model.EventDataSubmission.DataSubmissionIdentifier; 6 | 7 | import javax.transaction.Transactional; 8 | 9 | import org.springframework.data.util.Streamable; 10 | 11 | /** 12 | * @author Jens Kutzsche 13 | */ 14 | public interface EventDataSubmissionRepository 15 | extends AggregateRepository { 16 | 17 | @Transactional 18 | Streamable findAllByRequest(EventDataRequest request); 19 | 20 | @Transactional 21 | void deleteAllByRequestIn(Iterable requests); 22 | } 23 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/events/EventEmail.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.events; 2 | 3 | import iris.client_bff.core.mail.EmailSender.AbstractTemplatedEmail; 4 | import iris.client_bff.core.mail.EmailTemplates; 5 | 6 | import java.util.Map; 7 | 8 | class EventEmail extends AbstractTemplatedEmail { 9 | 10 | EventEmail(Recipient recipient, String subject, EmailTemplates.Key template, 11 | Map placeholders) { 12 | 13 | super(recipient, subject, template, placeholders, null); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/events/EventToUserReferenceChecker.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.events; 2 | 3 | import iris.client_bff.users.UserAccount; 4 | import iris.client_bff.users.UserAnonymizationReferenceChecker; 5 | import lombok.RequiredArgsConstructor; 6 | 7 | import org.springframework.stereotype.Component; 8 | 9 | /** 10 | * @author Jens Kutzsche 11 | */ 12 | @Component 13 | @RequiredArgsConstructor 14 | class EventToUserReferenceChecker implements UserAnonymizationReferenceChecker { 15 | 16 | private final EventDataRequestRepository eventRepo; 17 | private final EventDataSubmissionRepository submissionRepo; 18 | 19 | @Override 20 | public boolean canUserBeAnonymized(UserAccount user) { 21 | return !eventRepo.isReferencedToUser(user.getId().toUuid()) 22 | && !submissionRepo.isReferencedToUser(user.getId().toUuid()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/events/eps/DataProviderClient.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.events.eps; 2 | 3 | import iris.client_bff.events.EventDataRequest; 4 | import iris.client_bff.events.exceptions.IRISDataRequestException; 5 | 6 | public interface DataProviderClient { 7 | void requestGuestListData(EventDataRequest request) throws IRISDataRequestException; 8 | 9 | void abortGuestListDataRequest(EventDataRequest request) throws IRISDataRequestException; 10 | } 11 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/events/eps/JsonRpcClientDto.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.events.eps; 2 | 3 | import lombok.Data; 4 | import lombok.RequiredArgsConstructor; 5 | 6 | import javax.validation.constraints.NotNull; 7 | 8 | @Data 9 | @RequiredArgsConstructor 10 | public class JsonRpcClientDto { 11 | 12 | private @NotNull String name; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/events/exceptions/IRISDataRequestException.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.events.exceptions; 2 | 3 | public class IRISDataRequestException extends RuntimeException { 4 | 5 | private static final long serialVersionUID = 3906324468382013579L; 6 | 7 | public IRISDataRequestException() {} 8 | 9 | public IRISDataRequestException(String message) { 10 | super(message); 11 | } 12 | 13 | public IRISDataRequestException(String message, Throwable cause) { 14 | super(message, cause); 15 | } 16 | 17 | public IRISDataRequestException(Throwable cause) { 18 | super(cause); 19 | } 20 | 21 | public IRISDataRequestException(String message, Throwable cause, boolean enableSuppression, 22 | boolean writableStackTrace) { 23 | super(message, cause, enableSuppression, writableStackTrace); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/events/message/dto/ExportSelectionDto.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.events.message.dto; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | 7 | import javax.validation.Valid; 8 | import javax.validation.constraints.NotBlank; 9 | import javax.validation.constraints.NotEmpty; 10 | 11 | @Data 12 | public class ExportSelectionDto { 13 | 14 | @NotBlank 15 | String event; 16 | 17 | @Valid 18 | @NotEmpty 19 | List<@NotBlank String> guests; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/events/message/dto/ImportSelectionDto.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.events.message.dto; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | 7 | import javax.validation.Valid; 8 | import javax.validation.constraints.NotBlank; 9 | import javax.validation.constraints.NotEmpty; 10 | 11 | @Data 12 | public class ImportSelectionDto { 13 | 14 | @Valid 15 | @NotEmpty 16 | List<@NotBlank String> guests; 17 | 18 | } 19 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/events/message/dto/ImportSelectionViewPayloadDto.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.events.message.dto; 2 | 3 | import iris.client_bff.events.web.dto.Guest; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | 7 | import java.util.List; 8 | 9 | @Data 10 | @Builder 11 | public class ImportSelectionViewPayloadDto { 12 | private Selectables selectables; 13 | private Duplicates duplicates; 14 | 15 | @Data 16 | @Builder 17 | public static class Selectables { 18 | List guests; 19 | } 20 | 21 | @Data 22 | @Builder 23 | public static class Duplicates { 24 | List guests; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/events/model/AttendanceInformation.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.events.model; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.NoArgsConstructor; 8 | 9 | import java.time.Instant; 10 | 11 | import javax.persistence.Embeddable; 12 | 13 | @Embeddable 14 | @Data 15 | @EqualsAndHashCode 16 | @AllArgsConstructor 17 | @NoArgsConstructor(force = true, access = AccessLevel.PRIVATE) 18 | public class AttendanceInformation { 19 | 20 | private String descriptionOfParticipation; 21 | private Instant attendFrom; 22 | private Instant attendTo; 23 | private String additionalInformation; 24 | } 25 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/events/model/GuestListDataProvider.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.events.model; 2 | 3 | import iris.client_bff.core.model.Address; 4 | import lombok.AccessLevel; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Data; 7 | import lombok.EqualsAndHashCode; 8 | import lombok.NoArgsConstructor; 9 | 10 | import javax.persistence.Embeddable; 11 | import javax.persistence.Embedded; 12 | 13 | @Embeddable 14 | @Data 15 | @EqualsAndHashCode 16 | @AllArgsConstructor 17 | @NoArgsConstructor(force = true, access = AccessLevel.PRIVATE) 18 | public class GuestListDataProvider { 19 | 20 | private String name; 21 | @Embedded 22 | private Address address; 23 | } 24 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/events/web/dto/EventStatusDTO.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.events.web.dto; 2 | 3 | public enum EventStatusDTO { 4 | DATA_REQUESTED, DATA_RECEIVED, ABORTED, CLOSED; 5 | } 6 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/events/web/dto/EventUpdateDTO.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.events.web.dto; 2 | 3 | import static lombok.AccessLevel.*; 4 | 5 | import iris.client_bff.core.validation.NoSignOfAttack; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Builder; 8 | import lombok.Data; 9 | import lombok.NoArgsConstructor; 10 | import lombok.ToString; 11 | 12 | @Data 13 | @Builder 14 | @ToString 15 | @NoArgsConstructor(access = PRIVATE) 16 | @AllArgsConstructor(access = PRIVATE) 17 | public class EventUpdateDTO { 18 | 19 | @NoSignOfAttack 20 | private String comment; 21 | 22 | @NoSignOfAttack 23 | private String externalRequestId; 24 | 25 | @NoSignOfAttack 26 | private String name; 27 | 28 | private EventStatusDTO status; 29 | } 30 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/events/web/dto/ExistingDataRequestClientWithLocation.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.events.web.dto; 2 | 3 | import static lombok.AccessLevel.*; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | import lombok.ToString; 10 | 11 | import java.time.Instant; 12 | 13 | @Data 14 | @Builder 15 | @ToString 16 | @NoArgsConstructor(access = PRIVATE) 17 | @AllArgsConstructor(access = PRIVATE) 18 | public class ExistingDataRequestClientWithLocation { 19 | public enum StatusEnum { 20 | DATA_REQUESTED, DATA_RECEIVED, CLOSED, ABORTED; 21 | } 22 | 23 | private StatusEnum status; 24 | 25 | private String code; 26 | 27 | private String name; 28 | 29 | private String externalRequestId; 30 | 31 | private Instant start; 32 | 33 | private Instant end; 34 | 35 | private Instant requestedAt; 36 | 37 | private Instant lastUpdatedAt; 38 | 39 | private String requestDetails; 40 | 41 | private LocationInformation locationInformation; 42 | } 43 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/events/web/dto/ExistingDataRequestClientWithLocationList.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.events.web.dto; 2 | 3 | import static lombok.AccessLevel.*; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | import lombok.ToString; 10 | 11 | import java.util.List; 12 | 13 | @Data 14 | @Builder 15 | @ToString 16 | @NoArgsConstructor(access = PRIVATE) 17 | @AllArgsConstructor(access = PRIVATE) 18 | public class ExistingDataRequestClientWithLocationList { 19 | 20 | private List dataRequests; 21 | } 22 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/events/web/dto/GuestAttendanceInformation.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.events.web.dto; 2 | 3 | import static lombok.AccessLevel.*; 4 | 5 | import iris.client_bff.core.serialization.DefuseJsonString; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Builder; 8 | import lombok.Data; 9 | import lombok.NoArgsConstructor; 10 | 11 | import java.time.Instant; 12 | 13 | import javax.validation.constraints.Size; 14 | 15 | @Data 16 | @Builder 17 | @NoArgsConstructor(access = PRIVATE) 18 | @AllArgsConstructor(access = PRIVATE) 19 | public class GuestAttendanceInformation { 20 | 21 | @Size(max = 500) 22 | @DefuseJsonString(maxLength = 500) 23 | private String descriptionOfParticipation; 24 | 25 | private Instant attendFrom; 26 | private Instant attendTo; 27 | 28 | @Size(max = 500) 29 | @DefuseJsonString(maxLength = 500) 30 | private String additionalInformation; 31 | } 32 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/events/web/dto/GuestList.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.events.web.dto; 2 | 3 | import static lombok.AccessLevel.*; 4 | 5 | import iris.client_bff.core.serialization.DefuseJsonString; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Builder; 8 | import lombok.Data; 9 | import lombok.NoArgsConstructor; 10 | 11 | import java.time.Instant; 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | import javax.validation.Valid; 16 | import javax.validation.constraints.NotNull; 17 | 18 | @Data 19 | @Builder 20 | @NoArgsConstructor(access = PRIVATE) 21 | @AllArgsConstructor(access = PRIVATE) 22 | public class GuestList { 23 | 24 | @Builder.Default 25 | private List<@Valid Guest> guests = new ArrayList<>(); 26 | 27 | @NotNull 28 | @Valid 29 | private GuestListDataProvider dataProvider; 30 | 31 | @DefuseJsonString(maxLength = 500) 32 | private String additionalInformation; 33 | 34 | private Instant startDate; 35 | private Instant endDate; 36 | } 37 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/events/web/dto/GuestListDataProvider.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.events.web.dto; 2 | 3 | import static lombok.AccessLevel.*; 4 | 5 | import iris.client_bff.core.api.dto.AddressWithDefuseData; 6 | import iris.client_bff.core.serialization.DefuseJsonString; 7 | import lombok.AllArgsConstructor; 8 | import lombok.Builder; 9 | import lombok.Data; 10 | import lombok.NoArgsConstructor; 11 | 12 | import javax.validation.Valid; 13 | import javax.validation.constraints.NotNull; 14 | 15 | @Data 16 | @Builder 17 | @NoArgsConstructor(access = PRIVATE) 18 | @AllArgsConstructor(access = PRIVATE) 19 | public class GuestListDataProvider { 20 | 21 | @DefuseJsonString(maxLength = 256) 22 | private String name; 23 | 24 | @NotNull 25 | @Valid 26 | private AddressWithDefuseData address; 27 | } 28 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/events/web/dto/LocationAddress.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.events.web.dto; 2 | 3 | import static lombok.AccessLevel.*; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | import lombok.ToString; 10 | 11 | /** 12 | * Anschrift des Standorts 13 | */ 14 | @Data 15 | @Builder 16 | @ToString 17 | @NoArgsConstructor(access = PRIVATE) 18 | @AllArgsConstructor(access = PRIVATE) 19 | public class LocationAddress { 20 | 21 | private String street; 22 | private String city; 23 | private String zip; 24 | } 25 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/events/web/dto/LocationContact.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.events.web.dto; 2 | 3 | import static lombok.AccessLevel.*; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | import lombok.ToString; 10 | 11 | /** 12 | * Kontaktperson des Standorts 13 | */ 14 | @Data 15 | @Builder 16 | @ToString 17 | @NoArgsConstructor(access = PRIVATE) 18 | @AllArgsConstructor(access = PRIVATE) 19 | public class LocationContact { 20 | 21 | private String officialName; 22 | private String representative; 23 | private LocationAddress address; 24 | private String ownerEmail; 25 | private String email; 26 | private String phone; 27 | } 28 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/events/web/dto/LocationContext.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.events.web.dto; 2 | 3 | import static lombok.AccessLevel.*; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | import lombok.ToString; 10 | 11 | /** 12 | * Ein Standort hat ggf. weitere Informationen wie Tische/Räume, etc. 13 | */ 14 | @Data 15 | @Builder 16 | @ToString 17 | @NoArgsConstructor(access = PRIVATE) 18 | @AllArgsConstructor(access = PRIVATE) 19 | public class LocationContext { 20 | 21 | private String id; 22 | private String name; 23 | } 24 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/events/web/dto/LocationInformation.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.events.web.dto; 2 | 3 | import static lombok.AccessLevel.*; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | import java.util.List; 11 | 12 | @Data 13 | @Builder 14 | @AllArgsConstructor(access = PRIVATE) 15 | @NoArgsConstructor(access = PRIVATE) 16 | public class LocationInformation { 17 | 18 | private String name; 19 | private String publicKey; 20 | private LocationContact contact; 21 | private List contexts; 22 | } 23 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/feedback/FeedbackOutputDto.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.feedback; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import lombok.NonNull; 7 | import lombok.Setter; 8 | 9 | import javax.validation.constraints.Email; 10 | 11 | /** 12 | * @author Jens Kutzsche 13 | */ 14 | @Data 15 | @NoArgsConstructor(access = AccessLevel.PACKAGE) 16 | public class FeedbackOutputDto { 17 | 18 | private @NonNull String category; 19 | 20 | private @NonNull String title; 21 | 22 | private @NonNull String comment; 23 | 24 | private String name; 25 | 26 | @Email 27 | private String email; 28 | 29 | private String organisation; 30 | 31 | private String browserName; 32 | 33 | private String browserResolution; 34 | 35 | private @NonNull @Setter String sourceApp; 36 | 37 | private @NonNull @Setter String appVersion; 38 | } 39 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/feedback/FeedbackResponseDto.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.feedback; 2 | 3 | import lombok.Getter; 4 | import lombok.NonNull; 5 | 6 | /** 7 | * This class represents the json structure of a feedback response. 8 | * 9 | * @author Ostfalia Gruppe 12 10 | * @author Jens Kutzsche 11 | */ 12 | @Getter 13 | public class FeedbackResponseDto { 14 | 15 | private @NonNull String issueNumber; 16 | } 17 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/feedback/FeedbackSendingException.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.feedback; 2 | 3 | /** 4 | * @author Jens Kutzsche 5 | */ 6 | public class FeedbackSendingException extends RuntimeException { 7 | 8 | private static final long serialVersionUID = -1550186873048234582L; 9 | 10 | public FeedbackSendingException(Throwable cause) { 11 | super(cause); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/feedback/web/FeedbackInputDto.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.feedback.web; 2 | 3 | import lombok.Getter; 4 | import lombok.NonNull; 5 | 6 | import javax.validation.constraints.Email; 7 | 8 | /** 9 | * This class represents the json structure of a feedback request. 10 | * 11 | * @author Ostfalia Gruppe 12 12 | * @author Jens Kutzsche 13 | */ 14 | @Getter 15 | public class FeedbackInputDto { 16 | 17 | private @NonNull String category; 18 | 19 | private @NonNull String title; 20 | 21 | private @NonNull String comment; 22 | 23 | private String name; 24 | 25 | @Email 26 | private String email; 27 | 28 | private String organisation; 29 | 30 | private String browserName; 31 | 32 | private String browserResolution; 33 | } 34 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/hd_search/HdSearchException.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.hd_search; 2 | 3 | import java.io.Serial; 4 | 5 | import org.apache.commons.lang3.exception.ExceptionUtils; 6 | 7 | public class HdSearchException extends RuntimeException { 8 | 9 | @Serial 10 | private static final long serialVersionUID = -3649251457000674951L; 11 | 12 | public HdSearchException(String failedMethod, Throwable cause) { 13 | super("Call to '" + failedMethod + "' failed", cause); 14 | } 15 | 16 | public HdSearchException(String message) { 17 | super(message); 18 | } 19 | 20 | public HdSearchException(Throwable cause) { 21 | super(cause); 22 | } 23 | 24 | public String getErrorMessage() { 25 | return ExceptionUtils.getRootCause(this).getMessage(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/iris_messages/IrisMessageContext.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.iris_messages; 2 | 3 | public enum IrisMessageContext { 4 | INBOX, OUTBOX; 5 | } 6 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/iris_messages/IrisMessageDataRepository.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.iris_messages; 2 | 3 | import iris.client_bff.core.model.AggregateRepository; 4 | import iris.client_bff.iris_messages.IrisMessageData.IrisMessageDataIdentifier; 5 | 6 | interface IrisMessageDataRepository extends AggregateRepository {} 7 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/iris_messages/IrisMessageFolderRepository.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.iris_messages; 2 | 3 | import iris.client_bff.iris_messages.IrisMessageFolder.IrisMessageFolderIdentifier; 4 | 5 | import java.util.List; 6 | import java.util.Optional; 7 | 8 | import org.springframework.data.jpa.repository.JpaRepository; 9 | 10 | public interface IrisMessageFolderRepository 11 | extends JpaRepository { 12 | 13 | Optional findFirstByContextAndParentFolderIsNull(IrisMessageContext context); 14 | 15 | List findAllByParentFolder(IrisMessageFolderIdentifier parentFolder); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/iris_messages/IrisMessageRepository.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.iris_messages; 2 | 3 | import iris.client_bff.core.model.AggregateRepository; 4 | 5 | import org.springframework.data.domain.Page; 6 | import org.springframework.data.domain.Pageable; 7 | import org.springframework.data.jpa.repository.Query; 8 | 9 | public interface IrisMessageRepository extends AggregateRepository { 10 | 11 | @Query("select count(m) from IrisMessage m where m.isRead = false and m.folder.id = :folderId") 12 | int getCountUnreadByFolderId(IrisMessageFolder.IrisMessageFolderIdentifier folderId); 13 | 14 | int countByIsReadFalse(); 15 | 16 | Page findAllByFolderIdOrderByIsReadAsc(IrisMessageFolder.IrisMessageFolderIdentifier folder, 17 | Pageable pageable); 18 | } 19 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/iris_messages/IrisMessageToUserReferenceChecker.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.iris_messages; 2 | 3 | import iris.client_bff.users.UserAccount; 4 | import iris.client_bff.users.UserAnonymizationReferenceChecker; 5 | import lombok.RequiredArgsConstructor; 6 | 7 | import org.springframework.stereotype.Component; 8 | 9 | /** 10 | * @author Jens Kutzsche 11 | */ 12 | @Component 13 | @RequiredArgsConstructor 14 | class IrisMessageToUserReferenceChecker implements UserAnonymizationReferenceChecker { 15 | 16 | private final IrisMessageRepository messageRepo; 17 | 18 | @Override 19 | public boolean canUserBeAnonymized(UserAccount user) { 20 | return !messageRepo.isReferencedToUser(user.getId().toUuid()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/iris_messages/eps/IrisMessageDataController.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.iris_messages.eps; 2 | 3 | import iris.client_bff.iris_messages.exceptions.IrisMessageException; 4 | 5 | import javax.validation.Valid; 6 | import javax.validation.constraints.NotNull; 7 | 8 | import org.springframework.validation.annotation.Validated; 9 | 10 | import com.googlecode.jsonrpc4j.JsonRpcParam; 11 | 12 | @Validated 13 | public interface IrisMessageDataController { 14 | IrisMessageTransferDto createIrisMessage( 15 | @JsonRpcParam(value = "irisMessage") @NotNull @Valid IrisMessageTransferDto messageTransfer) 16 | throws IrisMessageException; 17 | } 18 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/iris_messages/exceptions/IrisMessageDataException.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.iris_messages.exceptions; 2 | 3 | import java.io.Serial; 4 | 5 | import org.apache.commons.lang3.exception.ExceptionUtils; 6 | 7 | public class IrisMessageDataException extends RuntimeException { 8 | 9 | @Serial 10 | private static final long serialVersionUID = -8707865003747114093L; 11 | 12 | public IrisMessageDataException(String failedMethod, Throwable cause) { 13 | super("Call to '" + failedMethod + "' failed", cause); 14 | } 15 | 16 | public IrisMessageDataException(String message) { 17 | super(message); 18 | } 19 | 20 | public IrisMessageDataException(Throwable cause) { 21 | super(cause); 22 | } 23 | 24 | public String getErrorMessage() { 25 | return ExceptionUtils.getRootCause(this).getMessage(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/iris_messages/exceptions/IrisMessageException.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.iris_messages.exceptions; 2 | 3 | import java.io.Serial; 4 | 5 | import org.apache.commons.lang3.exception.ExceptionUtils; 6 | 7 | public class IrisMessageException extends RuntimeException { 8 | @Serial 9 | private static final long serialVersionUID = 8068203942662884747L; 10 | 11 | public IrisMessageException(String message, Throwable cause) { 12 | super(message, cause); 13 | } 14 | 15 | public IrisMessageException(String message) { 16 | super(message); 17 | } 18 | 19 | public IrisMessageException(Throwable cause) { 20 | super(cause.getMessage(), cause); 21 | } 22 | 23 | public String getErrorMessage() { 24 | return ExceptionUtils.getRootCause(this).getMessage(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/iris_messages/web/IrisMessageDataAttachmentCountDto.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.iris_messages.web; 2 | 3 | import iris.client_bff.iris_messages.IrisMessageData; 4 | import lombok.Value; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | @Value 10 | class IrisMessageDataAttachmentCountDto { 11 | private int total; 12 | private int imported; 13 | 14 | public static IrisMessageDataAttachmentCountDto fromEntity(List dataList) { 15 | List attachments = dataList == null ? new ArrayList<>() : dataList; 16 | return new IrisMessageDataAttachmentCountDto( 17 | attachments.size(), 18 | (int) attachments.stream().filter(IrisMessageData::isImported).count()); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/iris_messages/web/IrisMessageDataViewDataDto.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.iris_messages.web; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class IrisMessageDataViewDataDto { 7 | private String id; 8 | private String discriminator; 9 | private Object payload; 10 | } 11 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/iris_messages/web/IrisMessageListItemDto.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.iris_messages.web; 2 | 3 | import iris.client_bff.iris_messages.IrisMessage; 4 | import iris.client_bff.iris_messages.IrisMessageHdContact; 5 | import lombok.Value; 6 | 7 | import java.time.Instant; 8 | 9 | @Value 10 | class IrisMessageListItemDto { 11 | 12 | private String id; 13 | private String subject; 14 | private IrisMessageHdContact hdAuthor; 15 | private IrisMessageHdContact hdRecipient; 16 | private Instant createdAt; 17 | private Boolean isRead; 18 | private IrisMessageDataAttachmentCountDto attachmentCount; 19 | 20 | public static IrisMessageListItemDto fromEntity(IrisMessage message) { 21 | return new IrisMessageListItemDto( 22 | message.getId().toString(), 23 | message.getSubject(), 24 | message.getHdAuthor(), 25 | message.getHdRecipient(), 26 | message.getMetadata().getCreated(), 27 | message.isRead(), 28 | IrisMessageDataAttachmentCountDto.fromEntity(message.getDataAttachments())); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/iris_messages/web/IrisMessageUpdateDto.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.iris_messages.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.validation.constraints.NotNull; 8 | 9 | @Data 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | class IrisMessageUpdateDto { 13 | 14 | @NotNull 15 | private Boolean isRead; 16 | } 17 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/proxy/IRISAnnouncementException.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.proxy; 2 | 3 | public class IRISAnnouncementException extends Exception { 4 | 5 | public IRISAnnouncementException(Throwable cause) { 6 | super(cause); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/proxy/ProxyServiceClient.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.proxy; 2 | 3 | import java.time.Instant; 4 | 5 | public interface ProxyServiceClient { 6 | String announce() throws IRISAnnouncementException; 7 | 8 | String announceExplicitToken(String connectionAuthorizationToken) throws IRISAnnouncementException; 9 | 10 | String abortAnnouncement(String domain) throws IRISAnnouncementException; 11 | 12 | String announce(Instant expirationTime) throws IRISAnnouncementException; 13 | } 14 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/search_client/SearchClient.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.search_client; 2 | 3 | import iris.client_bff.search_client.exceptions.IRISSearchException; 4 | import iris.client_bff.search_client.web.dto.LocationInformation; 5 | import iris.client_bff.search_client.web.dto.LocationQueryResult; 6 | 7 | import org.springframework.data.domain.Pageable; 8 | 9 | public interface SearchClient { 10 | LocationQueryResult search(String keyword, Pageable pageable) throws IRISSearchException; 11 | 12 | LocationInformation findByProviderIdAndLocationId(String providerId, String locationId) throws IRISSearchException; 13 | } 14 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/search_client/eps/dto/IdSearch.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.search_client.eps.dto; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | @Data 10 | @Builder 11 | @NoArgsConstructor(access = AccessLevel.PRIVATE) 12 | @AllArgsConstructor(access = AccessLevel.PRIVATE) 13 | public class IdSearch { 14 | private String providerId; 15 | private String locationId; 16 | } 17 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/search_client/eps/dto/KeywordSearch.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.search_client.eps.dto; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | @Data 10 | @Builder 11 | @NoArgsConstructor(access = AccessLevel.PRIVATE) 12 | @AllArgsConstructor(access = AccessLevel.PRIVATE) 13 | public class KeywordSearch { 14 | 15 | private String searchKeyword; 16 | private PageableDto pageable; 17 | } 18 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/search_client/eps/dto/PageableDto.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.search_client.eps.dto; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | import org.springframework.data.domain.Sort; 10 | 11 | @Builder 12 | @Data 13 | @NoArgsConstructor(access = AccessLevel.PRIVATE) 14 | @AllArgsConstructor(access = AccessLevel.PRIVATE) 15 | public class PageableDto { 16 | private int page; 17 | private int size; 18 | private String sortBy; 19 | private Sort.Direction direction = Sort.DEFAULT_DIRECTION; 20 | } 21 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/search_client/exceptions/IRISSearchException.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.search_client.exceptions; 2 | 3 | public class IRISSearchException extends RuntimeException { 4 | 5 | private static final long serialVersionUID = -4937902884117098576L; 6 | 7 | public IRISSearchException(String failedMethod, Throwable cause) { 8 | super("Call to '" + failedMethod + "' failed", cause); 9 | } 10 | 11 | public IRISSearchException(Throwable cause) { 12 | super(cause); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/statistics/web/dto/StatisticsDTO.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.statistics.web.dto; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | @Data 10 | @Builder 11 | @NoArgsConstructor(access = AccessLevel.PRIVATE) 12 | @AllArgsConstructor(access = AccessLevel.PRIVATE) 13 | public class StatisticsDTO { 14 | private int eventsCount; 15 | private int indexCasesCount; 16 | private int sumStatus; 17 | } 18 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/status/AppInfo.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.status; 2 | 3 | import lombok.Data; 4 | import lombok.RequiredArgsConstructor; 5 | 6 | import org.apache.commons.lang3.StringUtils; 7 | 8 | /** 9 | * @author Jens Kutzsche 10 | */ 11 | @Data 12 | @RequiredArgsConstructor 13 | public class AppInfo { 14 | 15 | private final String name; 16 | private final String version; 17 | private AppStatus status; 18 | 19 | boolean isTooOld() { 20 | return StringUtils.isBlank(version); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/status/AppStatusException.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.status; 2 | 3 | /** 4 | * @author Jens Kutzsche 5 | */ 6 | public class AppStatusException extends RuntimeException { 7 | 8 | private static final long serialVersionUID = 3580183974567793366L; 9 | 10 | public AppStatusException(String message) { 11 | super(message); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/status/AppStatusInternalException.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.status; 2 | 3 | import lombok.EqualsAndHashCode; 4 | import lombok.Value; 5 | 6 | /** 7 | * @author Jens Kutzsche 8 | */ 9 | @Value 10 | @EqualsAndHashCode(callSuper = true) 11 | public class AppStatusInternalException extends AppStatusException { 12 | 13 | private static final long serialVersionUID = -298204038489192894L; 14 | private Throwable exception; 15 | 16 | public AppStatusInternalException(String message, Throwable t) { 17 | super(message); 18 | 19 | this.exception = t; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/status/Apps.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.status; 2 | 3 | import iris.client_bff.status.Apps.App; 4 | 5 | import java.util.Comparator; 6 | import java.util.Iterator; 7 | import java.util.List; 8 | 9 | import org.springframework.data.util.Streamable; 10 | 11 | /** 12 | * @author Jens Kutzsche 13 | */ 14 | public record Apps(List apps) implements Streamable { 15 | 16 | @Override 17 | public Iterator iterator() { 18 | return apps.iterator(); 19 | } 20 | 21 | public Apps sort() { 22 | 23 | apps.sort(Comparator.comparing(App::name, String.CASE_INSENSITIVE_ORDER)); 24 | 25 | return this; 26 | } 27 | 28 | public record App(String name) {} 29 | } 30 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/status/EpsConnectionException.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.status; 2 | 3 | /** 4 | * @author Jens Kutzsche 5 | */ 6 | public class EpsConnectionException extends AppStatusException { 7 | 8 | private static final long serialVersionUID = 5854436436213842804L; 9 | 10 | public EpsConnectionException(String message) { 11 | super(message); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/users/IrisAuditorAware.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.users; 2 | 3 | import iris.client_bff.users.UserAccount.UserAccountIdentifier; 4 | import lombok.RequiredArgsConstructor; 5 | 6 | import java.util.Optional; 7 | import java.util.UUID; 8 | 9 | import org.springframework.data.domain.AuditorAware; 10 | import org.springframework.stereotype.Component; 11 | 12 | @Component 13 | @RequiredArgsConstructor 14 | class IrisAuditorAware implements AuditorAware { 15 | 16 | private final AuthenticatedUserAware authManager; 17 | 18 | @Override 19 | public Optional getCurrentAuditor() { 20 | 21 | return authManager.getCurrentUser() 22 | .map(UserAccount::getId) 23 | .map(UserAccountIdentifier::toUuid); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/users/UserRole.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.users; 2 | 3 | import lombok.NonNull; 4 | 5 | import java.util.Arrays; 6 | 7 | public enum UserRole { 8 | 9 | ADMIN, USER, DELETED, ANONYMOUS; 10 | 11 | public static boolean isUserRole(@NonNull String candidate) { 12 | 13 | return Arrays.stream(UserRole.values()) 14 | .map(UserRole::name) 15 | .anyMatch(candidate::equals); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/users/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * The user management and persistence of the IRIS client. This is about managing the data of users of the client. The 3 | * identification and provision of the currently authenticated user is also part of the package. Functions based on 4 | * this, such as authentication and authorization, are not part of this package. 5 | * 6 | * @author Jens Kutzsche 7 | */ 8 | package iris.client_bff.users; 9 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/vaccination_info/VaccinationInfoAnnouncementException.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.vaccination_info; 2 | 3 | /** 4 | * @author Jens Kutzsche 5 | */ 6 | public class VaccinationInfoAnnouncementException extends RuntimeException { 7 | 8 | private static final long serialVersionUID = -62922796972802753L; 9 | 10 | public VaccinationInfoAnnouncementException(String msg, Throwable e) { 11 | super(msg, e); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/vaccination_info/VaccinationInfoAnnouncementRepository.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.vaccination_info; 2 | 3 | import iris.client_bff.core.model.AggregateRepository; 4 | import iris.client_bff.vaccination_info.VaccinationInfoAnnouncement.AnnouncementIdentifier; 5 | 6 | /** 7 | * @author Jens Kutzsche 8 | */ 9 | public interface VaccinationInfoAnnouncementRepository 10 | extends AggregateRepository {} 11 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/vaccination_info/VaccinationInfoRepository.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.vaccination_info; 2 | 3 | import iris.client_bff.core.model.AggregateRepository; 4 | import iris.client_bff.vaccination_info.VaccinationInfo.VaccinationInfoIdentifier; 5 | 6 | /** 7 | * @author Jens Kutzsche 8 | */ 9 | public interface VaccinationInfoRepository extends AggregateRepository {} 10 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/vaccination_info/VaccinationInfoToUserReferenceChecker.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.vaccination_info; 2 | 3 | import iris.client_bff.users.UserAccount; 4 | import iris.client_bff.users.UserAnonymizationReferenceChecker; 5 | import lombok.RequiredArgsConstructor; 6 | 7 | import org.springframework.stereotype.Component; 8 | 9 | /** 10 | * @author Jens Kutzsche 11 | */ 12 | @Component 13 | @RequiredArgsConstructor 14 | class VaccinationInfoToUserReferenceChecker implements UserAnonymizationReferenceChecker { 15 | 16 | private final VaccinationInfoRepository vaccRepo; 17 | private final VaccinationInfoAnnouncementRepository announcementRepo; 18 | 19 | @Override 20 | public boolean canUserBeAnonymized(UserAccount user) { 21 | return !vaccRepo.isReferencedToUser(user.getId().toUuid()) 22 | && !announcementRepo.isReferencedToUser(user.getId().toUuid()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/vaccination_info/VaccinationStatus.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.vaccination_info; 2 | 3 | import static iris.client_bff.core.serialization.FlexibleEnum.*; 4 | 5 | import lombok.NonNull; 6 | 7 | import com.fasterxml.jackson.annotation.JsonCreator; 8 | 9 | public enum VaccinationStatus { 10 | VACCINATED, NOT_VACCINATED, SUSPICIOUS_PROOF, UNKNOWN; 11 | 12 | @JsonCreator 13 | public static VaccinationStatus of(@NonNull String string) { 14 | return VaccinationStatus.valueOf(cleanStringForEnum(string)); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/vaccination_info/VaccinationType.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.vaccination_info; 2 | 3 | import static iris.client_bff.core.serialization.FlexibleEnum.*; 4 | 5 | import lombok.NonNull; 6 | 7 | import com.fasterxml.jackson.annotation.JsonCreator; 8 | 9 | /** 10 | * @author Jens Kutzsche 11 | */ 12 | public enum VaccinationType { 13 | COVID_19; 14 | 15 | @JsonCreator 16 | public static VaccinationType of(@NonNull String string) { 17 | return VaccinationType.valueOf(cleanStringForEnum(string)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/vaccination_info/eps/InvalidPublicKeyException.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.vaccination_info.eps; 2 | 3 | /** 4 | * @author Jens Kutzsche 5 | */ 6 | public class InvalidPublicKeyException extends RuntimeException { 7 | 8 | private static final long serialVersionUID = -62922796972802753L; 9 | 10 | public InvalidPublicKeyException(String msg, Throwable e) { 11 | super(msg, e); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/vaccination_info/message/dto/ExportSelectionDto.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.vaccination_info.message.dto; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.Set; 6 | import java.util.UUID; 7 | 8 | import javax.validation.Valid; 9 | import javax.validation.constraints.NotBlank; 10 | import javax.validation.constraints.NotEmpty; 11 | import javax.validation.constraints.NotNull; 12 | 13 | @Data 14 | public class ExportSelectionDto { 15 | 16 | @NotNull 17 | UUID report; 18 | 19 | @Valid 20 | @NotEmpty 21 | Set<@NotBlank String> employees; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/vaccination_info/message/dto/ImportSelectionDto.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.vaccination_info.message.dto; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.Set; 6 | 7 | import javax.validation.Valid; 8 | import javax.validation.constraints.NotBlank; 9 | import javax.validation.constraints.NotEmpty; 10 | 11 | @Data 12 | public class ImportSelectionDto { 13 | 14 | @Valid 15 | @NotEmpty 16 | Set<@NotBlank String> employees; 17 | 18 | } 19 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/java/iris/client_bff/vaccination_info/message/dto/ImportSelectionViewPayloadDto.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.vaccination_info.message.dto; 2 | 3 | import iris.client_bff.vaccination_info.web.VaccinationInfoDto; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | 7 | import java.util.Set; 8 | 9 | @Data 10 | @Builder 11 | public class ImportSelectionViewPayloadDto { 12 | private Selectables selectables; 13 | private Duplicates duplicates; 14 | 15 | @Data 16 | @Builder 17 | public static class Selectables { 18 | Set employees; 19 | } 20 | 21 | @Data 22 | @Builder 23 | public static class Duplicates { 24 | Set employees; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/.gitignore: -------------------------------------------------------------------------------- 1 | /application-local.properties 2 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/META-INF/spring-devtools.properties: -------------------------------------------------------------------------------- 1 | restart.include.com.github.briandilley.jsonrpc4j=/com.github.briandilley.jsonrpc4j* -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/application-dev_auth.properties: -------------------------------------------------------------------------------- 1 | security.auth=db 2 | security.auth.db.admin-user-name=admin 3 | security.auth.db.admin-user-password=admin 4 | security.auth.db.mfa.option=OPTIONAL_DEFAULT_FALSE 5 | 6 | security.jwt.set-secure=false 7 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/application-h2_db.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.driver-class-name=org.h2.Driver 2 | spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect 3 | spring.datasource.generate-unique-name=true 4 | spring.h2.console.enabled=true -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/application-mariadb.properties: -------------------------------------------------------------------------------- 1 | spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDB103Dialect 2 | 3 | spring.datasource.driver-class-name=org.mariadb.jdbc.Driver 4 | spring.datasource.url= 5 | spring.datasource.username= 6 | spring.datasource.password= 7 | 8 | spring.flyway.locations=classpath:/db/migration_mysql 9 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/application-mssql.properties: -------------------------------------------------------------------------------- 1 | spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.SQLServerDialect 2 | 3 | spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver 4 | spring.datasource.url= 5 | spring.datasource.username= 6 | spring.datasource.password= 7 | 8 | spring.flyway.locations=classpath:/db/migration_mssql 9 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/application-mysql.properties: -------------------------------------------------------------------------------- 1 | spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect 2 | 3 | spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver 4 | spring.datasource.url= 5 | spring.datasource.username= 6 | spring.datasource.password= 7 | 8 | spring.flyway.locations=classpath:/db/migration_mysql 9 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/application-prod_auth.properties: -------------------------------------------------------------------------------- 1 | security.auth=db 2 | security.auth.db.admin-user-name= 3 | security.auth.db.admin-user-password= 4 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/application-prod_db.properties: -------------------------------------------------------------------------------- 1 | spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL10Dialect 2 | 3 | spring.datasource.driver-class-name=org.postgresql.Driver 4 | spring.datasource.url= 5 | spring.datasource.username= 6 | spring.datasource.password= 7 | 8 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/application-prod_env.properties: -------------------------------------------------------------------------------- 1 | spring.jackson.serialization.indent-output=true 2 | 3 | # Proxy Settings 4 | http.client.proxy.host= 5 | http.client.proxy.port= 6 | 7 | springdoc.api-docs.enabled=false 8 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/application-psql_compose_db.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.driver-class-name=org.postgresql.Driver 2 | spring.datasource.url=jdbc:postgresql://localhost:5433/iris_client 3 | spring.datasource.username=postgres 4 | spring.datasource.password=postgres 5 | spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL10Dialect 6 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/application-stage_live.properties: -------------------------------------------------------------------------------- 1 | iris.backend-service.endpoint=locations-production-1 2 | proxy-service.targetProxy=public-proxy-production-1 -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/application-stage_staging.properties: -------------------------------------------------------------------------------- 1 | iris.backend-service.endpoint=ls-1 2 | proxy-service.targetProxy=public-proxy-1 -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/db/migration/V1002__introduce_announcements.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE event_data_request ADD announcement_token varchar(256) NULL; -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/db/migration/V1003__introduce_allowed_tokens.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE allowed_tokens ( 2 | jwt_token_digest varchar(255) primary key, 3 | user_name varchar(50) NOT NULL, 4 | expiration_time timestamp NOT NULL, 5 | created timestamp default now() 6 | ); -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/db/migration/V1005__add_login_attempts.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE login_attempts ( 2 | remote_addr varchar(32) NOT NULL, 3 | attempts int NOT NULL, 4 | next_warning_threshold int NOT NULL, 5 | waiting_time bigint NOT NULL, 6 | created timestamp NOT NULL, 7 | last_modified timestamp NOT NULL, 8 | PRIMARY KEY (remote_addr) 9 | ); 10 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/db/migration/V1006__login_attempts_rename_column.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE login_attempts RENAME COLUMN remote_addr TO reference; 2 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/db/migration/V1007__readable_token_for_cases.sql: -------------------------------------------------------------------------------- 1 | DELETE FROM case_event; 2 | DELETE FROM contact; 3 | DELETE FROM case_data_submission; 4 | DELETE FROM case_data_request; 5 | 6 | ALTER TABLE case_data_request ADD data_authorization_token VARCHAR(255) NOT NULL; 7 | ALTER TABLE case_data_request ADD readable_token VARCHAR(255) NOT NULL; 8 | ALTER TABLE case_data_request DROP dw_submission_uri; -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/db/migration/V1010__add_vaccination_info_announcement.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE vaccination_info_announcement ( 2 | id uuid NOT NULL, 3 | external_id varchar(100) NOT NULL, 4 | announcement_token varchar(256) NULL, 5 | created timestamp NOT NULL, 6 | last_modified timestamp NOT NULL, 7 | created_by uuid NULL, 8 | last_modified_by uuid NULL, 9 | PRIMARY KEY (id), 10 | FOREIGN KEY (created_by) REFERENCES user_accounts(user_id), 11 | FOREIGN KEY (last_modified_by) REFERENCES user_accounts(user_id) 12 | ); 13 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/db/migration/V1012__add_iris_message_data.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE iris_message_data ( 2 | id uuid NOT NULL, 3 | message_id uuid NOT NULL, 4 | discriminator varchar(255) NOT NULL, 5 | payload bytea NOT NULL, 6 | description varchar(255) NOT NULL, 7 | is_imported bool NULL, 8 | created timestamp NOT NULL, 9 | last_modified timestamp NOT NULL, 10 | created_by uuid NULL, 11 | last_modified_by uuid NULL, 12 | CONSTRAINT iris_message_data_message_fk FOREIGN KEY (message_id) REFERENCES iris_message(id), 13 | FOREIGN KEY (created_by) REFERENCES user_accounts(user_id), 14 | FOREIGN KEY (last_modified_by) REFERENCES user_accounts(user_id) 15 | ); -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/db/migration/V1013__extends_user_account.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE user_accounts ADD locked boolean DEFAULT false NOT NULL; 2 | ALTER TABLE user_accounts ADD deleted_at timestamp NULL; -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/db/migration/V1014__add_settings.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE settings ( 2 | name varchar(50) primary key, 3 | stored_value varchar(1000) NOT NULL, 4 | saved_at date NOT NULL 5 | ); 6 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/db/migration/V1015__add_mfa.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE user_accounts ADD mfa_secret_enrolled BOOLEAN DEFAULT FALSE NOT NULL; 2 | ALTER TABLE user_accounts ADD mfa_secret varchar(128) NULL; -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/db/migration_mssql/V1002__introduce_announcements.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE event_data_request ADD announcement_token varchar(256) NULL; -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/db/migration_mssql/V1003__introduce_allowed_tokens.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE allowed_tokens ( 2 | jwt_token_digest varchar(255) primary key, 3 | user_name varchar(50) NOT NULL, 4 | expiration_time datetime2 NOT NULL, 5 | created datetime2 default SYSDATETIME() 6 | ); -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/db/migration_mssql/V1005__add_login_attempts.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE login_attempts ( 2 | reference varchar(32) NOT NULL, 3 | attempts int NOT NULL, 4 | next_warning_threshold int NOT NULL, 5 | waiting_time bigint NOT NULL, 6 | created datetime2 NOT NULL, 7 | last_modified datetime2 NOT NULL, 8 | PRIMARY KEY (reference) 9 | ); 10 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/db/migration_mssql/V1007__readable_token_for_cases.sql: -------------------------------------------------------------------------------- 1 | DELETE FROM case_event; 2 | DELETE FROM contact; 3 | DELETE FROM case_data_submission; 4 | DELETE FROM case_data_request; 5 | 6 | ALTER TABLE case_data_request ADD data_authorization_token VARCHAR(255) NOT NULL; 7 | ALTER TABLE case_data_request ADD readable_token VARCHAR(255) NOT NULL; 8 | ALTER TABLE case_data_request DROP COLUMN dw_submission_uri; -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/db/migration_mssql/V1010__add_vaccination_info_announcement.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE vaccination_info_announcement ( 2 | id binary(255) NOT NULL, 3 | external_id varchar(100) NOT NULL, 4 | announcement_token varchar(256) NULL, 5 | created datetime2 NOT NULL, 6 | last_modified datetime2 NOT NULL, 7 | created_by binary(255) NULL, 8 | last_modified_by binary(255) NULL, 9 | PRIMARY KEY (id), 10 | FOREIGN KEY (created_by) REFERENCES user_accounts(user_id), 11 | FOREIGN KEY (last_modified_by) REFERENCES user_accounts(user_id) 12 | ); 13 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/db/migration_mssql/V1012__add_iris_message_data.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE iris_message_data ( 2 | id binary(255) NOT NULL, 3 | message_id binary(255) NOT NULL, 4 | discriminator varchar(255) NOT NULL, 5 | payload varbinary(max) NOT NULL, 6 | description varchar(255) NOT NULL, 7 | is_imported bit NULL, 8 | created datetime2 NOT NULL, 9 | last_modified datetime2 NOT NULL, 10 | created_by binary(255) NULL, 11 | last_modified_by binary(255) NULL, 12 | CONSTRAINT iris_message_data_message_fk FOREIGN KEY (message_id) REFERENCES iris_message(id), 13 | FOREIGN KEY (created_by) REFERENCES user_accounts(user_id), 14 | FOREIGN KEY (last_modified_by) REFERENCES user_accounts(user_id) 15 | ); -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/db/migration_mssql/V1013__extends_user_account.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE user_accounts ADD locked bit DEFAULT 0 NOT NULL; 2 | ALTER TABLE user_accounts ADD deleted_at datetime2 NULL; -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/db/migration_mssql/V1014__add_settings.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE settings ( 2 | name varchar(50) primary key, 3 | stored_value varchar(1000) NOT NULL, 4 | saved_at date NOT NULL 5 | ); 6 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/db/migration_mssql/V1015__add_mfa.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE user_accounts ADD mfa_secret_enrolled Bit DEFAULT 0 NOT NULL; 2 | ALTER TABLE user_accounts ADD mfa_secret varchar(128) NULL; -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/db/migration_mysql/V1002__introduce_announcements.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE event_data_request ADD announcement_token varchar(256) NULL; -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/db/migration_mysql/V1003__introduce_allowed_tokens.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE allowed_tokens ( 2 | jwt_token_digest varchar(255) primary key, 3 | user_name varchar(50) NOT NULL, 4 | expiration_time timestamp NOT NULL, 5 | created timestamp default now() 6 | ); -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/db/migration_mysql/V1005__add_login_attempts.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE login_attempts ( 2 | reference varchar(32) NOT NULL, 3 | attempts int NOT NULL, 4 | next_warning_threshold int NOT NULL, 5 | waiting_time bigint NOT NULL, 6 | created timestamp NOT NULL, 7 | last_modified timestamp NOT NULL, 8 | PRIMARY KEY (reference) 9 | ); 10 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/db/migration_mysql/V1007__readable_token_for_cases.sql: -------------------------------------------------------------------------------- 1 | DELETE FROM case_event; 2 | DELETE FROM contact; 3 | DELETE FROM case_data_submission; 4 | DELETE FROM case_data_request; 5 | 6 | ALTER TABLE case_data_request ADD data_authorization_token VARCHAR(255) NOT NULL; 7 | ALTER TABLE case_data_request ADD readable_token VARCHAR(255) NOT NULL; 8 | ALTER TABLE case_data_request DROP dw_submission_uri; -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/db/migration_mysql/V1010__add_vaccination_info_announcement.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE vaccination_info_announcement ( 2 | id binary(16) NOT NULL, 3 | external_id varchar(100) NOT NULL, 4 | announcement_token varchar(256) NULL, 5 | created datetime NOT NULL, 6 | last_modified datetime NOT NULL, 7 | created_by binary(16) NULL, 8 | last_modified_by binary(16) NULL, 9 | PRIMARY KEY (id), 10 | FOREIGN KEY (created_by) REFERENCES user_accounts(user_id), 11 | FOREIGN KEY (last_modified_by) REFERENCES user_accounts(user_id) 12 | ); 13 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/db/migration_mysql/V1012__add_iris_message_data.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE iris_message_data ( 2 | id binary(16) NOT NULL, 3 | message_id binary(16) NOT NULL, 4 | discriminator varchar(255) NOT NULL, 5 | payload mediumblob NOT NULL, 6 | description varchar(255) NOT NULL, 7 | is_imported bool NULL, 8 | created datetime NOT NULL, 9 | last_modified datetime NOT NULL, 10 | created_by binary(16) NULL, 11 | last_modified_by binary(16) NULL, 12 | CONSTRAINT iris_message_data_message_fk FOREIGN KEY (message_id) REFERENCES iris_message(id), 13 | FOREIGN KEY (created_by) REFERENCES user_accounts(user_id), 14 | FOREIGN KEY (last_modified_by) REFERENCES user_accounts(user_id) 15 | ); -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/db/migration_mysql/V1013__extends_user_account.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE user_accounts ADD locked boolean DEFAULT false NOT NULL; 2 | ALTER TABLE user_accounts ADD deleted_at DATETIME NULL; -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/db/migration_mysql/V1014__add_settings.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE settings ( 2 | name varchar(50) primary key, 3 | stored_value varchar(1000) NOT NULL, 4 | saved_at date NOT NULL 5 | ); 6 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/db/migration_mysql/V1015__add_mfa.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE user_accounts ADD mfa_secret_enrolled boolean DEFAULT false NOT NULL; 2 | ALTER TABLE user_accounts ADD mfa_secret varchar(128) NULL; -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/iris-banner.txt: -------------------------------------------------------------------------------- 1 | 2 | _____ _____ _____ _____ 3 | |_ _| __ \|_ _|/ ____| ${spring.application.name} 4 | | | | |__) | | | | (___ 5 | | | | _ / | | \___ \ 6 | _| |_| | \ \ _| |_ ____) | 7 | |_____|_| \_\_____|_____/ ${application.version} 8 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BFF 6 | 7 | 8 | 9 | 10 | %clr(%d{"yyyy-MM-dd'T'HH:mm:ss,SSSXXX", UTC}){faint} %clr(%-5level) %clr(${PID:- }){magenta} %clr(%contextName){cyan} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx} 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /iris-client-bff/src/main/resources/mail-templates/event-data-received-mail_en.ftlh: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

Dear Sir or Madam,

8 |


9 |

New data is available for the Event "${eventId}" in your IRIS Portal.

10 |

Event:

11 |
    12 |
  • Event: ${eventId}
  • 13 |
  • External Id: ${externalId}
  • 14 |
  • Start: ${startTime?datetime?string.long}
  • 15 |
  • End: ${endTime?datetime?string.long}
  • 16 |
17 |

18 | With the provided data the event can be identified online. Alternatively the following link will redirect to it directly: Event ${eventId} 19 |

20 |


21 |

22 | With kind regards,
23 | IRIS connect
24 | Innovationsverbund Öffentliche Gesundheit (InÖG) 25 |

26 |


27 |

This is an automated message. Please do not reply.

28 | 29 | -------------------------------------------------------------------------------- /iris-client-bff/src/test/java/iris/client_bff/DataInitializer.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff; 2 | 3 | import org.springframework.stereotype.Component; 4 | import org.springframework.transaction.annotation.Transactional; 5 | 6 | /** 7 | * For data initialization on application startup. 8 | * 9 | * @author Jens Kutzsche 10 | */ 11 | @Component 12 | public interface DataInitializer { 13 | 14 | @Transactional 15 | void initialize(); 16 | } 17 | -------------------------------------------------------------------------------- /iris-client-bff/src/test/java/iris/client_bff/WithMockIrisUser.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Inherited; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | import org.springframework.security.test.context.support.WithMockUser; 11 | 12 | @WithMockUser(value = "user", authorities = "USER") 13 | @Target({ ElementType.METHOD, ElementType.TYPE }) 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Inherited 16 | @Documented 17 | public @interface WithMockIrisUser {} 18 | -------------------------------------------------------------------------------- /iris-client-bff/src/test/java/iris/client_bff/dbms/MSSQLServerIT.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.dbms; 2 | 3 | import org.springframework.boot.test.context.SpringBootTest; 4 | import org.springframework.test.context.ActiveProfiles; 5 | import org.springframework.test.context.TestConstructor; 6 | import org.springframework.test.context.TestConstructor.AutowireMode; 7 | 8 | @ActiveProfiles({ "dev", "inttest", "test", "mssql" }) 9 | @SpringBootTest(properties = { "spring.datasource.url=jdbc:tc:sqlserver:2019-latest:///db", 10 | "spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver" }) 11 | @TestConstructor(autowireMode = AutowireMode.ALL) 12 | class MSSQLServerIT extends DatabasesystemIT {} 13 | -------------------------------------------------------------------------------- /iris-client-bff/src/test/java/iris/client_bff/dbms/MariaDBIT.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.dbms; 2 | 3 | import org.springframework.boot.test.context.SpringBootTest; 4 | import org.springframework.test.context.ActiveProfiles; 5 | import org.springframework.test.context.TestConstructor; 6 | import org.springframework.test.context.TestConstructor.AutowireMode; 7 | 8 | @ActiveProfiles({ "dev", "inttest", "test", "mariadb" }) 9 | @SpringBootTest(properties = { "spring.datasource.url=jdbc:tc:mariadb:10.6.4:///db", 10 | "spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver" }) 11 | @TestConstructor(autowireMode = AutowireMode.ALL) 12 | class MariaDBIT extends DatabasesystemIT {} 13 | -------------------------------------------------------------------------------- /iris-client-bff/src/test/java/iris/client_bff/dbms/MySQLIT.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.dbms; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.ActiveProfiles; 7 | import org.springframework.test.context.TestConstructor; 8 | import org.springframework.test.context.TestConstructor.AutowireMode; 9 | 10 | @ActiveProfiles({ "dev", "inttest", "test", "mysql" }) 11 | @SpringBootTest(properties = { "spring.datasource.url=jdbc:tc:mysql:8.0.26:///db", 12 | "spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver" }) 13 | @TestConstructor(autowireMode = AutowireMode.ALL) 14 | @RequiredArgsConstructor 15 | class MySQLIT extends DatabasesystemIT {} 16 | -------------------------------------------------------------------------------- /iris-client-bff/src/test/java/iris/client_bff/dbms/PostgresIT.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.dbms; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.ActiveProfiles; 7 | import org.springframework.test.context.TestConstructor; 8 | import org.springframework.test.context.TestConstructor.AutowireMode; 9 | 10 | @ActiveProfiles({ "dev", "inttest", "test", "prod_db" }) 11 | @SpringBootTest(properties = { "spring.datasource.url=jdbc:tc:postgresql:13.5-alpine:///db", 12 | "spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver" }) 13 | @TestConstructor(autowireMode = AutowireMode.ALL) 14 | @RequiredArgsConstructor 15 | class PostgresIT extends DatabasesystemIT {} 16 | -------------------------------------------------------------------------------- /iris-client-bff/src/test/java/iris/client_bff/events/LocationRepository.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.events; 2 | 3 | import iris.client_bff.events.model.Location; 4 | import iris.client_bff.events.model.Location.LocationIdentifier; 5 | 6 | import org.springframework.data.jpa.repository.JpaRepository; 7 | 8 | /** 9 | * @author Jens Kutzsche 10 | */ 11 | public interface LocationRepository extends JpaRepository {} 12 | -------------------------------------------------------------------------------- /iris-client-bff/src/test/java/iris/client_bff/events/web/TestData.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.events.web; 2 | 3 | public class TestData { 4 | 5 | public static final String DATA_REQUEST = "{\"locationId\":\"7dd80f34-f9cd-456a-9b60-357d0a3485c7\",\n" + 6 | " \"providerId\":\"00000-00000-00000-00000\",\n" + 7 | " \"name\":\"string\",\n" + 8 | " \"externalRequestId\":\"string\",\n" + 9 | " \"start\":\"2021-03-29T23:00:10.113Z\",\n" + 10 | " \"end\":\"2021-03-29T23:00:34.113Z\",\n" + 11 | " \"requestDetails\":\"string\"\n" + 12 | "}"; 13 | } 14 | -------------------------------------------------------------------------------- /iris-client-bff/src/test/java/iris/client_bff/matchers/IrisMatchers.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.matchers; 2 | 3 | import static org.hamcrest.Matchers.*; 4 | 5 | import org.apache.commons.lang3.StringUtils; 6 | import org.hamcrest.FeatureMatcher; 7 | import org.hamcrest.Matcher; 8 | 9 | public class IrisMatchers { 10 | 11 | public static org.hamcrest.Matcher isUuid() { 12 | return IsUuid.uuidString(); 13 | } 14 | 15 | public static org.hamcrest.Matcher isCatWith(String proxyUrl) { 16 | return allOf( 17 | endsWith(proxyUrl), 18 | new HasToken(isUuid())); 19 | } 20 | 21 | static class HasToken extends FeatureMatcher { 22 | public HasToken(Matcher tokenMatcher) { 23 | super(tokenMatcher, "with token part", "token"); 24 | } 25 | 26 | @Override 27 | protected String featureValueOf(String actual) { 28 | return StringUtils.substringBefore(actual, "."); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /iris-client-bff/src/test/java/iris/client_bff/users/UserAccountsRepositoryForTests.java: -------------------------------------------------------------------------------- 1 | package iris.client_bff.users; 2 | 3 | import iris.client_bff.users.UserAccount.UserAccountIdentifier; 4 | 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | 7 | /** 8 | * @author Jens Kutzsche 9 | */ 10 | public interface UserAccountsRepositoryForTests extends JpaRepository { 11 | 12 | UserAccount findByUserName(String userName); 13 | } 14 | -------------------------------------------------------------------------------- /iris-client-bff/src/test/resources/container-license-acceptance.txt: -------------------------------------------------------------------------------- 1 | mcr.microsoft.com/mssql/server:2019-latest -------------------------------------------------------------------------------- /iris-client-bff/src/test/resources/mail-templates/test-html-mail_de.ftlh: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |

Hallo ${recipientName}

8 |

${text}

9 |

Viele Grüße,

10 |

11 | ${senderName}
12 | Gesundheitsamt XXX 13 |

14 | 15 | -------------------------------------------------------------------------------- /iris-client-bff/src/test/resources/mail-templates/test-mail.ftl: -------------------------------------------------------------------------------- 1 | Hi ${recipientName} 2 | 3 | ${text} 4 | 5 | Regards, 6 | ${senderName} 7 | 8 | Health Department XXX 9 | -------------------------------------------------------------------------------- /iris-client-bff/src/test/resources/mail-templates/test-mail_de.ftl: -------------------------------------------------------------------------------- 1 | Hallo ${recipientName}, 2 | 3 | ${text} 4 | 5 | Viele Grüße 6 | ${senderName} 7 | 8 | Gesundheitsamt XXX 9 | -------------------------------------------------------------------------------- /iris-client-bff/src/test/resources/messages.properties: -------------------------------------------------------------------------------- 1 | TestMail.subject=This is a test mail -------------------------------------------------------------------------------- /iris-client-bff/src/test/resources/messages_de_DE_test.properties: -------------------------------------------------------------------------------- 1 | TestMail.subject=Das ist eine Test-Mail -------------------------------------------------------------------------------- /iris-client-eps/README.md: -------------------------------------------------------------------------------- 1 | #IRIS EPS 2 | 3 | To communicate with the distributed services, IRIS uses its own EPS (endpoint server). The following describes how to install and configure the EPS. 4 | 5 | ## Local development setup 6 | 7 | ### Install EPS 8 | 9 | Please see iris-client-eps in gateway for instructions. 10 | 11 | -------------------------------------------------------------------------------- /iris-client-fe/.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not dead 4 | -------------------------------------------------------------------------------- /iris-client-fe/.env.bff_local: -------------------------------------------------------------------------------- 1 | VUE_APP_API_BASE_URL=http://localhost:8092 2 | 3 | VUE_APP_ENABLE_MOCK_SERVER=false 4 | 5 | VUE_APP_VERSION_ID=development 6 | VUE_APP_BUILD_ID=local 7 | 8 | VUE_APP_LOCAL_CONTACT_PERSON_NAME=Max Musterkontakt 9 | VUE_APP_LOCAL_CONTACT_PERSON_MAIL=max.musterkontakt@ga.de 10 | VUE_APP_LOCAL_CONTACT_PERSON_PHONE=069 123 4567 11 | 12 | VUE_APP_CSV_EXPORT_STANDARD_ATOMIC_ADDRESS=false 13 | -------------------------------------------------------------------------------- /iris-client-fe/.env.development: -------------------------------------------------------------------------------- 1 | VUE_APP_API_BASE_URL=http://localhost:8080 2 | 3 | VUE_APP_ENABLE_MOCK_SERVER=true 4 | 5 | VUE_APP_VERSION_ID=development 6 | VUE_APP_BUILD_ID=local 7 | 8 | VUE_APP_LOCAL_CONTACT_PERSON_NAME=Max Musterkontakt 9 | VUE_APP_LOCAL_CONTACT_PERSON_MAIL=max.musterkontakt@ga.de 10 | VUE_APP_LOCAL_CONTACT_PERSON_PHONE=069 123 4567 11 | 12 | VUE_APP_CSV_EXPORT_STANDARD_ATOMIC_ADDRESS=false 13 | -------------------------------------------------------------------------------- /iris-client-fe/.env.e2e_test: -------------------------------------------------------------------------------- 1 | NODE_ENV=production 2 | 3 | VUE_APP_API_BASE_URL=http://localhost:8080 4 | VUE_APP_ENABLE_MOCK_SERVER=true 5 | 6 | VUE_APP_VERSION_ID=version_e2e_test 7 | VUE_APP_BUILD_ID=build_e2e_test 8 | 9 | VUE_APP_LOCAL_CONTACT_PERSON_NAME=E2ETestName 10 | VUE_APP_LOCAL_CONTACT_PERSON_MAIL=E2ETestMail 11 | VUE_APP_LOCAL_CONTACT_PERSON_PHONE=E2ETestPhone 12 | 13 | VUE_APP_CSV_EXPORT_STANDARD_ATOMIC_ADDRESS=false 14 | -------------------------------------------------------------------------------- /iris-client-fe/.env.e2e_test_local.dist: -------------------------------------------------------------------------------- 1 | NODE_ENV=production 2 | 3 | # set the base url for the api you want to use for testing 4 | VUE_APP_API_BASE_URL=http://localhost:8080 5 | # disable the mock server if you want to test with a real server 6 | VUE_APP_ENABLE_MOCK_SERVER=true 7 | 8 | VUE_APP_VERSION_ID=version_e2e_test_local 9 | VUE_APP_BUILD_ID=build_e2e_test_local 10 | 11 | VUE_APP_LOCAL_CONTACT_PERSON_NAME=E2ETestName 12 | VUE_APP_LOCAL_CONTACT_PERSON_MAIL=E2ETestMail 13 | VUE_APP_LOCAL_CONTACT_PERSON_PHONE=E2ETestPhone 14 | 15 | VUE_APP_CSV_EXPORT_STANDARD_ATOMIC_ADDRESS=false 16 | -------------------------------------------------------------------------------- /iris-client-fe/.env.integration: -------------------------------------------------------------------------------- 1 | VUE_APP_API_BASE_URL=https://api.staging.iris-gateway.de 2 | 3 | VUE_APP_VERSION_ID=integration 4 | VUE_APP_BUILD_ID=local 5 | 6 | VUE_APP_LOCAL_CONTACT_PERSON_NAME= 7 | VUE_APP_LOCAL_CONTACT_PERSON_MAIL= 8 | VUE_APP_LOCAL_CONTACT_PERSON_PHONE= 9 | 10 | VUE_APP_CSV_EXPORT_STANDARD_ATOMIC_ADDRESS=false 11 | -------------------------------------------------------------------------------- /iris-client-fe/.env.production: -------------------------------------------------------------------------------- 1 | # This value is a placeholder which is then replaced by caddys template engine for the given env variable SORMAS_SIDECAR_BASE_URL 2 | VUE_APP_API_BASE_URL="{{env "SORMAS_SIDECAR_BASE_URL"}}" 3 | 4 | VUE_APP_VERSION_ID=production 5 | VUE_APP_BUILD_ID=local 6 | 7 | VUE_APP_LOCAL_CONTACT_PERSON_NAME="{{env "LOCAL_CONTACT_PERSON_NAME"}}" 8 | VUE_APP_LOCAL_CONTACT_PERSON_MAIL="{{env "LOCAL_CONTACT_PERSON_MAIL"}}" 9 | VUE_APP_LOCAL_CONTACT_PERSON_PHONE="{{env "LOCAL_CONTACT_PERSON_PHONE"}}" 10 | 11 | VUE_APP_CSV_EXPORT_STANDARD_ATOMIC_ADDRESS="{{env "CSV_EXPORT_STANDARD_ATOMIC_ADDRESS"}}" 12 | -------------------------------------------------------------------------------- /iris-client-fe/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # local cypress env files 10 | .env.e2e_test_local 11 | cypress.env.json 12 | 13 | # test files 14 | cypress 15 | tests/e2e/screenshots 16 | tests/e2e/videos 17 | tests/e2e/downloads 18 | 19 | # Log files 20 | npm-debug.log* 21 | yarn-debug.log* 22 | yarn-error.log* 23 | pnpm-debug.log* 24 | 25 | # Editor directories and files 26 | .idea 27 | .vscode 28 | *.suo 29 | *.ntvs* 30 | *.njsproj 31 | *.sln 32 | *.sw? -------------------------------------------------------------------------------- /iris-client-fe/.nvmrc: -------------------------------------------------------------------------------- 1 | lts/gallium -------------------------------------------------------------------------------- /iris-client-fe/Caddyfile: -------------------------------------------------------------------------------- 1 | # exposed port 2 | :28080 { 3 | 4 | # define web root 5 | root * /usr/share/caddy 6 | 7 | # enable caddy template engine for index.html 8 | templates index.html 9 | 10 | # enable file server for all paths under web root 11 | file_server /* 12 | 13 | # If the request does not match any static files, 14 | # rewrite to index.html for client side routing 15 | try_files {path} /index.html 16 | 17 | } -------------------------------------------------------------------------------- /iris-client-fe/autosave.json: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /iris-client-fe/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ["@vue/cli-plugin-babel/preset"], 3 | }; 4 | -------------------------------------------------------------------------------- /iris-client-fe/cypress.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "cypress"; 2 | 3 | export default defineConfig({ 4 | fixturesFolder: "tests/e2e/fixtures", 5 | screenshotsFolder: "tests/e2e/screenshots", 6 | downloadsFolder: "tests/e2e/downloads", 7 | videosFolder: "tests/e2e/videos", 8 | env: { 9 | FAIL_FAST_ENABLED: false, 10 | }, 11 | e2e: { 12 | setupNodeEvents(on, config) { 13 | // eslint-disable-next-line @typescript-eslint/no-var-requires 14 | require("cypress-fail-fast/plugin")(on, config); 15 | config.env.MOCK_SERVER = 16 | process.env.VUE_APP_ENABLE_MOCK_SERVER === "true"; 17 | return config; 18 | }, 19 | specPattern: "tests/e2e/specs/**/*.{js,jsx,ts,tsx}", 20 | supportFile: "tests/e2e/support/index.js", 21 | excludeSpecPattern: process.env.CI ? ["tests/e2e/specs/all.cy.ts"] : [], 22 | }, 23 | }); 24 | -------------------------------------------------------------------------------- /iris-client-fe/cypress.env.json.dist: -------------------------------------------------------------------------------- 1 | { 2 | "auth_username": "username", 3 | "auth_password": "password" 4 | } -------------------------------------------------------------------------------- /iris-client-fe/docs/RESOURCES.md: -------------------------------------------------------------------------------- 1 | # Helpful links and resources 2 | 3 | ## Vue.js 4 | 5 | - https://github.com/marekbrainhub/vue-developer-roadmap 6 | - https://vuejs.org/v2/guide/ 7 | - https://vuejs.org/v2/guide/typescript.html 8 | 9 | ## Routing 10 | 11 | - https://router.vuejs.org/guide/ 12 | 13 | ## State management 14 | 15 | - https://vuex.vuejs.org/guide/ 16 | 17 | ## Vuetify 18 | 19 | - https://vuetifyjs.com/en/introduction/why-vuetify/ 20 | 21 | ## TypeScript 22 | 23 | - https://www.typescriptlang.org/docs/handbook/typescript-from-scratch.html 24 | 25 | ## Linting 26 | 27 | - https://eslint.org/docs/user-guide/getting-started 28 | - https://prettier.io/docs/en/index.html 29 | 30 | ## VS Code 31 | 32 | - https://code.visualstudio.com/docs 33 | - https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint 34 | - https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode 35 | 36 | ## WebPack 37 | 38 | - https://webpack.js.org/guides/getting-started/ 39 | -------------------------------------------------------------------------------- /iris-client-fe/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: "@vue/cli-plugin-unit-jest/presets/typescript-and-babel", 3 | }; 4 | -------------------------------------------------------------------------------- /iris-client-fe/public/android-chrome-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/iris-client-fe/public/android-chrome-96x96.png -------------------------------------------------------------------------------- /iris-client-fe/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/iris-client-fe/public/apple-touch-icon.png -------------------------------------------------------------------------------- /iris-client-fe/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/iris-client-fe/public/favicon-16x16.png -------------------------------------------------------------------------------- /iris-client-fe/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/iris-client-fe/public/favicon-32x32.png -------------------------------------------------------------------------------- /iris-client-fe/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/iris-client-fe/public/favicon.ico -------------------------------------------------------------------------------- /iris-client-fe/public/favicon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /iris-client-fe/public/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/iris-client-fe/public/mstile-150x150.png -------------------------------------------------------------------------------- /iris-client-fe/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: / -------------------------------------------------------------------------------- /iris-client-fe/src/api/base.ts: -------------------------------------------------------------------------------- 1 | import globalAxios, { AxiosInstance } from "axios"; 2 | import { apiRequestBuilder, ApiRequestFunction } from "@/api/common"; 3 | 4 | /** 5 | * 6 | * @export 7 | * @class BaseAPI 8 | */ 9 | export class BaseAPI { 10 | protected axios: AxiosInstance | undefined; 11 | protected apiRequest: ApiRequestFunction; 12 | constructor(axios: AxiosInstance = globalAxios) { 13 | if (axios) { 14 | this.axios = axios; 15 | } 16 | this.apiRequest = apiRequestBuilder(this.axios); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /iris-client-fe/src/api/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./api"; 2 | -------------------------------------------------------------------------------- /iris-client-fe/src/assets/logo-iris-connect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iris-connect/iris-client/40d8a7f1a5991877cc297bb9645cfca9b7022667/iris-client-fe/src/assets/logo-iris-connect.png -------------------------------------------------------------------------------- /iris-client-fe/src/assets/scss/base/_global.scss: -------------------------------------------------------------------------------- 1 | .theme--light.v-btn { 2 | color: rgba(0, 0, 0, 0.87) !important; 3 | } 4 | 5 | a:active, 6 | .v-btn--active, 7 | a:hover { 8 | outline-width: 0; 9 | text-decoration: underline #46ff9f; 10 | text-decoration-thickness: 3px; 11 | text-underline-offset: 3px; 12 | } 13 | 14 | .theme--light.v-btn--active:hover::before, 15 | .theme--light.v-btn--active::before { 16 | opacity: 0; 17 | } 18 | 19 | .v-data-table { 20 | thead { 21 | tr { 22 | height: initial; 23 | } 24 | } 25 | tr { 26 | height: initial; 27 | /*height: 100px; TODO: Fix this shit. It applies to all data-tables globally.*/ 28 | } 29 | } 30 | 31 | .twolineTable { 32 | tr { 33 | height: 100px; 34 | } 35 | } 36 | 37 | .alertOverlay { 38 | position: fixed; 39 | z-index: 9999; 40 | bottom: 1rem; 41 | left: 2rem; 42 | right: 2rem; 43 | } 44 | 45 | .cursor-pointer { 46 | cursor: pointer; 47 | } -------------------------------------------------------------------------------- /iris-client-fe/src/assets/scss/modules/_card.scss: -------------------------------------------------------------------------------- 1 | .v-sheet.v-card { 2 | border-radius: .428rem; 3 | box-shadow: none !important; 4 | &.primary{ 5 | .v-btn{ 6 | background-color: #fff !important; 7 | border-color: #fff !important; 8 | } 9 | } 10 | &.v-card-table{ 11 | .v-card__text{ 12 | padding: 0; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /iris-client-fe/src/assets/scss/modules/_stepper.scss: -------------------------------------------------------------------------------- 1 | .v-application--is-ltr { 2 | .v-stepper--vertical { 3 | width: 100%; 4 | padding-bottom: 0; 5 | .v-stepper__step__step { 6 | border-radius: 0; 7 | font-size: 1rem; 8 | width: 36px; 9 | height: 36px; 10 | } 11 | .v-stepper__step { 12 | padding: 0 !important; 13 | margin-top: 8px !important; 14 | margin-bottom: 8px !important; 15 | } 16 | .v-stepper__content { 17 | margin: 0 !important; 18 | padding: 0 0 0 18px !important; 19 | border-left: 1px solid rgba(0, 0, 0, 0.12); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /iris-client-fe/src/assets/scss/modules/_table.scss: -------------------------------------------------------------------------------- 1 | .v-data-table{ 2 | .v-data-table__wrapper > table > thead > tr > th { 3 | color: #106a81 !important; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /iris-client-fe/src/assets/scss/modules/_tabs.scss: -------------------------------------------------------------------------------- 1 | .v-tab.v-tab--active { 2 | color: #106a81 !important; 3 | } 4 | 5 | .v-tabs-slider { 6 | color: #106a81 !important; 7 | } 8 | -------------------------------------------------------------------------------- /iris-client-fe/src/assets/scss/theme.scss: -------------------------------------------------------------------------------- 1 | 2 | @import 'utilities/variables'; 3 | @import 'utilities/mixins'; 4 | @import 'modules/card'; 5 | @import 'modules/table'; 6 | @import 'modules/tabs'; 7 | @import "modules/stepper"; 8 | @import 'base/global'; 9 | -------------------------------------------------------------------------------- /iris-client-fe/src/assets/scss/utilities/_mixins.scss: -------------------------------------------------------------------------------- 1 | 2 | .light-font{ 3 | font-weight: 300; 4 | } 5 | -------------------------------------------------------------------------------- /iris-client-fe/src/assets/scss/utilities/_variables.scss: -------------------------------------------------------------------------------- 1 | //Color palettes 2 | //Generic Gradient #46FF9F #00B6B0 #0E6A81 3 | //Three #46FF9F #00C4FF #FF7666 4 | -------------------------------------------------------------------------------- /iris-client-fe/src/common/messages.ts: -------------------------------------------------------------------------------- 1 | const messages = { 2 | error: { 3 | sessionExpired: "Ihre Sitzung ist abgelaufen", 4 | accessDenied: 5 | "Sie haben nicht die erforderliche Berechtigung, um diese Aktion auszuführen", 6 | userNotFound: (id: string): string => `No User found for id: "${id}"`, 7 | }, 8 | }; 9 | 10 | export default messages; 11 | -------------------------------------------------------------------------------- /iris-client-fe/src/components/alerts/alert-component.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 22 | -------------------------------------------------------------------------------- /iris-client-fe/src/components/app-settings-menu.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 36 | -------------------------------------------------------------------------------- /iris-client-fe/src/components/dashboard/cases-bar-chart.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 29 | -------------------------------------------------------------------------------- /iris-client-fe/src/components/dashboard/cases-pie-chart.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 28 | -------------------------------------------------------------------------------- /iris-client-fe/src/components/form/password-input-field.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 24 | 30 | -------------------------------------------------------------------------------- /iris-client-fe/src/components/stepper/vertical-stepper.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 35 | 36 | 44 | -------------------------------------------------------------------------------- /iris-client-fe/src/constants/ContactCategories.ts: -------------------------------------------------------------------------------- 1 | import { ContactCategory } from "@/api"; 2 | 3 | const getCategory = function ( 4 | contactCategory: ContactCategory | null | undefined 5 | ): string { 6 | switch (contactCategory) { 7 | case ContactCategory.NoRisk: 8 | return "Kein Risiko"; 9 | case ContactCategory.LowRisk: 10 | return "Niedriges Risiko"; 11 | case ContactCategory.MediumRiskMed: 12 | return "Mittleres Risiko"; 13 | case ContactCategory.HighRiskMed: 14 | return "Erhöhtes Risiko"; 15 | case ContactCategory.HighRisk: 16 | return "Hohes Risiko"; 17 | default: 18 | return "Unbekannt"; // TODO find better name 19 | } 20 | }; 21 | 22 | const ContactCategories = { 23 | getCategory, 24 | }; 25 | 26 | export default ContactCategories; 27 | -------------------------------------------------------------------------------- /iris-client-fe/src/constants/Discriminators.ts: -------------------------------------------------------------------------------- 1 | import { IrisMessageDataDiscriminator } from "@/api"; 2 | 3 | const getLabel = (discriminator: IrisMessageDataDiscriminator): string => { 4 | switch (discriminator) { 5 | case IrisMessageDataDiscriminator.EventTracking: 6 | return "Ereignis"; 7 | case IrisMessageDataDiscriminator.VaccinationReport: 8 | return "Impfpflichtmeldung"; 9 | default: 10 | return "Ungültiger Datentyp"; 11 | } 12 | }; 13 | 14 | const Discriminators = { 15 | getLabel, 16 | }; 17 | 18 | export default Discriminators; 19 | -------------------------------------------------------------------------------- /iris-client-fe/src/constants/Genders.ts: -------------------------------------------------------------------------------- 1 | import { Sex } from "@/api"; 2 | 3 | const getName = function (sex?: string): string { 4 | switch (sex) { 5 | case Sex.Male: 6 | return "männlich"; 7 | case Sex.Female: 8 | return "weiblich"; 9 | case Sex.Other: 10 | return "divers"; 11 | default: 12 | return "unbekannt"; 13 | } 14 | }; 15 | 16 | const Genders = { 17 | getName, 18 | }; 19 | 20 | export default Genders; 21 | -------------------------------------------------------------------------------- /iris-client-fe/src/constants/StatusColors.ts: -------------------------------------------------------------------------------- 1 | import { DataRequestStatus } from "@/api"; 2 | 3 | const getColor = function (status?: DataRequestStatus): string { 4 | switch (status) { 5 | case DataRequestStatus.DataRequested: 6 | return "blue"; 7 | case DataRequestStatus.DataReceived: 8 | return "red"; 9 | case DataRequestStatus.Closed: 10 | return "green"; 11 | case DataRequestStatus.Aborted: 12 | return "black"; 13 | default: 14 | return "gray"; // TODO 15 | } 16 | }; 17 | 18 | const StatusColors = { 19 | getColor, 20 | }; 21 | 22 | export default StatusColors; 23 | -------------------------------------------------------------------------------- /iris-client-fe/src/constants/StatusMessages.ts: -------------------------------------------------------------------------------- 1 | import { DataRequestStatus } from "@/api"; 2 | 3 | const getMessage = function (status?: DataRequestStatus): string { 4 | switch (status) { 5 | case DataRequestStatus.DataRequested: 6 | return "Angefragt"; 7 | case DataRequestStatus.DataReceived: 8 | return "Geliefert"; 9 | case DataRequestStatus.Closed: 10 | return "Bearbeitet"; 11 | case DataRequestStatus.Aborted: 12 | return "Abgebrochen"; 13 | default: 14 | return "Unbekannt"; // TODO find better name 15 | } 16 | }; 17 | 18 | const StatusMessages = { 19 | getMessage, 20 | }; 21 | 22 | export default StatusMessages; 23 | -------------------------------------------------------------------------------- /iris-client-fe/src/constants/StatusTestLabel.ts: -------------------------------------------------------------------------------- 1 | import { DataRequestStatus } from "@/api"; 2 | 3 | const getStatusTestLabel = function (status?: DataRequestStatus): string { 4 | switch (status) { 5 | case DataRequestStatus.DataRequested: 6 | return "requested"; 7 | case DataRequestStatus.DataReceived: 8 | return "received"; 9 | case DataRequestStatus.Closed: 10 | return "closed"; 11 | case DataRequestStatus.Aborted: 12 | return "aborted"; 13 | default: 14 | return "unknown"; // TODO find better name 15 | } 16 | }; 17 | 18 | const StatusTestLabel = { 19 | getStatusTestLabel, 20 | }; 21 | 22 | export default StatusTestLabel; 23 | -------------------------------------------------------------------------------- /iris-client-fe/src/main.ts: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import App from "./App.vue"; 3 | import router from "./router"; 4 | import store from "./store"; 5 | import vuetify from "./plugins/vuetify"; 6 | import initAppContext from "@/utils/appContext"; 7 | 8 | import "@fontsource/roboto/latin.css"; 9 | import "@mdi/font/css/materialdesignicons.css"; 10 | 11 | Vue.config.productionTip = false; 12 | 13 | // in case: config.ts file is loaded before main.ts 14 | initAppContext(); 15 | 16 | const app = new Vue({ 17 | router, 18 | store, 19 | vuetify, 20 | render: (h) => h(App), 21 | }).$mount("#app"); 22 | 23 | // only available during E2E tests 24 | if (window.Cypress) { 25 | window.irisApp = app; 26 | } 27 | -------------------------------------------------------------------------------- /iris-client-fe/src/mixins/HistoryBack.ts: -------------------------------------------------------------------------------- 1 | import { Vue } from "vue-property-decorator"; 2 | 3 | const HistoryBack = (target: string) => { 4 | return Vue.extend({ 5 | beforeRouteEnter(to, from, next) { 6 | next((vm) => { 7 | if (typeof from.name === "string") { 8 | (vm as unknown as { prevLocation: string }).prevLocation = from.name; 9 | } 10 | }); 11 | }, 12 | data() { 13 | return { 14 | target, 15 | prevLocation: null, 16 | }; 17 | }, 18 | methods: { 19 | goBack(): void { 20 | if (this.prevLocation === target) { 21 | return this.$router.back(); 22 | } 23 | this.$router.replace({ name: target }); 24 | }, 25 | }, 26 | }); 27 | }; 28 | 29 | export default HistoryBack; 30 | -------------------------------------------------------------------------------- /iris-client-fe/src/modules/event-tracking/modules/message-data/services/config.ts: -------------------------------------------------------------------------------- 1 | import { DataRequestStatus } from "@/api"; 2 | 3 | export const exportableStatus = [ 4 | DataRequestStatus.DataReceived, 5 | DataRequestStatus.Closed, 6 | ]; 7 | 8 | export const importableStatus = [ 9 | DataRequestStatus.DataRequested, 10 | DataRequestStatus.DataReceived, 11 | ]; 12 | -------------------------------------------------------------------------------- /iris-client-fe/src/modules/mfa/components/mfa-enrollment.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 37 | -------------------------------------------------------------------------------- /iris-client-fe/src/modules/mfa/services/api.ts: -------------------------------------------------------------------------------- 1 | import asyncAction from "@/utils/asyncAction"; 2 | import { apiBundleProvider } from "@/utils/api"; 3 | import authClient from "@/api-client"; 4 | import { normalizeMfaConfig } from "@/modules/mfa/services/normalizer"; 5 | 6 | const fetchMfaConfig = () => { 7 | const action = async () => { 8 | return normalizeMfaConfig((await authClient.mfaConfigGet()).data, true); 9 | }; 10 | return asyncAction(action); 11 | }; 12 | 13 | const resetUsersMfaSecret = () => { 14 | const action = async (userId: string) => { 15 | return (await authClient.usersMfaSecretDelete(userId)).data; 16 | }; 17 | return asyncAction(action); 18 | }; 19 | 20 | export const mfaApi = { 21 | fetchMfaConfig, 22 | resetUsersMfaSecret, 23 | }; 24 | 25 | export const bundleMfaApi = apiBundleProvider(mfaApi); 26 | -------------------------------------------------------------------------------- /iris-client-fe/src/modules/mfa/services/normalizer.ts: -------------------------------------------------------------------------------- 1 | import { MfaConfig, MfaOption } from "@/api"; 2 | import { normalizeData } from "@/utils/data"; 3 | 4 | export const normalizeMfaConfig = (source?: MfaConfig, parse?: boolean) => { 5 | return normalizeData( 6 | source, 7 | (normalizer) => { 8 | return { 9 | mfaOption: normalizer("mfaOption", MfaOption.DISABLED), 10 | }; 11 | }, 12 | parse, 13 | "MfaConfig" 14 | ); 15 | }; 16 | -------------------------------------------------------------------------------- /iris-client-fe/src/modules/vaccination-report/components/vaccination-status-chip.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 29 | -------------------------------------------------------------------------------- /iris-client-fe/src/modules/vaccination-report/modules/message-data/services/utils.ts: -------------------------------------------------------------------------------- 1 | import { VaccinationReport } from "@/api"; 2 | import { getFormattedDate } from "@/utils/date"; 3 | import { join } from "@/utils/misc"; 4 | 5 | export const getDefaultDescription = ( 6 | report?: VaccinationReport | null 7 | ): string => { 8 | const name = report?.facility?.name; 9 | const reportedAt = getFormattedDate(report?.reportedAt, "L", ""); 10 | return name ? join([name, reportedAt], " ") : ""; 11 | }; 12 | -------------------------------------------------------------------------------- /iris-client-fe/src/modules/vaccination-report/modules/message-data/vaccination-report-message-data.preview.vue: -------------------------------------------------------------------------------- 1 | 7 | 29 | -------------------------------------------------------------------------------- /iris-client-fe/src/server/utils/date.ts: -------------------------------------------------------------------------------- 1 | import dayjs from "./../../utils/date"; 2 | import { ManipulateType } from "dayjs"; 3 | 4 | export const timeAgo = ( 5 | value = 0, 6 | unit: ManipulateType, 7 | date = new Date().toISOString() 8 | ): string => { 9 | return dayjs(date).subtract(value, unit).toISOString(); 10 | }; 11 | 12 | export function daysAgo(days = 0, date = new Date().toISOString()): string { 13 | return timeAgo(days, "days", date); 14 | } 15 | 16 | export function hoursAgo(hours = 0, date = new Date().toISOString()): string { 17 | return timeAgo(hours, "hours", date); 18 | } 19 | -------------------------------------------------------------------------------- /iris-client-fe/src/shims-config.d.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | interface Window { 3 | irisAppContext?: IRISAppContext; 4 | Cypress?: unknown; 5 | irisApp?: Vue; 6 | } 7 | } 8 | 9 | export type IRISAppContext = { 10 | apiBaseURL: string; 11 | csvExportStandardAtomicAddress: string; 12 | localContactPerson: { 13 | name?: string; 14 | phone?: string; 15 | mail?: string; 16 | }; 17 | }; 18 | -------------------------------------------------------------------------------- /iris-client-fe/src/shims-tsx.d.ts: -------------------------------------------------------------------------------- 1 | import Vue, { VNode } from "vue"; 2 | 3 | declare global { 4 | namespace JSX { 5 | // tslint:disable no-empty-interface 6 | interface Element extends VNode {} 7 | // tslint:disable no-empty-interface 8 | interface ElementClass extends Vue {} 9 | interface IntrinsicElements { 10 | [elem: string]: any; 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /iris-client-fe/src/shims-vue.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*.vue" { 2 | import Vue from "vue"; 3 | export default Vue; 4 | } 5 | -------------------------------------------------------------------------------- /iris-client-fe/src/shims-vuetify.d.ts: -------------------------------------------------------------------------------- 1 | declare module "vuetify/lib/framework" { 2 | import Vuetify from "vuetify"; 3 | export default Vuetify; 4 | } 5 | -------------------------------------------------------------------------------- /iris-client-fe/src/store/index.ts: -------------------------------------------------------------------------------- 1 | import { storeOptions } from "@/store/store.config"; 2 | 3 | import Vue from "vue"; 4 | import Vuex, { Store } from "vuex"; 5 | 6 | Vue.use(Vuex); 7 | export default new Store(storeOptions); 8 | -------------------------------------------------------------------------------- /iris-client-fe/src/styles/variables.scss: -------------------------------------------------------------------------------- 1 | /** 2 | The "Details" button in some table views is outside the viewport on medium screen sizes as the container max width is to narrow. 3 | If we set the max-width to "none" there is a much better chance that the "Details" button is visible without scrolling the table horizontally. 4 | */ 5 | $container-max-widths: ( 6 | 'md': none 7 | ); 8 | -------------------------------------------------------------------------------- /iris-client-fe/src/utils/address.ts: -------------------------------------------------------------------------------- 1 | import { join } from "@/utils/misc"; 2 | type AddressLike = { 3 | street?: string; 4 | houseNumber?: string; 5 | zipCode?: string; 6 | city?: string; 7 | }; 8 | 9 | const sanitiseField = (text = ""): string => { 10 | return text.replace(/\s+/g, " "); 11 | }; 12 | 13 | export const getFormattedAddress = (address?: AddressLike | null): string => { 14 | if (address) { 15 | return join( 16 | [ 17 | join( 18 | [sanitiseField(address.street), sanitiseField(address.houseNumber)], 19 | " " 20 | ), 21 | join( 22 | [sanitiseField(address.zipCode), sanitiseField(address.city)], 23 | " " 24 | ), 25 | ], 26 | "\n" 27 | ); 28 | } 29 | return "-"; 30 | }; 31 | -------------------------------------------------------------------------------- /iris-client-fe/src/utils/appContext.ts: -------------------------------------------------------------------------------- 1 | const initAppContext = (): void => { 2 | try { 3 | if (window.irisAppContext) return; 4 | const appElement = document.querySelector("#app"); 5 | if (appElement) { 6 | const ctxString = appElement.getAttribute("data-iris-app-context"); 7 | if (ctxString) { 8 | window.irisAppContext = JSON.parse(ctxString); 9 | } 10 | } 11 | } catch (e) { 12 | // console.error(e); 13 | } 14 | }; 15 | 16 | export default initAppContext; 17 | -------------------------------------------------------------------------------- /iris-client-fe/src/utils/misc.ts: -------------------------------------------------------------------------------- 1 | import { flattenDeep } from "lodash"; 2 | 3 | export const join = (arr: Array, separator: string): string => { 4 | return flattenDeep(arr) 5 | .filter((n) => n) 6 | .join(separator); 7 | }; 8 | 9 | export const getValidPhoneNumber = ( 10 | ...numbers: Array 11 | ): string | undefined => { 12 | const validNumber = numbers.find(isPossiblePhoneNumber); 13 | return validNumber ? validNumber : numbers[0]; 14 | }; 15 | 16 | const isPossiblePhoneNumber = (phoneNumber?: string): boolean => { 17 | if (!phoneNumber) return false; 18 | const number = phoneNumber.replace(/[\s\-_+#*.,:;()/|]/g, ""); 19 | return /^\d+$/.test(number); 20 | }; 21 | -------------------------------------------------------------------------------- /iris-client-fe/src/views/admin-user-list/admin-user-list.data.ts: -------------------------------------------------------------------------------- 1 | import { UserList } from "@/api"; 2 | import { Complete, normalizeData } from "@/utils/data"; 3 | import { normalizeUser } from "@/views/user-login/user-login.data"; 4 | 5 | export const normalizeUserList = ( 6 | source?: UserList, 7 | parse?: boolean 8 | ): UserList => { 9 | return normalizeData( 10 | source, 11 | (normalizer) => { 12 | const users = normalizer("users", undefined, "array"); 13 | const normalized: Complete = { 14 | users: users ? users.map((user) => normalizeUser(user)) : undefined, 15 | }; 16 | return normalized; 17 | }, 18 | parse, 19 | "UserList" 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /iris-client-fe/src/views/app-settings/chunk-loader.store.ts: -------------------------------------------------------------------------------- 1 | import { RootState } from "@/store/types"; 2 | 3 | import { Module } from "vuex"; 4 | 5 | export type ChunkLoaderState = { 6 | reloadedAt: number | null; 7 | }; 8 | 9 | export interface ChunkLoaderModule extends Module { 10 | mutations: { 11 | setReloadedAt(state: ChunkLoaderState, reloadedAt: number | null): void; 12 | reset(state: ChunkLoaderState, payload: null): void; 13 | }; 14 | } 15 | 16 | const defaultState: ChunkLoaderState = { 17 | reloadedAt: null, 18 | }; 19 | 20 | const chunkLoader: ChunkLoaderModule = { 21 | namespaced: true, 22 | state() { 23 | return { ...defaultState }; 24 | }, 25 | mutations: { 26 | setReloadedAt(state: ChunkLoaderState, reloadedAt: number | null) { 27 | state.reloadedAt = reloadedAt; 28 | }, 29 | reset(state) { 30 | Object.assign(state, { ...defaultState }); 31 | }, 32 | }, 33 | }; 34 | 35 | export default chunkLoader; 36 | -------------------------------------------------------------------------------- /iris-client-fe/src/views/event-tracking-form/event-tracking-form.data.ts: -------------------------------------------------------------------------------- 1 | import { LocationList } from "@/api"; 2 | import { Complete, normalizeData } from "@/utils/data"; 3 | import { normalizeLocationInformation } from "@/views/event-tracking-details/event-tracking-details.data"; 4 | 5 | export const normalizeLocationList = ( 6 | source?: LocationList, 7 | parse?: boolean 8 | ): LocationList => { 9 | return normalizeData( 10 | source, 11 | (normalizer) => { 12 | const locations = normalizer("locations", [], "array"); 13 | const normalized: Complete = { 14 | locations: locations.map((location) => 15 | normalizeLocationInformation(location) 16 | ), 17 | totalElements: normalizer("totalElements", 0, "number"), 18 | page: normalizer("page", 0, "number"), 19 | size: normalizer("size", 0, "number"), 20 | }; 21 | return normalized; 22 | }, 23 | parse, 24 | "LocationList" 25 | ); 26 | }; 27 | -------------------------------------------------------------------------------- /iris-client-fe/src/views/home/home.data.ts: -------------------------------------------------------------------------------- 1 | import { Statistics } from "@/api"; 2 | import { Complete, normalizeData } from "@/utils/data"; 3 | 4 | export const normalizeStatistics = ( 5 | source?: Statistics, 6 | parse?: boolean 7 | ): Statistics => { 8 | return normalizeData( 9 | source, 10 | (normalizer) => { 11 | const normalized: Complete = { 12 | eventsCount: normalizer("eventsCount", undefined, "number"), 13 | indexCasesCount: normalizer("indexCasesCount", undefined, "number"), 14 | sumStatus: normalizer("sumStatus", undefined, "number"), 15 | }; 16 | return normalized; 17 | }, 18 | parse, 19 | "Statistics" 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /iris-client-fe/src/views/index-tracking-details/components/data-export/utils/exportStandardEvents.ts: -------------------------------------------------------------------------------- 1 | import dataExport, { Row } from "@/utils/data-export/data-export"; 2 | import { resolveAtomicAddressHeader } from "@/utils/data-export/common"; 3 | 4 | const getHeaders = () => { 5 | return [ 6 | { 7 | text: "Event", 8 | value: "name", 9 | }, 10 | { 11 | text: "Telefonnummer", 12 | value: "phone", 13 | }, 14 | resolveAtomicAddressHeader(), 15 | { 16 | text: "zus. Informationen", 17 | value: "additionalInformation", 18 | }, 19 | ]; 20 | }; 21 | 22 | const exportCsv = (rows: Row[], fileName: string): Promise => { 23 | const headers = getHeaders(); 24 | return dataExport.exportCsv(headers, rows, { fileName }); 25 | }; 26 | 27 | const exportStandardEvents = { 28 | exportCsv, 29 | }; 30 | 31 | export default exportStandardEvents; 32 | -------------------------------------------------------------------------------- /iris-client-fe/src/views/index-tracking-form/index-tracking-form.data.ts: -------------------------------------------------------------------------------- 1 | import { DataRequestCaseExtendedDetails } from "@/api"; 2 | import { Complete, normalizeData } from "@/utils/data"; 3 | 4 | export const normalizeDataRequestCaseExtendedDetails = ( 5 | source?: DataRequestCaseExtendedDetails, 6 | parse?: boolean 7 | ): DataRequestCaseExtendedDetails => { 8 | return normalizeData( 9 | source, 10 | (normalizer) => { 11 | const normalized: Complete = { 12 | externalCaseId: normalizer("externalCaseId", ""), 13 | name: normalizer("name", undefined), 14 | comment: normalizer("comment", undefined), 15 | start: normalizer("start", "", "dateString"), 16 | end: normalizer("end", undefined, "dateString"), 17 | caseId: normalizer("caseId", undefined), 18 | status: normalizer("status", undefined), 19 | nonce: normalizer("nonce", undefined), 20 | }; 21 | return normalized; 22 | }, 23 | parse, 24 | "DataRequestCaseExtendedDetails" 25 | ); 26 | }; 27 | -------------------------------------------------------------------------------- /iris-client-fe/src/views/iris-message-create/iris-message-create.data.ts: -------------------------------------------------------------------------------- 1 | import { IrisMessageHdContact } from "@/api"; 2 | import { normalizeData } from "@/utils/data"; 3 | import { normalizeIrisMessageHdContact } from "@/views/iris-message-list/iris-message-list.data"; 4 | 5 | export const normalizeIrisMessageHdContacts = ( 6 | source?: IrisMessageHdContact[], 7 | parse?: boolean 8 | ): IrisMessageHdContact[] => { 9 | return normalizeData( 10 | source, 11 | () => { 12 | return (source || []).map((item) => normalizeIrisMessageHdContact(item)); 13 | }, 14 | parse, 15 | "IrisMessageHdContacts" 16 | ); 17 | }; 18 | -------------------------------------------------------------------------------- /iris-client-fe/src/views/user-login/user-login.data.ts: -------------------------------------------------------------------------------- 1 | import { User, UserRole } from "@/api"; 2 | import { normalizeData } from "@/utils/data"; 3 | import { normalizeMetaData } from "@/common/normalizer"; 4 | 5 | export const normalizeUser = (source?: User, parse?: boolean): User => { 6 | return normalizeData( 7 | source, 8 | (normalizer) => { 9 | return { 10 | id: normalizer("id", undefined), 11 | firstName: normalizer("firstName", undefined), 12 | lastName: normalizer("lastName", undefined), 13 | userName: normalizer("userName", ""), 14 | role: normalizer("role", UserRole.User), 15 | locked: normalizer("locked", false, "boolean"), 16 | useMfa: normalizer("useMfa", false, "boolean"), 17 | mfaSecretEnrolled: normalizer("mfaSecretEnrolled", false, "boolean"), 18 | ...normalizeMetaData(source), 19 | }; 20 | }, 21 | parse, 22 | "User" 23 | ); 24 | }; 25 | -------------------------------------------------------------------------------- /iris-client-fe/tests/e2e/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: ["cypress"], 3 | env: { 4 | mocha: true, 5 | "cypress/globals": true, 6 | }, 7 | rules: { 8 | strict: "off", 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /iris-client-fe/tests/e2e/specs/000_prepare.js: -------------------------------------------------------------------------------- 1 | // https://docs.cypress.io/api/introduction/api.html 2 | 3 | import { 4 | getTestAdminCredentials, 5 | useDedicatedTestUser, 6 | } from "../support/commands"; 7 | 8 | describe("AdminCreate", () => { 9 | beforeEach(() => { 10 | cy.clearLocalStorage(); 11 | cy.visit("/"); 12 | }); 13 | it("should create the test admin if dedicated test user is used", () => { 14 | if (useDedicatedTestUser()) { 15 | cy.login({ 16 | userName: Cypress.env("auth_username"), 17 | password: Cypress.env("auth_password"), 18 | }); 19 | cy.getApp().then((app) => { 20 | app.$store.dispatch("adminUserCreate/createUser", { 21 | ...getTestAdminCredentials(), 22 | role: "ADMIN", 23 | }); 24 | }); 25 | } 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /iris-client-fe/tests/e2e/specs/100_about.js: -------------------------------------------------------------------------------- 1 | // https://docs.cypress.io/api/introduction/api.html 2 | 3 | describe("About", () => { 4 | beforeEach(() => { 5 | cy.clearLocalStorage(); 6 | cy.visit("/"); 7 | }); 8 | it("should check auth-nav guard, navigate to the about page and display content", () => { 9 | cy.visit("/about"); 10 | cy.location("pathname") 11 | .should("not.equal", "/about") 12 | .and("equal", "/user/login"); 13 | cy.login(); 14 | cy.visit("/about"); 15 | cy.location("pathname").should("equal", "/about"); 16 | cy.getBy("install.version").should("contain", "version_e2e_test"); 17 | cy.getBy("install.build").should("contain", "build_e2e_test"); 18 | cy.getBy("contact") 19 | .should("exist") 20 | .and("contain", "E2ETestName") 21 | .and("contain", "E2ETestMail") 22 | .and("contain", "E2ETestPhone"); 23 | cy.getBy("logo.inoeg").should("have.css", "background-image"); 24 | cy.getBy("logo.bss").should("have.css", "background-image"); 25 | cy.logout(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /iris-client-fe/tests/e2e/specs/108_logout.js: -------------------------------------------------------------------------------- 1 | // https://docs.cypress.io/api/introduction/api.html 2 | 3 | describe("Logout", () => { 4 | beforeEach(() => { 5 | cy.clearLocalStorage(); 6 | cy.visit("/"); 7 | }); 8 | it("should open user-menu and logout user with confirmation dialog and redirect to login page", () => { 9 | cy.login(); 10 | cy.getBy("user-menu.activator").should("exist").click(); 11 | cy.getBy("{user-menu} {logout-confirm-dialog.activator}") 12 | .should("exist") 13 | .click(); 14 | cy.getBy("logout-confirm-dialog.action.confirm").should("exist").click(); 15 | cy.location("pathname").should("equal", "/user/login"); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /iris-client-fe/tests/e2e/specs/999_cleanup.js: -------------------------------------------------------------------------------- 1 | // https://docs.cypress.io/api/introduction/api.html 2 | 3 | import { useDedicatedTestUser } from "../support/commands"; 4 | 5 | describe("AdminDelete", () => { 6 | beforeEach(() => { 7 | cy.clearLocalStorage(); 8 | cy.visit("/"); 9 | }); 10 | it("should delete the test admin if dedicated test user is used", () => { 11 | if (useDedicatedTestUser()) { 12 | let testAdminId; 13 | cy.login(); 14 | cy.fetchUser(); 15 | cy.getApp().then((app) => { 16 | testAdminId = app.$store.state.userLogin.user.id; 17 | }); 18 | cy.logout(); 19 | cy.login({ 20 | userName: Cypress.env("auth_username"), 21 | password: Cypress.env("auth_password"), 22 | }); 23 | cy.getApp().then((app) => { 24 | app.$store.dispatch("adminUserList/deleteUser", testAdminId); 25 | }); 26 | } 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /iris-client-fe/tests/e2e/specs/all.cy.ts: -------------------------------------------------------------------------------- 1 | import "./000_prepare"; 2 | import "./100_about"; 3 | import "./101_app-bar"; 4 | import "./102_checkin-apps-status"; 5 | import "./103_dashboard"; 6 | import "./104_events"; 7 | import "./105_index-cases"; 8 | import "./106_iris-messages"; 9 | import "./107_login"; 10 | import "./108_logout"; 11 | import "./109_users"; 12 | import "./110_vaccination-report"; 13 | import "./111_iris-message-data"; 14 | import "./999_cleanup"; 15 | -------------------------------------------------------------------------------- /iris-client-fe/tests/e2e/support/index.js: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example support/index.js is processed and 3 | // loaded automatically before your test files. 4 | // 5 | // This is a great place to put global configuration and 6 | // behavior that modifies Cypress. 7 | // 8 | // You can change the location of this file or turn off 9 | // automatically serving support files with the 10 | // 'supportFile' configuration option. 11 | // 12 | // You can read more here: 13 | // https://on.cypress.io/configuration 14 | // *********************************************************** 15 | 16 | import "cypress-fail-fast"; 17 | // Import commands.js using ES2015 syntax: 18 | import "./commands"; 19 | 20 | // Alternatively you can use CommonJS syntax: 21 | // require('./commands') 22 | 23 | Cypress.on("uncaught:exception", () => { 24 | // returning false here prevents Cypress from 25 | // failing the test 26 | return false; 27 | }); 28 | -------------------------------------------------------------------------------- /iris-client-fe/tests/e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "sourceMap": false, 5 | "types": ["cypress"] 6 | }, 7 | "include": ["**/*.ts"] 8 | } 9 | -------------------------------------------------------------------------------- /iris-client-fe/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2019", 4 | "module": "esnext", 5 | "strict": true, 6 | "jsx": "preserve", 7 | "importHelpers": true, 8 | "moduleResolution": "node", 9 | "experimentalDecorators": true, 10 | "skipLibCheck": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "sourceMap": true, 14 | "baseUrl": ".", 15 | "types": [ 16 | "webpack-env", 17 | "jest" 18 | ], 19 | "paths": { 20 | "@/*": [ 21 | "src/*" 22 | ] 23 | }, 24 | "lib": [ 25 | "esnext", 26 | "dom", 27 | "dom.iterable", 28 | "scripthost" 29 | ] 30 | }, 31 | "include": [ 32 | "src/**/*.ts", 33 | "src/**/*.tsx", 34 | "src/**/*.vue", 35 | "tests/**/*.ts", 36 | "tests/**/*.tsx" 37 | ], 38 | "exclude": [ 39 | "node_modules" 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /iris-client-fe/vue.config.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/no-var-requires 2 | const CompressionPlugin = require("compression-webpack-plugin"); 3 | 4 | module.exports = { 5 | transpileDependencies: ["vuetify"], 6 | configureWebpack: { 7 | plugins: [new CompressionPlugin()], 8 | }, 9 | chainWebpack: (config) => { 10 | config.plugin("html").tap((args) => { 11 | const htmlConfig = args[0]; 12 | htmlConfig.irisAppContext = { 13 | apiBaseURL: process.env.VUE_APP_API_BASE_URL, 14 | csvExportStandardAtomicAddress: 15 | process.env.VUE_APP_CSV_EXPORT_STANDARD_ATOMIC_ADDRESS, 16 | localContactPerson: { 17 | name: process.env.VUE_APP_LOCAL_CONTACT_PERSON_NAME, 18 | mail: process.env.VUE_APP_LOCAL_CONTACT_PERSON_MAIL, 19 | phone: process.env.VUE_APP_LOCAL_CONTACT_PERSON_PHONE, 20 | }, 21 | }; 22 | return args; 23 | }); 24 | }, 25 | }; 26 | --------------------------------------------------------------------------------