Use a token to ensure that messages are coming from Yomichan
This commit is contained in:
parent
aee16c4431
commit
0f46e3a093
@ -46,6 +46,8 @@ class Backend {
|
|||||||
this.popupWindow = null;
|
this.popupWindow = null;
|
||||||
|
|
||||||
this.apiForwarder = new BackendApiForwarder();
|
this.apiForwarder = new BackendApiForwarder();
|
||||||
|
|
||||||
|
this.messageToken = yomichan.generateId(16);
|
||||||
}
|
}
|
||||||
|
|
||||||
async prepare() {
|
async prepare() {
|
||||||
@ -614,6 +616,10 @@ class Backend {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _onApiGetMessageToken() {
|
||||||
|
return this.messageToken;
|
||||||
|
}
|
||||||
|
|
||||||
// Command handlers
|
// Command handlers
|
||||||
|
|
||||||
async _onCommandSearch(params) {
|
async _onCommandSearch(params) {
|
||||||
@ -875,7 +881,8 @@ Backend._messageHandlers = new Map([
|
|||||||
['clipboardGet', (self, ...args) => self._onApiClipboardGet(...args)],
|
['clipboardGet', (self, ...args) => self._onApiClipboardGet(...args)],
|
||||||
['getDisplayTemplatesHtml', (self, ...args) => self._onApiGetDisplayTemplatesHtml(...args)],
|
['getDisplayTemplatesHtml', (self, ...args) => self._onApiGetDisplayTemplatesHtml(...args)],
|
||||||
['getQueryParserTemplatesHtml', (self, ...args) => self._onApiGetQueryParserTemplatesHtml(...args)],
|
['getQueryParserTemplatesHtml', (self, ...args) => self._onApiGetQueryParserTemplatesHtml(...args)],
|
||||||
['getZoom', (self, ...args) => self._onApiGetZoom(...args)]
|
['getZoom', (self, ...args) => self._onApiGetZoom(...args)],
|
||||||
|
['getMessageToken', (self, ...args) => self._onApiGetMessageToken(...args)]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Backend._commandHandlers = new Map([
|
Backend._commandHandlers = new Map([
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*global popupNestedInitialize, apiForward, Display*/
|
/*global popupNestedInitialize, apiForward, apiGetMessageToken, Display*/
|
||||||
|
|
||||||
class DisplayFloat extends Display {
|
class DisplayFloat extends Display {
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -30,6 +30,8 @@ class DisplayFloat extends Display {
|
|||||||
|
|
||||||
this._orphaned = false;
|
this._orphaned = false;
|
||||||
this._prepareInvoked = false;
|
this._prepareInvoked = false;
|
||||||
|
this._messageToken = null;
|
||||||
|
this._messageTokenPromise = null;
|
||||||
|
|
||||||
yomichan.on('orphaned', () => this.onOrphaned());
|
yomichan.on('orphaned', () => this.onOrphaned());
|
||||||
window.addEventListener('message', (e) => this.onMessage(e), false);
|
window.addEventListener('message', (e) => this.onMessage(e), false);
|
||||||
@ -75,11 +77,23 @@ class DisplayFloat extends Display {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMessage(e) {
|
onMessage(e) {
|
||||||
const {action, params} = e.data;
|
const data = e.data;
|
||||||
const handler = DisplayFloat._messageHandlers.get(action);
|
if (typeof data !== 'object' || data === null) { return; } // Invalid data
|
||||||
if (typeof handler !== 'function') { return; }
|
|
||||||
|
|
||||||
handler(this, params);
|
const token = data.token;
|
||||||
|
if (typeof token !== 'string') { return; } // Invalid data
|
||||||
|
|
||||||
|
if (this._messageToken === null) {
|
||||||
|
// Async
|
||||||
|
this.getMessageToken()
|
||||||
|
.then(
|
||||||
|
() => { this.handleAction(token, data); },
|
||||||
|
() => {}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Sync
|
||||||
|
this.handleAction(token, data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onKeyDown(e) {
|
onKeyDown(e) {
|
||||||
@ -94,6 +108,30 @@ class DisplayFloat extends Display {
|
|||||||
return super.onKeyDown(e);
|
return super.onKeyDown(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getMessageToken() {
|
||||||
|
// this._messageTokenPromise is used to ensure that only one call to apiGetMessageToken is made.
|
||||||
|
if (this._messageTokenPromise === null) {
|
||||||
|
this._messageTokenPromise = apiGetMessageToken();
|
||||||
|
}
|
||||||
|
const messageToken = await this._messageTokenPromise;
|
||||||
|
if (this._messageToken === null) {
|
||||||
|
this._messageToken = messageToken;
|
||||||
|
}
|
||||||
|
this._messageTokenPromise = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleAction(token, {action, params}) {
|
||||||
|
if (token !== this._messageToken) {
|
||||||
|
// Invalid token
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const handler = DisplayFloat._messageHandlers.get(action);
|
||||||
|
if (typeof handler !== 'function') { return; }
|
||||||
|
|
||||||
|
handler(this, params);
|
||||||
|
}
|
||||||
|
|
||||||
getOptionsContext() {
|
getOptionsContext() {
|
||||||
return this.optionsContext;
|
return this.optionsContext;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*global apiInjectStylesheet*/
|
/*global apiInjectStylesheet, apiGetMessageToken*/
|
||||||
|
|
||||||
class Popup {
|
class Popup {
|
||||||
constructor(id, depth, frameIdPromise) {
|
constructor(id, depth, frameIdPromise) {
|
||||||
@ -34,6 +34,7 @@ class Popup {
|
|||||||
this._contentScale = 1.0;
|
this._contentScale = 1.0;
|
||||||
this._containerSizeContentScale = null;
|
this._containerSizeContentScale = null;
|
||||||
this._targetOrigin = chrome.runtime.getURL('/').replace(/\/$/, '');
|
this._targetOrigin = chrome.runtime.getURL('/').replace(/\/$/, '');
|
||||||
|
this._messageToken = null;
|
||||||
|
|
||||||
this._container = document.createElement('iframe');
|
this._container = document.createElement('iframe');
|
||||||
this._container.className = 'yomichan-float';
|
this._container.className = 'yomichan-float';
|
||||||
@ -198,6 +199,10 @@ class Popup {
|
|||||||
// NOP
|
// NOP
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this._messageToken === null) {
|
||||||
|
this._messageToken = await apiGetMessageToken();
|
||||||
|
}
|
||||||
|
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
const parentFrameId = (typeof this._frameId === 'number' ? this._frameId : null);
|
const parentFrameId = (typeof this._frameId === 'number' ? this._frameId : null);
|
||||||
this._container.setAttribute('src', chrome.runtime.getURL('/fg/float.html'));
|
this._container.setAttribute('src', chrome.runtime.getURL('/fg/float.html'));
|
||||||
@ -349,9 +354,11 @@ class Popup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_invokeApi(action, params={}) {
|
_invokeApi(action, params={}) {
|
||||||
if (this._container.contentWindow) {
|
const token = this._messageToken;
|
||||||
this._container.contentWindow.postMessage({action, params}, this._targetOrigin);
|
const contentWindow = this._container.contentWindow;
|
||||||
}
|
if (token === null || contentWindow === null) { return; }
|
||||||
|
|
||||||
|
contentWindow.postMessage({action, params, token}, this._targetOrigin);
|
||||||
}
|
}
|
||||||
|
|
||||||
static _getFullscreenElement() {
|
static _getFullscreenElement() {
|
||||||
|
@ -113,6 +113,10 @@ function apiGetZoom() {
|
|||||||
return _apiInvoke('getZoom');
|
return _apiInvoke('getZoom');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function apiGetMessageToken() {
|
||||||
|
return _apiInvoke('getMessageToken');
|
||||||
|
}
|
||||||
|
|
||||||
function _apiInvoke(action, params={}) {
|
function _apiInvoke(action, params={}) {
|
||||||
const data = {action, params};
|
const data = {action, params};
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user