passbolt-styleguide 5.12.0 → 5.12.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/RELEASE_NOTES.md +2 -53
- package/package.json +1 -1
- package/src/img/passbolt-default-resource-type-icons/pincode.svg +10 -10
- package/src/react-extension/components/Resource/ResourceForm/AddResourcePinCode.js +22 -1
- package/src/react-extension/components/Resource/ResourceForm/AddResourcePinCode.test.data.js +11 -0
- package/src/react-extension/components/Resource/ResourceForm/AddResourcePinCode.test.js +33 -1
- package/src/react-quickaccess/components/FilterResourcesByFavoritePage/FilterResourcesByFavoritePage.js +32 -1
- package/src/react-quickaccess/components/FilterResourcesByGroupPage/FilterResourcesByGroupPage.js +29 -1
- package/src/react-quickaccess/components/FilterResourcesByItemsIOwnPage/FilterResourcesByItemsIOwnPage.js +32 -1
- package/src/react-quickaccess/components/FilterResourcesByRecentlyModifiedPage/FilterResourcesByRecentlyModifiedPage.js +27 -8
- package/src/react-quickaccess/components/FilterResourcesBySharedWithMePage/FilterResourcesBySharedWithMePage.js +32 -1
- package/src/react-quickaccess/components/FilterResourcesByTagPage/FilterResourcesByTagPage.js +31 -6
- package/src/react-quickaccess/components/HomePage/HomePage.js +20 -10
- package/src/shared/components/Password/Password.js +3 -1
- package/src/shared/components/Password/Password.test.js +26 -0
package/RELEASE_NOTES.md
CHANGED
|
@@ -1,54 +1,3 @@
|
|
|
1
|
-
# v5.12.
|
|
1
|
+
# v5.12.1
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
### Added
|
|
5
|
-
- PB-51015 Add PIN code resource type in resourceTypeSchemasDefinition
|
|
6
|
-
- PB-51016 Handle PIN code in resourceTypeEntity
|
|
7
|
-
- PB-51017 Handle PIN code in resourceTypesCollection
|
|
8
|
-
- PB-51019 PINCODE - 1.5 Create secretDataV5StandalonePinCodeEntity and add...
|
|
9
|
-
- PB-51020 PINCODE - 1.6 Add pin code to ResourceEditCreateFormEnumerationTypes
|
|
10
|
-
- PB-51023 Update resourceTypesFormEntity to handle the new pin code resource type
|
|
11
|
-
- PB-51046 PINCODE - 3.2 Adapt ExternalResourceEntity to handle the pin code resource type schema
|
|
12
|
-
- PB-51047 PINCODE - 3.3 Adapt ExportResourcesService to handle the mapping of pin code
|
|
13
|
-
- PB-51048 PINCODE - 3.4 Adapt resourcesKdbxImportParser and to map pin code in case it exist to the correct resource types
|
|
14
|
-
- PB-51049 Add PIN code icon to passboltDefaultResourceTypeIcons.data
|
|
15
|
-
- PB-51050 Update DisplayContentTypesAllowedContentTypesAdministration to handle PIN code
|
|
16
|
-
- PB-51051 Add the pin code resource type to DisplayResourceCreationMenu
|
|
17
|
-
- PB-51052 Add PIN code in SelectResourceForm
|
|
18
|
-
- PB-51053 Create the new pin code resource type form
|
|
19
|
-
- PB-51054 Adapt OrchestrateResourceForm to handle the new AddResourcePinCode
|
|
20
|
-
- PB-51055 Create the new DisplayResourceDetailsPinCode to display the pin code into detail
|
|
21
|
-
- PB-51056 PINCODE - 3.5 Adapt resourcesKdbxExporter and to map pin code in case it exist to the correct resource types
|
|
22
|
-
- PB-51073 PINCODE - 2.8 Add pin code into the grid
|
|
23
|
-
- PB-51201 Fix notes-related issues
|
|
24
|
-
- PB-51246 Add pin code to workspace create menu
|
|
25
|
-
|
|
26
|
-
### Fixed
|
|
27
|
-
- PB-49888 The contents of Resource Creation Progress Dialog always shows Creating Password
|
|
28
|
-
- PB-50166 Fix break vs continue bug in MoveResourcesService batch permission calculation
|
|
29
|
-
- PB-50535 DisplayuserbadgeMenu should display attention required on page served by API if MFA is required
|
|
30
|
-
- PB-50617 Add PingOne redirect URL field
|
|
31
|
-
- PB-50945 Fix expired session when port is disconnected
|
|
32
|
-
- PB-51012 Hide 'set expired' option for already expired resources
|
|
33
|
-
- PB-51018 Tighten fields selectors to avoid false positives
|
|
34
|
-
- PB-51077 Fix typo "susccessfully" to "successfully"
|
|
35
|
-
|
|
36
|
-
### Security
|
|
37
|
-
- PB-50623 Fix GHSA-2328-f5f3-gj25 (HIGH)
|
|
38
|
-
- PB-50877 Fix undici GHSA-f269-vfmq-vjvj - MEDIUM CVSS3.1
|
|
39
|
-
- PB-50906 Fix svgo GHSA-xpqw-6gx7-v673 - HIGH CVSS3.1
|
|
40
|
-
- PB-50907 Fix flatted GHSA-rf6f-7fwh-wjgh - HIGH CVSS4.0
|
|
41
|
-
- PB-50908 Fix @xmldom/xmldom GHSA-wh4c-j3r5-mjhp - HIGH CVSS3.1
|
|
42
|
-
- PB-50920 Upgrade webpack-cli
|
|
43
|
-
- PB-50921 Upgrade web-ext
|
|
44
|
-
- PB-51060 Fix protocol-buffers-schema GHSA-j452-xhg8-qg39 - MEDIUM CVSS3.1
|
|
45
|
-
- PB-51151 Fix i18next-http-backend GHSA-r5fr-rjxr-66jc - MEDIUM CVSS3.1
|
|
46
|
-
- PB-51152 Fix uuid GHSA-w5hq-g745-h8pq - MEDIUM CVSS3.1
|
|
47
|
-
- PB-51170 Fix @xmldom/xmldom GHSA-2v35-w6hq-6mfw - HIGH CVSS4.0
|
|
48
|
-
- PB-51179 Investigate and/or enforce package cool down mechanism with safe-chain or npm or both
|
|
49
|
-
|
|
50
|
-
### Maintenance
|
|
51
|
-
- PB-50224 Add devcontainer to bext
|
|
52
|
-
- PB-50301 removed GitLab CI definition as it's been moved to the ci-definitions repo
|
|
53
|
-
- PB-50340 Small upgrade for picomatch (Medium)
|
|
54
|
-
- PB-51086 keep notify expired session tests skipping
|
|
3
|
+
Fix various issues regarding pin code
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
-
<path d="M20 11.6807C20.4825 11.6807 20.8736 11.2896 20.8736 10.8072C20.8736 10.3247 20.4825 9.93359 20 9.93359C19.5175 9.93359 19.1264 10.3247 19.1264 10.8072C19.1264 11.2896 19.5175 11.6807 20 11.6807Z" fill="
|
|
3
|
-
<path d="M26.115 11.6807C26.5974 11.6807 26.9885 11.2896 26.9885 10.8072C26.9885 10.3247 26.5974 9.93359 26.115 9.93359C25.6325 9.93359 25.2414 10.3247 25.2414 10.8072C25.2414 11.2896 25.6325 11.6807 26.115 11.6807Z" fill="
|
|
4
|
-
<path d="M13.885 11.6807C14.3675 11.6807 14.7586 11.2896 14.7586 10.8072C14.7586 10.3247 14.3675 9.93359 13.885 9.93359C13.4026 9.93359 13.0115 10.3247 13.0115 10.8072C13.0115 11.2896 13.4026 11.6807 13.885 11.6807Z" fill="
|
|
5
|
-
<path d="M20 17.795C20.4824 17.795 20.8736 17.4039 20.8736 16.9214C20.8736 16.439 20.4824 16.0479 20 16.0479C19.5175 16.0479 19.1264 16.439 19.1264 16.9214C19.1264 17.4039 19.5175 17.795 20 17.795Z" fill="
|
|
6
|
-
<path d="M26.115 17.795C26.5974 17.795 26.9885 17.4039 26.9885 16.9214C26.9885 16.439 26.5974 16.0479 26.115 16.0479C25.6325 16.0479 25.2414 16.439 25.2414 16.9214C25.2414 17.4039 25.6325 17.795 26.115 17.795Z" fill="
|
|
7
|
-
<path d="M13.885 17.795C14.3675 17.795 14.7586 17.4039 14.7586 16.9214C14.7586 16.439 14.3675 16.0479 13.885 16.0479C13.4026 16.0479 13.0115 16.439 13.0115 16.9214C13.0115 17.4039 13.4026 17.795 13.885 17.795Z" fill="
|
|
8
|
-
<path d="M20 23.9112C20.4824 23.9112 20.8736 23.5201 20.8736 23.0376C20.8736 22.5552 20.4824 22.1641 20 22.1641C19.5175 22.1641 19.1264 22.5552 19.1264 23.0376C19.1264 23.5201 19.5175 23.9112 20 23.9112Z" fill="
|
|
9
|
-
<path d="M26.115 23.9112C26.5974 23.9112 26.9885 23.5201 26.9885 23.0376C26.9885 22.5552 26.5974 22.1641 26.115 22.1641C25.6325 22.1641 25.2414 22.5552 25.2414 23.0376C25.2414 23.5201 25.6325 23.9112 26.115 23.9112Z" fill="
|
|
10
|
-
<path d="M13.885 23.9112C14.3675 23.9112 14.7586 23.5201 14.7586 23.0376C14.7586 22.5552 14.3675 22.1641 13.885 22.1641C13.4026 22.1641 13.0115 22.5552 13.0115 23.0376C13.0115 23.5201 13.4026 23.9112 13.885 23.9112Z" fill="
|
|
11
|
-
<path d="M20 30.0665C20.4825 30.0665 20.8736 29.6754 20.8736 29.1929C20.8736 28.7104 20.4825 28.3193 20 28.3193C19.5175 28.3193 19.1264 28.7104 19.1264 29.1929C19.1264 29.6754 19.5175 30.0665 20 30.0665Z" fill="
|
|
2
|
+
<path d="M20 11.6807C20.4825 11.6807 20.8736 11.2896 20.8736 10.8072C20.8736 10.3247 20.4825 9.93359 20 9.93359C19.5175 9.93359 19.1264 10.3247 19.1264 10.8072C19.1264 11.2896 19.5175 11.6807 20 11.6807Z" fill="var(--icon-color)" stroke="var(--icon-color)" stroke-width="var(--icon-stroke-width)" stroke-linecap="round" stroke-linejoin="round"/>
|
|
3
|
+
<path d="M26.115 11.6807C26.5974 11.6807 26.9885 11.2896 26.9885 10.8072C26.9885 10.3247 26.5974 9.93359 26.115 9.93359C25.6325 9.93359 25.2414 10.3247 25.2414 10.8072C25.2414 11.2896 25.6325 11.6807 26.115 11.6807Z" fill="var(--icon-color)" stroke="var(--icon-color)" stroke-width="var(--icon-stroke-width)" stroke-linecap="round" stroke-linejoin="round"/>
|
|
4
|
+
<path d="M13.885 11.6807C14.3675 11.6807 14.7586 11.2896 14.7586 10.8072C14.7586 10.3247 14.3675 9.93359 13.885 9.93359C13.4026 9.93359 13.0115 10.3247 13.0115 10.8072C13.0115 11.2896 13.4026 11.6807 13.885 11.6807Z" fill="var(--icon-color)" stroke="var(--icon-color)" stroke-width="var(--icon-stroke-width)" stroke-linecap="round" stroke-linejoin="round"/>
|
|
5
|
+
<path d="M20 17.795C20.4824 17.795 20.8736 17.4039 20.8736 16.9214C20.8736 16.439 20.4824 16.0479 20 16.0479C19.5175 16.0479 19.1264 16.439 19.1264 16.9214C19.1264 17.4039 19.5175 17.795 20 17.795Z" fill="var(--icon-color)" stroke="var(--icon-color)" stroke-width="var(--icon-stroke-width)" stroke-linecap="round" stroke-linejoin="round"/>
|
|
6
|
+
<path d="M26.115 17.795C26.5974 17.795 26.9885 17.4039 26.9885 16.9214C26.9885 16.439 26.5974 16.0479 26.115 16.0479C25.6325 16.0479 25.2414 16.439 25.2414 16.9214C25.2414 17.4039 25.6325 17.795 26.115 17.795Z" fill="var(--icon-color)" stroke="var(--icon-color)" stroke-width="var(--icon-stroke-width)" stroke-linecap="round" stroke-linejoin="round"/>
|
|
7
|
+
<path d="M13.885 17.795C14.3675 17.795 14.7586 17.4039 14.7586 16.9214C14.7586 16.439 14.3675 16.0479 13.885 16.0479C13.4026 16.0479 13.0115 16.439 13.0115 16.9214C13.0115 17.4039 13.4026 17.795 13.885 17.795Z" fill="var(--icon-color)" stroke="var(--icon-color)" stroke-width="var(--icon-stroke-width)" stroke-linecap="round" stroke-linejoin="round"/>
|
|
8
|
+
<path d="M20 23.9112C20.4824 23.9112 20.8736 23.5201 20.8736 23.0376C20.8736 22.5552 20.4824 22.1641 20 22.1641C19.5175 22.1641 19.1264 22.5552 19.1264 23.0376C19.1264 23.5201 19.5175 23.9112 20 23.9112Z" fill="var(--icon-color)" stroke="var(--icon-color)" stroke-width="var(--icon-stroke-width)" stroke-linecap="round" stroke-linejoin="round"/>
|
|
9
|
+
<path d="M26.115 23.9112C26.5974 23.9112 26.9885 23.5201 26.9885 23.0376C26.9885 22.5552 26.5974 22.1641 26.115 22.1641C25.6325 22.1641 25.2414 22.5552 25.2414 23.0376C25.2414 23.5201 25.6325 23.9112 26.115 23.9112Z" fill="var(--icon-color)" stroke="var(--icon-color)" stroke-width="var(--icon-stroke-width)" stroke-linecap="round" stroke-linejoin="round"/>
|
|
10
|
+
<path d="M13.885 23.9112C14.3675 23.9112 14.7586 23.5201 14.7586 23.0376C14.7586 22.5552 14.3675 22.1641 13.885 22.1641C13.4026 22.1641 13.0115 22.5552 13.0115 23.0376C13.0115 23.5201 13.4026 23.9112 13.885 23.9112Z" fill="var(--icon-color)" stroke="var(--icon-color)" stroke-width="var(--icon-stroke-width)" stroke-linecap="round" stroke-linejoin="round"/>
|
|
11
|
+
<path d="M20 30.0665C20.4825 30.0665 20.8736 29.6754 20.8736 29.1929C20.8736 28.7104 20.4825 28.3193 20 28.3193C19.5175 28.3193 19.1264 28.7104 19.1264 29.1929C19.1264 29.6754 19.5175 30.0665 20 30.0665Z" fill="var(--icon-color)" stroke="var(--icon-color)" stroke-width="var(--icon-stroke-width)" stroke-linecap="round" stroke-linejoin="round"/>
|
|
12
12
|
</svg>
|
|
@@ -22,6 +22,7 @@ import { PinCodeGenerator, PIN_CODE_LENGTH_CONSTRAINTS } from "../../../../share
|
|
|
22
22
|
import DiceSVG from "../../../../img/svg/dice.svg";
|
|
23
23
|
import CaretDownSVG from "../../../../img/svg/caret_down.svg";
|
|
24
24
|
import CaretRightSVG from "../../../../img/svg/caret_right.svg";
|
|
25
|
+
import AttentionSVG from "../../../../img/svg/attention.svg";
|
|
25
26
|
|
|
26
27
|
class AddResourcePinCode extends Component {
|
|
27
28
|
constructor(props) {
|
|
@@ -158,12 +159,22 @@ class AddResourcePinCode extends Component {
|
|
|
158
159
|
}
|
|
159
160
|
|
|
160
161
|
/**
|
|
161
|
-
*
|
|
162
|
+
* Checks if the pin code length exceeds the max pin code length
|
|
162
163
|
*/
|
|
163
164
|
isMaxLengthError() {
|
|
164
165
|
return this.props.errors?.details?.secret?.hasError("pin_code", "maxLength");
|
|
165
166
|
}
|
|
166
167
|
|
|
168
|
+
/**
|
|
169
|
+
* Checks if there is a max length warning for a specific property.
|
|
170
|
+
* @param {string} propName The name of the property to check.
|
|
171
|
+
* @param {string} association The association name.
|
|
172
|
+
* @returns {boolean}
|
|
173
|
+
*/
|
|
174
|
+
isMaxLengthWarnings(propName, association) {
|
|
175
|
+
return !this.isMaxLengthError() && this.props.warnings?.hasError(`${association}.${propName}`, "maxLength");
|
|
176
|
+
}
|
|
177
|
+
|
|
167
178
|
/**
|
|
168
179
|
* Focus the first erroring field, if any.
|
|
169
180
|
*/
|
|
@@ -192,6 +203,7 @@ class AddResourcePinCode extends Component {
|
|
|
192
203
|
>
|
|
193
204
|
<label htmlFor="resource-pin-code">
|
|
194
205
|
<Trans>Code</Trans>
|
|
206
|
+
{this.isMaxLengthWarnings("pin_code", "secret") && <AttentionSVG className="attention-required" />}
|
|
195
207
|
</label>
|
|
196
208
|
<div className="password-button-inline">
|
|
197
209
|
<Password
|
|
@@ -200,6 +212,7 @@ class AddResourcePinCode extends Component {
|
|
|
200
212
|
autoComplete="off"
|
|
201
213
|
placeholder={this.translate("Pin code")}
|
|
202
214
|
preview={true}
|
|
215
|
+
maxLength={PIN_CODE_LENGTH_CONSTRAINTS.MAX}
|
|
203
216
|
value={this.props.resource?.secret?.pin_code}
|
|
204
217
|
onChange={this.handlePinCodeInputChange}
|
|
205
218
|
inputRef={this.pinCodeInputRef}
|
|
@@ -215,6 +228,14 @@ class AddResourcePinCode extends Component {
|
|
|
215
228
|
</button>
|
|
216
229
|
</div>
|
|
217
230
|
{this.hasFieldPinCodeError() && <div className="pin-code error-message">{this.pinCodeErrorMessage}</div>}
|
|
231
|
+
{this.isMaxLengthWarnings("pin_code", "secret") && (
|
|
232
|
+
<div className="pin-code warning-message">
|
|
233
|
+
<strong>
|
|
234
|
+
<Trans>Warning:</Trans>
|
|
235
|
+
</strong>{" "}
|
|
236
|
+
<Trans>this is the maximum size for this field, make sure your data was not truncated.</Trans>
|
|
237
|
+
</div>
|
|
238
|
+
)}
|
|
218
239
|
</div>
|
|
219
240
|
</div>
|
|
220
241
|
<div className="additional-information">
|
package/src/react-extension/components/Resource/ResourceForm/AddResourcePinCode.test.data.js
CHANGED
|
@@ -61,3 +61,14 @@ export function pinCodeErrors(rule) {
|
|
|
61
61
|
|
|
62
62
|
return errors;
|
|
63
63
|
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Build warnings prop with a single `secret.pin_code` rule violation.
|
|
67
|
+
* @param {string} rule e.g. "maxLength"
|
|
68
|
+
* @returns {EntityValidationError}
|
|
69
|
+
*/
|
|
70
|
+
export function pinCodeWarnings(rule) {
|
|
71
|
+
const warnings = new EntityValidationError();
|
|
72
|
+
warnings.addError("secret.pin_code", rule, `pin_code ${rule} warning`);
|
|
73
|
+
return warnings;
|
|
74
|
+
}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import AddResourcePinCodePage from "./AddResourcePinCode.test.page";
|
|
16
|
-
import { defaultProps, defaultPropsWithValue, pinCodeErrors } from "./AddResourcePinCode.test.data";
|
|
16
|
+
import { defaultProps, defaultPropsWithValue, pinCodeErrors, pinCodeWarnings } from "./AddResourcePinCode.test.data";
|
|
17
17
|
import { PinCodeGenerator } from "../../../../shared/lib/SecretGenerator/PinCodeGenerator";
|
|
18
18
|
|
|
19
19
|
beforeEach(() => {
|
|
@@ -230,4 +230,36 @@ describe("AddResourcePinCode", () => {
|
|
|
230
230
|
expect(page.pinCodeErrorMessage.textContent).toEqual("The PIN code is required.");
|
|
231
231
|
});
|
|
232
232
|
});
|
|
233
|
+
|
|
234
|
+
describe("Warnings", () => {
|
|
235
|
+
it("renders the maxLength warning message and the attention icon when warnings include secret.pin_code maxLength.", () => {
|
|
236
|
+
expect.assertions(2);
|
|
237
|
+
|
|
238
|
+
const props = defaultProps({
|
|
239
|
+
warnings: pinCodeWarnings("maxLength"),
|
|
240
|
+
resource: { secret: { pin_code: "123456789012" } },
|
|
241
|
+
});
|
|
242
|
+
const page = new AddResourcePinCodePage(props);
|
|
243
|
+
|
|
244
|
+
expect(page.pinCodeWarningMessage.textContent).toEqual(
|
|
245
|
+
"Warning: this is the maximum size for this field, make sure your data was not truncated.",
|
|
246
|
+
);
|
|
247
|
+
expect(page.attentionIcon).not.toBeNull();
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
it("suppresses the maxLength warning when a maxLength error is also present.", () => {
|
|
251
|
+
expect.assertions(3);
|
|
252
|
+
|
|
253
|
+
const props = defaultProps({
|
|
254
|
+
errors: pinCodeErrors("maxLength"),
|
|
255
|
+
warnings: pinCodeWarnings("maxLength"),
|
|
256
|
+
resource: { secret: { pin_code: "1234567890123" } },
|
|
257
|
+
});
|
|
258
|
+
const page = new AddResourcePinCodePage(props);
|
|
259
|
+
|
|
260
|
+
expect(page.pinCodeErrorMessage.textContent).toEqual("The PIN code cannot exceed 12 digits.");
|
|
261
|
+
expect(page.pinCodeWarningMessage).toBeNull();
|
|
262
|
+
expect(page.attentionIcon).toBeNull();
|
|
263
|
+
});
|
|
264
|
+
});
|
|
233
265
|
});
|
|
@@ -113,6 +113,34 @@ class FilterResourcesByFavoritePage extends React.Component {
|
|
|
113
113
|
return search ? filterResourcesBySearch(favoriteResources, search, BROWSED_RESOURCES_LIMIT) : favoriteResources;
|
|
114
114
|
});
|
|
115
115
|
|
|
116
|
+
/**
|
|
117
|
+
* Is password resource
|
|
118
|
+
* @param {string} resourceTypeId
|
|
119
|
+
* @returns {boolean}
|
|
120
|
+
*/
|
|
121
|
+
isPasswordResource(resourceTypeId) {
|
|
122
|
+
return this.props.resourceTypes?.getFirstById(resourceTypeId)?.hasPassword();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Is OTP resource
|
|
127
|
+
* @param {string} resourceTypeId
|
|
128
|
+
* @returns {boolean}
|
|
129
|
+
*/
|
|
130
|
+
isOTPResource(resourceTypeId) {
|
|
131
|
+
return this.props.resourceTypes?.getFirstById(resourceTypeId)?.hasTotp();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Get resource filtered by resource type to have only resource with password and totp
|
|
136
|
+
* @return {Array}
|
|
137
|
+
*/
|
|
138
|
+
get resourcesFilterByResourceTypePasswordAndTotp() {
|
|
139
|
+
const keepOnlyResourcesPasswordAndTotp = (resource) =>
|
|
140
|
+
this.isPasswordResource(resource.resource_type_id) || this.isOTPResource(resource.resource_type_id);
|
|
141
|
+
return this.props.resources.filter(keepOnlyResourcesPasswordAndTotp);
|
|
142
|
+
}
|
|
143
|
+
|
|
116
144
|
/**
|
|
117
145
|
* Has metadata types settings
|
|
118
146
|
* @returns {boolean}
|
|
@@ -161,7 +189,10 @@ class FilterResourcesByFavoritePage extends React.Component {
|
|
|
161
189
|
let browsedResources;
|
|
162
190
|
|
|
163
191
|
if (isReady) {
|
|
164
|
-
browsedResources = this.filterSearchedResources(
|
|
192
|
+
browsedResources = this.filterSearchedResources(
|
|
193
|
+
this.resourcesFilterByResourceTypePasswordAndTotp,
|
|
194
|
+
this.props.context.search,
|
|
195
|
+
);
|
|
165
196
|
}
|
|
166
197
|
|
|
167
198
|
/**
|
package/src/react-quickaccess/components/FilterResourcesByGroupPage/FilterResourcesByGroupPage.js
CHANGED
|
@@ -222,6 +222,34 @@ class FilterResourcesByGroupPage extends React.Component {
|
|
|
222
222
|
search ? this.filterGroupsBySearch(groups, search, BROWSED_GROUPS_LIMIT) : groups.slice(0, BROWSED_GROUPS_LIMIT),
|
|
223
223
|
);
|
|
224
224
|
|
|
225
|
+
/**
|
|
226
|
+
* Is password resource
|
|
227
|
+
* @param {string} resourceTypeId
|
|
228
|
+
* @returns {boolean}
|
|
229
|
+
*/
|
|
230
|
+
isPasswordResource(resourceTypeId) {
|
|
231
|
+
return this.props.resourceTypes?.getFirstById(resourceTypeId)?.hasPassword();
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Is OTP resource
|
|
236
|
+
* @param {string} resourceTypeId
|
|
237
|
+
* @returns {boolean}
|
|
238
|
+
*/
|
|
239
|
+
isOTPResource(resourceTypeId) {
|
|
240
|
+
return this.props.resourceTypes?.getFirstById(resourceTypeId)?.hasTotp();
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Get resource filtered by resource type to have only resource with password and totp
|
|
245
|
+
* @return {Array}
|
|
246
|
+
*/
|
|
247
|
+
get resourcesFilterByResourceTypePasswordAndTotp() {
|
|
248
|
+
const keepOnlyResourcesPasswordAndTotp = (resource) =>
|
|
249
|
+
this.isPasswordResource(resource.resource_type_id) || this.isOTPResource(resource.resource_type_id);
|
|
250
|
+
return this.props.resources.filter(keepOnlyResourcesPasswordAndTotp);
|
|
251
|
+
}
|
|
252
|
+
|
|
225
253
|
/**
|
|
226
254
|
* Has metadata types settings
|
|
227
255
|
* @returns {boolean}
|
|
@@ -278,7 +306,7 @@ class FilterResourcesByGroupPage extends React.Component {
|
|
|
278
306
|
isReady = this.props.resources !== null && this.state.groupResourceIds !== null;
|
|
279
307
|
if (isReady) {
|
|
280
308
|
browsedResources = this.filterSearchedResources(
|
|
281
|
-
this.
|
|
309
|
+
this.resourcesFilterByResourceTypePasswordAndTotp,
|
|
282
310
|
this.state.groupResourceIds,
|
|
283
311
|
this.props.context.search,
|
|
284
312
|
);
|
|
@@ -121,6 +121,34 @@ class FilterResourcesByItemsIOwnPage extends React.Component {
|
|
|
121
121
|
return search ? filterResourcesBySearch(ownedResources, search, BROWSED_RESOURCES_LIMIT) : ownedResources;
|
|
122
122
|
});
|
|
123
123
|
|
|
124
|
+
/**
|
|
125
|
+
* Is password resource
|
|
126
|
+
* @param {string} resourceTypeId
|
|
127
|
+
* @returns {boolean}
|
|
128
|
+
*/
|
|
129
|
+
isPasswordResource(resourceTypeId) {
|
|
130
|
+
return this.props.resourceTypes?.getFirstById(resourceTypeId)?.hasPassword();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Is OTP resource
|
|
135
|
+
* @param {string} resourceTypeId
|
|
136
|
+
* @returns {boolean}
|
|
137
|
+
*/
|
|
138
|
+
isOTPResource(resourceTypeId) {
|
|
139
|
+
return this.props.resourceTypes?.getFirstById(resourceTypeId)?.hasTotp();
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Get resource filtered by resource type to have only resource with password and totp
|
|
144
|
+
* @return {Array}
|
|
145
|
+
*/
|
|
146
|
+
get resourcesFilterByResourceTypePasswordAndTotp() {
|
|
147
|
+
const keepOnlyResourcesPasswordAndTotp = (resource) =>
|
|
148
|
+
this.isPasswordResource(resource.resource_type_id) || this.isOTPResource(resource.resource_type_id);
|
|
149
|
+
return this.props.resources.filter(keepOnlyResourcesPasswordAndTotp);
|
|
150
|
+
}
|
|
151
|
+
|
|
124
152
|
/**
|
|
125
153
|
* Has metadata types settings
|
|
126
154
|
* @returns {boolean}
|
|
@@ -173,7 +201,10 @@ class FilterResourcesByItemsIOwnPage extends React.Component {
|
|
|
173
201
|
let browsedResources;
|
|
174
202
|
|
|
175
203
|
if (isReady) {
|
|
176
|
-
browsedResources = this.filterSearchedResources(
|
|
204
|
+
browsedResources = this.filterSearchedResources(
|
|
205
|
+
this.resourcesFilterByResourceTypePasswordAndTotp,
|
|
206
|
+
this.props.context.search,
|
|
207
|
+
);
|
|
177
208
|
}
|
|
178
209
|
|
|
179
210
|
return (
|
|
@@ -68,13 +68,32 @@ class FilterResourcesByRecentlyModifiedPage extends React.Component {
|
|
|
68
68
|
this.props.history.push(`/webAccessibleResources/quickaccess/resources/view/${resourceId}`);
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
71
|
+
/**
|
|
72
|
+
* Is password resource
|
|
73
|
+
* @param {string} resourceTypeId
|
|
74
|
+
* @returns {boolean}
|
|
75
|
+
*/
|
|
76
|
+
isPasswordResource(resourceTypeId) {
|
|
77
|
+
return this.props.resourceTypes?.getFirstById(resourceTypeId)?.hasPassword();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Is OTP resource
|
|
82
|
+
* @param {string} resourceTypeId
|
|
83
|
+
* @returns {boolean}
|
|
84
|
+
*/
|
|
85
|
+
isOTPResource(resourceTypeId) {
|
|
86
|
+
return this.props.resourceTypes?.getFirstById(resourceTypeId)?.hasTotp();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Get resource filtered by resource type to have only resource with password and totp
|
|
91
|
+
* @return {Array}
|
|
92
|
+
*/
|
|
93
|
+
get resourcesFilterByResourceTypePasswordAndTotp() {
|
|
94
|
+
const keepOnlyResourcesPasswordAndTotp = (resource) =>
|
|
95
|
+
this.isPasswordResource(resource.resource_type_id) || this.isOTPResource(resource.resource_type_id);
|
|
96
|
+
return this.props.resources.filter(keepOnlyResourcesPasswordAndTotp);
|
|
78
97
|
}
|
|
79
98
|
|
|
80
99
|
/**
|
|
@@ -82,7 +101,7 @@ class FilterResourcesByRecentlyModifiedPage extends React.Component {
|
|
|
82
101
|
* @returns {Array}
|
|
83
102
|
*/
|
|
84
103
|
sortResourcesByModifiedDesc() {
|
|
85
|
-
return this.
|
|
104
|
+
return this.resourcesFilterByResourceTypePasswordAndTotp.sort(
|
|
86
105
|
(resource1, resource2) => new Date(resource2.modified) - new Date(resource1.modified),
|
|
87
106
|
);
|
|
88
107
|
}
|
|
@@ -115,6 +115,34 @@ class FilterResourcesBySharedWithMePage extends React.Component {
|
|
|
115
115
|
: resourcesSharedWithMe;
|
|
116
116
|
});
|
|
117
117
|
|
|
118
|
+
/**
|
|
119
|
+
* Is password resource
|
|
120
|
+
* @param {string} resourceTypeId
|
|
121
|
+
* @returns {boolean}
|
|
122
|
+
*/
|
|
123
|
+
isPasswordResource(resourceTypeId) {
|
|
124
|
+
return this.props.resourceTypes?.getFirstById(resourceTypeId)?.hasPassword();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Is OTP resource
|
|
129
|
+
* @param {string} resourceTypeId
|
|
130
|
+
* @returns {boolean}
|
|
131
|
+
*/
|
|
132
|
+
isOTPResource(resourceTypeId) {
|
|
133
|
+
return this.props.resourceTypes?.getFirstById(resourceTypeId)?.hasTotp();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Get resource filtered by resource type to have only resource with password and totp
|
|
138
|
+
* @return {Array}
|
|
139
|
+
*/
|
|
140
|
+
get resourcesFilterByResourceTypePasswordAndTotp() {
|
|
141
|
+
const keepOnlyResourcesPasswordAndTotp = (resource) =>
|
|
142
|
+
this.isPasswordResource(resource.resource_type_id) || this.isOTPResource(resource.resource_type_id);
|
|
143
|
+
return this.props.resources.filter(keepOnlyResourcesPasswordAndTotp);
|
|
144
|
+
}
|
|
145
|
+
|
|
118
146
|
/**
|
|
119
147
|
* Has metadata types settings
|
|
120
148
|
* @returns {boolean}
|
|
@@ -167,7 +195,10 @@ class FilterResourcesBySharedWithMePage extends React.Component {
|
|
|
167
195
|
let browsedResources;
|
|
168
196
|
|
|
169
197
|
if (isReady) {
|
|
170
|
-
browsedResources = this.filterSearchedResources(
|
|
198
|
+
browsedResources = this.filterSearchedResources(
|
|
199
|
+
this.resourcesFilterByResourceTypePasswordAndTotp,
|
|
200
|
+
this.props.context.search,
|
|
201
|
+
);
|
|
171
202
|
}
|
|
172
203
|
|
|
173
204
|
return (
|
package/src/react-quickaccess/components/FilterResourcesByTagPage/FilterResourcesByTagPage.js
CHANGED
|
@@ -165,6 +165,34 @@ class FilterResourcesByTagPage extends React.Component {
|
|
|
165
165
|
: resourcesMatchingTag;
|
|
166
166
|
});
|
|
167
167
|
|
|
168
|
+
/**
|
|
169
|
+
* Is password resource
|
|
170
|
+
* @param {string} resourceTypeId
|
|
171
|
+
* @returns {boolean}
|
|
172
|
+
*/
|
|
173
|
+
isPasswordResource(resourceTypeId) {
|
|
174
|
+
return this.props.resourceTypes?.getFirstById(resourceTypeId)?.hasPassword();
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Is OTP resource
|
|
179
|
+
* @param {string} resourceTypeId
|
|
180
|
+
* @returns {boolean}
|
|
181
|
+
*/
|
|
182
|
+
isOTPResource(resourceTypeId) {
|
|
183
|
+
return this.props.resourceTypes?.getFirstById(resourceTypeId)?.hasTotp();
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Get resource filtered by resource type to have only resource with password and totp
|
|
188
|
+
* @return {Array}
|
|
189
|
+
*/
|
|
190
|
+
get resourcesFilterByResourceTypePasswordAndTotp() {
|
|
191
|
+
const keepOnlyResourcesPasswordAndTotp = (resource) =>
|
|
192
|
+
this.isPasswordResource(resource.resource_type_id) || this.isOTPResource(resource.resource_type_id);
|
|
193
|
+
return this.props.resources.filter(keepOnlyResourcesPasswordAndTotp);
|
|
194
|
+
}
|
|
195
|
+
|
|
168
196
|
/**
|
|
169
197
|
* Get the tags to display
|
|
170
198
|
* @param {Array<Object>} tags the tag list to filter from
|
|
@@ -251,14 +279,11 @@ class FilterResourcesByTagPage extends React.Component {
|
|
|
251
279
|
let browsedTags, browsedResources;
|
|
252
280
|
|
|
253
281
|
if (isReady) {
|
|
282
|
+
const resources = this.resourcesFilterByResourceTypePasswordAndTotp;
|
|
254
283
|
if (listTagsOnly) {
|
|
255
|
-
browsedTags = this.filterSearchedTags(
|
|
284
|
+
browsedTags = this.filterSearchedTags(resources, this.props.context.search);
|
|
256
285
|
} else {
|
|
257
|
-
browsedResources = this.filterSearchedResources(
|
|
258
|
-
this.props.resources,
|
|
259
|
-
this.props.context.search,
|
|
260
|
-
selectedTag?.id,
|
|
261
|
-
);
|
|
286
|
+
browsedResources = this.filterSearchedResources(resources, this.props.context.search, selectedTag?.id);
|
|
262
287
|
}
|
|
263
288
|
}
|
|
264
289
|
|
|
@@ -133,10 +133,7 @@ class HomePage extends React.Component {
|
|
|
133
133
|
|
|
134
134
|
for (const i in resources) {
|
|
135
135
|
const resource = resources[i];
|
|
136
|
-
if (
|
|
137
|
-
(this.isPasswordResource(resource.resource_type_id) || this.isOTPResource(resource.resource_type_id)) &&
|
|
138
|
-
CanSuggestService.canSuggestUris(activeTabUrl, resource.metadata.uris)
|
|
139
|
-
) {
|
|
136
|
+
if (CanSuggestService.canSuggestUris(activeTabUrl, resource.metadata.uris)) {
|
|
140
137
|
suggestedResources.push(resource);
|
|
141
138
|
if (suggestedResources.length === SUGGESTED_RESOURCES_LIMIT) {
|
|
142
139
|
break;
|
|
@@ -195,18 +192,30 @@ class HomePage extends React.Component {
|
|
|
195
192
|
|
|
196
193
|
/**
|
|
197
194
|
* Is password resource
|
|
195
|
+
* @param {string} resourceTypeId
|
|
198
196
|
* @returns {boolean}
|
|
199
197
|
*/
|
|
200
|
-
isPasswordResource(
|
|
201
|
-
return this.props.resourceTypes?.getFirstById(
|
|
198
|
+
isPasswordResource(resourceTypeId) {
|
|
199
|
+
return this.props.resourceTypes?.getFirstById(resourceTypeId)?.hasPassword();
|
|
202
200
|
}
|
|
203
201
|
|
|
204
202
|
/**
|
|
205
203
|
* Is OTP resource
|
|
204
|
+
* @param {string} resourceTypeId
|
|
206
205
|
* @returns {boolean}
|
|
207
206
|
*/
|
|
208
|
-
isOTPResource(
|
|
209
|
-
return this.props.resourceTypes?.getFirstById(
|
|
207
|
+
isOTPResource(resourceTypeId) {
|
|
208
|
+
return this.props.resourceTypes?.getFirstById(resourceTypeId)?.hasTotp();
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Get resource filtered by resource type to have only resource with password and totp
|
|
213
|
+
* @return {Array}
|
|
214
|
+
*/
|
|
215
|
+
get resourcesFilterByResourceTypePasswordAndTotp() {
|
|
216
|
+
const keepOnlyResourcesPasswordAndTotp = (resource) =>
|
|
217
|
+
this.isPasswordResource(resource.resource_type_id) || this.isOTPResource(resource.resource_type_id);
|
|
218
|
+
return this.props.resources.filter(keepOnlyResourcesPasswordAndTotp);
|
|
210
219
|
}
|
|
211
220
|
|
|
212
221
|
/**
|
|
@@ -266,8 +275,9 @@ class HomePage extends React.Component {
|
|
|
266
275
|
let browsedResources, suggestedResources;
|
|
267
276
|
|
|
268
277
|
if (isReady) {
|
|
269
|
-
|
|
270
|
-
|
|
278
|
+
const resources = this.resourcesFilterByResourceTypePasswordAndTotp;
|
|
279
|
+
browsedResources = this.filterSearchedResources(resources, this.props.context.search);
|
|
280
|
+
suggestedResources = this.filterSuggestedResources(resources, this.state.activeTabUrl);
|
|
271
281
|
}
|
|
272
282
|
|
|
273
283
|
return (
|
|
@@ -184,7 +184,7 @@ class Password extends Component {
|
|
|
184
184
|
<input
|
|
185
185
|
id={this.props.id}
|
|
186
186
|
name={this.props.name}
|
|
187
|
-
maxLength=
|
|
187
|
+
maxLength={this.props.maxLength}
|
|
188
188
|
placeholder={this.props.placeholder}
|
|
189
189
|
type={this.state.viewPassword && !this.props.disabled ? "text" : "password"}
|
|
190
190
|
onKeyUp={this.props.onKeyUp}
|
|
@@ -232,6 +232,7 @@ Password.defaultProps = {
|
|
|
232
232
|
id: "",
|
|
233
233
|
name: "",
|
|
234
234
|
autoComplete: "off",
|
|
235
|
+
maxLength: 4096,
|
|
235
236
|
};
|
|
236
237
|
|
|
237
238
|
Password.propTypes = {
|
|
@@ -252,6 +253,7 @@ Password.propTypes = {
|
|
|
252
253
|
backgroundColor: PropTypes.string,
|
|
253
254
|
textColor: PropTypes.string,
|
|
254
255
|
}), // The securityTokenDto
|
|
256
|
+
maxLength: PropTypes.number, // The max length of the input
|
|
255
257
|
};
|
|
256
258
|
|
|
257
259
|
export default withTranslation("common")(Password);
|
|
@@ -102,4 +102,30 @@ describe("As LU I should see the user confirm passphrase page", () => {
|
|
|
102
102
|
expect(page.isObfuscated).toBeTruthy();
|
|
103
103
|
});
|
|
104
104
|
});
|
|
105
|
+
|
|
106
|
+
describe("As LU I cannot exceed the password max length", () => {
|
|
107
|
+
it("maxLength is 4096 when no maxLength prop is provided", () => {
|
|
108
|
+
expect.assertions(1);
|
|
109
|
+
const props = defaultProps();
|
|
110
|
+
const page = new PasswordPage(props);
|
|
111
|
+
expect(page.passwordInput.maxLength).toBe(4096);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it("forwards a custom maxLength prop to the input element", () => {
|
|
115
|
+
expect.assertions(1);
|
|
116
|
+
const props = defaultProps({ maxLength: 12 });
|
|
117
|
+
const page = new PasswordPage(props);
|
|
118
|
+
expect(page.passwordInput.maxLength).toBe(12);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it("reflects an updated maxLength when the prop changes", () => {
|
|
122
|
+
expect.assertions(2);
|
|
123
|
+
const props = defaultProps({ maxLength: 8 });
|
|
124
|
+
const page = new PasswordPage(props);
|
|
125
|
+
expect(page.passwordInput.maxLength).toBe(8);
|
|
126
|
+
|
|
127
|
+
page.rerender(defaultProps({ maxLength: 16 }));
|
|
128
|
+
expect(page.passwordInput.maxLength).toBe(16);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
105
131
|
});
|