mirror of
https://github.com/wassname/talk.git
synced 2026-08-05 13:30:26 +08:00
fix: documentation + moved discover into query
This commit is contained in:
@@ -6,9 +6,9 @@ import { URL } from "url";
|
||||
*/
|
||||
export interface DiscoveryConfiguration {
|
||||
issuer: string;
|
||||
authorizationURL?: string;
|
||||
authorizationURL: string;
|
||||
tokenURL?: string;
|
||||
jwksURI?: string;
|
||||
jwksURI: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -18,9 +18,9 @@ export interface DiscoveryConfiguration {
|
||||
*/
|
||||
interface DiscoveryRawConfiguration {
|
||||
issuer: string;
|
||||
authorization_endpoint?: string;
|
||||
authorization_endpoint: string;
|
||||
token_endpoint?: string;
|
||||
jwks_uri?: string;
|
||||
jwks_uri: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -29,7 +29,9 @@ interface DiscoveryRawConfiguration {
|
||||
* @param issuer the Issuer URL that should be used to determine the
|
||||
* configuration
|
||||
*/
|
||||
export async function discover(issuer: URL): Promise<DiscoveryConfiguration> {
|
||||
export async function discover(
|
||||
issuer: URL
|
||||
): Promise<DiscoveryConfiguration | null> {
|
||||
// Any provider MUST provide a .well-known url that is JSON parsable based
|
||||
// on the issuer: https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig
|
||||
const configurationURL =
|
||||
@@ -38,13 +40,23 @@ export async function discover(issuer: URL): Promise<DiscoveryConfiguration> {
|
||||
"/.well-known/openid-configuration";
|
||||
const res = await fetch(configurationURL);
|
||||
|
||||
// Parse the configuration
|
||||
const meta: DiscoveryRawConfiguration = await res.json();
|
||||
// Ensure that it responds correctly.
|
||||
if (res.status !== 200) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
issuer: meta.issuer,
|
||||
authorizationURL: meta.authorization_endpoint,
|
||||
tokenURL: meta.token_endpoint,
|
||||
jwksURI: meta.jwks_uri,
|
||||
};
|
||||
try {
|
||||
// Parse the configuration
|
||||
const meta: DiscoveryRawConfiguration = await res.json();
|
||||
|
||||
return {
|
||||
issuer: meta.issuer,
|
||||
authorizationURL: meta.authorization_endpoint,
|
||||
tokenURL: meta.token_endpoint,
|
||||
jwksURI: meta.jwks_uri,
|
||||
};
|
||||
} catch (err) {
|
||||
// TODO: log the error
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import DataLoader from "dataloader";
|
||||
|
||||
import TenantContext from "talk-server/graph/tenant/context";
|
||||
import { GQLDiscoveredOIDCConfiguration } from "talk-server/graph/tenant/schema/__generated__/types";
|
||||
import { discoverOIDCConfiguration } from "talk-server/services/tenant";
|
||||
|
||||
export default (ctx: TenantContext) => ({
|
||||
discoverOIDCConfiguration: new DataLoader<
|
||||
string,
|
||||
GQLDiscoveredOIDCConfiguration | null
|
||||
>(issuers =>
|
||||
Promise.all(issuers.map(issuer => discoverOIDCConfiguration(issuer)))
|
||||
),
|
||||
});
|
||||
@@ -1,9 +1,11 @@
|
||||
import Context from "talk-server/graph/tenant/context";
|
||||
import Assets from "./assets";
|
||||
import Auth from "./auth";
|
||||
import Comments from "./comments";
|
||||
import Users from "./users";
|
||||
|
||||
export default (ctx: Context) => ({
|
||||
Auth: Auth(ctx),
|
||||
Assets: Assets(ctx),
|
||||
Comments: Comments(ctx),
|
||||
Users: Users(ctx),
|
||||
|
||||
@@ -4,8 +4,6 @@ import TenantContext from "talk-server/graph/tenant/context";
|
||||
import {
|
||||
GQLCreateOIDCAuthIntegrationInput,
|
||||
GQLDeleteOIDCAuthIntegrationInput,
|
||||
GQLDiscoverOIDCConfigurationInput,
|
||||
GQLOIDCConfiguration,
|
||||
GQLSettingsInput,
|
||||
GQLUpdateOIDCAuthIntegrationInput,
|
||||
} from "talk-server/graph/tenant/schema/__generated__/types";
|
||||
@@ -13,7 +11,6 @@ import { Tenant } from "talk-server/models/tenant";
|
||||
import {
|
||||
createOIDCAuthIntegration,
|
||||
deleteOIDCAuthIntegration,
|
||||
discoverOIDCConfiguration,
|
||||
regenerateSSOKey,
|
||||
update,
|
||||
updateOIDCAuthIntegration,
|
||||
@@ -24,9 +21,6 @@ export default ({ mongo, redis, tenantCache, tenant }: TenantContext) => ({
|
||||
update(mongo, redis, tenantCache, tenant, omitBy(input, isNull)),
|
||||
regenerateSSOKey: (): Promise<Tenant | null> =>
|
||||
regenerateSSOKey(mongo, redis, tenantCache, tenant),
|
||||
discoverOIDCConfiguration: (
|
||||
input: GQLDiscoverOIDCConfigurationInput
|
||||
): Promise<GQLOIDCConfiguration> => discoverOIDCConfiguration(input.issuer),
|
||||
createOIDCAuthIntegration: (
|
||||
input: GQLCreateOIDCAuthIntegrationInput
|
||||
): Promise<Tenant | null> =>
|
||||
|
||||
@@ -51,10 +51,6 @@ const Mutation: GQLMutationTypeResolver<void> = {
|
||||
settings: await ctx.mutators.Settings.regenerateSSOKey(),
|
||||
clientMutationId: input.clientMutationId,
|
||||
}),
|
||||
discoverOIDCConfiguration: async (source, { input }, ctx) => ({
|
||||
configuration: await ctx.mutators.Settings.discoverOIDCConfiguration(input),
|
||||
clientMutationId: input.clientMutationId,
|
||||
}),
|
||||
createOIDCAuthIntegration: async (source, { input }, ctx) => ({
|
||||
settings: await ctx.mutators.Settings.createOIDCAuthIntegration(input),
|
||||
clientMutationId: input.clientMutationId,
|
||||
|
||||
@@ -6,6 +6,8 @@ const Query: GQLQueryTypeResolver<void> = {
|
||||
id ? ctx.loaders.Comments.comment.load(id) : null,
|
||||
settings: (source, args, ctx) => ctx.tenant,
|
||||
me: (source, args, ctx) => ctx.user,
|
||||
discoverOIDCConfiguration: (source, { issuer }, ctx) =>
|
||||
ctx.loaders.Auth.discoverOIDCConfiguration.load(issuer),
|
||||
};
|
||||
|
||||
export default Query;
|
||||
|
||||
@@ -312,6 +312,47 @@ type SSOAuthIntegration {
|
||||
## OIDCAuthIntegration
|
||||
##########################
|
||||
|
||||
"""
|
||||
DiscoveredOIDCConfiguration contains the discovered Provider Metadata as defined
|
||||
in:
|
||||
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
|
||||
|
||||
Discovery is not supported on all providers, and is described in the OpenID
|
||||
Connect Discovery 1.0 incorporating errata set 1:
|
||||
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig
|
||||
"""
|
||||
type DiscoveredOIDCConfiguration {
|
||||
"""
|
||||
issuer is defined as the `issuer` in:
|
||||
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
|
||||
"""
|
||||
issuer: String!
|
||||
|
||||
"""
|
||||
authorizationURL is defined as the `authorization_endpoint` in:
|
||||
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
|
||||
"""
|
||||
authorizationURL: String!
|
||||
|
||||
"""
|
||||
tokenURL is defined as the `token_endpoint` in:
|
||||
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
|
||||
"""
|
||||
tokenURL: String
|
||||
|
||||
"""
|
||||
jwksURI is defined as the `jwks_uri` in:
|
||||
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
|
||||
"""
|
||||
jwksURI: String!
|
||||
}
|
||||
|
||||
"""
|
||||
OIDCAuthIntegration provides a way to store Open ID Connect credentials. This
|
||||
will be used in the admin to provide staff logins for users.
|
||||
@@ -335,7 +376,9 @@ type OIDCAuthIntegration {
|
||||
targetFilter: AuthenticationTargetFilter
|
||||
|
||||
"""
|
||||
name is the label assigned to reference the provider of the OIDC integration.
|
||||
name is the label assigned to reference the provider of the OIDC integration,
|
||||
and will be used in situations where the name of the provider needs to be
|
||||
displayed, like the login button.
|
||||
"""
|
||||
name: String
|
||||
|
||||
@@ -346,11 +389,46 @@ type OIDCAuthIntegration {
|
||||
"""
|
||||
callbackURL: String!
|
||||
|
||||
"""
|
||||
clientID is the Client Identifier as defined in:
|
||||
|
||||
https://tools.ietf.org/html/rfc6749#section-2.2
|
||||
"""
|
||||
clientID: String! @auth(roles: [ADMIN])
|
||||
|
||||
"""
|
||||
clientSecret is the Client Secret as defined in:
|
||||
|
||||
https://tools.ietf.org/html/rfc6749#section-2.3.1
|
||||
"""
|
||||
clientSecret: String! @auth(roles: [ADMIN])
|
||||
|
||||
"""
|
||||
authorizationURL is defined as the `authorization_endpoint` in:
|
||||
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
|
||||
"""
|
||||
authorizationURL: String! @auth(roles: [ADMIN])
|
||||
|
||||
"""
|
||||
tokenURL is defined as the `token_endpoint` in:
|
||||
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
|
||||
"""
|
||||
tokenURL: String! @auth(roles: [ADMIN])
|
||||
|
||||
"""
|
||||
jwksURI is defined as the `jwks_uri` in:
|
||||
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
|
||||
"""
|
||||
jwksURI: String! @auth(roles: [ADMIN])
|
||||
|
||||
"""
|
||||
issuer is defined as the `issuer` in:
|
||||
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
|
||||
"""
|
||||
issuer: String! @auth(roles: [ADMIN])
|
||||
|
||||
"""
|
||||
@@ -1200,7 +1278,8 @@ type Query {
|
||||
asset(id: ID, url: String): Asset
|
||||
|
||||
"""
|
||||
me is the current logged in User.
|
||||
me is the current logged in User. If no user is currently logged in, it will
|
||||
return null.
|
||||
"""
|
||||
me: User
|
||||
|
||||
@@ -1208,6 +1287,18 @@ type Query {
|
||||
settings is the Settings for a given Tenant.
|
||||
"""
|
||||
settings: Settings!
|
||||
|
||||
"""
|
||||
discoverOIDCConfiguration will discover the OpenID Connect configuration based
|
||||
on the provided issuer. Discovery is not supported on all providers, and is
|
||||
described in the OpenID Connect Discovery 1.0 incorporating errata set 1:
|
||||
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig
|
||||
|
||||
If the provider does not support discovery, the response will be null.
|
||||
"""
|
||||
discoverOIDCConfiguration(issuer: String!): DiscoveredOIDCConfiguration
|
||||
@auth(roles: [ADMIN])
|
||||
}
|
||||
|
||||
################################################################################
|
||||
@@ -1365,34 +1456,6 @@ input SettingsSSOAuthIntegrationInput {
|
||||
displayNameEnable: Boolean
|
||||
}
|
||||
|
||||
# input SettingsOIDCAuthIntegrationInput {
|
||||
# enabled: Boolean
|
||||
|
||||
# """
|
||||
# targetFilter will restrict where the authentication integration should be
|
||||
# displayed. If the value of targetFilter is null, then the authentication
|
||||
# integration should be displayed in all targets.
|
||||
# """
|
||||
# targetFilter: SettingsAuthenticationTargetFilterInput
|
||||
|
||||
# """
|
||||
# name is the label assigned to reference the provider of the OIDC integration.
|
||||
# """
|
||||
# name: String
|
||||
# clientID: String
|
||||
# clientSecret: String
|
||||
# authorizationURL: String
|
||||
# tokenURL: String
|
||||
# jwksURI: String
|
||||
# issuer: String
|
||||
|
||||
# """
|
||||
# displayNameEnable when enabled, will allow Users to set and view their
|
||||
# displayName's.
|
||||
# """
|
||||
# displayNameEnable: Boolean
|
||||
# }
|
||||
|
||||
input SettingsGoogleAuthIntegrationInput {
|
||||
enabled: Boolean
|
||||
|
||||
@@ -1915,53 +1978,58 @@ type RegenerateSSOKeyPayload {
|
||||
clientMutationId: String!
|
||||
}
|
||||
|
||||
##################
|
||||
## discoverOIDCConfiguration
|
||||
##################
|
||||
|
||||
input DiscoverOIDCConfigurationInput {
|
||||
"""
|
||||
|
||||
"""
|
||||
issuer: String!
|
||||
|
||||
"""
|
||||
clientMutationId is required for Relay support.
|
||||
"""
|
||||
clientMutationId: String!
|
||||
}
|
||||
|
||||
type OIDCConfiguration {
|
||||
issuer: String!
|
||||
authorizationURL: String
|
||||
tokenURL: String
|
||||
jwksURI: String
|
||||
}
|
||||
|
||||
type DiscoverOIDCConfigurationPayload {
|
||||
"""
|
||||
configuration was the discovered configuration for the OpenID Connect server
|
||||
given the provided issuer.
|
||||
"""
|
||||
configuration: OIDCConfiguration
|
||||
|
||||
"""
|
||||
clientMutationId is required for Relay support.
|
||||
"""
|
||||
clientMutationId: String!
|
||||
}
|
||||
|
||||
##################
|
||||
# createOIDCAuthIntegration
|
||||
##################
|
||||
|
||||
input CreateOIDCAuthIntegrationConfigurationInput {
|
||||
"""
|
||||
name is the label assigned to reference the provider of the OIDC integration,
|
||||
and will be used in situations where the name of the provider needs to be
|
||||
displayed, like the login button.
|
||||
"""
|
||||
name: String!
|
||||
|
||||
"""
|
||||
clientID is the Client Identifier as defined in:
|
||||
|
||||
https://tools.ietf.org/html/rfc6749#section-2.2
|
||||
"""
|
||||
clientID: String!
|
||||
|
||||
"""
|
||||
clientSecret is the Client Secret as defined in:
|
||||
|
||||
https://tools.ietf.org/html/rfc6749#section-2.3.1
|
||||
"""
|
||||
clientSecret: String!
|
||||
|
||||
"""
|
||||
authorizationURL is defined as the `authorization_endpoint` in:
|
||||
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
|
||||
"""
|
||||
authorizationURL: String!
|
||||
|
||||
"""
|
||||
tokenURL is defined as the `token_endpoint` in:
|
||||
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
|
||||
"""
|
||||
tokenURL: String!
|
||||
|
||||
"""
|
||||
jwksURI is defined as the `jwks_uri` in:
|
||||
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
|
||||
"""
|
||||
jwksURI: String!
|
||||
|
||||
"""
|
||||
issuer is defined as the `issuer` in:
|
||||
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
|
||||
"""
|
||||
issuer: String!
|
||||
}
|
||||
|
||||
@@ -1994,13 +2062,65 @@ type CreateOIDCAuthIntegrationPayload {
|
||||
##################
|
||||
|
||||
input UpdateOIDCAuthIntegrationConfigurationInput {
|
||||
"""
|
||||
enabled, when true, allows the integration to be enabled.
|
||||
"""
|
||||
enabled: Boolean
|
||||
|
||||
"""
|
||||
targetFilter will restrict where the authentication integration should be
|
||||
displayed. If the value of targetFilter is null, then the authentication
|
||||
integration should be displayed in all targets.
|
||||
"""
|
||||
targetFilter: SettingsAuthenticationTargetFilterInput
|
||||
|
||||
"""
|
||||
name is the label assigned to reference the provider of the OIDC integration,
|
||||
and will be used in situations where the name of the provider needs to be
|
||||
displayed, like the login button.
|
||||
"""
|
||||
name: String
|
||||
|
||||
"""
|
||||
clientID is the Client Identifier as defined in:
|
||||
|
||||
https://tools.ietf.org/html/rfc6749#section-2.2
|
||||
"""
|
||||
clientID: String
|
||||
|
||||
"""
|
||||
clientSecret is the Client Secret as defined in:
|
||||
|
||||
https://tools.ietf.org/html/rfc6749#section-2.3.1
|
||||
"""
|
||||
clientSecret: String
|
||||
|
||||
"""
|
||||
authorizationURL is defined as the `authorization_endpoint` in:
|
||||
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
|
||||
"""
|
||||
authorizationURL: String
|
||||
|
||||
"""
|
||||
tokenURL is defined as the `token_endpoint` in:
|
||||
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
|
||||
"""
|
||||
tokenURL: String
|
||||
|
||||
"""
|
||||
jwksURI is defined as the `jwks_uri` in:
|
||||
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
|
||||
"""
|
||||
jwksURI: String
|
||||
|
||||
"""
|
||||
issuer is defined as the `issuer` in:
|
||||
|
||||
https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
|
||||
"""
|
||||
issuer: String
|
||||
}
|
||||
|
||||
@@ -2091,14 +2211,6 @@ type Mutation {
|
||||
regenerateSSOKey(input: RegenerateSSOKeyInput!): RegenerateSSOKeyPayload
|
||||
@auth(roles: [ADMIN])
|
||||
|
||||
"""
|
||||
discoverOIDCConfiguration will discover the OpenID Connect configuration based
|
||||
on the provided input.
|
||||
"""
|
||||
discoverOIDCConfiguration(
|
||||
input: DiscoverOIDCConfigurationInput!
|
||||
): DiscoverOIDCConfigurationPayload @auth(roles: [ADMIN])
|
||||
|
||||
"""
|
||||
createOIDCAuthIntegration will create a OpenID Connect auth integration.
|
||||
"""
|
||||
|
||||
@@ -293,7 +293,7 @@ export async function updateTenantOIDCAuthIntegration(
|
||||
// $set: dotize({
|
||||
// "auth.integrations.oidc.$[oidc]": input,
|
||||
// }),
|
||||
// FIXME: replace with the above one once the types are updated.
|
||||
// FIXME: uncomment when https://github.com/DefinitelyTyped/DefinitelyTyped/pull/29986 gets merged
|
||||
$set: dotize({
|
||||
"auth.integrations.oidc.$[]": input,
|
||||
}),
|
||||
@@ -301,7 +301,7 @@ export async function updateTenantOIDCAuthIntegration(
|
||||
{
|
||||
// Add an ArrayFilter to only update one of the OpenID Connect
|
||||
// integrations.
|
||||
// arrayFilters: [{ "oidc.id": oidcID }], // FIXME: add back when we got the mongo fixes in place
|
||||
// arrayFilters: [{ "oidc.id": oidcID }], // FIXME: uncomment when https://github.com/DefinitelyTyped/DefinitelyTyped/pull/29986 gets merged
|
||||
// False to return the updated document instead of the original
|
||||
// document.
|
||||
returnOriginal: false,
|
||||
|
||||
Reference in New Issue
Block a user