Skip to content

Commit

Permalink
update permission helper
Browse files Browse the repository at this point in the history
  • Loading branch information
LiranCohen committed Aug 26, 2024
1 parent 5544fa1 commit afc4ec3
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 47 deletions.
27 changes: 4 additions & 23 deletions examples/wallet-connect.html
Original file line number Diff line number Diff line change
Expand Up @@ -128,35 +128,16 @@ <h1>Success</h1>
},
};

const scopes = [
{
interface: "Records",
method: "Write",
protocol: "http://profile-protocol.xyz",
},
{
interface: "Records",
method: "Query",
protocol: "http://profile-protocol.xyz",
},
{
interface: "Records",
method: "Read",
protocol: "http://profile-protocol.xyz",
},
];
const permissionRequests = Web5.requestPermissions([{
definition: profileProtocol,
}]);

try {
const { delegateDid } = await Web5.connect({
walletConnectOptions: {
walletUri: "web5://connect",
connectServerUrl: "http://localhost:3000/connect",
permissionRequests: [
{
protocolDefinition: profileProtocol,
permissionScopes: scopes,
},
],
permissionRequests: permissionRequests,
onWalletUriReady: generateQRCode,
validatePin: async () => {
goToPinScreen();
Expand Down
16 changes: 9 additions & 7 deletions packages/agent/src/connect.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { CryptoUtils } from '@web5/crypto';
import { DwnPermissionScope, DwnProtocolDefinition, DwnRecordsPermissionScope } from './index.js';

import type { PushedAuthResponse } from './oidc.js';
import type { DwnPermissionScope, DwnProtocolDefinition, Web5ConnectAuthResponse } from './index.js';

import {
Web5ConnectAuthResponse,
Oidc,
type PushedAuthResponse,
} from './oidc.js';
import { pollWithTtl } from './utils.js';
import { DidJwk } from '@web5/dids';

import { Convert } from '@web5/common';
import { CryptoUtils } from '@web5/crypto';
import { DidJwk } from '@web5/dids';
import { DwnInterfaceName, DwnMethodName } from '@tbd54566975/dwn-sdk-js';

/**
Expand Down Expand Up @@ -183,9 +185,9 @@ export type ConnectPermissionRequest = {
permissionScopes: DwnPermissionScope[];
};

export type PermissionRequest = 'write' | 'read' | 'delete' | 'query' | 'subscribe';
export type Permission = 'write' | 'read' | 'delete' | 'query' | 'subscribe';

function requestPermissionsForProtocol(definition: DwnProtocolDefinition, permissions: PermissionRequest[]): ConnectPermissionRequest {
function requestPermissionsForProtocol(definition: DwnProtocolDefinition, permissions: Permission[]): ConnectPermissionRequest {
const requests: DwnPermissionScope[] = [];

// In order to enable sync, we must request permissions for `MessagesQuery`, `MessagesRead` and `MessagesSubscribe`
Expand Down
28 changes: 13 additions & 15 deletions packages/agent/src/oidc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ import { concatenateUrl } from './utils.js';
import { xchacha20poly1305 } from '@noble/ciphers/chacha';
import type { ConnectPermissionRequest } from './connect.js';
import { DidDocument, DidJwk, PortableDid, type BearerDid } from '@web5/dids';
import { AgentDwnApi } from './dwn-api.js';
import type {
PermissionScope,
RecordsWriteMessage,
} from '@tbd54566975/dwn-sdk-js';
import { DwnInterface, DwnProtocolDefinition } from './types/dwn.js';
import { AgentPermissionsApi } from './permissions-api.js';
import type { Web5Agent } from './types/agent.js';

/**
* Sent to an OIDC server to authorize a client. Allows clients
Expand Down Expand Up @@ -614,11 +614,11 @@ function encryptAuthResponse({
async function createPermissionGrants(
selectedDid: string,
delegateBearerDid: BearerDid,
dwn: AgentDwnApi,
agent: Web5Agent,
scopes: PermissionScope[],
) {

const permissionsApi = new AgentPermissionsApi(dwn);
const permissionsApi = new AgentPermissionsApi({ agent });

// TODO: cleanup all grants if one fails by deleting them from the DWN: https://github.com/TBD54566975/web5-js/issues/849
const permissionGrants = await Promise.all(
Expand All @@ -638,19 +638,17 @@ async function createPermissionGrants(
const { encodedData, ...rawMessage } = grant.message;

const data = Convert.base64Url(encodedData).toUint8Array();
const params = {
const { reply } = await agent.sendDwnRequest({
author : selectedDid,
target : selectedDid,
messageType : DwnInterface.RecordsWrite,
dataStream : new Blob([data]),
rawMessage,
};

const sent = await dwn.sendRequest(params);
});

if (sent.reply.status.code !== 202) {
if (reply.status.code !== 202) {
throw new Error(
`Could not send the message. Error details: ${sent.reply.status.detail}`
`Could not send the message. Error details: ${reply.status.detail}`

Check warning on line 651 in packages/agent/src/oidc.ts

View check run for this annotation

Codecov / codecov/patch

packages/agent/src/oidc.ts#L651

Added line #L651 was not covered by tests
);
}

Expand All @@ -668,18 +666,18 @@ async function createPermissionGrants(
*/
async function prepareProtocols(
selectedDid: string,
agentDwnApi: AgentDwnApi,
agent: Web5Agent,
protocolDefinition: DwnProtocolDefinition
) {
const queryMessage = await agentDwnApi.processRequest({
const queryMessage = await agent.processDwnRequest({
author : selectedDid,
messageType : DwnInterface.ProtocolsQuery,
target : selectedDid,
messageParams : { filter: { protocol: protocolDefinition.protocol } },
});

if (queryMessage.reply.status.code === 404) {
const configureMessage = await agentDwnApi.processRequest({
const configureMessage = await agent.processDwnRequest({

Check warning on line 680 in packages/agent/src/oidc.ts

View check run for this annotation

Codecov / codecov/patch

packages/agent/src/oidc.ts#L680

Added line #L680 was not covered by tests
author : selectedDid,
messageType : DwnInterface.ProtocolsConfigure,
target : selectedDid,
Expand Down Expand Up @@ -707,7 +705,7 @@ async function submitAuthResponse(
selectedDid: string,
authRequest: Web5ConnectAuthRequest,
randomPin: string,
agentDwnApi: AgentDwnApi,
agent: Web5Agent,
) {
const delegateBearerDid = await DidJwk.create();
const delegatePortableDid = await delegateBearerDid.export();
Expand All @@ -716,8 +714,8 @@ async function submitAuthResponse(
// TODO: validate to make sure the scopes and definition are assigned to the same protocol
const { protocolDefinition, permissionScopes } = permissionRequest;

await prepareProtocols(selectedDid, agentDwnApi, protocolDefinition);
const permissionGrants = await Oidc.createPermissionGrants(selectedDid, delegateBearerDid, agentDwnApi, permissionScopes);
await prepareProtocols(selectedDid, agent, protocolDefinition);
const permissionGrants = await Oidc.createPermissionGrants(selectedDid, delegateBearerDid, agent, permissionScopes);

return permissionGrants;
});
Expand Down
4 changes: 2 additions & 2 deletions packages/agent/tests/connect.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ describe('web5 connect', function () {
const results = await Oidc.createPermissionGrants(
providerIdentity.did.uri,
delegateBearerDid,
testHarness.agent.dwn,
testHarness.agent,
permissionScopes
);
const scopesRequestedPlusTwoDefaultScopes = permissionScopes.length;
Expand Down Expand Up @@ -390,7 +390,7 @@ describe('web5 connect', function () {
selectedDid,
authRequest,
randomPin,
testHarness.agent.dwn
testHarness.agent
);
expect(fetchSpy.calledOnce).to.be.true;
});
Expand Down
13 changes: 13 additions & 0 deletions packages/api/src/web5.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@

import type {
BearerIdentity,
ConnectPermissionRequest,
DelegateGrant,
DwnDataEncodedRecordsWriteMessage,
DwnMessagesPermissionScope,
DwnProtocolDefinition,
DwnRecordsPermissionScope,
HdIdentityVault,
Permission,
WalletConnectOptions,
Web5Agent,
} from '@web5/agent';
Expand Down Expand Up @@ -480,4 +483,14 @@ export class Web5 {
// we expect that any connected protocols will include MessagesQuery and MessagesRead grants that will allow it to sync
return [...connectedProtocols];
}

/**
* Creates a connect permissions request for specific protocols.
* If no permissions are explicitly provided, the default is all permissions ('read', 'write', 'delete', 'query', 'subscribe').
*/
static requestPermissions(requests: { definition: DwnProtocolDefinition, permissions?: Permission[] }[]): ConnectPermissionRequest[] {
return requests.map(({ definition, permissions }) => WalletConnect.requestPermissionsForProtocol(definition, permissions ?? [
'read', 'write', 'delete', 'query', 'subscribe'
]));
}

Check warning on line 495 in packages/api/src/web5.ts

View check run for this annotation

Codecov / codecov/patch

packages/api/src/web5.ts#L492-L495

Added lines #L492 - L495 were not covered by tests
}

0 comments on commit afc4ec3

Please sign in to comment.