directus
226 строк · 5.4 Кб
1import { ErrorCode, isDirectusError } from '@directus/errors';
2import type { PrimaryKey } from '@directus/types';
3import express from 'express';
4import { respond } from '../middleware/respond.js';
5import useCollection from '../middleware/use-collection.js';
6import { validateBatch } from '../middleware/validate-batch.js';
7import { MetaService } from '../services/meta.js';
8import { PermissionsService } from '../services/permissions/index.js';
9import asyncHandler from '../utils/async-handler.js';
10import { sanitizeQuery } from '../utils/sanitize-query.js';
11
12const router = express.Router();
13
14router.use(useCollection('directus_permissions'));
15
16router.post(
17'/',
18asyncHandler(async (req, res, next) => {
19const service = new PermissionsService({
20accountability: req.accountability,
21schema: req.schema,
22});
23
24const savedKeys: PrimaryKey[] = [];
25
26if (Array.isArray(req.body)) {
27const keys = await service.createMany(req.body);
28savedKeys.push(...keys);
29} else {
30const key = await service.createOne(req.body);
31savedKeys.push(key);
32}
33
34try {
35if (Array.isArray(req.body)) {
36const items = await service.readMany(savedKeys, req.sanitizedQuery);
37res.locals['payload'] = { data: items };
38} else {
39const item = await service.readOne(savedKeys[0]!, req.sanitizedQuery);
40res.locals['payload'] = { data: item };
41}
42} catch (error: any) {
43if (isDirectusError(error, ErrorCode.Forbidden)) {
44return next();
45}
46
47throw error;
48}
49
50return next();
51}),
52respond,
53);
54
55const readHandler = asyncHandler(async (req, res, next) => {
56const service = new PermissionsService({
57accountability: req.accountability,
58schema: req.schema,
59});
60
61const metaService = new MetaService({
62accountability: req.accountability,
63schema: req.schema,
64});
65
66let result;
67
68// TODO fix this at the service level
69// temporary fix for missing permissions https://github.com/directus/directus/issues/18654
70const temporaryQuery = { ...req.sanitizedQuery, limit: -1 };
71
72if (req.singleton) {
73result = await service.readSingleton(temporaryQuery);
74} else if (req.body.keys) {
75result = await service.readMany(req.body.keys, temporaryQuery);
76} else {
77result = await service.readByQuery(temporaryQuery);
78}
79
80const meta = await metaService.getMetaForQuery('directus_permissions', temporaryQuery);
81
82res.locals['payload'] = { data: result, meta };
83return next();
84});
85
86router.get('/', validateBatch('read'), readHandler, respond);
87router.search('/', validateBatch('read'), readHandler, respond);
88
89router.get(
90'/:pk',
91asyncHandler(async (req, res, next) => {
92if (req.path.endsWith('me')) return next();
93
94const service = new PermissionsService({
95accountability: req.accountability,
96schema: req.schema,
97});
98
99const record = await service.readOne(req.params['pk']!, req.sanitizedQuery);
100
101res.locals['payload'] = { data: record };
102return next();
103}),
104respond,
105);
106
107router.patch(
108'/',
109validateBatch('update'),
110asyncHandler(async (req, res, next) => {
111const service = new PermissionsService({
112accountability: req.accountability,
113schema: req.schema,
114});
115
116let keys: PrimaryKey[] = [];
117
118if (Array.isArray(req.body)) {
119keys = await service.updateBatch(req.body);
120} else if (req.body.keys) {
121keys = await service.updateMany(req.body.keys, req.body.data);
122} else {
123const sanitizedQuery = sanitizeQuery(req.body.query, req.accountability);
124keys = await service.updateByQuery(sanitizedQuery, req.body.data);
125}
126
127try {
128const result = await service.readMany(keys, req.sanitizedQuery);
129res.locals['payload'] = { data: result };
130} catch (error: any) {
131if (isDirectusError(error, ErrorCode.Forbidden)) {
132return next();
133}
134
135throw error;
136}
137
138return next();
139}),
140respond,
141);
142
143router.patch(
144'/:pk',
145asyncHandler(async (req, res, next) => {
146const service = new PermissionsService({
147accountability: req.accountability,
148schema: req.schema,
149});
150
151const primaryKey = await service.updateOne(req.params['pk']!, req.body);
152
153try {
154const item = await service.readOne(primaryKey, req.sanitizedQuery);
155res.locals['payload'] = { data: item || null };
156} catch (error: any) {
157if (isDirectusError(error, ErrorCode.Forbidden)) {
158return next();
159}
160
161throw error;
162}
163
164return next();
165}),
166respond,
167);
168
169router.delete(
170'/',
171validateBatch('delete'),
172asyncHandler(async (req, _res, next) => {
173const service = new PermissionsService({
174accountability: req.accountability,
175schema: req.schema,
176});
177
178if (Array.isArray(req.body)) {
179await service.deleteMany(req.body);
180} else if (req.body.keys) {
181await service.deleteMany(req.body.keys);
182} else {
183const sanitizedQuery = sanitizeQuery(req.body.query, req.accountability);
184await service.deleteByQuery(sanitizedQuery);
185}
186
187return next();
188}),
189respond,
190);
191
192router.delete(
193'/:pk',
194asyncHandler(async (req, _res, next) => {
195const service = new PermissionsService({
196accountability: req.accountability,
197schema: req.schema,
198});
199
200await service.deleteOne(req.params['pk']!);
201
202return next();
203}),
204respond,
205);
206
207router.get(
208'/me/:collection/:pk?',
209asyncHandler(async (req, res, next) => {
210const { collection, pk } = req.params;
211
212const service = new PermissionsService({
213accountability: req.accountability,
214schema: req.schema,
215});
216
217const itemPermissions = await service.getItemPermissions(collection!, pk);
218
219res.locals['payload'] = { data: itemPermissions };
220
221return next();
222}),
223respond,
224);
225
226export default router;
227