oaeproject/Hilary

View on GitHub
packages/oae-jitsi/lib/rest.js

Summary

Maintainability
F
4 days
Test Coverage
A
91%
/*!
 * Copyright 2016 Apereo Foundation (AF) Licensed under the
 * Educational Community License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may
 * obtain a copy of the License at
 *
 *     http://opensource.org/licenses/ECL-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an "AS IS"
 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

import _ from 'underscore';

import { AuthzConstants } from 'oae-authz/lib/constants.js';
import * as OAE from 'oae-util/lib/oae.js';
import * as OaeUtil from 'oae-util/lib/util.js';
import * as MeetingsAPI from 'oae-jitsi';

/**
 * @REST postMeetingCreate
 *
 * Create a new meeting
 *
 * @Server      tenant
 * @Method      POST
 * @Path        /meeting/create
 * @FormParam   {string}            description         A longer description for the meeting
 * @FormParam   {string}            displayName         The display name of the meeting
 * @FormParam   {string}            [chat]              Flag declaring whether or not Jitsi chat should be enabled
 * @FormParam   {string}            [contactList]       Flag declaring whether or not Jitsi contact list should be enabled
 * @FormParam   {string[]}          [managers]          Unique identifier(s) for users and groups to add as managers of the meeting. The user creating the meeting will be added as a manager automatically
 * @FormParam   {string[]}          [members]           Unique identifier(s) for users and groups to add as members of the meeting
 * @FormParam   {string}            [visibility]        The visibility of the meeting. Defaults to the configured tenant default          [loggedin,private,public]
 * @Return      {BasicMeeting}                          The created meeting
 * @HttpResponse                    200                 Meeting created
 * @HttpResponse                    400                 Must provide a display name for the meeting
 * @HttpResponse                    400                 Must provide a description for the meeting
 * @HttpResponse                    400                 A display name can be at most 1000 characters long
 * @HttpResponse                    400                 A description can be at most 10000 characters long
 * @HttpResponse                    400                 An invalid meeting visibility option has been provided
 * @HttpResponse                    400                 One or more target members being granted access are not authorized to become members on this meeting
 * @HttpResponse                    400                 One or more target members being granted access do not exist
 * @HttpResponse                    401                 Anonymous users cannot create a meeting
 */
OAE.tenantRouter.on('post', '/api/meeting-jitsi/create', (request, response) => {
  // Ensure proper arrays for the multi-value parameters
  request.body.managers = OaeUtil.toArray(request.body.managers);
  request.body.members = OaeUtil.toArray(request.body.members);

  // Construct a hash for additional members that maps each user to their role
  const additionalMembers = {};
  _.each(request.body.managers, (userId) => {
    additionalMembers[userId] = AuthzConstants.role.MANAGER;
  });
  _.each(request.body.members, (userId) => {
    additionalMembers[userId] = AuthzConstants.role.MEMBER;
  });

  MeetingsAPI.Meetings.createMeeting(
    request.ctx,
    request.body.displayName,
    request.body.description,
    request.body.chat,
    request.body.contactList,
    request.body.visibility,
    additionalMembers,
    (error, meeting) => {
      if (error) {
        return response.status(error.code).send(error.msg);
      }

      return response.status(201).send(meeting);
    }
  );
});

/**
 * @REST getMeetingMeetingId
 *
 * Get a full meeting profile
 *
 * @Server      tenant
 * @Method      GET
 * @Path        /meeting/{meetingId}
 * @PathParam   {string}                meetingId           The id of the meeting to get
 * @Return      {Meeting}                                   Full meeting profile
 * @HttpResponse                        200                 Meeting profile available
 * @HttpResponse                        400                 meetingId must be a valid resource id
 * @HttpResponse                        401                 You are not authorized to view this meeting
 * @HttpResponse                        404                 Could not find the specified meeting
 */
OAE.tenantRouter.on('get', '/api/meeting-jitsi/:meetingId', (request, response) => {
  MeetingsAPI.Meetings.getFullMeetingProfile(request.ctx, request.params.meetingId, (error, meeting) => {
    if (error) {
      return response.status(error.code).send(error.msg);
    }

    return response.status(200).send(meeting);
  });
});

