Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Link folders #1258

Open
wants to merge 278 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
278 commits
Select commit Hold shift + click to select a range
36c1b53
update the folder listing with new UI
devkiran Sep 17, 2024
8781bb2
update title
devkiran Sep 18, 2024
6a921dc
Merge branch 'main' into link-folders
devkiran Sep 18, 2024
e26cdaf
format
devkiran Sep 18, 2024
2d5b400
rename the model
devkiran Sep 18, 2024
47d5ecf
add create modal form
devkiran Sep 18, 2024
f9d8474
display links count for each folder
devkiran Sep 18, 2024
61d7d19
add folder actions + rename folder
devkiran Sep 18, 2024
e5f34ab
delete folder modal
devkiran Sep 18, 2024
b4e4d19
Add workspace access to create folder modal
devkiran Sep 18, 2024
7ddabee
update styles
devkiran Sep 18, 2024
791e155
add description
devkiran Sep 18, 2024
0f95d85
wip folder members page
devkiran Sep 18, 2024
555a60f
format
devkiran Sep 18, 2024
72c897f
Merge branch 'main' into link-folders
devkiran Sep 18, 2024
905cd28
add MoveLinkToFolderModal
devkiran Sep 18, 2024
886ad76
wip move link to folder
devkiran Sep 18, 2024
10e5ad9
update the workspace access via UI
devkiran Sep 20, 2024
eb299a6
format
devkiran Sep 20, 2024
0e441c2
handle the very length name
devkiran Sep 20, 2024
cc5b648
folder access request
devkiran Sep 20, 2024
b089f03
Merge branch 'main' into link-folders
steven-tey Sep 20, 2024
a35edec
wip users folder access
devkiran Sep 20, 2024
5e8289b
Merge branch 'main' into link-folders
devkiran Sep 20, 2024
9ba76b9
Merge branch 'link-folders' of https://github.com/dubinc/dub into lin…
devkiran Sep 20, 2024
9948ab7
update roles and access level
devkiran Sep 20, 2024
033a5de
fix the select options
devkiran Sep 20, 2024
e21ca12
fix the folder role
devkiran Sep 20, 2024
83c6b94
disable edit for non-owner
devkiran Sep 20, 2024
59beb10
Merge branch 'main' into link-folders
devkiran Sep 21, 2024
6cc06c4
update folder permissions
devkiran Sep 21, 2024
a9ce5c6
apply folder permissions on UI
devkiran Sep 21, 2024
5b0bbca
more permission checks
devkiran Sep 21, 2024
e5da4f1
folder user role update
devkiran Sep 21, 2024
7a1b278
prevent current user from updating their own role
devkiran Sep 21, 2024
d685fd8
Display "All links" folder at the beginning of the folders list
devkiran Sep 21, 2024
7fe8e6b
fix types
devkiran Sep 21, 2024
495cccf
fix links count
devkiran Sep 21, 2024
bc8c532
Fix the count of links in a folder
devkiran Sep 21, 2024
e548f70
remove console.log
devkiran Sep 21, 2024
0f4c8e0
add search box
devkiran Sep 21, 2024
8648037
format
devkiran Sep 21, 2024
17d8edc
handle the permissions in UI
devkiran Sep 22, 2024
50ee561
send linkCount
devkiran Sep 22, 2024
56cc0df
Merge branch 'main' into link-folders
devkiran Sep 23, 2024
547bf64
move link to a folder
devkiran Sep 23, 2024
ac989c4
apply folder permission on link level
devkiran Sep 23, 2024
9b2d884
add throwIfInvalidFolderAccess
devkiran Sep 23, 2024
3a13f22
create folder from links page
devkiran Sep 23, 2024
b6a8eaf
display selected folder
devkiran Sep 23, 2024
9f0814d
create a link within the selected folder
devkiran Sep 23, 2024
3ea3734
add folder actions
devkiran Sep 23, 2024
968710d
send email to the owner asking for edit access
devkiran Sep 23, 2024
97f8202
Refresh the users list after updating the folder access level
devkiran Sep 23, 2024
225b97d
handle no access for the user
devkiran Sep 23, 2024
0520078
format
devkiran Sep 23, 2024
d94c110
display the folder access requested status
devkiran Sep 23, 2024
4972a42
some rename
devkiran Sep 23, 2024
d0269d1
add logo next to the workspace level access dropdown
devkiran Sep 23, 2024
a3109c1
add folder logos
devkiran Sep 23, 2024
1eed399
Merge branch 'main' into link-folders
devkiran Sep 23, 2024
d17b7c8
some fixes
devkiran Sep 23, 2024
4cd28c3
Merge branch 'link-folders' of https://github.com/dubinc/dub into lin…
devkiran Sep 23, 2024
22d2cca
Merge branch 'main' into link-folders
devkiran Sep 24, 2024
f617804
add folder access check
devkiran Sep 24, 2024
fc36812
apply folder permissions
devkiran Sep 24, 2024
fd58701
check for folder permissions and filter
devkiran Sep 24, 2024
4256506
some permission check
devkiran Sep 24, 2024
5bba119
rename
devkiran Sep 24, 2024
f959c55
update methods
devkiran Sep 24, 2024
276c52d
hide the create link if the user doesn't have access to folder
devkiran Sep 24, 2024
cc7caaf
update folder icons
devkiran Sep 24, 2024
6e03f97
fix icons
devkiran Sep 24, 2024
6f975dd
add request access button on links page
devkiran Sep 24, 2024
0cf26a9
add missing permissions
devkiran Sep 24, 2024
0913c70
update
devkiran Sep 24, 2024
b62d8e7
Merge branch 'main' into link-folders
devkiran Sep 24, 2024
73ea8d7
update ui
devkiran Sep 24, 2024
e31c74c
add getFolderOrThrow
devkiran Sep 24, 2024
96ee2fa
folder permission fixes
devkiran Sep 24, 2024
b10be87
Merge branch 'main' into link-folders
steven-tey Sep 25, 2024
c53c646
add bg color
devkiran Sep 25, 2024
64b25d2
add the step progress at the bottom
devkiran Sep 25, 2024
4617364
Merge branch 'link-folders' of https://github.com/dubinc/dub into lin…
devkiran Sep 25, 2024
fe93979
support folder search
devkiran Sep 25, 2024
2e52306
rename types
devkiran Sep 25, 2024
fcc85bf
make the folder shortcut works
devkiran Sep 25, 2024
e109c75
Merge branch 'main' into link-folders
devkiran Sep 25, 2024
663a7f2
some cleanup
devkiran Sep 25, 2024
6be02aa
consistent method name
devkiran Sep 25, 2024
e9bfa89
Fix fetching links
devkiran Sep 25, 2024
4fad662
filter analytics by folderId
devkiran Sep 25, 2024
a7f73b0
remove console.log
devkiran Sep 25, 2024
f3a4f44
add folderId to events API
devkiran Sep 25, 2024
b0fa0e9
update analytics and events
devkiran Sep 25, 2024
fcae3e2
fix query
devkiran Sep 25, 2024
a90d7fb
Merge branch 'main' into link-folders
devkiran Sep 25, 2024
48506d7
Merge branch 'main' into link-folders
steven-tey Sep 26, 2024
6038587
Merge branch 'main' into link-folders
steven-tey Sep 26, 2024
1e5da4d
update count of links
devkiran Sep 26, 2024
aac2ad2
update the analytics & events
devkiran Sep 26, 2024
5918f65
small tweaks
devkiran Sep 26, 2024
9920802
format
devkiran Sep 26, 2024
a87476e
use useKeyboardShortcut
devkiran Sep 26, 2024
16e85cd
update types
devkiran Sep 26, 2024
c982bb9
rename method
devkiran Sep 26, 2024
160d25f
format
devkiran Sep 26, 2024
f359b97
make the RESEND_API_KEY optional
devkiran Sep 27, 2024
07f4ba6
setup mailhog
devkiran Sep 27, 2024
f9571de
Revert "setup mailhog"
devkiran Sep 27, 2024
8e10fa1
Revert "make the RESEND_API_KEY optional"
devkiran Sep 27, 2024
4fe194e
Merge branch 'main' into link-folders
devkiran Sep 27, 2024
07b6e84
Merge branch 'main' into link-folders
devkiran Sep 28, 2024
f7a0c45
Merge branch 'main' into link-folders
steven-tey Oct 1, 2024
b6ac239
Merge branch 'main' into link-folders
steven-tey Oct 2, 2024
b20bbd4
Merge branch 'main' into link-folders
steven-tey Oct 2, 2024
55abe0f
Merge branch 'main' into link-folders
devkiran Oct 4, 2024
295ae9a
fix the links filter
devkiran Oct 4, 2024
f6d303d
format
devkiran Oct 4, 2024
8c54dd6
Merge branch 'main' into link-folders
devkiran Oct 4, 2024
d64a49a
add unsorted label
devkiran Oct 4, 2024
e292869
rename
devkiran Oct 4, 2024
e09cbc7
Merge branch 'main' into link-folders
steven-tey Oct 4, 2024
39c090b
Merge branch 'main' into link-folders
steven-tey Oct 6, 2024
f942544
Update index.tsx
steven-tey Oct 6, 2024
03daa60
Merge branch 'main' into link-folders
steven-tey Oct 6, 2024
9793da1
Merge branch 'main' into link-folders
devkiran Oct 7, 2024
1b3a7aa
add feature flag
devkiran Oct 7, 2024
c38f7f7
Merge branch 'main' into link-folders
steven-tey Oct 7, 2024
3d87472
Merge branch 'main' into link-folders
devkiran Oct 9, 2024
4bf4f82
Merge branch 'side-nav-layout' into link-folders
devkiran Oct 9, 2024
744cc5f
fix conflicts
devkiran Oct 9, 2024
b9b54f3
small fix
devkiran Oct 9, 2024
ccf1959
another fix
devkiran Oct 9, 2024
52e6052
Merge branch 'main' into link-folders
steven-tey Oct 10, 2024
cae3c74
Merge branch 'main' into link-folders
steven-tey Oct 11, 2024
1367985
Merge branch 'main' into link-folders
steven-tey Oct 11, 2024
4ee0eaf
Merge branch 'main' into link-folders
steven-tey Oct 13, 2024
671b702
Merge branch 'main' into link-folders
steven-tey Oct 14, 2024
bc935d8
Merge branch 'main' into link-folders
steven-tey Oct 14, 2024
ba1f3eb
Merge branch 'main' into link-folders
steven-tey Oct 14, 2024
b4039a6
Merge branch 'main' into link-folders
steven-tey Oct 15, 2024
84f4a58
Merge branch 'main' into link-folders
steven-tey Oct 15, 2024
98286d7
Merge branch 'main' into link-folders
devkiran Oct 17, 2024
9c2ce86
Merge branch 'main' into link-folders
steven-tey Oct 17, 2024
893a273
Merge branch 'main' into link-folders
steven-tey Oct 18, 2024
edbfdd7
Merge branch 'main' into link-folders
steven-tey Oct 20, 2024
a77e2f6
Update folder switcher for new app layout
TWilson023 Oct 21, 2024
7a155bc
Move folders into Library
TWilson023 Oct 21, 2024
4dbc6ad
Merge branch 'main' into link-folders
TWilson023 Oct 22, 2024
dead48f
Add permissions panel
TWilson023 Oct 22, 2024
5c3e705
Truncation fixes
TWilson023 Oct 22, 2024
28256f0
Merge branch 'main' into link-folders
devkiran Nov 12, 2024
b490d6e
match Prisma versions
devkiran Nov 12, 2024
aadad24
fix types
devkiran Nov 12, 2024
2dd1897
format
devkiran Nov 12, 2024
38a5037
update pnpm-lock
devkiran Nov 12, 2024
b2923d7
Merge branch 'main' into link-folders
devkiran Dec 18, 2024
1753e8c
use @dub/prisma
devkiran Dec 18, 2024
b18c9f7
Merge branch 'main' into link-folders
devkiran Dec 19, 2024
79f9820
fix icons imports
devkiran Dec 19, 2024
a6a56db
fix build
devkiran Dec 19, 2024
61b6165
fix the typo
devkiran Dec 19, 2024
02be3a6
use "@dub/prisma/client";
devkiran Dec 19, 2024
1674be5
format
devkiran Dec 19, 2024
af1c88c
Delete seed-test-data.ts
devkiran Dec 19, 2024
06252e5
rename Schema
devkiran Dec 19, 2024
c16bdda
some fixes
devkiran Dec 19, 2024
4be7471
some cleanup
devkiran Dec 19, 2024
0125cbf
add getFolderOrThrow
devkiran Dec 19, 2024
8f13eef
add // TODO
devkiran Dec 19, 2024
888112a
format
devkiran Dec 19, 2024
373aa1a
add copy folder id
devkiran Dec 19, 2024
f0a80bd
add prefix
devkiran Dec 19, 2024
5cdcd24
don't fetch links count
devkiran Dec 19, 2024
ac60a80
Update folder-permissions-panel.tsx
devkiran Dec 19, 2024
f17867b
Update get-folders.ts
devkiran Dec 19, 2024
5b64be1
Update route.ts
devkiran Dec 20, 2024
9407c2a
Merge branch 'main' into link-folders
steven-tey Dec 20, 2024
e3e3f9f
run prettier
steven-tey Dec 20, 2024
01fada3
Merge branch 'main' into link-folders
steven-tey Dec 21, 2024
7ba7804
Merge branch 'main' into link-folders
steven-tey Dec 21, 2024
1367f95
Merge branch 'main' into link-folders
steven-tey Dec 22, 2024
a05d2c0
folder_id
steven-tey Dec 22, 2024
c522e6e
Merge branch 'link-folders' of https://github.com/dubinc/dub into lin…
devkiran Dec 23, 2024
ad41654
Move all program links into a folder
devkiran Dec 23, 2024
07b3ff5
Merge branch 'main' into link-folders
devkiran Jan 21, 2025
52f4714
temp fix
devkiran Jan 21, 2025
c2c3342
Refactor folder permission checks across multiple API routes to ensur…
devkiran Jan 21, 2025
54e62ca
format
devkiran Jan 21, 2025
024349a
Update route.ts
devkiran Jan 21, 2025
2dfa477
Update pricing.tsx
devkiran Jan 21, 2025
447a01b
fix tests
devkiran Jan 21, 2025
d12a8d3
Update types.ts
devkiran Jan 21, 2025
00ca062
Update route.ts
devkiran Jan 21, 2025
dceeece
Update route.ts
devkiran Jan 21, 2025
baed16b
Update route.ts
devkiran Jan 21, 2025
d177be0
Update route.ts
devkiran Jan 21, 2025
aca2494
Merge branch 'main' into link-folders
steven-tey Jan 21, 2025
d667e72
move FolderEditAccessRequested to @dub/email
devkiran Jan 22, 2025
ef2608b
Merge branch 'main' into link-folders
steven-tey Jan 22, 2025
4a400dd
Add controls to allow for selecting and creating folders when creatin…
devkiran Jan 22, 2025
3758c3c
Merge branch 'link-folders' of https://github.com/dubinc/dub into lin…
devkiran Jan 22, 2025
ff3bd87
format
devkiran Jan 22, 2025
de1d49e
remove allowedFolderIds from analytics and events
devkiran Jan 22, 2025
d5199f2
rename to unsortedLinks
devkiran Jan 22, 2025
65b0fbf
Update route.ts
devkiran Jan 22, 2025
4de91e5
fix margin
devkiran Jan 22, 2025
709cccc
Enhance folder deletion handling and UI responsiveness
devkiran Jan 22, 2025
06ee2e7
Update index.tsx
devkiran Jan 22, 2025
1fca3a2
wip analytics
devkiran Jan 22, 2025
e4a1b80
filter by folderId
devkiran Jan 22, 2025
d37ef71
Update toggle.tsx
devkiran Jan 22, 2025
17110bb
rename to folder-icon
devkiran Jan 22, 2025
c17b353
Update folder-icon.tsx
devkiran Jan 22, 2025
2cb470e
Update toggle.tsx
devkiran Jan 22, 2025
cb40e25
Refactor folder user role management and permissions handling
devkiran Jan 22, 2025
af4f6fe
Update update-folder-user-role.ts
devkiran Jan 22, 2025
772262f
format
devkiran Jan 22, 2025
9f97ca1
fix folder icon
devkiran Jan 22, 2025
b39353c
Update folder-switcher.tsx
devkiran Jan 22, 2025
2eda80b
Update folder-dropdown.tsx
devkiran Jan 22, 2025
fd1c611
Merge branch 'main' into link-folders
devkiran Jan 23, 2025
feefb47
fix build
devkiran Jan 23, 2025
99f2fe4
wip
devkiran Jan 23, 2025
06c2d29
fix the folder switcher
devkiran Jan 23, 2025
c54d3de
Update folder-switcher.tsx
devkiran Jan 23, 2025
850c9ff
merge types
devkiran Jan 23, 2025
364c3ba
format
devkiran Jan 23, 2025
098c93d
fix build
devkiran Jan 23, 2025
a30b1bb
fix build
devkiran Jan 23, 2025
71db3b5
Update route.ts
devkiran Jan 23, 2025
9e557af
Update route.ts
devkiran Jan 23, 2025
21530a9
Update route.ts
devkiran Jan 23, 2025
5c1c9fa
Update types.ts
devkiran Jan 23, 2025
6be3e87
Update process-link.ts
devkiran Jan 23, 2025
c2cc6a8
Update create-link.test.ts
devkiran Jan 23, 2025
5e05ed8
Update route.ts
devkiran Jan 23, 2025
76ab7cb
Update get-links-count.ts
devkiran Jan 23, 2025
a8833bf
Update use-folders-count.ts
devkiran Jan 23, 2025
e4be678
Merge branch 'main' into link-folders
steven-tey Jan 24, 2025
92a1daf
Merge branch 'link-folders' of https://github.com/dubinc/dub into lin…
devkiran Jan 24, 2025
d1df48d
Update pnpm-lock.yaml
devkiran Jan 24, 2025
f76b796
Merge branch 'main' into link-folders
steven-tey Jan 24, 2025
d98a542
Update analytics.ts
devkiran Jan 25, 2025
194aecd
Merge branch 'link-folders' of https://github.com/dubinc/dub into lin…
devkiran Jan 25, 2025
75935ea
Merge branch 'main' into link-folders
steven-tey Jan 29, 2025
dd9ba10
Update pnpm-lock.yaml
steven-tey Jan 29, 2025
84f68a8
Merge branch 'main' into link-folders
steven-tey Jan 29, 2025
b211c70
Merge branch 'main' into link-folders
steven-tey Jan 29, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 28 additions & 2 deletions apps/web/app/api/analytics/export/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,19 @@ import { getDomainOrThrow } from "@/lib/api/domains/get-domain-or-throw";
import { getLinkOrThrow } from "@/lib/api/links/get-link-or-throw";
import { throwIfClicksUsageExceeded } from "@/lib/api/links/usage-checks";
import { withWorkspace } from "@/lib/auth";
import { checkFolderPermission } from "@/lib/folder/permissions";
import { analyticsQuerySchema } from "@/lib/zod/schemas/analytics";
import { Link } from "@dub/prisma/client";
import JSZip from "jszip";

