SHA256
TrustedDeviceLogin API и настройки входа через устройство
Что сделано:\n- публичный API сценария входа через доверенное устройство переведён на TrustedDeviceLogin\n- добавлен GetTrustedDeviceLoginSettings\n- отсутствие записи настроек на сервере теперь трактуется как enabled=true и hasPassword=false\n- ttlSeconds убран из клиентского API, TTL заявки фиксирован на сервере: 300 секунд\n- в shine-UI добавлен отдельный экран настроек входа через устройство и статус на основном экране\n- browser wallet переведён на новые TrustedDeviceLogin операции\n- в wallet добавлен выбор rootKey/deviceKey для будущего запроса подписи\n- документация API обновлена\n\nЧто ещё не проверено вручную end-to-end:\n- полный сценарий UI/plugin после этого деплоя не прогонялся руками до конца\n- сам signaling подписи в wallet всё ещё не реализован
This commit is contained in:
@@ -1091,17 +1091,22 @@ export class AuthService {
|
||||
if (response.status !== 200) throw opError('CloseActiveSession', response);
|
||||
}
|
||||
|
||||
async upsertEspPairingSettings({ enabled, passwordHash = '', ttlSeconds = 180 }) {
|
||||
const response = await this.ws.request('UpsertEspPairingSettings', {
|
||||
enabled: !!enabled,
|
||||
passwordHash: String(passwordHash || '').trim(),
|
||||
ttlSeconds: Number(ttlSeconds) || 180,
|
||||
});
|
||||
if (response.status !== 200) throw opError('UpsertEspPairingSettings', response);
|
||||
async getTrustedDeviceLoginSettings() {
|
||||
const response = await this.ws.request('GetTrustedDeviceLoginSettings', {});
|
||||
if (response.status !== 200) throw opError('GetTrustedDeviceLoginSettings', response);
|
||||
return response.payload || {};
|
||||
}
|
||||
|
||||
async startEspPairing({
|
||||
async upsertTrustedDeviceLoginSettings({ enabled, passwordHash = '' }) {
|
||||
const response = await this.ws.request('UpsertTrustedDeviceLoginSettings', {
|
||||
enabled: !!enabled,
|
||||
passwordHash: String(passwordHash || '').trim(),
|
||||
});
|
||||
if (response.status !== 200) throw opError('UpsertTrustedDeviceLoginSettings', response);
|
||||
return response.payload || {};
|
||||
}
|
||||
|
||||
async startTrustedDeviceLogin({
|
||||
login,
|
||||
passwordHash,
|
||||
requesterSessionKey,
|
||||
@@ -1109,7 +1114,7 @@ export class AuthService {
|
||||
requesterClientPlatform = makeClientPlatform(),
|
||||
payloadType = 3,
|
||||
}) {
|
||||
const response = await this.ws.request('StartEspPairing', {
|
||||
const response = await this.ws.request('StartTrustedDeviceLogin', {
|
||||
login: String(login || '').trim(),
|
||||
passwordHash: String(passwordHash || '').trim(),
|
||||
requesterSessionKey: String(requesterSessionKey || '').trim(),
|
||||
@@ -1117,51 +1122,59 @@ export class AuthService {
|
||||
requesterClientPlatform: String(requesterClientPlatform || '').trim() || makeClientPlatform(),
|
||||
payloadType: Number(payloadType) || 3,
|
||||
});
|
||||
if (response.status !== 200) throw opError('StartEspPairing', response);
|
||||
if (response.status !== 200) throw opError('StartTrustedDeviceLogin', response);
|
||||
return response.payload || {};
|
||||
}
|
||||
|
||||
async listEspPairingRequests() {
|
||||
const response = await this.ws.request('ListEspPairingRequests', {});
|
||||
if (response.status !== 200) throw opError('ListEspPairingRequests', response);
|
||||
async listTrustedDeviceLoginRequests() {
|
||||
const response = await this.ws.request('ListTrustedDeviceLoginRequests', {});
|
||||
if (response.status !== 200) throw opError('ListTrustedDeviceLoginRequests', response);
|
||||
return Array.isArray(response?.payload?.requests) ? response.payload.requests : [];
|
||||
}
|
||||
|
||||
async approveEspPairing(pairingId, encryptedPayload) {
|
||||
const response = await this.ws.request('ApproveEspPairing', {
|
||||
async approveTrustedDeviceLogin(pairingId, encryptedPayload) {
|
||||
const response = await this.ws.request('ApproveTrustedDeviceLogin', {
|
||||
pairingId: String(pairingId || '').trim(),
|
||||
encryptedPayload: String(encryptedPayload || '').trim(),
|
||||
});
|
||||
if (response.status !== 200) throw opError('ApproveEspPairing', response);
|
||||
if (response.status !== 200) throw opError('ApproveTrustedDeviceLogin', response);
|
||||
return response.payload || {};
|
||||
}
|
||||
|
||||
async rejectEspPairing(pairingId, reason = '') {
|
||||
const response = await this.ws.request('RejectEspPairing', {
|
||||
async rejectTrustedDeviceLogin(pairingId, reason = '') {
|
||||
const response = await this.ws.request('RejectTrustedDeviceLogin', {
|
||||
pairingId: String(pairingId || '').trim(),
|
||||
reason: String(reason || '').trim(),
|
||||
});
|
||||
if (response.status !== 200) throw opError('RejectEspPairing', response);
|
||||
if (response.status !== 200) throw opError('RejectTrustedDeviceLogin', response);
|
||||
return response.payload || {};
|
||||
}
|
||||
|
||||
async cancelEspPairing(pairingId, requesterSessionKey) {
|
||||
const response = await this.ws.request('CancelEspPairing', {
|
||||
async cancelTrustedDeviceLogin(pairingId, requesterSessionKey) {
|
||||
const response = await this.ws.request('CancelTrustedDeviceLogin', {
|
||||
pairingId: String(pairingId || '').trim(),
|
||||
requesterSessionKey: String(requesterSessionKey || '').trim(),
|
||||
});
|
||||
if (response.status !== 200) throw opError('CancelEspPairing', response);
|
||||
if (response.status !== 200) throw opError('CancelTrustedDeviceLogin', response);
|
||||
return response.payload || {};
|
||||
}
|
||||
|
||||
async getEspPairingStatus(pairingId) {
|
||||
const response = await this.ws.request('GetEspPairingStatus', {
|
||||
async getTrustedDeviceLoginStatus(pairingId) {
|
||||
const response = await this.ws.request('GetTrustedDeviceLoginStatus', {
|
||||
pairingId: String(pairingId || '').trim(),
|
||||
});
|
||||
if (response.status !== 200) throw opError('GetEspPairingStatus', response);
|
||||
if (response.status !== 200) throw opError('GetTrustedDeviceLoginStatus', response);
|
||||
return response.payload || {};
|
||||
}
|
||||
|
||||
async upsertEspPairingSettings(args) { return this.upsertTrustedDeviceLoginSettings(args); }
|
||||
async startEspPairing(args) { return this.startTrustedDeviceLogin(args); }
|
||||
async listEspPairingRequests() { return this.listTrustedDeviceLoginRequests(); }
|
||||
async approveEspPairing(pairingId, encryptedPayload) { return this.approveTrustedDeviceLogin(pairingId, encryptedPayload); }
|
||||
async rejectEspPairing(pairingId, reason = '') { return this.rejectTrustedDeviceLogin(pairingId, reason); }
|
||||
async cancelEspPairing(pairingId, requesterSessionKey) { return this.cancelTrustedDeviceLogin(pairingId, requesterSessionKey); }
|
||||
async getEspPairingStatus(pairingId) { return this.getTrustedDeviceLoginStatus(pairingId); }
|
||||
|
||||
async listSubscriptionsFeed(login, limit = 200) {
|
||||
const response = await this.ws.request('ListSubscriptionsFeed', { login, limit });
|
||||
if (response.status !== 200) throw opError('ListSubscriptionsFeed', response);
|
||||
|
||||
@@ -811,13 +811,13 @@ async function createShineUserPdaOnSolana({
|
||||
};
|
||||
}
|
||||
|
||||
export async function registerUserOnSolana({ login, keyBundle, solanaEndpoint }) {
|
||||
export async function registerUserOnSolana({ login, keyBundle, solanaEndpoint, accessServers = [] }) {
|
||||
return createShineUserPdaOnSolana({
|
||||
login,
|
||||
keyBundle,
|
||||
solanaEndpoint,
|
||||
isServer: false,
|
||||
accessServers: ['shineup.me'],
|
||||
accessServers: Array.isArray(accessServers) ? accessServers : [],
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -138,6 +138,6 @@ export async function checkLoginExistsOnSolana({ login, solanaEndpoint }) {
|
||||
return { exists: !!ai, userPda: userPda.toBase58() };
|
||||
}
|
||||
|
||||
export async function registerUserOnSolana({ login, keyBundle, solanaEndpoint }) {
|
||||
return registerUserOnSolanaShared({ login, keyBundle, solanaEndpoint });
|
||||
export async function registerUserOnSolana({ login, keyBundle, solanaEndpoint, accessServers }) {
|
||||
return registerUserOnSolanaShared({ login, keyBundle, solanaEndpoint, accessServers });
|
||||
}
|
||||
|
||||
@@ -54,6 +54,10 @@ export function toUserMessage(error, fallback = 'Действие не выпо
|
||||
return 'К сожалению сейчас нет ни одного активного устройства этого пользователя, подключенного к этому серверу в сети, и поэтому вход таким образом выполнить невозможно.';
|
||||
}
|
||||
|
||||
if (code === 'PAIRING_NOT_AVAILABLE') {
|
||||
return 'Для этого логина ещё не включено подключение по коду. На доверенном устройстве откройте «Подключить по коду» и нажмите «Включить подключение по коду» или задайте дополнительный пароль.';
|
||||
}
|
||||
|
||||
if (code === 'PAIRING_PASSWORD_INVALID') {
|
||||
return 'Пароль подключения не подходит.';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user