Last active
June 10, 2025 12:23
-
-
Save TheRealXaiL/823e5c6404fa2f3d8399d9dcfec83966 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| interface TenantInfo { | |
| tenant_id: string; | |
| tenant_name: string; | |
| tenant_region: string; | |
| cloud_instance: string; | |
| sso_enabled: string; | |
| domain_count: number; | |
| federated_domains?: string[]; // Optional field | |
| } | |
| async function getFederatedDomains(domain: string): Promise<{ count: number; domains: string[] }> { | |
| const autodiscoverPostBody = `<?xml version="1.0" encoding="utf-8"?> | |
| <soap:Envelope xmlns:exm="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:ext="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> | |
| <soap:Header> | |
| <a:Action soap:mustUnderstand="1">http://schemas.microsoft.com/exchange/2010/Autodiscover/Autodiscover/GetFederationInformation</a:Action> | |
| <a:To soap:mustUnderstand="1">https://autodiscover-s.outlook.com/autodiscover/autodiscover.svc</a:To> | |
| <a:ReplyTo> | |
| <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address> | |
| </a:ReplyTo> | |
| </soap:Header> | |
| <soap:Body> | |
| <GetFederationInformationRequestMessage xmlns="http://schemas.microsoft.com/exchange/2010/Autodiscover"> | |
| <Request> | |
| <Domain>${domain}</Domain> | |
| </Request> | |
| </GetFederationInformationRequestMessage> | |
| </soap:Body> | |
| </soap:Envelope>`; | |
| const autodiscoverPostHeaders = { | |
| "Content-Type": "text/xml; charset=utf-8", | |
| "SOAPAction": '"http://schemas.microsoft.com/exchange/2010/Autodiscover/Autodiscover/GetFederationInformation"', | |
| "User-Agent": "AutodiscoverClient" | |
| }; | |
| try { | |
| const response = await fetch('https://autodiscover-s.outlook.com/autodiscover/autodiscover.svc', { | |
| method: 'POST', | |
| headers: autodiscoverPostHeaders, | |
| body: autodiscoverPostBody, | |
| }); | |
| if (!response.ok) { | |
| return { count: 0, domains: [] }; | |
| } | |
| const text = await response.text(); | |
| // Extract domain names from XML response | |
| const domainMatches = text.match(/<Domain>([^<]+)<\/Domain>/g) || []; | |
| const domains = domainMatches.map(match => | |
| match.replace(/<Domain>|<\/Domain>/g, '') | |
| ); | |
| return { | |
| count: domains.length, | |
| domains: domains | |
| }; | |
| } catch (error) { | |
| return { count: 0, domains: [] }; | |
| } | |
| } | |
| async function getTenantInfo(domain: string, includeDomains: boolean = false): Promise<TenantInfo | null> { | |
| const url = `https://login.microsoftonline.com/${domain}/.well-known/openid-configuration`; | |
| try { | |
| const response = await fetch(url); | |
| if (!response.ok) { | |
| return null; | |
| } | |
| const tenantInfo = await response.json(); | |
| const issuer = tenantInfo.issuer || ""; | |
| const tenantId = issuer.split('/').slice(-2)[0] || "Unknown"; | |
| const federatedInfo = await getFederatedDomains(domain); | |
| const result: TenantInfo = { | |
| tenant_id: tenantId, | |
| tenant_name: domain, | |
| tenant_region: tenantInfo.tenant_region_scope || "Unknown", | |
| cloud_instance: tenantInfo.cloud_instance_name || "Unknown", | |
| sso_enabled: tenantInfo.frontchannel_logout_supported ? "Yes" : "No", | |
| domain_count: federatedInfo.count | |
| }; | |
| // Only include federated_domains if explicitly requested | |
| if (includeDomains) { | |
| result.federated_domains = federatedInfo.domains; | |
| } | |
| return result; | |
| } catch (error) { | |
| return null; | |
| } | |
| } | |
| export default { | |
| async fetch(request: Request): Promise<Response> { | |
| // Handle CORS preflight requests | |
| if (request.method === "OPTIONS") { | |
| return new Response(null, { | |
| headers: { | |
| "Access-Control-Allow-Origin": "*", | |
| "Access-Control-Allow-Methods": "GET", | |
| "Access-Control-Allow-Headers": "Content-Type", | |
| }, | |
| }); | |
| } | |
| // Only allow GET requests | |
| if (request.method !== "GET") { | |
| return new Response("Method not allowed", { status: 405 }); | |
| } | |
| const url = new URL(request.url); | |
| const domain = url.pathname.split("/").pop(); | |
| if (!domain) { | |
| return new Response(JSON.stringify({ | |
| error: "Domain parameter is required" | |
| }), { | |
| status: 400, | |
| headers: { | |
| "Content-Type": "application/json", | |
| "Access-Control-Allow-Origin": "*", | |
| }, | |
| }); | |
| } | |
| // Check if domains should be included based on GET parameter | |
| const includeDomains = url.searchParams.has('domains') || url.searchParams.get('domains') === 'true'; | |
| const tenantInfo = await getTenantInfo(domain, includeDomains); | |
| if (!tenantInfo) { | |
| return new Response(JSON.stringify({ | |
| error: "Unable to fetch tenant information", | |
| domain: domain | |
| }), { | |
| status: 404, | |
| headers: { | |
| "Content-Type": "application/json", | |
| "Access-Control-Allow-Origin": "*", | |
| }, | |
| }); | |
| } | |
| return new Response(JSON.stringify(tenantInfo), { | |
| headers: { | |
| "Content-Type": "application/json", | |
| "Access-Control-Allow-Origin": "*", | |
| }, | |
| }); | |
| }, | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment