'use strict' ; import { Config } from '@Base/config' ; import { Router , RequestHandler , Request , Response , NextFunction } from 'express' ; import { setupMetaverseAPI , finishMetaverseAPI } from '@Route-Tools/middleware' ; import { accountFromAuthToken } from '@Route-Tools/middleware' ; import { Accounts } from '@Entities/Accounts' ; import { PaginationInfo } from '@Entities/EntityFilters/PaginationInfo' ; import { AccountScopeFilter } from '@Entities/EntityFilters/AccountScopeFilter' ; import { AccountFilterInfo } from '@Entities/EntityFilters/AccountFilterInfo' ; import { buildUserInfo } from '@Route-Tools/Util' ; import { Logger } from '@Tools/Logging' ; import { IsNullOrEmpty , IsNotNullOrEmpty } from '@Tools/Misc' ; import { Roles } from '@Entities/Sets/Roles' ; import { SArray } from '@Tools/vTypes' ; const procGetUsers = async ( req , resp , next ) => { if ( req . vAuthAccount ) { const pager = new PaginationInfo ( ) ; const scoper = new AccountScopeFilter ( req . vAuthAccount ) ; const infoer = new AccountFilterInfo ( ) ; pager . parametersFromRequest ( req ) ; scoper . parametersFromRequest ( req ) ; infoer . parametersFromRequest ( req ) ; const accts = [ ] ; for await ( const acct of Accounts . enumerateAsync ( scoper , infoer , pager ) ) { const userInfo = await buildUserInfo ( acct ) ; if ( req . vAuthAccount . id === acct . id ) { userInfo . connection = "self" ; } ; accts . push ( userInfo ) ; } ; req . vRestResp . Data = { users : accts } ; pager . addResponseFields ( req ) ; infoer . addResponseFields ( req ) ; scoper . addResponseFields ( req ) ; } else { req . vRestResp . respondFailure ( req . vAccountError ?? 'Not logged in' ) ; } ; next ( ) ; } ; const procPostUsers = async ( req , resp , next ) => { if ( req . vRestResp ) { if ( req . body && req . body . user ) { const userName = req . body . user . username ; const userPassword = req . body . user . password ; const userEmail = req . body . user . email ; Logger . debug ( `procPostUsers: request to create account for ${ userName } with email ${ userEmail }` ) ; let ifValid = await Accounts . validateFieldValue ( 'username' , userName ) ; if ( ifValid . valid ) { ifValid = await Accounts . validateFieldValue ( 'email' , userEmail ) ; if ( ifValid . valid ) { let prevAccount = await Accounts . getAccountWithUsername ( userName ) ; if ( IsNullOrEmpty ( prevAccount ) ) { prevAccount = await Accounts . getAccountWithEmail ( userEmail ) ; if ( IsNullOrEmpty ( prevAccount ) ) { const newAcct = await Accounts . createAccount ( userName , userPassword , userEmail ) ; if ( newAcct ) { try { const adminAccountName = Config [ "metaverse-server" ] [ "base-admin-account" ] ; if ( IsNotNullOrEmpty ( adminAccountName ) ) { if ( newAcct . username === adminAccountName ) { if ( IsNullOrEmpty ( newAcct . roles ) ) newAcct . roles = [ ] ; SArray . add ( newAcct . roles , Roles . ADMIN ) ; Logger . info ( `procPostUsers: setting new account ${ adminAccountName } as admin` ) ; } } newAcct . IPAddrOfCreator = req . vSenderKey ; const accountIsActive = Accounts . enableAccount ( newAcct ) ; await Accounts . addAccount ( newAcct ) ; req . vRestResp . Data = { accountId : newAcct . id , username : newAcct . username , accountIsActive , accountWaitingVerification : ! accountIsActive } ; } catch ( err ) { Logger . error ( 'procPostUsers: exception adding user: ' + err ) ; req . vRestResp . respondFailure ( 'Exception adding user: ' + err ) ; } } else { Logger . debug ( 'procPostUsers: error creating account for ' + userName ) ; req . vRestResp . respondFailure ( 'could not create account' ) ; } ; } else { req . vRestResp . respondFailure ( 'Email already exists' ) ; } ; } else { req . vRestResp . respondFailure ( 'Account already exists' ) ; } ; } else { req . vRestResp . respondFailure ( ifValid . reason ?? 'Badly formatted email' ) ; } ; } else { req . vRestResp . respondFailure ( ifValid . reason ?? 'Badly formatted username' ) ; } ; } else { req . vRestResp . respondFailure ( 'Badly formatted request' ) ; } ; } ; next ( ) ; } ; export const name = '/api/v1/users' ; export const router = Router ( ) ; router . get ( '/api/v1/users' , [ setupMetaverseAPI , accountFromAuthToken , procGetUsers , finishMetaverseAPI ] ) ; router . post ( '/api/v1/users' , [ setupMetaverseAPI , procPostUsers , finishMetaverseAPI ] ) ;