Skip to content

Commit 17910fb

Browse files
authored
Merge pull request #207 from NetApp/external-api-genai-cognito-with-ad-docs-update
external-api-genai-cognito-with-ad-docs-update
2 parents c036f8d + cefbc2e commit 17910fb

File tree

10 files changed

+178
-103
lines changed

10 files changed

+178
-103
lines changed

AI/GenAI-ChatBot-application-sample/.env.local.sample

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ NEXT_PUBLIC_LOGIN_PROVIDER=cognito
22
NEXT_PUBLIC_KNOWLEDGE_BASE_ID=YOUR_KNOWLEDGE_BASE_ID
33
NEXT_PUBLIC_AWS_USER_POOLS_ID=YOUR_AWS_USER_POOLS_ID
44
NEXT_PUBLIC_AWS_USER_WEB_CLIENT_ID=YOUR_AWS_USER_WEB_CLIENT_ID
5+
# NEXT_PUBLIC_LOGIN_EXTERNAL_PROVIDER=AD--NAME-SAMPLE
6+
# NEXT_PUBLIC_AWS_OAUTH={"domain":"<DOMAIN_PREFIX>.auth.<REGION>.amazoncognito.com","scope":["openid","profile","email"],"redirectSignIn":"http://localhost:9091","redirectSignOut":"http://localhost:9091","responseType":"code"}
57

68
# NEXT_PUBLIC_LOGIN_PROVIDER=clerk
79
# NEXT_PUBLIC_KNOWLEDGE_BASE_ID=YOUR_KNOWLEDGE_BASE_ID

