🐛Fixed format of the logout token
This commit is contained in:
committed by
Anton Shepilov
parent
ff2b3ab7f9
commit
c3c039d1f9
@@ -281,40 +281,44 @@ export class ConsoleRemoteClient implements ConsoleServiceClient {
|
|||||||
async backChannelLogout(logoutToken: string): Promise<void> {
|
async backChannelLogout(logoutToken: string): Promise<void> {
|
||||||
const payload = await this.verifier.verifyLogoutToken(logoutToken);
|
const payload = await this.verifier.verifyLogoutToken(logoutToken);
|
||||||
|
|
||||||
if (!payload.iss) {
|
if (!payload.claims) {
|
||||||
|
throw new CrudException("Claims are missing in the jwt", 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!payload.claims.iss) {
|
||||||
throw new CrudException("Missing required 'iss' claim", 400);
|
throw new CrudException("Missing required 'iss' claim", 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!payload.aud) {
|
if (!payload.claims.aud) {
|
||||||
throw new CrudException("Missing required 'aud' claim", 400);
|
throw new CrudException("Missing required 'aud' claim", 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!payload.iat) {
|
if (!payload.claims.iat) {
|
||||||
throw new CrudException("Missing required 'iat' claim", 400);
|
throw new CrudException("Missing required 'iat' claim", 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!payload.jti) {
|
if (!payload.claims.jti) {
|
||||||
throw new CrudException("Missing required 'jti' claim", 400);
|
throw new CrudException("Missing required 'jti' claim", 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!payload.events) {
|
if (!payload.claims.events) {
|
||||||
throw new CrudException("Missing required 'events' claim", 400);
|
throw new CrudException("Missing required 'events' claim", 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (payload.nonce) {
|
if (payload.claims.nonce) {
|
||||||
throw new CrudException("Nonce claim is prohibited", 400);
|
throw new CrudException("Nonce claim is prohibited", 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!payload.sub) {
|
if (!payload.claims.sub) {
|
||||||
throw new CrudException("Missing 'sub' claim", 400);
|
throw new CrudException("Missing 'sub' claim", 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!payload.sid) {
|
if (!payload.claims.sid) {
|
||||||
throw new CrudException("Missing 'sid' claim", 400);
|
throw new CrudException("Missing 'sid' claim", 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
const sessionRepository = gr.services.console.getSessionRepo();
|
const sessionRepository = gr.services.console.getSessionRepo();
|
||||||
const session = await sessionRepository.findOne({ sid: payload.sid });
|
const session = await sessionRepository.findOne({ sid: payload.claims.sid });
|
||||||
if (session) {
|
if (session) {
|
||||||
await sessionRepository.remove(session);
|
await sessionRepository.remove(session);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -117,15 +117,17 @@ export default class UserApi {
|
|||||||
|
|
||||||
public async logout() {
|
public async logout() {
|
||||||
const payload = {
|
const payload = {
|
||||||
iss: "tdrive_lemonldap",
|
claims: {
|
||||||
sub: this.user.id,
|
iss: "tdrive_lemonldap",
|
||||||
sid: this.session,
|
sub: this.user.id,
|
||||||
aud: "your-audience",
|
sid: this.session,
|
||||||
iat: Math.floor(Date.now() / 1000),
|
aud: "your-audience",
|
||||||
jti: "jwt-id",
|
iat: Math.floor(Date.now() / 1000),
|
||||||
events: {
|
jti: "jwt-id",
|
||||||
"http://schemas.openid.net/event/backchannel-logout": {},
|
events: {
|
||||||
},
|
"http://schemas.openid.net/event/backchannel-logout": {},
|
||||||
|
},
|
||||||
|
}
|
||||||
};
|
};
|
||||||
const verifierMock = jest.spyOn(OidcJwtVerifier.prototype, "verifyLogoutToken");
|
const verifierMock = jest.spyOn(OidcJwtVerifier.prototype, "verifyLogoutToken");
|
||||||
verifierMock.mockImplementation(() => {
|
verifierMock.mockImplementation(() => {
|
||||||
|
|||||||
@@ -20,22 +20,29 @@ describe("Test back-channel logout", () => {
|
|||||||
const verifyTokenMock = jest.spyOn(OidcJwtVerifier.prototype, "verifyLogoutToken");
|
const verifyTokenMock = jest.spyOn(OidcJwtVerifier.prototype, "verifyLogoutToken");
|
||||||
|
|
||||||
const validToken = {
|
const validToken = {
|
||||||
"sid": "Ev81/QODom0HXu9MGjCwnn1tDTpji+j0jopjRAE0ypo",
|
"header": {
|
||||||
"aud": [
|
"typ": "JWT",
|
||||||
"twakedrive"
|
"alg": "RS256",
|
||||||
],
|
"kid": "UrLwYyzqASOKT5wUedHERA"
|
||||||
"sub": "shepilov3@stg.lin-saas.com",
|
|
||||||
"iat": 1716986356,
|
|
||||||
"jti": "F9R6DYPE",
|
|
||||||
"events": {
|
|
||||||
"http://schemas.openid.net/event/backchannel-logout": {}
|
|
||||||
},
|
},
|
||||||
"iss": "https://sign-up.stg.lin-saas.com/"
|
"claims": {
|
||||||
|
"iat": 1716995003,
|
||||||
|
"sub": "shepilov3@stg.lin-saas.com",
|
||||||
|
"sid": "WSqrLJG8wNLECdxKIBrR9mdu3PmLFDUd4zHZ+1RLOYI",
|
||||||
|
"events": {
|
||||||
|
"http://schemas.openid.net/event/backchannel-logout": {}
|
||||||
|
},
|
||||||
|
"jti": "K9B59EPB",
|
||||||
|
"aud": [
|
||||||
|
"twakedrive"
|
||||||
|
],
|
||||||
|
"iss": "https://sign-up.stg.lin-saas.com/"
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockTokenWithoutProperty = (prop: string) => {
|
const mockTokenWithoutClaim = (claim: string) => {
|
||||||
const token = _.cloneDeep(validToken);
|
const token = _.cloneDeep(validToken);
|
||||||
token[prop] = null
|
token.claims[claim] = null
|
||||||
verifyTokenMock.mockImplementation(() => {
|
verifyTokenMock.mockImplementation(() => {
|
||||||
return Promise.resolve(token); // Return the predefined payload
|
return Promise.resolve(token); // Return the predefined payload
|
||||||
});
|
});
|
||||||
@@ -43,7 +50,7 @@ describe("Test back-channel logout", () => {
|
|||||||
|
|
||||||
it("backChannelLogout should throw error if 'iss' claim is missing", () => {
|
it("backChannelLogout should throw error if 'iss' claim is missing", () => {
|
||||||
//given
|
//given
|
||||||
mockTokenWithoutProperty("iss")
|
mockTokenWithoutClaim("iss")
|
||||||
//when
|
//when
|
||||||
let logout = subj.backChannelLogout('');
|
let logout = subj.backChannelLogout('');
|
||||||
//then
|
//then
|
||||||
@@ -53,7 +60,7 @@ describe("Test back-channel logout", () => {
|
|||||||
|
|
||||||
it("backChannelLogout should throw error if 'aud' claim is missing", () => {
|
it("backChannelLogout should throw error if 'aud' claim is missing", () => {
|
||||||
//given
|
//given
|
||||||
mockTokenWithoutProperty("aud")
|
mockTokenWithoutClaim("aud")
|
||||||
//when
|
//when
|
||||||
let logout = subj.backChannelLogout('');
|
let logout = subj.backChannelLogout('');
|
||||||
//then
|
//then
|
||||||
@@ -62,7 +69,7 @@ describe("Test back-channel logout", () => {
|
|||||||
|
|
||||||
it("backChannelLogout should throw error if 'jti' claim is missing", () => {
|
it("backChannelLogout should throw error if 'jti' claim is missing", () => {
|
||||||
//given
|
//given
|
||||||
mockTokenWithoutProperty("jti")
|
mockTokenWithoutClaim("jti")
|
||||||
//when
|
//when
|
||||||
let logout = subj.backChannelLogout('');
|
let logout = subj.backChannelLogout('');
|
||||||
//then
|
//then
|
||||||
@@ -71,7 +78,7 @@ describe("Test back-channel logout", () => {
|
|||||||
|
|
||||||
it("backChannelLogout should throw error if 'iat' claim is missing", () => {
|
it("backChannelLogout should throw error if 'iat' claim is missing", () => {
|
||||||
//given
|
//given
|
||||||
mockTokenWithoutProperty("iat")
|
mockTokenWithoutClaim("iat")
|
||||||
//when
|
//when
|
||||||
let logout = subj.backChannelLogout('');
|
let logout = subj.backChannelLogout('');
|
||||||
//then
|
//then
|
||||||
@@ -80,7 +87,7 @@ describe("Test back-channel logout", () => {
|
|||||||
|
|
||||||
it("backChannelLogout should throw error if 'events' claim is missing", () => {
|
it("backChannelLogout should throw error if 'events' claim is missing", () => {
|
||||||
//given
|
//given
|
||||||
mockTokenWithoutProperty("events")
|
mockTokenWithoutClaim("events")
|
||||||
//when
|
//when
|
||||||
let logout = subj.backChannelLogout('');
|
let logout = subj.backChannelLogout('');
|
||||||
//then
|
//then
|
||||||
@@ -89,7 +96,7 @@ describe("Test back-channel logout", () => {
|
|||||||
|
|
||||||
it("backChannelLogout should throw error if 'sub' claim is missing", () => {
|
it("backChannelLogout should throw error if 'sub' claim is missing", () => {
|
||||||
//given
|
//given
|
||||||
mockTokenWithoutProperty("sub")
|
mockTokenWithoutClaim("sub")
|
||||||
//when
|
//when
|
||||||
let logout = subj.backChannelLogout('');
|
let logout = subj.backChannelLogout('');
|
||||||
//then
|
//then
|
||||||
@@ -98,7 +105,7 @@ describe("Test back-channel logout", () => {
|
|||||||
|
|
||||||
it("backChannelLogout should throw error if 'sid' claim is missing", () => {
|
it("backChannelLogout should throw error if 'sid' claim is missing", () => {
|
||||||
//given
|
//given
|
||||||
mockTokenWithoutProperty("sid")
|
mockTokenWithoutClaim("sid")
|
||||||
//when
|
//when
|
||||||
let logout = subj.backChannelLogout('');
|
let logout = subj.backChannelLogout('');
|
||||||
//then
|
//then
|
||||||
|
|||||||
Reference in New Issue
Block a user