Skip to content

Commit

Permalink
Fix users query
Browse files Browse the repository at this point in the history
  • Loading branch information
N2D4 committed Dec 27, 2024
1 parent 8f710fb commit 871dbb9
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 23 deletions.
16 changes: 15 additions & 1 deletion apps/backend/scripts/verify-data-integrity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ async function main() {
for (let i = 0; i < projects.length; i++) {
const projectId = projects[i].id;
await recurse(`[project ${i + 1}/${projects.length}] ${projectId} ${projects[i].displayName}`, async (recurse) => {
await Promise.all([
const [currentProject, users] = await Promise.all([
expectStatusCode(200, `/api/v1/projects/current`, {
method: "GET",
headers: {
Expand All @@ -88,6 +88,20 @@ async function main() {
},
}),
]);

for (let j = 0; j < users.items.length; j++) {
const user = users.items[j];
await recurse(`[user ${j + 1}/${users.items.length}] ${user.display_name ?? user.primary_email}`, async (recurse) => {
await expectStatusCode(200, `/api/v1/users/${user.id}`, {
method: "GET",
headers: {
"x-stack-project-id": projectId,
"x-stack-access-type": "admin",
"x-stack-development-override-key": getEnvVariable("STACK_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY"),
},
});
});
}
});
}

Expand Down
18 changes: 9 additions & 9 deletions apps/backend/src/app/api/v1/users/crud.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -352,15 +352,15 @@ export function getUserQuery(projectId: string, userId: string): RawQuery<UsersC
const otpAuth = row.AuthMethods.find((m: any) => m.OtpAuthMethod);
const passkeyAuth = row.AuthMethods.find((m: any) => m.PasskeyAuthMethod);

if (row.SelectedTeamMember && !row.SelectedTeamMember.team) {
if (row.SelectedTeamMember && !row.SelectedTeamMember.Team) {
// This seems to happen in production much more often than it should, so let's log some information for debugging
captureError("selected-team-member-and-team-consistency", new StackAssertionError("Selected team member has no team? Ignoring it", { row }));
row.SelectedTeamMember = null;
}

return {
id: row.projectUserId,
display_name: row.displayName,
display_name: row.displayName || null,
primary_email: primaryEmailContactChannel?.value || null,
primary_email_verified: primaryEmailContactChannel?.isVerified || false,
primary_email_auth_enabled: primaryEmailContactChannel?.usedForAuth === 'TRUE' ? true : false,
Expand All @@ -381,13 +381,13 @@ export function getUserQuery(projectId: string, userId: string): RawQuery<UsersC
})),
selected_team_id: row.SelectedTeamMember?.teamId ?? null,
selected_team: row.SelectedTeamMember ? {
id: row.SelectedTeamMember.team.teamId,
display_name: row.SelectedTeamMember.team.displayName,
profile_image_url: row.SelectedTeamMember.team.profileImageUrl,
created_at_millis: row.SelectedTeamMember.team.createdAt.getTime(),
client_metadata: row.SelectedTeamMember.team.clientMetadata,
client_read_only_metadata: row.SelectedTeamMember.team.clientReadOnlyMetadata,
server_metadata: row.SelectedTeamMember.team.serverMetadata,
id: row.SelectedTeamMember.Team.teamId,
display_name: row.SelectedTeamMember.Team.displayName,
profile_image_url: row.SelectedTeamMember.Team.profileImageUrl,
created_at_millis: new Date(row.SelectedTeamMember.Team.createdAt + "Z").getTime(),
client_metadata: row.SelectedTeamMember.Team.clientMetadata,
client_read_only_metadata: row.SelectedTeamMember.Team.clientReadOnlyMetadata,
server_metadata: row.SelectedTeamMember.Team.serverMetadata,
} : null,
last_active_at_millis: row.lastActiveAt ? new Date(row.lastActiveAt + "Z").getTime() : new Date(row.createdAt + "Z").getTime(),
};
Expand Down
11 changes: 0 additions & 11 deletions apps/backend/src/route-handlers/smart-request.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -163,17 +163,6 @@ const parseAuth = withTraceSpan('smart request parseAuth', async (req: NextReque
return result.data.userId;
};

const extractUserFromAccessToken = async (options: { token: string, projectId: string }) => {
const userId = await extractUserIdFromAccessToken(options);
const user = await getUser({ projectId: options.projectId, userId });
if (!user) {
// this is the case when access token is still valid, but the user is deleted from the database
throw new KnownErrors.AccessTokenExpired();
}

return user;
};

const extractUserFromAdminAccessToken = async (options: { token: string, projectId: string }) => {
const result = await decodeAccessToken(options.token);
if (result.status === "error") {
Expand Down
17 changes: 15 additions & 2 deletions apps/e2e/tests/backend/endpoints/api/v1/users.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { generateSecureRandomString } from "@stackframe/stack-shared/dist/utils/crypto";
import { describe } from "vitest";
import { it } from "../../../../helpers";
import { Auth, InternalProjectKeys, Project, backendContext, bumpEmailAddress, createMailbox, niceBackendFetch } from "../../../backend-helpers";
import { Auth, InternalProjectKeys, Project, Team, backendContext, bumpEmailAddress, createMailbox, niceBackendFetch } from "../../../backend-helpers";

describe("without project access", () => {
backendContext.set({
Expand Down Expand Up @@ -615,7 +615,20 @@ describe("with client access", () => {
`);
});

it.todo("should be able to set selected team id, updating the selected team object");
it("should be able to updated selected team", async ({ expect }) => {
await Auth.Otp.signIn();
const { teamId } = await Team.createAndAddCurrent({});
const response1 = await niceBackendFetch("/api/v1/users/me");
expect(response1).toMatchInlineSnapshot();

Check failure on line 622 in apps/e2e/tests/backend/endpoints/api/v1/users.test.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

tests/backend/endpoints/api/v1/users.test.ts > with client access > should be able to updated selected team

Error: Snapshot `with client access > should be able to updated selected team 3` mismatched ❯ tests/backend/endpoints/api/v1/users.test.ts:622:23
const response2 = await niceBackendFetch("/api/v1/users/me", {
method: "PATCH",
body: {
selected_team_id: teamId,
},
});
expect(response2).toMatchInlineSnapshot();
expect(response2.body.selected_team_id).toEqual(teamId);
});
});

describe("with server access", () => {
Expand Down

0 comments on commit 871dbb9

Please sign in to comment.