2019-03-13 21:35:19 +01:00
const _ = require ( 'lodash' ) ;
const Promise = require ( 'bluebird' ) ;
2020-05-28 20:30:23 +02:00
const logging = require ( '../../../../../shared/logging' ) ;
2019-03-13 21:35:19 +01:00
const settingsCache = require ( '../../../../services/settings/cache' ) ;
2020-05-27 19:47:53 +02:00
const config = require ( '../../../../../shared/config' ) ;
2019-03-13 21:35:19 +01:00
const moment = require ( 'moment' ) ;
const fs = require ( 'fs-extra' ) ;
const path = require ( 'path' ) ;
module . exports . config = {
transaction : true
} ;
const backupFileRegex = /ghost.([\d]{4}-[\d]{2}-[\d]{2}).json$/ ;
2019-03-13 23:40:50 +01:00
// @NOTE: spagetthi
2019-03-13 21:35:19 +01:00
module . exports . up = ( options ) => {
const contentPath = config . get ( 'paths' ) . contentPath ;
const dataPath = path . join ( contentPath , 'data' ) ;
const localOptions = _ . merge ( {
context : { internal : true }
} , options ) ;
return fs . readdir ( dataPath ) . then ( function ( files ) {
2019-03-13 22:03:54 +01:00
return files ;
} ) . catch ( function ( ) {
2020-05-25 10:48:50 +02:00
logging . warn ( ` Error reading ${ dataPath } whilst trying to ensure boolean settings are correct. Please double check your settings after this upgrade ` ) ;
2019-03-13 22:03:54 +01:00
return [ ] ;
} ) . then ( function ( files ) {
2019-03-13 21:35:19 +01:00
const backups = files . filter ( function ( filename ) {
return backupFileRegex . test ( filename ) ;
} ) . sort ( function ( a , b ) {
const dateA = new Date ( a . match ( backupFileRegex ) [ 1 ] ) ;
const dateB = new Date ( b . match ( backupFileRegex ) [ 1 ] ) ;
return dateB - dateA ;
} ) ;
if ( backups . length === 0 ) {
2020-05-25 10:48:50 +02:00
logging . warn ( 'No backup files found, skipping...' ) ;
2019-03-13 21:35:19 +01:00
return ;
}
const mostRecentBackup = backups [ 0 ] ;
2020-05-25 10:48:50 +02:00
logging . info ( ` Using backupfile ${ path . join ( dataPath , mostRecentBackup ) } ` ) ;
2019-03-13 21:35:19 +01:00
2019-03-13 22:03:54 +01:00
let backup ;
try {
backup = require ( path . join ( dataPath , mostRecentBackup ) ) ;
} catch ( e ) {
2020-05-25 10:48:50 +02:00
logging . warn ( ` Could not read ${ path . join ( dataPath , mostRecentBackup ) } whilst trying to ensure boolean settings are correct. Please double check your settings after this upgrade ` ) ;
2019-03-13 22:03:54 +01:00
return ;
}
2019-03-13 21:35:19 +01:00
const settings = backup && backup . data && backup . data . settings ;
if ( ! settings ) {
2020-05-25 10:48:50 +02:00
logging . warn ( 'Could not read settings from backup file, skipping...' ) ;
2019-03-13 21:35:19 +01:00
return ;
}
return localOptions
2019-03-13 23:40:50 +01:00
. transacting ( 'migrations' )
2019-03-13 21:35:19 +01:00
. then ( ( response ) => {
if ( ! response ) {
2020-05-25 10:48:50 +02:00
logging . warn ( 'Cannot find migrations.' ) ;
2019-03-13 21:35:19 +01:00
return ;
}
2019-03-13 23:40:50 +01:00
// NOTE: You are only affected if you migrated to 2.17
// 2.18 fixed the 2.17 migration (!)
const isAffected = _ . find ( response , { currentVersion : '2.17' , version : '2.17' } ) ;
if ( ! isAffected ) {
2020-05-25 10:48:50 +02:00
logging . warn ( 'Skipping migration. Not affected.' ) ;
2019-03-13 23:40:50 +01:00
return ;
}
2020-05-25 10:48:50 +02:00
logging . warn ( '...is affected.' ) ;
2019-03-13 23:40:50 +01:00
const relevantBackupSettings = settings . filter ( function ( entry ) {
2019-03-13 21:35:19 +01:00
return [ 'is_private' , 'force_i18n' , 'amp' ] . includes ( entry . key ) ;
2019-03-13 23:40:50 +01:00
} ) . reduce ( function ( obj , entry ) {
return Object . assign ( obj , {
[ entry . key ] : entry
} ) ;
} , { } ) ;
return localOptions
. transacting ( 'settings' )
. then ( ( response ) => {
if ( ! response ) {
2020-05-25 10:48:50 +02:00
logging . warn ( 'Cannot find settings.' ) ;
2019-03-13 23:40:50 +01:00
return ;
}
const relevantLiveSettings = response . filter ( function ( entry ) {
return [ 'is_private' , 'force_i18n' , 'amp' ] . includes ( entry . key ) ;
} ) ;
return Promise . each ( relevantLiveSettings , ( liveSetting ) => {
const backupSetting = relevantBackupSettings [ liveSetting . key ] ;
if ( liveSetting . value === 'false' && backupSetting . value === 'true' ) {
2020-05-25 10:48:50 +02:00
logging . info ( ` Reverting setting ${ liveSetting . key } ` ) ;
2019-03-13 23:40:50 +01:00
return localOptions
. transacting ( 'settings' )
. where ( 'key' , liveSetting . key )
. update ( {
value : backupSetting . value
} )
. then ( ( ) => {
// CASE: we have to update settings cache, because Ghost is able to run migrations on the same process
settingsCache . set ( liveSetting . key , {
id : liveSetting . id ,
key : liveSetting . key ,
type : liveSetting . type ,
created _at : moment ( liveSetting . created _at ) . startOf ( 'seconds' ) . toDate ( ) ,
updated _at : moment ( ) . startOf ( 'seconds' ) . toDate ( ) ,
updated _by : liveSetting . updated _by ,
created _by : liveSetting . created _by ,
value : backupSetting . value === 'true'
} ) ;
} ) ;
}
return Promise . resolve ( ) ;
} ) ;
} ) ;
2019-03-13 21:35:19 +01:00
} ) ;
} ) ;
} ;