diff --git a/samples/react-aad-implicitflow/package.json b/samples/react-aad-implicitflow/package.json index 727c7528e..c08432c2f 100644 --- a/samples/react-aad-implicitflow/package.json +++ b/samples/react-aad-implicitflow/package.json @@ -13,7 +13,6 @@ "@microsoft/sp-client-base": "~0.3.0", "@microsoft/sp-client-preview": "~0.4.0", "adal-angular": "^1.0.12", - "expose-loader": "^0.7.1", "office-ui-fabric-react": "0.36.0", "react": "0.14.8", "react-dom": "0.14.8" @@ -29,4 +28,4 @@ "clean": "gulp nuke", "test": "gulp test" } -} \ No newline at end of file +} diff --git a/samples/react-aad-implicitflow/src/webparts/upcomingMeetings/IAdalConfig.ts b/samples/react-aad-implicitflow/src/webparts/IAdalConfig.ts similarity index 84% rename from samples/react-aad-implicitflow/src/webparts/upcomingMeetings/IAdalConfig.ts rename to samples/react-aad-implicitflow/src/webparts/IAdalConfig.ts index ead6ebf00..f2e77bb25 100644 --- a/samples/react-aad-implicitflow/src/webparts/upcomingMeetings/IAdalConfig.ts +++ b/samples/react-aad-implicitflow/src/webparts/IAdalConfig.ts @@ -1,4 +1,5 @@ export interface IAdalConfig extends adal.Config { popUp?: boolean; callback?: (error: any, token: string) => void; + webPartId?: string; } \ No newline at end of file diff --git a/samples/react-aad-implicitflow/src/webparts/WebPartAuthenticationContext.js b/samples/react-aad-implicitflow/src/webparts/WebPartAuthenticationContext.js new file mode 100644 index 000000000..ed1240276 --- /dev/null +++ b/samples/react-aad-implicitflow/src/webparts/WebPartAuthenticationContext.js @@ -0,0 +1,83 @@ +const AuthenticationContext = require('adal-angular'); + +AuthenticationContext.prototype._getItemSuper = AuthenticationContext.prototype._getItem; +AuthenticationContext.prototype._saveItemSuper = AuthenticationContext.prototype._saveItem; +AuthenticationContext.prototype.handleWindowCallbackSuper = AuthenticationContext.prototype.handleWindowCallback; +AuthenticationContext.prototype._renewTokenSuper = AuthenticationContext.prototype._renewToken; +AuthenticationContext.prototype.getRequestInfoSuper = AuthenticationContext.prototype.getRequestInfo; + +AuthenticationContext.prototype._getItem = function (key) { + if (this.config.webPartId) { + key = this.config.webPartId + '_' + key; + } + + return this._getItemSuper(key); +}; + +AuthenticationContext.prototype._saveItem = function (key, object) { + if (this.config.webPartId) { + key = this.config.webPartId + '_' + key; + } + + return this._saveItemSuper(key, object); +}; + +AuthenticationContext.prototype.handleWindowCallback = function (hash) { + if (hash == null) { + hash = window.location.hash; + } + + if (!this.isCallback(hash)) { + return; + } + + var requestInfo = this.getRequestInfo(hash); + if (requestInfo.requestType === this.REQUEST_TYPE.LOGIN) { + return this.handleWindowCallbackSuper(hash); + } + + var resource = this._getResourceFromState(requestInfo.stateResponse); + if (!resource || resource.length === 0) { + return; + } + + if (this._getItem(this.CONSTANTS.STORAGE.RENEW_STATUS + resource) === this.CONSTANTS.TOKEN_RENEW_STATUS_IN_PROGRESS) { + return this.handleWindowCallbackSuper(hash); + } +} + +AuthenticationContext.prototype._renewToken = function (resource, callback) { + this._renewTokenSuper(resource, callback); + var _renewStates = this._getItem('renewStates'); + if (_renewStates) { + _renewStates = _renewStates.split(';'); + } + else { + _renewStates = []; + } + _renewStates.push(this.config.state); + this._saveItem('renewStates', _renewStates); +} + +AuthenticationContext.prototype.getRequestInfo = function (hash) { + var requestInfo = this.getRequestInfoSuper(hash); + var _renewStates = this._getItem('renewStates'); + if (!_renewStates) { + return requestInfo; + } + + _renewStates = _renewStates.split(';'); + for (var i = 0; i < _renewStates.length; i++) { + if (_renewStates[i] === requestInfo.stateResponse) { + requestInfo.requestType = this.REQUEST_TYPE.RENEW_TOKEN; + requestInfo.stateMatch = true; + break; + } + } + + return requestInfo; +} + +window.AuthenticationContext = function() { + return undefined; +} \ No newline at end of file diff --git a/samples/react-aad-implicitflow/src/webparts/upcomingMeetings/UpcomingMeetingsWebPart.ts b/samples/react-aad-implicitflow/src/webparts/upcomingMeetings/UpcomingMeetingsWebPart.ts index 33b0f4f11..56b5feccd 100644 --- a/samples/react-aad-implicitflow/src/webparts/upcomingMeetings/UpcomingMeetingsWebPart.ts +++ b/samples/react-aad-implicitflow/src/webparts/upcomingMeetings/UpcomingMeetingsWebPart.ts @@ -20,7 +20,8 @@ export default class UpcomingMeetingsWebPart extends BaseClientSideWebPart = React.createElement(UpcomingMeetings, { httpClient: this.context.httpClient, - title: this.properties.title + title: this.properties.title, + webPartId: this.context.instanceId }); ReactDom.render(element, this.domElement); diff --git a/samples/react-aad-implicitflow/src/webparts/upcomingMeetings/components/UpcomingMeetings.tsx b/samples/react-aad-implicitflow/src/webparts/upcomingMeetings/components/UpcomingMeetings.tsx index f5c13a6a7..e15460447 100644 --- a/samples/react-aad-implicitflow/src/webparts/upcomingMeetings/components/UpcomingMeetings.tsx +++ b/samples/react-aad-implicitflow/src/webparts/upcomingMeetings/components/UpcomingMeetings.tsx @@ -8,14 +8,16 @@ import { import styles from '../UpcomingMeetings.module.scss'; import { IUpcomingMeetingsWebPartProps } from '../IUpcomingMeetingsWebPartProps'; import { HttpClient } from '@microsoft/sp-client-base'; -const AuthenticationContext = require('expose?AuthenticationContext!adal-angular'); +const AuthenticationContext = require('adal-angular'); import adalConfig from '../AdalConfig'; -import { IAdalConfig } from '../IAdalConfig'; +import { IAdalConfig } from '../../IAdalConfig'; +import '../../WebPartAuthenticationContext'; import { ListItem } from './ListItem'; import { IMeeting } from './IMeeting'; export interface IUpcomingMeetingsProps extends IUpcomingMeetingsWebPartProps { httpClient: HttpClient; + webPartId: string; } export interface IUpcomingMeetingsState { @@ -63,6 +65,7 @@ export default class UpcomingMeetings extends React.Component { this.setState((previousState: IUpcomingMeetingsState, currentProps: IUpcomingMeetingsProps): IUpcomingMeetingsState => { previousState.error = error; @@ -72,6 +75,7 @@ export default class UpcomingMeetings extends React.Component