2022-02-10 15:47:44 +01:00
import { decrypt , encrypt } from '$lib/crypto' ;
import cuid from 'cuid' ;
import { generatePassword } from '.' ;
2022-04-06 19:45:47 +02:00
import { prisma } from './common' ;
2022-02-10 15:47:44 +01:00
import { asyncExecShell , getEngine , removeContainer } from '$lib/common' ;
2022-04-06 19:45:47 +02:00
import type { Database , DatabaseSettings , DestinationDocker } from '@prisma/client' ;
2022-02-10 15:47:44 +01:00
2022-04-06 19:45:47 +02:00
export async function listDatabases ( teamId : string ) : Promise < Database [ ] > {
2022-04-06 15:55:17 +02:00
if ( teamId === '0' ) {
return await prisma . database . findMany ( { include : { teams : true } } ) ;
} else {
return await prisma . database . findMany ( {
where : { teams : { some : { id : teamId } } } ,
include : { teams : true }
} ) ;
}
2022-02-10 15:47:44 +01:00
}
2022-04-06 19:45:47 +02:00
export async function newDatabase ( {
name ,
teamId
} : {
name : string ;
teamId : string ;
} ) : Promise < Database > {
2022-02-10 15:47:44 +01:00
const dbUser = cuid ( ) ;
const dbUserPassword = encrypt ( generatePassword ( ) ) ;
const rootUser = cuid ( ) ;
const rootUserPassword = encrypt ( generatePassword ( ) ) ;
const defaultDatabase = cuid ( ) ;
return await prisma . database . create ( {
data : {
name ,
defaultDatabase ,
dbUser ,
dbUserPassword ,
rootUser ,
rootUserPassword ,
teams : { connect : { id : teamId } } ,
settings : { create : { isPublic : false } }
}
} ) ;
}
2022-04-06 19:45:47 +02:00
export async function getDatabase ( {
id ,
teamId
} : {
id : string ;
teamId : string ;
} ) : Promise < Database & { destinationDocker : DestinationDocker ; settings : DatabaseSettings } > {
2022-04-07 01:03:13 +02:00
let body ;
2022-04-06 15:55:17 +02:00
if ( teamId === '0' ) {
body = await prisma . database . findFirst ( {
where : { id } ,
include : { destinationDocker : true , settings : true }
} ) ;
} else {
body = await prisma . database . findFirst ( {
where : { id , teams : { some : { id : teamId } } } ,
include : { destinationDocker : true , settings : true }
} ) ;
}
2022-02-10 15:47:44 +01:00
if ( body . dbUserPassword ) body . dbUserPassword = decrypt ( body . dbUserPassword ) ;
if ( body . rootUserPassword ) body . rootUserPassword = decrypt ( body . rootUserPassword ) ;
2022-04-06 19:45:47 +02:00
return body ;
2022-02-10 15:47:44 +01:00
}
2022-04-06 19:45:47 +02:00
export async function removeDatabase ( { id } : { id : string } ) : Promise < void > {
2022-02-10 15:47:44 +01:00
await prisma . databaseSettings . deleteMany ( { where : { databaseId : id } } ) ;
await prisma . database . delete ( { where : { id } } ) ;
return ;
}
2022-04-06 19:45:47 +02:00
export async function configureDatabaseType ( {
id ,
type
} : {
id : string ;
type : string ;
} ) : Promise < Database > {
2022-02-10 15:47:44 +01:00
return await prisma . database . update ( {
where : { id } ,
data : { type }
} ) ;
}
export async function setDatabase ( {
id ,
version ,
isPublic ,
appendOnly
} : {
id : string ;
version? : string ;
isPublic? : boolean ;
appendOnly? : boolean ;
2022-04-06 19:45:47 +02:00
} ) : Promise < Database > {
2022-02-10 15:47:44 +01:00
return await prisma . database . update ( {
where : { id } ,
data : {
version ,
settings : { upsert : { update : { isPublic , appendOnly } , create : { isPublic , appendOnly } } }
}
} ) ;
}
export async function updateDatabase ( {
id ,
name ,
defaultDatabase ,
dbUser ,
dbUserPassword ,
rootUser ,
rootUserPassword ,
version
2022-04-06 19:45:47 +02:00
} : {
id : string ;
name : string ;
defaultDatabase : string ;
dbUser : string ;
dbUserPassword : string ;
rootUser : string ;
rootUserPassword : string ;
version : string ;
} ) : Promise < Database > {
2022-02-10 15:47:44 +01:00
const encryptedDbUserPassword = dbUserPassword && encrypt ( dbUserPassword ) ;
const encryptedRootUserPassword = rootUserPassword && encrypt ( rootUserPassword ) ;
return await prisma . database . update ( {
where : { id } ,
data : {
name ,
defaultDatabase ,
dbUser ,
dbUserPassword : encryptedDbUserPassword ,
rootUser ,
rootUserPassword : encryptedRootUserPassword ,
version
}
} ) ;
}
2022-04-06 19:45:47 +02:00
export async function stopDatabase (
database : Database & { destinationDocker : DestinationDocker }
) : Promise < boolean > {
2022-02-10 15:47:44 +01:00
let everStarted = false ;
const {
id ,
destinationDockerId ,
destinationDocker : { engine }
} = database ;
if ( destinationDockerId ) {
try {
const host = getEngine ( engine ) ;
const { stdout } = await asyncExecShell (
` DOCKER_HOST= ${ host } docker inspect --format '{{json .State}}' ${ id } `
) ;
if ( stdout ) {
everStarted = true ;
await removeContainer ( id , engine ) ;
}
} catch ( error ) {
//
}
}
return everStarted ;
}
2022-04-07 14:29:40 +02:00
2022-04-09 13:33:23 +02:00
export async function updatePasswordInDb ( database , user , newPassword , isRoot ) {
2022-04-07 14:29:40 +02:00
const {
id ,
type ,
rootUser ,
rootUserPassword ,
dbUser ,
dbUserPassword ,
defaultDatabase ,
destinationDockerId ,
destinationDocker : { engine }
} = database ;
if ( destinationDockerId ) {
const host = getEngine ( engine ) ;
if ( type === 'mysql' ) {
await asyncExecShell (
` DOCKER_HOST= ${ host } docker exec ${ id } mysql -u ${ rootUser } -p ${ rootUserPassword } -e \ "ALTER USER ' ${ user } '@'%' IDENTIFIED WITH caching_sha2_password BY ' ${ newPassword } '; \ " `
) ;
} else if ( type === 'postgresql' ) {
2022-04-09 13:33:23 +02:00
if ( isRoot ) {
await asyncExecShell (
` DOCKER_HOST= ${ host } docker exec ${ id } psql postgresql://postgres: ${ rootUserPassword } @ ${ id } :5432/ ${ defaultDatabase } -c "ALTER role postgres WITH PASSWORD ' ${ newPassword } '" `
) ;
} else {
await asyncExecShell (
` DOCKER_HOST= ${ host } docker exec ${ id } psql postgresql:// ${ dbUser } : ${ dbUserPassword } @ ${ id } :5432/ ${ defaultDatabase } -c "ALTER role ${ user } WITH PASSWORD ' ${ newPassword } '" `
) ;
}
2022-04-07 14:29:40 +02:00
} else if ( type === 'mongodb' ) {
await asyncExecShell (
` DOCKER_HOST= ${ host } docker exec ${ id } mongo 'mongodb:// ${ rootUser } : ${ rootUserPassword } @ ${ id } :27017/admin?readPreference=primary&ssl=false' --eval "db.changeUserPassword(' ${ user } ',' ${ newPassword } ')" `
) ;
} else if ( type === 'redis' ) {
await asyncExecShell (
` DOCKER_HOST= ${ host } docker exec ${ id } redis-cli -u redis:// ${ dbUserPassword } @ ${ id } :6379 --raw CONFIG SET requirepass ${ newPassword } `
) ;
}
}
}