fix(editor): Re-initialize SSO store after login to populate OIDC redirect URL (#28386)

This commit is contained in:
Csaba Tuncsik 2026-04-17 14:05:48 +02:00 committed by GitHub
parent 46aa46d996
commit 21317b8945
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 80 additions and 0 deletions

View file

@ -134,6 +134,40 @@ describe('Init', () => {
});
});
it('should re-initialize ssoStore in login hook with authenticated settings', async () => {
const saml = { loginEnabled: false, loginLabel: '' };
const ldap = { loginEnabled: false, loginLabel: '' };
const oidc = {
loginEnabled: false,
loginUrl: 'http://localhost:5678/rest/sso/oidc/login',
callbackUrl: 'http://localhost:5678/rest/sso/oidc/callback',
};
settingsStore.userManagement.authenticationMethod = UserManagementAuthenticationMethod.Oidc;
settingsStore.settings.sso = { managedByEnv: false, saml, ldap, oidc };
settingsStore.isEnterpriseFeatureEnabled[EnterpriseEditionFeature.Oidc] = true;
usersStore.registerLoginHook.mockImplementation(async (hook) => {
await hook(mock<CurrentUserResponse>({ id: 'userId' }));
});
await initializeCore();
// ssoStore.initialize should be called twice:
// once during initializeCore and once during the login hook
expect(ssoStore.initialize).toHaveBeenCalledTimes(2);
expect(ssoStore.initialize).toHaveBeenLastCalledWith({
authenticationMethod: UserManagementAuthenticationMethod.Oidc,
managedByEnv: false,
config: { managedByEnv: false, saml, ldap, oidc },
features: {
saml: false,
ldap: false,
oidc: true,
},
});
});
it('should initialize ssoStore with settings SSO configuration', async () => {
const saml = { loginEnabled: true, loginLabel: '' };
const ldap = { loginEnabled: false, loginLabel: '' };

View file

@ -237,11 +237,27 @@ function registerAuthenticationHooks() {
const telemetry = useTelemetry();
const RBACStore = useRBACStore();
const settingsStore = useSettingsStore();
const ssoStore = useSSOStore();
const favoritesStore = useFavoritesStore();
usersStore.registerLoginHook(async (user) => {
await settingsStore.getSettings();
// Re-initialize SSO store with authenticated settings.
// Before login, public settings omit callbackUrl, leaving it empty.
// Without this, navigating to SSO settings after login shows an empty redirect URL.
ssoStore.initialize({
authenticationMethod: settingsStore.userManagement
.authenticationMethod as UserManagementAuthenticationMethod,
managedByEnv: settingsStore.settings.sso.managedByEnv,
config: settingsStore.settings.sso,
features: {
saml: settingsStore.isEnterpriseFeatureEnabled[EnterpriseEditionFeature.Saml],
ldap: settingsStore.isEnterpriseFeatureEnabled[EnterpriseEditionFeature.Ldap],
oidc: settingsStore.isEnterpriseFeatureEnabled[EnterpriseEditionFeature.Oidc],
},
});
RBACStore.setGlobalScopes(user.globalScopes ?? []);
telemetry.identify({
instanceId: rootStore.instanceId,

View file

@ -41,6 +41,36 @@ describe('SSO store', () => {
},
);
describe('OIDC callbackUrl after re-initialization', () => {
it('should populate callbackUrl when re-initialized with authenticated settings', () => {
// Simulate public settings (before login) — no callbackUrl
ssoStore.initialize({
authenticationMethod: 'oidc' as UserManagementAuthenticationMethod,
config: {
oidc: { loginEnabled: false, loginUrl: 'http://localhost:5678/rest/sso/oidc/login' },
},
features: { saml: false, ldap: false, oidc: true },
});
expect(ssoStore.oidc.callbackUrl).toBe('');
// Simulate authenticated settings (after login) — includes callbackUrl
ssoStore.initialize({
authenticationMethod: 'oidc' as UserManagementAuthenticationMethod,
config: {
oidc: {
loginEnabled: false,
loginUrl: 'http://localhost:5678/rest/sso/oidc/login',
callbackUrl: 'http://localhost:5678/rest/sso/oidc/callback',
},
},
features: { saml: false, ldap: false, oidc: true },
});
expect(ssoStore.oidc.callbackUrl).toBe('http://localhost:5678/rest/sso/oidc/callback');
});
});
describe('Protocol Selection Initialization', () => {
beforeEach(() => {
setActivePinia(createPinia());