import axios from 'axios' ; import { sign } from 'jsonwebtoken' ; import PortalRequest from '../queue/defs' ; import StoredPortal from '../../schemas/portal.schema' ; import IPortal from './defs' ; import { createRedisClient } from '../../config/redis.config' ; import { generateFlake } from '../../utils/generate.utils' ; import Mountpoint from '../mountpoint' ; const pub = createRedisClient ( ) ; export type PortalStatus = 'waiting' | 'requested' | 'in-queue' | 'creating' | 'starting' | 'open' | 'closed' | 'error' ; export default class Portal { public id : string ; public createdAt : number ; public recievedAt : number ; public serverId : string ; public status : PortalStatus ; public room : string ; public load = ( id ) => new Promise < Portal > ( async ( resolve , reject ) => { try { const doc = await StoredPortal . findOne ( { 'info.id' : id } ) ; if ( ! doc ) throw new Error ( 'PortalNotFound' ) ; this . setup ( doc ) ; resolve ( this ) ; } catch ( error ) { reject ( error ) ; } } ) ; public loadByRoomID = ( roomId ) => new Promise < Portal > ( async ( resolve , reject ) => { try { const doc = await StoredPortal . findOne ( { 'info.room' : roomId } ) ; if ( ! doc ) resolve ( null ) ; this . setup ( doc ) ; resolve ( this ) ; } catch ( error ) { reject ( error ) ; } } ) ; public create = ( request ) => new Promise < Portal > ( async ( resolve , reject ) => { try { const { roomId , receivedAt : recievedAt } = request ; const json = { info : { id : generateFlake ( ) , createdAt : Date . now ( ) , recievedAt , room : roomId , status : 'creating' } , data : { } } ; const stored = new StoredPortal ( json ) ; await stored . save ( ) ; this . setup ( json ) ; await axios . post ( `${ process . env . API_URL }/internal/portal` , { id : this . id , roomId } , { headers : { authorization : `Valve ${ sign ( { } , process . env . API_KEY ) }` } } ) ; resolve ( this ) ; } catch ( error ) { reject ( error ) ; } } ) ; public destroy = ( error ? ) => new Promise ( async ( resolve , reject ) => { try { await StoredPortal . deleteOne ( { 'info.id' : this . id } ) ; const { id } = this , message = { op : 0 , d : { id } , t : 'PORTAL_DESTROY' } ; pub . publish ( 'portals' , JSON . stringify ( message ) ) ; resolve ( ) ; } catch ( error ) { reject ( error ) ; } } ) ; public updateStatus = async ( status ) => new Promise < Portal > ( async ( resolve , reject ) => { try { await StoredPortal . updateOne ( { 'info.id' : this . id } , { $set : { 'info.status' : status } } ) ; let janusId , janusIp ; if ( status === 'open' && process . env . ENABLE_JANUS === 'true' ) { const mountpoint = await new Mountpoint ( ) . load ( 'Portal' , this . id ) ; janusId = mountpoint . janusId ; janusIp = mountpoint . janusIp ; } await axios . put ( `${ process . env . API_URL }/internal/portal` , { id : this . id , status , janusId , janusIp } , { headers : { authorization : `Valve ${ sign ( { } , process . env . API_KEY ) }` } } ) ; this . status = status ; resolve ( this ) ; } catch ( error ) { reject ( error ) ; } } ) ; public updateServerId = ( serverId ) => new Promise < Portal > ( async ( resolve , reject ) => { try { await StoredPortal . updateOne ( { 'info.id' : this . id } , { $set : { 'data.serverId' : serverId } } ) ; this . serverId = serverId ; resolve ( this ) ; } catch ( error ) { reject ( error ) ; } } ) ; public setup = ( json ) => { this . id = json . info . id ; this . createdAt = json . info . createdAt ; this . recievedAt = json . info . recievedAt ; this . room = json . info . room ; this . status = json . info . status ; if ( json . data ) if ( json . data . serverId ) this . serverId = json . data . serverId ; } ; }