@@ -32,154 +32,80 @@ import 'package:flutter/material.dart';
3232
3333import 'package:flutter_form_builder/flutter_form_builder.dart' ;
3434import 'package:solidpod/solidpod.dart'
35- show checkLoggedIn, getWebId, KeyManager, verifySecurityKey;
36-
37- import 'package:solidui/src/widgets/solid_popup_login.dart' ;
38-
39- /// Check if the user is logged in and prompt for login if required.
40- ///
41- /// This function checks whether the user is currently logged in to their
42- /// Solid Pod. If not logged in, it displays a login dialog to prompt the
43- /// user to authenticate.
44- ///
45- /// [context] - The build context for displaying dialogs
46- /// [child] - The child widget to return to after login
35+ show
36+ checkLoggedIn,
37+ getWebId,
38+ KeyManager,
39+ verifySecurityKey,
40+ SecurityKeyUI,
41+ SecurityStrings;
42+
43+ /// Login if the user has not done so.
4744///
48- /// Returns `true` if the user is logged in or successfully logs in,
49- /// `false` if the user cancels the login or login fails.
45+ /// [context] is the build context.
46+ /// [loginCallback] is a callback function that handles the login UI.
47+ /// If no callback is provided, this function simply checks if the user is
48+ /// logged in.
5049
5150Future <bool > loginIfRequired (
52- BuildContext context,
53- Widget child,
54- ) async {
55- if (await checkLoggedIn ()) {
56- return true ;
51+ BuildContext context, {
52+ Future <void > Function (BuildContext )? loginCallback,
53+ }) async {
54+ final loggedIn = await checkLoggedIn ();
55+ if (! loggedIn && context.mounted && loginCallback != null ) {
56+ await loginCallback (context);
5757 }
58-
59- if (! context.mounted) return false ;
60-
61- // Show login popup dialog.
62-
63- final result = await showDialog <bool >(
64- context: context,
65- barrierDismissible: false ,
66- builder: (dialogContext) => const SolidPopupLogin (),
67- );
68-
69- // Return whether the login was successful.
70-
71- return result ?? false ;
58+ return checkLoggedIn ();
7259}
7360
7461/// Ask for the security key from the user if the security key is not available
75- /// or cannot be verified using the verification key stored in Pods.
76- ///
77- /// This function checks if a security key is already cached. If not, it prompts
78- /// the user to enter their security key and verifies it against the verification
79- /// key stored in their Pod.
80- ///
81- /// [context] - The build context for displaying dialogs
82- /// [child] - The child widget to return to after entering the key
83- ///
84- /// Returns `true` if the security key is available or successfully entered,
85- /// `false` if the user cancels the operation.
62+ /// or cannot be verfied using the verification key stored in PODs.
8663
87- Future <bool > getKeyFromUserIfRequired (
64+ Future <void > getKeyFromUserIfRequired (
8865 BuildContext context,
8966 Widget child,
9067) async {
9168 if (await KeyManager .hasSecurityKey ()) {
92- return true ;
69+ return ;
70+ } else {
71+ final verificationKey = await KeyManager .getVerificationKey ();
72+ // Get the webId to display in the security key prompt.
73+
74+ final webId = await getWebId ();
75+
76+ const inputKey = 'security_key' ;
77+ final inputField = (
78+ fieldKey: inputKey,
79+ fieldLabel: 'Security Key' ,
80+ validateFunc: (key) {
81+ assert (key != null );
82+ return verifySecurityKey (key as String , verificationKey)
83+ ? null
84+ : 'Incorrect Security Key' ;
85+ }
86+ );
87+
88+ // Use the unified SecurityKeyUI widget with the appropriate configuration.
89+
90+ final securityKeyInput = SecurityKeyUI (
91+ webId: webId,
92+ title: 'Security Key' ,
93+ message: SecurityStrings .securityKeyPrompt,
94+ inputFields: [inputField],
95+ formKey: GlobalKey <FormBuilderState >(),
96+ submitFunc: (formDataMap) async {
97+ await KeyManager .setSecurityKey (formDataMap[inputKey].toString ());
98+ debugPrint ('Security key saved' );
99+ if (context.mounted) Navigator .pop (context);
100+ },
101+ child: child,
102+ );
103+
104+ if (context.mounted) {
105+ await Navigator .push (
106+ context,
107+ MaterialPageRoute (builder: (context) => securityKeyInput),
108+ );
109+ }
93110 }
94-
95- final verificationKey = await KeyManager .getVerificationKey ();
96-
97- // Get the webId to display in the security key prompt.
98-
99- final webId = await getWebId ();
100-
101- if (! context.mounted) return false ;
102-
103- // Create a simple security key input dialog.
104-
105- final keyController = TextEditingController ();
106- final formKey = GlobalKey <FormBuilderState >();
107-
108- final result = await showDialog <bool >(
109- context: context,
110- barrierDismissible: false ,
111- builder: (dialogContext) => AlertDialog (
112- title: const Text ('Security Key Required' ),
113- content: Column (
114- mainAxisSize: MainAxisSize .min,
115- crossAxisAlignment: CrossAxisAlignment .start,
116- children: [
117- Text (
118- 'Currently logged in as:' ,
119- style: Theme .of (dialogContext).textTheme.bodySmall,
120- ),
121- const SizedBox (height: 4 ),
122- Text (
123- webId ?? 'Not logged in' ,
124- style: Theme .of (dialogContext).textTheme.bodyMedium? .copyWith (
125- color: webId != null ? Colors .green : Colors .red,
126- fontWeight: FontWeight .bold,
127- ),
128- ),
129- const SizedBox (height: 16 ),
130- const Text (
131- 'Please enter your security key to access encrypted data:' ,
132- ),
133- const SizedBox (height: 16 ),
134- FormBuilder (
135- key: formKey,
136- child: FormBuilderTextField (
137- name: 'security_key' ,
138- controller: keyController,
139- obscureText: true ,
140- decoration: const InputDecoration (
141- labelText: 'Security Key' ,
142- border: OutlineInputBorder (),
143- ),
144- validator: (value) {
145- if (value == null || value.isEmpty) {
146- return 'Please enter a security key' ;
147- }
148- if (! verifySecurityKey (value, verificationKey)) {
149- return 'Incorrect security key' ;
150- }
151- return null ;
152- },
153- ),
154- ),
155- ],
156- ),
157- actions: [
158- TextButton (
159- onPressed: () {
160- Navigator .pop (dialogContext, false );
161- },
162- child: const Text ('Cancel' ),
163- ),
164- ElevatedButton (
165- onPressed: () async {
166- if (formKey.currentState? .saveAndValidate () ?? false ) {
167- final key = keyController.text;
168- await KeyManager .setSecurityKey (key);
169- if (dialogContext.mounted) {
170- Navigator .pop (dialogContext, true );
171- }
172- }
173- },
174- child: const Text ('Submit' ),
175- ),
176- ],
177- ),
178- );
179-
180- keyController.dispose ();
181-
182- // Return whether the key was successfully entered.
183-
184- return result ?? false ;
185111}
0 commit comments