mirror of
https://github.com/UNITRONIX/BetterDesk.git
synced 2026-09-10 17:45:42 +00:00
50d1942f8c
Add Go LDAP verify endpoint and probe it from the console when a local user's password fails, so valid domain credentials return HTTP 409 with a clear collision message instead of a misleading password mismatch. Includes i18n for auth.username_collision across all console locales.
88 lines
3.4 KiB
JavaScript
88 lines
3.4 KiB
JavaScript
/**
|
|
* Auth provider helpers and database facade (Issue #148)
|
|
*/
|
|
|
|
const mockAdapter = {
|
|
createUser: jest.fn(),
|
|
syncUserFromGo: jest.fn(),
|
|
};
|
|
|
|
jest.mock('../services/dbAdapter', () => ({
|
|
getAdapter: () => mockAdapter,
|
|
DB_TYPE: 'sqlite',
|
|
}));
|
|
|
|
jest.mock('../config/config', () => ({
|
|
dataDir: '/tmp',
|
|
dbPath: '/tmp/test.db',
|
|
dbType: 'sqlite',
|
|
}));
|
|
|
|
const authService = require('../services/authService');
|
|
const db = require('../services/database');
|
|
|
|
describe('authService provider helpers', () => {
|
|
it('normalizeAuthProvider accepts ldap, oidc, local', () => {
|
|
expect(authService.normalizeAuthProvider('LDAP')).toBe('ldap');
|
|
expect(authService.normalizeAuthProvider('oidc')).toBe('oidc');
|
|
expect(authService.normalizeAuthProvider('')).toBe('local');
|
|
expect(authService.normalizeAuthProvider('saml')).toBe('local');
|
|
});
|
|
|
|
it('inferAuthProviderFromSSO prefers Go response auth_provider', () => {
|
|
expect(authService.inferAuthProviderFromSSO(
|
|
{ auth_provider: 'ldap', role: 'operator' },
|
|
{ ldap: true, oidc: false, any: true }
|
|
)).toBe('ldap');
|
|
});
|
|
|
|
it('inferAuthProviderFromSSO falls back to SSO status when Go omits provider', () => {
|
|
expect(authService.inferAuthProviderFromSSO(
|
|
{ role: 'viewer' },
|
|
{ ldap: false, oidc: true, any: true }
|
|
)).toBe('oidc');
|
|
expect(authService.inferAuthProviderFromSSO(
|
|
{ role: 'viewer' },
|
|
{ ldap: true, oidc: false, any: true }
|
|
)).toBe('ldap');
|
|
});
|
|
|
|
it('authFailure / isAuthFailure identify structured login failures', () => {
|
|
const failure = authService.authFailure('username_collision');
|
|
expect(authService.isAuthFailure(failure)).toBe(true);
|
|
expect(failure.__authFailure).toBe('username_collision');
|
|
expect(authService.isAuthFailure(null)).toBe(false);
|
|
expect(authService.isAuthFailure({ id: 1, username: 'u' })).toBe(false);
|
|
});
|
|
|
|
it('isExternalAuthProvider / isExternalAuthResult detect ldap/oidc', () => {
|
|
expect(authService.isExternalAuthProvider('ldap')).toBe(true);
|
|
expect(authService.isExternalAuthProvider('oidc')).toBe(true);
|
|
expect(authService.isExternalAuthProvider('local')).toBe(false);
|
|
expect(authService.isExternalAuthProvider('SAML')).toBe(false);
|
|
|
|
expect(authService.isExternalAuthResult({ auth_provider: 'ldap' })).toBe(true);
|
|
expect(authService.isExternalAuthResult({ auth_provider: 'oidc' })).toBe(true);
|
|
expect(authService.isExternalAuthResult({ auth_provider: 'local' })).toBe(false);
|
|
expect(authService.isExternalAuthResult(null)).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('database facade auth_provider', () => {
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
mockAdapter.createUser.mockResolvedValue({ id: 1, username: 'u', role: 'viewer', auth_provider: 'ldap' });
|
|
mockAdapter.syncUserFromGo.mockResolvedValue(undefined);
|
|
});
|
|
|
|
it('createUser forwards authProvider to the adapter', async () => {
|
|
await db.createUser('aduser', 'hash', 'operator', 'ldap');
|
|
expect(mockAdapter.createUser).toHaveBeenCalledWith('aduser', 'hash', 'operator', 'ldap');
|
|
});
|
|
|
|
it('syncUserFromGo is exposed on the facade', async () => {
|
|
await db.syncUserFromGo(3, { authProvider: 'ldap', role: 'admin' });
|
|
expect(mockAdapter.syncUserFromGo).toHaveBeenCalledWith(3, { authProvider: 'ldap', role: 'admin' });
|
|
});
|
|
});
|