forked from baron/baron-sso
/api/v1/user/me 세션 시각을 추가하고 userfront 대시보드 Unknown 세션 시간 문제 수정
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import '../../profile/data/models/user_profile_model.dart';
|
||||
|
||||
DateTime? resolveDashboardSessionIssuedAt({
|
||||
String? token,
|
||||
UserProfile? profile,
|
||||
}) {
|
||||
final tokenIssuedAt = _getJwtIssuedAt(token);
|
||||
if (tokenIssuedAt != null) {
|
||||
return tokenIssuedAt;
|
||||
}
|
||||
return _parseSessionAuthenticatedAt(profile?.sessionAuthenticatedAt);
|
||||
}
|
||||
|
||||
DateTime? _getJwtIssuedAt(String? token) {
|
||||
if (token == null || token.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
final parts = token.split('.');
|
||||
if (parts.length != 3) {
|
||||
return null;
|
||||
}
|
||||
final payload = utf8.decode(
|
||||
base64Url.decode(base64Url.normalize(parts[1])),
|
||||
);
|
||||
final data = json.decode(payload) as Map<String, dynamic>;
|
||||
final iatValue = data['iat'] ?? data['auth_time'];
|
||||
if (iatValue is num) {
|
||||
return DateTime.fromMillisecondsSinceEpoch(
|
||||
iatValue.toInt() * 1000,
|
||||
).toLocal();
|
||||
}
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
DateTime? _parseSessionAuthenticatedAt(String? value) {
|
||||
if (value == null || value.trim().isEmpty) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return DateTime.parse(value).toLocal();
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import '../domain/session_time_resolver.dart';
|
||||
import '../domain/providers/linked_rps_provider.dart';
|
||||
import '../../../../core/notifiers/auth_notifier.dart';
|
||||
import '../../../../core/services/auth_proxy_service.dart';
|
||||
@@ -404,32 +405,6 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
||||
}
|
||||
}
|
||||
|
||||
DateTime? _getJwtIssuedAt() {
|
||||
final token = AuthTokenStore.getToken();
|
||||
if (token == null || token.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
final parts = token.split('.');
|
||||
if (parts.length != 3) {
|
||||
return null;
|
||||
}
|
||||
final payload = utf8.decode(
|
||||
base64Url.decode(base64Url.normalize(parts[1])),
|
||||
);
|
||||
final data = json.decode(payload) as Map<String, dynamic>;
|
||||
final iatValue = data['iat'] ?? data['auth_time'];
|
||||
if (iatValue is num) {
|
||||
return DateTime.fromMillisecondsSinceEpoch(
|
||||
iatValue.toInt() * 1000,
|
||||
).toLocal();
|
||||
}
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String _formatDateTime(DateTime dateTime) {
|
||||
final yyyy = dateTime.year.toString().padLeft(4, '0');
|
||||
final mm = dateTime.month.toString().padLeft(2, '0');
|
||||
@@ -716,7 +691,10 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
||||
final department = departmentValue.isNotEmpty
|
||||
? departmentValue
|
||||
: tr('ui.userfront.profile.department_empty');
|
||||
final sessionIssuedAt = _getJwtIssuedAt();
|
||||
final sessionIssuedAt = resolveDashboardSessionIssuedAt(
|
||||
token: AuthTokenStore.getToken(),
|
||||
profile: profile,
|
||||
);
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: _subtle,
|
||||
|
||||
@@ -33,6 +33,7 @@ class UserProfile {
|
||||
final String department;
|
||||
final String affiliationType;
|
||||
final String companyCode;
|
||||
final String? sessionAuthenticatedAt;
|
||||
final Map<String, dynamic>? metadata;
|
||||
final Tenant? tenant;
|
||||
|
||||
@@ -44,6 +45,7 @@ class UserProfile {
|
||||
required this.department,
|
||||
required this.affiliationType,
|
||||
required this.companyCode,
|
||||
this.sessionAuthenticatedAt,
|
||||
this.metadata,
|
||||
this.tenant,
|
||||
});
|
||||
@@ -57,6 +59,7 @@ class UserProfile {
|
||||
department: json['department'] ?? '',
|
||||
affiliationType: json['affiliationType'] ?? '',
|
||||
companyCode: json['companyCode'] ?? '',
|
||||
sessionAuthenticatedAt: json['sessionAuthenticatedAt'] as String?,
|
||||
metadata: json['metadata'] != null
|
||||
? Map<String, dynamic>.from(json['metadata'])
|
||||
: null,
|
||||
@@ -73,6 +76,7 @@ class UserProfile {
|
||||
'department': department,
|
||||
'affiliationType': affiliationType,
|
||||
'companyCode': companyCode,
|
||||
'sessionAuthenticatedAt': sessionAuthenticatedAt,
|
||||
'metadata': metadata,
|
||||
'tenant': tenant?.toJson(),
|
||||
};
|
||||
@@ -87,6 +91,7 @@ class UserProfile {
|
||||
department: department ?? this.department,
|
||||
affiliationType: affiliationType,
|
||||
companyCode: companyCode,
|
||||
sessionAuthenticatedAt: sessionAuthenticatedAt,
|
||||
tenant: tenant,
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user