@@ -11,13 +11,15 @@ const internalDeadHost = require('./internal/dead-host');
11
11
const internalNginx = require ( './internal/nginx' ) ;
12
12
const internalAccessList = require ( './internal/access-list' ) ;
13
13
const internalStream = require ( './internal/stream' ) ;
14
+ const internalCertificate = require ( './internal/certificate' ) ;
14
15
15
16
const accessListModel = require ( './models/access_list' ) ;
16
17
const accessListAuthModel = require ( './models/access_list_auth' ) ;
17
18
const proxyHostModel = require ( './models/proxy_host' ) ;
18
19
const redirectionHostModel = require ( './models/redirection_host' ) ;
19
20
const deadHostModel = require ( './models/dead_host' ) ;
20
21
const streamModel = require ( './models/stream' ) ;
22
+ const certificateModel = require ( './models/certificate' ) ;
21
23
22
24
module . exports = function ( ) {
23
25
@@ -126,9 +128,156 @@ module.exports = function () {
126
128
// - /etc/letsencrypt/renewal Modify filenames and file content
127
129
128
130
return new Promise ( ( resolve , reject ) => {
129
- // TODO
130
- resolve ( ) ;
131
- } ) ;
131
+ // 1. List all folders in `archive`
132
+ // 2. Create certificates from those folders, rename them, add to map
133
+ // 3.
134
+
135
+ try {
136
+ resolve ( fs . readdirSync ( '/etc/letsencrypt/archive' ) ) ;
137
+ } catch ( err ) {
138
+ reject ( err ) ;
139
+ }
140
+ } )
141
+ . then ( archive_dirs => {
142
+ return new Promise ( ( resolve , reject ) => {
143
+ batchflow ( archive_dirs ) . sequential ( )
144
+ . each ( ( i , archive_dir_name , next ) => {
145
+ importCertificate ( access , archive_dir_name )
146
+ . then ( ( ) => {
147
+ next ( ) ;
148
+ } )
149
+ . catch ( err => {
150
+ next ( err ) ;
151
+ } ) ;
152
+ } )
153
+ . end ( results => {
154
+ resolve ( results ) ;
155
+ } ) ;
156
+ } ) ;
157
+
158
+ } ) ;
159
+ } ;
160
+
161
+ /**
162
+ * @param {Access } access
163
+ * @param {String } archive_dir_name
164
+ * @returns {Promise }
165
+ */
166
+ const importCertificate = function ( access , archive_dir_name ) {
167
+ logger . info ( 'Importing Certificate: ' + archive_dir_name ) ;
168
+
169
+ let full_archive_path = '/etc/letsencrypt/archive/' + archive_dir_name ;
170
+ let full_live_path = '/etc/letsencrypt/live/' + archive_dir_name ;
171
+
172
+ let new_archive_path = '/etc/letsencrypt/archive/' ;
173
+ let new_live_path = '/etc/letsencrypt/live/' ;
174
+
175
+ // 1. Create certificate row to get the ID
176
+ return certificateModel
177
+ . query ( )
178
+ . insertAndFetch ( {
179
+ owner_user_id : 1 ,
180
+ provider : 'letsencrypt' ,
181
+ nice_name : archive_dir_name ,
182
+ domain_names : [ archive_dir_name ]
183
+ } )
184
+ . then ( certificate => {
185
+ certificate_map [ archive_dir_name ] = certificate . id ;
186
+
187
+ // 2. rename archive folder name
188
+ new_archive_path = new_archive_path + 'npm-' + certificate . id ;
189
+ //logger.debug('Renaming archive folder:', full_archive_path, '->', new_archive_path);
190
+
191
+ fs . renameSync ( full_archive_path , new_archive_path ) ;
192
+
193
+ return certificate ;
194
+ } )
195
+ . then ( certificate => {
196
+ // 3. rename live folder name
197
+ new_live_path = new_live_path + 'npm-' + certificate . id ;
198
+
199
+ //logger.debug('Renaming live folder:', full_live_path, '->', new_live_path);
200
+
201
+ fs . renameSync ( full_live_path , new_live_path ) ;
202
+
203
+ // and also update the symlinks in this folder:
204
+ process . chdir ( new_live_path ) ;
205
+ let version = getCertificateVersion ( new_archive_path ) ;
206
+ let names = [
207
+ [ 'cert.pem' , 'cert' + version + '.pem' ] ,
208
+ [ 'chain.pem' , 'chain' + version + '.pem' ] ,
209
+ [ 'fullchain.pem' , 'fullchain' + version + '.pem' ] ,
210
+ [ 'privkey.pem' , 'privkey' + version + '.pem' ]
211
+ ] ;
212
+
213
+ names . map ( function ( name ) {
214
+ //logger.debug('Live Link:', name);
215
+
216
+ // remove symlink
217
+ try {
218
+ fs . unlinkSync ( new_live_path + '/' + name [ 0 ] ) ;
219
+ } catch ( err ) {
220
+ // do nothing
221
+ logger . error ( err ) ;
222
+ }
223
+
224
+ //logger.debug('Creating Link:', '../../archive/npm-' + certificate.id + '/' + name[1]);
225
+ // create new symlink
226
+ fs . symlinkSync ( '../../archive/npm-' + certificate . id + '/' + name [ 1 ] , name [ 0 ] ) ;
227
+ } ) ;
228
+
229
+ return certificate ;
230
+ } )
231
+ . then ( certificate => {
232
+ // 4. rename and update renewal config file
233
+ let config_file = '/etc/letsencrypt/renewal/' + archive_dir_name + '.conf' ;
234
+
235
+ return utils . exec ( 'sed -i \'s/\\/config/\\/data/g\' ' + config_file )
236
+ . then ( ( ) => {
237
+ let escaped = archive_dir_name . split ( '.' ) . join ( '\\.' ) ;
238
+ return utils . exec ( 'sed -i \'s/\\/' + escaped + '/\\/npm-' + certificate . id + '/g\' ' + config_file ) ;
239
+ } )
240
+ . then ( ( ) => {
241
+ //rename config file
242
+ fs . renameSync ( config_file , '/etc/letsencrypt/renewal/npm-' + certificate . id + '.conf' ) ;
243
+ return certificate ;
244
+ } ) ;
245
+ } )
246
+ . then ( certificate => {
247
+ // 5. read the cert info back in to the db
248
+ return internalCertificate . getCertificateInfoFromFile ( new_live_path + '/fullchain.pem' )
249
+ . then ( cert_info => {
250
+ return certificateModel
251
+ . query ( )
252
+ . patchAndFetchById ( certificate . id , {
253
+ expires_on : certificateModel . raw ( 'FROM_UNIXTIME(' + cert_info . dates . to + ')' )
254
+ } ) ;
255
+ } ) ;
256
+ } ) ;
257
+ } ;
258
+
259
+ /**
260
+ * @param {String } archive_path
261
+ * @returns {Integer }
262
+ */
263
+ const getCertificateVersion = function ( archive_path ) {
264
+ let version = 1 ;
265
+
266
+ try {
267
+ let files = fs . readdirSync ( archive_path ) ;
268
+
269
+ files . map ( function ( file ) {
270
+ let res = file . match ( / f u l l c h a i n ( [ 0 - 9 ] ) + ?\. p e m / im) ;
271
+ if ( res && parseInt ( res [ 1 ] , 10 ) > version ) {
272
+ version = parseInt ( res [ 1 ] , 10 ) ;
273
+ }
274
+ } ) ;
275
+
276
+ } catch ( err ) {
277
+ // do nothing
278
+ }
279
+
280
+ return version ;
132
281
} ;
133
282
134
283
/**
@@ -388,7 +537,11 @@ module.exports = function () {
388
537
} )
389
538
. then ( ( ) => {
390
539
// Write the /config/v2-imported file so we don't import again
391
- // TODO
540
+ fs . writeFile ( '/config/v2-imported' , 'true' , function ( err ) {
541
+ if ( err ) {
542
+ logger . err ( err ) ;
543
+ }
544
+ } ) ;
392
545
} ) ;
393
546
} )
394
547
) ;
0 commit comments