Merge pull request #8425 from nodify-at/master
export typescript types for OIDC provider
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-auth-backend': patch
|
||||
---
|
||||
|
||||
export minimal typescript types for OIDC provider
|
||||
@@ -47,6 +47,16 @@ export type AtlassianProviderOptions = {
|
||||
};
|
||||
};
|
||||
|
||||
// @public
|
||||
export type AuthHandler<AuthResult> = (
|
||||
input: AuthResult,
|
||||
) => Promise<AuthHandlerResult>;
|
||||
|
||||
// @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)
|
||||
@@ -258,7 +268,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 +543,20 @@ export type OAuthState = {
|
||||
origin?: string;
|
||||
};
|
||||
|
||||
// @public
|
||||
export type OidcAuthResult = {
|
||||
tokenset: TokenSet;
|
||||
userinfo: UserinfoResponse;
|
||||
};
|
||||
|
||||
// @public
|
||||
export type OidcProviderOptions = {
|
||||
authHandler?: AuthHandler<OidcAuthResult>;
|
||||
signIn?: {
|
||||
resolver?: SignInResolver<OidcAuthResult>;
|
||||
};
|
||||
};
|
||||
|
||||
// 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)
|
||||
@@ -606,6 +629,22 @@ export type SamlProviderOptions = {
|
||||
};
|
||||
};
|
||||
|
||||
// @public
|
||||
export type SignInInfo<AuthResult> = {
|
||||
profile: ProfileInfo;
|
||||
result: AuthResult;
|
||||
};
|
||||
|
||||
// @public
|
||||
export type SignInResolver<AuthResult> = (
|
||||
info: SignInInfo<AuthResult>,
|
||||
context: {
|
||||
tokenIssuer: TokenIssuer;
|
||||
catalogIdentityClient: CatalogIdentityClient;
|
||||
logger: Logger_2;
|
||||
},
|
||||
) => Promise<BackstageSignInResult>;
|
||||
|
||||
// Warning: (ae-missing-release-tag) "TokenIssuer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public
|
||||
@@ -637,8 +676,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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -13,5 +13,5 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export type { OidcAuthResult, OidcProviderOptions } from './provider';
|
||||
export { createOidcProvider } from './provider';
|
||||
|
||||
@@ -56,7 +56,11 @@ type OidcImpl = {
|
||||
client: Client;
|
||||
};
|
||||
|
||||
type AuthResult = {
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
@@ -66,8 +70,8 @@ export type Options = OAuthProviderOptions & {
|
||||
scope?: string;
|
||||
prompt?: string;
|
||||
tokenSignedResponseAlg?: string;
|
||||
signInResolver?: SignInResolver<AuthResult>;
|
||||
authHandler: AuthHandler<AuthResult>;
|
||||
signInResolver?: SignInResolver<OidcAuthResult>;
|
||||
authHandler: AuthHandler<OidcAuthResult>;
|
||||
tokenIssuer: TokenIssuer;
|
||||
catalogIdentityClient: CatalogIdentityClient;
|
||||
logger: Logger;
|
||||
@@ -78,8 +82,8 @@ export class OidcAuthProvider implements OAuthHandlers {
|
||||
private readonly scope?: string;
|
||||
private readonly prompt?: string;
|
||||
|
||||
private readonly signInResolver?: SignInResolver<AuthResult>;
|
||||
private readonly authHandler: AuthHandler<AuthResult>;
|
||||
private readonly signInResolver?: SignInResolver<OidcAuthResult>;
|
||||
private readonly authHandler: AuthHandler<OidcAuthResult>;
|
||||
private readonly tokenIssuer: TokenIssuer;
|
||||
private readonly catalogIdentityClient: CatalogIdentityClient;
|
||||
private readonly logger: Logger;
|
||||
@@ -113,7 +117,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 +162,7 @@ export class OidcAuthProvider implements OAuthHandlers {
|
||||
(
|
||||
tokenset: TokenSet,
|
||||
userinfo: UserinfoResponse,
|
||||
done: PassportDoneCallback<AuthResult, PrivateInfo>,
|
||||
done: PassportDoneCallback<OidcAuthResult, PrivateInfo>,
|
||||
) => {
|
||||
if (typeof done !== 'function') {
|
||||
throw new Error(
|
||||
@@ -180,7 +184,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<OAuthResponse> {
|
||||
private async handleResult(result: OidcAuthResult): Promise<OAuthResponse> {
|
||||
const { profile } = await this.authHandler(result);
|
||||
const response: OAuthResponse = {
|
||||
providerInfo: {
|
||||
@@ -210,27 +214,37 @@ export class OidcAuthProvider implements OAuthHandlers {
|
||||
}
|
||||
}
|
||||
|
||||
export const oAuth2DefaultSignInResolver: SignInResolver<AuthResult> = async (
|
||||
info,
|
||||
ctx,
|
||||
) => {
|
||||
const { profile } = info;
|
||||
export const oAuth2DefaultSignInResolver: SignInResolver<OidcAuthResult> =
|
||||
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 };
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 {@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
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type OidcProviderOptions = {
|
||||
authHandler?: AuthHandler<AuthResult>;
|
||||
authHandler?: AuthHandler<OidcAuthResult>;
|
||||
|
||||
signIn?: {
|
||||
resolver?: SignInResolver<AuthResult>;
|
||||
resolver?: SignInResolver<OidcAuthResult>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -260,7 +274,7 @@ export const createOidcProvider = (
|
||||
tokenIssuer,
|
||||
});
|
||||
|
||||
const authHandler: AuthHandler<AuthResult> = options?.authHandler
|
||||
const authHandler: AuthHandler<OidcAuthResult> = options?.authHandler
|
||||
? options.authHandler
|
||||
: async ({ userinfo }) => ({
|
||||
profile: {
|
||||
@@ -271,7 +285,7 @@ export const createOidcProvider = (
|
||||
});
|
||||
const signInResolverFn =
|
||||
options?.signIn?.resolver ?? oAuth2DefaultSignInResolver;
|
||||
const signInResolver: SignInResolver<AuthResult> = info =>
|
||||
const signInResolver: SignInResolver<OidcAuthResult> = info =>
|
||||
signInResolverFn(info, {
|
||||
catalogIdentityClient,
|
||||
tokenIssuer,
|
||||
|
||||
@@ -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<AuthResult> = {
|
||||
/**
|
||||
* The simple profile passed down for use in the frontend.
|
||||
@@ -252,6 +256,11 @@ export type SignInInfo<AuthResult> = {
|
||||
result: AuthResult;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sign in resolver type describes the function which handles the result of a successful authentication
|
||||
* and it must return a valid {@link BackstageSignInResult}
|
||||
* @public
|
||||
*/
|
||||
export type SignInResolver<AuthResult> = (
|
||||
info: SignInInfo<AuthResult>,
|
||||
context: {
|
||||
@@ -261,6 +270,10 @@ export type SignInResolver<AuthResult> = (
|
||||
},
|
||||
) => Promise<BackstageSignInResult>;
|
||||
|
||||
/**
|
||||
* 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<AuthResult> = (
|
||||
input: AuthResult,
|
||||
|
||||
Reference in New Issue
Block a user