Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(chat): implement provider auto-redirect to skip provider selection page #2116

Merged
merged 43 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
efd00ac
feat(chat): implement provider auto-redirect to skip provider selecti…
valerydluski Sep 12, 2024
6e890f9
Merge branch 'development' into feat/skip-auth-provider-page
IlyaBondar Sep 19, 2024
cdd9c61
refactor: create list of providers which support federated logout
valerydluski Sep 20, 2024
1a94113
Merge branch 'feat/skip-auth-provider-page' of github.com:epam/ai-dia…
valerydluski Sep 20, 2024
8d9a7b8
Merge branch 'development' into feat/skip-auth-provider-page
valerydluski Sep 20, 2024
ec717a4
refactor: add comment
valerydluski Sep 20, 2024
38c391d
Merge branch 'feat/skip-auth-provider-page' of github.com:epam/ai-dia…
valerydluski Sep 20, 2024
3034b29
refactor: remove getCsrfToken import
valerydluski Sep 20, 2024
b87f707
fix: provider can be undefined
valerydluski Sep 23, 2024
a448837
refactor: allow dynamic import for lodash-es
valerydluski Sep 23, 2024
c8c6e73
Merge branch 'development' into feat/skip-auth-provider-page
valerydluski Sep 23, 2024
fb3a275
Merge branch 'development' into feat/skip-auth-provider-page
IlyaBondar Sep 27, 2024
139dfbf
Merge branch 'development' into feat/skip-auth-provider-page
IlyaBondar Oct 18, 2024
67c56c5
Merge branch 'development' into feat/skip-auth-provider-page
IlyaBondar Oct 18, 2024
0cf871a
Merge branch 'development' into feat/skip-auth-provider-page
valerydluski Nov 21, 2024
c195469
Merge branch 'development' into feat/skip-auth-provider-page
IlyaBondar Nov 22, 2024
13a7bf3
feat(auth): implement new sign-in flow and remove middleware file
valerydluski Nov 25, 2024
a7b34b5
refactor(auth): remove unused sign-in logic and clean up layout compo…
valerydluski Nov 26, 2024
b925bc5
Merge branch 'development' into feat/skip-auth-provider-page
valerydluski Nov 26, 2024
5c16720
feat(chat): trigger sign-in when login is required in layout component
valerydluski Nov 26, 2024
b992817
feat(auth): enhance sign-in flow with dynamic auth provider and remov…
valerydluski Nov 26, 2024
e45863c
Merge branch 'development' into feat/skip-auth-provider-page
valerydluski Nov 26, 2024
411265c
Merge branch 'development' into feat/skip-auth-provider-page
valerydluski Nov 26, 2024
5325847
Merge branch 'feat/skip-auth-provider-page' of github.com:epam/ai-dia…
valerydluski Nov 26, 2024
636eaa2
fix(layout): remove unnecessary blank line and improve code readability
valerydluski Nov 26, 2024
e0be038
fix(server): add a blank line for improved code readability in getCom…
valerydluski Nov 26, 2024
e06909f
Merge branch 'development' into feat/skip-auth-provider-page
valerydluski Nov 27, 2024
ffdb3f7
Merge branch 'development' into feat/skip-auth-provider-page
IlyaBondar Nov 27, 2024
7c40b6c
Tests are fixed
nartovm Nov 27, 2024
204e3a0
Merge branch 'development' into feat/skip-auth-provider-page
nartovm Nov 27, 2024
b27f839
fix(auth): redirect to callback URL after successful sign-in
valerydluski Nov 27, 2024
8b28334
Merge branch 'development' into feat/skip-auth-provider-page
valerydluski Nov 28, 2024
d976838
fix(auth): validate callback URL before redirecting after sign-in
valerydluski Nov 28, 2024
b542662
fix(chat): sanitize callback URL to prevent potential security issues
valerydluski Nov 28, 2024
0737c8c
fix(auth): ensure safe callback URL is used for redirection after sig…
valerydluski Nov 28, 2024
9333fbd
Merge branch 'development' into feat/skip-auth-provider-page
valerydluski Nov 28, 2024
28f712d
Merge branch 'development' into feat/skip-auth-provider-page
valerydluski Nov 28, 2024
0e8668e
overlayauth fix
nartovm Nov 29, 2024
8b715a1
Merge branch 'development' into feat/skip-auth-provider-page
nartovm Nov 29, 2024
6eacb30
Merge branch 'development' into feat/skip-auth-provider-page
valerydluski Nov 29, 2024
3e2dd9e
Merge branch 'development' into feat/skip-auth-provider-page
valerydluski Dec 2, 2024
f82385d
Merge branch 'development' into feat/skip-auth-provider-page
valerydluski Dec 2, 2024
535f499
Merge branch 'development' into feat/skip-auth-provider-page
valerydluski Dec 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions apps/chat-e2e/src/tests/overlay/overlayAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ for (let i = 0; i < overlayUsernames.length; i++) {

const loginPage = new LoginPage(newPage);
await newPage.waitForLoadState();
await loginPage.auth0SignInButton.click();

if (await loginPage.auth0SignInButton.isVisible()) {
await loginPage.auth0SignInButton.click();
}
const auth0Page = new Auth0Page(newPage);
await newPage.waitForLoadState();
const auth0Form = auth0Page.getAuth0();
Expand Down
5 changes: 3 additions & 2 deletions apps/chat-e2e/src/ui/actions/auth0Login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { LocalStorageManager } from '@/src/core/localStorageManager';
import { ProviderLogin } from '@/src/ui/actions/providerLogin';
import { Auth0Page } from '@/src/ui/pages/auth0Page';
import { LoginPage } from '@/src/ui/pages/loginPage';
import { BaseElement } from '@/src/ui/webElements';

export class Auth0Login extends ProviderLogin<Auth0Page> {
constructor(
Expand All @@ -12,7 +13,7 @@ export class Auth0Login extends ProviderLogin<Auth0Page> {
super(loginPage, authProviderPage, localStorageManager);
}

public async navigateToCredentialsPage() {
await this.loginPage.auth0SignInButton.click();
getSignInButton(): BaseElement {
return this.loginPage.auth0SignInButton;
}
}
5 changes: 3 additions & 2 deletions apps/chat-e2e/src/ui/actions/azureADLogin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { LocalStorageManager } from '@/src/core/localStorageManager';
import { ProviderLogin } from '@/src/ui/actions/providerLogin';
import { AzureADPage } from '@/src/ui/pages/azureADPage';
import { LoginPage } from '@/src/ui/pages/loginPage';
import { BaseElement } from '@/src/ui/webElements';

export class AzureADLogin extends ProviderLogin<AzureADPage> {
constructor(
Expand All @@ -12,7 +13,7 @@ export class AzureADLogin extends ProviderLogin<AzureADPage> {
super(loginPage, authProviderPage, localStorageManager);
}

public async navigateToCredentialsPage() {
await this.loginPage.keycloakSignInButton.click();
getSignInButton(): BaseElement {
return this.loginPage.keycloakSignInButton;
}
}
5 changes: 3 additions & 2 deletions apps/chat-e2e/src/ui/actions/keycloakLogin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { LocalStorageManager } from '@/src/core/localStorageManager';
import { ProviderLogin } from '@/src/ui/actions/providerLogin';
import { KeycloakPage } from '@/src/ui/pages';
import { LoginPage } from '@/src/ui/pages/loginPage';
import { BaseElement } from '@/src/ui/webElements';

export class KeycloakLogin extends ProviderLogin<KeycloakPage> {
constructor(
Expand All @@ -12,7 +13,7 @@ export class KeycloakLogin extends ProviderLogin<KeycloakPage> {
super(loginPage, authProviderPage, localStorageManager);
}

public async navigateToCredentialsPage() {
await this.loginPage.keycloakSignInButton.click();
getSignInButton(): BaseElement {
return this.loginPage.keycloakSignInButton;
}
}
10 changes: 9 additions & 1 deletion apps/chat-e2e/src/ui/actions/providerLogin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { API } from '@/src/testData';
import { LoginInterface } from '@/src/ui/actions/loginInterface';
import { BasePage } from '@/src/ui/pages/basePage';
import { LoginPage } from '@/src/ui/pages/loginPage';
import { BaseElement } from '@/src/ui/webElements';
import { TestInfo } from '@playwright/test';

export abstract class ProviderLogin<T extends BasePage & LoginInterface> {
Expand All @@ -20,7 +21,14 @@ export abstract class ProviderLogin<T extends BasePage & LoginInterface> {
this.localStorageManager = localStorageManager;
}

abstract navigateToCredentialsPage(): Promise<void>;
abstract getSignInButton(): BaseElement;

async navigateToCredentialsPage(): Promise<void> {
const signInButton = this.getSignInButton();
if (await signInButton.isVisible()) {
await signInButton.click();
}
}

public async login(
testInfo: TestInfo,
Expand Down
31 changes: 31 additions & 0 deletions apps/chat/src/pages/auth/signin/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { signIn, useSession } from 'next-auth/react';
import { useEffect } from 'react';

import { useRouter } from 'next/router';

import { getCommonPageProps } from '@/src/utils/server/get-common-page-props';

import { sanitizeUri } from 'micromark-util-sanitize-uri';

interface PageProps {
defaultAuthProvider?: string;
}

export default function Signin({ defaultAuthProvider }: PageProps) {
const router = useRouter();
const { status } = useSession();
useEffect(() => {
if (status === 'unauthenticated') {
signIn(defaultAuthProvider);
} else if (status === 'authenticated') {
const { callbackUrl } = router.query;
const safeUrl = callbackUrl ? sanitizeUri(callbackUrl.toString()) : '/';

router.push(safeUrl);
Fixed Show fixed Hide fixed
Fixed Show fixed Hide fixed
}
}, [status, router, defaultAuthProvider]);

return <div></div>;
}

export const getServerSideProps = getCommonPageProps;
4 changes: 3 additions & 1 deletion apps/chat/src/utils/auth/auth-pages.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { PagesOptions } from 'next-auth';

import { DEFAULT_PROVIDER } from './auth-providers';

export const pages: Partial<PagesOptions> = {
// Put here your custom pages for authentication,
// which will be used by next-auth instead of the default ones
// https://authjs.dev/getting-started/session-management/custom-pages
// ------------------------------------------------------------------
// signIn: '/auth/signin',
signIn: DEFAULT_PROVIDER ? '/auth/signin' : undefined,
// signOut: '/auth/signout',
// error: '/auth/error',
// verifyRequest: '/auth/verify-request',
Expand Down
20 changes: 19 additions & 1 deletion apps/chat/src/utils/auth/auth-providers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Provider } from 'next-auth/providers';
import { OAuthProviderType, Provider } from 'next-auth/providers';
import Auth0Provider from 'next-auth/providers/auth0';
import AzureProvider from 'next-auth/providers/azure-ad';
import CognitoProvider from 'next-auth/providers/cognito';
Expand Down Expand Up @@ -156,6 +156,24 @@ const allProviders: (Provider | boolean)[] = [

export const authProviders = allProviders.filter(Boolean) as Provider[];

/**
* Sets the DEFAULT_PROVIDER to the single available provider's ID if:
* - There is only one authentication provider configured.
* - The provider supports federated logout.
*
* This allows us to skip the NextAuth provider selection page and
* directly use the single available provider for authentication.
* By ensuring the provider supports federated logout, we maintain
* proper session management and user experience during logout operations.
*/
const FEDERATED_LOGOUT_PROVIDERS: OAuthProviderType[] = ['auth0', 'keycloak'];

export const DEFAULT_PROVIDER: OAuthProviderType | null =
authProviders.length === 1 &&
FEDERATED_LOGOUT_PROVIDERS.includes(authProviders[0]?.id as OAuthProviderType)
? (authProviders[0]?.id as OAuthProviderType)
: null;

/**
* Is authorization enabled
*
Expand Down
6 changes: 5 additions & 1 deletion apps/chat/src/utils/server/get-common-page-props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import { getServerSession } from 'next-auth/next';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';

import { pages } from '@/src/utils/auth/auth-pages';
import { isAuthDisabled } from '@/src/utils/auth/auth-providers';
import {
DEFAULT_PROVIDER,
isAuthDisabled,
} from '@/src/utils/auth/auth-providers';
import { isServerSessionValid } from '@/src/utils/auth/session';

import { StorageType } from '@/src/types/storage';
Expand Down Expand Up @@ -143,6 +146,7 @@ export const getCommonPageProps: GetServerSideProps = async ({
locale ?? 'en',
Object.values(Translation),
)),
defaultAuthProvider: DEFAULT_PROVIDER ?? undefined,
},
};
};
158 changes: 151 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading