Skip to content

Commit

Permalink
feat(platforms): alert users about missing CB attestation before oauth (
Browse files Browse the repository at this point in the history
#2584)

* feat(platforms): alert users about missing CB attestation before oauth

* test(platforms): added test

* changed error name for accuracy
  • Loading branch information
lucianHymer authored and tim-schultz committed Jun 21, 2024
1 parent 0e19d0f commit 182018d
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 4 deletions.
4 changes: 3 additions & 1 deletion app/components/GenericPlatform.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { useWalletStore } from "../context/walletStore";
import { waitForRedirect } from "../context/stampClaimingContext";

// --- Types
import { PlatformGroupSpec } from "@gitcoin/passport-platforms";
import { PlatformGroupSpec, PlatformPreCheckError } from "@gitcoin/passport-platforms";
import { PlatformClass } from "@gitcoin/passport-platforms";
import { IAM_SIGNATURE_TYPE, iamUrl } from "../config/stamp_config";

Expand Down Expand Up @@ -288,6 +288,8 @@ export const GenericPlatform = ({
fail,
platform.platformId as PLATFORM_ID
);
} else if (e instanceof PlatformPreCheckError) {
doneToast("Verification Failed", e.message, fail, platform.platformId as PLATFORM_ID);
} else {
console.error(e);
datadogLogs.logger.error("Verification Error", { error: e, platform: platform.platformId });
Expand Down
20 changes: 17 additions & 3 deletions platforms/src/Coinbase/App-Bindings.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { PlatformOptions } from "../types";
import { Platform } from "../utils/platform";
import { AppContext, PlatformOptions, ProviderPayload } from "../types";
import { Platform, PlatformPreCheckError } from "../utils/platform";
import React from "react";
import { verifyCoinbaseAttestation } from "./Providers/coinbase";

export class CoinbasePlatform extends Platform {
platformId = "Coinbase";
Expand Down Expand Up @@ -28,7 +29,8 @@ export class CoinbasePlatform extends Platform {
>
Verify Coinbase ID
</a>{" "}
on this wallet address <br /><br />
on this wallet address <br />
<br />
Step 2: Click Verify below to sign into your Coinbase account <br />
You cannot complete without completing the Coinbase attestation onchain in Step 1. Ensure you have an active
Coinbase account with a verified government ID to mint your onchain attestation for free on base.
Expand All @@ -46,6 +48,18 @@ export class CoinbasePlatform extends Platform {
this.redirectUri = options.redirectUri as string;
}

async getProviderPayload(appContext: AppContext): Promise<ProviderPayload> {
const address = appContext.userDid.split(":")[4].toLowerCase();
const hasAttestation = await verifyCoinbaseAttestation(address);
if (!hasAttestation) {
throw new PlatformPreCheckError(
"You need to verify your Coinbase ID onchain before you can verify your Coinbase account."
);
}

return super.getProviderPayload(appContext);
}

async getOAuthUrl(state: string): Promise<string> {
const coinbasebUrl = await Promise.resolve(
`https://www.coinbase.com/oauth/authorize?response_type=code&client_id=${this.clientId}&redirect_uri=${this.redirectUri}&state=${state}`
Expand Down
56 changes: 56 additions & 0 deletions platforms/src/Coinbase/__tests__/coinbaseGetProviderInfo.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/* eslint-disable */
// ---- Test subject
import { verifyCoinbaseAttestation } from "../Providers/coinbase";
import { CoinbasePlatform } from "../App-Bindings";
import { PlatformPreCheckError } from "../../utils/platform";

jest.mock("../Providers/coinbase");

const mockedVerifyCoinbaseAttestation = jest.mocked(verifyCoinbaseAttestation);

const mockResponse = {
code: 123,
sessionKey: "sessionKey",
signature: "signature",
};

const appContext = {
waitForRedirect: () => Promise.resolve(mockResponse),
window: {
open: jest.fn(),
},
screen: {
width: 800,
height: 600,
},
state: "state",
userDid: "did:pk:ethr:1:0x12345",
selectedProviders: [] as any[],
};

describe("getProviderInfo", () => {
it("should return oauth info for a valid attestation", async () => {
mockedVerifyCoinbaseAttestation.mockResolvedValueOnce(true);
const providerInfo = await new CoinbasePlatform({
clientId: "clientId",
redirectUri: "redirectUri",
}).getProviderPayload(appContext);
expect(providerInfo.code).toBe(mockResponse.code);
expect(mockedVerifyCoinbaseAttestation).toHaveBeenCalledWith("0x12345");
});

it("should return PlatformPreCheckError for an invalid attestation", async () => {
mockedVerifyCoinbaseAttestation.mockResolvedValueOnce(false);
await expect(
new CoinbasePlatform({
clientId: "clientId",
redirectUri: "redirectUri",
}).getProviderPayload(appContext)
).rejects.toThrowError(
new PlatformPreCheckError(
"You need to verify your Coinbase ID onchain before you can verify your Coinbase account."
)
);
expect(mockedVerifyCoinbaseAttestation).toHaveBeenCalledWith("0x12345");
});
});
1 change: 1 addition & 0 deletions platforms/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,4 @@ export { platforms as platforms };
export { initCacheSession, loadCacheSession, clearCacheSession } from "./utils/platform-cache";
export { handleAxiosError } from "./utils/handleAxiosError";
export { PassportCache } from "./utils/passport-cache";
export { PlatformPreCheckError } from "./utils/platform";
6 changes: 6 additions & 0 deletions platforms/src/utils/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ import { AppContext, ProviderPayload } from "../types";
import { PROVIDER_ID } from "@gitcoin/passport-types";
import { Platform as PlatformType, PlatformBanner } from "../types";

export class PlatformPreCheckError extends Error {
constructor(message: string) {
super(message);
}
}

export type PlatformOptions = {
platformId: string;
path: string;
Expand Down

0 comments on commit 182018d

Please sign in to comment.