// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
type ShouldSendTokenToUrlFunction = (token: string) => boolean;
type AllowedRequestFunction = (request: string) => boolean;
type OnBeforeSendHeadersListener = (obj: any) =>
chrome.webRequest.BlockingResponse|null;
/**
* Class that handles managing and configuring a <webview> for use
* for embedded hosted web apps in system components. Handles
* settings options to provide for the security and control of the
* content in the webview. Using this class doesn't precluding configuring
* the webview outside of this class. Rather, this class is intended to
* standardize some common configurations of webview.
*/
export class WebviewManager {
private webview_: chrome.webviewTag.WebView;
/**
* Tracks the current listener used to filter destinations
* to which we send access tokens.
*/
private shouldSendTokenToUrlListener_: OnBeforeSendHeadersListener|null;
/**
* Tracks the current listener used to filter destinations
* to which we send allow requests.
*/
private allowedRequestListener_: OnBeforeSendHeadersListener|null;
constructor(webview: chrome.webviewTag.WebView) {
this.webview_ = webview;
}
/**
* Configures the webview to use the specified token to authenticate the user.
* Sets the token as part of the Auhtorization: Bearer HTTP header.
* @param {string} accessToken the access token
* @param {!function(string):boolean} shouldSendTokenToUrlFn function that
* returns true if the access token should be sent to the specified host.
*/
setAccessToken(
accessToken: string,
shouldSendTokenToUrlFn: ShouldSendTokenToUrlFunction) {
if (this.shouldSendTokenToUrlListener_) {
this.webview_.request.onBeforeSendHeaders.removeListener(
this.shouldSendTokenToUrlListener_);
this.shouldSendTokenToUrlListener_ = null;
}
this.shouldSendTokenToUrlListener_ = (details) => {
if (shouldSendTokenToUrlFn(details.url)) {
details.requestHeaders.push({
name: 'Authorization',
value: 'Bearer ' + accessToken,
});
}
return {requestHeaders: details.requestHeaders};
};
this.webview_.request.onBeforeSendHeaders.addListener(
this.shouldSendTokenToUrlListener_, {urls: ['<all_urls>']},
['blocking', 'requestHeaders']);
}
/**
* Configures the webview to permit navigation only to URLs allowed
* by the specified function.
* @param {!function(string):boolean} allowedRequestFn function that returns
* true if the request to the specified URL is allowed.
*/
setAllowRequestFn(allowedRequestFn: AllowedRequestFunction) {
if (this.allowedRequestListener_) {
this.webview_.request.onBeforeSendHeaders.removeListener(
this.allowedRequestListener_);
this.allowedRequestListener_ = null;
}
this.allowedRequestListener_ = (details) => {
return {cancel: !allowedRequestFn(details.url)};
};
this.webview_.request.onBeforeRequest.addListener(
this.allowedRequestListener_, {urls: ['<all_urls>']}, ['blocking']);
}
}