aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.junit.ssh/src
Commit message (Collapse)AuthorAgeFilesLines
* Add missing since tag for SshTestHarness#publicKey2stable-5.10Matthias Sohn2023-04-201-0/+3
| | | | Change-Id: Ib6e4945340d2e1761dc0e787bdbe72286cdc95bc
* sshd: support the ProxyJump ssh configThomas Wolf2020-09-191-1/+3
| | | | | | | | | | | | | | This is useful to access git repositories behind a bastion server (jump host). Add a constant for the config; rewrite the whole connection initiation to parse the value and (recursively) set up the chain of hops. Add tests for a single hop and two different ways to configure a two-hop chain. The connection timeout applies to each hop in the chain individually. Change-Id: Idd25af95aa2ec5367404587e4e530b0663c03665 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
* Fix JSchProcess.waitFor() with time-outThomas Wolf2020-08-102-4/+108
| | | | | | | | | | | | | | | | SshSupport.runSshCommand() had a comment that wait with time-out could not be used because JSchProcess.exitValue() threw the wrong unchecked exception when the process was still running. Fix this and make JSchProcess.exitValue() throw the right exception, then wait with a time-out in SshSupport. The Apache sshd client's SshdExecProcess has always used the correct IllegalThreadStateException. Add tests for SshSupport.runCommand(). Change-Id: Id30893174ae8be3b9a16119674049337b0cf4381 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
* sshd: use PropertyResolver in testThomas Wolf2020-07-281-6/+6
| | | | | | | | | | Improve the SshTestGitServer API for accessing the server properties. Instead of returning the raw property map, return the proper sshd API abstraction PropertyResolver. This makes the interface more resilient against upstream changes. Change-Id: Ie5b685bddc4e59f3eb6c121026d3658d57618ca4 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
* Remove dependency on JSch from SSH test frameworkThomas Wolf2020-07-262-43/+115
| | | | | | | | | | Use standard java.security to generate test keys, use sshd to write public key files, and write PKCS#8 PEM files for our non-encrypted test private keys. This is a format that both JSch and Apache MINA sshd can read. Change-Id: I6ec55cfd7346b672a7fb6139d51abfb06d81a394 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
* Add a test for upstream bug SSHD-1028Thomas Wolf2020-07-031-0/+12
| | | | | | | | | SSHD-1028:[1] server doesn't close server-side sessions properly when client disconnects. [1] https://issues.apache.org/jira/projects/SSHD/issues/SSHD-1028 Change-Id: I0d67f49e35abe8375cb1370a494dc01d0fb2c9b1 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
* Decouple JSch from JGit CoreMatthias Sohn2020-06-012-0/+1231
| | | | | | | | | | | | | | | | | | | | | | | | Motivation: JSch serves as 'default' implementations of the SSH transport. If a client application does not use it then there is no need to pull in this dependency. Move the classes depending on JSch to an OSGi fragment extending the org.eclipse.jgit bundle and keep them in the same package as before since moving them to another package would break API. Defer moving them to a separate package to the next major release. Add a new feature org.eclipse.jgit.ssh.jsch feature to enable installation. With that users can now decide which of the ssh client integrations (JCraft JSch or Apache Mina SSHD) they want to install. We will remove the JCraft JSch integration in a later step due to the reasons discussed in bug 520927. Bug: 553625 Change-Id: I5979c8a9dbbe878a2e8ac0fbfde7230059d74dc2 Also-by: Michael Dardis <git@md-5.net> Signed-off-by: Michael Dardis <git@md-5.net> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com> Signed-off-by: David Ostrovsky <david@ostrovsky.org>
* In-memory SSH keys for the "no files" sshd testsThomas Wolf2020-05-231-6/+31
| | | | | | | Avoid using a key written to a file. This makes it clearer that the test does not rely on files being present. Change-Id: I31cf4f404aab5b891c32fc4bda906b7f8fe03777 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
* Update to org.apache.sshd 2.4.0Thomas Wolf2020-03-221-8/+9
| | | | | | | | | | | | | | | | | Change target platforms to Orbit I20200319180910 and regenerate them. Change package imports to [2.4.0,2.5.0); adapt code to upstream API changes. Maven build: update version in root pom. Bazel build: update version & hash in WORKSPACE file. Proxy functionality verified manually using 3proxy (HTTP & SOCKS, with basic authentication) and ssh -vvv -D7020 localhost (SOCKS, no authentication). Bug: 561078 Change-Id: I582f6b98055b013c006f2c749890fe6db801cbaa Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
* Update EDL 1.0 license headers to new short SPDX compliant formatMatthias Sohn2020-01-041-38/+5
| | | | | | | | | | This is the format given by the Eclipse legal doc generator [1]. [1] https://www.eclipse.org/projects/tools/documentation.php?id=technology.jgit Bug: 548298 Change-Id: I8d8cabc998ba1b083e3f0906a8d558d391ffb6c4 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
* sshd: add missing javadoc in SshTestGitServerThomas Wolf2019-07-151-0/+10
| | | | Change-Id: Ie2e207eb05e0f6da8018153f8a5dd636e8f35f4c Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
* sshd: correct the protocol version exchangeThomas Wolf2019-07-151-0/+18
| | | | | | | | | | | | | | | | | | | RFC 4253 section 4.2 allows an ssh server to send additional lines before its server identification string. Apache MINA sshd enforces for these lines the constraints specified for the server identification line, too: no NUL characters and not longer than 255 characters. That is too strict. RFC 4253 doesn't mandate this, and it also doesn't make sense given the rationale for these lines in RFC 4253: a TCP wrapper may not be aware of SSH restrictions, and may not adhere to these constraints. Be more lenient when parsing the server's protocol version. Allow NULs and longer lines in the preamble, and also handle line endings more leniently. Only enforce the restrictions for the actual server identification line. Bug: 545939 Change-Id: I75955e9d8a8daef7c04fc0f39539c2ee93514e1c Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
* Apache MINA sshd client: adapt to sshd 2.2.0Thomas Wolf2019-05-061-13/+17
| | | | | | | | | | | | | | Update target platforms, maven and bazel builds to use sshd 2.2.0. Adapt internal classes to changed sshd interfaces and remove previous work-arounds for asking repeatedly for key passwords and for loading keys lazily; both are now done by sshd. CQ: 19034 CQ: 19035 Bug: 541425 Change-Id: I85e1df6ebb8a94953a912d9b2b8a7b5bdfbd608a Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
* Apache MINA sshd client: test & fix password authenticationThomas Wolf2018-11-171-2/+32
| | | | | | | | | | | | | | | | | | | | | | | Add tests for password and keyboard-interactive authentication. Implement password authentication; the default provided by sshd is non-interactive, which is not useful for JGit. Make sure the CredentialsProvider gets reset on successive password retrieval attempts. Otherwise it might always return the same non- accepted password from a secure storage. (That one was discovered by actually trying this via EGit; the JGit tests don't catch this.) Change the default order of authentication mechanisms to prefer password over keyboard-interactive. This is a mitigation for upstream bug SSHD-866.[1] Also include a fix for upstream bug SSHD-867.[2] [1] https://issues.apache.org/jira/projects/SSHD/issues/SSHD-866 [2] https://issues.apache.org/jira/projects/SSHD/issues/SSHD-867 Bug: 520927 Change-Id: I423e548f06d3b51531016cf08938c8bd7acaa2a9 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
* Move SshTestGitServer to new bundle org.eclipse.jgit.junit.sshThomas Wolf2018-11-171-0/+362
Create the bundle and move the SshTestGitServer there. Verified that the Eclipse build still works and ran JSchSshTest and ApacheSshTest as junit tests inside Eclipse. Update maven build and features to account for that. Verified by running full maven build including packaging. Update bazel build files to account for that. Verified by a clean-slate bazel build :all, followed by running the JSchSshTest and the ApacheSshTest via bazel. Change-Id: Ia084942f4425b454529de148e00417e7da786a90 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
r: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
[[sending-email-from-java-applications]]
Sending email from Java Applications
------------------------------------

[[introduction]]
Introduction
^^^^^^^^^^^^

Sending email is a common feature required in many business applications.
From simple notifications containing plain text to complex reports with
links and multiple attachments, email is a common way of asynchronous
communication with end users.

This tutorial shows how to send email messages in two different ways:

1.  Using the Apache Commons Email library which offers a simplified API on top of the JavaMail API.
2.  Using Spring Mail Support, a utility library that encapsulates the specifics of the mailing system, also implemented on top of the JavaMail API. 

Although
email operations include sending, receiving, deleting, setting flags,
and others depending on the specific email server in use, this tutorial
only discusses email sending through SMTP.

[[how-does-email-work]]
How does Email Work?
~~~~~~~~~~~~~~~~~~~~

Let’s start
with a quick overview of the email communication process. It all begins
with the end user composing a message using a client desktop or web
application. The message is sent through multiple networking devices
until it reaches its destination at the recipient’s machine. The
relevant elements of this process are depicted in the following figure:

image:https://lh5.googleusercontent.com/GbbTWnXnPml4ijiQU1mMO8tkmGSGAcmpXEGwHQJwGOFGGI3zD98_rgYaGi-0OX18M9iTtkHyif8FnJNdKX1ubdE8MXIQ4k-Ww5qu0-MC4aoOhiqjKz56p8KLyN-QdonMZzSKEEGS[javamail-tutorial]

Once the end
user has triggered the action to send the email, the client application
connects to its configured email server, the SMTP Server, which can be
described as a program capable of communicating with other SMTP Servers
using the Simple Mail Transfer Protocol (SMTP). This SMTP Server can be
your own server running software, such as Apache James Server, Postfix,
Sendmail, qmail, or a server managed by a third party, such as Gmail,
Outlook, and Yahoo Mail. 

Your SMTP
Server (managed by yourself or by a third party) sends the email message
to the recipient’s SMTP Server. Once the message reaches its
destination, it is stored in the recipient’s inbox at the recipient’s
SMTP Server. Finally, the recipient can read the message by requesting
it from the SMTP Server.

Nowadays,
SMTP is used to send email messages and IMAP (Internet Message Access
Protocol) or POP (Post Office Protocol) to receive messages. In this
case, your client application will use SMTP to send the message and the
recipient’s SMTP Server will use SMTP to receive the message and IMAP or
POP to serve the message when the recipient requests it. You don’t need
to understand the specifics of these protocols in order to send email
from a Java application but you might want to understand them deeper, if
you are planning to implement operations such as receiving, deleting,
and setting flags, or if your applications require sending zillions of
emails in a batch.

[[configuring-a-test-smtp-server]]
Configuring a Test SMTP Server
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

For the
purposes of this tutorial, we are going to use FakeSMTP, a free email
server that offers a convenient GUI for testing email sending. You can
download it from the following website: https://nilhcem.github.io/FakeSMTP/download.html[https://nilhcem.github.io/FakeSMTP/download.html]

Extract the
content of the downloaded zip file and execute the extracted jar. You
can configure a port in the Listening port option (we will use 9090 in
this tutorial). Once ready, click the Start server button to start
getting emails.

Please note
that with FakeSMTP you don’t need to provide any authentication values
(they will be ignored).

[[javamail-api]]
JavaMail API
~~~~~~~~~~~~

The JavaMail
API is defined by the JSR 919 and is included in Java EE (but not in EJB
Lite nor Java EE Web Profile). It provides an abstraction over mail
systems which makes its API more verbose than those of Apache Commons
Email and Spring Mail Support. We are not covering JavaMail in this
tutorial. However, we provide an example application that uses JavaMail
to send emails. You can get the code from the following link: https://github.com/alejandro-du/java-email-tutorial/blob/master/javamail-example/src/main/java/com/example/javamail/JavaMailService.java[https://github.com/alejandro-du/java-email-tutorial/blob/master/javamail-example/src/main/java/com/example/javamail/JavaMailService.java]

[[apache-commons-email]]
Apache Commons Email
~~~~~~~~~~~~~~~~~~~~

Apache
Commons Email is built on top of JavaMail and hides much of its
complexity. Therefore, it offers an API that simplifies the code to
implement email sending from Java applications.

You must
download the Commons Email jar file from the following link:
https://commons.apache.org/proper/commons-email/download_email.cgi[https://commons.apache.org/proper/commons-email/download_email.cgi],
or add the dependency using a dependency management system. For example,
if you are using Maven, you can add the following to your pom.xml:

[source, xml]
....
<dependency>
   <groupId>org.apache.commons</groupId>
   <artifactId>commons-email</artifactId>
   <version>1.4</version>
</dependency>
....
 

With Commons
Email, you can send emails with HTML content using the `HtmlEmail` class.
This class offers an abstraction to send emails with attachments. For
example, during testing you can configure the `HtmlEmail` instance as
follows:

[source,java]
....
HtmlEmail email = new HtmlEmail();
email.setHostName("localhost");
email.setSmtpPort(9090);
email.setAuthentication()"sender@test.com", "password");
....
 
Or if you want to use Gmail:

[source,java]
....
HtmlEmail email = new HtmlEmail();
email.setHostName("smtp.gmail.com");
email.setSmtpPort(465);
email.setSSLOnConnect(true);
email.setAuthentication("your-account-name@gmail.com", "your-password");
....

Keep in mind
that hard-coding connection parameters like this is not good practice.
Instead, you should read the values from an external source (such as a
properties file) so that you can use different configurations for
different environments (development, testing, production). 

You can use
the email instance to set the sender’s email address, add recipients,
and set the subject and the text of the message:

[source,java]
....
email.setFrom("sender@test.com");
email.addTo("recipient1@test.com", "recipient2@test.com");
email.setSubject("The subject");
email.setHtmlMsg("This is the message.");
....

The `HtmlEmail`
class also exposes the attach method to add attachments to the message.
You can provide these attachments as an `InputStream` so that its content
can be dynamically generated at runtime if required (`FileInputStream` is
always an option in case you have `File` instances instead):

[source,java]
....
ByteArrayDataSource dataSource = new ByteArrayDataSource(inputStream, "text/plain");
DataHandler dataHandler = new DataHandler(dataSource);
email.attach(dataSource, "attachment.txt", "description");
....
 

The `attach`
method is overloaded with multiple implementations offering different
ways to attach files. The one used in the previous example requires to
specify a description for the attachment.

