├── .gitignore ├── .gitmodules ├── .travis.yml ├── LICENSE ├── README.md ├── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── registration-sample.yaml ├── settings.gradle └── src ├── main ├── docker │ └── Dockerfile ├── java │ └── io │ │ └── kamax │ │ └── matrix │ │ └── bridge │ │ └── email │ │ ├── MatrixAppserviceEmailApplication.java │ │ ├── config │ │ ├── bridge │ │ │ ├── BridgeCommandConfig.java │ │ │ └── BridgeInviteConfig.java │ │ ├── dao │ │ │ └── SubscriptionSqliteConfig.java │ │ ├── email │ │ │ ├── EmailReceiverConfig.java │ │ │ └── EmailSenderConfig.java │ │ ├── matrix │ │ │ ├── EntityTemplateConfig.java │ │ │ ├── HomeserverConfig.java │ │ │ ├── IdentityConfig.java │ │ │ └── MatrixConfig.java │ │ └── subscription │ │ │ ├── EmailNotificationConfig.java │ │ │ ├── EmailTemplateConfig.java │ │ │ ├── EmailTemplateContentConfig.java │ │ │ ├── MatrixNotificationConfig.java │ │ │ └── SubscriptionPortalConfig.java │ │ ├── controller │ │ ├── ApplicationServiceController.java │ │ ├── EmptyJsonResponse.java │ │ ├── MappingController.java │ │ ├── SubscriptionController.java │ │ ├── SubscriptionItem.java │ │ └── ThreePidMappingAnswer.java │ │ ├── dao │ │ ├── BridgeSubscriptionDao.java │ │ ├── _SubscriptionDao.java │ │ └── sqlite │ │ │ └── SubscriptionSqlite.java │ │ ├── exception │ │ ├── InvalidBodyContentException.java │ │ ├── InvalidConfigurationException.java │ │ ├── InvalidEmailKeyException.java │ │ ├── InvalidHomeserverTokenException.java │ │ ├── InvalidMatrixIdException.java │ │ ├── MatrixException.java │ │ ├── NoHomeserverTokenException.java │ │ ├── RoomNotFoundException.java │ │ ├── StorageException.java │ │ └── UserNotFoundException.java │ │ └── model │ │ ├── ABridgeMessage.java │ │ ├── AEndPoint.java │ │ ├── BridgeEmailCodec.java │ │ ├── BridgeMessageContent.java │ │ ├── BridgeMessageHtmlContent.java │ │ ├── BridgeMessageTextContent.java │ │ ├── MessageFormatter.java │ │ ├── _BridgeMessage.java │ │ ├── _BridgeMessageContent.java │ │ ├── _EndPoint.java │ │ ├── _MessageFormatter.java │ │ ├── email │ │ ├── AEmailClientFormatter.java │ │ ├── EmailBridgeMessage.java │ │ ├── EmailEndPoint.java │ │ ├── EmailFetcher.java │ │ ├── EmailFormatterInbound.java │ │ ├── EmailFormatterOutboud.java │ │ ├── EmailManager.java │ │ ├── EmailTemplate.java │ │ ├── EmailTemplateContent.java │ │ ├── EmailTemplateManager.java │ │ ├── EmailTemplateToken.java │ │ ├── GmailClientFormatter.java │ │ ├── ThunderbirdClientFormatter.java │ │ ├── _EmailBridgeMessage.java │ │ ├── _EmailClientFormatter.java │ │ ├── _EmailEndPoint.java │ │ ├── _EmailFetcher.java │ │ ├── _EmailFormatterInbound.java │ │ ├── _EmailFormatterOutbound.java │ │ ├── _EmailManager.java │ │ ├── _EmailMessageListener.java │ │ ├── _EmailTemplate.java │ │ ├── _EmailTemplateContent.java │ │ └── _EmailTemplateManager.java │ │ ├── matrix │ │ ├── AHomeserverCall.java │ │ ├── MatrixApplicationService.java │ │ ├── MatrixBridgeMessage.java │ │ ├── MatrixBridgeUser.java │ │ ├── MatrixEndPoint.java │ │ ├── MatrixManager.java │ │ ├── MatrixTransactionPush.java │ │ ├── RoomQuery.java │ │ ├── UserQuery.java │ │ ├── _HomeserverCall.java │ │ ├── _MatrixApplicationService.java │ │ ├── _MatrixBridgeMessage.java │ │ ├── _MatrixBridgeUser.java │ │ ├── _MatrixEndPoint.java │ │ └── _MatrixManager.java │ │ └── subscription │ │ ├── BridgeSubscription.java │ │ ├── SubscriptionEvent.java │ │ ├── SubscriptionEvents.java │ │ ├── SubscriptionManager.java │ │ ├── SubscriptionPortalService.java │ │ ├── _BridgeSubscription.java │ │ ├── _BridgeSubscriptionListener.java │ │ ├── _SubscriptionEvent.java │ │ └── _SubscriptionManager.java └── resources │ ├── application.yaml │ └── templates │ ├── email │ ├── footer.html │ ├── footer.txt │ ├── header.html │ ├── header.txt │ ├── onSubCreate-content.html │ ├── onSubCreate-content.txt │ ├── onSubDestroy-content.html │ ├── onSubDestroy-content.txt │ ├── onSubMessage-content.html │ └── onSubMessage-content.txt │ └── subscription │ ├── deleteSuccess.html │ ├── invalidToken.html │ └── list.html └── test ├── java └── io │ └── kamax │ └── matrix │ └── bridge │ └── email │ └── model │ ├── BridgeEmailCodecTest.java │ └── email │ ├── GmailClientFormatterTest.java │ └── ThunderbirdClientFormatterTest.java └── resources ├── gmailContent.html ├── gmailContent.txt ├── thunderbirdContent.html └── thunderbirdContent.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # Gradle 2 | .gradle 3 | build/ 4 | out/ 5 | 6 | # Intellij IDEA 7 | .idea/ 8 | 9 | # Local config files 10 | /application.yaml 11 | /application-*.yaml 12 | 13 | # Generated files 14 | /registration.yaml 15 | /as.db 16 | /as-*.db 17 | *.log -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamax-matrix/matrix-appservice-email/3b563d3a7840032a480dd57adbe20c3f6245b605/.gitmodules -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | 3 | jdk: 4 | - oraclejdk8 5 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | apply plugin: 'java' 22 | apply plugin: 'org.springframework.boot' 23 | apply plugin: 'docker' 24 | 25 | group = 'kamax' 26 | 27 | def configFile = "src/main/resources/application.yaml" 28 | def distBinDir = "${project.buildDir.absolutePath}/dist/bin" 29 | 30 | buildscript { 31 | repositories { 32 | mavenCentral() 33 | } 34 | 35 | dependencies { 36 | classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.5.3.RELEASE' 37 | classpath 'se.transmode.gradle:gradle-docker:1.2' 38 | } 39 | } 40 | 41 | repositories { 42 | mavenCentral() 43 | maven { url "https://kamax.io/maven/releases" } 44 | maven { url "https://kamax.io/maven/snapshots" } 45 | } 46 | 47 | dependencies { 48 | compile 'io.kamax:matrix-java-sdk:0.0.1-bridge-email' 49 | 50 | // Spring Boot - standalone app 51 | compile 'org.springframework.boot:spring-boot-starter-web:1.5.3.RELEASE' 52 | compile "org.springframework.boot:spring-boot-starter-thymeleaf" 53 | 54 | compile 'commons-lang:commons-lang:2.6' 55 | 56 | compile 'com.sun.mail:javax.mail:1.5.6' 57 | compile 'javax.mail:javax.mail-api:1.5.6' 58 | 59 | compile 'org.xerial:sqlite-jdbc:3.15.1' 60 | 61 | compile 'org.jsoup:jsoup:1.10.2' 62 | 63 | testCompile 'org.springframework.boot:spring-boot-starter-test' 64 | } 65 | 66 | springBoot { 67 | executable = true 68 | 69 | embeddedLaunchScriptProperties = [ 70 | confFolder: "/etc/default" 71 | ] 72 | } 73 | 74 | 75 | task buildBin(type: Copy, dependsOn: ['build']) { 76 | from jar 77 | into distBinDir 78 | 79 | doLast { 80 | project.exec { 81 | commandLine('chmod', 'a+x', "${distBinDir}/${jar.archiveName}") 82 | } 83 | } 84 | } 85 | 86 | task buildDocker(type: Docker, dependsOn: build) { 87 | push = false 88 | applicationName = "mxasd-email" 89 | dockerfile = file('src/main/docker/Dockerfile') 90 | 91 | doFirst { 92 | copy { 93 | from jar 94 | into stageDir 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamax-matrix/matrix-appservice-email/3b563d3a7840032a480dd57adbe20c3f6245b605/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Apr 26 16:46:55 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-bin.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn ( ) { 37 | echo "$*" 38 | } 39 | 40 | die ( ) { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save ( ) { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /registration-sample.yaml: -------------------------------------------------------------------------------- 1 | id: "appservice-email" 2 | url: "http://localhost:8091" 3 | as_token: "MY_SECRET_AS_TOKEN_CHANGE_ME" 4 | hs_token: "MY_SECRET_HS_TOKEN_CHANGE_ME" 5 | sender_localpart: "appservice-email" 6 | namespaces: 7 | users: 8 | - regex: "@email_*" 9 | exclusive: true 10 | aliases: [] 11 | rooms: [] 12 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | rootProject.name = 'matrix-appservice-email' 22 | -------------------------------------------------------------------------------- /src/main/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM frolvlad/alpine-oraclejdk8:slim 2 | MAINTAINER Maxime Dor 3 | 4 | EXPOSE 8091 5 | VOLUME "/data" 6 | 7 | ADD matrix-appservice-email.jar /mxas-email/mxas-email.jar 8 | 9 | WORKDIR "/data" 10 | ENTRYPOINT [ "/usr/bin/java" ] 11 | CMD [ "-Djava.security.egd=file:/dev/urandom", "-jar", "/mxas-email/mxas-email.jar", "--spring.config.location=/data/" ] 12 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/MatrixAppserviceEmailApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email; 22 | 23 | import org.springframework.boot.SpringApplication; 24 | import org.springframework.boot.autoconfigure.SpringBootApplication; 25 | 26 | @SpringBootApplication 27 | public class MatrixAppserviceEmailApplication { 28 | 29 | public static void main(String[] args) { 30 | SpringApplication.run(MatrixAppserviceEmailApplication.class, args); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/config/bridge/BridgeCommandConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.config.bridge; 22 | 23 | import org.springframework.boot.context.properties.ConfigurationProperties; 24 | import org.springframework.context.annotation.Configuration; 25 | 26 | @Configuration 27 | @ConfigurationProperties("bridge.command") 28 | public class BridgeCommandConfig { 29 | 30 | private String keyword; 31 | 32 | public String getKeyword() { 33 | return keyword; 34 | } 35 | 36 | public void setKeyword(String keyword) { 37 | this.keyword = keyword; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/config/bridge/BridgeInviteConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.config.bridge; 22 | 23 | import org.springframework.boot.context.properties.ConfigurationProperties; 24 | import org.springframework.context.annotation.Configuration; 25 | 26 | import java.util.ArrayList; 27 | import java.util.List; 28 | 29 | @Configuration 30 | @ConfigurationProperties("bridge.invite") 31 | public class BridgeInviteConfig { 32 | 33 | private List domain = new ArrayList<>(); 34 | 35 | public List getDomain() { 36 | return domain; 37 | } 38 | 39 | public void setDomain(List domain) { 40 | this.domain = domain; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/config/dao/SubscriptionSqliteConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.config.dao; 22 | 23 | import org.springframework.boot.context.properties.ConfigurationProperties; 24 | import org.springframework.context.annotation.Configuration; 25 | 26 | @Configuration 27 | @ConfigurationProperties("subscription.storage.sqlite") 28 | public class SubscriptionSqliteConfig { 29 | 30 | private String location; 31 | 32 | public String getLocation() { 33 | return location; 34 | } 35 | 36 | public void setLocation(String location) { 37 | this.location = location; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/config/email/EmailReceiverConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.config.email; 22 | 23 | import org.springframework.boot.context.properties.ConfigurationProperties; 24 | import org.springframework.context.annotation.Configuration; 25 | 26 | @Configuration 27 | @ConfigurationProperties("email.receiver") 28 | public class EmailReceiverConfig { 29 | 30 | private String type; 31 | private String host; 32 | private int port; 33 | private String login; 34 | private String password; 35 | private String email; 36 | 37 | public String getType() { 38 | return type; 39 | } 40 | 41 | public void setType(String type) { 42 | this.type = type; 43 | } 44 | 45 | public String getHost() { 46 | return host; 47 | } 48 | 49 | public void setHost(String host) { 50 | this.host = host; 51 | } 52 | 53 | public int getPort() { 54 | return port; 55 | } 56 | 57 | public void setPort(int port) { 58 | this.port = port; 59 | } 60 | 61 | public String getLogin() { 62 | return login; 63 | } 64 | 65 | public void setLogin(String login) { 66 | this.login = login; 67 | } 68 | 69 | public String getPassword() { 70 | return password; 71 | } 72 | 73 | public void setPassword(String password) { 74 | this.password = password; 75 | } 76 | 77 | public String getEmail() { 78 | return email; 79 | } 80 | 81 | public void setEmail(String email) { 82 | this.email = email; 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/config/email/EmailSenderConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.config.email; 22 | 23 | import org.springframework.boot.context.properties.ConfigurationProperties; 24 | import org.springframework.context.annotation.Configuration; 25 | 26 | @Configuration 27 | @ConfigurationProperties("email.sender") 28 | public class EmailSenderConfig { 29 | 30 | private String host; 31 | private int port; 32 | private int tls; 33 | private String login; 34 | private String password; 35 | private String email; 36 | private String name; 37 | 38 | public String getHost() { 39 | return host; 40 | } 41 | 42 | public void setHost(String host) { 43 | this.host = host; 44 | } 45 | 46 | public int getPort() { 47 | return port; 48 | } 49 | 50 | public void setPort(int port) { 51 | this.port = port; 52 | } 53 | 54 | public int getTls() { 55 | return tls; 56 | } 57 | 58 | public void setTls(int tls) { 59 | this.tls = tls; 60 | } 61 | 62 | public String getLogin() { 63 | return login; 64 | } 65 | 66 | public void setLogin(String login) { 67 | this.login = login; 68 | } 69 | 70 | public String getPassword() { 71 | return password; 72 | } 73 | 74 | public void setPassword(String password) { 75 | this.password = password; 76 | } 77 | 78 | public String getEmail() { 79 | return email; 80 | } 81 | 82 | public void setEmail(String email) { 83 | this.email = email; 84 | } 85 | 86 | public String getName() { 87 | return name; 88 | } 89 | 90 | public void setName(String name) { 91 | this.name = name; 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/config/matrix/EntityTemplateConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.config.matrix; 22 | 23 | import org.springframework.stereotype.Component; 24 | 25 | @Component 26 | public class EntityTemplateConfig { 27 | 28 | private String template; 29 | 30 | public String getTemplate() { 31 | return template; 32 | } 33 | 34 | public void setTemplate(String template) { 35 | this.template = template; 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return "EntityPattern{" + 41 | "template='" + template + '\'' + 42 | '}'; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/config/matrix/HomeserverConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.config.matrix; 22 | 23 | import io.kamax.matrix.bridge.email.exception.InvalidConfigurationException; 24 | import org.apache.commons.lang.StringUtils; 25 | import org.slf4j.Logger; 26 | import org.slf4j.LoggerFactory; 27 | import org.springframework.beans.factory.InitializingBean; 28 | import org.springframework.beans.factory.annotation.Autowired; 29 | import org.springframework.boot.context.properties.ConfigurationProperties; 30 | import org.springframework.context.annotation.Configuration; 31 | 32 | import java.util.List; 33 | 34 | @Configuration 35 | @ConfigurationProperties("matrix.home") 36 | public class HomeserverConfig implements InitializingBean { 37 | 38 | private Logger log = LoggerFactory.getLogger(HomeserverConfig.class); 39 | 40 | @Autowired 41 | private MatrixConfig mxCfg; 42 | 43 | private String host; 44 | private String asToken; 45 | private String hsToken; 46 | private String localpart; 47 | private List users; 48 | 49 | public String getDomain() { 50 | return mxCfg.getDomain(); 51 | } 52 | 53 | public String getHost() { 54 | return host; 55 | } 56 | 57 | public void setHost(String host) { 58 | this.host = host; 59 | } 60 | 61 | public String getAsToken() { 62 | return asToken; 63 | } 64 | 65 | public void setAsToken(String asToken) { 66 | this.asToken = asToken; 67 | } 68 | 69 | public String getHsToken() { 70 | return hsToken; 71 | } 72 | 73 | public void setHsToken(String hsToken) { 74 | this.hsToken = hsToken; 75 | } 76 | 77 | public String getLocalpart() { 78 | return localpart; 79 | } 80 | 81 | public void setLocalpart(String localpart) { 82 | this.localpart = localpart; 83 | } 84 | 85 | public List getUsers() { 86 | return users; 87 | } 88 | 89 | public void setUsers(List users) { 90 | this.users = users; 91 | } 92 | 93 | @Override 94 | public void afterPropertiesSet() throws Exception { 95 | if (StringUtils.isBlank(host)) { 96 | throw new InvalidConfigurationException("Matrix HS client endpoint must be configured"); 97 | } 98 | 99 | if (StringUtils.isBlank(asToken)) { 100 | throw new InvalidConfigurationException("Matrix AS token must be configured"); 101 | } 102 | 103 | if (StringUtils.isBlank(hsToken)) { 104 | throw new InvalidConfigurationException("Matrix HS token must be configured"); 105 | } 106 | 107 | if (StringUtils.isBlank(localpart)) { 108 | throw new InvalidConfigurationException("Matrix AS localpart must be configured"); 109 | } 110 | 111 | if (users == null || users.isEmpty()) { 112 | throw new InvalidConfigurationException("At least one Matrix user template must be configured"); 113 | } 114 | 115 | log.info("Domain: {}", getDomain()); 116 | log.info("Host: {}", getHost()); 117 | log.info("AS Token: {}", getAsToken()); 118 | log.info("HS Token: {}", getHsToken()); 119 | log.info("Localpart: {}", getLocalpart()); 120 | log.info("Users:"); 121 | for (EntityTemplateConfig p : getUsers()) { 122 | log.info("- {}", p); 123 | } 124 | } 125 | 126 | } 127 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/config/matrix/IdentityConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.config.matrix; 22 | 23 | import org.springframework.beans.factory.annotation.Autowired; 24 | import org.springframework.boot.context.properties.ConfigurationProperties; 25 | import org.springframework.context.annotation.Configuration; 26 | 27 | @Configuration 28 | @ConfigurationProperties("matrix.identity") 29 | public class IdentityConfig { 30 | 31 | @Autowired 32 | private MatrixConfig mxCfg; 33 | 34 | private String template; 35 | 36 | public String getDomain() { 37 | return mxCfg.getDomain(); 38 | } 39 | 40 | public String getTemplate() { 41 | return template; 42 | } 43 | 44 | public void setTemplate(String template) { 45 | this.template = template; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/config/matrix/MatrixConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.config.matrix; 22 | 23 | import io.kamax.matrix.bridge.email.exception.InvalidConfigurationException; 24 | import org.apache.commons.lang.StringUtils; 25 | import org.springframework.beans.factory.InitializingBean; 26 | import org.springframework.boot.context.properties.ConfigurationProperties; 27 | import org.springframework.context.annotation.Configuration; 28 | 29 | @Configuration 30 | @ConfigurationProperties("matrix") 31 | public class MatrixConfig implements InitializingBean { 32 | 33 | private String domain; 34 | 35 | public String getDomain() { 36 | return domain; 37 | } 38 | 39 | public void setDomain(String domain) { 40 | this.domain = domain; 41 | } 42 | 43 | @Override 44 | public void afterPropertiesSet() throws Exception { 45 | if (StringUtils.isBlank(domain)) { 46 | throw new InvalidConfigurationException("Matrix domain must be configured"); 47 | } 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/config/subscription/EmailNotificationConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.config.subscription; 22 | 23 | import io.kamax.matrix.bridge.email.model.subscription.SubscriptionEvents; 24 | import org.slf4j.Logger; 25 | import org.slf4j.LoggerFactory; 26 | import org.springframework.beans.factory.InitializingBean; 27 | import org.springframework.boot.context.properties.ConfigurationProperties; 28 | import org.springframework.context.annotation.Configuration; 29 | 30 | @Configuration 31 | @ConfigurationProperties("subscription.notification.email") 32 | public class EmailNotificationConfig implements InitializingBean { 33 | 34 | private Logger log = LoggerFactory.getLogger(EmailNotificationConfig.class); 35 | 36 | private EmailTemplateConfig onCreate; 37 | private EmailTemplateConfig onDestroy; 38 | private EmailTemplateConfig onMessage; 39 | 40 | public EmailTemplateConfig getOnCreate() { 41 | return onCreate; 42 | } 43 | 44 | public void setOnCreate(EmailTemplateConfig onCreate) { 45 | this.onCreate = onCreate; 46 | } 47 | 48 | public EmailTemplateConfig getOnDestroy() { 49 | return onDestroy; 50 | } 51 | 52 | public void setOnDestroy(EmailTemplateConfig onDestroy) { 53 | this.onDestroy = onDestroy; 54 | } 55 | 56 | public EmailTemplateConfig getOnMessage() { 57 | return onMessage; 58 | } 59 | 60 | public void setOnMessage(EmailTemplateConfig onMessage) { 61 | this.onMessage = onMessage; 62 | } 63 | 64 | public EmailTemplateConfig get(SubscriptionEvents event) { 65 | switch (event) { 66 | case OnCreate: 67 | return getOnCreate(); 68 | case OnDestroy: 69 | return getOnDestroy(); 70 | case OnMessage: 71 | return getOnMessage(); 72 | default: 73 | return new EmailTemplateConfig(); 74 | } 75 | } 76 | 77 | @Override 78 | public void afterPropertiesSet() throws Exception { 79 | for (SubscriptionEvents eventId : SubscriptionEvents.values()) { 80 | log.info("Template for {}:", eventId); 81 | EmailTemplateConfig cfg = get(eventId); 82 | log.info("Subject: {}", cfg.getSubject()); 83 | for (EmailTemplateContentConfig template : cfg.getContent()) { 84 | log.info("- Type: {}", template.getType()); 85 | log.info(" Header: {}", template.getHeader()); 86 | log.info(" Footer: {}", template.getFooter()); 87 | log.info(" Content: {}", template.getContent()); 88 | log.info(" Message: {}", template.getMessage()); 89 | } 90 | log.info("--"); 91 | } 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/config/subscription/EmailTemplateConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.config.subscription; 22 | 23 | import org.springframework.stereotype.Component; 24 | 25 | import java.util.ArrayList; 26 | import java.util.List; 27 | 28 | @Component 29 | public class EmailTemplateConfig { 30 | 31 | private String subject; 32 | private List content = new ArrayList<>(); 33 | 34 | public String getSubject() { 35 | return subject; 36 | } 37 | 38 | public void setSubject(String subject) { 39 | this.subject = subject; 40 | } 41 | 42 | public List getContent() { 43 | return content; 44 | } 45 | 46 | public void setContent(List content) { 47 | this.content = content; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/config/subscription/EmailTemplateContentConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.config.subscription; 22 | 23 | import org.springframework.stereotype.Component; 24 | 25 | @Component 26 | public class EmailTemplateContentConfig { 27 | 28 | private String type; 29 | private String header; 30 | private String footer; 31 | private String content; 32 | private String message; 33 | 34 | public String getType() { 35 | return type; 36 | } 37 | 38 | public void setType(String type) { 39 | this.type = type; 40 | } 41 | 42 | public String getHeader() { 43 | return header; 44 | } 45 | 46 | public void setHeader(String header) { 47 | this.header = header; 48 | } 49 | 50 | public String getFooter() { 51 | return footer; 52 | } 53 | 54 | public void setFooter(String footer) { 55 | this.footer = footer; 56 | } 57 | 58 | public String getContent() { 59 | return content; 60 | } 61 | 62 | public void setContent(String content) { 63 | this.content = content; 64 | } 65 | 66 | public String getMessage() { 67 | return message; 68 | } 69 | 70 | public void setMessage(String message) { 71 | this.message = message; 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/config/subscription/MatrixNotificationConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.config.subscription; 22 | 23 | import io.kamax.matrix.bridge.email.model.subscription.SubscriptionEvents; 24 | import org.springframework.boot.context.properties.ConfigurationProperties; 25 | import org.springframework.context.annotation.Configuration; 26 | 27 | @Configuration 28 | @ConfigurationProperties("subscription.notification.matrix") 29 | public class MatrixNotificationConfig { 30 | 31 | private boolean onCreate = false; 32 | private boolean onDestroy = false; 33 | private boolean onMessage = false; 34 | 35 | public boolean getOnCreate() { 36 | return onCreate; 37 | } 38 | 39 | public void setOnCreate(boolean onCreate) { 40 | this.onCreate = onCreate; 41 | } 42 | 43 | public boolean getOnDestroy() { 44 | return onDestroy; 45 | } 46 | 47 | public void setOnDestroy(boolean onDestroy) { 48 | this.onDestroy = onDestroy; 49 | } 50 | 51 | public boolean getOnMessage() { 52 | return onMessage; 53 | } 54 | 55 | public void setOnMessage(boolean onMessage) { 56 | this.onMessage = onMessage; 57 | } 58 | 59 | public boolean get(SubscriptionEvents event) { 60 | switch (event) { 61 | case OnCreate: 62 | return getOnCreate(); 63 | case OnDestroy: 64 | return getOnDestroy(); 65 | case OnMessage: 66 | return getOnMessage(); 67 | default: 68 | return false; 69 | } 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/config/subscription/SubscriptionPortalConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.config.subscription; 22 | 23 | 24 | import io.kamax.matrix.bridge.email.exception.InvalidConfigurationException; 25 | import org.slf4j.Logger; 26 | import org.slf4j.LoggerFactory; 27 | import org.springframework.beans.factory.InitializingBean; 28 | import org.springframework.boot.context.properties.ConfigurationProperties; 29 | import org.springframework.context.annotation.Configuration; 30 | 31 | import java.net.MalformedURLException; 32 | import java.net.URL; 33 | 34 | @Configuration 35 | @ConfigurationProperties("subscription.portal") 36 | public class SubscriptionPortalConfig implements InitializingBean { 37 | 38 | private Logger log = LoggerFactory.getLogger(SubscriptionPortalConfig.class); 39 | 40 | private URL urlValidated; 41 | 42 | public URL getUrl() { 43 | return urlValidated; 44 | } 45 | 46 | public void setUrl(String url) { 47 | try { 48 | // Remove any trailing slash 49 | while (url.endsWith("/")) { 50 | url = url.substring(0, url.length() - 1); 51 | } 52 | 53 | urlValidated = new URL(url); 54 | } catch (MalformedURLException e) { 55 | throw new InvalidConfigurationException(url + " is not a valid URL for the subscription portal"); 56 | } 57 | } 58 | 59 | @Override 60 | public void afterPropertiesSet() throws Exception { 61 | if (urlValidated == null) { 62 | throw new InvalidConfigurationException("Subscription Portal URL must be set"); 63 | } 64 | 65 | log.info("Subscription Portal URL: {}", urlValidated.toExternalForm()); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/controller/EmptyJsonResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.controller; 22 | 23 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 24 | 25 | @JsonSerialize 26 | public class EmptyJsonResponse { 27 | 28 | private final static EmptyJsonResponse obj = new EmptyJsonResponse(); 29 | 30 | public static EmptyJsonResponse get() { 31 | return obj; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/controller/MappingController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.controller; 22 | 23 | import io.kamax.matrix.ThreePid; 24 | import io.kamax.matrix.ThreePidMapping; 25 | import io.kamax.matrix.bridge.email.model.matrix._MatrixApplicationService; 26 | import org.springframework.beans.factory.annotation.Autowired; 27 | import org.springframework.http.ResponseEntity; 28 | import org.springframework.web.bind.annotation.RequestMapping; 29 | import org.springframework.web.bind.annotation.RequestParam; 30 | import org.springframework.web.bind.annotation.RestController; 31 | 32 | import java.util.Optional; 33 | 34 | import static org.springframework.web.bind.annotation.RequestMethod.GET; 35 | 36 | @RestController 37 | public class MappingController { 38 | 39 | @Autowired 40 | private _MatrixApplicationService as; 41 | 42 | @RequestMapping(value = "/_matrix/identity/api/v1/lookup", method = GET) 43 | ResponseEntity lookup(@RequestParam String medium, @RequestParam String address) { 44 | ThreePid threePid = new ThreePid(medium, address); 45 | 46 | Optional mapping = as.getMatrixId(threePid); 47 | if (mapping.isPresent()) { 48 | return ResponseEntity.ok(ThreePidMappingAnswer.get(mapping.get())); 49 | } else { 50 | return ResponseEntity.ok(EmptyJsonResponse.get()); 51 | } 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/controller/SubscriptionController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.controller; 22 | 23 | import io.kamax.matrix.bridge.email.exception.InvalidEmailKeyException; 24 | import io.kamax.matrix.bridge.email.model.subscription.SubscriptionPortalService; 25 | import io.kamax.matrix.bridge.email.model.subscription._BridgeSubscription; 26 | import io.kamax.matrix.bridge.email.model.subscription._SubscriptionManager; 27 | import org.slf4j.Logger; 28 | import org.slf4j.LoggerFactory; 29 | import org.springframework.beans.factory.annotation.Autowired; 30 | import org.springframework.http.HttpStatus; 31 | import org.springframework.stereotype.Controller; 32 | import org.springframework.ui.Model; 33 | import org.springframework.web.bind.annotation.ExceptionHandler; 34 | import org.springframework.web.bind.annotation.RequestMapping; 35 | import org.springframework.web.bind.annotation.RequestParam; 36 | import org.springframework.web.bind.annotation.ResponseStatus; 37 | 38 | import java.util.ArrayList; 39 | import java.util.List; 40 | import java.util.Optional; 41 | 42 | import static org.springframework.web.bind.annotation.RequestMethod.GET; 43 | 44 | @Controller 45 | public class SubscriptionController { 46 | 47 | private Logger log = LoggerFactory.getLogger(SubscriptionController.class); 48 | 49 | @Autowired 50 | private _SubscriptionManager subMgr; 51 | 52 | @ResponseStatus(value = HttpStatus.BAD_REQUEST) 53 | @ExceptionHandler(InvalidEmailKeyException.class) 54 | String handleBadRequest() { 55 | return "subscription/invalidToken"; 56 | } 57 | 58 | @RequestMapping(value = SubscriptionPortalService.BASE_PATH, method = GET) 59 | public String listSubscriptions(Model model, @RequestParam String token) { 60 | log.info("Subscription list request"); 61 | 62 | Optional<_BridgeSubscription> subOpt = subMgr.getWithEmailKey(token); 63 | if (!subOpt.isPresent()) { 64 | throw new InvalidEmailKeyException(); 65 | } 66 | 67 | log.info("E-mail token is valid: {}", token); 68 | String email = subOpt.get().getEmailEndpoint().getIdentity(); 69 | log.info("E-mail user: {}", email); 70 | 71 | List subs = new ArrayList<>(); 72 | for (_BridgeSubscription sub : subMgr.listForEmail(email)) { 73 | subs.add(new SubscriptionItem(sub)); 74 | } 75 | log.info("Found {} subscription(s)", subs.size()); 76 | 77 | model.addAttribute("subList", subs); 78 | 79 | return "subscription/list"; 80 | } 81 | 82 | @RequestMapping(value = SubscriptionPortalService.BASE_PATH + "/remove", method = GET) 83 | public String delete(Model model, @RequestParam String token) { 84 | log.info("Subscription {} remove request", token); 85 | 86 | Optional<_BridgeSubscription> subOpt = subMgr.getWithEmailKey(token); 87 | if (!subOpt.isPresent()) { 88 | throw new InvalidEmailKeyException(); 89 | } 90 | 91 | subOpt.get().terminate(); 92 | 93 | return "subscription/deleteSuccess"; 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/controller/SubscriptionItem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.controller; 22 | 23 | import io.kamax.matrix.MatrixID; 24 | import io.kamax.matrix.bridge.email.model.subscription._BridgeSubscription; 25 | import io.kamax.matrix.client._MatrixClient; 26 | import io.kamax.matrix.hs._MatrixRoom; 27 | 28 | import java.time.Instant; 29 | 30 | public class SubscriptionItem { 31 | 32 | private String id; 33 | private String token; 34 | private String name; 35 | private Instant date; 36 | private String creator; 37 | 38 | public SubscriptionItem(_BridgeSubscription sub) { 39 | _MatrixClient client = sub.getMatrixEndpoint().getClient(); 40 | _MatrixRoom room = client.getRoom(sub.getMatrixEndpoint().getChannelId()); 41 | 42 | this.id = sub.getId(); 43 | this.token = sub.getEmailKey(); 44 | this.name = room.getName().orElse(room.getAddress()); 45 | this.creator = client.getUser(new MatrixID(sub.getInitiator())).getName().orElse(sub.getInitiator()); 46 | this.date = sub.getCreation(); 47 | } 48 | 49 | public String getId() { 50 | return id; 51 | } 52 | 53 | public String getToken() { 54 | return token; 55 | } 56 | 57 | public String getName() { 58 | return name; 59 | } 60 | 61 | public Instant getDate() { 62 | return date; 63 | } 64 | 65 | public String getCreator() { 66 | return creator; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/controller/ThreePidMappingAnswer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.controller; 22 | 23 | import io.kamax.matrix.ThreePidMapping; 24 | 25 | public class ThreePidMappingAnswer { 26 | 27 | public static ThreePidMappingAnswer get(ThreePidMapping mapping) { 28 | ThreePidMappingAnswer answer = new ThreePidMappingAnswer(); 29 | answer.setMedium(mapping.getThreePid().getMedium()); 30 | answer.setAddress(mapping.getThreePid().getAddress()); 31 | answer.setMxid(mapping.getMatrixId().getId()); 32 | return answer; 33 | } 34 | 35 | private String medium; 36 | private String address; 37 | private String mxid; 38 | 39 | public String getMedium() { 40 | return medium; 41 | } 42 | 43 | public void setMedium(String medium) { 44 | this.medium = medium; 45 | } 46 | 47 | public String getAddress() { 48 | return address; 49 | } 50 | 51 | public void setAddress(String address) { 52 | this.address = address; 53 | } 54 | 55 | public String getMxid() { 56 | return mxid; 57 | } 58 | 59 | public void setMxid(String mxid) { 60 | this.mxid = mxid; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/dao/BridgeSubscriptionDao.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.dao; 22 | 23 | 24 | public class BridgeSubscriptionDao { 25 | 26 | private String subId; 27 | private String sourceMxId; 28 | private long timestamp; 29 | private String email; 30 | private String threadId; 31 | private String mxId; 32 | private String roomId; 33 | 34 | public String getSubId() { 35 | return subId; 36 | } 37 | 38 | public void setSubId(String subId) { 39 | this.subId = subId; 40 | } 41 | 42 | public String getSourceMxId() { 43 | return sourceMxId; 44 | } 45 | 46 | public void setSourceMxId(String sourceMxId) { 47 | this.sourceMxId = sourceMxId; 48 | } 49 | 50 | public long getTimestamp() { 51 | return timestamp; 52 | } 53 | 54 | public void setTimestamp(long timestamp) { 55 | this.timestamp = timestamp; 56 | } 57 | 58 | public String getEmail() { 59 | return email; 60 | } 61 | 62 | public void setEmail(String email) { 63 | this.email = email; 64 | } 65 | 66 | public String getThreadId() { 67 | return threadId; 68 | } 69 | 70 | public void setThreadId(String threadId) { 71 | this.threadId = threadId; 72 | } 73 | 74 | public String getMxId() { 75 | return mxId; 76 | } 77 | 78 | public void setMxId(String mxId) { 79 | this.mxId = mxId; 80 | } 81 | 82 | public String getRoomId() { 83 | return roomId; 84 | } 85 | 86 | public void setRoomId(String roomId) { 87 | this.roomId = roomId; 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/dao/_SubscriptionDao.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.dao; 22 | 23 | import org.springframework.stereotype.Component; 24 | 25 | import java.util.List; 26 | 27 | @Component 28 | public interface _SubscriptionDao { 29 | 30 | void store(BridgeSubscriptionDao dao); 31 | 32 | void delete(String id); 33 | 34 | List list(); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/dao/sqlite/SubscriptionSqlite.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.dao.sqlite; 22 | 23 | 24 | import io.kamax.matrix.bridge.email.config.dao.SubscriptionSqliteConfig; 25 | import io.kamax.matrix.bridge.email.dao.BridgeSubscriptionDao; 26 | import io.kamax.matrix.bridge.email.dao._SubscriptionDao; 27 | import io.kamax.matrix.bridge.email.exception.StorageException; 28 | import org.apache.commons.lang.StringUtils; 29 | import org.slf4j.Logger; 30 | import org.slf4j.LoggerFactory; 31 | import org.springframework.beans.factory.InitializingBean; 32 | import org.springframework.beans.factory.annotation.Autowired; 33 | import org.springframework.stereotype.Component; 34 | 35 | import java.io.File; 36 | import java.sql.*; 37 | import java.util.ArrayList; 38 | import java.util.List; 39 | 40 | @Component 41 | public class SubscriptionSqlite implements InitializingBean, _SubscriptionDao { 42 | 43 | private Logger log = LoggerFactory.getLogger(SubscriptionSqlite.class); 44 | 45 | @Autowired 46 | private SubscriptionSqliteConfig cfg; 47 | 48 | private Connection conn; 49 | 50 | @Override 51 | public void afterPropertiesSet() throws Exception { 52 | File dbFile = new File(StringUtils.defaultIfBlank(cfg.getLocation(), "as-subscriptions.db")).getAbsoluteFile(); 53 | log.info("SQLite DB: {}", dbFile.getPath()); 54 | 55 | if (!dbFile.exists()) { 56 | log.info("SQLlite DB file does not exist, provisioning"); 57 | } 58 | 59 | conn = DriverManager.getConnection("jdbc:sqlite:" + dbFile.getPath()); 60 | try (Statement stmt = conn.createStatement()) { 61 | stmt.executeUpdate("CREATE TABLE IF NOT EXISTS subscription (id string PRIMARY KEY, sourceMxId string, timestamp long, email string, threadId string, mxId string, roomId string)"); 62 | } 63 | } 64 | 65 | @Override 66 | public void store(BridgeSubscriptionDao dao) { 67 | log.info("Storing subscription {} in DB", dao.getSubId()); 68 | 69 | try (PreparedStatement stmt = conn.prepareStatement("REPLACE INTO subscription VALUES(?,?,?,?,?,?,?)")) { 70 | stmt.setString(1, dao.getSubId()); 71 | stmt.setString(2, dao.getSourceMxId()); 72 | stmt.setLong(3, dao.getTimestamp()); 73 | stmt.setString(4, dao.getEmail()); 74 | stmt.setString(5, dao.getThreadId()); 75 | stmt.setString(6, dao.getMxId()); 76 | stmt.setString(7, dao.getRoomId()); 77 | 78 | int rowCount = stmt.executeUpdate(); 79 | log.info("Updated rows: {}", rowCount); 80 | } catch (SQLException e) { 81 | throw new StorageException(e); 82 | } 83 | } 84 | 85 | @Override 86 | public void delete(String id) { 87 | log.info("Deleting subscription {} from DB", id); 88 | 89 | try (PreparedStatement stmt = conn.prepareStatement("DELETE FROM subscription WHERE id = ?")) { 90 | stmt.setString(1, id); 91 | int rowCount = stmt.executeUpdate(); 92 | log.info("Updated rows: {}", rowCount); 93 | } catch (SQLException e) { 94 | throw new StorageException(e); 95 | } 96 | } 97 | 98 | @Override 99 | public List list() { 100 | try (Statement stmt = conn.createStatement()) { 101 | try (ResultSet rSet = stmt.executeQuery("SELECT * FROM subscription")) { 102 | List daoList = new ArrayList<>(); 103 | 104 | while (rSet.next()) { 105 | BridgeSubscriptionDao dao = new BridgeSubscriptionDao(); 106 | dao.setSubId(rSet.getString("id")); 107 | dao.setSourceMxId(rSet.getString("sourceMxId")); 108 | dao.setTimestamp(rSet.getLong("timestamp")); 109 | dao.setEmail(rSet.getString("email")); 110 | dao.setThreadId(rSet.getString("threadId")); 111 | dao.setMxId(rSet.getString("mxId")); 112 | dao.setRoomId(rSet.getString("roomId")); 113 | daoList.add(dao); 114 | } 115 | 116 | return daoList; 117 | } 118 | } catch (SQLException e) { 119 | throw new StorageException(e); 120 | } 121 | } 122 | 123 | } 124 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/exception/InvalidBodyContentException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.exception; 22 | 23 | public class InvalidBodyContentException extends MatrixException { 24 | 25 | public InvalidBodyContentException(Throwable t) { 26 | super(t); 27 | } 28 | 29 | @Override 30 | public String getErrorCode() { 31 | return "M.INVALID_REQUEST.BODY_CONTENT"; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/exception/InvalidConfigurationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.exception; 22 | 23 | public class InvalidConfigurationException extends RuntimeException { 24 | 25 | public InvalidConfigurationException(String s) { 26 | super(s); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/exception/InvalidEmailKeyException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.exception; 22 | 23 | public class InvalidEmailKeyException extends RuntimeException { 24 | 25 | public InvalidEmailKeyException() { 26 | super("Your token is invalid"); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/exception/InvalidHomeserverTokenException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.exception; 22 | 23 | public class InvalidHomeserverTokenException extends MatrixException { 24 | 25 | @Override 26 | public String getErrorCode() { 27 | return "M_FORBIDDEN"; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/exception/InvalidMatrixIdException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.exception; 22 | 23 | public class InvalidMatrixIdException extends MatrixException { 24 | 25 | public InvalidMatrixIdException(String s) { 26 | super(s); 27 | } 28 | 29 | public InvalidMatrixIdException(Throwable t) { 30 | super(t); 31 | } 32 | 33 | @Override 34 | public String getErrorCode() { 35 | return "M_MATRIX_ID_INVALID"; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/exception/MatrixException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.exception; 22 | 23 | public abstract class MatrixException extends RuntimeException { 24 | 25 | public MatrixException() { 26 | super(); 27 | } 28 | 29 | public MatrixException(String s) { 30 | super(s); 31 | } 32 | 33 | public MatrixException(Throwable t) { 34 | super(t); 35 | } 36 | 37 | public abstract String getErrorCode(); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/exception/NoHomeserverTokenException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.exception; 22 | 23 | public class NoHomeserverTokenException extends MatrixException { 24 | 25 | @Override 26 | public String getErrorCode() { 27 | return "AS_CREDENTIALS_MISSING"; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/exception/RoomNotFoundException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.exception; 22 | 23 | public class RoomNotFoundException extends MatrixException { 24 | 25 | @Override 26 | public String getErrorCode() { 27 | return "AS_ROOM_NOT_FOUND"; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/exception/StorageException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.exception; 22 | 23 | public class StorageException extends RuntimeException { 24 | 25 | public StorageException(Throwable t) { 26 | super(t); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/exception/UserNotFoundException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.exception; 22 | 23 | public class UserNotFoundException extends MatrixException { 24 | 25 | @Override 26 | public String getErrorCode() { 27 | return "AS_USER_NOT_FOUND"; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/ABridgeMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model; 22 | 23 | import java.time.Instant; 24 | import java.util.HashMap; 25 | import java.util.List; 26 | import java.util.Map; 27 | import java.util.Optional; 28 | 29 | public abstract class ABridgeMessage implements _BridgeMessage { 30 | 31 | private String key; 32 | private Instant time; 33 | private T sender; 34 | private Map parts; 35 | 36 | public ABridgeMessage(String key, Instant time, T sender, List<_BridgeMessageContent> partsList) { 37 | this.key = key; 38 | this.time = time; 39 | this.sender = sender; 40 | 41 | Map partsMap = new HashMap<>(); 42 | for (_BridgeMessageContent part : partsList) { 43 | partsMap.put(part.getMime(), part); 44 | } 45 | this.parts = partsMap; 46 | } 47 | 48 | @Override 49 | public String getKey() { 50 | return key; 51 | } 52 | 53 | @Override 54 | public T getSender() { 55 | return sender; 56 | } 57 | 58 | @Override 59 | public Instant getTime() { 60 | return time; 61 | } 62 | 63 | @Override 64 | public Optional<_BridgeMessageContent> getContent(String mime) { 65 | return Optional.ofNullable(parts.get(mime)); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/AEndPoint.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model; 22 | 23 | import io.kamax.matrix.bridge.email.model.subscription._BridgeSubscription; 24 | import io.kamax.matrix.bridge.email.model.subscription._SubscriptionEvent; 25 | import org.slf4j.Logger; 26 | import org.slf4j.LoggerFactory; 27 | 28 | import java.util.ArrayList; 29 | import java.util.List; 30 | 31 | 32 | public abstract class AEndPoint implements _EndPoint { 33 | 34 | private Logger log = LoggerFactory.getLogger(AEndPoint.class); 35 | 36 | private String id; 37 | private K identity; 38 | private String channel; 39 | 40 | private boolean isClosed; 41 | private List<_EndPointMessageListener> msgListeners = new ArrayList<>(); 42 | private List<_EndPointStateListener> stateListeners = new ArrayList<>(); 43 | 44 | public AEndPoint(String id, K identity, String channel) { 45 | this.id = id; 46 | this.identity = identity; 47 | this.channel = channel; 48 | } 49 | 50 | @Override 51 | public String getId() { 52 | return id; 53 | } 54 | 55 | @Override 56 | public String getChannelId() { 57 | return channel; 58 | } 59 | 60 | @Override 61 | public K getIdentity() { 62 | return identity; 63 | } 64 | 65 | @Override 66 | public boolean isClosed() { 67 | return isClosed; 68 | } 69 | 70 | protected abstract void sendEventImpl(_SubscriptionEvent ev); 71 | 72 | @Override 73 | public void sendEvent(_SubscriptionEvent ev) { 74 | if (isClosed()) { 75 | log.info("Ignoring subscription event {} notification, endpoint {} is closed", ev.getType(), getId()); 76 | return; 77 | } 78 | 79 | sendEventImpl(ev); 80 | } 81 | 82 | protected abstract void sendMessageImpl(_BridgeSubscription sub, V msg); 83 | 84 | @Override 85 | public void sendMessage(_BridgeSubscription sub, V msg) { 86 | if (isClosed()) { 87 | log.info("Ignoring message {}, endpoint {} is closed", msg.getKey(), getId()); 88 | return; 89 | } 90 | 91 | sendMessageImpl(sub, msg); 92 | } 93 | 94 | protected abstract void closeImpl(); 95 | 96 | @Override 97 | public void close() { 98 | log.info("Closing endpoint for user {} in channel {}", getIdentity(), getChannelId()); 99 | 100 | closeImpl(); 101 | isClosed = true; 102 | 103 | fireClosedEvent(); 104 | } 105 | 106 | @Override 107 | public void addMessageListener(_EndPointMessageListener listener) { 108 | log.info("Adding message listener to endpoint {}", id); 109 | 110 | msgListeners.add(listener); 111 | } 112 | 113 | public void addStateListener(_EndPointStateListener listener) { 114 | log.info("Adding state listener to endpoint {}", id); 115 | 116 | stateListeners.add(listener); 117 | } 118 | 119 | protected void fireMessageEvent(S msg) { 120 | log.info("Sending message event to {} listeners", msgListeners.size()); 121 | 122 | for (_EndPointMessageListener listener : msgListeners) { 123 | listener.push(msg); 124 | } 125 | } 126 | 127 | protected void fireClosedEvent() { 128 | log.info("Sending close event to {} listeners", msgListeners.size()); 129 | 130 | for (_EndPointStateListener listener : stateListeners) { 131 | listener.closed(this); 132 | } 133 | } 134 | 135 | } 136 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/BridgeEmailCodec.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model; 22 | 23 | import org.apache.commons.codec.DecoderException; 24 | import org.apache.commons.codec.binary.Hex; 25 | import org.springframework.stereotype.Component; 26 | 27 | import java.nio.charset.StandardCharsets; 28 | import java.util.regex.Matcher; 29 | import java.util.regex.Pattern; 30 | 31 | @Component 32 | public class BridgeEmailCodec { 33 | 34 | 35 | public static final String delimiter = "="; 36 | public static final String charsToReplaceRegex = "[^0-9a-z-._]+"; 37 | public static final Pattern charsToReplacePattern = Pattern.compile(charsToReplaceRegex); 38 | public static final Pattern decodePattern = Pattern.compile("(=[0-9a-f]{2})+"); 39 | 40 | public String decode(String valueEncoded) { 41 | StringBuilder builder = new StringBuilder(); 42 | 43 | Matcher m = decodePattern.matcher(valueEncoded); 44 | int prevEnd = 0; 45 | while (m.find()) { 46 | try { 47 | int start = m.start(); 48 | int end = m.end(); 49 | String sub = valueEncoded.substring(start, end).replaceAll(delimiter, ""); 50 | String decoded = new String(Hex.decodeHex(sub.toCharArray()), StandardCharsets.UTF_8); 51 | builder.append(valueEncoded.substring(prevEnd, start)); 52 | builder.append(decoded); 53 | prevEnd = end - 1; 54 | } catch (DecoderException e) { 55 | e.printStackTrace(); 56 | } 57 | } 58 | prevEnd++; 59 | if (prevEnd < valueEncoded.length()) { 60 | builder.append(valueEncoded.substring(prevEnd, valueEncoded.length())); 61 | } 62 | 63 | if (builder.length() == 0) { 64 | return valueEncoded; 65 | } else { 66 | return builder.toString(); 67 | } 68 | } 69 | 70 | public String encode(String value) { 71 | value = value.toLowerCase(); 72 | 73 | StringBuilder builder = new StringBuilder(); 74 | for (Character c : value.toCharArray()) { 75 | String s = c.toString(); 76 | Matcher lp = charsToReplacePattern.matcher(s); 77 | if (!lp.find()) { 78 | builder.append(s); 79 | } else { 80 | for (byte b : c.toString().getBytes(StandardCharsets.UTF_8)) { 81 | builder.append(delimiter); 82 | builder.append(Hex.encodeHexString(new byte[]{b})); 83 | } 84 | } 85 | } 86 | 87 | return builder.toString(); 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/BridgeMessageContent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model; 22 | 23 | import org.apache.commons.lang.StringUtils; 24 | 25 | import java.nio.charset.StandardCharsets; 26 | 27 | public class BridgeMessageContent implements _BridgeMessageContent { 28 | 29 | private String mime; 30 | private String encoding; 31 | private byte[] content; 32 | 33 | public BridgeMessageContent(String mime) { 34 | this(mime, new byte[0]); 35 | } 36 | 37 | public BridgeMessageContent(String mime, byte[] content) { 38 | this(mime, null, content); 39 | } 40 | 41 | public BridgeMessageContent(String mime, String encoding, byte[] content) { 42 | this.mime = mime; 43 | this.encoding = StringUtils.defaultIfBlank(encoding, ""); 44 | this.content = content; 45 | } 46 | 47 | @Override 48 | public String getMime() { 49 | return mime; 50 | } 51 | 52 | @Override 53 | public String getEncoding() { 54 | return encoding; 55 | } 56 | 57 | @Override 58 | public byte[] getContent() { 59 | return content; 60 | } 61 | 62 | @Override 63 | public String getContentAsString() { 64 | return new String(getContent(), StandardCharsets.UTF_8); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/BridgeMessageHtmlContent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model; 22 | 23 | import org.springframework.util.MimeTypeUtils; 24 | 25 | public class BridgeMessageHtmlContent extends BridgeMessageContent { 26 | 27 | public BridgeMessageHtmlContent(String content) { 28 | super(MimeTypeUtils.TEXT_HTML_VALUE, content.getBytes()); 29 | } 30 | 31 | public BridgeMessageHtmlContent(String content, String encoding) { 32 | super(MimeTypeUtils.TEXT_HTML_VALUE, encoding, content.getBytes()); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/BridgeMessageTextContent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model; 22 | 23 | import org.springframework.util.MimeTypeUtils; 24 | 25 | public class BridgeMessageTextContent extends BridgeMessageContent { 26 | 27 | public BridgeMessageTextContent(String content) { 28 | super(MimeTypeUtils.TEXT_PLAIN_VALUE, content.getBytes()); 29 | } 30 | 31 | public BridgeMessageTextContent(String content, String encoding) { 32 | super(MimeTypeUtils.TEXT_PLAIN_VALUE, encoding, content.getBytes()); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/MessageFormatter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model; 22 | 23 | import io.kamax.matrix.bridge.email.model.email._EmailBridgeMessage; 24 | import io.kamax.matrix.bridge.email.model.matrix._MatrixBridgeMessage; 25 | import org.springframework.stereotype.Component; 26 | 27 | @Component 28 | public class MessageFormatter implements _MessageFormatter { 29 | 30 | @Override 31 | public _EmailBridgeMessage format(_EmailBridgeMessage msg) { 32 | return msg; 33 | } 34 | 35 | @Override 36 | public _MatrixBridgeMessage format(_MatrixBridgeMessage msg) { 37 | return msg; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/_BridgeMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model; 22 | 23 | import java.time.Instant; 24 | import java.util.Optional; 25 | 26 | public interface _BridgeMessage { 27 | 28 | String getKey(); 29 | 30 | T getSender(); 31 | 32 | Instant getTime(); 33 | 34 | Optional<_BridgeMessageContent> getContent(String mime); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/_BridgeMessageContent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model; 22 | 23 | public interface _BridgeMessageContent { 24 | 25 | String getMime(); 26 | 27 | String getEncoding(); 28 | 29 | byte[] getContent(); 30 | 31 | String getContentAsString(); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/_EndPoint.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model; 22 | 23 | import io.kamax.matrix.bridge.email.model.subscription._BridgeSubscription; 24 | import io.kamax.matrix.bridge.email.model.subscription._SubscriptionEvent; 25 | 26 | public interface _EndPoint { 27 | 28 | String getId(); 29 | 30 | String getChannelId(); 31 | 32 | K getIdentity(); 33 | 34 | boolean isClosed(); 35 | 36 | void close(); 37 | 38 | void sendEvent(_SubscriptionEvent ev); 39 | 40 | void sendMessage(_BridgeSubscription sub, V msg); 41 | 42 | void addMessageListener(_EndPointMessageListener listener); 43 | 44 | void addStateListener(_EndPointStateListener listener); 45 | 46 | interface _EndPointMessageListener { 47 | 48 | void push(S msg); 49 | 50 | } 51 | 52 | interface _EndPointStateListener { 53 | 54 | void closed(_EndPoint ep); 55 | 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/_MessageFormatter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model; 22 | 23 | import io.kamax.matrix.bridge.email.model.email._EmailBridgeMessage; 24 | import io.kamax.matrix.bridge.email.model.matrix._MatrixBridgeMessage; 25 | 26 | public interface _MessageFormatter { 27 | 28 | _EmailBridgeMessage format(_EmailBridgeMessage msg); 29 | 30 | _MatrixBridgeMessage format(_MatrixBridgeMessage msg); 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/email/AEmailClientFormatter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.email; 22 | 23 | import io.kamax.matrix.bridge.email.model.BridgeMessageHtmlContent; 24 | import io.kamax.matrix.bridge.email.model.BridgeMessageTextContent; 25 | import io.kamax.matrix.bridge.email.model._BridgeMessageContent; 26 | import org.apache.commons.io.IOUtils; 27 | import org.apache.commons.lang.StringUtils; 28 | 29 | import java.io.IOException; 30 | import java.io.StringReader; 31 | import java.util.ArrayList; 32 | import java.util.List; 33 | 34 | public abstract class AEmailClientFormatter implements _EmailClientFormatter { 35 | 36 | protected String formatPlain(String content) { 37 | // TODO do a proper algorithm 38 | 39 | try { 40 | int maxLine = 0; 41 | 42 | 43 | List linesIn = IOUtils.readLines(new StringReader(content)); 44 | for (int i = 0; i < linesIn.size(); i++) { 45 | if (linesIn.get(i).startsWith(">")) { 46 | maxLine = i - (StringUtils.isBlank(linesIn.get(i - 1)) ? 2 : 1); 47 | break; 48 | } 49 | } 50 | 51 | List linesOut = new ArrayList<>(); 52 | boolean prevLineBlank = false; 53 | for (int i = 0; i < maxLine; i++) { 54 | String line = StringUtils.trimToEmpty(linesIn.get(i)); 55 | if (StringUtils.isBlank(line)) { 56 | if (prevLineBlank) { 57 | continue; 58 | } 59 | 60 | prevLineBlank = true; 61 | } else { 62 | prevLineBlank = false; 63 | } 64 | linesOut.add(line); 65 | } 66 | 67 | if (prevLineBlank) { 68 | linesOut.remove(linesOut.size() - 1); 69 | } 70 | 71 | return StringUtils.join(linesOut, System.lineSeparator()); 72 | } catch (IOException e) { 73 | // This should never happen, we can't deal with it here 74 | throw new RuntimeException(e); 75 | } 76 | } 77 | 78 | protected abstract String formatHtml(String content); 79 | 80 | @Override 81 | public _BridgeMessageContent format(_BridgeMessageContent content) { 82 | if ("text/plain".contentEquals(content.getMime())) { 83 | return new BridgeMessageTextContent(formatPlain(content.getContentAsString())); 84 | } else if ("text/html".contentEquals(content.getMime())) { 85 | return new BridgeMessageHtmlContent(formatHtml(content.getContentAsString())); 86 | } else { 87 | throw new IllegalArgumentException(content.getMime() + " is not supported"); 88 | } 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/email/EmailBridgeMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.email; 22 | 23 | import io.kamax.matrix.bridge.email.model.ABridgeMessage; 24 | import io.kamax.matrix.bridge.email.model._BridgeMessageContent; 25 | 26 | import java.time.Instant; 27 | import java.util.List; 28 | 29 | public class EmailBridgeMessage extends ABridgeMessage implements _EmailBridgeMessage { 30 | 31 | public EmailBridgeMessage(String key, Instant time, String email, List<_BridgeMessageContent> parts) { 32 | super(key, time, email, parts); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/email/EmailEndPoint.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.email; 22 | 23 | import com.sun.mail.smtp.SMTPTransport; 24 | import io.kamax.matrix.bridge.email.config.email.EmailSenderConfig; 25 | import io.kamax.matrix.bridge.email.model.AEndPoint; 26 | import io.kamax.matrix.bridge.email.model.matrix._MatrixBridgeMessage; 27 | import io.kamax.matrix.bridge.email.model.subscription._BridgeSubscription; 28 | import io.kamax.matrix.bridge.email.model.subscription._SubscriptionEvent; 29 | import org.apache.commons.io.output.ByteArrayOutputStream; 30 | import org.slf4j.Logger; 31 | import org.slf4j.LoggerFactory; 32 | 33 | import javax.mail.Message; 34 | import javax.mail.MessagingException; 35 | import javax.mail.Session; 36 | import javax.mail.internet.InternetAddress; 37 | import javax.mail.internet.MimeMessage; 38 | import javax.mail.internet.ParseException; 39 | import java.io.IOException; 40 | import java.util.Date; 41 | import java.util.Optional; 42 | 43 | public class EmailEndPoint extends AEndPoint implements _EmailEndPoint { 44 | 45 | private Logger log = LoggerFactory.getLogger(EmailEndPoint.class); 46 | 47 | private EmailSenderConfig cfg; 48 | private _EmailFormatterOutbound formatter; 49 | 50 | private Session session; 51 | 52 | public EmailEndPoint(String id, String email, String emailKey, EmailSenderConfig cfg, _EmailFormatterOutbound formatter) { 53 | super(id, email, emailKey); 54 | this.cfg = cfg; 55 | this.formatter = formatter; 56 | 57 | session = Session.getInstance(System.getProperties()); 58 | } 59 | 60 | @Override 61 | protected void closeImpl() { 62 | // TODO implement me 63 | log.warn("Email endpoint close: stub"); 64 | } 65 | 66 | private void send(MimeMessage msg) throws MessagingException { 67 | msg.setHeader("X-Mailer", "matrix-appservice-email"); 68 | msg.setSentDate(new Date()); 69 | msg.setRecipients(Message.RecipientType.TO, getIdentity()); 70 | 71 | SMTPTransport transport = (SMTPTransport) session.getTransport("smtp"); 72 | transport.setStartTLS(cfg.getTls() > 0); 73 | transport.setRequireStartTLS(cfg.getTls() > 1); 74 | transport.connect(cfg.getHost(), cfg.getPort(), cfg.getLogin(), cfg.getPassword()); 75 | log.info("Sending email via SMTP using {}:{}", cfg.getHost(), cfg.getPort()); 76 | 77 | try { 78 | transport.sendMessage(msg, InternetAddress.parse(getIdentity())); 79 | } catch (ParseException e) { 80 | try { 81 | log.error("Invalid content in email: {}", e.getMessage()); 82 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 83 | msg.writeTo(out); 84 | log.info("Email dump:\n{}", out.toString()); 85 | } catch (IOException e1) { 86 | log.error("Impossible exception - REPORT!", e1); 87 | } 88 | } catch (MessagingException e) { 89 | log.error("Error when sending email to {}", getIdentity(), e); 90 | } finally { 91 | transport.close(); 92 | } 93 | } 94 | 95 | @Override 96 | protected void sendEventImpl(_SubscriptionEvent ev) { 97 | try { 98 | Optional msg = formatter.get(ev); 99 | if (!msg.isPresent()) { 100 | log.info("Formatter did not return message, ignoring notification"); 101 | return; 102 | } 103 | 104 | send(msg.get()); 105 | log.info("Email bridge: sending event {} to {} - success", ev.getType(), getIdentity()); 106 | } catch (IOException | MessagingException e) { 107 | log.error("Could not send notification to {} about event {}", getIdentity(), ev.getType(), e); 108 | } 109 | } 110 | 111 | @Override 112 | protected void sendMessageImpl(_BridgeSubscription sub, _MatrixBridgeMessage msg) { 113 | log.info("Email bridge: sending message from {} to {} - start", msg.getSender(), getIdentity()); 114 | 115 | try { 116 | Optional mimeMsg = formatter.get(sub, msg); 117 | if (!mimeMsg.isPresent()) { 118 | log.info("Email bridge: formatter did not return any content for matrix message, ignoring"); 119 | } else { 120 | send(mimeMsg.get()); 121 | log.info("Email bridge: sending message from {} to {} - success", msg.getSender(), getIdentity()); 122 | } 123 | } catch (Exception e) { 124 | log.error("Email bridge: sending message from {} to {} - failure", msg.getSender(), getIdentity()); 125 | throw new RuntimeException(e); 126 | } 127 | 128 | log.info("Email bridge: sending message from {} to {} - end", msg.getSender(), getIdentity()); 129 | } 130 | 131 | void inject(_EmailBridgeMessage msg) { 132 | log.info("Email message was injected into end point {} - {} - {}", getId(), getIdentity(), getChannelId()); 133 | 134 | fireMessageEvent(msg); 135 | } 136 | 137 | } 138 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/email/EmailFormatterInbound.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.email; 22 | 23 | import io.kamax.matrix.bridge.email.model.BridgeMessageHtmlContent; 24 | import io.kamax.matrix.bridge.email.model.BridgeMessageTextContent; 25 | import io.kamax.matrix.bridge.email.model._BridgeMessageContent; 26 | import org.apache.commons.codec.DecoderException; 27 | import org.apache.commons.codec.net.QuotedPrintableCodec; 28 | import org.apache.commons.lang.StringUtils; 29 | import org.slf4j.Logger; 30 | import org.slf4j.LoggerFactory; 31 | import org.springframework.beans.factory.annotation.Autowired; 32 | import org.springframework.stereotype.Component; 33 | import org.springframework.util.MimeTypeUtils; 34 | 35 | import javax.mail.Message; 36 | import javax.mail.MessagingException; 37 | import javax.mail.Multipart; 38 | import javax.mail.Part; 39 | import javax.mail.internet.InternetAddress; 40 | import java.io.IOException; 41 | import java.util.*; 42 | 43 | @Component 44 | public class EmailFormatterInbound implements _EmailFormatterInbound { 45 | 46 | private Logger log = LoggerFactory.getLogger(EmailFormatterInbound.class); 47 | 48 | @Autowired 49 | private List<_EmailClientFormatter> clientFormatters; 50 | 51 | protected List<_BridgeMessageContent> extractContent(Part p) throws MessagingException, IOException { 52 | if (p.isMimeType("multipart/*")) { 53 | log.info("Found multipart content, extracting"); 54 | 55 | List<_BridgeMessageContent> contents = new ArrayList<>(); 56 | Multipart mp = (Multipart) p.getContent(); 57 | int count = mp.getCount(); 58 | for (int i = 0; i < count; i++) { 59 | contents.addAll(extractContent(mp.getBodyPart(i))); 60 | } 61 | return contents; 62 | } 63 | 64 | if (p.isMimeType("message/rfc822")) { 65 | log.info("Found nested content, extracting"); 66 | return extractContent((Part) p.getContent()); 67 | } 68 | 69 | String content = p.getContent().toString(); 70 | String[] encodings = p.getHeader("Content-Transfer-Encoding"); 71 | String encoding = (encodings != null && encodings.length > 0) ? encodings[0] : null; 72 | 73 | if (StringUtils.equalsIgnoreCase("quoted-printable", encoding)) { 74 | try { 75 | // TODO actually extract the charset properly 76 | // TODO read RFC to know default charset 77 | log.info("Transfer encoding is {}, decoding", encoding); 78 | content = new String(QuotedPrintableCodec.decodeQuotedPrintable(content.getBytes())); 79 | } catch (DecoderException e) { 80 | log.warn("Content transfer encoding is set to {} but enable to decode: {}", encoding, e.getMessage()); 81 | } 82 | } 83 | 84 | if (p.isMimeType(MimeTypeUtils.TEXT_PLAIN_VALUE)) { 85 | log.info("Found plain text content"); 86 | return Collections.singletonList(new BridgeMessageTextContent(content, encoding)); 87 | } 88 | 89 | if (p.isMimeType(MimeTypeUtils.TEXT_HTML_VALUE)) { 90 | log.info("Found HTML content"); 91 | return Collections.singletonList(new BridgeMessageHtmlContent(content, encoding)); 92 | } 93 | 94 | return Collections.emptyList(); 95 | } 96 | 97 | @Override 98 | public Optional<_EmailBridgeMessage> get(String key, Message msg) { 99 | try { 100 | String sender = ((InternetAddress) msg.getFrom()[0]).getAddress(); // TODO sanitize properly 101 | log.info("Email is from {}", sender); 102 | 103 | if (Objects.isNull(msg.getSentDate())) { 104 | // As per https://tools.ietf.org/html/rfc5322#page-19 105 | log.warn("Email is illegal, Date info missing. Skipping"); 106 | return Optional.empty(); 107 | } 108 | 109 | List<_BridgeMessageContent> contents = extractContent(msg); 110 | if (contents.isEmpty()) { 111 | log.warn("Found no valid content, skipping"); 112 | return Optional.empty(); 113 | } 114 | 115 | for (_EmailClientFormatter f : clientFormatters) { 116 | if (f.matches(msg, contents)) { 117 | log.info("Using inbound formatter {}", f.getId()); 118 | 119 | List<_BridgeMessageContent> contentFormatted = new ArrayList<>(); 120 | for (_BridgeMessageContent content : contents) { 121 | contentFormatted.add(f.format(content)); 122 | } 123 | contents = contentFormatted; 124 | break; 125 | } else { 126 | log.info("Inbound formatter {} did not match", f.getId()); 127 | } 128 | } 129 | 130 | return Optional.of(new EmailBridgeMessage(key, msg.getSentDate().toInstant(), sender, contents)); 131 | } catch (IOException | MessagingException e) { 132 | throw new RuntimeException(e); 133 | } 134 | } 135 | 136 | } 137 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/email/EmailManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.email; 22 | 23 | import io.kamax.matrix.bridge.email.config.email.EmailSenderConfig; 24 | import io.kamax.matrix.bridge.email.model._EndPoint; 25 | import org.slf4j.Logger; 26 | import org.slf4j.LoggerFactory; 27 | import org.springframework.beans.factory.InitializingBean; 28 | import org.springframework.beans.factory.annotation.Autowired; 29 | import org.springframework.stereotype.Component; 30 | 31 | import java.util.HashMap; 32 | import java.util.Map; 33 | import java.util.Optional; 34 | 35 | @Component 36 | public class EmailManager implements InitializingBean, _EmailManager { 37 | 38 | private Logger log = LoggerFactory.getLogger(EmailManager.class); 39 | 40 | @Autowired 41 | private EmailSenderConfig sendCfg; 42 | 43 | @Autowired 44 | private _EmailFormatterOutbound formatOut; 45 | 46 | @Autowired 47 | private _EmailFormatterInbound formatIn; 48 | 49 | @Autowired 50 | private _EmailFetcher fetcher; 51 | 52 | private Map endpoints = new HashMap<>(); 53 | 54 | @Override 55 | public void afterPropertiesSet() throws Exception { 56 | fetcher.addListener((key, email) -> { 57 | Optional<_EmailBridgeMessage> msgOpt = formatIn.get(key, email); 58 | if (!msgOpt.isPresent()) { 59 | log.info("Inbound formatter did not return anything, skipping"); 60 | return; 61 | } 62 | _EmailBridgeMessage msg = msgOpt.get(); 63 | 64 | EmailEndPoint ep = endpoints.get(key); 65 | if (ep == null) { 66 | // TODO implement 67 | log.warn("DROP: Received e-mail with invalid key {} from {}", msg.getKey(), msg.getSender()); 68 | return; 69 | } 70 | 71 | if (!ep.getIdentity().contentEquals(msg.getSender())) { 72 | log.warn("DROP: Received e-mail with invalid sender: from {} but supposed to be {}", msg.getSender(), ep.getIdentity()); 73 | } 74 | 75 | log.info("Injecting e-mail from {} with key {}", msg.getSender(), msg.getKey()); 76 | ep.inject(msg); 77 | }); 78 | 79 | fetcher.connect(); 80 | } 81 | 82 | private EmailEndPoint createEndpoint(String email, String threadId) { 83 | String id = getKey(email, threadId); 84 | EmailEndPoint ep = new EmailEndPoint(id, email, threadId, sendCfg, formatOut); 85 | ep.addStateListener(this::destroyEndpoint); 86 | endpoints.put(id, ep); 87 | 88 | log.info("Created new email endpoint {} for {}", id, email); 89 | 90 | return ep; 91 | } 92 | 93 | private void destroyEndpoint(_EndPoint endpoint) { 94 | endpoints.remove(endpoint.getId()); 95 | } 96 | 97 | @Override 98 | public String getKey(String email, String threadId) { 99 | return threadId; 100 | } 101 | 102 | @Override 103 | public EmailEndPoint getEndpoint(String email, String threadId) { 104 | EmailEndPoint ep = endpoints.get(getKey(email, threadId)); 105 | if (ep != null) { 106 | return ep; 107 | } 108 | 109 | return createEndpoint(email, threadId); 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/email/EmailTemplate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.email; 22 | 23 | import org.springframework.context.annotation.Lazy; 24 | import org.springframework.context.annotation.Scope; 25 | import org.springframework.stereotype.Component; 26 | 27 | import java.util.*; 28 | 29 | @Component 30 | @Scope("prototype") 31 | @Lazy 32 | public class EmailTemplate implements _EmailTemplate { 33 | 34 | private String subject; 35 | private Map contentTemplates; 36 | 37 | public EmailTemplate(String subject, List<_EmailTemplateContent> contentTemplates) { 38 | this.subject = subject; 39 | this.contentTemplates = new HashMap<>(); 40 | for (_EmailTemplateContent content : contentTemplates) { 41 | this.contentTemplates.put(content.getType(), content); 42 | } 43 | } 44 | 45 | @Override 46 | public String getSubject() { 47 | return subject; 48 | } 49 | 50 | @Override 51 | public List<_EmailTemplateContent> listContents() { 52 | return new ArrayList<>(contentTemplates.values()); 53 | } 54 | 55 | @Override 56 | public Optional<_EmailTemplateContent> getContent(String mime) { 57 | return Optional.ofNullable(contentTemplates.get(mime)); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/email/EmailTemplateContent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.email; 22 | 23 | import io.kamax.matrix.bridge.email.config.subscription.EmailTemplateContentConfig; 24 | import org.apache.commons.io.IOUtils; 25 | import org.springframework.beans.factory.InitializingBean; 26 | import org.springframework.beans.factory.annotation.Autowired; 27 | import org.springframework.context.ApplicationContext; 28 | import org.springframework.context.annotation.Lazy; 29 | import org.springframework.context.annotation.Scope; 30 | import org.springframework.core.io.Resource; 31 | import org.springframework.stereotype.Component; 32 | 33 | import java.io.IOException; 34 | import java.nio.charset.StandardCharsets; 35 | 36 | @Component 37 | @Scope("prototype") 38 | @Lazy 39 | public class EmailTemplateContent implements InitializingBean, _EmailTemplateContent { 40 | 41 | @Autowired 42 | private ApplicationContext app; 43 | 44 | private EmailTemplateContentConfig cfg; 45 | private Resource header; 46 | private Resource footer; 47 | private Resource content; 48 | 49 | public EmailTemplateContent(EmailTemplateContentConfig cfg) { 50 | this.cfg = cfg; 51 | } 52 | 53 | private Resource get(String path) { 54 | return app.getResource(path); 55 | } 56 | 57 | @Override 58 | public void afterPropertiesSet() throws Exception { 59 | header = get(cfg.getHeader()); 60 | footer = get(cfg.getFooter()); 61 | content = get(cfg.getContent()); 62 | } 63 | 64 | @Override 65 | public String getType() { 66 | return cfg.getType(); 67 | } 68 | 69 | @Override 70 | public String getHeader() throws IOException { 71 | return IOUtils.toString(header.getInputStream(), StandardCharsets.UTF_8); 72 | } 73 | 74 | @Override 75 | public String getFooter() throws IOException { 76 | return IOUtils.toString(footer.getInputStream(), StandardCharsets.UTF_8); 77 | } 78 | 79 | @Override 80 | public String getContent() throws IOException { 81 | return IOUtils.toString(content.getInputStream(), StandardCharsets.UTF_8); 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/email/EmailTemplateManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.email; 22 | 23 | import io.kamax.matrix.bridge.email.config.subscription.EmailNotificationConfig; 24 | import io.kamax.matrix.bridge.email.config.subscription.EmailTemplateConfig; 25 | import io.kamax.matrix.bridge.email.config.subscription.EmailTemplateContentConfig; 26 | import io.kamax.matrix.bridge.email.model.subscription.SubscriptionEvents; 27 | import org.springframework.beans.factory.InitializingBean; 28 | import org.springframework.beans.factory.annotation.Autowired; 29 | import org.springframework.context.ApplicationContext; 30 | import org.springframework.stereotype.Component; 31 | 32 | import java.util.*; 33 | 34 | @Component 35 | public class EmailTemplateManager implements InitializingBean, _EmailTemplateManager { 36 | 37 | @Autowired 38 | private ApplicationContext app; 39 | 40 | @Autowired 41 | private EmailNotificationConfig notifCfg; 42 | 43 | private Map templates; 44 | 45 | @Override 46 | public void afterPropertiesSet() throws Exception { 47 | templates = new HashMap<>(); 48 | 49 | for (SubscriptionEvents ev : SubscriptionEvents.values()) { 50 | EmailTemplateConfig cfg = notifCfg.get(ev); 51 | if (cfg.getContent().isEmpty()) { 52 | continue; 53 | } 54 | 55 | List<_EmailTemplateContent> t = new ArrayList<>(); 56 | for (EmailTemplateContentConfig templateCfg : cfg.getContent()) { 57 | t.add(app.getBean(_EmailTemplateContent.class, templateCfg)); 58 | } 59 | 60 | templates.put(ev, app.getBean(_EmailTemplate.class, cfg.getSubject(), t)); 61 | } 62 | } 63 | 64 | @Override 65 | public Optional<_EmailTemplate> get(SubscriptionEvents event) { 66 | return Optional.ofNullable(templates.get(event)); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/email/EmailTemplateToken.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.email; 22 | 23 | public enum EmailTemplateToken { 24 | 25 | MsgContent("%MSG_CONTENT%"), 26 | MsgTimeHour("%MSG_TIME_HOUR%"), 27 | MsgTimeMin("%MSG_TIME_MIN%"), 28 | MsgTimeSec("%MSG_TIME_SEC%"), 29 | Sender("%SENDER%"), 30 | SenderName("%SENDER_NAME%"), 31 | SenderAddress("%SENDER_ADDRESS%"), 32 | 33 | /** 34 | * The ID of the attachment that will contain the sender avatar picture 35 | */ 36 | SenderAvatar("%SENDER_AVATAR%"), 37 | ReceiverAddress("%RECEIVER_ADDRESS%"), 38 | Room("%ROOM%"), 39 | RoomName("%ROOM_NAME%"), 40 | RoomAddress("%ROOM_ADDRESS%"), 41 | 42 | ManageUrl("%MANAGE_URL%"); 43 | 44 | private String token; 45 | 46 | EmailTemplateToken(String token) { 47 | this.token = token; 48 | } 49 | 50 | public String getToken() { 51 | return token; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/email/GmailClientFormatter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.email; 22 | 23 | import io.kamax.matrix.bridge.email.model._BridgeMessageContent; 24 | import org.jsoup.Jsoup; 25 | import org.jsoup.nodes.Element; 26 | import org.jsoup.safety.Whitelist; 27 | import org.slf4j.Logger; 28 | import org.slf4j.LoggerFactory; 29 | import org.springframework.stereotype.Component; 30 | 31 | import javax.mail.Message; 32 | import javax.mail.MessagingException; 33 | import java.util.List; 34 | import java.util.regex.Matcher; 35 | import java.util.regex.Pattern; 36 | 37 | @Component 38 | public class GmailClientFormatter extends AEmailClientFormatter { 39 | 40 | private Logger log = LoggerFactory.getLogger(GmailClientFormatter.class); 41 | 42 | private Pattern pattern = Pattern.compile("
"); 43 | 44 | @Override 45 | public String getId() { 46 | return "gmail"; 47 | } 48 | 49 | @Override 50 | public boolean matches(Message m, List<_BridgeMessageContent> contents) throws MessagingException { 51 | for (_BridgeMessageContent content : contents) { 52 | Matcher matcher = pattern.matcher(content.getContentAsString()); 53 | if (matcher.find()) { 54 | return true; 55 | } 56 | } 57 | 58 | return false; 59 | } 60 | 61 | @Override 62 | protected String formatHtml(String content) { 63 | Element body = Jsoup.parse(content).body(); 64 | Element contentDiv = body.select("div[dir='ltr']").first(); 65 | if (contentDiv == null) { 66 | log.warn("Found no valid content in e-mail from Gmail, returning empty"); 67 | return ""; 68 | } 69 | 70 | while (contentDiv.children().size() > 0 && contentDiv.children().last().is("br")) { 71 | contentDiv.children().last().remove(); 72 | } 73 | 74 | return Jsoup.clean(contentDiv.html(), Whitelist.basic()); 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/email/ThunderbirdClientFormatter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.email; 22 | 23 | import io.kamax.matrix.bridge.email.model._BridgeMessageContent; 24 | import org.apache.commons.lang.StringUtils; 25 | import org.jsoup.Jsoup; 26 | import org.jsoup.nodes.Element; 27 | import org.jsoup.safety.Whitelist; 28 | import org.springframework.stereotype.Component; 29 | 30 | import javax.mail.Message; 31 | import javax.mail.MessagingException; 32 | import java.util.List; 33 | 34 | @Component 35 | public class ThunderbirdClientFormatter extends AEmailClientFormatter { 36 | 37 | @Override 38 | public String getId() { 39 | return "thunderbird"; 40 | } 41 | 42 | @Override 43 | public boolean matches(Message m, List<_BridgeMessageContent> contents) throws MessagingException { 44 | String[] headers = m.getHeader("User-Agent"); 45 | if (headers != null) { 46 | for (String header : headers) { 47 | if (StringUtils.containsIgnoreCase(header, getId())) { 48 | return true; 49 | } 50 | } 51 | } 52 | 53 | return false; 54 | } 55 | 56 | @Override 57 | protected String formatHtml(String content) { 58 | Element body = Jsoup.parse(content).body(); 59 | body.select("blockquote[cite]").remove(); 60 | body.select("div.moz-cite-prefix").remove(); 61 | 62 | while (body.children().size() > 0 && body.children().last().is("br")) { 63 | body.children().last().remove(); 64 | } 65 | 66 | return Jsoup.clean(body.html(), Whitelist.basic()); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/email/_EmailBridgeMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.email; 22 | 23 | import io.kamax.matrix.bridge.email.model._BridgeMessage; 24 | 25 | public interface _EmailBridgeMessage extends _BridgeMessage { 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/email/_EmailClientFormatter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.email; 22 | 23 | import io.kamax.matrix.bridge.email.model._BridgeMessageContent; 24 | 25 | import javax.mail.Message; 26 | import javax.mail.MessagingException; 27 | import java.util.List; 28 | 29 | public interface _EmailClientFormatter { 30 | 31 | String getId(); 32 | 33 | boolean matches(Message m, List<_BridgeMessageContent> contents) throws MessagingException; 34 | 35 | _BridgeMessageContent format(_BridgeMessageContent content); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/email/_EmailEndPoint.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.email; 22 | 23 | import io.kamax.matrix.bridge.email.model._EndPoint; 24 | import io.kamax.matrix.bridge.email.model.matrix._MatrixBridgeMessage; 25 | 26 | public interface _EmailEndPoint extends _EndPoint { 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/email/_EmailFetcher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.email; 22 | 23 | 24 | public interface _EmailFetcher { 25 | 26 | void connect(); 27 | 28 | void disconnect(); 29 | 30 | void addListener(_EmailMessageListener listener); 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/email/_EmailFormatterInbound.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.email; 22 | 23 | import javax.mail.Message; 24 | import java.util.Optional; 25 | 26 | public interface _EmailFormatterInbound { 27 | 28 | Optional<_EmailBridgeMessage> get(String key, Message msg); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/email/_EmailFormatterOutbound.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.email; 22 | 23 | import io.kamax.matrix.bridge.email.model.matrix._MatrixBridgeMessage; 24 | import io.kamax.matrix.bridge.email.model.subscription._BridgeSubscription; 25 | import io.kamax.matrix.bridge.email.model.subscription._SubscriptionEvent; 26 | 27 | import javax.mail.MessagingException; 28 | import javax.mail.internet.MimeMessage; 29 | import java.io.IOException; 30 | import java.util.Optional; 31 | 32 | public interface _EmailFormatterOutbound { 33 | 34 | Optional get(_BridgeSubscription sub, _MatrixBridgeMessage msg) throws IOException, MessagingException; 35 | 36 | Optional get(_SubscriptionEvent ev) throws IOException, MessagingException; 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/email/_EmailManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.email; 22 | 23 | public interface _EmailManager { 24 | 25 | String getKey(String email, String threadId); 26 | 27 | _EmailEndPoint getEndpoint(String email, String threadId); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/email/_EmailMessageListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.email; 22 | 23 | import javax.mail.Message; 24 | 25 | public interface _EmailMessageListener { 26 | 27 | void push(String key, Message msg); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/email/_EmailTemplate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.email; 22 | 23 | import java.util.List; 24 | import java.util.Optional; 25 | 26 | public interface _EmailTemplate { 27 | 28 | String getSubject(); 29 | 30 | List<_EmailTemplateContent> listContents(); 31 | 32 | Optional<_EmailTemplateContent> getContent(String mime); 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/email/_EmailTemplateContent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.email; 22 | 23 | import java.io.IOException; 24 | 25 | public interface _EmailTemplateContent { 26 | 27 | String getType(); 28 | 29 | String getHeader() throws IOException; 30 | 31 | String getFooter() throws IOException; 32 | 33 | String getContent() throws IOException; 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/email/_EmailTemplateManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.email; 22 | 23 | import io.kamax.matrix.bridge.email.model.subscription.SubscriptionEvents; 24 | 25 | import java.util.Optional; 26 | 27 | public interface _EmailTemplateManager { 28 | 29 | Optional<_EmailTemplate> get(SubscriptionEvents event); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/matrix/AHomeserverCall.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.matrix; 22 | 23 | public abstract class AHomeserverCall implements _HomeserverCall { 24 | 25 | private String credentials; 26 | 27 | public void setCredentials(String credentials) { 28 | this.credentials = credentials; 29 | } 30 | 31 | @Override 32 | public String getCredentials() { 33 | return credentials; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/matrix/MatrixBridgeMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.matrix; 22 | 23 | import io.kamax.matrix._MatrixUser; 24 | import io.kamax.matrix.bridge.email.model.ABridgeMessage; 25 | import io.kamax.matrix.bridge.email.model.BridgeMessageTextContent; 26 | 27 | import java.time.Instant; 28 | import java.util.Collections; 29 | 30 | public class MatrixBridgeMessage extends ABridgeMessage<_MatrixUser> implements _MatrixBridgeMessage { 31 | 32 | public MatrixBridgeMessage(String key, Instant time, _MatrixUser sender, String txtContent) { 33 | super(key, time, sender, Collections.singletonList(new BridgeMessageTextContent(txtContent))); 34 | } 35 | 36 | public MatrixBridgeMessage(String key, Instant time, _MatrixUser sender) { 37 | super(key, time, sender, Collections.emptyList()); 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/matrix/MatrixBridgeUser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.matrix; 22 | 23 | import io.kamax.matrix.client._MatrixClient; 24 | 25 | public class MatrixBridgeUser implements _MatrixBridgeUser { 26 | 27 | private _MatrixClient client; 28 | private String email; 29 | 30 | public MatrixBridgeUser(_MatrixClient client, String email) { 31 | this.client = client; 32 | this.email = email; 33 | } 34 | 35 | @Override 36 | public _MatrixClient getClient() { 37 | return client; 38 | } 39 | 40 | @Override 41 | public String getEmail() { 42 | return email; 43 | } 44 | 45 | @Override 46 | public boolean is(_MatrixClient client) { 47 | return this.client.equals(client); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/matrix/MatrixEndPoint.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.matrix; 22 | 23 | import io.kamax.matrix._MatrixID; 24 | import io.kamax.matrix.bridge.email.config.subscription.MatrixNotificationConfig; 25 | import io.kamax.matrix.bridge.email.model.AEndPoint; 26 | import io.kamax.matrix.bridge.email.model._BridgeMessageContent; 27 | import io.kamax.matrix.bridge.email.model.email._EmailBridgeMessage; 28 | import io.kamax.matrix.bridge.email.model.subscription.SubscriptionPortalService; 29 | import io.kamax.matrix.bridge.email.model.subscription._BridgeSubscription; 30 | import io.kamax.matrix.bridge.email.model.subscription._SubscriptionEvent; 31 | import io.kamax.matrix.client._MatrixClient; 32 | import io.kamax.matrix.hs._MatrixRoom; 33 | import org.jsoup.Jsoup; 34 | import org.slf4j.Logger; 35 | import org.slf4j.LoggerFactory; 36 | import org.springframework.util.MimeTypeUtils; 37 | 38 | import java.util.Optional; 39 | 40 | public class MatrixEndPoint extends AEndPoint<_MatrixID, _EmailBridgeMessage, _MatrixBridgeMessage> implements _MatrixEndPoint { 41 | 42 | private Logger log = LoggerFactory.getLogger(MatrixEndPoint.class); 43 | 44 | private _MatrixClient client; 45 | private MatrixNotificationConfig notifCfg; 46 | private SubscriptionPortalService portalSvc; // TODO this is very hacky, do it another way 47 | 48 | public MatrixEndPoint(String id, _MatrixClient client, String roomId, MatrixNotificationConfig notifCfg, SubscriptionPortalService portalSvc) { 49 | super(id, client.getUser(), roomId); 50 | this.client = client; 51 | this.notifCfg = notifCfg; 52 | this.portalSvc = portalSvc; 53 | } 54 | 55 | @Override 56 | protected void sendEventImpl(_SubscriptionEvent ev) { 57 | if (!notifCfg.get(ev.getType())) { 58 | log.info("Subscription event {} has Matrix notification disabled, ignoring", ev.getType()); 59 | return; 60 | } 61 | 62 | _MatrixRoom room = client.getRoom(getChannelId()); 63 | switch (ev.getType()) { 64 | case OnDestroy: 65 | room.sendNotice("This user unsubscribed from this room."); 66 | room.leave(); 67 | break; 68 | default: 69 | log.warn("Unknown subscription event type {}", ev.getType().getId()); 70 | } 71 | } 72 | 73 | @Override 74 | protected void closeImpl() { 75 | client.getRoom(getChannelId()).leave(); 76 | } 77 | 78 | protected void sendMessageImpl(_BridgeSubscription sub, _EmailBridgeMessage msg) { 79 | Optional<_BridgeMessageContent> html = msg.getContent(MimeTypeUtils.TEXT_HTML_VALUE); 80 | Optional<_BridgeMessageContent> txt = msg.getContent(MimeTypeUtils.TEXT_PLAIN_VALUE); 81 | if (!html.isPresent() && !txt.isPresent()) { 82 | log.warn("Ignoring E-mail message {} to {}, no valid content", msg.getKey(), msg.getSender()); 83 | } 84 | 85 | if (html.isPresent() && txt.isPresent()) { 86 | log.info("Forwarding e-mail {} to Matrix from {} with formatted content", msg.getKey(), msg.getSender()); 87 | String contentHtml = portalSvc.redactToken(html.get().getContentAsString()); 88 | String contentText = portalSvc.redactToken(txt.get().getContentAsString()); 89 | client.getRoom(getChannelId()).sendFormattedText(contentHtml, contentText); 90 | } else { 91 | txt.ifPresent(content -> { 92 | log.info("Forwarding e-mail {} to Matrix from {} with only plain text content", msg.getKey(), msg.getSender()); 93 | String contentText = portalSvc.redactToken(content.getContentAsString()); 94 | client.getRoom(getChannelId()).sendText(contentText); 95 | }); 96 | 97 | html.ifPresent(content -> { 98 | log.info("Forwarding e-mail {} to Matrix from {} with only HTML content", msg.getKey(), msg.getSender()); 99 | String contentHtml = portalSvc.redactToken(content.getContentAsString()); 100 | try { 101 | client.getRoom(getChannelId()).sendText(Jsoup.parse(contentHtml).text()); 102 | } catch (RuntimeException e) { 103 | log.warn("Unable to clean up HTML content, skipping", e); 104 | } 105 | }); 106 | } 107 | } 108 | 109 | void inject(_MatrixBridgeMessage msg) { 110 | log.info("Matrix message was injected into end point {} - {} - {}", getId(), getIdentity(), getChannelId()); 111 | 112 | fireMessageEvent(msg); 113 | } 114 | 115 | @Override 116 | public _MatrixClient getClient() { 117 | return client; 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/matrix/MatrixManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.matrix; 22 | 23 | import io.kamax.matrix.MatrixID; 24 | import io.kamax.matrix._MatrixID; 25 | import io.kamax.matrix.bridge.email.config.matrix.EntityTemplateConfig; 26 | import io.kamax.matrix.bridge.email.config.matrix.HomeserverConfig; 27 | import io.kamax.matrix.bridge.email.config.subscription.MatrixNotificationConfig; 28 | import io.kamax.matrix.bridge.email.model.BridgeEmailCodec; 29 | import io.kamax.matrix.bridge.email.model._EndPoint; 30 | import io.kamax.matrix.bridge.email.model.subscription.SubscriptionPortalService; 31 | import io.kamax.matrix.client._MatrixClient; 32 | import io.kamax.matrix.client.as.MatrixApplicationServiceClient; 33 | import io.kamax.matrix.client.as._MatrixApplicationServiceClient; 34 | import io.kamax.matrix.hs.MatrixHomeserver; 35 | import io.kamax.matrix.hs._MatrixHomeserver; 36 | import org.slf4j.Logger; 37 | import org.slf4j.LoggerFactory; 38 | import org.springframework.beans.factory.InitializingBean; 39 | import org.springframework.beans.factory.annotation.Autowired; 40 | import org.springframework.stereotype.Component; 41 | 42 | import java.util.*; 43 | import java.util.regex.Matcher; 44 | import java.util.regex.Pattern; 45 | 46 | @Component 47 | public class MatrixManager implements _MatrixManager, InitializingBean { 48 | 49 | private Logger log = LoggerFactory.getLogger(MatrixManager.class); 50 | 51 | @Autowired 52 | private HomeserverConfig hsCfg; 53 | 54 | @Autowired 55 | private MatrixNotificationConfig notifCfg; 56 | 57 | @Autowired 58 | private BridgeEmailCodec emailCodec; 59 | 60 | @Autowired 61 | private SubscriptionPortalService portalSvc; 62 | 63 | private _MatrixApplicationServiceClient mgr; 64 | 65 | private List patterns; 66 | private Map vMxUsers = new HashMap<>(); 67 | private Map endpoints = new HashMap<>(); 68 | 69 | @Override 70 | public void afterPropertiesSet() throws Exception { 71 | patterns = new ArrayList<>(); 72 | for (EntityTemplateConfig entityTemplate : hsCfg.getUsers()) { 73 | patterns.add(Pattern.compile(entityTemplate.getTemplate().replace("%EMAIL%", "(?.*)"))); 74 | } 75 | if (patterns.size() < 1) { 76 | log.error("At least one user template must be configured"); 77 | System.exit(1); 78 | } 79 | 80 | _MatrixHomeserver hs = new MatrixHomeserver(hsCfg.getDomain(), hsCfg.getHost()); 81 | mgr = new MatrixApplicationServiceClient(hs, hsCfg.getAsToken(), hsCfg.getLocalpart()); 82 | } 83 | 84 | private Optional findMatcherForUser(_MatrixID mxId) { 85 | for (Pattern p : patterns) { 86 | Matcher m = p.matcher(mxId.getLocalPart()); 87 | if (m.matches()) { 88 | return Optional.of(m); 89 | } 90 | } 91 | 92 | return Optional.empty(); 93 | } 94 | 95 | public Optional<_MatrixBridgeUser> findClientForUser(_MatrixID mxId) { 96 | return Optional.ofNullable(vMxUsers.computeIfAbsent(mxId.getId(), id -> { 97 | Optional mOpt = findMatcherForUser(mxId); 98 | if (!mOpt.isPresent()) { 99 | return null; 100 | } 101 | 102 | String email = emailCodec.decode(mOpt.get().group("email")); 103 | 104 | log.info("Creating new Matrix client for {} as {}", email, mxId); 105 | return new MatrixBridgeUser(mgr.getUser(mxId.getLocalPart()), email); 106 | })); 107 | } 108 | 109 | public boolean isOurUser(_MatrixID mxId) { 110 | return vMxUsers.containsKey(mxId.getId()) || findMatcherForUser(mxId).isPresent(); 111 | } 112 | 113 | @Override 114 | public String getKey(String mxId, String roomId) { 115 | return mxId + "|" + roomId; 116 | } 117 | 118 | private MatrixEndPoint createEndpoint(_MatrixClient client, String roomId) { 119 | String id = getKey(client.getUser().getId(), roomId); 120 | MatrixEndPoint ep = new MatrixEndPoint(id, client, roomId, notifCfg, portalSvc); 121 | ep.addStateListener(this::destroyEndpoint); 122 | endpoints.put(id, ep); 123 | return ep; 124 | } 125 | 126 | private void destroyEndpoint(_EndPoint ep) { 127 | endpoints.remove(ep.getId()); 128 | } 129 | 130 | @Override 131 | public synchronized MatrixEndPoint getEndpoint(String mxId, String roomId) { 132 | MatrixEndPoint ep = endpoints.get(getKey(mxId, roomId)); 133 | if (ep != null) { 134 | return ep; 135 | } 136 | 137 | Optional<_MatrixBridgeUser> client = findClientForUser(new MatrixID(mxId)); 138 | if (!client.isPresent()) { 139 | throw new IllegalArgumentException(mxId + " is not a Matrix bridge user"); 140 | } 141 | 142 | return createEndpoint(client.get().getClient(), roomId); 143 | } 144 | 145 | public _MatrixApplicationServiceClient getClient() { 146 | return mgr; 147 | } 148 | 149 | } 150 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/matrix/MatrixTransactionPush.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.matrix; 22 | 23 | import io.kamax.matrix.event._MatrixEvent; 24 | 25 | import java.util.List; 26 | 27 | public class MatrixTransactionPush extends AHomeserverCall { 28 | 29 | private String id; 30 | private List<_MatrixEvent> events; 31 | 32 | public String getId() { 33 | return id; 34 | } 35 | 36 | public void setId(String id) { 37 | this.id = id; 38 | } 39 | 40 | public List<_MatrixEvent> getEvents() { 41 | return events; 42 | } 43 | 44 | public void setEvents(List<_MatrixEvent> events) { 45 | this.events = events; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/matrix/RoomQuery.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.matrix; 22 | 23 | public class RoomQuery extends AHomeserverCall { 24 | 25 | private String alias; 26 | 27 | public RoomQuery(String alias, String credentials) { 28 | this.alias = alias; 29 | setCredentials(credentials); 30 | } 31 | 32 | public String getAlias() { 33 | return alias; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/matrix/UserQuery.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.matrix; 22 | 23 | import io.kamax.matrix._MatrixID; 24 | 25 | public class UserQuery extends AHomeserverCall { 26 | 27 | private _MatrixID mxId; 28 | 29 | public UserQuery(_MatrixID mxId, String credentials) { 30 | this.mxId = mxId; 31 | setCredentials(credentials); 32 | } 33 | 34 | public _MatrixID getId() { 35 | return mxId; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/matrix/_HomeserverCall.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.matrix; 22 | 23 | public interface _HomeserverCall { 24 | 25 | String getCredentials(); 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/matrix/_MatrixApplicationService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.matrix; 22 | 23 | import io.kamax.matrix.ThreePid; 24 | import io.kamax.matrix.ThreePidMapping; 25 | import io.kamax.matrix._MatrixID; 26 | import io.kamax.matrix.bridge.email.exception.InvalidMatrixIdException; 27 | import io.kamax.matrix.bridge.email.exception.RoomNotFoundException; 28 | import io.kamax.matrix.bridge.email.exception.UserNotFoundException; 29 | 30 | import java.util.Optional; 31 | 32 | public interface _MatrixApplicationService { 33 | 34 | _MatrixID getId(String mxId) throws InvalidMatrixIdException; 35 | 36 | Optional getMatrixId(ThreePid threePid); 37 | 38 | void queryUser(UserQuery query) throws UserNotFoundException; 39 | 40 | void queryRoom(RoomQuery query) throws RoomNotFoundException; 41 | 42 | void push(MatrixTransactionPush transaction); 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/matrix/_MatrixBridgeMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.matrix; 22 | 23 | import io.kamax.matrix._MatrixUser; 24 | import io.kamax.matrix.bridge.email.model._BridgeMessage; 25 | 26 | public interface _MatrixBridgeMessage extends _BridgeMessage<_MatrixUser> { 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/matrix/_MatrixBridgeUser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.matrix; 22 | 23 | import io.kamax.matrix.client._MatrixClient; 24 | 25 | public interface _MatrixBridgeUser { 26 | 27 | _MatrixClient getClient(); 28 | 29 | String getEmail(); 30 | 31 | boolean is(_MatrixClient client); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/matrix/_MatrixEndPoint.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.matrix; 22 | 23 | import io.kamax.matrix._MatrixID; 24 | import io.kamax.matrix.bridge.email.model._EndPoint; 25 | import io.kamax.matrix.bridge.email.model.email._EmailBridgeMessage; 26 | import io.kamax.matrix.client._MatrixClient; 27 | 28 | public interface _MatrixEndPoint extends _EndPoint<_MatrixID, _EmailBridgeMessage, _MatrixBridgeMessage> { 29 | 30 | _MatrixClient getClient(); 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/matrix/_MatrixManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.matrix; 22 | 23 | public interface _MatrixManager { 24 | 25 | String getKey(String mxId, String roomId); 26 | 27 | _MatrixEndPoint getEndpoint(String mxId, String roomId); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/subscription/BridgeSubscription.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.subscription; 22 | 23 | import io.kamax.matrix.bridge.email.model._MessageFormatter; 24 | import io.kamax.matrix.bridge.email.model.email._EmailEndPoint; 25 | import io.kamax.matrix.bridge.email.model.matrix._MatrixEndPoint; 26 | import org.slf4j.Logger; 27 | import org.slf4j.LoggerFactory; 28 | 29 | import java.time.Instant; 30 | import java.util.ArrayList; 31 | import java.util.List; 32 | 33 | public class BridgeSubscription implements _BridgeSubscription { 34 | 35 | private Logger log = LoggerFactory.getLogger(BridgeSubscription.class); 36 | 37 | private String sourceMxId; 38 | private Instant timestamp; 39 | private String id; 40 | private String emKey; 41 | private String mxKey; 42 | private _MatrixEndPoint mxEp; 43 | private _EmailEndPoint emEp; 44 | 45 | private boolean isClosed; 46 | private List<_BridgeSubscriptionListener> listeners = new ArrayList<>(); 47 | 48 | public BridgeSubscription(String id, String sourceMxId, Instant timestamp, _MessageFormatter formatter, String emKey, _EmailEndPoint emEp, String mxKey, _MatrixEndPoint mxEp) { 49 | this.id = id; 50 | this.sourceMxId = sourceMxId; 51 | this.timestamp = timestamp; 52 | this.emKey = emKey; 53 | this.mxKey = mxKey; 54 | this.mxEp = mxEp; 55 | this.emEp = emEp; 56 | 57 | mxEp.addMessageListener(msg -> emEp.sendMessage(this, formatter.format(msg))); 58 | emEp.addMessageListener(msg -> mxEp.sendMessage(this, formatter.format(msg))); 59 | } 60 | 61 | @Override 62 | public String getId() { 63 | return id; 64 | } 65 | 66 | @Override 67 | public String getInitiator() { 68 | return sourceMxId; 69 | } 70 | 71 | @Override 72 | public Instant getCreation() { 73 | return timestamp; 74 | } 75 | 76 | @Override 77 | public String getEmailKey() { 78 | return emKey; 79 | } 80 | 81 | @Override 82 | public String getMatrixKey() { 83 | return mxKey; 84 | } 85 | 86 | @Override 87 | public _MatrixEndPoint getMatrixEndpoint() { 88 | return mxEp; 89 | } 90 | 91 | @Override 92 | public _EmailEndPoint getEmailEndpoint() { 93 | return emEp; 94 | } 95 | 96 | @Override 97 | public void commence() { 98 | if (isClosed) { 99 | throw new IllegalStateException(); 100 | } 101 | 102 | log.info("Commencing subscription {} | Matrix - ID: {} - Identity: {} | Email - ID: {} - Identity: {}", 103 | id, 104 | mxKey, 105 | mxEp.getIdentity(), 106 | emKey, 107 | emEp.getIdentity()); 108 | 109 | SubscriptionEvent ev = new SubscriptionEvent(SubscriptionEvents.OnCreate, this, timestamp, sourceMxId); 110 | emEp.sendEvent(ev); 111 | mxEp.sendEvent(ev); 112 | } 113 | 114 | @Override 115 | public void terminate() { 116 | terminate(getMatrixEndpoint().getClient().getUser().getId(), ""); 117 | } 118 | 119 | @Override 120 | public void terminate(String byUserId, String reason) { 121 | synchronized (this) { 122 | if (isClosed) { 123 | return; 124 | } 125 | 126 | isClosed = true; 127 | } 128 | 129 | log.info("Terminating subscription {} | Matrix - ID: {} - Identity: {} | Email - ID: {} - Identity: {}", 130 | id, 131 | mxKey, 132 | mxEp.getIdentity(), 133 | emKey, 134 | emEp.getIdentity()); 135 | 136 | SubscriptionEvent ev = new SubscriptionEvent(SubscriptionEvents.OnDestroy, this, Instant.now(), byUserId); 137 | 138 | if (!mxEp.isClosed()) { 139 | log.info("Closing Matrix endpoint"); 140 | mxEp.sendEvent(ev); 141 | mxEp.close(); 142 | } 143 | 144 | log.info("Closing Email endpoint"); 145 | emEp.sendEvent(ev); 146 | emEp.close(); 147 | 148 | for (_BridgeSubscriptionListener listener : listeners) { 149 | listener.onTerminate(this); 150 | } 151 | } 152 | 153 | @Override 154 | public void addListener(_BridgeSubscriptionListener listener) { 155 | listeners.add(listener); 156 | } 157 | 158 | } 159 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/subscription/SubscriptionEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.subscription; 22 | 23 | import java.time.Instant; 24 | 25 | public class SubscriptionEvent implements _SubscriptionEvent { 26 | 27 | private SubscriptionEvents type; 28 | private _BridgeSubscription sub; 29 | private Instant time; 30 | private String initiator; 31 | 32 | public SubscriptionEvent(SubscriptionEvents type, _BridgeSubscription sub, Instant time, String initiator) { 33 | this.type = type; 34 | this.sub = sub; 35 | this.time = time; 36 | this.initiator = initiator; 37 | } 38 | 39 | @Override 40 | public SubscriptionEvents getType() { 41 | return type; 42 | } 43 | 44 | @Override 45 | public Instant getTime() { 46 | return time; 47 | } 48 | 49 | @Override 50 | public String getInitiator() { 51 | return initiator; 52 | } 53 | 54 | @Override 55 | public _BridgeSubscription getSubscription() { 56 | return sub; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/subscription/SubscriptionEvents.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.subscription; 22 | 23 | public enum SubscriptionEvents { 24 | 25 | OnCreate("onCreate"), 26 | OnMessage("onMessage"), 27 | OnDestroy("onDestroy"); 28 | 29 | private String id; 30 | 31 | SubscriptionEvents(String id) { 32 | this.id = id; 33 | } 34 | 35 | public String getId() { 36 | return id; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/subscription/SubscriptionPortalService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.subscription; 22 | 23 | import io.kamax.matrix.bridge.email.config.subscription.SubscriptionPortalConfig; 24 | import org.springframework.beans.factory.annotation.Autowired; 25 | import org.springframework.stereotype.Service; 26 | 27 | import java.util.regex.Pattern; 28 | 29 | @Service 30 | public class SubscriptionPortalService { 31 | 32 | public static final String BASE_PATH = "/subscription"; 33 | public static final String TOKEN_PARAMETER = "token"; 34 | private Pattern subPattern = Pattern.compile(BASE_PATH + "\\?" + TOKEN_PARAMETER + "=(?[^&]*)"); 35 | 36 | @Autowired 37 | private SubscriptionPortalConfig portalCfg; 38 | 39 | public String redactToken(String data) { 40 | return subPattern.matcher(data).replaceAll(""); 41 | } 42 | 43 | public String getPublicLink(String token) { 44 | return portalCfg.getUrl().toExternalForm() + BASE_PATH + "?token=" + token; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/subscription/_BridgeSubscription.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.subscription; 22 | 23 | import io.kamax.matrix.bridge.email.model.email._EmailEndPoint; 24 | import io.kamax.matrix.bridge.email.model.matrix._MatrixEndPoint; 25 | 26 | import java.time.Instant; 27 | 28 | public interface _BridgeSubscription { 29 | 30 | String getId(); 31 | 32 | /** 33 | * User who initiated the subscription 34 | * 35 | * @return Matrix ID of the initiator 36 | */ 37 | String getInitiator(); 38 | 39 | Instant getCreation(); 40 | 41 | String getEmailKey(); 42 | 43 | String getMatrixKey(); 44 | 45 | _MatrixEndPoint getMatrixEndpoint(); 46 | 47 | _EmailEndPoint getEmailEndpoint(); 48 | 49 | void commence(); 50 | 51 | void terminate(); 52 | 53 | void terminate(String source, String reason); 54 | 55 | void addListener(_BridgeSubscriptionListener listener); 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/subscription/_BridgeSubscriptionListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.subscription; 22 | 23 | public interface _BridgeSubscriptionListener { 24 | 25 | void onTerminate(_BridgeSubscription sub); 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/subscription/_SubscriptionEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.subscription; 22 | 23 | import java.time.Instant; 24 | 25 | public interface _SubscriptionEvent { 26 | 27 | SubscriptionEvents getType(); 28 | 29 | Instant getTime(); 30 | 31 | /** 32 | * User who triggered the event 33 | * 34 | * @return Matrix ID of the user 35 | */ 36 | String getInitiator(); 37 | 38 | _BridgeSubscription getSubscription(); 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/io/kamax/matrix/bridge/email/model/subscription/_SubscriptionManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.subscription; 22 | 23 | import io.kamax.matrix._MatrixID; 24 | import io.kamax.matrix.bridge.email.model.matrix._MatrixBridgeUser; 25 | import io.kamax.matrix.client._MatrixClient; 26 | 27 | import java.time.Instant; 28 | import java.util.List; 29 | import java.util.Optional; 30 | 31 | public interface _SubscriptionManager { 32 | 33 | _BridgeSubscription create(_MatrixID initiator, Instant time, _MatrixBridgeUser mxUser, String roomId); 34 | 35 | Optional<_BridgeSubscription> find(String email, _MatrixClient mxUser, String roomId); 36 | 37 | Optional<_BridgeSubscription> getWithEmailKey(String emailKey); 38 | 39 | Optional<_BridgeSubscription> getWithMatrixKey(String matrixKey); 40 | 41 | List<_BridgeSubscription> listForEmail(String email); 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/resources/templates/email/footer.html: -------------------------------------------------------------------------------- 1 |
2 |

