mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 20:21:09 +02:00
♻️ refactor: migrate all remaining bots to shared services
Completed migration of all Matrix bots to @manacore/bot-services: **SessionService (11 bots migrated):** - matrix-chat-bot (with conversation/model mapping via setSessionData) - matrix-contacts-bot - matrix-skilltree-bot - matrix-presi-bot - matrix-questions-bot - matrix-storage-bot - matrix-planta-bot - matrix-manadeck-bot - matrix-nutriphi-bot (with pendingImage via setSessionData) - matrix-picture-bot (previous commit) - matrix-zitare-bot (previous commit) **TranscriptionService (5 bots migrated):** - matrix-todo-bot (previous commit) - matrix-clock-bot (previous commit) - matrix-zitare-bot (previous commit) - matrix-nutriphi-bot - matrix-project-doc-bot **Code Reduction:** - Deleted 22 local module files (session + transcription) - ~1100 lines of duplicate code removed total - All bots now share identical auth and STT logic **Special handling:** - matrix-chat-bot: Extended methods converted to setSessionData/getSessionData - matrix-nutriphi-bot: pendingImage state via setSessionData - matrix-project-doc-bot: TranscriptionService used by MediaService Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
9b61831cb5
commit
2b979d5548
61 changed files with 640 additions and 1393 deletions
|
|
@ -22,6 +22,7 @@
|
|||
"type-check": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@manacore/bot-services": "workspace:*",
|
||||
"@nestjs/common": "^10.4.15",
|
||||
"@nestjs/config": "^3.3.0",
|
||||
"@nestjs/core": "^10.4.15",
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { MatrixService } from './matrix.service';
|
||||
import { ChatModule } from '../chat/chat.module';
|
||||
import { SessionModule } from '../session/session.module';
|
||||
import { SessionModule } from '@manacore/bot-services';
|
||||
|
||||
@Module({
|
||||
imports: [ChatModule, SessionModule],
|
||||
imports: [ChatModule, SessionModule.forRoot()],
|
||||
providers: [MatrixService],
|
||||
exports: [MatrixService],
|
||||
})
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import {
|
|||
RichReply,
|
||||
} from 'matrix-bot-sdk';
|
||||
import { ChatService, Model, Conversation, Message } from '../chat/chat.service';
|
||||
import { SessionService } from '../session/session.service';
|
||||
import { SessionService } from '@manacore/bot-services';
|
||||
import { HELP_MESSAGE, BRANCH_ICONS } from '../config/configuration';
|
||||
|
||||
@Injectable()
|
||||
|
|
@ -22,6 +22,43 @@ export class MatrixService implements OnModuleInit {
|
|||
private sessionService: SessionService
|
||||
) {}
|
||||
|
||||
// Session data helper methods (wrapping the generic setSessionData/getSessionData)
|
||||
private getCurrentConversation(sender: string): string | null {
|
||||
return this.sessionService.getSessionData<string>(sender, 'currentConversationId');
|
||||
}
|
||||
|
||||
private setCurrentConversation(sender: string, conversationId: string | null): void {
|
||||
this.sessionService.setSessionData(sender, 'currentConversationId', conversationId);
|
||||
}
|
||||
|
||||
private getSelectedModel(sender: string): string | null {
|
||||
return this.sessionService.getSessionData<string>(sender, 'selectedModelId');
|
||||
}
|
||||
|
||||
private setSelectedModel(sender: string, modelId: string): void {
|
||||
this.sessionService.setSessionData(sender, 'selectedModelId', modelId);
|
||||
}
|
||||
|
||||
private setConversationMapping(sender: string, ids: string[]): void {
|
||||
this.sessionService.setSessionData(sender, 'conversationMapping', ids);
|
||||
}
|
||||
|
||||
private getConversationId(sender: string, number: number): string | null {
|
||||
const ids = this.sessionService.getSessionData<string[]>(sender, 'conversationMapping');
|
||||
if (!ids || number < 1 || number > ids.length) return null;
|
||||
return ids[number - 1];
|
||||
}
|
||||
|
||||
private setModelMapping(sender: string, ids: string[]): void {
|
||||
this.sessionService.setSessionData(sender, 'modelMapping', ids);
|
||||
}
|
||||
|
||||
private getModelId(sender: string, number: number): string | null {
|
||||
const ids = this.sessionService.getSessionData<string[]>(sender, 'modelMapping');
|
||||
if (!ids || number < 1 || number > ids.length) return null;
|
||||
return ids[number - 1];
|
||||
}
|
||||
|
||||
async onModuleInit() {
|
||||
const homeserverUrl = this.configService.get<string>('matrix.homeserverUrl');
|
||||
const accessToken = this.configService.get<string>('matrix.accessToken');
|
||||
|
|
@ -200,8 +237,8 @@ export class MatrixService implements OnModuleInit {
|
|||
|
||||
private handleStatus(sender: string): string {
|
||||
const isLoggedIn = this.sessionService.isLoggedIn(sender);
|
||||
const currentConv = this.sessionService.getCurrentConversation(sender);
|
||||
const selectedModel = this.sessionService.getSelectedModel(sender);
|
||||
const currentConv = this.getCurrentConversation(sender);
|
||||
const selectedModel = this.getSelectedModel(sender);
|
||||
|
||||
let status = `**Bot Status**\n`;
|
||||
status += `- Angemeldet: ${isLoggedIn ? 'Ja' : 'Nein'}\n`;
|
||||
|
|
@ -232,7 +269,7 @@ export class MatrixService implements OnModuleInit {
|
|||
return 'Keine AI-Modelle verfuegbar.';
|
||||
}
|
||||
|
||||
const selectedModelId = this.sessionService.getSelectedModel(sender);
|
||||
const selectedModelId = this.getSelectedModel(sender);
|
||||
const modelId = selectedModelId || modelsResult.data.find((m) => m.isDefault)?.id || modelsResult.data[0].id;
|
||||
|
||||
const result = await this.chatService.createCompletion(
|
||||
|
|
@ -265,7 +302,7 @@ export class MatrixService implements OnModuleInit {
|
|||
return 'Keine AI-Modelle verfuegbar.';
|
||||
}
|
||||
|
||||
const selectedModelId = this.sessionService.getSelectedModel(sender);
|
||||
const selectedModelId = this.getSelectedModel(sender);
|
||||
const modelId = selectedModelId || modelsResult.data.find((m) => m.isDefault)?.id || modelsResult.data[0].id;
|
||||
|
||||
const convTitle = title || `Matrix Chat ${new Date().toLocaleDateString('de-DE')}`;
|
||||
|
|
@ -279,7 +316,7 @@ export class MatrixService implements OnModuleInit {
|
|||
return `Fehler: ${result.error}`;
|
||||
}
|
||||
|
||||
this.sessionService.setCurrentConversation(sender, result.data!.id);
|
||||
this.setCurrentConversation(sender, result.data!.id);
|
||||
return `Neues Gespraech erstellt: **${result.data!.title}**\nNutze \`!senden [nachricht]\` um zu chatten.`;
|
||||
}
|
||||
|
||||
|
|
@ -305,12 +342,12 @@ export class MatrixService implements OnModuleInit {
|
|||
});
|
||||
|
||||
// Store mapping
|
||||
this.sessionService.setConversationMapping(
|
||||
this.setConversationMapping(
|
||||
sender,
|
||||
sorted.map((c) => c.id)
|
||||
);
|
||||
|
||||
const currentId = this.sessionService.getCurrentConversation(sender);
|
||||
const currentId = this.getCurrentConversation(sender);
|
||||
|
||||
let response = '**Deine Gespraeche:**\n\n';
|
||||
sorted.forEach((conv, index) => {
|
||||
|
|
@ -332,7 +369,7 @@ export class MatrixService implements OnModuleInit {
|
|||
|
||||
if (!numberStr) {
|
||||
// Show current conversation
|
||||
const currentId = this.sessionService.getCurrentConversation(sender);
|
||||
const currentId = this.getCurrentConversation(sender);
|
||||
if (!currentId) {
|
||||
return 'Kein Gespraech ausgewaehlt. Nutze `!gespraeche` und dann `!gespraech [nr]`';
|
||||
}
|
||||
|
|
@ -350,7 +387,7 @@ export class MatrixService implements OnModuleInit {
|
|||
return 'Bitte eine gueltige Nummer angeben.';
|
||||
}
|
||||
|
||||
const conversationId = this.sessionService.getConversationId(sender, number);
|
||||
const conversationId = this.getConversationId(sender, number);
|
||||
if (!conversationId) {
|
||||
return 'Ungueltige Nummer. Nutze `!gespraeche` fuer eine aktuelle Liste.';
|
||||
}
|
||||
|
|
@ -360,7 +397,7 @@ export class MatrixService implements OnModuleInit {
|
|||
return `Fehler: ${result.error}`;
|
||||
}
|
||||
|
||||
this.sessionService.setCurrentConversation(sender, conversationId);
|
||||
this.setCurrentConversation(sender, conversationId);
|
||||
return `Gespraech ausgewaehlt: **${result.data!.title}**\n\n${this.formatConversationDetails(result.data!)}`;
|
||||
}
|
||||
|
||||
|
|
@ -388,7 +425,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
|
|||
return 'Bitte zuerst anmelden mit `!login email passwort`';
|
||||
}
|
||||
|
||||
const conversationId = this.sessionService.getCurrentConversation(sender);
|
||||
const conversationId = this.getCurrentConversation(sender);
|
||||
if (!conversationId) {
|
||||
return 'Kein Gespraech ausgewaehlt. Nutze `!gespraeche` und `!gespraech [nr]` oder `!neu [titel]`';
|
||||
}
|
||||
|
|
@ -434,12 +471,12 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
|
|||
return 'Bitte zuerst anmelden mit `!login email passwort`';
|
||||
}
|
||||
|
||||
let conversationId = this.sessionService.getCurrentConversation(sender);
|
||||
let conversationId = this.getCurrentConversation(sender);
|
||||
|
||||
if (numberStr) {
|
||||
const number = parseInt(numberStr, 10);
|
||||
if (!isNaN(number)) {
|
||||
const id = this.sessionService.getConversationId(sender, number);
|
||||
const id = this.getConversationId(sender, number);
|
||||
if (id) conversationId = id;
|
||||
}
|
||||
}
|
||||
|
|
@ -489,7 +526,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
|
|||
return 'Bitte eine gueltige Nummer angeben.';
|
||||
}
|
||||
|
||||
const conversationId = this.sessionService.getConversationId(sender, number);
|
||||
const conversationId = this.getConversationId(sender, number);
|
||||
if (!conversationId) {
|
||||
return 'Ungueltige Nummer. Nutze `!gespraeche` fuer eine aktuelle Liste.';
|
||||
}
|
||||
|
|
@ -517,7 +554,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
|
|||
return 'Bitte eine gueltige Nummer angeben.';
|
||||
}
|
||||
|
||||
const conversationId = this.sessionService.getConversationId(sender, number);
|
||||
const conversationId = this.getConversationId(sender, number);
|
||||
if (!conversationId) {
|
||||
return 'Ungueltige Nummer. Nutze `!gespraeche` fuer eine aktuelle Liste.';
|
||||
}
|
||||
|
|
@ -546,7 +583,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
|
|||
}
|
||||
|
||||
// Store mapping for restore
|
||||
this.sessionService.setConversationMapping(
|
||||
this.setConversationMapping(
|
||||
sender,
|
||||
result.data.map((c) => c.id)
|
||||
);
|
||||
|
|
@ -576,7 +613,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
|
|||
return 'Bitte eine gueltige Nummer angeben.';
|
||||
}
|
||||
|
||||
const conversationId = this.sessionService.getConversationId(sender, number);
|
||||
const conversationId = this.getConversationId(sender, number);
|
||||
if (!conversationId) {
|
||||
return 'Ungueltige Nummer. Nutze `!archiviert` fuer eine aktuelle Liste.';
|
||||
}
|
||||
|
|
@ -604,7 +641,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
|
|||
return 'Bitte eine gueltige Nummer angeben.';
|
||||
}
|
||||
|
||||
const conversationId = this.sessionService.getConversationId(sender, number);
|
||||
const conversationId = this.getConversationId(sender, number);
|
||||
if (!conversationId) {
|
||||
return 'Ungueltige Nummer. Nutze `!gespraeche` fuer eine aktuelle Liste.';
|
||||
}
|
||||
|
|
@ -632,7 +669,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
|
|||
return 'Bitte eine gueltige Nummer angeben.';
|
||||
}
|
||||
|
||||
const conversationId = this.sessionService.getConversationId(sender, number);
|
||||
const conversationId = this.getConversationId(sender, number);
|
||||
if (!conversationId) {
|
||||
return 'Ungueltige Nummer. Nutze `!gespraeche` fuer eine aktuelle Liste.';
|
||||
}
|
||||
|
|
@ -660,7 +697,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
|
|||
return 'Bitte eine gueltige Nummer angeben.';
|
||||
}
|
||||
|
||||
const conversationId = this.sessionService.getConversationId(sender, number);
|
||||
const conversationId = this.getConversationId(sender, number);
|
||||
if (!conversationId) {
|
||||
return 'Ungueltige Nummer. Nutze `!gespraeche` fuer eine aktuelle Liste.';
|
||||
}
|
||||
|
|
@ -675,8 +712,8 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
|
|||
}
|
||||
|
||||
// Clear current conversation if it was the deleted one
|
||||
if (this.sessionService.getCurrentConversation(sender) === conversationId) {
|
||||
this.sessionService.setCurrentConversation(sender, null);
|
||||
if (this.getCurrentConversation(sender) === conversationId) {
|
||||
this.setCurrentConversation(sender, null);
|
||||
}
|
||||
|
||||
return `Gespraech **${title}** geloescht.`;
|
||||
|
|
@ -696,12 +733,12 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
|
|||
const activeModels = result.data.filter((m) => m.isActive);
|
||||
|
||||
// Store mapping
|
||||
this.sessionService.setModelMapping(
|
||||
this.setModelMapping(
|
||||
sender,
|
||||
activeModels.map((m) => m.id)
|
||||
);
|
||||
|
||||
const selectedModelId = this.sessionService.getSelectedModel(sender);
|
||||
const selectedModelId = this.getSelectedModel(sender);
|
||||
|
||||
let response = '**Verfuegbare AI-Modelle:**\n\n';
|
||||
activeModels.forEach((model, index) => {
|
||||
|
|
@ -718,7 +755,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
|
|||
|
||||
private async handleSelectModel(sender: string, numberStr: string): Promise<string> {
|
||||
if (!numberStr) {
|
||||
const selectedModelId = this.sessionService.getSelectedModel(sender);
|
||||
const selectedModelId = this.getSelectedModel(sender);
|
||||
if (!selectedModelId) {
|
||||
return 'Kein Modell ausgewaehlt (Standard wird verwendet). Nutze `!modelle` und `!modell [nr]`';
|
||||
}
|
||||
|
|
@ -737,7 +774,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
|
|||
return 'Bitte eine gueltige Nummer angeben.';
|
||||
}
|
||||
|
||||
const modelId = this.sessionService.getModelId(sender, number);
|
||||
const modelId = this.getModelId(sender, number);
|
||||
if (!modelId) {
|
||||
return 'Ungueltige Nummer. Nutze `!modelle` fuer eine aktuelle Liste.';
|
||||
}
|
||||
|
|
@ -747,7 +784,7 @@ Nutze \`!senden [nachricht]\` um zu chatten oder \`!verlauf\` fuer den Nachricht
|
|||
return `Fehler: ${result.error}`;
|
||||
}
|
||||
|
||||
this.sessionService.setSelectedModel(sender, modelId);
|
||||
this.setSelectedModel(sender, modelId);
|
||||
const icon = BRANCH_ICONS[result.data!.provider] || BRANCH_ICONS.default;
|
||||
return `Modell gewaehlt: ${icon} **${result.data!.name}**\nWird fuer neue Gespraeche und Quick-Chat verwendet.`;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { SessionService } from './session.service';
|
||||
|
||||
@Module({
|
||||
providers: [SessionService],
|
||||
exports: [SessionService],
|
||||
})
|
||||
export class SessionModule {}
|
||||
|
|
@ -1,142 +0,0 @@
|
|||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
||||
interface UserSession {
|
||||
token: string;
|
||||
email: string;
|
||||
expiresAt: Date;
|
||||
currentConversationId?: string;
|
||||
selectedModelId?: string;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class SessionService {
|
||||
private readonly logger = new Logger(SessionService.name);
|
||||
private sessions: Map<string, UserSession> = new Map();
|
||||
private authUrl: string;
|
||||
|
||||
// Store conversation list mappings per user
|
||||
private conversationMappings: Map<string, string[]> = new Map();
|
||||
private modelMappings: Map<string, string[]> = new Map();
|
||||
|
||||
constructor(private configService: ConfigService) {
|
||||
this.authUrl = this.configService.get<string>('auth.url') || 'http://localhost:3001';
|
||||
}
|
||||
|
||||
async login(
|
||||
matrixUserId: string,
|
||||
email: string,
|
||||
password: string
|
||||
): Promise<{ success: boolean; error?: string }> {
|
||||
try {
|
||||
const response = await fetch(`${this.authUrl}/api/v1/auth/login`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email, password }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}));
|
||||
return {
|
||||
success: false,
|
||||
error: errorData.message || 'Authentifizierung fehlgeschlagen',
|
||||
};
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const token = data.accessToken || data.token;
|
||||
|
||||
if (!token) {
|
||||
return { success: false, error: 'Kein Token erhalten' };
|
||||
}
|
||||
|
||||
this.sessions.set(matrixUserId, {
|
||||
token,
|
||||
email,
|
||||
expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
|
||||
});
|
||||
|
||||
this.logger.log(`User ${matrixUserId} logged in as ${email}`);
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
this.logger.error(`Login failed for ${matrixUserId}:`, error);
|
||||
return {
|
||||
success: false,
|
||||
error: 'Verbindung zum Auth-Server fehlgeschlagen',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
logout(matrixUserId: string): void {
|
||||
this.sessions.delete(matrixUserId);
|
||||
this.conversationMappings.delete(matrixUserId);
|
||||
this.modelMappings.delete(matrixUserId);
|
||||
this.logger.log(`User ${matrixUserId} logged out`);
|
||||
}
|
||||
|
||||
getToken(matrixUserId: string): string | null {
|
||||
const session = this.sessions.get(matrixUserId);
|
||||
if (!session) return null;
|
||||
if (session.expiresAt < new Date()) {
|
||||
this.sessions.delete(matrixUserId);
|
||||
return null;
|
||||
}
|
||||
return session.token;
|
||||
}
|
||||
|
||||
isLoggedIn(matrixUserId: string): boolean {
|
||||
return this.getToken(matrixUserId) !== null;
|
||||
}
|
||||
|
||||
getSessionCount(): number {
|
||||
return this.sessions.size;
|
||||
}
|
||||
|
||||
// Current conversation management
|
||||
setCurrentConversation(matrixUserId: string, conversationId: string | null): void {
|
||||
const session = this.sessions.get(matrixUserId);
|
||||
if (session) {
|
||||
session.currentConversationId = conversationId || undefined;
|
||||
}
|
||||
}
|
||||
|
||||
getCurrentConversation(matrixUserId: string): string | null {
|
||||
const session = this.sessions.get(matrixUserId);
|
||||
return session?.currentConversationId || null;
|
||||
}
|
||||
|
||||
// Selected model management
|
||||
setSelectedModel(matrixUserId: string, modelId: string): void {
|
||||
const session = this.sessions.get(matrixUserId);
|
||||
if (session) {
|
||||
session.selectedModelId = modelId;
|
||||
}
|
||||
}
|
||||
|
||||
getSelectedModel(matrixUserId: string): string | null {
|
||||
const session = this.sessions.get(matrixUserId);
|
||||
return session?.selectedModelId || null;
|
||||
}
|
||||
|
||||
// Conversation number mapping
|
||||
setConversationMapping(matrixUserId: string, ids: string[]): void {
|
||||
this.conversationMappings.set(matrixUserId, ids);
|
||||
}
|
||||
|
||||
getConversationId(matrixUserId: string, number: number): string | null {
|
||||
const ids = this.conversationMappings.get(matrixUserId);
|
||||
if (!ids || number < 1 || number > ids.length) return null;
|
||||
return ids[number - 1];
|
||||
}
|
||||
|
||||
// Model number mapping
|
||||
setModelMapping(matrixUserId: string, ids: string[]): void {
|
||||
this.modelMappings.set(matrixUserId, ids);
|
||||
}
|
||||
|
||||
getModelId(matrixUserId: string, number: number): string | null {
|
||||
const ids = this.modelMappings.get(matrixUserId);
|
||||
if (!ids || number < 1 || number > ids.length) return null;
|
||||
return ids[number - 1];
|
||||
}
|
||||
}
|
||||
|
|
@ -22,6 +22,7 @@
|
|||
"type-check": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@manacore/bot-services": "workspace:*",
|
||||
"@nestjs/common": "^10.4.15",
|
||||
"@nestjs/config": "^3.3.0",
|
||||
"@nestjs/core": "^10.4.15",
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { MatrixService } from './matrix.service';
|
||||
import { ContactsModule } from '../contacts/contacts.module';
|
||||
import { SessionModule } from '../session/session.module';
|
||||
import { SessionModule } from '@manacore/bot-services';
|
||||
|
||||
@Module({
|
||||
imports: [ContactsModule, SessionModule],
|
||||
imports: [ContactsModule, SessionModule.forRoot()],
|
||||
providers: [MatrixService],
|
||||
exports: [MatrixService],
|
||||
})
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import {
|
|||
LogLevel,
|
||||
} from 'matrix-bot-sdk';
|
||||
import { ContactsService, Contact } from '../contacts/contacts.service';
|
||||
import { SessionService } from '../session/session.service';
|
||||
import { SessionService } from '@manacore/bot-services';
|
||||
import { HELP_MESSAGE } from '../config/configuration';
|
||||
|
||||
// Natural language keywords
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { SessionService } from './session.service';
|
||||
|
||||
@Module({
|
||||
providers: [SessionService],
|
||||
exports: [SessionService],
|
||||
})
|
||||
export class SessionModule {}
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
||||
interface UserSession {
|
||||
token: string;
|
||||
email: string;
|
||||
expiresAt: Date;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class SessionService {
|
||||
private readonly logger = new Logger(SessionService.name);
|
||||
private sessions: Map<string, UserSession> = new Map();
|
||||
private authUrl: string;
|
||||
|
||||
constructor(private configService: ConfigService) {
|
||||
this.authUrl = this.configService.get<string>('auth.url') || 'http://localhost:3001';
|
||||
}
|
||||
|
||||
async login(
|
||||
matrixUserId: string,
|
||||
email: string,
|
||||
password: string
|
||||
): Promise<{ success: boolean; error?: string }> {
|
||||
try {
|
||||
const response = await fetch(`${this.authUrl}/api/v1/auth/login`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email, password }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}));
|
||||
return {
|
||||
success: false,
|
||||
error: errorData.message || 'Authentifizierung fehlgeschlagen',
|
||||
};
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const token = data.accessToken || data.token;
|
||||
|
||||
if (!token) {
|
||||
return { success: false, error: 'Kein Token erhalten' };
|
||||
}
|
||||
|
||||
// Store session (7 days expiry)
|
||||
this.sessions.set(matrixUserId, {
|
||||
token,
|
||||
email,
|
||||
expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
|
||||
});
|
||||
|
||||
this.logger.log(`User ${matrixUserId} logged in as ${email}`);
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
this.logger.error(`Login failed for ${matrixUserId}:`, error);
|
||||
return {
|
||||
success: false,
|
||||
error: 'Verbindung zum Auth-Server fehlgeschlagen',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
logout(matrixUserId: string): void {
|
||||
this.sessions.delete(matrixUserId);
|
||||
this.logger.log(`User ${matrixUserId} logged out`);
|
||||
}
|
||||
|
||||
getToken(matrixUserId: string): string | null {
|
||||
const session = this.sessions.get(matrixUserId);
|
||||
|
||||
if (!session) return null;
|
||||
|
||||
if (session.expiresAt < new Date()) {
|
||||
this.sessions.delete(matrixUserId);
|
||||
return null;
|
||||
}
|
||||
|
||||
return session.token;
|
||||
}
|
||||
|
||||
isLoggedIn(matrixUserId: string): boolean {
|
||||
return this.getToken(matrixUserId) !== null;
|
||||
}
|
||||
|
||||
getSessionCount(): number {
|
||||
return this.sessions.size;
|
||||
}
|
||||
}
|
||||
|
|
@ -22,6 +22,7 @@
|
|||
"type-check": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@manacore/bot-services": "workspace:*",
|
||||
"@nestjs/common": "^10.4.15",
|
||||
"@nestjs/config": "^3.3.0",
|
||||
"@nestjs/core": "^10.4.15",
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import { ConfigModule } from '@nestjs/config';
|
|||
import { HealthController } from './health.controller';
|
||||
import { BotModule } from './bot/bot.module';
|
||||
import { ManadeckModule } from './manadeck/manadeck.module';
|
||||
import { SessionModule } from './session/session.module';
|
||||
import configuration from './config/configuration';
|
||||
|
||||
@Module({
|
||||
|
|
@ -14,7 +13,6 @@ import configuration from './config/configuration';
|
|||
}),
|
||||
BotModule,
|
||||
ManadeckModule,
|
||||
SessionModule,
|
||||
],
|
||||
controllers: [HealthController],
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { MatrixService } from './matrix.service';
|
||||
import { ManadeckModule } from '../manadeck/manadeck.module';
|
||||
import { SessionModule } from '../session/session.module';
|
||||
import { SessionModule } from '@manacore/bot-services';
|
||||
|
||||
@Module({
|
||||
imports: [ManadeckModule, SessionModule],
|
||||
imports: [ManadeckModule, SessionModule.forRoot()],
|
||||
providers: [MatrixService],
|
||||
exports: [MatrixService],
|
||||
})
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import {
|
|||
AutojoinRoomsMixin,
|
||||
} from 'matrix-bot-sdk';
|
||||
import { ManadeckService, Deck, Card } from '../manadeck/manadeck.service';
|
||||
import { SessionService } from '../session/session.service';
|
||||
import { SessionService } from '@manacore/bot-services';
|
||||
import { HELP_MESSAGE } from '../config/configuration';
|
||||
|
||||
@Injectable()
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { SessionService } from './session.service';
|
||||
|
||||
@Module({
|
||||
providers: [SessionService],
|
||||
exports: [SessionService],
|
||||
})
|
||||
export class SessionModule {}
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
||||
interface UserSession {
|
||||
token: string;
|
||||
email: string;
|
||||
expiresAt: Date;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class SessionService {
|
||||
private readonly logger = new Logger(SessionService.name);
|
||||
private sessions: Map<string, UserSession> = new Map();
|
||||
private authUrl: string;
|
||||
|
||||
constructor(private configService: ConfigService) {
|
||||
this.authUrl = this.configService.get<string>('auth.url') || 'http://localhost:3001';
|
||||
}
|
||||
|
||||
async login(
|
||||
matrixUserId: string,
|
||||
email: string,
|
||||
password: string
|
||||
): Promise<{ success: boolean; error?: string }> {
|
||||
try {
|
||||
const response = await fetch(`${this.authUrl}/api/v1/auth/login`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email, password }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}));
|
||||
return {
|
||||
success: false,
|
||||
error: errorData.message || 'Authentifizierung fehlgeschlagen',
|
||||
};
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const token = data.accessToken || data.token;
|
||||
|
||||
if (!token) {
|
||||
return { success: false, error: 'Kein Token erhalten' };
|
||||
}
|
||||
|
||||
// Store session (7 days expiry)
|
||||
this.sessions.set(matrixUserId, {
|
||||
token,
|
||||
email,
|
||||
expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
|
||||
});
|
||||
|
||||
this.logger.log(`User ${matrixUserId} logged in as ${email}`);
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
this.logger.error(`Login failed for ${matrixUserId}:`, error);
|
||||
return {
|
||||
success: false,
|
||||
error: 'Verbindung zum Auth-Server fehlgeschlagen',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
logout(matrixUserId: string): void {
|
||||
this.sessions.delete(matrixUserId);
|
||||
this.logger.log(`User ${matrixUserId} logged out`);
|
||||
}
|
||||
|
||||
getToken(matrixUserId: string): string | null {
|
||||
const session = this.sessions.get(matrixUserId);
|
||||
|
||||
if (!session) return null;
|
||||
|
||||
if (session.expiresAt < new Date()) {
|
||||
this.sessions.delete(matrixUserId);
|
||||
return null;
|
||||
}
|
||||
|
||||
return session.token;
|
||||
}
|
||||
|
||||
isLoggedIn(matrixUserId: string): boolean {
|
||||
return this.getToken(matrixUserId) !== null;
|
||||
}
|
||||
|
||||
getSessionCount(): number {
|
||||
return this.sessions.size;
|
||||
}
|
||||
}
|
||||
|
|
@ -27,6 +27,7 @@
|
|||
"type-check": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@manacore/bot-services": "workspace:*",
|
||||
"@nestjs/common": "^10.4.15",
|
||||
"@nestjs/config": "^3.3.0",
|
||||
"@nestjs/core": "^10.4.15",
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { MatrixService } from './matrix.service';
|
||||
import { NutriPhiModule } from '../nutriphi/nutriphi.module';
|
||||
import { SessionModule } from '../session/session.module';
|
||||
import { TranscriptionModule } from '../transcription/transcription.module';
|
||||
import { SessionModule, TranscriptionModule } from '@manacore/bot-services';
|
||||
|
||||
@Module({
|
||||
imports: [NutriPhiModule, SessionModule, TranscriptionModule],
|
||||
imports: [NutriPhiModule, SessionModule.forRoot(), TranscriptionModule.forRoot()],
|
||||
providers: [MatrixService],
|
||||
exports: [MatrixService],
|
||||
})
|
||||
|
|
|
|||
|
|
@ -13,8 +13,7 @@ import {
|
|||
DailySummary,
|
||||
WeeklyStats,
|
||||
} from '../nutriphi/nutriphi.service';
|
||||
import { SessionService } from '../session/session.service';
|
||||
import { TranscriptionService } from '../transcription/transcription.service';
|
||||
import { SessionService, TranscriptionService } from '@manacore/bot-services';
|
||||
import { HELP_MESSAGE, MEAL_TYPE_LABELS } from '../config/configuration';
|
||||
|
||||
// Natural language keywords that trigger commands (German + English)
|
||||
|
|
@ -136,11 +135,10 @@ Sag "hilfe" fur alle Befehle!`;
|
|||
|
||||
// Handle image messages
|
||||
if (content.msgtype === 'm.image' && content.url) {
|
||||
this.sessionService.setPendingImage(
|
||||
event.sender,
|
||||
content.url,
|
||||
content.info?.mimetype || 'image/png'
|
||||
);
|
||||
this.sessionService.setSessionData(event.sender, 'pendingImage', {
|
||||
url: content.url,
|
||||
mimeType: content.info?.mimetype || 'image/png',
|
||||
});
|
||||
this.logger.log(`Image received from ${event.sender}`);
|
||||
await this.sendMessage(
|
||||
roomId,
|
||||
|
|
@ -298,7 +296,10 @@ Sag "hilfe" fur alle Befehle!`;
|
|||
return;
|
||||
}
|
||||
|
||||
const pendingImage = this.sessionService.getPendingImage(sender);
|
||||
const pendingImage = this.sessionService.getSessionData<{ url: string; mimeType: string }>(
|
||||
sender,
|
||||
'pendingImage'
|
||||
);
|
||||
|
||||
// If no image and no description, show help
|
||||
if (!pendingImage && !description.trim()) {
|
||||
|
|
@ -319,7 +320,7 @@ Sag "hilfe" fur alle Befehle!`;
|
|||
await this.sendMessage(roomId, 'Analysiere Bild...');
|
||||
const imageData = await this.downloadMatrixImage(pendingImage.url);
|
||||
result = await this.nutriphiService.analyzePhoto(imageData, pendingImage.mimeType, token);
|
||||
this.sessionService.clearPendingImage(sender);
|
||||
this.sessionService.setSessionData(sender, 'pendingImage', null);
|
||||
} else {
|
||||
// Analyze text
|
||||
await this.sendMessage(roomId, `Analysiere: "${description}"...`);
|
||||
|
|
@ -634,7 +635,7 @@ Sag "hilfe" fur alle Befehle!`;
|
|||
const backendHealthy = await this.nutriphiService.checkHealth();
|
||||
const isLoggedIn = this.sessionService.isLoggedIn(sender);
|
||||
const sessionCount = this.sessionService.getSessionCount();
|
||||
const loggedInCount = this.sessionService.getLoggedInCount();
|
||||
const loggedInCount = this.sessionService.getActiveSessionCount();
|
||||
|
||||
const statusText = `**NutriPhi Bot Status**
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { SessionService } from './session.service';
|
||||
|
||||
@Module({
|
||||
providers: [SessionService],
|
||||
exports: [SessionService],
|
||||
})
|
||||
export class SessionModule {}
|
||||
|
|
@ -1,152 +0,0 @@
|
|||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
||||
export interface UserSession {
|
||||
matrixUserId: string;
|
||||
jwtToken?: string;
|
||||
tokenExpiry?: Date;
|
||||
pendingImage?: { url: string; mimeType: string };
|
||||
lastActivity: Date;
|
||||
}
|
||||
|
||||
export interface LoginResult {
|
||||
success: boolean;
|
||||
token?: string;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class SessionService {
|
||||
private readonly logger = new Logger(SessionService.name);
|
||||
private sessions: Map<string, UserSession> = new Map();
|
||||
private readonly authUrl: string;
|
||||
private readonly devBypass: boolean;
|
||||
private readonly devUserId: string;
|
||||
|
||||
constructor(private configService: ConfigService) {
|
||||
this.authUrl = this.configService.get<string>('auth.url') || 'http://localhost:3001';
|
||||
this.devBypass = this.configService.get<boolean>('auth.devBypass') || false;
|
||||
this.devUserId = this.configService.get<string>('auth.devUserId') || '';
|
||||
}
|
||||
|
||||
getSession(matrixUserId: string): UserSession {
|
||||
if (!this.sessions.has(matrixUserId)) {
|
||||
this.sessions.set(matrixUserId, {
|
||||
matrixUserId,
|
||||
lastActivity: new Date(),
|
||||
});
|
||||
}
|
||||
const session = this.sessions.get(matrixUserId)!;
|
||||
session.lastActivity = new Date();
|
||||
return session;
|
||||
}
|
||||
|
||||
isLoggedIn(matrixUserId: string): boolean {
|
||||
if (this.devBypass && this.devUserId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const session = this.sessions.get(matrixUserId);
|
||||
if (!session?.jwtToken || !session.tokenExpiry) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if token is expired (with 5 minute buffer)
|
||||
const now = new Date();
|
||||
const expiryBuffer = new Date(session.tokenExpiry.getTime() - 5 * 60 * 1000);
|
||||
return now < expiryBuffer;
|
||||
}
|
||||
|
||||
getToken(matrixUserId: string): string | null {
|
||||
if (this.devBypass && this.devUserId) {
|
||||
// In dev mode, return a mock token (the backend should also bypass auth)
|
||||
return 'dev-bypass-token';
|
||||
}
|
||||
|
||||
const session = this.sessions.get(matrixUserId);
|
||||
if (!session?.jwtToken || !this.isLoggedIn(matrixUserId)) {
|
||||
return null;
|
||||
}
|
||||
return session.jwtToken;
|
||||
}
|
||||
|
||||
async login(matrixUserId: string, email: string, password: string): Promise<LoginResult> {
|
||||
try {
|
||||
const response = await fetch(`${this.authUrl}/api/v1/auth/login`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email, password }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.text();
|
||||
this.logger.warn(`Login failed for ${matrixUserId}: ${response.status}`);
|
||||
return { success: false, error: `Login fehlgeschlagen: ${error}` };
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const { accessToken, expiresIn } = data;
|
||||
|
||||
if (!accessToken) {
|
||||
return { success: false, error: 'Kein Token erhalten' };
|
||||
}
|
||||
|
||||
// Calculate expiry time (expiresIn is in seconds)
|
||||
const expiryTime = expiresIn
|
||||
? new Date(Date.now() + expiresIn * 1000)
|
||||
: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000); // Default: 7 days
|
||||
|
||||
const session = this.getSession(matrixUserId);
|
||||
session.jwtToken = accessToken;
|
||||
session.tokenExpiry = expiryTime;
|
||||
|
||||
this.logger.log(`User ${matrixUserId} logged in successfully`);
|
||||
return { success: true, token: accessToken };
|
||||
} catch (error) {
|
||||
this.logger.error(`Login error for ${matrixUserId}:`, error);
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Unbekannter Fehler',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
logout(matrixUserId: string): void {
|
||||
const session = this.sessions.get(matrixUserId);
|
||||
if (session) {
|
||||
session.jwtToken = undefined;
|
||||
session.tokenExpiry = undefined;
|
||||
}
|
||||
this.logger.log(`User ${matrixUserId} logged out`);
|
||||
}
|
||||
|
||||
setPendingImage(matrixUserId: string, url: string, mimeType: string): void {
|
||||
const session = this.getSession(matrixUserId);
|
||||
session.pendingImage = { url, mimeType };
|
||||
}
|
||||
|
||||
getPendingImage(matrixUserId: string): { url: string; mimeType: string } | undefined {
|
||||
return this.sessions.get(matrixUserId)?.pendingImage;
|
||||
}
|
||||
|
||||
clearPendingImage(matrixUserId: string): void {
|
||||
const session = this.sessions.get(matrixUserId);
|
||||
if (session) {
|
||||
session.pendingImage = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
getSessionCount(): number {
|
||||
return this.sessions.size;
|
||||
}
|
||||
|
||||
getLoggedInCount(): number {
|
||||
let count = 0;
|
||||
for (const [userId] of this.sessions) {
|
||||
if (this.isLoggedIn(userId)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { TranscriptionService } from './transcription.service';
|
||||
|
||||
@Module({
|
||||
providers: [TranscriptionService],
|
||||
exports: [TranscriptionService],
|
||||
})
|
||||
export class TranscriptionModule {}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
||||
interface SttResponse {
|
||||
text: string;
|
||||
language?: string;
|
||||
model?: string;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class TranscriptionService {
|
||||
private readonly logger = new Logger(TranscriptionService.name);
|
||||
private readonly sttUrl: string;
|
||||
|
||||
constructor(private configService: ConfigService) {
|
||||
this.sttUrl = this.configService.get<string>('stt.url') || 'http://localhost:3020';
|
||||
this.logger.log(`STT Service URL: ${this.sttUrl}`);
|
||||
}
|
||||
|
||||
async transcribe(audioBuffer: Buffer, language: string = 'de'): Promise<string> {
|
||||
const formData = new FormData();
|
||||
const blob = new Blob([new Uint8Array(audioBuffer)], { type: 'audio/ogg' });
|
||||
formData.append('file', blob, 'audio.ogg');
|
||||
formData.append('language', language);
|
||||
|
||||
try {
|
||||
const response = await fetch(`${this.sttUrl}/transcribe`, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
throw new Error(`STT service error: ${response.status} - ${errorText}`);
|
||||
}
|
||||
|
||||
const result: SttResponse = await response.json();
|
||||
this.logger.log(`Transcription completed: ${result.text.substring(0, 50)}...`);
|
||||
return result.text;
|
||||
} catch (error) {
|
||||
this.logger.error('Transcription failed:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async checkHealth(): Promise<boolean> {
|
||||
try {
|
||||
const response = await fetch(`${this.sttUrl}/health`);
|
||||
return response.ok;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -22,6 +22,7 @@
|
|||
"type-check": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@manacore/bot-services": "workspace:*",
|
||||
"@nestjs/common": "^10.4.15",
|
||||
"@nestjs/config": "^3.3.0",
|
||||
"@nestjs/core": "^10.4.15",
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import { ConfigModule } from '@nestjs/config';
|
|||
import { HealthController } from './health.controller';
|
||||
import { BotModule } from './bot/bot.module';
|
||||
import { PlantaModule } from './planta/planta.module';
|
||||
import { SessionModule } from './session/session.module';
|
||||
import configuration from './config/configuration';
|
||||
|
||||
@Module({
|
||||
|
|
@ -14,7 +13,6 @@ import configuration from './config/configuration';
|
|||
}),
|
||||
BotModule,
|
||||
PlantaModule,
|
||||
SessionModule,
|
||||
],
|
||||
controllers: [HealthController],
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { MatrixService } from './matrix.service';
|
||||
import { PlantaModule } from '../planta/planta.module';
|
||||
import { SessionModule } from '../session/session.module';
|
||||
import { SessionModule } from '@manacore/bot-services';
|
||||
|
||||
@Module({
|
||||
imports: [PlantaModule, SessionModule],
|
||||
imports: [PlantaModule, SessionModule.forRoot()],
|
||||
providers: [MatrixService],
|
||||
exports: [MatrixService],
|
||||
})
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import {
|
|||
AutojoinRoomsMixin,
|
||||
} from 'matrix-bot-sdk';
|
||||
import { PlantaService, Plant } from '../planta/planta.service';
|
||||
import { SessionService } from '../session/session.service';
|
||||
import { SessionService } from '@manacore/bot-services';
|
||||
import { HELP_MESSAGE } from '../config/configuration';
|
||||
|
||||
@Injectable()
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { SessionService } from './session.service';
|
||||
|
||||
@Module({
|
||||
providers: [SessionService],
|
||||
exports: [SessionService],
|
||||
})
|
||||
export class SessionModule {}
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
||||
interface UserSession {
|
||||
token: string;
|
||||
email: string;
|
||||
expiresAt: Date;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class SessionService {
|
||||
private readonly logger = new Logger(SessionService.name);
|
||||
private sessions: Map<string, UserSession> = new Map();
|
||||
private authUrl: string;
|
||||
|
||||
constructor(private configService: ConfigService) {
|
||||
this.authUrl = this.configService.get<string>('auth.url') || 'http://localhost:3001';
|
||||
}
|
||||
|
||||
async login(
|
||||
matrixUserId: string,
|
||||
email: string,
|
||||
password: string
|
||||
): Promise<{ success: boolean; error?: string }> {
|
||||
try {
|
||||
const response = await fetch(`${this.authUrl}/api/v1/auth/login`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email, password }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}));
|
||||
return {
|
||||
success: false,
|
||||
error: errorData.message || 'Authentifizierung fehlgeschlagen',
|
||||
};
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const token = data.accessToken || data.token;
|
||||
|
||||
if (!token) {
|
||||
return { success: false, error: 'Kein Token erhalten' };
|
||||
}
|
||||
|
||||
// Store session (7 days expiry)
|
||||
this.sessions.set(matrixUserId, {
|
||||
token,
|
||||
email,
|
||||
expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
|
||||
});
|
||||
|
||||
this.logger.log(`User ${matrixUserId} logged in as ${email}`);
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
this.logger.error(`Login failed for ${matrixUserId}:`, error);
|
||||
return {
|
||||
success: false,
|
||||
error: 'Verbindung zum Auth-Server fehlgeschlagen',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
logout(matrixUserId: string): void {
|
||||
this.sessions.delete(matrixUserId);
|
||||
this.logger.log(`User ${matrixUserId} logged out`);
|
||||
}
|
||||
|
||||
getToken(matrixUserId: string): string | null {
|
||||
const session = this.sessions.get(matrixUserId);
|
||||
|
||||
if (!session) return null;
|
||||
|
||||
if (session.expiresAt < new Date()) {
|
||||
this.sessions.delete(matrixUserId);
|
||||
return null;
|
||||
}
|
||||
|
||||
return session.token;
|
||||
}
|
||||
|
||||
isLoggedIn(matrixUserId: string): boolean {
|
||||
return this.getToken(matrixUserId) !== null;
|
||||
}
|
||||
|
||||
getSessionCount(): number {
|
||||
return this.sessions.size;
|
||||
}
|
||||
}
|
||||
|
|
@ -22,6 +22,7 @@
|
|||
"type-check": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@manacore/bot-services": "workspace:*",
|
||||
"@nestjs/common": "^10.4.15",
|
||||
"@nestjs/config": "^3.3.0",
|
||||
"@nestjs/core": "^10.4.15",
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import { ConfigModule } from '@nestjs/config';
|
|||
import { HealthController } from './health.controller';
|
||||
import { BotModule } from './bot/bot.module';
|
||||
import { PresiModule } from './presi/presi.module';
|
||||
import { SessionModule } from './session/session.module';
|
||||
import configuration from './config/configuration';
|
||||
|
||||
@Module({
|
||||
|
|
@ -14,7 +13,6 @@ import configuration from './config/configuration';
|
|||
}),
|
||||
BotModule,
|
||||
PresiModule,
|
||||
SessionModule,
|
||||
],
|
||||
controllers: [HealthController],
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { MatrixService } from './matrix.service';
|
||||
import { PresiModule } from '../presi/presi.module';
|
||||
import { SessionModule } from '../session/session.module';
|
||||
import { SessionModule } from '@manacore/bot-services';
|
||||
|
||||
@Module({
|
||||
imports: [PresiModule, SessionModule],
|
||||
imports: [PresiModule, SessionModule.forRoot()],
|
||||
providers: [MatrixService],
|
||||
exports: [MatrixService],
|
||||
})
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import {
|
|||
AutojoinRoomsMixin,
|
||||
} from 'matrix-bot-sdk';
|
||||
import { PresiService, Deck, Theme, SlideContent } from '../presi/presi.service';
|
||||
import { SessionService } from '../session/session.service';
|
||||
import { SessionService } from '@manacore/bot-services';
|
||||
import { HELP_MESSAGE } from '../config/configuration';
|
||||
|
||||
@Injectable()
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { SessionService } from './session.service';
|
||||
|
||||
@Module({
|
||||
providers: [SessionService],
|
||||
exports: [SessionService],
|
||||
})
|
||||
export class SessionModule {}
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
||||
interface UserSession {
|
||||
token: string;
|
||||
email: string;
|
||||
expiresAt: Date;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class SessionService {
|
||||
private readonly logger = new Logger(SessionService.name);
|
||||
private sessions: Map<string, UserSession> = new Map();
|
||||
private authUrl: string;
|
||||
|
||||
constructor(private configService: ConfigService) {
|
||||
this.authUrl = this.configService.get<string>('auth.url') || 'http://localhost:3001';
|
||||
}
|
||||
|
||||
async login(
|
||||
matrixUserId: string,
|
||||
email: string,
|
||||
password: string
|
||||
): Promise<{ success: boolean; error?: string }> {
|
||||
try {
|
||||
const response = await fetch(`${this.authUrl}/api/v1/auth/login`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email, password }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}));
|
||||
return {
|
||||
success: false,
|
||||
error: errorData.message || 'Authentifizierung fehlgeschlagen',
|
||||
};
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const token = data.accessToken || data.token;
|
||||
|
||||
if (!token) {
|
||||
return { success: false, error: 'Kein Token erhalten' };
|
||||
}
|
||||
|
||||
this.sessions.set(matrixUserId, {
|
||||
token,
|
||||
email,
|
||||
expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
|
||||
});
|
||||
|
||||
this.logger.log(`User ${matrixUserId} logged in as ${email}`);
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
this.logger.error(`Login failed for ${matrixUserId}:`, error);
|
||||
return {
|
||||
success: false,
|
||||
error: 'Verbindung zum Auth-Server fehlgeschlagen',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
logout(matrixUserId: string): void {
|
||||
this.sessions.delete(matrixUserId);
|
||||
this.logger.log(`User ${matrixUserId} logged out`);
|
||||
}
|
||||
|
||||
getToken(matrixUserId: string): string | null {
|
||||
const session = this.sessions.get(matrixUserId);
|
||||
if (!session) return null;
|
||||
if (session.expiresAt < new Date()) {
|
||||
this.sessions.delete(matrixUserId);
|
||||
return null;
|
||||
}
|
||||
return session.token;
|
||||
}
|
||||
|
||||
isLoggedIn(matrixUserId: string): boolean {
|
||||
return this.getToken(matrixUserId) !== null;
|
||||
}
|
||||
|
||||
getSessionCount(): number {
|
||||
return this.sessions.size;
|
||||
}
|
||||
}
|
||||
|
|
@ -27,6 +27,7 @@
|
|||
"db:studio": "drizzle-kit studio"
|
||||
},
|
||||
"dependencies": {
|
||||
"@manacore/bot-services": "workspace:*",
|
||||
"@nestjs/common": "^10.4.15",
|
||||
"@nestjs/config": "^3.3.0",
|
||||
"@nestjs/core": "^10.4.15",
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { MediaService } from './media.service';
|
||||
import { StorageService } from './storage.service';
|
||||
import { TranscriptionModule } from '../transcription/transcription.module';
|
||||
import { TranscriptionModule } from '@manacore/bot-services';
|
||||
|
||||
@Module({
|
||||
imports: [TranscriptionModule],
|
||||
imports: [TranscriptionModule.forRoot()],
|
||||
providers: [MediaService, StorageService],
|
||||
exports: [MediaService, StorageService],
|
||||
})
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { Injectable, Inject, Logger } from '@nestjs/common';
|
|||
import { DATABASE_CONNECTION } from '../database/database.module';
|
||||
import { projectItems } from '../database/schema';
|
||||
import { StorageService } from './storage.service';
|
||||
import { TranscriptionService } from '../transcription/transcription.service';
|
||||
import { TranscriptionService } from '@manacore/bot-services';
|
||||
import type { PostgresJsDatabase } from 'drizzle-orm/postgres-js';
|
||||
import type * as schema from '../database/schema';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { TranscriptionService } from './transcription.service';
|
||||
|
||||
@Module({
|
||||
providers: [TranscriptionService],
|
||||
exports: [TranscriptionService],
|
||||
})
|
||||
export class TranscriptionModule {}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
||||
interface SttResponse {
|
||||
text: string;
|
||||
language?: string;
|
||||
model?: string;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class TranscriptionService {
|
||||
private readonly logger = new Logger(TranscriptionService.name);
|
||||
private readonly sttUrl: string;
|
||||
|
||||
constructor(private configService: ConfigService) {
|
||||
this.sttUrl = this.configService.get<string>('stt.url') || 'http://localhost:3020';
|
||||
this.logger.log(`STT Service URL: ${this.sttUrl}`);
|
||||
}
|
||||
|
||||
async transcribe(audioBuffer: Buffer, language: string = 'de'): Promise<string> {
|
||||
const formData = new FormData();
|
||||
const blob = new Blob([new Uint8Array(audioBuffer)], { type: 'audio/ogg' });
|
||||
formData.append('file', blob, 'audio.ogg');
|
||||
formData.append('language', language);
|
||||
|
||||
try {
|
||||
const response = await fetch(`${this.sttUrl}/transcribe`, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
throw new Error(`STT service error: ${response.status} - ${errorText}`);
|
||||
}
|
||||
|
||||
const result: SttResponse = await response.json();
|
||||
this.logger.log(
|
||||
`Transcription completed (${result.model || 'whisper'}): ${result.text.substring(0, 50)}...`
|
||||
);
|
||||
return result.text;
|
||||
} catch (error) {
|
||||
this.logger.error('Transcription failed:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -22,6 +22,7 @@
|
|||
"type-check": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@manacore/bot-services": "workspace:*",
|
||||
"@nestjs/common": "^10.4.15",
|
||||
"@nestjs/config": "^3.3.0",
|
||||
"@nestjs/core": "^10.4.15",
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import { ConfigModule } from '@nestjs/config';
|
|||
import { HealthController } from './health.controller';
|
||||
import { BotModule } from './bot/bot.module';
|
||||
import { QuestionsModule } from './questions/questions.module';
|
||||
import { SessionModule } from './session/session.module';
|
||||
import configuration from './config/configuration';
|
||||
|
||||
@Module({
|
||||
|
|
@ -14,7 +13,6 @@ import configuration from './config/configuration';
|
|||
}),
|
||||
BotModule,
|
||||
QuestionsModule,
|
||||
SessionModule,
|
||||
],
|
||||
controllers: [HealthController],
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { MatrixService } from './matrix.service';
|
||||
import { QuestionsModule } from '../questions/questions.module';
|
||||
import { SessionModule } from '../session/session.module';
|
||||
import { SessionModule } from '@manacore/bot-services';
|
||||
|
||||
@Module({
|
||||
imports: [QuestionsModule, SessionModule],
|
||||
imports: [QuestionsModule, SessionModule.forRoot()],
|
||||
providers: [MatrixService],
|
||||
exports: [MatrixService],
|
||||
})
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import {
|
|||
AutojoinRoomsMixin,
|
||||
} from 'matrix-bot-sdk';
|
||||
import { QuestionsService, Question, Collection, Answer } from '../questions/questions.service';
|
||||
import { SessionService } from '../session/session.service';
|
||||
import { SessionService } from '@manacore/bot-services';
|
||||
import { HELP_MESSAGE } from '../config/configuration';
|
||||
|
||||
@Injectable()
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { SessionService } from './session.service';
|
||||
|
||||
@Module({
|
||||
providers: [SessionService],
|
||||
exports: [SessionService],
|
||||
})
|
||||
export class SessionModule {}
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
||||
interface UserSession {
|
||||
token: string;
|
||||
email: string;
|
||||
expiresAt: Date;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class SessionService {
|
||||
private readonly logger = new Logger(SessionService.name);
|
||||
private sessions: Map<string, UserSession> = new Map();
|
||||
private authUrl: string;
|
||||
|
||||
constructor(private configService: ConfigService) {
|
||||
this.authUrl = this.configService.get<string>('auth.url') || 'http://localhost:3001';
|
||||
}
|
||||
|
||||
async login(
|
||||
matrixUserId: string,
|
||||
email: string,
|
||||
password: string
|
||||
): Promise<{ success: boolean; error?: string }> {
|
||||
try {
|
||||
const response = await fetch(`${this.authUrl}/api/v1/auth/login`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email, password }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}));
|
||||
return {
|
||||
success: false,
|
||||
error: errorData.message || 'Authentifizierung fehlgeschlagen',
|
||||
};
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const token = data.accessToken || data.token;
|
||||
|
||||
if (!token) {
|
||||
return { success: false, error: 'Kein Token erhalten' };
|
||||
}
|
||||
|
||||
// Store session (7 days expiry)
|
||||
this.sessions.set(matrixUserId, {
|
||||
token,
|
||||
email,
|
||||
expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
|
||||
});
|
||||
|
||||
this.logger.log(`User ${matrixUserId} logged in as ${email}`);
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
this.logger.error(`Login failed for ${matrixUserId}:`, error);
|
||||
return {
|
||||
success: false,
|
||||
error: 'Verbindung zum Auth-Server fehlgeschlagen',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
logout(matrixUserId: string): void {
|
||||
this.sessions.delete(matrixUserId);
|
||||
this.logger.log(`User ${matrixUserId} logged out`);
|
||||
}
|
||||
|
||||
getToken(matrixUserId: string): string | null {
|
||||
const session = this.sessions.get(matrixUserId);
|
||||
|
||||
if (!session) return null;
|
||||
|
||||
if (session.expiresAt < new Date()) {
|
||||
this.sessions.delete(matrixUserId);
|
||||
return null;
|
||||
}
|
||||
|
||||
return session.token;
|
||||
}
|
||||
|
||||
isLoggedIn(matrixUserId: string): boolean {
|
||||
return this.getToken(matrixUserId) !== null;
|
||||
}
|
||||
|
||||
getSessionCount(): number {
|
||||
return this.sessions.size;
|
||||
}
|
||||
}
|
||||
|
|
@ -22,6 +22,7 @@
|
|||
"type-check": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@manacore/bot-services": "workspace:*",
|
||||
"@nestjs/common": "^10.4.15",
|
||||
"@nestjs/config": "^3.3.0",
|
||||
"@nestjs/core": "^10.4.15",
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import { ConfigModule } from '@nestjs/config';
|
|||
import { HealthController } from './health.controller';
|
||||
import { BotModule } from './bot/bot.module';
|
||||
import { SkilltreeModule } from './skilltree/skilltree.module';
|
||||
import { SessionModule } from './session/session.module';
|
||||
import configuration from './config/configuration';
|
||||
|
||||
@Module({
|
||||
|
|
@ -14,7 +13,6 @@ import configuration from './config/configuration';
|
|||
}),
|
||||
BotModule,
|
||||
SkilltreeModule,
|
||||
SessionModule,
|
||||
],
|
||||
controllers: [HealthController],
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { MatrixService } from './matrix.service';
|
||||
import { SkilltreeModule } from '../skilltree/skilltree.module';
|
||||
import { SessionModule } from '../session/session.module';
|
||||
import { SessionModule } from '@manacore/bot-services';
|
||||
|
||||
@Module({
|
||||
imports: [SkilltreeModule, SessionModule],
|
||||
imports: [SkilltreeModule, SessionModule.forRoot()],
|
||||
providers: [MatrixService],
|
||||
exports: [MatrixService],
|
||||
})
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import {
|
|||
AutojoinRoomsMixin,
|
||||
} from 'matrix-bot-sdk';
|
||||
import { SkilltreeService, Skill, SkillBranch } from '../skilltree/skilltree.service';
|
||||
import { SessionService } from '../session/session.service';
|
||||
import { SessionService } from '@manacore/bot-services';
|
||||
import { HELP_MESSAGE } from '../config/configuration';
|
||||
|
||||
@Injectable()
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { SessionService } from './session.service';
|
||||
|
||||
@Module({
|
||||
providers: [SessionService],
|
||||
exports: [SessionService],
|
||||
})
|
||||
export class SessionModule {}
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
||||
interface UserSession {
|
||||
token: string;
|
||||
email: string;
|
||||
expiresAt: Date;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class SessionService {
|
||||
private readonly logger = new Logger(SessionService.name);
|
||||
private sessions: Map<string, UserSession> = new Map();
|
||||
private authUrl: string;
|
||||
|
||||
constructor(private configService: ConfigService) {
|
||||
this.authUrl = this.configService.get<string>('auth.url') || 'http://localhost:3001';
|
||||
}
|
||||
|
||||
async login(
|
||||
matrixUserId: string,
|
||||
email: string,
|
||||
password: string
|
||||
): Promise<{ success: boolean; error?: string }> {
|
||||
try {
|
||||
const response = await fetch(`${this.authUrl}/api/v1/auth/login`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email, password }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}));
|
||||
return {
|
||||
success: false,
|
||||
error: errorData.message || 'Authentifizierung fehlgeschlagen',
|
||||
};
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const token = data.accessToken || data.token;
|
||||
|
||||
if (!token) {
|
||||
return { success: false, error: 'Kein Token erhalten' };
|
||||
}
|
||||
|
||||
this.sessions.set(matrixUserId, {
|
||||
token,
|
||||
email,
|
||||
expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
|
||||
});
|
||||
|
||||
this.logger.log(`User ${matrixUserId} logged in as ${email}`);
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
this.logger.error(`Login failed for ${matrixUserId}:`, error);
|
||||
return {
|
||||
success: false,
|
||||
error: 'Verbindung zum Auth-Server fehlgeschlagen',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
logout(matrixUserId: string): void {
|
||||
this.sessions.delete(matrixUserId);
|
||||
this.logger.log(`User ${matrixUserId} logged out`);
|
||||
}
|
||||
|
||||
getToken(matrixUserId: string): string | null {
|
||||
const session = this.sessions.get(matrixUserId);
|
||||
if (!session) return null;
|
||||
if (session.expiresAt < new Date()) {
|
||||
this.sessions.delete(matrixUserId);
|
||||
return null;
|
||||
}
|
||||
return session.token;
|
||||
}
|
||||
|
||||
isLoggedIn(matrixUserId: string): boolean {
|
||||
return this.getToken(matrixUserId) !== null;
|
||||
}
|
||||
|
||||
getSessionCount(): number {
|
||||
return this.sessions.size;
|
||||
}
|
||||
}
|
||||
|
|
@ -22,6 +22,7 @@
|
|||
"type-check": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@manacore/bot-services": "workspace:*",
|
||||
"@nestjs/common": "^10.4.15",
|
||||
"@nestjs/config": "^3.3.0",
|
||||
"@nestjs/core": "^10.4.15",
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import { ConfigModule } from '@nestjs/config';
|
|||
import { HealthController } from './health.controller';
|
||||
import { BotModule } from './bot/bot.module';
|
||||
import { StorageModule } from './storage/storage.module';
|
||||
import { SessionModule } from './session/session.module';
|
||||
import configuration from './config/configuration';
|
||||
|
||||
@Module({
|
||||
|
|
@ -14,7 +13,6 @@ import configuration from './config/configuration';
|
|||
}),
|
||||
BotModule,
|
||||
StorageModule,
|
||||
SessionModule,
|
||||
],
|
||||
controllers: [HealthController],
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { MatrixService } from './matrix.service';
|
||||
import { StorageModule } from '../storage/storage.module';
|
||||
import { SessionModule } from '../session/session.module';
|
||||
import { SessionModule } from '@manacore/bot-services';
|
||||
|
||||
@Module({
|
||||
imports: [StorageModule, SessionModule],
|
||||
imports: [StorageModule, SessionModule.forRoot()],
|
||||
providers: [MatrixService],
|
||||
exports: [MatrixService],
|
||||
})
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import {
|
|||
AutojoinRoomsMixin,
|
||||
} from 'matrix-bot-sdk';
|
||||
import { StorageService, StorageFile, Folder, ShareLink, TrashItem } from '../storage/storage.service';
|
||||
import { SessionService } from '../session/session.service';
|
||||
import { SessionService } from '@manacore/bot-services';
|
||||
import { HELP_MESSAGE } from '../config/configuration';
|
||||
|
||||
type ListItem = StorageFile | Folder;
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { SessionService } from './session.service';
|
||||
|
||||
@Module({
|
||||
providers: [SessionService],
|
||||
exports: [SessionService],
|
||||
})
|
||||
export class SessionModule {}
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
||||
interface UserSession {
|
||||
token: string;
|
||||
email: string;
|
||||
expiresAt: Date;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class SessionService {
|
||||
private readonly logger = new Logger(SessionService.name);
|
||||
private sessions: Map<string, UserSession> = new Map();
|
||||
private authUrl: string;
|
||||
|
||||
constructor(private configService: ConfigService) {
|
||||
this.authUrl = this.configService.get<string>('auth.url') || 'http://localhost:3001';
|
||||
}
|
||||
|
||||
async login(
|
||||
matrixUserId: string,
|
||||
email: string,
|
||||
password: string
|
||||
): Promise<{ success: boolean; error?: string }> {
|
||||
try {
|
||||
const response = await fetch(`${this.authUrl}/api/v1/auth/login`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email, password }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}));
|
||||
return {
|
||||
success: false,
|
||||
error: errorData.message || 'Authentifizierung fehlgeschlagen',
|
||||
};
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const token = data.accessToken || data.token;
|
||||
|
||||
if (!token) {
|
||||
return { success: false, error: 'Kein Token erhalten' };
|
||||
}
|
||||
|
||||
// Store session (7 days expiry)
|
||||
this.sessions.set(matrixUserId, {
|
||||
token,
|
||||
email,
|
||||
expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
|
||||
});
|
||||
|
||||
this.logger.log(`User ${matrixUserId} logged in as ${email}`);
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
this.logger.error(`Login failed for ${matrixUserId}:`, error);
|
||||
return {
|
||||
success: false,
|
||||
error: 'Verbindung zum Auth-Server fehlgeschlagen',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
logout(matrixUserId: string): void {
|
||||
this.sessions.delete(matrixUserId);
|
||||
this.logger.log(`User ${matrixUserId} logged out`);
|
||||
}
|
||||
|
||||
getToken(matrixUserId: string): string | null {
|
||||
const session = this.sessions.get(matrixUserId);
|
||||
|
||||
if (!session) return null;
|
||||
|
||||
if (session.expiresAt < new Date()) {
|
||||
this.sessions.delete(matrixUserId);
|
||||
return null;
|
||||
}
|
||||
|
||||
return session.token;
|
||||
}
|
||||
|
||||
isLoggedIn(matrixUserId: string): boolean {
|
||||
return this.getToken(matrixUserId) !== null;
|
||||
}
|
||||
|
||||
getSessionCount(): number {
|
||||
return this.sessions.size;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue