Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding "show password" option #1029

Merged
merged 3 commits into from
Jun 22, 2017
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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ The appearance of the widget and the mechanics of authentication can be customiz
+ **text {String}**: The text to show.
- **allowAutocomplete {Boolean}**: Determines whether or not the the email or username inputs will allow autocomplete (`<input autocomplete />`). Defaults to `false`.
- **scrollGlobalMessagesIntoView {Boolean}**: Determines whether or not a globalMessage should be scrolled into the user's viewport. Defaults to `true`.
- **allowShowPassword {Boolean}**: Determines whether or not add a checkbox to show the password when typing it. Defaults to `false`.


#### Theming options

Expand Down
25 changes: 25 additions & 0 deletions css/index.styl
Original file line number Diff line number Diff line change
Expand Up @@ -1326,5 +1326,30 @@ tabsHeight = 40px
margin-right 5px
position relative

// show password
.auth0-lock-input-show-password
position relative

.auth0-lock-show-password
position absolute
top 14px
right 12px
width 20px
height 14px

input[type=checkbox]
display none

input[type=checkbox] + label
background-image url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSIyMHB4IiBoZWlnaHQ9IjE0cHgiIHZpZXdCb3g9IjAgMCAyMCAxNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4gICAgICAgIDx0aXRsZT5zaG93X3Bhc3N3b3JkX2luYWN0aXZlPC90aXRsZT4gICAgPGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+ICAgIDxkZWZzPjwvZGVmcz4gICAgPGcgaWQ9IlBhZ2UtMSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+ICAgICAgICA8ZyBpZD0ic2hvd19wYXNzd29yZF9pbmFjdGl2ZSIgZmlsbC1ydWxlPSJub256ZXJvIiBmaWxsPSIjQ0NDQ0NDIj4gICAgICAgICAgICA8cGF0aCBkPSJNMjAsNy4xNDY0NjA3MSBDMjAsNy4zMjQ1NTU5MyAxOS44OTM4NzQ5LDcuNTA0OTY0MDcgMTkuNzg5NzkwNiw3LjYyMjkyMzI5IEMxOS41Nzk1ODExLDcuOTIxMjkwNjQgMTkuMzY5MzcxNiw4LjE1OTUyMTkzIDE5LjEwNjA5OTYsOC40NTc4ODkyMSBDMTcuODQyODAyMSw5Ljg4OTU4OTkzIDE2LjQyMDMxNjksMTEuMTQzMTk1NCAxNC44NDA2ODQ3LDEyLjA5ODQzMzUgQzEzLjg0MDY1OTIsMTIuNjk1MTY4MSAxMi43ODc1NzExLDEzLjE3Mzk0MzcgMTEuNjgxNDIwNCwxMy40MTIxNzUgQzEwLjQ2OTE0NDYsMTMuNjUwNDA2MyA5LjI1ODkwOTY0LDEzLjY1MDQwNjMgOC4wNDY2MzM4NiwxMy4zNTIwMzg5IEM1LjkzODQxNjgxLDEyLjgxNTQ0MDMgNC4wNDI0NTAwNCwxMS41NjE4MzQ5IDIuMzU2NjkyNzcsMTAuMDA5ODYyMSBDMS41NjY4NzY3MSw5LjI5Mjg1NTI5IDAuODMwMTIzMjE0LDguNTE4MDI1MjkgMC4xOTc0NTQwMTYsNy42MjI5MjMyOSBDLTAuMDY1ODE4MDA1Myw3LjI2NDQxOTg2IC0wLjA2NTgxODAwNTMsNi43ODc5NTczIDAuMTk3NDU0MDE2LDYuNDI5NDUzODcgQzAuNDA3NjYzNDU5LDYuMTMxMDg2NTUgMC42MTc4NzI5MDYsNS44OTI4NTUyNiAwLjg4MTE0NDkyOSw1LjU5NDQ4NzkgQzIuMTQ0NDQyNDYsNC4xNjI3ODcyMSAzLjU2NjkyNzczLDIuOTA5MTgxNzcgNS4xNDY1NTk4NSwxLjk1Mzk0MzY4IEM2LjE0NjU4NTM2LDEuMzU3MjA4OTkgNy4xOTk2NzM0MywwLjg3ODQzMzQ3MSA4LjMwNTgyNDE0LDAuNjQwMjAyMTgxIEM5LjUxODEsMC40MDE5NzA4ODkgMTAuNzI4MzM0OSwwLjQwMTk3MDg4OSAxMS45NDA2MTA3LDAuNzAwMzM4MjM2IEMxNC4wNDY3ODY5LDEuMjM2OTM2ODggMTUuOTQyNzUzNiwyLjQ5MDU0MjMxIDE3LjYyODUxMDksNC4wNDI1MTUxMSBDMTguNDE4MzI3LDQuNzU5NTIxOTEgMTkuMTU1MDgwNSw1LjUzNDM1MTgzIDE5Ljc4Nzc0OTYsNi40Mjk0NTM4NyBDMTkuODkzODc0OSw2LjU0OTcyNjAxIDE5Ljk5Nzk1OTEsNi43Mjc4MjEyMyAxOS45OTc5NTkxLDYuOTA1OTE2NDUgQzIwLDcuMDI2MTg4NTkgMjAsNy4wMjYxODg1OSAyMCw3LjA4NjMyNDYyIEMyMCw3LjE0NjQ2MDcxIDIwLDcuMTQ2NDYwNzEgMjAsNy4xNDY0NjA3MSBaIE05Ljk5MTk0NjA3LDIuMjkyOTUyNDIgQzcuNDk4OTQzMTQsMi4yOTI5NTI0MiA1LjQ1MjAwNDM4LDQuMzM5ODkxMiA1LjQ1MjAwNDM4LDYuODMyODk0MTMgQzUuNDUyMDA0MzgsOS4zMjU4OTcgNy40OTg5NDMxNCwxMS4zNzI4MzU5IDkuOTkxOTQ2MDcsMTEuMzcyODM1OSBDMTIuNDg0OTQ5LDExLjM3MjgzNTkgMTQuNTMxODg3Nyw5LjMyNTg5NyAxNC41MzE4ODc3LDYuODMyODk0MTMgQzE0LjUzMTg4NzcsNC4zMzk4OTEyIDEyLjQ4NDk0OSwyLjI5Mjk1MjQyIDkuOTkxOTQ2MDcsMi4yOTI5NTI0MiBaIE05Ljk5MTk0NjA3LDkuMTM3NTU4NzkgQzguNzEzMjI4ODYsOS4xMzc1NTg3OSA3LjY4OTc1OTQzLDguMTE0MDg5NDMgNy42ODk3NTk0Myw2LjgzNTM3MjI0IEM3LjY4OTc1OTQzLDUuNTU2NjU1MDcgOC43MTMyMjg4Niw0LjUzMzE4NTY2IDkuOTkxOTQ2MDcsNC41MzMxODU2NiBDMTEuMjcwNjYzMyw0LjUzMzE4NTY2IDEyLjI5NDEzMjYsNS41NTY2NTUwNyAxMi4yOTQxMzI2LDYuODM1MzcyMjQgQzEyLjI5NDEzMjYsOC4xMTQwODk0MyAxMS4yNzA2NjMzLDkuMTM3NTU4NzkgOS45OTE5NDYwNyw5LjEzNzU1ODc5IFoiIGlkPSJTaGFwZSI+PC9wYXRoPiAgICAgICAgPC9nPiAgICA8L2c+PC9zdmc+')
width 20px
height 14px
display inline-block
cursor pointer
vertical-align top

