@kwiz/common
Version:
KWIZ common utilities and helpers for M365 platform
133 lines (119 loc) • 6.06 kB
text/typescript
import { promiseOnce } from "../../helpers/promises";
import { isNullOrEmptyString, isValidGuid } from "../../helpers/typecheckers";
import { AzureEnvironment, ITenantInfo } from "../../types/auth";
import { GetJson, GetJsonSync } from "../rest";
interface IOpenidConfiguration {
token_endpoint: string;//https://login.microsoftonline.com/7d034656-be03-457d-8d82-60e90cf5f400/oauth2/token
cloud_instance_name: string;//microsoftonline.com
token_endpoint_auth_methods_supported: string[];// ["client_secret_post", "private_key_jwt", "client_secret_basic"]
response_modes_supported: string[];// ["query", "fragment", "form_post"]
response_types_supported: string[];// ["code", "id_token", "code id_token", "token id_token", "token"]
scopes_supported: string[];// ["openid"]
issuer: string;//https://sts.windows.net/7d034656-be03-457d-8d82-60e90cf5f400/
authorization_endpoint: string;//https://login.microsoftonline.com/7d034656-be03-457d-8d82-60e90cf5f400/oauth2/authorize
device_authorization_endpoint: string;//https://login.microsoftonline.com/7d034656-be03-457d-8d82-60e90cf5f400/oauth2/devicecode
end_session_endpoint: string;//https://login.microsoftonline.com/7d034656-be03-457d-8d82-60e90cf5f400/oauth2/logout
userinfo_endpoint: string;//https://login.microsoftonline.com/7d034656-be03-457d-8d82-60e90cf5f400/openid/userinfo
tenant_region_scope: string;//NA
cloud_graph_host_name: string;//graph.windows.net
msgraph_host: string;//graph.microsoft.com
}
function _getFriendlyName(hostName: string) {
if (hostName.indexOf(".sharepoint.") !== -1) {
let hostParts = hostName.split('.');//should be xxx.sharepoint.com or xxx.sharepoint.us
let firstHostPart = hostParts[0];
let lastHostPart = hostParts[hostParts.length - 1] === "us" || hostParts[hostParts.length - 1] === "de" ? hostParts[hostParts.length - 1] : "com";
if (firstHostPart.endsWith("-admin")) firstHostPart = firstHostPart.substring(0, firstHostPart.length - 6);
return `${firstHostPart}.onmicrosoft.${lastHostPart}`;
}
else {
return hostName;//could be an exchange email domain, or bpos customer
}
}
function _getOpenIdConfigurationUrl(friendlyName: string) {
return `https://login.microsoftonline.com/${friendlyName}/v2.0/.well-known/openid-configuration`;
}
function _processOpenidConfiguration(config: IOpenidConfiguration, friendlyName: string) {
let data: ITenantInfo = {
environment: AzureEnvironment.Production,
idOrName: null,
authorityUrl: null,
valid: false
};
let endpoint = config.token_endpoint;//https://xxxx/{tenant}/....
let tenantId = endpoint.replace("//", "/").split('/')[2];//replace :// with :/ split by / and take the second part.
let instance = config.cloud_instance_name;//microsoftonline.us
data.environment = GetEnvironmentFromACSEndPoint(instance);
if (!isNullOrEmptyString(tenantId) || isValidGuid(tenantId)) {
data.idOrName = tenantId;
} else {
data.idOrName = friendlyName;
}
data.authorityUrl = `${GetAzureADLoginEndPoint(data.environment)}/${data.idOrName}`;
data.valid = true;
return data;
}
export function DiscoverTenantInfo(hostName: string, sync?: false): Promise<ITenantInfo>
export function DiscoverTenantInfo(hostName: string, sync: true): ITenantInfo
export function DiscoverTenantInfo(hostName: string, sync?: boolean): ITenantInfo | Promise<ITenantInfo> {
hostName = hostName.toLowerCase();
let friendlyName = _getFriendlyName(hostName);
let url = _getOpenIdConfigurationUrl(friendlyName);
if (sync === true) {
try {
let response = GetJsonSync<IOpenidConfiguration>(url);
let config = response.result;
let data = _processOpenidConfiguration(config, friendlyName);
return data;
} catch (ex) {
console.log(ex);
}
return null;
} else {
return promiseOnce(`DiscoverTenantInfo|${hostName}`, async () => {
try {
let config = await GetJson<IOpenidConfiguration>(url);
let data = _processOpenidConfiguration(config, friendlyName);
return data;
}
catch (ex) {
console.log(ex);
}
return null;
});
}
}
export function AutoDiscoverTenantInfo(sync?: false): Promise<ITenantInfo>
export function AutoDiscoverTenantInfo(sync: true): ITenantInfo
export function AutoDiscoverTenantInfo(sync?: boolean): ITenantInfo | Promise<ITenantInfo> {
if (sync === true) {
return DiscoverTenantInfo(window.location.hostname.toLowerCase(), true);
}
return DiscoverTenantInfo(window.location.hostname.toLowerCase(), false);
}
export function GetEnvironmentFromACSEndPoint(ACSEndPoint: string): AzureEnvironment {
switch (ACSEndPoint) {
case "microsoftonline.us":
return AzureEnvironment.USGovernment;
case "microsoftonline.de":
return AzureEnvironment.Germany;
case "accesscontrol.chinacloudapi.cn":
return AzureEnvironment.China;
case "windows-ppe.net":
return AzureEnvironment.PPE;
case "accesscontrol.windows.net":
default:
return AzureEnvironment.Production;
}
}
export function GetAzureADLoginEndPoint(environment: AzureEnvironment): string {
switch (environment) {
case AzureEnvironment.Germany: return "https://login.microsoftonline.de";
case AzureEnvironment.China: return "https://login.chinacloudapi.cn";
case AzureEnvironment.USGovernment: return "https://login.microsoftonline.us";
case AzureEnvironment.PPE: return "https://login.windows-ppe.net";
case AzureEnvironment.Production:
default:
return "https://login.microsoftonline.com";
}
}