Skip to content

Commit

Permalink
Disallow editing of user properties that come from Cognito
Browse files Browse the repository at this point in the history
  • Loading branch information
benmartin-coforma committed Jan 21, 2025
1 parent 5c799ac commit 29e5ea8
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 7 deletions.
33 changes: 30 additions & 3 deletions services/app-api/handlers/users/post/updateUser.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,20 @@ export const main = handler(async (event, context) => {
await authorizeAdmin(event);
}

assertPayloadIsValid(data);

const params = {
TableName:
process.env.AUTH_USER_TABLE_NAME ?? process.env.AuthUserTableName,
Key: {
userId: currentUser["Items"][0].userId,
},
UpdateExpression:
"SET username = :username, #r = :role, states = :states, lastLogin = :lastLogin, usernameSub = :usernameSub",
"SET #r = :role, states = :states, lastLogin = :lastLogin",
ExpressionAttributeValues: {
":username": data.username,
":role": data.role,
":states": data.states ?? "",
":lastLogin": new Date().toISOString(),
":usernameSub": data.usernameSub ?? null,
},
ExpressionAttributeNames: {
"#r": "role",
Expand All @@ -51,3 +51,30 @@ function modifyingAnythingButAnEmptyStateList(incomingUser, existingUser) {
if (existingUser.states.length > 0) return true;
return false;
}

function assertPayloadIsValid (data) {
if (!data) {
throw new Error("User update payload is missing");
}

if (typeof data.role !== "string" || !data.role) {
throw new Error("Invalid user role - must be a nonempty string");
}
if (!["admin", "business", "state"].includes(data.role)) {
throw new Error("Invalid user role - must be an existing role");
}

if (data.states && data.states !== "null") {
if (!Array.isArray(data.states)) {
throw new Error("Invalid user states - must be an array");
}
for (let state of data.states) {
if (typeof state !== "string") {
throw new Error("Invalid user states - must be strings");
}
if (!/^[A-Z]{2}$/.test(state)) {
throw new Error("Invalid user states - must be 2-letter abbreviations");
}
}
}
}
1 change: 1 addition & 0 deletions services/ui-src/src/components/EditUser/EditUser.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ const EditUser = ({ stateList }) => {
value={user.username}
type="text"
onChange={e => updateLocalUser(e, "username")}
disabled={true}
name="username"
className="form-input"
/>
Expand Down
9 changes: 5 additions & 4 deletions services/ui-src/src/components/EditUser/EditUser.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -144,16 +144,17 @@ describe("Test EditUser.js", () => {
renderComponent(mockUser);
await waitFor(() => expect(getUserById).toHaveBeenCalled());

const table = screen.getByTestId("table");
const usernameInput = table.querySelector(".userName input");
userEvent.type(usernameInput, "TY");
const roleDropdown = screen.getByPlaceholderText("Select a Role");
userEvent.click(roleDropdown);
const adminOption = screen.getByText("Admin User");
userEvent.click(adminOption);

const saveButton = screen.getByText("Update User", { selector: "button" });
userEvent.click(saveButton);

expect(updateUser).toHaveBeenCalledWith(
expect.objectContaining({
username: "QWERTY"
role: "admin",
})
);
});
Expand Down

0 comments on commit 29e5ea8

Please sign in to comment.