/**
 * @REST getMeetingMeetingIdInvitations
 *
 * Get all the invitations associated to a meeting
 *
 * @Server      tenant
 * @Method      GET
 * @Path        /meeting/{meetingId}/invitations
 * @PathParam   {string}                meetingId           The id of the meeting for which to get invitations
 * @Return      {InvitationsResponse}                       The invitations associated to the meeting
 * @HttpResponse                        200                 Invitations available
 * @HttpResponse                        400                 A valid meeting id must be provided
 * @HttpResponse                        401                 You are not allowed to get invitations for this meeting
 * @HttpResponse                        404                 Meeting not available
 */
OAE.tenantRouter.on('get', '/api/meeting-jitsi/:meetingId/invitations', (request, response) => {
  MeetingsAPI.Meetings.getMeetingInvitations(request.ctx, request.params.meetingId, (error, invitations) => {
    if (error) {
      return response.status(error.code).send(error.msg);
    }

    return response.status(200).send({ results: invitations });
  });
});

/**
 * @REST getMeetingMeetingIdMembers
 *
 * Get the members of a meeting and their roles
 *
 * @Server      tenant
 * @Method      GET
 * @Path        /meeting/{meetingId}/members
 * @PathParam   {string}                meetingId           The id of the meeting to get the members for
 * @QueryParam  {number}                [limit]             The maximum number of results to return. Default: 10
 * @QueryParam  {string}                [start]             The meeting paging token from which to start fetching meeting members
 * @Return      {MembersResponse}                           Members of the specified meeting
 * @HttpResponse                        200                 Meeting members available
 * @HttpResponse                        400                 A valid meeting id must be provided
 * @HttpResponse                        401                 You are not authorized to view this meeting
 * @HttpResponse                        404                 Could not find the specified meeting
 */
OAE.tenantRouter.on('get', '/api/meeting-jitsi/:meetingId/members', (request, response) => {
  const limit = OaeUtil.getNumberParam(request.query.limit, 10, 1, 25);
  MeetingsAPI.Meetings.getMeetingMembers(
    request.ctx,
    request.params.meetingId,
    request.query.start,
    limit,
    (error, members, nextToken) => {
      if (error) {
        return response.status(error.code).send(error.msg);
      }

      return response.status(200).send({ results: members, nextToken });
    }
  );
});

/**
 * @REST postMeetingMeetingId
 *
 * Update a meeting's metadata.
 *
 * @Server      tenant
 * @Method      PUT
 * @Path        /meeting/{meetingId}
 * @PathParam   {string}            meetingId           The id of the meeting to update
 * @FormParam   {string}            description         Updated description for the meeting
 * @FormParam   {string}            displayName         Updated display name for the meeting
 * @FormParam   {string}            visibility          Updated visibility for the meeting           [loggedin,private,public]
 * @Return      {BasicMeeting}                          The updated meeting
 * @HttpResponse                    200                 Meeting updated
 * @HttpResponse                    400                 A valid meeting id must be provided
 * @HttpResponse                    400                 A display name cannot be empty
 * @HttpResponse                    400                 A description cannot be empty
 * @HttpResponse                    400                 A display name can be at most 1000 characters long
 * @HttpResponse                    400                 A description can only be 10000 characters long
 * @HttpResponse                    400                 An invalid visibility was specified
 * @HttpResponse                    400                 An invalid field was specified
 * @HttpResponse                    400                 You should specify at least one profile field to update
 * @HttpResponse                    401                 You are not authorized to update this meeting
 * @HttpResponse                    404                 Could not find the specified meeting
 */
OAE.tenantRouter.on('put', '/api/meeting-jitsi/:meetingId', (request, response) => {
  MeetingsAPI.Meetings.updateMeeting(request.ctx, request.params.meetingId, request.body, (error, meeting) => {
    if (error) {
      return response.status(error.code).send(error.msg);
    }

    return response.status(200).send(meeting);
  });
});

/**
 * @REST deleteMeetingMeetingId
 *
 * Delete a meeting
 *
 * @Server      tenant
 * @Method      DELETE
 * @Path        /meeting/{meetingId}
 * @PathParam   {string}        meetingId           The id of the meeting to delete
 * @HttpResponse                200                 Meeting deleted
 * @HttpResponse                400                 A valid meeting id must be provided
 * @HttpResponse                401                 You are not authorized to delete this meeting
 * @HttpResponse                404                 Could not find the specified meeting
 */
OAE.tenantRouter.on('delete', '/api/meeting-jitsi/:meetingId', (request, response) => {
  MeetingsAPI.Meetings.deleteMeeting(request.ctx, request.params.meetingId, (error) => {
    if (error) {
      return response.status(error.code).send(error.msg);
    }

    return response.status(200).end();
  });
});

