diff --git a/src/app/(main)/reports/ReportsHeader.tsx b/src/app/(main)/reports/ReportsHeader.tsx
index 068c0369..92f538ea 100644
--- a/src/app/(main)/reports/ReportsHeader.tsx
+++ b/src/app/(main)/reports/ReportsHeader.tsx
@@ -1,20 +1,25 @@
import PageHeader from 'components/layout/PageHeader';
import { Icon, Icons, Text } from 'react-basics';
-import { useMessages, useTeamUrl } from 'components/hooks';
+import { useLogin, useMessages, useTeamUrl } from 'components/hooks';
import LinkButton from 'components/common/LinkButton';
+import { ROLES } from 'lib/constants';
export function ReportsHeader() {
const { formatMessage, labels } = useMessages();
const { renderTeamUrl } = useTeamUrl();
+ const { user } = useLogin();
+ const canEdit = user.role !== ROLES.viewOnly;
return (
-
-
-
-
- {formatMessage(labels.createReport)}
-
+ {canEdit && (
+
+
+
+
+ {formatMessage(labels.createReport)}
+
+ )}
);
}
diff --git a/src/app/(main)/settings/teams/[teamId]/members/TeamMembersPage.tsx b/src/app/(main)/settings/teams/[teamId]/members/TeamMembersPage.tsx
index a8159891..3c166826 100644
--- a/src/app/(main)/settings/teams/[teamId]/members/TeamMembersPage.tsx
+++ b/src/app/(main)/settings/teams/[teamId]/members/TeamMembersPage.tsx
@@ -11,9 +11,9 @@ export function TeamMembersPage({ teamId }: { teamId: string }) {
const { user } = useLogin();
const { formatMessage, labels } = useMessages();
- const canEdit = team?.teamUser?.find(
- ({ userId, role }) => role === ROLES.teamOwner && userId === user.id,
- );
+ const canEdit =
+ team?.teamUser?.find(({ userId, role }) => role === ROLES.teamOwner && userId === user.id) &&
+ user.role !== ROLES.viewOnly;
return (
<>
diff --git a/src/app/(main)/settings/teams/[teamId]/team/TeamDetails.tsx b/src/app/(main)/settings/teams/[teamId]/team/TeamDetails.tsx
index 0ce43fec..9d8ea529 100644
--- a/src/app/(main)/settings/teams/[teamId]/team/TeamDetails.tsx
+++ b/src/app/(main)/settings/teams/[teamId]/team/TeamDetails.tsx
@@ -15,9 +15,9 @@ export function TeamDetails({ teamId }: { teamId: string }) {
const { user } = useLogin();
const [tab, setTab] = useState('details');
- const canEdit = !!team?.teamUser?.find(
- ({ userId, role }) => role === ROLES.teamOwner && userId === user.id,
- );
+ const canEdit =
+ !!team?.teamUser?.find(({ userId, role }) => role === ROLES.teamOwner && userId === user.id) &&
+ user.role !== ROLES.viewOnly;
return (
diff --git a/src/app/(main)/settings/teams/[teamId]/websites/TeamWebsitesPage.tsx b/src/app/(main)/settings/teams/[teamId]/websites/TeamWebsitesPage.tsx
index c5092c8b..882ef8ec 100644
--- a/src/app/(main)/settings/teams/[teamId]/websites/TeamWebsitesPage.tsx
+++ b/src/app/(main)/settings/teams/[teamId]/websites/TeamWebsitesPage.tsx
@@ -12,16 +12,17 @@ export function TeamWebsitesPage({ teamId }: { teamId: string }) {
const { formatMessage, labels } = useMessages();
const { user } = useLogin();
- const allowEdit = !!team?.teamUser?.find(
- ({ userId, role }) => userId === user.id && role !== ROLES.teamViewOnly,
- );
+ const canEdit =
+ !!team?.teamUser?.find(
+ ({ userId, role }) => userId === user.id && role !== ROLES.teamViewOnly,
+ ) && user.role !== ROLES.viewOnly;
return (
<>
- {allowEdit && }
+ {canEdit && }
-
+
>
);
}
diff --git a/src/app/(main)/settings/teams/[teamId]/websites/TeamWebsitesTable.tsx b/src/app/(main)/settings/teams/[teamId]/websites/TeamWebsitesTable.tsx
index 086cc03a..dc6760a6 100644
--- a/src/app/(main)/settings/teams/[teamId]/websites/TeamWebsitesTable.tsx
+++ b/src/app/(main)/settings/teams/[teamId]/websites/TeamWebsitesTable.tsx
@@ -13,12 +13,15 @@ export function TeamWebsitesTable({
allowEdit?: boolean;
}) {
const { user } = useLogin();
-
const { formatMessage, labels } = useMessages();
+
return (
+
+ {row => row?.createUser?.username}
+
{row => {
const { id: websiteId } = row;
diff --git a/src/app/(main)/settings/websites/WebsitesSettingsPage.tsx b/src/app/(main)/settings/websites/WebsitesSettingsPage.tsx
index 14411da1..ff0938d1 100644
--- a/src/app/(main)/settings/websites/WebsitesSettingsPage.tsx
+++ b/src/app/(main)/settings/websites/WebsitesSettingsPage.tsx
@@ -1,11 +1,16 @@
'use client';
+import { useLogin } from 'components/hooks';
import WebsitesDataTable from './WebsitesDataTable';
import WebsitesHeader from './WebsitesHeader';
+import { ROLES } from 'lib/constants';
export default function WebsitesSettingsPage({ teamId }: { teamId: string }) {
+ const { user } = useLogin();
+ const canCreate = user.role !== ROLES.viewOnly;
+
return (
<>
-
+
>
);
diff --git a/src/app/(main)/websites/WebsitesPage.tsx b/src/app/(main)/websites/WebsitesPage.tsx
index 75776c4c..8d8ee2e2 100644
--- a/src/app/(main)/websites/WebsitesPage.tsx
+++ b/src/app/(main)/websites/WebsitesPage.tsx
@@ -1,14 +1,11 @@
'use client';
import WebsitesHeader from 'app/(main)/settings/websites/WebsitesHeader';
import WebsitesDataTable from 'app/(main)/settings/websites/WebsitesDataTable';
-import { useLogin } from 'components/hooks';
-
-export default function WebsitesPage({ teamId }: { teamId: string; userId: string }) {
- const { user } = useLogin();
+export default function WebsitesPage({ teamId }: { teamId: string }) {
return (
<>
-
+
>
);
diff --git a/src/components/messages.ts b/src/components/messages.ts
index 2710e99d..0487004a 100644
--- a/src/components/messages.ts
+++ b/src/components/messages.ts
@@ -26,6 +26,7 @@ export const labels = defineMessages({
myWebsites: { id: 'label.my-websites', defaultMessage: 'My websites' },
teamWebsites: { id: 'label.team-websites', defaultMessage: 'Team websites' },
created: { id: 'label.created', defaultMessage: 'Created' },
+ createdBy: { id: 'label.created-by', defaultMessage: 'Created By' },
edit: { id: 'label.edit', defaultMessage: 'Edit' },
name: { id: 'label.name', defaultMessage: 'Name' },
member: { id: 'label.member', defaultMessage: 'Member' },
diff --git a/src/lib/data.ts b/src/lib/data.ts
index 47023bb4..5b502c5d 100644
--- a/src/lib/data.ts
+++ b/src/lib/data.ts
@@ -1,4 +1,4 @@
-import { isValid, parseISO } from 'date-fns';
+import { isValid } from 'date-fns';
import { DATA_TYPE } from './constants';
import { DynamicDataType } from './types';
@@ -28,7 +28,7 @@ export function flattenJSON(
export function getDataType(value: any): string {
let type: string = typeof value;
- if ((type === 'string' && isValid(value)) || isValid(parseISO(value))) {
+ if ((type === 'string' && isValid(value)) || isValid(new Date(value))) {
type = 'date';
}
diff --git a/src/pages/api/reports/index.ts b/src/pages/api/reports/index.ts
index b5478018..701ef649 100644
--- a/src/pages/api/reports/index.ts
+++ b/src/pages/api/reports/index.ts
@@ -6,7 +6,7 @@ import { NextApiResponse } from 'next';
import { methodNotAllowed, ok, unauthorized } from 'next-basics';
import { createReport, getReports } from 'queries';
import * as yup from 'yup';
-import { canViewTeam, canViewWebsite } from 'lib/auth';
+import { canUpdateWebsite, canViewTeam, canViewWebsite } from 'lib/auth';
export interface ReportRequestBody {
websiteId: string;
@@ -89,6 +89,10 @@ export default async (
if (req.method === 'POST') {
const { websiteId, type, name, description, parameters } = req.body;
+ if (!(await canUpdateWebsite(req.auth, websiteId))) {
+ return unauthorized(res);
+ }
+
const result = await createReport({
id: uuid(),
userId,
diff --git a/src/pages/api/websites/index.ts b/src/pages/api/websites/index.ts
index eb574415..0b7826ac 100644
--- a/src/pages/api/websites/index.ts
+++ b/src/pages/api/websites/index.ts
@@ -62,6 +62,7 @@ export default async (
const data: any = {
id: uuid(),
+ createdBy: userId,
name,
domain,
shareId,
diff --git a/src/queries/admin/website.ts b/src/queries/admin/website.ts
index 01d52019..cef7f15d 100644
--- a/src/queries/admin/website.ts
+++ b/src/queries/admin/website.ts
@@ -87,7 +87,7 @@ export async function getTeamWebsites(
teamId,
},
include: {
- user: {
+ createUser: {
select: {
id: true,
username: true,