summaryrefslogtreecommitdiff
path: root/packages/backend/src/server/api/endpoints/admin/drive
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2021-11-12 02:02:25 +0900
committersyuilo <Syuilotan@yahoo.co.jp>2021-11-12 02:02:25 +0900
commit0e4a111f81cceed275d9bec2695f6e401fb654d8 (patch)
tree40874799472fa07416f17b50a398ac33b7771905 /packages/backend/src/server/api/endpoints/admin/drive
parentupdate deps (diff)
downloadsharkey-0e4a111f81cceed275d9bec2695f6e401fb654d8.tar.gz
sharkey-0e4a111f81cceed275d9bec2695f6e401fb654d8.tar.bz2
sharkey-0e4a111f81cceed275d9bec2695f6e401fb654d8.zip
refactoring
Resolve #7779
Diffstat (limited to 'packages/backend/src/server/api/endpoints/admin/drive')
-rw-r--r--packages/backend/src/server/api/endpoints/admin/drive/clean-remote-files.ts13
-rw-r--r--packages/backend/src/server/api/endpoints/admin/drive/cleanup.ts21
-rw-r--r--packages/backend/src/server/api/endpoints/admin/drive/files.ts81
-rw-r--r--packages/backend/src/server/api/endpoints/admin/drive/show-file.ts180
4 files changed, 295 insertions, 0 deletions
diff --git a/packages/backend/src/server/api/endpoints/admin/drive/clean-remote-files.ts b/packages/backend/src/server/api/endpoints/admin/drive/clean-remote-files.ts
new file mode 100644
index 0000000000..76a6acff59
--- /dev/null
+++ b/packages/backend/src/server/api/endpoints/admin/drive/clean-remote-files.ts
@@ -0,0 +1,13 @@
+import define from '../../../define';
+import { createCleanRemoteFilesJob } from '@/queue/index';
+
+export const meta = {
+ tags: ['admin'],
+
+ requireCredential: true as const,
+ requireModerator: true,
+};
+
+export default define(meta, async (ps, me) => {
+ createCleanRemoteFilesJob();
+});
diff --git a/packages/backend/src/server/api/endpoints/admin/drive/cleanup.ts b/packages/backend/src/server/api/endpoints/admin/drive/cleanup.ts
new file mode 100644
index 0000000000..8497478da9
--- /dev/null
+++ b/packages/backend/src/server/api/endpoints/admin/drive/cleanup.ts
@@ -0,0 +1,21 @@
+import { IsNull } from 'typeorm';
+import define from '../../../define';
+import { deleteFile } from '@/services/drive/delete-file';
+import { DriveFiles } from '@/models/index';
+
+export const meta = {
+ tags: ['admin'],
+
+ requireCredential: true as const,
+ requireModerator: true,
+};
+
+export default define(meta, async (ps, me) => {
+ const files = await DriveFiles.find({
+ userId: IsNull()
+ });
+
+ for (const file of files) {
+ deleteFile(file);
+ }
+});
diff --git a/packages/backend/src/server/api/endpoints/admin/drive/files.ts b/packages/backend/src/server/api/endpoints/admin/drive/files.ts
new file mode 100644
index 0000000000..fe1c799805
--- /dev/null
+++ b/packages/backend/src/server/api/endpoints/admin/drive/files.ts
@@ -0,0 +1,81 @@
+import $ from 'cafy';
+import define from '../../../define';
+import { DriveFiles } from '@/models/index';
+import { makePaginationQuery } from '../../../common/make-pagination-query';
+import { ID } from '@/misc/cafy-id';
+
+export const meta = {
+ tags: ['admin'],
+
+ requireCredential: false as const,
+ requireModerator: true,
+
+ params: {
+ limit: {
+ validator: $.optional.num.range(1, 100),
+ default: 10
+ },
+
+ sinceId: {
+ validator: $.optional.type(ID),
+ },
+
+ untilId: {
+ validator: $.optional.type(ID),
+ },
+
+ type: {
+ validator: $.optional.nullable.str.match(/^[a-zA-Z0-9\/\-*]+$/)
+ },
+
+ origin: {
+ validator: $.optional.str.or([
+ 'combined',
+ 'local',
+ 'remote',
+ ]),
+ default: 'local'
+ },
+
+ hostname: {
+ validator: $.optional.nullable.str,
+ default: null
+ },
+ },
+
+ res: {
+ type: 'array' as const,
+ optional: false as const, nullable: false as const,
+ items: {
+ type: 'object' as const,
+ optional: false as const, nullable: false as const,
+ ref: 'DriveFile'
+ }
+ }
+};
+
+export default define(meta, async (ps, me) => {
+ const query = makePaginationQuery(DriveFiles.createQueryBuilder('file'), ps.sinceId, ps.untilId);
+
+ if (ps.origin === 'local') {
+ query.andWhere('file.userHost IS NULL');
+ } else if (ps.origin === 'remote') {
+ query.andWhere('file.userHost IS NOT NULL');
+ }
+
+ if (ps.hostname) {
+ query.andWhere('file.userHost = :hostname', { hostname: ps.hostname });
+ }
+
+ if (ps.type) {
+ if (ps.type.endsWith('/*')) {
+ query.andWhere('file.type like :type', { type: ps.type.replace('/*', '/') + '%' });
+ } else {
+ query.andWhere('file.type = :type', { type: ps.type });
+ }
+ }
+
+ const files = await query.take(ps.limit!).getMany();
+
+ return await DriveFiles.packMany(files, { detail: true, withUser: true, self: true });
+});
diff --git a/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts b/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts
new file mode 100644
index 0000000000..270b89c4fa
--- /dev/null
+++ b/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts
@@ -0,0 +1,180 @@
+import $ from 'cafy';
+import { ID } from '@/misc/cafy-id';
+import define from '../../../define';
+import { ApiError } from '../../../error';
+import { DriveFiles } from '@/models/index';
+
+export const meta = {
+ tags: ['admin'],
+
+ requireCredential: true as const,
+ requireModerator: true,
+
+ params: {
+ fileId: {
+ validator: $.optional.type(ID),
+ },
+
+ url: {
+ validator: $.optional.str,
+ },
+ },
+
+ errors: {
+ noSuchFile: {
+ message: 'No such file.',
+ code: 'NO_SUCH_FILE',
+ id: 'caf3ca38-c6e5-472e-a30c-b05377dcc240'
+ }
+ },
+
+ res: {
+ type: 'object' as const,
+ optional: false as const, nullable: false as const,
+ properties: {
+ id: {
+ type: 'string' as const,
+ optional: false as const, nullable: false as const,
+ format: 'id',
+ example: 'xxxxxxxxxx',
+ },
+ createdAt: {
+ type: 'string' as const,
+ optional: false as const, nullable: false as const,
+ format: 'date-time',
+ },
+ userId: {
+ type: 'string' as const,
+ optional: false as const, nullable: true as const,
+ format: 'id',
+ example: 'xxxxxxxxxx',
+ },
+ userHost: {
+ type: 'string' as const,
+ optional: false as const, nullable: true as const
+ },
+ md5: {
+ type: 'string' as const,
+ optional: false as const, nullable: false as const,
+ format: 'md5',
+ example: '15eca7fba0480996e2245f5185bf39f2'
+ },
+ name: {
+ type: 'string' as const,
+ optional: false as const, nullable: false as const,
+ example: 'lenna.jpg'
+ },
+ type: {
+ type: 'string' as const,
+ optional: false as const, nullable: false as const,
+ example: 'image/jpeg'
+ },
+ size: {
+ type: 'number' as const,
+ optional: false as const, nullable: false as const,
+ example: 51469
+ },
+ comment: {
+ type: 'string' as const,
+ optional: false as const, nullable: true as const
+ },
+ blurhash: {
+ type: 'string' as const,
+ optional: false as const, nullable: true as const
+ },
+ properties: {
+ type: 'object' as const,
+ optional: false as const, nullable: false as const,
+ properties: {
+ width: {
+ type: 'number' as const,
+ optional: false as const, nullable: false as const,
+ example: 1280
+ },
+ height: {
+ type: 'number' as const,
+ optional: false as const, nullable: false as const,
+ example: 720
+ },
+ avgColor: {
+ type: 'string' as const,
+ optional: true as const, nullable: false as const,
+ example: 'rgb(40,65,87)'
+ }
+ }
+ },
+ storedInternal: {
+ type: 'boolean' as const,
+ optional: false as const, nullable: true as const,
+ example: true
+ },
+ url: {
+ type: 'string' as const,
+ optional: false as const, nullable: true as const,
+ format: 'url',
+ },
+ thumbnailUrl: {
+ type: 'string' as const,
+ optional: false as const, nullable: true as const,
+ format: 'url',
+ },
+ webpublicUrl: {
+ type: 'string' as const,
+ optional: false as const, nullable: true as const,
+ format: 'url',
+ },
+ accessKey: {
+ type: 'string' as const,
+ optional: false as const, nullable: false as const,
+ },
+ thumbnailAccessKey: {
+ type: 'string' as const,
+ optional: false as const, nullable: false as const,
+ },
+ webpublicAccessKey: {
+ type: 'string' as const,
+ optional: false as const, nullable: false as const,
+ },
+ uri: {
+ type: 'string' as const,
+ optional: false as const, nullable: true as const
+ },
+ src: {
+ type: 'string' as const,
+ optional: false as const, nullable: true as const
+ },
+ folderId: {
+ type: 'string' as const,
+ optional: false as const, nullable: true as const,
+ format: 'id',
+ example: 'xxxxxxxxxx',
+ },
+ isSensitive: {
+ type: 'boolean' as const,
+ optional: false as const, nullable: false as const,
+ },
+ isLink: {
+ type: 'boolean' as const,
+ optional: false as const, nullable: false as const
+ }
+ }
+ }
+};
+
+export default define(meta, async (ps, me) => {
+ const file = ps.fileId ? await DriveFiles.findOne(ps.fileId) : await DriveFiles.findOne({
+ where: [{
+ url: ps.url
+ }, {
+ thumbnailUrl: ps.url
+ }, {
+ webpublicUrl: ps.url
+ }]
+ });
+
+ if (file == null) {
+ throw new ApiError(meta.errors.noSuchFile);
+ }
+
+ return file;
+});