input[type=checkbox]:checked + label
background-image url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSIyMHB4IiBoZWlnaHQ9IjE0cHgiIHZpZXdCb3g9IjAgMCAyMCAxNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4gICAgICAgIDx0aXRsZT5zaG93X3Bhc3N3b3JkX2FjdGl2ZTwvdGl0bGU+ICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPiAgICA8ZGVmcz48L2RlZnM+ICAgIDxnIGlkPSJQYWdlLTEiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPiAgICAgICAgPGcgaWQ9InNob3dfcGFzc3dvcmRfYWN0aXZlIiBmaWxsLXJ1bGU9Im5vbnplcm8iIGZpbGw9IiMyMEI0RkYiPiAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMCw3LjE0NjQ2MDcxIEMyMCw3LjMyNDU1NTkzIDE5Ljg5Mzg3NDksNy41MDQ5NjQwNyAxOS43ODk3OTA2LDcuNjIyOTIzMjkgQzE5LjU3OTU4MTEsNy45MjEyOTA2NCAxOS4zNjkzNzE2LDguMTU5NTIxOTMgMTkuMTA2MDk5Niw4LjQ1Nzg4OTIxIEMxNy44NDI4MDIxLDkuODg5NTg5OTMgMTYuNDIwMzE2OSwxMS4xNDMxOTU0IDE0Ljg0MDY4NDcsMTIuMDk4NDMzNSBDMTMuODQwNjU5MiwxMi42OTUxNjgxIDEyLjc4NzU3MTEsMTMuMTczOTQzNyAxMS42ODE0MjA0LDEzLjQxMjE3NSBDMTAuNDY5MTQ0NiwxMy42NTA0MDYzIDkuMjU4OTA5NjQsMTMuNjUwNDA2MyA4LjA0NjYzMzg2LDEzLjM1MjAzODkgQzUuOTM4NDE2ODEsMTIuODE1NDQwMyA0LjA0MjQ1MDA0LDExLjU2MTgzNDkgMi4zNTY2OTI3NywxMC4wMDk4NjIxIEMxLjU2Njg3NjcxLDkuMjkyODU1MjkgMC44MzAxMjMyMTQsOC41MTgwMjUyOSAwLjE5NzQ1NDAxNiw3LjYyMjkyMzI5IEMtMC4wNjU4MTgwMDUzLDcuMjY0NDE5ODYgLTAuMDY1ODE4MDA1Myw2Ljc4Nzk1NzMgMC4xOTc0NTQwMTYsNi40Mjk0NTM4NyBDMC40MDc2NjM0NTksNi4xMzEwODY1NSAwLjYxNzg3MjkwNiw1Ljg5Mjg1NTI2IDAuODgxMTQ0OTI5LDUuNTk0NDg3OSBDMi4xNDQ0NDI0Niw0LjE2Mjc4NzIxIDMuNTY2OTI3NzMsMi45MDkxODE3NyA1LjE0NjU1OTg1LDEuOTUzOTQzNjggQzYuMTQ2NTg1MzYsMS4zNTcyMDg5OSA3LjE5OTY3MzQzLDAuODc4NDMzNDcxIDguMzA1ODI0MTQsMC42NDAyMDIxODEgQzkuNTE4MSwwLjQwMTk3MDg4OSAxMC43MjgzMzQ5LDAuNDAxOTcwODg5IDExLjk0MDYxMDcsMC43MDAzMzgyMzYgQzE0LjA0Njc4NjksMS4yMzY5MzY4OCAxNS45NDI3NTM2LDIuNDkwNTQyMzEgMTcuNjI4NTEwOSw0LjA0MjUxNTExIEMxOC40MTgzMjcsNC43NTk1MjE5MSAxOS4xNTUwODA1LDUuNTM0MzUxODMgMTkuNzg3NzQ5Niw2LjQyOTQ1Mzg3IEMxOS44OTM4NzQ5LDYuNTQ5NzI2MDEgMTkuOTk3OTU5MSw2LjcyNzgyMTIzIDE5Ljk5Nzk1OTEsNi45MDU5MTY0NSBDMjAsNy4wMjYxODg1OSAyMCw3LjAyNjE4ODU5IDIwLDcuMDg2MzI0NjIgQzIwLDcuMTQ2NDYwNzEgMjAsNy4xNDY0NjA3MSAyMCw3LjE0NjQ2MDcxIFogTTkuOTkxOTQ2MDcsMi4yOTI5NTI0MiBDNy40OTg5NDMxNCwyLjI5Mjk1MjQyIDUuNDUyMDA0MzgsNC4zMzk4OTEyIDUuNDUyMDA0MzgsNi44MzI4OTQxMyBDNS40NTIwMDQzOCw5LjMyNTg5NyA3LjQ5ODk0MzE0LDExLjM3MjgzNTkgOS45OTE5NDYwNywxMS4zNzI4MzU5IEMxMi40ODQ5NDksMTEuMzcyODM1OSAxNC41MzE4ODc3LDkuMzI1ODk3IDE0LjUzMTg4NzcsNi44MzI4OTQxMyBDMTQuNTMxODg3Nyw0LjMzOTg5MTIgMTIuNDg0OTQ5LDIuMjkyOTUyNDIgOS45OTE5NDYwNywyLjI5Mjk1MjQyIFogTTkuOTkxOTQ2MDcsOS4xMzc1NTg3OSBDOC43MTMyMjg4Niw5LjEzNzU1ODc5IDcuNjg5NzU5NDMsOC4xMTQwODk0MyA3LjY4OTc1OTQzLDYuODM1MzcyMjQgQzcuNjg5NzU5NDMsNS41NTY2NTUwNyA4LjcxMzIyODg2LDQuNTMzMTg1NjYgOS45OTE5NDYwNyw0LjUzMzE4NTY2IEMxMS4yNzA2NjMzLDQuNTMzMTg1NjYgMTIuMjk0MTMyNiw1LjU1NjY1NTA3IDEyLjI5NDEzMjYsNi44MzUzNzIyNCBDMTIuMjk0MTMyNiw4LjExNDA4OTQzIDExLjI3MDY2MzMsOS4xMzc1NTg3OSA5Ljk5MTk0NjA3LDkuMTM3NTU4NzkgWiIgaWQ9IlNoYXBlIj48L3BhdGg+ICAgICAgICA8L2c+ICAgIDwvZz48L3N2Zz4=')

