import { IUser , IUsersStorage , IUserWithGroups , IUserWithRoles , UserType , } from "@staticdeploy/core" ; import { Knex } from "knex" ; import { flatMap , omit , isEmpty } from "lodash" ; import convertErrors from "./common/convertErrors" ; import tables from "./common/tables" ; @ convertErrors export default class UsersStorage implements IUsersStorage { private static omitGroupsIds < T > ( objectWithGroupsIds ) { return omit ( objectWithGroupsIds , "groupsIds" ) ; } constructor ( private knex ) { } async findOne ( id ) { const [ user = null ] = await this . knex ( tables . users ) . where ( { id } ) ; return user ; } async findOneWithGroups ( id ) { const [ user ] = await this . knex ( tables . users ) . where ( { id } ) ; if ( ! user ) { return null ; } const groups = await this . knex ( tables . usersAndGroups ) . where ( { userId : id } ) . leftOuterJoin ( tables . groups , `${ tables . usersAndGroups }.groupId` , `${ tables . groups }.id` ) . select ( [ "id" , "name" , "roles" , "createdAt" , "updatedAt" ] ) ; return { ... user , groups } ; } async findOneWithRolesByIdpAndIdpId ( idp , idpId ) { const [ user ] = await this . knex ( tables . users ) . where ( { idp , idpId , } ) ; if ( ! user ) { return null ; } const groupsRoles = await this . knex ( tables . usersAndGroups ) . where ( { userId : user . id } ) . leftOuterJoin ( tables . groups , `${ tables . usersAndGroups }.groupId` , `${ tables . groups }.id` ) . select ( [ "roles" ] ) ; return { ... user , roles : flatMap ( groupsRoles , "roles" ) } ; } async findMany ( ) { const users = await this . knex ( tables . users ) ; return users ; } async oneExistsWithIdpAndIdpId ( idp , idpId ) { const [ user = null ] = await this . knex ( tables . users ) . select ( "id" ) . where ( { idp , idpId } ) ; return user !== null ; } async anyExistsWithGroup ( groupId ) { const [ userAndGroup = null ] = await this . knex ( tables . usersAndGroups ) . where ( { groupId } ) . limit ( 1 ) ; return userAndGroup !== null ; } async createOne ( toBeCreatedUser ) { const [ createdUser ] = await this . knex ( tables . users ) . insert ( UsersStorage . omitGroupsIds ( toBeCreatedUser ) ) . returning ( "*" ) ; if ( ! isEmpty ( toBeCreatedUser . groupsIds ) ) { await this . knex ( tables . usersAndGroups ) . insert ( toBeCreatedUser . groupsIds . map ( ( groupId ) => ( { userId : toBeCreatedUser . id , groupId : groupId , } ) ) ) ; } return createdUser ; } async updateOne ( id , patch ) { const [ updatedUser ] = await this . knex ( tables . users ) . where ( { id } ) . update ( UsersStorage . omitGroupsIds ( patch ) ) . returning ( "*" ) ; if ( patch . groupsIds ) { if ( ! isEmpty ( patch . groupsIds ) ) { await this . knex ( tables . usersAndGroups ) . insert ( patch . groupsIds . map ( ( groupId ) => ( { userId : id , groupId : groupId , } ) ) ) ; } await this . knex ( tables . usersAndGroups ) . where ( { userId : id } ) . whereNotIn ( "groupId" , patch . groupsIds ) . delete ( ) ; } return updatedUser ; } async deleteOne ( id ) { await this . knex ( tables . users ) . where ( { id } ) . delete ( ) ; } }