AI/GenAI-ChatBot-application-sample/src/app/auth/auth-service.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export class AuthService {
1919
await Auth.signUp({
2020
username,
2121
password,
22-
}).then(data => {
22+
}).then(() => {
2323

2424
logger.info("Registering " + username);
2525

@@ -131,7 +131,7 @@ export class AuthService {
131131
data: data
132132
});
133133
})
134-
.catch(err => {
134+
.catch(() => {
135135
logger.error("Couldn't sign out for some reason");
136136
Hub.dispatch(AuthService.CHANNEL, {
137137
event: AuthService.AUTH_EVENTS.SIGN_OUT,

AI/GenAI-ChatBot-application-sample/src/app/cognito/aws-configs.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const awsConfig = {
55
aws_user_pools_mfa_type: 'OFF',
66
aws_user_pools_web_client_id: process.env.NEXT_PUBLIC_AWS_USER_WEB_CLIENT_ID,
77
aws_user_settings: 'enable',
8+
oauth: process.env.NEXT_PUBLIC_AWS_OAUTH
89
};
910

1011
export default awsConfig

AI/GenAI-ChatBot-application-sample/src/app/components/loginForm/loginForm.tsx

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,17 @@ import { addNotification, removeNotification } from '@/lib/slices/notifications.
1515
import { NOTIFICATION_CONSTS } from '../NotificationGroup/notification.consts';
1616
import { setAuth } from '@/lib/slices/auth.slice';
1717
import { ClerkSignIn } from '@/app/services/clerk.service';
18-
import { SignInResult, LoginProvider } from '@/lib/api/api.types';
18+
import {LoginProvider, SignInResultClerk, SignInResultCognito} from '@/lib/api/api.types';
1919
import useRunUntil from '@/app/hooks/useRunUntil';
2020

21-
const LoginForm = () => {
21+
export type LoginType = 'AD' | 'UserPassword'
22+
interface LoginFormProps {
23+
onLoginSuccess: (loginType:LoginType )=> void
24+
}
25+
26+
const LoginForm = ({onLoginSuccess}:LoginFormProps) => {
2227
const loginProvider = process.env.NEXT_PUBLIC_LOGIN_PROVIDER as LoginProvider;
28+
const loginEternalProvider:string | undefined = process.env.NEXT_PUBLIC_LOGIN_EXTERNAL_PROVIDER;
2329

2430
const emailRef = useRef<HTMLInputElement>(null);
2531

@@ -29,8 +35,8 @@ const LoginForm = () => {
2935
const [email, setEmail] = useState<string | undefined>();
3036
const [password, setPassword] = useState<string | undefined>();
3137

32-
const { isLoading: isLoadingCog, jwtToken: jwtTokenCog, email: emailCog, password: passwordCog, userName: userNameCog, error: errorCog, doLogin: doLoginCog } = loginProvider === 'cognito' ? CognitoSignIn() : {} as SignInResult
33-
const { isLoading: isLoadingClerk, jwtToken: jwtTokenClerk, email: emailClerk, password: passwordClerk, userName: userNameClerk, error: errorClerk, doLogin: doLoginClerk } = loginProvider === 'clerk' ? ClerkSignIn() : {} as SignInResult;
38+
const { isLoading: isLoadingCog, jwtToken: jwtTokenCog, email: emailCog, password: passwordCog, userName: userNameCog, error: errorCog, doLogin: doLoginCog } = loginProvider === 'cognito' ? CognitoSignIn() : {} as SignInResultCognito
39+
const { isLoading: isLoadingClerk, jwtToken: jwtTokenClerk, email: emailClerk, password: passwordClerk, userName: userNameClerk, error: errorClerk, doLogin: doLoginClerk } = loginProvider === 'clerk' ? ClerkSignIn() : {} as SignInResultClerk;
3440

3541
useRunUntil(() => {
3642
emailRef.current?.focus();
@@ -53,18 +59,19 @@ const LoginForm = () => {
5359

5460
useEffect(() => {
5561
if (jwtTokenCog || jwtTokenClerk) {
62+
onLoginSuccess(loginEternalProvider? 'AD': 'UserPassword')
5663
dispatch(setAuth({
5764
isSuccess: true,
5865
accessToken: jwtTokenCog || jwtTokenClerk,
5966
userName: userNameClerk || userNameCog
6067
}));
6168
router.push(`${ROUTES.BASE}${ROUTES.CHAT}`);
6269
}
63-
}, [jwtTokenCog, jwtTokenClerk, router, userNameClerk, userNameCog, dispatch])
70+
}, [jwtTokenCog, jwtTokenClerk, router, userNameClerk, userNameCog, dispatch, loginEternalProvider, onLoginSuccess])
6471

6572
const doLogin = () => {
6673
dispatch(removeNotification(NOTIFICATION_CONSTS.UNIQUE_IDS.USER_NOT_CONFIRMED));
67-
loginProvider === 'cognito' ? doLoginCog(email, password) : doLoginClerk(email, password);
74+
loginProvider === 'cognito' ? doLoginCog(email, password,loginEternalProvider) : doLoginClerk(email, password);
6875
}
6976

7077
return (
@@ -73,7 +80,8 @@ const LoginForm = () => {
7380
<div className={styles.formContent}>
7481
<span className={_Classes(global.Regular_24, styles.formTitle)}>Log in to Workload Factory GenAI sample application</span>
7582
<span className={`${global.Regular_14}`}>Log in to NetApp GenAI Studio chatbot sample application with<br />your company user account.</span>
76-
<DsTextField
83+
{!process.env.NEXT_PUBLIC_LOGIN_EXTERNAL_PROVIDER && <>
84+
<DsTextField
7785
ref={emailRef}
7886
title='Email'
7987
className={styles.formInput}
@@ -91,20 +99,21 @@ const LoginForm = () => {
9199
value: 'This field is required.'
92100
} : undefined}
93101
/>
94-
<DsTextField
95-
title='Password'
96-
isPassword
97-
className={styles.formInput}
98-
onChange={event => setPassword(event?.target.value)}
99-
onKeyDown={event => {
100-
if (event.key === 'Enter') {
101-
doLogin();
102-
}
103-
}}
104-
message={password === '' ? {
105-
type: 'error',
106-
value: 'This field is required.'
107-
} : undefined} />
102+
<DsTextField
103+
title='Password'
104+
isPassword
105+
className={styles.formInput}
106+
onChange={event => setPassword(event?.target.value)}
107+
onKeyDown={event => {
108+
if (event.key === 'Enter') {
109+
doLogin();
110+
}
111+
}}
112+
message={password === '' ? {
113+
type: 'error',
114+
value: 'This field is required.'
115+
} : undefined} />
116+
</>}
108117
<DsButton onClick={() => doLogin()} className={styles.loginButton} isLoading={isLoadingCog || isLoadingClerk}>Login</DsButton>
109118
</div>
110119
</div>

AI/GenAI-ChatBot-application-sample/src/app/global.module.scss

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
77
color: #404040;
88

9+
&.isHidden {
10+
opacity: 0;
11+
}
12+
913
&.font-variants {
1014
--semibold-font-weight: 500;
1115

@@ -37,7 +41,7 @@
3741
font-size: 20px;
3842
line-height: 32px;
3943
font-weight: 400;
40-
}
44+
}
4145

4246
.Regular_14 {
4347
font-size: 14px;

AI/GenAI-ChatBot-application-sample/src/app/home.tsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
11
'use client';
22

3+
import React from 'react';
34
import styles from './global.module.scss';
4-
import LoginForm from "./components/loginForm/loginForm";
5+
import LoginForm, { LoginType } from "./components/loginForm/loginForm";
56
import ChatBot from '@/app/svgs/login/chatBot.png'
67
import Cloud from '@/app/svgs/login/cloud.png'
78
import Image from 'next/image';
89
import { _Classes } from '@/utils/cssHelper.util';
910
import { useAppSelector } from '@/lib/hooks';
1011
import rootSelector from '@/lib/selectors/root.selector';
12+
import { useState } from "react";
1113

1214
const Home = () => {
1315
const { accessToken, isSuccess } = useAppSelector(rootSelector.auth);
14-
16+
const [loginType, setLoginType] = useState<LoginType | undefined>(undefined);
1517
return (
16-
<div className={styles.genAi}>
17-
{!accessToken && isSuccess && <>
18-
<LoginForm />
18+
<div className={_Classes(styles.genAi, loginType === 'AD' ? styles.isHidden : '')}>
19+
{(!accessToken && isSuccess) && <>
20+
<LoginForm onLoginSuccess={
21+
setLoginType
22+
} />
1923
<div className={styles.welcomeContent}>
2024
<Image
2125
src={ChatBot}

AI/GenAI-ChatBot-application-sample/src/app/services/clerk.service.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { SignInResult } from "@/lib/api/api.types";
1+
import { SignInResultClerk } from "@/lib/api/api.types";
22
import { useAuth, useClerk, useSignIn, useUser } from "@clerk/nextjs";
33
import { useEffect, useState } from "react";
44

5-
export const ClerkSignIn = (): SignInResult => {
5+
export const ClerkSignIn = (): SignInResultClerk => {
66
const [email, setEmail] = useState<string | undefined>();
77
const [password, setPassword] = useState<string | undefined>();
88
const [isLoading, setIsLoading] = useState<boolean>(false);

AI/GenAI-ChatBot-application-sample/src/app/services/cognito.service.ts

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@ import useRunOnce from "../hooks/useRunOnce";
33
import awsConfig from "../cognito/aws-configs";
44
import { useEffect, useState } from "react";
55
import { AuthService } from "../auth/auth-service";
6-
import { CognitoPayload } from "../cognito/cognito.types";
7-
import { SignInResult } from "@/lib/api/api.types";
6+
import {CognitoPayload} from "../cognito/cognito.types";
7+
import {SignInResultCognito} from "@/lib/api/api.types";
8+
import {CognitoUser} from "amazon-cognito-identity-js";
9+
import awsConfigs from "../cognito/aws-configs";
810

9-
const CognitoSignIn = (): SignInResult => {
11+
const isLoginEternalProvider:boolean = !!process.env.NEXT_PUBLIC_LOGIN_EXTERNAL_PROVIDER;
12+
13+
const CognitoSignIn = (): SignInResultCognito => {
1014
const [isLoading, setIsLoading] = useState<boolean>(false);
1115
const [email, setEmail] = useState<string | undefined>();
1216
const [password, setPassword] = useState<string | undefined>();
@@ -15,6 +19,7 @@ const CognitoSignIn = (): SignInResult => {
1519
const [userName, setUserName] = useState<string | undefined>();
1620

1721
useRunOnce(() => {
22+
if (awsConfig.oauth && typeof awsConfig.oauth === "string") awsConfigs.oauth = JSON.parse(awsConfigs.oauth!)
1823
Amplify.configure(awsConfig);
1924
})
2025

@@ -52,7 +57,17 @@ const CognitoSignIn = (): SignInResult => {
5257

5358
const updateUser = async () => {
5459
try {
55-
await Auth.currentAuthenticatedUser()
60+
const authenticatedUser:CognitoUser = await Auth.currentAuthenticatedUser()
61+
if (isLoginEternalProvider){
62+
Hub.dispatch(AuthService.CHANNEL, {
63+
event: AuthService.AUTH_EVENTS.LOGIN,
64+
// @ts-ignore
65+
success: true,
66+
message: "",
67+
username: authenticatedUser.getUsername(),
68+
user: authenticatedUser
69+
});
70+
}
5671
} catch {
5772
}
5873
}
@@ -64,13 +79,17 @@ const CognitoSignIn = (): SignInResult => {
6479
};
6580
}, []);
6681

67-
const doLogin = async (email?: string, password?: string) => {
82+
const doLogin = async (email?: string, password?: string,externalProviderName?:string) => {
6883
setError(undefined);
6984

7085
setEmail(email || '');
7186
setPassword(password || '');
7287

73-
if (email && password) {
88+
if (externalProviderName){
89+
setIsLoading(true);
90+
await Auth.federatedSignIn({ provider: externalProviderName as any });
91+
}
92+
else if (email && password){
7493
setIsLoading(true);
7594
await AuthService.login(email, password);
7695
}

AI/GenAI-ChatBot-application-sample/src/lib/api/api.types.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,18 @@ export type ChunkingStrategy = 'sentences' | 'words' | 'characters';
55
export type MessageType = 'ANSWER' | 'ERROR';
66
export type LoginProvider = 'cognito' | 'clerk';
77

8-
export interface SignInResult {
8+
export interface SignInResultCognito extends SignInResult {
9+
doLogin: (email?: string, password?: string, externalProviderName?: string) => void,
10+
}
11+
12+
export interface SignInResultClerk extends SignInResult {
13+
doLogin: (email?: string, password?: string) => void,
14+
}
15+
16+
interface SignInResult {
917
isLoading: boolean,
1018
email?: string,
1119
password?: string,
12-
doLogin: (email?: string, password?: string) => void,
1320
jwtToken?: string,
1421
error?: string,
1522
userName?: string

0 commit comments

Comments
 (0)