Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions js/packages/react/src/__tests__/widgets.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,66 @@ describe("widgets", () => {
expect(flow.reset).not.toHaveBeenCalled();
});

it("request widget shows requirements state for identity attribute mismatches", async () => {
const flow = createFlow({
isError: true,
errorCode: IDKitErrorCodes.IdentityAttributesNotMatched,
});
useIDKitRequestMock.mockReturnValue(flow);

const onError = vi.fn();
const onOpenChange = vi.fn();

render(
<IDKitRequestWidget {...createRequestProps({ onError, onOpenChange })} />,
);

await waitFor(() => {
expect(onError).toHaveBeenCalledWith(
IDKitErrorCodes.IdentityAttributesNotMatched,
);
});
expect(screen.getByText("Verification requirements not met")).toBeDefined();
expect(
screen.getByText(
"Your World ID doesn't meet the requirements for this verification.",
),
).toBeDefined();

fireEvent.click(screen.getByRole("button", { name: "Close" }));
expect(onOpenChange).toHaveBeenCalledWith(false);
expect(flow.reset).not.toHaveBeenCalled();
});

it("request widget shows terminal state for user presence failures", async () => {
const flow = createFlow({
isError: true,
errorCode: IDKitErrorCodes.UserPresenceFailed,
});
useIDKitRequestMock.mockReturnValue(flow);

const onError = vi.fn();
const onOpenChange = vi.fn();

render(
<IDKitRequestWidget {...createRequestProps({ onError, onOpenChange })} />,
);

await waitFor(() => {
expect(onError).toHaveBeenCalledWith(IDKitErrorCodes.UserPresenceFailed);
});
expect(screen.getByText("Presence check failed")).toBeDefined();
expect(
screen.getByText(
"World App couldn't confirm your presence for this request.",
),
).toBeDefined();

fireEvent.click(screen.getByRole("button", { name: "Close" }));
expect(onOpenChange).toHaveBeenCalledWith(false);
expect(flow.reset).not.toHaveBeenCalled();
});