input[type="button"]
cursor pointer
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"test:jest:watch": "jest --watch --coverage",
"publish:cdn": "ccu",
"release": "scripts/release.sh",
"i18n:translate": "grunt dist; node scripts/complete-translations.js"
"i18n:translate": "grunt dist && node scripts/complete-translations.js"
},
"devDependencies": {
"babel-core": "^6.17.0",
Expand Down Expand Up @@ -145,4 +145,4 @@
"git add"
]
}
}
}
121 changes: 89 additions & 32 deletions src/__tests__/field/__snapshots__/password_pane.test.jsx.snap
Original file line number Diff line number Diff line change
@@ -1,54 +1,111 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`PasswordPane calls \`swap\` onChange 1`] = `
exports[`PasswordPane calls \`swap\` when checkbox is clicked 1`] = `
Array [
"updateEntity",
"lock",
1,
undefined,
true,
]
`;

exports[`PasswordPane calls \`swap\` when password changes 1`] = `
Array [
"updateEntity",
"lock",
1,
"setPassword",
"newUser",
"newPassword",
"policy",
]
`;

exports[`PasswordPane disables input when submitting 1`] = `
<div
data-__type="password_input"
data-disabled={true}
data-invalidHint="blankErrorHint"
data-isValid={false}
data-onChange={[Function]}
data-placeholder="placeholder"
data-policy="policy"
data-strengthMessages={Object {}}
data-value="password"
/>
className="auth0-lock-input-show-password"
>
<div
data-__type="password_input"
data-disabled={true}
data-invalidHint="blankErrorHint"
data-isValid={false}
data-onChange={[Function]}
data-placeholder="placeholder"
data-policy="policy"
data-showPassword="showPassword"
data-strengthMessages={Object {}}
data-value="password"
/>
</div>
`;

