mirror of
https://github.com/stack-auth/stack.git
synced 2026-06-13 21:01:21 +08:00
updated image profile url
This commit is contained in:
parent
0a3e088578
commit
1b9d1b01fd
@ -3,3 +3,6 @@ ALTER TABLE "ProjectUser" ADD COLUMN "profileImageKey" TEXT;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Team" ADD COLUMN "profileImageKey" TEXT;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "TeamMember" ADD COLUMN "profileImageKey" TEXT;
|
||||
|
||||
@ -105,8 +105,13 @@ model TeamMember {
|
||||
teamId String @db.Uuid
|
||||
|
||||
// This will override the displayName of the user in this team.
|
||||
displayName String?
|
||||
displayName String?
|
||||
|
||||
// This will override the profileImageUrl of the user in this team.
|
||||
// if profileImageKey is set, we fetch the image from S3
|
||||
// otherwise if the profileImageUrl is set, we send the user to the URL.
|
||||
// if neither is set, we return null.
|
||||
profileImageKey String?
|
||||
profileImageUrl String?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { ensureTeamExists, ensureTeamMembershipExists, ensureUserExists, ensureUserTeamPermissionExists } from "@/lib/request-checks";
|
||||
import { getPrismaClientForTenancy, retryTransaction } from "@/prisma-client";
|
||||
import { createCrudHandlers } from "@/route-handlers/crud-handler";
|
||||
import { uploadAndGetImageUpdateInfo } from "@/s3";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { KnownErrors } from "@stackframe/stack-shared";
|
||||
import { teamMemberProfilesCrud } from "@stackframe/stack-shared/dist/interface/crud/team-member-profiles";
|
||||
@ -149,7 +150,7 @@ export const teamMemberProfilesCrudHandlers = createLazyProxy(() => createCrudHa
|
||||
},
|
||||
data: {
|
||||
displayName: data.display_name,
|
||||
profileImageUrl: data.profile_image_url,
|
||||
...await uploadAndGetImageUpdateInfo(data.profile_image_url, "team-member-profile-images")
|
||||
},
|
||||
include: fullInclude,
|
||||
});
|
||||
|
||||
@ -2,6 +2,7 @@ import { ensureTeamExists, ensureTeamMembershipExists, ensureUserExists, ensureU
|
||||
import { sendTeamCreatedWebhook, sendTeamDeletedWebhook, sendTeamUpdatedWebhook } from "@/lib/webhooks";
|
||||
import { getPrismaClientForTenancy, retryTransaction } from "@/prisma-client";
|
||||
import { createCrudHandlers } from "@/route-handlers/crud-handler";
|
||||
import { uploadAndGetImageUpdateInfo } from "@/s3";
|
||||
import { runAsynchronouslyAndWaitUntil } from "@/utils/vercel";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { KnownErrors } from "@stackframe/stack-shared";
|
||||
@ -17,7 +18,7 @@ export function teamPrismaToCrud(prisma: Prisma.TeamGetPayload<{}>) {
|
||||
return {
|
||||
id: prisma.teamId,
|
||||
display_name: prisma.displayName,
|
||||
profile_image_url: prisma.profileImageUrl,
|
||||
profile_image_url: prisma.profileImageKey ? getS3PublicUrl(prisma.profileImageKey) : prisma.profileImageUrl,
|
||||
created_at_millis: prisma.createdAt.getTime(),
|
||||
client_metadata: prisma.clientMetadata,
|
||||
client_read_only_metadata: prisma.clientReadOnlyMetadata,
|
||||
@ -77,10 +78,10 @@ export const teamsCrudHandlers = createLazyProxy(() => createCrudHandlers(teamsC
|
||||
mirroredProjectId: auth.project.id,
|
||||
mirroredBranchId: auth.branchId,
|
||||
tenancyId: auth.tenancy.id,
|
||||
profileImageUrl: data.profile_image_url,
|
||||
clientMetadata: data.client_metadata === null ? Prisma.JsonNull : data.client_metadata,
|
||||
clientReadOnlyMetadata: data.client_read_only_metadata === null ? Prisma.JsonNull : data.client_read_only_metadata,
|
||||
serverMetadata: data.server_metadata === null ? Prisma.JsonNull : data.server_metadata,
|
||||
...await uploadAndGetImageUpdateInfo(data.profile_image_url, "team-profile-images")
|
||||
},
|
||||
});
|
||||
|
||||
@ -161,10 +162,10 @@ export const teamsCrudHandlers = createLazyProxy(() => createCrudHandlers(teamsC
|
||||
},
|
||||
data: {
|
||||
displayName: data.display_name,
|
||||
profileImageUrl: data.profile_image_url,
|
||||
clientMetadata: data.client_metadata === null ? Prisma.JsonNull : data.client_metadata,
|
||||
clientReadOnlyMetadata: data.client_read_only_metadata === null ? Prisma.JsonNull : data.client_read_only_metadata,
|
||||
serverMetadata: data.server_metadata === null ? Prisma.JsonNull : data.server_metadata,
|
||||
...await uploadAndGetImageUpdateInfo(data.profile_image_url, "team-profile-images")
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@ -7,7 +7,7 @@ import { PrismaTransaction } from "@/lib/types";
|
||||
import { sendTeamMembershipDeletedWebhook, sendUserCreatedWebhook, sendUserDeletedWebhook, sendUserUpdatedWebhook } from "@/lib/webhooks";
|
||||
import { RawQuery, getPrismaClientForSourceOfTruth, getPrismaClientForTenancy, getPrismaSchemaForSourceOfTruth, getPrismaSchemaForTenancy, globalPrismaClient, rawQuery, retryTransaction, sqlQuoteIdent } from "@/prisma-client";
|
||||
import { createCrudHandlers } from "@/route-handlers/crud-handler";
|
||||
import { checkImageString, getS3PublicUrl, uploadBase64Image } from "@/s3";
|
||||
import { getS3PublicUrl, uploadAndGetImageUpdateInfo } from "@/s3";
|
||||
import { log } from "@/utils/telemetry";
|
||||
import { runAsynchronouslyAndWaitUntil } from "@/utils/vercel";
|
||||
import { BooleanTrue, Prisma } from "@prisma/client";
|
||||
@ -324,7 +324,7 @@ export function getUserQuery(projectId: string, branchId: string, userId: string
|
||||
selected_team: row.SelectedTeamMember ? {
|
||||
id: row.SelectedTeamMember.Team.teamId,
|
||||
display_name: row.SelectedTeamMember.Team.displayName,
|
||||
profile_image_url: row.SelectedTeamMember.Team.profileImageUrl,
|
||||
profile_image_url: row.SelectedTeamMember.Team.profileImageKey ? getS3PublicUrl(row.SelectedTeamMember.Team.profileImageKey) : 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,
|
||||
@ -347,37 +347,6 @@ export function getUserIfOnGlobalPrismaClientQuery(projectId: string, branchId:
|
||||
};
|
||||
}
|
||||
|
||||
async function getProfileImageUrl(input: string | null | undefined) {
|
||||
let profileImageKey: string | null | undefined = undefined;
|
||||
let profileImageUrl: string | null | undefined = undefined;
|
||||
if (input) {
|
||||
const checkResult = checkImageString(input);
|
||||
if (checkResult.isBase64Image) {
|
||||
const { key } = await uploadBase64Image({ input, folderName: "profile-images" });
|
||||
profileImageKey = key;
|
||||
} else if (checkResult.isUrl) {
|
||||
profileImageUrl = input;
|
||||
} else {
|
||||
throw new StatusError(StatusError.BadRequest, "Invalid profile image URL");
|
||||
}
|
||||
|
||||
return {
|
||||
profileImageKey,
|
||||
profileImageUrl,
|
||||
};
|
||||
} else if (input === null) {
|
||||
return {
|
||||
profileImageKey: null,
|
||||
profileImageUrl: null,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
profileImageKey: undefined,
|
||||
profileImageUrl: undefined,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export async function getUser(options: { userId: string } & ({ projectId: string, branchId: string } | { tenancyId: string })) {
|
||||
let projectId, branchId;
|
||||
if (!("tenancyId" in options)) {
|
||||
@ -520,7 +489,7 @@ export const usersCrudHandlers = createLazyProxy(() => createCrudHandlers(usersC
|
||||
serverMetadata: data.server_metadata === null ? Prisma.JsonNull : data.server_metadata,
|
||||
totpSecret: data.totp_secret_base64 == null ? data.totp_secret_base64 : Buffer.from(decodeBase64(data.totp_secret_base64)),
|
||||
isAnonymous: data.is_anonymous ?? false,
|
||||
...await getProfileImageUrl(data.profile_image_url)
|
||||
...await uploadAndGetImageUpdateInfo(data.profile_image_url, "user-profile-images")
|
||||
},
|
||||
include: userFullInclude,
|
||||
});
|
||||
@ -976,7 +945,7 @@ export const usersCrudHandlers = createLazyProxy(() => createCrudHandlers(usersC
|
||||
requiresTotpMfa: data.totp_secret_base64 === undefined ? undefined : (data.totp_secret_base64 !== null),
|
||||
totpSecret: data.totp_secret_base64 == null ? data.totp_secret_base64 : Buffer.from(decodeBase64(data.totp_secret_base64)),
|
||||
isAnonymous: data.is_anonymous ?? undefined,
|
||||
...await getProfileImageUrl(data.profile_image_url)
|
||||
...await uploadAndGetImageUpdateInfo(data.profile_image_url, "user-profile-images")
|
||||
},
|
||||
include: userFullInclude,
|
||||
});
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
|
||||
import { getEnvVariable } from "@stackframe/stack-shared/dist/utils/env";
|
||||
import { StatusError } from "@stackframe/stack-shared/dist/utils/errors";
|
||||
import { parseBase64Image } from "./lib/images";
|
||||
|
||||
export const s3 = new S3Client({
|
||||
@ -52,3 +53,37 @@ export function checkImageString(input: string) {
|
||||
isUrl: /^https?:\/\//.test(input),
|
||||
};
|
||||
}
|
||||
|
||||
export async function uploadAndGetImageUpdateInfo(
|
||||
input: string | null | undefined,
|
||||
folderName: 'user-profile-images' | 'team-profile-images' | 'team-member-profile-images'
|
||||
) {
|
||||
let profileImageKey: string | null | undefined = undefined;
|
||||
let profileImageUrl: string | null | undefined = undefined;
|
||||
if (input) {
|
||||
const checkResult = checkImageString(input);
|
||||
if (checkResult.isBase64Image) {
|
||||
const { key } = await uploadBase64Image({ input, folderName });
|
||||
profileImageKey = key;
|
||||
} else if (checkResult.isUrl) {
|
||||
profileImageUrl = input;
|
||||
} else {
|
||||
throw new StatusError(StatusError.BadRequest, "Invalid profile image URL");
|
||||
}
|
||||
|
||||
return {
|
||||
profileImageKey,
|
||||
profileImageUrl,
|
||||
};
|
||||
} else if (input === null) {
|
||||
return {
|
||||
profileImageKey: null,
|
||||
profileImageUrl: null,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
profileImageKey: undefined,
|
||||
profileImageUrl: undefined,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user