Skip to content
This repository has been archived by the owner on Sep 19, 2018. It is now read-only.

Added touch method to set last_used property #96

Merged
merged 3 commits into from
Mar 14, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"security/detect-non-literal-fs-filename": "off",
"security/detect-object-injection": "off",

"no-console": "off",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing this was put in place to troubleshoot tests, and just got missed with the last push. This option needs to be removed so we keep the default for "no-console" as "error".

"eqeqeq": "error",
"indent": ["error", 2, {"SwitchCase": 1, "VariableDeclarator": {"var": 2, "let": 2, "const": 3}}],
"linebreak-style": ["error", "unix"],
Expand Down
44 changes: 44 additions & 0 deletions lib/datastore.js
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,50 @@ class DataStore {

return item;
}
/**
* Touches an existing item in this DataStore.
*
* `{item}` is expected to be a complete object. API users should call
* {@link #get}, then pass the returned value to `{touch}`
*
* @param {Object} item The item to touch
* @returns {Object} The updated item
* @throws {Error} if this item does not exist
* @throws {TypeError} if `item` is not an object with a `id` member
* @throws {DataStoreError} if the `item` violates the schema
*/
async touch(item) {
checkState(this);

let self = instance.get(this);
if (!item || !item.id) {
throw new DataStoreError(DataStoreError.INVALID_ITEM);
}

let id = item.id;
let record = await self.ldb.items.get(id);
let orig, encrypted;
if (!record) {
throw new DataStoreError(DataStoreError.MISSING_ITEM);
} else {
encrypted = record.encrypted;
}

orig = await self.keystore.unprotect(id, encrypted);

orig.last_used = new Date().toISOString();
encrypted = await self.keystore.protect(orig);

record = {
id,
encrypted,
last_modified: record.last_modified
};

await self.ldb.items.put(record);
self.recordMetric("touched", item.id);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this might require an update to the extension's metrics reporting ...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this comment is really a note to go check the extension and ensure it won't cause additional failures.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this might require an update to the extension's metrics reporting
this comment is really a note to go check the extension and ensure it won't cause additional failures

@linuxwolf Good call. @sashei is going to do a quick smoke test before merging and have a follow-up here to do corresponding follow-on work: mozilla-lockwise/lockbox-extension#661

return orig;
}
/**
* Removes an item from this DataStore.
*
Expand Down
1 change: 1 addition & 0 deletions lib/items.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const SCHEMA = joi.object().keys({
origins: joi.array().items(STRING_500).max(5).default([]),
tags: joi.array().items(STRING_500).max(10).default([]),
entry: joi.alternatives(ENTRY_SCHEMAS).required(),
last_used: joi.date().allow(null).default(null),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this is what we really want. Adding it to the schema allows the API user to define when last_used was, including removing it altogether (accidentally or otherwise).

Other read-only properties (e.g., modified, created, disabled) are handled as a separate step post Joi validation. That feels like the right behavior for this property, but I'm open to different opinions.

});
const VALIDATE_OPTIONS = {
abortEarly: false,
Expand Down
Loading