Source: api/meeting.js

import {Config} from "../config.js"
import {getUserToken} from "./auth.js"
import {logger} from "../utils/logger/index.js"
import {InvalidArgumentError, NotFoundError, PermissionDeniedError} from "../types/exceptions.js"
import {http} from "../utils/http/index.js"
import {UserClaims, MeetingClaims, MeetingTypes} from "../types/types.js"

/**
 *
 * @module meeting
 *
 */

/**
 *
 * @async
 * @param {Object} param0
 * @param {string} [param0.title=""] - meeting title.
 * @param {boolean} [param0.isTemporary=false]  - meeting won't be saved in dashboard.
 * @param {Number} [param0.capacity=2] - 1 or 2 , number of allowed stream to the meeting.
 * @param {Number} [param0.meetingType=0] - 0 DEFAULT or 1 WHITEBOARD
 * @returns {string} - ID of created meeting
 */
export async function createMeeting({title, isTemporary, capacity, meetingType}) {
	let headers = {
		"Content-Type": "application/json",
		Accept: "application/json",
		"x-jibb-user-jwt": await getUserToken(),
	}
	let body = {
		title: title || "",
		isTemporary: isTemporary || false,
		capacity: capacity || 2,
		meetingType: meetingType || MeetingTypes.DEFAULT,
	}
	let response = await http.post(`${Config.apiBaseURL}/v1/meetings`, body, headers)
	return response.data.meetingId
}

/**
 *
 * @export export async function function 
 * @param {object} param0
 * @param {string} param0.meetingId - meeting ID.
 * @param {Number} param0.permission - bitfield value (1 ImageRead, 2 ImageWrite, 4 AnnotationRead, 8 AnnotationWrite, 16 MeetingWrite)
 * @param {Number} [param0.expiry=3600] - share time expiry in seconds.
 * @param {object} [param0.auxData={}] - object that can be used to include specific data in meeting share like call ID for this share.
 * @returns {string} - shareId
 */
export async function createTemporaryShare({meetingId, permission, expiry, auxData}) {
	let headers = {
		"Content-Type": "application/json",
		Accept: "application/json",
		"x-jibb-user-jwt": await getUserToken(),
	}
	let body = {
		permission: permission,
		expiry: {
			seconds: expiry || 3600,
		},
		auxilary: auxData || {},
	}

	let response = await http.post(`${Config.apiBaseURL}/v1/meetings/${meetingId}/temp-shares`, body, headers)
	return response.data.shareId
}

/**
 *
 * @async
 * @param {object} param0
 * @param {string} param0.meetingId
 * @param {string} param0.shareId
 * @returns {string} - token
 */
export async function getMeetingTokenFromTempShareId({meetingId, shareId}) {
	let headers = {
		"Content-Type": "application/json",
		Accept: "application/json",
	}
	let response = await http.get(`${Config.apiBaseURL}/v1/meetings/${meetingId}/temp-shares/${shareId}`, headers)
	return response.data.token
}

/**
 *
 * @async
 * @param {object} param0
 * @param {string} param0.meetingId
 * @param {string} param0.mtoken
 * @returns - http response
 */
export async function deleteMeetingImages({meetingId, mtoken}) {
	let headers = {
		"Content-Type": "application/json",
		Accept: "application/json",
		"x-jibb-user-jwt": await getUserToken(),
		"x-jibb-meeting-jwt": mtoken,
	}

	return http.delete(`${Config.apiBaseURL}/v1/meetings/${meetingId}/images`, headers)
}

/**
 *
 * @async
 * @param {object} param0
 * @param {string} param0.meetingId
 * @param {string} param0.meetingToken
 * @returns {Array} - list of images
 */
export async function getMeetingImages({meetingId, meetingToken}) {
	let headers = {
		"Content-Type": "application/json",
		Accept: "application/json",
		"x-jibb-user-jwt": await getUserToken(),
		"x-jibb-meeting-jwt": meetingToken,
	}

	let response = await http.get(`${Config.apiBaseURL}/v1/meetings/${meetingId}/images`, headers)
	return response.data
}

/**
 *
 * @async
 * @param {object} param0
 * @param {string} param0.meetingId
 * @param {string} param0.meetingToken
 * @param {string} param0.imageId
 * @returns {data} - base64 data
 */
export async function getMeetingImage({meetingId, meetingToken, imageId}) {
	let headers = {
		"Content-Type": "application/json",
		Accept: "application/json",
		"x-jibb-user-jwt": await getUserToken(),
		"x-jibb-meeting-jwt": meetingToken,
	}

	let response = await http.get(`${Config.apiBaseURL}/v1/meetings/${meetingId}/images/${imageId}`, headers)
	return response.data
}

/**
 *
 * @async
 * @param {object} param0
 * @param {string} param0.meetingId
 * @param {string} param0.meetingToken
 * @returns - http response
 */
export async function startMeeting({meetingId, meetingToken}) {
	let headers = {
		"Content-Type": "application/json",
		Accept: "application/json",
		"x-jibb-meeting-jwt": meetingToken,
	}

	try {
		let body = {}
		return await http.post(`${Config.apiBaseURL}/v1/meetings/${meetingId}/actions/start`, body, headers)
	} catch (e) {
		if (e?.response?.status == 404) throw new NotFoundError()
		else throw e
	}
}

/**
 *
 * @async
 * @param {object} param0
 * @param {string} param0.meetingId
 * @param {string} param0.meetingToken
 * @returns - http response
 */
export async function endMeeting({meetingId, meetingToken}) {
	let headers = {
		"Content-Type": "application/json",
		Accept: "application/json",
		"x-jibb-meeting-jwt": meetingToken,
	}
	let body = {}
	return http.post(`${Config.apiBaseURL}/v1/meetings/${meetingId}/actions/end`, body, headers)
}

/**
 *
 * @async
 * @param {string} meetingId
 * @returns - http response
 */
export async function deleteMeeting(meetingId) {
	let headers = {
		"Content-Type": "application/json",
		Accept: "application/json",
		"x-jibb-user-jwt": await getUserToken(),
	}
	return http.delete(`${Config.apiBaseURL}/v1/meetings/${meetingId}`, headers)
}

/**
 *
 * @async
 * @param {object} param0
 * @param {string} param0.meetingId
 * @param {Number} param0.permission - bitfield value (1 ImageRead, 2 ImageWrite, 4 AnnotationRead, 8 AnnotationWrite, 16 MeetingWrite)
 * @param {Number} [param0.expiry=3600] - share time expiry in seconds.
 * @returns {string} - token
 */
export async function getMeetingToken({meetingId, permission, expiry = 3600}) {
	let userToken

	try {
		userToken = await getUserToken()
	} catch (err) {
		logger.error({
			err,
		})
		throw new PermissionDeniedError("user is not authenticated")
	}

	try {
		let headers = {
			"Content-Type": "application/json",
			Accept: "application/json",
			"x-jibb-user-jwt": userToken,
		}

		let body = {
			permission: permission,
			expiry: {
				seconds: expiry,
			}
		}
		let response = await http.post(`${Config.apiBaseURL}/v1/meetings/${meetingId}/token`, body, headers)
		return response.data.token
	} catch (err) {
		if (err?.response?.status == 404) throw new NotFoundError("meeting not found")
		else throw err
	}
}

/**
 *
 * @async
 * @param {*} pagination
 * @returns {Array} - meeting list.
 */
export async function getMeetingList(pagination) {
	let headers = {
		"Content-Type": "application/json",
		Accept: "application/json",
		"x-jibb-user-jwt": await getUserToken(),
	}
	if (pagination !== undefined) headers["x-jibb-pagination"] = JSON.stringify(pagination)
	let response = await http.get(`${Config.apiBaseURL}/v1/meetings`, headers)
	pagination = response.headers["x-jibb-pagination"]
	pagination = pagination && JSON.parse(pagination)

	return {
		meetings: response.data.meetings,
		pagination: pagination,
	}
}

