✨ Keypair Infra
This commit is contained in:
parent
56711889ab
commit
64e2644745
@ -37,6 +37,8 @@ PODS:
|
|||||||
- DKPhotoGallery/Resource (0.0.19):
|
- DKPhotoGallery/Resource (0.0.19):
|
||||||
- SDWebImage
|
- SDWebImage
|
||||||
- SwiftyGif
|
- SwiftyGif
|
||||||
|
- fast_rsa (0.6.0):
|
||||||
|
- Flutter
|
||||||
- file_picker (0.0.1):
|
- file_picker (0.0.1):
|
||||||
- DKImagePickerController/PhotoGallery
|
- DKImagePickerController/PhotoGallery
|
||||||
- Flutter
|
- Flutter
|
||||||
@ -262,6 +264,7 @@ DEPENDENCIES:
|
|||||||
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
|
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
|
||||||
- croppy (from `.symlinks/plugins/croppy/ios`)
|
- croppy (from `.symlinks/plugins/croppy/ios`)
|
||||||
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
||||||
|
- fast_rsa (from `.symlinks/plugins/fast_rsa/ios`)
|
||||||
- file_picker (from `.symlinks/plugins/file_picker/ios`)
|
- file_picker (from `.symlinks/plugins/file_picker/ios`)
|
||||||
- file_saver (from `.symlinks/plugins/file_saver/ios`)
|
- file_saver (from `.symlinks/plugins/file_saver/ios`)
|
||||||
- firebase_analytics (from `.symlinks/plugins/firebase_analytics/ios`)
|
- firebase_analytics (from `.symlinks/plugins/firebase_analytics/ios`)
|
||||||
@ -331,6 +334,8 @@ EXTERNAL SOURCES:
|
|||||||
:path: ".symlinks/plugins/croppy/ios"
|
:path: ".symlinks/plugins/croppy/ios"
|
||||||
device_info_plus:
|
device_info_plus:
|
||||||
:path: ".symlinks/plugins/device_info_plus/ios"
|
:path: ".symlinks/plugins/device_info_plus/ios"
|
||||||
|
fast_rsa:
|
||||||
|
:path: ".symlinks/plugins/fast_rsa/ios"
|
||||||
file_picker:
|
file_picker:
|
||||||
:path: ".symlinks/plugins/file_picker/ios"
|
:path: ".symlinks/plugins/file_picker/ios"
|
||||||
file_saver:
|
file_saver:
|
||||||
@ -411,6 +416,7 @@ SPEC CHECKSUMS:
|
|||||||
device_info_plus: bf2e3232933866d73fe290f2942f2156cdd10342
|
device_info_plus: bf2e3232933866d73fe290f2942f2156cdd10342
|
||||||
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
|
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
|
||||||
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
|
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
|
||||||
|
fast_rsa: dc48fb05f26bb108863de122b2a9f5554e8e2591
|
||||||
file_picker: b159e0c068aef54932bb15dc9fd1571818edaf49
|
file_picker: b159e0c068aef54932bb15dc9fd1571818edaf49
|
||||||
file_saver: 503e386464dbe118f630e17b4c2e1190fa0cf808
|
file_saver: 503e386464dbe118f630e17b4c2e1190fa0cf808
|
||||||
Firebase: d80354ed7f6df5f9aca55e9eb47cc4b634735eaf
|
Firebase: d80354ed7f6df5f9aca55e9eb47cc4b634735eaf
|
||||||
|
@ -538,6 +538,282 @@ class SnLocalChatMessageCompanion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class $SnLocalKeyPairTable extends SnLocalKeyPair
|
||||||
|
with TableInfo<$SnLocalKeyPairTable, SnLocalKeyPairData> {
|
||||||
|
@override
|
||||||
|
final GeneratedDatabase attachedDatabase;
|
||||||
|
final String? _alias;
|
||||||
|
$SnLocalKeyPairTable(this.attachedDatabase, [this._alias]);
|
||||||
|
static const VerificationMeta _idMeta = const VerificationMeta('id');
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<String> id = GeneratedColumn<String>(
|
||||||
|
'id', aliasedName, false,
|
||||||
|
type: DriftSqlType.string, requiredDuringInsert: true);
|
||||||
|
static const VerificationMeta _accountIdMeta =
|
||||||
|
const VerificationMeta('accountId');
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<int> accountId = GeneratedColumn<int>(
|
||||||
|
'account_id', aliasedName, false,
|
||||||
|
type: DriftSqlType.int, requiredDuringInsert: true);
|
||||||
|
static const VerificationMeta _publicKeyMeta =
|
||||||
|
const VerificationMeta('publicKey');
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<String> publicKey = GeneratedColumn<String>(
|
||||||
|
'public_key', aliasedName, false,
|
||||||
|
type: DriftSqlType.string, requiredDuringInsert: true);
|
||||||
|
static const VerificationMeta _privateKeyMeta =
|
||||||
|
const VerificationMeta('privateKey');
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<String> privateKey = GeneratedColumn<String>(
|
||||||
|
'private_key', aliasedName, true,
|
||||||
|
type: DriftSqlType.string, requiredDuringInsert: false);
|
||||||
|
@override
|
||||||
|
List<GeneratedColumn> get $columns => [id, accountId, publicKey, privateKey];
|
||||||
|
@override
|
||||||
|
String get aliasedName => _alias ?? actualTableName;
|
||||||
|
@override
|
||||||
|
String get actualTableName => $name;
|
||||||
|
static const String $name = 'sn_local_key_pair';
|
||||||
|
@override
|
||||||
|
VerificationContext validateIntegrity(Insertable<SnLocalKeyPairData> instance,
|
||||||
|
{bool isInserting = false}) {
|
||||||
|
final context = VerificationContext();
|
||||||
|
final data = instance.toColumns(true);
|
||||||
|
if (data.containsKey('id')) {
|
||||||
|
context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta));
|
||||||
|
} else if (isInserting) {
|
||||||
|
context.missing(_idMeta);
|
||||||
|
}
|
||||||
|
if (data.containsKey('account_id')) {
|
||||||
|
context.handle(_accountIdMeta,
|
||||||
|
accountId.isAcceptableOrUnknown(data['account_id']!, _accountIdMeta));
|
||||||
|
} else if (isInserting) {
|
||||||
|
context.missing(_accountIdMeta);
|
||||||
|
}
|
||||||
|
if (data.containsKey('public_key')) {
|
||||||
|
context.handle(_publicKeyMeta,
|
||||||
|
publicKey.isAcceptableOrUnknown(data['public_key']!, _publicKeyMeta));
|
||||||
|
} else if (isInserting) {
|
||||||
|
context.missing(_publicKeyMeta);
|
||||||
|
}
|
||||||
|
if (data.containsKey('private_key')) {
|
||||||
|
context.handle(
|
||||||
|
_privateKeyMeta,
|
||||||
|
privateKey.isAcceptableOrUnknown(
|
||||||
|
data['private_key']!, _privateKeyMeta));
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Set<GeneratedColumn> get $primaryKey => const {};
|
||||||
|
@override
|
||||||
|
SnLocalKeyPairData map(Map<String, dynamic> data, {String? tablePrefix}) {
|
||||||
|
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
|
||||||
|
return SnLocalKeyPairData(
|
||||||
|
id: attachedDatabase.typeMapping
|
||||||
|
.read(DriftSqlType.string, data['${effectivePrefix}id'])!,
|
||||||
|
accountId: attachedDatabase.typeMapping
|
||||||
|
.read(DriftSqlType.int, data['${effectivePrefix}account_id'])!,
|
||||||
|
publicKey: attachedDatabase.typeMapping
|
||||||
|
.read(DriftSqlType.string, data['${effectivePrefix}public_key'])!,
|
||||||
|
privateKey: attachedDatabase.typeMapping
|
||||||
|
.read(DriftSqlType.string, data['${effectivePrefix}private_key']),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
$SnLocalKeyPairTable createAlias(String alias) {
|
||||||
|
return $SnLocalKeyPairTable(attachedDatabase, alias);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SnLocalKeyPairData extends DataClass
|
||||||
|
implements Insertable<SnLocalKeyPairData> {
|
||||||
|
final String id;
|
||||||
|
final int accountId;
|
||||||
|
final String publicKey;
|
||||||
|
final String? privateKey;
|
||||||
|
const SnLocalKeyPairData(
|
||||||
|
{required this.id,
|
||||||
|
required this.accountId,
|
||||||
|
required this.publicKey,
|
||||||
|
this.privateKey});
|
||||||
|
@override
|
||||||
|
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||||
|
final map = <String, Expression>{};
|
||||||
|
map['id'] = Variable<String>(id);
|
||||||
|
map['account_id'] = Variable<int>(accountId);
|
||||||
|
map['public_key'] = Variable<String>(publicKey);
|
||||||
|
if (!nullToAbsent || privateKey != null) {
|
||||||
|
map['private_key'] = Variable<String>(privateKey);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
SnLocalKeyPairCompanion toCompanion(bool nullToAbsent) {
|
||||||
|
return SnLocalKeyPairCompanion(
|
||||||
|
id: Value(id),
|
||||||
|
accountId: Value(accountId),
|
||||||
|
publicKey: Value(publicKey),
|
||||||
|
privateKey: privateKey == null && nullToAbsent
|
||||||
|
? const Value.absent()
|
||||||
|
: Value(privateKey),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
factory SnLocalKeyPairData.fromJson(Map<String, dynamic> json,
|
||||||
|
{ValueSerializer? serializer}) {
|
||||||
|
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||||
|
return SnLocalKeyPairData(
|
||||||
|
id: serializer.fromJson<String>(json['id']),
|
||||||
|
accountId: serializer.fromJson<int>(json['accountId']),
|
||||||
|
publicKey: serializer.fromJson<String>(json['publicKey']),
|
||||||
|
privateKey: serializer.fromJson<String?>(json['privateKey']),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson({ValueSerializer? serializer}) {
|
||||||
|
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||||
|
return <String, dynamic>{
|
||||||
|
'id': serializer.toJson<String>(id),
|
||||||
|
'accountId': serializer.toJson<int>(accountId),
|
||||||
|
'publicKey': serializer.toJson<String>(publicKey),
|
||||||
|
'privateKey': serializer.toJson<String?>(privateKey),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
SnLocalKeyPairData copyWith(
|
||||||
|
{String? id,
|
||||||
|
int? accountId,
|
||||||
|
String? publicKey,
|
||||||
|
Value<String?> privateKey = const Value.absent()}) =>
|
||||||
|
SnLocalKeyPairData(
|
||||||
|
id: id ?? this.id,
|
||||||
|
accountId: accountId ?? this.accountId,
|
||||||
|
publicKey: publicKey ?? this.publicKey,
|
||||||
|
privateKey: privateKey.present ? privateKey.value : this.privateKey,
|
||||||
|
);
|
||||||
|
SnLocalKeyPairData copyWithCompanion(SnLocalKeyPairCompanion data) {
|
||||||
|
return SnLocalKeyPairData(
|
||||||
|
id: data.id.present ? data.id.value : this.id,
|
||||||
|
accountId: data.accountId.present ? data.accountId.value : this.accountId,
|
||||||
|
publicKey: data.publicKey.present ? data.publicKey.value : this.publicKey,
|
||||||
|
privateKey:
|
||||||
|
data.privateKey.present ? data.privateKey.value : this.privateKey,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return (StringBuffer('SnLocalKeyPairData(')
|
||||||
|
..write('id: $id, ')
|
||||||
|
..write('accountId: $accountId, ')
|
||||||
|
..write('publicKey: $publicKey, ')
|
||||||
|
..write('privateKey: $privateKey')
|
||||||
|
..write(')'))
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(id, accountId, publicKey, privateKey);
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
(other is SnLocalKeyPairData &&
|
||||||
|
other.id == this.id &&
|
||||||
|
other.accountId == this.accountId &&
|
||||||
|
other.publicKey == this.publicKey &&
|
||||||
|
other.privateKey == this.privateKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
class SnLocalKeyPairCompanion extends UpdateCompanion<SnLocalKeyPairData> {
|
||||||
|
final Value<String> id;
|
||||||
|
final Value<int> accountId;
|
||||||
|
final Value<String> publicKey;
|
||||||
|
final Value<String?> privateKey;
|
||||||
|
final Value<int> rowid;
|
||||||
|
const SnLocalKeyPairCompanion({
|
||||||
|
this.id = const Value.absent(),
|
||||||
|
this.accountId = const Value.absent(),
|
||||||
|
this.publicKey = const Value.absent(),
|
||||||
|
this.privateKey = const Value.absent(),
|
||||||
|
this.rowid = const Value.absent(),
|
||||||
|
});
|
||||||
|
SnLocalKeyPairCompanion.insert({
|
||||||
|
required String id,
|
||||||
|
required int accountId,
|
||||||
|
required String publicKey,
|
||||||
|
this.privateKey = const Value.absent(),
|
||||||
|
this.rowid = const Value.absent(),
|
||||||
|
}) : id = Value(id),
|
||||||
|
accountId = Value(accountId),
|
||||||
|
publicKey = Value(publicKey);
|
||||||
|
static Insertable<SnLocalKeyPairData> custom({
|
||||||
|
Expression<String>? id,
|
||||||
|
Expression<int>? accountId,
|
||||||
|
Expression<String>? publicKey,
|
||||||
|
Expression<String>? privateKey,
|
||||||
|
Expression<int>? rowid,
|
||||||
|
}) {
|
||||||
|
return RawValuesInsertable({
|
||||||
|
if (id != null) 'id': id,
|
||||||
|
if (accountId != null) 'account_id': accountId,
|
||||||
|
if (publicKey != null) 'public_key': publicKey,
|
||||||
|
if (privateKey != null) 'private_key': privateKey,
|
||||||
|
if (rowid != null) 'rowid': rowid,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
SnLocalKeyPairCompanion copyWith(
|
||||||
|
{Value<String>? id,
|
||||||
|
Value<int>? accountId,
|
||||||
|
Value<String>? publicKey,
|
||||||
|
Value<String?>? privateKey,
|
||||||
|
Value<int>? rowid}) {
|
||||||
|
return SnLocalKeyPairCompanion(
|
||||||
|
id: id ?? this.id,
|
||||||
|
accountId: accountId ?? this.accountId,
|
||||||
|
publicKey: publicKey ?? this.publicKey,
|
||||||
|
privateKey: privateKey ?? this.privateKey,
|
||||||
|
rowid: rowid ?? this.rowid,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||||
|
final map = <String, Expression>{};
|
||||||
|
if (id.present) {
|
||||||
|
map['id'] = Variable<String>(id.value);
|
||||||
|
}
|
||||||
|
if (accountId.present) {
|
||||||
|
map['account_id'] = Variable<int>(accountId.value);
|
||||||
|
}
|
||||||
|
if (publicKey.present) {
|
||||||
|
map['public_key'] = Variable<String>(publicKey.value);
|
||||||
|
}
|
||||||
|
if (privateKey.present) {
|
||||||
|
map['private_key'] = Variable<String>(privateKey.value);
|
||||||
|
}
|
||||||
|
if (rowid.present) {
|
||||||
|
map['rowid'] = Variable<int>(rowid.value);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return (StringBuffer('SnLocalKeyPairCompanion(')
|
||||||
|
..write('id: $id, ')
|
||||||
|
..write('accountId: $accountId, ')
|
||||||
|
..write('publicKey: $publicKey, ')
|
||||||
|
..write('privateKey: $privateKey, ')
|
||||||
|
..write('rowid: $rowid')
|
||||||
|
..write(')'))
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
abstract class _$AppDatabase extends GeneratedDatabase {
|
abstract class _$AppDatabase extends GeneratedDatabase {
|
||||||
_$AppDatabase(QueryExecutor e) : super(e);
|
_$AppDatabase(QueryExecutor e) : super(e);
|
||||||
$AppDatabaseManager get managers => $AppDatabaseManager(this);
|
$AppDatabaseManager get managers => $AppDatabaseManager(this);
|
||||||
@ -545,12 +821,13 @@ abstract class _$AppDatabase extends GeneratedDatabase {
|
|||||||
$SnLocalChatChannelTable(this);
|
$SnLocalChatChannelTable(this);
|
||||||
late final $SnLocalChatMessageTable snLocalChatMessage =
|
late final $SnLocalChatMessageTable snLocalChatMessage =
|
||||||
$SnLocalChatMessageTable(this);
|
$SnLocalChatMessageTable(this);
|
||||||
|
late final $SnLocalKeyPairTable snLocalKeyPair = $SnLocalKeyPairTable(this);
|
||||||
@override
|
@override
|
||||||
Iterable<TableInfo<Table, Object?>> get allTables =>
|
Iterable<TableInfo<Table, Object?>> get allTables =>
|
||||||
allSchemaEntities.whereType<TableInfo<Table, Object?>>();
|
allSchemaEntities.whereType<TableInfo<Table, Object?>>();
|
||||||
@override
|
@override
|
||||||
List<DatabaseSchemaEntity> get allSchemaEntities =>
|
List<DatabaseSchemaEntity> get allSchemaEntities =>
|
||||||
[snLocalChatChannel, snLocalChatMessage];
|
[snLocalChatChannel, snLocalChatMessage, snLocalKeyPair];
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef $$SnLocalChatChannelTableCreateCompanionBuilder
|
typedef $$SnLocalChatChannelTableCreateCompanionBuilder
|
||||||
@ -869,6 +1146,165 @@ typedef $$SnLocalChatMessageTableProcessedTableManager = ProcessedTableManager<
|
|||||||
),
|
),
|
||||||
SnLocalChatMessageData,
|
SnLocalChatMessageData,
|
||||||
PrefetchHooks Function()>;
|
PrefetchHooks Function()>;
|
||||||
|
typedef $$SnLocalKeyPairTableCreateCompanionBuilder = SnLocalKeyPairCompanion
|
||||||
|
Function({
|
||||||
|
required String id,
|
||||||
|
required int accountId,
|
||||||
|
required String publicKey,
|
||||||
|
Value<String?> privateKey,
|
||||||
|
Value<int> rowid,
|
||||||
|
});
|
||||||
|
typedef $$SnLocalKeyPairTableUpdateCompanionBuilder = SnLocalKeyPairCompanion
|
||||||
|
Function({
|
||||||
|
Value<String> id,
|
||||||
|
Value<int> accountId,
|
||||||
|
Value<String> publicKey,
|
||||||
|
Value<String?> privateKey,
|
||||||
|
Value<int> rowid,
|
||||||
|
});
|
||||||
|
|
||||||
|
class $$SnLocalKeyPairTableFilterComposer
|
||||||
|
extends Composer<_$AppDatabase, $SnLocalKeyPairTable> {
|
||||||
|
$$SnLocalKeyPairTableFilterComposer({
|
||||||
|
required super.$db,
|
||||||
|
required super.$table,
|
||||||
|
super.joinBuilder,
|
||||||
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
ColumnFilters<String> get id => $composableBuilder(
|
||||||
|
column: $table.id, builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
|
ColumnFilters<int> get accountId => $composableBuilder(
|
||||||
|
column: $table.accountId, builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
|
ColumnFilters<String> get publicKey => $composableBuilder(
|
||||||
|
column: $table.publicKey, builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
|
ColumnFilters<String> get privateKey => $composableBuilder(
|
||||||
|
column: $table.privateKey, builder: (column) => ColumnFilters(column));
|
||||||
|
}
|
||||||
|
|
||||||
|
class $$SnLocalKeyPairTableOrderingComposer
|
||||||
|
extends Composer<_$AppDatabase, $SnLocalKeyPairTable> {
|
||||||
|
$$SnLocalKeyPairTableOrderingComposer({
|
||||||
|
required super.$db,
|
||||||
|
required super.$table,
|
||||||
|
super.joinBuilder,
|
||||||
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
ColumnOrderings<String> get id => $composableBuilder(
|
||||||
|
column: $table.id, builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
|
ColumnOrderings<int> get accountId => $composableBuilder(
|
||||||
|
column: $table.accountId, builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
|
ColumnOrderings<String> get publicKey => $composableBuilder(
|
||||||
|
column: $table.publicKey, builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
|
ColumnOrderings<String> get privateKey => $composableBuilder(
|
||||||
|
column: $table.privateKey, builder: (column) => ColumnOrderings(column));
|
||||||
|
}
|
||||||
|
|
||||||
|
class $$SnLocalKeyPairTableAnnotationComposer
|
||||||
|
extends Composer<_$AppDatabase, $SnLocalKeyPairTable> {
|
||||||
|
$$SnLocalKeyPairTableAnnotationComposer({
|
||||||
|
required super.$db,
|
||||||
|
required super.$table,
|
||||||
|
super.joinBuilder,
|
||||||
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
GeneratedColumn<String> get id =>
|
||||||
|
$composableBuilder(column: $table.id, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<int> get accountId =>
|
||||||
|
$composableBuilder(column: $table.accountId, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<String> get publicKey =>
|
||||||
|
$composableBuilder(column: $table.publicKey, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<String> get privateKey => $composableBuilder(
|
||||||
|
column: $table.privateKey, builder: (column) => column);
|
||||||
|
}
|
||||||
|
|
||||||
|
class $$SnLocalKeyPairTableTableManager extends RootTableManager<
|
||||||
|
_$AppDatabase,
|
||||||
|
$SnLocalKeyPairTable,
|
||||||
|
SnLocalKeyPairData,
|
||||||
|
$$SnLocalKeyPairTableFilterComposer,
|
||||||
|
$$SnLocalKeyPairTableOrderingComposer,
|
||||||
|
$$SnLocalKeyPairTableAnnotationComposer,
|
||||||
|
$$SnLocalKeyPairTableCreateCompanionBuilder,
|
||||||
|
$$SnLocalKeyPairTableUpdateCompanionBuilder,
|
||||||
|
(
|
||||||
|
SnLocalKeyPairData,
|
||||||
|
BaseReferences<_$AppDatabase, $SnLocalKeyPairTable, SnLocalKeyPairData>
|
||||||
|
),
|
||||||
|
SnLocalKeyPairData,
|
||||||
|
PrefetchHooks Function()> {
|
||||||
|
$$SnLocalKeyPairTableTableManager(
|
||||||
|
_$AppDatabase db, $SnLocalKeyPairTable table)
|
||||||
|
: super(TableManagerState(
|
||||||
|
db: db,
|
||||||
|
table: table,
|
||||||
|
createFilteringComposer: () =>
|
||||||
|
$$SnLocalKeyPairTableFilterComposer($db: db, $table: table),
|
||||||
|
createOrderingComposer: () =>
|
||||||
|
$$SnLocalKeyPairTableOrderingComposer($db: db, $table: table),
|
||||||
|
createComputedFieldComposer: () =>
|
||||||
|
$$SnLocalKeyPairTableAnnotationComposer($db: db, $table: table),
|
||||||
|
updateCompanionCallback: ({
|
||||||
|
Value<String> id = const Value.absent(),
|
||||||
|
Value<int> accountId = const Value.absent(),
|
||||||
|
Value<String> publicKey = const Value.absent(),
|
||||||
|
Value<String?> privateKey = const Value.absent(),
|
||||||
|
Value<int> rowid = const Value.absent(),
|
||||||
|
}) =>
|
||||||
|
SnLocalKeyPairCompanion(
|
||||||
|
id: id,
|
||||||
|
accountId: accountId,
|
||||||
|
publicKey: publicKey,
|
||||||
|
privateKey: privateKey,
|
||||||
|
rowid: rowid,
|
||||||
|
),
|
||||||
|
createCompanionCallback: ({
|
||||||
|
required String id,
|
||||||
|
required int accountId,
|
||||||
|
required String publicKey,
|
||||||
|
Value<String?> privateKey = const Value.absent(),
|
||||||
|
Value<int> rowid = const Value.absent(),
|
||||||
|
}) =>
|
||||||
|
SnLocalKeyPairCompanion.insert(
|
||||||
|
id: id,
|
||||||
|
accountId: accountId,
|
||||||
|
publicKey: publicKey,
|
||||||
|
privateKey: privateKey,
|
||||||
|
rowid: rowid,
|
||||||
|
),
|
||||||
|
withReferenceMapper: (p0) => p0
|
||||||
|
.map((e) => (e.readTable(table), BaseReferences(db, table, e)))
|
||||||
|
.toList(),
|
||||||
|
prefetchHooksCallback: null,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef $$SnLocalKeyPairTableProcessedTableManager = ProcessedTableManager<
|
||||||
|
_$AppDatabase,
|
||||||
|
$SnLocalKeyPairTable,
|
||||||
|
SnLocalKeyPairData,
|
||||||
|
$$SnLocalKeyPairTableFilterComposer,
|
||||||
|
$$SnLocalKeyPairTableOrderingComposer,
|
||||||
|
$$SnLocalKeyPairTableAnnotationComposer,
|
||||||
|
$$SnLocalKeyPairTableCreateCompanionBuilder,
|
||||||
|
$$SnLocalKeyPairTableUpdateCompanionBuilder,
|
||||||
|
(
|
||||||
|
SnLocalKeyPairData,
|
||||||
|
BaseReferences<_$AppDatabase, $SnLocalKeyPairTable, SnLocalKeyPairData>
|
||||||
|
),
|
||||||
|
SnLocalKeyPairData,
|
||||||
|
PrefetchHooks Function()>;
|
||||||
|
|
||||||
class $AppDatabaseManager {
|
class $AppDatabaseManager {
|
||||||
final _$AppDatabase _db;
|
final _$AppDatabase _db;
|
||||||
@ -877,4 +1313,6 @@ class $AppDatabaseManager {
|
|||||||
$$SnLocalChatChannelTableTableManager(_db, _db.snLocalChatChannel);
|
$$SnLocalChatChannelTableTableManager(_db, _db.snLocalChatChannel);
|
||||||
$$SnLocalChatMessageTableTableManager get snLocalChatMessage =>
|
$$SnLocalChatMessageTableTableManager get snLocalChatMessage =>
|
||||||
$$SnLocalChatMessageTableTableManager(_db, _db.snLocalChatMessage);
|
$$SnLocalChatMessageTableTableManager(_db, _db.snLocalChatMessage);
|
||||||
|
$$SnLocalKeyPairTableTableManager get snLocalKeyPair =>
|
||||||
|
$$SnLocalKeyPairTableTableManager(_db, _db.snLocalKeyPair);
|
||||||
}
|
}
|
||||||
|
@ -1,32 +1,4 @@
|
|||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:surface/types/keypair.dart';
|
|
||||||
|
|
||||||
class SnKeyPairConverter extends TypeConverter<SnKeyPair, String>
|
|
||||||
with JsonTypeConverter2<SnKeyPair, String, Map<String, Object?>> {
|
|
||||||
const SnKeyPairConverter();
|
|
||||||
|
|
||||||
@override
|
|
||||||
SnKeyPair fromSql(String fromDb) {
|
|
||||||
return fromJson(jsonDecode(fromDb) as Map<String, dynamic>);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toSql(SnKeyPair value) {
|
|
||||||
return jsonEncode(toJson(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
SnKeyPair fromJson(Map<String, Object?> json) {
|
|
||||||
return SnKeyPair.fromJson(json);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Map<String, Object?> toJson(SnKeyPair value) {
|
|
||||||
return value.toJson();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SnLocalKeyPair extends Table {
|
class SnLocalKeyPair extends Table {
|
||||||
TextColumn get id => text()();
|
TextColumn get id => text()();
|
||||||
|
@ -25,6 +25,7 @@ import 'package:surface/providers/channel.dart';
|
|||||||
import 'package:surface/providers/chat_call.dart';
|
import 'package:surface/providers/chat_call.dart';
|
||||||
import 'package:surface/providers/config.dart';
|
import 'package:surface/providers/config.dart';
|
||||||
import 'package:surface/providers/database.dart';
|
import 'package:surface/providers/database.dart';
|
||||||
|
import 'package:surface/providers/keypair.dart';
|
||||||
import 'package:surface/providers/link_preview.dart';
|
import 'package:surface/providers/link_preview.dart';
|
||||||
import 'package:surface/providers/navigation.dart';
|
import 'package:surface/providers/navigation.dart';
|
||||||
import 'package:surface/providers/notification.dart';
|
import 'package:surface/providers/notification.dart';
|
||||||
@ -108,7 +109,8 @@ void main() async {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!kIsWeb && Platform.isAndroid) {
|
if (!kIsWeb && Platform.isAndroid) {
|
||||||
final ImagePickerPlatform imagePickerImplementation = ImagePickerPlatform.instance;
|
final ImagePickerPlatform imagePickerImplementation =
|
||||||
|
ImagePickerPlatform.instance;
|
||||||
if (imagePickerImplementation is ImagePickerAndroid) {
|
if (imagePickerImplementation is ImagePickerAndroid) {
|
||||||
imagePickerImplementation.useAndroidPhotoPicker = true;
|
imagePickerImplementation.useAndroidPhotoPicker = true;
|
||||||
}
|
}
|
||||||
@ -160,6 +162,7 @@ class SolianApp extends StatelessWidget {
|
|||||||
Provider(create: (ctx) => SnStickerProvider(ctx)),
|
Provider(create: (ctx) => SnStickerProvider(ctx)),
|
||||||
ChangeNotifierProvider(create: (ctx) => UserProvider(ctx)),
|
ChangeNotifierProvider(create: (ctx) => UserProvider(ctx)),
|
||||||
ChangeNotifierProvider(create: (ctx) => WebSocketProvider(ctx)),
|
ChangeNotifierProvider(create: (ctx) => WebSocketProvider(ctx)),
|
||||||
|
Provider(create: (ctx) => KeyPairProvider(ctx)),
|
||||||
ChangeNotifierProvider(create: (ctx) => NotificationProvider(ctx)),
|
ChangeNotifierProvider(create: (ctx) => NotificationProvider(ctx)),
|
||||||
ChangeNotifierProvider(create: (ctx) => ChatChannelProvider(ctx)),
|
ChangeNotifierProvider(create: (ctx) => ChatChannelProvider(ctx)),
|
||||||
ChangeNotifierProvider(create: (ctx) => ChatCallProvider(ctx)),
|
ChangeNotifierProvider(create: (ctx) => ChatCallProvider(ctx)),
|
||||||
@ -227,7 +230,8 @@ class _AppSplashScreenState extends State<_AppSplashScreen> with TrayListener {
|
|||||||
if (prefs.containsKey('first_boot_time')) {
|
if (prefs.containsKey('first_boot_time')) {
|
||||||
final rawTime = prefs.getString('first_boot_time');
|
final rawTime = prefs.getString('first_boot_time');
|
||||||
final time = DateTime.tryParse(rawTime ?? '');
|
final time = DateTime.tryParse(rawTime ?? '');
|
||||||
if (time != null && time.isBefore(DateTime.now().subtract(const Duration(days: 3)))) {
|
if (time != null &&
|
||||||
|
time.isBefore(DateTime.now().subtract(const Duration(days: 3)))) {
|
||||||
final inAppReview = InAppReview.instance;
|
final inAppReview = InAppReview.instance;
|
||||||
if (prefs.getBool('rating_requested') == true) return;
|
if (prefs.getBool('rating_requested') == true) return;
|
||||||
if (await inAppReview.isAvailable()) {
|
if (await inAppReview.isAvailable()) {
|
||||||
@ -258,12 +262,18 @@ class _AppSplashScreenState extends State<_AppSplashScreen> with TrayListener {
|
|||||||
final remoteVersionString = resp.data?['tag_name'] ?? '0.0.0+0';
|
final remoteVersionString = resp.data?['tag_name'] ?? '0.0.0+0';
|
||||||
final remoteVersion = Version.parse(remoteVersionString.split('+').first);
|
final remoteVersion = Version.parse(remoteVersionString.split('+').first);
|
||||||
final localVersion = Version.parse(localVersionString.split('+').first);
|
final localVersion = Version.parse(localVersionString.split('+').first);
|
||||||
final remoteBuildNumber = int.tryParse(remoteVersionString.split('+').last) ?? 0;
|
final remoteBuildNumber =
|
||||||
final localBuildNumber = int.tryParse(localVersionString.split('+').last) ?? 0;
|
int.tryParse(remoteVersionString.split('+').last) ?? 0;
|
||||||
logging.info("[Update] Local: $localVersionString, Remote: $remoteVersionString");
|
final localBuildNumber =
|
||||||
if ((remoteVersion > localVersion || remoteBuildNumber > localBuildNumber) && mounted) {
|
int.tryParse(localVersionString.split('+').last) ?? 0;
|
||||||
|
logging.info(
|
||||||
|
"[Update] Local: $localVersionString, Remote: $remoteVersionString");
|
||||||
|
if ((remoteVersion > localVersion ||
|
||||||
|
remoteBuildNumber > localBuildNumber) &&
|
||||||
|
mounted) {
|
||||||
final config = context.read<ConfigProvider>();
|
final config = context.read<ConfigProvider>();
|
||||||
config.setUpdate(remoteVersionString, resp.data?['body'] ?? 'No changelog');
|
config.setUpdate(
|
||||||
|
remoteVersionString, resp.data?['body'] ?? 'No changelog');
|
||||||
logging.info("[Update] Update available: $remoteVersionString");
|
logging.info("[Update] Update available: $remoteVersionString");
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -298,6 +308,9 @@ class _AppSplashScreenState extends State<_AppSplashScreen> with TrayListener {
|
|||||||
notify.listen();
|
notify.listen();
|
||||||
await notify.registerPushNotifications();
|
await notify.registerPushNotifications();
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
final kp = context.read<KeyPairProvider>();
|
||||||
|
kp.listen();
|
||||||
|
if (!mounted) return;
|
||||||
final sticker = context.read<SnStickerProvider>();
|
final sticker = context.read<SnStickerProvider>();
|
||||||
await sticker.listSticker();
|
await sticker.listSticker();
|
||||||
logging.info('[Bootstrap] Everything initialized!');
|
logging.info('[Bootstrap] Everything initialized!');
|
||||||
@ -355,7 +368,9 @@ class _AppSplashScreenState extends State<_AppSplashScreen> with TrayListener {
|
|||||||
Future<void> _trayInitialization() async {
|
Future<void> _trayInitialization() async {
|
||||||
if (kIsWeb || Platform.isAndroid || Platform.isIOS) return;
|
if (kIsWeb || Platform.isAndroid || Platform.isIOS) return;
|
||||||
|
|
||||||
final icon = Platform.isWindows ? 'assets/icon/tray-icon.ico' : 'assets/icon/tray-icon.png';
|
final icon = Platform.isWindows
|
||||||
|
? 'assets/icon/tray-icon.ico'
|
||||||
|
: 'assets/icon/tray-icon.png';
|
||||||
final appVersion = await PackageInfo.fromPlatform();
|
final appVersion = await PackageInfo.fromPlatform();
|
||||||
|
|
||||||
trayManager.addListener(this);
|
trayManager.addListener(this);
|
||||||
|
211
lib/providers/keypair.dart
Normal file
211
lib/providers/keypair.dart
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:surface/database/database.dart';
|
||||||
|
import 'package:surface/logger.dart';
|
||||||
|
import 'package:surface/providers/database.dart';
|
||||||
|
import 'package:surface/providers/userinfo.dart';
|
||||||
|
import 'package:surface/providers/websocket.dart';
|
||||||
|
import 'package:surface/types/keypair.dart';
|
||||||
|
import 'package:fast_rsa/fast_rsa.dart';
|
||||||
|
import 'package:surface/types/websocket.dart';
|
||||||
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
|
// Currently the keypair only provide RSA encryption
|
||||||
|
// Supported by the `fast_rsa` package
|
||||||
|
class KeyPairProvider {
|
||||||
|
late final DatabaseProvider _dt;
|
||||||
|
late final UserProvider _ua;
|
||||||
|
late final WebSocketProvider _ws;
|
||||||
|
|
||||||
|
SnKeyPair? activeKp;
|
||||||
|
|
||||||
|
KeyPairProvider(BuildContext context) {
|
||||||
|
_dt = context.read<DatabaseProvider>();
|
||||||
|
_ua = context.read<UserProvider>();
|
||||||
|
_ws = context.read<WebSocketProvider>();
|
||||||
|
|
||||||
|
reloadActive();
|
||||||
|
}
|
||||||
|
|
||||||
|
void listen() {
|
||||||
|
_ws.pk.stream.listen((event) {
|
||||||
|
switch (event.method) {
|
||||||
|
case 'kex.ack':
|
||||||
|
ackKeyExchange(event);
|
||||||
|
break;
|
||||||
|
case 'key.ask':
|
||||||
|
replyAskKeyExchange(event);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> decryptText(String text, String kpId) async {
|
||||||
|
final kp = await (_dt.db.snLocalKeyPair.select()
|
||||||
|
..where((e) => e.id.equals(kpId)))
|
||||||
|
.getSingleOrNull();
|
||||||
|
if (kp == null) throw Exception('Key pair not found');
|
||||||
|
return await RSA.decryptPKCS1v15(text, kp.privateKey!);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> encryptText(String text) async {
|
||||||
|
if (activeKp == null) throw Exception('No active key pair');
|
||||||
|
return await RSA.encryptPKCS1v15(text, activeKp!.publicKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
final Map<String, Completer<SnKeyPair>> _requests = {};
|
||||||
|
|
||||||
|
Future<SnKeyPair> askKeyExchange(int kpOwner, String kpId) async {
|
||||||
|
if (_requests.containsKey(kpId)) return await _requests[kpId]!.future;
|
||||||
|
|
||||||
|
final completer = Completer<SnKeyPair>();
|
||||||
|
_requests[kpId] = completer;
|
||||||
|
|
||||||
|
_ws.conn?.sink.add(
|
||||||
|
jsonEncode(WebSocketPackage(
|
||||||
|
method: 'key.ask',
|
||||||
|
endpoint: 'id',
|
||||||
|
payload: {
|
||||||
|
'keypair_id': kpId,
|
||||||
|
'user_id': kpOwner,
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
|
||||||
|
return Future.any([
|
||||||
|
_requests[kpId]!.future,
|
||||||
|
Future.delayed(const Duration(seconds: 60), () {
|
||||||
|
_requests.remove(kpId);
|
||||||
|
throw TimeoutException("Key exchange timed out");
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> ackKeyExchange(WebSocketPackage pkt) async {
|
||||||
|
if (pkt.payload == null) return;
|
||||||
|
final kpMeta = SnKeyPair(
|
||||||
|
id: pkt.payload!['keypair_id'] as String,
|
||||||
|
accountId: pkt.payload!['user_id'] as int,
|
||||||
|
publicKey: pkt.payload!['public_key'] as String,
|
||||||
|
privateKey: pkt.payload?['private_key'] as String?,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (_requests.containsKey(kpMeta.id)) {
|
||||||
|
_requests[kpMeta.id]!.complete(kpMeta);
|
||||||
|
_requests.remove(kpMeta.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the keypair to the local database
|
||||||
|
await _dt.db.snLocalKeyPair.insertOne(
|
||||||
|
SnLocalKeyPairCompanion.insert(
|
||||||
|
id: kpMeta.id,
|
||||||
|
accountId: kpMeta.accountId,
|
||||||
|
publicKey: kpMeta.publicKey,
|
||||||
|
privateKey: Value(kpMeta.privateKey),
|
||||||
|
),
|
||||||
|
onConflict: DoUpdate(
|
||||||
|
(_) => SnLocalKeyPairCompanion.custom(
|
||||||
|
publicKey: Constant(kpMeta.publicKey),
|
||||||
|
privateKey: Constant(kpMeta.privateKey),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> replyAskKeyExchange(WebSocketPackage pkt) async {
|
||||||
|
final kpId = pkt.payload!['keypair_id'] as String;
|
||||||
|
final userId = pkt.payload!['user_id'] as int;
|
||||||
|
final clientId = pkt.payload!['client_id'] as String;
|
||||||
|
|
||||||
|
final localKp = await (_dt.db.snLocalKeyPair.select()
|
||||||
|
..where((e) => e.id.equals(kpId))
|
||||||
|
..limit(1))
|
||||||
|
.getSingleOrNull();
|
||||||
|
if (localKp == null) return;
|
||||||
|
|
||||||
|
logging.info(
|
||||||
|
'[Kex] Reply to key exchange request of $kpId from user $userId',
|
||||||
|
);
|
||||||
|
|
||||||
|
// We do not give the private key to the client
|
||||||
|
_ws.conn?.sink.add(jsonEncode(
|
||||||
|
WebSocketPackage(
|
||||||
|
method: 'kex.ack',
|
||||||
|
endpoint: 'id',
|
||||||
|
payload: {
|
||||||
|
'keypair_id': localKp.id,
|
||||||
|
'user_id': localKp.accountId,
|
||||||
|
'public_key': localKp.publicKey,
|
||||||
|
'client_id': clientId,
|
||||||
|
},
|
||||||
|
).toJson(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<SnKeyPair?> reloadActive({bool autoEnroll = true}) async {
|
||||||
|
final kp = await (_dt.db.snLocalKeyPair.select()
|
||||||
|
..where((e) => e.accountId.equals(_ua.user!.id))
|
||||||
|
..where((e) => e.privateKey.isNotNull())
|
||||||
|
..limit(1))
|
||||||
|
.getSingleOrNull();
|
||||||
|
|
||||||
|
if (kp != null) {
|
||||||
|
activeKp = SnKeyPair(
|
||||||
|
id: kp.id,
|
||||||
|
accountId: kp.accountId,
|
||||||
|
publicKey: kp.publicKey,
|
||||||
|
privateKey: kp.privateKey,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kp == null && autoEnroll) {
|
||||||
|
return await enrollNew();
|
||||||
|
}
|
||||||
|
|
||||||
|
return activeKp;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<SnKeyPair> enrollNew() async {
|
||||||
|
if (!_ua.isAuthorized) throw Exception('Unauthorized');
|
||||||
|
|
||||||
|
final existsOne = await (_dt.db.snLocalKeyPair.select()
|
||||||
|
..where((e) => e.accountId.equals(_ua.user!.id))
|
||||||
|
..where((e) => e.privateKey.isNotNull())
|
||||||
|
..limit(1))
|
||||||
|
.getSingleOrNull();
|
||||||
|
|
||||||
|
final id = existsOne?.id ?? const Uuid().v4();
|
||||||
|
final kp = await RSA.generate(2048);
|
||||||
|
final kpMeta = SnKeyPair(
|
||||||
|
id: id,
|
||||||
|
accountId: _ua.user!.id,
|
||||||
|
publicKey: kp.publicKey,
|
||||||
|
privateKey: kp.privateKey,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Save the keypair to the local database
|
||||||
|
// If there is already one with private key, it will be overwritten
|
||||||
|
await _dt.db.snLocalKeyPair.insertOne(
|
||||||
|
SnLocalKeyPairCompanion.insert(
|
||||||
|
id: kpMeta.id,
|
||||||
|
accountId: kpMeta.accountId,
|
||||||
|
publicKey: kpMeta.publicKey,
|
||||||
|
privateKey: Value(kpMeta.privateKey),
|
||||||
|
),
|
||||||
|
onConflict: DoUpdate(
|
||||||
|
(_) => SnLocalKeyPairCompanion.custom(
|
||||||
|
publicKey: Constant(kpMeta.publicKey),
|
||||||
|
privateKey: Constant(kpMeta.privateKey),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
await reloadActive(autoEnroll: false);
|
||||||
|
|
||||||
|
return kpMeta;
|
||||||
|
}
|
||||||
|
}
|
@ -117,7 +117,8 @@ class WebSocketProvider extends ChangeNotifier {
|
|||||||
(event) {
|
(event) {
|
||||||
final packet = WebSocketPackage.fromJson(jsonDecode(event));
|
final packet = WebSocketPackage.fromJson(jsonDecode(event));
|
||||||
logging.debug(
|
logging.debug(
|
||||||
'[Websocket] Incoming message: ${packet.method} ${packet.message}');
|
'[Websocket] Incoming message: ${packet.method} ${packet.message}',
|
||||||
|
);
|
||||||
pk.sink.add(packet);
|
pk.sink.add(packet);
|
||||||
},
|
},
|
||||||
onDone: () {
|
onDone: () {
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
#include <bitsdojo_window_linux/bitsdojo_window_plugin.h>
|
#include <bitsdojo_window_linux/bitsdojo_window_plugin.h>
|
||||||
|
#include <fast_rsa/fast_rsa_plugin.h>
|
||||||
#include <file_saver/file_saver_plugin.h>
|
#include <file_saver/file_saver_plugin.h>
|
||||||
#include <file_selector_linux/file_selector_plugin.h>
|
#include <file_selector_linux/file_selector_plugin.h>
|
||||||
#include <flutter_timezone/flutter_timezone_plugin.h>
|
#include <flutter_timezone/flutter_timezone_plugin.h>
|
||||||
@ -25,6 +26,9 @@ void fl_register_plugins(FlPluginRegistry* registry) {
|
|||||||
g_autoptr(FlPluginRegistrar) bitsdojo_window_linux_registrar =
|
g_autoptr(FlPluginRegistrar) bitsdojo_window_linux_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "BitsdojoWindowPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "BitsdojoWindowPlugin");
|
||||||
bitsdojo_window_plugin_register_with_registrar(bitsdojo_window_linux_registrar);
|
bitsdojo_window_plugin_register_with_registrar(bitsdojo_window_linux_registrar);
|
||||||
|
g_autoptr(FlPluginRegistrar) fast_rsa_registrar =
|
||||||
|
fl_plugin_registry_get_registrar_for_plugin(registry, "FastRsaPlugin");
|
||||||
|
fast_rsa_plugin_register_with_registrar(fast_rsa_registrar);
|
||||||
g_autoptr(FlPluginRegistrar) file_saver_registrar =
|
g_autoptr(FlPluginRegistrar) file_saver_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSaverPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSaverPlugin");
|
||||||
file_saver_plugin_register_with_registrar(file_saver_registrar);
|
file_saver_plugin_register_with_registrar(file_saver_registrar);
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
bitsdojo_window_linux
|
bitsdojo_window_linux
|
||||||
|
fast_rsa
|
||||||
file_saver
|
file_saver
|
||||||
file_selector_linux
|
file_selector_linux
|
||||||
flutter_timezone
|
flutter_timezone
|
||||||
|
@ -8,6 +8,7 @@ import Foundation
|
|||||||
import bitsdojo_window_macos
|
import bitsdojo_window_macos
|
||||||
import connectivity_plus
|
import connectivity_plus
|
||||||
import device_info_plus
|
import device_info_plus
|
||||||
|
import fast_rsa
|
||||||
import file_picker
|
import file_picker
|
||||||
import file_saver
|
import file_saver
|
||||||
import file_selector_macos
|
import file_selector_macos
|
||||||
@ -43,6 +44,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
|||||||
BitsdojoWindowPlugin.register(with: registry.registrar(forPlugin: "BitsdojoWindowPlugin"))
|
BitsdojoWindowPlugin.register(with: registry.registrar(forPlugin: "BitsdojoWindowPlugin"))
|
||||||
ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin"))
|
ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin"))
|
||||||
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
||||||
|
FastRsaPlugin.register(with: registry.registrar(forPlugin: "FastRsaPlugin"))
|
||||||
FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin"))
|
FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin"))
|
||||||
FileSaverPlugin.register(with: registry.registrar(forPlugin: "FileSaverPlugin"))
|
FileSaverPlugin.register(with: registry.registrar(forPlugin: "FileSaverPlugin"))
|
||||||
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
|
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
|
||||||
|
16
pubspec.lock
16
pubspec.lock
@ -513,6 +513,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.2"
|
version: "1.3.2"
|
||||||
|
fast_rsa:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: fast_rsa
|
||||||
|
sha256: "205a36c0412b9fabebf3e18ccb5221d819cc28cfb3da988c0bf7b646368d0270"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.8.0"
|
||||||
ffi:
|
ffi:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -665,6 +673,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.70.2"
|
version: "0.70.2"
|
||||||
|
flat_buffers:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flat_buffers
|
||||||
|
sha256: "380bdcba5664a718bfd4ea20a45d39e13684f5318fcd8883066a55e21f37f4c3"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "23.5.26"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -137,6 +137,7 @@ dependencies:
|
|||||||
flutter_timezone: ^4.1.0
|
flutter_timezone: ^4.1.0
|
||||||
flutter_map: ^8.1.0
|
flutter_map: ^8.1.0
|
||||||
geolocator: ^13.0.2
|
geolocator: ^13.0.2
|
||||||
|
fast_rsa: ^3.8.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <bitsdojo_window_windows/bitsdojo_window_plugin.h>
|
#include <bitsdojo_window_windows/bitsdojo_window_plugin.h>
|
||||||
#include <connectivity_plus/connectivity_plus_windows_plugin.h>
|
#include <connectivity_plus/connectivity_plus_windows_plugin.h>
|
||||||
|
#include <fast_rsa/fast_rsa_plugin.h>
|
||||||
#include <file_saver/file_saver_plugin.h>
|
#include <file_saver/file_saver_plugin.h>
|
||||||
#include <file_selector_windows/file_selector_windows.h>
|
#include <file_selector_windows/file_selector_windows.h>
|
||||||
#include <firebase_core/firebase_core_plugin_c_api.h>
|
#include <firebase_core/firebase_core_plugin_c_api.h>
|
||||||
@ -35,6 +36,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
|
|||||||
registry->GetRegistrarForPlugin("BitsdojoWindowPlugin"));
|
registry->GetRegistrarForPlugin("BitsdojoWindowPlugin"));
|
||||||
ConnectivityPlusWindowsPluginRegisterWithRegistrar(
|
ConnectivityPlusWindowsPluginRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin"));
|
registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin"));
|
||||||
|
FastRsaPluginRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("FastRsaPlugin"));
|
||||||
FileSaverPluginRegisterWithRegistrar(
|
FileSaverPluginRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("FileSaverPlugin"));
|
registry->GetRegistrarForPlugin("FileSaverPlugin"));
|
||||||
FileSelectorWindowsRegisterWithRegistrar(
|
FileSelectorWindowsRegisterWithRegistrar(
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
bitsdojo_window_windows
|
bitsdojo_window_windows
|
||||||
connectivity_plus
|
connectivity_plus
|
||||||
|
fast_rsa
|
||||||
file_saver
|
file_saver
|
||||||
file_selector_windows
|
file_selector_windows
|
||||||
firebase_core
|
firebase_core
|
||||||
|
Loading…
x
Reference in New Issue
Block a user