Treat PIN fields as sensitive (#81)
This commit is contained in:
@@ -684,7 +684,11 @@ fn classify(index: usize, line: &[u8]) -> EntryFieldMetadata {
|
|||||||
let kind = semantic_field_kind(name);
|
let kind = semantic_field_kind(name);
|
||||||
return EntryFieldMetadata {
|
return EntryFieldMetadata {
|
||||||
kind,
|
kind,
|
||||||
sensitivity: EntrySensitivity::Ordinary,
|
sensitivity: if name.eq_ignore_ascii_case("pin") {
|
||||||
|
EntrySensitivity::Sensitive
|
||||||
|
} else {
|
||||||
|
EntrySensitivity::Ordinary
|
||||||
|
},
|
||||||
name: Some(name.to_owned()),
|
name: Some(name.to_owned()),
|
||||||
otp: None,
|
otp: None,
|
||||||
diagnostic: std::str::from_utf8(&line[value_start..])
|
diagnostic: std::str::from_utf8(&line[value_start..])
|
||||||
|
|||||||
@@ -575,10 +575,7 @@ fn editor_field(index: usize, field: &EntryField) -> MobileEntryEditorField {
|
|||||||
| EntryFieldKind::Field => MobileEntryEditorFieldKind::Field,
|
| EntryFieldKind::Field => MobileEntryEditorFieldKind::Field,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let sensitive = matches!(
|
let sensitive = metadata.sensitivity() == EntrySensitivity::Sensitive;
|
||||||
kind,
|
|
||||||
MobileEntryEditorFieldKind::Password | MobileEntryEditorFieldKind::OtpUri
|
|
||||||
);
|
|
||||||
MobileEntryEditorField {
|
MobileEntryEditorField {
|
||||||
id: field.id().value(),
|
id: field.id().value(),
|
||||||
kind,
|
kind,
|
||||||
|
|||||||
@@ -277,6 +277,53 @@ fn mobile_projection_marks_an_empty_first_line_without_a_reveal_control() -> Tes
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pin_fields_are_sensitive_case_insensitively() -> TestResult {
|
||||||
|
let fixture = FixtureSet::load()?;
|
||||||
|
let store = fixture.materialize_store("basic")?;
|
||||||
|
let repository = Repository::open(store.path())?;
|
||||||
|
let keys = KeyStore::load(fixture.path("keys"))?;
|
||||||
|
let mut secrets = FixtureSecrets::all(&fixture);
|
||||||
|
write_plaintext(
|
||||||
|
&repository,
|
||||||
|
&keys,
|
||||||
|
"documents/pins",
|
||||||
|
b"password\nPIN: 1234\npin: 5678\nPiN: 9012\n",
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let document =
|
||||||
|
EntryDocumentService::new(&repository, &keys).open("documents/pins", &mut secrets)?;
|
||||||
|
let pins = &document.fields()[1..];
|
||||||
|
assert!(pins.iter().all(|field| {
|
||||||
|
field.metadata().kind() == EntryFieldKind::Field
|
||||||
|
&& field.metadata().sensitivity() == EntrySensitivity::Sensitive
|
||||||
|
}));
|
||||||
|
|
||||||
|
let page = MobileEntryPage::from_document(&document);
|
||||||
|
let projected = page
|
||||||
|
.sections()
|
||||||
|
.iter()
|
||||||
|
.flat_map(|section| section.fields())
|
||||||
|
.filter(|field| field.id() != 0)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
assert_eq!(projected.len(), 3);
|
||||||
|
assert!(projected.iter().all(|field| {
|
||||||
|
field.sensitive()
|
||||||
|
&& field.value().is_none()
|
||||||
|
&& field.masked_value() == "Hidden"
|
||||||
|
&& !field.selectable()
|
||||||
|
}));
|
||||||
|
assert_eq!(field_value(&document, pins[0].id().value())?, "1234");
|
||||||
|
|
||||||
|
let editor = MobileEntryDraft::new(document, false).page();
|
||||||
|
assert!(
|
||||||
|
editor.fields()[1..]
|
||||||
|
.iter()
|
||||||
|
.all(|field| field.sensitive() && field.masked_value() == "Hidden")
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn named_multiline_fields_are_one_lossless_logical_field() -> TestResult {
|
fn named_multiline_fields_are_one_lossless_logical_field() -> TestResult {
|
||||||
let fixture = FixtureSet::load()?;
|
let fixture = FixtureSet::load()?;
|
||||||
|
|||||||
Reference in New Issue
Block a user