ngx-pwd-strength
Version:
Angular Package, that measure password strength and indicate how secure is it
310 lines (298 loc) • 19.4 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('rxjs'), require('zxcvbn3'), require('@angular/common')) :
typeof define === 'function' && define.amd ? define('ngx-pwd-strength', ['exports', '@angular/core', 'rxjs', 'zxcvbn3', '@angular/common'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["ngx-pwd-strength"] = {}, global.ng.core, global.rxjs, global.zxcvbn3, global.ng.common));
})(this, (function (exports, i0, rxjs, zxcvbn3, i2) { 'use strict';
function _interopNamespace(e) {
if (e && e.__esModule) return e;
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n["default"] = e;
return Object.freeze(n);
}
var i0__namespace = /*#__PURE__*/_interopNamespace(i0);
var i2__namespace = /*#__PURE__*/_interopNamespace(i2);
var NgxPwdStrengthService = /** @class */ (function () {
function NgxPwdStrengthService() {
this._options = { enableFeedback: true };
this.score = new rxjs.BehaviorSubject(null);
this.updatedScore$ = this.score.asObservable();
}
NgxPwdStrengthService.prototype.updateScore = function (data) {
this.score.next(data);
};
NgxPwdStrengthService.prototype.init = function (options) {
this._options = options;
};
/**
* Score:
* 0 # too guessable: risky password. (guesses < 10^3)
* 1 # very guessable: protection from throttled online attacks. (guesses < 10^6)
* 2 # somewhat guessable: protection from unthrottled online attacks. (guesses < 10^8)
* 3 # safely unguessable: moderate protection from offline slow-hash scenario. (guesses < 10^10)
* 4 # very unguessable: strong protection from offline slow-hash scenario. (guesses >= 10^10)
* @param password
*/
NgxPwdStrengthService.prototype.getScore = function (password) {
var result = zxcvbn3.zxcvbn(password);
return this._options.enableFeedback ? { score: result.score, feedback: result.feedback } : { score: result.score };
};
return NgxPwdStrengthService;
}());
NgxPwdStrengthService.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.9", ngImport: i0__namespace, type: NgxPwdStrengthService, deps: [], target: i0__namespace.ɵɵFactoryTarget.Injectable });
NgxPwdStrengthService.ɵprov = i0__namespace.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.9", ngImport: i0__namespace, type: NgxPwdStrengthService });
i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.9", ngImport: i0__namespace, type: NgxPwdStrengthService, decorators: [{
type: i0.Injectable
}] });
var NgxPwdStrengthComponent = /** @class */ (function () {
function NgxPwdStrengthComponent(ngxPwdStrengthService, elementRef) {
this.ngxPwdStrengthService = ngxPwdStrengthService;
this.elementRef = elementRef;
this.display = false;
this.pwdScore = null;
this.popupOffset = 5;
this.popupPosition = "bottom";
}
NgxPwdStrengthComponent.prototype.ngOnInit = function () {
var _this = this;
this.subscription = this.ngxPwdStrengthService.updatedScore$.subscribe(function (data) {
_this.pwdScore = data;
});
};
Object.defineProperty(NgxPwdStrengthComponent.prototype, "show", {
get: function () {
return this.display;
},
set: function (value) {
if (value) {
this.setHostPosition(this.popupPosition);
}
this.display = value;
},
enumerable: false,
configurable: true
});
Object.defineProperty(NgxPwdStrengthComponent.prototype, "element", {
get: function () {
return this.data.element;
},
enumerable: false,
configurable: true
});
Object.defineProperty(NgxPwdStrengthComponent.prototype, "elementPosition", {
get: function () {
return this.data.elementPosition;
},
enumerable: false,
configurable: true
});
NgxPwdStrengthComponent.prototype.setHostPosition = function (position) {
var isSvg = this.element instanceof SVGElement;
var popup = this.elementRef.nativeElement;
var isCustomPosition = !this.elementPosition.right;
var elementHeight = isSvg ? this.element.getBoundingClientRect().height : this.element.offsetHeight;
var elementWidth = isSvg ? this.element.getBoundingClientRect().width : this.element.offsetWidth;
var popupHeight = popup.clientHeight;
var popupWidth = popup.clientWidth;
var scrollY = window.pageYOffset;
if (isCustomPosition) {
elementHeight = 0;
elementWidth = 0;
}
var topStyle;
var leftStyle;
switch (position) {
case "top":
topStyle = (this.elementPosition.top + scrollY) - (popupHeight + this.popupOffset);
leftStyle = this.elementPosition.left;
break;
case "bottom":
topStyle = (this.elementPosition.top + scrollY) + elementHeight + this.popupOffset;
leftStyle = this.elementPosition.left;
break;
case "left":
leftStyle = this.elementPosition.left - popupWidth - this.popupOffset;
topStyle = (this.elementPosition.top + scrollY);
break;
case "right":
leftStyle = this.elementPosition.left + elementWidth + this.popupOffset;
topStyle = (this.elementPosition.top + scrollY);
}
this.hostStyleTop = topStyle + "px";
this.hostStyleLeft = leftStyle + "px";
this.hostStyleWidth = this.elementPosition.width + "px";
};
NgxPwdStrengthComponent.prototype.ngOnDestroy = function () {
this.subscription.unsubscribe();
};
return NgxPwdStrengthComponent;
}());
NgxPwdStrengthComponent.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.9", ngImport: i0__namespace, type: NgxPwdStrengthComponent, deps: [{ token: NgxPwdStrengthService }, { token: i0__namespace.ElementRef }], target: i0__namespace.ɵɵFactoryTarget.Component });
NgxPwdStrengthComponent.ɵcmp = i0__namespace.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.9", type: NgxPwdStrengthComponent, selector: "lib-ngx-pwd-strength", inputs: { data: "data", show: "show" }, host: { properties: { "style.top": "this.hostStyleTop", "style.left": "this.hostStyleLeft", "style.width": "this.hostStyleWidth" }, classAttribute: "ngx-pwd-strength-popup" }, ngImport: i0__namespace, template: "<div class=\"pwd-popup\">\r\n <div class=\"pwd-strength\">\r\n <div class=\"pwd-strength-fill\" [attr.data-score]=\"pwdScore?.score\"></div>\r\n </div>\r\n <ng-container *ngIf=\"pwdScore?.feedback\">\r\n <p class=\"password-feedback\" *ngIf=\"pwdScore?.feedback?.warning\">\r\n <span>⚠</span> {{pwdScore?.feedback?.warning}}\r\n </p>\r\n <ul class=\"password-suggetion\" *ngIf=\"pwdScore?.feedback?.suggestions\">\r\n <li *ngFor=\"let suggetion of pwdScore?.feedback?.suggestions\">{{suggetion}}</li>\r\n </ul>\r\n </ng-container>\r\n</div>\r\n\r\n", styles: [":host{background-color:#fff;color:#000;text-align:left;border-radius:2px;position:absolute;pointer-events:none;padding:10px;z-index:1000;display:block;transition:opacity .3s;opacity:1;top:0;left:0;transition:opacity .3s ease-in-out;box-shadow:0 1px 3px #0006;font-family:-apple-system,BlinkMacSystemFont,Roboto,Helvetica,Arial,sans-serif}:host.ngx-pwd-strength-popup .pwd-popup .pwd-strength{position:relative;height:3px;background:#d3d3d3;margin:10px auto}:host.ngx-pwd-strength-popup .pwd-popup .pwd-strength:before,:host.ngx-pwd-strength-popup .pwd-popup .pwd-strength:after{content:\"\";height:inherit;background:transparent;display:block;border-color:#fff;border-style:solid;border-width:0 5px 0 5px;position:absolute;width:calc((100% - 20px) / 5);z-index:10}:host.ngx-pwd-strength-popup .pwd-popup .pwd-strength:before{left:calc((100% - 20px) / 5)}:host.ngx-pwd-strength-popup .pwd-popup .pwd-strength:after{right:calc((100% - 20px) / 5)}:host.ngx-pwd-strength-popup .pwd-popup .pwd-strength-fill{background:transparent;height:inherit;position:absolute;width:0;border-radius:inherit;transition:width .5s ease-in-out,background .25s}:host.ngx-pwd-strength-popup .pwd-popup .pwd-strength-fill[data-score=\"0\"]{background:darkred;width:20%}:host.ngx-pwd-strength-popup .pwd-popup .pwd-strength-fill[data-score=\"1\"]{background:orangered;width:40%}:host.ngx-pwd-strength-popup .pwd-popup .pwd-strength-fill[data-score=\"2\"]{background:orange;width:60%}:host.ngx-pwd-strength-popup .pwd-popup .pwd-strength-fill[data-score=\"3\"]{background:yellowgreen;width:80%}:host.ngx-pwd-strength-popup .pwd-popup .pwd-strength-fill[data-score=\"4\"]{background:green;width:100%}:host.ngx-pwd-strength-popup .pwd-popup .password-feedback,:host.ngx-pwd-strength-popup .pwd-popup .password-suggetion{font-size:80%;font-weight:400;display:block;margin-top:.25rem}:host.ngx-pwd-strength-popup .pwd-popup .password-suggetion{color:#6e757d!important}:host.ngx-pwd-strength-popup .pwd-popup .password-feedback{color:orange!important}:host ul{padding-left:14px;line-height:17px}\n"], directives: [{ type: i2__namespace.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2__namespace.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.9", ngImport: i0__namespace, type: NgxPwdStrengthComponent, decorators: [{
type: i0.Component,
args: [{
selector: 'lib-ngx-pwd-strength',
templateUrl: './lib-ngx-pwd-strength.component.html',
host: { class: "ngx-pwd-strength-popup" },
styleUrls: [
'./lib-ngx-pwd-strength.component.scss'
]
}]
}], ctorParameters: function () { return [{ type: NgxPwdStrengthService }, { type: i0__namespace.ElementRef }]; }, propDecorators: { data: [{
type: i0.Input
}], hostStyleTop: [{
type: i0.HostBinding,
args: ["style.top"]
}], hostStyleLeft: [{
type: i0.HostBinding,
args: ["style.left"]
}], hostStyleWidth: [{
type: i0.HostBinding,
args: ["style.width"]
}], show: [{
type: i0.Input
}] } });
var NgxPwdStrengthDirective = /** @class */ (function () {
function NgxPwdStrengthDirective(ngxPwdStrengthService, elementRef, componentFactoryResolver, appRef, injector) {
this.ngxPwdStrengthService = ngxPwdStrengthService;
this.elementRef = elementRef;
this.componentFactoryResolver = componentFactoryResolver;
this.appRef = appRef;
this.injector = injector;
}
Object.defineProperty(NgxPwdStrengthDirective.prototype, "isPopupDestroyed", {
get: function () {
return this.componentRef && this.componentRef.hostView.destroyed;
},
enumerable: false,
configurable: true
});
NgxPwdStrengthDirective.prototype.getHostPosition = function () {
this.hostPosition = this.elementRef.nativeElement.getBoundingClientRect();
};
NgxPwdStrengthDirective.prototype.onMouseEnter = function (value) {
this.displayPopup();
this.ratePassword(value);
};
NgxPwdStrengthDirective.prototype.onInput = function (value) {
this.ratePassword(value);
};
NgxPwdStrengthDirective.prototype.onMouseLeave = function () {
this.destroyPopup();
};
NgxPwdStrengthDirective.prototype.ratePassword = function (password) {
if (password) {
var score = this.ngxPwdStrengthService.getScore(password);
this.ngxPwdStrengthService.updateScore(score);
}
else {
this.ngxPwdStrengthService.updateScore(null);
}
};
NgxPwdStrengthDirective.prototype.displayPopup = function () {
if (!this.componentRef || this.isPopupDestroyed) {
this.buildPopup();
}
};
NgxPwdStrengthDirective.prototype.buildPopup = function () {
this.getHostPosition();
this.loadComponent(NgxPwdStrengthComponent);
};
NgxPwdStrengthDirective.prototype.loadComponent = function (component) {
this.componentRef = this.componentFactoryResolver
.resolveComponentFactory(component)
.create(this.injector);
var hostComponent = this.componentRef.instance;
hostComponent.data = {
element: this.elementRef.nativeElement,
elementPosition: this.hostPosition
};
this.appRef.attachView(this.componentRef.hostView);
var domElem = this.componentRef.hostView.rootNodes[0];
document.body.appendChild(domElem);
hostComponent.show = true;
};
NgxPwdStrengthDirective.prototype.destroyPopup = function () {
if (!this.isPopupDestroyed) {
this.componentRef.instance.show = false;
if (!this.componentRef || this.isPopupDestroyed) {
return;
}
this.appRef.detachView(this.componentRef.hostView);
this.componentRef.destroy();
}
};
return NgxPwdStrengthDirective;
}());
NgxPwdStrengthDirective.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.9", ngImport: i0__namespace, type: NgxPwdStrengthDirective, deps: [{ token: NgxPwdStrengthService }, { token: i0__namespace.ElementRef }, { token: i0__namespace.ComponentFactoryResolver }, { token: i0__namespace.ApplicationRef }, { token: i0__namespace.Injector }], target: i0__namespace.ɵɵFactoryTarget.Directive });
NgxPwdStrengthDirective.ɵdir = i0__namespace.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.2.9", type: NgxPwdStrengthDirective, selector: "input[type=password][ngxPwdStrength]", host: { listeners: { "focusin": "onMouseEnter($event.target.value)", "input": "onInput($event.target.value)", "focusout": "onMouseLeave()" } }, exportAs: ["ngxPwdStrength"], ngImport: i0__namespace });
i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.9", ngImport: i0__namespace, type: NgxPwdStrengthDirective, decorators: [{
type: i0.Directive,
args: [{
selector: 'input[type=password][ngxPwdStrength]',
exportAs: 'ngxPwdStrength'
}]
}], ctorParameters: function () { return [{ type: NgxPwdStrengthService }, { type: i0__namespace.ElementRef }, { type: i0__namespace.ComponentFactoryResolver }, { type: i0__namespace.ApplicationRef }, { type: i0__namespace.Injector }]; }, propDecorators: { onMouseEnter: [{
type: i0.HostListener,
args: ["focusin", ["$event.target.value"]]
}], onInput: [{
type: i0.HostListener,
args: ["input", ["$event.target.value"]]
}], onMouseLeave: [{
type: i0.HostListener,
args: ["focusout"]
}] } });
var NgxPwdStrengthModule = /** @class */ (function () {
function NgxPwdStrengthModule() {
}
return NgxPwdStrengthModule;
}());
NgxPwdStrengthModule.ɵfac = i0__namespace.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.9", ngImport: i0__namespace, type: NgxPwdStrengthModule, deps: [], target: i0__namespace.ɵɵFactoryTarget.NgModule });
NgxPwdStrengthModule.ɵmod = i0__namespace.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.9", ngImport: i0__namespace, type: NgxPwdStrengthModule, declarations: [NgxPwdStrengthComponent,
NgxPwdStrengthDirective], imports: [i2.CommonModule], exports: [NgxPwdStrengthDirective] });
NgxPwdStrengthModule.ɵinj = i0__namespace.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.9", ngImport: i0__namespace, type: NgxPwdStrengthModule, providers: [NgxPwdStrengthService], imports: [[
i2.CommonModule
]] });
i0__namespace.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.9", ngImport: i0__namespace, type: NgxPwdStrengthModule, decorators: [{
type: i0.NgModule,
args: [{
declarations: [
NgxPwdStrengthComponent,
NgxPwdStrengthDirective
],
imports: [
i2.CommonModule
],
exports: [
NgxPwdStrengthDirective
],
providers: [NgxPwdStrengthService],
entryComponents: [
NgxPwdStrengthComponent
]
}]
}] });
/*
* Public API Surface of ngx-pwd-strength
*/
/**
* Generated bundle index. Do not edit.
*/
exports.NgxPwdStrengthComponent = NgxPwdStrengthComponent;
exports.NgxPwdStrengthDirective = NgxPwdStrengthDirective;
exports.NgxPwdStrengthModule = NgxPwdStrengthModule;
exports.NgxPwdStrengthService = NgxPwdStrengthService;
Object.defineProperty(exports, '__esModule', { value: true });
}));
//# sourceMappingURL=ngx-pwd-strength.umd.js.map