Skip to content

Commit

Permalink
🐛Fixed bug with ability to log in with revoked session
Browse files Browse the repository at this point in the history
  • Loading branch information
shepilov committed May 30, 2024
1 parent d44174b commit 9026900
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 10 deletions.
10 changes: 8 additions & 2 deletions tdrive/backend/node/src/services/console/clients/remote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,9 @@ export class ConsoleRemoteClient implements ConsoleServiceClient {
sid: sessionInfo.sid,
});
if (existingSession) {
if (existingSession.revoked_at) {
throw CrudException.unauthorized(`Session ${sessionInfo.sid} expired`);
}
return existingSession.sid;
} else {
const sessionBody = new Session();
Expand Down Expand Up @@ -320,7 +323,8 @@ export class ConsoleRemoteClient implements ConsoleServiceClient {
const sessionRepository = gr.services.console.getSessionRepo();
const session = await sessionRepository.findOne({ sid: payload.claims.sid });
if (session) {
await sessionRepository.remove(session);
session.revoked_at = new Date().getTime();
await sessionRepository.save(session);
}
}

Expand All @@ -332,7 +336,9 @@ export class ConsoleRemoteClient implements ConsoleServiceClient {
});
if (!session) {
// fail for not matching session id
throw new Error("Invalid session id");
throw new Error(`Session ${sid} not found`);
} else if (session.revoked_at > 0) {
throw new Error(`Session ${sid} revoked`);
}
} else {
// fail for missing session id
Expand Down
5 changes: 4 additions & 1 deletion tdrive/backend/node/src/services/console/entities/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export const TYPE = "session";

@Entity(TYPE, {
primaryKey: [["company_id"], "sid"],
globalIndexes: [["sid"]],
globalIndexes: [["sid"], ["revoked_at"]],
type: TYPE,
})
export default class Session {
Expand All @@ -17,6 +17,9 @@ export default class Session {

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

@Column("revoked_at", "number")
revoked_at: number;
}

export type UserSessionPrimaryKey = Pick<Session, "sid">;
Expand Down
9 changes: 3 additions & 6 deletions tdrive/backend/node/test/e2e/common/user-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export default class UserApi {
this.jwt = await this.doLogin();
}

private async doLogin() {
public async doLogin() {
const loginResponse = await this.login();

expect(loginResponse).toBeDefined();
Expand Down Expand Up @@ -133,13 +133,10 @@ export default class UserApi {
verifierMock.mockImplementation(() => {
return Promise.resolve(payload); // Return the predefined payload
});
const logoutToken = "logout_token_rsa256";

const response = await this.api.post("/internal/services/console/v1/backchannel_logout", {
logout_token: logoutToken,
return await this.api.post("/internal/services/console/v1/backchannel_logout", {
logout_token: "logout_token_rsa256",
});

return response;
}


Expand Down
32 changes: 31 additions & 1 deletion tdrive/backend/node/test/e2e/console/backchannel-logout.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ describe("The /backchannel_logout API", () => {

// Verify the session is removed from the database
const deletedSession = await currentUser.dbService.getSessionById(currentUser.session);
expect(deletedSession).toBeNull();
expect(deletedSession).not.toBeNull();
expect(deletedSession.revoked_at).toBeGreaterThan(0);
});

it("should create a session on login", async () => {
Expand All @@ -82,6 +83,35 @@ describe("The /backchannel_logout API", () => {
expect(response.statusCode).toBe(401);
});

it("should receive 401 after logout and try to login one more time with the same token", async () => {
//when
await currentUser.logout();

//then
const response = await currentUser.login(currentUser.session);
expect(response.statusCode).toBe(401);
});

it("should receive 401 after logout successfully after logout", async () => {
//given
const myDriveId = "user_" + currentUser.user.id;
let response = await currentUser.getDocument(myDriveId);
expect(response.statusCode).toBe(200);

//when
await currentUser.logout();

//then
response = await currentUser.login(currentUser.session);
expect(response.statusCode).toBe(401);

currentUser.jwt = await currentUser.doLogin();


response = await currentUser.getDocument(myDriveId);
expect(response.statusCode).toBe(200);
});

it("should be able to log-in several times by having multiple sessions", async () => {
// Perform a second login
const newUserSession = await UserApi.getInstance(platform);
Expand Down

0 comments on commit 9026900

Please sign in to comment.