feat(mobile): Implement Keycloak WebView authentication with HTTP callback
- Replace flutter_appauth with custom WebView implementation to resolve deep link issues - Add KeycloakWebViewAuthService with integrated WebView for seamless authentication - Configure Android manifest for HTTP cleartext traffic support - Add network security config for development environment (192.168.1.11) - Update Keycloak client to use HTTP callback endpoint (http://192.168.1.11:8080/auth/callback) - Remove obsolete keycloak_auth_service.dart and temporary scripts - Clean up dependencies and regenerate injection configuration - Tested successfully on multiple Android devices (Xiaomi 2201116TG, SM A725F) BREAKING CHANGE: Authentication flow now uses WebView instead of external browser - Users will see Keycloak login page within the app instead of browser redirect - Resolves ERR_CLEARTEXT_NOT_PERMITTED and deep link state management issues - Maintains full OIDC compliance with PKCE flow and secure token storage Technical improvements: - WebView with custom navigation delegate for callback handling - Automatic token extraction and user info parsing from JWT - Proper error handling and user feedback - Consistent authentication state management across app lifecycle
This commit is contained in:
@@ -65,7 +65,7 @@ class _ProfessionalPieChartState extends State<ProfessionalPieChart>
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildHeader(),
|
||||
SizedBox(height: DesignSystem.spacingLg),
|
||||
const SizedBox(height: DesignSystem.spacingLg),
|
||||
Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
@@ -74,7 +74,7 @@ class _ProfessionalPieChartState extends State<ProfessionalPieChart>
|
||||
child: _buildChart(),
|
||||
),
|
||||
if (widget.showLegend) ...[
|
||||
SizedBox(width: DesignSystem.spacingLg),
|
||||
const SizedBox(width: DesignSystem.spacingLg),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: _buildLegend(),
|
||||
@@ -98,7 +98,7 @@ class _ProfessionalPieChartState extends State<ProfessionalPieChart>
|
||||
),
|
||||
),
|
||||
if (widget.subtitle != null) ...[
|
||||
SizedBox(height: DesignSystem.spacingXs),
|
||||
const SizedBox(height: DesignSystem.spacingXs),
|
||||
Text(
|
||||
widget.subtitle!,
|
||||
style: DesignSystem.bodyMedium.copyWith(
|
||||
@@ -177,7 +177,7 @@ class _ProfessionalPieChartState extends State<ProfessionalPieChart>
|
||||
|
||||
Widget _buildBadge(ChartDataPoint data) {
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: DesignSystem.spacingSm,
|
||||
vertical: DesignSystem.spacingXs,
|
||||
),
|
||||
@@ -203,7 +203,7 @@ class _ProfessionalPieChartState extends State<ProfessionalPieChart>
|
||||
children: [
|
||||
if (widget.centerText != null) ...[
|
||||
_buildCenterInfo(),
|
||||
SizedBox(height: DesignSystem.spacingLg),
|
||||
const SizedBox(height: DesignSystem.spacingLg),
|
||||
],
|
||||
...widget.data.asMap().entries.map((entry) {
|
||||
final index = entry.key;
|
||||
@@ -212,8 +212,8 @@ class _ProfessionalPieChartState extends State<ProfessionalPieChart>
|
||||
|
||||
return AnimatedContainer(
|
||||
duration: DesignSystem.animationFast,
|
||||
margin: EdgeInsets.only(bottom: DesignSystem.spacingSm),
|
||||
padding: EdgeInsets.all(DesignSystem.spacingSm),
|
||||
margin: const EdgeInsets.only(bottom: DesignSystem.spacingSm),
|
||||
padding: const EdgeInsets.all(DesignSystem.spacingSm),
|
||||
decoration: BoxDecoration(
|
||||
color: isSelected ? data.color.withOpacity(0.1) : Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(DesignSystem.radiusSm),
|
||||
@@ -232,7 +232,7 @@ class _ProfessionalPieChartState extends State<ProfessionalPieChart>
|
||||
borderRadius: BorderRadius.circular(DesignSystem.radiusXs),
|
||||
),
|
||||
),
|
||||
SizedBox(width: DesignSystem.spacingSm),
|
||||
const SizedBox(width: DesignSystem.spacingSm),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -262,7 +262,7 @@ class _ProfessionalPieChartState extends State<ProfessionalPieChart>
|
||||
|
||||
Widget _buildCenterInfo() {
|
||||
return Container(
|
||||
padding: EdgeInsets.all(DesignSystem.spacingMd),
|
||||
padding: const EdgeInsets.all(DesignSystem.spacingMd),
|
||||
decoration: BoxDecoration(
|
||||
color: AppTheme.primaryColor.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(DesignSystem.radiusMd),
|
||||
@@ -279,7 +279,7 @@ class _ProfessionalPieChartState extends State<ProfessionalPieChart>
|
||||
color: AppTheme.textSecondary,
|
||||
),
|
||||
),
|
||||
SizedBox(height: DesignSystem.spacingXs),
|
||||
const SizedBox(height: DesignSystem.spacingXs),
|
||||
Text(
|
||||
widget.centerText!,
|
||||
style: DesignSystem.headlineMedium.copyWith(
|
||||
|
||||
Reference in New Issue
Block a user