3 | Manage your subscriptions 4 |

5 | 6 | 7 | -------------------------------------------------------------------------------- /src/main/resources/templates/email/footer.txt: -------------------------------------------------------------------------------- 1 | 2 | ---------- 3 | To manage your subscription(s), visit %MANAGE_URL% 4 | -------------------------------------------------------------------------------- /src/main/resources/templates/email/header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Matrix Bridge Service

4 | -------------------------------------------------------------------------------- /src/main/resources/templates/email/header.txt: -------------------------------------------------------------------------------- 1 | Matrix Bridge Service 2 | --------------------- 3 | 4 | -------------------------------------------------------------------------------- /src/main/resources/templates/email/onSubCreate-content.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 9 | 10 |
4 | sender avatar 5 | 7 | %SENDER% has invited you to a new conversation on Matrix, in room "%ROOM%". 8 |
11 |

You receive this notification because no Matrix ID was found for your address %RECEIVER_ADDRESS%

12 |

Simply reply to this e-mail to send a message within the conversation!

13 | -------------------------------------------------------------------------------- /src/main/resources/templates/email/onSubCreate-content.txt: -------------------------------------------------------------------------------- 1 | %SENDER% has invited you to a new conversation on Matrix, in room "%ROOM%". 2 | You receive this notification because no Matrix ID was found for your address %RECEIVER_ADDRESS% 3 | Simply reply to this e-mail to send a message within the conversation! 4 | -------------------------------------------------------------------------------- /src/main/resources/templates/email/onSubDestroy-content.html: -------------------------------------------------------------------------------- 1 |