// GET /api/analytics/export – get export data for analytics
export const GET = withWorkspace(
async ({ searchParams, workspace }) => {
async ({ searchParams, workspace, session }) => {
throwIfClicksUsageExceeded(workspace);

const parsedParams = analyticsQuerySchema.parse(searchParams);

const { interval, start, end, linkId, externalId, domain, key } =
const { interval, start, end, linkId, externalId, domain, key, folderId } =
parsedParams;

let link: Link | null = null;
Expand All @@ -35,6 +36,30 @@ export const GET = withWorkspace(
});
}

await Promise.all([
...(link && link.folderId
? [
checkFolderPermission({
workspaceId: workspace.id,
userId: session.user.id,
folderId: link.folderId,
requiredPermission: "folders.read",
}),
]
: []),

...(folderId
? [
checkFolderPermission({
workspaceId: workspace.id,
userId: session.user.id,
folderId,
requiredPermission: "folders.read",
}),
]
: []),
]);

validDateRangeForPlan({
plan: workspace.plan,
interval,
Expand All @@ -60,6 +85,7 @@ export const GET = withWorkspace(
event: "clicks",
groupBy: endpoint,
});

if (!response || response.length === 0) return;

const csvData = convertToCSV(response);
Expand Down
33 changes: 30 additions & 3 deletions apps/web/app/api/analytics/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { getDomainOrThrow } from "@/lib/api/domains/get-domain-or-throw";
import { getLinkOrThrow } from "@/lib/api/links/get-link-or-throw";
import { throwIfClicksUsageExceeded } from "@/lib/api/links/usage-checks";
import { withWorkspace } from "@/lib/auth";
import { checkFolderPermission } from "@/lib/folder/permissions";
import {
analyticsPathParamsSchema,
analyticsQuerySchema,
Expand All @@ -14,7 +15,7 @@ import { NextResponse } from "next/server";

// GET /api/analytics – get analytics
export const GET = withWorkspace(
async ({ params, searchParams, workspace }) => {
async ({ params, searchParams, workspace, session }) => {
throwIfClicksUsageExceeded(workspace);

let { eventType: oldEvent, endpoint: oldType } =
Expand All @@ -38,9 +39,14 @@ export const GET = withWorkspace(
externalId,
domain,
key,
folderId,
} = parsedParams;

let link: Link | null = null;

event = oldEvent || event;
groupBy = oldType || groupBy;

if (domain) {
await getDomainOrThrow({ workspace, domain });
}
Expand All @@ -55,8 +61,29 @@ export const GET = withWorkspace(
});
}

event = oldEvent || event;
groupBy = oldType || groupBy;
await Promise.all([
...(link && link.folderId
? [
checkFolderPermission({
workspaceId: workspace.id,
userId: session.user.id,
folderId: link.folderId,
requiredPermission: "folders.read",
}),
]
: []),

...(folderId
? [
checkFolderPermission({
workspaceId: workspace.id,
userId: session.user.id,
folderId,
requiredPermission: "folders.read",
}),
]
: []),
]);

validDateRangeForPlan({
plan: workspace.plan,
Expand Down
30 changes: 28 additions & 2 deletions apps/web/app/api/events/export/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { getDomainOrThrow } from "@/lib/api/domains/get-domain-or-throw";
import { getLinkOrThrow } from "@/lib/api/links/get-link-or-throw";
import { throwIfClicksUsageExceeded } from "@/lib/api/links/usage-checks";
import { withWorkspace } from "@/lib/auth";
import { checkFolderPermission } from "@/lib/folder/permissions";
import { ClickEvent, LeadEvent, SaleEvent } from "@/lib/types";
import { eventsQuerySchema } from "@/lib/zod/schemas/analytics";
import { COUNTRIES, capitalize } from "@dub/utils";
Expand Down Expand Up @@ -33,7 +34,7 @@ const columnAccessors = {

// GET /api/events/export – get export data for analytics
export const GET = withWorkspace(
async ({ searchParams, workspace }) => {
async ({ searchParams, workspace, session }) => {
throwIfClicksUsageExceeded(workspace);

const parsedParams = eventsQuerySchema
Expand All @@ -47,7 +48,8 @@ export const GET = withWorkspace(
)
.parse(searchParams);

const { event, domain, interval, start, end, columns, key } = parsedParams;
const { event, domain, interval, start, end, columns, key, folderId } =
parsedParams;

if (domain) {
await getDomainOrThrow({ workspace, domain });
Expand All @@ -58,6 +60,30 @@ export const GET = withWorkspace(
? await getLinkOrThrow({ workspaceId: workspace.id, domain, key })
: null;

await Promise.all([
...(link && link.folderId
? [
checkFolderPermission({
workspaceId: workspace.id,
userId: session.user.id,
folderId: link.folderId,
requiredPermission: "folders.read",
}),
]
: []),

...(folderId
? [
checkFolderPermission({
workspaceId: workspace.id,
userId: session.user.id,
folderId,
requiredPermission: "folders.read",
}),
]
: []),
]);

validDateRangeForPlan({
plan: workspace.plan,
interval,
Expand Down
41 changes: 38 additions & 3 deletions apps/web/app/api/events/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,29 @@ import { getDomainOrThrow } from "@/lib/api/domains/get-domain-or-throw";
import { getLinkOrThrow } from "@/lib/api/links/get-link-or-throw";
import { throwIfClicksUsageExceeded } from "@/lib/api/links/usage-checks";
import { withWorkspace } from "@/lib/auth";
import { checkFolderPermission } from "@/lib/folder/permissions";
import { eventsQuerySchema } from "@/lib/zod/schemas/analytics";
import { Link } from "@dub/prisma/client";
import { NextResponse } from "next/server";

export const GET = withWorkspace(
async ({ searchParams, workspace }) => {
async ({ searchParams, workspace, session }) => {
throwIfClicksUsageExceeded(workspace);

const parsedParams = eventsQuerySchema.parse(searchParams);

let { event, interval, start, end, linkId, externalId, domain, key } =
parsedParams;
let {
event,
interval,
start,
end,
linkId,
externalId,
domain,
key,
folderId,
} = parsedParams;

let link: Link | null = null;

if (domain) {
Expand All @@ -32,6 +43,30 @@ export const GET = withWorkspace(
});
}

await Promise.all([
...(link && link.folderId
? [
checkFolderPermission({
workspaceId: workspace.id,
userId: session.user.id,
folderId: link.folderId,
requiredPermission: "folders.read",
}),
]
: []),

...(folderId
? [
checkFolderPermission({
workspaceId: workspace.id,
userId: session.user.id,
folderId,
requiredPermission: "folders.read",
}),
]
: []),
]);

validDateRangeForPlan({
plan: workspace.plan,
interval,
Expand Down
129 changes: 129 additions & 0 deletions apps/web/app/api/folders/[folderId]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import { DubApiError } from "@/lib/api/errors";
import { parseRequestBody } from "@/lib/api/utils";
import { withWorkspace } from "@/lib/auth";
import { checkFolderPermission } from "@/lib/folder/permissions";
import { recordLink } from "@/lib/tinybird";
import { FolderSchema, updateFolderSchema } from "@/lib/zod/schemas/folders";
import { prisma } from "@dub/prisma";
import { waitUntil } from "@vercel/functions";
import { NextResponse } from "next/server";

// GET /api/folders/[folderId] - get information about a folder
export const GET = withWorkspace(
async ({ params, workspace, session }) => {
const { folderId } = params;

const folder = await checkFolderPermission({
folderId,
workspaceId: workspace.id,
userId: session.user.id,
requiredPermission: "folders.read",
});

return NextResponse.json(FolderSchema.parse(folder));
},
{
requiredPermissions: ["folders.read"],
},
);

// PATCH /api/folders/[folderId] – update a folder for a workspace
export const PATCH = withWorkspace(
async ({ req, params, workspace, session }) => {
const { folderId } = params;

const { name, accessLevel } = updateFolderSchema.parse(
await parseRequestBody(req),
);

await checkFolderPermission({
workspaceId: workspace.id,
userId: session.user.id,
folderId,
requiredPermission: "folders.write",
});

try {
const updatedFolder = await prisma.folder.update({
where: {
id: folderId,
projectId: workspace.id,
},
data: {
name,
accessLevel,
},
});

return NextResponse.json(FolderSchema.parse(updatedFolder));
} catch (error) {
if (error.code === "P2002") {
throw new DubApiError({
code: "conflict",
message: `A folder with the name "${name}" already exists.`,
});
}

throw error;
}
},
{
requiredPermissions: ["folders.write"],
},
);

// DELETE /api/folders/[folderId] – delete a folder for a workspace
export const DELETE = withWorkspace(
async ({ params, workspace, session }) => {
const { folderId } = params;

await checkFolderPermission({
workspaceId: workspace.id,
userId: session.user.id,
folderId,
requiredPermission: "folders.write",
});

const deletedFolder = await prisma.folder.delete({
where: {
id: folderId,
projectId: workspace.id,
},
include: {
links: {
include: {
tags: {
include: {
tag: true,
},
},
},
},
},
});

waitUntil(
(async () => {
const links = deletedFolder.links;

// TODO:
// Handle this via background job if number of links is huge
if (links.length > 0) {
recordLink(
links.map((link) => {
return {
...link,
folderId: null,
};
}),
);
}
})(),
);

return NextResponse.json({ id: folderId });
},
{
requiredPermissions: ["folders.write"],
},
);
Loading
Loading