two_factor_authentication_page.dart 4.4 KB

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