2017-10-29 07:55:55 +08:00
"use strict" ;
2017-11-03 08:48:02 +08:00
const options = require ( '../../services/options' ) ;
2017-10-29 10:17:00 +08:00
const utils = require ( '../../services/utils' ) ;
2018-04-03 08:46:46 +08:00
const dateUtils = require ( '../../services/date_utils' ) ;
2018-04-02 09:27:46 +08:00
const sourceIdService = require ( '../../services/source_id' ) ;
const passwordEncryptionService = require ( '../../services/password_encryption' ) ;
const protectedSessionService = require ( '../../services/protected_session' ) ;
const appInfo = require ( '../../services/app_info' ) ;
2018-04-20 12:12:01 +08:00
const eventService = require ( '../../services/events' ) ;
const cls = require ( '../../services/cls' ) ;
2018-07-25 02:35:03 +08:00
const sqlInit = require ( '../../services/sql_init' ) ;
2019-01-05 01:58:46 +08:00
const sql = require ( '../../services/sql' ) ;
2017-10-29 07:55:55 +08:00
2018-03-31 07:31:22 +08:00
async function loginSync ( req ) {
2018-07-25 02:35:03 +08:00
if ( ! await sqlInit . schemaExists ( ) ) {
return [ 400 , { message : "DB schema does not exist, can't sync." } ] ;
}
2017-12-11 04:45:17 +08:00
const timestampStr = req . body . timestamp ;
2017-10-29 07:55:55 +08:00
2018-04-03 08:46:46 +08:00
const timestamp = dateUtils . parseDateTime ( timestampStr ) ;
2017-12-11 04:45:17 +08:00
const now = new Date ( ) ;
2019-01-08 06:29:56 +08:00
// login token is valid for 5 minutes
if ( Math . abs ( timestamp . getTime ( ) - now . getTime ( ) ) > 5 * 60 * 1000 ) {
2018-03-31 07:31:22 +08:00
return [ 400 , { message : 'Auth request time is out of sync' } ] ;
2017-10-29 10:17:00 +08:00
}
2018-06-11 03:55:29 +08:00
const syncVersion = req . body . syncVersion ;
2017-10-29 10:17:00 +08:00
2018-06-11 03:55:29 +08:00
if ( syncVersion !== appInfo . syncVersion ) {
2019-02-15 07:15:09 +08:00
return [ 400 , { message : ` Non-matching sync versions, local is version ${ appInfo . syncVersion } , remote is ${ syncVersion } . It is recommended to run same version of Trilium on both sides of sync. ` } ] ;
2017-10-29 10:17:00 +08:00
}
2018-04-03 09:47:46 +08:00
const documentSecret = await options . getOption ( 'documentSecret' ) ;
2017-12-11 04:45:17 +08:00
const expectedHash = utils . hmac ( documentSecret , timestampStr ) ;
2017-10-29 10:17:00 +08:00
const givenHash = req . body . hash ;
if ( expectedHash !== givenHash ) {
2018-09-11 02:05:10 +08:00
return [ 400 , { message : "Sync login credentials are incorrect." } ] ;
2017-10-29 10:17:00 +08:00
}
req . session . loggedIn = true ;
2018-03-31 07:31:22 +08:00
return {
2019-01-05 01:58:46 +08:00
sourceId : sourceIdService . getCurrentSourceId ( ) ,
maxSyncId : await sql . getValue ( "SELECT MAX(id) FROM sync" )
2018-03-31 07:31:22 +08:00
} ;
}
2017-10-29 07:55:55 +08:00
2018-03-31 07:31:22 +08:00
async function loginToProtectedSession ( req ) {
2017-11-10 12:25:23 +08:00
const password = req . body . password ;
2018-04-02 09:27:46 +08:00
if ( ! await passwordEncryptionService . verifyPassword ( password ) ) {
2018-03-31 07:31:22 +08:00
return {
2017-11-10 12:25:23 +08:00
success : false ,
message : "Given current password doesn't match hash"
2018-03-31 07:31:22 +08:00
} ;
2017-11-10 12:25:23 +08:00
}
2018-04-02 09:27:46 +08:00
const decryptedDataKey = await passwordEncryptionService . getDataKey ( password ) ;
2017-11-10 12:25:23 +08:00
2018-04-20 12:12:01 +08:00
const protectedSessionId = protectedSessionService . setDataKey ( decryptedDataKey ) ;
2018-04-22 00:23:35 +08:00
// this is set here so that event handlers have access to the protected session
2018-04-20 12:12:01 +08:00
cls . namespace . set ( 'protectedSessionId' , protectedSessionId ) ;
2018-08-13 02:07:02 +08:00
await eventService . emit ( eventService . ENTER _PROTECTED _SESSION ) ;
2017-11-10 12:25:23 +08:00
2018-03-31 07:31:22 +08:00
return {
2017-11-10 12:25:23 +08:00
success : true ,
protectedSessionId : protectedSessionId
2018-03-31 07:31:22 +08:00
} ;
}
2017-11-10 12:25:23 +08:00
2018-03-31 07:31:22 +08:00
module . exports = {
loginSync ,
loginToProtectedSession
} ;