Skip to content

Commit

Permalink
📘 Release notes (#1847)
Browse files Browse the repository at this point in the history
* Update changelog and readme

* Add build test to node backend test

* Fix ephemeral hook for deletion

* Fixed linebreak

* Make mentions works even without the id

* Update global indexes
  • Loading branch information
RomaricMourgues authored Dec 22, 2021
1 parent 224f83d commit 8db264c
Show file tree
Hide file tree
Showing 20 changed files with 134 additions and 34 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/backend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ jobs:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- name: build-test
run: cd twake && docker-compose -f docker-compose.tests.yml run -e NODE_OPTIONS=--unhandled-rejections=warn node npm run build
- name: unit-test
run: cd twake && docker-compose -f docker-compose.tests.yml run -e NODE_OPTIONS=--unhandled-rejections=warn node npm run test:unit
- name: e2e-mongo-test
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/saas-update-backend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ jobs:
deploy-php:
runs-on: ubuntu-20.04
steps:
- run: 'echo "DOCKERTAGVERSION=2021.Q4.846" >> $GITHUB_ENV'
- run: 'echo "DOCKERTAGVERSION=2021.Q4.860" >> $GITHUB_ENV'
- name: Set env to develop
if: endsWith(github.ref, '/develop')
run: 'echo "DOCKERTAG=develop" >> $GITHUB_ENV; echo "DOCKERTAGVERSION=2021.Q4.846" >> $GITHUB_ENV'
run: 'echo "DOCKERTAG=develop" >> $GITHUB_ENV; echo "DOCKERTAGVERSION=2021.Q4.860" >> $GITHUB_ENV'
- name: Set env to develop
if: endsWith(github.ref, '/qa')
run: 'echo "DOCKERTAG=qa" >> $GITHUB_ENV; echo "DOCKERTAGVERSION=2021.Q4.846" >> $GITHUB_ENV'
run: 'echo "DOCKERTAG=qa" >> $GITHUB_ENV; echo "DOCKERTAGVERSION=2021.Q4.860" >> $GITHUB_ENV'
- name: Set env to develop
if: endsWith(github.ref, '/canary')
run: 'echo "DOCKERTAG=canary" >> $GITHUB_ENV; echo "DOCKERTAGVERSION=${{ env.DOCKERTAGVERSION }}-canary" >> $GITHUB_ENV'
Expand All @@ -40,13 +40,13 @@ jobs:
deploy-node:
runs-on: ubuntu-20.04
steps:
- run: 'echo "DOCKERTAGVERSION=2021.Q4.846" >> $GITHUB_ENV'
- run: 'echo "DOCKERTAGVERSION=2021.Q4.860" >> $GITHUB_ENV'
- name: Set env to develop
if: endsWith(github.ref, '/develop')
run: 'echo "DOCKERTAG=develop" >> $GITHUB_ENV; echo "DOCKERTAGVERSION=2021.Q4.846" >> $GITHUB_ENV'
run: 'echo "DOCKERTAG=develop" >> $GITHUB_ENV; echo "DOCKERTAGVERSION=2021.Q4.860" >> $GITHUB_ENV'
- name: Set env to develop
if: endsWith(github.ref, '/qa')
run: 'echo "DOCKERTAG=qa" >> $GITHUB_ENV; echo "DOCKERTAGVERSION=2021.Q4.846" >> $GITHUB_ENV'
run: 'echo "DOCKERTAG=qa" >> $GITHUB_ENV; echo "DOCKERTAGVERSION=2021.Q4.860" >> $GITHUB_ENV'
- name: Set env to develop
if: endsWith(github.ref, '/canary')
run: 'echo "DOCKERTAG=canary" >> $GITHUB_ENV; echo "DOCKERTAGVERSION=${{ env.DOCKERTAGVERSION }}-canary" >> $GITHUB_ENV'
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/saas-update-front.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ jobs:
runs-on: ubuntu-20.04
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/qa' || github.ref == 'refs/heads/canary'
steps:
- run: 'echo "DOCKERTAGVERSION=2021.Q4.846" >> $GITHUB_ENV'
- run: 'echo "DOCKERTAGVERSION=2021.Q4.860" >> $GITHUB_ENV'
- name: Set env to develop
if: endsWith(github.ref, '/develop')
run: 'echo "DOCKERTAG=develop" >> $GITHUB_ENV; echo "DOCKERTAGVERSION=2021.Q4.846" >> $GITHUB_ENV'
run: 'echo "DOCKERTAG=develop" >> $GITHUB_ENV; echo "DOCKERTAGVERSION=2021.Q4.860" >> $GITHUB_ENV'
- name: Set env to develop
if: endsWith(github.ref, '/qa')
run: 'echo "DOCKERTAG=qa" >> $GITHUB_ENV; echo "DOCKERTAGVERSION=2021.Q4.846" >> $GITHUB_ENV'
run: 'echo "DOCKERTAG=qa" >> $GITHUB_ENV; echo "DOCKERTAGVERSION=2021.Q4.860" >> $GITHUB_ENV'
- name: Set env to develop
if: endsWith(github.ref, '/canary')
run: 'echo "DOCKERTAG=canary" >> $GITHUB_ENV; echo "DOCKERTAGVERSION=${{ env.DOCKERTAGVERSION }}-canary" >> $GITHUB_ENV'
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Or run your own local Twake instance with :
cd twake
sudo ./start.sh
```

Twake will be running on http//localhost and by default redirect to https and uses a self-signed certificate. If you want to run http only then set SSL_CERTS=none at docker-compose.yml

## Documentation
Expand Down Expand Up @@ -61,9 +62,9 @@ Everyone can contribute at their own level, even if they only give a few minutes
Install Twake on your machine with docker-compose using the install documentation here :
[doc.twake.app/installation](https://doc.twake.app/installation)

### Migration to 2021.Q1.385
`cd twake; docker-compose -f docker-compose.onpremise.mongo.yml up -d`

If you migrate to the 2021.Q1 version for a 2020.Q4 version or earlier, please follow the documentation at https://github.com/Twake/Twake/tree/main/migration/2020Q3_to_2020Q4
Twake will be available on port 3000.

## License

Expand Down
23 changes: 23 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
# Twake 2021.Q4.860

### Messages

- Improved message top right menu
- Fixed message sending / edition / reaction / pinned etc, now instant ⚡️
- User availability indicator 🟢
- User is writing indicator

### Workspace parameters

- Improved integrations management page 🧹
- Improved workspace users management page 🧹
- Improved workspace preferences management page 🧹

### General

- A lot of bug fixed, more to come on the 22 of January 🐞
- Improved Twake loading time (still in progress) ⏰
- New state management ( recoiljs.org ) on everything except channels and channels members
- Everything except Drive Tasks and Calendar was migrated to node backend 🧹
- Twake is now working with a simplified docker-compose with only node + mongodb. Note that this works only with messages (no Drive, Calendar or Tasks yet) 🚀

# Twake 2021.Q3.640

### Messages
Expand Down
6 changes: 3 additions & 3 deletions twake/backend/core/src/Twake/Core/Controller/Version.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ function getVersion(Request $request)
"auth_mode" => array_keys($auth),
"auth" => $auth,
"version" => [
"current" => /* @VERSION_DETAIL */ "2021.Q4.846",
"current" => /* @VERSION_DETAIL */ "2021.Q4.860",
"minimal" => [
"web" => /* @MIN_VERSION_WEB */ "2021.Q4.846",
"mobile" => /* @MIN_VERSION_MOBILE */ "2021.Q4.846",
"web" => /* @MIN_VERSION_WEB */ "2021.Q4.860",
"mobile" => /* @MIN_VERSION_MOBILE */ "2021.Q4.860",
]
],
"elastic_search_available" => !!$this->container->getParameter("es.host"),
Expand Down
2 changes: 1 addition & 1 deletion twake/backend/node/src/services/console/clients/remote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ export class ConsoleRemoteClient implements ConsoleServiceClient {
}

user = getInstance({});
user.username_canonical = username;
user.username_canonical = (username || "").toLocaleLowerCase();
user.email_canonical = userDTO.email;
user.deleted = false;
}
Expand Down
2 changes: 1 addition & 1 deletion twake/backend/node/src/services/console/web/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export class ConsoleController {
first_name: request.body.first_name,
last_name: request.body.last_name,
email_canonical: email,
username_canonical: email.replace("@", "."),
username_canonical: (email.replace("@", ".") || "").toLocaleLowerCase(),
});
const user = await this.userService.users.create(newUser);
await this.userService.users.setPassword({ id: user.entity.id }, request.body.password);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ export class MessageToNotificationsProcessor {
text = `${senderName}: ${text}`;
}

const mentions = getMentions(messageResource);
const mentions = await getMentions(messageResource, async (username: string) => {
return await this.user.users.getByUsername(username);
});

const messageEvent: MessageNotification = {
company_id: participant.company_id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,9 @@ export class ThreadMessagesService implements MessageThreadMessagesServiceAPI {
let ids: string[] = [];
if (message.user_id) ids.push(message.user_id);
if (message.pinned_info?.pinned_by) ids.push(message.pinned_info?.pinned_by);
const mentions = getMentions(message);
const mentions = await getMentions(message, async (username: string) => {
return await this.user.users.getByUsername(username);
});
for (const mentionedUser of mentions.users) {
ids.push(mentionedUser);
}
Expand Down
25 changes: 23 additions & 2 deletions twake/backend/node/src/services/messages/services/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { FindOptions } from "../../../core/platform/services/database/services/o
import { Pagination } from "../../../core/platform/framework/api/crud-service";
import { Message } from "../entities/messages";
import { specialMention } from "../types";
import User from "../../../services/user/entities/user";

export const buildMessageListPagination = (
pagination: Pagination,
Expand All @@ -16,14 +17,34 @@ export const buildMessageListPagination = (
};
};

export const getMentions = (messageResource: Message) => {
export const getMentions = async (
messageResource: Message,
findByUsername: (username: string) => Promise<User>,
) => {
let idsFromUsernames = [];
try {
const usersNoIdOutput = (messageResource.text || "").match(/( |^)@[a-zA-Z0-9-_.]+/gm);
const usernames = (usersNoIdOutput || []).map(u => (u || "").trim().split("@").pop());
for (const username of usernames) {
if (!"all|here|channel|everyone".split("|").includes(username)) {
const user = await findByUsername(username);
if (user) idsFromUsernames.push(user.id);
}
}
} catch (err) {
console.log(err);
}

const usersOutput = (messageResource.text || "").match(/@[^: ]+:([0-f-]{36})/gm);
const globalOutput = (messageResource.text || "").match(
/(^| )@(all|here|channel|everyone)([^a-z]|$)/gm,
);

return {
users: (usersOutput || []).map(u => (u || "").trim().split(":").pop()),
users: [
...(usersOutput || []).map(u => (u || "").trim().split(":").pop()),
...idsFromUsernames,
],
specials: (globalOutput || []).map(g => (g || "").trim().split("@").pop()) as specialMention[],
};
};
1 change: 1 addition & 0 deletions twake/backend/node/src/services/user/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export interface UsersServiceAPI
context?: ExecutionContext,
): Promise<ListResult<User>>;

getByUsername(username: string): Promise<User>;
getByEmail(email: string): Promise<User>;
getByEmails(email: string[]): Promise<User[]>;
getByConsoleId(consoleUserId: string): Promise<User>;
Expand Down
2 changes: 1 addition & 1 deletion twake/backend/node/src/services/user/entities/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const TYPE = "user";

@Entity(TYPE, {
primaryKey: [["id"]],
globalIndexes: [["email_canonical"]],
globalIndexes: [["email_canonical"], ["username_canonical"]],
type: TYPE,
search,
})
Expand Down
16 changes: 12 additions & 4 deletions twake/backend/node/src/services/user/services/users/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ export class UserService implements UsersServiceAPI {
if (user.identity_provider_id && !user.identity_provider) user.identity_provider = "console";
if (user.email_canonical) user.email_canonical = user.email_canonical.toLocaleLowerCase();
if (user.username_canonical)
user.username_canonical = user.username_canonical.toLocaleLowerCase();
user.username_canonical = (user.username_canonical || "")
.toLocaleLowerCase()
.replace(/[^a-z0-9_-]/, "");
}

async create(user: User): Promise<CreateResult<User>> {
Expand Down Expand Up @@ -204,6 +206,12 @@ export class UserService implements UsersServiceAPI {
return await this.repository.findOne(pk);
}

async getByUsername(username: string): Promise<User> {
return await this.repository.findOne({
username_canonical: (username || "").toLocaleLowerCase(),
});
}

async getByConsoleId(id: string, service_id: string = "console"): Promise<User> {
const extUser = await this.extUserRepository.findOne({ service_id, external_id: id });
if (!extUser) {
Expand All @@ -220,17 +228,17 @@ export class UserService implements UsersServiceAPI {
return this.repository.findOne({ email_canonical: email }).then(user => Boolean(user));
}
async getAvailableUsername(username: string): Promise<string> {
const users = await this.repository.find({}).then(a => a.getEntities());
const user = await this.getByUsername(username);

if (!users.find(user => user.username_canonical == username.toLocaleLowerCase())) {
if (!user) {
return username;
}

let suitableUsername = null;

for (let i = 1; i < 1000; i++) {
const dynamicUsername = username + i;
if (!users.find(user => user.username_canonical == dynamicUsername.toLocaleLowerCase())) {
if (!(await this.getByUsername(dynamicUsername.toLocaleLowerCase()))) {
suitableUsername = dynamicUsername;
break;
}
Expand Down
6 changes: 3 additions & 3 deletions twake/backend/node/src/version.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export default {
current: /* @VERSION_DETAIL */ "2021.Q4.846",
current: /* @VERSION_DETAIL */ "2021.Q4.860",
minimal: {
web: /* @MIN_VERSION_WEB */ "2021.Q4.846",
mobile: /* @MIN_VERSION_MOBILE */ "2021.Q4.846",
web: /* @MIN_VERSION_WEB */ "2021.Q4.860",
mobile: /* @MIN_VERSION_MOBILE */ "2021.Q4.860",
},
};
28 changes: 28 additions & 0 deletions twake/docker-compose.onpremise.mongo.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
version: "3.4"

services:
mongo:
container_name: mongo
image: mongo
volumes:
- ./docker-data/mongo:/data/db

node:
image: twaketech/twake-node
ports:
- 3000:3000
environment:
- DEV=production
- SEARCH_DRIVER=mongodb
- DB_DRIVER=mongodb
- PUBSUB_TYPE=local
build:
context: .
dockerfile: ./docker/twake-node/Dockerfile
target: development
volumes:
- ./docker-data/documents/:/storage/
depends_on:
- mongo
links:
- mongo
2 changes: 1 addition & 1 deletion twake/frontend/src/app/environment/version.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export default {
version: /* @VERSION */ '2021.Q4',
version_detail: /* @VERSION_DETAIL */ '2021.Q4.846',
version_detail: /* @VERSION_DETAIL */ '2021.Q4.860',
version_name: /* @VERSION_NAME */ 'Albatros',
};
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ export default React.memo((props: Props) => {
},
}}
>
{props.fallback}
{(props.fallback || '')
//Fix markdown simple line break
.replace(/\n/g, '&nbsp; \n')}
</Markdown>
</div>
) : (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,20 @@ import { useRealtimeRoom } from 'app/services/Realtime/useRealtime';
import CurrentUser from 'app/services/user/CurrentUser';
import _ from 'lodash';
import { useState } from 'react';
import { atomFamily, useRecoilCallback, useRecoilState } from 'recoil';
import { AtomChannelKey } from '../../atoms/Messages';
import { useSetMessage } from './useMessage';

const EphemeralMessageState = atomFamily<NodeMessage | null, AtomChannelKey>({
key: 'EphemeralMessageState',
default: key => null,
});

export const useEphemeralMessages = (key: AtomChannelKey) => {
const [lastEphemeral, setLastEphemeral] = useState<NodeMessage | null>(null);
const [lastEphemeral, setLastEphemeral] = useRecoilState(EphemeralMessageState(key));
const getLastEphemeral = useRecoilCallback(({ snapshot }) => (key: AtomChannelKey) => {
return snapshot.getLoadable(EphemeralMessageState(key)).valueMaybe();
});
const setMessage = useSetMessage(key.companyId);

useRealtimeRoom<MessageWithReplies>(
Expand All @@ -17,6 +26,7 @@ export const useEphemeralMessages = (key: AtomChannelKey) => {
async (action: string, event: any) => {
if (action === 'created' || action === 'updated') {
const message = event as NodeMessage;
const lastEphemeral = getLastEphemeral(key);
if (message.ephemeral) {
if (
message.subtype === 'deleted' &&
Expand Down
6 changes: 3 additions & 3 deletions twake/update_version.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
const versions = {
VERSION_NAME: process.env.TWAKE_VERSION_NAME || "Albatros",
VERSION: process.env.TWAKE_VERSION || "2021.Q4",
VERSION_DETAIL: process.env.TWAKE_VERSION_DETAIL || "2021.Q4.846",
MIN_VERSION_WEB: process.env.TWAKE_MIN_VERSION_WEB || "2021.Q4.846",
MIN_VERSION_MOBILE: process.env.TWAKE_MIN_VERSION_MOBILE || "2021.Q4.846",
VERSION_DETAIL: process.env.TWAKE_VERSION_DETAIL || "2021.Q4.860",
MIN_VERSION_WEB: process.env.TWAKE_MIN_VERSION_WEB || "2021.Q4.860",
MIN_VERSION_MOBILE: process.env.TWAKE_MIN_VERSION_MOBILE || "2021.Q4.860",
};

const files = [
Expand Down

0 comments on commit 8db264c

Please sign in to comment.