Use postRobot to listen for GitHub OAuth messages (#729)

This commit is contained in:
Tanuj Mittal 2021-04-27 12:52:52 -04:00 committed by GitHub
parent 10c4dd0f19
commit e8b79d6260
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 44 deletions

View File

@ -1,3 +1,5 @@
import postRobot from "post-robot";
export interface IGitHubConnectorParams { export interface IGitHubConnectorParams {
state: string; state: string;
code: string; code: string;
@ -6,25 +8,26 @@ export interface IGitHubConnectorParams {
export const GitHubConnectorMsgType = "GitHubConnectorMsgType"; export const GitHubConnectorMsgType = "GitHubConnectorMsgType";
export class GitHubConnector { export class GitHubConnector {
public start(params: URLSearchParams, window: Window & typeof globalThis) { public async start(params: URLSearchParams, window: Window & typeof globalThis): Promise<void> {
window.postMessage( await postRobot.send(
window,
GitHubConnectorMsgType,
{ {
type: GitHubConnectorMsgType, state: params.get("state"),
data: { code: params.get("code"),
state: params.get("state"), } as IGitHubConnectorParams,
code: params.get("code"), {
} as IGitHubConnectorParams, domain: window.location.origin,
}, }
window.location.origin
); );
} }
} }
var connector = new GitHubConnector(); var connector = new GitHubConnector();
window.addEventListener("load", () => { window.addEventListener("load", async () => {
const openerWindow = window.opener; const openerWindow = window.opener;
if (openerWindow) { if (openerWindow) {
connector.start(new URLSearchParams(document.location.search), openerWindow); await connector.start(new URLSearchParams(document.location.search), openerWindow);
window.close(); window.close();
} }
}); });

View File

@ -1,12 +1,12 @@
import ko from "knockout"; import ko from "knockout";
import { HttpStatusCodes } from "../Common/Constants"; import { HttpStatusCodes } from "../Common/Constants";
import * as DataModels from "../Contracts/DataModels"; import * as DataModels from "../Contracts/DataModels";
import { JunoClient } from "../Juno/JunoClient"; import Explorer from "../Explorer/Explorer";
import { GitHubConnector, IGitHubConnectorParams } from "./GitHubConnector";
import { GitHubOAuthService } from "./GitHubOAuthService";
import { ConsoleDataType } from "../Explorer/Menus/NotificationConsole/NotificationConsoleComponent"; import { ConsoleDataType } from "../Explorer/Menus/NotificationConsole/NotificationConsoleComponent";
import NotebookManager from "../Explorer/Notebook/NotebookManager"; import NotebookManager from "../Explorer/Notebook/NotebookManager";
import Explorer from "../Explorer/Explorer"; import { JunoClient } from "../Juno/JunoClient";
import { IGitHubConnectorParams } from "./GitHubConnector";
import { GitHubOAuthService } from "./GitHubOAuthService";
const sampleDatabaseAccount: DataModels.DatabaseAccount = { const sampleDatabaseAccount: DataModels.DatabaseAccount = {
id: "id", id: "id",
@ -85,25 +85,6 @@ describe("GitHubOAuthService", () => {
expect(newParams.get("state")).not.toEqual(initialParams.get("state")); expect(newParams.get("state")).not.toEqual(initialParams.get("state"));
}); });
it("finishOAuth is called whenever GitHubConnector is started", async () => {
const finishOAuthCallback = jest.fn().mockImplementation();
gitHubOAuthService.finishOAuth = finishOAuthCallback;
const params: IGitHubConnectorParams = {
state: "state",
code: "code",
};
const searchParams = new URLSearchParams({ ...params });
const gitHubConnector = new GitHubConnector();
gitHubConnector.start(searchParams, window);
// GitHubConnector uses Window.postMessage and there's no good way to know when the message has received
await new Promise((resolve) => setTimeout(resolve, 100));
expect(finishOAuthCallback).toBeCalledWith(params);
});
it("finishOAuth updates token", async () => { it("finishOAuth updates token", async () => {
const data = { key: "value" }; const data = { key: "value" };
const getGitHubTokenCallback = jest.fn().mockReturnValue({ status: HttpStatusCodes.OK, data }); const getGitHubTokenCallback = jest.fn().mockReturnValue({ status: HttpStatusCodes.OK, data });

View File

@ -1,24 +1,25 @@
import ko from "knockout"; import ko from "knockout";
import postRobot from "post-robot";
import { HttpStatusCodes } from "../Common/Constants"; import { HttpStatusCodes } from "../Common/Constants";
import { handleError } from "../Common/ErrorHandlingUtils"; import { handleError } from "../Common/ErrorHandlingUtils";
import { configContext } from "../ConfigContext"; import { configContext } from "../ConfigContext";
import { AuthorizeAccessComponent } from "../Explorer/Controls/GitHub/AuthorizeAccessComponent"; import { AuthorizeAccessComponent } from "../Explorer/Controls/GitHub/AuthorizeAccessComponent";
import { JunoClient } from "../Juno/JunoClient"; import { JunoClient } from "../Juno/JunoClient";
import { isInvalidParentFrameOrigin } from "../Utils/MessageValidation";
import { logConsoleInfo } from "../Utils/NotificationConsoleUtils"; import { logConsoleInfo } from "../Utils/NotificationConsoleUtils";
import { GitHubConnectorMsgType, IGitHubConnectorParams } from "./GitHubConnector"; import { GitHubConnectorMsgType, IGitHubConnectorParams } from "./GitHubConnector";
window.addEventListener("message", (event: MessageEvent) => { postRobot.on(
if (isInvalidParentFrameOrigin(event)) { GitHubConnectorMsgType,
return; {
} domain: window.location.origin,
},
const msg = event.data; (event) => {
if (msg.type === GitHubConnectorMsgType) { // Typescript definition for event is wrong. So read params by casting to <any>
const params = msg.data as IGitHubConnectorParams; // eslint-disable-next-line @typescript-eslint/no-explicit-any
const params = (event as any).data as IGitHubConnectorParams;
window.dataExplorer.notebookManager?.gitHubOAuthService.finishOAuth(params); window.dataExplorer.notebookManager?.gitHubOAuthService.finishOAuth(params);
} }
}); );
export interface IGitHubOAuthToken { export interface IGitHubOAuthToken {
// API properties // API properties