import '../../contracts/contracts.dart'; import '../errors.dart'; import '../ports/emby_gateway.dart'; import '../ports/server_repository.dart'; import '../ports/session_repository.dart'; class AuthByNameUseCase { final ServerRepository serverRepository; final SessionRepository sessionRepository; final EmbyGateway embyGateway; final DateTime Function() now; AuthByNameUseCase({ required this.serverRepository, required this.sessionRepository, required this.embyGateway, DateTime Function()? now, }) : now = now ?? DateTime.now; Future execute(AuthByNameReq input) async { final username = input.username.trim(); final password = input.password; if (username.isEmpty || password.isEmpty) { throw DomainError(ErrorCode.invalidParams, '用户名或密码不能为空'); } final server = await serverRepository.findById(input.serverId); if (server == null) { throw DomainError( ErrorCode.storeNotFound, '服务器不存在', details: {'serverId': input.serverId}, ); } final auth = await embyGateway.authenticateByName( baseUrl: server.baseUrl, username: username, password: password, ); final nowIso = now().toUtc().toIso8601String(); await sessionRepository.set( SessionData( serverId: server.id, token: auth.accessToken, userId: auth.userId, userName: auth.userName, password: password, createdAt: nowIso, ), ); await serverRepository.touchConnectedAt(server.id, nowIso); } } class LogoutUseCase { final SessionRepository sessionRepository; LogoutUseCase({required this.sessionRepository}); Future execute([String? serverId]) => sessionRepository.clear(serverId); } class ListSessionsUseCase { final SessionRepository sessionRepository; final ServerRepository serverRepository; ListSessionsUseCase({ required this.sessionRepository, required this.serverRepository, }); Future execute() async { final sessions = await sessionRepository.listAll(); final activeServerId = await sessionRepository.getActiveServerId(); final result = []; for (final session in sessions) { final server = await serverRepository.findById(session.serverId); if (server != null) { result.add( AuthedSession( serverId: session.serverId, serverName: server.name, serverUrl: server.baseUrl, token: session.token, userId: session.userId, userName: session.userName, password: session.password, isActive: session.serverId == activeServerId, ), ); } } return SessionListRes(sessions: result, activeServerId: activeServerId); } } class SwitchSessionUseCase { final SessionRepository sessionRepository; SwitchSessionUseCase({required this.sessionRepository}); Future execute(String serverId) async { final session = await sessionRepository.getByServerId(serverId); if (session == null) { throw DomainError( ErrorCode.storeNotFound, '该服务器没有可用会话', details: {'serverId': serverId}, ); } await sessionRepository.setActive(serverId); } } class ChangePasswordUseCase { final SessionRepository sessionRepository; final ServerRepository serverRepository; final EmbyGateway embyGateway; ChangePasswordUseCase({ required this.sessionRepository, required this.serverRepository, required this.embyGateway, }); Future execute({ required String serverId, required String currentPassword, required String newPassword, }) async { if (currentPassword.isEmpty || newPassword.isEmpty) { throw DomainError(ErrorCode.invalidParams, '密码不能为空'); } final session = await sessionRepository.getByServerId(serverId); if (session == null) { throw DomainError(ErrorCode.storeNotFound, '该服务器没有可用会话'); } final server = await serverRepository.findById(serverId); if (server == null) { throw DomainError(ErrorCode.storeNotFound, '服务器不存在'); } final ctx = AuthedRequestContext( baseUrl: server.baseUrl, token: session.token, userId: session.userId, ); await embyGateway.changePassword( ctx: ctx, currentPassword: currentPassword, newPassword: newPassword, ); await sessionRepository.setMany([session.copyWith(password: newPassword)]); } }