mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-04-27 07:48:01 -07:00
harden implementations
This commit is contained in:
parent
c3ae4cffd6
commit
559a3ff1f4
25 changed files with 240 additions and 37 deletions
|
|
@ -24,7 +24,9 @@ export * from './ping';
|
|||
export * from './register';
|
||||
export * from './removeFromList';
|
||||
export * from './replayDeleteMatch';
|
||||
export * from './replayGetCode';
|
||||
export * from './replayList';
|
||||
export * from './replayModifyMatch';
|
||||
export * from './replaySubmitCode';
|
||||
export * from './requestPasswordSalt';
|
||||
export * from './updateStatus';
|
||||
|
|
|
|||
|
|
@ -44,7 +44,8 @@ export function login(options: WebSocketConnectOptions, passwordSalt?: string):
|
|||
SessionPersistence.updateBuddyList(buddyList);
|
||||
SessionPersistence.updateIgnoreList(ignoreList);
|
||||
SessionPersistence.updateUser(userInfo);
|
||||
SessionPersistence.loginSuccessful(loginConfig);
|
||||
const { password: _password, ...safeConfig } = loginConfig;
|
||||
SessionPersistence.loginSuccessful(safeConfig);
|
||||
|
||||
listUsers();
|
||||
listRooms();
|
||||
|
|
|
|||
10
webclient/src/websocket/commands/session/replayGetCode.ts
Normal file
10
webclient/src/websocket/commands/session/replayGetCode.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { BackendService } from '../../services/BackendService';
|
||||
|
||||
export function replayGetCode(gameId: number, onCodeReceived: (code: string) => void): void {
|
||||
BackendService.sendSessionCommand('Command_ReplayGetCode', { gameId }, {
|
||||
responseName: 'Response_ReplayGetCode',
|
||||
onSuccess: (response) => {
|
||||
onCodeReceived(response.replayCode);
|
||||
},
|
||||
});
|
||||
}
|
||||
12
webclient/src/websocket/commands/session/replaySubmitCode.ts
Normal file
12
webclient/src/websocket/commands/session/replaySubmitCode.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import { BackendService } from '../../services/BackendService';
|
||||
|
||||
export function replaySubmitCode(
|
||||
replayCode: string,
|
||||
onSuccess?: () => void,
|
||||
onError?: (responseCode: number) => void,
|
||||
): void {
|
||||
BackendService.sendSessionCommand('Command_ReplaySubmitCode', { replayCode }, {
|
||||
onSuccess,
|
||||
onError,
|
||||
});
|
||||
}
|
||||
|
|
@ -163,6 +163,22 @@ describe('login', () => {
|
|||
expect(SessionIndexMocks.updateStatus).toHaveBeenCalledWith(StatusEnum.LOGGED_IN, 'Logged in.');
|
||||
});
|
||||
|
||||
it('onSuccess does NOT pass plaintext password to loginSuccessful', () => {
|
||||
login({ userName: 'alice', password: 'secret' } as any);
|
||||
const loginResp = { buddyList: [], ignoreList: [], userInfo: { name: 'alice' } };
|
||||
invokeOnSuccess(loginResp, { responseCode: 0, '.Response_Login.ext': loginResp });
|
||||
const calledWith = (SessionPersistence.loginSuccessful as jest.Mock).mock.calls[0][0];
|
||||
expect(calledWith).not.toHaveProperty('password');
|
||||
});
|
||||
|
||||
it('onSuccess passes hashedPassword to loginSuccessful when salt is used', () => {
|
||||
login({ userName: 'alice', password: 'pw' } as any, 'salt');
|
||||
const loginResp = { buddyList: [], ignoreList: [], userInfo: { name: 'alice' } };
|
||||
invokeOnSuccess(loginResp, { responseCode: 0, '.Response_Login.ext': loginResp });
|
||||
const calledWith = (SessionPersistence.loginSuccessful as jest.Mock).mock.calls[0][0];
|
||||
expect(calledWith).toHaveProperty('hashedPassword', 'hashed_pw');
|
||||
});
|
||||
|
||||
it('onResponseCode RespClientUpdateRequired calls onLoginError', () => {
|
||||
login({ userName: 'alice', password: 'pw' } as any);
|
||||
invokeResponseCode(1);
|
||||
|
|
|
|||
|
|
@ -423,3 +423,52 @@ describe('removeFromList / removeFromBuddyList / removeFromIgnoreList', () => {
|
|||
expect(SessionPersistence.removeFromList).toHaveBeenCalledWith('buddy', 'alice');
|
||||
});
|
||||
});
|
||||
|
||||
describe('replayGetCode', () => {
|
||||
const { replayGetCode } = jest.requireActual('./replayGetCode');
|
||||
beforeEach(() => jest.clearAllMocks());
|
||||
|
||||
it('sends Command_ReplayGetCode with gameId and responseName', () => {
|
||||
replayGetCode(42, jest.fn());
|
||||
expect(BackendService.sendSessionCommand).toHaveBeenCalledWith(
|
||||
'Command_ReplayGetCode',
|
||||
{ gameId: 42 },
|
||||
expect.objectContaining({ responseName: 'Response_ReplayGetCode' })
|
||||
);
|
||||
});
|
||||
|
||||
it('calls onCodeReceived with replayCode on success', () => {
|
||||
const onCodeReceived = jest.fn();
|
||||
replayGetCode(42, onCodeReceived);
|
||||
invokeOnSuccess({ replayCode: 'abc123-xyz' });
|
||||
expect(onCodeReceived).toHaveBeenCalledWith('abc123-xyz');
|
||||
});
|
||||
});
|
||||
|
||||
describe('replaySubmitCode', () => {
|
||||
const { replaySubmitCode } = jest.requireActual('./replaySubmitCode');
|
||||
beforeEach(() => jest.clearAllMocks());
|
||||
|
||||
it('sends Command_ReplaySubmitCode with replayCode', () => {
|
||||
replaySubmitCode('42-abc123');
|
||||
expect(BackendService.sendSessionCommand).toHaveBeenCalledWith(
|
||||
'Command_ReplaySubmitCode',
|
||||
{ replayCode: '42-abc123' },
|
||||
expect.any(Object)
|
||||
);
|
||||
});
|
||||
|
||||
it('forwards onSuccess callback', () => {
|
||||
const onSuccess = jest.fn();
|
||||
replaySubmitCode('42-abc123', onSuccess);
|
||||
invokeOnSuccess();
|
||||
expect(onSuccess).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('forwards onError callback', () => {
|
||||
const onError = jest.fn();
|
||||
replaySubmitCode('42-abc123', undefined, onError);
|
||||
invokeCallback('onError', 404);
|
||||
expect(onError).toHaveBeenCalledWith(404);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue