├── .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("