mirror of
https://github.com/ezhevita/YandexKeyExtractor
synced 2025-08-16 19:40:48 +07:00
Compare commits
8 Commits
1.1
...
a57d22a993
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a57d22a993 | ||
|
|
003c0609e3 | ||
|
|
ce705b635c | ||
|
|
b9fa61f7c9 | ||
|
|
84f40a86ac | ||
|
|
06b7413247 | ||
|
|
72b9b1031b | ||
|
|
e83a9fbe3d |
8
.github/workflows/dotnet.yml
vendored
8
.github/workflows/dotnet.yml
vendored
@@ -3,13 +3,13 @@ name: .NET
|
|||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
env:
|
env:
|
||||||
DOTNET_SDK_VERSION: 6.0.x
|
DOTNET_SDK_VERSION: 8.0.x
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
uses: actions/setup-dotnet@v4
|
uses: actions/setup-dotnet@v4
|
||||||
with:
|
with:
|
||||||
@@ -36,13 +36,13 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Download generic artifacts
|
- name: Download generic artifacts
|
||||||
uses: actions/download-artifact@v4.1.8
|
uses: actions/download-artifact@v4.2.1
|
||||||
with:
|
with:
|
||||||
name: ${{ github.event.repository.name }}
|
name: ${{ github.event.repository.name }}
|
||||||
path: out/${{ github.event.repository.name }}
|
path: out/${{ github.event.repository.name }}
|
||||||
|
|
||||||
- name: Download Windows artifacts
|
- name: Download Windows artifacts
|
||||||
uses: actions/download-artifact@v4.1.8
|
uses: actions/download-artifact@v4.2.1
|
||||||
with:
|
with:
|
||||||
name: ${{ github.event.repository.name }}-Windows
|
name: ${{ github.event.repository.name }}-Windows
|
||||||
path: out/${{ github.event.repository.name }}-Windows
|
path: out/${{ github.event.repository.name }}-Windows
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# 🔑 Yandex.Key Extractor
|
# 🔑 Yandex.Key Extractor
|
||||||
## 🇺🇸 Extracts TOTP authenticators from [Yandex.Key](https://play.google.com/store/apps/details?id=ru.yandex.key&hl=en&gl=US) app
|
## [EN] Extracts TOTP authenticators from [Yandex.Key](https://play.google.com/store/apps/details?id=ru.yandex.key&hl=en&gl=US) app
|
||||||
|
|
||||||
### How to use?
|
### How to use?
|
||||||
1. Create a cloud backup in the app settings using your device.
|
1. Create a cloud backup in the app settings using your device.
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
4. TOTP links will be saved in `results.txt`.<br>Use QR code generator to import to another TOTP app or just extract secrets (e.g. for [Bitwarden](https://bitwarden.com/) import).
|
4. TOTP links will be saved in `results.txt`.<br>Use QR code generator to import to another TOTP app or just extract secrets (e.g. for [Bitwarden](https://bitwarden.com/) import).
|
||||||
|
|
||||||
---
|
---
|
||||||
## 🇷🇺 Извлечение двухфакторных аутентификаторов из [Яндекс.Ключ](https://play.google.com/store/apps/details?id=ru.yandex.key&hl=ru&gl=RU)
|
## [RU] Извлечение двухфакторных аутентификаторов из [Яндекс.Ключ](https://play.google.com/store/apps/details?id=ru.yandex.key&hl=ru&gl=RU)
|
||||||
|
|
||||||
### Как использовать?
|
### Как использовать?
|
||||||
1. Создайте облачную резервную копию в настройках приложения с вашего устройства.
|
1. Создайте облачную резервную копию в настройках приложения с вашего устройства.
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ using System.Net.Http;
|
|||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Net.Http.Json;
|
using System.Net.Http.Json;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text.Json;
|
using System.Text.Json.Serialization.Metadata;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using YandexKeyExtractor.Exceptions;
|
using YandexKeyExtractor.Exceptions;
|
||||||
using YandexKeyExtractor.Models;
|
using YandexKeyExtractor.Models;
|
||||||
@@ -21,25 +21,22 @@ public sealed class WebHandler : IDisposable
|
|||||||
BaseAddress = new Uri("https://registrator.mobile.yandex.net/1/")
|
BaseAddress = new Uri("https://registrator.mobile.yandex.net/1/")
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly JsonSerializerOptions _jsonSettings = new()
|
|
||||||
{
|
|
||||||
TypeInfoResolver = SourceGenerationContext.Default
|
|
||||||
};
|
|
||||||
|
|
||||||
public async Task CheckCode(string smsCode, string trackID)
|
public async Task CheckCode(string smsCode, string trackID)
|
||||||
{
|
{
|
||||||
var checkCodeResponse = await PostUrlEncodedAndReceiveJson<StatusResponse>(
|
var checkCodeResponse = await PostUrlEncodedAndReceiveJson(
|
||||||
new Uri("bundle/yakey_backup/check_code/", UriKind.Relative),
|
new Uri("bundle/yakey_backup/check_code/", UriKind.Relative),
|
||||||
new Dictionary<string, string>(2) {["code"] = smsCode, ["track_id"] = trackID});
|
new Dictionary<string, string>(2) {["code"] = smsCode, ["track_id"] = trackID},
|
||||||
|
static context => context.StatusResponse);
|
||||||
|
|
||||||
ValidateResponse(checkCodeResponse);
|
ValidateResponse(checkCodeResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> GetBackupData(string phone, string trackID)
|
public async Task<string> GetBackupData(string phone, string trackID)
|
||||||
{
|
{
|
||||||
var backupResponse = await PostUrlEncodedAndReceiveJson<BackupResponse>(
|
var backupResponse = await PostUrlEncodedAndReceiveJson(
|
||||||
new Uri("bundle/yakey_backup/download", UriKind.Relative),
|
new Uri("bundle/yakey_backup/download", UriKind.Relative),
|
||||||
new Dictionary<string, string>(2) {["number"] = phone, ["track_id"] = trackID});
|
new Dictionary<string, string>(2) {["number"] = phone, ["track_id"] = trackID},
|
||||||
|
static context => context.BackupResponse);
|
||||||
|
|
||||||
ValidateResponse(backupResponse);
|
ValidateResponse(backupResponse);
|
||||||
|
|
||||||
@@ -55,7 +52,8 @@ public sealed class WebHandler : IDisposable
|
|||||||
{
|
{
|
||||||
var phoneNumberResponse = await PostUrlEncodedAndReceiveJson<PhoneNumberResponse>(
|
var phoneNumberResponse = await PostUrlEncodedAndReceiveJson<PhoneNumberResponse>(
|
||||||
new Uri("bundle/validate/phone_number/", UriKind.Relative),
|
new Uri("bundle/validate/phone_number/", UriKind.Relative),
|
||||||
new Dictionary<string, string>(2) {["phone_number"] = phoneNumber, ["country"] = country});
|
new Dictionary<string, string>(2) {["phone_number"] = phoneNumber, ["country"] = country},
|
||||||
|
static context => context.PhoneNumberResponse);
|
||||||
|
|
||||||
var phone = phoneNumberResponse?.PhoneNumber?.StandardizedNumber ?? $"+{phoneNumber}";
|
var phone = phoneNumberResponse?.PhoneNumber?.StandardizedNumber ?? $"+{phoneNumber}";
|
||||||
|
|
||||||
@@ -64,9 +62,10 @@ public sealed class WebHandler : IDisposable
|
|||||||
|
|
||||||
public async Task<string> SendSMSCodeAndGetTrackID(string phone, string country)
|
public async Task<string> SendSMSCodeAndGetTrackID(string phone, string country)
|
||||||
{
|
{
|
||||||
var trackResponse = await PostUrlEncodedAndReceiveJson<TrackResponse>(
|
var trackResponse = await PostUrlEncodedAndReceiveJson(
|
||||||
new Uri("bundle/yakey_backup/send_code/", UriKind.Relative),
|
new Uri("bundle/yakey_backup/send_code/", UriKind.Relative),
|
||||||
new Dictionary<string, string>(3) {["display_language"] = "en", ["number"] = phone, ["country"] = country});
|
new Dictionary<string, string>(3) {["display_language"] = "en", ["number"] = phone, ["country"] = country},
|
||||||
|
static context => context.TrackResponse);
|
||||||
|
|
||||||
ValidateResponse(trackResponse);
|
ValidateResponse(trackResponse);
|
||||||
|
|
||||||
@@ -81,16 +80,18 @@ public sealed class WebHandler : IDisposable
|
|||||||
|
|
||||||
public async Task<string?> TryGetCountry()
|
public async Task<string?> TryGetCountry()
|
||||||
{
|
{
|
||||||
var countryResponse = await _client.GetFromJsonAsync<CountryResponse>(new Uri("suggest/country", UriKind.Relative));
|
var countryResponse = await _client.GetFromJsonAsync(
|
||||||
|
new Uri("suggest/country", UriKind.Relative), SourceGenerationContext.Default.CountryResponse);
|
||||||
|
|
||||||
return countryResponse?.Country?.FirstOrDefault();
|
return countryResponse?.Country?.FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ValidateBackupInfo(string phone, string trackID, string country)
|
public async Task ValidateBackupInfo(string phone, string trackID, string country)
|
||||||
{
|
{
|
||||||
var backupInfoResponse = await PostUrlEncodedAndReceiveJson<BackupInfoResponse>(
|
var backupInfoResponse = await PostUrlEncodedAndReceiveJson(
|
||||||
new Uri("bundle/yakey_backup/info/", UriKind.Relative),
|
new Uri("bundle/yakey_backup/info/", UriKind.Relative),
|
||||||
new Dictionary<string, string>(3) {["number"] = phone, ["track_id"] = trackID, ["country"] = country});
|
new Dictionary<string, string>(3) {["number"] = phone, ["track_id"] = trackID, ["country"] = country},
|
||||||
|
static context => context.BackupInfoResponse);
|
||||||
|
|
||||||
ValidateResponse(backupInfoResponse);
|
ValidateResponse(backupInfoResponse);
|
||||||
|
|
||||||
@@ -100,13 +101,14 @@ public sealed class WebHandler : IDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<T?> PostUrlEncodedAndReceiveJson<T>(Uri url, Dictionary<string, string> data)
|
private async Task<T?> PostUrlEncodedAndReceiveJson<T>(Uri url, Dictionary<string, string> data,
|
||||||
|
Func<SourceGenerationContext, JsonTypeInfo<T>> typeInfoProvider)
|
||||||
{
|
{
|
||||||
using var content = new FormUrlEncodedContent(data);
|
using var content = new FormUrlEncodedContent(data);
|
||||||
using var responseMessage = await _client.PostAsync(url, content);
|
using var responseMessage = await _client.PostAsync(url, content);
|
||||||
responseMessage.EnsureSuccessStatusCode();
|
responseMessage.EnsureSuccessStatusCode();
|
||||||
|
|
||||||
return (await responseMessage.Content.ReadFromJsonAsync<T>(_jsonSettings))!;
|
return (await responseMessage.Content.ReadFromJsonAsync(typeInfoProvider(SourceGenerationContext.Default)))!;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ValidateResponse<T>([NotNull] T? response,
|
private static void ValidateResponse<T>([NotNull] T? response,
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
|
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
|
||||||
<AssemblyVersion>1.1.0</AssemblyVersion>
|
<AssemblyVersion>1.1.1</AssemblyVersion>
|
||||||
<FileVersion>1.1.0</FileVersion>
|
<FileVersion>1.1.1</FileVersion>
|
||||||
<NoWarn>$(NoWarn);CA1032;CA2007</NoWarn>
|
<NoWarn>$(NoWarn);CA1032;CA2007</NoWarn>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
|
|||||||
Reference in New Issue
Block a user