Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/datastore/local-store/repos/api-key.repo.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { createMock } from '@golevelup/ts-jest';
import { ConfigService } from '@nestjs/config';

import { ApiKeyRepo } from '~/auth/repos/api-key.repo';
import { AppNotFoundError } from '~/common/errors';
import { LocalApiKeysRepo } from '~/datastore/local-store/repos/api-key.repo';
import { defaultUser } from '~/users/user.consts';

Expand All @@ -23,4 +24,16 @@ describe('LocalApiKeyRepo', () => {

return expect(repo.getUserByApiKey(config)).resolves.toEqual(defaultUser);
});

it.each(['constructor', '__proto__', 'toString', 'valueOf', 'hasOwnProperty'])(
'should not treat the Object.prototype property "%s" as a configured key',
key => {
const mockConfig = createMock<ConfigService>();
mockConfig.getOrThrow.mockReturnValue(config);

const repo = new LocalApiKeysRepo(mockConfig);

return expect(repo.getUserByApiKey(key)).rejects.toThrow(AppNotFoundError);
}
);
});
2 changes: 1 addition & 1 deletion src/datastore/local-store/repos/api-key.repo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { defaultUser } from '~/users/user.consts';

@Injectable()
export class LocalApiKeysRepo implements ApiKeyRepo {
private apiKeys: Record<string, UserModel> = {};
private apiKeys: Record<string, UserModel> = Object.create(null);

constructor(readonly config: ConfigService) {
const givenApiKeys = config.getOrThrow<string>('API_KEYS');
Expand Down
15 changes: 15 additions & 0 deletions src/signing/services/local-signing.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ describe('LocalSigningService', () => {
it('should throw if an Account is not loaded', () => {
expect(() => service.getAddressByHandle('badId')).toThrow(AppNotFoundError);
});

it.each(['constructor', '__proto__', 'toString'])(
'should throw for the Object.prototype property "%s" when it is not loaded',
handle => {
expect(() => service.getAddressByHandle(handle)).toThrow(AppNotFoundError);
}
);
});

describe('isAddress', () => {
Expand Down Expand Up @@ -122,5 +129,13 @@ describe('LocalSigningService', () => {

await expect(service.addSigner(handle, mnemonic)).rejects.toThrow(AppConflictError);
});

it('should add a signer whose handle is an Object.prototype property name', async () => {
const handle = 'constructor';
const expectedAddress = '15oF4uVJwmo4TdGW7VfQxNLavjCXviqxT9S1MgbjMNHr6Sp5';

await expect(service.addSigner(handle, '//Alice')).resolves.toBe(expectedAddress);
await expect(service.getAddressByHandle(handle)).resolves.toBe(expectedAddress);
});
});
});
2 changes: 1 addition & 1 deletion src/signing/services/local-signing.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { PolymeshService } from '~/polymesh/polymesh.service';
import { SigningService } from '~/signing/services/signing.service';

export class LocalSigningService extends SigningService {
private addressBook: Record<string, string> = {};
private addressBook: Record<string, string> = Object.create(null);

constructor(
protected readonly signingManager: LocalSigningManager,
Expand Down
Loading