Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM maven:3.8.5-openjdk-17 AS build

WORKDIR /app


COPY pom.xml ./pom.xml
COPY src ./src
COPY resources ./resources

RUN mvn clean package -Pprod

EXPOSE 8080

ENTRYPOINT ["java", "-jar", "--spring.profiles.active=prod", "app/target/jira.jar"]

11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,13 @@
- https://habr.com/ru/articles/259055/

Список выполненных задач:
...
- Удалить социальные сети
- Вынести чувствительную информацию в отдельный проперти файл
- Добавить testcontainers
- Написать тесты для всех публичных методов контроллера ProfileRestController
- Сделать рефакторинг метода com.javarush.jira.bugtracking.attachment.FileUtil#upload
- Добавить новый функционал: добавления тегов к задаче(без фронта)
- Добавить подсчет времени сколько задача находилась в работе и тестировании.
- Написать Dockerfile для основного сервера
- Написать docker-compose файл для запуска контейнера сервера вместе с БД и nginx
- Добавить локализацию минимум на двух языках(en,es,ru) для шаблонов писем (mails) и стартовой страницы index.html
2 changes: 1 addition & 1 deletion config/nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ server {
gzip_min_length 2048;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
root /opt/jirarush/resources;
root /resources;

if ($request_uri ~ ';') {return 404;}

Expand Down
4 changes: 4 additions & 0 deletions dc-prop.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

POSTGRES_DB_URL=jdbc:postgresql://db:5432/jira
POSTGRES_DB_USER=jira
POSTGRES_DB_PASSWORD=JiraRush
40 changes: 40 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
version: '3.8'

services:
app:
container_name: app_container
image: jira:latest
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:8080"
env_file:
- dc-prop.env
depends_on:
- db
- nginx
restart: always


db:
container_name: db_container
image: postgres:latest
environment:
POSTGRES_USER: jira
POSTGRES_PASSWORD: JiraRush
ports:
- "5432:5432"
volumes:
- ./data/db:/var/lib/postgresql/data
restart: always


nginx:
container_name: nginx_container
image: nginx:latest
ports:
- "80:80"
volumes:
- ./config/nginx.conf:/etc/nginx/nginx.conf
restart: always
28 changes: 28 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers-bom</artifactId>
<version>1.20.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
Expand Down Expand Up @@ -97,6 +109,7 @@
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
<version>1.18.34</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
Expand Down Expand Up @@ -142,6 +155,21 @@
<artifactId>junit-platform-launcher</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
10 changes: 5 additions & 5 deletions resources/mails/email-confirmation.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<html th:lang="${#locale}" lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<title>JiraRush - подтверждение почты</title>
<title th:text="#{email.confirm.title}">JiraRush - подтверждение почты</title>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
</head>
<body>
<p th:text="'Привет, ' + ${user.firstName} + '.'"/>
<p>Чтобы завершить настройку учетной записи и начать пользоваться JiraRush, подтвердите, что вы правильно указали вашу
<p th:text="#{email.hello}', ' + ${user.firstName} + '.'"/>
<p th:text="#{email.complete}">Чтобы завершить настройку учетной записи и начать пользоваться JiraRush, подтвердите, что вы правильно указали вашу
электронную почту.</p>
<a th:href="${confirmationUrl}">Подтвердить почту</a>
<a th:text="#{email.confirm.url}" th:href="${confirmationUrl}">Подтвердить почту</a>
</body>
</html>
10 changes: 5 additions & 5 deletions resources/mails/password-reset.html
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<html th:lang="${#locale}" lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:fragment="head">
<title>JiraRush - установить новый пароль</title>
<title th:text="#{password.reset.title}">JiraRush - установить новый пароль</title>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
</head>
<body>
<p th:text="'Привет, ' + ${user.firstName} + '.'"/>
<p th:text="'Мы получили запрос на установку нового пароля JiraRush для учетной записи: ' + ${user.email} + '.'"/>
<a th:href="${resetUrl}">Установить пароль</a>
<p th:text="#{email.hello}', ' + ${user.firstName} + '.'"/>
<p th:text="#{password.reset.message}' ' + ${user.email} + '.'"/>
<a th:text="#{password.reset.url}" th:href="${resetUrl}">Установить пароль</a>
</body>
</html>
16 changes: 13 additions & 3 deletions resources/view/index.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
<!DOCTYPE html>
<html lang="ru" xmlns:th="http://www.thymeleaf.org">
<html th:lang="${#locale}" lang="en" xmlns:th="http://www.thymeleaf.org">
<!--/*@thymesVar id="authUser" type="com.javarush.jira.login.AuthUser"*/-->

<th:block th:replace="~{layout/main::page(title='JiraRush: mini bugtracking system',appMain=~{::appMain})}">
<appMain>
<h1>JiraRush Home page</h1>
<h1 th:text="#{index.homepage}">JiraRush Home page</h1>
<div>
<form action="#" method="get">
<label for="language-select">Language:</label>
<select id="language-select" name="lang" onchange="this.form.submit()">
<option value="en" th:text="#{lang.en}">English</option>
<option value="ru" th:text="#{lang.ru}">Russian</option>
<option value="es" th:text="#{lang.es}">Spanish</option>
</select>
</form>
</div>
<div th:if="${authUser} != null">
<form action="/ui/logout" method="post">
<button class="btn btn-primary btn-lg mt-3" type="submit">Logout</button>
<button class="btn btn-primary btn-lg mt-3" type="submit" th:text="#{logout.button}">Logout</button>
</form>
</div>
</appMain>
Expand Down
44 changes: 22 additions & 22 deletions resources/view/layout/footer.html
Original file line number Diff line number Diff line change
@@ -1,79 +1,79 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<html th:lang="${#locale}" lang="en" xmlns:th="http://www.thymeleaf.org">

<div th:fragment="footer">
<footer class="text-center text-lg-start text-white footer">
<section>
<div class="container text-center text-md-start">
<div class="row ms-0 ms-md-5">
<div class="col-md-4 col-xl-2 mb-4 mt-4">
<h6 class="fw-bold mt-2 mt-md-0 mb-4">
<h6 th:text="#{footer.learn}" class="fw-bold mt-2 mt-md-0 mb-4">
LEARN
</h6>
<p>
<a class="footer-href" href="#">Programming Courses</a>
<a th:text="#{footer.learn.courses}" class="footer-href" href="#">Programming Courses</a>
</p>
<p>
<a class="footer-href" href="#">Java Course</a>
<a th:text="#{footer.learn.java}" class="footer-href" href="#">Java Course</a>
</p>
<p>
<a class="footer-href" href="#">Help with Tasks</a>
<a th:text="#{footer.learn.help}" class="footer-href" href="#">Help with Tasks</a>
</p>
<p>
<a class="footer-href" href="#">Pricing</a>
<a th:text="#{footer.learn.pricing}" class="footer-href" href="#">Pricing</a>
</p>
<p>
<a class="footer-href" href="#">Game Projects</a>
<a th:text="#{footer.learn.project}" class="footer-href" href="#">Game Projects</a>
</p>
</div>
<div class="col-md-4 col-xl-2 mb-4 mt-0 mt-md-4">
<h6 class="fw-bold mb-4">
<h6 th:text="#{footer.community}" class="fw-bold mb-4">
COMMUNITY
</h6>
<p>
<a class="footer-href" href="#">Users</a>
<a th:text="#{footer.community.users}" class="footer-href" href="#">Users</a>
</p>
<p>
<a class="footer-href" href="#">Articles</a>
<a th:text="#{footer.community.articles}" class="footer-href" href="#">Articles</a>
</p>
<p>
<a class="footer-href" href="#">Forum</a>
<a th:text="#{footer.community.forum}" class="footer-href" href="#">Forum</a>
</p>
<p>
<a class="footer-href" href="#">Chat</a>
<a th:text="#{footer.community.chat}" class="footer-href" href="#">Chat</a>
</p>
<p>
<a class="footer-href" href="#">Success Stories</a>
<a th:text="#{footer.community.stories}" class="footer-href" href="#">Success Stories</a>
</p>
</div>
<div class="col-md-4 col-xl-2 mb-4 mt-0 mt-md-4">
<h6 class="fw-bold mb-4">COMPANY</h6>
<h6 th:text="#{footer.company}" class="fw-bold mb-4">COMPANY</h6>
<p>
<a class="footer-href" href="#">About us</a>
<a th:text="#{footer.company.about}" class="footer-href" href="#">About us</a>
<p>
<p>
<a class="footer-href" href="#">Contacts</a>
<a th:text="#{footer.company.contacts}" class="footer-href" href="#">Contacts</a>
<p>
<p>
<a class="footer-href" href="#">Reviews</a>
<a th:text="#{footer.company.reviews}" class="footer-href" href="#">Reviews</a>
<p>
<p>
<a class="footer-href" href="#">FAQ</a>
<a th:text="#{footer.company.faq}" class="footer-href" href="#">FAQ</a>
<p>
<p>
<a class="footer-href" href="#">Support</a>
<a th:text="#{footer.company.support}" class="footer-href" href="#">Support</a>
<p>
</div>

<div class="col-xl-5 mb-4 mt-0 mt-md-4">
<img alt="JavaRush" class="mb-3" src="/static/images/logo/jr.svg">
<p>
<p th:text="#{footer.javaRush}">
JavaRush is an online course for learning Java programming from scratch.
This course is a perfect way to master Java for beginners.
It contains 1200+ of tasks with instant verification and an essential scope of Java
fundamentals theory.
</p>
<h6>FOLLOW US</h6>
<h6 th:text="#{footer.follow}">FOLLOW US</h6>
<div>
<a class="btn btn-sm btn-outline-light me-2" href="#" type="button">
<i class="fab fa-facebook-f pe-1"></i>
Expand All @@ -98,7 +98,7 @@ <h6>FOLLOW US</h6>
</div>
</div>
</section>
<div class="text-center pb-4">
<div th:text="#{footer.slogan}" class="text-center pb-4">
Programmers Are Made, Not Born © 2023 JavaRush
</div>
</footer>
Expand Down
11 changes: 6 additions & 5 deletions resources/view/layout/header.html
Original file line number Diff line number Diff line change
@@ -1,29 +1,30 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<html th:lang="${#locale}" lang="en" xmlns:th="http://www.thymeleaf.org">
<!--/*@thymesVar id="authUser" type="com.javarush.jira.login.AuthUser"*/-->

<div th:fragment="header">
<header class="fixed-top d-none d-md-block header-nav">
<nav class="navbar navbar-expand-lg navbar-dark" id="header">

<div class="container-fluid">
<div class="collapse navbar-collapse mt-2 mb-2 px-5">
<ul class="navbar-nav m-auto">
<form class="d-flex" role="search">
<input aria-label="Search" class="form-control" id="header-search" placeholder="Search"
<input th:placeholder="#{header.search}" aria-label="Search" class="form-control" id="header-search" placeholder="Search"
type="search">
</form>
<li class="nav-item menu-item me-3 ms-4">
<a class="btn btn-yellow" href="/doc" target="_blank" type="button">Swagger API</a>
</li>
</ul>
<div th:if="${authUser} == null">
<a class="btn btn-orange" href="/view/login" type="button">Login/Register</a>
<a th:text="#{login.button}" class="btn btn-orange" href="/view/login" type="button">Login/Register</a>
</div>
<th:block th:if="${authUser} != null">
<a class="btn btn-orange" href="/ui/profile" type="button"><i
<a th:text="#{header.profile}" class="btn btn-orange" href="/ui/profile" type="button"><i
class="fa-solid fa-address-card"></i> Profile</a>
<form action="/ui/logout" class="mx-2" method="post">
<button class="btn btn-yellow btn-orange" type="submit"><i class="fa-solid fa-sign-out"></i>
<button th:text="#{logout.button}" class="btn btn-yellow btn-orange" type="submit"><i class="fa-solid fa-sign-out"></i>
Logout
</button>
</form>
Expand Down
Loading