You can find
a complete implementation of a utility class that implements email
sending using the Commons Email in the following link: https://github.com/alejandro-du/java-email-tutorial/blob/master/commons-email-example/src/main/java/com/example/javamail/CommonsEmailService.java[https://github.com/alejandro-du/java-email-tutorial/blob/master/commons-email-example/src/main/java/com/example/javamail/CommonsEmailService.java]

[[spring-email-support]]
Spring Email Support
~~~~~~~~~~~~~~~~~~~~

Similarly to
the Apache Commons Email library, Spring offers an API on top of
JavaMail which abstracts away the details of the mailing system. You
need to add the `spring-context-support` dependency using Maven or Gradle.
There is no official download site for this dependency, but you can
download it directly from the following link if required: http://mvnrepository.com/artifact/org.springframework/spring-context-support/4.2.4.RELEASE[http://mvnrepository.com/artifact/org.springframework/spring-context-support/4.2.4.RELEASE].

If you are
using Maven you can add the following dependency to your pom.xml:

[source,xml]
....
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context-support</artifactId>
  <version>4.2.4.RELEASE</version>
</dependency>
....

You start by
obtaining an implementation of the `MailSender` interface. Spring provides
the `JavaMailSenderImpl` class that implements `MailSender`. You can obtain
an instance of this class either by configuring and injecting a bean, if
you are already using Spring Framework and have configured an
application context, or by direct instantiation: 

