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

OIDC: Validate m.authentication configuration #3419

Merged
merged 15 commits into from
Jun 11, 2023
Merged
Prev Previous commit
Next Next commit
make registration_endpoint optional
Kerry Archibald committed Jun 9, 2023
commit dc841e1466e43fc3fccbc8cb4f3d1cbe67ab81fe
13 changes: 11 additions & 2 deletions spec/unit/oidc/validate.spec.ts
Original file line number Diff line number Diff line change
@@ -119,7 +119,7 @@ describe("validateWellKnownAuthentication()", () => {
});

describe("validateOIDCIssuerWellKnown", () => {
const validWk = {
const validWk: any = {
authorization_endpoint: "https://test.org/authorize",
token_endpoint: "https://authorize.org/token",
registration_endpoint: "https://authorize.org/regsiter",
@@ -163,13 +163,22 @@ describe("validateOIDCIssuerWellKnown", () => {
});
});

it("should return validated issuer config without registrationendpoint", () => {
const wk = { ...validWk };
delete wk.registration_endpoint;
expect(validateOIDCIssuerWellKnown(wk)).toEqual({
authorizationEndpoint: validWk.authorization_endpoint,
tokenEndpoint: validWk.token_endpoint,
registrationEndpoint: undefined,
});
});

type TestCase = [string, any];
it.each<TestCase>([
["authorization_endpoint", undefined],
["authorization_endpoint", { not: "a string" }],
["token_endpoint", undefined],
["token_endpoint", { not: "a string" }],
["registration_endpoint", undefined],
["registration_endpoint", { not: "a string" }],
["response_types_supported", undefined],
["response_types_supported", "not an array"],
13 changes: 10 additions & 3 deletions src/oidc/validate.ts
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ export enum OidcDiscoveryError {
export type ValidatedIssuerConfig = {
authorizationEndpoint: string;
tokenEndpoint: string;
registrationEndpoint: string;
registrationEndpoint?: string;
};

/**
@@ -60,7 +60,14 @@ export const validateWellKnownAuthentication = (wellKnown: IClientWellKnown): ID
const isRecord = (value: unknown): value is Record<string, unknown> =>
!!value && typeof value === "object" && !Array.isArray(value);
const requiredStringProperty = (wellKnown: Record<string, unknown>, key: string): boolean => {
if (!wellKnown[key] || typeof wellKnown[key] !== "string") {
if (!wellKnown[key] || !optionalStringProperty(wellKnown, key)) {
logger.error(`OIDC issuer configuration: ${key} is invalid`);
return false;
}
return true;
};
const optionalStringProperty = (wellKnown: Record<string, unknown>, key: string): boolean => {
if (!!wellKnown[key] && typeof wellKnown[key] !== "string") {
logger.error(`OIDC issuer configuration: ${key} is invalid`);
return false;
}
@@ -92,7 +99,7 @@ export const validateOIDCIssuerWellKnown = (wellKnown: unknown): ValidatedIssuer
const isInvalid = [
requiredStringProperty(wellKnown, "authorization_endpoint"),
requiredStringProperty(wellKnown, "token_endpoint"),
requiredStringProperty(wellKnown, "registration_endpoint"),
optionalStringProperty(wellKnown, "registration_endpoint"),
requiredArrayValue(wellKnown, "response_types_supported", "code"),
requiredArrayValue(wellKnown, "grant_types_supported", "authorization_code"),
requiredArrayValue(wellKnown, "code_challenge_methods_supported", "S256"),