mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-07 14:41:24 +02:00
feat(oidc): Azure Entra ID support — configurable email claim & verification + Remember Me persistent login (#1126)
feat(oidc): add Azure Entra ID support with configurable email claim resolution Adds two new OIDC provider fields: email_claim and require_email_verified.
This commit is contained in:
@@ -33,6 +33,8 @@ beforeAll(() => server.listen({ onUnhandledRequest: 'bypass' }));
|
||||
afterEach(() => {
|
||||
server.resetHandlers();
|
||||
sessionStorageMock.clear();
|
||||
vi.mocked(localStorage.setItem).mockClear();
|
||||
vi.mocked(localStorage.removeItem).mockClear();
|
||||
setAuthToken(null);
|
||||
});
|
||||
afterAll(() => server.close());
|
||||
@@ -50,6 +52,60 @@ describe('Auth Token Management', () => {
|
||||
expect(sessionStorageMock.removeItem).toHaveBeenCalledWith('auth_token');
|
||||
expect(getAuthToken()).toBeNull();
|
||||
});
|
||||
|
||||
it("setAuthToken('persistent') writes to both sessionStorage and localStorage", () => {
|
||||
setAuthToken('persist-token', 'persistent');
|
||||
expect(sessionStorageMock.setItem).toHaveBeenCalledWith('auth_token', 'persist-token');
|
||||
expect(vi.mocked(localStorage.setItem)).toHaveBeenCalledWith('auth_token', 'persist-token');
|
||||
expect(getAuthToken()).toBe('persist-token');
|
||||
});
|
||||
|
||||
it("setAuthToken('session') writes only to sessionStorage, not localStorage", () => {
|
||||
setAuthToken('session-token', 'session');
|
||||
expect(sessionStorageMock.setItem).toHaveBeenCalledWith('auth_token', 'session-token');
|
||||
expect(vi.mocked(localStorage.setItem)).not.toHaveBeenCalledWith('auth_token', expect.any(String));
|
||||
});
|
||||
|
||||
it('setAuthToken(null) removes from both storages regardless of previous persistence', () => {
|
||||
setAuthToken('some-token', 'persistent');
|
||||
vi.mocked(localStorage.setItem).mockClear();
|
||||
setAuthToken(null);
|
||||
expect(sessionStorageMock.removeItem).toHaveBeenCalledWith('auth_token');
|
||||
expect(vi.mocked(localStorage.removeItem)).toHaveBeenCalledWith('auth_token');
|
||||
expect(getAuthToken()).toBeNull();
|
||||
});
|
||||
|
||||
it('setAuthToken keeps in-memory token when sessionStorage throws', () => {
|
||||
sessionStorageMock.setItem.mockImplementationOnce(() => {
|
||||
throw new DOMException('QuotaExceededError');
|
||||
});
|
||||
// Should not throw even when storage is unavailable
|
||||
expect(() => setAuthToken('fallback-token')).not.toThrow();
|
||||
// In-memory token must still be set
|
||||
expect(getAuthToken()).toBe('fallback-token');
|
||||
});
|
||||
|
||||
it('setAuthToken(null) removes from sessionStorage even when localStorage.removeItem throws', () => {
|
||||
setAuthToken('some-token', 'persistent');
|
||||
vi.mocked(localStorage.removeItem).mockImplementationOnce(() => {
|
||||
throw new DOMException('SecurityError');
|
||||
});
|
||||
// Must not throw — localStorage failure must not abort the sessionStorage removal
|
||||
expect(() => setAuthToken(null)).not.toThrow();
|
||||
expect(sessionStorageMock.removeItem).toHaveBeenCalledWith('auth_token');
|
||||
expect(getAuthToken()).toBeNull();
|
||||
});
|
||||
|
||||
it('setAuthToken(null) removes from localStorage even when sessionStorage.removeItem throws', () => {
|
||||
setAuthToken('some-token', 'persistent');
|
||||
sessionStorageMock.removeItem.mockImplementationOnce(() => {
|
||||
throw new DOMException('SecurityError');
|
||||
});
|
||||
// Must not throw — sessionStorage failure must not abort the localStorage removal
|
||||
expect(() => setAuthToken(null)).not.toThrow();
|
||||
expect(vi.mocked(localStorage.removeItem)).toHaveBeenCalledWith('auth_token');
|
||||
expect(getAuthToken()).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('API Client Auth Header', () => {
|
||||
|
||||
Reference in New Issue
Block a user