[source,java]
....
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
....

The
connection to the SMTP server is configured using properties. The
following example shows how to configure the `mailSender` to connect to
Gmail’s SMTP server:

[source,java]
....
Properties properties = new Properties();
properties.put("mail.smtp.host", "smtp.gmail.com");
properties.put("mail.smtp.port", "465");
properties.put("mail.smtp.ssl.enable", "true");

mailSender.setJavaMailProperties(properties);
....
 
Alternatively,
you can use methods defined in the `MailSender` interface to configure the
host and port, but in the case of SMTP servers using SSL, you will have
to provide at least the `mail.smtp.ssl.enable` property through a
`Properties` object. For this reason, we prefer to configure all the
settings using properties in this example.

The authentication credentials are configured using the `MailSender` instance
as follows:

[source,java]
....
mailSender.setUsername("sender@test.com");
mailSender.setPassword("password");
....

The next step is to create a `MimeMessage` and a `MimeMessageHelper`:

[source,java]
....
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper("The message body", true);
....

The second
parameter is set to true to create a multipart message that will allow
us to add attachments later. The `MimeMessageHelper` exposes a handful of
methods to directly set up the message:

[source,java]
....
helper.setFrom("sender@test.com");
helper.setSubject("subject");
helper.setText(text, true); // true to activate multipart
helper.addTo("recipient@test.com");
....

There are
several overloaded methods in the `MimeMessageHelper` that provide
different ways to attach files. The following example uses the
`ByteArrayDataSource` class to provide an attachment from an `InputStream`:

[source,java]
....
ByteArrayDataSource dataSource = new ByteArrayDataSource(inputStream, "text/plain");
helper.addAttachment("file.txt", dataSource);
....

Finally, you can send the email using the `MailSender` instance:

[source,java]
....
mailSender.send(message);
....
 

You can find
a complete implementation of a utility class that implements email
sending using Spring Email Support in the following link: https://github.com/alejandro-du/java-email-tutorial/blob/master/spring-mail-example/src/main/java/com/example/javamail/SpringEmailService.java[https://github.com/alejandro-du/java-email-tutorial/blob/master/spring-mail-example/src/main/java/com/example/javamail/SpringEmailService.java]

[[an-example-web-application]]
An Example Web Application
~~~~~~~~~~~~~~~~~~~~~~~~~~