/**
 * @REST postMeetingMeetingIdMembers
 *
 * Update the members of a meeting
 *
 * @Server      tenant
 * @Method      PUT
 * @Path        /meeting/{meetingId}/members
 * @PathParam   {string}                    meetingId           The id of the meeting to update the members for
 * @BodyParam   {MeetingMembersUpdate}      body                Object that describes the membership updates to apply to the meeting
 * @Return      {void}
 * @HttpResponse                            200                 Meeting members updated
 * @HttpResponse                            400                 A valid meeting id must be provided
 * @HttpResponse                            400                 Invalid principal id specified
 * @HttpResponse                            400                 Must specify at least one permission change to apply
 * @HttpResponse                            400                 One or more target members being granted access are not authorized to become members on this meeting
 * @HttpResponse                            400                 The requested change results in a meeting with no managers
 * @HttpResponse                            400                 An invalid role value was specified. Must either be a string, or false
 * @HttpResponse                            400                 You must specify at least one permission change
 * @HttpResponse                            401                 You are not authorized to update the permissions of this meeting
 * @HttpResponse                            404                 Could not find the specified meeting
 */
OAE.tenantRouter.on('put', '/api/meeting-jitsi/:meetingId/members', (request, response) => {
  // Parse the incoming false values
  const permissionUpdates = {};
  _.each(request.body, (value, key) => {
    permissionUpdates[key] = OaeUtil.castToBoolean(value);
  });

  MeetingsAPI.Meetings.setMeetingMembers(request.ctx, request.params.meetingId, permissionUpdates, (error) => {
    if (error) {
      return response.status(error.code).send(error.msg);
    }

    return response.status(200).end();
  });
});

/**
 * @REST getMeetingMeetingIdMessages
 *
 * Get the messages in a meeting
 *
 * @Server      tenant
 * @Method      GET
 * @Path        /meeting/{meetingId}/messages
 * @PathParam   {string}                meetingId           The id of the meeting for which to get the messages
 * @QueryParam  {number}                [limit]             The maximum number of results to return. Default: 10
 * @QueryParam  {string}                [start]             The messages paging token from which to start fetching messages
 * @Return      {MessagesResponse}                          The messages in the meeting
 * @HttpResponse                        200                 Meeting messages available
 * @HttpResponse                        400                 A messageBoxId must be specified
 * @HttpResponse                        400                 A timestamp cannot be in the future.
 * @HttpResponse                        400                 A timestamp cannot be null
 * @HttpResponse                        400                 A timestamp should be an integer
 * @HttpResponse                        400                 Must provide a valid meeting id
 * @HttpResponse                        401                 You are not authorized to view this meeting
 * @HttpResponse                        404                 Could not find the specified meeting
 */
OAE.tenantRouter.on('get', '/api/meeting-jitsi/:meetingId/messages', (request, response) => {
  const limit = OaeUtil.getNumberParam(request.query.limit, 10, 1, 25);
  MeetingsAPI.Meetings.getMessages(
    request.ctx,
    request.params.meetingId,
    request.query.start,
    limit,
    (error, messages, nextToken) => {
      if (error) {
        return response.status(error.code).send(error.msg);
      }

      response.status(200).send({ results: messages, nextToken });
    }
  );
});

/**
 * @REST postMeetingMeetingIdMessages
 *
 * Create a new message in a meeting
 *
 * @Server      tenant
 * @Method      POST
 * @Path        /meeting/{meetingId}/messages
 * @PathParam   {string}        meetingId           The id of the meeting to which to post the message
 * @FormParam   {string}        body                The body of the message
 * @FormParam   {number}        [replyTo]           The timestamp of the message to which this message is a reply. Not specifying this will create a top level comment
 * @Return      {Message}                           The created message
 * @HttpResponse                200                 Meeting message created
 * @HttpResponse                400                 A meeting body can only be 100000 characters long
 * @HttpResponse                400                 A meeting body must be provided
 * @HttpResponse                400                 A messageBoxId must be specified
 * @HttpResponse                400                 If the replyToCreated optional parameter is specified, it should point to an existing reply
 * @HttpResponse                400                 Invalid meeting id provided
 * @HttpResponse                400                 The body of the message must be specified
 * @HttpResponse                401                 You are not authorized to post messages to this meeting
 * @HttpResponse                404                 Could not find the specified meeting
 */
