'use strict' ; import { Config } from '@Base/config' ; import { Router , RequestHandler , Request , Response , NextFunction } from 'express' ; import { Accounts } from '@Entities/Accounts' ; import { AccountEntity } from '@Entities/AccountEntity' ; import { Domains } from '@Entities/Domains' ; import { Tokens , TokenScope } from '@Entities/Tokens' ; import { AuthToken } from '@Entities/AuthToken' ; import { Sessions } from '@Entities/Sessions' ; import { Places } from '@Entities/Places' ; import { RESTResponse } from '@Route-Tools/RESTResponse' ; import { GenericFilter } from '@Entities/EntityFilters/GenericFilter' ; import { IsNullOrEmpty , IsNotNullOrEmpty } from '@Tools/Misc' ; import { SArray , VKeyedCollection } from '@Tools/vTypes' ; import { Logger } from '@Tools/Logging' ; export const setupMetaverseAPI = async ( req , resp , next ) => { req . vRestResp = new RESTResponse ( req , resp ) ; if ( req . socket ) { req . vSenderKey = `${ req . socket . remoteAddress }:${ req . socket . remotePort }` ; req . vSession = Sessions . getSessionWithSenderKey ( req . vSenderKey ) ; if ( req . vSession ) { Sessions . touchSession ( req . vSession ) ; } else { req . vSession = Sessions . createSession ( req . vSenderKey ) ; Sessions . addSession ( req . vSession ) ; Logger . debug ( 'setupMetaverseAPI: created new session for ' + req . vSenderKey ) ; } ; let authToken = req . vRestResp . getAuthToken ( ) ; if ( IsNullOrEmpty ( authToken ) ) { if ( req . query && req . query . access_token && typeof ( req . query . access_token ) === 'string' ) { authToken = ( req . query . access_token as string ) ; } ; } ; if ( IsNotNullOrEmpty ( authToken ) ) { try { req . vAuthToken = await Tokens . getTokenWithToken ( authToken ) ; } catch ( err ) { Logger . error ( `setupMetaverseAPI: exception in token lookup: ${ err }` ) ; } ; } ; } ; next ( ) ; } ; export const finishMetaverseAPI = async ( req , resp , next ) => { if ( req . vRestResp ) { resp . statusCode = req . vRestResp . HTTPStatus ; const response = req . vRestResp . buildRESTResponse ( ) ; if ( response ) { Logger . cdebug ( 'metaverseapi-response-detail' , 'finishMetaverseAPI: response: ' + JSON . stringify ( response ) ) ; resp . json ( response ) ; } else { resp . end ( ) ; } ; } ; } ; export const finishReturnData = async ( req , resp , next ) => { if ( req . vRestResp ) { resp . statusCode = req . vRestResp . HTTPStatus ; const response = req . vRestResp . buildRESTResponse ( ) ; if ( response && response . data ) { Logger . cdebug ( 'metaverseapi-response-detail' , 'finishMetaverseAPI: response: ' + JSON . stringify ( response . data ) ) ; resp . json ( response . data ) ; } else { resp . end ( ) ; } ; } ; } ; export const accountFromAuthToken = async ( req , resp , next ) => { if ( req . vRestResp ) { if ( IsNotNullOrEmpty ( req . vAuthToken ) ) { req . vAuthAccount = await Accounts . getAccountWithId ( req . vAuthToken . accountId ) ; if ( IsNullOrEmpty ( req . vAuthAccount ) ) { req . vAccountError = 'Not logged in' ; Logger . debug ( 'accountFromAuthToken: account lookup fail: authToken=' + req . vRestResp . getAuthToken ( ) ) ; } ; } ; } ; next ( ) ; } ; export const accountFromParams = async ( req , resp , next ) => { if ( req . vRestResp ) { if ( req . params && req . params . accountId && typeof ( req . params . accountId ) === 'string' ) { const accountId = decodeURIComponent ( req . params . accountId ) ; req . vAccount = await Accounts . getAccountWithUsername ( accountId ) ; if ( IsNullOrEmpty ( req . vAccount ) ) { req . vAccount = await Accounts . getAccountWithId ( accountId ) ; } ; } ; } ; if ( IsNullOrEmpty ( req . vAccount ) ) { req . vAccountError = 'AccountId does not match an account' ; } ; next ( ) ; } ; export const verifyDomainAccess = async ( req , resp , next ) => { if ( req . vRestResp && req . vDomain ) { let verified = false ; const authToken = req . vRestResp . getAuthToken ( ) ; if ( IsNullOrEmpty ( authToken ) ) { if ( req . vDomain . apiKey === req . vDomainAPIKey ) { req . vAuthToken = await Tokens . createToken ( req . vDomainAPIKey , [ TokenScope . DOMAIN ] , 1 ) ; verified = true ; } ; } else { const aToken = await Tokens . getTokenWithToken ( authToken ) ; if ( aToken && aToken . accountId ) { if ( SArray . has ( aToken . scope , TokenScope . DOMAIN ) ) { if ( IsNullOrEmpty ( req . vDomain . sponsorAccountId ) ) { const aAccount = await Accounts . getAccountWithId ( aToken . accountId ) ; if ( aAccount ) { Logger . debug ( `verifyDomainAccess: assigning domain ${ req . vDomain . id } to account ${ aAccount . id }` ) ; req . vDomain . sponsorAccountId = aAccount . id ; await Domains . updateEntityFields ( req . vDomain , { 'sponsorAccountId' : aAccount . id } ) ; } ; } ; if ( req . vDomain . sponsorAccountId === aToken . accountId ) { verified = true ; } ; } else { Logger . debug ( `verifyDomainAccess: not DOMAIN token: ${ authToken }` ) ; } ; } ; } ; if ( ! verified ) { req . vDomain = undefined ; req . vDomainError = 'Domain not authorized' ; } ; } ; next ( ) ; } ; export const usernameFromParams = async ( req , resp , next ) => { if ( req . params && req . params . username ) { if ( typeof ( req . params . username ) === 'string' ) { req . vUsername = decodeURIComponent ( req . params . username ) ; } ; } ; next ( ) ; } ; export const domainFromParams = async ( req , resp , next ) => { let domainId ; if ( req . params && req . params . domainId ) { if ( typeof ( req . params . domainId ) === 'string' ) { domainId = req . params . domainId ; req . vDomain = await Domains . getDomainWithId ( domainId ) ; } ; } ; if ( IsNullOrEmpty ( req . vDomain ) ) { req . vDomainError = 'DomainId does not match a domain' ; Logger . error ( `domainFromParams: wanted domain ${ domainId } but not found` ) ; } ; next ( ) ; } ; export const placeFromParams = async ( req , resp , next ) => { if ( req . params && req . params . placeId ) { if ( typeof ( req . params . placeId ) === 'string' ) { let aPlace = await Places . getPlaceWithId ( req . params . placeId ) ; if ( IsNullOrEmpty ( aPlace ) ) { aPlace = await Places . getPlaceWithName ( decodeURIComponent ( req . params . placeId ) ) ; } ; if ( IsNotNullOrEmpty ( aPlace ) ) { req . vPlace = aPlace ; } ; } ; } ; next ( ) ; } ; export const domainAPIkeyFromBody = async ( req , resp , next ) => { if ( req . body && req . body . domain && req . body . domain . api_key ) { if ( typeof ( req . body . domain . api_key ) === 'string' ) { req . vDomainAPIKey = req . body . domain . api_key ; } ; } ; next ( ) ; } ; export const domainAPIkeyFromMultipart = async ( req , resp , next ) => { if ( req . body && req . body . api_key ) { if ( typeof ( req . body . api_key ) === 'string' ) { req . vDomainAPIKey = req . body . api_key ; } ; } ; next ( ) ; } ; export const tokenFromParams = async ( req , resp , next ) => { if ( req . params && req . params . tokenId ) { if ( typeof ( req . params . tokenId ) === 'string' ) { req . vTokenId = req . params . tokenId ; } ; } ; next ( ) ; } ; export const param1FromParams = async ( req , resp , next ) => { if ( req . params && req . params . param1 ) { if ( typeof ( req . params . param1 ) === 'string' ) { req . vParam1 = decodeURIComponent ( req . params . param1 ) ; } ; } ; next ( ) ; } ; export const param2FromParams = async ( req , resp , next ) => { if ( req . params && req . params . param2 ) { if ( typeof ( req . params . param2 ) === 'string' ) { req . vParam2 = decodeURIComponent ( req . params . param2 ) ; } ; } ; next ( ) ; } ; export const param3FromParams = async ( req , resp , next ) => { if ( req . params && req . params . param3 ) { if ( typeof ( req . params . param3 ) === 'string' ) { req . vParam3 = decodeURIComponent ( req . params . param3 ) ; } ; } ; next ( ) ; } ;