mirror of
https://github.com/zapstore/zapstore.git
synced 2026-10-05 12:38:24 +00:00
Remember trusted signers, closes #141
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
analyzer:
|
||||
errors:
|
||||
no_leading_underscores_for_local_identifiers: ignore
|
||||
must_be_immutable: ignore
|
||||
include: package:flutter_lints/flutter.yaml
|
||||
|
||||
linter:
|
||||
|
||||
+8
-1
@@ -69,7 +69,7 @@ class App extends BaseApp with DataModelMixin<App> {
|
||||
bool get hasCertificateMismatch =>
|
||||
localApp.value?.status == AppInstallStatus.certificateMismatch;
|
||||
|
||||
Future<void> install() async {
|
||||
Future<void> install({bool alwaysTrustSigner = false}) async {
|
||||
if (!canInstall && !canUpdate || hasCertificateMismatch) {
|
||||
return;
|
||||
}
|
||||
@@ -78,6 +78,13 @@ class App extends BaseApp with DataModelMixin<App> {
|
||||
final notifier =
|
||||
adapter.ref.read(installationProgressProvider(id!).notifier);
|
||||
|
||||
// Persist trusted preference
|
||||
if (alwaysTrustSigner) {
|
||||
final settings = adapter.ref.settings.findOneLocalById('_')!;
|
||||
settings.trustedUsers.add(signer.value!);
|
||||
settings.saveLocal();
|
||||
}
|
||||
|
||||
final installPermission = await Permission.requestInstallPackages.status;
|
||||
if (!installPermission.isGranted) {
|
||||
final newStatus = await Permission.requestInstallPackages.request();
|
||||
|
||||
@@ -10,7 +10,7 @@ class Settings extends DataModel<Settings> {
|
||||
@override
|
||||
String get id => '_';
|
||||
final BelongsTo<User> user = BelongsTo();
|
||||
bool isLoggedIn = false;
|
||||
final HasMany<User> trustedUsers = HasMany();
|
||||
}
|
||||
|
||||
mixin SettingsAdapter on Adapter<Settings> {
|
||||
|
||||
@@ -15,6 +15,12 @@ mixin _$SettingsAdapter on Adapter<Settings> {
|
||||
type: 'users',
|
||||
kind: 'BelongsTo',
|
||||
instance: (_) => (_ as Settings).user,
|
||||
),
|
||||
'trustedUsers': RelationshipMeta<User>(
|
||||
name: 'trustedUsers',
|
||||
type: 'users',
|
||||
kind: 'HasMany',
|
||||
instance: (_) => (_ as Settings).trustedUsers,
|
||||
)
|
||||
};
|
||||
|
||||
@@ -54,15 +60,19 @@ extension SettingsRelationshipGraphNodeX on RelationshipGraphNode<Settings> {
|
||||
return meta.clone(
|
||||
parent: this is RelationshipMeta ? this as RelationshipMeta : null);
|
||||
}
|
||||
|
||||
RelationshipGraphNode<User> get trustedUsers {
|
||||
final meta = _$SettingsAdapter._kSettingsRelationshipMetas['trustedUsers']
|
||||
as RelationshipMeta<User>;
|
||||
return meta.clone(
|
||||
parent: this is RelationshipMeta ? this as RelationshipMeta : null);
|
||||
}
|
||||
}
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
Settings _$SettingsFromJson(Map<String, dynamic> json) =>
|
||||
Settings()..isLoggedIn = json['isLoggedIn'] as bool;
|
||||
Settings _$SettingsFromJson(Map<String, dynamic> json) => Settings();
|
||||
|
||||
Map<String, dynamic> _$SettingsToJson(Settings instance) => <String, dynamic>{
|
||||
'isLoggedIn': instance.isLoggedIn,
|
||||
};
|
||||
Map<String, dynamic> _$SettingsToJson(Settings instance) => <String, dynamic>{};
|
||||
|
||||
@@ -76,7 +76,7 @@ class AppDetailScreen extends HookConsumerWidget {
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: Text(
|
||||
'This update has a different certificate than the app installed on your device.\n\nHave you used another app store to install this app? If so, you can choose to remove it and re-install it using Zapstore.\n\nIt otherwise could be a malicious update, contact the developer for details.\n\nUpdate certificate hash: ${app.latestMetadata!.apkSignatureHash}',
|
||||
'${app.name} ${app.latestMetadata!.version} has a different Android certificate than version ${app.localApp.value!.installedVersion} installed on your device.\n\nHave you used another app store to install ${app.name}? If so, you can choose to remove it and re-install coming back to this screen.\n\nIt otherwise could be a malicious update, contact the developer for details.\n\nNew certificate hash: ${app.latestMetadata!.apkSignatureHash}',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -126,7 +126,7 @@ extension StringWidget on String {
|
||||
}
|
||||
|
||||
String substringMax(int size) {
|
||||
return substring(0, min(length, 80));
|
||||
return substring(0, min(length, size));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ class AppCard extends HookConsumerWidget {
|
||||
{kZapstoreAppIdentifier}.contains(app.identifier)))
|
||||
AuthorContainer(
|
||||
user: app.signer.value!,
|
||||
text: 'Signed by',
|
||||
beforeText: 'Signed by',
|
||||
oneLine: true,
|
||||
size: 12,
|
||||
),
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:zapstore/models/user.dart';
|
||||
import 'package:zapstore/utils/extensions.dart';
|
||||
import 'package:zapstore/widgets/rounded_image.dart';
|
||||
|
||||
class AuthorContainer extends StatelessWidget {
|
||||
final User user;
|
||||
final String text;
|
||||
final String beforeText;
|
||||
final String afterText;
|
||||
final bool oneLine;
|
||||
final double size;
|
||||
|
||||
const AuthorContainer({
|
||||
super.key,
|
||||
required this.user,
|
||||
this.text = 'Signed by',
|
||||
this.beforeText = 'Signed by',
|
||||
this.afterText = '',
|
||||
this.oneLine = true,
|
||||
this.size = 14,
|
||||
});
|
||||
@@ -28,7 +31,7 @@ class AuthorContainer extends StatelessWidget {
|
||||
if (oneLine)
|
||||
Expanded(
|
||||
child: Text(
|
||||
'$text ${user.nameOrNpub}',
|
||||
'$beforeText ${user.nameOrNpub}',
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(fontSize: size),
|
||||
@@ -39,16 +42,14 @@ class AuthorContainer extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(text),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 1),
|
||||
child: Text(
|
||||
user.nameOrNpub,
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
Text(beforeText),
|
||||
Text(
|
||||
user.nameOrNpub.substringMax(24),
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
Text(afterText),
|
||||
],
|
||||
)
|
||||
],
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:zapstore/main.data.dart';
|
||||
@@ -9,7 +10,7 @@ import 'package:zapstore/widgets/app_drawer.dart';
|
||||
import 'package:zapstore/widgets/author_container.dart';
|
||||
import 'package:zapstore/widgets/wot_container.dart';
|
||||
|
||||
class InstallAlertDialog extends ConsumerWidget {
|
||||
class InstallAlertDialog extends HookConsumerWidget {
|
||||
const InstallAlertDialog({
|
||||
super.key,
|
||||
required this.app,
|
||||
@@ -19,6 +20,7 @@ class InstallAlertDialog extends ConsumerWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final trustedSignerNotifier = useState(false);
|
||||
final user = ref.settings
|
||||
.watchOne('_', alsoWatch: (_) => {_.user})
|
||||
.model!
|
||||
@@ -41,7 +43,9 @@ class InstallAlertDialog extends ConsumerWidget {
|
||||
Gap(20),
|
||||
if (app.signer.value != null)
|
||||
AuthorContainer(
|
||||
user: app.signer.value!, text: 'Signed by', oneLine: true),
|
||||
user: app.signer.value!,
|
||||
beforeText: 'Signed by',
|
||||
oneLine: true),
|
||||
Gap(20),
|
||||
if (app.signer.value != null)
|
||||
WebOfTrustContainer(
|
||||
@@ -53,26 +57,24 @@ class InstallAlertDialog extends ConsumerWidget {
|
||||
minimal: true,
|
||||
labelText: 'Log in to view your own web of trust',
|
||||
),
|
||||
Gap(20),
|
||||
if (app.latestMetadata?.urls.isNotEmpty ?? false)
|
||||
RichText(
|
||||
text: WidgetSpan(
|
||||
child: Wrap(
|
||||
crossAxisAlignment: WrapCrossAlignment.center,
|
||||
children: [
|
||||
Text('This app will be downloaded from '),
|
||||
Text(
|
||||
Uri.parse(app.latestMetadata!.urls.first).host,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
),
|
||||
Text(' and verified.'),
|
||||
],
|
||||
),
|
||||
Gap(16),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Switch(
|
||||
value: trustedSignerNotifier.value,
|
||||
onChanged: (value) {
|
||||
trustedSignerNotifier.value = value;
|
||||
},
|
||||
),
|
||||
),
|
||||
Gap(4),
|
||||
Expanded(
|
||||
child: Text(
|
||||
'Do not ask again for ${app.signer.value!.name} apps',
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -81,16 +83,15 @@ class InstallAlertDialog extends ConsumerWidget {
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: TextButton(
|
||||
onPressed: () {
|
||||
app.install();
|
||||
app.install(alwaysTrustSigner: trustedSignerNotifier.value);
|
||||
// NOTE: can't use context.pop()
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: user != null
|
||||
? Text('Install', style: TextStyle(fontWeight: FontWeight.bold))
|
||||
: Text(
|
||||
'I trust the signer, install the app',
|
||||
textAlign: TextAlign.right,
|
||||
),
|
||||
child: Text(
|
||||
'${trustedSignerNotifier.value ? 'Always trust' : 'Trust'} ${app.signer.value!.name} and install app',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
textAlign: TextAlign.right,
|
||||
),
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:percent_indicator/linear_percent_indicator.dart';
|
||||
import 'package:zapstore/main.data.dart';
|
||||
import 'package:zapstore/models/app.dart';
|
||||
import 'package:zapstore/models/local_app.dart';
|
||||
import 'package:zapstore/utils/extensions.dart';
|
||||
@@ -46,14 +47,17 @@ class InstallButton extends HookConsumerWidget {
|
||||
_ => switch (progress) {
|
||||
IdleInstallProgress() => () {
|
||||
if (app.canInstall) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => InstallAlertDialog(app: app),
|
||||
);
|
||||
final settings = ref.settings.findOneLocalById('_')!;
|
||||
if (settings.trustedUsers.contains(app.signer.value!)) {
|
||||
app.install();
|
||||
} else {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => InstallAlertDialog(app: app),
|
||||
);
|
||||
}
|
||||
} else if (app.canUpdate) {
|
||||
app.install();
|
||||
} else if (app.hasCertificateMismatch) {
|
||||
// nothing
|
||||
} else {
|
||||
context.showError(
|
||||
title: 'Installation not possible',
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:zapstore/main.data.dart';
|
||||
import 'package:zapstore/models/app.dart';
|
||||
import 'package:zapstore/widgets/author_container.dart';
|
||||
|
||||
class SignerAndDeveloperRow extends StatelessWidget {
|
||||
class SignerAndDeveloperRow extends ConsumerWidget {
|
||||
const SignerAndDeveloperRow({
|
||||
super.key,
|
||||
required this.app,
|
||||
@@ -12,7 +14,9 @@ class SignerAndDeveloperRow extends StatelessWidget {
|
||||
final App app;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final settingsState = ref.settings.watchOne('_', remote: false);
|
||||
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
@@ -25,7 +29,7 @@ class SignerAndDeveloperRow extends StatelessWidget {
|
||||
},
|
||||
child: AuthorContainer(
|
||||
user: app.developer.value!,
|
||||
text: 'Developed by',
|
||||
beforeText: 'Developed by',
|
||||
oneLine: false),
|
||||
),
|
||||
if (app.signer.isPresent)
|
||||
@@ -35,8 +39,20 @@ class SignerAndDeveloperRow extends StatelessWidget {
|
||||
Uri.parse('https://njump.me/${app.signer.value!.npub}');
|
||||
launchUrl(url);
|
||||
},
|
||||
child: AuthorContainer(
|
||||
user: app.signer.value!, text: 'Signed by', oneLine: false),
|
||||
child: Row(
|
||||
children: [
|
||||
AuthorContainer(
|
||||
user: app.signer.value!,
|
||||
beforeText: 'Signed by',
|
||||
oneLine: false,
|
||||
afterText: settingsState.hasModel &&
|
||||
settingsState.model!.trustedUsers
|
||||
.contains(app.signer.value!)
|
||||
? '(trusted)'
|
||||
: '',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -9,7 +9,7 @@ import app_links
|
||||
import device_info_plus
|
||||
import path_provider_foundation
|
||||
import shared_preferences_foundation
|
||||
import sqflite
|
||||
import sqflite_darwin
|
||||
import sqlite3_flutter_libs
|
||||
import url_launcher_macos
|
||||
|
||||
|
||||
+97
-60
@@ -5,18 +5,23 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: _fe_analyzer_shared
|
||||
sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7"
|
||||
sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "67.0.0"
|
||||
version: "72.0.0"
|
||||
_macros:
|
||||
dependency: transitive
|
||||
description: dart
|
||||
source: sdk
|
||||
version: "0.3.2"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d"
|
||||
sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.4.1"
|
||||
version: "6.7.0"
|
||||
android_package_manager:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -165,18 +170,18 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: build_runner
|
||||
sha256: "644dc98a0f179b872f612d3eb627924b578897c629788e858157fa5e704ca0c7"
|
||||
sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.11"
|
||||
version: "2.4.13"
|
||||
build_runner_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_runner_core
|
||||
sha256: e3c79f69a64bdfcd8a776a3c28db4eb6e3fb5356d013ae5eb2e52007706d5dbe
|
||||
sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.3.1"
|
||||
version: "7.3.2"
|
||||
built_collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -245,10 +250,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: code_builder
|
||||
sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37
|
||||
sha256: "0ec10bf4a89e4c613960bf1e8b42c64127021740fb21640c29c909826a5eea3e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.10.0"
|
||||
version: "4.10.1"
|
||||
collection:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -293,10 +298,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dart_style
|
||||
sha256: "99e066ce75c89d6b29903d788a7bb9369cf754f7b24bf70bf4b6d6d6b26853b9"
|
||||
sha256: "7856d364b589d1f08986e140938578ed36ed948581fbc3bc9aef1805039ac5ab"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.6"
|
||||
version: "2.3.7"
|
||||
decimal:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -325,10 +330,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: equatable
|
||||
sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2
|
||||
sha256: "567c64b3cb4cf82397aac55f4f0cbd3ca20d77c6c03bedbc4ceaddc08904aef7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.5"
|
||||
version: "2.0.7"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -411,10 +416,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_markdown
|
||||
sha256: f0e599ba89c9946c8e051780f0ec99aba4ba15895e0380a7ab68f420046fc44e
|
||||
sha256: "255b00afa1a7bad19727da6a7780cf3db6c3c12e68d302d85e0ff1fdf173db9e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.4+1"
|
||||
version: "0.7.4+3"
|
||||
flutter_phoenix:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -485,10 +490,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: go_router
|
||||
sha256: ce89c5a993ca5eea74535f798478502c30a625ecb10a1de4d7fef5cd1bcac2a4
|
||||
sha256: "2fd11229f59e23e967b0775df8d5948a519cd7e1e8b6e849729e010587b46539"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "14.4.1"
|
||||
version: "14.6.2"
|
||||
graphs:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -621,10 +626,10 @@ packages:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: json_serializable
|
||||
sha256: ea1432d167339ea9b5bb153f0571d0039607a873d6e04e0117af043f14a1fd4b
|
||||
sha256: c2fcb3920cf2b6ae6845954186420fca40bc0a8abcc84903b7801f17d7050d7c
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.8.0"
|
||||
version: "6.9.0"
|
||||
leak_tracker:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -665,6 +670,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
macros:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: macros
|
||||
sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.2-main.4"
|
||||
markdown:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -701,10 +714,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: mime
|
||||
sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a"
|
||||
sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.6"
|
||||
version: "2.0.0"
|
||||
octo_image:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -741,18 +754,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_android
|
||||
sha256: "6f01f8e37ec30b07bc424b4deabac37cacb1bc7e2e515ad74486039918a37eb7"
|
||||
sha256: "8c4967f8b7cb46dc914e178daa29813d83ae502e0529d7b0478330616a691ef7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.10"
|
||||
version: "2.2.14"
|
||||
path_provider_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_foundation
|
||||
sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
|
||||
sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
version: "2.4.1"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -789,10 +802,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: percent_indicator
|
||||
sha256: c37099ad833a883c9d71782321cb65c3a848c21b6939b6185f0ff6640d05814c
|
||||
sha256: "0d77d5c6fa9b7f60202cedf748b568ba9ba38d3f30405d6ceae4da76f5185462"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.2.3"
|
||||
version: "4.2.4"
|
||||
permission_handler:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -821,10 +834,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: permission_handler_html
|
||||
sha256: af26edbbb1f2674af65a8f4b56e1a6f526156bc273d0e65dd8075fab51c78851
|
||||
sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.3+2"
|
||||
version: "0.1.3+5"
|
||||
permission_handler_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -950,18 +963,18 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: shared_preferences
|
||||
sha256: "746e5369a43170c25816cc472ee016d3a66bc13fcf430c0bc41ad7b4b2922051"
|
||||
sha256: "95f9997ca1fb9799d494d0cb2a780fd7be075818d59f00c43832ed112b158a82"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.2"
|
||||
version: "2.3.3"
|
||||
shared_preferences_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_android
|
||||
sha256: "480ba4345773f56acda9abf5f50bd966f581dac5d514e5fc4a18c62976bbba7e"
|
||||
sha256: "7f172d1b06de5da47b6264c2692ee2ead20bbbc246690427cdb4fc301cd0c549"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.2"
|
||||
version: "2.3.4"
|
||||
shared_preferences_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1014,10 +1027,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_web_socket
|
||||
sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611"
|
||||
sha256: cc36c297b52866d203dbf9332263c94becc2fe0ceaa9681d07b6ef9807023b67
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "2.0.1"
|
||||
skeletonizer:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -1067,34 +1080,58 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqflite
|
||||
sha256: a43e5a27235518c03ca238e7b4732cf35eabe863a369ceba6cbefa537a66f16d
|
||||
sha256: "2d7299468485dca85efeeadf5d38986909c5eb0cd71fd3db2c2f000e6c9454bb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.3+1"
|
||||
version: "2.4.1"
|
||||
sqflite_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqflite_android
|
||||
sha256: "78f489aab276260cdd26676d2169446c7ecd3484bbd5fead4ca14f3ed4dd9ee3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
sqflite_common:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqflite_common
|
||||
sha256: "3da423ce7baf868be70e2c0976c28a1bb2f73644268b7ffa7d2e08eab71f16a4"
|
||||
sha256: "761b9740ecbd4d3e66b8916d784e581861fd3c3553eda85e167bc49fdb68f709"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.5.4"
|
||||
version: "2.5.4+6"
|
||||
sqflite_darwin:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqflite_darwin
|
||||
sha256: "96a698e2bc82bd770a4d6aab00b42396a7c63d9e33513a56945cbccb594c2474"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.1"
|
||||
sqflite_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqflite_platform_interface
|
||||
sha256: "8dd4515c7bdcae0a785b0062859336de775e8c65db81ae33dd5445f35be61920"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
sqlite3:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqlite3
|
||||
sha256: bb174b3ec2527f9c5f680f73a89af8149dd99782fbb56ea88ad0807c5638f2ed
|
||||
sha256: cb7f4e9dc1b52b1fa350f7b3d41c662e75fc3d399555fa4e5efcf267e9a4fbb5
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.7"
|
||||
version: "2.5.0"
|
||||
sqlite3_flutter_libs:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: sqlite3_flutter_libs
|
||||
sha256: "7ae52b23366e5295005022e62fa093f64bfe190810223ea0ebf733a4cd140bce"
|
||||
sha256: "636b0fe8a2de894e5455572f6cbbc458f4ffecfe9f860b79439e27041ea4f0b9"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.26"
|
||||
version: "0.5.27"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1139,10 +1176,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: synchronized
|
||||
sha256: "539ef412b170d65ecdafd780f924e5be3f60032a1128df156adad6c5b373d558"
|
||||
sha256: "69fe30f3a8b04a0be0c15ae6490fc859a78ef4c43ae2dd5e8a623d45bfcf9225"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.0+1"
|
||||
version: "3.3.0+3"
|
||||
system_info2:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -1187,10 +1224,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: typed_data
|
||||
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
|
||||
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.2"
|
||||
version: "1.4.0"
|
||||
universal_io:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1211,34 +1248,34 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_android
|
||||
sha256: f0c73347dfcfa5b3db8bc06e1502668265d39c08f310c29bff4e28eea9699f79
|
||||
sha256: "6fc2f56536ee873eeb867ad176ae15f304ccccc357848b351f6f0d8d4a40d193"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.3.9"
|
||||
version: "6.3.14"
|
||||
url_launcher_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_ios
|
||||
sha256: e43b677296fadce447e987a2f519dcf5f6d1e527dc35d01ffab4fff5b8a7063e
|
||||
sha256: "16a513b6c12bb419304e72ea0ae2ab4fed569920d1c7cb850263fe3acc824626"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.3.1"
|
||||
version: "6.3.2"
|
||||
url_launcher_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_linux
|
||||
sha256: e2b9622b4007f97f504cd64c0128309dfb978ae66adbe944125ed9e1750f06af
|
||||
sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.0"
|
||||
version: "3.2.1"
|
||||
url_launcher_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_macos
|
||||
sha256: "769549c999acdb42b8bcfa7c43d72bf79a382ca7441ab18a808e101149daf672"
|
||||
sha256: "17ba2000b847f334f16626a574c702b196723af2a289e7a93ffcb79acff855c2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.1"
|
||||
version: "3.2.2"
|
||||
url_launcher_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1331,10 +1368,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
sha256: "68d1e89a91ed61ad9c370f9f8b6effed9ae5e0ede22a270bdfa6daf79fc2290a"
|
||||
sha256: "8b338d4486ab3fbc0ba0db9f9b4f5239b6697fcee427939a40e720cbb9ee0a69"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.5.4"
|
||||
version: "5.9.0"
|
||||
win32_registry:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1368,5 +1405,5 @@ packages:
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
sdks:
|
||||
dart: ">=3.4.0 <4.0.0"
|
||||
flutter: ">=3.22.0"
|
||||
dart: ">=3.5.0 <4.0.0"
|
||||
flutter: ">=3.24.0"
|
||||
|
||||
Reference in New Issue
Block a user