Добавить user_settings и синхронизацию настроек

This commit is contained in:
AidarKC
2026-08-19 19:45:09 +04:00
parent fac166f186
commit 6a5c20a165
37 changed files with 2079 additions and 3 deletions
+57
View File
@@ -153,6 +153,10 @@ function makeClientPlatform() {
return 'Web';
}
function escapeUserSettingPart(value = '') {
return String(value ?? '').replace(/\\/g, '\\\\').replace(/\|/g, '\\|');
}
function hexToBytes(hex) {
const clean = String(hex || '').trim().toLowerCase();
if (!clean || clean.length % 2 !== 0) throw new Error('Некорректный hex');
@@ -2898,6 +2902,59 @@ export class AuthService {
return response.payload || {};
}
async upsertUserSetting({
login,
settingType,
settingKey,
timeMs,
valueText = '',
valueNum = 0,
storagePwd,
syncDelivery = false,
}) {
const cleanLogin = String(login || '').trim();
const cleanSettingKey = String(settingKey || '').trim();
const cleanValueText = String(valueText ?? '');
const cleanTimeMs = Number(timeMs);
const cleanSettingType = Number(settingType);
const cleanValueNum = Number(valueNum ?? 0);
if (!cleanLogin || !cleanSettingKey) throw new Error('Не переданы login/settingKey');
if (!Number.isFinite(cleanTimeMs) || cleanTimeMs <= 0) throw new Error('Не передан корректный timeMs');
if (!Number.isFinite(cleanSettingType)) throw new Error('Не передан корректный settingType');
if (!storagePwd) throw new Error('Не передан storagePwd для подписи UpsertUserSetting.');
const secrets = await loadEncryptedUserSecrets(cleanLogin, storagePwd);
const clientPrivPkcs8 = String(secrets?.clientKey || '').trim();
if (!clientPrivPkcs8) throw new Error('Не найден приватный clientKey');
const privateKey = await importPkcs8Ed25519(clientPrivPkcs8);
const clientKey = await publicKeyB64FromPkcs8Ed25519(clientPrivPkcs8);
const preimage = [
'SHiNe/UserSettings:',
escapeUserSettingPart(cleanLogin),
String(cleanSettingType),
escapeUserSettingPart(cleanSettingKey),
String(Math.trunc(cleanTimeMs)),
escapeUserSettingPart(cleanValueText),
String(Math.trunc(cleanValueNum)),
].join('|');
const signature = await signBase64(privateKey, preimage);
const response = await this.ws.request('UpsertUserSetting', {
login: cleanLogin,
setting_type: Math.trunc(cleanSettingType),
setting_key: cleanSettingKey,
time_ms: Math.trunc(cleanTimeMs),
value_text: cleanValueText,
value_num: Math.trunc(cleanValueNum),
client_key: clientKey,
signature,
sync_delivery: !!syncDelivery,
});
if (response.status !== 200) throw opError('UpsertUserSetting', response);
return response.payload || {};
}
async getTestFreeAvatarQuota() {
const response = await this.ws.request('TestGetFreeAvatarQuota', {});
if (response.status !== 200) throw opError('TestGetFreeAvatarQuota', response);