🐛Fixed bug with ability to log in with revoked session
This commit is contained in:
committed by
Anton Shepilov
parent
d44174b7b1
commit
9026900005
@@ -265,6 +265,9 @@ export class ConsoleRemoteClient implements ConsoleServiceClient {
|
|||||||
sid: sessionInfo.sid,
|
sid: sessionInfo.sid,
|
||||||
});
|
});
|
||||||
if (existingSession) {
|
if (existingSession) {
|
||||||
|
if (existingSession.revoked_at) {
|
||||||
|
throw CrudException.unauthorized(`Session ${sessionInfo.sid} expired`);
|
||||||
|
}
|
||||||
return existingSession.sid;
|
return existingSession.sid;
|
||||||
} else {
|
} else {
|
||||||
const sessionBody = new Session();
|
const sessionBody = new Session();
|
||||||
@@ -320,7 +323,8 @@ export class ConsoleRemoteClient implements ConsoleServiceClient {
|
|||||||
const sessionRepository = gr.services.console.getSessionRepo();
|
const sessionRepository = gr.services.console.getSessionRepo();
|
||||||
const session = await sessionRepository.findOne({ sid: payload.claims.sid });
|
const session = await sessionRepository.findOne({ sid: payload.claims.sid });
|
||||||
if (session) {
|
if (session) {
|
||||||
await sessionRepository.remove(session);
|
session.revoked_at = new Date().getTime();
|
||||||
|
await sessionRepository.save(session);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,7 +336,9 @@ export class ConsoleRemoteClient implements ConsoleServiceClient {
|
|||||||
});
|
});
|
||||||
if (!session) {
|
if (!session) {
|
||||||
// fail for not matching session id
|
// 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 {
|
} else {
|
||||||
// fail for missing session id
|
// fail for missing session id
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ export const TYPE = "session";
|
|||||||
|
|
||||||
@Entity(TYPE, {
|
@Entity(TYPE, {
|
||||||
primaryKey: [["company_id"], "sid"],
|
primaryKey: [["company_id"], "sid"],
|
||||||
globalIndexes: [["sid"]],
|
globalIndexes: [["sid"], ["revoked_at"]],
|
||||||
type: TYPE,
|
type: TYPE,
|
||||||
})
|
})
|
||||||
export default class Session {
|
export default class Session {
|
||||||
@@ -17,6 +17,9 @@ export default class Session {
|
|||||||
|
|
||||||
@Column("sid", "string")
|
@Column("sid", "string")
|
||||||
sid: string;
|
sid: string;
|
||||||
|
|
||||||
|
@Column("revoked_at", "number")
|
||||||
|
revoked_at: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type UserSessionPrimaryKey = Pick<Session, "sid">;
|
export type UserSessionPrimaryKey = Pick<Session, "sid">;
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ export default class UserApi {
|
|||||||
this.jwt = await this.doLogin();
|
this.jwt = await this.doLogin();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async doLogin() {
|
public async doLogin() {
|
||||||
const loginResponse = await this.login();
|
const loginResponse = await this.login();
|
||||||
|
|
||||||
expect(loginResponse).toBeDefined();
|
expect(loginResponse).toBeDefined();
|
||||||
@@ -133,13 +133,10 @@ export default class UserApi {
|
|||||||
verifierMock.mockImplementation(() => {
|
verifierMock.mockImplementation(() => {
|
||||||
return Promise.resolve(payload); // Return the predefined payload
|
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", {
|
return await this.api.post("/internal/services/console/v1/backchannel_logout", {
|
||||||
logout_token: logoutToken,
|
logout_token: "logout_token_rsa256",
|
||||||
});
|
});
|
||||||
|
|
||||||
return response;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,8 @@ describe("The /backchannel_logout API", () => {
|
|||||||
|
|
||||||
// Verify the session is removed from the database
|
// Verify the session is removed from the database
|
||||||
const deletedSession = await currentUser.dbService.getSessionById(currentUser.session);
|
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 () => {
|
it("should create a session on login", async () => {
|
||||||
@@ -82,6 +83,35 @@ describe("The /backchannel_logout API", () => {
|
|||||||
expect(response.statusCode).toBe(401);
|
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 () => {
|
it("should be able to log-in several times by having multiple sessions", async () => {
|
||||||
// Perform a second login
|
// Perform a second login
|
||||||
const newUserSession = await UserApi.getInstance(platform);
|
const newUserSession = await UserApi.getInstance(platform);
|
||||||
|
|||||||
Reference in New Issue
Block a user