143 lines
3.5 KiB
Dart
143 lines
3.5 KiB
Dart
/// Domain Entity: User Session
|
|
///
|
|
/// Represents an active user session with device and authentication information.
|
|
library;
|
|
|
|
/// User Session Entity
|
|
///
|
|
/// Contains information about an active user session:
|
|
/// - Device details
|
|
/// - Authentication tokens
|
|
/// - Session timing
|
|
class UserSession {
|
|
/// Unique session identifier
|
|
final String sessionId;
|
|
|
|
/// User ID associated with this session
|
|
final String userId;
|
|
|
|
/// Unique device identifier
|
|
final String deviceId;
|
|
|
|
/// Device type (ios, android, web)
|
|
final String? deviceType;
|
|
|
|
/// Device name
|
|
final String? deviceName;
|
|
|
|
/// IP address
|
|
final String? ipAddress;
|
|
|
|
/// User agent string
|
|
final String? userAgent;
|
|
|
|
/// Refresh token for renewing access
|
|
final String? refreshToken;
|
|
|
|
/// Session expiration timestamp
|
|
final DateTime expiresAt;
|
|
|
|
/// Session creation timestamp
|
|
final DateTime createdAt;
|
|
|
|
/// Last activity timestamp
|
|
final DateTime? lastActivity;
|
|
|
|
const UserSession({
|
|
required this.sessionId,
|
|
required this.userId,
|
|
required this.deviceId,
|
|
this.deviceType,
|
|
this.deviceName,
|
|
this.ipAddress,
|
|
this.userAgent,
|
|
this.refreshToken,
|
|
required this.expiresAt,
|
|
required this.createdAt,
|
|
this.lastActivity,
|
|
});
|
|
|
|
/// Check if session is expired
|
|
bool get isExpired => DateTime.now().isAfter(expiresAt);
|
|
|
|
/// Check if session is expiring soon (within 1 hour)
|
|
bool get isExpiringSoon {
|
|
final hoursUntilExpiry = expiresAt.difference(DateTime.now()).inHours;
|
|
return hoursUntilExpiry > 0 && hoursUntilExpiry <= 1;
|
|
}
|
|
|
|
/// Check if session is active
|
|
bool get isActive => !isExpired;
|
|
|
|
/// Get device display name
|
|
String get deviceDisplayName => deviceName ?? deviceType ?? 'Unknown Device';
|
|
|
|
/// Get time since last activity
|
|
Duration? get timeSinceLastActivity {
|
|
if (lastActivity == null) return null;
|
|
return DateTime.now().difference(lastActivity!);
|
|
}
|
|
|
|
/// Copy with method for immutability
|
|
UserSession copyWith({
|
|
String? sessionId,
|
|
String? userId,
|
|
String? deviceId,
|
|
String? deviceType,
|
|
String? deviceName,
|
|
String? ipAddress,
|
|
String? userAgent,
|
|
String? refreshToken,
|
|
DateTime? expiresAt,
|
|
DateTime? createdAt,
|
|
DateTime? lastActivity,
|
|
}) {
|
|
return UserSession(
|
|
sessionId: sessionId ?? this.sessionId,
|
|
userId: userId ?? this.userId,
|
|
deviceId: deviceId ?? this.deviceId,
|
|
deviceType: deviceType ?? this.deviceType,
|
|
deviceName: deviceName ?? this.deviceName,
|
|
ipAddress: ipAddress ?? this.ipAddress,
|
|
userAgent: userAgent ?? this.userAgent,
|
|
refreshToken: refreshToken ?? this.refreshToken,
|
|
expiresAt: expiresAt ?? this.expiresAt,
|
|
createdAt: createdAt ?? this.createdAt,
|
|
lastActivity: lastActivity ?? this.lastActivity,
|
|
);
|
|
}
|
|
|
|
@override
|
|
bool operator ==(Object other) {
|
|
if (identical(this, other)) return true;
|
|
|
|
return other is UserSession &&
|
|
other.sessionId == sessionId &&
|
|
other.userId == userId &&
|
|
other.deviceId == deviceId &&
|
|
other.deviceType == deviceType &&
|
|
other.deviceName == deviceName &&
|
|
other.ipAddress == ipAddress &&
|
|
other.refreshToken == refreshToken;
|
|
}
|
|
|
|
@override
|
|
int get hashCode {
|
|
return Object.hash(
|
|
sessionId,
|
|
userId,
|
|
deviceId,
|
|
deviceType,
|
|
deviceName,
|
|
ipAddress,
|
|
refreshToken,
|
|
);
|
|
}
|
|
|
|
@override
|
|
String toString() {
|
|
return 'UserSession(sessionId: $sessionId, userId: $userId, deviceId: $deviceId, '
|
|
'deviceType: $deviceType, expiresAt: $expiresAt, isActive: $isActive)';
|
|
}
|
|
}
|