Your subscription to the Matrix room "%ROOM%" has been terminated.

2 |

You will no longer receive message from us concerning this conversation. You may still receive notifications for 3 | other room subscriptions.

4 | -------------------------------------------------------------------------------- /src/main/resources/templates/email/onSubDestroy-content.txt: -------------------------------------------------------------------------------- 1 | Your subscription to the Matrix room "%ROOM%" has been terminated. 2 | You will no longer receive message from us concerning this conversation. You may still receive notifications for other room subscriptions. 3 | -------------------------------------------------------------------------------- /src/main/resources/templates/email/onSubMessage-content.html: -------------------------------------------------------------------------------- 1 |

You received a new message from %SENDER% in the conversation "%ROOM%":
2 | 3 | 4 | 7 | 10 | 13 | 14 |
5 | sender avatar 6 | 8 | %MSG_TIME_HOUR%:%MSG_TIME_MIN% 9 | 11 | %MSG_CONTENT% 12 |
15 |

16 | -------------------------------------------------------------------------------- /src/main/resources/templates/email/onSubMessage-content.txt: -------------------------------------------------------------------------------- 1 | You received a new message from %SENDER% in the conversation "%ROOM%": 2 | 3 | %MSG_TIME_HOUR%:%MSG_TIME_MIN% - %MSG_CONTENT% 4 | -------------------------------------------------------------------------------- /src/main/resources/templates/subscription/deleteSuccess.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Matrix Bridge Service - Subscription cancellation 6 | 7 | 8 | The subscription has been successfully cancelled. You will no longer receive message from this service for the 9 | associated conversation. 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/main/resources/templates/subscription/invalidToken.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Matrix Bridge Service - Error 6 | 7 | 8 | Invalid token! 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main/resources/templates/subscription/list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Matrix Bridge Service - List of Subscriptions 6 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
Created onByNameAction
Timestamp of the subscription creationCreator of the subscriptionName of the SubscriptionUnsubscribe
28 |
29 | 30 | 31 | -------------------------------------------------------------------------------- /src/test/java/io/kamax/matrix/bridge/email/model/BridgeEmailCodecTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model; 22 | 23 | import org.junit.BeforeClass; 24 | import org.junit.Test; 25 | 26 | import java.util.Arrays; 27 | import java.util.List; 28 | 29 | import static org.junit.Assert.assertTrue; 30 | 31 | public class BridgeEmailCodecTest { 32 | 33 | private List pairs = Arrays.asList( 34 | new String[]{"á", "=c3=a1"}, 35 | new String[]{".abá12_", ".ab=c3=a112_"}, 36 | new String[]{"john.doe@example.org", "john.doe=40example.org"}, 37 | new String[]{"john.doe@sub.example.org", "john.doe=40sub.example.org"}, 38 | new String[]{"わたし@example.org", "=e3=82=8f=e3=81=9f=e3=81=97=40example.org"} 39 | ); 40 | 41 | private static BridgeEmailCodec codec; 42 | 43 | @BeforeClass 44 | public static void beforeClass() { 45 | codec = new BridgeEmailCodec(); 46 | } 47 | 48 | @Test 49 | public void doEncoding() { 50 | for (String[] pair : pairs) { 51 | String e = codec.encode(pair[0]); 52 | assertTrue(pair[0] + " -> " + e, pair[1].contentEquals(e)); 53 | } 54 | } 55 | 56 | @Test 57 | public void doDecoding() { 58 | for (String[] pair : pairs) { 59 | String d = codec.decode(pair[1]); 60 | assertTrue(pair[1] + " -> " + d, pair[0].contentEquals(d)); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/test/java/io/kamax/matrix/bridge/email/model/email/GmailClientFormatterTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.email; 22 | 23 | import org.apache.commons.io.IOUtils; 24 | import org.junit.Test; 25 | 26 | import java.io.File; 27 | import java.io.FileReader; 28 | import java.io.IOException; 29 | 30 | import static org.junit.Assert.assertTrue; 31 | 32 | public class GmailClientFormatterTest { 33 | 34 | private GmailClientFormatter formatter = new GmailClientFormatter(); 35 | 36 | @Test 37 | public void testPlain() throws IOException { 38 | File f = new File("src/test/resources/gmailContent.txt"); 39 | assertTrue(f.getAbsolutePath(), f.canRead()); 40 | 41 | String output = formatter.formatPlain(IOUtils.toString(new FileReader(f))); 42 | assertTrue(output, "a".contentEquals(output)); 43 | } 44 | 45 | @Test 46 | public void testHtml() throws IOException { 47 | File f = new File("src/test/resources/gmailContent.html"); 48 | assertTrue(f.getAbsolutePath(), f.canRead()); 49 | 50 | String output = formatter.formatHtml(IOUtils.toString(new FileReader(f))); 51 | assertTrue(output, "a".contentEquals(output)); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/test/java/io/kamax/matrix/bridge/email/model/email/ThunderbirdClientFormatterTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * matrix-appservice-email - Matrix Bridge to E-mail 3 | * Copyright (C) 2017 Kamax Sarl 4 | * 5 | * https://www.kamax.io/ 6 | * 7 | * This program is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Affero General Public License as 9 | * published by the Free Software Foundation, either version 3 of the 10 | * License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | package io.kamax.matrix.bridge.email.model.email; 22 | 23 | import org.apache.commons.io.IOUtils; 24 | import org.junit.Test; 25 | 26 | import java.io.File; 27 | import java.io.FileReader; 28 | import java.io.IOException; 29 | 30 | import static org.junit.Assert.assertTrue; 31 | 32 | public class ThunderbirdClientFormatterTest { 33 | 34 | private ThunderbirdClientFormatter formatter = new ThunderbirdClientFormatter(); 35 | 36 | @Test 37 | public void testPlain() throws IOException { 38 | File f = new File("src/test/resources/thunderbirdContent.txt"); 39 | assertTrue(f.getAbsolutePath(), f.canRead()); 40 | 41 | String output = formatter.formatPlain(IOUtils.toString(new FileReader(f))); 42 | assertTrue(output, "orly".contentEquals(output)); 43 | } 44 | 45 | @Test 46 | public void testHtml() throws IOException { 47 | File f = new File("src/test/resources/thunderbirdContent.html"); 48 | assertTrue(f.getAbsolutePath(), f.canRead()); 49 | 50 | String output = formatter.formatHtml(IOUtils.toString(new FileReader(f))); 51 | assertTrue(output, "orly".contentEquals(output)); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/test/resources/gmailContent.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | a 4 |
5 |
6 |
7 |
8 |
9 | 2017-06-17 1:55 GMT+02:00 John Doe 10 | < john.doe@gmail.com>: 11 |
12 |
13 | 14 |
15 | b 16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | 2017-06-17 1:49 GMT+02:00 John Doe 24 | <john.doe@gmail.com>: 26 |
27 |
29 |
30 | a 31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | 2017-06-17 1:49 GMT+02:00 Test User 39 | <matrix-appservice-email@localhost.io>: 41 |
42 |
44 |
45 |

Matrix Bridge Service

46 |

You received a new message from Test User in the conversation 47 | "!ktamnzNYaQveteTXqS:localhost 48 | 49 | ":

50 | 51 | 52 | 53 | 57 | 58 | 59 | 60 | 61 |
sender avatar 56 | 01:491
62 |

63 |
64 |

65 | Manage your subscriptions

67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 | 85 | -------------------------------------------------------------------------------- /src/test/resources/gmailContent.txt: -------------------------------------------------------------------------------- 1 | a 2 | 3 | 2017-06-17 1:55 GMT+02:00 John Doe : 4 | 5 | > b 6 | > 7 | > 2017-06-17 1:49 GMT+02:00 John Doe : 8 | > 9 | >> a 10 | >> 11 | >> 2017-06-17 1:49 GMT+02:00 Test User : 12 | >> 13 | >>> Matrix Bridge Service 14 | >>> 15 | >>> You received a new message from Test User in the conversation 16 | >>> "!ktamnzNYaQveteTXqS:localhost": 17 | >>> [image: sender avatar] 01:49 1 18 | >>> 19 | >>> ------------------------------ 20 | >>> 21 | >>> Manage your subscriptions 22 | >>> 23 | >>> 24 | >> 25 | >> 26 | > -------------------------------------------------------------------------------- /src/test/resources/thunderbirdContent.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | orly
7 |
8 |
On 06/05/17 20:33, Matrix E-mail Bridge 9 | wrote:
10 |
11 |
13 |

Matrix Bridge Service

14 |
You have been invited to a Matrix conversation
15 |
16 |
17 | 18 | -------------------------------------------------------------------------------- /src/test/resources/thunderbirdContent.txt: -------------------------------------------------------------------------------- 1 | orly 2 | 3 | On 06/05/17 20:33, Matrix E-mail Bridge wrote: 4 | > 5 | > 6 | > Matrix Bridge Service 7 | > 8 | > You have been invited to a Matrix conversation --------------------------------------------------------------------------------