Skip to content

Commit a684f63

Browse files
authored
Merge pull request #49 from headlines-toolkit/fix_auth_verify_code_in_demo
Fix_auth_verify_code_in_demo
2 parents b966daa + 06acb9a commit a684f63

File tree

6 files changed

+145
-65
lines changed

6 files changed

+145
-65
lines changed

lib/authentication/view/authentication_page.dart

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -48,20 +48,18 @@ class AuthenticationPage extends StatelessWidget {
4848
backgroundColor: Colors.transparent,
4949
elevation: 0,
5050
// Conditionally add the leading close button only in linking context
51-
leading:
52-
isLinkingContext
53-
? IconButton(
54-
icon: const Icon(Icons.close),
55-
tooltip:
56-
MaterialLocalizations.of(
57-
context,
58-
).closeButtonTooltip, // Accessibility
59-
onPressed: () {
60-
// Navigate back to the account page when close is pressed
61-
context.goNamed(Routes.accountName);
62-
},
63-
)
64-
: null, // No leading button if not linking (relies on system back if pushed)
51+
leading: isLinkingContext
52+
? IconButton(
53+
icon: const Icon(Icons.close),
54+
tooltip: MaterialLocalizations.of(
55+
context,
56+
).closeButtonTooltip, // Accessibility
57+
onPressed: () {
58+
// Navigate back to the account page when close is pressed
59+
context.goNamed(Routes.accountName);
60+
},
61+
)
62+
: null, // No leading button if not linking (relies on system back if pushed)
6563
),
6664
body: SafeArea(
6765
child: BlocConsumer<AuthenticationBloc, AuthenticationState>(
@@ -130,15 +128,15 @@ class AuthenticationPage extends StatelessWidget {
130128
// --- Email Sign-In Button ---
131129
ElevatedButton.icon(
132130
icon: const Icon(Icons.email_outlined),
133-
onPressed:
134-
isLoading
135-
? null
136-
: () {
137-
context.goNamed(
138-
Routes.requestCodeName,
139-
extra: isLinkingContext,
140-
);
141-
},
131+
onPressed: isLoading
132+
? null
133+
: () {
134+
context.goNamed(
135+
isLinkingContext
136+
? Routes.linkingRequestCodeName
137+
: Routes.requestCodeName,
138+
);
139+
},
142140
label: Text(l10n.authenticationEmailSignInButton),
143141
style: ElevatedButton.styleFrom(
144142
padding: const EdgeInsets.symmetric(
@@ -153,12 +151,11 @@ class AuthenticationPage extends StatelessWidget {
153151
if (showAnonymousButton) ...[
154152
OutlinedButton.icon(
155153
icon: const Icon(Icons.person_outline),
156-
onPressed:
157-
isLoading
158-
? null
159-
: () => context.read<AuthenticationBloc>().add(
160-
const AuthenticationAnonymousSignInRequested(),
161-
),
154+
onPressed: isLoading
155+
? null
156+
: () => context.read<AuthenticationBloc>().add(
157+
const AuthenticationAnonymousSignInRequested(),
158+
),
162159
label: Text(l10n.authenticationAnonymousSignInButton),
163160
style: OutlinedButton.styleFrom(
164161
padding: const EdgeInsets.symmetric(

lib/authentication/view/request_code_page.dart

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ class _RequestCodeView extends StatelessWidget {
6060
// If linking, go back to Auth page preserving the linking query param.
6161
context.goNamed(
6262
Routes.authenticationName,
63-
queryParameters: {'context': 'linking'},
63+
queryParameters:
64+
isLinkingContext ? {'context': 'linking'} : const {},
6465
);
6566
} else {
6667
// If normal sign-in, just go back to the Auth page.
@@ -84,7 +85,9 @@ class _RequestCodeView extends StatelessWidget {
8485
} else if (state is AuthenticationCodeSentSuccess) {
8586
// Navigate to the code verification page on success, passing the email
8687
context.goNamed(
87-
Routes.verifyCodeName,
88+
isLinkingContext
89+
? Routes.linkingVerifyCodeName
90+
: Routes.verifyCodeName,
8891
pathParameters: {'email': state.email},
8992
);
9093
}

lib/main.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ void main() async {
3434
enabled: true,
3535
builder: (context) => appWidget,
3636
tools: const [DeviceSection()],
37+
backgroundColor: Colors.black87,
3738
),
3839
);
3940
} else {

lib/router/router.dart

Lines changed: 70 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -135,23 +135,47 @@ GoRouter createRouter({
135135
appStatus == AppStatus.authenticated) {
136136
print(' Redirect Decision: User is $appStatus.');
137137

138-
final isLinkingContext =
139-
currentUri.queryParameters['context'] == 'linking';
138+
final isLinkingContextQueryPresent = state.uri.queryParameters['context'] == 'linking';
139+
final isLinkingPathSegmentPresent = currentLocation.contains('/linking/');
140140

141-
// If an authenticated/anonymous user tries to access the BASE /authentication path
142-
// AND it's NOT for account linking, redirect them to the feed.
143-
if (currentLocation == authenticationPath && !isLinkingContext) {
141+
// Determine if the current location is part of any linking flow (either via query or path segment)
142+
final isAnyLinkingContext = isLinkingContextQueryPresent || isLinkingPathSegmentPresent;
143+
144+
// If an authenticated/anonymous user is on any authentication-related path:
145+
if (currentLocation.startsWith(authenticationPath)) {
146+
print(' Debug: Auth path detected. Current Location: $currentLocation');
147+
print(' Debug: URI Query Parameters: ${state.uri.queryParameters}');
148+
print(' Debug: isLinkingContextQueryPresent: $isLinkingContextQueryPresent');
149+
print(' Debug: isLinkingPathSegmentPresent: $isLinkingPathSegmentPresent');
150+
print(' Debug: isAnyLinkingContext evaluated to: $isAnyLinkingContext');
151+
152+
// If the user is authenticated, always redirect away from auth paths.
153+
if (appStatus == AppStatus.authenticated) {
154+
print(
155+
' Action: Authenticated user on auth path ($currentLocation). Redirecting to $feedPath',
156+
);
157+
return feedPath;
158+
}
159+
160+
// If the user is anonymous, allow navigation within auth paths if in a linking context.
161+
// Otherwise, redirect anonymous users trying to access non-linking auth paths to feed.
162+
if (isAnyLinkingContext) {
163+
print(
164+
' Action: Anonymous user on auth linking path ($currentLocation). Allowing navigation.',
165+
);
166+
return null;
167+
} else {
168+
print(
169+
' Action: Anonymous user trying to access non-linking auth path ($currentLocation). Redirecting to $feedPath',
170+
);
171+
return feedPath;
172+
}
173+
}
174+
// Allow access to other routes (non-auth paths)
144175
print(
145-
' Action: $appStatus user trying to access base auth path without linking context. Redirecting to $feedPath',
176+
' Action: Allowing navigation to $currentLocation for $appStatus user (non-auth path).',
146177
);
147-
return feedPath;
148-
}
149-
150-
// Allow access to other routes (including auth sub-routes if linking, or any other app route)
151-
print(
152-
' Action: Allowing navigation to $currentLocation for $appStatus user.',
153-
);
154-
return null;
178+
return null;
155179
}
156180

157181
// Fallback (should ideally not be reached if all statuses are handled)
@@ -200,24 +224,41 @@ GoRouter createRouter({
200224
);
201225
},
202226
routes: [
227+
// Nested route for account linking flow (defined first for priority)
203228
GoRoute(
204-
path: Routes.requestCode, // Use new path
205-
name: Routes.requestCodeName, // Use new name
206-
builder: (context, state) {
207-
// Extract the linking context flag from 'extra', default to false.
208-
final isLinking = (state.extra as bool?) ?? false;
209-
return RequestCodePage(isLinkingContext: isLinking);
210-
},
229+
path: Routes.accountLinking, // This is 'linking'
230+
name: Routes.accountLinkingName, // Name for the linking segment
231+
builder: (context, state) => const SizedBox.shrink(), // Placeholder
232+
routes: [
233+
GoRoute(
234+
path: Routes.requestCode, // Path: /authentication/linking/request-code
235+
name: Routes.linkingRequestCodeName,
236+
builder: (context, state) =>
237+
const RequestCodePage(isLinkingContext: true),
238+
),
239+
GoRoute(
240+
path: '${Routes.verifyCode}/:email', // Path: /authentication/linking/verify-code/:email
241+
name: Routes.linkingVerifyCodeName,
242+
builder: (context, state) {
243+
final email = state.pathParameters['email']!;
244+
return EmailCodeVerificationPage(email: email);
245+
},
246+
),
247+
],
211248
),
249+
// Non-linking authentication routes (defined after linking routes)
212250
GoRoute(
213-
path:
214-
'${Routes.verifyCode}/:email', // Use new path with email parameter
215-
name: Routes.verifyCodeName, // Use new name
251+
path: Routes.requestCode,
252+
name: Routes.requestCodeName,
253+
builder: (context, state) =>
254+
const RequestCodePage(isLinkingContext: false),
255+
),
256+
GoRoute(
257+
path: '${Routes.verifyCode}/:email',
258+
name: Routes.verifyCodeName,
216259
builder: (context, state) {
217-
final email = state.pathParameters['email']!; // Extract email
218-
return EmailCodeVerificationPage(
219-
email: email,
220-
); // Use renamed page
260+
final email = state.pathParameters['email']!;
261+
return EmailCodeVerificationPage(email: email);
221262
},
222263
),
223264
],
@@ -731,7 +772,7 @@ GoRouter createRouter({
731772
.read<
732773
HtDataRepository<Headline>
733774
>(),
734-
),
775+
),
735776
),
736777
BlocProvider(
737778
create:

lib/router/routes.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ abstract final class Routes {
5858
static const verifyCode = 'verify-code';
5959
static const verifyCodeName = 'verifyCode';
6060

61+
// Linking-specific authentication routes
62+
static const linkingRequestCode = 'linking/request-code';
63+
static const linkingRequestCodeName = 'linkingRequestCode';
64+
static const linkingVerifyCode = 'linking/verify-code';
65+
static const linkingVerifyCodeName = 'linkingVerifyCode';
66+
6167
// --- Settings Sub-Routes (relative to /account/settings) ---
6268
static const settingsAppearance = 'appearance';
6369
static const settingsAppearanceName = 'settingsAppearance';

pubspec.lock

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,14 @@ packages:
8989
url: "https://pub.dev"
9090
source: hosted
9191
version: "1.4.0"
92+
checked_yaml:
93+
dependency: transitive
94+
description:
95+
name: checked_yaml
96+
sha256: "959525d3162f249993882720d52b7e0c833978df229be20702b33d48d91de70f"
97+
url: "https://pub.dev"
98+
source: hosted
99+
version: "2.0.4"
92100
cli_config:
93101
dependency: transitive
94102
description:
@@ -97,6 +105,14 @@ packages:
97105
url: "https://pub.dev"
98106
source: hosted
99107
version: "0.2.0"
108+
cli_util:
109+
dependency: transitive
110+
description:
111+
name: cli_util
112+
sha256: ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c
113+
url: "https://pub.dev"
114+
source: hosted
115+
version: "0.4.2"
100116
clock:
101117
dependency: transitive
102118
description:
@@ -270,6 +286,14 @@ packages:
270286
url: "https://pub.dev"
271287
source: hosted
272288
version: "9.1.1"
289+
flutter_launcher_icons:
290+
dependency: "direct main"
291+
description:
292+
name: flutter_launcher_icons
293+
sha256: "10f13781741a2e3972126fae08393d3c4e01fa4cd7473326b94b72cf594195e7"
294+
url: "https://pub.dev"
295+
source: hosted
296+
version: "0.14.4"
273297
flutter_localizations:
274298
dependency: "direct main"
275299
description: flutter
@@ -356,7 +380,7 @@ packages:
356380
description:
357381
path: "."
358382
ref: HEAD
359-
resolved-ref: "028ebfa29ebc8f95c2da30fee68566723d1e6897"
383+
resolved-ref: "3a8dc5ff81c59805fa59996517eb0fdf136a0b67"
360384
url: "https://github.com/headlines-toolkit/ht-auth-inmemory"
361385
source: git
362386
version: "0.0.0"
@@ -501,10 +525,18 @@ packages:
501525
dependency: transitive
502526
description:
503527
name: js
504-
sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc"
528+
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
505529
url: "https://pub.dev"
506530
source: hosted
507-
version: "0.7.2"
531+
version: "0.6.7"
532+
js_interop:
533+
dependency: "direct main"
534+
description:
535+
name: js_interop
536+
sha256: "7ec859c296958ccea34dc770504bd3ff4ae52fdd9e7eeb2bacc7081ad476a1f5"
537+
url: "https://pub.dev"
538+
source: hosted
539+
version: "0.0.1"
508540
json_annotation:
509541
dependency: transitive
510542
description:
@@ -1050,10 +1082,10 @@ packages:
10501082
dependency: transitive
10511083
description:
10521084
name: watcher
1053-
sha256: "69da27e49efa56a15f8afe8f4438c4ec02eff0a117df1b22ea4aad194fe1c104"
1085+
sha256: "0b7fd4a0bbc4b92641dbf20adfd7e3fd1398fe17102d94b674234563e110088a"
10541086
url: "https://pub.dev"
10551087
source: hosted
1056-
version: "1.1.1"
1088+
version: "1.1.2"
10571089
web:
10581090
dependency: transitive
10591091
description:

0 commit comments

Comments
 (0)