Created
October 17, 2017 09:35
-
-
Save stupiduglyfool/42197f96f93584b5fdccdca7fc90f785 to your computer and use it in GitHub Desktop.
Updated electron request handler demonstrating async/await vs emitter
This file contains 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
/* | |
* Copyright 2017 Google Inc. | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except | |
* in compliance with the License. You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software distributed under the | |
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either | |
* express or implied. See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
import * as url from 'url'; | |
import * as EventEmitter from 'events'; | |
import { | |
AuthorizationError, | |
AuthorizationErrorJson, | |
AuthorizationRequest, | |
AuthorizationRequestHandler, | |
AuthorizationRequestResponse, | |
AuthorizationResponse, | |
AuthorizationResponseJson, | |
AuthorizationServiceConfiguration, | |
BasicQueryStringUtils, | |
QueryStringUtils | |
} from '@openid/appauth'; | |
import { BrowserWindow } from 'electron'; | |
export interface IElectronTokenRequestBehavior { | |
begin(): void; | |
loadUrl(url: string): void; | |
getWebContents(): Electron.WebContents; | |
complete(): void; | |
} | |
export class ElectronBrowserWindowBehavior implements IElectronTokenRequestBehavior { | |
private _authWindow: Electron.BrowserWindow | null; | |
constructor(private _options?: Electron.BrowserWindowConstructorOptions) { } | |
public begin() { | |
this._authWindow = new BrowserWindow(this._options); | |
this._authWindow.setMenu(null); | |
this._authWindow.on('closed', () => { | |
let browserWindow = this._authWindow as Electron.BrowserWindow; | |
browserWindow.removeAllListeners(); | |
}); | |
} | |
public loadUrl(url: string) { | |
let browserWindow = this._authWindow as Electron.BrowserWindow; | |
browserWindow.loadURL(url); | |
} | |
public getWebContents() { | |
let browserWindow = this._authWindow as Electron.BrowserWindow; | |
return browserWindow.webContents; | |
} | |
public complete() { | |
let browserWindow = this._authWindow as Electron.BrowserWindow; | |
browserWindow.destroy(); | |
this._authWindow = null; | |
} | |
} | |
export class ElectronWebviewBehavior implements IElectronTokenRequestBehavior { | |
constructor(private _webview: Electron.WebviewTag | null) { } | |
public begin() { } | |
public loadUrl(url: string) { | |
let webview = this._webview as Electron.WebviewTag; | |
webview.loadURL(url); | |
} | |
public getWebContents() { | |
let webview = this._webview as Electron.WebviewTag; | |
return webview.getWebContents(); | |
} | |
public complete() { | |
let webview = this._webview as Electron.WebviewTag; | |
if (webview) webview.getWebContents().removeAllListeners(); | |
} | |
} | |
export class ElectronRequestHandler extends AuthorizationRequestHandler { | |
// the handle to the current authorization request | |
public authorizationPromise: Promise<AuthorizationRequestResponse | null> | null; | |
constructor( | |
private _tokenRequestBehavior: IElectronTokenRequestBehavior, | |
utils?: QueryStringUtils) { | |
super(utils || new BasicQueryStringUtils()); | |
this.authorizationPromise = null; | |
} | |
private handleNavigation(navigationUri: string) { | |
let request = url.parse(navigationUri, true); | |
let queryParams = request.query as (AuthorizationResponseJson & AuthorizationErrorJson); | |
let state = queryParams['state']; | |
let code = queryParams['code']; | |
let error = queryParams['error']; | |
let authorizationResponse: AuthorizationResponse; | |
let authorizationError: AuthorizationError; | |
if (error) { | |
// get additional optional info. | |
let errorUri = queryParams['error_uri']; | |
let errorDescription = queryParams['error_description']; | |
throw new AuthorizationError(error, errorDescription, errorUri, state); | |
} | |
if (!code) return null; | |
authorizationResponse = new AuthorizationResponse(code!, state!); | |
return { | |
request: request, | |
response: authorizationResponse, | |
error: authorizationError | |
} as AuthorizationRequestResponse; | |
} | |
public performAuthorizationRequest(configuration: AuthorizationServiceConfiguration, request: AuthorizationRequest) { | |
return new Promise<AuthorizationRequestResponse>((resolve, reject) => { | |
this._tokenRequestBehavior.begin(); | |
this._tokenRequestBehavior.loadUrl(this.buildRequestUrl(configuration, request)); | |
let webContents = this._tokenRequestBehavior.getWebContents(); | |
webContents.on('will-navigate', (event, url) => { | |
try { | |
let response = this.handleNavigation(url); | |
if (response) | |
{ | |
resolve(response); | |
this._tokenRequestBehavior.complete(); | |
} | |
} | |
catch (ex) { | |
reject(ex); | |
this._tokenRequestBehavior.complete(); | |
} | |
}); | |
webContents.on('did-get-redirect-request', (event, oldUrl, newUrl) => { | |
try { | |
let response = this.handleNavigation(newUrl); | |
if (response) | |
{ | |
resolve(response); | |
this._tokenRequestBehavior.complete(); | |
} | |
} | |
catch (ex) { | |
reject(ex); | |
this._tokenRequestBehavior.complete(); | |
} | |
}); | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment