diff --git a/twake/.gitignore b/twake/.gitignore index 0ad1d088..1f785e57 100644 --- a/twake/.gitignore +++ b/twake/.gitignore @@ -125,7 +125,7 @@ docker-compose.yml /docker-data/* /docker/data/* -### Twake specific ### +### Tdrive specific ### /build/ /vendor/ /app/Ressources/DatabaseEncryption/.HaliteEncryptor.key diff --git a/twake/backend/node/README.md b/twake/backend/node/README.md index fe33933d..e92e7480 100644 --- a/twake/backend/node/README.md +++ b/twake/backend/node/README.md @@ -1,4 +1,4 @@ -# Twake backend +# Tdrive backend ## Developer guide @@ -7,8 +7,8 @@ 1. Clone and install dependencies (assumes that you have Node.js 12 and npm installed. If not, we suggest to use [nvm](https://github.com/nvm-sh/nvm/)): ```sh -git clone git@github.com:Twake/Twake.git -cd Twake/Twake/backend/node +git clone git@github.com:Tdrive/Tdrive.git +cd Tdrive/Tdrive/backend/node npm install ``` @@ -38,15 +38,15 @@ will run unit tests only (`test:unit`). For possible tests to run, check the `pa ### Command Line Interface (CLI) -The Twake backend CLI provides a set of commands to manage/use/develop Twake from the `twake-cli` binary. -Before to use the CLI, you must `compile` Twake with `npm run build`. Once done, you can get help on on any command with the `--help` flag like `./bin/twake-cli console --help`. +The Tdrive backend CLI provides a set of commands to manage/use/develop Tdrive from the `tdrive-cli` binary. +Before to use the CLI, you must `compile` Tdrive with `npm run build`. Once done, you can get help on on any command with the `--help` flag like `./bin/tdrive-cli console --help`. #### The 'console merge' command -This command allows to connect to the database configured in the `./config/default.json` file and to "merge" the Twake users and companies into the "Twake Console". +This command allows to connect to the database configured in the `./config/default.json` file and to "merge" the Tdrive users and companies into the "Tdrive Console". ```sh -./bin/twake-cli console merge --url http://console.twake.app --client twake-app --secret supersecret +./bin/tdrive-cli console merge --url http://console.tdrive.app --client tdrive-app --secret supersecret ``` The simplified console workflow is like (some parts are done in parallel): @@ -90,10 +90,10 @@ In order to illustrate how to create a component, let's create a fake Notificati ```js // File src/services/notification/index.ts -import { TwakeService } from "../../core/platform/framework"; +import { TdriveService } from "../../core/platform/framework"; import NotificationServiceAPI from "./api.ts"; -export default class NotificationService extends TwakeService { +export default class NotificationService extends TdriveService { version = "1"; name = "notification"; service: NotificationServiceAPI; @@ -104,14 +104,14 @@ export default class NotificationService extends TwakeService;` Customize the `init` step of the component. This is generally the place where services are instanciated. From this step, you can retrieve services consumed by the current component which have been already initialized by the platform. - `public async doStart(): Promise;` Customize the `start` step of the component. You have access to all other services which are already started. ```js // File src/services/notification/index.ts -import { TwakeService } from "../../core/platform/framework"; +import { TdriveService } from "../../core/platform/framework"; import NotificationServiceAPI from "./api.ts"; import NotificationServiceImpl from "./services/api.ts"; -export default class NotificationService extends TwakeService { +export default class NotificationService extends TdriveService { version = "1"; name = "notification"; service: NotificationServiceAPI; @@ -166,12 +166,12 @@ export default class NotificationService extends TwakeService { +export default class MessageService extends TdriveService { public async doInit(): Promise { const notificationService = this.context.getProvider("notification"); @@ -214,7 +214,7 @@ Then each service can have its own configuration block which is accessible from On the component class side, the configuration object is directly accessible from the `configuration` property like: ```js -export default class WebSocket extends TwakeService { +export default class WebSocket extends TdriveService { async doInit(): Promise { // get the "path" value, defaults to "/socket" if not defined const path = this.configuration.get < string > ("path", "/socket"); @@ -232,7 +232,7 @@ interface AdaptersConfiguration { ### Platform -The Twake Platform is built using the component framework described just before and so, is composed of several technical services on which business services can rely on to provide a micro-services based platform. +The Tdrive Platform is built using the component framework described just before and so, is composed of several technical services on which business services can rely on to provide a micro-services based platform. The current chapter describes the technical services of the plaform, how to use them, how to build business services on top of them... @@ -256,12 +256,12 @@ Supported databases are currently [MongoDB](https://www.mongodb.com/) and [Cassa "type": "cassandra", "mongodb": { "uri": "mongodb://localhost:27017", - "database": "twake" + "database": "tdrive" }, "cassandra": { "contactPoints": ["localhost:9042"], "localDataCenter": "datacenter1", - "keyspace": "twake" + "keyspace": "tdrive" } } } @@ -273,7 +273,7 @@ In the example above, the `type` is set to `cassandra`, so the `database.cassand In order to use Cassandra, we will have to: -1. Create a keyspace. From the configuration above, the keyspace is `twake` +1. Create a keyspace. From the configuration above, the keyspace is `tdrive` 2. Create all the required tables To achieve these steps, you have to use [cqlsh](https://cassandra.apache.org/doc/latest/tools/cqlsh.html) from a terminal then: @@ -281,13 +281,13 @@ To achieve these steps, you have to use [cqlsh](https://cassandra.apache.org/doc 1. Create the keyspace: ```sh -CREATE KEYSPACE twake WITH replication = {'class': 'NetworkTopologyStrategy', 'datacenter1': '2'} AND durable_writes = true; +CREATE KEYSPACE tdrive WITH replication = {'class': 'NetworkTopologyStrategy', 'datacenter1': '2'} AND durable_writes = true; ``` 2. Create the required tables ```sh -USE twake; +USE tdrive; CREATE TABLE channels(company_id uuid, workspace_id uuid, id uuid, archivation_date date, archived boolean, channel_group text, description text, icon text, is_default boolean, name text, owner uuid, visibility text, PRIMARY KEY ((company_id, workspace_id), id)); ``` @@ -391,7 +391,7 @@ Services annotated as described above automatically publish events to WebSockets ```js const io = require("socket.io-client"); -// Get a JWT token from the Twake API first +// Get a JWT token from the Tdrive API first const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOjEsImlhdCI6MTYwMzE5ODkzMn0.NvQoV9KeWuTNzRvzqbJ5uZCQ8Nmi2rCYQzcKk-WsJJ8"; const socket = io.connect("http://localhost:3000", { path: "/socket" }); @@ -433,7 +433,7 @@ socket.on("connect", () => { .emit("authenticate", { token }) .on("authenticated", () => { // join the /channels room - socket.emit("realtime:join", { name: "/channels", token: "twake" }); + socket.emit("realtime:join", { name: "/channels", token: "tdrive" }); socket.on("realtime:join:error", message => { // will fire when join does not provide a valid token console.log("Error on join", message); @@ -514,7 +514,7 @@ socket.on("connect", () => { .emit("authenticate", { token }) .on("authenticated", () => { // join the "/channels" room - socket.emit("realtime:join", { name: "/channels", token: "twake" }); + socket.emit("realtime:join", { name: "/channels", token: "tdrive" }); // will only occur when an action occured on a resource // and if and only if the client joined the room diff --git a/twake/backend/node/config/default.json b/twake/backend/node/config/default.json index 986258b2..27622995 100644 --- a/twake/backend/node/config/default.json +++ b/twake/backend/node/config/default.json @@ -2,11 +2,11 @@ "general": { "help_url": false, "pricing_plan_url": "", - "app_download_url": "https://twake.app/download", + "app_download_url": "https://tdrive.app/download", "mobile": { - "mobile_redirect": "mobile.twake.app", - "mobile_appstore": "https://apps.apple.com/fr/app/twake/id1588764852?l=en", - "mobile_googleplay": "https://play.google.com/store/apps/details?id=com.twake.twake&gl=FR" + "mobile_redirect": "mobile.tdrive.app", + "mobile_appstore": "https://apps.apple.com/fr/app/tdrive/id1588764852?l=en", + "mobile_googleplay": "https://play.google.com/store/apps/details?id=com.tdrive.tdrive&gl=FR" }, "app_grid": [ { @@ -15,9 +15,9 @@ "url": "https://tmail.linagora.com/" }, { - "name": "Twake", - "logo": "/public/img/grid/twake.png", - "url": "https://twake.app/" + "name": "Tdrive", + "logo": "/public/img/grid/tdrive.png", + "url": "https://tdrive.app/" } ], "accounts": { @@ -28,14 +28,14 @@ }, "remote": { "authority": "http://auth.example.com/", - "client_id": "twakeweb", + "client_id": "tdriveweb", "client_secret": "", "issuer": "", "audience": "", "redirect_uris": [""], - "account_management_url": "http://web.twake-console.local/profile?company-code={company_id}", - "collaborators_management_url": "http://web.twake-console.local/compaies/{company_id}/users?company-code={company_id}", - "company_management_url": "http://web.twake-console.local/companies?company-code={company_id}" + "account_management_url": "http://web.tdrive-console.local/profile?company-code={company_id}", + "collaborators_management_url": "http://web.tdrive-console.local/compaies/{company_id}/users?company-code={company_id}", + "company_management_url": "http://web.tdrive-console.local/companies?company-code={company_id}" } } }, @@ -93,12 +93,12 @@ "type": "cassandra", "mongodb": { "uri": "mongodb://mongo:27017", - "database": "twake" + "database": "tdrive" }, "cassandra": { "contactPoints": ["scylladb:9042"], "localDataCenter": "datacenter1", - "keyspace": "twake", + "keyspace": "tdrive", "wait": false, "retries": 10, "delay": 200 @@ -151,7 +151,7 @@ "email-pusher": { "endpoint": "https://api.smtp2go.com/v3/email/send", "api_key": "secret", - "sender": "noreply@twake.app" + "sender": "noreply@tdrive.app" }, "services": [ "auth", @@ -168,15 +168,11 @@ "tracker", "general", "user", - "applications-api", - "applications", "channels", "notifications", - "messages", "files", "workspaces", "console", - "previews", "counter", "statistics", "cron", diff --git a/twake/backend/node/package-lock.json b/twake/backend/node/package-lock.json index 7bc522c7..b0f67c4f 100644 --- a/twake/backend/node/package-lock.json +++ b/twake/backend/node/package-lock.json @@ -1,5 +1,5 @@ { - "name": "@twake/twake-backend", + "name": "@tdrive/tdrive-backend", "version": "1.0.0", "lockfileVersion": 1, "requires": true, diff --git a/twake/backend/node/package.json b/twake/backend/node/package.json index ec5e3b36..2a448719 100644 --- a/twake/backend/node/package.json +++ b/twake/backend/node/package.json @@ -1,7 +1,7 @@ { - "name": "@twake/twake-backend", + "name": "@tdrive/tdrive-backend", "version": "1.0.0", - "description": "Twake backend", + "description": "Tdrive backend", "scripts": { "build": "npm run build:clean && npm run build:ts && npm run build:copy-assets", "build:ts": "tsc", @@ -44,16 +44,16 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/Twake/twake-backend.git" + "url": "git+https://github.com/Tdrive/tdrive-backend.git" }, - "author": "Twake", + "author": "Tdrive", "license": "ISC", "bugs": { - "url": "https://github.com/Twake/twake-backend/issues" + "url": "https://github.com/Tdrive/tdrive-backend/issues" }, - "homepage": "https://github.com/Twake/twake-backend#readme", + "homepage": "https://github.com/Tdrive/tdrive-backend#readme", "bin": { - "twake-cli": "bin/twake-cli" + "tdrive-cli": "bin/tdrive-cli" }, "devDependencies": { "@babel/core": "^7.11.6", diff --git a/twake/backend/node/public/index.html b/twake/backend/node/public/index.html index f2d2dbd4..360441c3 100644 --- a/twake/backend/node/public/index.html +++ b/twake/backend/node/public/index.html @@ -1,4 +1,4 @@ -Twake frontend is not here, please do one of the following:
+Tdrive frontend is not here, please do one of the following:
- use the nginx container as a separate process
- attach the built frontend to this container and use the STATIC_ROOT env variable
- use the production container \ No newline at end of file diff --git a/twake/backend/node/src/cli/cmds/applications.ts b/twake/backend/node/src/cli/cmds/applications.ts index e7acd332..b389590d 100644 --- a/twake/backend/node/src/cli/cmds/applications.ts +++ b/twake/backend/node/src/cli/cmds/applications.ts @@ -1,7 +1,7 @@ import { CommandModule } from "yargs"; const command: CommandModule = { - describe: "Manage Twake Applications", + describe: "Manage Tdrive Applications", command: "applications ", builder: yargs => yargs.commandDir("applications_cmds", { diff --git a/twake/backend/node/src/cli/cmds/export.ts b/twake/backend/node/src/cli/cmds/export.ts index 97f88aa6..37e12334 100644 --- a/twake/backend/node/src/cli/cmds/export.ts +++ b/twake/backend/node/src/cli/cmds/export.ts @@ -1,7 +1,7 @@ import { CommandModule } from "yargs"; const command: CommandModule = { - describe: "Export Twake data", + describe: "Export Tdrive data", command: "export ", builder: yargs => yargs.commandDir("export_cmds", { diff --git a/twake/backend/node/src/cli/cmds/export_cmds/export_company.ts b/twake/backend/node/src/cli/cmds/export_cmds/export_company.ts index 8c8b26b2..6615a102 100644 --- a/twake/backend/node/src/cli/cmds/export_cmds/export_company.ts +++ b/twake/backend/node/src/cli/cmds/export_cmds/export_company.ts @@ -1,5 +1,5 @@ import yargs from "yargs"; -import twake from "../../../twake"; +import tdrive from "../../../tdrive"; import { mkdirSync, writeFileSync } from "fs"; import { Pagination } from "../../../core/platform/framework/api/crud-service"; import WorkspaceUser from "../../../services/workspaces/entities/workspace_user"; @@ -52,7 +52,7 @@ const command: yargs.CommandModule = { }, }, handler: async argv => { - const platform = await twake.run(services); + const platform = await tdrive.run(services); await gr.doInit(platform); const company = await gr.services.companies.getCompany({ id: argv.id }); diff --git a/twake/backend/node/src/cli/cmds/generate.ts b/twake/backend/node/src/cli/cmds/generate.ts index c71ca84d..cea700d2 100644 --- a/twake/backend/node/src/cli/cmds/generate.ts +++ b/twake/backend/node/src/cli/cmds/generate.ts @@ -1,7 +1,7 @@ import { CommandModule } from "yargs"; const command: CommandModule = { - describe: "Generate Twake data", + describe: "Generate Tdrive data", command: "generate ", builder: yargs => yargs.commandDir("generate_cmds", { diff --git a/twake/backend/node/src/cli/cmds/generate_cmds/users-and-companies.ts b/twake/backend/node/src/cli/cmds/generate_cmds/users-and-companies.ts index a4d1e77c..9865ec09 100644 --- a/twake/backend/node/src/cli/cmds/generate_cmds/users-and-companies.ts +++ b/twake/backend/node/src/cli/cmds/generate_cmds/users-and-companies.ts @@ -8,7 +8,7 @@ import Company, { getInstance as getCompanyInstance, } from "../../../services/user/entities/company"; import CompanyUser from "../../../services/user/entities/company_user"; -import twake from "../../../twake"; +import tdrive from "../../../tdrive"; import User, { getInstance as getUserInstance } from "../../../services/user/entities/user"; import gr from "../../../services/global-resolver"; @@ -63,7 +63,7 @@ const command: yargs.CommandModule<{}, CLIArgs> = { const concurrentTasks = argv.concurrent; const nbUsersPerCompany = argv.user; const nbCompanies = argv.company; - const platform = await twake.run(services); + const platform = await tdrive.run(services); await gr.doInit(platform); const companies = getCompanies(nbCompanies); const createUser = async (userInCompany: { @@ -114,8 +114,8 @@ const getCompanies = (size: number = 10): Company[] => { return [...Array(size).keys()].map(i => getCompanyInstance({ id: uuid(), - name: `twake${i}.app`, - displayName: `My Twake Company #${i}`, + name: `tdrive${i}.app`, + displayName: `My Tdrive Company #${i}`, }), ); }; diff --git a/twake/backend/node/src/cli/cmds/search_cmds/index_all.ts b/twake/backend/node/src/cli/cmds/search_cmds/index_all.ts index 54ee745c..4de1a6b2 100644 --- a/twake/backend/node/src/cli/cmds/search_cmds/index_all.ts +++ b/twake/backend/node/src/cli/cmds/search_cmds/index_all.ts @@ -1,7 +1,7 @@ import yargs from "yargs"; -import twake from "../../../twake"; +import tdrive from "../../../tdrive"; import ora from "ora"; -import { TwakePlatform } from "../../../core/platform/platform"; +import { TdrivePlatform } from "../../../core/platform/platform"; import { DatabaseServiceAPI } from "../../../core/platform/services/database/api"; import { Pagination } from "../../../core/platform/framework/api/crud-service"; @@ -21,7 +21,7 @@ class SearchIndexAll { database: DatabaseServiceAPI; search: SearchServiceAPI; - constructor(readonly platform: TwakePlatform) { + constructor(readonly platform: TdrivePlatform) { this.database = this.platform.getProvider("database"); this.search = this.platform.getProvider("search"); } @@ -122,7 +122,7 @@ const command: yargs.CommandModule = { // eslint-disable-next-line @typescript-eslint/no-unused-vars handler: async argv => { const spinner = ora({ text: "Reindex repository - " }).start(); - const platform = await twake.run(services); + const platform = await tdrive.run(services); await gr.doInit(platform); const migrator = new SearchIndexAll(platform); diff --git a/twake/backend/node/src/cli/cmds/users.ts b/twake/backend/node/src/cli/cmds/users.ts index 02fb151d..d92c61af 100644 --- a/twake/backend/node/src/cli/cmds/users.ts +++ b/twake/backend/node/src/cli/cmds/users.ts @@ -1,7 +1,7 @@ import { CommandModule } from "yargs"; const command: CommandModule = { - describe: "Manage Twake Users", + describe: "Manage Tdrive Users", command: "users ", builder: yargs => yargs.commandDir("users_cmds", { diff --git a/twake/backend/node/src/cli/cmds/users_cmds/remove.ts b/twake/backend/node/src/cli/cmds/users_cmds/remove.ts index f9304309..3ab9afab 100644 --- a/twake/backend/node/src/cli/cmds/users_cmds/remove.ts +++ b/twake/backend/node/src/cli/cmds/users_cmds/remove.ts @@ -1,6 +1,6 @@ import yargs from "yargs"; import ora from "ora"; -import twake from "../../../twake"; +import tdrive from "../../../tdrive"; import Table from "cli-table"; import { exit } from "process"; import gr from "../../../services/global-resolver"; @@ -49,7 +49,7 @@ const command: yargs.CommandModule = { }); const spinner = ora({ text: "Retrieving user" }).start(); - const platform = await twake.run(services); + const platform = await tdrive.run(services); await gr.doInit(platform); const user = await gr.services.users.get({ id: argv.id }); diff --git a/twake/backend/node/src/cli/cmds/workspace.ts b/twake/backend/node/src/cli/cmds/workspace.ts index 9eb9bd8b..95686ec5 100644 --- a/twake/backend/node/src/cli/cmds/workspace.ts +++ b/twake/backend/node/src/cli/cmds/workspace.ts @@ -1,7 +1,7 @@ import { CommandModule } from "yargs"; const command: CommandModule = { - describe: "Manage Twake Workspaces", + describe: "Manage Tdrive Workspaces", command: "workspace ", builder: yargs => yargs.commandDir("workspace_cmds", { diff --git a/twake/backend/node/src/cli/cmds/workspace_cmds/list.ts b/twake/backend/node/src/cli/cmds/workspace_cmds/list.ts index 910f1f4c..d11e9e18 100644 --- a/twake/backend/node/src/cli/cmds/workspace_cmds/list.ts +++ b/twake/backend/node/src/cli/cmds/workspace_cmds/list.ts @@ -1,7 +1,7 @@ import yargs from "yargs"; import ora from "ora"; import Table from "cli-table"; -import twake from "../../../twake"; +import tdrive from "../../../tdrive"; import gr from "../../../services/global-resolver"; /** * Merge command parameters. Check the builder definition below for more details. @@ -23,7 +23,7 @@ const services = [ const command: yargs.CommandModule = { command: "list", - describe: "List Twake workspaces", + describe: "List Tdrive workspaces", builder: { size: { default: "50", @@ -33,8 +33,8 @@ const command: yargs.CommandModule = { }, handler: async argv => { const table = new Table({ head: ["ID", "Name"], colWidths: [40, 50] }); - const spinner = ora({ text: "List Twake workspaces" }).start(); - const platform = await twake.run(services); + const spinner = ora({ text: "List Tdrive workspaces" }).start(); + const platform = await tdrive.run(services); await gr.doInit(platform); const workspaces = await gr.services.workspaces.list({ limitStr: argv.size }); diff --git a/twake/backend/node/src/cli/cmds/workspace_cmds/user.ts b/twake/backend/node/src/cli/cmds/workspace_cmds/user.ts index bc5b139b..3388e5ff 100644 --- a/twake/backend/node/src/cli/cmds/workspace_cmds/user.ts +++ b/twake/backend/node/src/cli/cmds/workspace_cmds/user.ts @@ -1,7 +1,7 @@ import yargs from "yargs"; import ora from "ora"; import Table from "cli-table"; -import twake from "../../../twake"; +import tdrive from "../../../tdrive"; import gr from "../../../services/global-resolver"; /** * Merge command parameters. Check the builder definition below for more details. @@ -34,7 +34,7 @@ const command: yargs.CommandModule = { handler: async argv => { const table = new Table({ head: ["user ID", "Date Added"], colWidths: [40, 40] }); const spinner = ora({ text: "Retrieving workspace users" }).start(); - const platform = await twake.run(services); + const platform = await tdrive.run(services); await gr.doInit(platform); const users = await gr.services.workspaces.getUsers({ workspaceId: argv.id }); diff --git a/twake/backend/node/src/cli/index.ts b/twake/backend/node/src/cli/index.ts index c1350f05..848b708b 100644 --- a/twake/backend/node/src/cli/index.ts +++ b/twake/backend/node/src/cli/index.ts @@ -24,5 +24,5 @@ yargs .alias("help", "h") .help("help") .version() - .epilogue("for more information, go to https://twake.app") + .epilogue("for more information, go to https://tdrive.app") .example("$0 --help", "show help of the issue command").argv; diff --git a/twake/backend/node/src/cli/utils/copy-cluster/index.js b/twake/backend/node/src/cli/utils/copy-cluster/index.js index e478433c..1c4d5716 100644 --- a/twake/backend/node/src/cli/utils/copy-cluster/index.js +++ b/twake/backend/node/src/cli/utils/copy-cluster/index.js @@ -3,18 +3,18 @@ var cassandra = require("cassandra-driver"); var fromAuthProvider = new cassandra.auth.PlainTextAuthProvider("", ""); var fromContactPoints = [""]; -var fromKeyspace = "twake"; +var fromKeyspace = "tdrive"; var toAuthProvider = new cassandra.auth.PlainTextAuthProvider("", ""); var toContactPoints = [""]; -var toKeyspace = "twake"; +var toKeyspace = "tdrive"; var forceUpdateAll = false; var ignoreTables = ["notification"]; var countersTables = ["statistics", "stats_counter", "channel_counters", "scheduled_queue_counter"]; var specialConversions = { - "twake.group_user.date_added": value => { + "tdrive.group_user.date_added": value => { return new Date(value).getTime(); }, }; diff --git a/twake/backend/node/src/cli/utils/copy-messages/index.js b/twake/backend/node/src/cli/utils/copy-messages/index.js index ddaf0d75..e9edf081 100644 --- a/twake/backend/node/src/cli/utils/copy-messages/index.js +++ b/twake/backend/node/src/cli/utils/copy-messages/index.js @@ -13,14 +13,14 @@ var fromClient = new cassandra.Client({ localDataCenter: "datacenter1", contactPoints: fromContactPoints, authProvider: fromAuthProvider, - keyspace: "twake", + keyspace: "tdrive", }); var toClient = new cassandra.Client({ localDataCenter: "datacenter1", contactPoints: toContactPoints, authProvider: toAuthProvider, - keyspace: "twake", + keyspace: "tdrive", queryOptions: { consistency: cassandra.types.consistencies.quorum, }, @@ -48,7 +48,7 @@ let copiedThreads = 0; (async () => { await new Promise(r => { fromClient.eachRow( - "SELECT id from twake.threads", + "SELECT id from tdrive.threads", [], { prepare: true, fetchSize: 50 }, async function (n, row) { @@ -60,7 +60,7 @@ let copiedThreads = 0; await new Promise(r2 => { fromClient.eachRow( - "SELECT JSON * from twake.messages where thread_id = ? order by id desc", + "SELECT JSON * from tdrive.messages where thread_id = ? order by id desc", [threadId], { prepare: true, fetchSize: 1000 }, async function (n, row) { @@ -69,7 +69,7 @@ let copiedThreads = 0; copiedMessages++; await toClient.execute( - "INSERT INTO twake.messages JSON '" + message.replace(/'/g, "'$&") + "'", + "INSERT INTO tdrive.messages JSON '" + message.replace(/'/g, "'$&") + "'", [], { prepare: true }, ); diff --git a/twake/backend/node/src/cli/utils/copy-table/index.js b/twake/backend/node/src/cli/utils/copy-table/index.js index 112abdae..50ed0db1 100644 --- a/twake/backend/node/src/cli/utils/copy-table/index.js +++ b/twake/backend/node/src/cli/utils/copy-table/index.js @@ -10,7 +10,7 @@ var client = new cassandra.Client({ localDataCenter: "datacenter1", contactPoints: contactPoints, authProvider: authProvider, - keyspace: "twake", + keyspace: "tdrive", }); //Copy object to other table diff --git a/twake/backend/node/src/cli/utils/repair-threads/index.js b/twake/backend/node/src/cli/utils/repair-threads/index.js index 87a00d5a..7eeb9a4d 100644 --- a/twake/backend/node/src/cli/utils/repair-threads/index.js +++ b/twake/backend/node/src/cli/utils/repair-threads/index.js @@ -8,7 +8,7 @@ var client = new cassandra.Client({ localDataCenter: "datacenter1", contactPoints: contactPoints, authProvider: authProvider, - keyspace: "twake", + keyspace: "tdrive", }); var threadsTable = "threads"; diff --git a/twake/backend/node/src/core/crypto/legacy.ts b/twake/backend/node/src/core/crypto/legacy.ts index f18479e0..96718875 100644 --- a/twake/backend/node/src/core/crypto/legacy.ts +++ b/twake/backend/node/src/core/crypto/legacy.ts @@ -2,7 +2,6 @@ import { createDecipheriv } from "crypto"; import { CryptoResult } from "."; const PREFIX = "encrypted_"; -const DEFAULT_IV = "twake_constantiv"; export default { decrypt, @@ -25,9 +24,10 @@ function decrypt(data: string, encryptionKey: string): CryptoResult { const salt = encryptedArray[1] ? Buffer.from(encryptedArray[1], "utf-8") : Buffer.from("", "utf-8"); - const iv = encryptedArray[2] - ? Buffer.from(encryptedArray[2], "base64") - : Buffer.from(DEFAULT_IV, "utf-8"); + const iv = + encryptedArray.length >= 3 + ? Buffer.from(encryptedArray[2], "base64") + : Buffer.from("twake_constantiv", "utf-8"); const password = Buffer.concat([Buffer.from(encryptionKey, "hex"), salt], 32); const decipher = createDecipheriv("AES-256-CBC", password, iv); diff --git a/twake/backend/node/src/core/platform/framework/api/application-configuration.ts b/twake/backend/node/src/core/platform/framework/api/application-configuration.ts index ae678c5f..cd9453c3 100644 --- a/twake/backend/node/src/core/platform/framework/api/application-configuration.ts +++ b/twake/backend/node/src/core/platform/framework/api/application-configuration.ts @@ -1,7 +1,7 @@ -import { TwakeServiceOptions } from "./service-options"; -import { TwakeServiceConfiguration } from "./service-configuration"; +import { TdriveServiceOptions } from "./service-options"; +import { TdriveServiceConfiguration } from "./service-configuration"; -export class TwakeAppConfiguration extends TwakeServiceOptions { +export class TdriveAppConfiguration extends TdriveServiceOptions { services: Array; servicesPath: string; } diff --git a/twake/backend/node/src/core/platform/framework/api/component.ts b/twake/backend/node/src/core/platform/framework/api/component.ts index 7a982410..dfa12085 100644 --- a/twake/backend/node/src/core/platform/framework/api/component.ts +++ b/twake/backend/node/src/core/platform/framework/api/component.ts @@ -1,13 +1,13 @@ import { BehaviorSubject } from "rxjs"; -import { TwakeService } from "./service"; -import { TwakeServiceProvider } from "./service-provider"; +import { TdriveService } from "./service"; +import { TdriveServiceProvider } from "./service-provider"; import { ServiceDefinition } from "./service-definition"; -import { TwakeServiceState } from "./service-state"; +import { TdriveServiceState } from "./service-state"; import { logger } from "../logger"; -export class TwakeComponent { - instance: TwakeService; - components: Array = new Array(); +export class TdriveComponent { + instance: TdriveService; + components: Array = new Array(); constructor(public name: string, private serviceDefinition: ServiceDefinition) {} @@ -15,15 +15,15 @@ export class TwakeComponent { return this.serviceDefinition; } - setServiceInstance(instance: TwakeService): void { + setServiceInstance(instance: TdriveService): void { this.instance = instance; } - getServiceInstance(): TwakeService { + getServiceInstance(): TdriveService { return this.instance; } - addDependency(component: TwakeComponent): void { + addDependency(component: TdriveComponent): void { this.components.push(component); } @@ -34,7 +34,7 @@ export class TwakeComponent { } async switchToState( - state: TwakeServiceState.Initialized | TwakeServiceState.Started | TwakeServiceState.Stopped, + state: TdriveServiceState.Initialized | TdriveServiceState.Started | TdriveServiceState.Stopped, recursionDepth?: number, ): Promise { if (recursionDepth > 10) { @@ -42,7 +42,7 @@ export class TwakeComponent { process.exit(1); } - const states: BehaviorSubject[] = this.components.map( + const states: BehaviorSubject[] = this.components.map( component => component.instance.state, ); @@ -57,10 +57,10 @@ export class TwakeComponent { } // eslint-disable-next-line @typescript-eslint/no-explicit-any - async function _switchServiceToState(service: TwakeService) { - state === TwakeServiceState.Initialized && (await service.init()); - state === TwakeServiceState.Started && (await service.start()); - state === TwakeServiceState.Stopped && (await service.stop()); + async function _switchServiceToState(service: TdriveService) { + state === TdriveServiceState.Initialized && (await service.init()); + state === TdriveServiceState.Started && (await service.start()); + state === TdriveServiceState.Stopped && (await service.stop()); } await _switchServiceToState(this.instance); } diff --git a/twake/backend/node/src/core/platform/framework/api/container.ts b/twake/backend/node/src/core/platform/framework/api/container.ts index c374a9ee..ba340d2f 100644 --- a/twake/backend/node/src/core/platform/framework/api/container.ts +++ b/twake/backend/node/src/core/platform/framework/api/container.ts @@ -1,30 +1,30 @@ -import { TwakeAppConfiguration } from "./application-configuration"; -import { TwakeComponent } from "./component"; -import { TwakeContext } from "./context"; -import { TwakeServiceProvider } from "./service-provider"; -import { TwakeService } from "./service"; -import { TwakeServiceState } from "./service-state"; +import { TdriveAppConfiguration } from "./application-configuration"; +import { TdriveComponent } from "./component"; +import { TdriveContext } from "./context"; +import { TdriveServiceProvider } from "./service-provider"; +import { TdriveService } from "./service"; +import { TdriveServiceState } from "./service-state"; import * as ComponentUtils from "../utils/component-utils"; /** * A container contains components. It provides methods to manage and to retrieve them. */ -export abstract class TwakeContainer - extends TwakeService - implements TwakeContext +export abstract class TdriveContainer + extends TdriveService + implements TdriveContext { - private components: Map; - name = "TwakeContainer"; + private components: Map; + name = "TdriveContainer"; - constructor(protected options?: TwakeAppConfiguration) { + constructor(protected options?: TdriveAppConfiguration) { super(options); } - abstract loadComponents(): Promise>; + abstract loadComponents(): Promise>; - abstract loadComponent(name: string): Promise; + abstract loadComponent(name: string): Promise; - getProvider(name: string): T { + getProvider(name: string): T { const service = this.components.get(name)?.getServiceInstance(); if (!service) { @@ -48,25 +48,25 @@ export abstract class TwakeContainer } protected async launchInit(): Promise { - await this.switchToState(TwakeServiceState.Initialized); + await this.switchToState(TdriveServiceState.Initialized); return this; } async doStart(): Promise { - await this.switchToState(TwakeServiceState.Started); + await this.switchToState(TdriveServiceState.Started); return this; } async doStop(): Promise { - await this.switchToState(TwakeServiceState.Stopped); + await this.switchToState(TdriveServiceState.Stopped); return this; } protected async switchToState( - state: TwakeServiceState.Started | TwakeServiceState.Initialized | TwakeServiceState.Stopped, + state: TdriveServiceState.Started | TdriveServiceState.Initialized | TdriveServiceState.Stopped, ): Promise { await ComponentUtils.switchComponentsToState(this.components, state); } diff --git a/twake/backend/node/src/core/platform/framework/api/context.ts b/twake/backend/node/src/core/platform/framework/api/context.ts index f9ac36e4..c26eb400 100644 --- a/twake/backend/node/src/core/platform/framework/api/context.ts +++ b/twake/backend/node/src/core/platform/framework/api/context.ts @@ -1,5 +1,5 @@ -import { TwakeServiceProvider } from "./service-provider"; +import { TdriveServiceProvider } from "./service-provider"; -export interface TwakeContext { - getProvider(name: string): T; +export interface TdriveContext { + getProvider(name: string): T; } diff --git a/twake/backend/node/src/core/platform/framework/api/lifecycle.ts b/twake/backend/node/src/core/platform/framework/api/lifecycle.ts index eb938efe..6b9a0188 100644 --- a/twake/backend/node/src/core/platform/framework/api/lifecycle.ts +++ b/twake/backend/node/src/core/platform/framework/api/lifecycle.ts @@ -1,6 +1,6 @@ -import { TwakeContext } from "./context"; +import { TdriveContext } from "./context"; export interface Initializable { // TODO: Flag to tell if a service which fails to initialize must break all - init?(context?: TwakeContext): Promise; + init?(context?: TdriveContext): Promise; } diff --git a/twake/backend/node/src/core/platform/framework/api/service-configuration.ts b/twake/backend/node/src/core/platform/framework/api/service-configuration.ts index 4cf6816b..c7285d8b 100644 --- a/twake/backend/node/src/core/platform/framework/api/service-configuration.ts +++ b/twake/backend/node/src/core/platform/framework/api/service-configuration.ts @@ -1,3 +1,3 @@ -export interface TwakeServiceConfiguration { +export interface TdriveServiceConfiguration { get(name?: string, defaultValue?: T): T; } diff --git a/twake/backend/node/src/core/platform/framework/api/service-interface.ts b/twake/backend/node/src/core/platform/framework/api/service-interface.ts index 4bec93b9..45dff4f8 100644 --- a/twake/backend/node/src/core/platform/framework/api/service-interface.ts +++ b/twake/backend/node/src/core/platform/framework/api/service-interface.ts @@ -1,6 +1,6 @@ -import { TwakeServiceProvider } from "./service-provider"; +import { TdriveServiceProvider } from "./service-provider"; -export interface TwakeServiceInterface { +export interface TdriveServiceInterface { doInit(): Promise; doStart(): Promise; doStop(): Promise; diff --git a/twake/backend/node/src/core/platform/framework/api/service-options.ts b/twake/backend/node/src/core/platform/framework/api/service-options.ts index 86bb44fd..e107735a 100644 --- a/twake/backend/node/src/core/platform/framework/api/service-options.ts +++ b/twake/backend/node/src/core/platform/framework/api/service-options.ts @@ -1,5 +1,5 @@ -export class TwakeServiceOptions { +export class TdriveServiceOptions { name?: string; // TODO: configuration is abstract and comes from all others - configuration?: TwakeServiceConfiguration; + configuration?: TdriveServiceConfiguration; } diff --git a/twake/backend/node/src/core/platform/framework/api/service-provider.ts b/twake/backend/node/src/core/platform/framework/api/service-provider.ts index 5d247a91..0b48b970 100644 --- a/twake/backend/node/src/core/platform/framework/api/service-provider.ts +++ b/twake/backend/node/src/core/platform/framework/api/service-provider.ts @@ -1,3 +1,3 @@ -export interface TwakeServiceProvider { +export interface TdriveServiceProvider { version: string; } diff --git a/twake/backend/node/src/core/platform/framework/api/service-state.ts b/twake/backend/node/src/core/platform/framework/api/service-state.ts index 35b9e9c1..26e5bdf7 100644 --- a/twake/backend/node/src/core/platform/framework/api/service-state.ts +++ b/twake/backend/node/src/core/platform/framework/api/service-state.ts @@ -1,4 +1,4 @@ -export enum TwakeServiceState { +export enum TdriveServiceState { Ready = "READY", Initializing = "INITIALIZING", Initialized = "INITIALIZED", diff --git a/twake/backend/node/src/core/platform/framework/api/service.ts b/twake/backend/node/src/core/platform/framework/api/service.ts index 9e9ab643..801f0151 100644 --- a/twake/backend/node/src/core/platform/framework/api/service.ts +++ b/twake/backend/node/src/core/platform/framework/api/service.ts @@ -1,27 +1,27 @@ import { BehaviorSubject } from "rxjs"; -import { TwakeServiceInterface } from "./service-interface"; -import { TwakeServiceProvider } from "./service-provider"; -import { TwakeServiceState } from "./service-state"; -import { TwakeServiceConfiguration } from "./service-configuration"; -import { TwakeContext } from "./context"; -import { TwakeServiceOptions } from "./service-options"; +import { TdriveServiceInterface } from "./service-interface"; +import { TdriveServiceProvider } from "./service-provider"; +import { TdriveServiceState } from "./service-state"; +import { TdriveServiceConfiguration } from "./service-configuration"; +import { TdriveContext } from "./context"; +import { TdriveServiceOptions } from "./service-options"; import { CONSUMES_METADATA, PREFIX_METADATA } from "./constants"; import { getLogger, logger } from "../logger"; -import { TwakeLogger } from ".."; +import { TdriveLogger } from ".."; const pendingServices: any = {}; -export abstract class TwakeService - implements TwakeServiceInterface +export abstract class TdriveService + implements TdriveServiceInterface { - state: BehaviorSubject; + state: BehaviorSubject; readonly name: string; - protected readonly configuration: TwakeServiceConfiguration; - context: TwakeContext; - logger: TwakeLogger; + protected readonly configuration: TdriveServiceConfiguration; + context: TdriveContext; + logger: TdriveLogger; - constructor(protected options?: TwakeServiceOptions) { - this.state = new BehaviorSubject(TwakeServiceState.Ready); + constructor(protected options?: TdriveServiceOptions) { + this.state = new BehaviorSubject(TdriveServiceState.Ready); // REMOVE ME, we should import config from framework folder instead this.configuration = options?.configuration; this.logger = getLogger(`core.platform.services.${this.name}Service`); @@ -38,7 +38,7 @@ export abstract class TwakeService } async init(): Promise { - if (this.state.value !== TwakeServiceState.Ready) { + if (this.state.value !== TdriveServiceState.Ready) { logger.info("Service %s is already initialized", this.name); return this; } @@ -46,9 +46,9 @@ export abstract class TwakeService try { logger.info("Initializing service %s", this.name); pendingServices[this.name] = true; - this.state.next(TwakeServiceState.Initializing); + this.state.next(TdriveServiceState.Initializing); await this.doInit(); - this.state.next(TwakeServiceState.Initialized); + this.state.next(TdriveServiceState.Initialized); logger.info("Service %s is initialized", this.name); delete pendingServices[this.name]; logger.info("Pending services: %s", JSON.stringify(Object.keys(pendingServices))); @@ -72,8 +72,8 @@ export abstract class TwakeService async start(): Promise { if ( - this.state.value === TwakeServiceState.Starting || - this.state.value === TwakeServiceState.Started + this.state.value === TdriveServiceState.Starting || + this.state.value === TdriveServiceState.Started ) { logger.info("Service %s is already started", this.name); return this; @@ -81,9 +81,9 @@ export abstract class TwakeService try { logger.info("Starting service %s", this.name); - this.state.next(TwakeServiceState.Starting); + this.state.next(TdriveServiceState.Starting); await this.doStart(); - this.state.next(TwakeServiceState.Started); + this.state.next(TdriveServiceState.Started); logger.info("Service %s is started", this.name); return this; @@ -98,23 +98,23 @@ export abstract class TwakeService async stop(): Promise { if ( - this.state.value === TwakeServiceState.Stopping || - this.state.value === TwakeServiceState.Stopped + this.state.value === TdriveServiceState.Stopping || + this.state.value === TdriveServiceState.Stopped ) { logger.info("Service %s is already stopped", this.name); return this; } - if (this.state.value !== TwakeServiceState.Started) { + if (this.state.value !== TdriveServiceState.Started) { logger.info("Service %s can not be stopped until started", this.name); return this; } try { logger.info("Stopping service %s", this.name); - this.state.next(TwakeServiceState.Stopping); + this.state.next(TdriveServiceState.Stopping); await this.doStop(); - this.state.next(TwakeServiceState.Stopped); + this.state.next(TdriveServiceState.Stopped); logger.info("Service %s is stopped", this.name); return this; diff --git a/twake/backend/node/src/core/platform/framework/configuration.ts b/twake/backend/node/src/core/platform/framework/configuration.ts index cf77e855..50fc4c3d 100644 --- a/twake/backend/node/src/core/platform/framework/configuration.ts +++ b/twake/backend/node/src/core/platform/framework/configuration.ts @@ -1,7 +1,7 @@ import { IConfig } from "config"; import configuration from "../../config"; -import { TwakeServiceConfiguration } from "./api"; -export class Configuration implements TwakeServiceConfiguration { +import { TdriveServiceConfiguration } from "./api"; +export class Configuration implements TdriveServiceConfiguration { configuration: IConfig; serviceConfiguration: IConfig; diff --git a/twake/backend/node/src/core/platform/framework/event-bus.ts b/twake/backend/node/src/core/platform/framework/event-bus.ts index 361ea4ce..2b285832 100644 --- a/twake/backend/node/src/core/platform/framework/event-bus.ts +++ b/twake/backend/node/src/core/platform/framework/event-bus.ts @@ -3,7 +3,7 @@ import { logger as rootLogger } from "./logger"; import { ExecutionContext } from "./api/crud-service"; const logger = rootLogger.child({ - component: "twake.core.platform.framework.event-bus", + component: "tdrive.core.platform.framework.event-bus", }); /** diff --git a/twake/backend/node/src/core/platform/framework/factory.ts b/twake/backend/node/src/core/platform/framework/factory.ts index 315c13f8..c5e4ec00 100644 --- a/twake/backend/node/src/core/platform/framework/factory.ts +++ b/twake/backend/node/src/core/platform/framework/factory.ts @@ -1,18 +1,18 @@ import { - TwakeContext, - TwakeService, - TwakeServiceConfiguration, - TwakeServiceOptions, - TwakeServiceProvider, + TdriveContext, + TdriveService, + TdriveServiceConfiguration, + TdriveServiceOptions, + TdriveServiceProvider, } from "./api"; import { Configuration } from "./configuration"; -class StaticTwakeServiceFactory { +class StaticTdriveServiceFactory { public async create< - T extends TwakeService = TwakeService, + T extends TdriveService = TdriveService, >( - module: { new (options?: TwakeServiceOptions): T }, - context: TwakeContext, + module: { new (options?: TdriveServiceOptions): T }, + context: TdriveContext, configuration?: string, ): Promise { let config; @@ -29,4 +29,4 @@ class StaticTwakeServiceFactory { } } -export const TwakeServiceFactory = new StaticTwakeServiceFactory(); +export const TdriveServiceFactory = new StaticTdriveServiceFactory(); diff --git a/twake/backend/node/src/core/platform/framework/logger.ts b/twake/backend/node/src/core/platform/framework/logger.ts index 8c0aa335..41faa757 100644 --- a/twake/backend/node/src/core/platform/framework/logger.ts +++ b/twake/backend/node/src/core/platform/framework/logger.ts @@ -3,19 +3,13 @@ import { Configuration } from "./configuration"; const config = new Configuration("logger"); -export type TwakeLogger = pino.Logger; +export type TdriveLogger = pino.Logger; export const logger = pino({ - name: "TwakeApp", + name: "TdriveApp", level: config.get("level", "info") || "info", - prettyPrint: - process.env.NODE_ENV?.indexOf("test") > -1 - ? { - translateTime: "HH:MM:ss Z", - ignore: "pid,hostname,name", - } - : false, + prettyPrint: false, }); -export const getLogger = (name?: string): TwakeLogger => - logger.child({ name: `twake${name ? "." + name : ""}` }); +export const getLogger = (name?: string): TdriveLogger => + logger.child({ name: `tdrive${name ? "." + name : ""}` }); diff --git a/twake/backend/node/src/core/platform/framework/utils/component-utils.ts b/twake/backend/node/src/core/platform/framework/utils/component-utils.ts index f74697e6..99775cf9 100644 --- a/twake/backend/node/src/core/platform/framework/utils/component-utils.ts +++ b/twake/backend/node/src/core/platform/framework/utils/component-utils.ts @@ -1,15 +1,15 @@ /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types */ import { logger, - TwakeComponent, - TwakeContext, - TwakeServiceFactory, - TwakeServiceState, + TdriveComponent, + TdriveContext, + TdriveServiceFactory, + TdriveServiceState, } from "../index"; import { Loader } from "./loader"; export async function buildDependenciesTree( - components: Map, + components: Map, loadComponent: (name: string) => any, ): Promise { for (const [name, component] of components) { @@ -62,15 +62,15 @@ export async function buildDependenciesTree( export async function loadComponents( paths: string[], names: string[] = [], - context: TwakeContext, -): Promise> { - const result = new Map(); + context: TdriveContext, +): Promise> { + const result = new Map(); const loader = new Loader(paths); - const components: TwakeComponent[] = await Promise.all( + const components: TdriveComponent[] = await Promise.all( names.map(async name => { const clazz = await loader.load(name); - const component = new TwakeComponent(name, { clazz, name }); + const component = new TdriveComponent(name, { clazz, name }); result.set(name, component); return component; @@ -79,7 +79,7 @@ export async function loadComponents( await Promise.all( components.map(async component => { - const service = await TwakeServiceFactory.create( + const service = await TdriveServiceFactory.create( component.getServiceDefinition().clazz, context, component.getServiceDefinition().name, @@ -93,8 +93,8 @@ export async function loadComponents( } export async function switchComponentsToState( - components: Map, - state: TwakeServiceState.Initialized | TwakeServiceState.Started | TwakeServiceState.Stopped, + components: Map, + state: TdriveServiceState.Initialized | TdriveServiceState.Started | TdriveServiceState.Stopped, ): Promise { const states = []; diff --git a/twake/backend/node/src/core/platform/platform.ts b/twake/backend/node/src/core/platform/platform.ts index 689703f1..02467239 100644 --- a/twake/backend/node/src/core/platform/platform.ts +++ b/twake/backend/node/src/core/platform/platform.ts @@ -1,17 +1,17 @@ -import { TwakeContainer, TwakeServiceProvider, TwakeComponent } from "./framework"; +import { TdriveContainer, TdriveServiceProvider, TdriveComponent } from "./framework"; import * as ComponentUtils from "./framework/utils/component-utils"; import path from "path"; -export class TwakePlatform extends TwakeContainer { - constructor(protected options: TwakePlatformConfiguration) { +export class TdrivePlatform extends TdriveContainer { + constructor(protected options: TdrivePlatformConfiguration) { super(); } - api(): TwakeServiceProvider { + api(): TdriveServiceProvider { return null; } - async loadComponents(): Promise> { + async loadComponents(): Promise> { return await ComponentUtils.loadComponents( [this.options.servicesPath, path.resolve(__dirname, "./services/")], this.options.services, @@ -21,7 +21,7 @@ export class TwakePlatform extends TwakeContainer { ); } - async loadComponent(name: string): Promise { + async loadComponent(name: string): Promise { return ( await ComponentUtils.loadComponents( [this.options.servicesPath, path.resolve(__dirname, "./services/")], @@ -34,7 +34,7 @@ export class TwakePlatform extends TwakeContainer { } } -export class TwakePlatformConfiguration { +export class TdrivePlatformConfiguration { /** * The services to load in the container */ diff --git a/twake/backend/node/src/core/platform/services/auth/index.ts b/twake/backend/node/src/core/platform/services/auth/index.ts index a1f0c028..e21fd8a9 100644 --- a/twake/backend/node/src/core/platform/services/auth/index.ts +++ b/twake/backend/node/src/core/platform/services/auth/index.ts @@ -1,4 +1,4 @@ -import { TwakeService, Consumes, Prefix, ServiceName } from "../../framework"; +import { TdriveService, Consumes, Prefix, ServiceName } from "../../framework"; import web from "./web/index"; import AuthServiceAPI, { JwtConfiguration } from "./provider"; import { AuthService as AuthServiceImpl } from "./service"; @@ -7,7 +7,7 @@ import WebServerAPI from "../webserver/provider"; @Prefix("/api/auth") @Consumes(["webserver"]) @ServiceName("auth") -export default class AuthService extends TwakeService { +export default class AuthService extends TdriveService { name = "auth"; service: AuthServiceAPI; diff --git a/twake/backend/node/src/core/platform/services/auth/provider.ts b/twake/backend/node/src/core/platform/services/auth/provider.ts index 264430d1..6dc4b902 100644 --- a/twake/backend/node/src/core/platform/services/auth/provider.ts +++ b/twake/backend/node/src/core/platform/services/auth/provider.ts @@ -1,7 +1,7 @@ -import { TwakeServiceProvider } from "../../framework/api"; +import { TdriveServiceProvider } from "../../framework/api"; import { AccessToken, JWTObject, uuid } from "../../../../utils/types"; -export default interface AuthServiceAPI extends TwakeServiceProvider { +export default interface AuthServiceAPI extends TdriveServiceProvider { /** * Get the authentication types */ diff --git a/twake/backend/node/src/core/platform/services/counter/index.ts b/twake/backend/node/src/core/platform/services/counter/index.ts index 3e14ec8d..62446556 100644 --- a/twake/backend/node/src/core/platform/services/counter/index.ts +++ b/twake/backend/node/src/core/platform/services/counter/index.ts @@ -1,9 +1,9 @@ -import { TwakeService } from "../../framework"; +import { TdriveService } from "../../framework"; import { CounterProvider } from "./provider"; import { CounterAPI } from "./types"; import Repository from "../database/services/orm/repository/repository"; -export default class CounterService extends TwakeService implements CounterAPI { +export default class CounterService extends TdriveService implements CounterAPI { name = "counter"; version = "1"; diff --git a/twake/backend/node/src/core/platform/services/counter/types.ts b/twake/backend/node/src/core/platform/services/counter/types.ts index c3b83ff6..7eaacfb5 100644 --- a/twake/backend/node/src/core/platform/services/counter/types.ts +++ b/twake/backend/node/src/core/platform/services/counter/types.ts @@ -1,7 +1,7 @@ -import { TwakeServiceProvider } from "../../framework"; +import { TdriveServiceProvider } from "../../framework"; import Repository from "../database/services/orm/repository/repository"; import { CounterProvider } from "./provider"; -export interface CounterAPI extends TwakeServiceProvider { +export interface CounterAPI extends TdriveServiceProvider { getCounter(repository: Repository): CounterProvider; } diff --git a/twake/backend/node/src/core/platform/services/cron/api.ts b/twake/backend/node/src/core/platform/services/cron/api.ts index 2d495b77..9df091c1 100644 --- a/twake/backend/node/src/core/platform/services/cron/api.ts +++ b/twake/backend/node/src/core/platform/services/cron/api.ts @@ -1,5 +1,5 @@ import { ScheduledTask } from "node-cron"; -import { TwakeServiceProvider } from "../../framework"; +import { TdriveServiceProvider } from "../../framework"; export type CronJob = () => void; @@ -18,7 +18,7 @@ export type CronTask = { stop: () => void; }; -export interface CronAPI extends TwakeServiceProvider { +export interface CronAPI extends TdriveServiceProvider { /** * Schedule a Job * diff --git a/twake/backend/node/src/core/platform/services/cron/index.ts b/twake/backend/node/src/core/platform/services/cron/index.ts index b2e09283..ee120f80 100644 --- a/twake/backend/node/src/core/platform/services/cron/index.ts +++ b/twake/backend/node/src/core/platform/services/cron/index.ts @@ -1,10 +1,10 @@ import * as cron from "node-cron"; import uuid from "node-uuid"; -import { TwakeService } from "../../framework"; +import { TdriveService } from "../../framework"; import { CronAPI, CronJob, CronExpression, CronTask } from "./api"; -export default class CronService extends TwakeService implements CronAPI { +export default class CronService extends TdriveService implements CronAPI { name = "cron"; version = "1"; private tasks = new Array(); diff --git a/twake/backend/node/src/core/platform/services/database/api.ts b/twake/backend/node/src/core/platform/services/database/api.ts index b5312f70..105ce97d 100644 --- a/twake/backend/node/src/core/platform/services/database/api.ts +++ b/twake/backend/node/src/core/platform/services/database/api.ts @@ -1,10 +1,10 @@ -import { TwakeServiceProvider } from "../../framework"; +import { TdriveServiceProvider } from "../../framework"; import { Connector } from "./services/orm/connectors"; import Manager from "./services/orm/manager"; import Repository from "./services/orm/repository/repository"; import { EntityTarget } from "./services/orm/types"; -export interface DatabaseServiceAPI extends TwakeServiceProvider { +export interface DatabaseServiceAPI extends TdriveServiceProvider { /** * Get the database connector */ diff --git a/twake/backend/node/src/core/platform/services/database/index.ts b/twake/backend/node/src/core/platform/services/database/index.ts index a2ec8261..2f662c24 100644 --- a/twake/backend/node/src/core/platform/services/database/index.ts +++ b/twake/backend/node/src/core/platform/services/database/index.ts @@ -1,11 +1,11 @@ -import { TwakeService, logger, ServiceName } from "../../framework"; +import { TdriveService, logger, ServiceName } from "../../framework"; import { DatabaseServiceAPI } from "./api"; import DatabaseService from "./services"; import { DatabaseType } from "./services"; import { ConnectionOptions } from "./services/orm/connectors"; @ServiceName("database") -export default class Database extends TwakeService { +export default class Database extends TdriveService { version = "1"; name = "database"; service: DatabaseService; diff --git a/twake/backend/node/src/core/platform/services/database/services/orm/connectors/cassandra/query-builder.ts b/twake/backend/node/src/core/platform/services/database/services/orm/connectors/cassandra/query-builder.ts index 192c1573..553cac5f 100644 --- a/twake/backend/node/src/core/platform/services/database/services/orm/connectors/cassandra/query-builder.ts +++ b/twake/backend/node/src/core/platform/services/database/services/orm/connectors/cassandra/query-builder.ts @@ -12,7 +12,7 @@ export function buildSelectQuery( keyspace: string; } = { secret: "", - keyspace: "twake", + keyspace: "tdrive", }, ): string { const instance = new (entityType as any)(); diff --git a/twake/backend/node/src/core/platform/services/database/services/orm/connectors/cassandra/typeTransforms.ts b/twake/backend/node/src/core/platform/services/database/services/orm/connectors/cassandra/typeTransforms.ts index 230420c0..2213ef8d 100644 --- a/twake/backend/node/src/core/platform/services/database/services/orm/connectors/cassandra/typeTransforms.ts +++ b/twake/backend/node/src/core/platform/services/database/services/orm/connectors/cassandra/typeTransforms.ts @@ -19,9 +19,9 @@ export const cassandraType = { boolean: "BOOLEAN", // backward compatibility - twake_boolean: "TINYINT", - twake_int: "INT", //Depreciated - twake_datetime: "TIMESTAMP", //Depreciated + tdrive_boolean: "TINYINT", + tdrive_int: "INT", //Depreciated + tdrive_datetime: "TIMESTAMP", //Depreciated }; type TransformOptions = { @@ -36,14 +36,14 @@ export const transformValueToDbString = ( type: ColumnType, options: TransformOptions = {}, ): string => { - if (type === "twake_datetime") { + if (type === "tdrive_datetime") { if (isNaN(v) || isNull(v)) { return "null"; } return `${v}`; } - if (type === "number" || type === "twake_int") { + if (type === "number" || type === "tdrive_int") { if (isNull(v)) { return "null"; } @@ -67,7 +67,7 @@ export const transformValueToDbString = ( } return `${!!v}`; } - if (type === "twake_boolean") { + if (type === "tdrive_boolean") { if (!isBoolean(v)) { throw new Error(`'${v}' is not a ${type}`); } @@ -111,7 +111,7 @@ export const transformValueFromDbString = ( ): any => { logger.trace(`Transform value %o of type ${type}`, v); - if (type === "twake_datetime") { + if (type === "tdrive_datetime") { return new Date(`${v}`).getTime(); } @@ -146,7 +146,7 @@ export const transformValueFromDbString = ( return decryptedValue; } - if (type === "twake_boolean" || type === "boolean") { + if (type === "tdrive_boolean" || type === "boolean") { return Boolean(v).valueOf(); } diff --git a/twake/backend/node/src/core/platform/services/database/services/orm/connectors/mongodb/query-builder.ts b/twake/backend/node/src/core/platform/services/database/services/orm/connectors/mongodb/query-builder.ts index c99e103f..decb7391 100644 --- a/twake/backend/node/src/core/platform/services/database/services/orm/connectors/mongodb/query-builder.ts +++ b/twake/backend/node/src/core/platform/services/database/services/orm/connectors/mongodb/query-builder.ts @@ -12,7 +12,7 @@ export function buildSelectQuery( keyspace: string; } = { secret: "", - keyspace: "twake", + keyspace: "tdrive", }, ): any { const instance = new (entityType as any)(); diff --git a/twake/backend/node/src/core/platform/services/database/services/orm/connectors/mongodb/typeTransforms.ts b/twake/backend/node/src/core/platform/services/database/services/orm/connectors/mongodb/typeTransforms.ts index 933039da..4b6c45df 100644 --- a/twake/backend/node/src/core/platform/services/database/services/orm/connectors/mongodb/typeTransforms.ts +++ b/twake/backend/node/src/core/platform/services/database/services/orm/connectors/mongodb/typeTransforms.ts @@ -54,7 +54,7 @@ export const transformValueToDbString = ( return v; } - if (type === "twake_boolean") { + if (type === "tdrive_boolean") { return Boolean(v); } @@ -91,7 +91,7 @@ export const transformValueFromDbString = (v: any, type: string, options: any = return null; } } - if (type === "twake_boolean" || type === "boolean") { + if (type === "tdrive_boolean" || type === "boolean") { return Boolean(v).valueOf(); } if (type === "number") { diff --git a/twake/backend/node/src/core/platform/services/database/services/orm/types.ts b/twake/backend/node/src/core/platform/services/database/services/orm/types.ts index 6888dd8e..3d04efad 100644 --- a/twake/backend/node/src/core/platform/services/database/services/orm/types.ts +++ b/twake/backend/node/src/core/platform/services/database/services/orm/types.ts @@ -39,9 +39,9 @@ export type ColumnType = | "blob" | "boolean" // backward compatibility - | "twake_boolean" - | "twake_int" - | "twake_datetime"; + | "tdrive_boolean" + | "tdrive_int" + | "tdrive_datetime"; export type EntityTarget = ObjectType; diff --git a/twake/backend/node/src/core/platform/services/database/services/orm/utils.ts b/twake/backend/node/src/core/platform/services/database/services/orm/utils.ts index bf4db2ae..91abd369 100644 --- a/twake/backend/node/src/core/platform/services/database/services/orm/utils.ts +++ b/twake/backend/node/src/core/platform/services/database/services/orm/utils.ts @@ -41,7 +41,7 @@ export function secureOperators( keyspace: string; } = { secret: "", - keyspace: "twake", + keyspace: "tdrive", }, ): FindOptions { const instance = new (entityType as any)(); diff --git a/twake/backend/node/src/core/platform/services/email-pusher/index.ts b/twake/backend/node/src/core/platform/services/email-pusher/index.ts index d47a594d..a6b61127 100644 --- a/twake/backend/node/src/core/platform/services/email-pusher/index.ts +++ b/twake/backend/node/src/core/platform/services/email-pusher/index.ts @@ -1,4 +1,4 @@ -import { getLogger, TwakeLogger, TwakeService } from "../../framework"; +import { getLogger, TdriveLogger, TdriveService } from "../../framework"; import EmailPusherAPI from "./provider"; import { EmailBuilderDataPayload, @@ -15,12 +15,12 @@ import { existsSync } from "fs"; import axios from "axios"; export default class EmailPusherClass - extends TwakeService + extends TdriveService implements EmailPusherAPI { readonly name = "email-pusher"; readonly version: "1.0.0"; - logger: TwakeLogger = getLogger("email-pusher-service"); + logger: TdriveLogger = getLogger("email-pusher-service"); apiKey: string; apiUrl: string; sender: string; diff --git a/twake/backend/node/src/core/platform/services/email-pusher/provider.ts b/twake/backend/node/src/core/platform/services/email-pusher/provider.ts index fc6c5817..f81edd2e 100644 --- a/twake/backend/node/src/core/platform/services/email-pusher/provider.ts +++ b/twake/backend/node/src/core/platform/services/email-pusher/provider.ts @@ -1,4 +1,4 @@ -import { TwakeServiceProvider } from "../../framework"; +import { TdriveServiceProvider } from "../../framework"; import { EmailBuilderDataPayload, EmailBuilderRenderedResult, @@ -6,7 +6,7 @@ import { EmailPusherPayload, } from "./types"; -export default interface EmailPusherAPI extends TwakeServiceProvider { +export default interface EmailPusherAPI extends TdriveServiceProvider { build( template: EmailBuilderTemplateName, language: string, diff --git a/twake/backend/node/src/core/platform/services/email-pusher/templates/common/_title.eta b/twake/backend/node/src/core/platform/services/email-pusher/templates/common/_title.eta index d1797518..2448daa6 100644 --- a/twake/backend/node/src/core/platform/services/email-pusher/templates/common/_title.eta +++ b/twake/backend/node/src/core/platform/services/email-pusher/templates/common/_title.eta @@ -32,7 +32,7 @@ role="presentation" style="vertical-align:top;" width="100%" >
romaric.mollard@gmail.com has invited you to use Twake + >romaric.mollard@gmail.com has invited you to use Tdrive on Crayon Company.
diff --git a/twake/backend/node/src/core/platform/services/email-pusher/templates/en/_structure.eta b/twake/backend/node/src/core/platform/services/email-pusher/templates/en/_structure.eta index 0695e651..d7e393cb 100644 --- a/twake/backend/node/src/core/platform/services/email-pusher/templates/en/_structure.eta +++ b/twake/backend/node/src/core/platform/services/email-pusher/templates/en/_structure.eta @@ -5,8 +5,8 @@ privacy: "Privacy Policy", terms: "Terms of Service", links: { - help: "https://twake.app/", - privacy: "https://twake.app/en/privacy-policy/", - terms: "https://twake.app/en/terms-of-service/" + help: "https://tdrive.app/", + privacy: "https://tdrive.app/en/privacy-policy/", + terms: "https://tdrive.app/en/terms-of-service/" } })) %> \ No newline at end of file diff --git a/twake/backend/node/src/core/platform/services/email-pusher/templates/en/notification-digest.eta b/twake/backend/node/src/core/platform/services/email-pusher/templates/en/notification-digest.eta index db7f25d9..8c74a8f4 100644 --- a/twake/backend/node/src/core/platform/services/email-pusher/templates/en/notification-digest.eta +++ b/twake/backend/node/src/core/platform/services/email-pusher/templates/en/notification-digest.eta @@ -34,8 +34,8 @@ ), ` ` diff --git a/twake/backend/node/src/core/platform/services/email-pusher/templates/en/notification-digest/notification.eta b/twake/backend/node/src/core/platform/services/email-pusher/templates/en/notification-digest/notification.eta index bee47338..f8758e94 100644 --- a/twake/backend/node/src/core/platform/services/email-pusher/templates/en/notification-digest/notification.eta +++ b/twake/backend/node/src/core/platform/services/email-pusher/templates/en/notification-digest/notification.eta @@ -1,6 +1,6 @@
- <%= it.message.user.first_name %> + <%= it.message.user.first_name %>
diff --git a/twake/backend/node/src/core/platform/services/email-pusher/templates/fr/_structure.eta b/twake/backend/node/src/core/platform/services/email-pusher/templates/fr/_structure.eta index d0fa48b4..c6dc00dd 100644 --- a/twake/backend/node/src/core/platform/services/email-pusher/templates/fr/_structure.eta +++ b/twake/backend/node/src/core/platform/services/email-pusher/templates/fr/_structure.eta @@ -5,8 +5,8 @@ privacy: "Confidentialité", terms: "CGU", links: { - help: "https://twake.app/", - privacy: "https://twake.app/fr/privacy-policy/", - terms: "https://twake.app/fr/terms-of-service/" + help: "https://tdrive.app/", + privacy: "https://tdrive.app/fr/privacy-policy/", + terms: "https://tdrive.app/fr/terms-of-service/" } })) %> \ No newline at end of file diff --git a/twake/backend/node/src/core/platform/services/email-pusher/templates/fr/notification-digest.eta b/twake/backend/node/src/core/platform/services/email-pusher/templates/fr/notification-digest.eta index 00c4aea7..01b6a4e1 100644 --- a/twake/backend/node/src/core/platform/services/email-pusher/templates/fr/notification-digest.eta +++ b/twake/backend/node/src/core/platform/services/email-pusher/templates/fr/notification-digest.eta @@ -36,8 +36,8 @@ , ` ` diff --git a/twake/backend/node/src/core/platform/services/email-pusher/templates/fr/notification-digest/notification.eta b/twake/backend/node/src/core/platform/services/email-pusher/templates/fr/notification-digest/notification.eta index bee47338..f8758e94 100644 --- a/twake/backend/node/src/core/platform/services/email-pusher/templates/fr/notification-digest/notification.eta +++ b/twake/backend/node/src/core/platform/services/email-pusher/templates/fr/notification-digest/notification.eta @@ -1,6 +1,6 @@
- <%= it.message.user.first_name %> + <%= it.message.user.first_name %>
diff --git a/twake/backend/node/src/core/platform/services/knowledge-graph/api-client.ts b/twake/backend/node/src/core/platform/services/knowledge-graph/api-client.ts index f958655c..5734293e 100644 --- a/twake/backend/node/src/core/platform/services/knowledge-graph/api-client.ts +++ b/twake/backend/node/src/core/platform/services/knowledge-graph/api-client.ts @@ -8,13 +8,13 @@ import gr from "../../../../services/global-resolver"; import Company from "../../../../services/user/entities/company"; import User from "../../../../services/user/entities/user"; import Workspace from "../../../../services/workspaces/entities/workspace"; -import { getLogger, TwakeLogger } from "../../framework"; +import { getLogger, TdriveLogger } from "../../framework"; export default class KnowledgeGraphAPIClient { protected readonly version = "1.0.0"; protected readonly axiosInstance: AxiosInstance = axios.create(); readonly apiUrl: string; - readonly logger: TwakeLogger = getLogger("knowledge-graph-api-client"); + readonly logger: TdriveLogger = getLogger("knowledge-graph-api-client"); constructor(apiUrl: string) { this.apiUrl = apiUrl; @@ -141,7 +141,7 @@ export default class KnowledgeGraphAPIClient { private async send(data: any) { return await this.axiosInstance.post< KnowledgeGraphCreateBodyRequest - >(`${this.apiUrl}/topics/twake`, data, { + >(`${this.apiUrl}/topics/tdrive`, data, { headers: { "Content-Type": "application/vnd.kafka.json.v2+json", Accept: "application/vnd.kafka.v2+json", diff --git a/twake/backend/node/src/core/platform/services/knowledge-graph/index.ts b/twake/backend/node/src/core/platform/services/knowledge-graph/index.ts index 154a7611..579bbcf2 100644 --- a/twake/backend/node/src/core/platform/services/knowledge-graph/index.ts +++ b/twake/backend/node/src/core/platform/services/knowledge-graph/index.ts @@ -1,4 +1,4 @@ -import { Configuration, Consumes, getLogger, TwakeLogger, TwakeService } from "../../framework"; +import { Configuration, Consumes, getLogger, TdriveLogger, TdriveService } from "../../framework"; import { localEventBus } from "../../framework/event-bus"; import KnowledgeGraphAPI from "./provider"; import Workspace from "../../../../services/workspaces/entities/workspace"; @@ -15,13 +15,13 @@ import gr from "../../../../services/global-resolver"; @Consumes([]) export default class KnowledgeGraphService - extends TwakeService + extends TdriveService implements KnowledgeGraphAPI { readonly name = "knowledge-graph"; readonly version = "1.0.0"; protected kgAPIClient: KnowledgeGraphAPIClient = this.getKnowledgeGraphApiClient(); - logger: TwakeLogger = getLogger("knowledge-graph-service"); + logger: TdriveLogger = getLogger("knowledge-graph-service"); async doInit(): Promise { const use = this.getConfigurationEntry("use"); diff --git a/twake/backend/node/src/core/platform/services/knowledge-graph/provider.ts b/twake/backend/node/src/core/platform/services/knowledge-graph/provider.ts index 46eecd0c..612fd0f9 100644 --- a/twake/backend/node/src/core/platform/services/knowledge-graph/provider.ts +++ b/twake/backend/node/src/core/platform/services/knowledge-graph/provider.ts @@ -1,11 +1,11 @@ import Company from "../../../../services/user/entities/company"; import { Channel } from "../../../../services/channels/entities"; -import { TwakeServiceProvider } from "../../framework"; +import { TdriveServiceProvider } from "../../framework"; import { KnowledgeGraphGenericEventPayload } from "./types"; import Workspace from "../../../../services/workspaces/entities/workspace"; import User from "../../../../services/user/entities/user"; -export default interface KnowledgeGraphAPI extends TwakeServiceProvider { +export default interface KnowledgeGraphAPI extends TdriveServiceProvider { onCompanyCreated(data: KnowledgeGraphGenericEventPayload): void; onWorkspaceCreated(data: KnowledgeGraphGenericEventPayload): void; onChannelCreated(data: KnowledgeGraphGenericEventPayload): void; diff --git a/twake/backend/node/src/core/platform/services/message-queue/amqp/index.ts b/twake/backend/node/src/core/platform/services/message-queue/amqp/index.ts index 4c14a20d..dcc7e22f 100644 --- a/twake/backend/node/src/core/platform/services/message-queue/amqp/index.ts +++ b/twake/backend/node/src/core/platform/services/message-queue/amqp/index.ts @@ -12,7 +12,7 @@ import { AMQPMessageQueueManager } from "./manager"; import { SkipCLI } from "../../../framework/decorators/skip"; const logger = rootLogger.child({ - component: "twake.core.platform.services.message-queue.amqp", + component: "tdrive.core.platform.services.message-queue.amqp", }); export class AMQPMessageQueueService implements MessageQueueAdapter { diff --git a/twake/backend/node/src/core/platform/services/message-queue/amqp/manager.ts b/twake/backend/node/src/core/platform/services/message-queue/amqp/manager.ts index 276671a8..f17eb704 100644 --- a/twake/backend/node/src/core/platform/services/message-queue/amqp/manager.ts +++ b/twake/backend/node/src/core/platform/services/message-queue/amqp/manager.ts @@ -56,7 +56,7 @@ export class AMQPMessageQueueManager implements MessageQueueClientManager { private create(connection: AmqpConnectionManager): Promise { logger.info(`${LOG_PREFIX} Creating AMQP Channel`); - const channel = connection.createChannel({ name: "Twake" }); + const channel = connection.createChannel({ name: "Tdrive" }); channel.on("close", () => { logger.info(`${LOG_PREFIX} Channel is closed`); diff --git a/twake/backend/node/src/core/platform/services/message-queue/api.ts b/twake/backend/node/src/core/platform/services/message-queue/api.ts index 3df4475c..8eb68deb 100644 --- a/twake/backend/node/src/core/platform/services/message-queue/api.ts +++ b/twake/backend/node/src/core/platform/services/message-queue/api.ts @@ -1,6 +1,6 @@ import { Subject } from "rxjs"; import { v4 as uuidv4 } from "uuid"; -import { Initializable, logger, TwakeServiceProvider } from "../../framework"; +import { Initializable, logger, TdriveServiceProvider } from "../../framework"; import { Processor } from "./processor"; import { ExecutionContext } from "../../framework/api/crud-service"; @@ -60,7 +60,7 @@ export type MessageQueueSubscriptionOptions = { export type MessageQueueListener = (message: IncomingMessageQueueMessage) => void; -export interface MessageQueueServiceAPI extends TwakeServiceProvider { +export interface MessageQueueServiceAPI extends TdriveServiceProvider { /** * Publish a message to a given topic * @param topic The topic to publish the message to diff --git a/twake/backend/node/src/core/platform/services/message-queue/factory.ts b/twake/backend/node/src/core/platform/services/message-queue/factory.ts index fbf39f9a..46ef31c5 100644 --- a/twake/backend/node/src/core/platform/services/message-queue/factory.ts +++ b/twake/backend/node/src/core/platform/services/message-queue/factory.ts @@ -1,17 +1,17 @@ import { MessageQueueAdapter, MessageQueueType } from "./api"; import { AMQPMessageQueueService } from "./amqp"; import { LocalMessageQueueService } from "./local"; -import { TwakeServiceConfiguration, logger as rootLogger } from "../../framework"; +import { TdriveServiceConfiguration, logger as rootLogger } from "../../framework"; const logger = rootLogger.child({ - component: "twake.core.platform.services.message-queue.factory", + component: "tdrive.core.platform.services.message-queue.factory", }); const DEFAULT_AMQP_URL = "amqp://guest:guest@localhost:5672"; const DEFAULT_ADAPTER = "amqp"; export class MessageQueueAdapterFactory { - public create(configuration: TwakeServiceConfiguration): MessageQueueAdapter { + public create(configuration: TdriveServiceConfiguration): MessageQueueAdapter { const type: MessageQueueType = configuration.get("type", DEFAULT_ADAPTER); logger.info("Building Adapter %o", type); diff --git a/twake/backend/node/src/core/platform/services/message-queue/index.ts b/twake/backend/node/src/core/platform/services/message-queue/index.ts index cb5393e3..b2baf214 100644 --- a/twake/backend/node/src/core/platform/services/message-queue/index.ts +++ b/twake/backend/node/src/core/platform/services/message-queue/index.ts @@ -1,4 +1,4 @@ -import { TwakeService, ServiceName, logger as rootLogger } from "../../framework"; +import { TdriveService, ServiceName, logger as rootLogger } from "../../framework"; import { MessageQueueAdapter, MessageQueueListener, @@ -13,10 +13,10 @@ import { SkipCLI } from "../../framework/decorators/skip"; import config from "../../../../core/config"; const logger = rootLogger.child({ - component: "twake.core.platform.services.message-queue", + component: "tdrive.core.platform.services.message-queue", }); @ServiceName("message-queue") -export default class MessageQueue extends TwakeService { +export default class MessageQueue extends TdriveService { version = "1"; name = "message-queue"; service: MessageQueueService; diff --git a/twake/backend/node/src/core/platform/services/message-queue/local/index.ts b/twake/backend/node/src/core/platform/services/message-queue/local/index.ts index 1eb4cdfd..fe67fa27 100644 --- a/twake/backend/node/src/core/platform/services/message-queue/local/index.ts +++ b/twake/backend/node/src/core/platform/services/message-queue/local/index.ts @@ -10,7 +10,7 @@ import { import MessageQueueProxy from "../proxy"; const logger = rootLogger.child({ - component: "twake.core.platform.services.message-queue.local", + component: "tdrive.core.platform.services.message-queue.local", }); /** diff --git a/twake/backend/node/src/core/platform/services/phpnode/index.ts b/twake/backend/node/src/core/platform/services/phpnode/index.ts index ae5c098f..36eda3e6 100644 --- a/twake/backend/node/src/core/platform/services/phpnode/index.ts +++ b/twake/backend/node/src/core/platform/services/phpnode/index.ts @@ -10,7 +10,7 @@ import { ChannelParameters, CreateChannelBody, } from "../../../../services/channels/web/types"; -import { Consumes, TwakeService } from "../../framework"; +import { Consumes, TdriveService } from "../../framework"; import WebServerAPI from "../webserver/provider"; import WebSocketAPI from "../websocket/provider"; import PhpNodeAPI from "./provider"; @@ -18,7 +18,7 @@ import { RealtimeServiceAPI } from "../realtime/api"; import gr from "../../../../services/global-resolver"; @Consumes(["webserver", "websocket", "user", "channels"]) -export default class PhpNodeService extends TwakeService implements PhpNodeAPI { +export default class PhpNodeService extends TdriveService implements PhpNodeAPI { name = "phpnode"; version = "1"; private server: FastifyInstance; diff --git a/twake/backend/node/src/core/platform/services/phpnode/provider.ts b/twake/backend/node/src/core/platform/services/phpnode/provider.ts index d9686c0a..1a8a2f7a 100644 --- a/twake/backend/node/src/core/platform/services/phpnode/provider.ts +++ b/twake/backend/node/src/core/platform/services/phpnode/provider.ts @@ -1,8 +1,8 @@ import { FastifyInstance, FastifyRequest, RouteHandlerMethod } from "fastify"; import { IncomingMessage, ServerResponse, Server } from "http"; -import { TwakeServiceProvider } from "../../framework"; +import { TdriveServiceProvider } from "../../framework"; -export default interface PhpNodeAPI extends TwakeServiceProvider { +export default interface PhpNodeAPI extends TdriveServiceProvider { accessControl( request: FastifyRequest, server: FastifyInstance, diff --git a/twake/backend/node/src/core/platform/services/push/api.ts b/twake/backend/node/src/core/platform/services/push/api.ts index 08d52134..ac69bbe2 100644 --- a/twake/backend/node/src/core/platform/services/push/api.ts +++ b/twake/backend/node/src/core/platform/services/push/api.ts @@ -1,7 +1,7 @@ -import { TwakeServiceProvider } from "../../framework"; +import { TdriveServiceProvider } from "../../framework"; import { PushMessageNotification, PushMessageOptions } from "./types"; -export interface PushServiceAPI extends TwakeServiceProvider { +export interface PushServiceAPI extends TdriveServiceProvider { push( devices: string[], notification: PushMessageNotification, diff --git a/twake/backend/node/src/core/platform/services/push/index.ts b/twake/backend/node/src/core/platform/services/push/index.ts index c0550bec..15844f5d 100644 --- a/twake/backend/node/src/core/platform/services/push/index.ts +++ b/twake/backend/node/src/core/platform/services/push/index.ts @@ -1,11 +1,11 @@ -import { TwakeService, logger, ServiceName } from "../../framework"; +import { TdriveService, logger, ServiceName } from "../../framework"; import { PushServiceAPI } from "./api"; import { PushConnector } from "./connectors/connector"; import FcmPushConnector from "./connectors/fcm/service"; import { PushConfiguration, PushMessageNotification, PushMessageOptions } from "./types"; @ServiceName("push") -export default class Push extends TwakeService { +export default class Push extends TdriveService { version = "1"; name = "push"; service: PushConnector; diff --git a/twake/backend/node/src/core/platform/services/realtime/api.ts b/twake/backend/node/src/core/platform/services/realtime/api.ts index 9b3c4a96..e2ae08d4 100644 --- a/twake/backend/node/src/core/platform/services/realtime/api.ts +++ b/twake/backend/node/src/core/platform/services/realtime/api.ts @@ -1,9 +1,9 @@ -import { TwakeServiceProvider } from "../../framework"; +import { TdriveServiceProvider } from "../../framework"; import { WebSocketUser, WebSocket } from "../../services/websocket/types"; import RealtimeEntityManager from "./services/entity-manager"; import { RealtimeEntityEvent } from "./types"; -export interface RealtimeServiceAPI extends TwakeServiceProvider { +export interface RealtimeServiceAPI extends TdriveServiceProvider { /** * Get the realtime event bus instance */ diff --git a/twake/backend/node/src/core/platform/services/realtime/index.ts b/twake/backend/node/src/core/platform/services/realtime/index.ts index 9cc94ee5..c6208068 100644 --- a/twake/backend/node/src/core/platform/services/realtime/index.ts +++ b/twake/backend/node/src/core/platform/services/realtime/index.ts @@ -1,4 +1,4 @@ -import { Consumes, ServiceName, TwakeService } from "../../framework"; +import { Consumes, ServiceName, TdriveService } from "../../framework"; import { SkipCLI } from "../../framework/decorators/skip"; import { localEventBus } from "../../framework/event-bus"; import WebSocketAPI from "../../services/websocket/provider"; @@ -12,7 +12,7 @@ import { RealtimeBaseBusEvent, RealtimeLocalBusEvent } from "./types"; @Consumes(["websocket", "auth"]) @ServiceName("realtime") export default class RealtimeService - extends TwakeService + extends TdriveService implements RealtimeServiceAPI { private roomManager: RoomManagerImpl; diff --git a/twake/backend/node/src/core/platform/services/realtime/services/room-manager.ts b/twake/backend/node/src/core/platform/services/realtime/services/room-manager.ts index c8cdb0ed..2df14689 100644 --- a/twake/backend/node/src/core/platform/services/realtime/services/room-manager.ts +++ b/twake/backend/node/src/core/platform/services/realtime/services/room-manager.ts @@ -88,7 +88,7 @@ export default class RoomManager implements RealtimeRoomManager { } //Retro-compatibility for mobile up to february 2021 (to remove after this date) - if (joinEvent.token === "twake") return true; + if (joinEvent.token === "tdrive") return true; const signature = this.auth.verifyTokenObject(joinEvent.token); diff --git a/twake/backend/node/src/core/platform/services/search/api.ts b/twake/backend/node/src/core/platform/services/search/api.ts index 87f03fde..e64d574d 100644 --- a/twake/backend/node/src/core/platform/services/search/api.ts +++ b/twake/backend/node/src/core/platform/services/search/api.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types */ -import { TwakeServiceProvider } from "../../framework"; +import { TdriveServiceProvider } from "../../framework"; import { ListResult } from "../../framework/api/crud-service"; import { FindFilter as OrmFindFilter, @@ -57,7 +57,7 @@ export interface SearchAdapterInterface { ): Promise>; } -export interface SearchServiceAPI extends TwakeServiceProvider { +export interface SearchServiceAPI extends TdriveServiceProvider { getRepository(table: string, entityType: EntityTarget): SearchRepository; upsert(entities: any[]): Promise; remove(entities: any[]): Promise; diff --git a/twake/backend/node/src/core/platform/services/search/index.ts b/twake/backend/node/src/core/platform/services/search/index.ts index c339b72a..f9a90d3e 100644 --- a/twake/backend/node/src/core/platform/services/search/index.ts +++ b/twake/backend/node/src/core/platform/services/search/index.ts @@ -1,4 +1,4 @@ -import { TwakeService, logger, ServiceName, Consumes } from "../../framework"; +import { TdriveService, logger, ServiceName, Consumes } from "../../framework"; import { DatabaseEntitiesRemovedEvent, DatabaseEntitiesSavedEvent, @@ -15,7 +15,7 @@ import SearchRepository from "./repository"; @ServiceName("search") @Consumes(["database"]) -export default class Search extends TwakeService { +export default class Search extends TdriveService { version = "1"; name = "search"; service: SearchAdapterInterface; diff --git a/twake/backend/node/src/core/platform/services/storage/index.ts b/twake/backend/node/src/core/platform/services/storage/index.ts index ffc96e47..9fe35a2a 100644 --- a/twake/backend/node/src/core/platform/services/storage/index.ts +++ b/twake/backend/node/src/core/platform/services/storage/index.ts @@ -1,7 +1,7 @@ import { createCipheriv, createDecipheriv, Decipher } from "crypto"; import { Stream, Readable } from "stream"; import Multistream from "multistream"; -import { Consumes, logger, TwakeService } from "../../framework"; +import { Consumes, logger, TdriveService } from "../../framework"; import LocalConnectorService, { LocalConfiguration } from "./connectors/local/service"; import S3ConnectorService, { S3Configuration } from "./connectors/S3/service"; import StorageAPI, { @@ -17,7 +17,7 @@ type EncryptionConfiguration = { iv: string | null; }; @Consumes([]) -export default class StorageService extends TwakeService implements StorageAPI { +export default class StorageService extends TdriveService implements StorageAPI { name = "storage"; version = "1"; diff --git a/twake/backend/node/src/core/platform/services/storage/provider.ts b/twake/backend/node/src/core/platform/services/storage/provider.ts index f6149853..8a9c1d48 100644 --- a/twake/backend/node/src/core/platform/services/storage/provider.ts +++ b/twake/backend/node/src/core/platform/services/storage/provider.ts @@ -1,5 +1,5 @@ import { Stream, Readable } from "stream"; -import { TwakeServiceProvider } from "../../framework"; +import { TdriveServiceProvider } from "../../framework"; import { ExecutionContext } from "../../framework/api/crud-service"; export type WriteMetadata = { @@ -51,7 +51,7 @@ export interface StorageConnectorAPI { remove(path: string, options?: DeleteOptions, context?: ExecutionContext): Promise; } -export default interface StorageAPI extends TwakeServiceProvider, StorageConnectorAPI { +export default interface StorageAPI extends TdriveServiceProvider, StorageConnectorAPI { getConnector(): StorageConnectorAPI; getConnectorType(): string; } diff --git a/twake/backend/node/src/core/platform/services/tracker/index.ts b/twake/backend/node/src/core/platform/services/tracker/index.ts index ea8852cf..cc4cf493 100644 --- a/twake/backend/node/src/core/platform/services/tracker/index.ts +++ b/twake/backend/node/src/core/platform/services/tracker/index.ts @@ -1,6 +1,6 @@ import Segment from "./adapters/segment"; import { Analytics } from "./adapters/types"; -import { Consumes, TwakeService, logger } from "../../framework"; +import { Consumes, TdriveService, logger } from "../../framework"; import TrackerAPI from "./provider"; import { localEventBus } from "../../framework/event-bus"; import { IdentifyObjectType, TrackedEventType, TrackerConfiguration } from "./types"; @@ -8,7 +8,7 @@ import { ResourceEventsPayload } from "../../../../utils/types"; import { md5 } from "../../../../core/crypto"; @Consumes([]) -export default class Tracker extends TwakeService implements TrackerAPI { +export default class Tracker extends TdriveService implements TrackerAPI { name = "tracker"; version = "1"; analytics: Analytics; @@ -121,14 +121,14 @@ export default class Tracker extends TwakeService implements Tracker // Fixme: For now we have zero users allowing to track (value false by default and not asked during sign up) // As soon as we clearly define a way for users to choose this option we will enable this code again. - // Right now we need stats to move forward with Twake. + // Right now we need stats to move forward with Tdrive. // Note that the user that create the event will be anonymised here // if (!event.user?.allow_tracking) return; const analytics = await this.getAnalytics(); if (analytics && event) { - event.event = `twake:${event.event}`; + event.event = `tdrive:${event.event}`; analytics.track( { userId: event.user?.allow_tracking diff --git a/twake/backend/node/src/core/platform/services/tracker/provider.ts b/twake/backend/node/src/core/platform/services/tracker/provider.ts index b8a98765..d295cebe 100644 --- a/twake/backend/node/src/core/platform/services/tracker/provider.ts +++ b/twake/backend/node/src/core/platform/services/tracker/provider.ts @@ -1,7 +1,7 @@ -import { TwakeServiceProvider } from "../../framework"; +import { TdriveServiceProvider } from "../../framework"; import { IdentifyObjectType, TrackedEventType } from "./types"; -export default interface TrackerAPI extends TwakeServiceProvider { +export default interface TrackerAPI extends TdriveServiceProvider { identify(identity: IdentifyObjectType, callback?: (err: Error) => void): Promise; remove(identity: IdentifyObjectType, callback?: (err: Error) => void): Promise; track(tracker: TrackedEventType, callback?: (err: Error) => void): Promise; diff --git a/twake/backend/node/src/core/platform/services/tracker/types.ts b/twake/backend/node/src/core/platform/services/tracker/types.ts index 7256ced3..119e63ec 100644 --- a/twake/backend/node/src/core/platform/services/tracker/types.ts +++ b/twake/backend/node/src/core/platform/services/tracker/types.ts @@ -9,7 +9,7 @@ export type IdentifyObjectType = IdentityType & { }; export type TrackedEventType = IdentityType & { - // event starts with prefix `twake:` + // event starts with prefix `tdrive:` event: string; properties?: { [key: string]: unknown }; timestamp?: Date; diff --git a/twake/backend/node/src/core/platform/services/webserver/index.ts b/twake/backend/node/src/core/platform/services/webserver/index.ts index f639675a..6613c5fd 100644 --- a/twake/backend/node/src/core/platform/services/webserver/index.ts +++ b/twake/backend/node/src/core/platform/services/webserver/index.ts @@ -1,4 +1,4 @@ -import { logger, TwakeService } from "../../framework"; +import { logger, TdriveService } from "../../framework"; import { Server, IncomingMessage, ServerResponse } from "http"; import { FastifyInstance, fastify } from "fastify"; import sensible from "fastify-sensible"; @@ -14,7 +14,7 @@ import swaggerPlugin from "fastify-swagger"; import { SkipCLI } from "../../framework/decorators/skip"; import fs from "fs"; // import { throws } from "assert"; -export default class WebServerService extends TwakeService implements WebServerAPI { +export default class WebServerService extends TdriveService implements WebServerAPI { name = "webserver"; version = "1"; private server: FastifyInstance; @@ -73,12 +73,12 @@ export default class WebServerService extends TwakeService impleme routePrefix: "/internal/docs", swagger: { info: { - title: "Twake Swagger", - description: "Automatically generate Twake Swagger API", + title: "Tdrive Swagger", + description: "Automatically generate Tdrive Swagger API", version: "0.1.0", }, externalDocs: { - url: "http://linagora.github.io/Twake", + url: "http://linagora.github.io/Tdrive", description: "Find more info here", }, host: "localhost", diff --git a/twake/backend/node/src/core/platform/services/webserver/provider.ts b/twake/backend/node/src/core/platform/services/webserver/provider.ts index aa7d8b4f..b5294e80 100644 --- a/twake/backend/node/src/core/platform/services/webserver/provider.ts +++ b/twake/backend/node/src/core/platform/services/webserver/provider.ts @@ -1,8 +1,8 @@ import { Server, IncomingMessage, ServerResponse } from "http"; import { FastifyInstance } from "fastify"; -import { TwakeServiceProvider } from "../../framework/api"; +import { TdriveServiceProvider } from "../../framework/api"; -export default interface WebServerAPI extends TwakeServiceProvider { +export default interface WebServerAPI extends TdriveServiceProvider { /** * Get the fastify webserver instance */ diff --git a/twake/backend/node/src/core/platform/services/websocket/index.ts b/twake/backend/node/src/core/platform/services/websocket/index.ts index d039796f..5cce9045 100644 --- a/twake/backend/node/src/core/platform/services/websocket/index.ts +++ b/twake/backend/node/src/core/platform/services/websocket/index.ts @@ -1,4 +1,4 @@ -import { Consumes, ServiceName, TwakeService } from "../../framework"; +import { Consumes, ServiceName, TdriveService } from "../../framework"; import WebServerAPI from "../webserver/provider"; import WebSocketAPI from "./provider"; import { WebSocketService } from "./services"; @@ -7,7 +7,7 @@ import FastifyIO from "fastify-socket.io"; @Consumes(["webserver"]) @ServiceName("websocket") -export default class WebSocket extends TwakeService { +export default class WebSocket extends TdriveService { private service: WebSocketService; name = "websocket"; version = "1"; diff --git a/twake/backend/node/src/core/platform/services/websocket/provider.ts b/twake/backend/node/src/core/platform/services/websocket/provider.ts index 1306c742..0d790dfc 100644 --- a/twake/backend/node/src/core/platform/services/websocket/provider.ts +++ b/twake/backend/node/src/core/platform/services/websocket/provider.ts @@ -1,10 +1,10 @@ import { EventEmitter } from "events"; import socketIO from "socket.io"; -import { TwakeServiceProvider } from "../../framework"; +import { TdriveServiceProvider } from "../../framework"; import { User } from "../../../../utils/types"; import { WebsocketUserEvent, WebSocket, WebSocketUser } from "./types"; -export default interface WebSocketAPI extends TwakeServiceProvider, EventEmitter { +export default interface WebSocketAPI extends TdriveServiceProvider, EventEmitter { getIo(): socketIO.Server; isConnected(user: User): boolean; diff --git a/twake/backend/node/src/server.ts b/twake/backend/node/src/server.ts index ef38dee7..91a9c64c 100644 --- a/twake/backend/node/src/server.ts +++ b/twake/backend/node/src/server.ts @@ -1,7 +1,7 @@ import * as Sentry from "@sentry/node"; -import { TwakePlatform } from "./core/platform/platform"; +import { TdrivePlatform } from "./core/platform/platform"; import config from "./core/config"; -import twake from "./twake"; +import tdrive from "./tdrive"; if (config.get("sentry.dsn")) { Sentry.init({ @@ -10,7 +10,7 @@ if (config.get("sentry.dsn")) { }); } -const launch = async (): Promise => twake.run(config.get("services")); +const launch = async (): Promise => tdrive.run(config.get("services")); // noinspection JSIgnoredPromiseFromCall launch(); diff --git a/twake/backend/node/src/services/applications/entities/application.search.ts b/twake/backend/node/src/services/applications/entities/application.search.ts new file mode 100644 index 00000000..669e0245 --- /dev/null +++ b/twake/backend/node/src/services/applications/entities/application.search.ts @@ -0,0 +1,33 @@ +import Application, { TYPE } from "./application"; + +export default { + index: TYPE, + source: (entity: Application) => { + return { + company_id: entity.company_id, + name: entity.identity.name, + description: entity.identity.description, + categories: entity.identity.categories, + compatibility: entity.identity.compatibility, + published: entity.publication.published, + created_at: entity.stats.created_at, + }; + }, + mongoMapping: { + text: { + name: "text", + description: "text", + }, + }, + esMapping: { + properties: { + company_id: { type: "keyword" }, + name: { type: "text", index_prefixes: { min_chars: 1 } }, + description: { type: "text" }, + categories: { type: "keyword" }, + compatibility: { type: "keyword" }, + published: { type: "boolean" }, + created_at: { type: "number" }, + }, + }, +}; diff --git a/twake/backend/node/src/services/applications/entities/application.ts b/twake/backend/node/src/services/applications/entities/application.ts new file mode 100644 index 00000000..1cd1c793 --- /dev/null +++ b/twake/backend/node/src/services/applications/entities/application.ts @@ -0,0 +1,212 @@ +import { Type } from "class-transformer"; +import _, { merge } from "lodash"; +import { Column, Entity } from "../../../core/platform/services/database/services/orm/decorators"; +import search from "./application.search"; + +export const TYPE = "applications"; + +@Entity(TYPE, { + primaryKey: ["id"], + type: TYPE, + search, +}) +export default class Application { + @Type(() => String) + @Column("id", "timeuuid", { generator: "timeuuid" }) + id: string; + + @Type(() => String) + @Column("group_id", "timeuuid") + company_id: string; + + @Column("is_default", "boolean") + is_default: boolean; + + @Column("identity", "json") + identity: ApplicationIdentity; + + //This information is private to the application, make sure not to disclose it + @Column("api", "encoded_json") + api: ApplicationApi; + + @Column("access", "json") + access: ApplicationAccess; + + @Column("display", "json") + display: ApplicationDisplay; + + @Column("publication", "json") + publication: ApplicationPublication; + + @Column("stats", "json") + stats: ApplicationStatistics; + + getPublicObject(): PublicApplicationObject { + const i = _.pick( + this, + "id", + "company_id", + "is_default", + "identity", + "access", + "display", + "publication", + "stats", + ); + + i.is_default = !!i.is_default; + return i; + } + + getApplicationObject(): ApplicationObject { + const i = _.pick( + this, + "id", + "company_id", + "is_default", + "identity", + "access", + "display", + "publication", + "stats", + "api", + ); + + i.is_default = !!i.is_default; + return i; + } +} + +export type PublicApplicationObject = Pick< + Application, + "id" | "company_id" | "is_default" | "identity" | "access" | "display" | "publication" | "stats" +>; + +export type ApplicationObject = Pick< + Application, + | "id" + | "company_id" + | "is_default" + | "identity" + | "access" + | "display" + | "publication" + | "stats" + | "api" +>; + +export type ApplicationPrimaryKey = { id: string }; + +export function getInstance(message: Application): Application { + return merge(new Application(), message); +} + +export type ApplicationIdentity = { + code: string; + name: string; + icon: string; + description: string; + website: string; + categories: string[]; + compatibility: "tdrive"[]; + repository?: string; +}; + +export type ApplicationPublication = { + published: boolean; //Publication accepted // RO + requested: boolean; //Publication requested +}; + +export type ApplicationStatistics = { + created_at: number; // RO + updated_at: number; // RO + version: number; // RO +}; + +export type ApplicationApi = { + hooks_url: string; + allowed_ips: string; + private_key: string; // RO +}; + +type ApplicationScopes = + | "files" + | "applications" + | "workspaces" + | "users" + | "messages" + | "channels"; + +export type ApplicationAccess = { + read: ApplicationScopes[]; + write: ApplicationScopes[]; + delete: ApplicationScopes[]; + hooks: ApplicationScopes[]; +}; + +export type ApplicationDisplay = { + tdrive: { + files?: { + editor?: { + preview_url: string; //Open a preview inline (iframe) + edition_url: string; //Url to edit the file (full screen) + extensions?: string[]; //Main extensions app can read + // if file was created by the app, then the app is able to edit with or without extension + empty_files?: { + url: string; // "https://[...]/empty.docx"; + filename: string; // "Untitled.docx"; + name: string; // "Word Document"; + }[]; + }; + actions?: //List of action that can apply on a file + { + name: string; + id: string; + }[]; + }; + + //Chat plugin + chat?: { + input?: + | true + | { + icon?: string; //If defined replace original icon url of your app + type?: "file" | "call"; //To add in existing apps folder / default icon + }; + commands?: { + command: string; // my_app mycommand + description: string; + }[]; + actions?: //List of action that can apply on a message + { + name: string; + id: string; + }[]; + }; + + //Allow app to appear as a bot user in direct chat + direct?: + | true + | { + name?: string; + icon?: string; //If defined replace original icon url of your app + }; + + //Display app as a standalone application in a tab + tab?: + | { + url: string; + } + | true; + + //Display app as a standalone application on the left bar + standalone?: + | { + url: string; + } + | true; + + //Define where the app can be configured from + configuration?: ("global" | "channel")[]; + }; +}; diff --git a/twake/backend/node/src/services/applications/entities/company-application.ts b/twake/backend/node/src/services/applications/entities/company-application.ts new file mode 100644 index 00000000..e3d85e55 --- /dev/null +++ b/twake/backend/node/src/services/applications/entities/company-application.ts @@ -0,0 +1,40 @@ +import { Type } from "class-transformer"; +import { Column, Entity } from "../../../core/platform/services/database/services/orm/decorators"; +import { PublicApplicationObject } from "./application"; + +export const TYPE = "group_app"; + +@Entity(TYPE, { + primaryKey: [["group_id"], "app_id", "id"], + type: TYPE, +}) +export default class CompanyApplication { + @Type(() => String) + @Column("group_id", "timeuuid") + company_id: string; + + @Type(() => String) + @Column("app_id", "timeuuid") + application_id: string; + + @Type(() => String) + @Column("id", "timeuuid", { generator: "timeuuid" }) + id: string; + + @Column("created_at", "number") + created_at: number; + + @Type(() => String) + @Column("created_by", "string") + created_by: string; //Will be the default delegated user when doing actions on Tdrive +} + +export type CompanyApplicationPrimaryKey = Pick< + CompanyApplication, + "company_id" | "application_id" | "id" +>; + +export class CompanyApplicationWithApplication extends CompanyApplication { + //Not in database but attached to this object + application?: PublicApplicationObject; +} diff --git a/twake/backend/node/src/services/applications/index.ts b/twake/backend/node/src/services/applications/index.ts new file mode 100644 index 00000000..fd52feb1 --- /dev/null +++ b/twake/backend/node/src/services/applications/index.ts @@ -0,0 +1,24 @@ +import { Prefix, TdriveService } from "../../core/platform/framework"; +import WebServerAPI from "../../core/platform/services/webserver/provider"; +import web from "./web"; + +@Prefix("/internal/services/applications/v1") +export default class ApplicationsService extends TdriveService { + version = "1"; + name = "applications"; + + public async doInit(): Promise { + const fastify = this.context.getProvider("webserver").getServer(); + fastify.register((instance, _opts, next) => { + web(instance, { prefix: this.prefix }); + next(); + }); + + return this; + } + + // TODO: remove + api(): undefined { + return undefined; + } +} diff --git a/twake/backend/node/src/services/applications/realtime.ts b/twake/backend/node/src/services/applications/realtime.ts new file mode 100644 index 00000000..074f8a3e --- /dev/null +++ b/twake/backend/node/src/services/applications/realtime.ts @@ -0,0 +1,13 @@ +import { WebsocketMetadata } from "../../utils/types"; + +export function getCompanyApplicationRooms(companyId: string): WebsocketMetadata[] { + return [ + { + room: getCompanyApplicationRoom(companyId), + }, + ]; +} + +export function getCompanyApplicationRoom(companyApplicationId: string): string { + return `/company-application/${companyApplicationId}`; +} diff --git a/twake/backend/node/src/services/applications/services/applications.ts b/twake/backend/node/src/services/applications/services/applications.ts new file mode 100644 index 00000000..b480fd4f --- /dev/null +++ b/twake/backend/node/src/services/applications/services/applications.ts @@ -0,0 +1,140 @@ +import Application, { + ApplicationPrimaryKey, + getInstance as getApplicationInstance, + PublicApplicationObject, + TYPE, +} from "../entities/application"; +import Repository from "../../../core/platform/services/database/services/orm/repository/repository"; +import { Initializable, logger, TdriveServiceProvider } from "../../../core/platform/framework"; +import { + DeleteResult, + ExecutionContext, + ListResult, + OperationType, + Pagination, + SaveResult, +} from "../../../core/platform/framework/api/crud-service"; +import SearchRepository from "../../../core/platform/services/search/repository"; +import assert from "assert"; + +import gr from "../../global-resolver"; + +export class ApplicationServiceImpl implements TdriveServiceProvider, Initializable { + version: "1"; + repository: Repository; + searchRepository: SearchRepository; + + async init(): Promise { + try { + this.searchRepository = gr.platformServices.search.getRepository( + TYPE, + Application, + ); + this.repository = await gr.database.getRepository(TYPE, Application); + } catch (err) { + console.log(err); + logger.error("Error while initializing applications service"); + } + + return this; + } + + async get(pk: ApplicationPrimaryKey, context: ExecutionContext): Promise { + return await this.repository.findOne(pk, {}, context); + } + + async list( + pagination: Pagination, + options?: { search?: string }, + context?: ExecutionContext, + ): Promise> { + let entities: ListResult; + if (options.search) { + entities = await this.searchRepository.search( + {}, + { + pagination, + $text: { + $search: options.search, + }, + }, + context, + ); + } else { + entities = await this.repository.find({}, { pagination }, context); + } + entities.filterEntities(app => app.publication.published); + + const applications = entities + .getEntities() + .filter(app => app) + .map(app => app.getPublicObject()); + return new ListResult(entities.type, applications, entities.nextPage); + } + + async listUnpublished(context: ExecutionContext): Promise { + const entities = await this.repository.find({}, {}, context); + entities.filterEntities(app => !app.publication.published); + return entities.getEntities(); + } + + async listDefaults(context: ExecutionContext): Promise> { + const entities = []; + + let page: Pagination = { limitStr: "100" }; + do { + const applicationListResult = await this.repository.find({}, { pagination: page }, context); + page = applicationListResult.nextPage as Pagination; + applicationListResult.filterEntities(app => app.publication.published && app.is_default); + + for (const application of applicationListResult.getEntities()) { + if (application) entities.push(application.getPublicObject()); + } + } while (page.page_token); + + return new ListResult(TYPE, entities); + } + + async save( + item: Application, + options?: SaveOptions, + context?: ExecutionContext, + ): Promise> { + assert(item.company_id, "company_id is not defined"); + + try { + const entity = getApplicationInstance(item); + await this.repository.save(entity, context); + return new SaveResult("application", entity, OperationType.UPDATE); + } catch (e) { + throw e; + } + } + + async delete( + pk: ApplicationPrimaryKey, + context?: ExecutionContext, + ): Promise> { + const entity = await this.get(pk, context); + await this.repository.remove(entity, context); + return new DeleteResult("application", entity, true); + } + + async publish(pk: ApplicationPrimaryKey, context: ExecutionContext): Promise { + const entity = await this.get(pk, context); + if (!entity) { + throw new Error("Entity not found"); + } + entity.publication.published = true; + await this.repository.save(entity, context); + } + + async unpublish(pk: ApplicationPrimaryKey, context: ExecutionContext): Promise { + const entity = await this.get(pk, context); + if (!entity) { + throw new Error("Entity not found"); + } + entity.publication.published = false; + await this.repository.save(entity, context); + } +} diff --git a/twake/backend/node/src/services/applications/services/company-applications.ts b/twake/backend/node/src/services/applications/services/company-applications.ts new file mode 100644 index 00000000..4df059ec --- /dev/null +++ b/twake/backend/node/src/services/applications/services/company-applications.ts @@ -0,0 +1,188 @@ +import CompanyApplication, { + CompanyApplicationPrimaryKey, + CompanyApplicationWithApplication, + TYPE, +} from "../entities/company-application"; +import Repository from "../../../core/platform/services/database/services/orm/repository/repository"; +import { + Initializable, + logger, + RealtimeDeleted, + RealtimeSaved, + TdriveServiceProvider, +} from "../../../core/platform/framework"; +import { + DeleteResult, + ListResult, + OperationType, + Paginable, + Pagination, + SaveResult, +} from "../../../core/platform/framework/api/crud-service"; +import { CompanyExecutionContext } from "../web/types"; +import { getCompanyApplicationRoom } from "../realtime"; +import gr from "../../global-resolver"; + +export class CompanyApplicationServiceImpl implements TdriveServiceProvider, Initializable { + version: "1"; + repository: Repository; + + async init(): Promise { + try { + this.repository = await gr.database.getRepository( + TYPE, + CompanyApplication, + ); + } catch (err) { + console.log(err); + logger.error("Error while initializing applications service"); + } + return this; + } + + // TODO: remove logic from context + async get( + pk: Pick & { id?: string }, + context?: CompanyExecutionContext, + ): Promise { + const companyApplication = await this.repository.findOne( + { + group_id: context ? context.company.id : pk.company_id, + app_id: pk.application_id, + }, + {}, + context, + ); + + const application = await gr.services.applications.marketplaceApps.get( + { + id: pk.application_id, + }, + context, + ); + + return { + ...companyApplication, + application: application, + }; + } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + @RealtimeSaved((companyApplication, _context) => { + return [ + { + room: getCompanyApplicationRoom(companyApplication.id), + resource: companyApplication, + }, + ]; + }) + async save( + item: Pick, + _?: SaveOptions, + context?: CompanyExecutionContext, + ): Promise> { + if (!context?.user?.id && !context?.user?.server_request) { + throw new Error("Only an user of a company can add an application to a company."); + } + + let operation = OperationType.UPDATE; + let companyApplication = await this.repository.findOne( + { + group_id: context?.company.id, + app_id: item.application_id, + }, + {}, + context, + ); + if (!companyApplication) { + operation = OperationType.CREATE; + + companyApplication = new CompanyApplication(); + companyApplication.company_id = context.company.id; + companyApplication.application_id = item.application_id; + companyApplication.created_at = new Date().getTime(); + companyApplication.created_by = context?.user?.id || ""; + + await this.repository.save(companyApplication, context); + } + + return new SaveResult(TYPE, companyApplication, operation); + } + + async initWithDefaultApplications( + companyId: string, + context: CompanyExecutionContext, + ): Promise { + const defaultApps = await gr.services.applications.marketplaceApps.listDefaults(context); + for (const defaultApp of defaultApps.getEntities()) { + await this.save({ company_id: companyId, application_id: defaultApp.id }, {}, context); + } + } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + @RealtimeDeleted((companyApplication, _context) => { + return [ + { + room: getCompanyApplicationRoom(companyApplication.id), + resource: companyApplication, + }, + ]; + }) + async delete( + pk: CompanyApplicationPrimaryKey, + context?: CompanyExecutionContext, + ): Promise> { + const companyApplication = await this.repository.findOne( + { + group_id: context.company.id, + app_id: pk.application_id, + }, + {}, + context, + ); + + let deleted = false; + if (companyApplication) { + this.repository.remove(companyApplication, context); + deleted = true; + } + + return new DeleteResult(TYPE, companyApplication, deleted); + } + + async list( + pagination: Paginable, + options?: ListOptions, + context?: CompanyExecutionContext, + ): Promise> { + const companyApplications = await this.repository.find( + { + group_id: context.company.id, + }, + { pagination: Pagination.fromPaginable(pagination) }, + context, + ); + + const applications = []; + + for (const companyApplication of companyApplications.getEntities()) { + const application = await gr.services.applications.marketplaceApps.get( + { + id: companyApplication.application_id, + }, + context, + ); + if (application) + applications.push({ + ...companyApplication, + application: application, + }); + } + + return new ListResult( + TYPE, + applications, + companyApplications.nextPage, + ); + } +} diff --git a/twake/backend/node/src/services/applications/services/hooks.ts b/twake/backend/node/src/services/applications/services/hooks.ts new file mode 100644 index 00000000..036d7157 --- /dev/null +++ b/twake/backend/node/src/services/applications/services/hooks.ts @@ -0,0 +1,96 @@ +import Application from "../entities/application"; +import Repository from "../../../core/platform/services/database/services/orm/repository/repository"; +import { + Initializable, + logger as log, + TdriveServiceProvider, +} from "../../../core/platform/framework"; +import { CrudException, ExecutionContext } from "../../../core/platform/framework/api/crud-service"; +import SearchRepository from "../../../core/platform/services/search/repository"; +import axios from "axios"; +import * as crypto from "crypto"; +import { isObject } from "lodash"; +import gr from "../../global-resolver"; + +export class ApplicationHooksService implements TdriveServiceProvider, Initializable { + version: "1"; + repository: Repository; + searchRepository: SearchRepository; + + async init() { + return this; + } + + async notifyApp( + application_id: string, + connection_id: string, + user_id: string, + type: string, + name: string, + content: any, + company_id: string, + workspace_id: string, + context: ExecutionContext, + ): Promise { + const app = await gr.services.applications.marketplaceApps.get({ id: application_id }, context); + if (!app) { + throw CrudException.notFound("Application not found"); + } + + if (!app.api.hooks_url) { + throw CrudException.badRequest("Application hooks_url is not defined"); + } + + const payload = { + type, + name, + content, + connection_id: connection_id, + user_id: user_id, + company_id, + workspace_id, + }; + + const signature = crypto + .createHmac("sha256", app.api.private_key) + .update(JSON.stringify(payload)) + .digest("hex"); + + return await axios + .post(app.api.hooks_url, payload, { + headers: { + "Content-Type": "application/json", + "X-Tdrive-Signature": signature, + }, + }) + + .then(({ data }) => data) + .catch(e => { + log.error(e.message); + const r = e.response; + + if (!r) { + throw CrudException.badGateway("Can't connect remote application"); + } + + let msg = r.data; + + if (isObject(msg)) { + // parse typical responses + if (r.data.message) { + msg = r.data.message; + } else if (r.data.error) { + msg = r.data.error; + } else { + msg = JSON.stringify(r.data); + } + } + + if (r.status == 403) { + throw CrudException.forbidden(msg); + } else { + throw CrudException.badRequest(msg); + } + }); + } +} diff --git a/twake/backend/node/src/services/applications/web/controllers/applications.ts b/twake/backend/node/src/services/applications/web/controllers/applications.ts new file mode 100644 index 00000000..11cbaa2d --- /dev/null +++ b/twake/backend/node/src/services/applications/web/controllers/applications.ts @@ -0,0 +1,296 @@ +import { FastifyReply, FastifyRequest } from "fastify"; +import { CrudController } from "../../../../core/platform/services/webserver/types"; +import { + PaginationQueryParameters, + ResourceCreateResponse, + ResourceDeleteResponse, + ResourceGetResponse, + ResourceListResponse, + ResourceUpdateResponse, +} from "../../../../utils/types"; +import Application, { + ApplicationObject, + PublicApplicationObject, +} from "../../entities/application"; +import { + CrudException, + ExecutionContext, + Pagination, +} from "../../../../core/platform/framework/api/crud-service"; +import _ from "lodash"; +import { randomBytes } from "crypto"; +import { ApplicationEventRequestBody } from "../types"; +import { logger as log } from "../../../../core/platform/framework"; +import { hasCompanyAdminLevel } from "../../../../utils/company"; +import gr from "../../../global-resolver"; +import config from "../../../../core/config"; +import axios from "axios"; + +export class ApplicationController + implements + CrudController< + ResourceGetResponse, + ResourceUpdateResponse, + ResourceListResponse, + ResourceDeleteResponse + > +{ + async get( + request: FastifyRequest<{ Params: { application_id: string } }>, + ): Promise> { + const context = getExecutionContext(request); + + const entity = await gr.services.applications.marketplaceApps.get( + { + id: request.params.application_id, + }, + context, + ); + + const companyUser = await gr.services.companies.getCompanyUser( + { id: entity.company_id }, + { id: context.user.id }, + ); + + const isAdmin = companyUser && companyUser.role == "admin"; + + return { + resource: isAdmin ? entity.getApplicationObject() : entity.getPublicObject(), + }; + } + + async list( + request: FastifyRequest<{ + Querystring: PaginationQueryParameters & { search: string }; + }>, + ): Promise> { + const entities = await gr.services.applications.marketplaceApps.list(new Pagination(), { + search: request.query.search, + }); + return { + resources: entities.getEntities(), + next_page_token: entities.nextPage.page_token, + }; + } + + async save( + request: FastifyRequest<{ + Params: { application_id: string }; + Body: { resource: Application }; + }>, + _reply: FastifyReply, + ): Promise> { + const context = getExecutionContext(request); + + try { + const app = request.body.resource; + const now = new Date().getTime(); + const pluginsEndpoint = config.get("plugins.api"); + + let entity: Application; + + if (request.params.application_id) { + entity = await gr.services.applications.marketplaceApps.get( + { + id: request.params.application_id, + }, + context, + ); + + if (!entity) { + throw CrudException.notFound("Application not found"); + } + + entity.publication.requested = app.publication.requested; + if (app.publication.requested === false) { + entity.publication.published = false; + } + + if (entity.publication.published) { + if ( + !_.isEqual( + _.pick(entity, "identity", "api", "access", "display"), + _.pick(app, "identity", "api", "access", "display"), + ) + ) { + throw CrudException.badRequest( + "You can't update applications details while it published", + ); + } + } + + entity.identity = app.identity; + entity.api.hooks_url = app.api.hooks_url; + entity.api.allowed_ips = app.api.allowed_ips; + entity.access = app.access; + entity.display = app.display; + + entity.stats.updated_at = now; + entity.stats.version++; + + const res = await gr.services.applications.marketplaceApps.save(entity); + entity = res.entity; + } else { + // INSERT + + app.is_default = false; + app.publication.published = false; + app.api.private_key = randomBytes(32).toString("base64"); + + app.stats = { + created_at: now, + updated_at: now, + version: 0, + }; + + const res = await gr.services.applications.marketplaceApps.save(app); + entity = res.entity; + } + + // SYNC PLUGINS + if (app.identity.repository) { + try { + axios + .post( + `${pluginsEndpoint}/add`, + { + gitRepo: app.identity.repository, + pluginId: entity.getApplicationObject().id, + pluginSecret: entity.getApplicationObject().api.private_key, + }, + { + headers: { + "Content-Type": "application/json", + }, + }, + ) + .then(response => { + log.info(response.data); + }) + .catch(error => { + log.error(error); + }); + } catch (error) { + console.error(error); + } + } + + return { + resource: entity.getApplicationObject(), + }; + } catch (e) { + log.error(e); + throw e; + } + } + + async delete( + request: FastifyRequest<{ Params: { application_id: string } }>, + reply: FastifyReply, + ): Promise { + const context = getExecutionContext(request); + + const application = await gr.services.applications.marketplaceApps.get( + { + id: request.params.application_id, + }, + context, + ); + + const compUser = await gr.services.companies.getCompanyUser( + { id: application.company_id }, + { id: context.user.id }, + ); + if (!compUser || !hasCompanyAdminLevel(compUser.role)) { + throw CrudException.forbidden("You don't have the rights to delete this application"); + } + + const deleteResult = await gr.services.applications.marketplaceApps.delete( + { + id: request.params.application_id, + }, + context, + ); + + if (deleteResult.deleted) { + reply.code(204); + + return { + status: "success", + }; + } + + return { + status: "error", + }; + } + + async event( + request: FastifyRequest<{ + Body: ApplicationEventRequestBody; + Params: { application_id: string }; + }>, + _reply: FastifyReply, + ): Promise> { + const context = getExecutionContext(request); + + const content = request.body.data; + + const applicationEntity = await gr.services.applications.marketplaceApps.get( + { + id: request.params.application_id, + }, + context, + ); + + if (!applicationEntity) { + throw CrudException.notFound("Application not found"); + } + + const companyUser = gr.services.companies.getCompanyUser( + { id: request.body.company_id }, + { id: context.user.id }, + ); + + if (!companyUser) { + throw CrudException.badRequest( + "You cannot send event to an application from another company", + ); + } + + const applicationInCompany = await gr.services.applications.companyApps.get({ + company_id: request.body.company_id, + application_id: request.params.application_id, + id: undefined, + }); + + if (!applicationInCompany) { + throw CrudException.badRequest("Application isn't installed in this company"); + } + + const hookResponse = await gr.services.applications.hooks.notifyApp( + request.params.application_id, + request.body.connection_id, + context.user.id, + request.body.type, + request.body.name, + content, + request.body.company_id, + request.body.workspace_id, + context, + ); + + return { + resource: hookResponse, + }; + } +} + +function getExecutionContext(request: FastifyRequest): ExecutionContext { + return { + user: request.currentUser, + url: request.url, + method: request.routerMethod, + transport: "http", + }; +} diff --git a/twake/backend/node/src/services/applications/web/controllers/company-applications.ts b/twake/backend/node/src/services/applications/web/controllers/company-applications.ts new file mode 100644 index 00000000..26542e39 --- /dev/null +++ b/twake/backend/node/src/services/applications/web/controllers/company-applications.ts @@ -0,0 +1,119 @@ +import { FastifyReply, FastifyRequest } from "fastify"; + +import { + PaginationQueryParameters, + ResourceDeleteResponse, + ResourceGetResponse, + ResourceListResponse, + ResourceUpdateResponse, +} from "../../../../utils/types"; +import { PublicApplicationObject } from "../../entities/application"; +import { CompanyExecutionContext } from "../types"; +import { CrudController } from "../../../../core/platform/services/webserver/types"; +import { getCompanyApplicationRooms } from "../../realtime"; +import gr from "../../../global-resolver"; + +export class CompanyApplicationController + implements + CrudController< + ResourceGetResponse, + ResourceUpdateResponse, + ResourceListResponse, + ResourceDeleteResponse + > +{ + async get( + request: FastifyRequest<{ Params: { company_id: string; application_id: string } }>, + ): Promise> { + const context = getCompanyExecutionContext(request); + const resource = await gr.services.applications.companyApps.get( + { + application_id: request.params.application_id, + company_id: context.company.id, + id: undefined, + }, + context, + ); + return { + resource: resource?.application, + }; + } + + async list( + request: FastifyRequest<{ + Params: { company_id: string }; + Querystring: PaginationQueryParameters & { search: string }; + }>, + ): Promise> { + const context = getCompanyExecutionContext(request); + const resources = await gr.services.applications.companyApps.list( + request.query, + { search: request.query.search }, + context, + ); + + return { + resources: resources.getEntities().map(ca => ca.application), + next_page_token: resources.nextPage.page_token, + websockets: + gr.platformServices.realtime.sign( + getCompanyApplicationRooms(request.params.company_id), + context.user.id, + ) || [], + }; + } + + async save( + request: FastifyRequest<{ + Params: { company_id: string; application_id: string }; + Body: PublicApplicationObject; + }>, + ): Promise> { + const context = getCompanyExecutionContext(request); + + const resource = await gr.services.applications.companyApps.save( + { application_id: request.params.application_id, company_id: context.company.id }, + {}, + context, + ); + + const app = await gr.services.applications.companyApps.get(resource.entity); + + return { + resource: app.application, + }; + } + + async delete( + request: FastifyRequest<{ Params: { company_id: string; application_id: string } }>, + _reply: FastifyReply, + ): Promise { + const context = getCompanyExecutionContext(request); + const resource = await gr.services.applications.companyApps.delete( + { + application_id: request.params.application_id, + company_id: context.company.id, + id: undefined, + }, + context, + ); + return { + status: resource.deleted ? "success" : "error", + }; + } +} + +function getCompanyExecutionContext( + request: FastifyRequest<{ + Params: { company_id: string }; + }>, +): CompanyExecutionContext { + return { + user: request.currentUser, + company: { id: request.params.company_id }, + url: request.url, + method: request.routerMethod, + reqId: request.id, + transport: "http", + }; +} diff --git a/twake/backend/node/src/services/applications/web/controllers/index.ts b/twake/backend/node/src/services/applications/web/controllers/index.ts new file mode 100644 index 00000000..ef52722d --- /dev/null +++ b/twake/backend/node/src/services/applications/web/controllers/index.ts @@ -0,0 +1 @@ +export * from "./applications"; diff --git a/twake/backend/node/src/services/applications/web/index.ts b/twake/backend/node/src/services/applications/web/index.ts new file mode 100644 index 00000000..3c2df979 --- /dev/null +++ b/twake/backend/node/src/services/applications/web/index.ts @@ -0,0 +1,12 @@ +import { FastifyInstance, FastifyRegisterOptions } from "fastify"; +import routes from "./routes"; + +export default ( + fastify: FastifyInstance, + options: FastifyRegisterOptions<{ + prefix: string; + }>, +): void => { + fastify.log.debug("Configuring /internal/services/applications/v1 routes"); + fastify.register(routes, options); +}; diff --git a/twake/backend/node/src/services/applications/web/routes.ts b/twake/backend/node/src/services/applications/web/routes.ts new file mode 100644 index 00000000..3d5835c7 --- /dev/null +++ b/twake/backend/node/src/services/applications/web/routes.ts @@ -0,0 +1,161 @@ +import { FastifyInstance, FastifyPluginCallback, FastifyRequest } from "fastify"; +import { ApplicationController } from "./controllers/applications"; +import { CompanyApplicationController } from "./controllers/company-applications"; + +import Application from "../entities/application"; +import { applicationEventHookSchema, applicationPostSchema } from "./schemas"; +import { logger as log } from "../../../core/platform/framework"; +import { checkUserBelongsToCompany, hasCompanyAdminLevel } from "../../../utils/company"; +import gr from "../../global-resolver"; + +const applicationsUrl = "/applications"; +const companyApplicationsUrl = "/companies/:company_id/applications"; + +const routes: FastifyPluginCallback = (fastify: FastifyInstance, options, next) => { + const applicationController = new ApplicationController(); + const companyApplicationController = new CompanyApplicationController(); + + const adminCheck = async ( + request: FastifyRequest<{ + Body: { resource: Application }; + Params: { application_id: string }; + }>, + ) => { + try { + let companyId: string = request.body?.resource?.company_id; + + if (request.params.application_id) { + const application = await gr.services.applications.marketplaceApps.get( + { + id: request.params.application_id, + }, + undefined, + ); + + if (!application) { + throw fastify.httpErrors.notFound("Application is not defined"); + } + + companyId = application.company_id; + } + + const userId = request.currentUser.id; + + if (!companyId) { + throw fastify.httpErrors.forbidden(`Company ${companyId} not found`); + } + + const companyUser = await checkUserBelongsToCompany(userId, companyId); + + if (!hasCompanyAdminLevel(companyUser.role)) { + throw fastify.httpErrors.forbidden("You must be an admin of this company"); + } + } catch (e) { + log.error(e); + throw e; + } + }; + + /** + * Applications collection + * Marketplace of applications + */ + + //Get and search list of applications in the marketplace + fastify.route({ + method: "GET", + url: `${applicationsUrl}`, + preValidation: [fastify.authenticate], + // schema: applicationGetSchema, + handler: applicationController.list.bind(applicationController), + }); + + //Get a single application in the marketplace + fastify.route({ + method: "GET", + url: `${applicationsUrl}/:application_id`, + preValidation: [fastify.authenticate], + // schema: applicationGetSchema, + handler: applicationController.get.bind(applicationController), + }); + + //Create application (must be my company application and I must be company admin) + fastify.route({ + method: "POST", + url: `${applicationsUrl}`, + preHandler: [adminCheck], + preValidation: [fastify.authenticate], + schema: applicationPostSchema, + handler: applicationController.save.bind(applicationController), + }); + + //Edit application (must be my company application and I must be company admin) + fastify.route({ + method: "POST", + url: `${applicationsUrl}/:application_id`, + preHandler: [adminCheck], + preValidation: [fastify.authenticate], + schema: applicationPostSchema, + handler: applicationController.save.bind(applicationController), + }); + + // Delete application (must be my company application and I must be company admin) + fastify.route({ + method: "DELETE", + url: `${applicationsUrl}/:application_id`, + preHandler: [adminCheck], + preValidation: [fastify.authenticate], + handler: applicationController.delete.bind(applicationController), + }); + + /** + * Company applications collection + * Company-wide available applications + * (must be my company application and I must be company admin) + */ + + //Get list of applications for a company + fastify.route({ + method: "GET", + url: `${companyApplicationsUrl}`, + preValidation: [fastify.authenticate], + handler: companyApplicationController.list.bind(companyApplicationController), + }); + + //Get one application of a company + fastify.route({ + method: "GET", + url: `${companyApplicationsUrl}/:application_id`, + preValidation: [fastify.authenticate], + handler: companyApplicationController.get.bind(companyApplicationController), + }); + + //Remove an application from a company + fastify.route({ + method: "DELETE", + url: `${companyApplicationsUrl}/:application_id`, + preValidation: [fastify.authenticate], + handler: companyApplicationController.delete.bind(companyApplicationController), + }); + + //Add an application to the company + fastify.route({ + method: "POST", + url: `${companyApplicationsUrl}/:application_id`, + preValidation: [fastify.authenticate], + handler: companyApplicationController.save.bind(companyApplicationController), + }); + + //Application event triggered by a user + fastify.route({ + method: "POST", + url: `${applicationsUrl}/:application_id/event`, + preValidation: [fastify.authenticate], + schema: applicationEventHookSchema, + handler: applicationController.event.bind(applicationController), + }); + + next(); +}; + +export default routes; diff --git a/twake/backend/node/src/services/applications/web/schemas.ts b/twake/backend/node/src/services/applications/web/schemas.ts new file mode 100644 index 00000000..996cea70 --- /dev/null +++ b/twake/backend/node/src/services/applications/web/schemas.ts @@ -0,0 +1,129 @@ +export const applicationsSchema = { + type: "object", + properties: {}, +}; + +const applicationIdentity = { + type: "object", + properties: { + code: { type: "string" }, + name: { type: "string" }, + icon: { type: "string" }, + description: { type: "string" }, + website: { type: "string" }, + categories: { type: "array", items: { type: "string" } }, + compatibility: { type: "array", items: { type: "string" } }, + }, + required: ["code", "name", "icon", "description", "website", "categories", "compatibility"], +}; + +const applicationAccess = { + type: "object", + properties: { + read: { type: "array", items: { type: "string" } }, + write: { type: "array", items: { type: "string" } }, + delete: { type: "array", items: { type: "string" } }, + hooks: { type: "array", items: { type: "string" } }, + }, + required: ["read", "write", "delete", "hooks"], +}; + +const requestApplicationPublication = { + type: "object", + properties: { + requested: { type: "boolean" }, + }, + required: ["requested"], +}; + +const responseApplicationPublication = { + type: "object", + properties: { + published: { type: "boolean" }, + requested: { type: "boolean" }, + }, + required: ["requested", "published"], +}; + +const applicationStats = { + type: "object", + properties: { + created_at: { type: "number" }, + updated_at: { type: "number" }, + version: { type: "number" }, + }, + required: ["created_at", "updated_at", "version"], +}; + +const apiObject = { + type: "object", + properties: { + hooks_url: { type: "string" }, + allowed_ips: { type: "string" }, + private_key: { type: "string" }, + }, + required: ["hooks_url", "allowed_ips"], +}; + +const requestApplicationObject = { + type: "object", + properties: { + company_id: { type: "string" }, + identity: applicationIdentity, + access: applicationAccess, + display: {}, + api: apiObject, + publication: requestApplicationPublication, + }, + required: ["company_id", "identity", "access", "display", "api", "publication"], + additionalProperties: false, +}; + +const responseApplicationObject = { + type: "object", + properties: { + id: { type: "string" }, + is_default: { type: "boolean" }, + company_id: { type: "string" }, + identity: applicationIdentity, + access: applicationAccess, + display: {}, + publication: responseApplicationPublication, + api: apiObject, + stats: applicationStats, + }, + required: [ + "id", + "is_default", + "company_id", + "identity", + "access", + "display", + "publication", + "stats", + ], + additionalProperties: false, +}; + +export const applicationPostSchema = { + body: { type: "object", properties: { resource: requestApplicationObject } }, + response: { + "2xx": { + resource: responseApplicationObject, + }, + }, +}; + +export const applicationEventHookSchema = { + body: { + type: "object", + properties: { + company_id: { type: "string" }, + workspace_id: { type: "string" }, + type: { type: "string" }, + name: { type: "string" }, + content: {}, + }, + required: ["company_id", "workspace_id", "type", "content"], + }, +}; diff --git a/twake/backend/node/src/services/applications/web/types.ts b/twake/backend/node/src/services/applications/web/types.ts new file mode 100644 index 00000000..5a60f3b3 --- /dev/null +++ b/twake/backend/node/src/services/applications/web/types.ts @@ -0,0 +1,15 @@ +import { ExecutionContext } from "../../../core/platform/framework/api/crud-service"; + +export interface CompanyExecutionContext extends ExecutionContext { + company: { id: string }; +} + +export interface ApplicationEventRequestBody { + company_id: string; + workspace_id: string; + connection_id: string; + type: string; + name?: string; + content: any; + data: any; +} diff --git a/twake/backend/node/src/services/channels/index.ts b/twake/backend/node/src/services/channels/index.ts index 1aec35f8..e9ad5571 100644 --- a/twake/backend/node/src/services/channels/index.ts +++ b/twake/backend/node/src/services/channels/index.ts @@ -1,9 +1,9 @@ -import { Prefix, TwakeService } from "../../core/platform/framework"; +import { Prefix, TdriveService } from "../../core/platform/framework"; import WebServerAPI from "../../core/platform/services/webserver/provider"; import web from "./web"; @Prefix("/internal/services/channels/v1") -export default class ChannelService extends TwakeService { +export default class ChannelService extends TdriveService { version = "1"; name = "channels"; diff --git a/twake/backend/node/src/services/channels/services/member/service.ts b/twake/backend/node/src/services/channels/services/member/service.ts index 014f19ce..f16aadbd 100644 --- a/twake/backend/node/src/services/channels/services/member/service.ts +++ b/twake/backend/node/src/services/channels/services/member/service.ts @@ -26,7 +26,6 @@ import { ChannelMemberType, ChannelVisibility, WorkspaceExecutionContext, - CompanyExecutionContext, } from "../../types"; import { Channel, ResourceEventsPayload, User } from "../../../../utils/types"; import { cloneDeep, isNil, omitBy } from "lodash"; @@ -53,7 +52,7 @@ import { WorkspacePrimaryKey } from "../../../workspaces/entities/workspace"; import gr from "../../../global-resolver"; import uuidTime from "uuid-time"; import { ChannelObject } from "../channel/types"; - +import { CompanyExecutionContext } from "../../../applications/web/types"; const USER_CHANNEL_KEYS = [ "id", "company_id", diff --git a/twake/backend/node/src/services/channels/types.ts b/twake/backend/node/src/services/channels/types.ts index 0b9e4a28..20894579 100644 --- a/twake/backend/node/src/services/channels/types.ts +++ b/twake/backend/node/src/services/channels/types.ts @@ -52,7 +52,3 @@ export type ChannelActivityNotification = { sender_name: string; body: string; }; - -export interface CompanyExecutionContext extends ExecutionContext { - company: { id: string }; -} diff --git a/twake/backend/node/src/services/console/client-interface.ts b/twake/backend/node/src/services/console/client-interface.ts index af2d4eae..440147b3 100644 --- a/twake/backend/node/src/services/console/client-interface.ts +++ b/twake/backend/node/src/services/console/client-interface.ts @@ -31,11 +31,11 @@ export interface ConsoleServiceClient { addUserToCompany(company: ConsoleCompany, user: CreateConsoleUser): Promise; /** - * Add user to twake in general (for non-console version) + * Add user to tdrive in general (for non-console version) * * @param user */ - addUserToTwake(user: CreateInternalUser): Promise; + addUserToTdrive(user: CreateInternalUser): Promise; /** * Update user role diff --git a/twake/backend/node/src/services/console/clients/internal.ts b/twake/backend/node/src/services/console/clients/internal.ts index ade2763d..ccbbfed9 100644 --- a/twake/backend/node/src/services/console/clients/internal.ts +++ b/twake/backend/node/src/services/console/clients/internal.ts @@ -49,8 +49,8 @@ export class ConsoleInternalClient implements ConsoleServiceClient { throw Error("ConsoleInternalClient.createCompany is not implemented"); } - async addUserToTwake(user: CreateConsoleUser): Promise { - logger.info("Internal: addUserToTwake"); + async addUserToTdrive(user: CreateConsoleUser): Promise { + logger.info("Internal: addUserToTdrive"); const userToCreate = getUserInstance({ id: uuidv1(), email_canonical: user.email, diff --git a/twake/backend/node/src/services/console/clients/remote.ts b/twake/backend/node/src/services/console/clients/remote.ts index 78db34b1..79e715cf 100644 --- a/twake/backend/node/src/services/console/clients/remote.ts +++ b/twake/backend/node/src/services/console/clients/remote.ts @@ -37,16 +37,17 @@ export class ConsoleRemoteClient implements ConsoleServiceClient { issuer: this.infos.issuer?.replace(/\/+$/, ""), jwksUri: this.infos.jwks_uri, // For local deployment create a https agent that ignore self signed certificate + // eslint-disable-next-line @typescript-eslint/no-var-requires requestAgent: new (require("https").Agent)({ rejectUnauthorized: this.infos.issuer.includes("example.com") ? false : true, }), }); } fetchCompanyInfo(consoleCompanyCode: string): Promise { - throw new Error("Method not implemented."); + throw new Error(`Method not implemented, ${consoleCompanyCode}.`); } resendVerificationEmail(email: string): Promise { - throw new Error("Method not implemented."); + throw new Error(`Method not implemented, ${email}.`); } private auth() { @@ -57,6 +58,7 @@ export class ConsoleRemoteClient implements ConsoleServiceClient { company: ConsoleCompany, user: CreateConsoleUser, ): Promise { + logger.info(`Method not implemented, ${company.id}, ${user.id}.`); return null; } @@ -65,22 +67,25 @@ export class ConsoleRemoteClient implements ConsoleServiceClient { user: UpdateConsoleUserRole, ): Promise { logger.info("Remote: updateUserRole"); + logger.info(`Method not implemented, ${company.id}, ${user.id}.`); return null; } async createCompany(company: CreateConsoleCompany): Promise { logger.info("Remote: createCompany"); + logger.info(`Method not implemented, ${company}.`); return null; } // eslint-disable-next-line @typescript-eslint/no-unused-vars - addUserToTwake(user: CreateConsoleUser): Promise { - logger.info("Remote: addUserToTwake"); + addUserToTdrive(user: CreateConsoleUser): Promise { + logger.info("Remote: addUserToTdrive"); //should do noting for real console return Promise.resolve(undefined); } async updateLocalCompanyFromConsole(partialCompanyDTO: ConsoleHookCompany): Promise { + logger.info(`Method not implemented, ${partialCompanyDTO}.`); return null; } @@ -92,9 +97,12 @@ export class ConsoleRemoteClient implements ConsoleServiceClient { } const roles = userDTO.roles.filter( - role => role.applications === undefined || role.applications.find(a => a.code === "twake"), + role => role.applications === undefined || role.applications.find(a => a.code === "tdrive"), ); + //REMOVE LATER + logger.info(`Roles are: ${roles}.`); + let user = await gr.services.users.getByConsoleId(userDTO.email); if (!user) { @@ -153,7 +161,7 @@ export class ConsoleRemoteClient implements ConsoleServiceClient { company = await gr.services.companies.createCompany( getCompanyInstance({ id: "00000000-0000-4000-0000-000000000000", - name: "Twake", + name: "Tdrive", plan: { name: "Local", limits: undefined, features: undefined }, }), ); @@ -182,7 +190,7 @@ export class ConsoleRemoteClient implements ConsoleServiceClient { const user = await gr.services.users.getByConsoleId(consoleUserId); if (!user) { - throw new Error("User does not exists on Twake."); + throw new Error("User does not exists on Tdrive."); } await gr.services.users.anonymizeAndDelete( diff --git a/twake/backend/node/src/services/console/index.ts b/twake/backend/node/src/services/console/index.ts index 43eac0d2..84ee1c14 100644 --- a/twake/backend/node/src/services/console/index.ts +++ b/twake/backend/node/src/services/console/index.ts @@ -1,9 +1,9 @@ -import { Prefix, TwakeService } from "../../core/platform/framework"; +import { Prefix, TdriveService } from "../../core/platform/framework"; import WebServerAPI from "../../core/platform/services/webserver/provider"; import web from "./web"; @Prefix("/internal/services/console/v1") -export default class ConsoleService extends TwakeService { +export default class ConsoleService extends TdriveService { version = "1"; name = "console"; diff --git a/twake/backend/node/src/services/console/service.ts b/twake/backend/node/src/services/console/service.ts index afd60e08..c8c9342a 100644 --- a/twake/backend/node/src/services/console/service.ts +++ b/twake/backend/node/src/services/console/service.ts @@ -4,11 +4,11 @@ import { ConsoleServiceClient } from "./client-interface"; import { ConsoleClientFactory } from "./client-factory"; import User from "../user/entities/user"; import gr from "../global-resolver"; -import { Configuration, TwakeServiceProvider } from "../../core/platform/framework"; +import { Configuration, TdriveServiceProvider } from "../../core/platform/framework"; import assert from "assert"; import { ExecutionContext } from "../../core/platform/framework/api/crud-service"; -export class ConsoleServiceImpl implements TwakeServiceProvider { +export class ConsoleServiceImpl implements TdriveServiceProvider { version: "1"; consoleType: ConsoleType; diff --git a/twake/backend/node/src/services/console/types.ts b/twake/backend/node/src/services/console/types.ts index 59ff0bd6..310fe281 100644 --- a/twake/backend/node/src/services/console/types.ts +++ b/twake/backend/node/src/services/console/types.ts @@ -22,7 +22,7 @@ export interface CreateConsoleCompany { limits?: { members?: number; //Old console version guests?: number; //Old console version - twake: { + tdrive: { members: number; guests: number; storage: number; @@ -141,7 +141,7 @@ export type ConsoleHookCompany = { limits: { members?: number; //Old console version guests?: number; //Old console version - twake: { + tdrive: { members: number; guests: number; storage: number; @@ -169,7 +169,7 @@ export type ConsoleHookUser = { roleCode: CompanyUserRole; status: "active" | "deactivated"; applications: { - code: "twake"; + code: "tdrive"; }[]; }, ]; diff --git a/twake/backend/node/src/services/console/web/controller.ts b/twake/backend/node/src/services/console/web/controller.ts index 2fdbc35b..3ba492e6 100644 --- a/twake/backend/node/src/services/console/web/controller.ts +++ b/twake/backend/node/src/services/console/web/controller.ts @@ -80,7 +80,7 @@ export class ConsoleController { let company = companies.getEntities()?.[0]; if (!company) { const newCompany = getCompanyInstance({ - name: "Twake", + name: "Tdrive", plan: { name: "Local", limits: undefined, features: undefined }, }); company = await gr.services.companies.createCompany(newCompany); @@ -238,7 +238,7 @@ export class ConsoleController { private async userUpdated(code: string) { //Not implemented yet - throw CrudException.notImplemented("Unimplemented"); + throw CrudException.notImplemented(`Method not implemented, ${code}.`); } private async companyRemoved(content: ConsoleHookCompanyDeletedContent) { diff --git a/twake/backend/node/src/services/console/web/routes.ts b/twake/backend/node/src/services/console/web/routes.ts index 6fc96220..7edcd1b2 100644 --- a/twake/backend/node/src/services/console/web/routes.ts +++ b/twake/backend/node/src/services/console/web/routes.ts @@ -12,7 +12,7 @@ const routes: FastifyPluginCallback = (fastify: FastifyInstance, options, next) const accessControl = async ( request: FastifyRequest<{ Body: ConsoleHookBody; Querystring: ConsoleHookQueryString }>, ) => { - throw fastify.httpErrors.notImplemented("Hook service doesn't exist anymore"); + throw fastify.httpErrors.notImplemented(`Hook service doesn't exist anymore, ${request}.`); }; fastify.route({ diff --git a/twake/backend/node/src/services/documents/entities/drive-twake-tab.ts b/twake/backend/node/src/services/documents/entities/drive-tdrive-tab.ts similarity index 89% rename from twake/backend/node/src/services/documents/entities/drive-twake-tab.ts rename to twake/backend/node/src/services/documents/entities/drive-tdrive-tab.ts index ca8fb6cb..d1fb5dd9 100644 --- a/twake/backend/node/src/services/documents/entities/drive-twake-tab.ts +++ b/twake/backend/node/src/services/documents/entities/drive-tdrive-tab.ts @@ -1,13 +1,13 @@ import { Type } from "class-transformer"; import { Column, Entity } from "../../../core/platform/services/database/services/orm/decorators"; -export const TYPE = "drive_twake_tab"; +export const TYPE = "drive_tdrive_tab"; @Entity(TYPE, { primaryKey: [["company_id"], "tab_id"], type: TYPE, }) -export class DriveTwakeTab { +export class DriveTdriveTab { @Type(() => String) @Column("company_id", "string") company_id: string; diff --git a/twake/backend/node/src/services/documents/index.ts b/twake/backend/node/src/services/documents/index.ts index 0b93f379..2512558c 100644 --- a/twake/backend/node/src/services/documents/index.ts +++ b/twake/backend/node/src/services/documents/index.ts @@ -1,9 +1,9 @@ -import { Prefix, TwakeService } from "../../core/platform/framework"; +import { Prefix, TdriveService } from "../../core/platform/framework"; import WebServerAPI from "../../core/platform/services/webserver/provider"; import web from "./web"; @Prefix("/internal/services/documents/v1") -export default class DocumentsService extends TwakeService { +export default class DocumentsService extends TdriveService { version = "1"; name = "documents"; diff --git a/twake/backend/node/src/services/documents/services/index.ts b/twake/backend/node/src/services/documents/services/index.ts index 6dc760b8..39a07910 100644 --- a/twake/backend/node/src/services/documents/services/index.ts +++ b/twake/backend/node/src/services/documents/services/index.ts @@ -1,5 +1,5 @@ import SearchRepository from "../../../core/platform/services/search/repository"; -import { getLogger, logger, TwakeLogger } from "../../../core/platform/framework"; +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 { PublicFile } from "../../../services/files/entities/file"; @@ -9,9 +9,9 @@ import gr from "../../global-resolver"; import { DriveFile, TYPE } from "../entities/drive-file"; import { FileVersion, TYPE as FileVersionType } from "../entities/file-version"; import { - DriveTwakeTab as DriveTwakeTabEntity, - TYPE as DriveTwakeTabRepoType, -} from "../entities/drive-twake-tab"; + DriveTdriveTab as DriveTdriveTabEntity, + TYPE as DriveTdriveTabRepoType, +} from "../entities/drive-tdrive-tab"; import { DriveExecutionContext, DocumentsMessageQueueRequest, @@ -20,7 +20,7 @@ import { SearchDocumentsOptions, TrashType, CompanyExecutionContext, - DriveTwakeTab, + DriveTdriveTab, } from "../types"; import { addDriveItemToArchive, @@ -51,10 +51,10 @@ export class DocumentsService { repository: Repository; searchRepository: SearchRepository; fileVersionRepository: Repository; - driveTwakeTabRepository: Repository; + driveTdriveTabRepository: Repository; ROOT: RootType = "root"; TRASH: TrashType = "trash"; - logger: TwakeLogger = getLogger("Documents Service"); + logger: TdriveLogger = getLogger("Documents Service"); async init(): Promise { try { @@ -67,10 +67,10 @@ export class DocumentsService { FileVersionType, FileVersion, ); - this.driveTwakeTabRepository = - await globalResolver.database.getRepository( - DriveTwakeTabRepoType, - DriveTwakeTabEntity, + this.driveTdriveTabRepository = + await globalResolver.database.getRepository( + DriveTdriveTabRepoType, + DriveTdriveTabEntity, ); } catch (error) { logger.error("Error while initializing Documents Service", error); @@ -769,8 +769,8 @@ export class DocumentsService { return new ListResult(result.type, filteredResult, result.nextPage); }; - getTab = async (tabId: string, context: CompanyExecutionContext): Promise => { - const tab = await this.driveTwakeTabRepository.findOne( + getTab = async (tabId: string, context: CompanyExecutionContext): Promise => { + const tab = await this.driveTdriveTabRepository.findOne( { company_id: context.company.id, tab_id: tabId }, {}, context, @@ -784,7 +784,7 @@ export class DocumentsService { itemId: string, level: "read" | "write", context: CompanyExecutionContext, - ): Promise => { + ): Promise => { const hasAccess = await checkAccess(itemId, null, "manage", this.repository, context); if (!hasAccess) { @@ -801,8 +801,8 @@ export class DocumentsService { context, ); - await this.driveTwakeTabRepository.save( - Object.assign(new DriveTwakeTabEntity(), { + await this.driveTdriveTabRepository.save( + Object.assign(new DriveTdriveTabEntity(), { company_id: context.company.id, tab_id: tabId, channel_id: channelId, diff --git a/twake/backend/node/src/services/documents/types.ts b/twake/backend/node/src/services/documents/types.ts index 79d5f360..2d77c6bc 100644 --- a/twake/backend/node/src/services/documents/types.ts +++ b/twake/backend/node/src/services/documents/types.ts @@ -66,7 +66,7 @@ export type exportKeywordPayload = { company_id: string; }; -export type DriveTwakeTab = { +export type DriveTdriveTab = { company_id: string; tab_id: string; channel_id: string; diff --git a/twake/backend/node/src/services/documents/utils.ts b/twake/backend/node/src/services/documents/utils.ts index 31f847bf..221f7d4f 100644 --- a/twake/backend/node/src/services/documents/utils.ts +++ b/twake/backend/node/src/services/documents/utils.ts @@ -318,7 +318,7 @@ export const checkAccess = async ( item: DriveFile | null, level: DriveFileAccessLevel, repository: Repository, - context: CompanyExecutionContext & { public_token?: string; twake_tab_token?: string }, + context: CompanyExecutionContext & { public_token?: string; tdrive_tab_token?: string }, ): Promise => { if (context.user?.server_request) { return true; @@ -346,7 +346,7 @@ export const getAccessLevel = async ( id: string, item: DriveFile | null, repository: Repository, - context: CompanyExecutionContext & { public_token?: string; twake_tab_token?: string }, + context: CompanyExecutionContext & { public_token?: string; tdrive_tab_token?: string }, ): Promise => { if (!id || id === "root") return !context?.user?.id ? "none" : (await isCompanyGuest(context)) ? "read" : "manage"; @@ -393,9 +393,9 @@ export const getAccessLevel = async ( if (matchingUser) return matchingUser.level; //Channels - if (context.twake_tab_token) { + if (context.tdrive_tab_token) { try { - const [channelId] = context.twake_tab_token.split("+"); //First item will be the channel id + const [channelId] = context.tdrive_tab_token.split("+"); //First item will be the channel id const matchingChannel = accessEntities.find( a => a.type === "channel" && a.id === channelId, ); diff --git a/twake/backend/node/src/services/documents/web/controllers/documents.ts b/twake/backend/node/src/services/documents/web/controllers/documents.ts index c5e4cdfe..3253a21c 100644 --- a/twake/backend/node/src/services/documents/web/controllers/documents.ts +++ b/twake/backend/node/src/services/documents/web/controllers/documents.ts @@ -11,7 +11,7 @@ import { CompanyExecutionContext, DriveExecutionContext, DriveItemDetails, - DriveTwakeTab, + DriveTdriveTab, ItemRequestParams, RequestParams, SearchDocumentsBody, @@ -338,7 +338,7 @@ export class DocumentsController { request: FastifyRequest<{ Params: { tab_id: string; company_id: string }; }>, - ): Promise => { + ): Promise => { const context = getCompanyExecutionContext(request); const { tab_id } = request.params; @@ -348,9 +348,9 @@ export class DocumentsController { setTab = async ( request: FastifyRequest<{ Params: { tab_id: string; company_id: string }; - Body: DriveTwakeTab; + Body: DriveTdriveTab; }>, - ): Promise => { + ): Promise => { const context = getCompanyExecutionContext(request); const { tab_id } = request.params; diff --git a/twake/backend/node/src/services/files/index.ts b/twake/backend/node/src/services/files/index.ts index da5bab3d..b80f28f5 100644 --- a/twake/backend/node/src/services/files/index.ts +++ b/twake/backend/node/src/services/files/index.ts @@ -1,9 +1,9 @@ -import { Prefix, TwakeService } from "../../core/platform/framework"; +import { Prefix, TdriveService } from "../../core/platform/framework"; import WebServerAPI from "../../core/platform/services/webserver/provider"; import web from "./web"; @Prefix("/internal/services/files/v1") -export default class FilesService extends TwakeService { +export default class FilesService extends TdriveService { version = "1"; name = "files"; diff --git a/twake/backend/node/src/services/files/services/index.ts b/twake/backend/node/src/services/files/services/index.ts index efa1cdaa..e8ff1ac8 100644 --- a/twake/backend/node/src/services/files/services/index.ts +++ b/twake/backend/node/src/services/files/services/index.ts @@ -227,5 +227,5 @@ export class FileServiceImpl { } function getFilePath(entity: File): string { - return `/twake/files/${entity.company_id}/${entity.user_id || "anonymous"}/${entity.id}`; + return `/tdrive/files/${entity.company_id}/${entity.user_id || "anonymous"}/${entity.id}`; } diff --git a/twake/backend/node/src/services/general/api.ts b/twake/backend/node/src/services/general/api.ts index 00fc56fc..371bbb7b 100644 --- a/twake/backend/node/src/services/general/api.ts +++ b/twake/backend/node/src/services/general/api.ts @@ -1,3 +1,3 @@ -import { Initializable, TwakeServiceProvider } from "../../core/platform/framework/api"; +import { Initializable, TdriveServiceProvider } from "../../core/platform/framework/api"; -export interface GeneralServiceAPI extends TwakeServiceProvider, Initializable {} +export interface GeneralServiceAPI extends TdriveServiceProvider, Initializable {} diff --git a/twake/backend/node/src/services/general/index.ts b/twake/backend/node/src/services/general/index.ts index e0396478..28da91c3 100644 --- a/twake/backend/node/src/services/general/index.ts +++ b/twake/backend/node/src/services/general/index.ts @@ -1,12 +1,12 @@ import WebServerAPI from "../../core/platform/services/webserver/provider"; -import { Consumes, Prefix, TwakeService } from "../../core/platform/framework"; +import { Consumes, Prefix, TdriveService } from "../../core/platform/framework"; import { GeneralServiceAPI } from "./api"; import web from "./web/index"; import { ServerConfiguration } from "./types"; @Prefix("/internal/services/general/v1") @Consumes(["webserver"]) -export default class GeneralService extends TwakeService { +export default class GeneralService extends TdriveService { version = "1"; name = "general"; service: GeneralServiceAPI; diff --git a/twake/backend/node/src/services/global-resolver.ts b/twake/backend/node/src/services/global-resolver.ts index a7f111ed..bc8b519f 100644 --- a/twake/backend/node/src/services/global-resolver.ts +++ b/twake/backend/node/src/services/global-resolver.ts @@ -1,7 +1,7 @@ import { FastifyInstance } from "fastify"; import { IncomingMessage, Server, ServerResponse } from "http"; -import { TwakePlatform } from "../core/platform/platform"; +import { TdrivePlatform } from "../core/platform/platform"; import { RealtimeServiceAPI } from "../core/platform/services/realtime/api"; import WebServerAPI from "../core/platform/services/webserver/provider"; import { SearchServiceAPI } from "../core/platform/services/search/api"; @@ -25,6 +25,8 @@ import { UserExternalLinksServiceImpl } from "./user/services/external_links"; import { UserNotificationBadgeService } from "./notifications/services/bages"; import { NotificationPreferencesService } from "./notifications/services/preferences"; import { UserServiceImpl } from "./user/services/users/service"; +import { CompanyApplicationServiceImpl } from "./applications/services/company-applications"; +import { ApplicationServiceImpl } from "./applications/services/applications"; import { FileServiceImpl } from "./files/services"; import { ChannelServiceImpl } from "./channels/services/channel/service"; import { MemberServiceImpl } from "./channels/services/member/service"; @@ -36,6 +38,7 @@ import { NotificationEngine } from "./notifications/services/engine"; import { MobilePushService } from "./notifications/services/mobile-push"; import { ChannelMemberPreferencesServiceImpl } from "./notifications/services/channel-preferences"; import { ChannelThreadUsersServiceImpl } from "./notifications/services/channel-thread-users"; +import { ApplicationHooksService } from "./applications/services/hooks"; import OnlineServiceImpl from "./online/service"; import { ChannelsMessageQueueListener } from "./channels/services/pubsub"; import { UserNotificationDigestService } from "./notifications/services/digest"; @@ -59,7 +62,7 @@ type PlatformServices = { emailPusher: EmailPusherAPI; }; -type TwakeServices = { +type TdriveServices = { workspaces: WorkspaceServiceImpl; companies: CompanyServiceImpl; users: UserServiceImpl; @@ -75,6 +78,11 @@ type TwakeServices = { mobilePush: MobilePushService; digest: UserNotificationDigestService; }; + applications: { + marketplaceApps: ApplicationServiceImpl; + companyApps: CompanyApplicationServiceImpl; + hooks: ApplicationHooksService; + }; files: FileServiceImpl; channels: { channels: ChannelServiceImpl; @@ -92,7 +100,7 @@ type TwakeServices = { }; class GlobalResolver { - public services: TwakeServices; + public services: TdriveServices; public platformServices: PlatformServices; public database: DatabaseServiceAPI; @@ -100,7 +108,7 @@ class GlobalResolver { private alreadyInitialized = false; - async doInit(platform: TwakePlatform) { + async doInit(platform: TdrivePlatform) { if (this.alreadyInitialized) { return; } @@ -145,6 +153,11 @@ class GlobalResolver { mobilePush: await new MobilePushService().init(), digest: await new UserNotificationDigestService().init(), }, + applications: { + marketplaceApps: await new ApplicationServiceImpl().init(), + companyApps: await new CompanyApplicationServiceImpl().init(), + hooks: await new ApplicationHooksService().init(), + }, files: await new FileServiceImpl().init(), channels: { channels: await new ChannelServiceImpl().init(), @@ -161,7 +174,7 @@ class GlobalResolver { tags: await new TagsService().init(), }; - Object.keys(this.services).forEach((key: keyof TwakeServices) => { + Object.keys(this.services).forEach((key: keyof TdriveServices) => { assert(this.services[key], `Service ${key} was not initialized`); if (this.services[key].constructor.name == "Object") { const subs = this.services[key] as any; diff --git a/twake/backend/node/src/services/knowledge-graph-web/index.ts b/twake/backend/node/src/services/knowledge-graph-web/index.ts index 6a6d601b..24e77a28 100644 --- a/twake/backend/node/src/services/knowledge-graph-web/index.ts +++ b/twake/backend/node/src/services/knowledge-graph-web/index.ts @@ -1,10 +1,10 @@ -import { Consumes, Prefix, TwakeService } from "../../core/platform/framework"; +import { Consumes, Prefix, TdriveService } from "../../core/platform/framework"; import WebServerAPI from "../../core/platform/services/webserver/provider"; import web from "./web/index"; @Prefix("/internal/services/knowledge-graph/v1") @Consumes(["webserver"]) -export default class MessageService extends TwakeService { +export default class MessageService extends TdriveService { version = "1"; name = "knowledge-graph"; diff --git a/twake/backend/node/src/services/notifications/index.ts b/twake/backend/node/src/services/notifications/index.ts index 10cbb157..eff45ed0 100644 --- a/twake/backend/node/src/services/notifications/index.ts +++ b/twake/backend/node/src/services/notifications/index.ts @@ -1,9 +1,9 @@ -import { Prefix, TwakeService } from "../../core/platform/framework"; +import { Prefix, TdriveService } from "../../core/platform/framework"; import WebServerAPI from "../../core/platform/services/webserver/provider"; import web from "./web"; @Prefix("/internal/services/notifications/v1") -export default class NotificationService extends TwakeService { +export default class NotificationService extends TdriveService { version = "1"; name = "notifications"; diff --git a/twake/backend/node/src/services/notifications/services/bages.ts b/twake/backend/node/src/services/notifications/services/bages.ts index 4c73b5bd..572c7264 100644 --- a/twake/backend/node/src/services/notifications/services/bages.ts +++ b/twake/backend/node/src/services/notifications/services/bages.ts @@ -3,8 +3,8 @@ import { Initializable, RealtimeDeleted, RealtimeSaved, - TwakeContext, - TwakeServiceProvider, + TdriveContext, + TdriveServiceProvider, } from "../../../core/platform/framework"; import { ResourcePath } from "../../../core/platform/services/realtime/types"; import { @@ -28,11 +28,11 @@ import Repository from "../../../core/platform/services/database/services/orm/re import gr from "../../global-resolver"; import _, { pick, uniq } from "lodash"; -export class UserNotificationBadgeService implements TwakeServiceProvider, Initializable { +export class UserNotificationBadgeService implements TdriveServiceProvider, Initializable { version: "1"; repository: Repository; - async init(context: TwakeContext): Promise { + async init(context: TdriveContext): Promise { this.repository = await gr.database.getRepository( UserNotificationBadgeType, UserNotificationBadge, diff --git a/twake/backend/node/src/services/notifications/services/channel-preferences.ts b/twake/backend/node/src/services/notifications/services/channel-preferences.ts index 8fa21c3f..e876b3ba 100644 --- a/twake/backend/node/src/services/notifications/services/channel-preferences.ts +++ b/twake/backend/node/src/services/notifications/services/channel-preferences.ts @@ -11,12 +11,12 @@ import { ChannelMemberNotificationPreferencePrimaryKey, } from "../entities"; import Repository from "../../../core/platform/services/database/services/orm/repository/repository"; -import { Initializable, logger, TwakeServiceProvider } from "../../../core/platform/framework"; +import { Initializable, logger, TdriveServiceProvider } from "../../../core/platform/framework"; import gr from "../../global-resolver"; const TYPE = "channel_members_notification_preferences"; -export class ChannelMemberPreferencesServiceImpl implements TwakeServiceProvider, Initializable { +export class ChannelMemberPreferencesServiceImpl implements TdriveServiceProvider, Initializable { version: "1"; repository: Repository; diff --git a/twake/backend/node/src/services/notifications/services/channel-thread-users.ts b/twake/backend/node/src/services/notifications/services/channel-thread-users.ts index 2c490bfc..a96918ec 100644 --- a/twake/backend/node/src/services/notifications/services/channel-thread-users.ts +++ b/twake/backend/node/src/services/notifications/services/channel-thread-users.ts @@ -12,9 +12,9 @@ import { } from "../entities"; import Repository from "../../../core/platform/services/database/services/orm/repository/repository"; import gr from "../../global-resolver"; -import { Initializable, TwakeServiceProvider } from "../../../core/platform/framework"; +import { Initializable, TdriveServiceProvider } from "../../../core/platform/framework"; -export class ChannelThreadUsersServiceImpl implements TwakeServiceProvider, Initializable { +export class ChannelThreadUsersServiceImpl implements TdriveServiceProvider, Initializable { version: "1"; repository: Repository; diff --git a/twake/backend/node/src/services/notifications/services/digest.ts b/twake/backend/node/src/services/notifications/services/digest.ts index 62926306..b6e01bf7 100644 --- a/twake/backend/node/src/services/notifications/services/digest.ts +++ b/twake/backend/node/src/services/notifications/services/digest.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ -import { Initializable, TwakeServiceProvider } from "../../../core/platform/framework"; +import { Initializable, TdriveServiceProvider } from "../../../core/platform/framework"; import { Paginable, Pagination } from "../../../core/platform/framework/api/crud-service"; import Repository from "../../../core/platform/services/database/services/orm/repository/repository"; import { Channel } from "../../../services/channels/entities"; @@ -8,7 +8,7 @@ import gr from "../../global-resolver"; import { UserNotificationBadge } from "../entities"; import { getInstance, TYPE, UserNotificationDigest } from "../entities/user-notification-digest"; -export class UserNotificationDigestService implements TwakeServiceProvider, Initializable { +export class UserNotificationDigestService implements TdriveServiceProvider, Initializable { version: "1"; repository: Repository; diff --git a/twake/backend/node/src/services/notifications/services/engine/processors/reaction-notification.ts b/twake/backend/node/src/services/notifications/services/engine/processors/reaction-notification.ts index 7b0d7527..a231b60a 100644 --- a/twake/backend/node/src/services/notifications/services/engine/processors/reaction-notification.ts +++ b/twake/backend/node/src/services/notifications/services/engine/processors/reaction-notification.ts @@ -105,7 +105,7 @@ export class PushReactionNotification const companyName = company?.name || ""; const workspaceName = workspace_id === "direct" ? "Direct" : workspace?.name || ""; - const userName = this.getUserName(user) || "Twake"; + const userName = this.getUserName(user) || "Tdrive"; if (Channel.isDirectChannel(channel)) { title = `${userName} in ${companyName}`; diff --git a/twake/backend/node/src/services/notifications/services/preferences.ts b/twake/backend/node/src/services/notifications/services/preferences.ts index 7314e30b..2002b121 100644 --- a/twake/backend/node/src/services/notifications/services/preferences.ts +++ b/twake/backend/node/src/services/notifications/services/preferences.ts @@ -1,5 +1,5 @@ import _ from "lodash"; -import { Initializable, TwakeServiceProvider } from "../../../core/platform/framework"; +import { Initializable, TdriveServiceProvider } from "../../../core/platform/framework"; import { CrudException, DeleteResult, @@ -18,7 +18,7 @@ type UserNotificationPreferencesPrimaryKey = { user_id: string; }; -export class NotificationPreferencesService implements TwakeServiceProvider, Initializable { +export class NotificationPreferencesService implements TdriveServiceProvider, Initializable { version: "1"; repository: Repository; @@ -59,7 +59,7 @@ export class NotificationPreferencesService implements TwakeServiceProvider, Ini ); } - /** We can define preferences for specifically a workspace or for all a company or all Twake + /** We can define preferences for specifically a workspace or for all a company or all Tdrive * This function will ensure we get all with inherit and all */ async getMerged( diff --git a/twake/backend/node/src/services/online/api.ts b/twake/backend/node/src/services/online/api.ts index ca78f8ed..66341b1d 100644 --- a/twake/backend/node/src/services/online/api.ts +++ b/twake/backend/node/src/services/online/api.ts @@ -1,4 +1,4 @@ -import { TwakeServiceProvider } from "../../core/platform/framework"; +import { TdriveServiceProvider } from "../../core/platform/framework"; import UserOnline, { UserOnlinePrimaryKey } from "./entities/user-online"; export type OnlineEvent = { @@ -18,7 +18,7 @@ export type OnlineGetResponse = { data: Array<[string, boolean]>; }; -export interface OnlineServiceAPI extends TwakeServiceProvider { +export interface OnlineServiceAPI extends TdriveServiceProvider { isOnline(userId: string): Promise; setLastSeenOnline(userIds: Array, lastSeen: number, is_connected: boolean): Promise; get(userId: UserOnlinePrimaryKey): Promise; diff --git a/twake/backend/node/src/services/online/index.ts b/twake/backend/node/src/services/online/index.ts index 9c9f9f02..a6d815cb 100644 --- a/twake/backend/node/src/services/online/index.ts +++ b/twake/backend/node/src/services/online/index.ts @@ -1,7 +1,7 @@ -import { Prefix, TwakeService } from "../../core/platform/framework"; +import { Prefix, TdriveService } from "../../core/platform/framework"; @Prefix("/internal/services/online/v1") -export default class OnlineService extends TwakeService { +export default class OnlineService extends TdriveService { version = "1"; name = "online"; diff --git a/twake/backend/node/src/services/online/pubsub/index.ts b/twake/backend/node/src/services/online/pubsub/index.ts index 44ac7680..44f14b1c 100644 --- a/twake/backend/node/src/services/online/pubsub/index.ts +++ b/twake/backend/node/src/services/online/pubsub/index.ts @@ -1,11 +1,11 @@ -import { getLogger, Initializable, TwakeLogger } from "../../../core/platform/framework"; +import { getLogger, Initializable, TdriveLogger } from "../../../core/platform/framework"; import { UsersOnlineMessage } from "../api"; import { ONLINE_TOPIC } from "../constants"; import { UserOnlineProcessor } from "./processor"; import gr from "../../global-resolver"; export class OnlinePubsubService implements Initializable { - private logger: TwakeLogger; + private logger: TdriveLogger; constructor() { this.logger = getLogger("online.pubsub.OnlinePubsubService"); } diff --git a/twake/backend/node/src/services/online/pubsub/processor.ts b/twake/backend/node/src/services/online/pubsub/processor.ts index a73e48f9..8f898df9 100644 --- a/twake/backend/node/src/services/online/pubsub/processor.ts +++ b/twake/backend/node/src/services/online/pubsub/processor.ts @@ -1,5 +1,5 @@ import _ from "lodash"; -import { getLogger, TwakeLogger } from "../../../core/platform/framework"; +import { getLogger, TdriveLogger } from "../../../core/platform/framework"; import { MessageQueueHandler } from "../../../core/platform/services/message-queue/api"; import { websocketEventBus } from "../../../core/platform/services/realtime/bus"; import { @@ -10,7 +10,7 @@ import { UsersOnlineMessage } from "../api"; import { ONLINE_TOPIC } from "../constants"; export class UserOnlineProcessor implements MessageQueueHandler { - private logger: TwakeLogger; + private logger: TdriveLogger; readonly topics = { in: ONLINE_TOPIC, }; diff --git a/twake/backend/node/src/services/online/service/index.ts b/twake/backend/node/src/services/online/service/index.ts index 98e6a360..e5d7e1e1 100644 --- a/twake/backend/node/src/services/online/service/index.ts +++ b/twake/backend/node/src/services/online/service/index.ts @@ -9,18 +9,18 @@ import UserOnline, { UserOnlinePrimaryKey, } from "../entities/user-online"; import gr from "../../global-resolver"; -import { getLogger, TwakeLogger, TwakeServiceProvider } from "../../../core/platform/framework"; +import { getLogger, TdriveLogger, TdriveServiceProvider } from "../../../core/platform/framework"; import { getUserRoom } from "../../../services/user/realtime"; import User from "../../../services/user/entities/user"; import { WebsocketUserEvent } from "../../../core/platform/services/websocket/types"; import { ExecutionContext } from "../../../core/platform/framework/api/crud-service"; -export default class OnlineServiceImpl implements TwakeServiceProvider { +export default class OnlineServiceImpl implements TdriveServiceProvider { version = "1"; service: OnlineServiceAPI; private pubsubService: OnlinePubsubService; onlineRepository: Repository; - private logger: TwakeLogger; + private logger: TdriveLogger; constructor() { this.logger = getLogger("online.service"); @@ -130,7 +130,7 @@ export default class OnlineServiceImpl implements TwakeServiceProvider { context?: ExecutionContext, ): Promise> { const users = []; - //This foreach is needed for $in operators https://github.com/linagora/Twake/issues/1246 + //This foreach is needed for $in operators https://github.com/linagora/Tdrive/issues/1246 for (let i = 0; i < ids.length; i += 100) { users.push( ...( diff --git a/twake/backend/node/src/services/statistics/index.ts b/twake/backend/node/src/services/statistics/index.ts index 78479bdd..64e5cabe 100644 --- a/twake/backend/node/src/services/statistics/index.ts +++ b/twake/backend/node/src/services/statistics/index.ts @@ -1,6 +1,6 @@ -import { TwakeService } from "../../core/platform/framework"; +import { TdriveService } from "../../core/platform/framework"; -export default class StatisticService extends TwakeService { +export default class StatisticService extends TdriveService { version = "1"; name = "statistics"; diff --git a/twake/backend/node/src/services/statistics/service/index.ts b/twake/backend/node/src/services/statistics/service/index.ts index f1048c6e..f350c68f 100644 --- a/twake/backend/node/src/services/statistics/service/index.ts +++ b/twake/backend/node/src/services/statistics/service/index.ts @@ -5,10 +5,10 @@ import StatisticsEntity, { } from "../entities/statistics"; import Repository from "../../../core/platform/services/database/services/orm/repository/repository"; import gr from "../../global-resolver"; -import { Initializable, TwakeServiceProvider } from "../../../core/platform/framework"; +import { Initializable, TdriveServiceProvider } from "../../../core/platform/framework"; import { ExecutionContext } from "../../../core/platform/framework/api/crud-service"; -export class StatisticsServiceImpl implements TwakeServiceProvider, Initializable { +export class StatisticsServiceImpl implements TdriveServiceProvider, Initializable { version: "1"; private repository: Repository; diff --git a/twake/backend/node/src/services/statistics/types.ts b/twake/backend/node/src/services/statistics/types.ts index 493236eb..b6f7949b 100644 --- a/twake/backend/node/src/services/statistics/types.ts +++ b/twake/backend/node/src/services/statistics/types.ts @@ -1,6 +1,6 @@ -import { Initializable, TwakeServiceProvider } from "../../core/platform/framework"; +import { Initializable, TdriveServiceProvider } from "../../core/platform/framework"; -export interface StatisticsAPI extends TwakeServiceProvider, Initializable { +export interface StatisticsAPI extends TdriveServiceProvider, Initializable { increase(companyId: string, eventName: string, value?: number): Promise; get(companyId: string | null, eventName: string): Promise; } diff --git a/twake/backend/node/src/services/tags/index.ts b/twake/backend/node/src/services/tags/index.ts index 0993400c..f542fab8 100644 --- a/twake/backend/node/src/services/tags/index.ts +++ b/twake/backend/node/src/services/tags/index.ts @@ -1,9 +1,9 @@ import WebServerAPI from "../../core/platform/services/webserver/provider"; -import { Prefix, TwakeService } from "../../core/platform/framework"; +import { Prefix, TdriveService } from "../../core/platform/framework"; import web from "./web"; @Prefix("/internal/services/tags/v1") -export default class TagsService extends TwakeService { +export default class TagsService extends TdriveService { version = "1"; name = "tags"; diff --git a/twake/backend/node/src/services/tags/services/tags.ts b/twake/backend/node/src/services/tags/services/tags.ts index f5a2baf9..debb1a7f 100644 --- a/twake/backend/node/src/services/tags/services/tags.ts +++ b/twake/backend/node/src/services/tags/services/tags.ts @@ -1,4 +1,4 @@ -import { TwakeServiceProvider, Initializable } from "src/core/platform/framework/api"; +import { TdriveServiceProvider, Initializable } from "src/core/platform/framework/api"; import Repository from "src/core/platform/services/database/services/orm/repository/repository"; import { Tag, TagsType, TagsPrimaryKey } from "../entities"; import gr from "../../global-resolver"; @@ -13,7 +13,7 @@ import { plainToClass } from "class-transformer"; import { createTagEntity, TYPE } from "../entities/tags"; import { logger } from "../../../core/platform/framework"; -export class TagsService implements TwakeServiceProvider, Initializable { +export class TagsService implements TdriveServiceProvider, Initializable { version: "1"; repository: Repository; diff --git a/twake/backend/node/src/services/user/entities/company_user.ts b/twake/backend/node/src/services/user/entities/company_user.ts index 3d9c1a52..65ba0a96 100644 --- a/twake/backend/node/src/services/user/entities/company_user.ts +++ b/twake/backend/node/src/services/user/entities/company_user.ts @@ -44,10 +44,10 @@ export default class CompanyUser { @Column("level", "number") level: number; //Depreciated - @Column("is_externe", "twake_boolean") + @Column("is_externe", "tdrive_boolean") isExterne: boolean; //Depreciated - @Column("did_connect_today", "twake_boolean") + @Column("did_connect_today", "tdrive_boolean") didConnectToday: boolean; //Depreciated @Column("app_used_today", "json") diff --git a/twake/backend/node/src/services/user/entities/user.ts b/twake/backend/node/src/services/user/entities/user.ts index aa7987bf..0be7e75b 100644 --- a/twake/backend/node/src/services/user/entities/user.ts +++ b/twake/backend/node/src/services/user/entities/user.ts @@ -47,7 +47,7 @@ export default class User { @Column("last_activity", "number") last_activity: number; - @Column("creation_date", "twake_datetime") + @Column("creation_date", "tdrive_datetime") creation_date: number; @Column("notification_preference", "encoded_json") @@ -74,10 +74,10 @@ export default class User { @Column("password", "string") password: string; - @Column("deleted", "twake_boolean") + @Column("deleted", "tdrive_boolean") deleted: boolean; - @Column("mail_verified", "twake_boolean") + @Column("mail_verified", "tdrive_boolean") mail_verified: boolean; @Column("phone", "string") diff --git a/twake/backend/node/src/services/user/index.ts b/twake/backend/node/src/services/user/index.ts index 90bbd4d9..cb96dfaf 100644 --- a/twake/backend/node/src/services/user/index.ts +++ b/twake/backend/node/src/services/user/index.ts @@ -1,9 +1,9 @@ -import { Prefix, TwakeService } from "../../core/platform/framework"; +import { Prefix, TdriveService } from "../../core/platform/framework"; import WebServerAPI from "../../core/platform/services/webserver/provider"; import web from "./web"; @Prefix("/internal/services/users/v1") -export default class UserService extends TwakeService { +export default class UserService extends TdriveService { version = "1"; name = "user"; diff --git a/twake/backend/node/src/services/user/services/users/service.ts b/twake/backend/node/src/services/user/services/users/service.ts index cd8c6041..2faba390 100644 --- a/twake/backend/node/src/services/user/services/users/service.ts +++ b/twake/backend/node/src/services/user/services/users/service.ts @@ -63,7 +63,7 @@ export class UserServiceImpl { this.cache = new NodeCache({ stdTTL: 0.2, checkperiod: 120 }); - //If user deleted from Twake, remove it from all companies + //If user deleted from Tdrive, remove it from all companies localEventBus.subscribe("user:deleted", async data => { if (data?.user?.id) gr.services.companies.ensureDeletedUserNotInCompanies(data.user); }); @@ -161,7 +161,7 @@ export class UserServiceImpl { const partialId = user.id.toString().split("-")[0]; user.username_canonical = `deleted-user-${partialId}`; - user.email_canonical = `${partialId}@twake.removed`; + user.email_canonical = `${partialId}@tdrive.removed`; user.first_name = ""; user.last_name = ""; user.phone = ""; diff --git a/twake/backend/node/src/services/user/utils.ts b/twake/backend/node/src/services/user/utils.ts index a66ce095..a345be49 100644 --- a/twake/backend/node/src/services/user/utils.ts +++ b/twake/backend/node/src/services/user/utils.ts @@ -22,7 +22,7 @@ export function formatCompany( }; if (companyUserObject) { - res.status = "active"; // FIXME: Deactivated console user are removed from company on twake side + res.status = "active"; // FIXME: Deactivated console user are removed from company on tdrive side res.role = companyUserObject.role; } diff --git a/twake/backend/node/src/services/workspaces/entities/workspace_user.ts b/twake/backend/node/src/services/workspaces/entities/workspace_user.ts index 49144725..00258975 100644 --- a/twake/backend/node/src/services/workspaces/entities/workspace_user.ts +++ b/twake/backend/node/src/services/workspaces/entities/workspace_user.ts @@ -30,7 +30,7 @@ export default class WorkspaceUser { @Column("last_access", "number") lastAccess: number; - @Column("is_externe", "twake_boolean") + @Column("is_externe", "tdrive_boolean") isExternal: boolean; //Depreciated } diff --git a/twake/backend/node/src/services/workspaces/index.ts b/twake/backend/node/src/services/workspaces/index.ts index 4b940982..2b72865b 100644 --- a/twake/backend/node/src/services/workspaces/index.ts +++ b/twake/backend/node/src/services/workspaces/index.ts @@ -1,10 +1,10 @@ -import { Prefix, TwakeService } from "../../core/platform/framework"; +import { Prefix, TdriveService } from "../../core/platform/framework"; import WebServerAPI from "../../core/platform/services/webserver/provider"; import web from "./web"; import { WorkspaceServiceImpl } from "./services/workspace"; @Prefix("/internal/services/workspaces/v1") -export default class Service extends TwakeService { +export default class Service extends TdriveService { version = "1"; name = "workspaces"; diff --git a/twake/backend/node/src/services/workspaces/services/workspace.ts b/twake/backend/node/src/services/workspaces/services/workspace.ts index 87f6ff6e..78cbaf16 100644 --- a/twake/backend/node/src/services/workspaces/services/workspace.ts +++ b/twake/backend/node/src/services/workspaces/services/workspace.ts @@ -44,7 +44,7 @@ import { countRepositoryItems } from "../../../utils/counters"; import { Initializable, RealtimeSaved, - TwakeServiceProvider, + TdriveServiceProvider, } from "../../../core/platform/framework"; import { ResourcePath } from "../../../core/platform/services/realtime/types"; import { getRoomName, getWorkspacePath } from "../realtime"; @@ -69,7 +69,7 @@ import WorkspaceInviteDomain, { getInstance as getWorkspaceInviteDomainInstance, } from "../entities/workspace_invite_domain"; -export class WorkspaceServiceImpl implements TwakeServiceProvider, Initializable { +export class WorkspaceServiceImpl implements TdriveServiceProvider, Initializable { version: "1"; private workspaceUserRepository: Repository; private workspaceRepository: Repository; diff --git a/twake/backend/node/src/services/workspaces/web/controllers/workspace-users.ts b/twake/backend/node/src/services/workspaces/web/controllers/workspace-users.ts index d6cc88d6..5c7b14f6 100644 --- a/twake/backend/node/src/services/workspaces/web/controllers/workspace-users.ts +++ b/twake/backend/node/src/services/workspaces/web/controllers/workspace-users.ts @@ -388,7 +388,7 @@ export class WorkspaceUsersCrudController ): Promise { const context = getExecutionContext(request); - const usersInTwake: Map = new Map( + const usersInTdrive: Map = new Map( await gr.services.users .getByEmails(request.body.invitations.map(a => a.email)) .then(users => users.map(user => [user.email_canonical, user])), @@ -443,8 +443,8 @@ export class WorkspaceUsersCrudController const consoleClient = gr.services.console.getClient(); - if (usersInTwake.has(invitation.email)) { - user = usersInTwake.get(invitation.email); + if (usersInTdrive.has(invitation.email)) { + user = usersInTdrive.get(invitation.email); usersToProcessImmediately.push(user); if (user) { @@ -453,7 +453,7 @@ export class WorkspaceUsersCrudController ); } } else { - user = await consoleClient.addUserToTwake({ + user = await consoleClient.addUserToTdrive({ email: invitation.email, password: invitation.password, }); diff --git a/twake/backend/node/src/services/workspaces/web/controllers/workspaces.ts b/twake/backend/node/src/services/workspaces/web/controllers/workspaces.ts index 3a4446d0..4f1f29e0 100644 --- a/twake/backend/node/src/services/workspaces/web/controllers/workspaces.ts +++ b/twake/backend/node/src/services/workspaces/web/controllers/workspaces.ts @@ -26,7 +26,7 @@ import { } from "../../../../core/platform/framework/api/crud-service"; import CompanyUser from "../../../user/entities/company_user"; import gr from "../../../global-resolver"; -import { getLogger, TwakeLogger } from "../../../../core/platform/framework"; +import { getLogger, TdriveLogger } from "../../../../core/platform/framework"; export class WorkspacesCrudController implements @@ -37,7 +37,7 @@ export class WorkspacesCrudController ResourceDeleteResponse > { - private logger: TwakeLogger; + private logger: TdriveLogger; private getCompanyUserRole(companyId: string, userId: string, context?: ExecutionContext) { return gr.services.companies .getCompanyUser({ id: companyId }, { id: userId }, context) diff --git a/twake/backend/node/src/twake.ts b/twake/backend/node/src/tdrive.ts similarity index 69% rename from twake/backend/node/src/twake.ts rename to twake/backend/node/src/tdrive.ts index b07a221e..8bb509ed 100644 --- a/twake/backend/node/src/twake.ts +++ b/twake/backend/node/src/tdrive.ts @@ -1,21 +1,21 @@ import path from "path"; -import { TwakePlatform, TwakePlatformConfiguration } from "./core/platform/platform"; +import { TdrivePlatform, TdrivePlatformConfiguration } from "./core/platform/platform"; import globalResolver from "./services/global-resolver"; /** - * Instantiate and start a new TwakePlatform with the given services. + * Instantiate and start a new TdrivePlatform with the given services. */ -async function run(services: string[] = []): Promise { - let platform: TwakePlatform; +async function run(services: string[] = []): Promise { + let platform: TdrivePlatform; - const start = async (): Promise => { + const start = async (): Promise => { try { - const configuration: TwakePlatformConfiguration = { + const configuration: TdrivePlatformConfiguration = { services, servicesPath: path.resolve(__dirname, "./services/"), }; - platform = new TwakePlatform(configuration); + platform = new TdrivePlatform(configuration); await platform.init(); await platform.start(); await globalResolver.doInit(platform); diff --git a/twake/backend/node/src/utils/users.ts b/twake/backend/node/src/utils/users.ts index 2b6d4c20..2d360350 100644 --- a/twake/backend/node/src/utils/users.ts +++ b/twake/backend/node/src/utils/users.ts @@ -74,7 +74,7 @@ export async function formatUser( companies, }; - // Fixme: this is for retro compatibility, should be deleted after march 2022 if mobile did implement it https://github.com/linagora/Twake-Mobile/issues/1265 + // Fixme: this is for retro compatibility, should be deleted after march 2022 if mobile did implement it https://github.com/linagora/Tdrive-Mobile/issues/1265 resUser.preference = resUser.preferences; let name: string = resUser?.username; diff --git a/twake/backend/node/test/e2e/counters.spec.ts b/twake/backend/node/test/e2e/counters.spec.ts deleted file mode 100644 index d26a3cc5..00000000 --- a/twake/backend/node/test/e2e/counters.spec.ts +++ /dev/null @@ -1,239 +0,0 @@ -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-nocheck -import { beforeAll, describe, expect, it } from "@jest/globals"; -import { init, TestPlatform } from "./setup"; -import { v1 as uuidv1 } from "uuid"; -import { CounterAPI } from "../../src/core/platform/services/counter/types"; -import { - WorkspaceCounterEntity, - WorkspaceCounterPrimaryKey, - WorkspaceCounterType, -} from "../../src/services/workspaces/entities/workspace_counters"; -import { CounterProvider } from "../../src/core/platform/services/counter/provider"; -import WorkspaceUser, { - getInstance as getWorkspaceUserInstance, - TYPE as WorkspaceUserEntityType, -} from "../../src/services/workspaces/entities/workspace_user"; - -import { countRepositoryItems } from "../../src/utils/counters"; -import { TestDbService } from "./utils.prepare.db"; -import { - ChannelCounterEntity, - ChannelCounterPrimaryKey, - ChannelUserCounterType, -} from "../../src/services/channels/entities/channel-counters"; -import { ChannelMemberType } from "../../src/services/channels/types"; -import { getMemberOfChannelInstance, MemberOfChannel } from "../../src/services/channels/entities"; -import gr from "../../src/services/global-resolver"; - -describe("Counters implementation", () => { - let platform: TestPlatform; - // let database: DatabaseServiceAPI; - let counterApi: CounterAPI; - let testDbService: TestDbService; - - beforeAll(async ends => { - platform = await init(); - - testDbService = new TestDbService(platform); - - await gr.database.getConnector().drop(); - - counterApi = platform.platform.getProvider("counter"); - expect(counterApi).toBeTruthy(); - - ends(); - }); - - afterAll(done => { - platform.tearDown().then(done); - }); - - const getCounter = async (type, entity) => { - return counterApi.getCounter(await testDbService.getRepository(type, entity)); - }; - - describe("Workspace counters", () => { - let counter: CounterProvider; - const counterPk = { id: uuidv1(), counter_type: WorkspaceCounterType.MEMBERS }; - - beforeAll(async ends => { - counter = await getCounter("workspace_counters", WorkspaceCounterEntity); - - const workspaceUserRepository = await testDbService.getRepository( - WorkspaceUserEntityType, - WorkspaceUser, - ); - - await workspaceUserRepository.save( - getWorkspaceUserInstance({ - workspaceId: counterPk.id, - userId: uuidv1(), - id: uuidv1(), - }), - ); - - expect(counter).toBeTruthy(); - - ends(); - }); - - it("Initializing empty value", async done => { - await counter.increase(counterPk, 0); - const val = await counter.get(counterPk); - expect(val).toEqual(0); - done(); - }); - - it("Adding value", async done => { - // adding 1 - - await counter.increase(counterPk, 1); - let val = await counter.get(counterPk); - expect(val).toEqual(1); - - // adding 2 - - await counter.increase(counterPk, 2); - val = await counter.get(counterPk); - expect(val).toEqual(3); - - done(); - }); - - it("Subtracting value", async done => { - // Subtracting 2 - - await counter.increase(counterPk, -2); - let val = await counter.get(counterPk); - expect(val).toEqual(1); - - // Subtracting 10 - - await counter.increase(counterPk, -10); - val = await counter.get(counterPk); - expect(val).toEqual(-9); - - done(); - }); - - it("Revising counter", async done => { - // Subtracting 2 - - const workspaceUserRepository = await testDbService.getRepository( - WorkspaceUserEntityType, - WorkspaceUser, - ); - - counter.setReviseCallback(async (pk: WorkspaceCounterPrimaryKey) => { - if (pk.counter_type == "members") { - return countRepositoryItems(workspaceUserRepository, { workspace_id: pk.id }); - } - }, 4); - - await counter.increase(counterPk, 1); - const val = await counter.get(counterPk); - expect(val).toEqual(1); - - done(); - }); - }); - - describe("Channel counters", () => { - let counter: CounterProvider; - let counterPk: ChannelCounterPrimaryKey; - - beforeAll(async ends => { - counterPk = { - id: uuidv1(), - company_id: uuidv1(), - workspace_id: uuidv1(), - counter_type: ChannelUserCounterType.MEMBERS, - }; - - counter = await getCounter("channel_counters", ChannelCounterEntity); - - const memberOfChannelRepository = await testDbService.getRepository( - "channel_members", - MemberOfChannel, - ); - - await memberOfChannelRepository.save( - getMemberOfChannelInstance({ - company_id: counterPk.company_id, - workspace_id: counterPk.workspace_id, - channel_id: counterPk.id, - user_id: uuidv1(), - }), - ); - - expect(counter).toBeTruthy(); - - ends(); - }); - - it("Initializing empty value", async done => { - await counter.increase(counterPk, 0); - const val = await counter.get(counterPk); - expect(val).toEqual(0); - done(); - }); - - it("Adding value", async done => { - // adding 1 - - await counter.increase(counterPk, 1); - let val = await counter.get(counterPk); - expect(val).toEqual(1); - - // adding 2 - - await counter.increase(counterPk, 2); - val = await counter.get(counterPk); - expect(val).toEqual(3); - - done(); - }); - - it("Subtracting value", async done => { - // Subtracting 2 - - await counter.increase(counterPk, -2); - let val = await counter.get(counterPk); - expect(val).toEqual(1); - - // Subtracting 10 - - await counter.increase(counterPk, -10); - val = await counter.get(counterPk); - expect(val).toEqual(-9); - - done(); - }); - - it("Revising counter", async done => { - // Subtracting 2 - - const memberOfChannelRepository = await testDbService.getRepository( - "channel_members", - MemberOfChannel, - ); - - counter.setReviseCallback(async (pk: ChannelCounterPrimaryKey) => { - if (pk.counter_type == ChannelUserCounterType.MEMBERS) { - return countRepositoryItems( - memberOfChannelRepository, - { channel_id: pk.id, company_id: pk.company_id, workspace_id: pk.workspace_id }, - { type: ChannelMemberType.MEMBER }, - ); - } - }, 4); - - await counter.increase(counterPk, 1); - const val = await counter.get(counterPk); - expect(val).toEqual(1); - - done(); - }); - }); -}); diff --git a/twake/backend/node/test/e2e/documents/documents-tab.spec.ts b/twake/backend/node/test/e2e/documents/documents-tab.spec.ts index e9d6c84e..d1baca6e 100644 --- a/twake/backend/node/test/e2e/documents/documents-tab.spec.ts +++ b/twake/backend/node/test/e2e/documents/documents-tab.spec.ts @@ -7,7 +7,7 @@ import { e2e_createDocument, e2e_getDocument } from "./utils"; const url = "/internal/services/documents/v1"; -describe("the Drive Twake tabs feature", () => { +describe("the Drive Tdrive tabs feature", () => { let platform: TestPlatform; class DriveFileMockClass { diff --git a/twake/backend/node/test/e2e/run-all.js b/twake/backend/node/test/e2e/run-all.js index 78d09aac..22619b89 100644 --- a/twake/backend/node/test/e2e/run-all.js +++ b/twake/backend/node/test/e2e/run-all.js @@ -1,9 +1,9 @@ /** * To run all tests in local development mode: - * cd twake/; docker-compose -f docker-compose.dev.tests.mongo.yml run -e NODE_OPTIONS=--unhandled-rejections=warn -e SEARCH_DRIVER=mongodb -e DB_DRIVER=mongodb -e PUBSUB_TYPE=local node npm run test:e2e + * cd tdrive/; docker-compose -f docker-compose.dev.tests.mongo.yml run -e NODE_OPTIONS=--unhandled-rejections=warn -e SEARCH_DRIVER=mongodb -e DB_DRIVER=mongodb -e PUBSUB_TYPE=local node npm run test:e2e * * To run only specific tests: - * cd twake/; docker-compose -f docker-compose.dev.tests.mongo.yml run -e NODE_OPTIONS=--unhandled-rejections=warn -e SEARCH_DRIVER=mongodb -e DB_DRIVER=mongodb -e PUBSUB_TYPE=local node npm run test:e2e -- test/e2e/application/app-create-update.spec.ts test/e2e/application/application-events.spec.ts + * cd tdrive/; docker-compose -f docker-compose.dev.tests.mongo.yml run -e NODE_OPTIONS=--unhandled-rejections=warn -e SEARCH_DRIVER=mongodb -e DB_DRIVER=mongodb -e PUBSUB_TYPE=local node npm run test:e2e -- test/e2e/application/app-create-update.spec.ts test/e2e/application/application-events.spec.ts */ const fs = require("fs"); diff --git a/twake/backend/node/test/e2e/setup/index.ts b/twake/backend/node/test/e2e/setup/index.ts index 54026c35..10d17e61 100644 --- a/twake/backend/node/test/e2e/setup/index.ts +++ b/twake/backend/node/test/e2e/setup/index.ts @@ -1,7 +1,7 @@ import { resolve as pathResolve } from "path"; import { v1 as uuidv1 } from "uuid"; import { FastifyInstance } from "fastify"; -import { TwakePlatform, TwakePlatformConfiguration } from "../../../src/core/platform/platform"; +import { TdrivePlatform, TdrivePlatformConfiguration } from "../../../src/core/platform/platform"; import WebServerAPI from "../../../src/core/platform/services/webserver/provider"; import { DatabaseServiceAPI } from "../../../src/core/platform/services/database/api"; import AuthServiceAPI from "../../../src/core/platform/services/auth/provider"; @@ -28,7 +28,7 @@ type User = { export interface TestPlatform { currentUser: User; - platform: TwakePlatform; + platform: TdrivePlatform; workspace: Workspace; app: FastifyInstance; database: DatabaseServiceAPI; @@ -51,11 +51,11 @@ export async function init( prePlatformStartCallback?: (fastify: FastifyInstance) => void, ): Promise { if (!testPlatform) { - const configuration: TwakePlatformConfiguration = { + const configuration: TdrivePlatformConfiguration = { services: config.get("services"), servicesPath: pathResolve(__dirname, "../../../src/services/"), }; - const platform = new TwakePlatform(configuration); + const platform = new TdrivePlatform(configuration); await platform.init(); await globalResolver.doInit(platform); diff --git a/twake/backend/node/test/e2e/statistics.spec.ts b/twake/backend/node/test/e2e/statistics.spec.ts deleted file mode 100644 index 4d70b35f..00000000 --- a/twake/backend/node/test/e2e/statistics.spec.ts +++ /dev/null @@ -1,155 +0,0 @@ -import { afterAll, beforeAll, beforeEach, describe, expect, it } from "@jest/globals"; -import { init, TestPlatform } from "./setup"; - -import { v1 as uuidv1 } from "uuid"; -import { - createMessage, - createParticipant, - e2e_createMessage, - e2e_createThread, -} from "./messages/utils"; -import { Thread } from "../../src/services/messages/entities/threads"; -import { deserialize } from "class-transformer"; -import { WorkspaceExecutionContext } from "../../src/services/channels/types"; -import { ChannelUtils, get as getChannelUtils } from "./channels/utils"; -import { ResourceUpdateResponse, User } from "../../src/utils/types"; -import gr from "../../src/services/global-resolver"; - -describe("Statistics implementation", () => { - let platform: TestPlatform; - // let database: DatabaseServiceAPI; - let channelUtils: ChannelUtils; - - beforeAll(async ends => { - platform = await init({ - services: ["database", "statistics", "webserver", "auth"], - }); - - expect(gr.services.statistics).toBeTruthy(); - - ends(); - channelUtils = getChannelUtils(platform); - }); - - beforeEach(async ends => { - await platform.database.getConnector().drop(); - ends(); - }); - - afterAll(async done => { - await platform.tearDown(); - done(); - }); - - it("Check statistics counters", async done => { - console.log(await gr.services.statistics.get(undefined, "counter-test")); - - expect(await gr.services.statistics.get(undefined, "counter-test")).toEqual(0); - - await gr.services.statistics.increase(platform.workspace.company_id, "counter-test"); - await gr.services.statistics.increase(platform.workspace.company_id, "counter-test"); - const secondCompanyId = uuidv1(); - await gr.services.statistics.increase(secondCompanyId, "counter-test"); - await gr.services.statistics.increase(secondCompanyId, "counter-test"); - await gr.services.statistics.increase(platform.workspace.company_id, "counter-test2"); - - expect(await gr.services.statistics.get(platform.workspace.company_id, "counter-test")).toEqual( - 2, - ); - expect(await gr.services.statistics.get(secondCompanyId, "counter-test")).toEqual(2); - expect(await gr.services.statistics.get(undefined, "counter-test")).toEqual(4); - - expect( - await gr.services.statistics.get(platform.workspace.company_id, "counter-test2"), - ).toEqual(1); - expect(await gr.services.statistics.get(secondCompanyId, "counter-test2")).toEqual(0); - expect(await gr.services.statistics.get(undefined, "counter-test2")).toEqual(1); - - done(); - }); - - function getContext(user?: User): WorkspaceExecutionContext { - return { - workspace: platform.workspace, - user: user || platform.currentUser, - }; - } - - async function sleep(timeout = 0) { - return new Promise(r => setTimeout(r, timeout)); - } - - describe("On user use messages in channel view", () => { - it("should create a message and retrieve it in channel view", async () => { - const channel = channelUtils.getChannel(); - await gr.services.channels.channels.save(channel, {}, getContext()); - const channelId = channel.id; - - //Reset global value because messages could have been created somewhere else - const value = await gr.services.statistics.get(undefined, "messages"); - await gr.services.statistics.increase(undefined, "messages", -value); - - const response = await e2e_createThread( - platform, - [ - createParticipant( - { - type: "channel", - id: channelId, - }, - platform, - ), - ], - createMessage({ text: "Initial thread 1 message" }), - ); - - await sleep(); - - const result: ResourceUpdateResponse = deserialize( - ResourceUpdateResponse, - response.body, - ); - const threadId = result.resource.id; - - await e2e_createMessage(platform, threadId, createMessage({ text: "Reply 1" })); - - await e2e_createMessage(platform, threadId, createMessage({ text: "Reply 2" })); - await e2e_createThread( - platform, - [ - createParticipant( - { - type: "channel", - id: channelId, - }, - platform, - ), - ], - createMessage({ text: "Initial thread 2 message" }), - ); - - await e2e_createMessage(platform, threadId, createMessage({ text: "Reply 3" })); - - await e2e_createThread( - platform, - [ - createParticipant( - { - type: "channel", - id: channelId, - }, - platform, - ), - ], - createMessage({ text: "Initial thread 3 message" }), - ); - - await new Promise(r => setTimeout(r, 5000)); - - expect(await gr.services.statistics.get(undefined, "messages")).toEqual(6); - expect(await gr.services.statistics.get(platform.workspace.company_id, "messages")).toEqual( - 6, - ); - }); - }); -}); diff --git a/twake/backend/node/test/e2e/tags/tags.spec.ts b/twake/backend/node/test/e2e/tags/tags.spec.ts deleted file mode 100644 index bdb6129d..00000000 --- a/twake/backend/node/test/e2e/tags/tags.spec.ts +++ /dev/null @@ -1,308 +0,0 @@ -import "reflect-metadata"; -import { afterAll, beforeAll, describe, expect, it } from "@jest/globals"; -import { init, TestPlatform } from "../setup"; -import { TestDbService } from "../utils.prepare.db"; -import { Tags } from "../../../src/services/tags/entities/tags"; -import { deserialize } from "class-transformer"; -import { - ResourceCreateResponse, - ResourceGetResponse, - ResourceListResponse, -} from "../../../src/utils/types"; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore - -describe("The Tags feature", () => { - const url = "/internal/services/tags/v1"; - let platform: TestPlatform; - let testDbService: TestDbService; - const tagIds: string[] = []; - - beforeAll(async ends => { - platform = await init({ - services: ["webserver", "database", "storage", "message-queue", "tags"], - }); - testDbService = await TestDbService.getInstance(platform, true); - ends(); - }); - - afterAll(async done => { - for (let i = 0; i < tagIds.length; i++) { - for (let j = 0; j < tagIds.length; j++) { - if (tagIds[j] === tagIds[i] && j !== i) { - throw new Error("Tag are not unique"); - } - } - } - await platform?.tearDown(); - platform = null; - done(); - }); - - describe("Create tag", () => { - it("should 201 if creator is a company admin", async done => { - const user = await testDbService.createUser([testDbService.defaultWorkspace()], { - companyRole: "admin", - }); - - const jwtToken = await platform.auth.getJWTToken({ sub: user.id }); - - for (let i = 0; i < 3; i++) { - const createTag = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${platform.workspace.company_id}/tags`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - payload: { - name: `test${i}`, - colour: `#00000${i}`, - }, - }); - - const tagResult: ResourceCreateResponse = deserialize( - ResourceCreateResponse, - createTag.body, - ); - expect(createTag.statusCode).toBe(201); - expect(tagResult.resource).toBeDefined(); - expect(tagResult.resource.name).toBe(`test${i}`); - expect(tagResult.resource.colour).toBe(`#00000${i}`); - expect(tagResult.resource.company_id).toBe(platform.workspace.company_id); - expect(tagResult.resource.tag_id).toBe(`test${i}`); - - const getTag = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${platform.workspace.company_id}/tags/${tagResult.resource.tag_id}`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - }); - expect(getTag.statusCode).toBe(200); - - tagIds.push(tagResult.resource.tag_id); - } - done(); - }); - - it("should 401 if creator is not a company admin", async done => { - const user = await testDbService.createUser([testDbService.defaultWorkspace()], { - companyRole: "member", - }); - const jwtToken = await platform.auth.getJWTToken({ sub: user.id }); - const createTag = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${platform.workspace.company_id}/tags`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - payload: { - name: "testNotAdmin", - colour: "#000000", - }, - }); - expect(createTag.statusCode).toBe(401); - - const tagResult: ResourceCreateResponse = deserialize( - ResourceCreateResponse, - createTag.body, - ); - expect(tagResult.resource).toBe(undefined); - done(); - }); - }); - - describe("Get tag", () => { - it("should 200 get a tag", async done => { - const user = await testDbService.createUser([testDbService.defaultWorkspace()], { - companyRole: "member", - }); - const jwtToken = await platform.auth.getJWTToken({ sub: user.id }); - const getTag = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${platform.workspace.company_id}/tags/${tagIds[0]}`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - }); - expect(getTag.statusCode).toBe(200); - - const getResult: ResourceGetResponse = deserialize(ResourceGetResponse, getTag.body); - expect(getResult.resource).toBeDefined(); - expect(getResult.resource.name).toBe("test0"); - expect(getResult.resource.colour).toBe("#000000"); - expect(getResult.resource.company_id).toBe(platform.workspace.company_id); - - done(); - }); - - it("should 200 tag does not exist", async done => { - const user = await testDbService.createUser([testDbService.defaultWorkspace()], { - companyRole: "member", - }); - const jwtToken = await platform.auth.getJWTToken({ sub: user.id }); - const getTag = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${platform.workspace.company_id}/tags/NonExistingTag`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - }); - expect(getTag.statusCode).toBe(200); - - const getResult: ResourceGetResponse = deserialize(ResourceGetResponse, getTag.body); - expect(getResult.resource).toBe(null); - - done(); - }); - }); - - describe("Update tag", () => { - it("Should 204 if user is admin", async done => { - const user = await testDbService.createUser([testDbService.defaultWorkspace()], { - companyRole: "admin", - }); - const jwtToken = await platform.auth.getJWTToken({ sub: user.id }); - const updateTag = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${platform.workspace.company_id}/tags`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - payload: { - name: "test1", - colour: "#000003", - }, - }); - expect(updateTag.statusCode).toBe(201); - - const tagUpdatedResult: ResourceCreateResponse = deserialize( - ResourceCreateResponse, - updateTag.body, - ); - expect(tagUpdatedResult.resource).toBeDefined(); - expect(tagUpdatedResult.resource.name).toBe("test1"); - expect(tagUpdatedResult.resource.colour).toBe("#000003"); - expect(tagUpdatedResult.resource.company_id).toBe(platform.workspace.company_id); - expect(tagUpdatedResult.resource.tag_id).toBe("test1"); - - const getUpdatedTag = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${platform.workspace.company_id}/tags/${tagUpdatedResult.resource.tag_id}`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - }); - expect(getUpdatedTag.statusCode).toBe(200); - - done(); - }); - - it("should 401 if creator is not a company admin", async done => { - const user = await testDbService.createUser([testDbService.defaultWorkspace()], { - companyRole: "member", - }); - const jwtToken = await platform.auth.getJWTToken({ sub: user.id }); - const createTag = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${platform.workspace.company_id}/tags/testNotAdmin`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - payload: { - name: "testNotAdmin", - colour: "#000000", - }, - }); - expect(createTag.statusCode).toBe(401); - - const tagResult: ResourceCreateResponse = deserialize( - ResourceCreateResponse, - createTag.body, - ); - console.log("tagResult2", tagResult, jwtToken); - expect(tagResult.resource).toBe(undefined); - - done(); - }); - }); - - describe("List tags", () => { - it("should 200 list a tag", async done => { - const user = await testDbService.createUser([testDbService.defaultWorkspace()], { - companyRole: "member", - }); - const jwtToken = await platform.auth.getJWTToken({ sub: user.id }); - const listTag = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${platform.workspace.company_id}/tags`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - }); - expect(listTag.statusCode).toBe(200); - - const tagResult: ResourceListResponse = deserialize(ResourceListResponse, listTag.body); - expect(tagResult.resources).toBeDefined(); - for (const tag of tagResult.resources) { - expect(tag.name).toBeDefined(); - expect(tag.colour).toBeDefined(); - expect(tag.company_id).toBe(platform.workspace.company_id); - expect(tag.tag_id).toBeDefined(); - } - - done(); - }); - }); - - describe("Delete tag", () => { - it("should 200 if admin delete a tag", async done => { - const user = await testDbService.createUser([testDbService.defaultWorkspace()], { - companyRole: "admin", - }); - const jwtToken = await platform.auth.getJWTToken({ sub: user.id }); - const deleteTag = await platform.app.inject({ - method: "DELETE", - url: `${url}/companies/${platform.workspace.company_id}/tags/${tagIds[0]}`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - }); - expect(deleteTag.statusCode).toBe(200); - - done(); - }); - - it("should 200 if tag does not exist", async done => { - const user = await testDbService.createUser([testDbService.defaultWorkspace()], { - companyRole: "admin", - }); - const jwtToken = await platform.auth.getJWTToken({ sub: user.id }); - const deleteTag = await platform.app.inject({ - method: "DELETE", - url: `${url}/companies/${platform.workspace.company_id}/tags/NonExistingTag`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - }); - expect(deleteTag.statusCode).toBe(200); - done(); - }); - - it("should 401 if not admin", async done => { - const user = await testDbService.createUser([testDbService.defaultWorkspace()], { - companyRole: "member", - }); - const jwtToken = await platform.auth.getJWTToken({ sub: user.id }); - const deleteTag = await platform.app.inject({ - method: "DELETE", - url: `${url}/companies/${platform.workspace.company_id}/tags/${tagIds[0]}`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - }); - expect(deleteTag.statusCode).toBe(401); - done(); - }); - }); -}); diff --git a/twake/backend/node/test/e2e/users/users.search.spec.ts b/twake/backend/node/test/e2e/users/users.search.spec.ts index b95d1320..e096e02a 100644 --- a/twake/backend/node/test/e2e/users/users.search.spec.ts +++ b/twake/backend/node/test/e2e/users/users.search.spec.ts @@ -52,32 +52,32 @@ describe("The /users API", () => { await testDbService.createUser([workspacePk], { firstName: "Ha", lastName: "Nguyen", - email: "hnguyen@twake.app", + email: "hnguyen@tdrive.app", }); await testDbService.createUser([workspacePk], { firstName: "Harold", lastName: "Georges", - email: "hgeorges@twake.app", + email: "hgeorges@tdrive.app", }); await testDbService.createUser([workspacePk], { firstName: "Bob", lastName: "Smith", - email: "bob@twake.app", + email: "bob@tdrive.app", }); await testDbService.createUser([workspacePk], { firstName: "Bob", lastName: "Rabiot", - email: "rabiot.b@twake.app", + email: "rabiot.b@tdrive.app", }); await testDbService.createUser([workspacePk, workspacePk2], { firstName: "Bob", lastName: "Smith-Rabiot", - email: "rbs@twake.app", + email: "rbs@tdrive.app", }); await testDbService.createUser([workspacePk], { firstName: "Alexïs", lastName: "Goélâns", - email: "alexis.goelans@twake.app", + email: "alexis.goelans@tdrive.app", }); //Wait for indexation to happen @@ -88,38 +88,38 @@ describe("The /users API", () => { resources = await search("bob rabiot"); - expect(resources.map(e => e.email).includes("rabiot.b@twake.app")).toBe(true); - expect(resources.map(e => e.email).includes("rbs@twake.app")).toBe(true); - expect(resources.map(e => e.email).includes("bob@twake.app")).toBe(true); + expect(resources.map(e => e.email).includes("rabiot.b@tdrive.app")).toBe(true); + expect(resources.map(e => e.email).includes("rbs@tdrive.app")).toBe(true); + expect(resources.map(e => e.email).includes("bob@tdrive.app")).toBe(true); resources = await search("alexis"); - expect(resources[0].email).toBe("alexis.goelans@twake.app"); + expect(resources[0].email).toBe("alexis.goelans@tdrive.app"); resources = await search("ALEXIS"); - expect(resources[0].email).toBe("alexis.goelans@twake.app"); + expect(resources[0].email).toBe("alexis.goelans@tdrive.app"); resources = await search("AleXis"); - expect(resources[0].email).toBe("alexis.goelans@twake.app"); + expect(resources[0].email).toBe("alexis.goelans@tdrive.app"); resources = await search("alex"); - expect(resources[0].email).toBe("alexis.goelans@twake.app"); + expect(resources[0].email).toBe("alexis.goelans@tdrive.app"); resources = await search("àlèXïs"); - expect(resources[0].email).toBe("alexis.goelans@twake.app"); + expect(resources[0].email).toBe("alexis.goelans@tdrive.app"); resources = await search("rbs"); - expect(resources[0].email).toBe("rbs@twake.app"); + expect(resources[0].email).toBe("rbs@tdrive.app"); - resources = await search("rbs@twake.app"); - expect(resources[0].email).toBe("rbs@twake.app"); + resources = await search("rbs@tdrive.app"); + expect(resources[0].email).toBe("rbs@tdrive.app"); resources = await search("bob", workspacePk2.company_id); expect(resources.length).toBe(1); - resources = await search("rbs@twake.app", workspacePk.company_id); - expect(resources[0].email).toBe("rbs@twake.app"); + resources = await search("rbs@tdrive.app", workspacePk.company_id); + expect(resources[0].email).toBe("rbs@tdrive.app"); - resources = await search("rbs@twake.app", uuidv1()); + resources = await search("rbs@tdrive.app", uuidv1()); expect(resources.length).toBe(0); done(); diff --git a/twake/backend/node/test/e2e/users/users.spec.ts b/twake/backend/node/test/e2e/users/users.spec.ts index a8c03130..742d6cf8 100644 --- a/twake/backend/node/test/e2e/users/users.spec.ts +++ b/twake/backend/node/test/e2e/users/users.spec.ts @@ -2,14 +2,7 @@ import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it } from import { init, TestPlatform } from "../setup"; import { TestDbService } from "../utils.prepare.db"; import { v1 as uuidv1 } from "uuid"; -import { CompanyLimitsEnum, UserObject } from "../../../src/services/user/web/types"; -import { ChannelVisibility } from "../../../src/services/channels/types"; -import gr from "../../../src/services/global-resolver"; -import { ResourceListResponse, Workspace } from "../../../src/utils/types"; -import { ChannelSaveOptions } from "../../../src/services/channels/web/types"; -import { createMessage, e2e_createThread } from "../messages/utils"; -import { deserialize } from "class-transformer"; -import { get as getChannelUtils } from "../channels/utils"; +import { CompanyLimitsEnum } from "../../../src/services/user/web/types"; describe("The /users API", () => { const url = "/internal/services/users/v1"; @@ -557,89 +550,4 @@ describe("The /users API", () => { }); }); }); - - describe("Recent contacts", () => { - it("should return list of recent contacts of user", async done => { - // api = new Api(platform); - const channelUtils = getChannelUtils(platform); - - await testDbService.createDefault(platform); - - const channels = []; - - for (let i = 0; i < 5; i++) { - // const channel = channelUtils.getChannel(); - const directChannelIn = channelUtils.getDirectChannel(); - - const nextUser = await testDbService.createUser( - [{ id: platform.workspace.workspace_id, company_id: platform.workspace.company_id }], - { firstName: "FirstName" + i, lastName: "LastName" + i }, - ); - - const members = [platform.currentUser.id, nextUser.id]; - const directWorkspace: Workspace = { - company_id: platform.workspace.company_id, - workspace_id: ChannelVisibility.DIRECT, - }; - await Promise.all([ - // gr.services.channels.channels.save(channel, {}, getContext()), - gr.services.channels.channels.save( - directChannelIn, - { - members, - }, - { - ...{ - workspace: platform.workspace, - user: platform.currentUser, - }, - ...{ workspace: directWorkspace }, - }, - ), - ]); - channels.push(directChannelIn); - } - - await new Promise(resolve => setTimeout(resolve, 1000)); - - await e2e_createThread( - platform, - [ - { - company_id: platform.workspace.company_id, - created_at: 0, - created_by: "", - id: channels[2].id, - type: "channel", - workspace_id: "direct", - }, - ], - createMessage({ text: "Some message" }), - ); - - await new Promise(resolve => setTimeout(resolve, 1000)); - - const jwtToken = await platform.auth.getJWTToken(); - - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${platform.workspace.company_id}/users/recent`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - }); - - expect(response.statusCode).toBe(200); - - const result: ResourceListResponse = deserialize( - ResourceListResponse, - response.body, - ); - - expect(result.resources.length).toEqual(5); - expect(result.resources[0].first_name).toEqual("FirstName2"); - - done(); - }); - }); }); diff --git a/twake/backend/node/test/e2e/utils.prepare.db.ts b/twake/backend/node/test/e2e/utils.prepare.db.ts index b8cdfa3c..f91d6bdf 100644 --- a/twake/backend/node/test/e2e/utils.prepare.db.ts +++ b/twake/backend/node/test/e2e/utils.prepare.db.ts @@ -15,8 +15,6 @@ import Repository from "../../src/core/platform/services/database/services/orm/r import Device from "../../src/services/user/entities/device"; import gr from "../../src/services/global-resolver"; -import { Channel } from "../../src/services/channels/entities"; -import { get as getChannelUtils } from "./channels/utils"; export type uuid = string; @@ -73,7 +71,7 @@ export class TestDbService { async createCompany(id?: uuid, name?: string): Promise { if (!name) { - name = `TwakeAutotests-test-company-${this.rand()}`; + name = `TdriveAutotests-test-company-${this.rand()}`; } this.company = await gr.services.companies.createCompany( getCompanyInstance({ @@ -88,7 +86,7 @@ export class TestDbService { async createWorkspace( workspacePk: WorkspacePrimaryKey, - name = `TwakeAutotests-test-workspace-${this.rand()}`, + name = `TdriveAutotests-test-workspace-${this.rand()}`, ): Promise { if (!workspacePk.company_id) throw new Error("company_id is not defined for workspace"); @@ -139,7 +137,7 @@ export class TestDbService { user.username_canonical = options.username || `test${random}`; user.first_name = options.firstName || `test${random}_first_name`; user.last_name = options.lastName || `test${random}_last_name`; - user.email_canonical = options.email || `test${random}@twake.app`; + user.email_canonical = options.email || `test${random}@tdrive.app`; user.identity_provider_id = user.id; user.cache = options.cache || user.cache || { companies: [] }; @@ -259,15 +257,4 @@ export class TestDbService { defaultWorkspace() { return this.workspaces[0].workspace; } - - async createChannel(userId): Promise { - const channelUtils = getChannelUtils(this.testPlatform); - const channel = channelUtils.getChannel(userId); - const creationResult = await gr.services.channels.channels.save( - channel, - {}, - channelUtils.getContext({ id: userId }), - ); - return creationResult.entity; - } } diff --git a/twake/backend/node/test/e2e/websocket/auth.spec.ts b/twake/backend/node/test/e2e/websocket/auth.spec.ts deleted file mode 100644 index 2326101c..00000000 --- a/twake/backend/node/test/e2e/websocket/auth.spec.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { afterEach, beforeEach, describe, it } from "@jest/globals"; -import { init, TestPlatform } from "../setup"; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore -import io from "socket.io-client"; - -describe("The Websocket authentication", () => { - let platform: TestPlatform; - let socket: SocketIOClient.Socket; - - beforeEach(async ends => { - platform = await init({ - services: [ - "webserver", - "database", - "search", - "storage", - "message-queue", - "user", - "websocket", - "webserver", - "applications", - "auth", - "realtime", - "channels" /* FIXME: platform is not started if a business service is not in dependencies */, - "counter", - "statistics", - "platform-services", - ], - }); - - socket = io.connect("http://localhost:3000", { path: "/socket" }); - - ends(); - }); - - afterEach(async ends => { - platform && (await platform.tearDown()); - platform = null; - socket && socket.close(); - socket = null; - ends(); - }); - - describe("JWT-based Authentication", () => { - it("should not be able to connect without a JWT token", done => { - socket.connect(); - socket.on("connect", () => { - socket - .emit("authenticate", {}) - .on("authenticated", () => { - done(new Error("Should not occur")); - }) - .on("unauthorized", (msg: any) => { - done(); - }); - }); - }); - - it("should not be able to connect with something which is not a JWT token", done => { - socket.connect(); - socket.on("connect", () => { - socket - .emit("authenticate", { token: "Not a JWT token" }) - .on("authenticated", () => { - done(new Error("Should not occur")); - }) - .on("unauthorized", (msg: any) => { - done(); - }); - }); - }); - - it("should be able to connect with a JWT token", async done => { - const token = await platform.auth.getJWTToken(); - - socket.connect(); - socket.on("connect", () => { - socket - .emit("authenticate", { token }) - .on("authenticated", () => { - done(); - }) - .on("unauthorized", () => { - done(new Error("Should not occur")); - }); - }); - }); - }); -}); diff --git a/twake/backend/node/test/e2e/websocket/realtime.spec.ts b/twake/backend/node/test/e2e/websocket/realtime.spec.ts deleted file mode 100644 index d5199328..00000000 --- a/twake/backend/node/test/e2e/websocket/realtime.spec.ts +++ /dev/null @@ -1,157 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it } from "@jest/globals"; -import { init, TestPlatform } from "../setup"; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore -import io from "socket.io-client"; - -describe("The Realtime API", () => { - let platform: TestPlatform; - let socket: SocketIOClient.Socket; - - beforeEach(async ends => { - platform = await init({ - services: [ - "webserver", - "database", - "search", - "storage", - "message-queue", - "applications", - "user", - "auth", - "websocket", - "realtime", - "channels" /* FIXME: platform is not started if a business service is not in dependencies */, - "counter", - "statistics", - "platform-services", - ], - }); - - socket = io.connect("http://localhost:3000", { path: "/socket" }); - - ends(); - }); - - afterEach(async ends => { - await platform.tearDown(); - platform = null; - socket && socket.close(); - socket = null; - - ends(); - }); - - describe("Joining rooms", () => { - it("should fail when token is not defined", async done => { - const token = await platform.auth.getJWTToken(); - const name = "/ping"; - - socket.on("connect", () => { - socket - .emit("authenticate", { token }) - .on("authenticated", () => { - socket.emit("realtime:join", { name }); - socket.on("realtime:join:error", (event: any) => { - expect(event.name).toEqual(name); - done(); - }); - socket.on("realtime:join:success", () => done(new Error("Should not occur"))); - }) - .on("unauthorized", () => { - done(new Error("Should not occur")); - }); - }); - }); - - it("should fail when token is not valid", async done => { - const token = await platform.auth.getJWTToken(); - const name = "/ping"; - const roomToken = "invalid token"; - - socket.on("connect", () => { - socket - .emit("authenticate", { token }) - .on("authenticated", () => { - socket.emit("realtime:join", { name, token: roomToken }); - socket.on("realtime:join:error", (event: any) => { - expect(event.name).toEqual(name); - done(); - }); - socket.on("realtime:join:success", () => done(new Error("Should not occur"))); - }) - .on("unauthorized", () => { - done(new Error("Should not occur")); - }); - }); - }); - - it("should receive a realtime:join:success when token is valid and room has been joined", async done => { - const token = await platform.auth.getJWTToken(); - const name = "test"; - const roomToken = "twake"; - - socket.on("connect", () => { - socket - .emit("authenticate", { token }) - .on("authenticated", () => { - socket.emit("realtime:join", { name, token: roomToken }); - socket.on("realtime:join:error", () => done(new Error("Should not occur"))); - socket.on("realtime:join:success", (event: any) => { - expect(event.name).toEqual(name); - done(); - }); - }) - .on("unauthorized", () => { - done(new Error("Should not occur")); - }); - }); - }); - }); - - describe("Leaving rooms", () => { - it("should not fail when room has not been joined first", async done => { - const token = await platform.auth.getJWTToken(); - const name = "roomtest"; - - socket.on("connect", () => { - socket - .emit("authenticate", { token }) - .on("authenticated", () => { - socket.emit("realtime:leave", { name }); - socket.on("realtime:leave:error", () => done(new Error("should not fail"))); - socket.on("realtime:leave:success", (event: any) => { - expect(event.name).toEqual(name); - done(); - }); - }) - .on("unauthorized", () => { - done(new Error("Should not occur")); - }); - }); - }); - - it("should send success when room has been joined first", async done => { - const token = await platform.auth.getJWTToken(); - const roomToken = "twake"; - const name = "roomtest"; - - socket.on("connect", () => { - socket - .emit("authenticate", { token }) - .on("authenticated", () => { - socket.emit("realtime:join", { name, token: roomToken }); - socket.emit("realtime:leave", { name }); - socket.on("realtime:leave:error", () => done(new Error("should not fail"))); - socket.on("realtime:leave:success", (event: any) => { - expect(event.name).toEqual(name); - done(); - }); - }) - .on("unauthorized", () => { - done(new Error("Should not occur")); - }); - }); - }); - }); -}); diff --git a/twake/backend/node/test/e2e/workspaces/workspace-users.spec.ts b/twake/backend/node/test/e2e/workspaces/workspace-users.spec.ts new file mode 100644 index 00000000..c70f2e83 --- /dev/null +++ b/twake/backend/node/test/e2e/workspaces/workspace-users.spec.ts @@ -0,0 +1,469 @@ +import { afterAll, beforeAll, describe, expect, it } from "@jest/globals"; +import { init, TestPlatform } from "../setup"; +import { TestDbService, uuid } from "../utils.prepare.db"; +import { v1 as uuidv1 } from "uuid"; + +describe("The /workspace users API", () => { + const url = "/internal/services/workspaces/v1"; + let platform: TestPlatform; + + let testDbService: TestDbService; + + const nonExistentId = uuidv1(); + let companyId = ""; + + const checkUserObject = (resource: any) => { + expect(resource).toMatchObject({ + id: expect.any(String), + company_id: expect.any(String), + workspace_id: expect.any(String), + user_id: expect.any(String), + created_at: expect.any(Number), + role: expect.stringMatching(/moderator|member/), + user: { + id: expect.any(String), + provider: expect.any(String), + provider_id: expect.any(String), + email: expect.any(String), + is_verified: expect.any(Boolean), + picture: expect.any(String), + first_name: expect.any(String), + last_name: expect.any(String), + created_at: expect.any(Number), + deleted: expect.any(Boolean), + status: expect.any(String), + last_activity: expect.any(Number), + }, + }); + }; + + beforeAll(async ends => { + platform = await init({ + services: [ + "database", + "message-queue", + "search", + "webserver", + "user", + "workspaces", + "applications", + "auth", + "console", + "counter", + "storage", + "statistics", + "platform-services", + ], + }); + + companyId = platform.workspace.company_id; + + await platform.database.getConnector().init(); + testDbService = new TestDbService(platform); + await testDbService.createCompany(companyId); + const ws0pk = { id: uuidv1(), company_id: companyId }; + const ws1pk = { id: uuidv1(), company_id: companyId }; + const ws2pk = { id: uuidv1(), company_id: companyId }; + const ws3pk = { id: uuidv1(), company_id: companyId }; + await testDbService.createWorkspace(ws0pk); + await testDbService.createWorkspace(ws1pk); + await testDbService.createWorkspace(ws2pk); + await testDbService.createWorkspace(ws3pk); + await testDbService.createUser([ws0pk, ws1pk]); + await testDbService.createUser([ws2pk], { companyRole: "admin" }); + await testDbService.createUser([ws2pk], { workspaceRole: "moderator" }); + await testDbService.createUser([ws2pk], { workspaceRole: "member" }); + await testDbService.createUser([ws2pk], { workspaceRole: "member" }); + await testDbService.createUser([], { companyRole: "member" }); + await testDbService.createUser([ws3pk], { companyRole: "guest", workspaceRole: "member" }); + ends(); + }); + + afterAll(async ends => { + await platform.tearDown(); + ends(); + }); + + describe("The GET /workspaces/users route", () => { + it("should 401 when not authenticated", async done => { + const companyId = testDbService.company.id; + + const response = await platform.app.inject({ + method: "GET", + url: `${url}/companies/${companyId}/workspaces/${nonExistentId}/users`, + }); + expect(response.statusCode).toBe(401); + done(); + }); + + it("should 404 when workspace not found", async done => { + const userId = testDbService.users[0].id; + + const jwtToken = await platform.auth.getJWTToken({ sub: userId }); + + const response = await platform.app.inject({ + method: "GET", + url: `${url}/companies/${companyId}/workspaces/${nonExistentId}/users`, + headers: { authorization: `Bearer ${jwtToken}` }, + }); + expect(response.statusCode).toBe(404); + done(); + }); + + it("should 200 when ok", async done => { + const companyId = testDbService.company.id; + const workspaceId = testDbService.workspaces[2].workspace.id; + const userId = testDbService.workspaces[2].users[0].id; + + const jwtToken = await platform.auth.getJWTToken({ sub: userId }); + const response = await platform.app.inject({ + method: "GET", + url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users`, + headers: { authorization: `Bearer ${jwtToken}` }, + }); + expect(response.statusCode).toBe(200); + + const resources = response.json()["resources"]; + + expect(resources.length).toBeGreaterThan(0); + + for (const resource of resources) { + checkUserObject(resource); + } + + done(); + }); + }); + + describe("The GET /workspaces/users/:user_id route", () => { + it("should 401 when not authenticated", async done => { + const companyId = testDbService.company.id; + const userId = testDbService.users[0].id; + + const response = await platform.app.inject({ + method: "GET", + url: `${url}/companies/${companyId}/workspaces/${nonExistentId}/users/${userId}`, + }); + expect(response.statusCode).toBe(401); + done(); + }); + + it("should 404 when workspace not found", async done => { + const userId = testDbService.users[0].id; + + const jwtToken = await platform.auth.getJWTToken({ sub: userId }); + + const response = await platform.app.inject({ + method: "GET", + url: `${url}/companies/${companyId}/workspaces/${nonExistentId}/users/${userId}`, + headers: { authorization: `Bearer ${jwtToken}` }, + }); + expect(response.statusCode).toBe(404); + done(); + }); + + it("should 200 when ok", async done => { + const companyId = testDbService.company.id; + const workspaceId = testDbService.workspaces[0].workspace.id; + const userId = testDbService.workspaces[0].users[0].id; + + const jwtToken = await platform.auth.getJWTToken({ sub: userId }); + const response = await platform.app.inject({ + method: "GET", + url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/${userId}`, + headers: { authorization: `Bearer ${jwtToken}` }, + }); + expect(response.statusCode).toBe(200); + + const resource = response.json()["resource"]; + checkUserObject(resource); + done(); + }); + }); + + describe("The POST /workspaces/users route (add)", () => { + it("should 401 when not authenticated", async done => { + const companyId = testDbService.company.id; + + const response = await platform.app.inject({ + method: "POST", + url: `${url}/companies/${companyId}/workspaces/${nonExistentId}/users`, + }); + expect(response.statusCode).toBe(401); + done(); + }); + + it("should 403 user is not workspace moderator", async done => { + const userId = testDbService.users[0].id; + const anotherUserId = testDbService.users[1].id; + const workspaceId = testDbService.workspaces[0].workspace.id; + + const jwtToken = await platform.auth.getJWTToken({ sub: userId }); + + const response = await platform.app.inject({ + method: "POST", + url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users`, + headers: { authorization: `Bearer ${jwtToken}` }, + payload: { + resource: { + user_id: anotherUserId, + role: "moderator", + }, + }, + }); + expect(response.statusCode).toBe(403); + done(); + }); + + it("should 400 when requested user not in company", async done => { + const companyId = testDbService.company.id; + const workspaceId = testDbService.workspaces[2].workspace.id; + const userId = testDbService.workspaces[2].users[1].id; + + const jwtToken = await platform.auth.getJWTToken({ sub: userId }); + const response = await platform.app.inject({ + method: "POST", + url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users`, + headers: { authorization: `Bearer ${jwtToken}` }, + payload: { + resource: { + user_id: nonExistentId, + role: "moderator", + }, + }, + }); + expect(response.statusCode).toBe(400); + done(); + }); + + it("should 201 when requested already in workspace (ignore)", async done => { + const companyId = testDbService.company.id; + const workspaceId = testDbService.workspaces[2].workspace.id; + const userId = testDbService.workspaces[2].users[1].id; + + const jwtToken = await platform.auth.getJWTToken({ sub: userId }); + const response = await platform.app.inject({ + method: "POST", + url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users`, + headers: { authorization: `Bearer ${jwtToken}` }, + payload: { + resource: { + user_id: userId, + role: "moderator", + }, + }, + }); + expect(response.statusCode).toBe(201); + done(); + }); + + it("should 200 when ok", async done => { + const companyId = testDbService.company.id; + const workspaceId = testDbService.workspaces[2].workspace.id; + const userId = testDbService.workspaces[2].users[1].id; + const anotherUserId = testDbService.workspaces[0].users[0].id; + + let workspaceUsersCount = await testDbService.getWorkspaceUsersCountFromDb(workspaceId); + let companyUsersCount = await testDbService.getCompanyUsersCountFromDb(companyId); + + console.log(testDbService.workspaces[2].users); + console.log(workspaceUsersCount); + + expect(workspaceUsersCount).toBe(4); + // expect(companyUsersCount).toBe(6); + + const jwtToken = await platform.auth.getJWTToken({ sub: userId }); + const response = await platform.app.inject({ + method: "POST", + url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users`, + headers: { authorization: `Bearer ${jwtToken}` }, + payload: { + resource: { + user_id: anotherUserId, + role: "moderator", + }, + }, + }); + + expect(response.statusCode).toBe(201); + const resource = response.json()["resource"]; + checkUserObject(resource); + + workspaceUsersCount = await testDbService.getWorkspaceUsersCountFromDb(workspaceId); + companyUsersCount = await testDbService.getCompanyUsersCountFromDb(companyId); + expect(workspaceUsersCount).toBe(5); + // expect(companyUsersCount).toBe(6); + + done(); + }); + }); + + describe("The POST /workspaces/users/:user_id route (update)", () => { + it("should 401 when not authenticated", async done => { + const companyId = testDbService.company.id; + const userId = testDbService.users[0].id; + + const response = await platform.app.inject({ + method: "POST", + url: `${url}/companies/${companyId}/workspaces/${nonExistentId}/users/${userId}`, + }); + expect(response.statusCode).toBe(401); + done(); + }); + + it("should 403 user is not workspace moderator", async done => { + const userId = testDbService.users[0].id; + const anotherUserId = testDbService.users[1].id; + const workspaceId = testDbService.workspaces[0].workspace.id; + + const jwtToken = await platform.auth.getJWTToken({ sub: userId }); + + const response = await platform.app.inject({ + method: "POST", + url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/${userId}`, + headers: { authorization: `Bearer ${jwtToken}` }, + payload: { + resource: { + user_id: anotherUserId, + role: "moderator", + }, + }, + }); + expect(response.statusCode).toBe(403); + done(); + }); + + it("should 404 when user not found in workspace", async done => { + const workspaceId = testDbService.workspaces[2].workspace.id; + const userId = testDbService.workspaces[2].users[1].id; + const anotherWorkspaceUserId = testDbService.workspaces[3].users[0].id; + const jwtToken = await platform.auth.getJWTToken({ sub: userId }); + + const response = await platform.app.inject({ + method: "POST", + url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/${anotherWorkspaceUserId}`, + headers: { authorization: `Bearer ${jwtToken}` }, + payload: { + resource: { + role: "moderator", + }, + }, + }); + + expect(response.statusCode).toBe(404); + done(); + }); + + it("should 200 when ok", async done => { + const companyId = testDbService.company.id; + const workspaceId = testDbService.workspaces[2].workspace.id; + const userId = testDbService.workspaces[2].users[1].id; + const anotherUserId = testDbService.workspaces[2].users[2].id; + + const jwtToken = await platform.auth.getJWTToken({ sub: userId }); + const response = await platform.app.inject({ + method: "POST", + url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/${anotherUserId}`, + headers: { authorization: `Bearer ${jwtToken}` }, + payload: { + resource: { + role: "moderator", + }, + }, + }); + + expect(response.statusCode).toBe(201); + const resource = response.json()["resource"]; + checkUserObject(resource); + + expect(resource["role"]).toBe("moderator"); + + const usersCount = await testDbService.getWorkspaceUsersCountFromDb(workspaceId); + expect(usersCount).toBe(5); + + done(); + }); + }); + + describe("The DELETE /workspaces/users/:user_id route", () => { + it("should 401 when not authenticated", async done => { + const companyId = testDbService.company.id; + const anotherUserId = testDbService.users[1].id; + + const response = await platform.app.inject({ + method: "DELETE", + url: `${url}/companies/${companyId}/workspaces/${nonExistentId}/users/${anotherUserId}`, + }); + expect(response.statusCode).toBe(401); + done(); + }); + + it("should 403 user is not workspace moderator", async done => { + const companyId = testDbService.company.id; + const workspaceId = testDbService.workspaces[2].workspace.id; + const userId = testDbService.workspaces[2].users[3].id; + const anotherUserId = testDbService.workspaces[2].users[1].id; + + const jwtToken = await platform.auth.getJWTToken({ sub: userId }); + + const response = await platform.app.inject({ + method: "DELETE", + url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/${anotherUserId}`, + headers: { authorization: `Bearer ${jwtToken}` }, + }); + + console.log(response.body); + + expect(response.statusCode).toBe(403); + done(); + }); + + it("should 404 when user not found in workspace", async done => { + const companyId = testDbService.company.id; + const workspaceId = testDbService.workspaces[2].workspace.id; + const userId = testDbService.workspaces[2].users[1].id; + + const jwtToken = await platform.auth.getJWTToken({ sub: userId }); + const response = await platform.app.inject({ + method: "DELETE", + url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/${nonExistentId}`, + headers: { authorization: `Bearer ${jwtToken}` }, + }); + + expect(response.statusCode).toBe(404); + + done(); + }); + + it("should 200 when ok", async done => { + const companyId = testDbService.company.id; + const workspaceId = testDbService.workspaces[2].workspace.id; + const userId = testDbService.workspaces[2].users[1].id; + const anotherUserId = testDbService.workspaces[2].users[2].id; + + const jwtToken = await platform.auth.getJWTToken({ sub: userId }); + let response = await platform.app.inject({ + method: "DELETE", + url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/${anotherUserId}`, + headers: { authorization: `Bearer ${jwtToken}` }, + }); + + expect(response.statusCode).toBe(204); + + response = await platform.app.inject({ + method: "GET", + url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users`, + headers: { authorization: `Bearer ${jwtToken}` }, + }); + + expect(response.statusCode).toBe(200); + const resources = response.json()["resources"]; + expect(resources.find((a: { user_id: uuid }) => a.user_id === anotherUserId)).toBeUndefined(); + + const usersCount = await testDbService.getWorkspaceUsersCountFromDb(workspaceId); + expect(usersCount).toBe(4); + + done(); + }); + }); +}); diff --git a/twake/backend/node/test/e2e/workspaces/workspaces.spec.ts b/twake/backend/node/test/e2e/workspaces/workspaces.spec.ts new file mode 100644 index 00000000..d251e304 --- /dev/null +++ b/twake/backend/node/test/e2e/workspaces/workspaces.spec.ts @@ -0,0 +1,513 @@ +import { afterAll, beforeAll, describe, expect, it } from "@jest/globals"; +import { init, TestPlatform } from "../setup"; +import { TestDbService } from "../utils.prepare.db"; +import { v1 as uuidv1 } from "uuid"; + +describe("The /workspaces API", () => { + const url = "/internal/services/workspaces/v1"; + let platform: TestPlatform; + + let testDbService: TestDbService; + + const nonExistentId = uuidv1(); + let companyId = ""; + + beforeAll(async ends => { + platform = await init({ + services: [ + "database", + "message-queue", + "webserver", + "user", + "search", + "workspaces", + "auth", + "console", + "counter", + "storage", + "applications", + "statistics", + "platform-services", + ], + }); + + companyId = platform.workspace.company_id; + + await platform.database.getConnector().init(); + testDbService = new TestDbService(platform); + await testDbService.createCompany(companyId); + const ws0pk = { id: uuidv1(), company_id: companyId }; + const ws1pk = { id: uuidv1(), company_id: companyId }; + const ws2pk = { id: uuidv1(), company_id: companyId }; + await testDbService.createWorkspace(ws0pk); + await testDbService.createWorkspace(ws1pk); + await testDbService.createWorkspace(ws2pk); + await testDbService.createUser([ws0pk, ws1pk]); + await testDbService.createUser([ws2pk], { companyRole: "admin" }); + await testDbService.createUser([ws2pk], { companyRole: undefined, workspaceRole: "moderator" }); + await testDbService.createUser([], { companyRole: "guest" }); + ends(); + }); + + afterAll(async ends => { + await platform.tearDown(); + ends(); + }); + + describe("The GET /workspaces/ route", () => { + it("should 401 when not authenticated", async done => { + const response = await platform.app.inject({ + method: "GET", + url: `${url}/companies/${nonExistentId}/workspaces`, + }); + expect(response.statusCode).toBe(401); + done(); + }); + + it("should 404 when company not found", async done => { + const userId = testDbService.workspaces[0].users[0].id; + + const jwtToken = await platform.auth.getJWTToken({ sub: userId }); + + const response = await platform.app.inject({ + method: "GET", + url: `${url}/companies/${nonExistentId}/workspaces`, + headers: { authorization: `Bearer ${jwtToken}` }, + }); + expect(response.statusCode).toBe(404); + done(); + }); + + it("should 200 when company belongs to user", async done => { + const userId = testDbService.workspaces[0].users[0].id; + + const jwtToken = await platform.auth.getJWTToken({ sub: userId }); + const companyId = testDbService.company.id; + const response = await platform.app.inject({ + method: "GET", + url: `${url}/companies/${companyId}/workspaces`, + headers: { authorization: `Bearer ${jwtToken}` }, + }); + expect(response.statusCode).toBe(200); + + const resources = response.json()["resources"]; + + expect(resources.length).toBe(2); + + for (const resource of resources) { + expect(resource).toMatchObject({ + id: expect.any(String), + company_id: expect.any(String), + name: expect.any(String), + logo: expect.any(String), + default: expect.any(Boolean), + archived: expect.any(Boolean), + role: expect.stringMatching(/moderator|member/), + }); + + if (resource.stats) { + expect(resource.stats).toMatchObject({ + created_at: expect.any(Number), + total_members: 1, + }); + } + } + + done(); + }); + }); + + describe("The GET /workspaces/:workspace_id route", () => { + it("should 401 when not authenticated", async done => { + const workspaceId = testDbService.workspaces[0].workspace.id; + + const response = await platform.app.inject({ + method: "GET", + url: `${url}/companies/${nonExistentId}/workspaces/${workspaceId}`, + }); + expect(response.statusCode).toBe(401); + done(); + }); + + it("should 404 when workspace not found", async done => { + const userId = testDbService.workspaces[0].users[0].id; + const jwtToken = await platform.auth.getJWTToken({ sub: userId }); + + const response = await platform.app.inject({ + method: "GET", + url: `${url}/companies/${companyId}/workspaces/${uuidv1()}`, + headers: { authorization: `Bearer ${jwtToken}` }, + }); + expect(response.statusCode).toBe(404); + done(); + }); + + it("should 403 when user not belong to workspace and not company_admin", async done => { + const workspaceId = testDbService.workspaces[2].workspace.id; + const userIdFromAnotherWorkspace = testDbService.workspaces[0].users[0].id; + + const jwtToken = await platform.auth.getJWTToken({ sub: userIdFromAnotherWorkspace }); + + const response = await platform.app.inject({ + method: "GET", + url: `${url}/companies/${companyId}/workspaces/${workspaceId}`, + headers: { authorization: `Bearer ${jwtToken}` }, + }); + expect(response.statusCode).toBe(403); + + expect(response.json()).toEqual({ + error: "Forbidden", + message: `You are not belong to workspace ${workspaceId}`, + statusCode: 403, + }); + + done(); + }); + + it("should 200 when user is company_admin", async done => { + const workspaceId = testDbService.workspaces[0].workspace.id; + const userIdFromAnotherWorkspace = testDbService.workspaces[2].users[0].id; + + const jwtToken = await platform.auth.getJWTToken({ sub: userIdFromAnotherWorkspace }); + + const response = await platform.app.inject({ + method: "GET", + url: `${url}/companies/${companyId}/workspaces/${workspaceId}`, + headers: { authorization: `Bearer ${jwtToken}` }, + }); + expect(response.statusCode).toBe(200); + + const resource = response.json()["resource"]; + + expect(resource).toMatchObject({ + id: expect.any(String), + company_id: expect.any(String), + name: expect.any(String), + logo: expect.any(String), + default: expect.any(Boolean), + archived: expect.any(Boolean), + }); + + if (resource.stats) { + expect(resource.stats).toMatchObject({ + created_at: expect.any(Number), + total_members: 1, + }); + } + + done(); + }); + + it("should 200 when user is belong to workspace", async done => { + const workspaceId = testDbService.workspaces[0].workspace.id; + const userIdFromThisWorkspace = testDbService.workspaces[0].users[0].id; + + const jwtToken = await platform.auth.getJWTToken({ sub: userIdFromThisWorkspace }); + + const response = await platform.app.inject({ + method: "GET", + url: `${url}/companies/${companyId}/workspaces/${workspaceId}`, + headers: { authorization: `Bearer ${jwtToken}` }, + }); + expect(response.statusCode).toBe(200); + + const resource = response.json()["resource"]; + + expect(resource).toMatchObject({ + id: expect.any(String), + company_id: expect.any(String), + name: expect.any(String), + logo: expect.any(String), + default: expect.any(Boolean), + archived: expect.any(Boolean), + role: expect.stringMatching(/moderator|member/), + }); + + if (resource.stats) { + expect(resource.stats).toMatchObject({ + created_at: expect.any(Number), + total_members: 1, + }); + } + + done(); + }); + }); + + // create + + describe("The POST /workspaces route (creating workspace)", () => { + it("should 401 when not authenticated", async done => { + const companyId = testDbService.company.id; + + const response = await platform.app.inject({ + method: "POST", + url: `${url}/companies/${companyId}/workspaces/${nonExistentId}`, + }); + expect(response.statusCode).toBe(401); + done(); + }); + + it("should 403 when user is not (company member or company admin) ", async done => { + const companyId = testDbService.company.id; + const userId = testDbService.users[3].id; + const jwtToken = await platform.auth.getJWTToken({ sub: userId }); + + const response = await platform.app.inject({ + method: "POST", + url: `${url}/companies/${companyId}/workspaces`, + headers: { authorization: `Bearer ${jwtToken}` }, + payload: { + resource: { + name: "Some channel name", + logo: "", + default: false, + }, + }, + }); + + expect(response.statusCode).toBe(403); + done(); + }); + + it("should 201 when workspace created well", async done => { + const companyId = testDbService.company.id; + const userId = testDbService.users[0].id; + const jwtToken = await platform.auth.getJWTToken({ sub: userId }); + + const response = await platform.app.inject({ + method: "POST", + url: `${url}/companies/${companyId}/workspaces`, + headers: { authorization: `Bearer ${jwtToken}` }, + payload: { + resource: { + name: "Random channel name", + logo: "logo", + default: false, + }, + }, + }); + + expect(response.statusCode).toBe(201); + + const resource = response.json()["resource"]; + + expect(resource).toMatchObject({ + id: expect.any(String), + company_id: expect.any(String), + name: expect.any(String), + logo: expect.any(String), + default: expect.any(Boolean), + archived: expect.any(Boolean), + role: expect.stringMatching(/moderator/), + }); + + done(); + }); + }); + + // update + + describe("The POST /workspaces/:workspace_id route (updating workspace)", () => { + it("should 401 when not authenticated", async done => { + const companyId = testDbService.company.id; + + const response = await platform.app.inject({ + method: "POST", + url: `${url}/companies/${companyId}/workspaces/${nonExistentId}`, + payload: { resource: {} }, + }); + expect(response.statusCode).toBe(401); + done(); + }); + + it("should 403 when not workspace not found", async done => { + const companyId = testDbService.company.id; + const userId = testDbService.workspaces[0].users[0].id; + + const jwtToken = await platform.auth.getJWTToken({ sub: userId }); + + const response = await platform.app.inject({ + method: "POST", + url: `${url}/companies/${companyId}/workspaces/${nonExistentId}`, + headers: { authorization: `Bearer ${jwtToken}` }, + payload: { resource: {} }, + }); + + expect(response.statusCode).toBe(403); + + done(); + }); + + it("should 403 when not belong to workspace", async done => { + const companyId = testDbService.company.id; + const workspaceId = testDbService.workspaces[1].workspace.id; + const userId = testDbService.workspaces[0].users[0].id; + + const jwtToken = await platform.auth.getJWTToken({ sub: userId }); + + const response = await platform.app.inject({ + method: "POST", + url: `${url}/companies/${companyId}/workspaces/${workspaceId}`, + headers: { authorization: `Bearer ${jwtToken}` }, + payload: { resource: {} }, + }); + + expect(response.statusCode).toBe(403); + + done(); + }); + + it("should 403 when not workspace moderator", async done => { + const companyId = testDbService.company.id; + const workspaceId = testDbService.workspaces[1].workspace.id; + const userId = testDbService.workspaces[0].users[0].id; + + const jwtToken = await platform.auth.getJWTToken({ sub: userId }); + + const response = await platform.app.inject({ + method: "POST", + url: `${url}/companies/${companyId}/workspaces/${workspaceId}`, + headers: { authorization: `Bearer ${jwtToken}` }, + payload: { resource: {} }, + }); + + expect(response.statusCode).toBe(403); + + done(); + }); + + it("should 200 when admin of company (full update)", async done => { + const companyId = testDbService.company.id; + const workspaceId = testDbService.workspaces[2].workspace.id; + const userId = testDbService.workspaces[2].users[0].id; // company owner + + const jwtToken = await platform.auth.getJWTToken({ sub: userId }); + + const response = await platform.app.inject({ + method: "POST", + url: `${url}/companies/${companyId}/workspaces/${workspaceId}`, + headers: { authorization: `Bearer ${jwtToken}` }, + payload: { + resource: { + name: "Another workspace name", + logo: "logo", + default: false, + archived: false, + }, + }, + }); + + expect(response.statusCode).toBe(200); + + const resource = response.json()["resource"]; + + expect(resource).toMatchObject({ + id: workspaceId, + company_id: companyId, + name: "Another workspace name", + logo: expect.any(String), + default: false, + archived: false, + role: "moderator", //Company admin is a moderator + }); + + done(); + }); + + it("should 200 when moderator of workspace (partial update)", async done => { + const companyId = testDbService.company.id; + const workspaceId = testDbService.workspaces[2].workspace.id; + const userId = testDbService.workspaces[2].users[1].id; // workspace admin + + const jwtToken = await platform.auth.getJWTToken({ sub: userId }); + + const response = await platform.app.inject({ + method: "POST", + url: `${url}/companies/${companyId}/workspaces/${workspaceId}`, + headers: { authorization: `Bearer ${jwtToken}` }, + payload: { + resource: { + name: "My awesome workspace", + default: true, + logo: "", + }, + }, + }); + + expect(response.statusCode).toBe(200); + + const resource = response.json()["resource"]; + + expect(resource).toMatchObject({ + id: workspaceId, + company_id: companyId, + name: "My awesome workspace", + logo: expect.any(String), + default: true, + archived: false, + role: "moderator", + }); + + done(); + }); + }); + + // delete + + describe("The DELETE /workspaces route", () => { + it("should 401 when not authenticated", async done => { + const companyId = testDbService.company.id; + + const response = await platform.app.inject({ + method: "DELETE", + url: `${url}/companies/${companyId}/workspaces/${nonExistentId}`, + }); + expect(response.statusCode).toBe(401); + done(); + }); + + it("should 403 when user is not (company member or company admin) ", async done => { + const companyId = testDbService.company.id; + const userId = testDbService.users[3].id; + const jwtToken = await platform.auth.getJWTToken({ sub: userId }); + const workspaceId = testDbService.workspaces[0].workspace.id; + + const response = await platform.app.inject({ + method: "DELETE", + url: `${url}/companies/${companyId}/workspaces/${workspaceId}`, + headers: { authorization: `Bearer ${jwtToken}` }, + }); + + expect(response.statusCode).toBe(403); + done(); + }); + + it("should 204 when workspace deleted", async done => { + const companyId = testDbService.company.id; + const workspaceId = testDbService.workspaces[2].workspace.id; + const userId = testDbService.workspaces[2].users[0].id; + const jwtToken = await platform.auth.getJWTToken({ sub: userId }); + + const response = await platform.app.inject({ + method: "DELETE", + url: `${url}/companies/${companyId}/workspaces/${workspaceId}`, + headers: { authorization: `Bearer ${jwtToken}` }, + }); + + expect(response.statusCode).toBe(204); + + const checkResponse = await platform.app.inject({ + method: "GET", + url: `${url}/companies/${companyId}/workspaces`, + headers: { authorization: `Bearer ${jwtToken}` }, + }); + + const checkResponseJson = checkResponse.json(); + + expect(checkResponseJson.resources.find((a: any) => a.id === workspaceId)).toBe(undefined); + + done(); + }); + }); +}); diff --git a/twake/backend/node/test/http/channel-as-read.http b/twake/backend/node/test/http/channel-as-read.http index 880d90d2..2ee7cdc0 100644 --- a/twake/backend/node/test/http/channel-as-read.http +++ b/twake/backend/node/test/http/channel-as-read.http @@ -22,9 +22,9 @@ Authorization: Bearer {{authToken}} { "resource": { "name": "My channel", - "icon": "twake logo", - "description": "This channel allow twake's team to chat easily", - "channel_group": "twake", + "icon": "tdrive logo", + "description": "This channel allow tdrive's team to chat easily", + "channel_group": "tdrive", "visibility": "public", "is_default": true, "archived": false diff --git a/twake/backend/node/test/http/channels.http b/twake/backend/node/test/http/channels.http index 29eb21bf..c665d84c 100644 --- a/twake/backend/node/test/http/channels.http +++ b/twake/backend/node/test/http/channels.http @@ -35,9 +35,9 @@ Authorization: Bearer {{authToken}} { "resource": { "name": "My channel", - "icon": "twake logo", - "description": "This channel allow twake's team to chat easily", - "channel_group": "twake", + "icon": "tdrive logo", + "description": "This channel allow tdrive's team to chat easily", + "channel_group": "tdrive", "visibility": "public", "is_default": true, "archived": false diff --git a/twake/backend/node/test/http/direct-channels.http b/twake/backend/node/test/http/direct-channels.http index ee436a2e..c3bbe15d 100644 --- a/twake/backend/node/test/http/direct-channels.http +++ b/twake/backend/node/test/http/direct-channels.http @@ -45,7 +45,7 @@ Authorization: Bearer {{authToken1}} "resource": { "icon": "hello", "description": "A direct channel", - "channel_group": "twake", + "channel_group": "tdrive", "is_default": false, "archived": false } diff --git a/twake/backend/node/test/http/private-channels-membership.http b/twake/backend/node/test/http/private-channels-membership.http index 12c75b2d..5b1fc3f1 100644 --- a/twake/backend/node/test/http/private-channels-membership.http +++ b/twake/backend/node/test/http/private-channels-membership.http @@ -30,9 +30,9 @@ Authorization: Bearer {{authTokenUser1}} { "resource": { "name": "My private channel", - "icon": "twake logo", - "description": "This channel allow twake's team to chat easily", - "channel_group": "twake", + "icon": "tdrive logo", + "description": "This channel allow tdrive's team to chat easily", + "channel_group": "tdrive", "visibility": "private", "is_default": true, "archived": false diff --git a/twake/backend/node/test/http/private-channels.http b/twake/backend/node/test/http/private-channels.http index 35dc682e..cbfecc4a 100644 --- a/twake/backend/node/test/http/private-channels.http +++ b/twake/backend/node/test/http/private-channels.http @@ -35,9 +35,9 @@ Authorization: Bearer {{authToken}} { "resource": { "name": "My private channel", - "icon": "twake logo", + "icon": "tdrive logo", "description": "A private channel", - "channel_group": "twake", + "channel_group": "tdrive", "visibility": "private", "is_default": true, "archived": false diff --git a/twake/backend/node/test/http/public-channels-membership.http b/twake/backend/node/test/http/public-channels-membership.http index ed8447f5..04123337 100644 --- a/twake/backend/node/test/http/public-channels-membership.http +++ b/twake/backend/node/test/http/public-channels-membership.http @@ -30,9 +30,9 @@ Authorization: Bearer {{authTokenUser1}} { "resource": { "name": "A public channel", - "icon": "twake logo", - "description": "This channel allow twake's team to chat easily", - "channel_group": "twake", + "icon": "tdrive logo", + "description": "This channel allow tdrive's team to chat easily", + "channel_group": "tdrive", "visibility": "public", "is_default": true, "archived": false diff --git a/twake/backend/node/test/http/tabs.http b/twake/backend/node/test/http/tabs.http index 1306d705..fcd432b4 100644 --- a/twake/backend/node/test/http/tabs.http +++ b/twake/backend/node/test/http/tabs.http @@ -29,9 +29,9 @@ Authorization: Bearer {{authToken}} { "resource": { "name": "My channel", - "icon": "twake logo", - "description": "This channel allow twake's team to chat easily", - "channel_group": "twake", + "icon": "tdrive logo", + "description": "This channel allow tdrive's team to chat easily", + "channel_group": "tdrive", "visibility": "public", "is_default": true, "archived": false diff --git a/twake/backend/node/test/unit/core/services/database/services/orm/connectors/cassandra/query-builder.test.ts b/twake/backend/node/test/unit/core/services/database/services/orm/connectors/cassandra/query-builder.test.ts index 62f111d6..d365e899 100644 --- a/twake/backend/node/test/unit/core/services/database/services/orm/connectors/cassandra/query-builder.test.ts +++ b/twake/backend/node/test/unit/core/services/database/services/orm/connectors/cassandra/query-builder.test.ts @@ -18,11 +18,11 @@ describe("The QueryBuilder module", () => { ChannelMemberNotificationPreference, filters, {}, - { keyspace: "twake" }, + { keyspace: "tdrive" }, ); expect(result).toEqual( - "SELECT * FROM twake.channel_members_notification_preferences WHERE company_id = comp1 AND channel_id = chan1;", + "SELECT * FROM tdrive.channel_members_notification_preferences WHERE company_id = comp1 AND channel_id = chan1;", ); }); @@ -37,11 +37,11 @@ describe("The QueryBuilder module", () => { { $lt: [["last_read", 1000]], }, - { keyspace: "twake" }, + { keyspace: "tdrive" }, ); expect(result).toEqual( - "SELECT * FROM twake.channel_members_notification_preferences WHERE company_id = comp1 AND channel_id = chan1 AND last_read < 1000;", + "SELECT * FROM tdrive.channel_members_notification_preferences WHERE company_id = comp1 AND channel_id = chan1 AND last_read < 1000;", ); }); @@ -55,11 +55,11 @@ describe("The QueryBuilder module", () => { ChannelMemberNotificationPreference, filters, {}, - { keyspace: "twake" }, + { keyspace: "tdrive" }, ); expect(result).toEqual( - "SELECT * FROM twake.channel_members_notification_preferences WHERE company_id = comp1 AND channel_id = chan1 AND user_id IN (u1,u2,u3);", + "SELECT * FROM tdrive.channel_members_notification_preferences WHERE company_id = comp1 AND channel_id = chan1 AND user_id IN (u1,u2,u3);", ); }); @@ -73,11 +73,11 @@ describe("The QueryBuilder module", () => { ChannelMemberNotificationPreference, filters, {}, - { keyspace: "twake" }, + { keyspace: "tdrive" }, ); expect(result).toEqual( - "SELECT * FROM twake.channel_members_notification_preferences WHERE company_id = comp1 AND channel_id = chan1;", + "SELECT * FROM tdrive.channel_members_notification_preferences WHERE company_id = comp1 AND channel_id = chan1;", ); }); }); diff --git a/twake/default-configuration/backend-node/production.json b/twake/default-configuration/backend-node/production.json index 0b421da1..e80f9365 100644 --- a/twake/default-configuration/backend-node/production.json +++ b/twake/default-configuration/backend-node/production.json @@ -24,7 +24,7 @@ "cassandra": { "contactPoints": ["scylladb:9042"], "localDataCenter": "datacenter1", - "keyspace": "twake", + "keyspace": "tdrive", "wait": false, "retries": 10, "delay": 200 diff --git a/twake/default-configuration/backend-node/production.json.template b/twake/default-configuration/backend-node/production.json.template index 34e9d24d..d5583fe0 100644 --- a/twake/default-configuration/backend-node/production.json.template +++ b/twake/default-configuration/backend-node/production.json.template @@ -26,7 +26,7 @@ "scylladb:9042" ], "localDataCenter": "datacenter1", - "keyspace": "twake", + "keyspace": "tdrive", "wait": false, "retries": 10, "delay": 200 diff --git a/twake/default-configuration/backend/Parameters.php b/twake/default-configuration/backend/Parameters.php index 24692b18..890ffef0 100644 --- a/twake/default-configuration/backend/Parameters.php +++ b/twake/default-configuration/backend/Parameters.php @@ -33,7 +33,7 @@ class Parameters extends \Common\Configuration "driver" => "pdo_cassandra", "host" => "scylladb", "port" => 9042, - "dbname" => "twake", + "dbname" => "tdrive", "user" => "root", "password" => "root", "encryption_key" => "ab63bb3e90c0271c9a1c06651a7c0967eab8851a7a897766", @@ -113,11 +113,11 @@ class Parameters extends \Common\Configuration "password" => "", "auth_mode" => "plain" ], - "template_dir" => "/src/Twake/Core/Resources/views/", - "twake_domain_url" => "https://twakeapp.com/", - "from" => "noreply@twakeapp.com", - "from_name" => "Twake", - "twake_address" => "Twake, 54000 Nancy, France", + "template_dir" => "/src/Tdrive/Core/Resources/views/", + "tdrive_domain_url" => "https://tdriveapp.com/", + "from" => "noreply@tdriveapp.com", + "from_name" => "Tdrive", + "tdrive_address" => "Tdrive, 54000 Nancy, France", "dkim" => [ "private_key" => "", "domain_name" => '', @@ -136,9 +136,9 @@ class Parameters extends \Common\Configuration //Defaults values for all clients but editable in database "defaults" => [ "applications" => [ - "twake_drive" => [ "default" => true ], //False to not install - "twake_calendar" => [ "default" => true ], - "twake_tasks" => [ "default" => true ], + "tdrive_drive" => [ "default" => true ], //False to not install + "tdrive_calendar" => [ "default" => true ], + "tdrive_tasks" => [ "default" => true ], "connectors" => [ "jitsi" => [ "default" => true ], ] @@ -146,7 +146,7 @@ class Parameters extends \Common\Configuration "connectors" => [ ], "branding" => [ - "name" => "Twake", + "name" => "Tdrive", "enable_newsletter" => false, /* "header" => [ diff --git a/twake/docker-compose.dev.tests.cassandra.yml b/twake/docker-compose.dev.tests.cassandra.yml index 0c9bd3b9..9147f31f 100644 --- a/twake/docker-compose.dev.tests.cassandra.yml +++ b/twake/docker-compose.dev.tests.cassandra.yml @@ -45,6 +45,6 @@ services: soft: -1 hard: -1 volumes: - - ./docker-data/es_twake:/usr/share/elasticsearch/data + - ./docker-data/es_tdrive:/usr/share/elasticsearch/data ports: - 9200:9200 diff --git a/twake/docker-compose.dev.yml b/twake/docker-compose.dev.yml index 627d80c6..e8754a3d 100644 --- a/twake/docker-compose.dev.yml +++ b/twake/docker-compose.dev.yml @@ -19,7 +19,7 @@ services: - DEV=dev - DB_DRIVER=cassandra - DB_CASSANDRA_URI=scylladb:9042 - - DB_CASSANDRA_KEYSPACE=twake + - DB_CASSANDRA_KEYSPACE=tdrive - PUBSUB_URLS=amqp://guest:guest@rabbitmq:5672 build: context: . @@ -65,6 +65,6 @@ services: volumes: - ./docker-data/logs/nginx/:/var/log/nginx - ./docker-data/letsencrypt/:/etc/letsencrypt/ - - ./frontend/:/twake-react/ - - ./docker-data/drive-preview/:/twake-core/web/medias/ - - ./docker-data/uploads/:/twake-core/web/upload/ + - ./frontend/:/tdrive-react/ + - ./docker-data/drive-preview/:/tdrive-core/web/medias/ + - ./docker-data/uploads/:/tdrive-core/web/upload/ diff --git a/twake/docker-compose.onpremise.yml b/twake/docker-compose.onpremise.yml index 7daf78fe..0de55b51 100644 --- a/twake/docker-compose.onpremise.yml +++ b/twake/docker-compose.onpremise.yml @@ -55,6 +55,6 @@ services: volumes: - ./docker-data/logs/nginx/:/var/log/nginx - ./docker-data/letsencrypt/:/etc/letsencrypt/ - - ./docker-data/drive-preview/:/twake-core/web/medias/ - - ./docker-data/uploads/:/twake-core/web/upload/ + - ./docker-data/drive-preview/:/tdrive-core/web/medias/ + - ./docker-data/uploads/:/tdrive-core/web/upload/ - ./docker-data/ssl:/etc/nginx/ssl diff --git a/twake/docker-compose.tests.yml b/twake/docker-compose.tests.yml index f598face..09c4eaf2 100644 --- a/twake/docker-compose.tests.yml +++ b/twake/docker-compose.tests.yml @@ -69,4 +69,4 @@ services: volumes: - ./docker-data/logs/nginx/:/var/log/nginx - ./docker-data/letsencrypt/:/etc/letsencrypt/ - - ./frontend/:/twake-react/ \ No newline at end of file + - ./frontend/:/tdrive-react/ \ No newline at end of file diff --git a/twake/docker/tdrive-frontend/Dockerfile b/twake/docker/tdrive-frontend/Dockerfile index ebcb2136..496be1ae 100755 --- a/twake/docker/tdrive-frontend/Dockerfile +++ b/twake/docker/tdrive-frontend/Dockerfile @@ -2,15 +2,15 @@ FROM node:lts AS build RUN yarn global add webpack webpack-cli -COPY frontend /twake-react/ +COPY frontend /tdrive-react/ -WORKDIR /twake-react/ +WORKDIR /tdrive-react/ ENV GENERATE_SOURCEMAP=false -RUN cp /twake-react/src/app/environment/environment.ts.dist /twake-react/src/app/environment/environment.ts && \ +RUN cp /tdrive-react/src/app/environment/environment.ts.dist /tdrive-react/src/app/environment/environment.ts && \ yarn install --network-timeout 1000000000 && \ - # cat /twake-react/src/app/environment/environment.ts.dist && \ - # cat /twake-react/src/app/environment/environment.ts && \ + # cat /tdrive-react/src/app/environment/environment.ts.dist && \ + # cat /tdrive-react/src/app/environment/environment.ts && \ yarn build && \ rm -rf node_modules @@ -21,7 +21,7 @@ COPY docker/tdrive-frontend/site.conf /etc/nginx/sites-available/site.template COPY docker/tdrive-frontend/redirect.conf /etc/nginx/sites-available/redirect COPY docker/tdrive-frontend/entrypoint.sh / COPY docker/tdrive-frontend/self-signed.sh /usr/local/bin/ -COPY --from=build /twake-react /twake-react +COPY --from=build /tdrive-react /tdrive-react RUN chmod +x /entrypoint.sh && rm /etc/nginx/conf.d/default.conf diff --git a/twake/docker/tdrive-frontend/entrypoint.sh b/twake/docker/tdrive-frontend/entrypoint.sh index 2d7ee37c..14c894ae 100755 --- a/twake/docker/tdrive-frontend/entrypoint.sh +++ b/twake/docker/tdrive-frontend/entrypoint.sh @@ -2,16 +2,16 @@ if [ "$1" = "dev" ] then - if test -f "/twake-react/src/app/environment/environment.ts"; then + if test -f "/tdrive-react/src/app/environment/environment.ts"; then echo "Configuration exists, doing nothing." else - cp /twake-react/src/app/environment/environment.ts.dist.dev /twake-react/src/app/environment/environment.ts + cp /tdrive-react/src/app/environment/environment.ts.dist.dev /tdrive-react/src/app/environment/environment.ts fi else if test -f "/configuration/environment.ts"; then - cp /configuration/environment.ts /twake-react/src/app/environment/environment.ts + cp /configuration/environment.ts /tdrive-react/src/app/environment/environment.ts else - cp /twake-react/src/app/environment/environment.ts.dist /twake-react/src/app/environment/environment.ts + cp /tdrive-react/src/app/environment/environment.ts.dist /tdrive-react/src/app/environment/environment.ts fi fi diff --git a/twake/docker/tdrive-frontend/self-signed.sh b/twake/docker/tdrive-frontend/self-signed.sh index b4412342..a5d33e66 100755 --- a/twake/docker/tdrive-frontend/self-signed.sh +++ b/twake/docker/tdrive-frontend/self-signed.sh @@ -19,7 +19,7 @@ SSL_SUBJ_COUNTRY="${SSL_SUBJ_COUNTRY:-FR}" SSL_SUBJ_STATE="${SSL_SUBJ_STATE:-Hauts-de-France}" SSL_SUBJ_LOCALITY="${SSL_SUBJ_LOCALITY:-Paris}" SSL_SUBJ_ORG="${SSL_SUBJ_ORG:-Linagora}" -SSL_SUBJ_ORG_UNIT="${SSL_SUBJ_ORG_UNIT:- Twake}" +SSL_SUBJ_ORG_UNIT="${SSL_SUBJ_ORG_UNIT:- Tdrive}" SSL_SUBJ_CN="${SSL_SUBJ_CN:-localhost}" SSL_SUBJECT="/C=${SSL_SUBJ_COUNTRY}/ST=${SSL_SUBJ_STATE}/L=${SSL_SUBJ_LOCALITY}/O=${SSL_SUBJ_ORG}/OU=${SSL_SUBJ_ORG_UNIT}/CN=${SSL_SUBJ_CN}" SSL_KEY_LENGTH=${SSL_KEY_LENGTH:-2048} diff --git a/twake/docker/tdrive-frontend/site.conf b/twake/docker/tdrive-frontend/site.conf index 12740940..6d742227 100644 --- a/twake/docker/tdrive-frontend/site.conf +++ b/twake/docker/tdrive-frontend/site.conf @@ -5,12 +5,12 @@ server { ssl_certificate_key /etc/nginx/ssl/selfsigned.key; server_name localhost; - root /twake-core/web; + root /tdrive-core/web; add_header Strict-Transport-Security "max-age=31536000"; location /.well-known { - alias /twake-react/build/.well-known/; + alias /tdrive-react/build/.well-known/; gzip on; gzip_disable "msie6"; @@ -53,7 +53,7 @@ server { application/xml application/rss+xml image/svg+xml; - alias /twake-react/build/; + alias /tdrive-react/build/; allow all; try_files $uri /index.html; } diff --git a/twake/frontend/package-lock.json b/twake/frontend/package-lock.json index 5b6b2e91..0ce7eeed 100644 --- a/twake/frontend/package-lock.json +++ b/twake/frontend/package-lock.json @@ -1,11 +1,11 @@ { - "name": "twake", + "name": "tdrive", "version": "2020.3.107", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "twake", + "name": "tdrive", "version": "2020.3.107", "license": "AGPL-3.0", "dependencies": { diff --git a/twake/frontend/package.json b/twake/frontend/package.json index 16d0d19d..daa9d873 100644 --- a/twake/frontend/package.json +++ b/twake/frontend/package.json @@ -1,7 +1,7 @@ { - "name": "twake", + "name": "tdrive", "version": "2020.3.107", - "repository": "https://github.com/Twake/Twake", + "repository": "https://github.com/Tdrive/Tdrive", "license": "AGPL-3.0", "scripts": { "dev:frontend": "craco start", diff --git a/twake/frontend/public/.well-known/apple-app-site-association b/twake/frontend/public/.well-known/apple-app-site-association index 180b1ea6..daeaab1c 100644 --- a/twake/frontend/public/.well-known/apple-app-site-association +++ b/twake/frontend/public/.well-known/apple-app-site-association @@ -3,7 +3,7 @@ "apps": [], "details": [ { - "appID": "KUT463DS29.com.linagora.ios.twake", + "appID": "KUT463DS29.com.linagora.ios.tdrive", "paths": [ "*" ] diff --git a/twake/frontend/public/.well-known/assetlinks.json b/twake/frontend/public/.well-known/assetlinks.json index e25c80ab..8b7b83a2 100644 --- a/twake/frontend/public/.well-known/assetlinks.json +++ b/twake/frontend/public/.well-known/assetlinks.json @@ -1 +1 @@ -[{"relation":["delegate_permission/common.handle_all_urls"],"target":{"namespace":"android_app","package_name":"com.twake.twake","sha256_cert_fingerprints":["E5:26:98:12:06:5D:7A:82:55:FA:19:0B:64:1D:EE:AC:7D:F8:BD:97:18:42:58:48:AB:E9:91:75:88:32:5C:03","3F:A6:0E:29:87:A4:0E:EA:12:02:16:8F:DA:76:86:22:F0:64:EB:2D:14:3D:6F:92:D6:F4:16:CB:DA:69:53:2C"]}}] +[{"relation":["delegate_permission/common.handle_all_urls"],"target":{"namespace":"android_app","package_name":"com.tdrive.tdrive","sha256_cert_fingerprints":["E5:26:98:12:06:5D:7A:82:55:FA:19:0B:64:1D:EE:AC:7D:F8:BD:97:18:42:58:48:AB:E9:91:75:88:32:5C:03","3F:A6:0E:29:87:A4:0E:EA:12:02:16:8F:DA:76:86:22:F0:64:EB:2D:14:3D:6F:92:D6:F4:16:CB:DA:69:53:2C"]}}] diff --git a/twake/frontend/public/index.html b/twake/frontend/public/index.html index 26e3785c..fff039d0 100644 --- a/twake/frontend/public/index.html +++ b/twake/frontend/public/index.html @@ -131,7 +131,7 @@