From 7658dbe85c39757f5f604f78e912a8f58ec7ea18 Mon Sep 17 00:00:00 2001 From: Emily Date: Wed, 26 Mar 2025 16:15:46 +0100 Subject: [PATCH] fix members --- dashboard/server/LIVE_DEMO_DATA.ts | 2 +- dashboard/server/api/domains/list.ts | 2 +- .../server/api/metrics/[project_id]/query.ts | 2 +- dashboard/server/api/project/list_guest.ts | 8 ++++++- .../server/api/project/members/kick.post.ts | 1 + dashboard/server/api/project/members/list.ts | 17 +++++++++---- dashboard/server/api/project/members/me.ts | 15 ++++++++---- .../server/api/user/delete_account.delete.ts | 24 ++++++++++++++++--- dashboard/server/utils/getRequestData.ts | 14 +++++------ dashboard/server/utils/hasAccessToProject.ts | 4 ++-- .../schema/shields/PageBlacklistSchema.ts | 18 -------------- 11 files changed, 63 insertions(+), 44 deletions(-) delete mode 100644 shared_global/schema/shields/PageBlacklistSchema.ts diff --git a/dashboard/server/LIVE_DEMO_DATA.ts b/dashboard/server/LIVE_DEMO_DATA.ts index dab78b2..7bd4040 100644 --- a/dashboard/server/LIVE_DEMO_DATA.ts +++ b/dashboard/server/LIVE_DEMO_DATA.ts @@ -14,7 +14,7 @@ export async function getUserProjectFromId(project_id: string, user: AuthContext const project = await ProjectModel.findById(project_id); if (!project) return; - const [hasAccess, role] = await hasAccessToProject(user.id, project_id, project); + const [hasAccess, role] = await hasAccessToProject(user.id, project_id, user.user.email, project); if (!hasAccess) return; if (role === 'GUEST' && !allowGuest) return false; diff --git a/dashboard/server/api/domains/list.ts b/dashboard/server/api/domains/list.ts index 8c92252..fd00443 100644 --- a/dashboard/server/api/domains/list.ts +++ b/dashboard/server/api/domains/list.ts @@ -23,7 +23,7 @@ export default defineEventHandler(async event => { ...result ] - const member = await TeamMemberModel.findOne({ project_id, user_id: data.user.id, pending: false }); + const member = await TeamMemberModel.findOne({ project_id, $or: [{ user_id: user.id }, { email: user.user.email }], pending: false }); if (!member) return setResponseStatus(event, 400, 'Not a member'); if (!member.permission) return setResponseStatus(event, 400, 'No permission'); diff --git a/dashboard/server/api/metrics/[project_id]/query.ts b/dashboard/server/api/metrics/[project_id]/query.ts index d39ba4f..5ad0751 100644 --- a/dashboard/server/api/metrics/[project_id]/query.ts +++ b/dashboard/server/api/metrics/[project_id]/query.ts @@ -11,7 +11,7 @@ export default defineEventHandler(async event => { const project = await ProjectModel.findOne({ _id: project_id }); if (!project) return; - const [hasAccess] = await hasAccessToProject(user.id, project_id, project) + const [hasAccess] = await hasAccessToProject(user.id, project_id, user.user.email, project) if (!hasAccess) return; const query = getQuery(event); diff --git a/dashboard/server/api/project/list_guest.ts b/dashboard/server/api/project/list_guest.ts index 74a5b63..9beade6 100644 --- a/dashboard/server/api/project/list_guest.ts +++ b/dashboard/server/api/project/list_guest.ts @@ -7,7 +7,13 @@ export default defineEventHandler(async event => { if (!userData?.logged) return []; - const members = await TeamMemberModel.find({ user_id: userData.id, pending: false }); + const members = await TeamMemberModel.find({ + $or: [ + { user_id: userData.id }, + { email: userData.user.email } + ], + pending: false + }); const projects: TProject[] = []; diff --git a/dashboard/server/api/project/members/kick.post.ts b/dashboard/server/api/project/members/kick.post.ts index be3ff23..63f4ea1 100644 --- a/dashboard/server/api/project/members/kick.post.ts +++ b/dashboard/server/api/project/members/kick.post.ts @@ -16,6 +16,7 @@ export default defineEventHandler(async event => { if (!user) return setResponseStatus(event, 400, 'Email not found'); await TeamMemberModel.deleteOne({ project_id, user_id: user.id }); + await TeamMemberModel.deleteOne({ project_id, email: email }); return { ok: true } diff --git a/dashboard/server/api/project/members/list.ts b/dashboard/server/api/project/members/list.ts index 3801cd9..15f0501 100644 --- a/dashboard/server/api/project/members/list.ts +++ b/dashboard/server/api/project/members/list.ts @@ -42,8 +42,15 @@ export default defineEventHandler(async event => { }) for (const member of members) { - const userMember = member.user_id ? await UserModel.findById(member.user_id) : await UserModel.findOne({ email: member.email }); - if (!userMember) continue; + + let userMember; + + if (member.user_id) { + userMember = await UserModel.findById(member.user_id); + } else { + userMember = await UserModel.findOne({ email: member.email }); + } + const permission: TPermission = { webAnalytics: member.permission?.webAnalytics || false, @@ -54,11 +61,11 @@ export default defineEventHandler(async event => { result.push({ id: member.id, - email: userMember.email, - name: userMember.name, + email: userMember?.email || member.email || 'NO_EMAIL', + name: userMember?.name || 'NO_NAME', role: member.role, pending: member.pending, - me: user.id === userMember.id, + me: user.id === (userMember?.id || member.user_id || 'NO_ID'), permission }) } diff --git a/dashboard/server/api/project/members/me.ts b/dashboard/server/api/project/members/me.ts index 2ae16b4..6b97be2 100644 --- a/dashboard/server/api/project/members/me.ts +++ b/dashboard/server/api/project/members/me.ts @@ -19,13 +19,18 @@ export default defineEventHandler(async event => { webAnalytics: true } - const member = await TeamMemberModel.findOne({ project_id, user_id: user.id }); + const member = await TeamMemberModel.findOne({ + project_id, + $or: [ + { user_id: user.id }, { email: user.user.email } + ] + }); if (!member) return { - ai: true, - domains: ['All domains'], - events: true, - webAnalytics: true + ai: false, + domains: [], + events: false, + webAnalytics: false } return { diff --git a/dashboard/server/api/user/delete_account.delete.ts b/dashboard/server/api/user/delete_account.delete.ts index 84401b2..9cafd5b 100644 --- a/dashboard/server/api/user/delete_account.delete.ts +++ b/dashboard/server/api/user/delete_account.delete.ts @@ -8,6 +8,12 @@ import { LimitNotifyModel } from "@schema/broker/LimitNotifySchema"; import { SessionModel } from "@schema/metrics/SessionSchema"; import StripeService from "~/server/services/StripeService"; import { UserModel } from "@schema/UserSchema"; +import { AddressBlacklistModel } from "~/shared/schema/shields/AddressBlacklistSchema"; +import { DomainWhitelistModel } from "~/shared/schema/shields/DomainWhitelistSchema"; +import { CountryBlacklistModel } from "~/shared/schema/shields/CountryBlacklistSchema"; +import { BotTrafficOptionModel } from "~/shared/schema/shields/BotTrafficOptionSchema"; +import { TeamMemberModel } from "~/shared/schema/TeamMemberSchema"; +import { PasswordModel } from "~/shared/schema/PasswordSchema"; export default defineEventHandler(async event => { @@ -19,6 +25,11 @@ export default defineEventHandler(async event => { const premiumProjects = projects.filter(e => { return e.premium && e.premium_type != 0 }).length; if (premiumProjects > 0) return setResponseStatus(event, 400, 'Cannot delete an account with a premium project'); + const membersDeletation = await TeamMemberModel.deleteMany({ user_id: userData.id }); + const membersEmailDeletation = await TeamMemberModel.deleteMany({ email: userData.user.email }); + + const passwordDeletation = await PasswordModel.deleteMany({ user_id: userData.id }); + for (const project of projects) { const project_id = project._id; await StripeService.deleteCustomer(project.customer_id); @@ -28,9 +39,16 @@ export default defineEventHandler(async event => { const limitdeletation = await ProjectLimitModel.deleteMany({ project_id }); const sessionsDeletation = await SessionModel.deleteMany({ project_id }); const notifiesDeletation = await LimitNotifyModel.deleteMany({ project_id }); - const aiChatsDeletation = await AiChatModel.deleteMany({ project_id }); - - const userDeletation = await UserModel.deleteOne({ _id: userData.id }); + const aiChatsDeletation = await AiChatModel.deleteMany({ project_id }); + + //Shields + const addressBlacklistDeletation = await AddressBlacklistModel.deleteMany({ project_id }); + const botTrafficOptionsDeletation = await BotTrafficOptionModel.deleteMany({ project_id }); + const countryBlacklistDeletation = await CountryBlacklistModel.deleteMany({ project_id }); + const domainWhitelistDeletation = await DomainWhitelistModel.deleteMany({ project_id }); + + + const userDeletation = await UserModel.deleteOne({ _id: userData.id }); } diff --git a/dashboard/server/utils/getRequestData.ts b/dashboard/server/utils/getRequestData.ts index 4a40614..be1a202 100644 --- a/dashboard/server/utils/getRequestData.ts +++ b/dashboard/server/utils/getRequestData.ts @@ -35,7 +35,7 @@ export type GetRequestDataOptions = { export type RequestDataScope = 'SCHEMA' | 'ANON' | 'SLICE' | 'RANGE' | 'OFFSET' | 'DOMAIN'; export type RequestDataPermissions = 'WEB' | 'EVENTS' | 'AI' | 'OWNER'; -async function getAccessPermission(user_id: string, project: TProject): Promise { +async function getAccessPermission(user_id: string, project: TProject, email: string): Promise { if (!project) return { ai: false, domains: [], events: false, webAnalytics: false } //TODO: Create table with admins @@ -44,17 +44,17 @@ async function getAccessPermission(user_id: string, project: TProject): Promise< const owner = project.owner.toString(); const project_id = project._id; if (owner === user_id) return { ai: true, domains: ['All domains'], events: true, webAnalytics: true } - const member = await TeamMemberModel.findOne({ project_id, user_id }, { permission: 1 }); + const member = await TeamMemberModel.findOne({ project_id, $or: [{ user_id }, { email }] }, { permission: 1 }); if (!member) return { ai: false, domains: [], events: false, webAnalytics: false } return { ai: false, domains: [], events: false, webAnalytics: false, ...member.permission as any } } -async function hasAccessToProject(user_id: string, project: TProject) { +async function hasAccessToProject(user_id: string, project: TProject, email: string) { if (!project) return [false, 'NONE']; const owner = project.owner.toString(); const project_id = project._id; if (owner === user_id) return [true, 'OWNER']; - const isGuest = await TeamMemberModel.exists({ project_id, user_id }); + const isGuest = await TeamMemberModel.exists({ project_id, $or: [{ user_id }, { email }] }); if (isGuest) return [true, 'GUEST']; //TODO: Create table with admins @@ -128,14 +128,14 @@ export async function getRequestData(event: H3Event, requir if (user.id != project.owner.toString()) { if (required_permissions.includes('OWNER')) return setResponseStatus(event, 403, 'ADMIN permission required'); - const hasAccess = await TeamMemberModel.findOne({ project_id, user_id: user.id }); + const hasAccess = await TeamMemberModel.findOne({ project_id, $or: [{ user_id: user.id }, { email: user.user.email }] }); if (!hasAccess) return setResponseStatus(event, 403, 'No permissions'); } if (required_permissions.length > 0 || requireDomain) { - const permission = await getAccessPermission(user.id, project); + const permission = await getAccessPermission(user.id, project, user.user.email); if (required_permissions.includes('WEB') && permission.webAnalytics === false) { return setResponseStatus(event, 403, 'WEB permission required'); @@ -220,7 +220,7 @@ export async function getRequestDataOld(event: H3Event, opt if (pid !== "6643cd08a1854e3b81722ab5") { - const [hasAccess, role] = await hasAccessToProject(user.id, project); + const [hasAccess, role] = await hasAccessToProject(user.id, project, user.user.email); if (!hasAccess) return setResponseStatus(event, 400, 'no access to project'); if (role === 'GUEST' && !allowGuests) return setResponseStatus(event, 403, 'only owner can access this'); } else { diff --git a/dashboard/server/utils/hasAccessToProject.ts b/dashboard/server/utils/hasAccessToProject.ts index 6681b7b..568bd06 100644 --- a/dashboard/server/utils/hasAccessToProject.ts +++ b/dashboard/server/utils/hasAccessToProject.ts @@ -1,11 +1,11 @@ import { ProjectModel, TProject } from "@schema/project/ProjectSchema"; import { TeamMemberModel } from "@schema/TeamMemberSchema"; -export async function hasAccessToProject(user_id: string, project_id: string, project?: TProject) { +export async function hasAccessToProject(user_id: string, project_id: string, email: string, project?: TProject) { const targetProject = project ?? await ProjectModel.findById(project_id, { owner: true }); if (!targetProject) return [false, 'NONE']; if (targetProject.owner.toString() === user_id) return [true, 'OWNER']; - const isGuest = await TeamMemberModel.exists({ project_id, user_id }); + const isGuest = await TeamMemberModel.exists({ project_id, $or: [{ user_id }, { email }] }); if (isGuest) return [true, 'GUEST']; return [false, 'NONE']; } \ No newline at end of file diff --git a/shared_global/schema/shields/PageBlacklistSchema.ts b/shared_global/schema/shields/PageBlacklistSchema.ts deleted file mode 100644 index df8d6c7..0000000 --- a/shared_global/schema/shields/PageBlacklistSchema.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { model, Schema, Types } from 'mongoose'; - -export type TPageBlacklistSchema = { - _id: Schema.Types.ObjectId, - project_id: Schema.Types.ObjectId, - page: string, - description:string, - created_at: Date -} - -const CountryBlacklistSchema = new Schema({ - project_id: { type: Types.ObjectId, index: 1 }, - page: { type: String, required: true }, - description: { type: String }, - created_at: { type: Date, default: () => Date.now() }, -}); - -export const CountryBlacklistModel = model('country_blacklists', CountryBlacklistSchema);