11import { Collection , Binary } from 'mongodb'
2+ import { pipe } from 'ramda'
23
4+ import { encrypt , decrypt } from '../helpers/crypto'
35import { bytesToUuid , uuidToBytes } from '../helpers/uuid'
46import { Network } from '../interfaces/Network'
57import { Account } from '../models/Account'
@@ -12,31 +14,34 @@ export interface AccountDao {
1214 insertToken : ( filter : Partial < Account > , network : Network , token : string ) => Promise < void >
1315}
1416
15- export const AccountDao = ( collection : Collection ) : AccountDao => {
17+ export const AccountDao = ( collection : Collection , encryptionKey : string ) : AccountDao => {
18+ const modelToEncryptedDocument = pipe ( encryptAccount ( encryptionKey ) , modelToDocument )
19+ const documentToDecryptedModel = pipe ( documentToModel , decryptAccount ( encryptionKey ) )
20+
1621 const createIndices = async ( ) => {
1722 await collection . createIndex ( { email : 1 } , { unique : true } )
1823 await collection . createIndex ( { id : 1 } , { unique : false } )
1924 }
2025
2126 const insertOne = async ( account : Account ) : Promise < void > => {
22- const document = modelToDocument ( account )
27+ const document = modelToEncryptedDocument ( account )
2328 await collection . insertOne ( document )
2429 }
2530
2631 const findOne = async ( filter : Partial < Account > ) : Promise < Account > => {
27- const document = modelToDocument ( filter )
32+ const document = modelToEncryptedDocument ( filter )
2833 const account : AccountDocument = await collection . findOne ( document )
29- return account && documentToModel ( account ) as Account
34+ return account && documentToDecryptedModel ( account ) as Account
3035 }
3136
3237 const updateOne = async ( filter : Partial < Account > , updates : Partial < Account > ) : Promise < void > => {
33- const filterDocument = modelToDocument ( filter )
34- const updatesDocument = modelToDocument ( updates )
38+ const filterDocument = modelToEncryptedDocument ( filter )
39+ const updatesDocument = modelToEncryptedDocument ( updates )
3540 await collection . updateOne ( filterDocument , { $set : updatesDocument } )
3641 }
3742
3843 const insertToken = async ( filter : Partial < Account > , network : Network , token : string ) : Promise < void > => {
39- const filterDocument = modelToDocument ( filter )
44+ const filterDocument = modelToEncryptedDocument ( filter )
4045 const array = network === Network . LIVE ? 'apiTokens' : 'testApiTokens'
4146 await collection . updateOne ( filterDocument , { $push : { [ array ] : { token } } } )
4247 }
@@ -81,6 +86,30 @@ const modelToDocument = (model: Partial<Account>): Partial<AccountDocument> => {
8186 return document
8287}
8388
89+ const encryptAccount = ( encryptionKey : string ) => ( account : Partial < Account > ) : Partial < Account > => {
90+ const encryptedAccount = {
91+ ...account ,
92+ privateKey : account . privateKey && encrypt ( account . privateKey , encryptionKey ) ,
93+ }
94+
95+ if ( ! account . privateKey )
96+ delete encryptedAccount . privateKey
97+
98+ return encryptedAccount
99+ }
100+
101+ const decryptAccount = ( decryptionKey : string ) => ( account : Partial < Account > ) : Partial < Account > => {
102+ const decryptedAccount = {
103+ ...account ,
104+ privateKey : account . privateKey && decrypt ( account . privateKey , decryptionKey ) ,
105+ }
106+
107+ if ( ! account . privateKey )
108+ delete decryptedAccount . privateKey
109+
110+ return decryptedAccount
111+ }
112+
84113interface AccountDocument {
85114 readonly id ?: Buffer | Binary
86115 readonly email : string
0 commit comments