Skip to content

Commit f411729

Browse files
committed
Add access control
1 parent 61fdf05 commit f411729

File tree

16 files changed

+157
-54
lines changed

16 files changed

+157
-54
lines changed

demo/src/payload.config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ export default buildConfig({
5353
plugins: [
5454
payloadDashboardAnalytics({
5555
provider: plausibleProvider,
56+
access: (user: any) => {
57+
return Boolean(user);
58+
},
5659
navigation: {
5760
afterNavLinks: [
5861
{

src/index.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const payloadDashboardAnalytics =
2424
(incomingConfig: DashboardAnalyticsConfig) =>
2525
(config: PayloadConfig): PayloadConfig => {
2626
const { admin, collections, globals } = config;
27-
const { provider, navigation, dashboard } = incomingConfig;
27+
const { provider, navigation, dashboard, access } = incomingConfig;
2828
const endpoints = config.endpoints ?? [];
2929
const apiProvider = getProvider(provider);
3030

@@ -71,12 +71,12 @@ const payloadDashboardAnalytics =
7171
},
7272
endpoints: [
7373
...endpoints,
74-
getGlobalAggregate(apiProvider),
75-
getGlobalChart(apiProvider),
76-
getPageChart(apiProvider),
77-
getPageAggregate(apiProvider),
78-
getLive(apiProvider),
79-
getReport(apiProvider),
74+
getGlobalAggregate(apiProvider, access),
75+
getGlobalChart(apiProvider, access),
76+
getPageChart(apiProvider, access),
77+
getPageAggregate(apiProvider, access),
78+
getLive(apiProvider, access),
79+
getReport(apiProvider, access),
8080
],
8181
...(collections && {
8282
collections: collections.map((collection) => {

src/providers/plausible/client.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ function client(provider: PlausibleProvider, options: ClientOptions) {
7171
propertiesMap: PropertyMap,
7272
fetch: async (customUrl?: string) => {
7373
const fetchUrl = customUrl ?? url.toString();
74-
console.log("fetching with", url.toString());
74+
7575
return await fetch(fetchUrl, {
7676
method: "get",
7777
headers: new Headers({

src/routes/getGlobalAggregate/handler.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,24 @@
1-
import { Endpoint } from "payload/config";
2-
import { ApiProvider } from "../../providers";
1+
import type { Endpoint } from "payload/config";
2+
import type { ApiProvider } from "../../providers";
3+
import type { AccessControl } from "../../types";
34

4-
const handler = (provider: ApiProvider) => {
5+
const handler = (provider: ApiProvider, access?: AccessControl) => {
56
const handler: Endpoint["handler"] = async (req, res, next) => {
6-
const { payload } = req;
7+
const { payload, user } = req;
78
const { timeframe, metrics } = req.body;
89

10+
if (access) {
11+
const accessControl = access(user);
12+
13+
if (!accessControl) {
14+
payload.logger.error("📊 Analytics API: Request fails access control.");
15+
res
16+
.status(500)
17+
.send("Request fails access control. Are you authenticated?");
18+
return next();
19+
}
20+
}
21+
922
if (!metrics) {
1023
payload.logger.error("📊 Analytics API: Missing metrics argument.");
1124
res.status(500).send("Missing metrics argument.");

src/routes/getGlobalAggregate/index.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1-
import { Endpoint } from "payload/config";
1+
import type { Endpoint } from "payload/config";
2+
import type { ApiProvider } from "../../providers";
3+
import type { AccessControl } from "../../types";
24
import handler from "./handler";
3-
import { ApiProvider } from "../../providers";
45

5-
const getGlobalAggregate = (provider: ApiProvider): Endpoint => {
6+
const getGlobalAggregate = (
7+
provider: ApiProvider,
8+
access?: AccessControl
9+
): Endpoint => {
610
return {
711
path: "/analytics/globalAggregate",
812
method: "post",
9-
handler: handler(provider),
13+
handler: handler(provider, access),
1014
};
1115
};
1216

src/routes/getGlobalChart/handler.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,24 @@
1-
import { Endpoint } from "payload/config";
2-
import { ApiProvider } from "../../providers";
1+
import type { Endpoint } from "payload/config";
2+
import type { ApiProvider } from "../../providers";
3+
import type { AccessControl } from "../../types";
34

4-
const handler = (provider: ApiProvider) => {
5+
const handler = (provider: ApiProvider, access?: AccessControl) => {
56
const handler: Endpoint["handler"] = async (req, res, next) => {
6-
const { payload } = req;
7+
const { payload, user } = req;
78
const { timeframe, metrics } = req.body;
89

10+
if (access) {
11+
const accessControl = access(user);
12+
13+
if (!accessControl) {
14+
payload.logger.error("📊 Analytics API: Request fails access control.");
15+
res
16+
.status(500)
17+
.send("Request fails access control. Are you authenticated?");
18+
return next();
19+
}
20+
}
21+
922
if (!metrics) {
1023
payload.logger.error("📊 Analytics API: Missing metrics argument.");
1124
res.status(500).send("Missing metrics argument.");

src/routes/getGlobalChart/index.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1-
import { Endpoint } from "payload/config";
1+
import type { Endpoint } from "payload/config";
2+
import type { ApiProvider } from "../../providers";
3+
import type { AccessControl } from "../../types";
24
import handler from "./handler";
3-
import { ApiProvider } from "../../providers";
45

5-
const getGlobalChart = (provider: ApiProvider): Endpoint => {
6+
const getGlobalChart = (
7+
provider: ApiProvider,
8+
access?: AccessControl
9+
): Endpoint => {
610
return {
711
path: "/analytics/globalChart",
812
method: "post",
9-
handler: handler(provider),
13+
handler: handler(provider, access),
1014
};
1115
};
1216

src/routes/getLive/handler.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,22 @@
1-
import { Endpoint } from "payload/config";
2-
import { ApiProvider } from "../../providers";
1+
import type { Endpoint } from "payload/config";
2+
import type { ApiProvider } from "../../providers";
3+
import type { AccessControl } from "../../types";
34

4-
const handler = (provider: ApiProvider) => {
5+
const handler = (provider: ApiProvider, access?: AccessControl) => {
56
const handler: Endpoint["handler"] = async (req, res, next) => {
6-
const { payload } = req;
7+
const { payload, user } = req;
8+
9+
if (access) {
10+
const accessControl = access(user);
11+
12+
if (!accessControl) {
13+
payload.logger.error("📊 Analytics API: Request fails access control.");
14+
res
15+
.status(500)
16+
.send("Request fails access control. Are you authenticated?");
17+
return next();
18+
}
19+
}
720

821
try {
922
const data = await provider.getLiveData({});

src/routes/getLive/index.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
import { Endpoint } from "payload/config";
1+
import type { Endpoint } from "payload/config";
2+
import type { ApiProvider } from "../../providers";
3+
import type { AccessControl } from "../../types";
24
import handler from "./handler";
3-
import { ApiProvider } from "../../providers";
45

5-
const getLive = (provider: ApiProvider): Endpoint => {
6+
const getLive = (provider: ApiProvider, access?: AccessControl): Endpoint => {
67
return {
78
path: "/analytics/live",
89
method: "post",
9-
handler: handler(provider),
10+
handler: handler(provider, access),
1011
};
1112
};
1213

src/routes/getPageAggregate/handler.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
11
import type { Endpoint } from "payload/config";
2-
import { ApiProvider } from "../../providers";
2+
import type { ApiProvider } from "../../providers";
33
import type { AggregateData } from "../../types/data";
4+
import type { AccessControl } from "../../types";
45

5-
const handler = (provider: ApiProvider) => {
6+
const handler = (provider: ApiProvider, access?: AccessControl) => {
67
const handler: Endpoint["handler"] = async (req, res, next) => {
7-
const { payload } = req;
8+
const { payload, user } = req;
89
const { timeframe, metrics, pageId } = req.body;
910

11+
if (access) {
12+
const accessControl = access(user);
13+
14+
if (!accessControl) {
15+
payload.logger.error("📊 Analytics API: Request fails access control.");
16+
res
17+
.status(500)
18+
.send("Request fails access control. Are you authenticated?");
19+
return next();
20+
}
21+
}
22+
1023
if (!metrics) {
1124
payload.logger.error("📊 Analytics API: Missing metrics argument.");
1225
res.status(500).send("Missing metrics argument.");

0 commit comments

Comments
 (0)