Skip to content

Commit

Permalink
🛠 Fix canary 1802 (#1966)
Browse files Browse the repository at this point in the history
* Fix #1963

* Fix #1964

* Update invite token test
  • Loading branch information
RomaricMourgues authored Feb 18, 2022
1 parent 473720f commit 1752971
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 24 deletions.
5 changes: 2 additions & 3 deletions twake/backend/node/src/services/console/processing/merge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,7 @@ export class MergeProcess {
return progress$;
}

private getStreams(
concurrent: number = 1,
): {
private getStreams(concurrent: number = 1): {
// hot companies observable
companies$: Observable<CompanyCreatedStreamObject>;
// hot users observable
Expand Down Expand Up @@ -325,6 +323,7 @@ export class MergeProcess {
}),
skipInvite: true,
role,
inviterEmail: "",
},
);

Expand Down
2 changes: 1 addition & 1 deletion twake/backend/node/src/services/console/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export interface CreateConsoleUser {
password: string;
role: CompanyUserRole;
skipInvite: boolean;
inviterEmail?: string;
inviterEmail: string;
}

export interface CreateInternalUser {
Expand Down
16 changes: 12 additions & 4 deletions twake/backend/node/src/services/workspaces/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,19 @@ export interface WorkspaceServiceAPI
workspaceUserPk: WorkspacePendingUserPrimaryKey,
): Promise<DeleteResult<WorkspacePendingUserPrimaryKey>>;

getInviteToken(companyId: string, workspaceId: string): Promise<WorkspaceInviteTokenObject>;
createInviteToken(companyId: string, workspaceId: string): Promise<WorkspaceInviteTokenObject>;
deleteInviteToken(companyId: string, workspaceId: string): Promise<boolean>;
getInviteToken(
companyId: string,
workspaceId: string,
userId: string,
): Promise<WorkspaceInviteTokenObject>;
createInviteToken(
companyId: string,
workspaceId: string,
userId: string,
): Promise<WorkspaceInviteTokenObject>;
deleteInviteToken(companyId: string, workspaceId: string, userId: string): Promise<boolean>;
getInviteTokenInfo(jwtToken: string): Promise<WorkspaceInviteTokens>;

encodeInviteToken(companyId: string, workspaceId: string, token: string): string;
encodeInviteToken(companyId: string, workspaceId: string, userId: string, token: string): string;
decodeInviteToken(encodedToken: string): InviteTokenObject;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Column, Entity } from "../../../core/platform/services/database/service
export const TYPE = "workspace_invite_tokens";

