import { BadRequestException, Controller, UseFilters } from '@nestjs/common'; import { GrpcMethod } from '@nestjs/microservices'; import { GrpcExceptionFilter } from '../infra/grpc-exception.filter'; import { AdminService } from './admin.service'; import { AuthService } from './auth.service'; import { LoginCommand, RegisterCommand, VerifyPinCommand } from './dto'; import { PinService } from './pin.service'; import { SessionService } from './session.service'; import { RbacService } from './rbac.service'; import { SecurityService } from './security.service'; import { SettingsService } from './settings.service'; import { UserStatus } from '../generated/prisma/client'; import { ProfileService } from './profile.service'; import { DocumentsService } from './documents.service'; import { AddressesService } from './addresses.service'; import { OAuthCoreService } from './oauth-core.service'; import { OtpService } from './otp.service'; import { AdvancedAuthService } from './advanced-auth.service'; import { FamilyService } from './family.service'; import { MediaService } from './media.service'; import { NotificationsService } from './notifications.service'; import { ChatService } from './chat.service'; import { PresenceService } from './presence.service'; import { TotpService } from './totp.service'; import { MessagingService } from '../infra/messaging.service'; @Controller() @UseFilters(new GrpcExceptionFilter()) export class AuthGrpcController { constructor( private readonly auth: AuthService, private readonly pin: PinService, private readonly session: SessionService, private readonly admin: AdminService, private readonly rbac: RbacService, private readonly security: SecurityService, private readonly settings: SettingsService, private readonly profile: ProfileService, private readonly documents: DocumentsService, private readonly addresses: AddressesService, private readonly oauthCore: OAuthCoreService, private readonly otp: OtpService, private readonly advancedAuth: AdvancedAuthService, private readonly family: FamilyService, private readonly media: MediaService, private readonly notifications: NotificationsService, private readonly chat: ChatService, private readonly presence: PresenceService, private readonly messaging: MessagingService, private readonly totp: TotpService ) {} @GrpcMethod('AuthService', 'Register') register(command: RegisterCommand) { return this.auth.register(command); } @GrpcMethod('AuthService', 'Login') login(command: LoginCommand) { return this.auth.login(command); } @GrpcMethod('AuthService', 'Identify') identify(command: { login: string }) { return this.auth.identify(command.login); } @GrpcMethod('AuthService', 'SendOtp') sendPasswordlessOtp(command: { recipient: string; channel?: string; ipAddress?: string }) { return this.auth.sendOtp(command.recipient, command.channel, command.ipAddress); } @GrpcMethod('AuthService', 'VerifyOtp') verifyPasswordlessOtp(command: LoginCommand & { recipient: string; code: string }) { return this.auth.verifyOtp(command); } @GrpcMethod('AuthService', 'LoginWithPassword') loginWithPassword(command: LoginCommand & { tempAuthToken?: string }) { return this.auth.loginWithPassword(command); } @GrpcMethod('AuthService', 'LoginWithLdap') loginWithLdap(command: { username: string; password: string; fingerprint: string; deviceName?: string; deviceType?: string; ipAddress?: string; userAgent?: string; }) { return this.auth.loginWithLdap(command); } @GrpcMethod('AuthService', 'VerifyTotpLogin') verifyTotpLogin(command: { totpChallengeToken: string; code: string }) { return this.auth.verifyTotpLogin(command.totpChallengeToken, command.code); } @GrpcMethod('AuthService', 'BeginTotpLogin') beginTotpLogin(command: { recipient: string; fingerprint: string; deviceName?: string; deviceType?: string; ipAddress?: string; userAgent?: string; }) { return this.auth.beginTotpLogin(command); } @GrpcMethod('AuthService', 'VerifyPin') verifyPin(command: VerifyPinCommand) { return this.pin.verifyPin(command.sessionId, command.pin); } @GrpcMethod('AuthService', 'GetMe') getMe(command: { userId: string }) { return this.auth.getMe(command.userId); } @GrpcMethod('AuthService', 'RefreshSession') refreshSession(command: { refreshToken: string; sessionId?: string }) { return this.session.refreshSession(command.refreshToken, command.sessionId); } @GrpcMethod('AuthService', 'ValidateSession') validateSession(command: { userId: string; sessionId: string; touchActivity?: boolean }) { return this.session.validateSession(command.userId, command.sessionId, command.touchActivity ?? false); } @GrpcMethod('AdminService', 'ListUsers') async listUsers(command: { search?: string }) { const users = await this.admin.listUsers(command.search); return { users }; } @GrpcMethod('AdminService', 'SuspendUser') suspendUser(command: { userId: string }) { return this.admin.suspendUser(command.userId); } @GrpcMethod('AdminService', 'UpdateUserProfile') updateUserProfile(command: { userId: string; displayName?: string; email?: string; phone?: string; backupEmail?: string; backupPhone?: string; status?: UserStatus }) { const { userId, ...data } = command; return this.admin.updateUserProfile(userId, data); } @GrpcMethod('AdminService', 'ResetPassword') resetPassword(command: { userId: string; newPassword: string }) { return this.admin.resetPassword(command.userId, command.newPassword); } @GrpcMethod('AdminService', 'SetSuperAdmin') setSuperAdmin(command: { actorUserId: string; userId: string; isSuperAdmin: boolean }) { return this.admin.setSuperAdmin(command.actorUserId, command.userId, command.isSuperAdmin); } @GrpcMethod('RbacService', 'ListRoles') async listRoles() { const roles = await this.rbac.listRoles(); return { roles: roles.map((role) => ({ id: role.id, slug: role.slug, name: role.name, description: role.description ?? undefined, isSystem: role.isSystem, isDefault: role.isDefault, permissions: role.permissions.map((link) => ({ id: link.permission.id, slug: link.permission.slug, name: link.permission.name, description: link.permission.description ?? undefined })) })) }; } @GrpcMethod('RbacService', 'ListOAuthClients') async listOAuthClients(command: { actorUserId: string }) { const clients = await this.rbac.listOAuthClients(command.actorUserId); return { clients: clients.map((client) => ({ id: client.id, name: client.name, clientId: client.clientId, redirectUris: client.redirectUris, scopes: client.scopes, isActive: client.isActive, type: client.type, createdById: client.createdById ?? undefined, createdByDisplayName: client.createdByDisplayName ?? undefined, canManage: client.canManage })) }; } @GrpcMethod('RbacService', 'ListPermissions') async listPermissions() { const permissions = await this.rbac.listPermissions(); return { permissions: permissions.map((permission) => ({ id: permission.id, slug: permission.slug, name: permission.name, description: permission.description ?? undefined })) }; } @GrpcMethod('RbacService', 'ListOAuthScopes') async listOAuthScopes() { const scopes = await this.rbac.listOAuthScopes(); return { scopes: scopes.map((scope) => ({ id: scope.id, slug: scope.slug, name: scope.name, description: scope.description ?? undefined })) }; } @GrpcMethod('RbacService', 'CreateRole') async createRole(command: { actorUserId: string; slug: string; name: string; description?: string; permissionSlugs?: string[] }) { const role = await this.rbac.createRole(command.actorUserId, { slug: command.slug, name: command.name, description: command.description, permissionSlugs: command.permissionSlugs }); return { id: role.id, slug: role.slug, name: role.name, description: role.description ?? undefined, isSystem: role.isSystem, isDefault: role.isDefault, permissions: role.permissions.map((link) => ({ id: link.permission.id, slug: link.permission.slug, name: link.permission.name, description: link.permission.description ?? undefined })) }; } @GrpcMethod('RbacService', 'UpdateRole') async updateRole(command: { actorUserId: string; roleSlug: string; name?: string; description?: string; permissionSlugs?: string[]; }) { const role = await this.rbac.updateRole(command.actorUserId, command.roleSlug, { name: command.name, description: command.description, permissionSlugs: command.permissionSlugs }); return { id: role.id, slug: role.slug, name: role.name, description: role.description ?? undefined, isSystem: role.isSystem, isDefault: role.isDefault, permissions: role.permissions.map((link) => ({ id: link.permission.id, slug: link.permission.slug, name: link.permission.name, description: link.permission.description ?? undefined })) }; } @GrpcMethod('RbacService', 'DeleteRole') async deleteRole(command: { actorUserId: string; roleSlug: string }) { await this.rbac.deleteRole(command.actorUserId, command.roleSlug); return {}; } @GrpcMethod('RbacService', 'AssignUserRole') async assignUserRole(command: { actorUserId: string; userId: string; roleSlug: string }) { const roles = await this.rbac.assignRole(command.actorUserId, command.userId, command.roleSlug); return { userId: command.userId, roles }; } @GrpcMethod('RbacService', 'RemoveUserRole') async removeUserRole(command: { actorUserId: string; userId: string; roleSlug: string }) { await this.rbac.removeRole(command.actorUserId, command.userId, command.roleSlug); return {}; } @GrpcMethod('RbacService', 'AssignUserPermission') async assignUserPermission(command: { actorUserId: string; userId: string; permissionSlug: string }) { const permissions = await this.rbac.assignUserPermission(command.actorUserId, command.userId, command.permissionSlug); return { userId: command.userId, permissions }; } @GrpcMethod('RbacService', 'RemoveUserPermission') async removeUserPermission(command: { actorUserId: string; userId: string; permissionSlug: string }) { const permissions = await this.rbac.removeUserPermission(command.actorUserId, command.userId, command.permissionSlug); return { userId: command.userId, permissions }; } @GrpcMethod('RbacService', 'CreateOAuthClient') async createOAuthClient(command: { actorUserId: string; name: string; redirectUris: string[]; scopes: string[]; type?: string }) { const { client, clientSecret } = await this.rbac.createOAuthClient(command.actorUserId, { name: command.name, redirectUris: command.redirectUris, scopes: command.scopes, type: command.type as never }); return { id: client.id, name: client.name, clientId: client.clientId, redirectUris: client.redirectUris, scopes: client.scopes.map((link) => link.scope.slug), isActive: client.isActive, type: client.type, clientSecret: clientSecret ?? undefined }; } @GrpcMethod('RbacService', 'UpdateOAuthClient') async updateOAuthClient(command: { actorUserId: string; clientId: string; name?: string; redirectUris?: string[]; scopes?: string[]; isActive?: boolean; }) { const { client } = await this.rbac.updateOAuthClient(command.actorUserId, command.clientId, { name: command.name, redirectUris: command.redirectUris, scopes: command.scopes, isActive: command.isActive }); return { id: client.id, name: client.name, clientId: client.clientId, redirectUris: client.redirectUris, scopes: client.scopes.map((link) => link.scope.slug), isActive: client.isActive, type: client.type }; } @GrpcMethod('RbacService', 'RotateOAuthSecret') async rotateOAuthSecret(command: { actorUserId: string; clientId: string }) { return this.rbac.rotateOAuthSecret(command.actorUserId, command.clientId); } @GrpcMethod('RbacService', 'DeleteOAuthClient') async deleteOAuthClient(command: { actorUserId: string; clientId: string }) { return this.rbac.deleteOAuthClient(command.actorUserId, command.clientId); } @GrpcMethod('SecurityService', 'ListActiveDevices') async listActiveDevices(command: { userId: string; exceptSessionId?: string }) { const devices = await this.security.listActiveDevices(command.userId, command.exceptSessionId); return { devices: devices.map((device) => ({ id: device.id, name: device.name, type: device.type, lastIp: device.lastIp, lastSeenAt: device.lastSeenAt.toISOString(), trusted: device.trusted })) }; } @GrpcMethod('SecurityService', 'ListSignInHistory') async listSignInHistory(command: { userId: string }) { const events = await this.security.listSignInHistory(command.userId); return { events: events.map((event) => ({ id: event.id, success: event.success, reason: event.reason, ipAddress: event.ipAddress, userAgent: event.userAgent, createdAt: event.createdAt.toISOString() })) }; } @GrpcMethod('SecurityService', 'ListActiveSessions') async listActiveSessions(command: { userId: string }) { const sessions = await this.security.listActiveSessions(command.userId); return { sessions: sessions.map((session) => this.toSessionResponse(session)) }; } @GrpcMethod('SecurityService', 'LockSession') async lockSession(command: { userId: string; sessionId: string }) { return this.toSessionResponse(await this.security.lockSession(command.userId, command.sessionId)); } @GrpcMethod('SecurityService', 'RevokeSession') async revokeSession(command: { userId: string; sessionId: string }) { return this.toSessionResponse(await this.security.revokeSession(command.userId, command.sessionId)); } @GrpcMethod('SecurityService', 'RevokeDevice') async revokeDevice(command: { userId: string; deviceId: string }) { const result = await this.security.revokeDevice(command.userId, command.deviceId); return { count: result.count }; } @GrpcMethod('SecurityService', 'RevokeAllSessions') async revokeAllSessions(command: { userId: string; exceptSessionId?: string }) { const result = await this.security.revokeAllSessions(command.userId, command.exceptSessionId); return { count: result.count }; } @GrpcMethod('SecurityService', 'GetTotpStatus') getTotpStatus(command: { userId: string }) { return this.totp.getStatus(command.userId); } @GrpcMethod('SecurityService', 'SetupTotp') setupTotp(command: { userId: string }) { return this.totp.setup(command.userId); } @GrpcMethod('SecurityService', 'EnableTotp') enableTotp(command: { userId: string; code: string }) { return this.totp.enable(command.userId, command.code); } @GrpcMethod('SecurityService', 'DisableTotp') disableTotp(command: { userId: string; code: string }) { return this.totp.disable(command.userId, command.code); } @GrpcMethod('SecurityService', 'SetupPin') setupPin(command: { userId: string; pin: string }) { return this.pin.setupPin(command.userId, command.pin); } @GrpcMethod('SecurityService', 'UpdatePin') updatePin(command: { userId: string; pin: string }) { return this.pin.updatePin(command.userId, command.pin); } @GrpcMethod('SecurityService', 'RequestPinDeletion') requestPinDeletion(command: { userId: string; pin: string }) { return this.pin.requestPinDeletion(command.userId, command.pin); } @GrpcMethod('SecurityService', 'CancelPinDeletion') cancelPinDeletion(command: { userId: string }) { return this.pin.cancelPinDeletion(command.userId); } @GrpcMethod('SecurityService', 'VerifyPinCode') verifyPinCode(command: { sessionId: string; pin: string }) { return this.pin.verifyPin(command.sessionId, command.pin); } @GrpcMethod('SecurityService', 'ConnectLinkedAccount') async connectLinkedAccount(command: { userId: string; providerName: string; providerId: string; email?: string; displayName?: string; avatarUrl?: string }) { return this.toLinkedAccountResponse(await this.security.connectSocialAccount(command.userId, command)); } @GrpcMethod('SecurityService', 'DisconnectLinkedAccount') disconnectLinkedAccount(command: { userId: string; providerName: string }) { return this.security.disconnectSocialAccount(command.userId, command.providerName); } @GrpcMethod('SecurityService', 'ListLinkedAccounts') async listLinkedAccounts(command: { userId: string }) { const accounts = await this.security.listLinkedAccounts(command.userId); return { accounts: accounts.map((account) => this.toLinkedAccountResponse(account)) }; } @GrpcMethod('SettingsService', 'ListSettings') async listSettings() { const settings = await this.settings.list(); return { settings: settings.map((setting) => ({ id: setting.id, key: setting.key, value: setting.value, description: setting.description ?? undefined, isSecret: setting.isSecret })) }; } @GrpcMethod('SettingsService', 'ListPublicSettings') async listPublicSettings() { const settings = await this.settings.listPublic(); return { settings: settings.map((setting) => ({ key: setting.key, value: setting.value })) }; } @GrpcMethod('SettingsService', 'GetSetting') getSetting(command: { key: string }) { return this.settings.get(command.key); } @GrpcMethod('SettingsService', 'UpsertSetting') upsertSetting(command: { key: string; value: string; description?: string; isSecret?: boolean }) { return this.settings.upsert(command); } @GrpcMethod('SettingsService', 'DeleteSetting') deleteSetting(command: { key: string }) { return this.settings.delete(command.key); } @GrpcMethod('SettingsService', 'ListSocialProviders') async listSocialProviders() { const providers = await this.settings.listSocialProviders(); return { providers: providers.map((provider) => this.toSocialProviderResponse(provider)) }; } @GrpcMethod('SettingsService', 'UpsertSocialProvider') async upsertSocialProvider(command: { providerName: string; clientId: string; clientSecret?: string; isEnabled: boolean }) { return this.toSocialProviderResponse(await this.settings.upsertSocialProvider(command)); } @GrpcMethod('SettingsService', 'DeleteSocialProvider') deleteSocialProvider(command: { providerName: string }) { return this.settings.deleteSocialProvider(command.providerName); } @GrpcMethod('SettingsService', 'TestMessagingDelivery') async testMessagingDelivery(command: { channel: string; target: string }) { const channel = command.channel === 'sms' ? 'sms' : 'email'; if (!command.target?.trim()) { throw new BadRequestException('Укажите email или номер телефона для тестовой отправки'); } return this.messaging.sendTestDelivery(channel, command.target.trim()); } @GrpcMethod('ProfileService', 'GetProfile') getProfile(command: { userId: string }) { return this.profile.getProfile(command.userId); } @GrpcMethod('ProfileService', 'UpdateAvatar') updateAvatar(command: { userId: string; avatarUrl?: string; avatarStorageKey?: string }) { return this.profile.updateAvatar(command.userId, command.avatarUrl, command.avatarStorageKey); } @GrpcMethod('ProfileService', 'UpdateProfile') updateProfile(command: { userId: string; firstName?: string; lastName?: string; bio?: string; age?: number; gender?: string; birthDate?: string }) { return this.profile.updateProfile(command); } @GrpcMethod('ProfileService', 'UpdateContacts') updateContacts(command: { userId: string; email?: string; phone?: string; backupEmail?: string; backupPhone?: string }) { return this.profile.updateContacts(command); } @GrpcMethod('ProfileService', 'SetPassword') setPassword(command: { userId: string; password: string }) { return this.profile.setPassword(command.userId, command.password); } @GrpcMethod('ProfileService', 'SendPasswordVerificationOtp') sendPasswordVerificationOtp(command: { userId: string; channel: string }) { return this.profile.sendPasswordVerificationOtp(command.userId, command.channel as 'sms' | 'email'); } @GrpcMethod('ProfileService', 'ChangePassword') changePassword(command: { userId: string; newPassword: string; currentPassword?: string; otpCode?: string; otpChannel?: string; totpCode?: string; }) { return this.profile.changePassword(command.userId, command.newPassword, command); } @GrpcMethod('ProfileService', 'RemovePassword') removePassword(command: { userId: string; currentPassword?: string; otpCode?: string; otpChannel?: string; totpCode?: string; }) { return this.profile.removePassword(command.userId, command); } @GrpcMethod('ProfileService', 'SoftDeleteProfile') softDeleteProfile(command: { userId: string }) { return this.profile.softDeleteProfile(command.userId); } @GrpcMethod('ProfileService', 'RequestAccountDeletion') requestAccountDeletion(command: { userId: string }) { return this.profile.requestAccountDeletion(command.userId); } @GrpcMethod('ProfileService', 'CancelAccountDeletion') cancelAccountDeletion(command: { userId: string }) { return this.profile.cancelAccountDeletion(command.userId); } @GrpcMethod('ProfileService', 'GetAccountDeletionStatus') getAccountDeletionStatus(command: { userId: string }) { return this.profile.getAccountDeletionStatus(command.userId); } @GrpcMethod('DocumentsService', 'CreateDocument') createDocument(command: { userId: string; type: string; number: string; issuedAt?: string; expiresAt?: string; metadataJson?: string }) { return this.documents.create(command); } @GrpcMethod('DocumentsService', 'ListDocuments') listDocuments(command: { userId: string }) { return this.documents.list(command.userId); } @GrpcMethod('DocumentsService', 'GetDocument') getDocument(command: { documentId: string; userId: string }) { return this.documents.get(command.documentId, command.userId); } @GrpcMethod('DocumentsService', 'UpdateDocument') updateDocument(command: { documentId: string; userId: string; number?: string; issuedAt?: string; expiresAt?: string; metadataJson?: string }) { return this.documents.update(command); } @GrpcMethod('DocumentsService', 'DeleteDocument') deleteDocument(command: { documentId: string; userId: string }) { return this.documents.delete(command.documentId, command.userId); } @GrpcMethod('AddressesService', 'ListAddresses') listAddresses(command: { userId: string }) { return this.addresses.list(command.userId); } @GrpcMethod('AddressesService', 'UpsertAddress') upsertAddress(command: { userId: string; addressId?: string; label: string; city: string; street: string; house: string; apartment?: string; comment?: string; latitude?: number; longitude?: number; fullAddress?: string; }) { return this.addresses.upsert(command); } @GrpcMethod('AddressesService', 'DeleteAddress') deleteAddress(command: { addressId: string; userId: string }) { return this.addresses.delete(command.addressId, command.userId); } @GrpcMethod('MediaService', 'CreateAvatarUploadUrl') createAvatarUploadUrl(command: { userId: string; contentType: string }) { return this.media.createAvatarUploadUrl(command.userId, command.contentType); } @GrpcMethod('MediaService', 'ConfirmAvatar') confirmAvatar(command: { userId: string; storageKey: string }) { return this.media.confirmAvatar(command.userId, command.storageKey); } @GrpcMethod('MediaService', 'GetAvatarAccessUrl') getAvatarAccessUrl(command: { requesterId: string; targetUserId: string }) { return this.media.getAvatarAccessUrl(command.requesterId, command.targetUserId); } @GrpcMethod('MediaService', 'CreateDocumentPhotoUploadUrl') createDocumentPhotoUploadUrl(command: { userId: string; documentId: string; contentType: string }) { return this.media.createDocumentPhotoUploadUrl(command.userId, command.documentId, command.contentType); } @GrpcMethod('MediaService', 'GetDocumentPhotoAccessUrl') getDocumentPhotoAccessUrl(command: { requesterId: string; targetUserId: string; storageKey: string }) { return this.media.getDocumentPhotoAccessUrl(command.requesterId, command.targetUserId, command.storageKey); } @GrpcMethod('MediaService', 'ResolveStreamToken') resolveStreamToken(command: { token: string; requesterId?: string }) { return this.media.resolveStreamToken(command.token, command.requesterId); } @GrpcMethod('MediaService', 'CreateFamilyAvatarUploadUrl') createFamilyAvatarUploadUrl(command: { requesterId: string; groupId: string; contentType: string }) { return this.media.createFamilyAvatarUploadUrl(command.requesterId, command.groupId, command.contentType); } @GrpcMethod('MediaService', 'ConfirmFamilyAvatar') confirmFamilyAvatar(command: { requesterId: string; groupId: string; storageKey: string }) { return this.media.confirmFamilyAvatar(command.requesterId, command.groupId, command.storageKey); } @GrpcMethod('MediaService', 'GetFamilyAvatarAccessUrl') getFamilyAvatarAccessUrl(command: { requesterId: string; groupId: string }) { return this.media.getFamilyAvatarAccessUrl(command.requesterId, command.groupId); } @GrpcMethod('MediaService', 'CreateChatMediaUploadUrl') createChatMediaUploadUrl(command: { requesterId: string; roomId: string; contentType: string; fileName?: string }) { return this.media.createChatMediaUploadUrl(command.requesterId, command.roomId, command.contentType, command.fileName); } @GrpcMethod('MediaService', 'GetChatMediaAccessUrl') getChatMediaAccessUrl(command: { requesterId: string; roomId: string; storageKey: string; fileName?: string }) { return this.media.getChatMediaAccessUrl(command.requesterId, command.roomId, command.storageKey, command.fileName); } @GrpcMethod('MediaService', 'CreateChatRoomAvatarUploadUrl') createChatRoomAvatarUploadUrl(command: { requesterId: string; roomId: string; contentType: string }) { return this.media.createChatRoomAvatarUploadUrl(command.requesterId, command.roomId, command.contentType); } @GrpcMethod('MediaService', 'ConfirmChatRoomAvatar') confirmChatRoomAvatar(command: { requesterId: string; roomId: string; storageKey: string }) { return this.media.confirmChatRoomAvatar(command.requesterId, command.roomId, command.storageKey); } @GrpcMethod('MediaService', 'GetChatRoomAvatarAccessUrl') getChatRoomAvatarAccessUrl(command: { requesterId: string; roomId: string }) { return this.media.getChatRoomAvatarAccessUrl(command.requesterId, command.roomId); } @GrpcMethod('OAuthCoreService', 'Authorize') authorize(command: { userId: string; clientId: string; redirectUri: string; scope: string; state?: string }) { return this.oauthCore.authorize(command); } @GrpcMethod('OAuthCoreService', 'Token') token(command: { grantType: string; code?: string; refreshToken?: string; clientId: string; clientSecret?: string; redirectUri?: string }) { return this.oauthCore.token(command); } @GrpcMethod('OAuthCoreService', 'UserInfo') userInfo(command: { accessToken: string }) { return this.oauthCore.userInfo(command.accessToken); } @GrpcMethod('OtpService', 'SendOtp') sendOtp(command: { target: string; channel: string; purpose: string; userId?: string }) { return this.otp.send(command); } @GrpcMethod('OtpService', 'VerifyOtp') verifyOtp(command: { target: string; code: string; purpose: string }) { return this.otp.verify(command); } @GrpcMethod('AdvancedAuthService', 'CreateWebAuthnRegistrationChallenge') createWebAuthnRegistrationChallenge(command: { userId: string }) { return this.advancedAuth.createWebAuthnRegistrationChallenge(command.userId); } @GrpcMethod('AdvancedAuthService', 'CreateWebAuthnLoginChallenge') createWebAuthnLoginChallenge(command: { userId: string }) { return this.advancedAuth.createWebAuthnLoginChallenge(command.userId); } @GrpcMethod('AdvancedAuthService', 'CreateQrSession') createQrSession(command: { deviceName: string; fingerprint?: string; deviceType?: string; ipAddress?: string; userAgent?: string }) { return this.advancedAuth.createQrSession({ deviceName: command.deviceName, fingerprint: command.fingerprint ?? command.deviceName, deviceType: command.deviceType, ipAddress: command.ipAddress, userAgent: command.userAgent }); } @GrpcMethod('AdvancedAuthService', 'PollQrSession') pollQrSession(command: { sessionId: string }) { return this.advancedAuth.pollQrSession(command.sessionId); } @GrpcMethod('AdvancedAuthService', 'ApproveQrSession') approveQrSession(command: { sessionId: string; userId: string }) { return this.advancedAuth.approveQrSession(command.sessionId, command.userId); } @GrpcMethod('FamilyService', 'CreateFamilyGroup') createFamilyGroup(command: { ownerId: string; name: string }) { return this.family.create(command.ownerId, command.name); } @GrpcMethod('FamilyService', 'ListFamilyGroups') listFamilyGroups(command: { userId: string }) { return this.family.list(command.userId); } @GrpcMethod('FamilyService', 'GetFamilyGroup') getFamilyGroup(command: { requesterId: string; groupId: string }) { return this.family.get(command.requesterId, command.groupId); } @GrpcMethod('FamilyService', 'UpdateFamilyGroup') updateFamilyGroup(command: { requesterId: string; groupId: string; name: string }) { return this.family.update(command.requesterId, command.groupId, command.name); } @GrpcMethod('FamilyService', 'DeleteFamilyGroup') deleteFamilyGroup(command: { requesterId: string; groupId: string }) { return this.family.delete(command.requesterId, command.groupId); } @GrpcMethod('FamilyService', 'AddFamilyMember') addFamilyMember(command: { groupId: string; userId: string; role: string }) { return this.family.addMember(command.groupId, command.userId, command.role); } @GrpcMethod('FamilyService', 'RemoveFamilyMember') removeFamilyMember(command: { requesterId: string; memberId: string }) { return this.family.removeMember(command.requesterId, command.memberId); } @GrpcMethod('FamilyService', 'SendFamilyInvite') sendFamilyInvite(command: { requesterId: string; groupId: string; target?: string; inviteeUserId?: string }) { return this.family.sendInvite(command.requesterId, command.groupId, { target: command.target, inviteeUserId: command.inviteeUserId }); } @GrpcMethod('FamilyService', 'SearchFamilyInviteUsers') searchFamilyInviteUsers(command: { requesterId: string; groupId: string; query: string }) { return this.family.searchInviteUsers(command.requesterId, command.groupId, command.query); } @GrpcMethod('FamilyService', 'RespondFamilyInvite') respondFamilyInvite(command: { userId: string; inviteId: string; accept: boolean }) { return this.family.respondInvite(command.userId, command.inviteId, command.accept); } @GrpcMethod('FamilyService', 'ListFamilyInvites') listFamilyInvites(command: { userId: string; groupId?: string }) { return this.family.listInvites(command.userId, command.groupId); } @GrpcMethod('FamilyService', 'GetFamilyPresence') getFamilyPresence(command: { requesterId: string; groupId: string }) { return this.presence.getFamilyPresence(command.requesterId, command.groupId); } @GrpcMethod('NotificationsService', 'ListNotifications') listNotifications(command: { userId: string; limit?: number; unreadOnly?: boolean }) { return this.notifications.list(command.userId, command.limit, command.unreadOnly); } @GrpcMethod('NotificationsService', 'GetUnreadCount') getUnreadCount(command: { userId: string }) { return this.notifications.unreadCount(command.userId); } @GrpcMethod('NotificationsService', 'MarkNotificationRead') markNotificationRead(command: { userId: string; notificationId: string }) { return this.notifications.markRead(command.userId, command.notificationId); } @GrpcMethod('NotificationsService', 'MarkAllNotificationsRead') markAllNotificationsRead(command: { userId: string }) { return this.notifications.markAllRead(command.userId); } @GrpcMethod('NotificationsService', 'DeleteNotification') deleteNotification(command: { userId: string; notificationId: string }) { return this.notifications.delete(command.userId, command.notificationId); } @GrpcMethod('NotificationsService', 'DeleteAllNotifications') deleteAllNotifications(command: { userId: string }) { return this.notifications.deleteAll(command.userId); } @GrpcMethod('ChatService', 'ListRooms') listChatRooms(command: { userId: string; groupId: string }) { return this.chat.listRooms(command.userId, command.groupId); } @GrpcMethod('ChatService', 'CreateRoom') createChatRoom(command: { userId: string; groupId: string; name: string; memberUserIds?: string[] }) { return this.chat.createRoom(command.userId, command.groupId, command.name, command.memberUserIds ?? []); } @GrpcMethod('ChatService', 'UpdateRoomSettings') updateChatRoomSettings(command: { userId: string; roomId: string; name?: string; notificationsMuted?: boolean }) { return this.chat.updateRoomSettings(command.userId, command.roomId, command.name, command.notificationsMuted); } @GrpcMethod('ChatService', 'AddRoomMember') addChatRoomMember(command: { userId: string; roomId: string; memberUserId: string }) { return this.chat.addRoomMember(command.userId, command.roomId, command.memberUserId); } @GrpcMethod('ChatService', 'RemoveRoomMember') removeChatRoomMember(command: { userId: string; roomId: string; memberUserId: string }) { return this.chat.removeRoomMember(command.userId, command.roomId, command.memberUserId); } @GrpcMethod('ChatService', 'ListMessages') listChatMessages(command: { userId: string; roomId: string; beforeMessageId?: string; limit?: number }) { return this.chat.listMessages(command.userId, command.roomId, command.beforeMessageId, command.limit); } @GrpcMethod('ChatService', 'SendMessage') sendChatMessage(command: { userId: string; roomId: string; type: string; content?: string; replyToId?: string; storageKey?: string; mimeType?: string; metadataJson?: string; poll?: { question: string; options: string[]; allowsMultiple?: boolean; isAnonymous?: boolean }; }) { return this.chat.sendMessage( command.userId, command.roomId, command.type, command.content, command.replyToId, command.storageKey, command.mimeType, command.metadataJson, command.poll ); } @GrpcMethod('ChatService', 'VotePoll') voteChatPoll(command: { userId: string; messageId: string; optionIds?: string[] }) { return this.chat.votePoll(command.userId, command.messageId, command.optionIds ?? []); } @GrpcMethod('ChatService', 'SetRoomNotificationsMuted') setRoomNotificationsMuted(command: { userId: string; roomId: string; muted: boolean }) { return this.chat.setRoomNotificationsMuted(command.userId, command.roomId, command.muted); } @GrpcMethod('ChatService', 'EditMessage') editChatMessage(command: { userId: string; messageId: string; content: string }) { return this.chat.editMessage(command.userId, command.messageId, command.content); } @GrpcMethod('ChatService', 'DeleteMessage') deleteChatMessage(command: { userId: string; messageId: string }) { return this.chat.deleteMessage(command.userId, command.messageId); } @GrpcMethod('ChatService', 'MarkRoomRead') markChatRoomRead(command: { userId: string; roomId: string; lastMessageId?: string }) { return this.chat.markRoomRead(command.userId, command.roomId, command.lastMessageId); } private toSessionResponse(session: { id: string; userId: string; deviceId: string | null; pinVerified: boolean; status: string; ipAddress: string | null; userAgent: string | null; expiresAt: Date; createdAt: Date; updatedAt: Date }) { return { id: session.id, userId: session.userId, deviceId: session.deviceId, pinVerified: session.pinVerified, status: session.status, ipAddress: session.ipAddress, userAgent: session.userAgent, expiresAt: session.expiresAt.toISOString(), createdAt: session.createdAt.toISOString(), updatedAt: session.updatedAt.toISOString() }; } private toLinkedAccountResponse(account: { id: string; userId: string; providerName: string; providerId: string; email: string | null; displayName: string | null; avatarUrl: string | null; createdAt: Date; updatedAt: Date }) { return { ...account, createdAt: account.createdAt.toISOString(), updatedAt: account.updatedAt.toISOString() }; } private toSocialProviderResponse(provider: { id: string; providerName: string; clientId: string; clientSecret: string | null; isEnabled: boolean; createdAt: Date; updatedAt: Date }) { return { ...provider, createdAt: provider.createdAt.toISOString(), updatedAt: provider.updatedAt.toISOString() }; } }