diff --git a/lib/types.ts b/lib/types.ts index 007d6fdb..9dc01719 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -7,7 +7,9 @@ export interface Auth { role: string; isAdmin: boolean; }; - shareToken?: string; + shareToken?: { + websiteId: string; + }; } export interface NextApiRequestQueryBody extends NextApiRequest { diff --git a/pages/api/share/[id].ts b/pages/api/share/[id].ts index b8a37e25..b5511f2d 100644 --- a/pages/api/share/[id].ts +++ b/pages/api/share/[id].ts @@ -23,8 +23,7 @@ export default async ( const website = await getWebsite({ shareId }); if (website) { - const { id } = website; - const data = { id }; + const data = { websiteId: website.id }; const token = createToken(data, secret()); return ok(res, { ...data, token }); diff --git a/pages/api/websites/[id]/active.ts b/pages/api/websites/[id]/active.ts index 1d007f7f..a293b637 100644 --- a/pages/api/websites/[id]/active.ts +++ b/pages/api/websites/[id]/active.ts @@ -1,5 +1,4 @@ -import { WebsiteActive } from 'lib/types'; -import { NextApiRequestQueryBody } from 'lib/types'; +import { NextApiRequestQueryBody, WebsiteActive } from 'lib/types'; import { canViewWebsite } from 'lib/auth'; import { useAuth, useCors } from 'lib/middleware'; import { NextApiResponse } from 'next'; @@ -17,13 +16,15 @@ export default async ( await useCors(req, res); await useAuth(req, res); - const { - user: { id: userId }, - } = req.auth; - const { id: websiteId } = req.query; + const { user, shareToken } = req.auth; + const userId = user?.id; + const websiteId = req.query.id; + const shared = shareToken?.websiteId === websiteId; if (req.method === 'GET') { - if (await canViewWebsite(userId, websiteId)) { + const canView = await canViewWebsite(userId, websiteId); + + if (!canView && !shared) { return unauthorized(res); } diff --git a/pages/api/websites/[id]/eventdata.ts b/pages/api/websites/[id]/eventdata.ts index 9293cbad..8ceb0abc 100644 --- a/pages/api/websites/[id]/eventdata.ts +++ b/pages/api/websites/[id]/eventdata.ts @@ -30,7 +30,9 @@ export default async ( const { id: websiteId } = req.query; if (req.method === 'POST') { - if (canViewWebsite(userId, websiteId)) { + const canView = canViewWebsite(userId, websiteId); + + if (!canView) { return unauthorized(res); } diff --git a/pages/api/websites/[id]/events.ts b/pages/api/websites/[id]/events.ts index 726669a3..d328c83d 100644 --- a/pages/api/websites/[id]/events.ts +++ b/pages/api/websites/[id]/events.ts @@ -25,13 +25,15 @@ export default async ( await useCors(req, res); await useAuth(req, res); - const { - user: { id: userId }, - } = req.auth; const { id: websiteId, start_at, end_at, unit, tz, url, event_name } = req.query; + const { user, shareToken } = req.auth; + const userId = user?.id; + const shared = shareToken?.websiteId === websiteId; if (req.method === 'GET') { - if (canViewWebsite(userId, websiteId)) { + const canView = canViewWebsite(userId, websiteId); + + if (!canView && !shared) { return unauthorized(res); } diff --git a/pages/api/websites/[id]/index.ts b/pages/api/websites/[id]/index.ts index 2f11ec70..0a0fa662 100644 --- a/pages/api/websites/[id]/index.ts +++ b/pages/api/websites/[id]/index.ts @@ -22,13 +22,15 @@ export default async ( await useCors(req, res); await useAuth(req, res); - const { - user: { id: userId }, - } = req.auth; - const { id: websiteId } = req.query; + const { user, shareToken } = req.auth; + const userId = user?.id; + const websiteId = req.query.id; + const shared = shareToken?.websiteId === websiteId; if (req.method === 'GET') { - if (!(await canViewWebsite(userId, websiteId))) { + const canView = await canViewWebsite(userId, websiteId); + + if (!canView && !shared) { return unauthorized(res); } @@ -38,7 +40,9 @@ export default async ( } if (req.method === 'POST') { - if (!(await canUpdateWebsite(userId, websiteId))) { + const canUpdate = await canUpdateWebsite(userId, websiteId); + + if (!canUpdate) { return unauthorized(res); } @@ -56,7 +60,9 @@ export default async ( } if (req.method === 'DELETE') { - if (!(await canDeleteWebsite(userId, websiteId))) { + const canDelete = await canDeleteWebsite(userId, websiteId); + + if (!canDelete) { return unauthorized(res); } diff --git a/pages/api/websites/[id]/metrics.ts b/pages/api/websites/[id]/metrics.ts index 260814da..7eb364a1 100644 --- a/pages/api/websites/[id]/metrics.ts +++ b/pages/api/websites/[id]/metrics.ts @@ -55,9 +55,6 @@ export default async ( await useCors(req, res); await useAuth(req, res); - const { - user: { id: userId }, - } = req.auth; const { id: websiteId, type, @@ -70,9 +67,14 @@ export default async ( device, country, } = req.query; + const { user, shareToken } = req.auth; + const userId = user?.id; + const shared = shareToken?.websiteId === websiteId; if (req.method === 'GET') { - if (!(await canViewWebsite(userId, websiteId))) { + const canView = await canViewWebsite(userId, websiteId); + + if (!canView && !shared) { return unauthorized(res); } diff --git a/pages/api/websites/[id]/pageviews.ts b/pages/api/websites/[id]/pageviews.ts index ea6c5df4..a9d91444 100644 --- a/pages/api/websites/[id]/pageviews.ts +++ b/pages/api/websites/[id]/pageviews.ts @@ -30,9 +30,6 @@ export default async ( await useCors(req, res); await useAuth(req, res); - const { - user: { id: userId }, - } = req.auth; const { id: websiteId, start_at, @@ -46,9 +43,14 @@ export default async ( device, country, } = req.query; + const { user, shareToken } = req.auth; + const userId = user?.id; + const shared = shareToken?.websiteId === websiteId; if (req.method === 'GET') { - if (!(await canViewWebsite(userId, websiteId))) { + const canView = await canViewWebsite(userId, websiteId); + + if (!canView && !shared) { return unauthorized(res); } diff --git a/pages/api/websites/[id]/reset.ts b/pages/api/websites/[id]/reset.ts index 292672ae..70f5618a 100644 --- a/pages/api/websites/[id]/reset.ts +++ b/pages/api/websites/[id]/reset.ts @@ -1,5 +1,5 @@ import { NextApiRequestQueryBody } from 'lib/types'; -import { canViewWebsite } from 'lib/auth'; +import { canUpdateWebsite } from 'lib/auth'; import { useAuth, useCors } from 'lib/middleware'; import { NextApiResponse } from 'next'; import { methodNotAllowed, ok, unauthorized } from 'next-basics'; @@ -22,7 +22,9 @@ export default async ( const { id: websiteId } = req.query; if (req.method === 'POST') { - if (!(await canViewWebsite(userId, websiteId))) { + const canUpdate = await canUpdateWebsite(userId, websiteId); + + if (!canUpdate) { return unauthorized(res); } diff --git a/pages/api/websites/[id]/stats.ts b/pages/api/websites/[id]/stats.ts index 85c4f254..c5b9bbf1 100644 --- a/pages/api/websites/[id]/stats.ts +++ b/pages/api/websites/[id]/stats.ts @@ -1,5 +1,4 @@ -import { WebsiteStats } from 'lib/types'; -import { NextApiRequestQueryBody } from 'lib/types'; +import { NextApiRequestQueryBody, WebsiteStats } from 'lib/types'; import { canViewWebsite } from 'lib/auth'; import { useAuth, useCors } from 'lib/middleware'; import { NextApiResponse } from 'next'; @@ -26,9 +25,6 @@ export default async ( await useCors(req, res); await useAuth(req, res); - const { - user: { id: userId }, - } = req.auth; const { id: websiteId, start_at, @@ -40,9 +36,14 @@ export default async ( device, country, } = req.query; + const { user, shareToken } = req.auth; + const userId = user?.id; + const shared = shareToken?.websiteId === websiteId; if (req.method === 'GET') { - if (!(await canViewWebsite(userId, websiteId))) { + const canView = await canViewWebsite(userId, websiteId); + + if (!canView && !shared) { return unauthorized(res); } diff --git a/pages/share/[...id].js b/pages/share/[...id].js index d449afa5..e46c6af2 100644 --- a/pages/share/[...id].js +++ b/pages/share/[...id].js @@ -16,7 +16,7 @@ export default function SharePage() { return ( - + ); }