Skip to content

Commit

Permalink
feat(core,schemas): update consent info
Browse files Browse the repository at this point in the history
  • Loading branch information
wangsijie committed May 9, 2024
1 parent 726a65d commit eb99031
Show file tree
Hide file tree
Showing 10 changed files with 438 additions and 181 deletions.
31 changes: 14 additions & 17 deletions packages/core/src/libraries/session.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ describe('consent', () => {

it('should update with new grantId if not exist', async () => {
const provider = createMockProvider(jest.fn().mockResolvedValue(baseInteractionDetails), Grant);
await consent(context, provider, queries, baseInteractionDetails);
await consent({ ctx: context, provider, queries, interactionDetails: baseInteractionDetails });

expect(grantSave).toHaveBeenCalled();

Expand All @@ -85,7 +85,7 @@ describe('consent', () => {

const provider = createMockProvider(jest.fn().mockResolvedValue(interactionDetails), Grant);

await consent(context, provider, queries, interactionDetails);
await consent({ ctx: context, provider, queries, interactionDetails });

expect(grantSave).toHaveBeenCalled();

Expand All @@ -109,29 +109,26 @@ describe('consent', () => {
}));

const provider = createMockProvider(jest.fn().mockResolvedValue(baseInteractionDetails), Grant);
await consent(context, provider, queries, baseInteractionDetails);
await consent({ ctx: context, provider, queries, interactionDetails: baseInteractionDetails });

expect(userQueries.updateUserById).toHaveBeenCalledWith(mockUser.id, {
applicationId: baseInteractionDetails.params.client_id,
});
});

it('should grant missing scopes', async () => {
const interactionDetails = {
...baseInteractionDetails,
prompt: {
details: {
missingOIDCScope: ['openid', 'profile'],
missingResourceScopes: {
resource1: ['resource1_scope1', 'resource1_scope2'],
resource2: ['resource2_scope1'],
},
},
const provider = createMockProvider(jest.fn().mockResolvedValue(baseInteractionDetails), Grant);
await consent({
ctx: context,
provider,
queries,
interactionDetails: baseInteractionDetails,
missingOIDCScopes: ['openid', 'profile'],
resourceScopesToGrant: {
resource1: ['resource1_scope1', 'resource1_scope2'],
resource2: ['resource2_scope1'],
},
} as unknown as Interaction;

const provider = createMockProvider(jest.fn().mockResolvedValue(interactionDetails), Grant);
await consent(context, provider, queries, interactionDetails);
});

expect(grantAddOIDCScope).toHaveBeenCalledWith('openid profile');
expect(grantAddResourceScope).toHaveBeenCalledWith(
Expand Down
40 changes: 25 additions & 15 deletions packages/core/src/libraries/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,27 @@ export const getMissingScopes = (prompt: PromptDetail) => {
return missingScopesGuard.parse(prompt.details);
};

export const consent = async (
ctx: Context,
provider: Provider,
queries: Queries,
interactionDetails: Awaited<ReturnType<Provider['interactionDetails']>>
) => {
export const consent = async ({
ctx,
provider,
queries,
interactionDetails,
missingOIDCScopes = [],
resourceScopesToGrant = {},
resourceScopesToReject = {},
}: {
ctx: Context;
provider: Provider;
queries: Queries;
interactionDetails: Awaited<ReturnType<Provider['interactionDetails']>>;
missingOIDCScopes?: string[];
resourceScopesToGrant?: Record<string, string[]>;
resourceScopesToReject?: Record<string, string[]>;
}) => {
const {
session,
grantId,
params: { client_id },
prompt,
} = interactionDetails;

assertThat(session, 'session.not_found');
Expand All @@ -91,17 +101,17 @@ export const consent = async (

await saveUserFirstConsentedAppId(queries, accountId, String(client_id));

const { missingOIDCScope, missingResourceScopes } = getMissingScopes(prompt);

// Fulfill missing scopes
if (missingOIDCScope) {
grant.addOIDCScope(missingOIDCScope.join(' '));
if (missingOIDCScopes.length > 0) {
grant.addOIDCScope(missingOIDCScopes.join(' '));
}

if (missingResourceScopes) {
for (const [indicator, scope] of Object.entries(missingResourceScopes)) {
grant.addResourceScope(indicator, scope.join(' '));
}
for (const [indicator, scope] of Object.entries(resourceScopesToGrant)) {
grant.addResourceScope(indicator, scope.join(' '));
}

for (const [indicator, scope] of Object.entries(resourceScopesToReject)) {
grant.rejectResourceScope(indicator, scope.join(' '));

Check warning on line 114 in packages/core/src/libraries/session.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/libraries/session.ts#L114

Added line #L114 was not covered by tests
}

const finalGrantId = await grant.save();
Expand Down
19 changes: 16 additions & 3 deletions packages/core/src/middleware/koa-auto-consent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { type IRouterParamContext } from 'koa-router';
import type Provider from 'oidc-provider';
import { errors } from 'oidc-provider';

import { consent } from '#src/libraries/session.js';
import { consent, getMissingScopes } from '#src/libraries/session.js';
import type Queries from '#src/tenants/Queries.js';
import assertThat from '#src/utils/assert-that.js';

Expand All @@ -18,7 +18,10 @@ export default function koaAutoConsent<StateT, ContextT extends IRouterParamCont
): MiddlewareType<StateT, ContextT, ResponseBodyT> {
return async (ctx, next) => {
const interactionDetails = await provider.interactionDetails(ctx.req, ctx.res);
const { client_id: clientId } = interactionDetails.params;
const {
params: { client_id: clientId },
prompt,
} = interactionDetails;

Check warning on line 24 in packages/core/src/middleware/koa-auto-consent.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/middleware/koa-auto-consent.ts#L21-L24

Added lines #L21 - L24 were not covered by tests

const {
applications: { findApplicationById },
Expand All @@ -36,7 +39,17 @@ export default function koaAutoConsent<StateT, ContextT extends IRouterParamCont
const shouldAutoConsent = !application?.isThirdParty;

if (shouldAutoConsent) {
const redirectTo = await consent(ctx, provider, query, interactionDetails);
const { missingOIDCScope: missingOIDCScopes, missingResourceScopes: resourceScopesToGrant } =
getMissingScopes(prompt);

const redirectTo = await consent({
ctx,
provider,
queries: query,
interactionDetails,
missingOIDCScopes,
resourceScopesToGrant,
});

Check warning on line 52 in packages/core/src/middleware/koa-auto-consent.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/middleware/koa-auto-consent.ts#L42-L52

Added lines #L42 - L52 were not covered by tests

ctx.redirect(redirectTo);
return;
Expand Down
Loading

0 comments on commit eb99031

Please sign in to comment.