@angular-helpers/security 21.2.0 → 21.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.es.md +195 -0
- package/README.md +291 -0
- package/fesm2022/angular-helpers-security-forms.mjs +110 -0
- package/fesm2022/angular-helpers-security-signal-forms.mjs +159 -0
- package/fesm2022/angular-helpers-security.mjs +1163 -181
- package/package.json +23 -3
- package/types/angular-helpers-security-forms.d.ts +65 -0
- package/types/angular-helpers-security-signal-forms.d.ts +99 -0
- package/types/angular-helpers-security.d.ts +498 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular-helpers/security",
|
|
3
|
-
"version": "21.
|
|
3
|
+
"version": "21.4.1",
|
|
4
4
|
"description": "Angular security helpers for preventing ReDoS and other security vulnerabilities",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"angular",
|
|
@@ -16,7 +16,12 @@
|
|
|
16
16
|
"xss",
|
|
17
17
|
"sanitization",
|
|
18
18
|
"password-strength",
|
|
19
|
-
"secure-storage"
|
|
19
|
+
"secure-storage",
|
|
20
|
+
"session-idle",
|
|
21
|
+
"inactivity",
|
|
22
|
+
"postmessage",
|
|
23
|
+
"iframe",
|
|
24
|
+
"secure-channel"
|
|
20
25
|
],
|
|
21
26
|
"author": "Angular Helpers Team",
|
|
22
27
|
"license": "MIT",
|
|
@@ -34,8 +39,14 @@
|
|
|
34
39
|
"peerDependencies": {
|
|
35
40
|
"@angular/common": "^21.0.0",
|
|
36
41
|
"@angular/core": "^21.0.0",
|
|
42
|
+
"@angular/forms": "^21.0.0",
|
|
37
43
|
"rxjs": "^7.0.0 || ^8.0.0"
|
|
38
44
|
},
|
|
45
|
+
"peerDependenciesMeta": {
|
|
46
|
+
"@angular/forms": {
|
|
47
|
+
"optional": true
|
|
48
|
+
}
|
|
49
|
+
},
|
|
39
50
|
"dependencies": {
|
|
40
51
|
"tslib": "^2.0.0"
|
|
41
52
|
},
|
|
@@ -48,7 +59,16 @@
|
|
|
48
59
|
".": {
|
|
49
60
|
"types": "./types/angular-helpers-security.d.ts",
|
|
50
61
|
"default": "./fesm2022/angular-helpers-security.mjs"
|
|
62
|
+
},
|
|
63
|
+
"./forms": {
|
|
64
|
+
"types": "./types/angular-helpers-security-forms.d.ts",
|
|
65
|
+
"default": "./fesm2022/angular-helpers-security-forms.mjs"
|
|
66
|
+
},
|
|
67
|
+
"./signal-forms": {
|
|
68
|
+
"types": "./types/angular-helpers-security-signal-forms.d.ts",
|
|
69
|
+
"default": "./fesm2022/angular-helpers-security-signal-forms.mjs"
|
|
51
70
|
}
|
|
52
71
|
},
|
|
53
|
-
"sideEffects": false
|
|
72
|
+
"sideEffects": false,
|
|
73
|
+
"type": "module"
|
|
54
74
|
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { ValidatorFn } from '@angular/forms';
|
|
2
|
+
import { HtmlSanitizerOptions, PasswordScore } from '@angular-helpers/security';
|
|
3
|
+
|
|
4
|
+
interface StrongPasswordOptions {
|
|
5
|
+
minScore?: PasswordScore;
|
|
6
|
+
}
|
|
7
|
+
interface SafeUrlOptions {
|
|
8
|
+
schemes?: readonly string[];
|
|
9
|
+
}
|
|
10
|
+
type SafeHtmlOptions = HtmlSanitizerOptions;
|
|
11
|
+
/**
|
|
12
|
+
* Collection of Reactive Forms validators that bridge the shared security helpers into
|
|
13
|
+
* the Angular `ValidatorFn` contract. All validators are static factory functions and do not
|
|
14
|
+
* require provider registration.
|
|
15
|
+
*
|
|
16
|
+
* For the Signal Forms equivalents see `@angular-helpers/security/signal-forms`.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* const form = new FormGroup({
|
|
20
|
+
* password: new FormControl('', [
|
|
21
|
+
* Validators.required,
|
|
22
|
+
* SecurityValidators.strongPassword({ minScore: 3 }),
|
|
23
|
+
* ]),
|
|
24
|
+
* bio: new FormControl('', [SecurityValidators.safeHtml()]),
|
|
25
|
+
* homepage: new FormControl('', [SecurityValidators.safeUrl({ schemes: ['https:'] })]),
|
|
26
|
+
* });
|
|
27
|
+
*/
|
|
28
|
+
declare class SecurityValidators {
|
|
29
|
+
/**
|
|
30
|
+
* Validates password strength using the shared entropy-based scoring logic.
|
|
31
|
+
* Returns `{ weakPassword: { score, required } }` when the score is below `minScore`.
|
|
32
|
+
*
|
|
33
|
+
* @param options.minScore Minimum acceptable score (0..4). Default: `2` (fair).
|
|
34
|
+
*/
|
|
35
|
+
static strongPassword(options?: StrongPasswordOptions): ValidatorFn;
|
|
36
|
+
/**
|
|
37
|
+
* Validates that the given HTML string contains no tags or attributes outside the allowlist.
|
|
38
|
+
* Returns `{ unsafeHtml: true }` when sanitization would alter the value.
|
|
39
|
+
*
|
|
40
|
+
* Requires a browser environment (DOMParser). In SSR contexts the validator returns `null`
|
|
41
|
+
* (no error) to avoid blocking forms server-side; re-validation happens automatically on
|
|
42
|
+
* hydration.
|
|
43
|
+
*/
|
|
44
|
+
static safeHtml(options?: SafeHtmlOptions): ValidatorFn;
|
|
45
|
+
/**
|
|
46
|
+
* Validates that the given URL is well-formed and uses an allowed scheme.
|
|
47
|
+
* Returns `{ unsafeUrl: true }` for `javascript:`, `data:`, relative URLs, and other
|
|
48
|
+
* non-allowlisted protocols.
|
|
49
|
+
*/
|
|
50
|
+
static safeUrl(options?: SafeUrlOptions): ValidatorFn;
|
|
51
|
+
/**
|
|
52
|
+
* Rejects values that look like script injection attempts (`<script>`, `javascript:`,
|
|
53
|
+
* or inline event handlers). Lightweight pattern check — NOT a substitute for a full
|
|
54
|
+
* HTML sanitizer.
|
|
55
|
+
*/
|
|
56
|
+
static noScriptInjection(): ValidatorFn;
|
|
57
|
+
/**
|
|
58
|
+
* Heuristic check for common SQL-injection sentinel strings. Intended as defense-in-depth
|
|
59
|
+
* for user-facing inputs. Use parameterized queries on the server as the primary defense.
|
|
60
|
+
*/
|
|
61
|
+
static noSqlInjectionHints(): ValidatorFn;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export { SecurityValidators };
|
|
65
|
+
export type { SafeHtmlOptions, SafeUrlOptions, StrongPasswordOptions };
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { PathKind, SchemaPath, SchemaPathRules } from '@angular/forms/signals';
|
|
2
|
+
import { HtmlSanitizerOptions, PasswordScore } from '@angular-helpers/security';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Options for {@link strongPassword}.
|
|
6
|
+
*/
|
|
7
|
+
interface StrongPasswordRuleOptions {
|
|
8
|
+
/** Minimum acceptable score (0..4). Default: `2` (fair). */
|
|
9
|
+
minScore?: PasswordScore;
|
|
10
|
+
/** Custom message shown to the user. Default: `'Password is too weak'`. */
|
|
11
|
+
message?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Options for {@link safeUrl}.
|
|
15
|
+
*/
|
|
16
|
+
interface SafeUrlRuleOptions {
|
|
17
|
+
/** Allowed URL schemes including the trailing colon. Default: `['http:', 'https:']`. */
|
|
18
|
+
schemes?: readonly string[];
|
|
19
|
+
/** Custom message. Default: `'URL scheme is not allowed'`. */
|
|
20
|
+
message?: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Options for {@link safeHtml}.
|
|
24
|
+
*/
|
|
25
|
+
interface SafeHtmlRuleOptions extends HtmlSanitizerOptions {
|
|
26
|
+
/** Custom message. Default: `'Value contains unsafe HTML'`. */
|
|
27
|
+
message?: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Options for {@link noScriptInjection} and {@link noSqlInjectionHints}.
|
|
31
|
+
*/
|
|
32
|
+
interface PatternRuleOptions {
|
|
33
|
+
/** Custom message. Default varies per rule. */
|
|
34
|
+
message?: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Registers a sync validation rule on a string field that fails when the password strength
|
|
38
|
+
* is below the required score. Uses the shared `assessPasswordStrength` helper for behavioural
|
|
39
|
+
* parity with the Reactive Forms `SecurityValidators.strongPassword`.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* form(model, (p) => {
|
|
43
|
+
* required(p.password);
|
|
44
|
+
* strongPassword(p.password, { minScore: 3 });
|
|
45
|
+
* });
|
|
46
|
+
*/
|
|
47
|
+
declare function strongPassword<TPathKind extends PathKind = PathKind.Root>(path: SchemaPath<string, SchemaPathRules.Supported, TPathKind>, options?: StrongPasswordRuleOptions): void;
|
|
48
|
+
/**
|
|
49
|
+
* Registers a sync validation rule that fails when the input contains tags or attributes
|
|
50
|
+
* outside the allowed HTML sanitizer allowlist.
|
|
51
|
+
*
|
|
52
|
+
* Requires a browser environment. In SSR contexts the rule is a no-op (returns `null`) so
|
|
53
|
+
* server-rendered forms remain submittable; re-validation happens on hydration.
|
|
54
|
+
*/
|
|
55
|
+
declare function safeHtml<TPathKind extends PathKind = PathKind.Root>(path: SchemaPath<string, SchemaPathRules.Supported, TPathKind>, options?: SafeHtmlRuleOptions): void;
|
|
56
|
+
/**
|
|
57
|
+
* Registers a sync validation rule that fails for malformed URLs or URLs using schemes
|
|
58
|
+
* outside the allowlist (default: `http:` and `https:`).
|
|
59
|
+
*/
|
|
60
|
+
declare function safeUrl<TPathKind extends PathKind = PathKind.Root>(path: SchemaPath<string, SchemaPathRules.Supported, TPathKind>, options?: SafeUrlRuleOptions): void;
|
|
61
|
+
/**
|
|
62
|
+
* Registers a sync validation rule that rejects values matching common script-injection
|
|
63
|
+
* sentinels (`<script>`, `javascript:`, inline event handlers).
|
|
64
|
+
*/
|
|
65
|
+
declare function noScriptInjection<TPathKind extends PathKind = PathKind.Root>(path: SchemaPath<string, SchemaPathRules.Supported, TPathKind>, options?: PatternRuleOptions): void;
|
|
66
|
+
/**
|
|
67
|
+
* Registers a sync validation rule that rejects common SQL-injection sentinel strings.
|
|
68
|
+
* Intended as defense-in-depth alongside server-side parameterized queries.
|
|
69
|
+
*/
|
|
70
|
+
declare function noSqlInjectionHints<TPathKind extends PathKind = PathKind.Root>(path: SchemaPath<string, SchemaPathRules.Supported, TPathKind>, options?: PatternRuleOptions): void;
|
|
71
|
+
/**
|
|
72
|
+
* Options for {@link hibpPassword}.
|
|
73
|
+
*/
|
|
74
|
+
interface HibpPasswordRuleOptions {
|
|
75
|
+
/** Custom message. Default: `'This password has appeared in a data breach'`. */
|
|
76
|
+
message?: string;
|
|
77
|
+
/** Debounce value changes before contacting HIBP. Default: `300` ms. */
|
|
78
|
+
debounceMs?: number;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Registers an async validation rule that checks the password against the Have I Been Pwned
|
|
82
|
+
* breach corpus via the k-anonymity API. Requires `provideHibp()` to be set up in the
|
|
83
|
+
* injector hierarchy.
|
|
84
|
+
*
|
|
85
|
+
* Fail-open semantics: network errors and unsupported environments do NOT produce a
|
|
86
|
+
* validation error — the form remains submittable. This is intentional to prevent HIBP
|
|
87
|
+
* outages from blocking user sign-ups.
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* form(model, (p) => {
|
|
91
|
+
* required(p.password);
|
|
92
|
+
* strongPassword(p.password, { minScore: 3 });
|
|
93
|
+
* hibpPassword(p.password);
|
|
94
|
+
* });
|
|
95
|
+
*/
|
|
96
|
+
declare function hibpPassword<TPathKind extends PathKind = PathKind.Root>(path: SchemaPath<string, SchemaPathRules.Supported, TPathKind>, options?: HibpPasswordRuleOptions): void;
|
|
97
|
+
|
|
98
|
+
export { hibpPassword, noScriptInjection, noSqlInjectionHints, safeHtml, safeUrl, strongPassword };
|
|
99
|
+
export type { HibpPasswordRuleOptions, PatternRuleOptions, SafeHtmlRuleOptions, SafeUrlRuleOptions, StrongPasswordRuleOptions };
|