Skip to content

Commit

Permalink
ChangePass from TxComponent (#2520)
Browse files Browse the repository at this point in the history
* ChangePass from TxComponent

* Import as functional

* Cleanups (vanity)

* Use bundled node
  • Loading branch information
jacogr authored Apr 6, 2020
1 parent ca749ef commit 31796b8
Show file tree
Hide file tree
Showing 5 changed files with 224 additions and 330 deletions.
3 changes: 0 additions & 3 deletions .github/workflows/pr-any.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: '12.x'
- name: ${{ matrix.step }}
run: |
yarn install --immutable | grep -v 'YN0013'
Expand Down
3 changes: 0 additions & 3 deletions .github/workflows/push-master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ jobs:
- uses: actions/checkout@v1
with:
token: ${{ secrets.GH_PAT }}
- uses: actions/setup-node@v1
with:
node-version: '12.x'
- name: ${{ matrix.step }}
env:
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
Expand Down
203 changes: 78 additions & 125 deletions packages/page-accounts/src/Accounts/modals/ChangePass.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,71 +2,83 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.

import { I18nProps } from '@polkadot/react-components/types';

import React from 'react';
import { AddressRow, Button, Modal, Password, TxComponent } from '@polkadot/react-components';
import { ActionStatus } from '@polkadot/react-components/Status/types';
import React, { useCallback, useState } from 'react';
import { AddressRow, Button, Modal, Password } from '@polkadot/react-components';
import keyring from '@polkadot/ui-keyring';

import translate from '../../translate';
import { useTranslation } from '../../translate';

interface Props extends I18nProps {
interface Props {
className?: string;
address: string;
onClose: () => void;
}

interface State {
interface NewPass {
isNewValid: boolean;
isOldValid: boolean;
newPass: string;
}

interface OldPass {
isOldValid: boolean;
oldPass: string;
}

class ChangePass extends TxComponent<Props, State> {
public state: State = {
isNewValid: false,
isOldValid: false,
newPass: '',
oldPass: ''
};

public render (): React.ReactNode {
const { t } = this.props;

return (
<Modal
className='app--accounts-Modal'
header={t('Change account password')}
>
{this.renderContent()}
{this.renderButtons()}
</Modal>
);
}

private renderButtons (): React.ReactNode {
const { onClose, t } = this.props;
const { isNewValid, isOldValid } = this.state;

return (
<Modal.Actions onCancel={onClose}>
<Button
icon='sign-in'
isDisabled={!isNewValid || !isOldValid}
isPrimary
label={t('Change')}
onClick={this.doChange}
/>
</Modal.Actions>
);
}
function ChangePass ({ address, className, onClose }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const [{ isNewValid, newPass }, setNewPass] = useState<NewPass>({ isNewValid: false, newPass: '' });
const [{ isOldValid, oldPass }, setOldPass] = useState<OldPass>({ isOldValid: false, oldPass: '' });

const _onChangeNew = useCallback(
(newPass: string) =>
setNewPass({ isNewValid: keyring.isPassValid(newPass), newPass }),
[]
);

const _onChangeOld = useCallback(
(oldPass: string) =>
setOldPass({ isOldValid: keyring.isPassValid(oldPass), oldPass }),
[]
);

const _doChange = useCallback(
(): void => {
const account = address && keyring.getPair(address);

if (!account) {
return;
}

try {
if (!account.isLocked) {
account.lock();
}

account.decodePkcs8(oldPass);
} catch (error) {
setOldPass((state: OldPass) => ({ ...state, isOldValid: false }));

return;
}

try {
keyring.encryptAccount(account, newPass);
} catch (error) {
setNewPass((state: NewPass) => ({ ...state, isNewValid: false }));

return;
}

private renderContent (): React.ReactNode {
const { address, t } = this.props;
const { isNewValid, isOldValid, newPass, oldPass } = this.state;
onClose();
},
[address, newPass, oldPass, onClose]
);

return (
return (
<Modal
className={`${className} app--accounts-Modal`}
header={t('Change account password')}
>
<Modal.Content>
<AddressRow
isInline
Expand All @@ -79,92 +91,33 @@ class ChangePass extends TxComponent<Props, State> {
help={t('The existing account password as specified when this account was created or when it was last changed.')}
isError={!isOldValid}
label={t('your current password')}
onChange={this.onChangeOld}
onChange={_onChangeOld}
tabIndex={1}
value={oldPass}
/>
<Password
help={t('The new account password. Once set, all future account unlocks will be performed with this new password.')}
isError={!isNewValid}
label={t('your new password')}
onChange={this.onChangeNew}
onEnter={this.submit}
onChange={_onChangeNew}
onEnter={_doChange}
tabIndex={2}
value={newPass}
/>
</div>
</AddressRow>
</Modal.Content>
);
}

private doChange = (): void => {
const { address, onClose, t } = this.props;
const { newPass, oldPass } = this.state;
const status: Partial<ActionStatus> = {
action: 'changePassword'
};

try {
const account = address && keyring.getPair(address);

if (!account) {
status.message = t(`No keypair found for this address ${address}`);

return;
}

try {
if (!account.isLocked) {
account.lock();
}

account.decodePkcs8(oldPass);
} catch (error) {
this.setState({ isOldValid: false });
status.message = error.message;

return;
}

try {
keyring.encryptAccount(account, newPass);
status.account = address;
status.status = 'success';
status.message = t('password changed');
} catch (error) {
this.setState({ isNewValid: false });
status.status = 'error';
status.message = error.message;

return;
}
} catch (error) {
status.message = error.message;

return;
}

onClose();
}

private onChangeNew = (newPass: string): void => {
this.setState({
isNewValid: this.validatePass(newPass),
newPass
});
}

private onChangeOld = (oldPass: string): void => {
this.setState({
isOldValid: this.validatePass(oldPass),
oldPass
});
}

private validatePass (password: string): boolean {
return keyring.isPassValid(password);
}
<Modal.Actions onCancel={onClose}>
<Button
icon='sign-in'
isDisabled={!isNewValid || !isOldValid}
isPrimary
label={t('Change')}
onClick={_doChange}
/>
</Modal.Actions>
</Modal>
);
}

export default translate(ChangePass);
export default React.memo(ChangePass);
Loading

0 comments on commit 31796b8

Please sign in to comment.