refactor(auth/sso): rename GetAuthorizationUrl for clarity (#10173)

- Rename `GetAuthorizationUrl` to `GetAuthorizationUrlForSSO`
- Move `GetAuthorizationUrlForSSO` from `sso.resolver.ts` to
`auth.resolver.ts` to avoid the permission guard and let users use an
SSO provider.
- Fix an issue in OIDC guard that breaks the connection if you have
multiple SSO providers + add tests for OIDC guard.
This commit is contained in:
Antoine Moreaux
2025-02-13 11:15:22 +01:00
committed by GitHub
parent d7b84de1b5
commit 77d72e9b1c
16 changed files with 214 additions and 66 deletions

View File

@ -1,11 +0,0 @@
import { gql } from '@apollo/client';
export const GET_AUTHORIZATION_URL = gql`
mutation GetAuthorizationUrl($input: GetAuthorizationUrlInput!) {
getAuthorizationUrl(input: $input) {
id
type
authorizationURL
}
}
`;

View File

@ -0,0 +1,11 @@
import { gql } from '@apollo/client';
export const GET_AUTHORIZATION_URL_FOR_SSO = gql`
mutation GetAuthorizationUrlForSSO($input: GetAuthorizationUrlForSSOInput!) {
getAuthorizationUrlForSSO(input: $input) {
id
type
authorizationURL
}
}
`;

View File

@ -8,6 +8,7 @@ import { HorizontalSeparator, MainButton } from 'twenty-ui';
import { workspaceAuthProvidersState } from '@/workspace/states/workspaceAuthProvidersState';
import { isDefined } from 'twenty-shared';
import React from 'react';
const StyledContentContainer = styled.div`
margin-bottom: ${({ theme }) => theme.spacing(8)};
@ -24,16 +25,15 @@ export const SignInUpSSOIdentityProviderSelection = () => {
<StyledContentContainer>
{isDefined(workspaceAuthProviders?.sso) &&
workspaceAuthProviders?.sso.map((idp) => (
<>
<React.Fragment key={idp.id}>
<MainButton
key={idp.id}
title={idp.name}
onClick={() => redirectToSSOLoginPage(idp.id)}
Icon={guessSSOIdentityProviderIconByUrl(idp.issuer)}
fullWidth
/>
<HorizontalSeparator visible={false} />
</>
</React.Fragment>
))}
</StyledContentContainer>
</>

View File

@ -1,4 +1,4 @@
import { GET_AUTHORIZATION_URL } from '@/auth/graphql/mutations/getAuthorizationUrl';
import { GET_AUTHORIZATION_URL_FOR_SSO } from '@/auth/graphql/mutations/getAuthorizationUrlForSSO';
import { useSSO } from '@/auth/sign-in-up/hooks/useSSO';
import { useRedirect } from '@/domain-manager/hooks/useRedirect';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
@ -23,7 +23,7 @@ const mockRedirect = jest.fn();
const apolloMocks = [
{
request: {
query: GET_AUTHORIZATION_URL,
query: GET_AUTHORIZATION_URL_FOR_SSO,
variables: {
input: {
identityProviderId: 'success-id',
@ -32,13 +32,13 @@ const apolloMocks = [
},
result: {
data: {
getAuthorizationUrl: { authorizationURL: 'http://example.com' },
getAuthorizationUrlForSSO: { authorizationURL: 'http://example.com' },
},
},
},
{
request: {
query: GET_AUTHORIZATION_URL,
query: GET_AUTHORIZATION_URL_FOR_SSO,
variables: {
input: {
identityProviderId: 'error-id',

View File

@ -1,6 +1,6 @@
/* @license Enterprise */
import { GET_AUTHORIZATION_URL } from '@/auth/graphql/mutations/getAuthorizationUrl';
import { GET_AUTHORIZATION_URL_FOR_SSO } from '@/auth/graphql/mutations/getAuthorizationUrlForSSO';
import { useRedirect } from '@/domain-manager/hooks/useRedirect';
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
@ -17,7 +17,7 @@ export const useSSO = () => {
let authorizationUrlForSSOResult;
try {
authorizationUrlForSSOResult = await apolloClient.mutate({
mutation: GET_AUTHORIZATION_URL,
mutation: GET_AUTHORIZATION_URL_FOR_SSO,
variables: {
input: {
identityProviderId,
@ -32,7 +32,8 @@ export const useSSO = () => {
}
redirect(
authorizationUrlForSSOResult.data?.getAuthorizationUrl.authorizationURL,
authorizationUrlForSSOResult.data?.getAuthorizationUrlForSSO
.authorizationURL,
);
};