@Entity(TYPE, {
primaryKey: [["company_id"], "workspace_id", "invite_token"],
primaryKey: [["company_id"], "workspace_id", "user_id", "invite_token"],
type: TYPE,
})
export default class WorkspaceInviteTokens {
Expand All @@ -14,13 +14,16 @@ export default class WorkspaceInviteTokens {
@Column("workspace_id", "string")
workspace_id: string;

@Column("user_id", "string")
user_id: string;

@Column("invite_token", "string")
invite_token: string;
}

export type WorkspaceInviteTokensPrimaryKey = Pick<
WorkspaceInviteTokens,
"company_id" | "workspace_id" | "invite_token"
"company_id" | "workspace_id" | "user_id" | "invite_token"
>;

export function getInstance(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -569,33 +569,39 @@ export class WorkspaceService implements WorkspaceServiceAPI {
async getInviteToken(
companyId: string,
workspaceId: string,
userId: string,
): Promise<WorkspaceInviteTokenObject> {
const pk = { company_id: companyId, workspace_id: workspaceId };
const pk = { company_id: companyId, workspace_id: workspaceId, user_id: userId };
const res = await this.workspaceInviteTokensRepository.findOne(pk);
if (!res) return null;

return {
token: this.encodeInviteToken(companyId, workspaceId, res.invite_token),
token: this.encodeInviteToken(companyId, workspaceId, userId, res.invite_token),
};
}

async createInviteToken(
companyId: string,
workspaceId: string,
userId: string,
): Promise<WorkspaceInviteTokenObject> {
await this.deleteInviteToken(companyId, workspaceId);
await this.deleteInviteToken(companyId, workspaceId, userId);
const token = randomBytes(32).toString("base64");
const pk = { company_id: companyId, workspace_id: workspaceId };
const pk = { company_id: companyId, workspace_id: workspaceId, user_id: userId };
await this.workspaceInviteTokensRepository.save(
getWorkspaceInviteTokensInstance({ ...pk, invite_token: token }),
);
return {
token: this.encodeInviteToken(companyId, workspaceId, token),
token: this.encodeInviteToken(companyId, workspaceId, userId, token),
};
}

async deleteInviteToken(companyId: string, workspaceId: string): Promise<boolean> {
const pk = { company_id: companyId, workspace_id: workspaceId };
async deleteInviteToken(
companyId: string,
workspaceId: string,
userId: string,
): Promise<boolean> {
const pk = { company_id: companyId, workspace_id: workspaceId, user_id: userId };
const currentRecord = await this.workspaceInviteTokensRepository.findOne(pk);
if (!currentRecord) {
return false;
Expand All @@ -617,23 +623,31 @@ export class WorkspaceService implements WorkspaceServiceAPI {
const pk: WorkspaceInviteTokensPrimaryKey = {
company_id: tokenInfo.c,
workspace_id: tokenInfo.w,
user_id: tokenInfo.u,
invite_token: tokenInfo.t,
};
return this.workspaceInviteTokensRepository.findOne(pk);
}

public encodeInviteToken(companyId: string, workspaceId: string, token: string) {
public encodeInviteToken(companyId: string, workspaceId: string, userId: string, token: string) {
// Change base64 characters to make them url safe
token = token.replace(/\+/g, ".").replace(/\//g, "_").replace(/=/g, "-");
const encodedToken = `${reduceUUID4(companyId)}-${reduceUUID4(workspaceId)}-${token}`;
const encodedToken = `${reduceUUID4(companyId)}-${reduceUUID4(workspaceId)}-${reduceUUID4(
userId,
)}-${token}`;
return encodedToken;
}

public decodeInviteToken(encodedToken: string): InviteTokenObject | null {
try {
let split = encodedToken.split("-");
//We split on "-" but the token can contain "-" so be careful
let [companyId, workspaceId, token] = [split.shift(), split.shift(), split.join("-")];
let [companyId, workspaceId, userId, token] = [
split.shift(),
split.shift(),
split.shift(),
split.join("-"),
];
if (!token) {
return;
}
Expand All @@ -642,6 +656,7 @@ export class WorkspaceService implements WorkspaceServiceAPI {
return {
c: expandUUID4(companyId),
w: expandUUID4(workspaceId),
u: expandUUID4(userId),
t: token,
};
} catch (e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export class WorkspaceInviteTokensCrudController
const res = await this.services.workspaces.getInviteToken(
context.company_id,
context.workspace_id,
context.user.id,
);

if (!res) {
Expand All @@ -62,6 +63,7 @@ export class WorkspaceInviteTokensCrudController
const res = await this.services.workspaces.createInviteToken(
context.company_id,
context.workspace_id,
context.user.id,
);

return {
Expand All @@ -84,6 +86,7 @@ export class WorkspaceInviteTokensCrudController
const deleted = await this.services.workspaces.deleteInviteToken(
context.company_id,
context.workspace_id,
context.user.id,
);

if (!deleted) {
Expand Down Expand Up @@ -134,6 +137,8 @@ export class WorkspaceInviteTokensCrudController
{ id: userId },
);
if (!companyUser) {
const inviter = await this.services.users.get({ id: entity.user_id });

const createdConsoleUser = await this.services.console
.getClient()
.addUserToCompany(
Expand All @@ -151,6 +156,7 @@ export class WorkspaceInviteTokensCrudController
},
role: "member",
skipInvite: true,
inviterEmail: inviter.email_canonical,
},
);
await this.services.console
Expand Down
1 change: 1 addition & 0 deletions twake/backend/node/src/services/workspaces/web/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ export interface WorkspaceInviteTokenObject {
export interface InviteTokenObject {
c: string;
w: string;
u: string;
t: string;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ describe("The /workspaces API (invite tokens)", () => {
const userId = testDbService.workspaces[0].users[0].id;
const companyId = testDbService.company.id;

await workspaceServicesAPI.workspaces.createInviteToken(companyId, workspaceId);
await workspaceServicesAPI.workspaces.createInviteToken(companyId, workspaceId, userId);

const jwtToken = await platform.auth.getJWTToken({ sub: userId });

Expand Down Expand Up @@ -340,7 +340,7 @@ describe("The /workspaces API (invite tokens)", () => {
const userId = testDbService.workspaces[0].users[0].id;
const companyId = testDbService.company.id;

await workspaceServicesAPI.workspaces.createInviteToken(companyId, workspaceId);
await workspaceServicesAPI.workspaces.createInviteToken(companyId, workspaceId, userId);

const jwtToken = await platform.auth.getJWTToken({ sub: userId });

Expand Down Expand Up @@ -403,7 +403,11 @@ describe("The /workspaces API (invite tokens)", () => {
companyId = testDbService.company.id;
workspaceId = testDbService.workspaces[0].workspace.id;
userId = testDbService.workspaces[2].users[0].id;
inviteToken = await workspaceServicesAPI.workspaces.createInviteToken(companyId, workspaceId);
inviteToken = await workspaceServicesAPI.workspaces.createInviteToken(
companyId,
workspaceId,
userId,
);
});
afterAll(shutdown);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,19 @@ export function usePublicOrPrivateChannels(): {
[companyId, workspaceId],
);

//Public channels
useRealtimeRoom<ChannelType[]>(
ChannelsMineAPIClient.websockets(companyId, workspaceId)[0],
'usePublicOrPrivateChannels',
'usePublicOrPrivateChannelsPublic',
(_action, _resource) => {
if (_action === 'saved') refresh();
},
);

//Private channels
useRealtimeRoom<ChannelType[]>(
ChannelsMineAPIClient.websockets(companyId, workspaceId)[1],
'usePublicOrPrivateChannelsPrivate',
(_action, _resource) => {
if (_action === 'saved') refresh();
},
Expand Down

0 comments on commit 1752971

Please sign in to comment.