Skip to content

Commit 7b277f5

Browse files
committed
Added connect api
1 parent 087be59 commit 7b277f5

1 file changed

Lines changed: 72 additions & 1 deletion

File tree

src/trpc/routers/microsoft.ts

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,81 @@
11
import { z } from 'zod';
2-
import { createTRPCRouter, protectedProcedure } from '../init.js';
2+
import { createTRPCRouter, protectedProcedure, publicProcedure } from '../init.js';
33
import { db } from '../../lib/db/prisma.js';
44
import { TRPCError } from '@trpc/server';
55
import { PermissionsClient } from '../../lib/microsoft/permissions.js';
6+
import { getAppCredentials } from '../../lib/microsoft/token-manager.js';
67

78
export const microsoftRouter = createTRPCRouter({
9+
/**
10+
* Check if API can connect to Microsoft using Client Credentials (env vars)
11+
* This is for SPFx apps that use the API's app-only authentication
12+
*/
13+
checkConnection: publicProcedure.query(async () => {
14+
try {
15+
const credentials = await getAppCredentials();
16+
17+
// Try to get a token using Client Credentials flow
18+
const tokenEndpoint = `https://login.microsoftonline.com/${credentials.tenantId}/oauth2/v2.0/token`;
19+
20+
const response = await fetch(tokenEndpoint, {
21+
method: 'POST',
22+
headers: {
23+
'Content-Type': 'application/x-www-form-urlencoded',
24+
},
25+
body: new URLSearchParams({
26+
client_id: credentials.clientId,
27+
client_secret: credentials.clientSecret,
28+
grant_type: 'client_credentials',
29+
scope: 'https://graph.microsoft.com/.default',
30+
}),
31+
});
32+
33+
if (!response.ok) {
34+
const error = await response.text();
35+
console.error('Microsoft connection check failed:', error);
36+
return {
37+
connected: false,
38+
message: 'Failed to authenticate with Microsoft',
39+
tenantId: credentials.tenantId,
40+
tenantName: null,
41+
};
42+
}
43+
44+
// Try to get tenant info
45+
const tokenData = await response.json() as { access_token: string };
46+
let tenantName: string | null = null;
47+
48+
try {
49+
const orgResponse = await fetch('https://graph.microsoft.com/v1.0/organization', {
50+
headers: {
51+
Authorization: `Bearer ${tokenData.access_token}`,
52+
},
53+
});
54+
if (orgResponse.ok) {
55+
const orgData = await orgResponse.json() as { value?: Array<{ displayName?: string }> };
56+
tenantName = orgData.value?.[0]?.displayName || null;
57+
}
58+
} catch {
59+
// Ignore errors getting tenant name
60+
}
61+
62+
return {
63+
connected: true,
64+
message: 'Connected to Microsoft 365',
65+
tenantId: credentials.tenantId,
66+
tenantName,
67+
};
68+
} catch (error) {
69+
console.error('Microsoft connection check error:', error);
70+
return {
71+
connected: false,
72+
message: error instanceof Error ? error.message : 'Microsoft credentials not configured',
73+
tenantId: null,
74+
tenantName: null,
75+
};
76+
}
77+
}),
78+
879
/**
980
* Get Microsoft connection status
1081
*/

0 commit comments

Comments
 (0)