diff --git a/debug/launch/sp.ts b/debug/launch/sp.ts index c9c2201ef..903e7bd89 100644 --- a/debug/launch/sp.ts +++ b/debug/launch/sp.ts @@ -1,6 +1,6 @@ import { Logger, LogLevel } from "@pnp/logging"; import { sp } from "@pnp/sp"; -import { SPFetchClient } from "@pnp/nodejs"; +import { SPFetchClient, SPOAuthEnv } from "@pnp/nodejs"; declare var process: { exit(code?: number): void }; @@ -10,7 +10,7 @@ export function Example(settings: any) { sp.setup({ sp: { fetchClientFactory: () => { - return new SPFetchClient(settings.testing.sp.url, settings.testing.sp.id, settings.testing.sp.secret); + return new SPFetchClient(settings.testing.sp.url, settings.testing.sp.id, settings.testing.sp.secret, SPOAuthEnv.SPO); }, }, }); diff --git a/packages/nodejs/docs/sp-fetch-client.md b/packages/nodejs/docs/sp-fetch-client.md index b1e9ed2c0..48655974e 100644 --- a/packages/nodejs/docs/sp-fetch-client.md +++ b/packages/nodejs/docs/sp-fetch-client.md @@ -25,15 +25,46 @@ sp.web.get().then(w => { }); ``` +## Set Authentication Environment + +_Added in 1.1.2_ + +For some areas such as Germany, China, and US Gov clouds you need to specifiy a different authentication url to the service. This is done by specifying the correct SPOAuthEnv enumeration to the SPFetchClient constructor. The options are listed below. If you are not sure which option to specify the default is likely OK. + +- SPO : (default) for all *.sharepoint.com urls +- China: for China hosted cloud +- Germany: for Germany local cloud +- USDef: USA Defense cloud +- USGov: USA Government cloud + +```TypeScript +import { sp } from "@pnp/sp"; +import { SPFetchClient, SPOAuthEnv } from "@pnp/nodejs"; + +sp.setup({ + sp: { + fetchClientFactory: () => { + return new SPFetchClient("{site url}", "{client id}", "{client secret}", SPOAuthEnv.China); + }, + }, +}); +``` + + ## Set Realm In some cases automatically resolving the realm may not work. In this case you can set the realm parameter in the SPFetchClient constructor. You can determine the correct value for the realm by navigating to "https://{site name}-admin.sharepoint.com/_layouts/15/TA_AllAppPrincipals.aspx" and copying the GUID value that appears after the "@" - this is the realm id. +**As of version 1.1.2 the realm parameter is now the 5th parameter in the constructor.** + ```TypeScript +import { sp } from "@pnp/sp"; +import { SPFetchClient, SPOAuthEnv } from "@pnp/nodejs"; + sp.setup({ sp: { fetchClientFactory: () => { - return new SPFetchClient("{site url}", "{client id}", "{client secret}", "{realm}"); + return new SPFetchClient("{site url}", "{client id}", "{client secret}", SPOAuthEnv.SPO, "{realm}"); }, }, }); diff --git a/packages/nodejs/src/net/spfetchclient.ts b/packages/nodejs/src/net/spfetchclient.ts index 0fd74386a..2d03d8e02 100644 --- a/packages/nodejs/src/net/spfetchclient.ts +++ b/packages/nodejs/src/net/spfetchclient.ts @@ -16,6 +16,14 @@ export interface AuthToken { access_token: string; } +export enum SPOAuthEnv { + SPO, + China, + Germany, + USDef, + USGov, +} + /** * Fetch client for use within nodejs, requires you register a client id and secret with app only permissions */ @@ -24,7 +32,7 @@ export class SPFetchClient implements HttpClientImpl { private static SharePointServicePrincipal = "00000003-0000-0ff1-ce00-000000000000"; private token: AuthToken | null = null; - constructor(public siteUrl: string, private _clientId: string, private _clientSecret: string, private _realm = "") { + constructor(public siteUrl: string, private _clientId: string, private _clientSecret: string, public authEnv: SPOAuthEnv = SPOAuthEnv.SPO, private _realm = "") { // here we set the globals for page context info to help when building absolute urls global._spPageContextInfo = { @@ -83,6 +91,17 @@ export class SPFetchClient implements HttpClientImpl { }); } + public getAuthHostUrl(env: SPOAuthEnv): string { + switch (env) { + case SPOAuthEnv.China: + return "accounts.accesscontrol.chinacloudapi.cn"; + case SPOAuthEnv.Germany: + return "login.microsoftonline.de"; + default: + return "accounts.accesscontrol.windows.net"; + } + } + private getRealm(): Promise { return new Promise(resolve => { @@ -110,7 +129,7 @@ export class SPFetchClient implements HttpClientImpl { private getAuthUrl(realm: string): Promise { - const url = `https://accounts.accesscontrol.windows.net/metadata/json/1?realm=${realm}`; + const url = `https://${this.getAuthHostUrl(this.authEnv)}/metadata/json/1?realm=${realm}`; return nodeFetch(url).then((r: Response) => r.json()).then((json: { endpoints: { protocol: string, location: string }[] }) => { diff --git a/packages/nodejs/src/nodejs.ts b/packages/nodejs/src/nodejs.ts index 65af2f999..034922033 100644 --- a/packages/nodejs/src/nodejs.ts +++ b/packages/nodejs/src/nodejs.ts @@ -18,5 +18,5 @@ const NodeFetch = require("node-fetch"); })(global); -export { SPFetchClient } from "./net/spfetchclient"; +export { SPFetchClient, SPOAuthEnv } from "./net/spfetchclient"; export { AdalFetchClient, AADToken } from "./net/adalfetchclient";