/**
 *
 * @async
 * @param {string} meetingId
 * @returns {object} - object with meeting details.
 */
export async function getMeetingDetails(meetingId) {
	let headers = {
		"Content-Type": "application/json",
		Accept: "application/json",
		"x-jibb-user-jwt": await getUserToken(),
	}

	let response = await http.get(`${Config.apiBaseURL}/v1/meetings/${meetingId}`, headers)
	return response.data
}

/**
 *
 * @async
 * @param {object} param0
 * @param {string} param0.meetingId
 * @param {string} param0.title
 * @param {Number} param0.capacity
 * @returns - http result
 */
export async function updateMeeting({meetingId, title, capacity}) {
	let headers = {
		"Content-Type": "application/json",
		Accept: "application/json",
		"x-jibb-user-jwt": await getUserToken(),
	}

	let body = {}
	if (title) {
		body["title"] = title
	}
	if (capacity) {
		body["capacity"] = capacity
	}

	return http.post(`${Config.apiBaseURL}/v1/meetings/${meetingId}`, body, headers)
}

/**
 *
 * @async
 * @param {string} meetingToken
 * @returns {Boolean}
 */
export async function isMeetingOwner(meetingToken) {
	try {
		let meetingClaims = new MeetingClaims(meetingToken)
		let userClaims = new UserClaims(await getUserToken())
		return userClaims.userId === meetingClaims.ownerId
	} catch (err) {
		return false
	}
}

/**
 *
 * @async
 * @param {object} param0
 * @param {string} param0.email
 * @param {string} param0.meetingId
 * @param {Number} param0.permission - 1 Read or 2 Write.
 * @param {string} param0.meetingToken
 * @returns {string}
 */

export async function createShare({email, meetingId, permission, meetingToken}) {
	let headers = {
		"Content-Type": "application/json",
		Accept: "application/json",
		"x-jibb-user-jwt": await getUserToken(),
		"x-jibb-meeting-jwt": meetingToken,
	}
	let body = {
		email: email,
		permission: permission,
	}
	let response = await http.post(`${Config.apiBaseURL}/v1/meetings/${meetingId}/shares`, body, headers)
	return response.data
}

/**
 * @async
 * @returns {list} a list of meetings shared with the current user
 */
export async function getIncomingShares() {
	let headers = {
		"Content-Type": "application/json",
		Accept: "application/json",
		"x-jibb-user-jwt": await getUserToken(),
	}
	let response = await http.get(`${Config.apiBaseURL}/v1/meetings/shares?incoming=true`, headers)
	return response.data.shares
}

/**
 * @async
 * @returns {list} a list of meetings this user has shared with others
 */
export async function getOutgoingShares() {
	let headers = {
		"Content-Type": "application/json",
		Accept: "application/json",
		"x-jibb-user-jwt": await getUserToken(),
	}
	let response = await http.get(`${Config.apiBaseURL}/v1/meetings/shares?outgoing=true`, headers)
	return response.data.shares
}

/**
 * Delete a meeting share
 * @async
 * @param {integer} ID of the share
 * @returns - http result
 */
export async function deleteShare(shareId) {
	let headers = {
		"Content-Type": "application/json",
		Accept: "application/json",
		"x-jibb-user-jwt": await getUserToken(),
	}
	return http.delete(`${Config.apiBaseURL}/v1/meetings/shares/${shareId}`, headers)
}

/**
 * Update meeting share permission details
 * @async
 * @param {object} param0
 * @param {integer} param0.shareId
 * @param {string} param0.permission
 * @returns - http result
 */
export async function updateShare({shareId, permission}) {
	let headers = {
		"Content-Type": "application/json",
		Accept: "application/json",
		"x-jibb-user-jwt": await getUserToken(),
	}
	let body = {
		permission: permission,
	}
	return http.patch(`${Config.apiBaseURL}/v1/meetings/shares/${shareId}`, body, headers)
}