@nextcloud/vue
Version:
Nextcloud vue components
311 lines (310 loc) • 10.8 kB
JavaScript
require('../assets/NcPasswordField-mhXQk8aT.css');
;
const axios = require("@nextcloud/axios");
const initialState = require("@nextcloud/initial-state");
const router = require("@nextcloud/router");
const core = require("@vueuse/core");
const debounce = require("debounce");
const _pluginVue2_normalizer = require("./_plugin-vue2_normalizer-V0q-tHlQ.cjs");
const NcInputField = require("./NcInputField-Dry3uU_8.cjs");
const useModelMigration = require("./useModelMigration-D5zhrNXr.cjs");
const _l10n = require("./_l10n-DM-VRK9x.cjs");
const logger = require("./logger-3HuiEIF6.cjs");
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
const axios__default = /* @__PURE__ */ _interopDefault(axios);
const debounce__default = /* @__PURE__ */ _interopDefault(debounce);
const _sfc_main$2 = {
name: "EyeIcon",
emits: ["click"],
props: {
title: {
type: String
},
fillColor: {
type: String,
default: "currentColor"
},
size: {
type: Number,
default: 24
}
}
};
var _sfc_render$2 = function render() {
var _vm = this, _c = _vm._self._c;
return _c("span", _vm._b({ staticClass: "material-design-icon eye-icon", attrs: { "aria-hidden": _vm.title ? null : "true", "aria-label": _vm.title, "role": "img" }, on: { "click": function($event) {
return _vm.$emit("click", $event);
} } }, "span", _vm.$attrs, false), [_c("svg", { staticClass: "material-design-icon__svg", attrs: { "fill": _vm.fillColor, "width": _vm.size, "height": _vm.size, "viewBox": "0 0 24 24" } }, [_c("path", { attrs: { "d": "M12,9A3,3 0 0,0 9,12A3,3 0 0,0 12,15A3,3 0 0,0 15,12A3,3 0 0,0 12,9M12,17A5,5 0 0,1 7,12A5,5 0 0,1 12,7A5,5 0 0,1 17,12A5,5 0 0,1 12,17M12,4.5C7,4.5 2.73,7.61 1,12C2.73,16.39 7,19.5 12,19.5C17,19.5 21.27,16.39 23,12C21.27,7.61 17,4.5 12,4.5Z" } }, [_vm.title ? _c("title", [_vm._v(_vm._s(_vm.title))]) : _vm._e()])])]);
};
var _sfc_staticRenderFns$2 = [];
var __component__$2 = /* @__PURE__ */ _pluginVue2_normalizer.normalizeComponent(
_sfc_main$2,
_sfc_render$2,
_sfc_staticRenderFns$2,
false,
null,
null
);
const IconEye = __component__$2.exports;
const _sfc_main$1 = {
name: "EyeOffIcon",
emits: ["click"],
props: {
title: {
type: String
},
fillColor: {
type: String,
default: "currentColor"
},
size: {
type: Number,
default: 24
}
}
};
var _sfc_render$1 = function render2() {
var _vm = this, _c = _vm._self._c;
return _c("span", _vm._b({ staticClass: "material-design-icon eye-off-icon", attrs: { "aria-hidden": _vm.title ? null : "true", "aria-label": _vm.title, "role": "img" }, on: { "click": function($event) {
return _vm.$emit("click", $event);
} } }, "span", _vm.$attrs, false), [_c("svg", { staticClass: "material-design-icon__svg", attrs: { "fill": _vm.fillColor, "width": _vm.size, "height": _vm.size, "viewBox": "0 0 24 24" } }, [_c("path", { attrs: { "d": "M11.83,9L15,12.16C15,12.11 15,12.05 15,12A3,3 0 0,0 12,9C11.94,9 11.89,9 11.83,9M7.53,9.8L9.08,11.35C9.03,11.56 9,11.77 9,12A3,3 0 0,0 12,15C12.22,15 12.44,14.97 12.65,14.92L14.2,16.47C13.53,16.8 12.79,17 12,17A5,5 0 0,1 7,12C7,11.21 7.2,10.47 7.53,9.8M2,4.27L4.28,6.55L4.73,7C3.08,8.3 1.78,10 1,12C2.73,16.39 7,19.5 12,19.5C13.55,19.5 15.03,19.2 16.38,18.66L16.81,19.08L19.73,22L21,20.73L3.27,3M12,7A5,5 0 0,1 17,12C17,12.64 16.87,13.26 16.64,13.82L19.57,16.75C21.07,15.5 22.27,13.86 23,12C21.27,7.61 17,4.5 12,4.5C10.6,4.5 9.26,4.75 8,5.2L10.17,7.35C10.74,7.13 11.35,7 12,7Z" } }, [_vm.title ? _c("title", [_vm._v(_vm._s(_vm.title))]) : _vm._e()])])]);
};
var _sfc_staticRenderFns$1 = [];
var __component__$1 = /* @__PURE__ */ _pluginVue2_normalizer.normalizeComponent(
_sfc_main$1,
_sfc_render$1,
_sfc_staticRenderFns$1,
false,
null,
null
);
const IconEyeOff = __component__$1.exports;
_l10n.register(_l10n.t28);
const passwordPolicy = initialState.loadState("core", "capabilities", {}).password_policy || null;
const NcInputFieldProps = new Set(Object.keys(NcInputField.NcInputField.props));
const _sfc_main = {
name: "NcPasswordField",
components: {
NcInputField: NcInputField.NcInputField,
IconEye,
IconEyeOff
},
// Allow forwarding all attributes
inheritAttrs: false,
model: {
prop: "modelValue",
event: "update:modelValue"
},
props: {
/**
* Any [NcInputField](#/Components/NcFields?id=ncinputfield) props
*/
// Not an actual prop but needed to show in vue-styleguidist docs
// eslint-disable-next-line
" ": {},
// Reuse all the props from NcInputField for better typing and documentation
...NcInputField.NcInputField.props,
// Redefined props
/**
* Controls whether to display the trailing button.
*/
showTrailingButton: {
type: Boolean,
// eslint-disable-next-line vue/no-boolean-default
default: true
},
/**
* Removed NcInputField props, defined only by this component
*/
trailingButtonLabel: void 0,
// Custom props
/**
* Check if the user entered a valid password using the password_policy
* app if available.
*
* Warning: this doesn't replace server side checking and will do nothing
* if the password_policy app is disabled.
*/
checkPasswordStrength: {
type: Boolean,
default: false
},
/**
* The minlength property defines the minimum number of characters
* (as UTF-16 code units) the user can enter
*/
minlength: {
type: Number,
default: 0
},
/**
* The maxlength property defines the maximum number of characters
* (as UTF-16 code units) the user can enter
*/
maxlength: {
type: Number,
default: null
},
/**
* Render as input[type=text] that looks like password field.
* Allows to avoid unwanted password-specific browser behavior,
* such as save or generate password prompt.
* Useful for secret token fields.
* Note: autocomplete="off" is ignored by browsers.
*/
asText: {
type: Boolean,
default: false
},
/**
* Visibility of the password.
* If this is set to `true` then the password will be shown to the user (input type will be set to `text`).
*/
visible: {
type: Boolean,
default: false
}
},
emits: [
"valid",
"invalid",
/**
* Removed in v9 - use `update:modelValue` (`v-model`) instead
*
* @deprecated
*/
"update:value",
/**
* Triggers when the value inside the password field is
* updated.
*
* @property {string} The new value
*/
"update:modelValue",
/** Same as update:modelValue for Vue 2 compatibility */
"update:model-value",
/**
* Updated visibility of the password
*
* @property {boolean} visible the new visibility state
*/
"update:visible"
],
setup(props, { emit }) {
const model = useModelMigration.useModelMigration("value", "update:value");
const visibility = core.useVModel(props, "visible", emit, { passive: true });
return {
t: _l10n.t,
model,
visibility
};
},
data() {
return {
internalHelpMessage: "",
isValid: null
};
},
computed: {
computedError() {
return this.error || this.isValid === false;
},
computedSuccess() {
return this.success || this.isValid === true;
},
computedHelperText() {
if (this.helperText.length > 0) {
return this.helperText;
}
return this.internalHelpMessage;
},
rules() {
const { minlength } = this;
return {
minlength: minlength ?? passwordPolicy?.minLength
};
},
trailingButtonLabelPassword() {
return this.visibility ? _l10n.t("Hide password") : _l10n.t("Show password");
},
propsAndAttrsToForward() {
return {
// Proxy all the HTML attributes
...this.$attrs,
// Proxy original NcInputField's props
...Object.fromEntries(Object.entries(this.$props).filter(([key]) => NcInputFieldProps.has(key)))
};
}
},
watch: {
model(newValue) {
if (this.checkPasswordStrength) {
if (passwordPolicy === null) {
return;
}
this.checkPassword(newValue);
}
}
},
methods: {
/**
* Focus the input element
*
* @public
*/
focus() {
this.$refs.inputField.focus();
},
/**
* Select all the text in the input
*
* @public
*/
select() {
this.$refs.inputField.select();
},
handleInput(event) {
this.model = event.target.value;
},
toggleVisibility() {
this.visibility = !this.visibility;
},
checkPassword: debounce__default.default(async function(password) {
try {
const { data } = await axios__default.default.post(router.generateOcsUrl("apps/password_policy/api/v1/validate"), { password });
this.isValid = data.ocs.data.passed;
if (data.ocs.data.passed) {
this.internalHelpMessage = _l10n.t("Password is secure");
this.$emit("valid");
return;
}
this.internalHelpMessage = data.ocs.data.reason;
this.$emit("invalid");
} catch (e) {
logger.logger.error("Password policy returned an error", e);
}
}, 500)
}
};
var _sfc_render = function render3() {
var _vm = this, _c = _vm._self._c;
return _c("NcInputField", _vm._g(_vm._b({ ref: "inputField", attrs: { "type": _vm.visibility || _vm.asText ? "text" : "password", "trailing-button-label": _vm.trailingButtonLabelPassword, "helper-text": _vm.computedHelperText, "error": _vm.computedError, "success": _vm.computedSuccess, "minlength": _vm.rules.minlength, "input-class": { "password-field__input--secure-text": !_vm.visibility && _vm.asText } }, on: { "trailing-button-click": _vm.toggleVisibility, "input": _vm.handleInput }, scopedSlots: _vm._u([!!_vm.$scopedSlots.icon || !!_vm.$slots.default || !!_vm.$scopedSlots.default ? { key: "icon", fn: function() {
return [_vm._t("icon", function() {
return [_vm._t("default")];
})];
}, proxy: true } : null, { key: "trailing-button-icon", fn: function() {
return [_vm.visibility ? _c("IconEyeOff", { attrs: { "size": 18 } }) : _c("IconEye", { attrs: { "size": 18 } })];
}, proxy: true }], null, true) }, "NcInputField", _vm.propsAndAttrsToForward, false), _vm.$listeners));
};
var _sfc_staticRenderFns = [];
var __component__ = /* @__PURE__ */ _pluginVue2_normalizer.normalizeComponent(
_sfc_main,
_sfc_render,
_sfc_staticRenderFns,
false,
null,
"822eec9d"
);
const NcPasswordField = __component__.exports;
exports.NcPasswordField = NcPasswordField;
//# sourceMappingURL=NcPasswordField-DPGGwGEl.cjs.map