mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
refactor(core): fix resource
parameter
This commit is contained in:
parent
d3e7cff0bd
commit
fcda26ac2f
6 changed files with 39 additions and 21 deletions
27
packages/core/src/oidc/grants/index.ts
Normal file
27
packages/core/src/oidc/grants/index.ts
Normal file
|
@ -0,0 +1,27 @@
|
|||
import { GrantType } from '@logto/schemas';
|
||||
import type Provider from 'oidc-provider';
|
||||
import instance from 'oidc-provider/lib/helpers/weak_cache.js';
|
||||
|
||||
import { type EnvSet } from '#src/env-set/index.js';
|
||||
import type Queries from '#src/tenants/Queries.js';
|
||||
|
||||
import * as refreshToken from './refresh-token.js';
|
||||
|
||||
export const registerGrants = (oidc: Provider, envSet: EnvSet, queries: Queries) => {
|
||||
const {
|
||||
features: { resourceIndicators },
|
||||
} = instance(oidc).configuration();
|
||||
|
||||
// If resource indicators are enabled, append `resource` to the parameters and allow it to
|
||||
// be duplicated
|
||||
const parameterConfig: [parameters: string[], duplicates: string[]] = resourceIndicators.enabled
|
||||
? [[...refreshToken.parameters, 'resource'], ['resource']]
|
||||
: [[...refreshToken.parameters], []];
|
||||
|
||||
// Override the default `refresh_token` grant
|
||||
oidc.registerGrantType(
|
||||
GrantType.RefreshToken,
|
||||
refreshToken.buildHandler(envSet, queries.organizations),
|
||||
...parameterConfig
|
||||
);
|
||||
};
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
|
||||
import { UserScope, buildOrganizationUrn } from '@logto/core-kit';
|
||||
import { type Optional, cond, isKeyInObject } from '@silverhand/essentials';
|
||||
import { type Optional, isKeyInObject, cond } from '@silverhand/essentials';
|
||||
import type Provider from 'oidc-provider';
|
||||
import { errors } from 'oidc-provider';
|
||||
import difference from 'oidc-provider/lib/helpers/_/difference.js';
|
||||
|
@ -53,7 +53,7 @@ const gty = 'refresh_token';
|
|||
|
||||
/**
|
||||
* The valid parameters for the `organization_token` grant type. Note the `resource` parameter is
|
||||
* handled by oidc-provider so we don't need to include it here.
|
||||
* not included here since it should be handled per configuration when registering the grant type.
|
||||
*/
|
||||
export const parameters = Object.freeze(['refresh_token', 'organization_id', 'scope'] as const);
|
||||
|
||||
|
@ -130,7 +130,9 @@ export const buildHandler: (
|
|||
}
|
||||
|
||||
/* === RFC 0001 === */
|
||||
if (params.organization_id) {
|
||||
// The params object may have the key with `undefined` value, so we have to use `Boolean` to check.
|
||||
const organizationId = cond(Boolean(params.organization_id) && String(params.organization_id));
|
||||
if (organizationId) {
|
||||
// Validate if the refresh token has the required scope from RFC 0001.
|
||||
if (!refreshToken.scopes.has(UserScope.Organizations)) {
|
||||
throw new InsufficientScope('refresh token missing required scope', UserScope.Organizations);
|
||||
|
@ -218,7 +220,6 @@ export const buildHandler: (
|
|||
|
||||
/* === RFC 0001 === */
|
||||
// Check membership
|
||||
const organizationId = cond(Boolean(params.organization_id) && String(params.organization_id));
|
||||
if (
|
||||
organizationId &&
|
||||
!(await queries.relations.users.exists(organizationId, account.accountId))
|
||||
|
|
|
@ -7,6 +7,6 @@ describe('oidc provider init', () => {
|
|||
it('init should not throw', async () => {
|
||||
const { queries, libraries } = new MockTenant();
|
||||
|
||||
expect(() => initOidc('mock_id', mockEnvSet, queries, libraries)).not.toThrow();
|
||||
expect(() => initOidc(mockEnvSet, queries, libraries)).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,7 +8,6 @@ import {
|
|||
customClientMetadataDefault,
|
||||
CustomClientMetadataKey,
|
||||
demoAppApplicationId,
|
||||
GrantType,
|
||||
inSeconds,
|
||||
logtoCookieKey,
|
||||
type LogtoUiCookie,
|
||||
|
@ -31,7 +30,7 @@ import type Libraries from '#src/tenants/Libraries.js';
|
|||
import type Queries from '#src/tenants/Queries.js';
|
||||
|
||||
import defaults from './defaults.js';
|
||||
import * as refreshToken from './grants/refresh-token.js';
|
||||
import { registerGrants } from './grants/index.js';
|
||||
import { findResource, findResourceScopes, getSharedResourceServerData } from './resource.js';
|
||||
import { getUserClaimData, getUserClaims } from './scope.js';
|
||||
import { OIDCExtraParametersKey, InteractionMode } from './type.js';
|
||||
|
@ -39,12 +38,7 @@ import { OIDCExtraParametersKey, InteractionMode } from './type.js';
|
|||
// Temporarily removed 'EdDSA' since it's not supported by browser yet
|
||||
const supportedSigningAlgs = Object.freeze(['RS256', 'PS256', 'ES256', 'ES384', 'ES512'] as const);
|
||||
|
||||
export default function initOidc(
|
||||
tenantId: string,
|
||||
envSet: EnvSet,
|
||||
queries: Queries,
|
||||
libraries: Libraries
|
||||
): Provider {
|
||||
export default function initOidc(envSet: EnvSet, queries: Queries, libraries: Libraries): Provider {
|
||||
const {
|
||||
resources: { findDefaultResource },
|
||||
users: { findUserById },
|
||||
|
@ -287,11 +281,7 @@ export default function initOidc(
|
|||
});
|
||||
|
||||
addOidcEventListeners(oidc, queries);
|
||||
|
||||
// Override the default `refresh_token` grant
|
||||
oidc.registerGrantType(GrantType.RefreshToken, refreshToken.buildHandler(envSet, organizations), [
|
||||
...refreshToken.parameters,
|
||||
]);
|
||||
registerGrants(oidc, envSet, queries);
|
||||
|
||||
// Provide audit log context for event listeners
|
||||
oidc.use(koaAuditLog(queries));
|
||||
|
|
|
@ -83,7 +83,7 @@ export default class Tenant implements TenantContext {
|
|||
app.use(koaSecurityHeaders(mountedApps, id));
|
||||
|
||||
// Mount OIDC
|
||||
const provider = initOidc(id, envSet, queries, libraries);
|
||||
const provider = initOidc(envSet, queries, libraries);
|
||||
app.use(mount('/oidc', provider.app));
|
||||
|
||||
const tenantContext: TenantContext = {
|
||||
|
|
|
@ -101,8 +101,8 @@ const App = () => {
|
|||
config={{
|
||||
endpoint: window.location.origin,
|
||||
appId: demoAppApplicationId,
|
||||
prompt: Prompt.Consent,
|
||||
// Use enum values once JS SDK is updated
|
||||
prompt: Prompt.Login,
|
||||
// TODO: Use enum values once JS SDK is updated
|
||||
scopes: ['urn:logto:scope:organizations', 'urn:logto:scope:organization_roles'],
|
||||
resources: ['urn:logto:resource:organizations'],
|
||||
}}
|
||||
|
|
Loading…
Reference in a new issue