123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- import 'dart:async';
- import 'dart:io';
- import 'package:expandable/expandable.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter_windowmanager/flutter_windowmanager.dart';
- import 'package:photos/core/configuration.dart';
- import 'package:photos/core/event_bus.dart';
- import 'package:photos/ente_theme_data.dart';
- import 'package:photos/events/two_factor_status_change_event.dart';
- import 'package:photos/services/user_service.dart';
- import 'package:photos/ui/account/sessions_page.dart';
- import 'package:photos/ui/common/loading_widget.dart';
- import 'package:photos/ui/settings/common_settings.dart';
- import 'package:photos/ui/settings/settings_section_title.dart';
- import 'package:photos/ui/settings/settings_text_item.dart';
- import 'package:photos/ui/tools/app_lock.dart';
- import 'package:photos/utils/auth_util.dart';
- import 'package:photos/utils/toast_util.dart';
- class SecuritySectionWidget extends StatefulWidget {
- const SecuritySectionWidget({Key key}) : super(key: key);
- @override
- State<SecuritySectionWidget> createState() => _SecuritySectionWidgetState();
- }
- class _SecuritySectionWidgetState extends State<SecuritySectionWidget> {
- static const kAuthToViewSessions =
- "Please authenticate to view your active sessions";
- final _config = Configuration.instance;
- StreamSubscription<TwoFactorStatusChangeEvent> _twoFactorStatusChangeEvent;
- @override
- void initState() {
- super.initState();
- _twoFactorStatusChangeEvent =
- Bus.instance.on<TwoFactorStatusChangeEvent>().listen((event) async {
- if (mounted) {
- setState(() {});
- }
- });
- }
- @override
- void dispose() {
- _twoFactorStatusChangeEvent.cancel();
- super.dispose();
- }
- @override
- Widget build(BuildContext context) {
- return ExpandablePanel(
- header: const SettingsSectionTitle("Security"),
- collapsed: Container(),
- expanded: _getSectionOptions(context),
- theme: getExpandableTheme(context),
- );
- }
- Widget _getSectionOptions(BuildContext context) {
- final List<Widget> children = [];
- if (_config.hasConfiguredAccount()) {
- children.addAll(
- [
- const Padding(padding: EdgeInsets.all(2)),
- SizedBox(
- height: 48,
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Text(
- "Two-factor",
- style: Theme.of(context).textTheme.subtitle1,
- ),
- FutureBuilder(
- future: UserService.instance.fetchTwoFactorStatus(),
- builder: (_, snapshot) {
- if (snapshot.hasData) {
- return Switch.adaptive(
- value: snapshot.data,
- onChanged: (value) async {
- AppLock.of(context).setEnabled(false);
- String reason =
- "Please authenticate to configure two-factor authentication";
- final result = await requestAuthentication(reason);
- AppLock.of(context).setEnabled(
- Configuration.instance.shouldShowLockScreen(),
- );
- if (!result) {
- showToast(context, reason);
- return;
- }
- if (value) {
- UserService.instance.setupTwoFactor(context);
- } else {
- _disableTwoFactor();
- }
- },
- );
- } else if (snapshot.hasError) {
- return Icon(
- Icons.error_outline,
- color: Colors.white.withOpacity(0.8),
- );
- }
- return const EnteLoadingWidget();
- },
- ),
- ],
- ),
- ),
- ],
- );
- }
- children.addAll([
- sectionOptionDivider,
- SizedBox(
- height: 48,
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Text(
- "Lockscreen",
- style: Theme.of(context).textTheme.subtitle1,
- ),
- Switch.adaptive(
- value: _config.shouldShowLockScreen(),
- onChanged: (value) async {
- AppLock.of(context).disable();
- final result = await requestAuthentication(
- "Please authenticate to change lockscreen setting",
- );
- if (result) {
- AppLock.of(context).setEnabled(value);
- _config.setShouldShowLockScreen(value);
- setState(() {});
- } else {
- AppLock.of(context)
- .setEnabled(_config.shouldShowLockScreen());
- }
- },
- ),
- ],
- ),
- ),
- ]);
- if (Platform.isAndroid) {
- children.addAll(
- [
- sectionOptionDivider,
- SizedBox(
- height: 48,
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Text(
- "Hide from recents",
- style: Theme.of(context).textTheme.subtitle1,
- ),
- Switch.adaptive(
- value: _config.shouldHideFromRecents(),
- onChanged: (value) async {
- if (value) {
- AlertDialog alert = AlertDialog(
- title: const Text("Hide from recents?"),
- content: SingleChildScrollView(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.start,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: const [
- Text(
- "Hiding from the task switcher will prevent you from taking screenshots in this app.",
- style: TextStyle(
- height: 1.5,
- ),
- ),
- Padding(padding: EdgeInsets.all(8)),
- Text(
- "Are you sure?",
- style: TextStyle(
- height: 1.5,
- ),
- ),
- ],
- ),
- ),
- actions: [
- TextButton(
- child: Text(
- "No",
- style: TextStyle(
- color: Theme.of(context)
- .colorScheme
- .defaultTextColor,
- ),
- ),
- onPressed: () {
- Navigator.of(context, rootNavigator: true)
- .pop('dialog');
- },
- ),
- TextButton(
- child: Text(
- "Yes",
- style: TextStyle(
- color: Theme.of(context)
- .colorScheme
- .defaultTextColor,
- ),
- ),
- onPressed: () async {
- Navigator.of(context, rootNavigator: true)
- .pop('dialog');
- await _config.setShouldHideFromRecents(true);
- await FlutterWindowManager.addFlags(
- FlutterWindowManager.FLAG_SECURE,
- );
- setState(() {});
- },
- ),
- ],
- );
- showDialog(
- context: context,
- builder: (BuildContext context) {
- return alert;
- },
- );
- } else {
- await _config.setShouldHideFromRecents(false);
- await FlutterWindowManager.clearFlags(
- FlutterWindowManager.FLAG_SECURE,
- );
- setState(() {});
- }
- },
- ),
- ],
- ),
- ),
- ],
- );
- }
- children.addAll([
- sectionOptionDivider,
- GestureDetector(
- behavior: HitTestBehavior.translucent,
- onTap: () async {
- AppLock.of(context).setEnabled(false);
- final result = await requestAuthentication(kAuthToViewSessions);
- AppLock.of(context)
- .setEnabled(Configuration.instance.shouldShowLockScreen());
- if (!result) {
- showToast(context, kAuthToViewSessions);
- return;
- }
- Navigator.of(context).push(
- MaterialPageRoute(
- builder: (BuildContext context) {
- return const SessionsPage();
- },
- ),
- );
- },
- child: const SettingsTextItem(
- text: "Active sessions",
- icon: Icons.navigate_next,
- ),
- ),
- ]);
- return Column(
- children: children,
- );
- }
- void _disableTwoFactor() {
- AlertDialog alert = AlertDialog(
- title: const Text("Disable two-factor"),
- content: const Text(
- "Are you sure you want to disable two-factor authentication?",
- ),
- actions: [
- TextButton(
- child: Text(
- "No",
- style: TextStyle(
- color: Theme.of(context).buttonColor,
- ),
- ),
- onPressed: () {
- Navigator.of(context, rootNavigator: true).pop('dialog');
- },
- ),
- TextButton(
- child: const Text(
- "Yes",
- style: TextStyle(
- color: Colors.red,
- ),
- ),
- onPressed: () async {
- await UserService.instance.disableTwoFactor(context);
- Navigator.of(context, rootNavigator: true).pop('dialog');
- },
- ),
- ],
- );
- showDialog(
- context: context,
- builder: (BuildContext context) {
- return alert;
- },
- );
- }
- }
|