Skip to content

Commit 2f13a87

Browse files
committed
update user info from login
1 parent 16f776a commit 2f13a87

File tree

5 files changed

+66
-23
lines changed

5 files changed

+66
-23
lines changed

src/frontend_react/src/api/config.tsx

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
// src/config.js
22

3-
import { UserInfo } from "@/models";
3+
import { UserInfo, claim } from "@/models";
4+
45

56
declare global {
67
interface Window {
78
appConfig?: Record<string, any>;
89
activeUserId?: string;
9-
userInfo?: UserInfo[];
10+
userInfo?: UserInfo;
1011
}
1112
}
1213

1314
export let API_URL: string | null = null;
1415
export let USER_ID: string | null = null;
16+
export let USER_INFO: UserInfo | null = null;
1517

1618
export let config = {
1719
API_URL: "http://localhost:8000/api",
@@ -23,7 +25,12 @@ export function setApiUrl(url: string | null) {
2325
API_URL = url.includes('/api') ? url : `${url}/api`;
2426
}
2527
}
26-
28+
export function setUserInfoGlobal(userInfo: UserInfo | null) {
29+
if (userInfo) {
30+
USER_ID = userInfo.user_id || null;
31+
USER_INFO = userInfo;
32+
}
33+
}
2734
export function setEnvData(configData: Record<string, any>) {
2835
if (configData) {
2936
config.API_URL = configData.API_URL || "";
@@ -41,7 +48,7 @@ export function getConfigData() {
4148

4249
return { ...config };
4350
}
44-
export async function getUserInfo(): Promise<UserInfo[]> {
51+
export async function getUserInfo(): Promise<UserInfo> {
4552
try {
4653
const response = await fetch("/.auth/me");
4754
console.log("Fetching user info from: ", "/.auth/me");
@@ -50,12 +57,25 @@ export async function getUserInfo(): Promise<UserInfo[]> {
5057
console.log(
5158
"No identity provider found. Access to chat will be blocked."
5259
);
53-
return [];
60+
return {} as UserInfo;
5461
}
5562
const payload = await response.json();
56-
return payload;
63+
console.log("User info payload: ", payload[0]);
64+
const userInfo: UserInfo = {
65+
access_token: payload[0].access_token || "",
66+
expires_on: payload[0].expires_on || "",
67+
id_token: payload[0].id_token || "",
68+
provider_name: payload[0].provider_name || "",
69+
user_claims: payload[0].user_claims || [],
70+
user_email: payload[0].user_id || "",
71+
user_first_last_name: payload[0].user_claims?.find((claim: claim) => claim.typ === 'name')?.val || "",
72+
user_id: payload[0].user_claims?.find((claim: claim) => claim.typ === 'http://schemas.microsoft.com/identity/claims/objectidentifier')?.val || '',
73+
};
74+
console.log("User info: ", userInfo);
75+
return userInfo;
5776
} catch (e) {
58-
return [];
77+
console.error("Error fetching user info: ", e);
78+
return {} as UserInfo;
5979
}
6080
}
6181
export function getApiUrl() {
@@ -73,9 +93,27 @@ export function getApiUrl() {
7393

7494
return API_URL;
7595
}
96+
export function getUserInfoGlobal() {
97+
if (!USER_INFO) {
98+
// Check if window.userInfo exists
99+
if (window.userInfo) {
100+
setUserInfoGlobal(window.userInfo);
101+
}
102+
}
103+
104+
if (!USER_INFO) {
105+
console.info('User info not yet configured');
106+
return null;
107+
}
108+
109+
return USER_INFO;
110+
}
76111

77112
export function getUserId(): string {
78-
// USER_ID = window.userInfo && window.userInfo[0] && window.userInfo[0].user_id ? window.userInfo[0].user_id : null;
113+
// USER_ID = getUserInfoGlobal()?.user_id || null;
114+
if (!USER_ID) {
115+
USER_ID = getUserInfoGlobal()?.user_id || null;
116+
}
79117
const userId = USER_ID ?? "00000000-0000-0000-0000-000000000000";
80118
return userId;
81119
}

src/frontend_react/src/auth/index.ts

Whitespace-only changes.

src/frontend_react/src/components/content/PlanPanelLeft.tsx

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@ import {
1616
import TaskList from "./TaskList";
1717
import { useCallback, useEffect, useState } from "react";
1818
import { useNavigate, useParams } from "react-router-dom";
19-
import { PlanPanelLefProps, PlanWithSteps, Task } from "@/models";
19+
import { PlanPanelLefProps, PlanWithSteps, Task, UserInfo } from "@/models";
2020
import { apiService } from "@/api";
2121
import { TaskService } from "@/services";
2222
import MsftColor from "@/coral/imports/MsftColor";
2323
import ContosoLogo from "../../coral/imports/ContosoLogo";
2424
import "../../styles/PlanPanelLeft.css";
2525
import PanelFooter from "@/coral/components/Panels/PanelFooter";
2626
import PanelUserCard from "../../coral/components/Panels/UserCard";
27+
import { getUserInfoGlobal } from "@/api/config";
2728

2829
const PlanPanelLeft: React.FC<PlanPanelLefProps> = ({ onNewTaskButton }) => {
2930
const { dispatchToast } = useToastController("toast");
@@ -35,7 +36,7 @@ const PlanPanelLeft: React.FC<PlanPanelLefProps> = ({ onNewTaskButton }) => {
3536
const [plans, setPlans] = useState<PlanWithSteps[] | null>(null);
3637
const [plansLoading, setPlansLoading] = useState<boolean>(false);
3738
const [plansError, setPlansError] = useState<Error | null>(null);
38-
39+
const [userInfo, setUserInfo] = useState<UserInfo | null>(getUserInfoGlobal());
3940
// Fetch plans
4041
const loadPlansData = useCallback(async (forceRefresh = false) => {
4142
try {
@@ -123,15 +124,13 @@ const PlanPanelLeft: React.FC<PlanPanelLefProps> = ({ onNewTaskButton }) => {
123124
/>
124125

125126
<PanelFooter>
126-
<PanelUserCard
127-
name="Pepper Hayuki"
128-
129-
// image={{ src: "https://fabricweb.azureedge.net/fabric-website/assets/images/avatar/KatriAthokas.jpg" }}
130-
// shape="square"
131-
// badge={{ status: 'available' }}
132-
// color="colorful"
133-
size={32} // Default=32
134-
/>
127+
{userInfo && (
128+
<PanelUserCard
129+
name={userInfo.user_first_last_name || ""}
130+
alias={userInfo.user_email || ""}
131+
size={32} // Default=32
132+
/>
133+
)}
135134
</PanelFooter>
136135
</PanelLeft>
137136
</div>

src/frontend_react/src/index.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,14 @@ import './index.css';
44
import App from './App';
55
import reportWebVitals from './reportWebVitals';
66
import { FluentProvider, teamsLightTheme, teamsDarkTheme } from "@fluentui/react-components";
7-
import { setEnvData, setApiUrl, config as defaultConfig, toBoolean, getUserInfo } from './api/config';
7+
import { setEnvData, setApiUrl, config as defaultConfig, toBoolean, getUserInfo, setUserInfoGlobal } from './api/config';
88
import { UserInfo } from './models';
99
const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement);
1010

1111
const AppWrapper = () => {
1212
// State to store the current theme
1313
const [isConfigLoaded, setIsConfigLoaded] = useState(false);
1414
const [isUserInfoLoaded, setIsUserInfoLoaded] = useState(false);
15-
const [userInfo, setUserInfo] = useState<UserInfo[] | null>(null);
1615
const [isDarkMode, setIsDarkMode] = useState(
1716
window.matchMedia("(prefers-color-scheme: dark)").matches
1817
);
@@ -36,9 +35,9 @@ const AppWrapper = () => {
3635
setEnvData(config);
3736
setApiUrl(config.API_URL);
3837
setConfig(config);
39-
let defaultUserInfo = config.ENABLE_AUTH ? await getUserInfo() : [] as UserInfo[];
38+
let defaultUserInfo = config.ENABLE_AUTH ? await getUserInfo() : ({} as UserInfo);
4039
window.userInfo = defaultUserInfo;
41-
setUserInfo(defaultUserInfo);
40+
setUserInfoGlobal(defaultUserInfo);
4241

4342
} catch (error) {
4443
console.info("frontend config did not load from python", error);

src/frontend_react/src/models/auth.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,12 @@ export type UserInfo = {
44
id_token: string;
55
provider_name: string;
66
user_claims: any[];
7+
user_email: string;
8+
user_first_last_name: string;
79
user_id: string;
10+
};
11+
12+
export type claim = {
13+
typ: string;
14+
val: string;
815
};

0 commit comments

Comments
 (0)