summaryrefslogtreecommitdiff
path: root/source/import/Aegis.mc
diff options
context:
space:
mode:
Diffstat (limited to 'source/import/Aegis.mc')
-rw-r--r--source/import/Aegis.mc44
1 files changed, 25 insertions, 19 deletions
diff --git a/source/import/Aegis.mc b/source/import/Aegis.mc
index 05905e9..0d515cd 100644
--- a/source/import/Aegis.mc
+++ b/source/import/Aegis.mc
@@ -4,7 +4,8 @@
// README 11.3. The reader consumes the token stream of Json.Tokenizer and
// tracks the path of the current value ("/db/entries/[]/info/secret"), so it
// can stop after any token and continue in the next event. It keeps only
-// the parsed items and the group names, never the document.
+// the parsed items (packed, see ImportItem) and the group names; the
+// document's bytes stay with the tokenizer.
//
// * Encrypted exports are refused: header.slots is not null, or db is a
// string.
@@ -34,7 +35,10 @@ class AegisReader {
static const ENCRYPTED_MESSAGE = "This Aegis export is encrypted. In Aegis choose Export, then turn encryption off, and paste that file.";
- var items as Array<ImportItem> = [] as Array<ImportItem>;
+ // Parsed items, packed (ImportItem.pack); unpack with item(i).
+ var items as Array<ByteArray> = [] as Array<ByteArray>;
+ // Group UUID -> name, from db.groups.
+ var groups as Dictionary<String, String> = {} as Dictionary<String, String>;
var error as String? = null;
private var _tok as Json.Tokenizer;
@@ -44,7 +48,6 @@ class AegisReader {
private var _fields as ImportFields? = null;
private var _seen as Dictionary<String, Boolean> = {} as Dictionary<String, Boolean>;
private var _group as Dictionary<String, String>? = null;
- private var _groups as Dictionary<String, String> = {} as Dictionary<String, String>;
private var _encrypted as Boolean = false;
private var _vaultVersion as Long = -1l;
private var _sawEntries as Boolean = false;
@@ -53,11 +56,25 @@ class AegisReader {
_tok = new Json.Tokenizer(data);
}
- // Bytes read so far (for progress).
+ // Bytes read so far, and in all (for progress).
function position() as Number {
return _tok.pos;
}
+ function size() as Number {
+ return _tok.size();
+ }
+
+ // The document's bytes (saved when it is incomplete).
+ function data() as ByteArray {
+ return _tok.data();
+ }
+
+ // Parsed item i, unpacked, with its group name resolved.
+ function item(i as Number) as ImportItem {
+ return ImportItem.unpack(items[i], groups);
+ }
+
// Process up to TOKENS_PER_STEP tokens. Returns RUNNING, DONE,
// INCOMPLETE (the text ends early: wait for more) or FAILED (error set).
function step() as Number {
@@ -139,14 +156,14 @@ class AegisReader {
item.label = fields.issuer.length() > 0 ? fields.issuer : fields.account;
}
fields.secret = null;
- items.add(item);
+ items.add(item.pack());
}
_item = null;
_fields = null;
} else if (p.equals("/db/groups/[]")) {
var g = _group;
if (g != null && g.hasKey("uuid") && g.hasKey("name")) {
- _groups[g["uuid"] as String] = g["name"] as String;
+ groups[g["uuid"] as String] = g["name"] as String;
}
_group = null;
}
@@ -244,19 +261,8 @@ class AegisReader {
return fail(_vaultVersion > 1 ? "Aegis export version " + _vaultVersion + " is not supported"
: "not an Aegis export (no version 1 vault with db.entries)");
}
- // Resolve group references now that db.groups has been read.
- for (var i = 0; i < items.size(); i++) {
- var item = items[i];
- var ref = item.groupRef;
- var e = item.entry;
- if (ref == null || e == null) {
- continue;
- }
- var name = ref.find("uuid:") == 0 ? _groups[ref.substring(5, ref.length()) as String] : ref.substring(5, ref.length());
- if (name != null) {
- e.group = fitBytes(Text.trim(name as String), Entry.MAX_GROUP_BYTES);
- }
- }
+ // Group references are resolved when items are unpacked (db.groups
+ // may come after the entries).
return DONE;
}