Skip to content

Commit

Permalink
fix: only creates a new passport if we get an empty response from cer…
Browse files Browse the repository at this point in the history
…amic
  • Loading branch information
gdixon committed Jun 13, 2022
1 parent 1b76954 commit f7f1eca
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 19 deletions.
5 changes: 3 additions & 2 deletions app/components/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const Card = ({
issueCredentialWidget,
isLoading = false,
}: CardProps): JSX.Element => {
const { isLoadingPassport } = useContext(UserContext);
const { passport, isLoadingPassport } = useContext(UserContext);
const { isOpen, onOpen, onClose } = useDisclosure();
return (
<div className="w-full p-4 md:w-1/2 xl:w-1/4">
Expand Down Expand Up @@ -81,7 +81,8 @@ export const Card = ({
<h1 className="title-font mb-3 text-lg font-medium text-gray-900">{providerSpec.name}</h1>
<p className="pleading-relaxed">{providerSpec.description}</p>
</div>
{isLoadingPassport ? (
{/* TODO: change this to passport===false and introduce an offline save state when passport===undefined */}
{!passport || isLoadingPassport ? (
<span className="flex w-full items-center justify-center border-t-2 p-3 text-gray-900">
<span>
<Spinner
Expand Down
23 changes: 18 additions & 5 deletions app/context/userContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,10 @@ export const UserContextProvider = ({ children }: { children: any }) => {
setAllProviderState(startingAllProvidersState);
};

const cleanPassport = (passport: Passport | undefined, database: CeramicDatabase): Passport | undefined => {
const cleanPassport = (
passport: Passport | undefined | false,
database: CeramicDatabase
): Passport | undefined | false => {
// clean stamp content if expired or from a different issuer
if (passport) {
passport.stamps = passport.stamps.filter((stamp: Stamp) => {
Expand All @@ -273,10 +276,20 @@ export const UserContextProvider = ({ children }: { children: any }) => {

const fetchPassport = async (database: CeramicDatabase): Promise<void> => {
// fetch, clean and set the new Passport state
const passport = await database.getPassport();
const cleanedPassport = cleanPassport(passport, database);
hydrateAllProvidersState(cleanedPassport);
setPassport(cleanedPassport);
let passport = (await database.getPassport()) as Passport;
if (passport) {
passport = cleanPassport(passport, database) as Passport;
hydrateAllProvidersState(passport);
} else if (passport === false) {
handleCreatePassport();
} else {
// something is wrong with Ceramic...
console.warn("Ceramic connection failed");
// no ceramic...
setAddress(undefined);
handleConnection();
}
setPassport(passport);
setIsLoadingPassport(false);
};

Expand Down
8 changes: 1 addition & 7 deletions app/pages/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { UserContext } from "../context/userContext";
import { useViewerConnection } from "@self.id/framework";

export default function Dashboard() {
const { passport, isLoadingPassport, handleCreatePassport, wallet } = useContext(UserContext);
const { passport, wallet } = useContext(UserContext);

const { isOpen, onOpen, onClose } = useDisclosure();

Expand All @@ -30,12 +30,6 @@ export default function Dashboard() {
}
}, [wallet]);

useEffect(() => {
if (!passport && !isLoadingPassport) {
handleCreatePassport();
}
}, [passport, isLoadingPassport]);

return (
<>
<div className="flex w-full flex-col flex-wrap border-b-2 p-5 md:flex-row">
Expand Down
4 changes: 2 additions & 2 deletions database-client/integration-tests/ceramicDatabaseTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ describe("when there is an existing passport without stamps for the given did",
});

it("getPassport retrieves the passport from ceramic", async () => {
const actualPassport = await ceramicDatabase.getPassport();
const actualPassport = await ceramicDatabase.getPassport() as Passport;

expect(actualPassport).toBeDefined();
expect(actualPassport).toEqual(existingPassport);
Expand Down Expand Up @@ -195,7 +195,7 @@ describe("when there is an existing passport with stamps for the given did", ()
});

it("getPassport retrieves the passport and stamps from ceramic", async () => {
const actualPassport = await ceramicDatabase.getPassport();
const actualPassport = await ceramicDatabase.getPassport() as Passport;

const formattedDate = new Date(actualPassport["issuanceDate"]);
const todaysDate = new Date();
Expand Down
4 changes: 2 additions & 2 deletions database-client/src/ceramicClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,11 @@ export class CeramicDatabase implements DataStorageBase {
const stream = await this.store.set("Passport", { ...newPassport });
return stream.toUrl();
}
async getPassport(): Promise<Passport | undefined> {
async getPassport(): Promise<Passport | undefined | false> {
try {
const passport = await this.store.get("Passport");
console.info(`loaded passport for did ${this.did} => ${JSON.stringify(passport)}`);
if (!passport) return undefined;
if (!passport) return false;
// `stamps` is stored as ceramic URLs - must load actual VC data from URL
const stampsToLoad =
passport?.stamps.map(async (_stamp) => {
Expand Down
2 changes: 1 addition & 1 deletion database-client/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ import { Passport, Stamp, DID } from "@dpopp/types";
// calling createPassport, getPassport, addStamp
export abstract class DataStorageBase {
abstract createPassport(): Promise<DID>;
abstract getPassport(): Promise<Passport | undefined>;
abstract getPassport(): Promise<Passport | undefined | false>;
abstract addStamp(stamp: Stamp): Promise<void>;
}

0 comments on commit f7f1eca

Please sign in to comment.