✨ Share with me endpoint (#77)
* 🛠️ remove babel from dependencies * 🛠️ removes some of the redundant dependencies + versions update * ✨ separate endpoint for "shared with me"
This commit is contained in:
@@ -1 +1 @@
|
|||||||
12
|
18
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
presets: [["@babel/preset-env", { targets: { node: "current" } }], "@babel/preset-typescript"],
|
|
||||||
plugins: [
|
|
||||||
["@babel/plugin-proposal-decorators", { legacy: true }],
|
|
||||||
["@babel/plugin-proposal-class-properties", { loose: true }],
|
|
||||||
["@babel/plugin-proposal-private-property-in-object", { loose: true }],
|
|
||||||
"babel-plugin-parameter-decorator",
|
|
||||||
],
|
|
||||||
};
|
|
||||||
Generated
+6499
-5853
File diff suppressed because it is too large
Load Diff
@@ -32,6 +32,7 @@
|
|||||||
"kill": "kill $(lsof -t -i:3000) | exit 0"
|
"kill": "kill $(lsof -t -i:3000) | exit 0"
|
||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
|
"preset": "ts-jest",
|
||||||
"collectCoverage": true,
|
"collectCoverage": true,
|
||||||
"coverageReporters": [
|
"coverageReporters": [
|
||||||
"json",
|
"json",
|
||||||
@@ -57,47 +58,29 @@
|
|||||||
"tdrive-cli": "bin/tdrive-cli"
|
"tdrive-cli": "bin/tdrive-cli"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.22.5",
|
|
||||||
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
|
||||||
"@babel/plugin-proposal-private-property-in-object": "^7.18.6",
|
|
||||||
"@babel/plugin-proposal-decorators": "^7.18.10",
|
|
||||||
"@babel/preset-env": "^7.19.4",
|
|
||||||
"@babel/preset-typescript": "^7.18.6",
|
|
||||||
"@types/amqp-connection-manager": "^2.0.10",
|
"@types/amqp-connection-manager": "^2.0.10",
|
||||||
"@types/analytics-node": "^3.1.5",
|
"@types/analytics-node": "^3.1.5",
|
||||||
"@types/archiver": "^5.3.1",
|
"@types/archiver": "^5.3.1",
|
||||||
"@types/bcrypt": "^5.0.0",
|
"@types/bcrypt": "^5.0.0",
|
||||||
"@types/busboy": "^0.2.3",
|
|
||||||
"@types/chai": "^4.2.12",
|
|
||||||
"@types/cli-table": "^0.3.0",
|
"@types/cli-table": "^0.3.0",
|
||||||
"@types/config": "0.0.36",
|
"@types/config": "0.0.36",
|
||||||
"@types/eslint": "^7.2.3",
|
"@types/eslint": "^7.2.3",
|
||||||
"@types/fastify-multipart": "^0.7.0",
|
|
||||||
"@types/fastify-static": "^2.2.1",
|
|
||||||
"@types/fluent-ffmpeg": "^2.1.20",
|
"@types/fluent-ffmpeg": "^2.1.20",
|
||||||
"@types/html-to-text": "^8.1.1",
|
"@types/html-to-text": "^8.1.1",
|
||||||
"@types/jest": "^29.1.0",
|
"@types/jest": "^29.1.0",
|
||||||
"@types/lodash": "^4.14.165",
|
"@types/lodash": "^4.14.165",
|
||||||
"@types/minio": "^7.0.7",
|
|
||||||
"@types/mongodb": "^4.0.7",
|
|
||||||
"@types/node": "^18.11",
|
"@types/node": "^18.11",
|
||||||
"@types/node-cron": "^3.0.0",
|
"@types/node-cron": "^3.0.0",
|
||||||
"@types/node-fetch": "^2.5.12",
|
"@types/node-fetch": "^2.5.12",
|
||||||
"@types/node-uuid": "^0.0.28",
|
"@types/node-uuid": "^0.0.28",
|
||||||
"@types/pdf-image": "^2.0.1",
|
"@types/pdf-image": "^2.0.1",
|
||||||
"@types/pino": "^6.3.2",
|
|
||||||
"@types/probe-image-size": "^7.0.1",
|
|
||||||
"@types/pump": "^1.1.1",
|
"@types/pump": "^1.1.1",
|
||||||
"@types/random-useragent": "^0.3.1",
|
"@types/random-useragent": "^0.3.1",
|
||||||
"@types/socket.io-client": "^1.4.34",
|
"@types/socket.io-client": "^1.4.36",
|
||||||
"@types/supertest": "2.0.4",
|
|
||||||
"@types/uuid": "^8.3.0",
|
"@types/uuid": "^8.3.0",
|
||||||
"@types/ws": "^7.2.7",
|
"@types/ws": "^7.2.7",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.59.9",
|
"@typescript-eslint/eslint-plugin": "^5.59.9",
|
||||||
"@typescript-eslint/parser": "^5.59.9",
|
"@typescript-eslint/parser": "^5.59.9",
|
||||||
"babel-jest": "^29.1.0",
|
|
||||||
"babel-plugin-parameter-decorator": "^1.0.16",
|
|
||||||
"chai": "^4.2.0",
|
|
||||||
"cpy-cli": "^4.2.0",
|
"cpy-cli": "^4.2.0",
|
||||||
"eslint": "^8.42.0",
|
"eslint": "^8.42.0",
|
||||||
"eslint-config-prettier": "^8.8.0",
|
"eslint-config-prettier": "^8.8.0",
|
||||||
@@ -106,17 +89,16 @@
|
|||||||
"form-auto-content": "^2.2.0",
|
"form-auto-content": "^2.2.0",
|
||||||
"jest": "^29.1.0",
|
"jest": "^29.1.0",
|
||||||
"jest-mock-extended": "^3.0.4",
|
"jest-mock-extended": "^3.0.4",
|
||||||
"nodemon": "2.0.4",
|
"nodemon": "^2.0.22",
|
||||||
"pino-pretty": "^10.0.0",
|
"pino-pretty": "^10.0.0",
|
||||||
"prettier": "^2.1.2",
|
"prettier": "^2.1.2",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"supertest": "4.0.2",
|
|
||||||
"ts-jest": "^29.1.0",
|
"ts-jest": "^29.1.0",
|
||||||
"ts-node": "^9.0.0",
|
"ts-node": "^9.0.0",
|
||||||
"ts-node-dev": "^1.1.8",
|
"ts-node-dev": "^1.1.8",
|
||||||
"tsc-watch": "^4.2.9",
|
"tsc-watch": "^4.2.9",
|
||||||
"typescript": "^4.9.5",
|
"tsconfig-paths": "^3.14.1",
|
||||||
"tsconfig-paths": "^3.14.1"
|
"typescript": "^4.9.5"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@elastic/elasticsearch": "7",
|
"@elastic/elasticsearch": "7",
|
||||||
@@ -126,7 +108,7 @@
|
|||||||
"@ffprobe-installer/ffprobe": "^1.4.1",
|
"@ffprobe-installer/ffprobe": "^1.4.1",
|
||||||
"@sentry/node": "^6.19.7",
|
"@sentry/node": "^6.19.7",
|
||||||
"@sentry/tracing": "^6.19.7",
|
"@sentry/tracing": "^6.19.7",
|
||||||
"@socket.io/redis-adapter": "^7.1.0",
|
"@socket.io/redis-adapter": "^7.2.0",
|
||||||
"@types/http-proxy": "^1.17.11",
|
"@types/http-proxy": "^1.17.11",
|
||||||
"@types/pdf-parse": "^1.1.1",
|
"@types/pdf-parse": "^1.1.1",
|
||||||
"@types/redis": "^4.0.11",
|
"@types/redis": "^4.0.11",
|
||||||
@@ -144,7 +126,7 @@
|
|||||||
"config": "^3.3.2",
|
"config": "^3.3.2",
|
||||||
"deep-object-diff": "^1.1.0",
|
"deep-object-diff": "^1.1.0",
|
||||||
"emoji-name-map": "^1.2.9",
|
"emoji-name-map": "^1.2.9",
|
||||||
"eta": "^1.12.3",
|
"eta": "^2.2.0",
|
||||||
"fastify": "^3.29.4",
|
"fastify": "^3.29.4",
|
||||||
"fastify-cors": "^4.1.0",
|
"fastify-cors": "^4.1.0",
|
||||||
"fastify-formbody": "^5.0.0",
|
"fastify-formbody": "^5.0.0",
|
||||||
@@ -156,7 +138,6 @@
|
|||||||
"fastify-static": "^4.7.0",
|
"fastify-static": "^4.7.0",
|
||||||
"fastify-swagger": "^4.12.6",
|
"fastify-swagger": "^4.12.6",
|
||||||
"fastify-websocket": "^2.0.11",
|
"fastify-websocket": "^2.0.11",
|
||||||
"find-my-way": "^5.2.0",
|
|
||||||
"fluent-ffmpeg": "^2.1.2",
|
"fluent-ffmpeg": "^2.1.2",
|
||||||
"fold-to-ascii": "^5.0.0",
|
"fold-to-ascii": "^5.0.0",
|
||||||
"free-email-domains": "1.0.26",
|
"free-email-domains": "1.0.26",
|
||||||
@@ -165,12 +146,10 @@
|
|||||||
"html-metadata-parser": "^2.0.4",
|
"html-metadata-parser": "^2.0.4",
|
||||||
"html-to-text": "^8.2.1",
|
"html-to-text": "^8.2.1",
|
||||||
"idtoken-verifier": "^2.2.3",
|
"idtoken-verifier": "^2.2.3",
|
||||||
"jsonwebtoken": "^8.5.1",
|
"jsonwebtoken": "^9.0.0",
|
||||||
"jwks-rsa": "^3.0.1",
|
"jwks-rsa": "^3.0.1",
|
||||||
"keyv": "^4.5.0",
|
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"match-all": "^1.2.6",
|
"minio": "7.0.18",
|
||||||
"minio": "^7.0.18",
|
|
||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
"mongodb": "^5.6.0",
|
"mongodb": "^5.6.0",
|
||||||
"multistream": "^4.1.0",
|
"multistream": "^4.1.0",
|
||||||
@@ -179,7 +158,6 @@
|
|||||||
"node-cache": "^5.1.2",
|
"node-cache": "^5.1.2",
|
||||||
"node-cron": "^3.0.0",
|
"node-cron": "^3.0.0",
|
||||||
"node-fetch": "^2.6.7",
|
"node-fetch": "^2.6.7",
|
||||||
"node-uuid": "^1.4.8",
|
|
||||||
"openid-client": "^5.4.0",
|
"openid-client": "^5.4.0",
|
||||||
"ora": "^5.4.0",
|
"ora": "^5.4.0",
|
||||||
"pdf-parse": "^1.1.1",
|
"pdf-parse": "^1.1.1",
|
||||||
@@ -193,7 +171,7 @@
|
|||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
"rxjs": "^6.6.3",
|
"rxjs": "^6.6.3",
|
||||||
"sharp": "^0.30.5",
|
"sharp": "^0.30.5",
|
||||||
"socket.io": "4",
|
"socket.io": "^4.6.2",
|
||||||
"socket.io-client": "^3.0.0",
|
"socket.io-client": "^3.0.0",
|
||||||
"unoconv-promise": "^1.0.8",
|
"unoconv-promise": "^1.0.8",
|
||||||
"uuid": "^8.3.2",
|
"uuid": "^8.3.2",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as cron from "node-cron";
|
import * as cron from "node-cron";
|
||||||
import uuid from "node-uuid";
|
import uuid from "uuid";
|
||||||
|
|
||||||
import { TdriveService } from "../../framework";
|
import { TdriveService } from "../../framework";
|
||||||
import { CronAPI, CronJob, CronExpression, CronTask } from "./api";
|
import { CronAPI, CronJob, CronExpression, CronTask } from "./api";
|
||||||
|
|||||||
@@ -168,12 +168,12 @@ export const getAccessLevel = async (
|
|||||||
const prevalidatedPublicTokenDocumentId = context?.user?.public_token_document_id;
|
const prevalidatedPublicTokenDocumentId = context?.user?.public_token_document_id;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
item =
|
if (!item) {
|
||||||
item ||
|
item = await repository.findOne({
|
||||||
(await repository.findOne({
|
|
||||||
id,
|
id,
|
||||||
company_id: context.company.id,
|
company_id: context.company.id,
|
||||||
}));
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (!item) {
|
if (!item) {
|
||||||
throw Error("Drive item doesn't exist");
|
throw Error("Drive item doesn't exist");
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import SearchRepository from "../../../core/platform/services/search/repository"
|
|||||||
import { getLogger, logger, TdriveLogger } from "../../../core/platform/framework";
|
import { getLogger, logger, TdriveLogger } from "../../../core/platform/framework";
|
||||||
import { CrudException, ListResult } from "../../../core/platform/framework/api/crud-service";
|
import { CrudException, ListResult } from "../../../core/platform/framework/api/crud-service";
|
||||||
import Repository, {
|
import Repository, {
|
||||||
inType,
|
|
||||||
comparisonType,
|
comparisonType,
|
||||||
|
inType,
|
||||||
} from "../../../core/platform/services/database/services/orm/repository/repository";
|
} from "../../../core/platform/services/database/services/orm/repository/repository";
|
||||||
import { PublicFile } from "../../../services/files/entities/file";
|
import { PublicFile } from "../../../services/files/entities/file";
|
||||||
import globalResolver from "../../../services/global-resolver";
|
import globalResolver from "../../../services/global-resolver";
|
||||||
@@ -16,15 +16,15 @@ import {
|
|||||||
TYPE as DriveTdriveTabRepoType,
|
TYPE as DriveTdriveTabRepoType,
|
||||||
} from "../entities/drive-tdrive-tab";
|
} from "../entities/drive-tdrive-tab";
|
||||||
import {
|
import {
|
||||||
DriveExecutionContext,
|
CompanyExecutionContext,
|
||||||
DocumentsMessageQueueRequest,
|
DocumentsMessageQueueRequest,
|
||||||
|
DriveExecutionContext,
|
||||||
|
DriveFileAccessLevel,
|
||||||
DriveItemDetails,
|
DriveItemDetails,
|
||||||
|
DriveTdriveTab,
|
||||||
RootType,
|
RootType,
|
||||||
SearchDocumentsOptions,
|
SearchDocumentsOptions,
|
||||||
TrashType,
|
TrashType,
|
||||||
CompanyExecutionContext,
|
|
||||||
DriveTdriveTab,
|
|
||||||
DriveFileAccessLevel,
|
|
||||||
} from "../types";
|
} from "../types";
|
||||||
import {
|
import {
|
||||||
addDriveItemToArchive,
|
addDriveItemToArchive,
|
||||||
@@ -783,7 +783,9 @@ export class DocumentsService {
|
|||||||
limitStr: "100",
|
limitStr: "100",
|
||||||
},
|
},
|
||||||
$in: [
|
$in: [
|
||||||
["access_entities", [context.user.id, context.company.id]],
|
...(options.onlyDirectlyShared
|
||||||
|
? [["access_entities", [context.user.id, context.company.id]] as inType]
|
||||||
|
: []),
|
||||||
...(options.company_id ? [["company_id", [options.company_id]] as inType] : []),
|
...(options.company_id ? [["company_id", [options.company_id]] as inType] : []),
|
||||||
...(options.creator ? [["creator", [options.creator]] as inType] : []),
|
...(options.creator ? [["creator", [options.creator]] as inType] : []),
|
||||||
...(options.mime_type
|
...(options.mime_type
|
||||||
@@ -819,24 +821,31 @@ export class DocumentsService {
|
|||||||
context,
|
context,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Use Promise.all to check access on each item in parallel
|
// if this flag is on, the access permissions were checked inside the database
|
||||||
const filteredResult = await Promise.all(
|
if (!options.onlyDirectlyShared) {
|
||||||
result.getEntities().filter(async item => {
|
const filteredResult = await this.filter(result.getEntities(), async item => {
|
||||||
try {
|
try {
|
||||||
// Check access for each item
|
// Check access for each item
|
||||||
const hasAccess = await checkAccess(item.id, null, "read", this.repository, context);
|
return await checkAccess(item.id, null, "read", this.repository, context);
|
||||||
// Return true if the user has access
|
|
||||||
return hasAccess;
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.warn("failed to check item access", error);
|
this.logger.warn("failed to check item access", error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}),
|
});
|
||||||
);
|
|
||||||
|
|
||||||
return new ListResult(result.type, filteredResult, result.nextPage);
|
return new ListResult(result.type, filteredResult, result.nextPage);
|
||||||
|
} else {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private async filter(arr, callback) {
|
||||||
|
const fail = Symbol();
|
||||||
|
return (
|
||||||
|
await Promise.all(arr.map(async item => ((await callback(item)) ? item : fail)))
|
||||||
|
).filter(i => i !== fail);
|
||||||
|
}
|
||||||
|
|
||||||
getTab = async (tabId: string, context: CompanyExecutionContext): Promise<DriveTdriveTab> => {
|
getTab = async (tabId: string, context: CompanyExecutionContext): Promise<DriveTdriveTab> => {
|
||||||
const tab = await this.driveTdriveTabRepository.findOne(
|
const tab = await this.driveTdriveTabRepository.findOne(
|
||||||
{ company_id: context.company.id, tab_id: tabId },
|
{ company_id: context.company.id, tab_id: tabId },
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ export type SearchDocumentsOptions = {
|
|||||||
sort?: SortType;
|
sort?: SortType;
|
||||||
view?: string;
|
view?: string;
|
||||||
fields?: string[];
|
fields?: string[];
|
||||||
|
onlyDirectlyShared?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SearchDocumentsBody = {
|
export type SearchDocumentsBody = {
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ export class DocumentsController {
|
|||||||
filename: q.resumableFilename || q.filename || file?.filename || undefined,
|
filename: q.resumableFilename || q.filename || file?.filename || undefined,
|
||||||
type: q.resumableType || q.type || file?.mimetype || undefined,
|
type: q.resumableType || q.type || file?.mimetype || undefined,
|
||||||
waitForThumbnail: !!q.thumbnail_sync,
|
waitForThumbnail: !!q.thumbnail_sync,
|
||||||
|
ignoreThumbnails: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
createdFile = await globalResolver.services.files.save(null, file, options, context);
|
createdFile = await globalResolver.services.files.save(null, file, options, context);
|
||||||
@@ -140,6 +141,35 @@ export class DocumentsController {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
sharedWithMe = async (
|
||||||
|
request: FastifyRequest<{
|
||||||
|
Params: RequestParams;
|
||||||
|
Body: SearchDocumentsBody;
|
||||||
|
Querystring: { public_token?: string };
|
||||||
|
}>,
|
||||||
|
): Promise<ListResult<DriveFileDTO>> => {
|
||||||
|
try {
|
||||||
|
const context = getDriveExecutionContext(request);
|
||||||
|
|
||||||
|
const options: SearchDocumentsOptions = {
|
||||||
|
...request.body,
|
||||||
|
company_id: request.body.company_id || context.company.id,
|
||||||
|
onlyDirectlyShared: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!Object.keys(options).length) {
|
||||||
|
this.throw500Search();
|
||||||
|
}
|
||||||
|
|
||||||
|
const fileList = await globalResolver.services.documents.documents.search(options, context);
|
||||||
|
|
||||||
|
return this.driveFileDTOBuilder.build(fileList, context, options.fields, options.view);
|
||||||
|
} catch (error) {
|
||||||
|
logger.error({ error: `${error}` }, "error while searching for document");
|
||||||
|
this.throw500Search();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return access level of a given user on a given item
|
* Return access level of a given user on a given item
|
||||||
*/
|
*/
|
||||||
@@ -352,6 +382,7 @@ export class DocumentsController {
|
|||||||
const options: SearchDocumentsOptions = {
|
const options: SearchDocumentsOptions = {
|
||||||
...request.body,
|
...request.body,
|
||||||
company_id: request.body.company_id || context.company.id,
|
company_id: request.body.company_id || context.company.id,
|
||||||
|
onlyDirectlyShared: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!Object.keys(options).length) {
|
if (!Object.keys(options).length) {
|
||||||
|
|||||||
@@ -13,7 +13,27 @@ import { getSharedByUser } from "../../services/access-check";
|
|||||||
|
|
||||||
export class DriveFileDTOBuilder {
|
export class DriveFileDTOBuilder {
|
||||||
private views: Map<string, string[]> = new Map([
|
private views: Map<string, string[]> = new Map([
|
||||||
["default", Object.getOwnPropertyNames(new DriveFile())],
|
[
|
||||||
|
"default",
|
||||||
|
[
|
||||||
|
"company_id",
|
||||||
|
"id",
|
||||||
|
"parent_id",
|
||||||
|
"is_in_trash",
|
||||||
|
"is_directory",
|
||||||
|
"name",
|
||||||
|
"extension",
|
||||||
|
"description",
|
||||||
|
"added",
|
||||||
|
"last_modified",
|
||||||
|
"size",
|
||||||
|
"last_version_cache",
|
||||||
|
"tags",
|
||||||
|
"access_info",
|
||||||
|
"content_keywords",
|
||||||
|
"creator",
|
||||||
|
],
|
||||||
|
],
|
||||||
[
|
[
|
||||||
"shared_with_me",
|
"shared_with_me",
|
||||||
[
|
[
|
||||||
@@ -39,6 +59,8 @@ export class DriveFileDTOBuilder {
|
|||||||
fields?: string[],
|
fields?: string[],
|
||||||
view?: string,
|
view?: string,
|
||||||
): Promise<ListResult<DriveFileDTO>> {
|
): Promise<ListResult<DriveFileDTO>> {
|
||||||
|
const file = new DriveFile();
|
||||||
|
file.id = "1";
|
||||||
if (view) {
|
if (view) {
|
||||||
fields = this.views.get(view);
|
fields = this.views.get(view);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,6 +87,13 @@ const routes: FastifyPluginCallback = (fastify: FastifyInstance, _options, next)
|
|||||||
handler: documentsController.search.bind(documentsController),
|
handler: documentsController.search.bind(documentsController),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
fastify.route({
|
||||||
|
method: "POST",
|
||||||
|
url: `${baseUrl}/shared-with-me`,
|
||||||
|
preValidation: [fastify.authenticate],
|
||||||
|
handler: documentsController.sharedWithMe.bind(documentsController),
|
||||||
|
});
|
||||||
|
|
||||||
fastify.route({
|
fastify.route({
|
||||||
method: "GET",
|
method: "GET",
|
||||||
url: `${baseUrl}/tabs/:tab_id`,
|
url: `${baseUrl}/tabs/:tab_id`,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { logger, TwakeContext } from "../../../../../core/platform/framework";
|
import { logger, TdriveContext } from "../../../../../core/platform/framework";
|
||||||
import { PreviewClearMessageQueueRequest, PreviewMessageQueueCallback } from "../../../types";
|
import { PreviewClearMessageQueueRequest, PreviewMessageQueueCallback } from "../../../types";
|
||||||
import gr from "../../../../global-resolver";
|
import gr from "../../../../global-resolver";
|
||||||
import { MessageQueueHandler } from "../../../../../core/platform/services/message-queue/api";
|
import { MessageQueueHandler } from "../../../../../core/platform/services/message-queue/api";
|
||||||
@@ -22,7 +22,7 @@ export class ClearProcessor
|
|||||||
};
|
};
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
init?(context?: TwakeContext): Promise<this> {
|
init?(context?: TdriveContext): Promise<this> {
|
||||||
throw new Error("Method not implemented.");
|
throw new Error("Method not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ import {
|
|||||||
} from "../../../../../utils/mime";
|
} from "../../../../../utils/mime";
|
||||||
import { PreviewMessageQueueRequest, ThumbnailResult } from "../../../types";
|
import { PreviewMessageQueueRequest, ThumbnailResult } from "../../../types";
|
||||||
import { generateVideoPreview } from "./video";
|
import { generateVideoPreview } from "./video";
|
||||||
import { Initializable, TwakeServiceProvider } from "../../../../../core/platform/framework";
|
import { Initializable, TdriveServiceProvider } from "../../../../../core/platform/framework";
|
||||||
import { cleanFiles } from "../../../../../utils/files";
|
import { cleanFiles } from "../../../../../utils/files";
|
||||||
|
|
||||||
export class PreviewProcessService implements TwakeServiceProvider, Initializable {
|
export class PreviewProcessService implements TdriveServiceProvider, Initializable {
|
||||||
name: "PreviewProcessService";
|
name: "PreviewProcessService";
|
||||||
version: "1";
|
version: "1";
|
||||||
|
|
||||||
|
|||||||
@@ -125,10 +125,10 @@ async function getVideoDimensions(videoPath: string): Promise<{ width: number; h
|
|||||||
ffmpeg.ffprobe(videoPath, (err, metadata) => {
|
ffmpeg.ffprobe(videoPath, (err, metadata) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
reject(err);
|
reject(err);
|
||||||
|
} else {
|
||||||
|
const { width, height } = metadata.streams[0];
|
||||||
|
resolve({ width, height });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { width, height } = metadata.streams[0];
|
|
||||||
resolve({ width, height });
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,11 +73,11 @@ export default class TestHelpers {
|
|||||||
|
|
||||||
const filesUploadRaw = await this.platform.app.inject({
|
const filesUploadRaw = await this.platform.app.inject({
|
||||||
method: "POST",
|
method: "POST",
|
||||||
url: `${url}/companies/${this.platform.workspace.company_id}/files?thumbnail_sync=1`,
|
url: `${url}/companies/${this.platform.workspace.company_id}/files?thumbnail_sync=0`,
|
||||||
...form,
|
...form,
|
||||||
});
|
});
|
||||||
|
|
||||||
const filesUpload: ResourceUpdateResponse<File> = deserialize(
|
const filesUpload: ResourceUpdateResponse<File> = deserialize<ResourceUpdateResponse<File>>(
|
||||||
ResourceUpdateResponse,
|
ResourceUpdateResponse,
|
||||||
filesUploadRaw.body,
|
filesUploadRaw.body,
|
||||||
);
|
);
|
||||||
@@ -188,5 +188,22 @@ export default class TestHelpers {
|
|||||||
response.body)
|
response.body)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
async sharedWithMeDocuments (
|
||||||
|
payload: Record<string, any>
|
||||||
|
){
|
||||||
|
const response = await this.platform.app.inject({
|
||||||
|
method: "POST",
|
||||||
|
url: `${TestHelpers.DOC_URL}/companies/${this.platform.workspace.company_id}/shared-with-me`,
|
||||||
|
headers: {
|
||||||
|
authorization: `Bearer ${this.jwt}`,
|
||||||
|
},
|
||||||
|
payload,
|
||||||
|
});
|
||||||
|
|
||||||
|
return deserialize<SearchResultMockClass>(
|
||||||
|
SearchResultMockClass,
|
||||||
|
response.body)
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ describe("the Drive feature", () => {
|
|||||||
});
|
});
|
||||||
currentUser = await TestHelpers.getInstance(platform);
|
currentUser = await TestHelpers.getInstance(platform);
|
||||||
dbService = await TestDbService.getInstance(platform, true);
|
dbService = await TestDbService.getInstance(platform, true);
|
||||||
});
|
}, 300000000);
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
await platform?.tearDown();
|
await platform?.tearDown();
|
||||||
@@ -294,7 +294,6 @@ describe("the Drive feature", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("did search a file shared by another user", async () => {
|
it("did search a file shared by another user", async () => {
|
||||||
jest.setTimeout(30000);
|
|
||||||
//given:
|
//given:
|
||||||
const oneUser = await TestHelpers.getInstance(platform, true);
|
const oneUser = await TestHelpers.getInstance(platform, true);
|
||||||
const anotherUser = await TestHelpers.getInstance(platform, true);
|
const anotherUser = await TestHelpers.getInstance(platform, true);
|
||||||
@@ -304,7 +303,7 @@ describe("the Drive feature", () => {
|
|||||||
await new Promise(r => setTimeout(r, 5000));
|
await new Promise(r => setTimeout(r, 5000));
|
||||||
|
|
||||||
//then:: files are not searchable for user without permissions
|
//then:: files are not searchable for user without permissions
|
||||||
expect((await anotherUser.searchDocument({})).entities).toHaveLength(0);
|
expect((await anotherUser.sharedWithMeDocuments({})).entities).toHaveLength(0);
|
||||||
|
|
||||||
//and searchable for user that have
|
//and searchable for user that have
|
||||||
expect((await oneUser.searchDocument({})).entities).toHaveLength(TestHelpers.ALL_FILES.length);
|
expect((await oneUser.searchDocument({})).entities).toHaveLength(TestHelpers.ALL_FILES.length);
|
||||||
@@ -320,8 +319,8 @@ describe("the Drive feature", () => {
|
|||||||
await new Promise(r => setTimeout(r, 3000));
|
await new Promise(r => setTimeout(r, 3000));
|
||||||
|
|
||||||
//then file become searchable
|
//then file become searchable
|
||||||
expect((await anotherUser.searchDocument({})).entities).toHaveLength(1);
|
expect((await anotherUser.sharedWithMeDocuments({})).entities).toHaveLength(1);
|
||||||
});
|
}, 30000000);
|
||||||
|
|
||||||
it("did search a file by file owner", async () => {
|
it("did search a file by file owner", async () => {
|
||||||
jest.setTimeout(30000);
|
jest.setTimeout(30000);
|
||||||
@@ -387,7 +386,6 @@ describe("the Drive feature", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("did search order by name", async () => {
|
it("did search order by name", async () => {
|
||||||
jest.setTimeout(10000);
|
|
||||||
const user = await TestHelpers.getInstance(platform, true);
|
const user = await TestHelpers.getInstance(platform, true);
|
||||||
// given:: all the sample files uploaded and documents for them created
|
// given:: all the sample files uploaded and documents for them created
|
||||||
await user.uploadAllFilesAndCreateDocuments();
|
await user.uploadAllFilesAndCreateDocuments();
|
||||||
@@ -404,7 +402,7 @@ describe("the Drive feature", () => {
|
|||||||
|
|
||||||
//then all the files are sorted properly by name
|
//then all the files are sorted properly by name
|
||||||
expect(documents.entities.map(e => e.name)).toEqual(TestHelpers.ALL_FILES.sort());
|
expect(documents.entities.map(e => e.name)).toEqual(TestHelpers.ALL_FILES.sort());
|
||||||
});
|
}, 30000);
|
||||||
|
|
||||||
it("did search order by name desc", async () => {
|
it("did search order by name desc", async () => {
|
||||||
jest.setTimeout(10000);
|
jest.setTimeout(10000);
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ describe("The Tag feature", () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const tagResult: ResourceCreateResponse<Tag> = deserialize(
|
const tagResult: ResourceCreateResponse<Tag> = deserialize<ResourceCreateResponse<Tag>>(
|
||||||
ResourceCreateResponse,
|
ResourceCreateResponse,
|
||||||
createTag.body,
|
createTag.body,
|
||||||
);
|
);
|
||||||
@@ -98,7 +98,7 @@ describe("The Tag feature", () => {
|
|||||||
});
|
});
|
||||||
expect(createTag.statusCode).toBe(401);
|
expect(createTag.statusCode).toBe(401);
|
||||||
|
|
||||||
const tagResult: ResourceCreateResponse<Tag> = deserialize(
|
const tagResult: ResourceCreateResponse<Tag> = deserialize<ResourceCreateResponse<Tag>>(
|
||||||
ResourceCreateResponse,
|
ResourceCreateResponse,
|
||||||
createTag.body,
|
createTag.body,
|
||||||
);
|
);
|
||||||
@@ -121,7 +121,7 @@ describe("The Tag feature", () => {
|
|||||||
});
|
});
|
||||||
expect(getTag.statusCode).toBe(200);
|
expect(getTag.statusCode).toBe(200);
|
||||||
|
|
||||||
const getResult: ResourceGetResponse<Tag> = deserialize(ResourceGetResponse, getTag.body);
|
const getResult: ResourceGetResponse<Tag> = deserialize<ResourceGetResponse<Tag>>(ResourceGetResponse, getTag.body);
|
||||||
expect(getResult.resource).toBeDefined();
|
expect(getResult.resource).toBeDefined();
|
||||||
expect(getResult.resource.name).toBe("test0");
|
expect(getResult.resource.name).toBe("test0");
|
||||||
expect(getResult.resource.colour).toBe("#000000");
|
expect(getResult.resource.colour).toBe("#000000");
|
||||||
@@ -144,7 +144,7 @@ describe("The Tag feature", () => {
|
|||||||
});
|
});
|
||||||
expect(getTag.statusCode).toBe(200);
|
expect(getTag.statusCode).toBe(200);
|
||||||
|
|
||||||
const getResult: ResourceGetResponse<Tag> = deserialize(ResourceGetResponse, getTag.body);
|
const getResult: ResourceGetResponse<Tag> = deserialize<ResourceGetResponse<Tag>>(ResourceGetResponse, getTag.body);
|
||||||
expect(getResult.resource).toBe(null);
|
expect(getResult.resource).toBe(null);
|
||||||
|
|
||||||
|
|
||||||
@@ -170,7 +170,7 @@ describe("The Tag feature", () => {
|
|||||||
});
|
});
|
||||||
expect(updateTag.statusCode).toBe(201);
|
expect(updateTag.statusCode).toBe(201);
|
||||||
|
|
||||||
const tagUpdatedResult: ResourceCreateResponse<Tag> = deserialize(
|
const tagUpdatedResult: ResourceCreateResponse<Tag> = deserialize<ResourceCreateResponse<Tag>>(
|
||||||
ResourceCreateResponse,
|
ResourceCreateResponse,
|
||||||
updateTag.body,
|
updateTag.body,
|
||||||
);
|
);
|
||||||
@@ -210,7 +210,7 @@ describe("The Tag feature", () => {
|
|||||||
});
|
});
|
||||||
expect(createTag.statusCode).toBe(401);
|
expect(createTag.statusCode).toBe(401);
|
||||||
|
|
||||||
const tagResult: ResourceCreateResponse<Tag> = deserialize(
|
const tagResult: ResourceCreateResponse<any> = deserialize(
|
||||||
ResourceCreateResponse,
|
ResourceCreateResponse,
|
||||||
createTag.body,
|
createTag.body,
|
||||||
);
|
);
|
||||||
@@ -236,7 +236,7 @@ describe("The Tag feature", () => {
|
|||||||
});
|
});
|
||||||
expect(listTag.statusCode).toBe(200);
|
expect(listTag.statusCode).toBe(200);
|
||||||
|
|
||||||
const tagResult: ResourceListResponse<Tag> = deserialize(ResourceListResponse, listTag.body);
|
const tagResult: ResourceListResponse<any> = deserialize(ResourceListResponse, listTag.body);
|
||||||
expect(tagResult.resources).toBeDefined();
|
expect(tagResult.resources).toBeDefined();
|
||||||
for (const tag of tagResult.resources) {
|
for (const tag of tagResult.resources) {
|
||||||
expect(tag.name).toBeDefined();
|
expect(tag.name).toBeDefined();
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
"target": "es6",
|
"target": "es6",
|
||||||
"noImplicitAny": true,
|
"noImplicitAny": false,
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"outDir": "dist",
|
"outDir": "dist",
|
||||||
|
|||||||
+523
-2217
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user