Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 5 additions & 5 deletions src/api/functions/entraId.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
EntraInvitationResponse,
ProfilePatchRequest,
} from "../../common/types/iam.js";
import { UserProfileDataBase } from "common/types/msGraphApi.js";
import { UserProfileData } from "common/types/msGraphApi.js";
import { SecretsManagerClient } from "@aws-sdk/client-secrets-manager";
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { checkPaidMembershipFromTable } from "./membership.js";
Expand Down Expand Up @@ -366,15 +366,15 @@ export async function listGroupMembers(
* @param token - Entra ID token authorized to perform this action.
* @param userId - The user ID to fetch the profile for.
* @throws {EntraUserError} If fetching the user profile fails.
* @returns {Promise<UserProfileDataBase>} The user's profile information.
* @returns {Promise<UserProfileData>} The user's profile information.
*/
export async function getUserProfile(
token: string,
email: string,
): Promise<UserProfileDataBase> {
): Promise<UserProfileData> {
const userId = await resolveEmailToOid(token, email);
try {
const url = `https://graph.microsoft.com/v1.0/users/${userId}?$select=userPrincipalName,givenName,surname,displayName,otherMails,mail`;
const url = `https://graph.microsoft.com/v1.0/users/${userId}?$select=userPrincipalName,givenName,surname,displayName,mail`;
const response = await fetch(url, {
method: "GET",
headers: {
Expand All @@ -392,7 +392,7 @@ export async function getUserProfile(
email,
});
}
return (await response.json()) as UserProfileDataBase;
return (await response.json()) as UserProfileData;
} catch (error) {
if (error instanceof EntraFetchError) {
throw error;
Expand Down
1 change: 1 addition & 0 deletions src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ async function init(prettyPrint: boolean = false) {
);
await app.register(cors, {
origin: app.environmentConfig.ValidCorsOrigins,
methods: ["GET", "HEAD", "POST", "PATCH", "DELETE"],
});
app.log.info("Initialized new Fastify instance...");
return app;
Expand Down
2 changes: 2 additions & 0 deletions src/api/routes/iam.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ const iamRoutes: FastifyPluginAsync = async (fastify, _options) => {
const entraIdToken = await getEntraIdToken(
await getAuthorizedClients(),
fastify.environmentConfig.AadValidClientId,
undefined,
genericConfig.EntraSecretName,
);
await patchUserProfile(
entraIdToken,
Expand Down
1 change: 0 additions & 1 deletion src/common/types/iam.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ export const entraProfilePatchRequest = z.object({
givenName: z.string().min(1),
surname: z.string().min(1),
mail: z.string().email(),
otherMails: z.array(z.string()).min(1),
});

export type ProfilePatchRequest = z.infer<typeof entraProfilePatchRequest>;
7 changes: 1 addition & 6 deletions src/common/types/msGraphApi.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
export interface UserProfileDataBase {
export interface UserProfileData {
userPrincipalName: string;
displayName?: string;
givenName?: string;
surname?: string;
mail?: string;
otherMails?: string[];
}

export interface UserProfileData extends UserProfileDataBase {
discordUsername?: string;
}
35 changes: 8 additions & 27 deletions src/ui/pages/profile/ManageProfile.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from "react";
import { Container, Title } from "@mantine/core";
import { AuthGuard } from "@ui/components/AuthGuard";
import { useApi } from "@ui/util/api";
import { UserProfileData, UserProfileDataBase } from "@common/types/msGraphApi";
import { UserProfileData } from "@common/types/msGraphApi";
import { ManageProfileComponent } from "./ManageProfileComponent";
import { useNavigate, useSearchParams } from "react-router-dom";
import { useAuth } from "@ui/components/AuthContext";
Expand All @@ -19,43 +19,24 @@ export const ManageProfilePage: React.FC = () => {
const getProfile = async () => {
const raw = (
await graphApi.get(
"/v1.0/me?$select=userPrincipalName,givenName,surname,displayName,otherMails,mail",
"/v1.0/me?$select=userPrincipalName,givenName,surname,displayName,mail",
)
).data as UserProfileDataBase;
const discordUsername = raw.otherMails?.filter((x) =>
x.endsWith("@discord"),
);
const enhanced = raw as UserProfileData;
if (discordUsername?.length === 1) {
enhanced.discordUsername = discordUsername[0].replace("@discord", "");
enhanced.otherMails = enhanced.otherMails?.filter(
(x) => !x.endsWith("@discord"),
);
}
const normalizedName = transformCommaSeperatedName(
enhanced.displayName || "",
);
const extractedFirstName =
enhanced.givenName || normalizedName.split(" ")[0];
let extractedLastName = enhanced.surname || normalizedName.split(" ")[1];
if (!enhanced.surname) {
).data as UserProfileData;
const normalizedName = transformCommaSeperatedName(raw.displayName || "");
const extractedFirstName = raw.givenName || normalizedName.split(" ")[0];
let extractedLastName = raw.surname || normalizedName.split(" ")[1];
if (!raw.surname) {
extractedLastName = extractedLastName.slice(1, extractedLastName.length);
}
return {
...enhanced,
...raw,
displayName: normalizedName,
givenName: extractedFirstName,
surname: extractedLastName,
};
};

const setProfile = async (data: UserProfileData) => {
const newOtherEmails = [data.mail || data.userPrincipalName];
if (data.discordUsername && data.discordUsername !== "") {
newOtherEmails.push(`${data.discordUsername}@discord`);
}
data.otherMails = newOtherEmails;
delete data.discordUsername;
const response = await api.patch("/api/v1/iam/profile", data);
if (response.status < 299 && firstTime) {
setLoginStatus(true);
Expand Down
9 changes: 0 additions & 9 deletions src/ui/pages/profile/ManageProfileComponent.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ describe("ManageProfileComponent tests", () => {
givenName: "John",
surname: "Doe",
mail: "[email protected]",
discordUsername: "johndoe#1234",
});
const setProfile = vi.fn();

Expand All @@ -63,9 +62,6 @@ describe("ManageProfileComponent tests", () => {
expect(screen.getByTestId("edit-email")).toHaveValue(
"[email protected]",
);
expect(screen.getByTestId("edit-discordUsername")).toHaveValue(
"johndoe#1234",
);
});

it("handles profile fetch failure gracefully", async () => {
Expand Down Expand Up @@ -94,7 +90,6 @@ describe("ManageProfileComponent tests", () => {
givenName: "John",
surname: "Doe",
mail: "[email protected]",
discordUsername: "",
});
const setProfile = vi.fn().mockResolvedValue({});

Expand All @@ -105,7 +100,6 @@ describe("ManageProfileComponent tests", () => {
// Edit fields
await user.clear(screen.getByTestId("edit-displayName"));
await user.type(screen.getByTestId("edit-displayName"), "Jane Doe");
await user.type(screen.getByTestId("edit-discordUsername"), "janedoe#5678");

// Save changes
const saveButton = screen.getByRole("button", { name: "Save" });
Expand All @@ -116,7 +110,6 @@ describe("ManageProfileComponent tests", () => {
givenName: "John",
surname: "Doe",
mail: "[email protected]",
discordUsername: "janedoe#5678",
});

expect(notificationsMock).toHaveBeenCalledWith(
Expand All @@ -136,7 +129,6 @@ describe("ManageProfileComponent tests", () => {
givenName: "",
surname: "",
mail: "[email protected]",
discordUsername: "",
});
const setProfile = vi.fn();

Expand All @@ -156,7 +148,6 @@ describe("ManageProfileComponent tests", () => {
givenName: "John",
surname: "Doe",
mail: "[email protected]",
discordUsername: "",
});
const setProfile = vi
.fn()
Expand Down
14 changes: 2 additions & 12 deletions src/ui/pages/profile/ManageProfileComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ export const ManageProfileComponent: React.FC<ManageProfileComponentProps> = ({
}}
>
<TextInput
label="Full Name"
label="Display Name"
description="This is how your name will be shown accross all ACM @ UIUC services."
value={userProfile?.displayName || ""}
onChange={(e) =>
setUserProfile(
Expand Down Expand Up @@ -144,17 +145,6 @@ export const ManageProfileComponent: React.FC<ManageProfileComponentProps> = ({
data-testid="edit-email"
/>

<TextInput
label="Discord Username"
value={userProfile?.discordUsername || ""}
onChange={(e) =>
setUserProfile(
(prev) => prev && { ...prev, discordUsername: e.target.value },
)
}
data-testid="edit-discordUsername"
/>

<Group mt="md">
<Button
type="submit"
Expand Down
Loading