Skip to content

Commit

Permalink
feat: add skip logout consent option (#319)
Browse files Browse the repository at this point in the history
  • Loading branch information
aeneasr committed Jan 30, 2024
1 parent 2c2c90a commit 88e3b77
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 23 deletions.
8 changes: 8 additions & 0 deletions src/pkg/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import sdk, { apiBaseUrl } from "./sdk"
import {
UiNode,
ErrorAuthenticatorAssuranceLevelNotSatisfied,
OAuth2LogoutRequest,
} from "@ory/client"
import { ButtonLink, Divider, MenuLink, Typography } from "@ory/elements-markup"
import { filterNodesByGroups } from "@ory/integrations/ui"
Expand Down Expand Up @@ -50,6 +51,13 @@ export const defaultConfig: RouteOptionsCreator = () => {
? true
: false
},
shouldSkipLogoutConsent: (challenge) => {
return (
challenge.client as OAuth2LogoutRequest & {
skip_logout_consent: boolean
}
)?.skip_logout_consent
},
...sdk,
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/pkg/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
IdentityApi,
OAuth2Api,
OAuth2ConsentRequest,
OAuth2LogoutRequest,
} from "@ory/client"
import { Theme } from "@ory/elements-markup"
import { NextFunction, Request, Response, Router } from "express"
Expand All @@ -20,11 +21,15 @@ export interface RouteOptions {
// This is used to determine if the consent route should be registered
// We need to check if the required environment variables are set
isOAuthConsentRouteEnabled: () => boolean

// Checks if the OAuth2 consent request should be skipped
// In some cases Hydra will let us skip the consent request
// Setting `TRUSTED_CLIENT_IDS` will skip the consent request for the given client ids
shouldSkipConsent: (challenge: OAuth2ConsentRequest) => boolean

// When this returns true, the logout screen will not be shown.
shouldSkipLogoutConsent: (challenge: OAuth2LogoutRequest) => boolean

logoUrl?: string
faviconUrl?: string
faviconType?: string
Expand Down
58 changes: 35 additions & 23 deletions src/routes/logout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,30 +19,42 @@ export const createShowLogoutRoute: RouteCreator =

if (typeof logoutChallenge !== "string") {
logger.debug("Expected a logout challenge to be set but received none.")
next(
new Error("Expected a logout challenge to be set but received none."),
)
res.redirect("login")
return
}

// this should never happen
if (!req.csrfToken) {
logger.warn("Expected CSRF token middleware to be set but received none.")
next(
new Error(
"Expected CSRF token middleware to be set but received none.",
),
)
return
}
const { oauth2, shouldSkipLogoutConsent } = createHelpers(req, res)
oauth2
.getOAuth2LogoutRequest({ logoutChallenge })
.then(({ data: body }) => {
if (shouldSkipLogoutConsent(body)) {
return oauth2
.acceptOAuth2LogoutRequest({ logoutChallenge })
.then(({ data: body }) => res.redirect(body.redirect_to))
}

// this should never happen
if (!req.csrfToken) {
logger.warn(
"Expected CSRF token middleware to be set but received none.",
)
next(
new Error(
"Expected CSRF token middleware to be set but received none.",
),
)
return
}

res.render("logout", {
card: UserLogoutCard({
csrfToken: req.csrfToken(true),
challenge: logoutChallenge,
action: "logout",
}),
})
res.render("logout", {
card: UserLogoutCard({
csrfToken: req.csrfToken(true),
challenge: logoutChallenge,
action: "logout",
}),
})
})
.catch(() => res.redirect("login"))
}

export const createSubmitLogoutRoute: RouteCreator =
Expand All @@ -60,15 +72,15 @@ export const createSubmitLogoutRoute: RouteCreator =
// The user rejected to log out, so we'll redirect to /ui/welcome
return oauth2
.rejectOAuth2LogoutRequest({ logoutChallenge })
.then(() => res.redirect("welcome"))
.catch(() => res.redirect("welcome"))
.then(() => res.redirect("login"))
.catch(() => res.redirect("login"))
} else {
logger.debug("User agreed to log out.")
// The user agreed to log out, let's accept the logout request.
return oauth2
.acceptOAuth2LogoutRequest({ logoutChallenge })
.then(({ data: body }) => res.redirect(body.redirect_to))
.catch(() => res.redirect("welcome"))
.catch(() => res.redirect("login"))
}
}

Expand Down

0 comments on commit 88e3b77

Please sign in to comment.