Skip to content

Commit

Permalink
Add delete sessions endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
bischofmax committed May 13, 2024
1 parent 247ab0d commit 9ba0f25
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 11 deletions.
12 changes: 10 additions & 2 deletions apps/server/src/infra/etherpad-client/etherpad-client.adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export class EtherpadClientAdapter {
private readonly authorApi: AuthorApi
) {}

public async getOrCreateAuthorId(userId: EntityId, username: string): Promise<AuthorId> {
public async getOrCreateAuthorId(userId: EntityId, username?: string): Promise<AuthorId> {
const response = await this.tryCreateAuthor(userId, username);
const user = this.handleEtherpadResponse<InlineResponse2003>(response, { userId });

Expand All @@ -40,7 +40,7 @@ export class EtherpadClientAdapter {
return authorId;
}

private async tryCreateAuthor(userId: string, username: string): Promise<AxiosResponse<InlineResponse2003>> {
private async tryCreateAuthor(userId: string, username?: string): Promise<AxiosResponse<InlineResponse2003>> {
try {
const response = await this.authorApi.createAuthorIfNotExistsForUsingGET(userId, username);

Expand Down Expand Up @@ -71,6 +71,14 @@ export class EtherpadClientAdapter {
return sessionId;
}

public async deleteSession(sessionId: SessionId) {
try {
await this.sessionApi.deleteSessionUsingPOST(sessionId);
} catch (error) {
throw EtherpadResponseMapper.mapResponseToException(EtherpadErrorType.CONNECTION_ERROR, { sessionId }, error);
}
}

private async tryCreateSession(
groupId: string,
authorId: string,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Authenticate, CurrentUser, ICurrentUser } from '@modules/authentication';
import { Controller, ForbiddenException, Get, NotFoundException, Param, Res } from '@nestjs/common';
import { Controller, Delete, ForbiddenException, Get, NotFoundException, Param, Res } from '@nestjs/common';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { ApiValidationError } from '@shared/common';
import { Response } from 'express';
Expand Down Expand Up @@ -30,13 +30,24 @@ export class CollaborativeTextEditorController {
getCollaborativeTextEditorForParentParams
);

res.cookie('sessionID', textEditor.sessions.toString(), {
res.cookie('sessionID', textEditor.sessionId, {
expires: textEditor.sessionExpiryDate,
secure: true,
path: textEditor.path,
});

Check warning

Code scanning / CodeQL

Sensitive server cookie exposed to the client Medium

Sensitive server cookie is missing 'httpOnly' flag.

const dto = CollaborativeTextEditorMapper.mapCollaborativeTextEditorToResponse(textEditor);

return dto;
}

@ApiOperation({ summary: 'Delete all etherpad sessions for user' })
@ApiResponse({ status: 200, type: CollaborativeTextEditorResponse })
@ApiResponse({ status: 400, type: ApiValidationError })
@ApiResponse({ status: 403, type: ForbiddenException })
@ApiResponse({ status: 404, type: NotFoundException })
@Delete('/delete-sessions')
async deleteSessionsByUser(@CurrentUser() currentUser: ICurrentUser): Promise<void> {
await this.collaborativeTextEditorUc.deleteSessionsByUser(currentUser.userId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ export class CollaborativeTextEditorUc {
return textEditor;
}

async deleteSessionsByUser(userId: string): Promise<void> {
const user = await this.authorizationService.getUserWithPermissions(userId);

await this.collaborativeTextEditorService.deleteSessionsByUser(user.id);
}

private async authorizeByParentType(params: GetCollaborativeTextEditorForParentParams, user: User) {
if (params.parentType === CollaborativeTextEditorParentType.BOARD_CONTENT_ELEMENT) {
await this.authorizeForContentElement(params, user);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { SessionId } from '@src/infra/etherpad-client/interface';

export interface CollaborativeTextEditor {
url: string;
sessions: string[];
path: string;
sessionId: SessionId;
sessionExpiryDate: Date;
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,13 @@ export class CollaborativeTextEditorService {
parentId,
sessionExpiryDate
);
const authorsSessionIds = await this.collaborativeTextEditorAdapter.listSessionIdsOfAuthor(authorId);

const url = this.buildPath(padId);
const uniqueSessionIds = this.removeDuplicateSessions([...authorsSessionIds, sessionId]);

return {
sessions: uniqueSessionIds,
sessionId,
url,
path: `/p/${padId}`,
sessionExpiryDate,
};
}
Expand All @@ -51,10 +50,13 @@ export class CollaborativeTextEditorService {
await this.collaborativeTextEditorAdapter.deleteGroup(groupId);
}

private removeDuplicateSessions(sessions: string[]): string[] {
const uniqueSessions = [...new Set(sessions)];
async deleteSessionsByUser(userId: string) {
const authorId = await this.collaborativeTextEditorAdapter.getOrCreateAuthorId(userId);
const sessionIds = await this.collaborativeTextEditorAdapter.listSessionIdsOfAuthor(authorId);

return uniqueSessions;
const promises = sessionIds.map((sessionId) => this.collaborativeTextEditorAdapter.deleteSession(sessionId));

await Promise.all(promises);
}

private buildSessionExpiryDate(): Date {
Expand Down

0 comments on commit 9ba0f25

Please sign in to comment.