Simplify OIDC callback navigation handling

This commit is contained in:
Quentin Gliech 2022-03-03 15:30:28 +01:00
parent bbfa6de6dc
commit 8fbff2fd07
No known key found for this signature in database
GPG Key ID: 22D62B84552719FC
2 changed files with 28 additions and 32 deletions

View File

@ -38,8 +38,7 @@ export class RootViewModel extends ViewModel {
this.track(this.navigation.observe("login").subscribe(() => this._applyNavigation())); this.track(this.navigation.observe("login").subscribe(() => this._applyNavigation()));
this.track(this.navigation.observe("session").subscribe(() => this._applyNavigation())); this.track(this.navigation.observe("session").subscribe(() => this._applyNavigation()));
this.track(this.navigation.observe("sso").subscribe(() => this._applyNavigation())); this.track(this.navigation.observe("sso").subscribe(() => this._applyNavigation()));
this.track(this.navigation.observe("oidc-callback").subscribe(() => this._applyNavigation())); this.track(this.navigation.observe("oidc").subscribe(() => this._applyNavigation()));
this.track(this.navigation.observe("oidc-error").subscribe(() => this._applyNavigation()));
this._applyNavigation(true); this._applyNavigation(true);
} }
@ -48,8 +47,7 @@ export class RootViewModel extends ViewModel {
const logoutSessionId = this.navigation.path.get("logout")?.value; const logoutSessionId = this.navigation.path.get("logout")?.value;
const sessionId = this.navigation.path.get("session")?.value; const sessionId = this.navigation.path.get("session")?.value;
const loginToken = this.navigation.path.get("sso")?.value; const loginToken = this.navigation.path.get("sso")?.value;
const oidcCallback = this.navigation.path.get("oidc-callback")?.value; const oidcCallback = this.navigation.path.get("oidc")?.value;
const oidcError = this.navigation.path.get("oidc-error")?.value;
if (isLogin) { if (isLogin) {
if (this.activeSection !== "login") { if (this.activeSection !== "login") {
this._showLogin(); this._showLogin();
@ -83,20 +81,18 @@ export class RootViewModel extends ViewModel {
if (this.activeSection !== "login") { if (this.activeSection !== "login") {
this._showLogin({loginToken}); this._showLogin({loginToken});
} }
} else if (oidcError) {
this._setSection(() => this._error = new Error(`OIDC error: ${oidcError[1]}`));
} else if (oidcCallback) { } else if (oidcCallback) {
this._setSection(() => this._error = new Error(`OIDC callback: state=${oidcCallback[0]}, code=${oidcCallback[1]}`)); if (oidcCallback.error) {
this._setSection(() => this._error = new Error(`OIDC error: ${oidcCallback.error}`));
} else {
this.urlCreator.normalizeUrl(); this.urlCreator.normalizeUrl();
if (this.activeSection !== "login") { if (this.activeSection !== "login") {
this._showLogin({ this._showLogin({
oidc: { oidc: oidcCallback,
state: oidcCallback[0],
code: oidcCallback[1],
}
}); });
} }
} }
}
else { else {
try { try {
if (!(shouldRestoreLastUrl && this.urlCreator.tryRestoreLastUrl())) { if (!(shouldRestoreLastUrl && this.urlCreator.tryRestoreLastUrl())) {

View File

@ -50,7 +50,7 @@ function allowsChild(parent: Segment<SegmentType> | undefined, child: Segment<Se
switch (parent?.type) { switch (parent?.type) {
case undefined: case undefined:
// allowed root segments // allowed root segments
return type === "login" || type === "session" || type === "sso" || type === "logout" || type === "oidc-callback" || type === "oidc-error"; return type === "login" || type === "session" || type === "sso" || type === "logout" || type === "oidc";
case "session": case "session":
return type === "room" || type === "rooms" || type === "settings" || type === "create-room"; return type === "room" || type === "rooms" || type === "settings" || type === "create-room";
case "rooms": case "rooms":
@ -134,18 +134,18 @@ export function parseUrlPath(urlPath: string, currentNavPath: Path<SegmentType>,
if (params.has("state")) { if (params.has("state")) {
// This is a proper OIDC callback // This is a proper OIDC callback
if (params.has("code")) { if (params.has("code")) {
segments.push(new Segment("oidc-callback", [ segments.push(new Segment("oidc", {
params.get("state"), state: params.get("state"),
params.get("code"), code: params.get("code"),
])); }));
return segments; return segments;
} else if (params.has("error")) { } else if (params.has("error")) {
segments.push(new Segment("oidc-error", [ segments.push(new Segment("oidc", {
params.get("state"), state: params.get("state"),
params.get("error"), error: params.get("error"),
params.get("error_description"), errorDescription: params.get("error_description"),
params.get("error_uri"), errorUri: params.get("error_uri"),
])); }));
return segments; return segments;
} }
} }
@ -516,20 +516,20 @@ export function tests() {
"Parse OIDC callback": assert => { "Parse OIDC callback": assert => {
const segments = parseUrlPath("state=tc9CnLU7&code=cnmUnwIYtY7V8RrWUyhJa4yvX72jJ5Yx"); const segments = parseUrlPath("state=tc9CnLU7&code=cnmUnwIYtY7V8RrWUyhJa4yvX72jJ5Yx");
assert.equal(segments.length, 1); assert.equal(segments.length, 1);
assert.equal(segments[0].type, "oidc-callback"); assert.equal(segments[0].type, "oidc");
assert.deepEqual(segments[0].value, ["tc9CnLU7", "cnmUnwIYtY7V8RrWUyhJa4yvX72jJ5Yx"]); assert.deepEqual(segments[0].value, {state: "tc9CnLU7", code: "cnmUnwIYtY7V8RrWUyhJa4yvX72jJ5Yx"});
}, },
"Parse OIDC error": assert => { "Parse OIDC error": assert => {
const segments = parseUrlPath("state=tc9CnLU7&error=invalid_request"); const segments = parseUrlPath("state=tc9CnLU7&error=invalid_request");
assert.equal(segments.length, 1); assert.equal(segments.length, 1);
assert.equal(segments[0].type, "oidc-error"); assert.equal(segments[0].type, "oidc");
assert.deepEqual(segments[0].value, ["tc9CnLU7", "invalid_request", null, null]); assert.deepEqual(segments[0].value, {state: "tc9CnLU7", error: "invalid_request", errorUri: null, errorDescription: null});
}, },
"Parse OIDC error with description": assert => { "Parse OIDC error with description": assert => {
const segments = parseUrlPath("state=tc9CnLU7&error=invalid_request&error_description=Unsupported%20response_type%20value"); const segments = parseUrlPath("state=tc9CnLU7&error=invalid_request&error_description=Unsupported%20response_type%20value");
assert.equal(segments.length, 1); assert.equal(segments.length, 1);
assert.equal(segments[0].type, "oidc-error"); assert.equal(segments[0].type, "oidc");
assert.deepEqual(segments[0].value, ["tc9CnLU7", "invalid_request", "Unsupported response_type value", null]); assert.deepEqual(segments[0].value, {state: "tc9CnLU7", error: "invalid_request", errorDescription: "Unsupported response_type value", errorUri: null});
}, },
} }
} }