🚧 #46 Shared with me (#67)

* 🚧 #46 Shared with me
This commit is contained in:
Anton Shepilov
2023-06-07 10:48:44 +02:00
committed by GitHub
parent 49ec20d60e
commit f1bf507865
42 changed files with 1122 additions and 867 deletions
@@ -8,43 +8,36 @@ export default {
creator: entity.creator,
added: entity.added,
name: entity.name,
//especially for ES because it doesn't allow to sort by not a keyword fields
name_keyword: entity.name,
company_id: entity.company_id,
access_users: ["user_1234", "user_454"],
access_users_x_initiator: ["user_1234_x_user_4343", "user_1234_x_user_4343"],
access_entities: [
{
type: "user",
level: "read",
target: "user_1234",
source: "user_5678",
},
{
type: "user",
level: "read",
target: "user_abcd",
source: "user_5678",
},
],
access_entities: entity.access_info?.entities?.filter(e => e.level != "none").map(e => e.id),
last_modified: entity.last_modified,
mime_type: entity.last_version_cache?.file_metadata?.mime,
}),
mongoMapping: {
text: {
content_keywords: "text",
tags: "text",
creator: "text",
added: "text",
name: "text",
name_keyword: "text",
company_id: "text",
mime_type: "text",
},
},
esMapping: {
properties: {
name: { type: "text", index_prefixes: { min_chars: 1 } },
name_keyword: { type: "keyword" },
content_keywords: { type: "text", index_prefixes: { min_chars: 1 } },
tags: { type: "keyword" },
creator: { type: "keyword" },
added: { type: "keyword" },
added: { type: "unsigned_long" },
company_id: { type: "keyword" },
access_entities: { type: "keyword" },
mime_type: { type: "keyword" },
last_modified: { type: "unsigned_long" },
},
},
};
@@ -48,13 +48,13 @@ export class DriveFile {
@Column("tags", "encoded_json")
tags: string[];
@Type(() => String)
@Column("added", "string")
added: string;
@Type(() => Number)
@Column("added", "number")
added: number;
@Type(() => String)
@Column("last_modified", "string")
last_modified: string;
@Type(() => Number)
@Column("last_modified", "number")
last_modified: number;
@Column("access_info", "encoded_json")
access_info: AccessInformation;
@@ -1,7 +1,10 @@
import SearchRepository from "../../../core/platform/services/search/repository";
import { getLogger, logger, TdriveLogger } from "../../../core/platform/framework";
import { CrudException, ListResult } from "../../../core/platform/framework/api/crud-service";
import Repository from "../../../core/platform/services/database/services/orm/repository/repository";
import Repository, {
inType,
comparisonType,
} from "../../../core/platform/services/database/services/orm/repository/repository";
import { PublicFile } from "../../../services/files/entities/file";
import globalResolver from "../../../services/global-resolver";
import { hasCompanyAdminLevel } from "../../../utils/company";
@@ -291,9 +294,9 @@ export class DocumentsService {
await this.repository.save(driveItem);
await updateItemSize(driveItem.parent_id, this.repository, context);
this.notifyWebsocket(driveItem.parent_id, context);
await this.notifyWebsocket(driveItem.parent_id, context);
globalResolver.platformServices.messageQueue.publish<DocumentsMessageQueueRequest>(
await globalResolver.platformServices.messageQueue.publish<DocumentsMessageQueueRequest>(
"services:documents:process",
{
data: {
@@ -307,7 +310,7 @@ export class DocumentsService {
return driveItem;
} catch (error) {
this.logger.error("Failed to create drive item", error);
throw new CrudException("Failed to create item", 500);
CrudException.throwMe(error, new CrudException("Failed to create item", 500));
}
};
@@ -768,12 +771,39 @@ export class DocumentsService {
pagination: {
limitStr: "100",
},
...(options.company_id ? { $in: [["company_id", [options.company_id]]] } : {}),
...(options.creator ? { $in: [["creator", [options.creator]]] } : {}),
...(options.added ? { $in: [["added", [options.added]]] } : {}),
$text: {
$search: options.search,
},
$in: [
["access_entities", [context.user.id, context.company.id]],
...(options.company_id ? [["company_id", [options.company_id]] as inType] : []),
...(options.creator ? [["creator", [options.creator]] as inType] : []),
...(options.mime_type
? [
[
"mime_type",
Array.isArray(options.mime_type) ? options.mime_type : [options.mime_type],
] as inType,
]
: []),
],
$lte: [
...(options.last_modified_lt
? [["last_modified", options.last_modified_lt] as comparisonType]
: []),
...(options.added_lt ? [["added", options.added_lt] as comparisonType] : []),
],
$gte: [
...(options.last_modified_gt
? [["last_modified", options.last_modified_gt] as comparisonType]
: []),
...(options.added_gt ? [["added", options.added_gt] as comparisonType] : []),
],
...(options.search
? {
$text: {
$search: options.search,
},
}
: {}),
...(options.sort ? { $sort: options.sort } : {}),
},
context,
);
@@ -1,6 +1,7 @@
import { ExecutionContext } from "../../core/platform/framework/api/crud-service";
import { DriveFile } from "./entities/drive-file";
import { FileVersion } from "./entities/file-version";
import { SortType } from "src/core/platform/services/search/api";
export interface CompanyExecutionContext extends ExecutionContext {
company: { id: string };
@@ -40,14 +41,24 @@ export type SearchDocumentsOptions = {
search?: string;
company_id?: string;
creator?: string;
added?: string;
added_gt?: number;
added_lt?: number;
mime_type?: Array<string>;
last_modified_gt?: number;
last_modified_lt?: number;
sort?: SortType;
};
export type SearchDocumentsBody = {
search?: string;
company_id?: string;
creator?: string;
added?: string;
added_gt?: number;
added_lt?: number;
mime_type?: [string];
last_modified_gt?: number;
last_modified_lt?: number;
sort?: SortType;
};
export type DocumentsMessageQueueRequest = {
@@ -47,11 +47,11 @@ export const getDefaultDriveItem = (
): DriveFile => {
const defaultDriveItem = merge<DriveFile, Partial<DriveFile>>(new DriveFile(), {
company_id: context.company.id,
added: item.added || new Date().getTime().toString(),
added: item.added || new Date().getTime(),
creator: item.creator || context.user?.id,
is_directory: item.is_directory || false,
is_in_trash: item.is_in_trash || false,
last_modified: new Date().getTime().toString(),
last_modified: new Date().getTime(),
parent_id: item.parent_id || "root",
content_keywords: item.content_keywords || "",
description: item.description || "",
@@ -422,7 +422,9 @@ export const getFileMetadata = async (
* Finds a suitable name for an item based on items inside the same folder.
*
* @param {string} parent_id - the parent id.
* @param id
* @param {string} name - the item name.
* @param is_directory
* @param {Repository<DriveFile>} repository - the drive repository.
* @param {CompanyExecutionContext} context - the execution context.
* @returns {Promise<string>} - the drive item name.
@@ -65,7 +65,7 @@ export class DocumentsController {
);
} catch (error) {
logger.error("Failed to create Drive item", error);
throw new CrudException("Failed to create Drive item", 500);
CrudException.throwMe(error, new CrudException("Failed to create Drive item", 500));
}
};
@@ -73,6 +73,7 @@ export class DocumentsController {
* Deletes a DriveFile item or empty the trash or delete root folder contents
*
* @param {FastifyRequest} request
* @param {FastifyReply} reply
* @returns {Promise<void>}
*/
delete = async (
@@ -227,7 +228,7 @@ export class DocumentsController {
* If the item is a folder, a zip will be automatically generated.
*
* @param {FastifyRequest} request
* @param {FastifyReply} reply
* @param {FastifyReply} response
*/
download = async (
request: FastifyRequest<{
@@ -342,26 +343,27 @@ export class DocumentsController {
): Promise<ListResult<DriveFile>> => {
try {
const context = getDriveExecutionContext(request);
const { search = "", added = "", company_id = "", creator = "" } = request.body;
const options: SearchDocumentsOptions = {
company_id: company_id || context.company.id,
...(search ? { search } : {}),
...(added ? { added } : {}),
...(creator ? { creator } : {}),
...request.body,
company_id: request.body.company_id || context.company.id,
};
if (!Object.keys(options).length) {
throw Error("Search options are empty");
this.throw500Search();
}
return await globalResolver.services.documents.documents.search(options, context);
} catch (error) {
logger.error("error while searching for document", error);
throw new CrudException("Failed to search for documents", 500);
this.throw500Search();
}
};
private throw500Search() {
throw new CrudException("Failed to search for documents", 500);
}
getTab = async (
request: FastifyRequest<{
Params: { tab_id: string; company_id: string };