exports[`PasswordPane renders correctly 1`] = `
<div
data-__type="password_input"
data-disabled={false}
data-invalidHint="blankErrorHint"
data-isValid={false}
data-onChange={[Function]}
data-placeholder="placeholder"
data-policy="policy"
data-strengthMessages={Object {}}
data-value="password"
/>
className="auth0-lock-input-show-password"
>
<div
data-__type="password_input"
data-disabled={false}
data-invalidHint="blankErrorHint"
data-isValid={false}
data-onChange={[Function]}
data-placeholder="placeholder"
data-policy="policy"
data-showPassword="showPassword"
data-strengthMessages={Object {}}
data-value="password"
/>
</div>
`;

exports[`PasswordPane renders correctly when \`allowShowPassword\` is true 1`] = `
<div
className="auth0-lock-input-show-password"
>
<div
data-__type="password_input"
data-disabled={false}
data-invalidHint="blankErrorHint"
data-isValid={false}
data-onChange={[Function]}
data-placeholder="placeholder"
data-policy="policy"
data-showPassword="showPassword"
data-strengthMessages={Object {}}
data-value="password"
/>
<div
className="auth0-lock-show-password"
>
<input
id="slideOne"
onChange={[Function]}
type="checkbox"
/>
<label
htmlFor="slideOne"
title="showPassword"
/>
</div>
</div>
`;

