Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Simplify Connect Auth Response #951

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
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
8 changes: 8 additions & 0 deletions .changeset/tidy-ladybugs-lick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@web5/agent": minor
"@web5/identity-agent": minor
"@web5/proxy-agent": minor
"@web5/user-agent": minor
---

Break apart OIDC `submitAuthResponse`
67 changes: 40 additions & 27 deletions packages/agent/src/oidc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,7 @@ function shouldUseDelegatePermission(scope: DwnPermissionScope): boolean {
*/
async function createPermissionGrants(
selectedDid: string,
delegateBearerDid: BearerDid,
delegatedPortableDid: PortableDid,
agent: Web5Agent,
scopes: DwnPermissionScope[],
) {
Expand All @@ -639,7 +639,7 @@ async function createPermissionGrants(
return permissionsApi.createGrant({
delegated,
store : true,
grantedTo : delegateBearerDid.uri,
grantedTo : delegatedPortableDid.uri,
scope,
dateExpires : '2040-06-25T16:09:16.693356Z', // TODO: make dateExpires optional
author : selectedDid,
Expand Down Expand Up @@ -745,6 +745,36 @@ async function prepareProtocol(
}
}

async function createAuthResponseGrants(
delegatedPortableDid: PortableDid,
selectedDid: string,
permissionRequests: ConnectPermissionRequest[],
agent: Web5Agent
) {
// TODO: roll back permissions and protocol configurations if an error occurs. Need a way to delete protocols to achieve this.
const processGrant = async (permissionRequest: ConnectPermissionRequest): Promise<DwnDataEncodedRecordsWriteMessage[]> => {
const { protocolDefinition, permissionScopes } = permissionRequest;

// We validate that all permission scopes match the protocol uri of the protocol definition they are provided with.
const grantsMatchProtocolUri = permissionScopes.every(scope => 'protocol' in scope && scope.protocol === protocolDefinition.protocol);
if (!grantsMatchProtocolUri) {
throw new Error('All permission scopes must match the protocol uri they are provided with.');
}

await prepareProtocol(selectedDid, agent, protocolDefinition);

return await Oidc.createPermissionGrants(
selectedDid,
delegatedPortableDid,
agent,
permissionScopes
);
};

const delegateGrants = await Promise.all(permissionRequests.map(processGrant));
return delegateGrants .flat();
}

/**
* Creates a delegate did which the web app will use as its future indentity.
* Assigns to that DID the level of permissions that the web app requested in
Expand All @@ -758,37 +788,19 @@ async function submitAuthResponse(
selectedDid: string,
authRequest: Web5ConnectAuthRequest,
randomPin: string,
agent: Web5Agent
agent: Web5Agent,
) {
const delegateBearerDid = await DidJwk.create();
const delegatePortableDid = await delegateBearerDid.export();

// TODO: roll back permissions and protocol configurations if an error occurs. Need a way to delete protocols to achieve this.
const delegateGrantPromises = authRequest.permissionRequests.map(
async (permissionRequest) => {
const { protocolDefinition, permissionScopes } = permissionRequest;

// We validate that all permission scopes match the protocol uri of the protocol definition they are provided with.
const grantsMatchProtocolUri = permissionScopes.every(scope => 'protocol' in scope && scope.protocol === protocolDefinition.protocol);
if (!grantsMatchProtocolUri) {
throw new Error('All permission scopes must match the protocol uri they are provided with.');
}

await prepareProtocol(selectedDid, agent, protocolDefinition);

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

return permissionGrants;
}
// Create the permission grants for the selected DID.
const delegateGrants = await Oidc.createAuthResponseGrants(
delegatePortableDid,
selectedDid,
authRequest.permissionRequests,
agent
);

const delegateGrants = (await Promise.all(delegateGrantPromises)).flat();

logger.log('Generating auth response object...');
const responseObject = await Oidc.createResponseObject({
//* the IDP's did that was selected to be connected
Expand Down Expand Up @@ -853,5 +865,6 @@ export const Oidc = {
verifyJwt,
buildOidcUrl,
generateCodeChallenge,
createAuthResponseGrants,
submitAuthResponse,
};
Loading