UNPKG

google-closure-library

Version:
170 lines (138 loc) 3.58 kB
/** * @license * Copyright The Closure Library Authors. * SPDX-License-Identifier: Apache-2.0 */ goog.provide('goog.testing.CspViolationObserver'); goog.setTestOnly('goog.testing.CspViolationObserver'); /** * A class for watching Content Security Policy violation reports. * * @constructor */ goog.testing.CspViolationObserver = function() { if (!window.ReportingObserver) { return; } /** @private {?ReportingObserver} */ this.reportingObserver_ = null; /** @private {boolean} */ this.enabled_ = true; /** @private {!Array<!Report>} */ this.reports_ = []; }; /** * Starts listening for CSP reports. */ goog.testing.CspViolationObserver.prototype.start = function() { if (!window.ReportingObserver || !this.enabled_) { return; } if (this.reportingObserver_) { throw new Error('CspViolationObserver already started'); } this.reportingObserver_ = new ReportingObserver(this.onReport_.bind(this), { types: ['csp-violation'], buffered: false, }); this.reports_ = []; this.reportingObserver_.observe(); }; /** * Returns CSP reports collected so far and empties the collection buffer. * * @return {!Array<!Report>} * @private */ goog.testing.CspViolationObserver.prototype.take_ = function() { const newReports = this.reportingObserver_.takeRecords(); this.reports_.push(...newReports); const results = this.reports_; this.reports_ = []; return results; }; /** * Stops listening for violation reports and returns all reports captured so * far. * * @return {!Array<!Report>} */ goog.testing.CspViolationObserver.prototype.stop = function() { if (!window.ReportingObserver) { return []; } if (!this.reportingObserver_) { return []; } const results = this.take_(); this.reportingObserver_.disconnect(); this.reportingObserver_ = null; return results; }; /** * If called with false, violation reports will no longer be captured and empty * arrays will be returned from stop(). * * @param {boolean} enabled */ goog.testing.CspViolationObserver.prototype.setEnabled = function(enabled) { if (!window.ReportingObserver) { return; } if (enabled === this.enabled_) { return; } this.reports_ = []; if (this.reportingObserver_) { if (enabled) { this.reportingObserver_.observe(); } else { this.reportingObserver_.disconnect(); } } this.enabled_ = enabled; }; /** * ReportingObserver callback. * * @param {!Array<!Report>} reports * @param {!ReportingObserver} observer * @private */ goog.testing.CspViolationObserver.prototype.onReport_ = function( reports, observer) { this.reports_.push(...reports); }; /** * Returns previously generated reports. * * @return {!Array<!Report>} */ goog.testing.CspViolationObserver.getBufferedReports = function() { if (!window.ReportingObserver) { return []; } const reportingObserver = new ReportingObserver(function() {}, { types: ['csp-violation'], buffered: true, }); // Calling .observe() is necessary otherwise takeRecords() will not return // results. reportingObserver.observe(); const reports = reportingObserver.takeRecords(); reportingObserver.disconnect(); return reports; }; /** * Formats the given list of reports as a string. * * @param {!Array<!Report>} reports * @return {string} */ goog.testing.CspViolationObserver.formatReports = function(reports) { return reports .map(function(report) { return JSON.stringify(report.body.toJSON(), null, ' '); }) .join(', '); };