exports[`PasswordPane sets isValid as true when \`isFieldVisiblyInvalid\` is false 1`] = `
<div
data-__type="password_input"
data-disabled={false}
data-invalidHint="blankErrorHint"
data-isValid={true}
data-onChange={[Function]}
data-placeholder="placeholder"
data-policy="policy"
data-strengthMessages={Object {}}
data-value="password"
/>
className="auth0-lock-input-show-password"
>
<div
data-__type="password_input"
data-disabled={false}
data-invalidHint="blankErrorHint"
data-isValid={true}
data-onChange={[Function]}
data-placeholder="placeholder"
data-policy="policy"
data-showPassword="showPassword"
data-strengthMessages={Object {}}
data-value="password"
/>
</div>
`;
30 changes: 24 additions & 6 deletions src/__tests__/field/password_pane.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ const getComponent = () => require('field/password/password_pane').default;
describe('PasswordPane', () => {
const defaultProps = {
i18n: {
str: (...keys) => keys.join(',')
str: (...keys) => keys.join(','),
html: (...keys) => keys.join(',')
},
lock: {},
placeholder: 'placeholder',
Expand All @@ -22,7 +23,7 @@ describe('PasswordPane', () => {
jest.resetModules();

jest.mock('field/index', () => ({
getFieldValue: () => 'password',
getFieldValue: (m, field) => field,
isFieldVisiblyInvalid: () => true
}));

Expand All @@ -34,7 +35,7 @@ describe('PasswordPane', () => {
id: () => 1,
submitting: () => false,
ui: {
avatar: () => false
allowShowPassword: () => false
}
}));

Expand All @@ -48,6 +49,11 @@ describe('PasswordPane', () => {
const PasswordPane = getComponent();
expectComponent(<PasswordPane {...defaultProps} />).toMatchSnapshot();
});
it('renders correctly when `allowShowPassword` is true', () => {
require('core/index').ui.allowShowPassword = () => true;
const PasswordPane = getComponent();
expectComponent(<PasswordPane {...defaultProps} />).toMatchSnapshot();
});
it('disables input when submitting', () => {
require('core/index').submitting = () => true;
const PasswordPane = getComponent();
Expand All @@ -60,12 +66,24 @@ describe('PasswordPane', () => {

expectComponent(<PasswordPane {...defaultProps} />).toMatchSnapshot();
});
it('calls `swap` onChange', () => {
it('calls `swap` when password changes', () => {
let PasswordPane = getComponent();

const wrapper = mount(<PasswordPane {...defaultProps} />);
const props = extractPropsFromWrapper(wrapper, 1);
props.onChange({ target: { value: 'newPassword' } });

const { mock } = require('store/index').swap;
expect(mock.calls.length).toBe(1);
expect(mock.calls[0]).toMatchSnapshot();
});
it('calls `swap` when checkbox is clicked', () => {
require('core/index').ui.allowShowPassword = () => true;
let PasswordPane = getComponent();

const wrapper = mount(<PasswordPane {...defaultProps} />);
const props = extractPropsFromWrapper(wrapper);
props.onChange({ target: { value: 'newUser' } });
const props = wrapper.find('div input').props();
props.onChange({ target: { checked: true } });

const { mock } = require('store/index').swap;
expect(mock.calls.length).toBe(1);
Expand Down
10 changes: 7 additions & 3 deletions src/core/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ function extractUIOptions(id, options) {
rememberLastLogin: undefined === options.rememberLastLogin ? true : !!options.rememberLastLogin,
allowAutocomplete: !!options.allowAutocomplete,
authButtonsTheme: typeof authButtons === 'object' ? authButtons : {},
allowShowPassword: !!options.allowShowPassword,
scrollGlobalMessagesIntoView: undefined === options.scrollGlobalMessagesIntoView
? true
: !!options.scrollGlobalMessagesIntoView
Expand Down Expand Up @@ -189,7 +190,8 @@ export const ui = {
authButtonsTheme: lock => getUIAttribute(lock, 'authButtonsTheme'),
rememberLastLogin: m => tget(m, 'rememberLastLogin', getUIAttribute(m, 'rememberLastLogin')),
allowAutocomplete: m => tget(m, 'allowAutocomplete', getUIAttribute(m, 'allowAutocomplete')),
scrollGlobalMessagesIntoView: lock => getUIAttribute(lock, 'scrollGlobalMessagesIntoView')
scrollGlobalMessagesIntoView: lock => getUIAttribute(lock, 'scrollGlobalMessagesIntoView'),
allowShowPassword: m => tget(m, 'allowShowPassword', getUIAttribute(m, 'allowShowPassword'))
};

const { get: getAuthAttribute } = dataFns(['core', 'auth']);
Expand Down Expand Up @@ -217,8 +219,7 @@ function extractAuthOptions(options) {
sso,
state,
nonce
} =
options.auth || {};
} = options.auth || {};

let { oidcConformant } = options;

Expand Down Expand Up @@ -585,6 +586,9 @@ export function overrideOptions(m, opts) {
if (typeof opts.allowAutocomplete === 'boolean') {
m = tset(m, 'allowAutocomplete', opts.allowAutocomplete);
}
if (typeof opts.allowShowPassword === 'boolean') {
m = tset(m, 'allowShowPassword', opts.allowShowPassword);
}

return m;
}
4 changes: 4 additions & 0 deletions src/field/password.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@ export function validatePassword(password, policy) {
export function setPassword(m, password, policy) {
return setField(m, 'password', password, validatePassword, policy);
}

export function setShowPassword(m, checked) {
return setField(m, 'showPassword', checked, () => true);
}
39 changes: 25 additions & 14 deletions src/field/password/password_pane.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,39 @@ import PasswordInput from '../../ui/input/password_input';
import * as c from '../index';
import { swap, updateEntity } from '../../store/index';
import * as l from '../../core/index';
import { setPassword } from '../password';
import { setPassword, setShowPassword } from '../password';

export default class PasswordPane extends React.Component {
handleChange(e) {
handleChange = e => {
const { lock, policy } = this.props;
swap(updateEntity, 'lock', l.id(lock), setPassword, e.target.value, policy);
}
};
handleShowPasswordChange = e => {
const { lock } = this.props;
swap(updateEntity, 'lock', l.id(lock), setShowPassword, e.target.checked);
};

render() {
const { i18n, lock, placeholder, policy, strengthMessages } = this.props;

return (
<PasswordInput
value={c.getFieldValue(lock, 'password')}
invalidHint={i18n.str('blankErrorHint')}
isValid={!c.isFieldVisiblyInvalid(lock, 'password')}
onChange={::this.handleChange}
placeholder={placeholder}
strengthMessages={strengthMessages}
disabled={l.submitting(lock)}
policy={policy}
/>
<div className="auth0-lock-input-show-password">
<PasswordInput
value={c.getFieldValue(lock, 'password')}
invalidHint={i18n.str('blankErrorHint')}
isValid={!c.isFieldVisiblyInvalid(lock, 'password')}
onChange={this.handleChange}
placeholder={placeholder}
strengthMessages={strengthMessages}
disabled={l.submitting(lock)}
policy={policy}
showPassword={c.getFieldValue(lock, 'showPassword', false)}
/>
{l.ui.allowShowPassword(lock) &&
<div className="auth0-lock-show-password">
<input type="checkbox" id="slideOne" onChange={this.handleShowPasswordChange} />
<label htmlFor="slideOne" title={i18n.str('showPassword')} />
</div>}
</div>
);
}
}
Expand Down
6 changes: 5 additions & 1 deletion src/i18n/ca.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// This file was automatically translated.
// Feel free to submit a PR if you find a more accurate translation.

export default {
error: {
forgotPassword: {
Expand Down Expand Up @@ -109,5 +112,6 @@ export default {
mfaLoginTitle: 'Verificació en 2 passos',
mfaLoginInstructions: 'Indiqueu el codi de verificació generat per la seva aplicació de mòbil.',
mfaSubmitLabel: 'Inicia sessió',
mfaCodeErrorHint: 'Utilitzeu %d xifres'
mfaCodeErrorHint: 'Utilitzeu %d xifres',
showPassword: 'Ensenya la contrasenya'
};
3 changes: 2 additions & 1 deletion src/i18n/cs.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,5 +112,6 @@ export default {
mfaSubmitLabel: 'Přihlásit',
mfaCodeErrorHint: 'Použijte %d čísel',
forgotPasswordTitle: 'Obnovit heslo',
signupTitle: 'Registrovat se'
signupTitle: 'Registrovat se',
showPassword: 'Zobrazit heslo'
};
3 changes: 2 additions & 1 deletion src/i18n/da.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,5 +112,6 @@ export default {
mfaLoginTitle: 'Tofaktorgodkendelse',
mfaLoginInstructions: 'Indtast venligst bekræftelseskoden genereret af din mobilapplikation.',
mfaSubmitLabel: 'Log på',
mfaCodeErrorHint: 'Brug %d tal'
mfaCodeErrorHint: 'Brug %d tal',
showPassword: 'Vis adgangskode'
};
Loading