diff --git a/packages/server/modules/activitystream/graph/resolvers/activity.js b/packages/server/modules/activitystream/graph/resolvers/activity.js new file mode 100644 index 000000000..95da2d0d8 --- /dev/null +++ b/packages/server/modules/activitystream/graph/resolvers/activity.js @@ -0,0 +1,30 @@ +const appRoot = require( 'app-root-path' ) +const { validateServerRole, validateScopes } = require( `${appRoot}/modules/shared` ) +const { ForbiddenError, UserInputError, ApolloError, withFilter } = require( 'apollo-server-express' ) +const { getUserActivity, getStreamActivity, getResourceActivity, getUserTimeline } = require( '../../services/index' ) + + +module.exports = { + User: { + async activity( parent, args, context, info ) { + if ( args.limit && args.limit > 100 ) + throw new UserInputError( 'Cannot return more than 100 items; please use pagination.' ) + + // TODO: cursor and total count + let items = await getUserActivity( { userId: parent.id, timeEnd: args.timeEnd, limit: args.limit } ) + + return { items } + } + }, + + Stream: { + async activity( parent, args, context, info ) { + } + }, + + Branch: { + async activity( parent, args, context, info ) { + } + } + +} diff --git a/packages/server/modules/activitystream/graph/resolvers/index.js b/packages/server/modules/activitystream/graph/resolvers/index.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/packages/server/modules/activitystream/graph/schemas/activity.graphql b/packages/server/modules/activitystream/graph/schemas/activity.graphql new file mode 100644 index 000000000..3bf3d06cc --- /dev/null +++ b/packages/server/modules/activitystream/graph/schemas/activity.graphql @@ -0,0 +1,45 @@ +# TODO: allow queries + +extend type User { + """ + All the recent activity from this user in chronological order + """ + activity(limit: Int! = 25, cursor: String): ActivityCollection + @hasRole(role: "server:user") + @hasScope(scope: "users:read") +} + +extend type Stream { + """ + All the recent activity on this stream in chronological order + """ + activity(limit: Int! = 25, cursor: String): ActivityCollection + @hasRole(role: "server:user") + @hasScope(scope: "streams:read") +} + +extend type Branch { + """ + All the recent activity on this branch in chronological order + """ + activity(limit: Int! = 25, cursor: String): ActivityCollection + @hasRole(role: "server:user") + @hasScope(scope: "streams:read") +} + +type ActivityCollection { + totalCount: Int! + cursor: String + items: [Activity] +} + +type Activity { + actionType: String! + info: JSONObject! + userId: String! + streamId: String + resourceId: String! + resourceType: String! + time: DateTime! + message: String! +} diff --git a/packages/server/modules/activitystream/graph/schemas/index.js b/packages/server/modules/activitystream/graph/schemas/index.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/packages/server/modules/activitystream/services/index.js b/packages/server/modules/activitystream/services/index.js index 9a6fd5827..f8f770303 100644 --- a/packages/server/modules/activitystream/services/index.js +++ b/packages/server/modules/activitystream/services/index.js @@ -24,6 +24,7 @@ module.exports = { if ( !limit ) { limit = 100 } + let dbQuery = StreamActivity().where( { streamId: streamId } ) if ( timeEnd ) dbQuery.andWhere( 'time', '<', timeEnd ) dbQuery.orderBy( 'time', 'desc' ) @@ -37,6 +38,7 @@ module.exports = { if ( !limit ) { limit = 100 } + let dbQuery = StreamActivity().where( { userId: userId } ) if ( timeEnd ) dbQuery.andWhere( 'time', '<', timeEnd ) dbQuery.orderBy( 'time', 'desc' ) @@ -50,6 +52,7 @@ module.exports = { if ( !limit ) { limit = 100 } + let dbQuery = StreamActivity().where( { resourceType, resourceId } ) if ( timeEnd ) dbQuery.andWhere( 'time', '<', timeEnd ) dbQuery.orderBy( 'time', 'desc' ) @@ -63,9 +66,11 @@ module.exports = { if ( !timeEnd ) { timeEnd = Date.now() } + if ( !limit ) { limit = 100 } + let dbRawQuery = ` SELECT act.* FROM stream_acl acl diff --git a/packages/server/modules/core/graph/resolvers/users.js b/packages/server/modules/core/graph/resolvers/users.js index eaece00b8..6b15a6fbf 100644 --- a/packages/server/modules/core/graph/resolvers/users.js +++ b/packages/server/modules/core/graph/resolvers/users.js @@ -1,10 +1,9 @@ 'use strict' const appRoot = require( 'app-root-path' ) -const { ApolloError, ForbiddenError, UserInputError } = require( 'apollo-server-express' ) -const { createUser, getUser, getUserByEmail, getUserRole, updateUser, deleteUser, searchUsers, validatePasssword, getUserById } = require( '../../services/users' ) -const { createPersonalAccessToken, createAppToken, revokeToken, revokeTokenById, validateToken, getUserTokens } = require( '../../services/tokens' ) +const { UserInputError } = require( 'apollo-server-express' ) +const { getUser, getUserRole, updateUser, deleteUser, searchUsers, getUserById } = require( '../../services/users' ) const { saveActivity } = require( `${appRoot}/modules/activitystream/services` ) -const { validateServerRole, validateScopes, authorizeResolver } = require( `${appRoot}/modules/shared` ) +const { validateServerRole, validateScopes } = require( `${appRoot}/modules/shared` ) const zxcvbn = require( 'zxcvbn' ) module.exports = { @@ -38,7 +37,7 @@ module.exports = { throw new UserInputError( 'Search query must be at least 3 carachters.' ) - if ( args.limit && args.limit > 100 ) + if ( args.limit && args.limit > 100 ) throw new UserInputError( 'Cannot return more than 100 items, please use pagination.' ) let { cursor, users } = await searchUsers( args.query, args.limit, args.cursor ) @@ -86,7 +85,7 @@ module.exports = { let oldValue = await getUserById( { userId: context.userId } ) await updateUser( context.userId, args.user ) - + await saveActivity( { streamId: null, resourceType: 'user', @@ -108,8 +107,8 @@ module.exports = { } // The below are not really needed anymore as we've added the hasRole and hasScope - // directives in the graphql schema itself. - // Since I am paranoid, I'll leave them here too. + // directives in the graphql schema itself. + // Since I am paranoid, I'll leave them here too. await validateServerRole( context, 'server:user' ) await validateScopes( context.scopes, 'profile:delete' )