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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"responsive:smoke": "node tests/responsive-smoke.mjs",
"unit:test": "vitest run tests/unit",
"scenario:test": "vitest run tests/scenarios/salty.test.ts tests/scenarios/randy.test.ts tests/scenarios/witnessed.test.ts tests/scenarios/challenge.test.ts tests/scenarios/controller-rotation.test.ts tests/scenarios/oobi-contacts.test.ts tests/scenarios/credentials.test.ts",
"delegation:test": "vitest run tests/scenarios/optional/delegation.test.ts",
"scenario:test:all": "vitest run tests/scenarios",
"test:ci": "pnpm lint && pnpm build && pnpm unit:test && pnpm responsive:smoke && pnpm keria:smoke -- --mode connect && pnpm keria:smoke && pnpm scenario:test && pnpm contact:ui-smoke && pnpm browser:smoke"
},
Expand Down
7 changes: 5 additions & 2 deletions src/app/PayloadDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export const PayloadDetails = ({
title={
detail.copyable
? `Copy ${detail.label}`
: detail.value
: (detail.displayValue ?? detail.value)
}
>
<Box
Expand Down Expand Up @@ -107,7 +107,10 @@ export const PayloadDetails = ({
minWidth: 0,
}}
>
{abbreviate(detail.value, maxLength)}
{abbreviate(
detail.displayValue ?? detail.value,
maxLength
)}
</Typography>
{detail.copyable && (
<ContentCopyIcon
Expand Down
8 changes: 7 additions & 1 deletion src/app/RootLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
selectActiveOperations,
selectActionableChallengeRequestNotifications,
selectActionableCredentialGrantNotifications,
selectActionableDelegationRequestNotifications,
selectAppNotifications,
selectIdentifiers,
selectUnreadAppNotifications,
Expand Down Expand Up @@ -52,6 +53,9 @@ const RootLayoutContent = () => {
const credentialGrants = useAppSelector(
selectActionableCredentialGrantNotifications
);
const delegationRequests = useAppSelector(
selectActionableDelegationRequestNotifications
);
const identifiers = useAppSelector(selectIdentifiers);
const connectDialogOpen = connectOpen && connection.status !== 'connected';
const pending = derivePendingState({
Expand All @@ -75,11 +79,13 @@ const RootLayoutContent = () => {
recentNotifications={appNotifications}
challengeRequests={challengeRequests}
credentialGrants={credentialGrants}
delegationRequests={delegationRequests}
identifiers={identifiers}
unreadNotificationCount={
unreadAppNotifications.length +
challengeRequests.length +
credentialGrants.length
credentialGrants.length +
delegationRequests.length
}
onMenuClick={() => setDrawerOpen(true)}
onConnectClick={() => setConnectOpen(true)}
Expand Down
234 changes: 225 additions & 9 deletions src/app/TopBar.tsx

Large diffs are not rendered by default.

87 changes: 86 additions & 1 deletion src/app/routeData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import type {
VerifyContactChallengeInput,
} from '../workflows/challenges.op';
import type { DismissExchangeNotificationInput } from '../workflows/notifications.op';
import type { ApproveDelegationInput } from '../workflows/delegations.op';
import type {
AdmitCredentialGrantInput,
CreateCredentialRegistryInput,
Expand Down Expand Up @@ -139,6 +140,7 @@ export type ContactActionData =
| 'respondChallenge'
| 'verifyChallenge'
| 'dismissExchangeNotification'
| 'approveDelegationRequest'
| 'delete'
| 'updateAlias';
ok: true;
Expand All @@ -162,6 +164,7 @@ export type ContactActionData =
| 'respondChallenge'
| 'verifyChallenge'
| 'dismissExchangeNotification'
| 'approveDelegationRequest'
| 'delete'
| 'updateAlias'
| 'unsupported';
Expand Down Expand Up @@ -321,6 +324,11 @@ export interface RouteDataRuntime {
input: DismissExchangeNotificationInput,
options?: { signal?: AbortSignal; requestId?: string }
): Promise<void>;
/** Start manual delegation approval in the background. */
startApproveDelegation(
input: ApproveDelegationInput,
options?: { requestId?: string }
): BackgroundWorkflowStartResult;
/** Start adding the SEDI credential schema type in the background. */
startResolveCredentialSchema(
input: ResolveCredentialSchemaInput,
Expand Down Expand Up @@ -391,6 +399,7 @@ const contactIntentFromString = (
value === 'respondChallenge' ||
value === 'verifyChallenge' ||
value === 'dismissExchangeNotification' ||
value === 'approveDelegationRequest' ||
value === 'delete' ||
value === 'updateAlias'
? value
Expand Down Expand Up @@ -1094,6 +1103,80 @@ export const contactsAction = async (
};
}

if (intent === 'approveDelegationRequest') {
const notificationId = formString(
formData,
'notificationId'
).trim();
const delegatorName = formString(formData, 'delegatorName').trim();
const delegatorAid = formString(formData, 'delegatorAid').trim();
const delegateAid = formString(formData, 'delegateAid').trim();
const delegateEventSaid = formString(
formData,
'delegateEventSaid'
).trim();
const sequence = formString(formData, 'sequence').trim();
const sourceAid = formString(formData, 'sourceAid').trim();
const createdAt = formString(formData, 'createdAt').trim();
if (
notificationId.length === 0 ||
delegatorName.length === 0 ||
delegatorAid.length === 0 ||
delegateAid.length === 0 ||
delegateEventSaid.length === 0 ||
sequence.length === 0 ||
createdAt.length === 0
) {
return {
intent,
ok: false,
message:
'Notification id, delegator, delegate event, sequence, and request time are required.',
requestId,
};
}

const started = runtime.startApproveDelegation(
{
notificationId,
delegatorName,
request: {
notificationId,
delegatorAid,
delegateAid,
delegateEventSaid,
sequence,
anchor: {
i: delegateAid,
s: sequence,
d: delegateEventSaid,
},
sourceAid: sourceAid.length > 0 ? sourceAid : null,
createdAt,
status: 'actionable',
},
},
{ requestId: requestId || undefined }
);
if (started.status === 'conflict') {
return {
intent,
ok: false,
message: started.message,
requestId: started.requestId,
operationRoute: started.operationRoute,
};
}

return {
intent,
ok: true,
message: `Approving delegation for ${delegateAid}`,
requestId: started.requestId,
operationRoute: started.operationRoute,
};
}

if (intent === 'delete') {
const contactId = formString(formData, 'contactId').trim();
if (contactId.length === 0) {
Expand Down Expand Up @@ -1215,7 +1298,9 @@ export const credentialsAction = async (
runtime.syncCredentialRegistries({ signal: request.signal }),
runtime.syncCredentialInventory({ signal: request.signal }),
]);
await runtime.syncCredentialIpexActivity({ signal: request.signal });
await runtime.syncCredentialIpexActivity({
signal: request.signal,
});
return {
intent,
ok: true,
Expand Down
Loading
Loading