diff --git a/shine-UI/index.html b/shine-UI/index.html index 5011458..61d6613 100644 --- a/shine-UI/index.html +++ b/shine-UI/index.html @@ -5,9 +5,9 @@ Shine UI Demo - - - + + +
@@ -27,6 +27,6 @@ }; window.__SHINE_FIREBASE_VAPID_KEY__ = ''; - + diff --git a/shine-UI/js/app.js b/shine-UI/js/app.js index 33c6abe..386fe8d 100644 --- a/shine-UI/js/app.js +++ b/shine-UI/js/app.js @@ -1,7 +1,7 @@ -import { navigate, getRoute, PRE_AUTH_PAGES } from './router.js?v=20260403081123'; -import { renderToolbar } from './components/toolbar.js?v=20260403081123'; -import { captureClientError, setClientErrorTransport } from './services/client-error-reporter.js?v=20260403081123'; -import { initPwaPush } from './services/pwa-push-service.js?v=20260403081123'; +import { navigate, getRoute, PRE_AUTH_PAGES } from './router.js?v=20260405171816'; +import { renderToolbar } from './components/toolbar.js?v=20260405171816'; +import { captureClientError, setClientErrorTransport } from './services/client-error-reporter.js?v=20260405171816'; +import { initPwaPush } from './services/pwa-push-service.js?v=20260405171816'; import { authService, authorizeSession, @@ -12,38 +12,38 @@ import { terminateCurrentSession, addIncomingMessage, setContacts, -} from './state.js?v=20260403081123'; +} from './state.js?v=20260405171816'; -import * as startView from './pages/start-view.js?v=20260403081123'; -import * as entrySettingsView from './pages/entry-settings-view.js?v=20260403081123'; -import * as registerView from './pages/register-view.js?v=20260403081123'; -import * as registrationPaymentView from './pages/registration-payment-view.js?v=20260403081123'; -import * as registrationKeysView from './pages/registration-keys-view.js?v=20260403081123'; -import * as topupView from './pages/topup-view.js?v=20260403081123'; -import * as loginView from './pages/login-view.js?v=20260403081123'; -import * as loginCameraView from './pages/login-camera-view.js?v=20260403081123'; -import * as loginPasswordView from './pages/login-password-view.js?v=20260403081123'; -import * as keyStorageView from './pages/key-storage-view.js?v=20260403081123'; +import * as startView from './pages/start-view.js?v=20260405171816'; +import * as entrySettingsView from './pages/entry-settings-view.js?v=20260405171816'; +import * as registerView from './pages/register-view.js?v=20260405171816'; +import * as registrationPaymentView from './pages/registration-payment-view.js?v=20260405171816'; +import * as registrationKeysView from './pages/registration-keys-view.js?v=20260405171816'; +import * as topupView from './pages/topup-view.js?v=20260405171816'; +import * as loginView from './pages/login-view.js?v=20260405171816'; +import * as loginCameraView from './pages/login-camera-view.js?v=20260405171816'; +import * as loginPasswordView from './pages/login-password-view.js?v=20260405171816'; +import * as keyStorageView from './pages/key-storage-view.js?v=20260405171816'; -import * as profileView from './pages/profile-view.js?v=20260403081123'; -import * as walletView from './pages/wallet-view.js?v=20260403081123'; -import * as settingsView from './pages/settings-view.js?v=20260403081123'; -import * as serverSettingsView from './pages/server-settings-view.js?v=20260403081123'; -import * as deviceView from './pages/device-view.js?v=20260403081123'; -import * as connectDeviceView from './pages/connect-device-view.js?v=20260403081123'; -import * as deviceQrView from './pages/device-qr-view.js?v=20260403081123'; -import * as deviceCameraView from './pages/device-camera-view.js?v=20260403081123'; -import * as showKeysView from './pages/show-keys-view.js?v=20260403081123'; -import * as deviceSessionView from './pages/device-session-view.js?v=20260403081123'; -import * as languageView from './pages/language-view.js?v=20260403081123'; -import * as messagesList from './pages/messages-list.js?v=20260403081123'; -import * as contactSearchView from './pages/contact-search-view.js?v=20260403081123'; -import * as chatView from './pages/chat-view.js?v=20260403081123'; -import * as channelsList from './pages/channels-list.js?v=20260403081123'; -import * as channelView from './pages/channel-view.js?v=20260403081123'; -import * as addChannelView from './pages/add-channel-view.js?v=20260403081123'; -import * as networkView from './pages/network-view.js?v=20260403081123'; -import * as notificationsView from './pages/notifications-view.js?v=20260403081123'; +import * as profileView from './pages/profile-view.js?v=20260405171816'; +import * as walletView from './pages/wallet-view.js?v=20260405171816'; +import * as settingsView from './pages/settings-view.js?v=20260405171816'; +import * as serverSettingsView from './pages/server-settings-view.js?v=20260405171816'; +import * as deviceView from './pages/device-view.js?v=20260405171816'; +import * as connectDeviceView from './pages/connect-device-view.js?v=20260405171816'; +import * as deviceQrView from './pages/device-qr-view.js?v=20260405171816'; +import * as deviceCameraView from './pages/device-camera-view.js?v=20260405171816'; +import * as showKeysView from './pages/show-keys-view.js?v=20260405171816'; +import * as deviceSessionView from './pages/device-session-view.js?v=20260405171816'; +import * as languageView from './pages/language-view.js?v=20260405171816'; +import * as messagesList from './pages/messages-list.js?v=20260405171816'; +import * as contactSearchView from './pages/contact-search-view.js?v=20260405171816'; +import * as chatView from './pages/chat-view.js?v=20260405171816'; +import * as channelsList from './pages/channels-list.js?v=20260405171816'; +import * as channelView from './pages/channel-view.js?v=20260405171816'; +import * as addChannelView from './pages/add-channel-view.js?v=20260405171816'; +import * as networkView from './pages/network-view.js?v=20260405171816'; +import * as notificationsView from './pages/notifications-view.js?v=20260405171816'; const routes = { 'start-view': startView, diff --git a/shine-UI/js/components/toolbar.js b/shine-UI/js/components/toolbar.js index bf88771..1c5484f 100644 --- a/shine-UI/js/components/toolbar.js +++ b/shine-UI/js/components/toolbar.js @@ -1,4 +1,4 @@ -import { resolveToolbarActive } from '../router.js?v=20260403081123'; +import { resolveToolbarActive } from '../router.js?v=20260405171816'; const ITEMS = [ { pageId: 'messages-list', label: 'Личные сообщения', icon: '💬' }, diff --git a/shine-UI/js/pages/add-channel-view.js b/shine-UI/js/pages/add-channel-view.js index a031fb0..4177aa5 100644 --- a/shine-UI/js/pages/add-channel-view.js +++ b/shine-UI/js/pages/add-channel-view.js @@ -1,4 +1,4 @@ -import { renderHeader } from '../components/header.js?v=20260403081123'; +import { renderHeader } from '../components/header.js?v=20260405171816'; export const pageMeta = { id: 'add-channel-view', title: 'Добавить канал' }; diff --git a/shine-UI/js/pages/channel-view.js b/shine-UI/js/pages/channel-view.js index 5f88f55..ab8bc91 100644 --- a/shine-UI/js/pages/channel-view.js +++ b/shine-UI/js/pages/channel-view.js @@ -1,6 +1,6 @@ -import { renderHeader } from '../components/header.js?v=20260403081123'; -import { channelPosts, channels } from '../mock-data.js?v=20260403081123'; -import { addLocalChannelPost, authService, getLocalChannelPosts, state } from '../state.js?v=20260403081123'; +import { renderHeader } from '../components/header.js?v=20260405171816'; +import { channelPosts, channels } from '../mock-data.js?v=20260405171816'; +import { addLocalChannelPost, authService, getLocalChannelPosts, state } from '../state.js?v=20260405171816'; export const pageMeta = { id: 'channel-view', title: 'Канал' }; diff --git a/shine-UI/js/pages/channels-list.js b/shine-UI/js/pages/channels-list.js index 875b8de..d65e364 100644 --- a/shine-UI/js/pages/channels-list.js +++ b/shine-UI/js/pages/channels-list.js @@ -1,6 +1,6 @@ -import { renderHeader } from '../components/header.js?v=20260403081123'; -import { channels as mockChannels } from '../mock-data.js?v=20260403081123'; -import { authService, setChannelsFeed, state } from '../state.js?v=20260403081123'; +import { renderHeader } from '../components/header.js?v=20260405171816'; +import { channels as mockChannels } from '../mock-data.js?v=20260405171816'; +import { authService, setChannelsFeed, state } from '../state.js?v=20260405171816'; export const pageMeta = { id: 'channels-list', title: 'Каналы' }; diff --git a/shine-UI/js/pages/chat-view.js b/shine-UI/js/pages/chat-view.js index 76404a1..cc3d90f 100644 --- a/shine-UI/js/pages/chat-view.js +++ b/shine-UI/js/pages/chat-view.js @@ -1,6 +1,6 @@ -import { renderHeader } from '../components/header.js?v=20260403081123'; -import { directMessages } from '../mock-data.js?v=20260403081123'; -import { addChatMessage, getChatMessages, authService, state } from '../state.js?v=20260403081123'; +import { renderHeader } from '../components/header.js?v=20260405171816'; +import { directMessages } from '../mock-data.js?v=20260405171816'; +import { addChatMessage, getChatMessages, authService, state } from '../state.js?v=20260405171816'; export const pageMeta = { id: 'chat-view', title: 'Чат' }; diff --git a/shine-UI/js/pages/connect-device-view.js b/shine-UI/js/pages/connect-device-view.js index 889c44b..ac768cc 100644 --- a/shine-UI/js/pages/connect-device-view.js +++ b/shine-UI/js/pages/connect-device-view.js @@ -1,5 +1,5 @@ -import { renderHeader } from '../components/header.js?v=20260403081123'; -import { state } from '../state.js?v=20260403081123'; +import { renderHeader } from '../components/header.js?v=20260405171816'; +import { state } from '../state.js?v=20260405171816'; export const pageMeta = { id: 'connect-device-view', title: 'Подключить устройство' }; diff --git a/shine-UI/js/pages/contact-search-view.js b/shine-UI/js/pages/contact-search-view.js index 4b87e4c..b5402c7 100644 --- a/shine-UI/js/pages/contact-search-view.js +++ b/shine-UI/js/pages/contact-search-view.js @@ -1,6 +1,6 @@ -import { renderHeader } from '../components/header.js?v=20260403081123'; -import { directMessages } from '../mock-data.js?v=20260403081123'; -import { authService, ensureChat, setContacts, state } from '../state.js?v=20260403081123'; +import { renderHeader } from '../components/header.js?v=20260405171816'; +import { directMessages } from '../mock-data.js?v=20260405171816'; +import { authService, ensureChat, setContacts, state } from '../state.js?v=20260405171816'; export const pageMeta = { id: 'contact-search-view', title: 'Поиск контактов' }; diff --git a/shine-UI/js/pages/device-camera-view.js b/shine-UI/js/pages/device-camera-view.js index 9ffb556..e12a1cc 100644 --- a/shine-UI/js/pages/device-camera-view.js +++ b/shine-UI/js/pages/device-camera-view.js @@ -1,4 +1,4 @@ -import { renderHeader } from '../components/header.js?v=20260403081123'; +import { renderHeader } from '../components/header.js?v=20260405171816'; export const pageMeta = { id: 'device-camera-view', title: 'Подключить через камеру' }; diff --git a/shine-UI/js/pages/device-qr-view.js b/shine-UI/js/pages/device-qr-view.js index 558ef1f..99aca4f 100644 --- a/shine-UI/js/pages/device-qr-view.js +++ b/shine-UI/js/pages/device-qr-view.js @@ -1,6 +1,6 @@ -import { renderHeader } from '../components/header.js?v=20260403081123'; -import { profile } from '../mock-data.js?v=20260403081123'; -import { state } from '../state.js?v=20260403081123'; +import { renderHeader } from '../components/header.js?v=20260405171816'; +import { profile } from '../mock-data.js?v=20260405171816'; +import { state } from '../state.js?v=20260405171816'; export const pageMeta = { id: 'device-qr-view', title: 'Показать QR-код' }; diff --git a/shine-UI/js/pages/device-session-view.js b/shine-UI/js/pages/device-session-view.js index 11ed610..39763fe 100644 --- a/shine-UI/js/pages/device-session-view.js +++ b/shine-UI/js/pages/device-session-view.js @@ -1,4 +1,4 @@ -import { renderHeader } from '../components/header.js?v=20260403081123'; +import { renderHeader } from '../components/header.js?v=20260405171816'; import { authService, isSessionInvalidError, @@ -6,7 +6,7 @@ import { setAuthError, state, terminateCurrentSession, -} from '../state.js?v=20260403081123'; +} from '../state.js?v=20260405171816'; export const pageMeta = { id: 'device-session-view', title: 'Сеанс устройства' }; diff --git a/shine-UI/js/pages/device-view.js b/shine-UI/js/pages/device-view.js index f9d96fa..7e47e18 100644 --- a/shine-UI/js/pages/device-view.js +++ b/shine-UI/js/pages/device-view.js @@ -1,4 +1,4 @@ -import { renderHeader } from '../components/header.js?v=20260403081123'; +import { renderHeader } from '../components/header.js?v=20260405171816'; import { authService, isSessionInvalidError, @@ -7,7 +7,7 @@ import { setAuthInfo, state, terminateCurrentSession, -} from '../state.js?v=20260403081123'; +} from '../state.js?v=20260405171816'; export const pageMeta = { id: 'device-view', title: 'Устройства' }; diff --git a/shine-UI/js/pages/entry-settings-view.js b/shine-UI/js/pages/entry-settings-view.js index d0ebde8..57f4234 100644 --- a/shine-UI/js/pages/entry-settings-view.js +++ b/shine-UI/js/pages/entry-settings-view.js @@ -1,5 +1,5 @@ -import { renderHeader } from '../components/header.js?v=20260403081123'; -import { checkServerAvailability, saveEntrySettings, state } from '../state.js?v=20260403081123'; +import { renderHeader } from '../components/header.js?v=20260405171816'; +import { checkServerAvailability, saveEntrySettings, state } from '../state.js?v=20260405171816'; export const pageMeta = { id: 'entry-settings-view', title: 'Настройки входа', showAppChrome: false }; diff --git a/shine-UI/js/pages/key-storage-view.js b/shine-UI/js/pages/key-storage-view.js index eed3ebd..627b08a 100644 --- a/shine-UI/js/pages/key-storage-view.js +++ b/shine-UI/js/pages/key-storage-view.js @@ -1,5 +1,5 @@ -import { renderHeader } from '../components/header.js?v=20260403081123'; -import { authorizeSession, state } from '../state.js?v=20260403081123'; +import { renderHeader } from '../components/header.js?v=20260405171816'; +import { authorizeSession, state } from '../state.js?v=20260405171816'; export const pageMeta = { id: 'key-storage-view', title: 'Какие ключи сохранить', showAppChrome: false }; diff --git a/shine-UI/js/pages/language-view.js b/shine-UI/js/pages/language-view.js index ada0b7b..b4d7d3c 100644 --- a/shine-UI/js/pages/language-view.js +++ b/shine-UI/js/pages/language-view.js @@ -1,5 +1,5 @@ -import { renderHeader } from '../components/header.js?v=20260403081123'; -import { state } from '../state.js?v=20260403081123'; +import { renderHeader } from '../components/header.js?v=20260405171816'; +import { state } from '../state.js?v=20260405171816'; export const pageMeta = { id: 'language-view', title: 'Язык' }; diff --git a/shine-UI/js/pages/login-camera-view.js b/shine-UI/js/pages/login-camera-view.js index 995a1c0..05f01d7 100644 --- a/shine-UI/js/pages/login-camera-view.js +++ b/shine-UI/js/pages/login-camera-view.js @@ -1,4 +1,4 @@ -import { renderHeader } from '../components/header.js?v=20260403081123'; +import { renderHeader } from '../components/header.js?v=20260405171816'; export const pageMeta = { id: 'login-camera-view', title: 'Войти по камере', showAppChrome: false }; diff --git a/shine-UI/js/pages/login-password-view.js b/shine-UI/js/pages/login-password-view.js index ddc5d07..5dd99e1 100644 --- a/shine-UI/js/pages/login-password-view.js +++ b/shine-UI/js/pages/login-password-view.js @@ -1,11 +1,11 @@ -import { renderHeader } from '../components/header.js?v=20260403081123'; +import { renderHeader } from '../components/header.js?v=20260405171816'; import { authService, clearAuthMessages, setAuthBusy, setAuthError, state, -} from '../state.js?v=20260403081123'; +} from '../state.js?v=20260405171816'; export const pageMeta = { id: 'login-password-view', title: 'Войти по логину', showAppChrome: false }; diff --git a/shine-UI/js/pages/login-view.js b/shine-UI/js/pages/login-view.js index 1a42045..1cfb7ac 100644 --- a/shine-UI/js/pages/login-view.js +++ b/shine-UI/js/pages/login-view.js @@ -1,4 +1,4 @@ -import { renderHeader } from '../components/header.js?v=20260405091124'; +import { renderHeader } from '../components/header.js?v=20260405171816'; export const pageMeta = { id: 'login-view', title: 'Войти', showAppChrome: false }; diff --git a/shine-UI/js/pages/messages-list.js b/shine-UI/js/pages/messages-list.js index 652cdd0..5ecf732 100644 --- a/shine-UI/js/pages/messages-list.js +++ b/shine-UI/js/pages/messages-list.js @@ -1,5 +1,5 @@ -import { renderHeader } from '../components/header.js?v=20260403081123'; -import { directMessages } from '../mock-data.js?v=20260403081123'; +import { renderHeader } from '../components/header.js?v=20260405171816'; +import { directMessages } from '../mock-data.js?v=20260405171816'; export const pageMeta = { id: 'messages-list', title: 'Личные сообщения' }; diff --git a/shine-UI/js/pages/network-view.js b/shine-UI/js/pages/network-view.js index fd30c3d..082be41 100644 --- a/shine-UI/js/pages/network-view.js +++ b/shine-UI/js/pages/network-view.js @@ -1,5 +1,5 @@ -import { renderHeader } from '../components/header.js?v=20260403081123'; -import { authService, state } from '../state.js?v=20260403081123'; +import { renderHeader } from '../components/header.js?v=20260405171816'; +import { authService, state } from '../state.js?v=20260405171816'; export const pageMeta = { id: 'network-view', title: 'Связи' }; diff --git a/shine-UI/js/pages/notifications-view.js b/shine-UI/js/pages/notifications-view.js index b85c974..430df94 100644 --- a/shine-UI/js/pages/notifications-view.js +++ b/shine-UI/js/pages/notifications-view.js @@ -1,6 +1,6 @@ -import { renderHeader } from '../components/header.js?v=20260403081123'; -import { notifications } from '../mock-data.js?v=20260403081123'; -import { state } from '../state.js?v=20260403081123'; +import { renderHeader } from '../components/header.js?v=20260405171816'; +import { notifications } from '../mock-data.js?v=20260405171816'; +import { state } from '../state.js?v=20260405171816'; export const pageMeta = { id: 'notifications-view', title: 'Уведомления' }; diff --git a/shine-UI/js/pages/profile-view.js b/shine-UI/js/pages/profile-view.js index c51a689..caf0e7e 100644 --- a/shine-UI/js/pages/profile-view.js +++ b/shine-UI/js/pages/profile-view.js @@ -1,6 +1,6 @@ -import { renderHeader } from '../components/header.js?v=20260403081123'; -import { profile } from '../mock-data.js?v=20260403081123'; -import { state } from '../state.js?v=20260403081123'; +import { renderHeader } from '../components/header.js?v=20260405171816'; +import { profile } from '../mock-data.js?v=20260405171816'; +import { state } from '../state.js?v=20260405171816'; export const pageMeta = { id: 'profile-view', title: 'Профиль' }; diff --git a/shine-UI/js/pages/register-view.js b/shine-UI/js/pages/register-view.js index d2bde99..dcf6e12 100644 --- a/shine-UI/js/pages/register-view.js +++ b/shine-UI/js/pages/register-view.js @@ -1,5 +1,5 @@ -import { renderHeader } from '../components/header.js?v=20260403081123'; -import { authService, clearAuthMessages, state } from '../state.js?v=20260403081123'; +import { renderHeader } from '../components/header.js?v=20260405171816'; +import { authService, clearAuthMessages, state } from '../state.js?v=20260405171816'; export const pageMeta = { id: 'register-view', title: 'Зарегистрироваться', showAppChrome: false }; diff --git a/shine-UI/js/pages/registration-keys-view.js b/shine-UI/js/pages/registration-keys-view.js index 83942fc..8f7a69c 100644 --- a/shine-UI/js/pages/registration-keys-view.js +++ b/shine-UI/js/pages/registration-keys-view.js @@ -1,4 +1,4 @@ -import { renderHeader } from '../components/header.js?v=20260403081123'; +import { renderHeader } from '../components/header.js?v=20260405171816'; import { authService, authorizeSession, @@ -6,7 +6,7 @@ import { setAuthError, setAuthInfo, state, -} from '../state.js?v=20260403081123'; +} from '../state.js?v=20260405171816'; export const pageMeta = { id: 'registration-keys-view', title: 'Сохранение ключей', showAppChrome: false }; diff --git a/shine-UI/js/pages/registration-payment-view.js b/shine-UI/js/pages/registration-payment-view.js index 3556c30..2f4a4f9 100644 --- a/shine-UI/js/pages/registration-payment-view.js +++ b/shine-UI/js/pages/registration-payment-view.js @@ -1,11 +1,11 @@ -import { renderHeader } from '../components/header.js?v=20260403081123'; +import { renderHeader } from '../components/header.js?v=20260405171816'; import { authService, refreshRegistrationBalance, setAuthError, setAuthInfo, state, -} from '../state.js?v=20260403081123'; +} from '../state.js?v=20260405171816'; export const pageMeta = { id: 'registration-payment-view', title: 'Оплата регистрации', showAppChrome: false }; diff --git a/shine-UI/js/pages/server-settings-view.js b/shine-UI/js/pages/server-settings-view.js index 6958539..a4d107a 100644 --- a/shine-UI/js/pages/server-settings-view.js +++ b/shine-UI/js/pages/server-settings-view.js @@ -1,5 +1,5 @@ -import { renderHeader } from '../components/header.js?v=20260403081123'; -import { checkServerAvailability, saveEntrySettings, state } from '../state.js?v=20260403081123'; +import { renderHeader } from '../components/header.js?v=20260405171816'; +import { checkServerAvailability, saveEntrySettings, state } from '../state.js?v=20260405171816'; export const pageMeta = { id: 'server-settings-view', title: 'Настройки серверов' }; diff --git a/shine-UI/js/pages/settings-view.js b/shine-UI/js/pages/settings-view.js index 11146e2..1813dd8 100644 --- a/shine-UI/js/pages/settings-view.js +++ b/shine-UI/js/pages/settings-view.js @@ -1,4 +1,4 @@ -import { renderHeader } from '../components/header.js?v=20260403081123'; +import { renderHeader } from '../components/header.js?v=20260405171816'; export const pageMeta = { id: 'settings-view', title: 'Настройки' }; diff --git a/shine-UI/js/pages/show-keys-view.js b/shine-UI/js/pages/show-keys-view.js index c3cf2dc..433c37f 100644 --- a/shine-UI/js/pages/show-keys-view.js +++ b/shine-UI/js/pages/show-keys-view.js @@ -1,6 +1,6 @@ -import { renderHeader } from '../components/header.js?v=20260403081123'; -import { state } from '../state.js?v=20260403081123'; -import { loadEncryptedUserSecrets } from '../services/key-vault.js?v=20260403081123'; +import { renderHeader } from '../components/header.js?v=20260405171816'; +import { state } from '../state.js?v=20260405171816'; +import { loadEncryptedUserSecrets } from '../services/key-vault.js?v=20260405171816'; export const pageMeta = { id: 'show-keys-view', title: 'Показать ключи' }; diff --git a/shine-UI/js/pages/start-view.js b/shine-UI/js/pages/start-view.js index cf4b295..32fb4e1 100644 --- a/shine-UI/js/pages/start-view.js +++ b/shine-UI/js/pages/start-view.js @@ -1,4 +1,4 @@ -import { clearStartHint, state } from '../state.js?v=20260403081123'; +import { clearStartHint, state } from '../state.js?v=20260405171816'; export const pageMeta = { id: 'start-view', title: 'Старт', showAppChrome: false }; diff --git a/shine-UI/js/pages/topup-view.js b/shine-UI/js/pages/topup-view.js index f1ea9c4..8414ceb 100644 --- a/shine-UI/js/pages/topup-view.js +++ b/shine-UI/js/pages/topup-view.js @@ -1,5 +1,5 @@ -import { renderHeader } from '../components/header.js?v=20260403081123'; -import { state } from '../state.js?v=20260403081123'; +import { renderHeader } from '../components/header.js?v=20260405171816'; +import { state } from '../state.js?v=20260405171816'; export const pageMeta = { id: 'topup-view', title: 'Пополнение счета', showAppChrome: false }; diff --git a/shine-UI/js/pages/wallet-view.js b/shine-UI/js/pages/wallet-view.js index ed98067..9233863 100644 --- a/shine-UI/js/pages/wallet-view.js +++ b/shine-UI/js/pages/wallet-view.js @@ -1,5 +1,5 @@ -import { renderHeader } from '../components/header.js?v=20260403081123'; -import { wallet } from '../mock-data.js?v=20260403081123'; +import { renderHeader } from '../components/header.js?v=20260405171816'; +import { wallet } from '../mock-data.js?v=20260405171816'; export const pageMeta = { id: 'wallet-view', title: 'Кошелёк' }; diff --git a/shine-UI/js/services/auth-service.js b/shine-UI/js/services/auth-service.js index bd2afb5..94ffd04 100644 --- a/shine-UI/js/services/auth-service.js +++ b/shine-UI/js/services/auth-service.js @@ -1,4 +1,4 @@ -import { WsJsonClient } from './ws-client.js?v=20260403081123'; +import { WsJsonClient } from './ws-client.js?v=20260405171816'; import { deriveEd25519FromPassword, exportEd25519PublicKeyB64, @@ -7,8 +7,8 @@ import { importPkcs8Ed25519, randomBase64, signBase64, -} from './crypto-utils.js?v=20260403081123'; -import { loadSessionMaterial, saveEncryptedUserSecrets, saveSessionMaterial } from './key-vault.js?v=20260403081123'; +} from './crypto-utils.js?v=20260405171816'; +import { loadSessionMaterial, saveEncryptedUserSecrets, saveSessionMaterial } from './key-vault.js?v=20260405171816'; const BCH_SUFFIX = '001'; diff --git a/shine-UI/js/services/key-vault.js b/shine-UI/js/services/key-vault.js index 7ed81b3..e41b8fe 100644 --- a/shine-UI/js/services/key-vault.js +++ b/shine-UI/js/services/key-vault.js @@ -1,7 +1,7 @@ import { decryptJsonWithStoragePwd, encryptJsonWithStoragePwd, -} from './crypto-utils.js?v=20260403081123'; +} from './crypto-utils.js?v=20260405171816'; const DB_NAME = 'shine-ui-auth'; const DB_VERSION = 1; diff --git a/shine-UI/js/services/ws-client.js b/shine-UI/js/services/ws-client.js index 559a6ff..90ad022 100644 --- a/shine-UI/js/services/ws-client.js +++ b/shine-UI/js/services/ws-client.js @@ -1,4 +1,4 @@ -import { captureClientError } from './client-error-reporter.js?v=20260403081123'; +import { captureClientError } from './client-error-reporter.js?v=20260405171816'; const DEFAULT_TIMEOUT_MS = 12000; diff --git a/shine-UI/js/state.js b/shine-UI/js/state.js index 84a874a..fb20698 100644 --- a/shine-UI/js/state.js +++ b/shine-UI/js/state.js @@ -1,6 +1,6 @@ -import { chatMessages, wallet } from './mock-data.js?v=20260403081123'; -import { AuthService } from './services/auth-service.js?v=20260403081123'; -import { clearClientAuthData } from './services/key-vault.js?v=20260403081123'; +import { chatMessages, wallet } from './mock-data.js?v=20260405171816'; +import { AuthService } from './services/auth-service.js?v=20260405171816'; +import { clearClientAuthData } from './services/key-vault.js?v=20260405171816'; const clone = (value) => JSON.parse(JSON.stringify(value)); const SESSION_STORAGE_KEY = 'shine-ui-current-session-v1'; diff --git a/shine-server-db/src/main/java/shine/db/dao/ActiveSessionsDAO.java b/shine-server-db/src/main/java/shine/db/dao/ActiveSessionsDAO.java index 9af6428..46ac9b9 100644 --- a/shine-server-db/src/main/java/shine/db/dao/ActiveSessionsDAO.java +++ b/shine-server-db/src/main/java/shine/db/dao/ActiveSessionsDAO.java @@ -129,7 +129,7 @@ public final class ActiveSessionsDAO { client_info_from_request, user_language FROM active_sessions - WHERE login = ? + WHERE login = ? COLLATE NOCASE """; List result = new ArrayList<>(); @@ -267,4 +267,4 @@ public final class ActiveSessionsDAO { userLanguage ); } -} \ No newline at end of file +} diff --git a/shine-server-db/src/main/java/shine/db/dao/UserParamsDAO.java b/shine-server-db/src/main/java/shine/db/dao/UserParamsDAO.java index 3611e8c..0cb87f2 100644 --- a/shine-server-db/src/main/java/shine/db/dao/UserParamsDAO.java +++ b/shine-server-db/src/main/java/shine/db/dao/UserParamsDAO.java @@ -89,7 +89,7 @@ public final class UserParamsDAO { device_key, signature FROM users_params - WHERE login = ? AND param = ? + WHERE login = ? COLLATE NOCASE AND param = ? LIMIT 1 """; @@ -120,7 +120,7 @@ public final class UserParamsDAO { device_key, signature FROM users_params - WHERE login = ? + WHERE login = ? COLLATE NOCASE ORDER BY time_ms DESC """; @@ -159,4 +159,4 @@ public final class UserParamsDAO { return e; } -} \ No newline at end of file +} diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/ActiveConnectionsRegistry.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/ActiveConnectionsRegistry.java index 29c3bf6..6387b23 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/ActiveConnectionsRegistry.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/ActiveConnectionsRegistry.java @@ -3,6 +3,7 @@ package server.logic.ws_protocol.JSON; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Locale; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; @@ -27,7 +28,7 @@ public final class ActiveConnectionsRegistry { // sessionId (String) -> ConnectionContext private final ConcurrentHashMap bySessionId = new ConcurrentHashMap<>(); - // login (String) -> множество ConnectionContext для этого пользователя + // lowercase(login) -> множество ConnectionContext для этого пользователя private final ConcurrentHashMap> byLogin = new ConcurrentHashMap<>(); /** @@ -50,11 +51,12 @@ public final class ActiveConnectionsRegistry { if (prev != null && prev != ctx) { String prevLogin = prev.getLogin(); if (prevLogin != null && !prevLogin.isBlank()) { - Set prevSet = byLogin.get(prevLogin); + String prevKey = toLoginKey(prevLogin); + Set prevSet = byLogin.get(prevKey); if (prevSet != null) { prevSet.remove(prev); if (prevSet.isEmpty()) { - byLogin.remove(prevLogin); + byLogin.remove(prevKey); } } } @@ -63,7 +65,7 @@ public final class ActiveConnectionsRegistry { } byLogin - .computeIfAbsent(login, id -> new CopyOnWriteArraySet<>()) + .computeIfAbsent(toLoginKey(login), id -> new CopyOnWriteArraySet<>()) .add(ctx); log.debug("registered ctx (login={}, sessionId={})", login, sessionId); @@ -89,11 +91,12 @@ public final class ActiveConnectionsRegistry { } if (login != null && !login.isBlank()) { - Set set = byLogin.get(login); + String key = toLoginKey(login); + Set set = byLogin.get(key); if (set != null) { set.remove(ctx); if (set.isEmpty()) { - byLogin.remove(login); + byLogin.remove(key); } } } @@ -112,11 +115,12 @@ public final class ActiveConnectionsRegistry { String login = ctx.getLogin(); if (login != null && !login.isBlank()) { - Set set = byLogin.get(login); + String key = toLoginKey(login); + Set set = byLogin.get(key); if (set != null) { set.remove(ctx); if (set.isEmpty()) { - byLogin.remove(login); + byLogin.remove(key); } } } @@ -137,7 +141,11 @@ public final class ActiveConnectionsRegistry { */ public Set getByLogin(String login) { if (login == null || login.isBlank()) return Set.of(); - Set set = byLogin.get(login); + Set set = byLogin.get(toLoginKey(login)); return (set == null) ? Set.of() : set; // CopyOnWriteArraySet можно отдавать как есть } -} \ No newline at end of file + + private static String toLoginKey(String login) { + return login.trim().toLowerCase(Locale.ROOT); + } +} diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_CreateAuthSession__Handler.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_CreateAuthSession__Handler.java index 6241f38..947a6a2 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_CreateAuthSession__Handler.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/auth/Net_CreateAuthSession__Handler.java @@ -75,8 +75,8 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler { SolanaUserEntry userFromContext = ctx.getSolanaUser(); String loginFromContext = userFromContext.getLogin(); - String login = req.getLogin(); - if (login == null || login.isBlank()) { + String loginFromReq = req.getLogin(); + if (loginFromReq == null || loginFromReq.isBlank()) { Net_Response err = NetExceptionResponseFactory.error( req, WireCodes.Status.BAD_REQUEST, @@ -86,7 +86,8 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler { closeConnectionAfterErrorResponse(ctx, 4001, "Auth failed: empty login"); return err; } - if (!login.equals(loginFromContext)) { + loginFromReq = loginFromReq.trim(); + if (!loginFromReq.equalsIgnoreCase(loginFromContext)) { Net_Response err = NetExceptionResponseFactory.error( req, WireCodes.Status.BAD_REQUEST, @@ -99,7 +100,7 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler { SolanaUserEntry user; try { - user = SolanaUsersDAO.getInstance().getByLogin(login); + user = SolanaUsersDAO.getInstance().getByLogin(loginFromContext); } catch (SQLException e) { Net_Response err = NetExceptionResponseFactory.error( req, @@ -121,7 +122,8 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler { return err; } - if (login == null || login.isBlank()) { + String canonicalLogin = user.getLogin(); + if (canonicalLogin == null || canonicalLogin.isBlank()) { Net_Response err = NetExceptionResponseFactory.error( req, WireCodes.Status.SERVER_DATA_ERROR, @@ -273,7 +275,7 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler { boolean sigOk; try { sigOk = verifyCreateSessionSignature( - login, + loginFromReq, sessionKey, storagePwd, authNonce, @@ -342,7 +344,7 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler { try { activeSessionEntry = new ActiveSessionEntry( sessionId, - login, + canonicalLogin, sessionKey, // session_key (pubkey string as-is) storagePwd, now, @@ -358,7 +360,7 @@ public class Net_CreateAuthSession__Handler implements JsonMessageHandler { dao.insert(activeSessionEntry); } catch (SQLException e) { - log.error("Ошибка БД при создании новой сессии для login={}", login, e); + log.error("Ошибка БД при создании новой сессии для login={}", canonicalLogin, e); Net_Response err = NetExceptionResponseFactory.error( req, WireCodes.Status.SERVER_DATA_ERROR, diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/connections/Net_AddCloseFriend_Handler.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/connections/Net_AddCloseFriend_Handler.java index 3cfe34f..93d7ae0 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/connections/Net_AddCloseFriend_Handler.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/connections/Net_AddCloseFriend_Handler.java @@ -74,7 +74,7 @@ public class Net_AddCloseFriend_Handler implements JsonMessageHandler { } private String findPrimaryBlockchain(Connection c, String login) throws Exception { - String sql = "SELECT blockchain_name FROM blockchain_state WHERE login=? ORDER BY blockchain_name LIMIT 1"; + String sql = "SELECT blockchain_name FROM blockchain_state WHERE login = ? COLLATE NOCASE ORDER BY blockchain_name LIMIT 1"; try (PreparedStatement ps = c.prepareStatement(sql)) { ps.setString(1, login); try (ResultSet rs = ps.executeQuery()) { diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/connections/Net_GetUserConnectionsGraph_Handler.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/connections/Net_GetUserConnectionsGraph_Handler.java index 837de68..b0e1d42 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/connections/Net_GetUserConnectionsGraph_Handler.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/connections/Net_GetUserConnectionsGraph_Handler.java @@ -12,6 +12,8 @@ import shine.db.MsgSubType; import shine.db.dao.ConnectionsStateDAO; import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; import java.util.List; public class Net_GetUserConnectionsGraph_Handler implements JsonMessageHandler { @@ -21,20 +23,35 @@ public class Net_GetUserConnectionsGraph_Handler implements JsonMessageHandler { if (ctx == null || !ctx.isAuthenticatedUser()) { return NetExceptionResponseFactory.error(req, WireCodes.Status.UNVERIFIED, "NOT_AUTHENTICATED", "Требуется авторизация"); } - String login = (req.getLogin() == null || req.getLogin().isBlank()) ? ctx.getLogin() : req.getLogin().trim(); + String requestedLogin = (req.getLogin() == null || req.getLogin().isBlank()) ? ctx.getLogin() : req.getLogin().trim(); try (Connection c = shine.db.SqliteDbController.getInstance().getConnection()) { - List out = ConnectionsStateDAO.getInstance().listOutgoingByRelTypeCanonical(c, login, MsgSubType.CONNECTION_FRIEND); - List in = ConnectionsStateDAO.getInstance().listIncomingByRelTypeCanonical(c, login, MsgSubType.CONNECTION_FRIEND); + String canonicalLogin = findCanonicalLogin(c, requestedLogin); + if (canonicalLogin == null) { + return NetExceptionResponseFactory.error(req, 404, "USER_NOT_FOUND", "Пользователь не найден"); + } + + List out = ConnectionsStateDAO.getInstance().listOutgoingByRelTypeCanonical(c, canonicalLogin, MsgSubType.CONNECTION_FRIEND); + List in = ConnectionsStateDAO.getInstance().listIncomingByRelTypeCanonical(c, canonicalLogin, MsgSubType.CONNECTION_FRIEND); Net_GetUserConnectionsGraph_Response resp = new Net_GetUserConnectionsGraph_Response(); resp.setOp(req.getOp()); resp.setRequestId(req.getRequestId()); resp.setStatus(WireCodes.Status.OK); - resp.setLogin(login); + resp.setLogin(canonicalLogin); resp.setOutFriends(out); resp.setInFriends(in); return resp; } } + + private String findCanonicalLogin(Connection c, String loginAnyCase) throws Exception { + String sql = "SELECT login FROM solana_users WHERE login = ? COLLATE NOCASE LIMIT 1"; + try (PreparedStatement ps = c.prepareStatement(sql)) { + ps.setString(1, loginAnyCase); + try (ResultSet rs = ps.executeQuery()) { + return rs.next() ? rs.getString("login") : null; + } + } + } } diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/userParams/Net_ListUserParams_Handler.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/userParams/Net_ListUserParams_Handler.java index b97584c..c70c79f 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/userParams/Net_ListUserParams_Handler.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/userParams/Net_ListUserParams_Handler.java @@ -11,7 +11,9 @@ import server.logic.ws_protocol.JSON.handlers.userParams.entyties.Net_ListUserPa import server.logic.ws_protocol.JSON.utils.NetExceptionResponseFactory; import server.logic.ws_protocol.WireCodes; import shine.db.SqliteDbController; +import shine.db.dao.SolanaUsersDAO; import shine.db.dao.UserParamsDAO; +import shine.db.entities.SolanaUserEntry; import shine.db.entities.UserParamEntry; import java.sql.Connection; @@ -61,7 +63,8 @@ public class Net_ListUserParams_Handler implements JsonMessageHandler { resp.setRequestId(req.getRequestId()); resp.setStatus(WireCodes.Status.OK); - resp.setLogin(login); + SolanaUserEntry user = SolanaUsersDAO.getInstance().getByLogin(login); + resp.setLogin(user != null && user.getLogin() != null ? user.getLogin() : login); List items = new ArrayList<>(); for (UserParamEntry e : entries) { diff --git a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/messages/Net_SendDirectMessage_Handler.java b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/messages/Net_SendDirectMessage_Handler.java index 12c1bb8..7b021a3 100644 --- a/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/messages/Net_SendDirectMessage_Handler.java +++ b/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/messages/Net_SendDirectMessage_Handler.java @@ -16,8 +16,10 @@ import server.logic.ws_protocol.JSON.utils.NetIdGenerator; import server.logic.ws_protocol.WireCodes; import shine.db.dao.DirectMessagesDAO; import shine.db.dao.PushTokensDAO; +import shine.db.dao.SolanaUsersDAO; import shine.db.entities.DirectMessageEntry; import shine.db.entities.PushTokenEntry; +import shine.db.entities.SolanaUserEntry; import java.util.HashSet; import java.util.List; @@ -39,9 +41,15 @@ public class Net_SendDirectMessage_Handler implements JsonMessageHandler { } String from = ctx.getLogin(); - String to = req.getToLogin().trim(); + String toRequest = req.getToLogin().trim(); String text = req.getText().trim(); + SolanaUserEntry targetUser = SolanaUsersDAO.getInstance().getByLogin(toRequest); + if (targetUser == null) { + return NetExceptionResponseFactory.error(req, 404, "USER_NOT_FOUND", "Пользователь не найден"); + } + String to = targetUser.getLogin(); + if (!canSend(from, to)) { return NetExceptionResponseFactory.error(req, WireCodes.Status.UNVERIFIED, "NO_PERMISSION", "Можно писать только контактам или тем, кто уже писал вам"); } @@ -120,4 +128,3 @@ public class Net_SendDirectMessage_Handler implements JsonMessageHandler { return from != null && !from.isBlank() && to != null && !to.isBlank(); } } -