186 lines
5.2 KiB
Dart
186 lines
5.2 KiB
Dart
import 'package:hive_ce/hive.dart';
|
|
|
|
import 'package:worker/core/constants/storage_constants.dart';
|
|
|
|
part 'user_session_model.g.dart';
|
|
|
|
/// User Session Model
|
|
///
|
|
/// Hive CE model for caching user session data locally.
|
|
/// Maps to the 'user_sessions' table in the database.
|
|
///
|
|
/// Type ID: 1
|
|
@HiveType(typeId: HiveTypeIds.userSessionModel)
|
|
class UserSessionModel extends HiveObject {
|
|
UserSessionModel({
|
|
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,
|
|
});
|
|
|
|
/// Session ID (Primary Key)
|
|
@HiveField(0)
|
|
final String sessionId;
|
|
|
|
/// User ID (Foreign Key to users)
|
|
@HiveField(1)
|
|
final String userId;
|
|
|
|
/// Device ID (unique identifier for the device)
|
|
@HiveField(2)
|
|
final String deviceId;
|
|
|
|
/// Device type (android, ios, web, etc.)
|
|
@HiveField(3)
|
|
final String? deviceType;
|
|
|
|
/// Device name (e.g., "Samsung Galaxy S21")
|
|
@HiveField(4)
|
|
final String? deviceName;
|
|
|
|
/// IP address of the device
|
|
@HiveField(5)
|
|
final String? ipAddress;
|
|
|
|
/// User agent string
|
|
@HiveField(6)
|
|
final String? userAgent;
|
|
|
|
/// Refresh token for session renewal
|
|
@HiveField(7)
|
|
final String? refreshToken;
|
|
|
|
/// Session expiration timestamp
|
|
@HiveField(8)
|
|
final DateTime expiresAt;
|
|
|
|
/// Session creation timestamp
|
|
@HiveField(9)
|
|
final DateTime createdAt;
|
|
|
|
/// Last activity timestamp
|
|
@HiveField(10)
|
|
final DateTime? lastActivity;
|
|
|
|
// =========================================================================
|
|
// JSON SERIALIZATION
|
|
// =========================================================================
|
|
|
|
/// Create UserSessionModel from JSON
|
|
factory UserSessionModel.fromJson(Map<String, dynamic> json) {
|
|
return UserSessionModel(
|
|
sessionId: json['session_id'] as String,
|
|
userId: json['user_id'] as String,
|
|
deviceId: json['device_id'] as String,
|
|
deviceType: json['device_type'] as String?,
|
|
deviceName: json['device_name'] as String?,
|
|
ipAddress: json['ip_address'] as String?,
|
|
userAgent: json['user_agent'] as String?,
|
|
refreshToken: json['refresh_token'] as String?,
|
|
expiresAt: DateTime.parse(json['expires_at'] as String),
|
|
createdAt: DateTime.parse(json['created_at'] as String),
|
|
lastActivity: json['last_activity'] != null
|
|
? DateTime.parse(json['last_activity'] as String)
|
|
: null,
|
|
);
|
|
}
|
|
|
|
/// Convert UserSessionModel to JSON
|
|
Map<String, dynamic> toJson() {
|
|
return {
|
|
'session_id': sessionId,
|
|
'user_id': userId,
|
|
'device_id': deviceId,
|
|
'device_type': deviceType,
|
|
'device_name': deviceName,
|
|
'ip_address': ipAddress,
|
|
'user_agent': userAgent,
|
|
'refresh_token': refreshToken,
|
|
'expires_at': expiresAt.toIso8601String(),
|
|
'created_at': createdAt.toIso8601String(),
|
|
'last_activity': lastActivity?.toIso8601String(),
|
|
};
|
|
}
|
|
|
|
// =========================================================================
|
|
// HELPER METHODS
|
|
// =========================================================================
|
|
|
|
/// Check if session is expired
|
|
bool get isExpired => DateTime.now().isAfter(expiresAt);
|
|
|
|
/// Check if session is valid (not expired)
|
|
bool get isValid => !isExpired;
|
|
|
|
/// Get session duration
|
|
Duration get duration => DateTime.now().difference(createdAt);
|
|
|
|
/// Get time until expiration
|
|
Duration get timeUntilExpiration => expiresAt.difference(DateTime.now());
|
|
|
|
/// Get session age
|
|
Duration get age => DateTime.now().difference(createdAt);
|
|
|
|
/// Get time since last activity
|
|
Duration? get timeSinceLastActivity {
|
|
if (lastActivity == null) return null;
|
|
return DateTime.now().difference(lastActivity!);
|
|
}
|
|
|
|
// =========================================================================
|
|
// COPY WITH
|
|
// =========================================================================
|
|
|
|
/// Create a copy with updated fields
|
|
UserSessionModel copyWith({
|
|
String? sessionId,
|
|
String? userId,
|
|
String? deviceId,
|
|
String? deviceType,
|
|
String? deviceName,
|
|
String? ipAddress,
|
|
String? userAgent,
|
|
String? refreshToken,
|
|
DateTime? expiresAt,
|
|
DateTime? createdAt,
|
|
DateTime? lastActivity,
|
|
}) {
|
|
return UserSessionModel(
|
|
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
|
|
String toString() {
|
|
return 'UserSessionModel(sessionId: $sessionId, userId: $userId, isValid: $isValid)';
|
|
}
|
|
|
|
@override
|
|
bool operator ==(Object other) {
|
|
if (identical(this, other)) return true;
|
|
|
|
return other is UserSessionModel && other.sessionId == sessionId;
|
|
}
|
|
|
|
@override
|
|
int get hashCode => sessionId.hashCode;
|
|
}
|