Skip to content

Commit 98bac5e

Browse files
refactor: move encryption/decryption of pks responsibility to dao (#998)
1 parent 6d7f73b commit 98bac5e

File tree

4 files changed

+39
-28
lines changed

4 files changed

+39
-28
lines changed

src/Frost.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export async function Frost(localVars: any = {}) {
4242
const mongoClient = await MongoClient.connect(configuration.mongodbUrl)
4343
const dbConnection = await mongoClient.db()
4444
const accountCollection = dbConnection.collection('accounts')
45-
const accountDao = AccountDao(accountCollection)
45+
const accountDao = AccountDao(accountCollection, configuration.privateKeyEncryptionKey)
4646

4747
const sendEmail = SendEmail({
4848
nodemailer: {
@@ -78,14 +78,10 @@ export async function Frost(localVars: any = {}) {
7878
configuration: {
7979
verifiedAccount: configuration.verifiedAccount,
8080
jwtSecret: configuration.jwt,
81-
privateKeyEncryptionKey: configuration.privateKeyEncryptionKey,
8281
},
8382
})
8483

8584
const workController = WorkController({
86-
configuration: {
87-
privateKeyEncryptionKey: configuration.privateKeyEncryptionKey,
88-
},
8985
dependencies: {
9086
logger: logger.child({ file: 'WorkController' }),
9187
mainnetNode,

src/controllers/AccountController.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import {
1818
Unauthorized,
1919
} from '../errors/errors'
2020
import { PasswordHelper } from '../helpers/Password'
21-
import { encrypt } from '../helpers/crypto'
2221
import { tokenMatch } from '../helpers/token'
2322
import { uuid4 } from '../helpers/uuid'
2423
import { isJWTData, JWTData } from '../interfaces/JWTData'
@@ -76,7 +75,6 @@ interface Dependencies {
7675
interface Configuration {
7776
readonly verifiedAccount: boolean
7877
readonly jwtSecret: string
79-
readonly privateKeyEncryptionKey: string
8078
}
8179

8280
interface Arguments {
@@ -132,7 +130,6 @@ export const AccountController = ({
132130

133131
const id = await getUnusedId()
134132
const { privateKey, publicKey } = generateED25519Base58Keys()
135-
const encryptedPrivateKey = encrypt(privateKey, configuration.privateKeyEncryptionKey)
136133
const apiToken = await createJWT({ accountId: id, network: Network.TEST }, Token.TestApiKey)
137134
const encryptedToken = await Vault.encrypt(`TEST_${apiToken}`)
138135
const issuer = createIssuerFromPrivateKey(privateKey)
@@ -143,7 +140,7 @@ export const AccountController = ({
143140
email,
144141
emailPublic: false,
145142
password: hashedPassword,
146-
privateKey: encryptedPrivateKey,
143+
privateKey,
147144
publicKey,
148145
createdAt: Date.now().toString(), // .toString(): legacy reasons
149146
verified: configuration.verifiedAccount,

src/controllers/WorkController.ts

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import * as Pino from 'pino'
77
import { pipeP } from 'ramda'
88

99
import { PoetNode, WorkSearchFilters } from '../daos/PoetNodeDao'
10-
import { decrypt } from '../helpers/crypto'
1110
import { Network } from '../interfaces/Network'
1211

1312
export interface WorkController {
@@ -23,14 +22,9 @@ export interface WorkController {
2322
}
2423

2524
interface Arguments {
26-
readonly configuration: Configuration
2725
readonly dependencies: Dependencies
2826
}
2927

30-
interface Configuration {
31-
readonly privateKeyEncryptionKey: string
32-
}
33-
3428
interface Dependencies {
3529
readonly logger: Pino.Logger
3630
readonly mainnetNode: PoetNode
@@ -45,9 +39,6 @@ export const WorkController = ({
4539
testnetNode,
4640
verifiableClaimSigner,
4741
},
48-
configuration: {
49-
privateKeyEncryptionKey,
50-
},
5142
}: Arguments): WorkController => {
5243
const networkToNode = (network: Network) => network === Network.LIVE ? mainnetNode : testnetNode
5344

@@ -61,7 +52,7 @@ export const WorkController = ({
6152
return node.searchWorks(filters)
6253
}
6354

64-
const create = async (claim: any, context: any, issuer: string, encryptedPrivateKey: string, network: Network) => {
55+
const create = async (claim: any, context: any, issuer: string, privateKey: string, network: Network) => {
6556
const node = networkToNode(network)
6657

6758
const legacyContext = {
@@ -75,8 +66,6 @@ export const WorkController = ({
7566
},
7667
}
7768

78-
const privateKey = decrypt(encryptedPrivateKey, privateKeyEncryptionKey)
79-
8069
const createAndSignClaim = pipeP(
8170
configureCreateVerifiableClaim({ issuer, context: { ...legacyContext, ...context, ...aboutContext} }),
8271
verifiableClaimSigner.configureSignVerifiableClaim({ privateKey }),

src/daos/AccountDao.ts

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { Collection, Binary } from 'mongodb'
2+
import { pipe } from 'ramda'
23

4+
import { encrypt, decrypt } from '../helpers/crypto'
35
import { bytesToUuid, uuidToBytes } from '../helpers/uuid'
46
import { Network } from '../interfaces/Network'
57
import { 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+
84113
interface AccountDocument {
85114
readonly id?: Buffer | Binary
86115
readonly email: string

0 commit comments

Comments
 (0)