two_factor_authentication_page.dart 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter/services.dart';
  3. import 'package:flutter/widgets.dart';
  4. import 'package:photos/services/user_service.dart';
  5. import 'package:photos/ui/lifecycle_event_handler.dart';
  6. import 'package:pinput/pin_put/pin_put.dart';
  7. class TwoFactorAuthenticationPage extends StatefulWidget {
  8. final String sessionID;
  9. const TwoFactorAuthenticationPage(this.sessionID, {Key key})
  10. : super(key: key);
  11. @override
  12. _TwoFactorAuthenticationPageState createState() =>
  13. _TwoFactorAuthenticationPageState();
  14. }
  15. class _TwoFactorAuthenticationPageState
  16. extends State<TwoFactorAuthenticationPage> {
  17. final _pinController = TextEditingController();
  18. final _pinPutDecoration = BoxDecoration(
  19. border: Border.all(color: Color.fromRGBO(45, 194, 98, 1.0)),
  20. borderRadius: BorderRadius.circular(15.0),
  21. );
  22. String _code = "";
  23. LifecycleEventHandler _lifecycleEventHandler;
  24. @override
  25. void initState() {
  26. _lifecycleEventHandler = LifecycleEventHandler(
  27. resumeCallBack: () async {
  28. if (mounted) {
  29. final data = await Clipboard.getData(Clipboard.kTextPlain);
  30. if (data != null && data.text != null && data.text.length == 6) {
  31. _pinController.text = data.text;
  32. }
  33. }
  34. },
  35. );
  36. WidgetsBinding.instance.addObserver(_lifecycleEventHandler);
  37. super.initState();
  38. }
  39. @override
  40. void dispose() {
  41. WidgetsBinding.instance.removeObserver(_lifecycleEventHandler);
  42. super.dispose();
  43. }
  44. @override
  45. Widget build(BuildContext context) {
  46. return Scaffold(
  47. appBar: AppBar(
  48. title: Text(
  49. "two-factor authentication",
  50. ),
  51. ),
  52. body: _getBody(),
  53. );
  54. }
  55. Widget _getBody() {
  56. return Column(
  57. crossAxisAlignment: CrossAxisAlignment.stretch,
  58. mainAxisAlignment: MainAxisAlignment.center,
  59. mainAxisSize: MainAxisSize.max,
  60. children: [
  61. Text(
  62. "enter the 6-digit code from\nyour authenticator app",
  63. style: TextStyle(
  64. height: 1.4,
  65. fontSize: 16,
  66. ),
  67. textAlign: TextAlign.center,
  68. ),
  69. Padding(padding: EdgeInsets.all(32)),
  70. Padding(
  71. padding: const EdgeInsets.fromLTRB(40, 0, 40, 0),
  72. child: PinPut(
  73. fieldsCount: 6,
  74. onSubmit: (String code) {
  75. _verifyTwoFactorCode(code);
  76. },
  77. onChanged: (String pin) {
  78. setState(() {
  79. _code = pin;
  80. });
  81. },
  82. controller: _pinController,
  83. submittedFieldDecoration: _pinPutDecoration.copyWith(
  84. borderRadius: BorderRadius.circular(20.0),
  85. ),
  86. selectedFieldDecoration: _pinPutDecoration,
  87. followingFieldDecoration: _pinPutDecoration.copyWith(
  88. borderRadius: BorderRadius.circular(5.0),
  89. border: Border.all(
  90. color: Color.fromRGBO(45, 194, 98, 0.5),
  91. ),
  92. ),
  93. inputDecoration: InputDecoration(
  94. focusedBorder: InputBorder.none,
  95. border: InputBorder.none,
  96. counterText: '',
  97. ),
  98. autofocus: true,
  99. ),
  100. ),
  101. Padding(padding: EdgeInsets.all(24)),
  102. Container(
  103. padding: const EdgeInsets.fromLTRB(80, 0, 80, 0),
  104. width: double.infinity,
  105. height: 64,
  106. child: OutlinedButton(
  107. child: Text("verify"),
  108. onPressed: _code.length == 6
  109. ? () async {
  110. _verifyTwoFactorCode(_code);
  111. }
  112. : null,
  113. ),
  114. ),
  115. Padding(padding: EdgeInsets.all(30)),
  116. GestureDetector(
  117. behavior: HitTestBehavior.opaque,
  118. onTap: () {
  119. UserService.instance.recoverTwoFactor(context, widget.sessionID);
  120. },
  121. child: Container(
  122. padding: EdgeInsets.all(10),
  123. child: Center(
  124. child: Text(
  125. "lost device?",
  126. style: TextStyle(
  127. decoration: TextDecoration.underline,
  128. fontSize: 12,
  129. ),
  130. ),
  131. ),
  132. ),
  133. ),
  134. ],
  135. );
  136. }
  137. Future<void> _verifyTwoFactorCode(String code) async {
  138. await UserService.instance.verifyTwoFactor(context, widget.sessionID, code);
  139. }
  140. }