add typecheck to background operations
This commit is contained in:
parent
8a98a5f880
commit
7873571d22
@ -34,7 +34,10 @@ export function useAutoOpenPermissions(): ToggleHandler {
|
||||
|
||||
useEffect(() => {
|
||||
async function getValue(): Promise<void> {
|
||||
const res = await api.background.containsHeaderListener();
|
||||
const res = await api.background.call(
|
||||
"containsHeaderListener",
|
||||
undefined,
|
||||
);
|
||||
setEnabled(res.newValue);
|
||||
}
|
||||
getValue();
|
||||
@ -63,12 +66,12 @@ async function handleAutoOpenPerm(
|
||||
onChange(false);
|
||||
throw lastError;
|
||||
}
|
||||
const res = await background.toggleHeaderListener(granted);
|
||||
const res = await background.call("toggleHeaderListener", granted);
|
||||
onChange(res.newValue);
|
||||
} else {
|
||||
try {
|
||||
await background
|
||||
.toggleHeaderListener(false)
|
||||
.call("toggleHeaderListener", false)
|
||||
.then((r) => onChange(r.newValue));
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
|
@ -35,7 +35,10 @@ export function useClipboardPermissions(): ToggleHandler {
|
||||
|
||||
useEffect(() => {
|
||||
async function getValue(): Promise<void> {
|
||||
const res = await api.background.containsHeaderListener();
|
||||
const res = await api.background.call(
|
||||
"containsHeaderListener",
|
||||
undefined,
|
||||
);
|
||||
setEnabled(res.newValue);
|
||||
}
|
||||
getValue();
|
||||
@ -71,7 +74,7 @@ async function handleClipboardPerm(
|
||||
} else {
|
||||
try {
|
||||
await background
|
||||
.toggleHeaderListener(false)
|
||||
.call("toggleHeaderListener", false)
|
||||
.then((r) => onChange(r.newValue));
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
|
@ -34,7 +34,7 @@ export function useDiagnostics(): [WalletDiagnostics | undefined, boolean] {
|
||||
}
|
||||
}, 1000);
|
||||
const doFetch = async (): Promise<void> => {
|
||||
const d = await api.background.getDiagnostics();
|
||||
const d = await api.background.call("getDiagnostics", undefined);
|
||||
gotDiagnostics = true;
|
||||
setDiagnostics(d);
|
||||
};
|
||||
|
@ -15,6 +15,8 @@
|
||||
*/
|
||||
|
||||
import { CoreApiResponse, NotificationType } from "@gnu-taler/taler-util";
|
||||
import { WalletOperations } from "@gnu-taler/taler-wallet-core";
|
||||
import { BackgroundOperations } from "../wxApi.js";
|
||||
|
||||
export interface Permissions {
|
||||
/**
|
||||
@ -50,6 +52,30 @@ export type MessageFromBackend = {
|
||||
type: NotificationType;
|
||||
};
|
||||
|
||||
export type MessageFromFrontend<
|
||||
Op extends BackgroundOperations | WalletOperations,
|
||||
> = Op extends BackgroundOperations
|
||||
? MessageFromFrontendBackground<keyof BackgroundOperations>
|
||||
: Op extends WalletOperations
|
||||
? MessageFromFrontendWallet<keyof WalletOperations>
|
||||
: never;
|
||||
|
||||
export type MessageFromFrontendBackground<
|
||||
Op extends keyof BackgroundOperations,
|
||||
> = {
|
||||
channel: "background";
|
||||
operation: Op;
|
||||
payload: BackgroundOperations[Op]["request"];
|
||||
};
|
||||
|
||||
export type MessageFromFrontendWallet<Op extends keyof WalletOperations> = {
|
||||
channel: "wallet";
|
||||
operation: Op;
|
||||
payload: WalletOperations[Op]["request"];
|
||||
};
|
||||
|
||||
export type MessageResponse = CoreApiResponse;
|
||||
|
||||
export interface WalletWebExVersion {
|
||||
version_name?: string | undefined;
|
||||
version: string;
|
||||
@ -183,10 +209,9 @@ export interface PlatformAPI {
|
||||
*
|
||||
* @return response from the backend
|
||||
*/
|
||||
sendMessageToWalletBackground(
|
||||
operation: string,
|
||||
payload: any,
|
||||
): Promise<CoreApiResponse>;
|
||||
sendMessageToBackground<Op extends WalletOperations | BackgroundOperations>(
|
||||
message: MessageFromFrontend<Op>,
|
||||
): Promise<MessageResponse>;
|
||||
|
||||
/**
|
||||
* Used from the frontend to receive notifications about new information
|
||||
@ -204,11 +229,9 @@ export interface PlatformAPI {
|
||||
* @param onNewMessage
|
||||
*/
|
||||
listenToAllChannels(
|
||||
onNewMessage: (
|
||||
message: any,
|
||||
sender: any,
|
||||
sendResponse: (r: CoreApiResponse) => void,
|
||||
) => void,
|
||||
notifyNewMessage: <Op extends WalletOperations | BackgroundOperations>(
|
||||
message: MessageFromFrontend<Op> & { id: string },
|
||||
) => Promise<MessageResponse>,
|
||||
): void;
|
||||
|
||||
/**
|
||||
|
@ -20,9 +20,13 @@ import {
|
||||
Logger,
|
||||
TalerUriType,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { WalletOperations } from "@gnu-taler/taler-wallet-core";
|
||||
import { BackgroundOperations } from "../wxApi.js";
|
||||
import {
|
||||
CrossBrowserPermissionsApi,
|
||||
MessageFromBackend,
|
||||
MessageFromFrontend,
|
||||
MessageResponse,
|
||||
Permissions,
|
||||
PlatformAPI,
|
||||
} from "./api.js";
|
||||
@ -41,11 +45,11 @@ const api: PlatformAPI = {
|
||||
redirectTabToWalletPage,
|
||||
registerAllIncomingConnections,
|
||||
registerOnInstalled,
|
||||
listenToAllChannels,
|
||||
listenToAllChannels: listenToAllChannels as any,
|
||||
registerReloadOnNewVersion,
|
||||
registerTalerHeaderListener,
|
||||
sendMessageToAllChannels,
|
||||
sendMessageToWalletBackground,
|
||||
sendMessageToBackground,
|
||||
useServiceWorkerAsBackgroundProcess,
|
||||
containsTalerHeaderListener,
|
||||
keepAlive,
|
||||
@ -302,30 +306,22 @@ function openWalletPageFromPopup(page: string): void {
|
||||
|
||||
let i = 0;
|
||||
|
||||
async function sendMessageToWalletBackground(
|
||||
operation: string,
|
||||
payload: any,
|
||||
): Promise<any> {
|
||||
return new Promise<any>((resolve, reject) => {
|
||||
logger.trace("send operation to the wallet background", operation);
|
||||
chrome.runtime.sendMessage(
|
||||
{ operation, payload, id: `id_${i++ % 1000}` },
|
||||
(backgroundResponse) => {
|
||||
logger.trace(
|
||||
"BUG: got response from background",
|
||||
backgroundResponse,
|
||||
chrome.runtime.lastError,
|
||||
);
|
||||
async function sendMessageToBackground<
|
||||
Op extends WalletOperations | BackgroundOperations,
|
||||
>(message: MessageFromFrontend<Op>): Promise<MessageResponse> {
|
||||
const messageWithId = { ...message, id: `id_${i++ % 1000}` };
|
||||
|
||||
if (chrome.runtime.lastError) {
|
||||
reject(chrome.runtime.lastError.message);
|
||||
} else {
|
||||
resolve(backgroundResponse);
|
||||
}
|
||||
// return true to keep the channel open
|
||||
return true;
|
||||
},
|
||||
);
|
||||
return new Promise<any>((resolve, reject) => {
|
||||
logger.trace("send operation to the wallet background", message);
|
||||
chrome.runtime.sendMessage(messageWithId, (backgroundResponse) => {
|
||||
if (chrome.runtime.lastError) {
|
||||
reject(chrome.runtime.lastError.message);
|
||||
} else {
|
||||
resolve(backgroundResponse);
|
||||
}
|
||||
// return true to keep the channel open
|
||||
return true;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -377,21 +373,27 @@ function registerAllIncomingConnections(): void {
|
||||
}
|
||||
|
||||
function listenToAllChannels(
|
||||
cb: (
|
||||
message: any,
|
||||
sender: any,
|
||||
callback: (r: CoreApiResponse) => void,
|
||||
) => void,
|
||||
notifyNewMessage: <Op extends WalletOperations | BackgroundOperations>(
|
||||
message: MessageFromFrontend<Op> & { id: string },
|
||||
) => Promise<MessageResponse>,
|
||||
): void {
|
||||
chrome.runtime.onMessage.addListener((m, s, c) => {
|
||||
cb(m, s, (apiResponse) => {
|
||||
logger.trace("BUG: sending response to client", apiResponse);
|
||||
try {
|
||||
c(apiResponse);
|
||||
} catch (e) {
|
||||
logger.error("wallet operation ended with error", e);
|
||||
}
|
||||
});
|
||||
chrome.runtime.onMessage.addListener((message, sender, reply) => {
|
||||
notifyNewMessage(message)
|
||||
.then((apiResponse) => {
|
||||
try {
|
||||
reply(apiResponse);
|
||||
} catch (e) {
|
||||
logger.error(
|
||||
"sending response to frontend failed",
|
||||
message,
|
||||
apiResponse,
|
||||
e,
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
logger.error("notify to background failed", e);
|
||||
});
|
||||
|
||||
// keep the connection open
|
||||
return true;
|
||||
|
@ -15,7 +15,14 @@
|
||||
*/
|
||||
|
||||
import { CoreApiResponse } from "@gnu-taler/taler-util";
|
||||
import { MessageFromBackend, PlatformAPI } from "./api.js";
|
||||
import { WalletOperations } from "@gnu-taler/taler-wallet-core";
|
||||
import { BackgroundOperations } from "../wxApi.js";
|
||||
import {
|
||||
MessageFromBackend,
|
||||
MessageFromFrontend,
|
||||
MessageResponse,
|
||||
PlatformAPI,
|
||||
} from "./api.js";
|
||||
|
||||
const frames = ["popup", "wallet"];
|
||||
|
||||
@ -121,12 +128,17 @@ const api: PlatformAPI = {
|
||||
window.parent.removeEventListener("message", listener);
|
||||
};
|
||||
},
|
||||
sendMessageToWalletBackground: async (operation: string, payload: any) => {
|
||||
|
||||
sendMessageToBackground: async <
|
||||
Op extends WalletOperations | BackgroundOperations,
|
||||
>(
|
||||
payload: MessageFromFrontend<Op>,
|
||||
): Promise<MessageResponse> => {
|
||||
const replyMe = `reply-${Math.floor(Math.random() * 100000)}`;
|
||||
const message: IframeMessageCommand = {
|
||||
type: "command",
|
||||
header: { replyMe },
|
||||
body: { operation, payload, id: "(none)" },
|
||||
body: payload,
|
||||
};
|
||||
window.parent.postMessage(message);
|
||||
|
||||
@ -150,6 +162,7 @@ type IframeMessageType =
|
||||
| IframeMessageNotification
|
||||
| IframeMessageResponse
|
||||
| IframeMessageCommand;
|
||||
|
||||
interface IframeMessageNotification {
|
||||
type: "notification";
|
||||
header: Record<string, never>;
|
||||
@ -160,7 +173,7 @@ interface IframeMessageResponse {
|
||||
header: {
|
||||
responseId: string;
|
||||
};
|
||||
body: CoreApiResponse;
|
||||
body: MessageResponse;
|
||||
}
|
||||
|
||||
interface IframeMessageCommand {
|
||||
@ -168,11 +181,7 @@ interface IframeMessageCommand {
|
||||
header: {
|
||||
replyMe: string;
|
||||
};
|
||||
body: {
|
||||
operation: any;
|
||||
id: string;
|
||||
payload: any;
|
||||
};
|
||||
body: MessageFromFrontend<any>;
|
||||
}
|
||||
|
||||
export default api;
|
||||
|
@ -177,7 +177,7 @@ export function View({
|
||||
onClick={() =>
|
||||
confirmReset(
|
||||
i18n.str`Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL YOUR COINS?`,
|
||||
() => api.background.resetDb(),
|
||||
() => api.background.call("resetDb", undefined),
|
||||
)
|
||||
}
|
||||
>
|
||||
@ -190,7 +190,7 @@ export function View({
|
||||
onClick={() =>
|
||||
confirmReset(
|
||||
i18n.str`TESTING: This may delete all your coin, proceed with caution`,
|
||||
() => api.background.runGarbageCollector(),
|
||||
() => api.background.call("runGarbageCollector", undefined),
|
||||
)
|
||||
}
|
||||
>
|
||||
|
@ -34,70 +34,72 @@ import {
|
||||
WalletCoreRequestType,
|
||||
WalletCoreResponseType,
|
||||
} from "@gnu-taler/taler-wallet-core";
|
||||
import { MessageFromBackend, platform } from "./platform/api.js";
|
||||
import { nullFunction } from "./test-utils.js";
|
||||
import {
|
||||
MessageFromBackend,
|
||||
MessageFromFrontendBackground,
|
||||
MessageFromFrontendWallet,
|
||||
platform,
|
||||
} from "./platform/api.js";
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Florian Dold
|
||||
* @author sebasjm
|
||||
*/
|
||||
|
||||
const logger = new Logger("wxApi");
|
||||
|
||||
export interface ExtendedPermissionsResponse {
|
||||
newValue: boolean;
|
||||
}
|
||||
const logger = new Logger("wxApi");
|
||||
|
||||
/**
|
||||
* Response with information about available version upgrades.
|
||||
*/
|
||||
export interface UpgradeResponse {
|
||||
/**
|
||||
* Is a reset required because of a new DB version
|
||||
* that can't be automatically upgraded?
|
||||
*/
|
||||
dbResetRequired: boolean;
|
||||
|
||||
/**
|
||||
* Current database version.
|
||||
*/
|
||||
currentDbVersion: string;
|
||||
|
||||
/**
|
||||
* Old db version (if applicable).
|
||||
*/
|
||||
oldDbVersion: string;
|
||||
export interface BackgroundOperations {
|
||||
resetDb: {
|
||||
request: void;
|
||||
response: void;
|
||||
};
|
||||
containsHeaderListener: {
|
||||
request: void;
|
||||
response: ExtendedPermissionsResponse;
|
||||
};
|
||||
getDiagnostics: {
|
||||
request: void;
|
||||
response: WalletDiagnostics;
|
||||
};
|
||||
toggleHeaderListener: {
|
||||
request: boolean;
|
||||
response: ExtendedPermissionsResponse;
|
||||
};
|
||||
runGarbageCollector: {
|
||||
request: void;
|
||||
response: void;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link WxWalletCoreApiClient} instead.
|
||||
*/
|
||||
async function callBackend(operation: string, payload: any): Promise<any> {
|
||||
let response: CoreApiResponse;
|
||||
try {
|
||||
response = await platform.sendMessageToWalletBackground(operation, payload);
|
||||
} catch (e) {
|
||||
console.log("Error calling backend");
|
||||
throw new Error(`Error contacting backend: ${e}`);
|
||||
}
|
||||
logger.info("got response", response);
|
||||
if (response.type === "error") {
|
||||
throw TalerError.fromUncheckedDetail(response.error);
|
||||
}
|
||||
return response.result;
|
||||
}
|
||||
|
||||
export class WxWalletCoreApiClient implements WalletCoreApiClient {
|
||||
async call<Op extends WalletCoreOpKeys>(
|
||||
export interface BackgroundApiClient {
|
||||
call<Op extends keyof BackgroundOperations>(
|
||||
operation: Op,
|
||||
payload: WalletCoreRequestType<Op>,
|
||||
): Promise<WalletCoreResponseType<Op>> {
|
||||
payload: BackgroundOperations[Op]["request"],
|
||||
): Promise<BackgroundOperations[Op]["response"]>;
|
||||
}
|
||||
|
||||
/**
|
||||
* BackgroundApiClient integration with browser platform
|
||||
*/
|
||||
class BackgroundApiClientImpl implements BackgroundApiClient {
|
||||
async call<Op extends keyof BackgroundOperations>(
|
||||
operation: Op,
|
||||
payload: BackgroundOperations[Op]["request"],
|
||||
): Promise<BackgroundOperations[Op]["response"]> {
|
||||
let response: CoreApiResponse;
|
||||
|
||||
const message: MessageFromFrontendBackground<Op> = {
|
||||
channel: "background",
|
||||
operation,
|
||||
payload,
|
||||
};
|
||||
|
||||
try {
|
||||
response = await platform.sendMessageToWalletBackground(
|
||||
operation,
|
||||
payload,
|
||||
);
|
||||
response = await platform.sendMessageToBackground(message);
|
||||
} catch (e) {
|
||||
console.log("Error calling backend");
|
||||
throw new Error(`Error contacting backend: ${e}`);
|
||||
@ -110,29 +112,34 @@ export class WxWalletCoreApiClient implements WalletCoreApiClient {
|
||||
}
|
||||
}
|
||||
|
||||
export class BackgroundApiClient {
|
||||
public resetDb(): Promise<void> {
|
||||
return callBackend("reset-db", {});
|
||||
}
|
||||
|
||||
public containsHeaderListener(): Promise<ExtendedPermissionsResponse> {
|
||||
return callBackend("containsHeaderListener", {});
|
||||
}
|
||||
|
||||
public getDiagnostics(): Promise<WalletDiagnostics> {
|
||||
return callBackend("wxGetDiagnostics", {});
|
||||
}
|
||||
|
||||
public toggleHeaderListener(
|
||||
value: boolean,
|
||||
): Promise<ExtendedPermissionsResponse> {
|
||||
return callBackend("toggleHeaderListener", { value });
|
||||
}
|
||||
|
||||
public runGarbageCollector(): Promise<void> {
|
||||
return callBackend("run-gc", {});
|
||||
/**
|
||||
* WalletCoreApiClient integration with browser platform
|
||||
*/
|
||||
class WalletApiClientImpl implements WalletCoreApiClient {
|
||||
async call<Op extends WalletCoreOpKeys>(
|
||||
operation: Op,
|
||||
payload: WalletCoreRequestType<Op>,
|
||||
): Promise<WalletCoreResponseType<Op>> {
|
||||
let response: CoreApiResponse;
|
||||
try {
|
||||
const message: MessageFromFrontendWallet<Op> = {
|
||||
channel: "wallet",
|
||||
operation,
|
||||
payload,
|
||||
};
|
||||
response = await platform.sendMessageToBackground(message);
|
||||
} catch (e) {
|
||||
console.log("Error calling backend");
|
||||
throw new Error(`Error contacting backend: ${e}`);
|
||||
}
|
||||
logger.info("got response", response);
|
||||
if (response.type === "error") {
|
||||
throw TalerError.fromUncheckedDetail(response.error);
|
||||
}
|
||||
return response.result as any;
|
||||
}
|
||||
}
|
||||
|
||||
function onUpdateNotification(
|
||||
messageTypes: Array<NotificationType>,
|
||||
doCallback: undefined | (() => void),
|
||||
@ -160,8 +167,8 @@ export type WxApiType = {
|
||||
};
|
||||
|
||||
export const wxApi = {
|
||||
wallet: new WxWalletCoreApiClient(),
|
||||
background: new BackgroundApiClient(),
|
||||
wallet: new WalletApiClientImpl(),
|
||||
background: new BackgroundApiClientImpl(),
|
||||
listener: {
|
||||
onUpdateNotification,
|
||||
},
|
||||
|
@ -25,8 +25,6 @@
|
||||
*/
|
||||
import {
|
||||
classifyTalerUri,
|
||||
CoreApiResponse,
|
||||
CoreApiResponseSuccess,
|
||||
Logger,
|
||||
TalerErrorCode,
|
||||
TalerUriType,
|
||||
@ -36,20 +34,27 @@ import {
|
||||
DbAccess,
|
||||
deleteTalerDatabase,
|
||||
exportDb,
|
||||
getErrorDetailFromException,
|
||||
importDb,
|
||||
makeErrorDetail,
|
||||
OpenedPromise,
|
||||
openPromise,
|
||||
openTalerDatabase,
|
||||
SetTimeoutTimerAPI,
|
||||
Wallet,
|
||||
WalletOperations,
|
||||
WalletStoresV1,
|
||||
} from "@gnu-taler/taler-wallet-core";
|
||||
import { SetTimeoutTimerAPI } from "@gnu-taler/taler-wallet-core";
|
||||
import { BrowserCryptoWorkerFactory } from "./browserCryptoWorkerFactory.js";
|
||||
import { BrowserHttpLib } from "./browserHttpLib.js";
|
||||
import { MessageFromBackend, platform } from "./platform/api.js";
|
||||
import {
|
||||
MessageFromBackend,
|
||||
MessageFromFrontend,
|
||||
MessageResponse,
|
||||
platform,
|
||||
} from "./platform/api.js";
|
||||
import { SynchronousCryptoWorkerFactory } from "./serviceWorkerCryptoWorkerFactory.js";
|
||||
import { ServiceWorkerHttpLib } from "./serviceWorkerHttpLib.js";
|
||||
import { BackgroundOperations, ExtendedPermissionsResponse } from "./wxApi.js";
|
||||
|
||||
/**
|
||||
* Currently active wallet instance. Might be unloaded and
|
||||
@ -107,92 +112,115 @@ async function getDiagnostics(): Promise<WalletDiagnostics> {
|
||||
return diagnostics;
|
||||
}
|
||||
|
||||
async function dispatch(
|
||||
req: any,
|
||||
sender: any,
|
||||
sendResponse: any,
|
||||
): Promise<void> {
|
||||
let r: CoreApiResponse;
|
||||
type BackendHandlerType = {
|
||||
[Op in keyof BackgroundOperations]: (
|
||||
req: BackgroundOperations[Op]["request"],
|
||||
) => Promise<BackgroundOperations[Op]["response"]>;
|
||||
};
|
||||
|
||||
const wrapResponse = (result: unknown): CoreApiResponseSuccess => {
|
||||
async function containsHeaderListener(): Promise<ExtendedPermissionsResponse> {
|
||||
const result = await platform.containsTalerHeaderListener();
|
||||
return { newValue: result };
|
||||
}
|
||||
|
||||
async function resetDb(): Promise<void> {
|
||||
await deleteTalerDatabase(indexedDB as any);
|
||||
await reinitWallet();
|
||||
}
|
||||
|
||||
async function runGarbageCollector(): Promise<void> {
|
||||
const dbBeforeGc = currentDatabase;
|
||||
if (!dbBeforeGc) {
|
||||
throw Error("no current db before running gc");
|
||||
}
|
||||
const dump = await exportDb(dbBeforeGc.idbHandle());
|
||||
|
||||
await deleteTalerDatabase(indexedDB as any);
|
||||
logger.info("cleaned");
|
||||
await reinitWallet();
|
||||
logger.info("init");
|
||||
|
||||
const dbAfterGc = currentDatabase;
|
||||
if (!dbAfterGc) {
|
||||
throw Error("no current db before running gc");
|
||||
}
|
||||
await importDb(dbAfterGc.idbHandle(), dump);
|
||||
logger.info("imported");
|
||||
}
|
||||
|
||||
async function toggleHeaderListener(
|
||||
newVal: boolean,
|
||||
): Promise<ExtendedPermissionsResponse> {
|
||||
logger.trace("new extended permissions value", newVal);
|
||||
if (newVal) {
|
||||
platform.registerTalerHeaderListener(parseTalerUriAndRedirect);
|
||||
return { newValue: true };
|
||||
}
|
||||
|
||||
const rem = await platform.getPermissionsApi().removeHostPermissions();
|
||||
logger.trace("permissions removed:", rem);
|
||||
return { newValue: false };
|
||||
}
|
||||
|
||||
const backendHandlers: BackendHandlerType = {
|
||||
containsHeaderListener,
|
||||
getDiagnostics,
|
||||
resetDb,
|
||||
runGarbageCollector,
|
||||
toggleHeaderListener,
|
||||
};
|
||||
|
||||
async function dispatch<Op extends WalletOperations | BackgroundOperations>(
|
||||
req: MessageFromFrontend<Op> & { id: string },
|
||||
): Promise<MessageResponse> {
|
||||
if (req.channel === "background") {
|
||||
const handler = backendHandlers[req.operation] as (req: any) => any;
|
||||
if (!handler) {
|
||||
return {
|
||||
type: "error",
|
||||
id: req.id,
|
||||
operation: String(req.operation),
|
||||
error: getErrorDetailFromException(
|
||||
Error(`unknown background operation`),
|
||||
),
|
||||
};
|
||||
}
|
||||
const result = await handler(req.payload);
|
||||
return {
|
||||
type: "response",
|
||||
id: req.id,
|
||||
operation: req.operation,
|
||||
operation: String(req.operation),
|
||||
result,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
switch (req.operation) {
|
||||
case "wxGetDiagnostics": {
|
||||
r = wrapResponse(await getDiagnostics());
|
||||
break;
|
||||
}
|
||||
case "reset-db": {
|
||||
await deleteTalerDatabase(indexedDB as any);
|
||||
r = wrapResponse(await reinitWallet());
|
||||
break;
|
||||
}
|
||||
case "run-gc": {
|
||||
logger.info("gc");
|
||||
const dump = await exportDb(currentDatabase!.idbHandle());
|
||||
await deleteTalerDatabase(indexedDB as any);
|
||||
logger.info("cleaned");
|
||||
await reinitWallet();
|
||||
logger.info("init");
|
||||
await importDb(currentDatabase!.idbHandle(), dump);
|
||||
logger.info("imported");
|
||||
r = wrapResponse({ result: true });
|
||||
break;
|
||||
}
|
||||
case "containsHeaderListener": {
|
||||
const res = await platform.containsTalerHeaderListener();
|
||||
r = wrapResponse({ newValue: res });
|
||||
break;
|
||||
}
|
||||
//FIXME: implement type checked api like WalletCoreApi
|
||||
case "toggleHeaderListener": {
|
||||
const newVal = req.payload.value;
|
||||
logger.trace("new extended permissions value", newVal);
|
||||
if (newVal) {
|
||||
platform.registerTalerHeaderListener(parseTalerUriAndRedirect);
|
||||
r = wrapResponse({ newValue: true });
|
||||
} else {
|
||||
const rem = await platform
|
||||
.getPermissionsApi()
|
||||
.removeHostPermissions();
|
||||
logger.trace("permissions removed:", rem);
|
||||
r = wrapResponse({ newVal: false });
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
const w = currentWallet;
|
||||
if (!w) {
|
||||
r = {
|
||||
type: "error",
|
||||
id: req.id,
|
||||
operation: req.operation,
|
||||
error: makeErrorDetail(
|
||||
TalerErrorCode.WALLET_CORE_NOT_AVAILABLE,
|
||||
{},
|
||||
"wallet core not available",
|
||||
),
|
||||
};
|
||||
break;
|
||||
}
|
||||
r = await w.handleCoreApiRequest(req.operation, req.id, req.payload);
|
||||
console.log("response received from wallet", r);
|
||||
break;
|
||||
}
|
||||
if (req.channel === "wallet") {
|
||||
const w = currentWallet;
|
||||
if (!w) {
|
||||
return {
|
||||
type: "error",
|
||||
id: req.id,
|
||||
operation: req.operation,
|
||||
error: makeErrorDetail(
|
||||
TalerErrorCode.WALLET_CORE_NOT_AVAILABLE,
|
||||
{},
|
||||
"wallet core not available",
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
sendResponse(r);
|
||||
} catch (e) {
|
||||
logger.error(`Error sending operation: ${req.operation}`, e);
|
||||
// might fail if tab disconnected
|
||||
return await w.handleCoreApiRequest(req.operation, req.id, req.payload);
|
||||
}
|
||||
|
||||
const anyReq = req as any;
|
||||
return {
|
||||
type: "error",
|
||||
id: anyReq.id,
|
||||
operation: String(anyReq.operation),
|
||||
error: getErrorDetailFromException(
|
||||
Error(`unknown channel ${anyReq.channel}`),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
async function reinitWallet(): Promise<void> {
|
||||
@ -328,12 +356,11 @@ export async function wxMain(): Promise<void> {
|
||||
|
||||
// Handlers for messages coming directly from the content
|
||||
// script on the page
|
||||
platform.listenToAllChannels((message, sender, callback) => {
|
||||
afterWalletIsInitialized.then(() => {
|
||||
dispatch(message, sender, (response: CoreApiResponse) => {
|
||||
callback(response);
|
||||
});
|
||||
});
|
||||
platform.listenToAllChannels(async (message) => {
|
||||
//wait until wallet is initialized
|
||||
await afterWalletIsInitialized;
|
||||
const result = await dispatch(message);
|
||||
return result;
|
||||
});
|
||||
|
||||
platform.registerAllIncomingConnections();
|
||||
|
Loading…
Reference in New Issue
Block a user