Let’s create
a Java web application to test this functionality. The application
consists of a text field where users can type an email address and a
button that will send an email with an attachment to the specified
address.

We are going
to use the https://vaadin.com[Vaadin Framework] which allows us to quickly create a web
application by using only the Java Programming Language. This way, we
don’t need to worry about writing any HTML or JavaScript at all.

Although most
IDEs have plugins to easily generate a new Vaadin project, we are going
to use a Maven archetype to generate the project that you can later
import into your favorite IDE. You can create a new Vaadin project with
Maven using the following command line: 

[source]
....
mvn archetype:generate -DarchetypeGroupId=com.vaadin -DarchetypeArtifactId=vaadin-archetype-application -DarchetypeVersion=7.6.2
....

After
specifying a group and artifact id, you can run `mvn clean install` to
compile the project and `mvn jetty:run` to deploy and run the application.
Open your browser and navigate to http://localhost:8080[http://localhost:8080] to see the application
running.

Open the `MyUI.java` file (it should be the only Java file in the project) and change the `init` method to the following:

[source,java]
....
//... imports mostly from com.vaadin package

public class MyUI extends UI {
   @Override
   protected void init(VaadinRequest vaadinRequest) {
       // the text field where users will specify their email address
       TextField textField = new TextField("Your email:");

       // a button with a click listener that sends the email
       Button button = new Button("Send me the PDF", e -> sendEmail(textField.getValue()));

       // a layout containing the previous components
       VerticalLayout layout = new VerticalLayout(textField, button);
       layout.setMargin(true);
       layout.setSpacing(true);

       setContent(layout); // sets the content for this UI
   }
   ...
}
....

Add the missing `sendEmail` method and implement it as follows:

[source,java]
....
private void sendEmail(String to) {
    try {
        // all values as variables to clarify its usage
        InputStream inputStream = getClass().getResourceAsStream("/dock-magazine.pdf");
        String from = "sender@test.com";
        String subject = "Your PDF";
        String text = "Here there is your <b>PDF</b> file!";
        String fileName = "file.pdf";
        String mimeType = "application/pdf";

        CommonsEmailService.send(from, to, subject, text, inputStream, fileName, mimeType);

        Notification.show("Email sent");
    } catch (MessagingException | IOException e) {
        e.printStackTrace();
        Notification.show("Error sending the email", Notification.Type.ERROR_MESSAGE);
    }
}
....
 

At this point
you might want to create the missing `CommonsEmailService` class (or
`SpringMailService` class) and implement the send method as an exercise.
But if you prefer, you can take the example implementation from the
following link: https://github.com/alejandro-du/java-email-tutorial/blob/master/commons-email-example/src/main/java/com/example/javamail/CommonsEmailService.java[https://github.com/alejandro-du/java-email-tutorial/blob/master/commons-email-example/src/main/java/com/example/javamail/CommonsEmailService.java]

Finally, add
a PDF file with the name file.pdf in the resources directory of your
Maven project. You may want to use a small file so that SMTP servers
would be able to accept it.

Stop the
Jetty server if necessary, run `mvn clean install` again, and reload the
web page in the browser. The following is a screenshot of the web
application: image:https://lh5.googleusercontent.com/zcy_LwtCa9TW-sP3phTlczRP9lBvE9ozaxd0Ae4yJghOjQnAjxOlhYp2n5ruLiLlroZ9HW_LEoJN-5qPJI60rXMiFvGuHcibvP5txCMhiS9ZPn1wCMYkN43Zkjqbuw1kTi0nXn_v[screenshot.png,width=622,height=433]

If you have
FakeSMTP running, you should be able to see the email messages sent
through the web application.

[[which-approach-to-use]]
Which Approach to Use?
~~~~~~~~~~~~~~~~~~~~~~

Choosing an
option depends on different factors. However, I would recommend to use
Spring Email Support if you are developing a Spring application. If not,
go with Apache Commons Email, it offers the most intuitive API. Also,
Apache Commons Email jar is lighter than the spring-context-support jar,
as the later includes more than just the email support classes. Using
the JavaMail API directly may be convenient only when you need lower
level interaction with the mailing system.

You can experiment with the code by downloading the example web applications
from GitHub:

[source]
....
$ git clone https://github.com/alejandro-du/java-email-tutorial
$ cd java-email-tutorial
$ cd commons-email-example
# (Or cd spring-mail-example)

$ mvn clean install
$ mvn jetty:run
....
 

Don’t forget to configure run FakeSMTP before using the web application deployed at
http://localhost:8080[http://localhost:8080].