2019-08-12 18:31:32 +02:00
|
|
|
import { BrowserApi } from './browserApi';
|
|
|
|
|
|
|
|
export class SafariApp {
|
2019-08-19 18:44:05 +02:00
|
|
|
static inited = false;
|
|
|
|
|
2019-08-12 18:31:32 +02:00
|
|
|
static init() {
|
2019-08-19 18:44:05 +02:00
|
|
|
if (SafariApp.inited) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
SafariApp.inited = true;
|
2019-08-12 18:31:32 +02:00
|
|
|
if (BrowserApi.isSafariApi) {
|
2019-08-15 22:52:58 +02:00
|
|
|
(window as any).bitwardenSafariAppRequests =
|
2019-08-19 18:44:05 +02:00
|
|
|
new Map<string, { resolve: (value?: unknown) => void, timeoutDate: Date }>();
|
2019-08-15 22:52:58 +02:00
|
|
|
(window as any).bitwardenSafariAppMessageListeners =
|
2019-08-19 18:44:05 +02:00
|
|
|
new Map<string, (message: any, sender: any, response: any) => void>();
|
2019-08-15 20:06:59 +02:00
|
|
|
(window as any).bitwardenSafariAppMessageReceiver = (message: any) => {
|
2019-08-15 20:48:02 +02:00
|
|
|
SafariApp.receiveMessageFromApp(message);
|
2019-08-15 20:06:59 +02:00
|
|
|
};
|
2019-08-19 18:44:05 +02:00
|
|
|
setInterval(() => SafariApp.cleanupOldRequests(), 5 * 60000);
|
2019-08-12 18:31:32 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-19 18:44:05 +02:00
|
|
|
static sendMessageToApp(command: string, data: any = null, resolveNow = false): Promise<any> {
|
2019-08-12 18:31:32 +02:00
|
|
|
if (!BrowserApi.isSafariApi) {
|
|
|
|
return Promise.resolve(null);
|
|
|
|
}
|
|
|
|
return new Promise((resolve) => {
|
2019-08-12 21:50:47 +02:00
|
|
|
const now = new Date();
|
|
|
|
const messageId = now.getTime().toString() + '_' + Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
|
|
|
|
(window as any).webkit.messageHandlers.bitwardenApp.postMessage(JSON.stringify({
|
2019-08-12 18:31:32 +02:00
|
|
|
id: messageId,
|
|
|
|
command: command,
|
|
|
|
data: data,
|
2019-08-15 20:06:59 +02:00
|
|
|
responseData: null,
|
2019-08-12 21:50:47 +02:00
|
|
|
}));
|
2019-08-19 18:44:05 +02:00
|
|
|
if (resolveNow) {
|
|
|
|
resolve();
|
|
|
|
} else {
|
|
|
|
(window as any).bitwardenSafariAppRequests.set(messageId, {
|
|
|
|
resolve: resolve,
|
|
|
|
timeoutDate: new Date(now.getTime() + 5 * 60000),
|
|
|
|
});
|
|
|
|
}
|
2019-08-12 18:31:32 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-08-15 22:36:49 +02:00
|
|
|
static addMessageListener(name: string, callback: (message: any, sender: any, response: any) => void) {
|
2019-08-15 22:52:58 +02:00
|
|
|
(window as any).bitwardenSafariAppMessageListeners.set(name, callback);
|
2019-08-15 22:36:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static sendMessageToListeners(message: any, sender: any, response: any) {
|
2019-08-15 22:52:58 +02:00
|
|
|
(window as any).bitwardenSafariAppMessageListeners.forEach((f: any) => f(message, sender, response));
|
2019-08-15 22:36:49 +02:00
|
|
|
}
|
|
|
|
|
2019-08-12 18:31:32 +02:00
|
|
|
private static receiveMessageFromApp(message: any) {
|
2019-08-16 14:48:43 +02:00
|
|
|
if (message == null) {
|
2019-08-12 18:31:32 +02:00
|
|
|
return;
|
|
|
|
}
|
2019-08-17 02:46:19 +02:00
|
|
|
if ((message.id == null || message.id === '') && message.command === 'app_message') {
|
2019-08-16 14:48:43 +02:00
|
|
|
try {
|
|
|
|
const msg = JSON.parse(message.data);
|
2019-08-17 02:46:19 +02:00
|
|
|
SafariApp.sendMessageToListeners(msg, 'app_message', null);
|
2019-08-16 14:48:43 +02:00
|
|
|
} catch { }
|
|
|
|
} else if (message.id != null && (window as any).bitwardenSafariAppRequests.has(message.id)) {
|
|
|
|
const p = (window as any).bitwardenSafariAppRequests.get(message.id);
|
|
|
|
p.resolve(message.responseData);
|
2019-08-19 18:44:05 +02:00
|
|
|
(window as any).bitwardenSafariAppRequests.delete(message.id);
|
2019-08-16 14:48:43 +02:00
|
|
|
}
|
2019-08-12 18:31:32 +02:00
|
|
|
}
|
2019-08-19 18:44:05 +02:00
|
|
|
|
|
|
|
private static cleanupOldRequests() {
|
2019-08-19 20:13:14 +02:00
|
|
|
const removeIds: string[] = [];
|
2019-08-19 18:44:05 +02:00
|
|
|
((window as any).bitwardenSafariAppRequests as
|
|
|
|
Map<string, { resolve: (value?: unknown) => void, timeoutDate: Date }>)
|
|
|
|
.forEach((v, key) => {
|
|
|
|
if (v.timeoutDate < new Date()) {
|
2019-08-19 20:13:14 +02:00
|
|
|
removeIds.push(key);
|
2019-08-19 18:44:05 +02:00
|
|
|
}
|
|
|
|
});
|
2019-08-19 20:13:14 +02:00
|
|
|
removeIds.forEach((id) => {
|
2019-08-19 18:44:05 +02:00
|
|
|
(window as any).bitwardenSafariAppRequests.delete(id);
|
|
|
|
});
|
|
|
|
}
|
2019-08-12 18:31:32 +02:00
|
|
|
}
|