93 lines
2.4 KiB
Dart
93 lines
2.4 KiB
Dart
import 'dart:convert';
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:dio/dio.dart';
|
|
|
|
import '../../../common/network/dio_provider.dart';
|
|
|
|
/// Compatible with Yanting's protobuf `/api/v1/auth/onekey/verify` contract.
|
|
class OneKeyLoginApi {
|
|
OneKeyLoginApi(this._dio);
|
|
final Dio _dio;
|
|
|
|
Future<OneKeyLoginReply> verify(String loginToken) async {
|
|
final bytes = utf8.encode(loginToken);
|
|
final request = Uint8List.fromList([
|
|
0x0A,
|
|
..._varint(bytes.length),
|
|
...bytes,
|
|
]);
|
|
final response = await _dio.post<List<int>>(
|
|
'/api/v1/auth/onekey/verify',
|
|
data: request,
|
|
options: protobufOptions(),
|
|
);
|
|
return _decode(Uint8List.fromList(response.data ?? const []));
|
|
}
|
|
|
|
OneKeyLoginReply _decode(Uint8List data) {
|
|
final fields = _fields(data);
|
|
final token = utf8.decode(fields[1] ?? const []);
|
|
final user = _fields(Uint8List.fromList(fields[3] ?? const []));
|
|
if (token.isEmpty) throw StateError('一键登录服务未返回登录凭证');
|
|
return OneKeyLoginReply(
|
|
token: token,
|
|
phone: utf8.decode(user[2] ?? const []),
|
|
);
|
|
}
|
|
|
|
Map<int, List<int>> _fields(Uint8List data) {
|
|
final result = <int, List<int>>{};
|
|
var i = 0;
|
|
while (i < data.length) {
|
|
final tag = _readVarint(data, i);
|
|
i = tag.$2;
|
|
final wireType = tag.$1 & 7;
|
|
if (wireType == 0) {
|
|
i = _readVarint(data, i).$2;
|
|
continue;
|
|
}
|
|
if (wireType != 2) {
|
|
throw const FormatException('Unsupported protobuf field');
|
|
}
|
|
final length = _readVarint(data, i);
|
|
i = length.$2;
|
|
final end = i + length.$1;
|
|
if (end > data.length) {
|
|
throw const FormatException('Invalid protobuf payload');
|
|
}
|
|
result[tag.$1 >> 3] = data.sublist(i, end);
|
|
i = end;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
(int, int) _readVarint(Uint8List data, int index) {
|
|
var value = 0;
|
|
var shift = 0;
|
|
while (index < data.length) {
|
|
final byte = data[index++];
|
|
value |= (byte & 0x7f) << shift;
|
|
if (byte & 0x80 == 0) return (value, index);
|
|
shift += 7;
|
|
}
|
|
throw const FormatException('Invalid protobuf varint');
|
|
}
|
|
|
|
List<int> _varint(int value) {
|
|
final result = <int>[];
|
|
while (value > 0x7f) {
|
|
result.add((value & 0x7f) | 0x80);
|
|
value >>= 7;
|
|
}
|
|
result.add(value);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
class OneKeyLoginReply {
|
|
const OneKeyLoginReply({required this.token, required this.phone});
|
|
final String token;
|
|
final String phone;
|
|
}
|