{
if (checked) {
setTwoFactorModalOpen(true);
diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/profile/components/DeleteAccount.tsx b/apps/web/app/(app)/environments/[environmentId]/settings/profile/components/DeleteAccount.tsx
index da850d4c08..5ef39b8f88 100644
--- a/apps/web/app/(app)/environments/[environmentId]/settings/profile/components/DeleteAccount.tsx
+++ b/apps/web/app/(app)/environments/[environmentId]/settings/profile/components/DeleteAccount.tsx
@@ -11,7 +11,7 @@ import { signOut } from "next-auth/react";
import Image from "next/image";
import { Dispatch, SetStateAction, useState } from "react";
import toast from "react-hot-toast";
-import { deleteProfileAction } from "../actions";
+import { deleteUserAction } from "../actions";
export function EditAvatar({ session }) {
return (
@@ -52,7 +52,7 @@ function DeleteAccountModal({ setOpen, open, session }: DeleteAccountModalProps)
const deleteAccount = async () => {
try {
setDeleting(true);
- await deleteProfileAction();
+ await deleteUserAction();
await signOut();
await formbricksLogout();
} catch (error) {
diff --git a/apps/web/app/(app)/environments/[environmentId]/settings/profile/components/EditName.tsx b/apps/web/app/(app)/environments/[environmentId]/settings/profile/components/EditName.tsx
index 77be58026d..43999bb0f2 100644
--- a/apps/web/app/(app)/environments/[environmentId]/settings/profile/components/EditName.tsx
+++ b/apps/web/app/(app)/environments/[environmentId]/settings/profile/components/EditName.tsx
@@ -5,14 +5,14 @@ import { Input } from "@formbricks/ui/Input";
import { Label } from "@formbricks/ui/Label";
import { useForm, SubmitHandler } from "react-hook-form";
import toast from "react-hot-toast";
-import { updateProfileAction } from "../actions";
-import { TProfile } from "@formbricks/types/profile";
+import { updateUserAction } from "../actions";
+import { TUser } from "@formbricks/types/user";
type FormData = {
name: string;
};
-export function EditName({ profile }: { profile: TProfile }) {
+export function EditName({ user }: { user: TUser }) {
const {
register,
handleSubmit,
@@ -20,7 +20,7 @@ export function EditName({ profile }: { profile: TProfile }) {
watch,
} = useForm();
- const nameValue = watch("name", profile.name || "");
+ const nameValue = watch("name", user.name || "");
const isNotEmptySpaces = (value: string) => value.trim() !== "";
const onSubmit: SubmitHandler = async (data) => {
@@ -30,11 +30,11 @@ export function EditName({ profile }: { profile: TProfile }) {
toast.error("Please enter at least one character");
return;
}
- if (data.name === profile.name) {
+ if (data.name === user.name) {
toast.success("This is already your name");
return;
}
- await updateProfileAction({ name: data.name });
+ await updateUserAction({ name: data.name });
toast.success("Your name was updated successfully");
} catch (error) {
toast.error(`Error: ${error.message}`);
@@ -48,13 +48,13 @@ export function EditName({ profile }: { profile: TProfile }) {
-
+
{survey.type === "link" && (
-
+
)}
{!isViewer &&
(environment?.widgetSetupCompleted || survey.type === "link") &&
@@ -92,7 +92,7 @@ const SummaryHeader = ({
survey={survey}
webAppUrl={webAppUrl}
product={product}
- profile={profile}
+ user={user}
/>
>
@@ -177,7 +177,7 @@ const SummaryHeader = ({
survey={survey}
webAppUrl={webAppUrl}
product={product}
- profile={profile}
+ user={user}
/>
);
diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/components/SurveyList.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/components/SurveyList.tsx
index 95017fd1dd..871ae1c198 100644
--- a/apps/web/app/(app)/environments/[environmentId]/surveys/components/SurveyList.tsx
+++ b/apps/web/app/(app)/environments/[environmentId]/surveys/components/SurveyList.tsx
@@ -53,7 +53,7 @@ export default async function SurveysList({ environmentId }: { environmentId: st
environmentId={environmentId}
environment={environment}
product={product}
- profile={session.user}
+ user={session.user}
/>
);
}
diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/components/SurveyStarter.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/components/SurveyStarter.tsx
index e068a1f7a6..7c86638b2a 100644
--- a/apps/web/app/(app)/environments/[environmentId]/surveys/components/SurveyStarter.tsx
+++ b/apps/web/app/(app)/environments/[environmentId]/surveys/components/SurveyStarter.tsx
@@ -9,18 +9,18 @@ import { TTemplate } from "@formbricks/types/templates";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { toast } from "react-hot-toast";
-import { TProfile } from "@formbricks/types/profile";
+import { TUser } from "@formbricks/types/user";
export default function SurveyStarter({
environmentId,
environment,
product,
- profile,
+ user,
}: {
environmentId: string;
environment: TEnvironment;
product: TProduct;
- profile: TProfile;
+ user: TUser;
}) {
const [isCreateSurveyLoading, setIsCreateSurveyLoading] = useState(false);
const router = useRouter();
@@ -59,7 +59,7 @@ export default function SurveyStarter({
}}
environment={environment}
product={product}
- profile={profile}
+ user={user}
/>
>
)}
diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/templates/TemplateContainer.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/templates/TemplateContainer.tsx
index 30b9bcd15c..11d76d6f38 100644
--- a/apps/web/app/(app)/environments/[environmentId]/surveys/templates/TemplateContainer.tsx
+++ b/apps/web/app/(app)/environments/[environmentId]/surveys/templates/TemplateContainer.tsx
@@ -10,20 +10,20 @@ import TemplateList from "./TemplateList";
import type { TProduct } from "@formbricks/types/product";
import type { TEnvironment } from "@formbricks/types/environment";
import { SearchBox } from "@formbricks/ui/SearchBox";
-import { TProfile } from "@formbricks/types/profile";
+import { TUser } from "@formbricks/types/user";
type TemplateContainerWithPreviewProps = {
environmentId: string;
product: TProduct;
environment: TEnvironment;
- profile: TProfile;
+ user: TUser;
};
export default function TemplateContainerWithPreview({
environmentId,
product,
environment,
- profile,
+ user,
}: TemplateContainerWithPreviewProps) {
const [activeTemplate, setActiveTemplate] = useState
(null);
const [activeQuestionId, setActiveQuestionId] = useState(null);
@@ -59,7 +59,7 @@ export default function TemplateContainerWithPreview({
environmentId={environmentId}
environment={environment}
product={product}
- profile={profile}
+ user={user}
templateSearch={templateSearch ?? ""}
onTemplateClick={(template) => {
setActiveQuestionId(template.preset.questions[0].id);
diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/templates/TemplateList.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/templates/TemplateList.tsx
index a34fdd0eac..71f954af83 100644
--- a/apps/web/app/(app)/environments/[environmentId]/surveys/templates/TemplateList.tsx
+++ b/apps/web/app/(app)/environments/[environmentId]/surveys/templates/TemplateList.tsx
@@ -4,7 +4,7 @@ import { replacePresetPlaceholders } from "@/app/lib/templates";
import { cn } from "@formbricks/lib/cn";
import type { TEnvironment } from "@formbricks/types/environment";
import type { TProduct } from "@formbricks/types/product";
-import { TProfile } from "@formbricks/types/profile";
+import { TUser } from "@formbricks/types/user";
import { TSurveyInput } from "@formbricks/types/surveys";
import { TTemplate } from "@formbricks/types/templates";
import { Button } from "@formbricks/ui/Button";
@@ -19,7 +19,7 @@ import { customSurvey, templates, testTemplate } from "./templates";
type TemplateList = {
environmentId: string;
- profile: TProfile;
+ user: TUser;
onTemplateClick: (template: TTemplate) => void;
environment: TEnvironment;
product: TProduct;
@@ -30,7 +30,7 @@ const ALL_CATEGORY_NAME = "All";
const RECOMMENDED_CATEGORY_NAME = "For you";
export default function TemplateList({
environmentId,
- profile,
+ user,
onTemplateClick,
product,
environment,
@@ -50,7 +50,7 @@ export default function TemplateList({
];
const fullCategories =
- !!profile?.objective && profile.objective !== "other"
+ !!user?.objective && user.objective !== "other"
? [RECOMMENDED_CATEGORY_NAME, ALL_CATEGORY_NAME, ...defaultCategories]
: [ALL_CATEGORY_NAME, ...defaultCategories];
@@ -58,11 +58,11 @@ export default function TemplateList({
const activeFilter = templateSearch
? ALL_CATEGORY_NAME
- : !!profile?.objective && profile.objective !== "other"
+ : !!user?.objective && user.objective !== "other"
? RECOMMENDED_CATEGORY_NAME
: ALL_CATEGORY_NAME;
setSelectedFilter(activeFilter);
- }, [profile, templateSearch]);
+ }, [user, templateSearch]);
const addSurvey = async (activeTemplate) => {
setLoading(true);
@@ -81,9 +81,9 @@ export default function TemplateList({
const matchesCategory =
selectedFilter === ALL_CATEGORY_NAME ||
template.category === selectedFilter ||
- (profile.objective &&
+ (user.objective &&
selectedFilter === RECOMMENDED_CATEGORY_NAME &&
- template.objectives?.includes(profile.objective));
+ template.objectives?.includes(user.objective));
const templateName = template.name?.toLowerCase();
const templateDescription = template.description?.toLowerCase();
diff --git a/apps/web/app/(app)/environments/[environmentId]/surveys/templates/page.tsx b/apps/web/app/(app)/environments/[environmentId]/surveys/templates/page.tsx
index 8900194c3b..f4d037012f 100644
--- a/apps/web/app/(app)/environments/[environmentId]/surveys/templates/page.tsx
+++ b/apps/web/app/(app)/environments/[environmentId]/surveys/templates/page.tsx
@@ -28,7 +28,7 @@ export default async function SurveyTemplatesPage({ params }) {
return (
diff --git a/apps/web/app/(app)/onboarding/actions.ts b/apps/web/app/(app)/onboarding/actions.ts
index 449bb5c7ad..895c03312a 100644
--- a/apps/web/app/(app)/onboarding/actions.ts
+++ b/apps/web/app/(app)/onboarding/actions.ts
@@ -3,17 +3,17 @@
import { authOptions } from "@formbricks/lib/authOptions";
import { canUserAccessProduct, verifyUserRoleAccess } from "@formbricks/lib/product/auth";
import { getProduct, updateProduct } from "@formbricks/lib/product/service";
-import { updateProfile } from "@formbricks/lib/profile/service";
+import { updateUser } from "@formbricks/lib/user/service";
import { AuthorizationError } from "@formbricks/types/errors";
import { TProductUpdateInput } from "@formbricks/types/product";
-import { TProfileUpdateInput } from "@formbricks/types/profile";
+import { TUserUpdateInput } from "@formbricks/types/user";
import { getServerSession } from "next-auth";
-export async function updateProfileAction(updatedProfile: TProfileUpdateInput) {
+export async function updateUserAction(updatedUser: TUserUpdateInput) {
const session = await getServerSession(authOptions);
if (!session) throw new AuthorizationError("Not authorized");
- return await updateProfile(session.user.id, updatedProfile);
+ return await updateUser(session.user.id, updatedUser);
}
export async function updateProductAction(productId: string, updatedProduct: Partial) {
diff --git a/apps/web/app/(app)/onboarding/components/Objective.tsx b/apps/web/app/(app)/onboarding/components/Objective.tsx
index a15dcc6fb2..ed9a4efba2 100644
--- a/apps/web/app/(app)/onboarding/components/Objective.tsx
+++ b/apps/web/app/(app)/onboarding/components/Objective.tsx
@@ -1,10 +1,10 @@
"use client";
-import { updateProfileAction } from "@/app/(app)/onboarding/actions";
+import { updateUserAction } from "@/app/(app)/onboarding/actions";
import { formbricksEnabled, updateResponse } from "@/app/lib/formbricks";
import { cn } from "@formbricks/lib/cn";
import { env } from "@formbricks/lib/env.mjs";
-import { TProfile, TProfileObjective } from "@formbricks/types/profile";
+import { TUser, TUserObjective } from "@formbricks/types/user";
import { Button } from "@formbricks/ui/Button";
import { useEffect, useRef, useState } from "react";
import { toast } from "react-hot-toast";
@@ -14,15 +14,15 @@ type ObjectiveProps = {
next: () => void;
skip: () => void;
formbricksResponseId?: string;
- profile: TProfile;
+ user: TUser;
};
type ObjectiveChoice = {
label: string;
- id: TProfileObjective;
+ id: TUserObjective;
};
-const Objective: React.FC = ({ next, skip, formbricksResponseId, profile }) => {
+const Objective: React.FC = ({ next, skip, formbricksResponseId, user }) => {
const objectives: Array = [
{ label: "Increase conversion", id: "increase_conversion" },
{ label: "Improve user retention", id: "improve_user_retention" },
@@ -51,9 +51,9 @@ const Objective: React.FC = ({ next, skip, formbricksResponseId,
if (selectedObjective) {
try {
setIsProfileUpdating(true);
- await updateProfileAction({
+ await updateUserAction({
objective: selectedObjective.id,
- name: profile.name ?? undefined,
+ name: user.name ?? undefined,
});
setIsProfileUpdating(false);
} catch (e) {
diff --git a/apps/web/app/(app)/onboarding/components/Onboarding.tsx b/apps/web/app/(app)/onboarding/components/Onboarding.tsx
index 687ff545d7..2466251c91 100644
--- a/apps/web/app/(app)/onboarding/components/Onboarding.tsx
+++ b/apps/web/app/(app)/onboarding/components/Onboarding.tsx
@@ -1,8 +1,8 @@
"use client";
-import { updateProfileAction } from "@/app/(app)/onboarding/actions";
+import { updateUserAction } from "@/app/(app)/onboarding/actions";
import { TProduct } from "@formbricks/types/product";
-import { TProfile } from "@formbricks/types/profile";
+import { TUser } from "@formbricks/types/user";
import { Logo } from "@formbricks/ui/Logo";
import { ProgressBar } from "@formbricks/ui/ProgressBar";
import { Session } from "next-auth";
@@ -19,11 +19,11 @@ const MAX_STEPS = 6;
interface OnboardingProps {
session: Session;
environmentId: string;
- profile: TProfile;
+ user: TUser;
product: TProduct;
}
-export default function Onboarding({ session, environmentId, profile, product }: OnboardingProps) {
+export default function Onboarding({ session, environmentId, user, product }: OnboardingProps) {
const [formbricksResponseId, setFormbricksResponseId] = useState();
const [currentStep, setCurrentStep] = useState(1);
const [isLoading, setIsLoading] = useState(false);
@@ -53,8 +53,8 @@ export default function Onboarding({ session, environmentId, profile, product }:
setIsLoading(true);
try {
- const updatedProfile = { ...profile, onboardingCompleted: true };
- await updateProfileAction(updatedProfile);
+ const updatedProfile = { ...user, onboardingCompleted: true };
+ await updateUserAction(updatedProfile);
if (environmentId) {
router.push(`/environments/${environmentId}/surveys`);
@@ -85,7 +85,7 @@ export default function Onboarding({ session, environmentId, profile, product }:
{currentStep === 1 && (
-
+
)}
{currentStep === 2 && (
)}
{currentStep === 3 && (
-
+
)}
{currentStep === 4 && (
diff --git a/apps/web/app/(app)/onboarding/components/Role.tsx b/apps/web/app/(app)/onboarding/components/Role.tsx
index c18f3b77e3..f17ed82003 100644
--- a/apps/web/app/(app)/onboarding/components/Role.tsx
+++ b/apps/web/app/(app)/onboarding/components/Role.tsx
@@ -1,6 +1,6 @@
"use client";
-import { updateProfileAction } from "@/app/(app)/onboarding/actions";
+import { updateUserAction } from "@/app/(app)/onboarding/actions";
import { createResponse, formbricksEnabled } from "@/app/lib/formbricks";
import { cn } from "@formbricks/lib/cn";
import { env } from "@formbricks/lib/env.mjs";
@@ -49,7 +49,7 @@ const Role: React.FC
= ({ next, skip, setFormbricksResponseId, sessio
if (selectedRole) {
try {
setIsUpdating(true);
- await updateProfileAction({ role: selectedRole.id });
+ await updateUserAction({ role: selectedRole.id });
setIsUpdating(false);
} catch (e) {
setIsUpdating(false);
diff --git a/apps/web/app/(app)/onboarding/page.tsx b/apps/web/app/(app)/onboarding/page.tsx
index 11f7fee251..94106f6829 100644
--- a/apps/web/app/(app)/onboarding/page.tsx
+++ b/apps/web/app/(app)/onboarding/page.tsx
@@ -4,7 +4,7 @@ import { authOptions } from "@formbricks/lib/authOptions";
import { REVALIDATION_INTERVAL } from "@formbricks/lib/constants";
import { getFirstEnvironmentByUserId } from "@formbricks/lib/environment/service";
import { getProductByEnvironmentId } from "@formbricks/lib/product/service";
-import { getProfile } from "@formbricks/lib/profile/service";
+import { getUser } from "@formbricks/lib/user/service";
import { getServerSession } from "next-auth";
import Onboarding from "./components/Onboarding";
import { redirect } from "next/navigation";
@@ -21,12 +21,12 @@ export default async function OnboardingPage() {
throw new Error("No environment found for user");
}
- const profile = await getProfile(userId);
+ const user = await getUser(userId);
const product = await getProductByEnvironmentId(environment?.id!);
- if (!environment || !profile || !product) {
- throw new Error("Failed to get environment, profile, or product");
+ if (!environment || !user || !product) {
+ throw new Error("Failed to get environment, user, or product");
}
- return ;
+ return ;
}
diff --git a/apps/web/app/api/cron/weekly_summary/types.ts b/apps/web/app/api/cron/weekly_summary/types.ts
index 9c7de5e928..dbb840e52e 100644
--- a/apps/web/app/api/cron/weekly_summary/types.ts
+++ b/apps/web/app/api/cron/weekly_summary/types.ts
@@ -1,6 +1,6 @@
import { TResponseData } from "@formbricks/types/responses";
import { TSurveyQuestion, TSurveyStatus } from "@formbricks/types/surveys";
-import { TUserNotificationSettings } from "@formbricks/types/users";
+import { TUserNotificationSettings } from "@formbricks/types/user";
export interface Insights {
totalCompletedResponses: number;
diff --git a/apps/web/app/api/pipeline/route.ts b/apps/web/app/api/pipeline/route.ts
index ac35250e51..d5d4abdd90 100644
--- a/apps/web/app/api/pipeline/route.ts
+++ b/apps/web/app/api/pipeline/route.ts
@@ -5,7 +5,7 @@ import { prisma } from "@formbricks/database";
import { INTERNAL_SECRET } from "@formbricks/lib/constants";
import { convertDatesInObject } from "@formbricks/lib/time";
import { TSurveyQuestion } from "@formbricks/types/surveys";
-import { TUserNotificationSettings } from "@formbricks/types/users";
+import { TUserNotificationSettings } from "@formbricks/types/user";
import { ZPipelineInput } from "@formbricks/types/pipelines";
import { headers } from "next/headers";
import { NextResponse } from "next/server";
diff --git a/apps/web/app/api/v1/users/route.ts b/apps/web/app/api/v1/users/route.ts
index 646ea726a0..b5a200cda3 100644
--- a/apps/web/app/api/v1/users/route.ts
+++ b/apps/web/app/api/v1/users/route.ts
@@ -6,7 +6,7 @@ import { deleteInvite } from "@formbricks/lib/invite/service";
import { verifyInviteToken } from "@formbricks/lib/jwt";
import { createMembership } from "@formbricks/lib/membership/service";
import { createProduct } from "@formbricks/lib/product/service";
-import { createProfile } from "@formbricks/lib/profile/service";
+import { createUser } from "@formbricks/lib/user/service";
import { createTeam, getTeam } from "@formbricks/lib/team/service";
import { NextResponse } from "next/server";
@@ -23,7 +23,7 @@ export async function POST(request: Request) {
let invite;
// create the user
- user = await createProfile(user);
+ user = await createUser(user);
// User is invited to team
if (inviteToken) {
diff --git a/apps/web/app/lib/users/users.ts b/apps/web/app/lib/users/users.ts
index 06bb8d84e2..fe576735ce 100644
--- a/apps/web/app/lib/users/users.ts
+++ b/apps/web/app/lib/users/users.ts
@@ -88,7 +88,7 @@ export const resetPassword = async (token: string, password: string): Promise => {
+export const deleteUser = async (): Promise => {
try {
const res = await fetch("/api/v1/users/me/", {
method: "DELETE",
diff --git a/packages/database/jsonTypes.ts b/packages/database/jsonTypes.ts
index 8560d63514..3f9e4996d9 100644
--- a/packages/database/jsonTypes.ts
+++ b/packages/database/jsonTypes.ts
@@ -13,7 +13,7 @@ import {
TSurveyVerifyEmail,
} from "@formbricks/types/surveys";
import { TTeamBilling } from "@formbricks/types/teams";
-import { TUserNotificationSettings } from "@formbricks/types/users";
+import { TUserNotificationSettings } from "@formbricks/types/user";
declare global {
namespace PrismaJson {
diff --git a/packages/database/zod-utils.ts b/packages/database/zod-utils.ts
index 65ae087715..2d4c51456d 100644
--- a/packages/database/zod-utils.ts
+++ b/packages/database/zod-utils.ts
@@ -24,4 +24,4 @@ export {
} from "@formbricks/types/surveys";
export { ZTeamBilling } from "@formbricks/types/teams";
-export { ZUserNotificationSettings } from "@formbricks/types/users";
+export { ZUserNotificationSettings } from "@formbricks/types/user";
diff --git a/packages/ee/RoleManagement/lib/actions.ts b/packages/ee/RoleManagement/lib/actions.ts
index b10ef99d47..1f95c98a36 100644
--- a/packages/ee/RoleManagement/lib/actions.ts
+++ b/packages/ee/RoleManagement/lib/actions.ts
@@ -7,16 +7,16 @@ import {
updateMembership,
} from "@formbricks/lib/membership/service";
import { updateInvite } from "@formbricks/lib/invite/service";
-import { TInviteUpdateInput } from "../../../types/invites";
-import { TMembershipUpdateInput } from "../../../types/memberships";
+import { TInviteUpdateInput } from "@formbricks/types/invites";
+import { TMembershipUpdateInput } from "@formbricks/types/memberships";
import { hasTeamAccess, hasTeamAuthority, isOwner } from "@formbricks/lib/auth";
import { getServerSession } from "next-auth";
-import { AuthenticationError, AuthorizationError, ValidationError } from "../../../types/errors";
-import { TProfile } from "../../../types/profile";
+import { AuthenticationError, AuthorizationError, ValidationError } from "@formbricks/types/errors";
+import { TUser } from "@formbricks/types/user";
export const transferOwnershipAction = async (teamId: string, newOwnerId: string) => {
const session = await getServerSession(authOptions);
- const user = session?.user as TProfile;
+ const user = session?.user as TUser;
if (!session) {
throw new AuthenticationError("Not authenticated");
}
@@ -49,7 +49,7 @@ export const transferOwnershipAction = async (teamId: string, newOwnerId: string
export const updateInviteAction = async (inviteId: string, teamId: string, data: TInviteUpdateInput) => {
const session = await getServerSession(authOptions);
- const user = session?.user as TProfile;
+ const user = session?.user as TUser;
if (!user) {
throw new AuthenticationError("Not authenticated");
@@ -74,7 +74,7 @@ export const updateMembershipAction = async (
data: TMembershipUpdateInput
) => {
const session = await getServerSession(authOptions);
- const user = session?.user as TProfile;
+ const user = session?.user as TUser;
if (!user) {
throw new AuthenticationError("Not authenticated");
diff --git a/packages/lib/auth/service.ts b/packages/lib/auth/service.ts
index 3c8b969e17..9d0892aa51 100644
--- a/packages/lib/auth/service.ts
+++ b/packages/lib/auth/service.ts
@@ -5,7 +5,7 @@ import { prisma } from "@formbricks/database";
import { symmetricDecrypt, symmetricEncrypt } from "../crypto";
import { verifyPassword } from "../auth";
import { totpAuthenticatorCheck } from "../totp";
-import { profileCache } from "../profile/cache";
+import { userCache } from "../user/cache";
import { ENCRYPTION_KEY } from "../constants";
export const setupTwoFactorAuth = async (
@@ -120,7 +120,7 @@ export const enableTwoFactorAuth = async (id: string, code: string) => {
},
});
- profileCache.revalidate({
+ userCache.revalidate({
id,
});
@@ -221,7 +221,7 @@ export const disableTwoFactorAuth = async (id: string, params: TDisableTwoFactor
},
});
- profileCache.revalidate({
+ userCache.revalidate({
id,
});
diff --git a/packages/lib/authOptions.ts b/packages/lib/authOptions.ts
index a74cf97172..0a238b8cdc 100644
--- a/packages/lib/authOptions.ts
+++ b/packages/lib/authOptions.ts
@@ -12,7 +12,7 @@ import { env } from "./env.mjs";
import { verifyToken } from "./jwt";
import { createMembership } from "./membership/service";
import { createProduct } from "./product/service";
-import { createProfile, getProfileByEmail, updateProfile } from "./profile/service";
+import { createUser, getUserByEmail, updateUser } from "./user/service";
import { createTeam, getTeam } from "./team/service";
export const authOptions: NextAuthOptions = {
@@ -110,7 +110,7 @@ export const authOptions: NextAuthOptions = {
throw new Error("Email already verified");
}
- user = await updateProfile(user.id, { emailVerified: new Date() });
+ user = await updateUser(user.id, { emailVerified: new Date() });
return user;
},
@@ -132,7 +132,7 @@ export const authOptions: NextAuthOptions = {
],
callbacks: {
async jwt({ token }) {
- const existingUser = await getProfileByEmail(token?.email!);
+ const existingUser = await getUserByEmail(token?.email!);
if (!existingUser) {
return token;
@@ -191,10 +191,10 @@ export const authOptions: NextAuthOptions = {
// check if user with this email already exist
// if not found just update user with new email address
// if found throw an error (TODO find better solution)
- const otherUserWithEmail = await getProfileByEmail(user.email);
+ const otherUserWithEmail = await getUserByEmail(user.email);
if (!otherUserWithEmail) {
- await updateProfile(existingUserWithAccount.id, { email: user.email });
+ await updateUser(existingUserWithAccount.id, { email: user.email });
return true;
}
throw new Error(
@@ -205,13 +205,13 @@ export const authOptions: NextAuthOptions = {
// There is no existing account for this identity provider / account id
// check if user account with this email already exists
// if user already exists throw error and request password login
- const existingUserWithEmail = await getProfileByEmail(user.email);
+ const existingUserWithEmail = await getUserByEmail(user.email);
if (existingUserWithEmail) {
throw new Error("A user with this email exists already.");
}
- const userProfile = await createProfile({
+ const userProfile = await createUser({
name: user.name,
email: user.email,
emailVerified: new Date(Date.now()),
diff --git a/packages/lib/membership/hooks/actions.ts b/packages/lib/membership/hooks/actions.ts
index 796e62a65c..76d11a115d 100644
--- a/packages/lib/membership/hooks/actions.ts
+++ b/packages/lib/membership/hooks/actions.ts
@@ -6,12 +6,12 @@ import { authOptions } from "../../authOptions";
import { getTeamByEnvironmentId } from "../../team/service";
import { AuthenticationError } from "@formbricks/types/errors";
import { getMembershipByUserIdTeamId } from "../service";
-import { TProfile } from "@formbricks/types/profile";
+import { TUser } from "@formbricks/types/user";
export const getMembershipByUserIdTeamIdAction = async (environmentId: string) => {
const session = await getServerSession(authOptions);
const team = await getTeamByEnvironmentId(environmentId);
- const user = session?.user as TProfile;
+ const user = session?.user as TUser;
if (!session) {
throw new AuthenticationError("Not authenticated");
diff --git a/packages/lib/profile/util.ts b/packages/lib/profile/util.ts
deleted file mode 100644
index dd03720642..0000000000
--- a/packages/lib/profile/util.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { TProfile } from "@formbricks/types/profile";
-
-export const formatProfileDateFields = (profile: TProfile): TProfile => {
- if (typeof profile.createdAt === "string") {
- profile.createdAt = new Date(profile.createdAt);
- }
- if (typeof profile.updatedAt === "string") {
- profile.updatedAt = new Date(profile.updatedAt);
- }
- if (typeof profile.emailVerified === "string") {
- profile.emailVerified = new Date(profile.emailVerified);
- }
-
- return profile;
-};
diff --git a/packages/lib/profile/cache.ts b/packages/lib/user/cache.ts
similarity index 80%
rename from packages/lib/profile/cache.ts
rename to packages/lib/user/cache.ts
index e964eeb591..f7bf2d68a8 100644
--- a/packages/lib/profile/cache.ts
+++ b/packages/lib/user/cache.ts
@@ -5,13 +5,13 @@ interface RevalidateProps {
email?: string;
}
-export const profileCache = {
+export const userCache = {
tag: {
byId(id: string) {
- return `profiles-${id}`;
+ return `users-${id}`;
},
byEmail(email: string) {
- return `profiles-${email}`;
+ return `users-${email}`;
},
},
revalidate({ id, email }: RevalidateProps): void {
diff --git a/packages/lib/profile/service.ts b/packages/lib/user/service.ts
similarity index 64%
rename from packages/lib/profile/service.ts
rename to packages/lib/user/service.ts
index 4631d92177..87fe58de36 100644
--- a/packages/lib/profile/service.ts
+++ b/packages/lib/user/service.ts
@@ -4,13 +4,7 @@ import { prisma } from "@formbricks/database";
import { ZId } from "@formbricks/types/environment";
import { DatabaseError, ResourceNotFoundError } from "@formbricks/types/errors";
import { TMembership } from "@formbricks/types/memberships";
-import {
- TProfile,
- TProfileCreateInput,
- TProfileUpdateInput,
- ZProfile,
- ZProfileUpdateInput,
-} from "@formbricks/types/profile";
+import { TUser, TUserCreateInput, TUserUpdateInput, ZUser, ZUserUpdateInput } from "@formbricks/types/user";
import { Prisma } from "@prisma/client";
import { unstable_cache } from "next/cache";
import { z } from "zod";
@@ -19,9 +13,7 @@ import { updateMembership } from "../membership/service";
import { deleteTeam } from "../team/service";
import { formatDateFields } from "../utils/datetime";
import { validateInputs } from "../utils/validate";
-import { profileCache } from "./cache";
-import { formatProfileDateFields } from "./util";
-
+import { userCache } from "./cache";
const responseSelection = {
id: true,
name: true,
@@ -36,24 +28,24 @@ const responseSelection = {
objective: true,
};
-// function to retrive basic information about a user's profile
-export const getProfile = async (id: string): Promise => {
- const profile = await unstable_cache(
+// function to retrive basic information about a user's user
+export const getUser = async (id: string): Promise => {
+ const user = await unstable_cache(
async () => {
validateInputs([id, ZId]);
try {
- const profile = await prisma.user.findUnique({
+ const user = await prisma.user.findUnique({
where: {
id,
},
select: responseSelection,
});
- if (!profile) {
+ if (!user) {
return null;
}
- return profile;
+ return user;
} catch (error) {
if (error instanceof Prisma.PrismaClientKnownRequestError) {
throw new DatabaseError(error.message);
@@ -62,35 +54,35 @@ export const getProfile = async (id: string): Promise => {
throw error;
}
},
- [`getProfile-${id}`],
+ [`getUser-${id}`],
{
- tags: [profileCache.tag.byId(id)],
+ tags: [userCache.tag.byId(id)],
revalidate: SERVICES_REVALIDATION_INTERVAL,
}
)();
- return profile
+ return user
? {
- ...profile,
- ...formatDateFields(profile, ZProfile),
+ ...user,
+ ...formatDateFields(user, ZUser),
}
: null;
};
-export const getProfileByEmail = async (email: string): Promise => {
- const profile = await unstable_cache(
+export const getUserByEmail = async (email: string): Promise => {
+ const user = await unstable_cache(
async () => {
validateInputs([email, z.string().email()]);
try {
- const profile = await prisma.user.findFirst({
+ const user = await prisma.user.findFirst({
where: {
email,
},
select: responseSelection,
});
- return profile;
+ return user;
} catch (error) {
if (error instanceof Prisma.PrismaClientKnownRequestError) {
throw new DatabaseError(error.message);
@@ -99,17 +91,17 @@ export const getProfileByEmail = async (email: string): Promise
throw error;
}
},
- [`getProfileByEmail-${email}`],
+ [`getUserByEmail-${email}`],
{
- tags: [profileCache.tag.byEmail(email)],
+ tags: [userCache.tag.byEmail(email)],
revalidate: SERVICES_REVALIDATION_INTERVAL,
}
)();
- return profile
+ return user
? {
- ...profile,
- ...formatProfileDateFields(profile),
+ ...user,
+ ...formatDateFields(user, ZUser),
}
: null;
};
@@ -117,12 +109,12 @@ export const getProfileByEmail = async (email: string): Promise
const getAdminMemberships = (memberships: TMembership[]): TMembership[] =>
memberships.filter((membership) => membership.role === "admin");
-// function to update a user's profile
-export const updateProfile = async (personId: string, data: TProfileUpdateInput): Promise => {
- validateInputs([personId, ZId], [data, ZProfileUpdateInput.partial()]);
+// function to update a user's user
+export const updateUser = async (personId: string, data: TUserUpdateInput): Promise => {
+ validateInputs([personId, ZId], [data, ZUserUpdateInput.partial()]);
try {
- const updatedProfile = await prisma.user.update({
+ const updatedUser = await prisma.user.update({
where: {
id: personId,
},
@@ -130,57 +122,57 @@ export const updateProfile = async (personId: string, data: TProfileUpdateInput)
select: responseSelection,
});
- profileCache.revalidate({
- email: updatedProfile.email,
- id: updatedProfile.id,
+ userCache.revalidate({
+ email: updatedUser.email,
+ id: updatedUser.id,
});
- return updatedProfile;
+ return updatedUser;
} catch (error) {
if (error instanceof Prisma.PrismaClientKnownRequestError && error.code === "P2016") {
- throw new ResourceNotFoundError("Profile", personId);
+ throw new ResourceNotFoundError("User", personId);
} else {
throw error; // Re-throw any other errors
}
}
};
-const deleteUser = async (id: string): Promise => {
+const deleteUserById = async (id: string): Promise => {
validateInputs([id, ZId]);
- const profile = await prisma.user.delete({
+ const user = await prisma.user.delete({
where: {
id,
},
select: responseSelection,
});
- profileCache.revalidate({
- email: profile.email,
+ userCache.revalidate({
+ email: user.email,
id,
});
- return profile;
+ return user;
};
-export const createProfile = async (data: TProfileCreateInput): Promise => {
- validateInputs([data, ZProfileUpdateInput]);
+export const createUser = async (data: TUserCreateInput): Promise => {
+ validateInputs([data, ZUserUpdateInput]);
- const profile = await prisma.user.create({
+ const user = await prisma.user.create({
data: data,
select: responseSelection,
});
- profileCache.revalidate({
- email: profile.email,
- id: profile.id,
+ userCache.revalidate({
+ email: user.email,
+ id: user.id,
});
- return profile;
+ return user;
};
-// function to delete a user's profile including teams
-export const deleteProfile = async (id: string): Promise => {
+// function to delete a user's user including teams
+export const deleteUser = async (id: string): Promise => {
validateInputs([id, ZId]);
try {
@@ -219,9 +211,9 @@ export const deleteProfile = async (id: string): Promise => {
}
}
- const deletedProfile = await deleteUser(id);
+ const deletedUser = await deleteUserById(id);
- return deletedProfile;
+ return deletedUser;
} catch (error) {
if (error instanceof Prisma.PrismaClientKnownRequestError) {
throw new DatabaseError(error.message);
diff --git a/packages/types/auth.ts b/packages/types/auth.ts
index b83337838e..1c45a5e77e 100644
--- a/packages/types/auth.ts
+++ b/packages/types/auth.ts
@@ -1,8 +1,8 @@
import { z } from "zod";
-import { ZProfile } from "./profile";
+import { ZUser } from "./user";
const ZAuthSession = z.object({
- user: ZProfile,
+ user: ZUser,
});
const ZAuthenticationApiKey = z.object({
diff --git a/packages/types/next-auth.d.ts b/packages/types/next-auth.d.ts
index 0773fb4968..3584faf2e5 100644
--- a/packages/types/next-auth.d.ts
+++ b/packages/types/next-auth.d.ts
@@ -1,11 +1,11 @@
import NextAuth from "next-auth";
-import { TProfile } from "./profile";
+import { TUser } from "./user";
declare module "next-auth" {
/**
* Returned by `useSession`, `getSession` and received as a prop on the `SessionProvider` React Context
*/
interface Session {
- user: TProfile;
+ user: TUser;
}
}
diff --git a/packages/types/templates.ts b/packages/types/templates.ts
index c2fba539a5..b99ea616e9 100644
--- a/packages/types/templates.ts
+++ b/packages/types/templates.ts
@@ -1,6 +1,6 @@
import { z } from "zod";
import { ZSurveyWelcomeCard, ZSurveyHiddenFields, ZSurveyQuestions, ZSurveyThankYouCard } from "./surveys";
-import { ZProfileObjective } from "./profile";
+import { ZUserObjective } from "./user";
export const ZTemplate = z.object({
name: z.string(),
@@ -9,7 +9,7 @@ export const ZTemplate = z.object({
category: z
.enum(["Product Experience", "Exploration", "Growth", "Increase Revenue", "Customer Success"])
.optional(),
- objectives: z.array(ZProfileObjective).optional(),
+ objectives: z.array(ZUserObjective).optional(),
preset: z.object({
name: z.string(),
welcomeCard: ZSurveyWelcomeCard,
diff --git a/packages/types/profile.ts b/packages/types/user.ts
similarity index 61%
rename from packages/types/profile.ts
rename to packages/types/user.ts
index e2a3412d19..196f7723b7 100644
--- a/packages/types/profile.ts
+++ b/packages/types/user.ts
@@ -2,7 +2,7 @@ import z from "zod";
const ZRole = z.enum(["project_manager", "engineer", "founder", "marketing_specialist", "other"]);
-export const ZProfileObjective = z.enum([
+export const ZUserObjective = z.enum([
"increase_conversion",
"improve_user_retention",
"increase_user_adoption",
@@ -11,9 +11,9 @@ export const ZProfileObjective = z.enum([
"other",
]);
-export type TProfileObjective = z.infer;
+export type TUserObjective = z.infer;
-export const ZProfile = z.object({
+export const ZUser = z.object({
id: z.string(),
name: z.string().nullable(),
email: z.string(),
@@ -24,32 +24,39 @@ export const ZProfile = z.object({
createdAt: z.date(),
updatedAt: z.date(),
onboardingCompleted: z.boolean(),
- objective: ZProfileObjective.nullable(),
+ objective: ZUserObjective.nullable(),
});
-export type TProfile = z.infer;
+export type TUser = z.infer;
-export const ZProfileUpdateInput = z.object({
+export const ZUserUpdateInput = z.object({
name: z.string().nullish(),
email: z.string().optional(),
emailVerified: z.date().nullish(),
onboardingCompleted: z.boolean().optional(),
role: ZRole.optional(),
- objective: ZProfileObjective.nullish(),
+ objective: ZUserObjective.nullish(),
imageUrl: z.string().url().nullish(),
});
-export type TProfileUpdateInput = z.infer;
+export type TUserUpdateInput = z.infer;
-export const ZProfileCreateInput = z.object({
+export const ZUserCreateInput = z.object({
name: z.string().optional(),
email: z.string(),
emailVerified: z.date().optional(),
onboardingCompleted: z.boolean().optional(),
role: ZRole.optional(),
- objective: ZProfileObjective.nullish(),
+ objective: ZUserObjective.nullish(),
identityProvider: z.enum(["email", "google", "github", "azuread"]).optional(),
identityProviderAccountId: z.string().optional(),
});
-export type TProfileCreateInput = z.infer;
+export type TUserCreateInput = z.infer;
+
+export const ZUserNotificationSettings = z.object({
+ alert: z.record(z.boolean()),
+ weeklySummary: z.record(z.boolean()),
+});
+
+export type TUserNotificationSettings = z.infer;
diff --git a/packages/types/users.ts b/packages/types/users.ts
deleted file mode 100644
index 38c9bc57c7..0000000000
--- a/packages/types/users.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { z } from "zod";
-
-export const ZUserNotificationSettings = z.object({
- alert: z.record(z.boolean()),
- weeklySummary: z.record(z.boolean()),
-});
-
-export type TUserNotificationSettings = z.infer;
diff --git a/packages/ui/SingleResponseCard/components/ResponseNote.tsx b/packages/ui/SingleResponseCard/components/ResponseNote.tsx
index cc7a86580d..3dfa401656 100644
--- a/packages/ui/SingleResponseCard/components/ResponseNote.tsx
+++ b/packages/ui/SingleResponseCard/components/ResponseNote.tsx
@@ -2,7 +2,7 @@
import { cn } from "@formbricks/lib/cn";
import { timeSince } from "@formbricks/lib/time";
-import { TProfile } from "@formbricks/types/profile";
+import { TUser } from "@formbricks/types/user";
import { TResponseNote } from "@formbricks/types/responses";
import { CheckIcon, PencilIcon, PlusIcon } from "@heroicons/react/24/solid";
import clsx from "clsx";
@@ -15,14 +15,14 @@ import { Button } from "../../Button";
import { resolveResponseNoteAction, updateResponseNoteAction, createResponseNoteAction } from "../actions";
interface ResponseNotesProps {
- profile: TProfile;
+ user: TUser;
responseId: string;
notes: TResponseNote[];
isOpen: boolean;
setIsOpen: (isOpen: boolean) => void;
}
-export default function ResponseNotes({ profile, responseId, notes, isOpen, setIsOpen }: ResponseNotesProps) {
+export default function ResponseNotes({ user, responseId, notes, isOpen, setIsOpen }: ResponseNotesProps) {
const router = useRouter();
const [noteText, setNoteText] = useState("");
const [isCreatingNote, setIsCreatingNote] = useState(false);
@@ -35,7 +35,7 @@ export default function ResponseNotes({ profile, responseId, notes, isOpen, setI
e.preventDefault();
setIsCreatingNote(true);
try {
- await createResponseNoteAction(responseId, profile.id, noteText);
+ await createResponseNoteAction(responseId, user.id, noteText);
router.refresh();
setIsCreatingNote(false);
setNoteText("");
@@ -162,7 +162,7 @@ export default function ResponseNotes({ profile, responseId, notes, isOpen, setI
{note.text}
- {profile.id === note.user.id && (
+ {user.id === note.user.id && (
{pageType === "response" && (