add pri(accounts.changePassword) message (#450)

This commit is contained in:
Remon Nashid
2020-09-10 08:31:41 +02:00
committed by GitHub
parent 87a590d618
commit 6704c8d8e6
3 changed files with 80 additions and 18 deletions
@@ -12,6 +12,10 @@ import Extension from './Extension';
import State from './State';
describe('Extension', () => {
let extension: Extension;
const suri = 'seed sock milk update focus rotate barely fade car face mechanic mercy';
const password = 'passw0rd';
async function createExtension (): Promise<Extension> {
await cryptoWaitReady();
@@ -20,15 +24,23 @@ describe('Extension', () => {
return new Extension(new State());
}
let extension: Extension;
const createAccount = async (): Promise<string> => {
await extension.handle('id', 'pri(accounts.create.suri)', {
name: 'parent',
password,
suri
}, {} as chrome.runtime.Port);
const { address } = await extension.handle('id', 'pri(seed.validate)', {
suri
}, {} as chrome.runtime.Port);
return address;
};
beforeAll(async () => {
extension = await createExtension();
});
const suri = 'seed sock milk update focus rotate barely fade car face mechanic mercy';
const password = 'passw0rd';
test('exports account from keyring', async () => {
const { pair: { address } } = keyring.addUri(suri, password);
const result = await extension.handle('id', 'pri(accounts.export)', {
@@ -41,19 +53,6 @@ describe('Extension', () => {
});
describe('account derivation', () => {
const createAccount = async (): Promise<string> => {
await extension.handle('id', 'pri(accounts.create.suri)', {
name: 'parent',
password,
suri
}, {} as chrome.runtime.Port);
const { address } = await extension.handle('id', 'pri(seed.validate)', {
suri
}, {} as chrome.runtime.Port);
return address;
};
let address: string;
beforeEach(async () => {
@@ -111,4 +110,37 @@ describe('Extension', () => {
expect(keyring.getAccount('5FP3TT3EruYBNh8YM8yoxsreMx7uZv1J1zNX7fFhoC5enwmN')?.meta.parentAddress).toEqual(address);
});
});
describe('account management', () => {
let address: string;
beforeEach(async () => {
address = await createAccount();
});
test('pri(accounts.changePassword) changes account password', async () => {
const newPass = 'pa55word';
const wrongPass = 'ZZzzZZzz';
await expect(extension.handle('id', 'pri(accounts.changePassword)', {
address,
newPass,
oldPass: wrongPass
}, {} as chrome.runtime.Port)).rejects.toStrictEqual(new Error('oldPass is invalid'));
await expect(extension.handle('id', 'pri(accounts.changePassword)', {
address,
newPass,
oldPass: password
}, {} as chrome.runtime.Port)).resolves.toEqual(true);
const pair = keyring.getPair(address);
expect(pair.decodePkcs8(newPass)).toEqual(undefined);
expect(() => {
pair.decodePkcs8(password);
}).toThrowError('Unable to decode using the supplied passphrase');
});
});
});
@@ -4,7 +4,7 @@
import { MetadataDef } from '@polkadot/extension-inject/types';
import { SubjectInfo } from '@polkadot/ui-keyring/observable/types';
import { AccountJson, AuthorizeRequest, MessageTypes, MetadataRequest, RequestAccountCreateExternal, RequestAccountCreateSuri, RequestAccountEdit, RequestAccountExport, RequestAccountShow, RequestAccountTie, RequestAccountValidate, RequestAuthorizeApprove, RequestAuthorizeReject, RequestDeriveCreate, ResponseDeriveValidate, RequestMetadataApprove, RequestMetadataReject, RequestSigningApprovePassword, RequestSigningApproveSignature, RequestSigningCancel, RequestSigningIsLocked, RequestSeedCreate, RequestTypes, ResponseAccountExport, RequestAccountForget, ResponseSeedCreate, RequestSeedValidate, RequestDeriveValidate, ResponseSeedValidate, ResponseType, SigningRequest, RequestJsonRestore, ResponseJsonRestore } from '../types';
import { AccountJson, AuthorizeRequest, MessageTypes, MetadataRequest, RequestAccountCreateExternal, RequestAccountCreateSuri, RequestAccountEdit, RequestAccountExport, RequestAccountShow, RequestAccountTie, RequestAccountValidate, RequestAuthorizeApprove, RequestAuthorizeReject, RequestDeriveCreate, ResponseDeriveValidate, RequestMetadataApprove, RequestMetadataReject, RequestSigningApprovePassword, RequestSigningApproveSignature, RequestSigningCancel, RequestSigningIsLocked, RequestSeedCreate, RequestTypes, ResponseAccountExport, RequestAccountForget, ResponseSeedCreate, RequestSeedValidate, RequestDeriveValidate, ResponseSeedValidate, ResponseType, SigningRequest, RequestJsonRestore, ResponseJsonRestore, RequestAccountChangePassword } from '../types';
import chrome from '@polkadot/extension-inject/chrome';
import keyring from '@polkadot/ui-keyring';
@@ -55,6 +55,26 @@ export default class Extension {
return true;
}
private accountsChangePassword ({ address, newPass, oldPass }: RequestAccountChangePassword): boolean {
const pair = keyring.getPair(address);
assert(pair, 'Unable to find pair');
try {
if (!pair.isLocked) {
pair.lock();
}
pair.decodePkcs8(oldPass);
} catch (error) {
throw new Error('oldPass is invalid');
}
keyring.encryptAccount(pair, newPass);
return true;
}
private accountsEdit ({ address, name }: RequestAccountEdit): boolean {
const pair = keyring.getPair(address);
@@ -425,6 +445,9 @@ export default class Extension {
case 'pri(accounts.create.suri)':
return this.accountsCreateSuri(request as RequestAccountCreateSuri);
case 'pri(accounts.changePassword)':
return this.accountsChangePassword(request as RequestAccountChangePassword);
case 'pri(accounts.edit)':
return this.accountsEdit(request as RequestAccountEdit);
@@ -77,6 +77,7 @@ export interface RequestSignatures {
'pri(accounts.tie)': [RequestAccountTie, boolean];
'pri(accounts.subscribe)': [RequestAccountSubscribe, boolean, AccountJson[]];
'pri(accounts.validate)': [RequestAccountValidate, boolean];
'pri(accounts.changePassword)': [RequestAccountChangePassword, boolean];
'pri(authorize.approve)': [RequestAuthorizeApprove, boolean];
'pri(authorize.reject)': [RequestAuthorizeReject, boolean];
'pri(authorize.requests)': [RequestAuthorizeSubscribe, boolean, AuthorizeRequest[]];
@@ -170,6 +171,12 @@ export interface RequestAccountCreateSuri {
type?: KeypairType;
}
export interface RequestAccountChangePassword {
address: string;
oldPass: string;
newPass: string;
}
export interface RequestAccountEdit {
address: string;
genesisHash?: string | null;