fix: Bug - Add logout in mobile version of settings, allow clearing data on android
All checks were successful
Queue Release Build / prepare (push) Successful in 19s
Deploy Web Apps / deploy (push) Successful in 7m55s
Queue Release Build / build-windows (push) Successful in 28m37s
Queue Release Build / build-linux (push) Successful in 47m3s
Queue Release Build / build-android (push) Successful in 20m33s
Queue Release Build / finalize (push) Successful in 3m48s
All checks were successful
Queue Release Build / prepare (push) Successful in 19s
Deploy Web Apps / deploy (push) Successful in 7m55s
Queue Release Build / build-windows (push) Successful in 28m37s
Queue Release Build / build-linux (push) Successful in 47m3s
Queue Release Build / build-android (push) Successful in 20m33s
Queue Release Build / finalize (push) Successful in 3m48s
Expose settings logout on mobile where the title bar is hidden, and enable Capacitor data settings with storage visibility and local erase/sign-out. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -43,4 +43,13 @@ describe('AuthTokenStoreService', () => {
|
||||
|
||||
expect(service.getToken('http://localhost:3001')).toBeNull();
|
||||
});
|
||||
|
||||
it('clears every stored token', () => {
|
||||
service.setToken('http://localhost:3001', 'token-abc', Date.now() + 60_000);
|
||||
service.setToken('http://localhost:3002', 'token-def', Date.now() + 60_000);
|
||||
|
||||
service.clearAllTokens();
|
||||
|
||||
expect(service.hasAnyValidToken()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -49,6 +49,12 @@ export class AuthTokenStoreService {
|
||||
this.writeStore(nextStore);
|
||||
}
|
||||
|
||||
clearAllTokens(): void {
|
||||
try {
|
||||
localStorage.removeItem(STORAGE_KEY);
|
||||
} catch {}
|
||||
}
|
||||
|
||||
hasAnyValidToken(): boolean {
|
||||
const now = Date.now();
|
||||
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
import '@angular/compiler';
|
||||
import { Injector, runInInjectionContext } from '@angular/core';
|
||||
import {
|
||||
beforeEach,
|
||||
describe,
|
||||
expect,
|
||||
it,
|
||||
vi
|
||||
} from 'vitest';
|
||||
import { Router } from '@angular/router';
|
||||
import { Store } from '@ngrx/store';
|
||||
|
||||
import { RealtimeSessionFacade } from '../../../../core/realtime';
|
||||
import { MessagesActions } from '../../../../store/messages/messages.actions';
|
||||
import { RoomsActions } from '../../../../store/rooms/rooms.actions';
|
||||
import { UsersActions } from '../../../../store/users/users.actions';
|
||||
import { UserLogoutService } from './user-logout.service';
|
||||
|
||||
describe('UserLogoutService', () => {
|
||||
let webrtc: { disconnect: ReturnType<typeof vi.fn> };
|
||||
let store: { dispatch: ReturnType<typeof vi.fn> };
|
||||
let router: { navigate: ReturnType<typeof vi.fn> };
|
||||
let service: UserLogoutService;
|
||||
|
||||
beforeEach(() => {
|
||||
vi.stubGlobal('localStorage', {
|
||||
getItem: vi.fn(() => null),
|
||||
setItem: vi.fn(),
|
||||
removeItem: vi.fn(),
|
||||
clear: vi.fn(),
|
||||
key: vi.fn(() => null),
|
||||
length: 0
|
||||
});
|
||||
|
||||
webrtc = { disconnect: vi.fn() };
|
||||
store = { dispatch: vi.fn() };
|
||||
router = { navigate: vi.fn(() => Promise.resolve(true)) };
|
||||
|
||||
const injector = Injector.create({
|
||||
providers: [
|
||||
UserLogoutService,
|
||||
{ provide: RealtimeSessionFacade, useValue: webrtc },
|
||||
{ provide: Store, useValue: store },
|
||||
{ provide: Router, useValue: router }
|
||||
]
|
||||
});
|
||||
|
||||
service = runInInjectionContext(injector, () => injector.get(UserLogoutService));
|
||||
});
|
||||
|
||||
it('disconnects, clears persisted user scope, resets store slices, and navigates to login', () => {
|
||||
service.logout();
|
||||
|
||||
expect(webrtc.disconnect).toHaveBeenCalledOnce();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(MessagesActions.clearMessages());
|
||||
expect(store.dispatch).toHaveBeenCalledWith(RoomsActions.resetRoomsState());
|
||||
expect(store.dispatch).toHaveBeenCalledWith(UsersActions.resetUsersState());
|
||||
expect(router.navigate).toHaveBeenCalledWith(['/login']);
|
||||
});
|
||||
|
||||
it('can reset client state without navigating away', () => {
|
||||
service.logout({ navigate: false });
|
||||
|
||||
expect(router.navigate).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { Store } from '@ngrx/store';
|
||||
|
||||
import { RealtimeSessionFacade } from '../../../../core/realtime';
|
||||
import { clearStoredCurrentUserId } from '../../../../core/storage/current-user-storage';
|
||||
import { MessagesActions } from '../../../../store/messages/messages.actions';
|
||||
import { RoomsActions } from '../../../../store/rooms/rooms.actions';
|
||||
import { UsersActions } from '../../../../store/users/users.actions';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class UserLogoutService {
|
||||
private readonly webrtc = inject(RealtimeSessionFacade);
|
||||
private readonly store = inject(Store);
|
||||
private readonly router = inject(Router);
|
||||
|
||||
logout(options?: { navigate?: boolean }): void {
|
||||
this.webrtc.disconnect();
|
||||
clearStoredCurrentUserId();
|
||||
this.store.dispatch(MessagesActions.clearMessages());
|
||||
this.store.dispatch(RoomsActions.resetRoomsState());
|
||||
this.store.dispatch(UsersActions.resetUsersState());
|
||||
|
||||
if (options?.navigate !== false) {
|
||||
void this.router.navigate(['/login']);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
export * from './application/services/authentication.service';
|
||||
export * from './application/services/auth-token-store.service';
|
||||
export * from './application/services/user-logout.service';
|
||||
export * from './application/services/signal-server-auth.service';
|
||||
export * from './application/services/signal-server-authorize.service';
|
||||
export * from './application/services/signal-server-credential-store.service';
|
||||
|
||||
Reference in New Issue
Block a user