From 2e582e12fc3e5bf9688b3ba80da33e4a5a5fa84f Mon Sep 17 00:00:00 2001 From: john gravois Date: Tue, 10 Jul 2018 10:32:37 -0700 Subject: [PATCH 1/2] feat(:unlock:): add support for an OAuth flow that triggers social media login automatically AFFECTS PACKAGES: @esri/arcgis-rest-auth ISSUES CLOSED: #239 --- packages/arcgis-rest-auth/src/UserSession.ts | 35 ++++++++++++-- .../arcgis-rest-auth/test/UserSession.test.ts | 46 +++++++++++++++++++ 2 files changed, 77 insertions(+), 4 deletions(-) diff --git a/packages/arcgis-rest-auth/src/UserSession.ts b/packages/arcgis-rest-auth/src/UserSession.ts index 46940c1cc6..d2707e9f3c 100644 --- a/packages/arcgis-rest-auth/src/UserSession.ts +++ b/packages/arcgis-rest-auth/src/UserSession.ts @@ -22,6 +22,8 @@ interface IDeferred { reject: (v: any) => void; } +export type IAuthenticationProvider = "arcgis" | "facebook" | "google"; + /** * Represents a [credential]((https://developers.arcgis.com/javascript/latest/api-reference/esri-identity-Credential.html)) object used to access a secure ArcGIS resource. */ @@ -70,6 +72,11 @@ export interface IOauth2Options { */ portal?: string; + /** + * The authentication provider to use. Defaults to ArcGIS, but Google and Facebook social media logins can also be used. + */ + provider?: IAuthenticationProvider; + /** * Duration (in minutes) that a token will be valid. Defaults to 20160 (two weeks). */ @@ -156,6 +163,11 @@ export interface IUserSessionOptions { */ portal?: string; + /** + * The authentication provider to use. Defaults to ArcGIS, but Google and Facebook social media logins can also be used. + */ + provider?: IAuthenticationProvider; + /** * Duration of requested token validity in minutes. Used when requesting tokens with `username` and `password` or when validating the identity of unknown servers. Defaults to two weeks. */ @@ -201,6 +213,11 @@ export class UserSession implements IAuthenticationManager { */ readonly portal: string; + /** + * The authentication provider to use. + */ + readonly provider: IAuthenticationProvider; + /** * Determines how long new tokens requested are valid. */ @@ -282,9 +299,11 @@ export class UserSession implements IAuthenticationManager { this._token = options.token; this._tokenExpires = options.tokenExpires; this.portal = options.portal || "https://www.arcgis.com/sharing/rest"; + this.provider = options.provider || "arcgis"; this.tokenDuration = options.tokenDuration || 20160; this.redirectUri = options.redirectUri; this.refreshTokenTTL = options.refreshTokenTTL || 1440; + this.trustedServers = {}; this._pendingTokenRequests = {}; } @@ -300,6 +319,7 @@ export class UserSession implements IAuthenticationManager { static beginOAuth2(options: IOauth2Options, win: any = window) { const { portal, + provider, clientId, duration, redirectUri, @@ -309,6 +329,7 @@ export class UserSession implements IAuthenticationManager { }: IOauth2Options = { ...{ portal: "https://www.arcgis.com/sharing/rest", + provider: "arcgis", duration: 20160, popup: true, state: options.clientId, @@ -316,10 +337,16 @@ export class UserSession implements IAuthenticationManager { }, ...options }; - - const url = `${portal}/oauth2/authorize?client_id=${clientId}&response_type=token&expiration=${duration}&redirect_uri=${encodeURIComponent( - redirectUri - )}&state=${state}&locale=${locale}`; + let url: string; + if (provider === "arcgis") { + url = `${portal}/oauth2/authorize?client_id=${clientId}&response_type=token&expiration=${duration}&redirect_uri=${encodeURIComponent( + redirectUri + )}&state=${state}&locale=${locale}`; + } else { + url = `${portal}/oauth2/social/authorize?client_id=${clientId}&socialLoginProviderName=${provider}&autoAccountCreateForSocial=true&response_type=token&expiration=${duration}&redirect_uri=${encodeURIComponent( + redirectUri + )}&state=${state}&locale=${locale}`; + } if (!popup) { win.location.href = url; diff --git a/packages/arcgis-rest-auth/test/UserSession.test.ts b/packages/arcgis-rest-auth/test/UserSession.test.ts index a425c81651..af8a1ad281 100644 --- a/packages/arcgis-rest-auth/test/UserSession.test.ts +++ b/packages/arcgis-rest-auth/test/UserSession.test.ts @@ -562,6 +562,52 @@ describe("UserSession", () => { "https://www.arcgis.com/sharing/rest/oauth2/authorize?client_id=clientId123&response_type=token&expiration=20160&redirect_uri=http%3A%2F%2Fexample-app.com%2Fredirect&state=clientId123&locale=" ); }); + + it("should authorize using a social media provider", () => { + const MockWindow: any = { + location: { + href: "" + } + }; + + // https://github.com/palantir/tslint/issues/3056 + void UserSession.beginOAuth2( + { + clientId: "clientId123", + redirectUri: "http://example-app.com/redirect", + popup: false, + provider: "facebook" + }, + MockWindow + ); + + expect(MockWindow.location.href).toBe( + "https://www.arcgis.com/sharing/rest/oauth2/social/authorize?client_id=clientId123&socialLoginProviderName=facebook&autoAccountCreateForSocial=true&response_type=token&expiration=20160&redirect_uri=http%3A%2F%2Fexample-app.com%2Fredirect&state=clientId123&locale=" + ); + }); + + it("should authorize using the other social media provider", () => { + const MockWindow: any = { + location: { + href: "" + } + }; + + // https://github.com/palantir/tslint/issues/3056 + void UserSession.beginOAuth2( + { + clientId: "clientId123", + redirectUri: "http://example-app.com/redirect", + popup: false, + provider: "google" + }, + MockWindow + ); + + expect(MockWindow.location.href).toBe( + "https://www.arcgis.com/sharing/rest/oauth2/social/authorize?client_id=clientId123&socialLoginProviderName=google&autoAccountCreateForSocial=true&response_type=token&expiration=20160&redirect_uri=http%3A%2F%2Fexample-app.com%2Fredirect&state=clientId123&locale=" + ); + }); }); describe(".completeOAuth2()", () => { From a0458f8cb02373a4b06c9ba2708a69df7b95a848 Mon Sep 17 00:00:00 2001 From: john gravois Date: Tue, 10 Jul 2018 12:18:09 -0700 Subject: [PATCH 2/2] address feedback --- packages/arcgis-rest-auth/src/UserSession.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/arcgis-rest-auth/src/UserSession.ts b/packages/arcgis-rest-auth/src/UserSession.ts index d2707e9f3c..1aaa407811 100644 --- a/packages/arcgis-rest-auth/src/UserSession.ts +++ b/packages/arcgis-rest-auth/src/UserSession.ts @@ -22,7 +22,7 @@ interface IDeferred { reject: (v: any) => void; } -export type IAuthenticationProvider = "arcgis" | "facebook" | "google"; +export type AuthenticationProvider = "arcgis" | "facebook" | "google"; /** * Represents a [credential]((https://developers.arcgis.com/javascript/latest/api-reference/esri-identity-Credential.html)) object used to access a secure ArcGIS resource. @@ -73,9 +73,9 @@ export interface IOauth2Options { portal?: string; /** - * The authentication provider to use. Defaults to ArcGIS, but Google and Facebook social media logins can also be used. + * ArcGIS Authentication is used by default. Specifying an alternative will take users directly to the corresponding provider's OAuth page. */ - provider?: IAuthenticationProvider; + provider?: AuthenticationProvider; /** * Duration (in minutes) that a token will be valid. Defaults to 20160 (two weeks). @@ -164,9 +164,9 @@ export interface IUserSessionOptions { portal?: string; /** - * The authentication provider to use. Defaults to ArcGIS, but Google and Facebook social media logins can also be used. + * ArcGIS Authentication is used by default. Specifying an alternative will take users directly to the corresponding provider's OAuth page. */ - provider?: IAuthenticationProvider; + provider?: AuthenticationProvider; /** * Duration of requested token validity in minutes. Used when requesting tokens with `username` and `password` or when validating the identity of unknown servers. Defaults to two weeks. @@ -216,7 +216,7 @@ export class UserSession implements IAuthenticationManager { /** * The authentication provider to use. */ - readonly provider: IAuthenticationProvider; + readonly provider: AuthenticationProvider; /** * Determines how long new tokens requested are valid.