Skip to content

Commit

Permalink
Merge pull request #411 from jdesboeufs/fix/crypto-all-api
Browse files Browse the repository at this point in the history
fix: all() not work with crypto enabled
  • Loading branch information
mingchuno authored Mar 23, 2021
2 parents ddc131a + 6e2a179 commit 2ffa841
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 27 deletions.
11 changes: 9 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Fixed

- `store.all()` method not working with encrypted store [#410](https://github.com/jdesboeufs/connect-mongo/issues/410) [#411](https://github.com/jdesboeufs/connect-mongo/issues/411)
- Update and unpin `mongodb` dependency due to upstream fix has been deployed [#409](https://github.com/jdesboeufs/connect-mongo/issues/409)

## [4.4.0] - 2021-03-11

### **BREAKING CHANGES**

- Use `export =` for better cjs require without `.default`
Expand Down Expand Up @@ -41,9 +48,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- Use `matchedCount` instead of `modifiedCount` to avoid throwing exceptions when nothing to modify (#390)
- Use `matchedCount` instead of `modifiedCount` to avoid throwing exceptions when nothing to modify [#390](https://github.com/jdesboeufs/connect-mongo/issues/390)
- Fixed `Warning: Accessing non-existent property 'MongoError' of module exports inside circular dependency` by downgrade to `mongodb@3.6.3`
- Revert update session when touch (#351)
- Revert update session when touch #351
- Fix cannot read property `lastModified` of null
- Fix TS typing error

Expand Down
6 changes: 6 additions & 0 deletions src/lib/MongoStore.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,8 @@ test.serial('touch ops with touchAfter with touch', async (t) => {
test.serial('basic operation flow with crypto', async (t) => {
;({ store, storePromise } = createStoreHelper({
crypto: { secret: 'secret' },
collectionName: 'crypto-test',
autoRemove: 'disabled',
}))
let orgSession = makeData()
const sid = 'test-basic-flow-with-crypto'
Expand All @@ -288,6 +290,10 @@ test.serial('basic operation flow with crypto', async (t) => {
orgSession = JSON.parse(JSON.stringify(orgSession))
// @ts-ignore
t.deepEqual(session, orgSession)
const sessions = await storePromise.all()
t.not(sessions, undefined)
t.not(sessions, null)
t.is(sessions?.length, 1)
})

test.serial('with touch after and get non-exist session', async (t) => {
Expand Down
63 changes: 38 additions & 25 deletions src/lib/MongoStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,36 @@ export default class MongoStore extends session.Store {
return sessionId
}

/**
* promisify and bind the `this.crypto.get` function.
* Please check !!this.crypto === true before using this getter!
*/
private get cryptoGet() {
if (!this.crypto) {
throw new Error('Check this.crypto before calling this.cryptoGet!')
}
return util.promisify(this.crypto.get).bind(this.crypto)
}

/**
* Decrypt given session data
* @param session session data to be decrypt. Mutate the input session.
*/
private async decryptSession(
session: session.SessionData | undefined | null
) {
if (this.crypto && session) {
const plaintext = await this.cryptoGet(
this.options.crypto.secret as string,
session.session
).catch((err) => {
throw new Error(err)
})
// @ts-ignore
session.session = JSON.parse(plaintext)
}
}

/**
* Get a session from the store given a session ID (sid)
* @param sid session ID
Expand All @@ -277,19 +307,7 @@ export default class MongoStore extends session.Store {
],
})
if (this.crypto && session) {
const cryptoGet = util.promisify(this.crypto.get).bind(this.crypto)
try {
const plaintext = await cryptoGet(
this.options.crypto.secret as string,
session.session
).catch((err) => {
throw new Error(err)
})
// @ts-ignore
session.session = JSON.parse(plaintext)
} catch (error) {
callback(error)
}
await this.decryptSession(session).catch((err) => callback(err))
}
const s =
session && this.transformFunctions.unserialize(session.session)
Expand Down Expand Up @@ -457,19 +475,14 @@ export default class MongoStore extends session.Store {
],
})
const results: session.SessionData[] = []
sessions.forEach(
(session) => {
results.push(this.transformFunctions.unserialize(session.session))
},
(err) => {
if (err) {
callback(err)
} else {
this.emit('all', results)
callback(null, results)
}
for await (const session of sessions) {
if (this.crypto && session) {
await this.decryptSession(session)
}
)
results.push(this.transformFunctions.unserialize(session.session))
}
this.emit('all', results)
callback(null, results)
} catch (error) {
callback(error)
}
Expand Down

0 comments on commit 2ffa841

Please sign in to comment.