From 8e3363a1d82940a53934737e02141382066afb94 Mon Sep 17 00:00:00 2001 From: Hasan Ozdemir <21654050+nodify-at@users.noreply.github.com> Date: Thu, 9 Dec 2021 11:46:36 +0100 Subject: [PATCH 1/5] export typescript types for OIDC provider Signed-off-by: Hasan Ozdemir <21654050+nodify-at@users.noreply.github.com> --- .../auth-backend/src/providers/oidc/index.ts | 7 ++- .../src/providers/oidc/provider.ts | 53 ++++++++++--------- 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/plugins/auth-backend/src/providers/oidc/index.ts b/plugins/auth-backend/src/providers/oidc/index.ts index 20d014a783..1d0f592359 100644 --- a/plugins/auth-backend/src/providers/oidc/index.ts +++ b/plugins/auth-backend/src/providers/oidc/index.ts @@ -13,5 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +export type { + OidcSignInResolver, + OidcAuthHandler, + OidcAuthResult, + OidcProviderOptions, +} from './provider'; export { createOidcProvider } from './provider'; diff --git a/plugins/auth-backend/src/providers/oidc/provider.ts b/plugins/auth-backend/src/providers/oidc/provider.ts index 158af6f830..b9ae15f370 100644 --- a/plugins/auth-backend/src/providers/oidc/provider.ts +++ b/plugins/auth-backend/src/providers/oidc/provider.ts @@ -56,18 +56,21 @@ type OidcImpl = { client: Client; }; -type AuthResult = { +export type OidcAuthResult = { tokenset: TokenSet; userinfo: UserinfoResponse; }; +export type OidcSignInResolver = SignInResolver; +export type OidcAuthHandler = AuthHandler; + export type Options = OAuthProviderOptions & { metadataUrl: string; scope?: string; prompt?: string; tokenSignedResponseAlg?: string; - signInResolver?: SignInResolver; - authHandler: AuthHandler; + signInResolver?: OidcSignInResolver; + authHandler: OidcAuthHandler; tokenIssuer: TokenIssuer; catalogIdentityClient: CatalogIdentityClient; logger: Logger; @@ -78,8 +81,8 @@ export class OidcAuthProvider implements OAuthHandlers { private readonly scope?: string; private readonly prompt?: string; - private readonly signInResolver?: SignInResolver; - private readonly authHandler: AuthHandler; + private readonly signInResolver?: SignInResolver; + private readonly authHandler: AuthHandler; private readonly tokenIssuer: TokenIssuer; private readonly catalogIdentityClient: CatalogIdentityClient; private readonly logger: Logger; @@ -113,7 +116,7 @@ export class OidcAuthProvider implements OAuthHandlers { ): Promise<{ response: OAuthResponse; refreshToken?: string }> { const { strategy } = await this.implementation; const strategyResponse = await executeFrameHandlerStrategy< - AuthResult, + OidcAuthResult, PrivateInfo >(req, strategy); const { @@ -158,7 +161,7 @@ export class OidcAuthProvider implements OAuthHandlers { ( tokenset: TokenSet, userinfo: UserinfoResponse, - done: PassportDoneCallback, + done: PassportDoneCallback, ) => { if (typeof done !== 'function') { throw new Error( @@ -180,7 +183,7 @@ export class OidcAuthProvider implements OAuthHandlers { // Use this function to grab the user profile info from the token // Then populate the profile with it - private async handleResult(result: AuthResult): Promise { + private async handleResult(result: OidcAuthResult): Promise { const { profile } = await this.authHandler(result); const response: OAuthResponse = { providerInfo: { @@ -210,27 +213,25 @@ export class OidcAuthProvider implements OAuthHandlers { } } -export const oAuth2DefaultSignInResolver: SignInResolver = async ( - info, - ctx, -) => { - const { profile } = info; +export const oAuth2DefaultSignInResolver: SignInResolver = + async (info, ctx) => { + const { profile } = info; - if (!profile.email) { - throw new Error('Profile contained no email'); - } - const userId = profile.email.split('@')[0]; - const token = await ctx.tokenIssuer.issueToken({ - claims: { sub: userId, ent: [`user:default/${userId}`] }, - }); - return { id: userId, token }; -}; + if (!profile.email) { + throw new Error('Profile contained no email'); + } + const userId = profile.email.split('@')[0]; + const token = await ctx.tokenIssuer.issueToken({ + claims: { sub: userId, ent: [`user:default/${userId}`] }, + }); + return { id: userId, token }; + }; export type OidcProviderOptions = { - authHandler?: AuthHandler; + authHandler?: AuthHandler; signIn?: { - resolver?: SignInResolver; + resolver?: SignInResolver; }; }; @@ -260,7 +261,7 @@ export const createOidcProvider = ( tokenIssuer, }); - const authHandler: AuthHandler = options?.authHandler + const authHandler: AuthHandler = options?.authHandler ? options.authHandler : async ({ userinfo }) => ({ profile: { @@ -271,7 +272,7 @@ export const createOidcProvider = ( }); const signInResolverFn = options?.signIn?.resolver ?? oAuth2DefaultSignInResolver; - const signInResolver: SignInResolver = info => + const signInResolver: SignInResolver = info => signInResolverFn(info, { catalogIdentityClient, tokenIssuer, From 699c2e9ddcd78a07811aae8c31008019a689ca25 Mon Sep 17 00:00:00 2001 From: Hasan Ozdemir <21654050+nodify-at@users.noreply.github.com> Date: Thu, 9 Dec 2021 12:33:18 +0100 Subject: [PATCH 2/5] added a changeset and generate api reports Signed-off-by: Hasan Ozdemir <21654050+nodify-at@users.noreply.github.com> --- .changeset/strong-paws-laugh.md | 5 +++++ plugins/auth-backend/api-report.md | 29 ++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 .changeset/strong-paws-laugh.md diff --git a/.changeset/strong-paws-laugh.md b/.changeset/strong-paws-laugh.md new file mode 100644 index 0000000000..de39440e34 --- /dev/null +++ b/.changeset/strong-paws-laugh.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend': patch +--- + +export minimal typescript types for OIDC provider diff --git a/plugins/auth-backend/api-report.md b/plugins/auth-backend/api-report.md index a637118130..ca212e0ad8 100644 --- a/plugins/auth-backend/api-report.md +++ b/plugins/auth-backend/api-report.md @@ -258,7 +258,6 @@ export const createOAuth2Provider: ( options?: OAuth2ProviderOptions | undefined, ) => AuthProviderFactory; -// Warning: (ae-forgotten-export) The symbol "OidcProviderOptions" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "createOidcProvider" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -534,6 +533,34 @@ export type OAuthState = { origin?: string; }; +// Warning: (ae-missing-release-tag) "OidcAuthHandler" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type OidcAuthHandler = AuthHandler; + +// Warning: (ae-missing-release-tag) "OidcAuthResult" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type OidcAuthResult = { + tokenset: TokenSet; + userinfo: UserinfoResponse; +}; + +// Warning: (ae-missing-release-tag) "OidcProviderOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type OidcProviderOptions = { + authHandler?: AuthHandler; + signIn?: { + resolver?: SignInResolver; + }; +}; + +// Warning: (ae-missing-release-tag) "OidcSignInResolver" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type OidcSignInResolver = SignInResolver; + // Warning: (ae-missing-release-tag) "oktaEmailSignInResolver" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) From abd6ff3430bfb55aab65a420310bb45c25c76658 Mon Sep 17 00:00:00 2001 From: Hasan Ozdemir <21654050+nodify-at@users.noreply.github.com> Date: Thu, 9 Dec 2021 21:32:31 +0100 Subject: [PATCH 3/5] improve exported type to include resolver and handlers for auth providers, add additional types to fix api-doc related warnings Signed-off-by: Hasan Ozdemir <21654050+nodify-at@users.noreply.github.com> --- plugins/auth-backend/api-report.md | 42 ++++++++++++------- plugins/auth-backend/src/providers/index.ts | 4 ++ .../auth-backend/src/providers/oidc/index.ts | 7 +--- .../src/providers/oidc/provider.ts | 19 ++++++--- plugins/auth-backend/src/providers/types.ts | 15 +++++++ 5 files changed, 62 insertions(+), 25 deletions(-) diff --git a/plugins/auth-backend/api-report.md b/plugins/auth-backend/api-report.md index ca212e0ad8..c076058a0c 100644 --- a/plugins/auth-backend/api-report.md +++ b/plugins/auth-backend/api-report.md @@ -47,6 +47,16 @@ export type AtlassianProviderOptions = { }; }; +// @public +export type AuthHandler = ( + input: AuthResult, +) => Promise; + +// @public +export type AuthHandlerResult = { + profile: ProfileInfo; +}; + // Warning: (ae-missing-release-tag) "AuthProviderFactory" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -533,11 +543,6 @@ export type OAuthState = { origin?: string; }; -// Warning: (ae-missing-release-tag) "OidcAuthHandler" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type OidcAuthHandler = AuthHandler; - // Warning: (ae-missing-release-tag) "OidcAuthResult" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -546,9 +551,9 @@ export type OidcAuthResult = { userinfo: UserinfoResponse; }; -// Warning: (ae-missing-release-tag) "OidcProviderOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (tsdoc-undefined-tag) The TSDoc tag "@BackstageSignInResult" is not defined in this configuration // -// @public (undocumented) +// @public export type OidcProviderOptions = { authHandler?: AuthHandler; signIn?: { @@ -556,11 +561,6 @@ export type OidcProviderOptions = { }; }; -// Warning: (ae-missing-release-tag) "OidcSignInResolver" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type OidcSignInResolver = SignInResolver; - // Warning: (ae-missing-release-tag) "oktaEmailSignInResolver" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -633,6 +633,22 @@ export type SamlProviderOptions = { }; }; +// @public +export type SignInInfo = { + profile: ProfileInfo; + result: AuthResult; +}; + +// @public +export type SignInResolver = ( + info: SignInInfo, + context: { + tokenIssuer: TokenIssuer; + catalogIdentityClient: CatalogIdentityClient; + logger: Logger_2; + }, +) => Promise; + // Warning: (ae-missing-release-tag) "TokenIssuer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public @@ -664,8 +680,6 @@ export type WebMessageResponse = // Warnings were encountered during analysis: // // src/identity/types.d.ts:31:9 - (ae-forgotten-export) The symbol "AnyJWK" needs to be exported by the entry point index.d.ts -// src/providers/atlassian/provider.d.ts:37:5 - (ae-forgotten-export) The symbol "AuthHandler" needs to be exported by the entry point index.d.ts -// src/providers/atlassian/provider.d.ts:42:9 - (ae-forgotten-export) The symbol "SignInResolver" needs to be exported by the entry point index.d.ts // src/providers/aws-alb/provider.d.ts:77:5 - (ae-forgotten-export) The symbol "AwsAlbResult" needs to be exported by the entry point index.d.ts // src/providers/github/provider.d.ts:71:58 - (tsdoc-escape-greater-than) The ">" character should be escaped using a backslash to avoid confusion with an HTML tag // src/providers/github/provider.d.ts:71:90 - (tsdoc-escape-greater-than) The ">" character should be escaped using a backslash to avoid confusion with an HTML tag diff --git a/plugins/auth-backend/src/providers/index.ts b/plugins/auth-backend/src/providers/index.ts index 4ecbb98fd2..9589e97265 100644 --- a/plugins/auth-backend/src/providers/index.ts +++ b/plugins/auth-backend/src/providers/index.ts @@ -34,6 +34,10 @@ export type { AuthProviderRouteHandlers, AuthProviderFactoryOptions, AuthProviderFactory, + AuthHandler, + AuthHandlerResult, + SignInResolver, + SignInInfo, } from './types'; // These types are needed for a postMessage from the login pop-up diff --git a/plugins/auth-backend/src/providers/oidc/index.ts b/plugins/auth-backend/src/providers/oidc/index.ts index 1d0f592359..39bd02928d 100644 --- a/plugins/auth-backend/src/providers/oidc/index.ts +++ b/plugins/auth-backend/src/providers/oidc/index.ts @@ -13,10 +13,5 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export type { - OidcSignInResolver, - OidcAuthHandler, - OidcAuthResult, - OidcProviderOptions, -} from './provider'; +export type { OidcAuthResult, OidcProviderOptions } from './provider'; export { createOidcProvider } from './provider'; diff --git a/plugins/auth-backend/src/providers/oidc/provider.ts b/plugins/auth-backend/src/providers/oidc/provider.ts index b9ae15f370..347820d2d6 100644 --- a/plugins/auth-backend/src/providers/oidc/provider.ts +++ b/plugins/auth-backend/src/providers/oidc/provider.ts @@ -61,16 +61,13 @@ export type OidcAuthResult = { userinfo: UserinfoResponse; }; -export type OidcSignInResolver = SignInResolver; -export type OidcAuthHandler = AuthHandler; - export type Options = OAuthProviderOptions & { metadataUrl: string; scope?: string; prompt?: string; tokenSignedResponseAlg?: string; - signInResolver?: OidcSignInResolver; - authHandler: OidcAuthHandler; + signInResolver?: SignInResolver; + authHandler: AuthHandler; tokenIssuer: TokenIssuer; catalogIdentityClient: CatalogIdentityClient; logger: Logger; @@ -227,6 +224,18 @@ export const oAuth2DefaultSignInResolver: SignInResolver = return { id: userId, token }; }; +/** + * OIDC provider callback options. An auth handler and a sign in resolver + * can be passed while creating a OIDC provider. + * + * authHandler : called after sign in was successful, a new object must be returned which includes a profile + * signInResolver: called after sign in was successful, expects to return a new @BackstageSignInResult + * + * Both options are optional. There is fallback for authHandler where the default handler expect an e-mail explicitly + * otherwise it throws an error + * + * @public + */ export type OidcProviderOptions = { authHandler?: AuthHandler; diff --git a/plugins/auth-backend/src/providers/types.ts b/plugins/auth-backend/src/providers/types.ts index dafa52163c..6e61682f86 100644 --- a/plugins/auth-backend/src/providers/types.ts +++ b/plugins/auth-backend/src/providers/types.ts @@ -240,6 +240,10 @@ export type ProfileInfo = { picture?: string; }; +/** + * type of sign in information context, includes the profile information and authentication result which contains auth. related information + * @public + */ export type SignInInfo = { /** * The simple profile passed down for use in the frontend. @@ -252,6 +256,11 @@ export type SignInInfo = { result: AuthResult; }; +/** + * Sign in resolver type describes the function which handles the result of a successful authentication + * and must return a valid BackStageSignInResult + * @public + */ export type SignInResolver = ( info: SignInInfo, context: { @@ -261,6 +270,10 @@ export type SignInResolver = ( }, ) => Promise; +/** + * The return type of authentication handler which must contain a valid profile information + * @public + */ export type AuthHandlerResult = { profile: ProfileInfo }; /** @@ -270,6 +283,8 @@ export type AuthHandlerResult = { profile: ProfileInfo }; * * Throwing an error in the function will cause the authentication to fail, making it * possible to use this function as a way to limit access to a certain group of users. + * + * @public */ export type AuthHandler = ( input: AuthResult, From e0c63b37db172ed75ddf88ec158e2de8f114758d Mon Sep 17 00:00:00 2001 From: Hasan Ozdemir <21654050+nodify-at@users.noreply.github.com> Date: Thu, 9 Dec 2021 21:37:57 +0100 Subject: [PATCH 4/5] add missing documentation for OidcAuthResult Signed-off-by: Hasan Ozdemir <21654050+nodify-at@users.noreply.github.com> --- plugins/auth-backend/api-report.md | 4 +--- plugins/auth-backend/src/providers/oidc/provider.ts | 4 ++++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/plugins/auth-backend/api-report.md b/plugins/auth-backend/api-report.md index c076058a0c..fd8d357a09 100644 --- a/plugins/auth-backend/api-report.md +++ b/plugins/auth-backend/api-report.md @@ -543,9 +543,7 @@ export type OAuthState = { origin?: string; }; -// Warning: (ae-missing-release-tag) "OidcAuthResult" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type OidcAuthResult = { tokenset: TokenSet; userinfo: UserinfoResponse; diff --git a/plugins/auth-backend/src/providers/oidc/provider.ts b/plugins/auth-backend/src/providers/oidc/provider.ts index 347820d2d6..98988ae6f7 100644 --- a/plugins/auth-backend/src/providers/oidc/provider.ts +++ b/plugins/auth-backend/src/providers/oidc/provider.ts @@ -56,6 +56,10 @@ type OidcImpl = { client: Client; }; +/** + * authentication result for the OIDC which includes the token set and user information (a profile response sent by OIDC server) + * @public + */ export type OidcAuthResult = { tokenset: TokenSet; userinfo: UserinfoResponse; From 133769ea846331f1ce10b4f59801ce1b3842cbf8 Mon Sep 17 00:00:00 2001 From: Hasan Ozdemir <21654050+nodify-at@users.noreply.github.com> Date: Sat, 11 Dec 2021 01:45:39 +0100 Subject: [PATCH 5/5] add links to docs for type BackstageSignInResult Signed-off-by: Hasan Ozdemir <21654050+nodify-at@users.noreply.github.com> --- plugins/auth-backend/api-report.md | 2 -- plugins/auth-backend/src/providers/oidc/provider.ts | 2 +- plugins/auth-backend/src/providers/types.ts | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/plugins/auth-backend/api-report.md b/plugins/auth-backend/api-report.md index fd8d357a09..9ed523c678 100644 --- a/plugins/auth-backend/api-report.md +++ b/plugins/auth-backend/api-report.md @@ -549,8 +549,6 @@ export type OidcAuthResult = { userinfo: UserinfoResponse; }; -// Warning: (tsdoc-undefined-tag) The TSDoc tag "@BackstageSignInResult" is not defined in this configuration -// // @public export type OidcProviderOptions = { authHandler?: AuthHandler; diff --git a/plugins/auth-backend/src/providers/oidc/provider.ts b/plugins/auth-backend/src/providers/oidc/provider.ts index 98988ae6f7..fe4c042500 100644 --- a/plugins/auth-backend/src/providers/oidc/provider.ts +++ b/plugins/auth-backend/src/providers/oidc/provider.ts @@ -233,7 +233,7 @@ export const oAuth2DefaultSignInResolver: SignInResolver = * can be passed while creating a OIDC provider. * * authHandler : called after sign in was successful, a new object must be returned which includes a profile - * signInResolver: called after sign in was successful, expects to return a new @BackstageSignInResult + * signInResolver: called after sign in was successful, expects to return a new {@link BackstageSignInResult} * * Both options are optional. There is fallback for authHandler where the default handler expect an e-mail explicitly * otherwise it throws an error diff --git a/plugins/auth-backend/src/providers/types.ts b/plugins/auth-backend/src/providers/types.ts index 6e61682f86..ecb466c768 100644 --- a/plugins/auth-backend/src/providers/types.ts +++ b/plugins/auth-backend/src/providers/types.ts @@ -258,7 +258,7 @@ export type SignInInfo = { /** * Sign in resolver type describes the function which handles the result of a successful authentication - * and must return a valid BackStageSignInResult + * and it must return a valid {@link BackstageSignInResult} * @public */ export type SignInResolver = (