Skip to content

Instantly share code, notes, and snippets.

@stupiduglyfool
Created October 17, 2017 09:35
Show Gist options
  • Save stupiduglyfool/42197f96f93584b5fdccdca7fc90f785 to your computer and use it in GitHub Desktop.
Save stupiduglyfool/42197f96f93584b5fdccdca7fc90f785 to your computer and use it in GitHub Desktop.
Updated electron request handler demonstrating async/await vs emitter
/*
* 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