fix: don't reject offline_accessscope

This commit is contained in:
Elias Schneider
2026-06-26 14:43:22 +02:00
parent cf54786cc3
commit 2ed703540d
3 changed files with 19 additions and 2 deletions

View File

@@ -84,7 +84,7 @@ func (wkc *WellKnownController) computeOIDCConfiguration() ([]byte, error) {
"device_authorization_endpoint": appUrl + "/api/oidc/device/authorize",
"jwks_uri": internalAppUrl + "/.well-known/jwks.json",
"grant_types_supported": []string{service.GrantTypeAuthorizationCode, service.GrantTypeRefreshToken, service.GrantTypeDeviceCode, service.GrantTypeClientCredentials},
"scopes_supported": []string{"openid", "profile", "email", "groups"},
"scopes_supported": []string{"openid", "profile", "email", "groups", "offline_access"},
"claims_supported": []string{"sub", "given_name", "family_name", "name", "display_name", "email", "email_verified", "preferred_username", "picture", "groups", "auth_time", "amr"},
"response_types_supported": []string{"code", "id_token"},
"subject_types_supported": []string{"public"},

View File

@@ -41,7 +41,7 @@ func (c Client) GetResponseTypes() fosite.Arguments {
}
func (c Client) GetScopes() fosite.Arguments {
return fosite.Arguments{"openid", "profile", "email", "groups"}
return fosite.Arguments{"openid", "profile", "email", "groups", "offline_access"}
}
func (c Client) IsPublic() bool {

View File

@@ -57,6 +57,23 @@ test('Authorize new client', async ({ page }) => {
);
});
test('Authorize client requesting offline_access scope', async ({ page }) => {
const oidcClient = oidcClients.immich;
const urlParams = createUrlParams(oidcClient);
urlParams.set('scope', 'openid profile email offline_access');
await page.goto(`/authorize?${urlParams.toString()}`);
// offline_access is a valid OIDC scope: the flow must reach the consent screen rather than
// being rejected with invalid_scope (offline_access itself has no displayable scope item)
await expectScopes(page, ['Email', 'Profile']);
const callbackUrl = await expectCallbackRedirect(page, oidcClient.callbackUrl, () =>
page.getByRole('button', { name: 'Sign in' }).click()
);
expect(callbackUrl.searchParams.get('code')).toBeTruthy();
expect(callbackUrl.searchParams.get('error')).toBeNull();
});
test('Authorize new client while not signed in', async ({ page }) => {
const oidcClient = oidcClients.immich;
const urlParams = createUrlParams(oidcClient);