feat: add common sign-in resolver for simple email-to-email matching

- `providers.google.resolvers.emailMatchingUserEntityEmail()`
- `providers.microsoft.resolvers.emailMatchingUserEntityEmail()`
- `providers.okta.resolvers.emailMatchingUserEntityEmail()`

Signed-off-by: Patrick Jungermann <Patrick.Jungermann@gmail.com>
This commit is contained in:
Patrick Jungermann
2022-04-21 16:30:46 +02:00
parent 6aea66b400
commit 44bdcbdb66
6 changed files with 57 additions and 4 deletions
+9 -1
View File
@@ -2,7 +2,15 @@
'@backstage/plugin-auth-backend': patch
---
Add common signIn resolver to more providers.
Add more common predefined sign-in resolvers to auth providers.
Add the existing resolver to more providers (already available at `google`):
- `providers.microsoft.resolvers.emailLocalPartMatchingUserEntityName()`
- `providers.okta.resolvers.emailLocalPartMatchingUserEntityName()`
Add a new resolver for simple email-to-email matching:
- `providers.google.resolvers.emailMatchingUserEntityEmail()`
- `providers.microsoft.resolvers.emailMatchingUserEntityEmail()`
- `providers.okta.resolvers.emailMatchingUserEntityEmail()`
+3
View File
@@ -872,6 +872,7 @@ export const providers: Readonly<{
) => AuthProviderFactory;
resolvers: Readonly<{
emailLocalPartMatchingUserEntityName: () => SignInResolver<unknown>;
emailMatchingUserEntityEmail: () => SignInResolver<unknown>;
emailMatchingUserEntityAnnotation(): SignInResolver<OAuthResult>;
}>;
}>;
@@ -890,6 +891,7 @@ export const providers: Readonly<{
) => AuthProviderFactory;
resolvers: Readonly<{
emailLocalPartMatchingUserEntityName: () => SignInResolver<unknown>;
emailMatchingUserEntityEmail: () => SignInResolver<unknown>;
emailMatchingUserEntityAnnotation(): SignInResolver<OAuthResult>;
}>;
}>;
@@ -947,6 +949,7 @@ export const providers: Readonly<{
) => AuthProviderFactory;
resolvers: Readonly<{
emailLocalPartMatchingUserEntityName: () => SignInResolver<unknown>;
emailMatchingUserEntityEmail: () => SignInResolver<unknown>;
emailMatchingUserEntityAnnotation(): SignInResolver<OAuthResult>;
}>;
}>;
@@ -43,7 +43,10 @@ import {
SignInResolver,
} from '../types';
import { createAuthProviderIntegration } from '../createAuthProviderIntegration';
import { commonByEmailLocalPartResolver } from '../resolvers';
import {
commonByEmailLocalPartResolver,
commonByEmailResolver,
} from '../resolvers';
type PrivateInfo = {
refreshToken: string;
@@ -248,6 +251,10 @@ export const google = createAuthProviderIntegration({
* Looks up the user by matching their email local part to the entity name.
*/
emailLocalPartMatchingUserEntityName: () => commonByEmailLocalPartResolver,
/**
* Looks up the user by matching their email to the entity email.
*/
emailMatchingUserEntityEmail: () => commonByEmailResolver,
/**
* Looks up the user by matching their email to the `google.com/email` annotation.
*/
@@ -43,7 +43,10 @@ import {
AuthResolverContext,
} from '../types';
import { createAuthProviderIntegration } from '../createAuthProviderIntegration';
import { commonByEmailLocalPartResolver } from '../resolvers';
import {
commonByEmailLocalPartResolver,
commonByEmailResolver,
} from '../resolvers';
import { Logger } from 'winston';
import fetch from 'node-fetch';
@@ -275,6 +278,10 @@ export const microsoft = createAuthProviderIntegration({
* Looks up the user by matching their email local part to the entity name.
*/
emailLocalPartMatchingUserEntityName: () => commonByEmailLocalPartResolver,
/**
* Looks up the user by matching their email to the entity email.
*/
emailMatchingUserEntityEmail: () => commonByEmailResolver,
/**
* Looks up the user by matching their email to the `microsoft.com/email` annotation.
*/
@@ -43,7 +43,10 @@ import {
AuthResolverContext,
} from '../types';
import { createAuthProviderIntegration } from '../createAuthProviderIntegration';
import { commonByEmailLocalPartResolver } from '../resolvers';
import {
commonByEmailLocalPartResolver,
commonByEmailResolver,
} from '../resolvers';
import { StateStore } from 'passport-oauth2';
type PrivateInfo = {
@@ -279,6 +282,10 @@ export const okta = createAuthProviderIntegration({
* Looks up the user by matching their email local part to the entity name.
*/
emailLocalPartMatchingUserEntityName: () => commonByEmailLocalPartResolver,
/**
* Looks up the user by matching their email to the entity email.
*/
emailMatchingUserEntityEmail: () => commonByEmailResolver,
/**
* Looks up the user by matching their email to the `okta.com/email` annotation.
*/
@@ -35,3 +35,24 @@ export const commonByEmailLocalPartResolver: SignInResolver<unknown> = async (
entityRef: { name: localPart },
});
};
/**
* A common sign-in resolver that looks up the user using their email address
* as email of the entity.
*/
export const commonByEmailResolver: SignInResolver<unknown> = async (
info,
ctx,
) => {
const { profile } = info;
if (!profile.email) {
throw new Error('Login failed, user profile does not contain an email');
}
return ctx.signInWithCatalogUser({
filter: {
'spec.profile.email': profile.email,
},
});
};