Skip to content

Commit b9e4944

Browse files
committed
update subdocument encryption example
1 parent 83a6e9b commit b9e4944

File tree

2 files changed

+107
-32
lines changed

2 files changed

+107
-32
lines changed

README.md

+34-31
Original file line numberDiff line numberDiff line change
@@ -164,47 +164,46 @@ const decrypted = fieldEncryption.decrypt(encrypted, 'secret')); // decrypted =
164164

165165
Note that while this plugin is designed to encrypt only top level fields, nested fields can be easily encrypted by creating a mongoose schema for the nested objects and adding the plugin to them.
166166

167-
See comment for discussion: [https://github.com/wheresvic/mongoose-field-encryption/issues/34#issuecomment-577383776](https://github.com/wheresvic/mongoose-field-encryption/issues/34#issuecomment-577383776)
167+
See comment for discussion: [https://github.com/wheresvic/mongoose-field-encryption/issues/34#issuecomment-577383776](https://github.com/wheresvic/mongoose-field-encryption/issues/34#issuecomment-577383776).
168168

169-
Example
169+
_Please also note that this example is provided as a best-effort basis and this plugin does not take responsibility for what quirks mongoose might bring if you use this feature._
170+
171+
See relevant test in `test/test-db.js`:
170172

171173
```js
172-
const mongoose = require('mongoose');
173-
const mongooseFieldEncryption = require("mongoose-field-encryption").fieldEncryption;
174+
// subdocument encryption
174175

175-
const CredentialSchema = new mongoose.Schema({
176-
type: {
177-
required: true,
178-
type: String,
179-
},
180-
value: {
181-
required: true,
182-
type: String,
183-
},
176+
const UserExtraSchema = new mongoose.Schema({
177+
city: { type: String },
178+
country: { type: String },
179+
address: { type: String },
180+
postalCode: { type: String },
184181
});
185182

186-
CredentialSchema.plugin(mongooseFieldEncryption, {
187-
fields: ["value"],
188-
secret: process.env.MONGOOSE_ENCRYPTION_KEY,
183+
UserExtraSchema.plugin(fieldEncryptionPlugin, {
184+
fields: ["address"],
185+
secret: "icanhazcheeseburger",
186+
saltGenerator: (secret) => secret.slice(0, 16),
189187
});
190188

191-
const accountSchema = new mongoose.Schema({
192-
provider: {
193-
type: String,
194-
required: true,
195-
lowercase: true,
196-
trim: true,
197-
},
198-
credentials: [CredentialSchema],
199-
owner: {
200-
required: true,
201-
type: mongoose.Schema.Types.ObjectId,
202-
ref: 'User',
203-
},
189+
const UserSchema = new mongoose.Schema(
190+
{
191+
name: { type: String, required: true },
192+
surname: { type: String, required: true },
193+
email: { type: String, required: true },
194+
extra: UserExtraSchema,
195+
},
196+
{ collection: "users" }
197+
);
198+
199+
UserSchema.plugin(fieldEncryptionPlugin, {
200+
fields: ["name", "surname"],
201+
secret: "icanhazcheeseburger",
202+
saltGenerator: (secret) => secret.slice(0, 16),
204203
});
205204

206-
module.exports = mongoose.model('Account', accountSchema);
207-
```
205+
const UserModel = mongoose.model("User", UserSchema);
206+
```
208207

209208
## Development
210209

@@ -235,6 +234,10 @@ Feel free to make changes to the default docker configuration as required.
235234

236235
## Changelog
237236

237+
### 4.0.2
238+
239+
- Update documentation for subdocument encryption
240+
238241
### 4.0.1
239242

240243
- Update documentation to add nested field encryption example

test/test-db.js

+73-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,13 @@ describe("mongoose-field-encryption plugin db", function () {
1616

1717
before(function (done) {
1818
mongoose
19-
.connect(uri, { useNewUrlParser: true, promiseLibrary: Promise, autoIndex: false, useUnifiedTopology: true })
19+
.connect(uri, {
20+
useNewUrlParser: true,
21+
promiseLibrary: Promise,
22+
autoIndex: false,
23+
useUnifiedTopology: true,
24+
keepAlive: 1,
25+
})
2026
.then(function () {
2127
done();
2228
});
@@ -203,6 +209,72 @@ describe("mongoose-field-encryption plugin db", function () {
203209
runTests(NestedFieldEncryptionCustomSalt, getSut, expectEncryptionValues, expectDecryptionValues);
204210
});
205211

212+
describe("subdocument encryption", function () {
213+
it("should encrypt and decrypt subdocuments", function (done) {
214+
const UserExtraSchema = new mongoose.Schema({
215+
city: { type: String },
216+
country: { type: String },
217+
address: { type: String },
218+
postalCode: { type: String },
219+
});
220+
221+
UserExtraSchema.plugin(fieldEncryptionPlugin, {
222+
fields: ["address"],
223+
secret: "icanhazcheeseburger",
224+
saltGenerator: (secret) => secret.slice(0, 16),
225+
});
226+
227+
const UserSchema = new mongoose.Schema(
228+
{
229+
name: { type: String, required: true },
230+
surname: { type: String, required: true },
231+
email: { type: String, required: true },
232+
extra: UserExtraSchema,
233+
},
234+
{ collection: "users" }
235+
);
236+
237+
UserSchema.plugin(fieldEncryptionPlugin, {
238+
fields: ["name", "surname"],
239+
secret: "icanhazcheeseburger",
240+
saltGenerator: (secret) => secret.slice(0, 16),
241+
});
242+
243+
const UserModel = mongoose.model("User", UserSchema);
244+
245+
// given
246+
const sut = new UserModel({
247+
name: "snoop",
248+
surname: "dawg",
249+
email: "snoop.dawg@dadadadada.com",
250+
extra: {
251+
city: "cali",
252+
country: "usa",
253+
address: "bowchickabowwow",
254+
postalCode: "90210",
255+
},
256+
});
257+
258+
// when
259+
sut
260+
.save()
261+
.then(() => {
262+
// then
263+
expect(sut.name).to.equal("31393663303733396265616337353364:5b8c2d2160c935152c7dd6bf6a31f894");
264+
expect(sut.extra.address).to.equal("31393663303733396265616337353364:b9610446ddefafef177ffe0cdfec2d2d");
265+
266+
return UserModel.findById(sut._id);
267+
})
268+
.then((found) => {
269+
expect(found.name).to.equal("snoop");
270+
expect(found.extra.address).to.equal("bowchickabowwow");
271+
})
272+
.finally(() => {
273+
done();
274+
});
275+
});
276+
});
277+
206278
function runTests(MongooseModel, getSut, expectEncryptionValues, expectDecryptionValues) {
207279
it("should encrypt fields on save and decrypt fields on findById", function () {
208280
// given

0 commit comments

Comments
 (0)