@@ -2,27 +2,32 @@ import fs from 'fs'
2
2
import { MongoClient } from 'mongodb'
3
3
import ShareDbMongo from 'sharedb-mongo'
4
4
5
- export const { db, mongo, mongoClient, createMongoIndex } = getMongoDb ( {
6
- url : process . env . MONGO_URL ,
7
- optsString : process . env . MONGO_OPTS ,
8
- sslKeyPath : process . env . MONGO_SSL_KEY_PATH ,
9
- sslCertPath : process . env . MONGO_SSL_CERT_PATH ,
10
- sslCaPath : process . env . MONGO_SSL_CA_PATH
5
+ export const { db, mongo, mongoClient, createMongoIndex } = getMongoDb ( process . env . MONGO_URL , {
6
+ // ssl key, cert and ca can be provided as paths or base64 or directly as strings
7
+
8
+ // ssl as string
9
+ key : process . env . MONGO_SSL_KEY ,
10
+ cert : process . env . MONGO_SSL_CERT ,
11
+ ca : process . env . MONGO_SSL_CA ,
12
+
13
+ // ssl as path to the file
14
+ keyPath : process . env . MONGO_SSL_KEY_PATH ,
15
+ certPath : process . env . MONGO_SSL_CERT_PATH ,
16
+ caPath : process . env . MONGO_SSL_CA_PATH ,
17
+
18
+ // ssl as base64
19
+ keyBase64 : process . env . MONGO_SSL_KEY_BASE64 ,
20
+ certBase64 : process . env . MONGO_SSL_CERT_BASE64 ,
21
+ caBase64 : process . env . MONGO_SSL_CA_BASE64 ,
22
+
23
+ ...( process . env . MONGO_OPTIONS ? JSON . parse ( process . env . MONGO_OPTIONS ) : undefined )
11
24
} )
12
25
13
- function getMongoDb ( { url, optsString, sslKeyPath, sslCertPath, sslCaPath } ) {
14
- const options = { useUnifiedTopology : true }
15
-
16
- if ( typeof optsString === 'string' ) {
17
- const { key, cert, ca } = JSON . parse ( optsString )
18
- options . sslKey = fs . readFileSync ( key )
19
- options . sslCert = fs . readFileSync ( cert )
20
- options . sslCA = fs . readFileSync ( ca )
21
- } else if ( sslKeyPath ) {
22
- options . sslKey = fs . readFileSync ( sslKeyPath )
23
- options . sslCert = fs . readFileSync ( sslCertPath )
24
- options . sslCA = fs . readFileSync ( sslCaPath )
25
- }
26
+ function getMongoDb ( url , options = { } ) {
27
+ options = { ...options }
28
+ options = processSslOptions ( options )
29
+
30
+ options . useUnifiedTopology ??= true
26
31
27
32
const mongoClient = new MongoClient ( url , options )
28
33
const mongo = mongoClient . db ( )
@@ -38,3 +43,68 @@ function getMongoDb ({ url, optsString, sslKeyPath, sslCertPath, sslCaPath }) {
38
43
}
39
44
}
40
45
}
46
+
47
+ function processSslOptions ( options = { } ) {
48
+ options = { ...options }
49
+ let initialized = false
50
+ if ( options . key || options . cert || options . ca ) {
51
+ if ( ! ( options . key && options . cert && options . ca ) ) {
52
+ throw Error ( '[teamplay/mongo] SSL: All 3 strings must be provided: key, cert, ca' )
53
+ }
54
+ if ( ! ( typeof options . key === 'string' && typeof options . cert === 'string' && typeof options . ca === 'string' ) ) {
55
+ throw Error ( '[teamplay/mongo] SSL: All 3 strings must be provided as strings' )
56
+ }
57
+ options = {
58
+ ...options ,
59
+ key : Buffer . from ( options . key ) ,
60
+ cert : Buffer . from ( options . cert ) ,
61
+ ca : Buffer . from ( options . ca )
62
+ }
63
+ initialized = true
64
+ }
65
+ if ( options . keyPath || options . certPath || options . caPath ) {
66
+ if ( initialized ) {
67
+ throw Error ( '[teamplay/mongo] SSL: Cannot mix paths and strings or base64' )
68
+ }
69
+ if ( ! ( options . keyPath && options . certPath && options . caPath ) ) {
70
+ throw Error ( '[teamplay/mongo] SSL: All 3 paths to files must be provided: keyPath, certPath, caPath' )
71
+ }
72
+ options = {
73
+ ...options ,
74
+ key : fs . readFileSync ( options . keyPath ) ,
75
+ cert : fs . readFileSync ( options . certPath ) ,
76
+ ca : fs . readFileSync ( options . caPath )
77
+ }
78
+ initialized = true
79
+ }
80
+ if ( options . keyBase64 || options . certBase64 || options . caBase64 ) {
81
+ if ( initialized ) {
82
+ throw Error ( '[teamplay/mongo] SSL: Cannot mix base64 and strings or paths' )
83
+ }
84
+ if ( ! ( options . keyBase64 && options . certBase64 && options . caBase64 ) ) {
85
+ throw Error ( '[teamplay/mongo] SSL: All 3 base64 strings must be provided: keyBase64, certBase64, caBase64' )
86
+ }
87
+ options = {
88
+ ...options ,
89
+ key : Buffer . from ( options . keyBase64 , 'base64' ) ,
90
+ cert : Buffer . from ( options . certBase64 , 'base64' ) ,
91
+ ca : Buffer . from ( options . caBase64 , 'base64' )
92
+ }
93
+ }
94
+ // enable tls mode if certificates are provided (unless explicitly disabled)
95
+ if ( options . key && options . cert && options . ca ) {
96
+ options . tls ??= true
97
+ }
98
+ // cleanup options object from the processed keys
99
+ delete options . keyPath
100
+ delete options . certPath
101
+ delete options . caPath
102
+ delete options . keyBase64
103
+ delete options . certBase64
104
+ delete options . caBase64
105
+ // delete the undefined values if they were not provided
106
+ if ( ! options . key ) delete options . key
107
+ if ( ! options . cert ) delete options . cert
108
+ if ( ! options . ca ) delete options . ca
109
+ return options
110
+ }
0 commit comments