OAE.tenantRouter.on('post', '/api/meeting-jitsi/:meetingId/messages', (request, response) => {
  MeetingsAPI.Meetings.createMessage(
    request.ctx,
    request.params.meetingId,
    request.body.body,
    request.body.replyTo,
    (error, message) => {
      if (error) {
        return response.status(error.code).send(error.msg);
      }

      response.status(200).send(message);
    }
  );
});

/**
 * @REST deleteMeetingMeetingIdMessagesCreated
 *
 * Delete a message in a meeting
 *
 * @Server      tenant
 * @Method      DELETE
 * @Path        /meeting/{meetingId}/messages/{created}
 * @PathParam   {string}                meetingId           The id of the meeting from which to delete the message
 * @PathParam   {number}                created             The timestamp of the message that should be deleted
 * @Return      {Message}                                   When the message has been soft deleted (because it has replies), a stripped down message object representing the deleted message will be returned, with the `deleted` parameter set to `false`. If the message has been removed entirely, no message object will be returned
 * @HttpResponse                        200                 Meeting message deleted
 * @HttpResponse                        400                 A meeting id must be provided
 * @HttpResponse                        400                 A messageBoxId must be specified
 * @HttpResponse                        400                 A valid integer message created timestamp must be specified
 * @HttpResponse                        400                 The createdTimestamp should point to an existing message
 * @HttpResponse                        401                 You are not authorized to delete this message
 * @HttpResponse                        404                 Could not find the specified meeting
 * @HttpResponse                        404                 Could not find the specified message
 */
OAE.tenantRouter.on('delete', '/api/meeting-jitsi/:meetingId/messages/:created', (request, response) => {
  MeetingsAPI.Meetings.deleteMessage(
    request.ctx,
    request.params.meetingId,
    request.params.created,
    (error, message) => {
      if (error) {
        return response.status(error.code).send(error.msg);
      }

      response.status(200).send(message);
    }
  );
});

/**
 * @REST getMeetingLibraryPrincipalId
 *
 * Get the meetings library items for a user or group
 *
 * @Server      tenant
 * @Method      GET
 * @Path        /meeting-jitsi/library/{principalId}
 * @PathParam   {string}                principalId         The id of the principal whose meeting library to fetch
 * @QueryParam  {number}                [limit]             The maximum number of results to return. Default: 10
 * @QueryParam  {string}                [start]             The meeting paging token from which to start fetching meetings
 * @Return      {MeetingsLibrary}                           The meetings library items for the specified user or group
 * @HttpResponse                        200                 Meeting library available
 * @HttpResponse                        400                 A user or group id must be provided
 * @HttpResponse                        401                 You do not have have access to this library
 */
OAE.tenantRouter.on('get', '/api/meeting-jitsi/library/:principalId', (request, response) => {
  const limit = OaeUtil.getNumberParam(request.query.limit, 12, 1, 25);
  MeetingsAPI.Meetings.getMeetingsLibrary(
    request.ctx,
    request.params.principalId,
    request.query.start,
    limit,
    (error, meetings, nextToken) => {
      if (error) {
        return response.status(error.code).send(error.msg);
      }

      response.status(200).send({ results: meetings, nextToken });
    }
  );
});

/**
 * @REST deleteMeetingLibraryPrincipalIdMeetingId
 *
 * Remove a meeting from a meeting library
 *
 * @Server      tenant
 * @Method      DELETE
 * @Path        /meeting/library/{principalId}/{meetingId}
 * @PathParam   {string}                principalId         The id of the principal from whose meeting library to remove the meeting
 * @PathParam   {string}                meetingId           The id of the meeting to remove from the library
 * @HttpResponse                        200                 Meeting removed from library
 * @HttpResponse                        400                 A user or group id must be provided
 * @HttpResponse                        400                 An invalid meeting id was provided
 * @HttpResponse                        400                 The requested change results in a meeting with no managers
 * @HttpResponse                        400                 The specified meeting is not in this library
 * @HttpResponse                        401                 You are not authorized to remove a meeting from this library
 * @HttpResponse                        404                 Could not find the specified meeting
 */
OAE.tenantRouter.on('delete', '/api/meeting-jitsi/library/:principalId/:meetingId', (request, response) => {
  MeetingsAPI.Meetings.removeMeetingFromLibrary(
    request.ctx,
    request.params.principalId,
    request.params.meetingId,
    (error) => {
      if (error) {
        return response.status(error.code).send(error.msg);
      }

      return response.status(200).end();
    }
  );
});