diff --git a/packages/core-service/src/core/integrations/integrations.controller.ts b/packages/core-service/src/core/integrations/integrations.controller.ts index 9ca7753..2e82b4b 100644 --- a/packages/core-service/src/core/integrations/integrations.controller.ts +++ b/packages/core-service/src/core/integrations/integrations.controller.ts @@ -5,7 +5,6 @@ import { Query, Res, Logger, - UseGuards, Param, } from '@nestjs/common'; import { ApiTags, ApiOperation } from '@nestjs/swagger'; @@ -53,15 +52,15 @@ export class IntegrationsController { /** * GET /api/v1/auth/integrations/microsoft-365 - * OAuth2-Flow fuer Microsoft 365 starten. - * User muss eingeloggt sein — userId wird im State gespeichert. + * OAuth2-Flow fuer Microsoft 365 vorbereiten. + * Gibt die Microsoft-Authorisierungs-URL als JSON zurueck. + * Das Frontend leitet den Browser dann client-seitig weiter (axios + window.location). */ @Get('auth/integrations/microsoft-365') @ApiOperation({ summary: 'Microsoft 365 Integration starten' }) async initM365Integration( @CurrentUser() user: JwtUser, - @Res() res: Response, - ): Promise { + ): Promise<{ success: boolean; data: { url: string } }> { // State = UUID, in Redis mit userId hinterlegen (5 Min TTL) const state = uuidv4(); await this.redis.set( @@ -74,7 +73,7 @@ export class IntegrationsController { this.logger.log( `M365-Integration OAuth-Flow gestartet fuer User ${user.sub}`, ); - res.redirect(authUrl); + return { success: true, data: { url: authUrl } }; } /** diff --git a/packages/frontend/src/crm/api.ts b/packages/frontend/src/crm/api.ts index 96e4ba1..2e2feb7 100644 --- a/packages/frontend/src/crm/api.ts +++ b/packages/frontend/src/crm/api.ts @@ -771,8 +771,15 @@ export const integrationsApi = { ) .then((r) => r.data), - /** Gibt die URL zurück, zu der der Browser weitergeleitet werden soll */ - getM365ConnectUrl: (): string => '/api/v1/auth/integrations/microsoft-365', + /** Ruft die Microsoft OAuth-URL via API ab (JWT-geschützt) und leitet den Browser weiter */ + connectM365: () => + api + .get<{ success: boolean; data: { url: string } }>( + '/auth/integrations/microsoft-365', + ) + .then((r) => { + window.location.href = r.data.data.url; + }), }; // --- Microsoft Graph Proxy (CRM) --- diff --git a/packages/frontend/src/crm/contacts/CalendarTab.tsx b/packages/frontend/src/crm/contacts/CalendarTab.tsx index 1a7e0d2..8f2d506 100644 --- a/packages/frontend/src/crm/contacts/CalendarTab.tsx +++ b/packages/frontend/src/crm/contacts/CalendarTab.tsx @@ -32,8 +32,9 @@ export function CalendarTab({ contactId }: Props) {

Verbinden Sie Microsoft 365, um Kalendertermine zu diesem Kontakt zu sehen.

- integrationsApi.connectM365()} style={{ display: 'inline-flex', alignItems: 'center', @@ -41,14 +42,15 @@ export function CalendarTab({ contactId }: Props) { padding: '0.4375rem 1rem', background: 'var(--color-primary)', color: 'white', + border: 'none', borderRadius: 'var(--radius-sm)', fontSize: '0.875rem', fontWeight: 600, - textDecoration: 'none', + cursor: 'pointer', }} > Microsoft 365 verbinden - + ); } diff --git a/packages/frontend/src/crm/contacts/EmailsTab.tsx b/packages/frontend/src/crm/contacts/EmailsTab.tsx index 4834f48..dd30893 100644 --- a/packages/frontend/src/crm/contacts/EmailsTab.tsx +++ b/packages/frontend/src/crm/contacts/EmailsTab.tsx @@ -31,8 +31,9 @@ export function EmailsTab({ contactId }: Props) {

Verbinden Sie Microsoft 365, um E-Mails zu diesem Kontakt zu sehen.

- integrationsApi.connectM365()} style={{ display: 'inline-flex', alignItems: 'center', @@ -40,14 +41,15 @@ export function EmailsTab({ contactId }: Props) { padding: '0.4375rem 1rem', background: 'var(--color-primary)', color: 'white', + border: 'none', borderRadius: 'var(--radius-sm)', fontSize: '0.875rem', fontWeight: 600, - textDecoration: 'none', + cursor: 'pointer', }} > Microsoft 365 verbinden - + ); } diff --git a/packages/frontend/src/crm/contacts/TasksTab.tsx b/packages/frontend/src/crm/contacts/TasksTab.tsx index 8af2302..dd24764 100644 --- a/packages/frontend/src/crm/contacts/TasksTab.tsx +++ b/packages/frontend/src/crm/contacts/TasksTab.tsx @@ -117,8 +117,9 @@ export function TasksTab({ contactId }: Props) {

Verbinden Sie Microsoft 365, um Aufgaben zu diesem Kontakt zu sehen.

- integrationsApi.connectM365()} style={{ display: 'inline-flex', alignItems: 'center', @@ -126,14 +127,15 @@ export function TasksTab({ contactId }: Props) { padding: '0.4375rem 1rem', background: 'var(--color-primary)', color: 'white', + border: 'none', borderRadius: 'var(--radius-sm)', fontSize: '0.875rem', fontWeight: 600, - textDecoration: 'none', + cursor: 'pointer', }} > Microsoft 365 verbinden - + ); } diff --git a/packages/frontend/src/profile/ProfilePage.tsx b/packages/frontend/src/profile/ProfilePage.tsx index 18fc857..ebd36cc 100644 --- a/packages/frontend/src/profile/ProfilePage.tsx +++ b/packages/frontend/src/profile/ProfilePage.tsx @@ -843,9 +843,9 @@ export function ProfilePage() { Verbinden Sie Ihr Microsoft 365 Konto, um E-Mails, Kalendertermine und Aufgaben direkt in Kontaktprofilen zu sehen.

- integrationsApi.connectM365()} style={{ display: 'inline-flex', alignItems: 'center', @@ -853,17 +853,18 @@ export function ProfilePage() { padding: '0.5rem 1.25rem', background: 'var(--color-primary)', color: 'white', + border: 'none', borderRadius: 'var(--radius-sm)', fontSize: '0.9375rem', fontWeight: 600, - textDecoration: 'none', + cursor: 'pointer', }} > Microsoft 365 verbinden - + )}