it("request widget waits for handleVerify to resolve before calling onSuccess", async () => {
const flow = createFlow({
isSuccess: true,
Expand Down
21 changes: 21 additions & 0 deletions js/packages/react/src/components/States/ErrorState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@ type ErrorVariant =
| "configuration_error"
| "connection"
| "host_verification"
| "identity_attributes_not_matched"
| "user_presence_failed"
| "generic";

const errorCodeVariants: Partial<Record<IDKitErrorCodes, ErrorVariant>> = {
[IDKitErrorCodes.UserRejected]: "cancelled",
[IDKitErrorCodes.VerificationRejected]: "cancelled",
[IDKitErrorCodes.Cancelled]: "cancelled",
[IDKitErrorCodes.UserPresenceFailed]: "user_presence_failed",
[IDKitErrorCodes.ConnectionFailed]: "connection",
[IDKitErrorCodes.FailedByHostApp]: "host_verification",
[IDKitErrorCodes.InvalidRpSignature]: "configuration_error",
Expand All @@ -33,6 +36,8 @@ const errorCodeVariants: Partial<Record<IDKitErrorCodes, ErrorVariant>> = {
[IDKitErrorCodes.TimestampTooFarInFuture]: "configuration_error",
[IDKitErrorCodes.InvalidTimestamp]: "configuration_error",
[IDKitErrorCodes.RpSignatureExpired]: "configuration_error",
[IDKitErrorCodes.IdentityAttributesNotMatched]:
"identity_attributes_not_matched",
[IDKitErrorCodes.InvalidRpIdFormat]: "configuration_error",
};

Expand Down Expand Up @@ -74,6 +79,22 @@ const variantConfig = {
actionLabel: "Try Again" as const,
action: "retry" as const,
},
identity_attributes_not_matched: {
title: "Verification requirements not met" as const,
message:
"Your World ID doesn't meet the requirements for this verification." as const,
Icon: WarningIcon,
actionLabel: "Close" as const,
action: "close" as const,
},
user_presence_failed: {
title: "Presence check failed" as const,
message:
"World App couldn't confirm your presence for this request." as const,
Icon: WarningIcon,
actionLabel: "Close" as const,
action: "close" as const,
},
generic: {
title: "Something went wrong" as const,
message: "We couldn't complete your request. Please try again." as const,
Expand Down
6 changes: 6 additions & 0 deletions js/packages/react/src/lang/translations/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ export const en: TranslationStrings = {
"Verification declined": "Verification declined",
"Failed to verify your credential proof. Please contact the website owner.":
"Failed to verify your credential proof. Please contact the website owner.",
"Verification requirements not met": "Verification requirements not met",
"Your World ID doesn't meet the requirements for this verification.":
"Your World ID doesn't meet the requirements for this verification.",
"Presence check failed": "Presence check failed",
"World App couldn't confirm your presence for this request.":
"World App couldn't confirm your presence for this request.",
"We couldn't complete your request. Please try again.":
"We couldn't complete your request. Please try again.",
"Try Again": "Try Again",
Expand Down
7 changes: 7 additions & 0 deletions js/packages/react/src/lang/translations/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ export const es: TranslationStrings = {
"Verification declined": "Verificaci\u00f3n rechazada",
"Failed to verify your credential proof. Please contact the website owner.":
"No se pudo verificar tu prueba de credencial. Por favor contacta al propietario del sitio web.",
"Verification requirements not met":
"No se cumplen los requisitos de verificacion",
"Your World ID doesn't meet the requirements for this verification.":
"Tu World ID no cumple los requisitos para esta verificacion.",
"Presence check failed": "Fallo la comprobacion de presencia",
"World App couldn't confirm your presence for this request.":
"World App no pudo confirmar tu presencia para esta solicitud.",
"We couldn't complete your request. Please try again.":
"No pudimos completar tu solicitud. Por favor intenta de nuevo.",
"Try Again": "Intentar de nuevo",
Expand Down
8 changes: 8 additions & 0 deletions js/packages/react/src/lang/translations/th.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ export const th: TranslationStrings = {
"\u0e01\u0e32\u0e23\u0e22\u0e37\u0e19\u0e22\u0e31\u0e19\u0e16\u0e39\u0e01\u0e1b\u0e0f\u0e34\u0e40\u0e2a\u0e18",
"Failed to verify your credential proof. Please contact the website owner.":
"\u0e44\u0e21\u0e48\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e22\u0e37\u0e19\u0e22\u0e31\u0e19\u0e2b\u0e25\u0e31\u0e01\u0e10\u0e32\u0e19\u0e02\u0e2d\u0e07 Credential \u0e44\u0e14\u0e49 \u0e42\u0e1b\u0e23\u0e14\u0e15\u0e34\u0e14\u0e15\u0e48\u0e2d\u0e40\u0e08\u0e49\u0e32\u0e02\u0e2d\u0e07\u0e40\u0e27\u0e47\u0e1a\u0e44\u0e0b\u0e15\u0e4c",
"Verification requirements not met":
"\u0e44\u0e21\u0e48\u0e40\u0e1b\u0e47\u0e19\u0e44\u0e1b\u0e15\u0e32\u0e21\u0e02\u0e49\u0e2d\u0e01\u0e33\u0e2b\u0e19\u0e14\u0e01\u0e32\u0e23\u0e22\u0e37\u0e19\u0e22\u0e31\u0e19",
"Your World ID doesn't meet the requirements for this verification.":
"World ID \u0e02\u0e2d\u0e07\u0e04\u0e38\u0e13\u0e44\u0e21\u0e48\u0e15\u0e23\u0e07\u0e15\u0e32\u0e21\u0e02\u0e49\u0e2d\u0e01\u0e33\u0e2b\u0e19\u0e14\u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a\u0e01\u0e32\u0e23\u0e22\u0e37\u0e19\u0e22\u0e31\u0e19\u0e19\u0e35\u0e49",
"Presence check failed":
"\u0e01\u0e32\u0e23\u0e15\u0e23\u0e27\u0e08\u0e2a\u0e2d\u0e1a\u0e01\u0e32\u0e23\u0e21\u0e35\u0e2d\u0e22\u0e39\u0e48\u0e25\u0e49\u0e21\u0e40\u0e2b\u0e25\u0e27",
"World App couldn't confirm your presence for this request.":
"World App \u0e44\u0e21\u0e48\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e22\u0e37\u0e19\u0e22\u0e31\u0e19\u0e01\u0e32\u0e23\u0e21\u0e35\u0e2d\u0e22\u0e39\u0e48\u0e02\u0e2d\u0e07\u0e04\u0e38\u0e13\u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a\u0e04\u0e33\u0e02\u0e2d\u0e19\u0e35\u0e49\u0e44\u0e14\u0e49",
"We couldn't complete your request. Please try again.":
"\u0e40\u0e23\u0e32\u0e44\u0e21\u0e48\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e14\u0e33\u0e40\u0e19\u0e34\u0e19\u0e01\u0e32\u0e23\u0e15\u0e32\u0e21\u0e04\u0e33\u0e02\u0e2d\u0e02\u0e2d\u0e07\u0e04\u0e38\u0e13\u0e44\u0e14\u0e49 \u0e01\u0e23\u0e38\u0e13\u0e32\u0e25\u0e2d\u0e07\u0e2d\u0e35\u0e01\u0e04\u0e23\u0e31\u0e49\u0e07",
"Try Again":
Expand Down
4 changes: 4 additions & 0 deletions js/packages/react/src/lang/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ export interface TranslationStrings {
"Please check your connection and try again.": string;
"Verification declined": string;
"Failed to verify your credential proof. Please contact the website owner.": string;
"Verification requirements not met": string;
"Your World ID doesn't meet the requirements for this verification.": string;
"Presence check failed": string;
"World App couldn't confirm your presence for this request.": string;
"We couldn't complete your request. Please try again.": string;
"Try Again": string;
Close: string;
Expand Down
Loading