1
0
forked from baron/baron-sso

/api/v1/user/me 세션 시각을 추가하고 userfront 대시보드 Unknown 세션 시간 문제 수정

This commit is contained in:
2026-03-24 11:19:36 +09:00
parent 39efd68296
commit 118e004294
9 changed files with 304 additions and 56 deletions

View File

@@ -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;
}
}

View File

@@ -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,

View File

@@ -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,
);
}