SHA256
10 12 25
промежуточный не рабочий комит
This commit is contained in:
@@ -34,7 +34,6 @@ public class DatabaseInitializer {
|
||||
|
||||
Path dbFile = Paths.get(dbPath);
|
||||
try {
|
||||
// создаём директорию, если нужно
|
||||
Path parent = dbFile.getParent();
|
||||
if (parent != null && !Files.exists(parent)) {
|
||||
Files.createDirectories(parent);
|
||||
@@ -75,18 +74,17 @@ public class DatabaseInitializer {
|
||||
try (Connection conn = DriverManager.getConnection(jdbcUrl);
|
||||
Statement st = conn.createStatement()) {
|
||||
|
||||
// включаем внешние ключи на этом соединении (для инициализации тоже)
|
||||
st.execute("PRAGMA foreign_keys = ON");
|
||||
|
||||
// 1. Таблица solana_users
|
||||
// 1. solana_users
|
||||
st.executeUpdate("""
|
||||
CREATE TABLE IF NOT EXISTS solana_users (
|
||||
login TEXT NOT NULL,
|
||||
loginId INTEGER NOT NULL PRIMARY KEY,
|
||||
bchId INTEGER NOT NULL,
|
||||
loginKey TEXT, -- основной публичный ключ (логин)
|
||||
deviceKey TEXT, -- публичный ключ устройства
|
||||
bchLimit INTEGER -- может быть NULL
|
||||
loginKey TEXT,
|
||||
deviceKey TEXT,
|
||||
bchLimit INTEGER
|
||||
);
|
||||
""");
|
||||
|
||||
@@ -95,8 +93,7 @@ public class DatabaseInitializer {
|
||||
ON solana_users (login);
|
||||
""");
|
||||
|
||||
// 2. Таблица active_sessions
|
||||
// sessionId TEXT (base64 от 32 байт).
|
||||
// 2. active_sessions
|
||||
st.executeUpdate("""
|
||||
CREATE TABLE IF NOT EXISTS active_sessions (
|
||||
sessionId TEXT NOT NULL PRIMARY KEY,
|
||||
@@ -108,6 +105,10 @@ public class DatabaseInitializer {
|
||||
pushEndpoint TEXT,
|
||||
pushP256dhKey TEXT,
|
||||
pushAuthKey TEXT,
|
||||
clientIp TEXT,
|
||||
clientInfoFromClient TEXT,
|
||||
clientInfoFromRequest TEXT,
|
||||
userLanguage TEXT,
|
||||
FOREIGN KEY (loginId) REFERENCES solana_users(loginId)
|
||||
);
|
||||
""");
|
||||
@@ -117,8 +118,7 @@ public class DatabaseInitializer {
|
||||
ON active_sessions (loginId);
|
||||
""");
|
||||
|
||||
// 3. Таблица users_params
|
||||
// Пара (loginId, param) должна быть уникальна.
|
||||
// 3. users_params
|
||||
st.executeUpdate("""
|
||||
CREATE TABLE IF NOT EXISTS users_params (
|
||||
loginId INTEGER NOT NULL,
|
||||
@@ -138,7 +138,7 @@ public class DatabaseInitializer {
|
||||
ON users_params (loginId);
|
||||
""");
|
||||
|
||||
// 4. Таблица ip_geo_cache — персистентный кэш геолокации по IP
|
||||
// 4. ip_geo_cache
|
||||
st.executeUpdate("""
|
||||
CREATE TABLE IF NOT EXISTS ip_geo_cache (
|
||||
ip TEXT NOT NULL PRIMARY KEY,
|
||||
|
||||
@@ -9,6 +9,25 @@ import java.sql.*;
|
||||
* DAO для таблицы active_sessions.
|
||||
*
|
||||
* Здесь мы храним данные об активных сессиях пользователя (для wss-соединений).
|
||||
*
|
||||
* Структура таблицы:
|
||||
*
|
||||
* CREATE TABLE active_sessions (
|
||||
* sessionId TEXT NOT NULL PRIMARY KEY,
|
||||
* loginId INTEGER NOT NULL,
|
||||
* sessionPwd TEXT NOT NULL,
|
||||
* storagePwd TEXT NOT NULL,
|
||||
* sessionCreatedAtMs INTEGER NOT NULL,
|
||||
* lastAuthirificatedAtMs INTEGER NOT NULL,
|
||||
* pushEndpoint TEXT,
|
||||
* pushP256dhKey TEXT,
|
||||
* pushAuthKey TEXT,
|
||||
* clientIp TEXT,
|
||||
* clientInfoFromClient TEXT,
|
||||
* clientInfoFromRequest TEXT,
|
||||
* userLanguage TEXT,
|
||||
* FOREIGN KEY (loginId) REFERENCES solana_users(loginId)
|
||||
* );
|
||||
*/
|
||||
public final class ActiveSessionsDAO {
|
||||
|
||||
@@ -43,20 +62,28 @@ public final class ActiveSessionsDAO {
|
||||
lastAuthirificatedAtMs,
|
||||
pushEndpoint,
|
||||
pushP256dhKey,
|
||||
pushAuthKey
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
pushAuthKey,
|
||||
clientIp,
|
||||
clientInfoFromClient,
|
||||
clientInfoFromRequest,
|
||||
userLanguage
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
""";
|
||||
|
||||
try (PreparedStatement ps = db.getConnection().prepareStatement(sql)) {
|
||||
ps.setString(1, session.getSessionId());
|
||||
ps.setLong(2, session.getLoginId());
|
||||
ps.setString(3, session.getSessionPwd());
|
||||
ps.setString(4, session.getStoragePwd());
|
||||
ps.setLong(5, session.getSessionCreatedAtMs());
|
||||
ps.setLong(6, session.getLastAuthirificatedAtMs());
|
||||
ps.setString(7, session.getPushEndpoint());
|
||||
ps.setString(8, session.getPushP256dhKey());
|
||||
ps.setString(9, session.getPushAuthKey());
|
||||
ps.setString(1, session.getSessionId());
|
||||
ps.setLong(2, session.getLoginId());
|
||||
ps.setString(3, session.getSessionPwd());
|
||||
ps.setString(4, session.getStoragePwd());
|
||||
ps.setLong(5, session.getSessionCreatedAtMs());
|
||||
ps.setLong(6, session.getLastAuthirificatedAtMs());
|
||||
ps.setString(7, session.getPushEndpoint());
|
||||
ps.setString(8, session.getPushP256dhKey());
|
||||
ps.setString(9, session.getPushAuthKey());
|
||||
ps.setString(10, session.getClientIp());
|
||||
ps.setString(11, session.getClientInfoFromClient());
|
||||
ps.setString(12, session.getClientInfoFromRequest());
|
||||
ps.setString(13, session.getUserLanguage());
|
||||
|
||||
ps.executeUpdate();
|
||||
}
|
||||
@@ -76,7 +103,11 @@ public final class ActiveSessionsDAO {
|
||||
lastAuthirificatedAtMs,
|
||||
pushEndpoint,
|
||||
pushP256dhKey,
|
||||
pushAuthKey
|
||||
pushAuthKey,
|
||||
clientIp,
|
||||
clientInfoFromClient,
|
||||
clientInfoFromRequest,
|
||||
userLanguage
|
||||
FROM active_sessions
|
||||
WHERE sessionId = ?
|
||||
""";
|
||||
@@ -94,6 +125,7 @@ public final class ActiveSessionsDAO {
|
||||
|
||||
/**
|
||||
* Обновить только lastAuthirificatedAtMs для конкретной сессии.
|
||||
* (оставляю для совместимости, вдруг ещё где-то используется)
|
||||
*/
|
||||
public void updateLastAuthirificatedAtMs(String sessionId, long lastAuthMs) throws SQLException {
|
||||
String sql = """
|
||||
@@ -109,6 +141,45 @@ public final class ActiveSessionsDAO {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Обновление метаданных при RefreshSession:
|
||||
* - lastAuthirificatedAtMs
|
||||
* - clientIp
|
||||
* - clientInfoFromClient
|
||||
* - clientInfoFromRequest
|
||||
* - userLanguage
|
||||
*/
|
||||
public void updateOnRefresh(
|
||||
String sessionId,
|
||||
long lastAuthMs,
|
||||
String clientIp,
|
||||
String clientInfoFromClient,
|
||||
String clientInfoFromRequest,
|
||||
String userLanguage
|
||||
) throws SQLException {
|
||||
|
||||
String sql = """
|
||||
UPDATE active_sessions
|
||||
SET
|
||||
lastAuthirificatedAtMs = ?,
|
||||
clientIp = ?,
|
||||
clientInfoFromClient = ?,
|
||||
clientInfoFromRequest = ?,
|
||||
userLanguage = ?
|
||||
WHERE sessionId = ?
|
||||
""";
|
||||
|
||||
try (PreparedStatement ps = db.getConnection().prepareStatement(sql)) {
|
||||
ps.setLong(1, lastAuthMs);
|
||||
ps.setString(2, clientIp);
|
||||
ps.setString(3, clientInfoFromClient);
|
||||
ps.setString(4, clientInfoFromRequest);
|
||||
ps.setString(5, userLanguage);
|
||||
ps.setString(6, sessionId);
|
||||
ps.executeUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Удаление записи по sessionId.
|
||||
* Если записи нет — просто ничего не удалит (0 строк).
|
||||
@@ -122,16 +193,23 @@ public final class ActiveSessionsDAO {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Маппинг ResultSet → ActiveSession (все 13 полей).
|
||||
*/
|
||||
private ActiveSession mapRow(ResultSet rs) throws SQLException {
|
||||
String sessionId = rs.getString("sessionId");
|
||||
long loginId = rs.getLong("loginId");
|
||||
String sessionPwd = rs.getString("sessionPwd");
|
||||
String storagePwd = rs.getString("storagePwd");
|
||||
long sessionCreatedAtMs = rs.getLong("sessionCreatedAtMs");
|
||||
long lastAuthirificatedAtMs = rs.getLong("lastAuthirificatedAtMs");
|
||||
String pushEndpoint = rs.getString("pushEndpoint");
|
||||
String pushP256dhKey = rs.getString("pushP256dhKey");
|
||||
String pushAuthKey = rs.getString("pushAuthKey");
|
||||
String sessionId = rs.getString("sessionId");
|
||||
long loginId = rs.getLong("loginId");
|
||||
String sessionPwd = rs.getString("sessionPwd");
|
||||
String storagePwd = rs.getString("storagePwd");
|
||||
long sessionCreatedAtMs = rs.getLong("sessionCreatedAtMs");
|
||||
long lastAuthirificatedAtMs = rs.getLong("lastAuthirificatedAtMs");
|
||||
String pushEndpoint = rs.getString("pushEndpoint");
|
||||
String pushP256dhKey = rs.getString("pushP256dhKey");
|
||||
String pushAuthKey = rs.getString("pushAuthKey");
|
||||
String clientIp = rs.getString("clientIp");
|
||||
String clientInfoFromClient = rs.getString("clientInfoFromClient");
|
||||
String clientInfoFromRequest = rs.getString("clientInfoFromRequest");
|
||||
String userLanguage = rs.getString("userLanguage");
|
||||
|
||||
return new ActiveSession(
|
||||
sessionId,
|
||||
@@ -142,7 +220,11 @@ public final class ActiveSessionsDAO {
|
||||
lastAuthirificatedAtMs,
|
||||
pushEndpoint,
|
||||
pushP256dhKey,
|
||||
pushAuthKey
|
||||
pushAuthKey,
|
||||
clientIp,
|
||||
clientInfoFromClient,
|
||||
clientInfoFromRequest,
|
||||
userLanguage
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,6 @@ package shine.db.entities;
|
||||
/**
|
||||
* Модель активной сессии (таблица active_sessions).
|
||||
*
|
||||
* Поля соответствуют схеме:
|
||||
*
|
||||
* CREATE TABLE active_sessions (
|
||||
* sessionId TEXT NOT NULL PRIMARY KEY,
|
||||
* loginId INTEGER NOT NULL,
|
||||
@@ -15,6 +13,10 @@ package shine.db.entities;
|
||||
* pushEndpoint TEXT,
|
||||
* pushP256dhKey TEXT,
|
||||
* pushAuthKey TEXT,
|
||||
* clientIp TEXT,
|
||||
* clientInfoFromClient TEXT,
|
||||
* clientInfoFromRequest TEXT,
|
||||
* userLanguage TEXT,
|
||||
* FOREIGN KEY (loginId) REFERENCES solana_users(loginId)
|
||||
* );
|
||||
*/
|
||||
@@ -30,6 +32,12 @@ public class ActiveSession {
|
||||
private String pushP256dhKey; // TEXT (nullable)
|
||||
private String pushAuthKey; // TEXT (nullable)
|
||||
|
||||
// Новые поля
|
||||
private String clientIp; // IP клиента при auth/refresh
|
||||
private String clientInfoFromClient; // строка от клиента (PWA)
|
||||
private String clientInfoFromRequest; // строка, собранная на сервере
|
||||
private String userLanguage; // prefer-language (например, "ru-RU")
|
||||
|
||||
public ActiveSession() {
|
||||
}
|
||||
|
||||
@@ -41,7 +49,11 @@ public class ActiveSession {
|
||||
long lastAuthirificatedAtMs,
|
||||
String pushEndpoint,
|
||||
String pushP256dhKey,
|
||||
String pushAuthKey) {
|
||||
String pushAuthKey,
|
||||
String clientIp,
|
||||
String clientInfoFromClient,
|
||||
String clientInfoFromRequest,
|
||||
String userLanguage) {
|
||||
this.sessionId = sessionId;
|
||||
this.loginId = loginId;
|
||||
this.sessionPwd = sessionPwd;
|
||||
@@ -51,6 +63,10 @@ public class ActiveSession {
|
||||
this.pushEndpoint = pushEndpoint;
|
||||
this.pushP256dhKey = pushP256dhKey;
|
||||
this.pushAuthKey = pushAuthKey;
|
||||
this.clientIp = clientIp;
|
||||
this.clientInfoFromClient = clientInfoFromClient;
|
||||
this.clientInfoFromRequest = clientInfoFromRequest;
|
||||
this.userLanguage = userLanguage;
|
||||
}
|
||||
|
||||
// --- getters / setters ---
|
||||
@@ -126,4 +142,36 @@ public class ActiveSession {
|
||||
public void setPushAuthKey(String pushAuthKey) {
|
||||
this.pushAuthKey = pushAuthKey;
|
||||
}
|
||||
}
|
||||
|
||||
public String getClientIp() {
|
||||
return clientIp;
|
||||
}
|
||||
|
||||
public void setClientIp(String clientIp) {
|
||||
this.clientIp = clientIp;
|
||||
}
|
||||
|
||||
public String getClientInfoFromClient() {
|
||||
return clientInfoFromClient;
|
||||
}
|
||||
|
||||
public void setClientInfoFromClient(String clientInfoFromClient) {
|
||||
this.clientInfoFromClient = clientInfoFromClient;
|
||||
}
|
||||
|
||||
public String getClientInfoFromRequest() {
|
||||
return clientInfoFromRequest;
|
||||
}
|
||||
|
||||
public void setClientInfoFromRequest(String clientInfoFromRequest) {
|
||||
this.clientInfoFromRequest = clientInfoFromRequest;
|
||||
}
|
||||
|
||||
public String getUserLanguage() {
|
||||
return userLanguage;
|
||||
}
|
||||
|
||||
public void setUserLanguage(String userLanguage) {
|
||||
this.userLanguage = userLanguage;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user