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
-
+
)}