Первый

This commit is contained in:
2024-12-09 19:24:12 +06:00
commit 3e35cf6980
32 changed files with 3535 additions and 0 deletions

35
.gitignore vendored Normal file
View File

@ -0,0 +1,35 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
/logs
/temporary.sqlite

BIN
.mvn/wrapper/maven-wrapper.jar vendored Normal file

Binary file not shown.

2
.mvn/wrapper/maven-wrapper.properties vendored Normal file
View File

@ -0,0 +1,2 @@
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar

248
README.md Normal file
View File

@ -0,0 +1,248 @@
# Описание функций авторизации
____
#### Алгоритм
Refresh token токен действует 12 часов и за эти 12 часов не реже чем раз в 3 часа нужно обновить Refresh token ну и заодно Access token обновиться.
Аccess token действует 20 минут (позже уменьшу до 10 минут) и его можно обновить в любое время, если будет просрочен выдаст 401 ошибку. Чтобы время от времени по расписанию не запрашивать обновление токена,
можно сделать обвёртку для 2й отправки запроса, в случае выявления просрочки токена чтобы эта обвёртка отправляла запрос Refresh, а потом обратно в нужное место отправляла запрос.
____
## Оглавление
1. [Получить список разрешений для пользователя по Access token](#получить-список-разрешений-для-пользователя-по-Access-token)
2. [Получить CAPTCHA с проверочным токеном](#получить-captcha-с-проверочным-токеном)
3. [Создать нового пользователя](#создать-нового-пользователя)
4. [Получить информацию о пользователе по его Access token ](#получить-информацию-о-пользователе-по-его-access-token )
5. [Авторизоваться](#авторизоваться)
6. [Обновить токен доступа (а также обновить рефреш токен)](#обновить-токен-доступа-а-также-обновить-рефреш-токен)
7. [Ссылка для подтверждения смены пароля (переходят на неё из почты)](#ссылка-для-подтверждения-смены-пароля-переходят-на-неё-из-почты)
8. [Принять капчу и код для инициализации процедуры восстановления пароля](#принять-капчу-и-код-для-инициализации-процедуры-восстановления-пароля)
9. [Обновить пароль по логину и старому паролю](#обновить-пароль-по-логину-и-старому-паролю)
10. [Проверить валидность токена](#проверить-валидность-токена)
____
### Получить список разрешений для пользователя по Access token
https://istransit.kz/api/authorization/v02/access/
Запрос может содержать параметры фильтрации для поиска частичного совпадения названия (действия), если параметров фильтрации нет или он равен null то вернёт все записи.
Пример запроса:
```json
{
"action_name":"arm_"
}
```
Пример ответа:
```json
{
"error_code": 0,
"error_message": "",
"data": [
"arm_accounting",
"arm_carrier",
"arm_hr"]
}
```
### Получить CAPTCHA с проверочным токеном
https://istransit.kz/api/authorization/v02/captcha/
Пример запроса:
```json
{
"email":"test@mail.ru"
}
```
Пример ответа:
```json
{
"image":"тут gif в base64",
"token":"ZUROMC9xQVpRNjVGZGZBSWdrSGk5NHlPK2JXcHJMHVlbWVBPT0=.ywHb5zzI+ARK3XDRpgVkC1fdlqEQWWOXLuVIu\/rRMho="
}
```
Где "image" это рисунок в base64
А "token" это токен для последующей проверки введённого кода "code":"XXXXXX".
По умолчанию токен captcha действует 10 минут.
### Создать нового пользователя
https://istransit.kz/api/authorization/v02/create/
Письмо с паролем придёт на почту
Пример запроса:
```json5
{
"country_id": "1",
"company_name": "ТОО 'Тестовая компания'",
"position": "Менеджер",
"name": "Берик",
"surname": "Султанов",
"patronymic": "Серикович",
"phone": "+7777123456",
"email": "test@test.kz",
"code":"11111", //Код с CAPTCHA
"token":"ZUROMC9xQVpRNjVGZGZBSdyc2JIV0ZueHdDMHVlbWVBPT0=.ywHb5zzI+ARK3XDRpgVkC1fdlqEQWWOXLuVIu\/rRMho=" //Токен с CAPTCHA
}
```
Пример ответа:
```json
{
"error_code": "0",
"error_message":""
}
```
### Получить информацию о пользователе по его Access token
https://istransit.kz/api/authorization/v02/info/
Запрос:
```
Cookie: jwt_a = Access token
```
Пример ответа:
```json5
{
"error_code": "0",
"error_message": "",
"name": "Igor",
"surname": "M",
"patronymic": "I",
"roles": "Кассир, Кладовщик",
"time": "1703838784", //Время с сервера
"expiration": "1696924443", //Когда "протухнет" пароль
"appid": "postman",
"arm": "monitoring"
}
```
### Авторизоваться
https://istransit.kz/api/authorization/v02/login/
Пример запроса:
```json
{
"login" : "test@istt.kz",
"password" : "test",
"totp": "123456",
"appid" : "postman"
}
```
В ответ:
```json5
{
"error_code": "0",
"error_message": "",
"name": "Igor",
"surname": "M",
"patronymic": "I",
"roles": "Кассир, Кладовщик",
"time": "1703838784", //Время с сервера
"expiration": "1696924443", //Когда протухает пароль
"appid": "postman",
"arm": "monitoring"
}
```
Также в ответ Cookie:
```
Cookie: jwt_a = Access token
Cookie: jwt_r = Refresh token
```
### Обновить токен доступа (а также обновить рефреш токен)
https://istransit.kz/api/authorization/v02/refresh/
В запросе Cookie:
```
Cookie: jwt_a = Access token
Cookie: jwt_r = Refresh token
```
Пример ответа:
```json
{
"error_code": "0",
"error_message":""
}
```
Также в ответе Cookie:
```
Cookie: jwt_a = Access token
Cookie: jwt_r = Refresh token
```
### Ссылка для подтверждения смены пароля (переходят на неё из почты)
https://istransit.kz/api/authorization/v02/reset/
Пример запроса:
```html
https://istransit.kz/api/authorization/v02/reset/?token=xxxxx&lng=1
```
В ответ HTML страница с результатом на 7 секунд, с переходом на главную страницу:
```html
<!DOCTYPE html>
<html lang="ru">
<head>
<title></title>
<meta http-equiv="refresh" content="7; url='https://aistransit.kz'" />
</head>
<body>
<h1>Описание результата</h1>
</body>
</html>
```
### Принять капчу и код для инициализации процедуры восстановления пароля
https://istransit.kz/api/authorization/v02/restore/
Пример запроса:
```json
{
"code":"11111",
"token":"ZUROMC9xQVpRNjVGZGZBSdyc2JIV0ZueHdDMHVlbWVBPT0=.ywHb5zzI+ARK3XDRpgVkC1fdlqEQWWOXLuVIu\/rRMho="
}
```
Код и токен из captcha
Пример ответа:
```json
{
"error_code": "0",
"error_message":""
}
```
### Обновить пароль по логину и старому паролю
https://istransit.kz/api/authorization/v02/update/
Для этой функции авторизация пользователя не обязательна, а значит пользователя можно не авторизовывать если у него просрочен пароль.
В новом пароле должно быть цифра, большая латинская буква, маленькая латинская буква, один спец символ и длина не менее 6 символов.
Пример запроса:
```json
{
"login":"test@mail.ru",
"password":"12345",
"password_new":"54321"
}
```
Пример ответа:
```json
{
"error_code": "0",
"error_message":""
}
```
### Проверить валидность токена
https://istransit.kz/api/authorization/v02/alive/
На вход Cookie с jwt_a токеном, на выход код ошибки.
Пример ответа:
```json
{
"error_code": "0",
"error_message":""
}
```

View File

@ -0,0 +1,38 @@
spring.application.name=kg_gpti_jwt
server.port=8082
issuer.name=transit
logging.level.com.zaxxer.hikari=DEBUG
spring.datasource.url=jdbc:postgresql://192.168.6.25:5432/transit?ApplicationName=transit_jwt
spring.datasource.username=postgres
spring.datasource.password=lelPfAtgQWhHYfy1SsHk
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.max-lifetime=1700000
spring.datasource.hikari.idle-timeout=600000
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.connection-test-query=SELECT now()
spring.datasource.hikari.validation-timeout=60000
private.key=MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQD1GHVopvcvpJyU/ha7+R9IDC6EoZyZKZ14XBGu95ikEUSPkIoxE8n6TbF8Srj95OxrowHhOejtMrUhF+NBJNR59evR9ZT1JO2yo/QvvfA834wiDpNzCDFQbGO5emuN9KoinZIpFSyMtjGNlaj7zf01wYIglSqr3kzpTYlF3zlVlW/6oGECA3swKnz9eiNEMg7WEHCIZx+HureHySSJi4MZLizH4EzAW8geUB7Vi5rJLfg5fPcXkJfOcP6PoSnfHqXkSw2DFEoM+hz3vrS/rj05YlkmTTKarnr+GOAc4IhE36zbSx93BaZ4d59Hsk5CuS4qk/sI9dn7IQYJKuypKJiFAgMBAAECggEBAI2AwoBaLUofYpuOmveJm+rPxaejWrL+2MBdf4QhxMmsgoXUcERnZWwSoQ7eYTGMkoaORQ6QjY8sgHCLxxOcPOPw/GZqv8ZMvMMvb1KE+YdblR8whSabq0UAXw79w8zgXb3AdVsss1zF75QLvNUsFy2K/CLtnAZAQO1Na5yghQyIKjKd8YXSP8Ylk15Nz942jbo71h980Uk3mr8tV/PqJ1x7cs1Z5femhQHNFDsuJMRh6TpPDSqEir3ziZs9jVQMR4pAMm5bCvfcsnOPaltomRymUKOTdvHBVv1LCTWNipQgqNPMitmcWtJnC48j62M5ADtnF1p30VezMQnylLS+3kECgYEA+rXZQdbndKHaROTE1bDAmthxgrOBW5wrzZ7B9Z0zDnrsuOa8bk8Dc0WNGd8/mzKz1t4fAfA7W9c/748erhwUFhBlzpv8COOcEJwWSL4dV0mCLBqMuhmb4yJRYwv2kVEdFvbWPjKRhr7WcnIV7rrbc/jr3kdr/aKSXzxt7J0BaDUCgYEA+kRIb8/0XC6YJL84v8NlkpgaGx7BDGqIsjVYrWAfTWtS01HxT+39QG6T5tT6rgkIN1FBxkvSvvuz2/mwSpAvVktCuZyIHoAutJUuowwwT9yYy0zaLyrhX44zoXZiHmZAHObxo1oYogtH64yhiC3X+uLtScW0g5Z7SFxjDOTFmRECgYEAxVNnwjhhSB0z7FGa0w4hKj79aH/carxKhbZUtvqZeuYpd4az/KZX8txlKF3cdEy923pMMXxhW/HZMrYU0bjr3kndt3ZyMpTi+ve/WlW4RkFnIUtsQ/VwCp+yKyD5WnrbSH3TNnUasVF2+/DrblDH9UmQbA0O5DyWtDqd0kPpHZkCgYEAs95rqWDuoWojkxWUNc67q9aBvMgnu0K+KEbLCyCwnrXp+1NDekzz3WEcD6U23epD624NNfW86+J/bDRSjeR/AShqNnjYJAPAja1CrZDPEDbd4g/EKG5LOKA9X2h0MKEQpzUcqmjQl3ZAJH0Yg4VfW0PJg2IC0ShQRruPvO6XTeECgYA54eQya6sEIpE7aIKXwitRMV3VE8jMP5cQHTLK841pFPKiC2iMQDrgJqjYuMJUdhx2WRhoHQwy76XvLMWzLmD+k2U4DwzSq3APc6r+m4EesUdhsmt8/DFyR29OT0r7OuVVppQbQ+SPHrtNxVrAVuwhpnfW8rTdZRdbPHAnwgs/lg==
public.key=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA9Rh1aKb3L6SclP4Wu/kfSAwuhKGcmSmdeFwRrveYpBFEj5CKMRPJ+k2xfEq4/eTsa6MB4Tno7TK1IRfjQSTUefXr0fWU9STtsqP0L73wPN+MIg6TcwgxUGxjuXprjfSqIp2SKRUsjLYxjZWo+839NcGCIJUqq95M6U2JRd85VZVv+qBhAgN7MCp8/XojRDIO1hBwiGcfh7q3h8kkiYuDGS4sx+BMwFvIHlAe1YuayS34OXz3F5CXznD+j6Ep3x6l5EsNgxRKDPoc9760v649OWJZJk0ymq56/hjgHOCIRN+s20sfdwWmeHefR7JOQrkuKpP7CPXZ+yEGCSrsqSiYhQIDAQAB
access.time=600
refresh.time=43200
captcha.key=PPExpv36jk4Vzda3NpYnXLfuHCLYXqaNrxlOH/Jr/1M=
captcha.time=600
mail.host=mail.gpti.kg
mail.port=587
mail.login=noreply@gpti.kg
mail.password=PasW#vc!a24
url.reset=https://transit.gpti.kg/api/authorization/v02/reset
url.main=https://transit.gpti.kg/
spring.redis.host=192.168.6.25
spring.redis.port=6379
spring.redis.password=9F3/NKWeOjd815vkadT2DcgVHf6fEpVQXw==

View File

@ -0,0 +1,40 @@
spring.application.name=kz_istransit_jwt
server.port=8082
issuer.name=istransit
logging.level.com.zaxxer.hikari=DEBUG
spring.datasource.url=jdbc:postgresql://10.101.1.6:5432/transit_2024_09_03?ApplicationName=kz_istransit_jwt
spring.datasource.username=postgres
spring.datasource.password=PasSecrKey1
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.max-lifetime=1700000
spring.datasource.hikari.idle-timeout=600000
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.connection-test-query=SELECT now()
spring.datasource.hikari.validation-timeout=60000
private.key=MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCsrV60WgOCbFDz7mrr5Ade4wSrKjgB4PX+Y2zzttc87FKILzZswpQv2XLRZXEbkgpAViV99BsKDSd0f46FTynTH3SqbAJ4KfhsVPqfMD2yNjJBJSRyLZ19QAFdyyveRI/b4oQ+dOl0ZhlAUQ5Hfg5G34cE/AyfoVaHRol2ZOpkf5XL90/dPKxPsAaWw+LwgD2PdqzINl1L17EspVUjNiRsclQqkodhzhP/brRhq5S03KKNtPnDhlZJsep67NX8cZQJgil8BnIzGHMqdFF+NBZoLPy/+r4U/Vr6O1oPZ7RK3ontY6fJPHY/bI17KxwQusk8C3tPJNwg2U3mhkJ3mF93AgMBAAECggEAE9nCX11RtfaZv9ESvZdzOXdDnCG4Wo7v+JSZe9LzH2/TdRBoY0xjGLUYu/W7cP3y6757hOVBDoDAnmXjjnOxTTH6iXTtO78nbdy/CvnSvd/5GwAYFoAj8Lgg8BVhL6YWG6MIrN1n0RfDo18uEw3suj0MGoiXMuqrNdXoC5JCV9cajVSDhABw761sNrwBgYCOxk28KrfTRLh6QsQGSf8stLDDwgfImWXJTLzKacFAemNRFuBqp+pQdVuBtorN9rYoGyiswVBTWIA06uUYZqK1uIRLh7wHf2cFARm5rREDwYmG8EHe8JXYeOU2JUF/Rd0V4EQVZHFB4VLwYYumwq2XUQKBgQDcyrmpaA7xjt7ilIV50CtzrY8hAJST2bbdnl/aMm7JI/ZjNFVXbTDHxUen0IvyHmpPS1Z3K8XJ2IR07L7vO3E96OJcYsU2dJ9/HZ5Vg+Q+f3TrscbNRc6Dn6knG9Vr/D/x3pJoyRR7VoWQXs6y87Df5eVtdjmzTTKtY/tmMhEyrQKBgQDINnvwg9vxhhaqflQmNCxGoAkImrYsyGBVlhOy3qbqnMVSQGW8ub/MChpNPrOBTNq6Nb7kK4dzYGSa7lK3vjX+9bc/8vUY69DpV9yZpp370UXTnrKkPUIgrVHiQfjfOXDXeHcpCNQD7E+cDM+DtPtgjtPV966HipFMSvOBmohDMwKBgQDY3Ro9ZeL/qpgLr1vnCOwVBA1ImhxVmIt/5FY7qDuevv778+Q7Khm2rnQyRamfl/ZNii8UgF8WYd/AROVJb3ZMG9lyauVQFn6uyXXCgviF1oUOGCCvcPhl2kW4DyOynCJmvHnMCG1gs9wesLCPnsJFOLb/rBcCoTm8iy7b8yNnRQKBgCeDSTaQb2ndMr/3KphXl51gnCfMkMOJ0ClT8xNMCdknk3HGL83tQsL8A3DXPQn5pvk0/jV9ub+1eGVzP3Pv4CwvRjkis+h1Mce7hVf1oBxAku1O1qa/SDu2uQBUUM+NQI3lwm6gxWb4zkVX6eRuZWYLCheiSBmL6V0LNb+QRfAtAoGBAJ4tM34ovk0Ag/fRjxgEYqo7FcMplBs3nymGV/zS9QQA4gorGq5mBiQX0n8wR68UpKz7u1NXNXc7hJGvP0uHK+/GCQd9i1Csow641TIdMv+4XhQl2/ZO0NuJb/NVB6qJ93WlnhWJP3s1a1zVlRyF3+Zn0D8nbBp+tkCbET0+XGuB
public.key=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArK1etFoDgmxQ8+5q6+QHXuMEqyo4AeD1/mNs87bXPOxSiC82bMKUL9ly0WVxG5IKQFYlffQbCg0ndH+OhU8p0x90qmwCeCn4bFT6nzA9sjYyQSUkci2dfUABXcsr3kSP2+KEPnTpdGYZQFEOR34ORt+HBPwMn6FWh0aJdmTqZH+Vy/dP3TysT7AGlsPi8IA9j3asyDZdS9exLKVVIzYkbHJUKpKHYc4T/260YauUtNyijbT5w4ZWSbHqeuzV/HGUCYIpfAZyMxhzKnRRfjQWaCz8v/q+FP1a+jtaD2e0St6J7WOnyTx2P2yNeyscELrJPAt7TyTcINlN5oZCd5hfdwIDAQAB
access.time=600
refresh.time=43200
captcha.key=PPExpv36jk4Vzda3NpYnXLfuHCLYXqaNrxlOH/Jr/1M=
captcha.time=600
mail.host=92.46.51.29
mail.port=465
mail.login=no-reply@istt.kz
mail.password=je6&HHCEmJ
url.reset=http://127.0.0.1:8088/reset
url.main=http://127.0.0.1:8088/
spring.redis.host=10.101.1.6
spring.redis.port=6379
spring.redis.password=9F3/NKWeOjd815vkadT2DcgVHf6fEpVQXw==

43
kz_mcp_jwt.properties Normal file
View File

@ -0,0 +1,43 @@
spring.application.name=kz_mcp_jwt
server.port=8082
issuer.name=geovizor
logging.level.com.zaxxer.hikari=DEBUG
#spring.datasource.url=jdbc:postgresql://geovizor.com:5432/monitoring_new
#spring.datasource.username=postgres
#spring.datasource.password=y7HMHi0ATxx1VC3UU5WG
#spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://mcp.kz:5432/mcp
spring.datasource.username=igor
spring.datasource.password=VnzbUdcePSLtg22ktz13
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.max-lifetime=600000
spring.datasource.hikari.idle-timeout=60000
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.connection-test-query=SELECT 1
spring.datasource.hikari.validation-timeout=30000
public.key=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA30j+pSoKFHSdSulIGzdFtg+z+ANJPOSVFJ6jvehj1sonOqQsI2rz539+FgIrsDZE8iydFAlQNxS8vqYtWiQSksAUId7aOY/eq7mFkGW+U5xIA2OPgIvN0uhW1Edm85jS7aAg/P/c+lLHnPzQIFdsgVrAh4esFvVS10Pj6TjJVprDj0jOraIw84GVt0gYXZTudcvZavWcmGV1mQJf0jDIHQsCRcMJAE2lzBIKpJGPPZke9xs25lm8feTFR0NNjDNvCG4dYAimyAH36UslXa/zIfRB/7r4AB9KPBFxGe8szK1EcXbJY+paq+TazZJ8Lo8nEmpehCdHUNdD9iWtiYRjNQIDAQAB
private.key=MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDfSP6lKgoUdJ1K6UgbN0W2D7P4A0k85JUUnqO96GPWyic6pCwjavPnf34WAiuwNkTyLJ0UCVA3FLy+pi1aJBKSwBQh3to5j96ruYWQZb5TnEgDY4+Ai83S6FbUR2bzmNLtoCD8/9z6Usec/NAgV2yBWsCHh6wW9VLXQ+PpOMlWmsOPSM6tojDzgZW3SBhdlO51y9lq9ZyYZXWZAl/SMMgdCwJFwwkATaXMEgqkkY89mR73GzbmWbx95MVHQ02MM28Ibh1gCKbIAffpSyVdr/Mh9EH/uvgAH0o8EXEZ7yzMrURxdslj6lqr5NrNknwujycSal6EJ0dQ10P2Ja2JhGM1AgMBAAECggEAPWsLuIzOxv+owJFYpzvV7hV1sJPe0mQh6dEVQ0ioJc3naob8KSXjP1tfaFhigg77eg3xizBgozYOEPcO5IulnD4/i22MY2cCngPjDGwgJUmIuX3qXDaYgBouwCd/1yPDaV+xk0YiF60rgTA9Y5gInbBD40Pbf1kt106yY1WedDaMaogilC6nZwde7H6UQrjoxQ3fSyw9brH04Vma7awcaEYQ6C0NM4uMJFws9jnwDXkYh0QnPW5eIIf9gmr2a+FtKtqlQyZiCjrQOJuU2TQo9wgKiOkVRIfmivXbt5I1O7SkPPUl2mtQAjbZxtHqooLC6It9svO/4rRJY0egjvsGZQKBgQDwCTGhExOahz/UH0I58Ksq44Zz6c6wt7Pt8U2S9L4Sfgjt4Gxu5XcdgMchZHu+xQtONpd7HWO4d9zK1IIHgJ/4IBMA2Lcp7EglHsnuc9II31EU9uP6Ar3yD3UC3zP/lszQs7t3Tagpq3I0bUuSnKH+SMW+mKztg5Xiu4x72HeIGwKBgQDuIpryaOhCEuwN6VguTSStNJe6fxI1NlHLF0anacuT43MotsRXYWRKWdu2nkupB3SqY+Lxipibu8I5CkWoKV8pbGYSqW8YDSzxoSPocTrbkuai7mczMSBCtFZ3nDFx1J3O2IJZaBT4OA+HEVaj+rzeyEYrwACmtSAl+YBNXE4W7wKBgH4ohuIe0aXdQgnuJ/Ol74DKNueDUnQFCVedBOWhJqk3ft/vnW4nwpRKE98UHgnlLIz+Gl3F05ynuu8MBA+HZgyWZwaB4LrzCfQgm4dtbk3leYsoPCgx+r1XrGtG/uBt1NY4MOaCdUj5aDvv2dGD64xnmS8UtYbcKxIQ+sQ4wJJTAoGAVOcVo3Pvyw8ABn25qNhsSSzFJAMGNN6nDue/kxTPNm0Ts+Jl4lmg7jlXcqbBhwRXfiCa20901aF9v+R/rVMC0LwLMIAkUcjwyz2OleM4/uxDOrgRJ1lOjTnK0l5n6pPJp+PdpY7MWytxrdBquZA+Ipf5HMQZ91YAnkl0iyBr3xUCgYBNBIb0fVTlAf7KJ4urjOE+305oRmEU5eHK2KiAViPDj16BuPy/hE11BnZE5HT4AMfuAm6AmLdrdiyb2iROMrsEQ8AFsGaFsY/njXqV75nNWceLpqrMk1FcYmnAEv0X/RhvsPzv79RzEf9jyjZlQ1XMfBfuuwwjWaUTLBcQhGFOqQ==
access.time=600
refresh.time=43200
captcha.key=PPExpv36jk4Vzda3NpYnXLfuHCLYXqaNrxlOH/Jr/1M=
captcha.time=600
mail.host=smtp.yandex.ru
mail.port=465
mail.login=info@ccalm.org
mail.password=fu2lpsoGPGiq1xlRm8ag
url.reset=https://mcp.test/api/authorization/login/reset
url.main=https://mcp.test/
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=9F3/NKWeOjd815vkadT2DcgVHf6fEpVQXw==

308
mvnw vendored Normal file
View File

@ -0,0 +1,308 @@
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Apache Maven Wrapper startup batch script, version 3.2.0
#
# Required ENV vars:
# ------------------
# JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
if [ -z "$MAVEN_SKIP_RC" ] ; then
if [ -f /usr/local/etc/mavenrc ] ; then
. /usr/local/etc/mavenrc
fi
if [ -f /etc/mavenrc ] ; then
. /etc/mavenrc
fi
if [ -f "$HOME/.mavenrc" ] ; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
mingw=false
case "$(uname)" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
if [ -z "$JAVA_HOME" ]; then
if [ -x "/usr/libexec/java_home" ]; then
JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME
else
JAVA_HOME="/Library/Java/Home"; export JAVA_HOME
fi
fi
;;
esac
if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=$(java-config --jre-home)
fi
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=$(cygpath --unix "$JAVA_HOME")
[ -n "$CLASSPATH" ] &&
CLASSPATH=$(cygpath --path --unix "$CLASSPATH")
fi
# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw ; then
[ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] &&
JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)"
fi
if [ -z "$JAVA_HOME" ]; then
javaExecutable="$(which javac)"
if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=$(which readlink)
if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then
if $darwin ; then
javaHome="$(dirname "\"$javaExecutable\"")"
javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac"
else
javaExecutable="$(readlink -f "\"$javaExecutable\"")"
fi
javaHome="$(dirname "\"$javaExecutable\"")"
javaHome=$(expr "$javaHome" : '\(.*\)/bin')
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)"
fi
fi
if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2
exit 1
fi
if [ -z "$JAVA_HOME" ] ; then
echo "Warning: JAVA_HOME environment variable is not set."
fi
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
if [ -z "$1" ]
then
echo "Path not specified to find_maven_basedir"
return 1
fi
basedir="$1"
wdir="$1"
while [ "$wdir" != '/' ] ; do
if [ -d "$wdir"/.mvn ] ; then
basedir=$wdir
break
fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
if [ -d "${wdir}" ]; then
wdir=$(cd "$wdir/.." || exit 1; pwd)
fi
# end of workaround
done
printf '%s' "$(cd "$basedir" || exit 1; pwd)"
}
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
# Remove \r in case we run on Windows within Git Bash
# and check out the repository with auto CRLF management
# enabled. Otherwise, we may read lines that are delimited with
# \r\n and produce $'-Xarg\r' rather than -Xarg due to word
# splitting rules.
tr -s '\r\n' ' ' < "$1"
fi
}
log() {
if [ "$MVNW_VERBOSE" = true ]; then
printf '%s\n' "$1"
fi
}
BASE_DIR=$(find_maven_basedir "$(dirname "$0")")
if [ -z "$BASE_DIR" ]; then
exit 1;
fi
MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR
log "$MAVEN_PROJECTBASEDIR"
##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar"
if [ -r "$wrapperJarPath" ]; then
log "Found $wrapperJarPath"
else
log "Couldn't find $wrapperJarPath, downloading it ..."
if [ -n "$MVNW_REPOURL" ]; then
wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
else
wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
fi
while IFS="=" read -r key value; do
# Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' )
safeValue=$(echo "$value" | tr -d '\r')
case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;;
esac
done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
log "Downloading from: $wrapperUrl"
if $cygwin; then
wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath")
fi
if command -v wget > /dev/null; then
log "Found wget ... using wget"
[ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet"
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
else
wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
fi
elif command -v curl > /dev/null; then
log "Found curl ... using curl"
[ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent"
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
else
curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
fi
else
log "Falling back to using Java to download"
javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java"
javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class"
# For Cygwin, switch paths to Windows format before running javac
if $cygwin; then
javaSource=$(cygpath --path --windows "$javaSource")
javaClass=$(cygpath --path --windows "$javaClass")
fi
if [ -e "$javaSource" ]; then
if [ ! -e "$javaClass" ]; then
log " - Compiling MavenWrapperDownloader.java ..."
("$JAVA_HOME/bin/javac" "$javaSource")
fi
if [ -e "$javaClass" ]; then
log " - Running MavenWrapperDownloader.java ..."
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath"
fi
fi
fi
fi
##########################################################################################
# End of extension
##########################################################################################
# If specified, validate the SHA-256 sum of the Maven wrapper jar file
wrapperSha256Sum=""
while IFS="=" read -r key value; do
case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;;
esac
done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
if [ -n "$wrapperSha256Sum" ]; then
wrapperSha256Result=false
if command -v sha256sum > /dev/null; then
if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then
wrapperSha256Result=true
fi
elif command -v shasum > /dev/null; then
if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then
wrapperSha256Result=true
fi
else
echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available."
echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties."
exit 1
fi
if [ $wrapperSha256Result = false ]; then
echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2
echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2
echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2
exit 1
fi
fi
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME")
[ -n "$CLASSPATH" ] &&
CLASSPATH=$(cygpath --path --windows "$CLASSPATH")
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR")
fi
# Provide a "standardized" way to retrieve the CLI args that will
# work with both Windows and non-Windows executions.
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*"
export MAVEN_CMD_LINE_ARGS
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
# shellcheck disable=SC2086 # safe args
exec "$JAVACMD" \
$MAVEN_OPTS \
$MAVEN_DEBUG_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"

205
mvnw.cmd vendored Normal file
View File

@ -0,0 +1,205 @@
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM https://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Apache Maven Wrapper startup batch script, version 3.2.0
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
if "%MVNW_VERBOSE%" == "true" (
echo Found %WRAPPER_JAR%
)
) else (
if not "%MVNW_REPOURL%" == "" (
SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
)
if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %WRAPPER_URL%
)
powershell -Command "&{"^
"$webclient = new-object System.Net.WebClient;"^
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
"}"^
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^
"}"
if "%MVNW_VERBOSE%" == "true" (
echo Finished downloading %WRAPPER_JAR%
)
)
@REM End of extension
@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file
SET WRAPPER_SHA_256_SUM=""
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B
)
IF NOT %WRAPPER_SHA_256_SUM%=="" (
powershell -Command "&{"^
"$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^
"If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^
" Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^
" Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^
" Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^
" exit 1;"^
"}"^
"}"
if ERRORLEVEL 1 goto error
)
@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*
%MAVEN_JAVA_EXE% ^
%JVM_CONFIG_MAVEN_PROPS% ^
%MAVEN_OPTS% ^
%MAVEN_DEBUG_OPTS% ^
-classpath %WRAPPER_JAR% ^
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%"=="on" pause
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
cmd /C exit /B %ERROR_CODE%

38
org_ccalm_jwt.properties Normal file
View File

@ -0,0 +1,38 @@
spring.application.name=org_ccalm_jwt
server.port=8082
issuer.name=ccalm
logging.level.com.zaxxer.hikari=DEBUG
spring.datasource.url=jdbc:postgresql://91.201.214.156:5432/CCALM?ApplicationName=org_ccalm_jwt
spring.datasource.username=postgres
spring.datasource.password=PasSecrKey1
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.max-lifetime=1700000
spring.datasource.hikari.idle-timeout=600000
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.connection-test-query=SELECT now()
spring.datasource.hikari.validation-timeout=60000
private.key=MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDNgtaCfu5QlhWfU8bJAooLoX+bo/ARsvoWUJf5NodkGOivze5Lqtu5eq6ptT+gVKK+IEsjpmDsFPMCE2CW7xLZfgbtrWmTPd+fiRb2Z/fMudedo166H5WEgS3+TDWKt7WkLA/3kqvIqdBotuL4BENwZj6CIjGNdG01RNsCaDA/vxTkzx9njz6kfgAda/+wbdOJNwjNRgIb9AyedQT5OKvqRXequzrrOKD9wrm1O4nv8lA6WFg5YEMSW7T6WRIeArZsQr1aHv6qkiu47YreApfdFIWHxd9QinA9WrLPYdWXONr7+xyvqS4MHSJh9ZmCvMsc/HcF3RHJgEwgiC8E6hiZAgMBAAECggEAByZOICwaTmNqTSi0+blE5DKyJdAGQhdf6/bR0rG69BiJv9QCPk+rZUCHYxATLpjDMKoe8xaOuKfh7GiQK7AVj8t6ojouOhkk9n/mdJwZWt38Slesq/z9TqbP2tD769+ISjXeOFa58zk1Lu9t5gL/9aEY+54E607pnbjPhb3qL819/7absLbY1y3GKw2Cwd7RfP8nOWj0ViwnalFjfg6YZS1BL5c9NSg41FzZolwPruZ/bBGbc3nMW2khpuK7CtRk1pRJHUNYuVCsaBU4M4sf3tlZQPOdB6eYmQ3xmPtdnHYB13s588KialXKFlAuO4zG0CFa8DfIKsWDv6xTC1cMgQKBgQD6CjJuu715oKob7ohDTfrSppk4PY/kxWhUkKyKVW1Y1jXQOcd4BwVSyH6s7N8pCSWMwWmoF/t/l2kIcAWNZnsbzAQ8TYOhp1THstXMVb6c7JOL3SQC5RjbgW1RWCalh7/4QVE0xYeEL3qv5I2t9215zKR87Z6LIdJkxxAsHgMSbQKBgQDSaOp0kJZPkQH/75ltaI9exczyoaf+5U/OrnqT2lpRwa+5wqUTPWpTFTCDcJdu8OKCgrKPOQ6NACuX4PbIW/jR+70w7nbC46Tx3JdDYxBlm+6MuHUs5RXufFDJyGoN8lJzoPGax3uxY1kxWwSaSIB0sVXV/P3PIE31I5DbarWjXQKBgQCrRyLm4anYUCtWuN4UpK0lcUPR17Hi9ysRioz2sbAWw53XRk0SNlT6MSc9E4GGnaJgOflDUTJRY4lqYzoac1HvZ6CbIkoCCRq1NRbpQu8wlYo4q8JITWDqtE0LBMRsbYId77hN2uWKse9r37cBrVULsxgWD7uj+QYjTI0Se3iFPQJ/SSYwXFXn68F98Hxb2q1/KnOZzMBmpzcRh8kg1EYVIFc1wF7rBMVVMY0sUIXUH72fAcBuU1yCsoJcpXCQWxeeaWIbY+eDYj3CGlOWQtct3CVZyZJXKkR6W27cp0oFlNOp1okddbHkTsc7Ou1prDmIbwk3zi0mD9wrPg4fTijK/QKBgQDrYEWT77dQLPcN3RTVn3Ua2d9aj/IWwC330I4qZq2SFKOaB/olnPA6fLNYToTWO70A2ZlsMtVepdThIeYFidkA7Lj7lTVYFdQQzREsO5908A1YWE4sgMEEdMc7n5xKT85vpkPOjBOLZYQ6JjDeWBMDxnXR9/txwbau4bsq3/QFuQ==
public.key=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzYLWgn7uUJYVn1PGyQKKC6F/m6PwEbL6FlCX+TaHZBjor83uS6rbuXquqbU/oFSiviBLI6Zg7BTzAhNglu8S2X4G7a1pkz3fn4kW9mf3zLnXnaNeuh+VhIEt/kw1ire1pCwP95KryKnQaLbi+ARDcGY+giIxjXRtNUTbAmgwP78U5M8fZ48+pH4AHWv/sG3TiTcIzUYCG/QMnnUE+Tir6kV3qrs66zig/cK5tTuJ7/JQOlhYOWBDElu0+lkSHgK2bEK9Wh7+qpIruO2K3gKX3RSFh8XfUIpwPVqyz2HVlzja+/scr6kuDB0iYfWZgrzLHPx3Bd0RyYBMIIgvBOoYmQIDAQAB
access.time=600
refresh.time=43200
captcha.key=PPExpv36jk4Vzda3NpYnXLfuHCLYXqaNrxlOH/Jr/1M=
captcha.time=600
mail.host=smtp.yandex.ru
mail.port=465
mail.login=info@ccalm.org
mail.password=fu2lpsoGPGiq1xlRm8ag
url.reset=https://ccalm.org/api/authorization/v02/reset
url.main=https://ccalm.org/
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=9F3/NKWeOjd815vkadT2DcgVHf6fEpVQXw==

135
pom.xml Normal file
View File

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.ccalm</groupId>
<artifactId>jwt</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>jwt</name>
<description>jwt</description>
<properties>
<java.version>21</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.7.4</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20231013</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.2</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.2</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.2</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.7.0</version>
</dependency>
<dependency>
<groupId>net.logicsquad</groupId>
<artifactId>nanocaptcha</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.5.6</version>
</dependency>
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>6.6</version> <!-- Замените на актуальную версию -->
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.36.0.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.18.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.12.0</version>
</dependency>
<dependency>
<groupId>com.warrenstrange</groupId>
<artifactId>googleauth</artifactId>
<version>1.5.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<systemPropertyVariables>
<spring.config.location>file:kz_mcp_jwt.properties</spring.config.location>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
</project>

3
run.sh Normal file
View File

@ -0,0 +1,3 @@
#!/bin/bash
cd target
java -jar jwt-0.0.1-SNAPSHOT.jar

View File

@ -0,0 +1,20 @@
package org.ccalm.jwt;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan(basePackages = {"org.ccalm.jwt"})
public class JwtApplication {
private static final Logger logger = LogManager.getLogger(JwtApplication.class);
public static void main(String[] args) {
logger.info("Start JwtApplication");
SpringApplication.run(JwtApplication.class, args);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,60 @@
package org.ccalm.jwt;
import org.ccalm.jwt.tools.DBTools;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import java.util.List;
public class Translation {
public int language_id;
public NamedParameterJdbcTemplate jdbcTemplate;
Translation(String lng, NamedParameterJdbcTemplate jdbcTemplate){
language_id=1;
switch (lng) {
case "kz":
case "kk":
language_id = 2;
break;
case "en":
language_id = 3;
break;
case "uz":
language_id = 4;
break;
case "ru":
default:
language_id = 1;
break;
}
this.jdbcTemplate = jdbcTemplate;
}
String trt(String text){
String sql = """
select
translation
from
main._translations
where
del=false
and language_id=:language_id
and identifier=:identifier;
""";
MapSqlParameterSource parameters = new MapSqlParameterSource();
parameters.addValue("language_id", language_id);
parameters.addValue("identifier", text);
List<String> ret = jdbcTemplate.query(sql, parameters, new DBTools.JsonRowMapper());
int i = 0;
for (i = 0; i < ret.size(); i++) {
JSONObject json = new JSONObject(ret.get(i));
text = json.getString("translation");
}
if(i==0){
text = text.replace("_", " ");
}
return text;
}
}

View File

@ -0,0 +1,16 @@
package org.ccalm.jwt.models;
//import jakarta.persistence.Column;
import com.fasterxml.jackson.annotation.JsonProperty;
public class ActionName {
//@Column(name = "action_name", nullable = true)
@JsonProperty("action_name")
private String action_name;
public String getActionName() {
return action_name;
}
public void setActionName(String action_name) {
this.action_name = action_name;
}
}

View File

@ -0,0 +1,14 @@
package org.ccalm.jwt.models;
import com.fasterxml.jackson.annotation.JsonProperty;
public class EmailModel {
@JsonProperty("email")
String email;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}

View File

@ -0,0 +1,19 @@
package org.ccalm.jwt.models;
import com.fasterxml.jackson.annotation.JsonProperty;
public class ErrorModel {
@JsonProperty("timestamp")
private String timestamp;
@JsonProperty("status")
private int status;
@JsonProperty("error")
private String error;
@JsonProperty("path")
private String path;
// Конструктор, геттеры и сеттеры
}

View File

@ -0,0 +1,36 @@
package org.ccalm.jwt.models;
public class LoginModel {
//@JsonProperty("login")
private String login;
//@JsonProperty("password")
private String password;
//@JsonProperty("appid")
private String totp;
private String appid;
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getTotp() { return totp; }
public void setTotp(String totp) {
this.totp = totp;
}
public String getAppid() {
return appid;
}
public void setAppid(String appid) {
this.appid = appid;
}
}

View File

@ -0,0 +1,47 @@
package org.ccalm.jwt.models;
import com.fasterxml.jackson.annotation.JsonProperty;
public class NewUserModel {
@JsonProperty("name")
private String name;
@JsonProperty("email")
private String email;
@JsonProperty("code")
private String code;
@JsonProperty("token")
private String token;
public String getName() {
if(name==null) return "";
else return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
if(email==null) return "";
else return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getCode() {
if(code==null) return "";
else return code;
}
public void setCode(String code) {
this.code = code;
}
public String getToken() {
if(token==null) return "";
else return token;
}
public void setToken(String token) {
this.token = token;
}
}

View File

@ -0,0 +1,25 @@
package org.ccalm.jwt.models;
import com.fasterxml.jackson.annotation.JsonProperty;
public class RestoreModel {
@JsonProperty("code")
String code;
@JsonProperty("token")
String token;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
}

View File

@ -0,0 +1,28 @@
package org.ccalm.jwt.models;
import com.fasterxml.jackson.annotation.JsonProperty;
public class SettingModel {
@JsonProperty("identifier")
private String identifier;
@JsonProperty("value")
private String value;
public String getIdentifier() {
return identifier;
}
public void setIdentifier(String identifier) {
this.identifier = identifier;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}

View File

@ -0,0 +1,42 @@
package org.ccalm.jwt.models;
import com.fasterxml.jackson.annotation.JsonProperty;
public class UpdateModel {
@JsonProperty("login")
private String login;
@JsonProperty("password")
private String password;
@JsonProperty("password_new")
private String passwordNew;
// Геттеры и сеттеры для полей
public String getLogin() {
if(login==null) return "";
else return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
if(password==null) return "";
else return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPasswordNew() {
if(passwordNew==null) return "";
else return passwordNew;
}
public void setPasswordNew(String passwordNew) {
this.passwordNew = passwordNew;
}
}

View File

@ -0,0 +1,96 @@
package org.ccalm.jwt.models;
import com.fasterxml.jackson.annotation.JsonProperty;
public class UserModel {
@JsonProperty("country_id")
private Long countryId;
@JsonProperty("company_name")
private String companyName;
@JsonProperty("position")
private String position;
@JsonProperty("name")
private String name;
@JsonProperty("surname")
private String surname;
@JsonProperty("patronymic")
private String patronymic;
@JsonProperty("phone")
private String phone;
@JsonProperty("email")
private String email;
@JsonProperty("password")
private String password;
public Long getCountryId() {
return countryId;
}
public void setCountryId(Long countryId) {
this.countryId = countryId;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public String getPatronymic() {
return patronymic;
}
public void setPatronymic(String patronymic) {
this.patronymic = patronymic;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}

View File

@ -0,0 +1,63 @@
package org.ccalm.jwt.tools;
import org.ccalm.jwt.MainController;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class Cache implements AutoCloseable {
private static final Logger logger = LogManager.getLogger(Cache.class);
private Jedis jedis = null;
String host = null;
int port = 0;
String password = null;
public Cache(String host,int port,String password) {
this.host=host;
this.port=port;
this.password=password;
}
public boolean open(){
try {
jedis = new Jedis(host, port);
jedis.auth(password);
}catch (Exception e)
{
logger.error(e);
}
return true;
}
@Override
public void close() throws Exception {
if(jedis!=null)
jedis.close();
}
public String get(String key) {
return jedis.get(key);
}
public boolean set(String key,String data,int ttl){
jedis.set(key, data);
long currentTimeMillis = System.currentTimeMillis();
long expireTimeMillis = currentTimeMillis + ttl * 1000;
jedis.expireAt(key, expireTimeMillis / 1000);
return true;
}
public void delete(String key) {
jedis.del(key.getBytes());
}
}

View File

@ -0,0 +1,30 @@
package org.ccalm.jwt.tools;
import org.json.JSONObject;
public class CustomException extends Exception {
private int errorCode;
private String marker;
public CustomException(int errorCode,String message,String marker) {
super(message);
this.errorCode = errorCode;
this.marker = marker;
}
public int getErrorCode() {
return errorCode;
}
public String getErrorMarker() {
return marker;
}
public JSONObject getJson() {
JSONObject json = new JSONObject();
json.put("error_code", getErrorCode());
json.put("error_message", getMessage());
json.put("error_marker", getErrorMarker());
return json;
}
}

View File

@ -0,0 +1,40 @@
package org.ccalm.jwt.tools;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.jdbc.core.RowMapper;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class DBTools {
public static class JsonRowMapper implements RowMapper<String> {
@Override
public String mapRow(ResultSet rs, int rowNum) throws SQLException {
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> resultMap = new HashMap<>();
// Получаем метаданные ResultSet для получения названий столбцов
int columnCount = rs.getMetaData().getColumnCount();
for (int i = 1; i <= columnCount; i++) {
String columnName = rs.getMetaData().getColumnName(i);
Object columnValue = rs.getObject(i);
resultMap.put(columnName, columnValue);
}
// Преобразовываем Map в JSON строку
try {
return objectMapper.writeValueAsString(resultMap);
} catch (Exception e) {
throw new RuntimeException("Failed to convert Map to JSON", e);
}
}
}
}

View File

@ -0,0 +1,65 @@
//From: http://www.codejava.net/java-ee/jsp/sending-e-mail-with-jsp-servlet-and-javamail
package org.ccalm.jwt.tools;
import java.util.Date;
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
/**
* A utility class for sending e-mail messages
* @author www.codejava.net
*
*/
public class EmailUtility {
public static void sendEmail(String host, String port,
final String userName, final String password, String toAddress,
String subject, String message) throws AddressException,
MessagingException
{
// sets SMTP server properties
Properties properties = new Properties();
properties.put("mail.smtp.host", host);
properties.put("mail.smtp.port", port);
properties.put("mail.smtp.auth", "true");
//properties.put("mail.smtp.starttls.enable","true"); STARTTLS requested but already using SSL
properties.put("mail.smtp.EnableSSL.enable","true");
properties.put("mail.smtp.socketFactory.port", port);
properties.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory");
//properties.put("mail.debug", "true");
// creates a new session with an authenticator
Authenticator auth = new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(userName, password);
}
};
Session session = Session.getInstance(properties, auth);
//creates a new e-mail message
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(userName));
InternetAddress[] toAddresses = { new InternetAddress(toAddress) };
msg.setRecipients(Message.RecipientType.TO, toAddresses);
msg.setSubject(subject);
msg.setSentDate(new Date());
//msg.setText(message);
msg.setContent(message, "text/html; charset=utf-8");
// sends the e-mail
Transport.send(msg);
}
}

View File

@ -0,0 +1,167 @@
package org.ccalm.jwt.tools;
import org.ccalm.jwt.MainController;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.json.JSONObject;
import java.sql.*;
public class Storage implements AutoCloseable {
private static final Logger logger = LogManager.getLogger(Storage.class);
private Connection conn = null;
public Storage(){
String url = "jdbc:sqlite:temporary.sqlite";
try {
conn = DriverManager.getConnection(url);
Statement stmt = conn.createStatement();
String sql= """
CREATE TABLE IF NOT EXISTS _users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
email TEXT NOT NULL, --Email пользователя
key TEXT NOT NULL, --Ключ для токена обновления (refresh token)
jwt_r TEXT NOT NULL, --Сам ключ обновления
jwt_a TEXT NOT NULL, --Сам ключ доступа
time_r INTEGER, --Unix time в секундах, когда заканчивается токен обновления
time_a INTEGER --Unix time в секундах, когда заканчивается токен доступа
);
""";
stmt.execute(sql);
stmt.close();
} catch (SQLException e) {
logger.error("Error connecting or executing SQL query in SQLite", e);
}
}
//Для выполнения: try-with-resources
@Override
public void close() throws Exception {
if(conn!=null) {
try {
conn.close();
conn=null;
} catch (SQLException e) {
logger.error("SQLite close error", e);
}
}
}
// В коде не надеюсь на finalize, использую try-with-resources из AutoCloseable
@Override
protected void finalize() throws Throwable {
if(conn!=null) {
try {
conn.close();
conn=null;
} catch (SQLException e) {
logger.error("SQLite close error", e);
}
}
super.finalize();
}
//Получаю поля из базы email пользователя
public JSONObject getJWT(String email){
JSONObject result = new JSONObject();
try {
PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM _users WHERE email=?");
pstmt.setString(1, email);
ResultSet rs = pstmt.executeQuery();
if (rs.next()) {
result.put("id", rs.getInt("id"));
result.put("email", rs.getString("email"));
result.put("key", rs.getString("key"));
result.put("jwt_r", rs.getString("jwt_r"));
result.put("jwt_a", rs.getString("jwt_a"));
result.put("time_r", rs.getLong("time_r"));
result.put("time_a", rs.getLong("time_a"));
}
} catch (SQLException e) {
logger.error("An error occurred", e);
}
return result;
}
//Сохранить либо обновить Refresh токен
public boolean setJWT(String email,String key,String jwt_r,String jwt_a,long time_r,long time_a){
try {
// Проверка существует ли запись с данным email
PreparedStatement selectStmt = conn.prepareStatement("SELECT * FROM _users WHERE email=?");
selectStmt.setString(1, email);
ResultSet rs = selectStmt.executeQuery();
boolean exists = rs.next();
selectStmt.close();
if (exists) {
String updateSql = "UPDATE _users SET key=?, jwt_r=?, jwt_a=?, time_r=?, time_a=? WHERE email=?";
PreparedStatement updateStmt = conn.prepareStatement(updateSql);
updateStmt.setString(1, key);
updateStmt.setString(2, jwt_r);
updateStmt.setString(3, jwt_a);
updateStmt.setLong(4, time_r); // Время в секундах
updateStmt.setLong(5, time_a); // Время в секундах
updateStmt.setString(6, email);
updateStmt.executeUpdate();
updateStmt.close();
} else {
String insertSql = "INSERT INTO _users(email, key, jwt_r, jwt_a, time_r, time_a) VALUES (?, ?, ?, ?, ?, ?)";
PreparedStatement insertStmt = conn.prepareStatement(insertSql);
insertStmt.setString(1, email);
insertStmt.setString(2, key);
insertStmt.setString(3, jwt_r);
insertStmt.setString(4, jwt_a);
insertStmt.setLong(5, time_r); // Время в секундах
insertStmt.setLong(6, time_a); // Время в секундах
insertStmt.executeUpdate();
insertStmt.close();
}
return true;
} catch (SQLException e) {
logger.error("SQLite query execution error", e);
return false;
}
}
//Получаю пароль для токена обновления из базы
public String getKey(String email){
String key="";
try {
PreparedStatement pstmt = conn.prepareStatement("SELECT key FROM _users WHERE email=?");
pstmt.setString(1, email);
ResultSet rs = pstmt.executeQuery();
if (rs.next()) {
key = rs.getString("key");
}
} catch (SQLException e) {
logger.error("SQLite query execution error", e);
}
return key;
}
//Получаю время когда Refresh token "протухнет"
public long getTime(String email){
long time = 1;
try {
PreparedStatement pstmt = conn.prepareStatement("SELECT time_r FROM _users WHERE email=?");
pstmt.setString(1, email);
ResultSet rs = pstmt.executeQuery();
if (rs.next()) {
time = rs.getLong("time_r");
}
} catch (SQLException e) {
logger.error("SQLite query execution error", e);
}
return time;
}
//Удалить токен обновления из базы данных
public boolean delToken(String email){
try {
PreparedStatement pstmt = conn.prepareStatement("DELETE FROM _users WHERE email=?");
pstmt.setString(1, email);
pstmt.executeUpdate();
return true;
} catch (SQLException e) {
logger.error("SQLite query execution error", e);
return false;
}
}
}

View File

@ -0,0 +1,148 @@
package org.ccalm.jwt.tools;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.json.JSONException;
import org.json.JSONObject;
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.Base64;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Tools {
//Зашифровать
public static String encryptText(String pass,String data){
String encryptedBase64="";
String encryptionIV = "jazz_tyt_net_111"; // Ваш вектор инициализации
try {
Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
SecretKeySpec key = new SecretKeySpec(Base64.getDecoder().decode(pass), "AES");
IvParameterSpec iv = new IvParameterSpec(encryptionIV.getBytes()); // Создание объекта IvParameterSpec для вектора инициализации
cipher.init(Cipher.ENCRYPT_MODE, key, iv); // Инициализация шифра с ключом и вектором инициализации
byte[] encrypted = cipher.doFinal(data.getBytes()); // Шифрование строки
encryptedBase64 = Base64.getEncoder().encodeToString(encrypted); // Преобразование зашифрованных данных в base64
} catch (InvalidKeyException e) {
throw new RuntimeException(e);
} catch (InvalidAlgorithmParameterException e) {
throw new RuntimeException(e);
} catch (NoSuchPaddingException e) {
throw new RuntimeException(e);
} catch (IllegalBlockSizeException e) {
throw new RuntimeException(e);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
} catch (BadPaddingException e) {
throw new RuntimeException(e);
}
return encryptedBase64;
}
public static String decryptText(String pass,String data){
String encryptionIV = "jazz_tyt_net_111"; // Ваш вектор инициализации
String decryptedText= "";
try {
Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
SecretKeySpec key = new SecretKeySpec(Base64.getDecoder().decode(pass), "AES");
IvParameterSpec iv = new IvParameterSpec(encryptionIV.getBytes()); // Создание объекта IvParameterSpec для вектора инициализации
cipher.init(Cipher.DECRYPT_MODE, key, iv); // Инициализация шифра с ключом и вектором инициализации
byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(data)); // Расшифровка данных
decryptedText = new String(decrypted); // Преобразование расшифрованных данных в строку
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException |
InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException e) {
e.printStackTrace();
}
return decryptedText;
}
public static String generateSignature(String pass,String input) {
try {
SecretKey secretKey = new SecretKeySpec(Base64.getDecoder().decode(pass), "HmacSHA256");
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] encodedInput = digest.digest(input.getBytes(StandardCharsets.UTF_8));
byte[] encodedKey = secretKey.getEncoded();
// Создание HMAC-подписи
javax.crypto.spec.SecretKeySpec keySpec = new javax.crypto.spec.SecretKeySpec(encodedKey, "HmacSHA256");
javax.crypto.Mac mac = javax.crypto.Mac.getInstance("HmacSHA256");
mac.init(keySpec);
byte[] rawHmac = mac.doFinal(encodedInput);
// Кодирование подписи в base64
return Base64.getEncoder().encodeToString(rawHmac);
} catch (NoSuchAlgorithmException | java.security.InvalidKeyException e) {
e.printStackTrace();
return null;
}
}
public static boolean isValidEmail(String email) {
String EMAIL_REGEX = "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$";
Pattern pattern = Pattern.compile(EMAIL_REGEX);
Matcher matcher = pattern.matcher(email);
return matcher.matches();
}
public static boolean isInteger(String str) {
if (str == null || str.isEmpty()) {
return false;
}
try {
Integer.parseInt(str);
return true;
} catch (NumberFormatException e) {
return false;
}
}
public static String genKey(){
SecretKey key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
byte[] keyBytes = key.getEncoded();
return Base64.getEncoder().encodeToString(keyBytes);
}
public static String generatePassword(int length) {
String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
SecureRandom random = new SecureRandom();
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; i++) {
int randomIndex = random.nextInt(CHARACTERS.length());
sb.append(CHARACTERS.charAt(randomIndex));
}
return sb.toString();
}
// Метод для извлечения подписи из JWT токена
public static String extractSignature(String jwtToken) {
String[] jwtParts = jwtToken.split("\\.");
if (jwtParts.length != 3) {
return null;
}
return jwtParts[2];
}
//Для извлечения содержимого токена
public static JSONObject extractToken(String jwtToken) {
String[] jwtParts = jwtToken.split("\\.");
if (jwtParts.length != 3) {
return null;
}
String payloadJson = new String(Base64.getUrlDecoder().decode(jwtParts[1]));
JSONObject payload=null;
try {
payload = new JSONObject(payloadJson);
} catch (JSONException e) {
return null;
}
return payload;
}
}

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- Please check if the user has access to the directory from which the application is being executed -->
<property name="LOGS" value="logs" />
<springProperty scope="context" name="appName" source="spring.application.name"/>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOGS}/${appName}.log</file>
<encoder>
<pattern>{"timestamp":"%d{yyyy-MM-dd'T'HH:mm:ss.SSS'Z'}","thread":"[%thread]","level":"%level","logger":"%logger{36}","marker":"%X{marker}","message":"%msg"}%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOGS}/${appName}.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxHistory>30</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSS'Z'} | %level | %logger{36} | %X{marker} | %msg%n</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="FILE" />
<appender-ref ref="CONSOLE" />
</root>
</configuration>

View File

@ -0,0 +1,13 @@
package org.ccalm.jwt;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class JwtApplicationTests {
@Test
void contextLoads() {
}
}