Skip to content
This repository was archived by the owner on Mar 1, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions backend/src/client.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// For more information about this file see https://dove.feathersjs.com/guides/cli/client.html
import { feathers } from '@feathersjs/feathers'
import authenticationClient from '@feathersjs/authentication-client'
import { shareLinkAnalyticsClient } from './services/share-link-analytics/share-link-analytics.shared.js'

import { userEngagementsClient } from './services/user-engagements/user-engagements.shared.js'

import { notificationsClient } from './services/notifications/notifications.shared.js'
Expand Down Expand Up @@ -108,5 +110,7 @@ export const createClient = (connection, authenticationOptions = {}) => {

client.configure(publisherClient)

client.configure(shareLinkAnalyticsClient)

return client
}
26 changes: 14 additions & 12 deletions backend/src/hooks/handle-public-info-query.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,17 @@ export const ThrowBadRequestIfNotForPublicInfo = async (context) => {
return context;
}

//
// export const tryToAuthenticate = () => {
// // this is an "around" hook
// // Try To authenticate context but also allow anonymous calls
// return async (context, next) => {
// if (context.params.user) {
// await authenticate("jwt")(context, next);
// }
// await next();
// return context;
// }
// }

export const tryToAuthenticate = () => {
// this is an "around" hook
// Try To authenticate context but also allow anonymous calls
return async (context, next) => {
try {
await authenticate("jwt")(context, next);
} catch (e) {
console.log(e);
await next();
}
return context;
}
}
5 changes: 5 additions & 0 deletions backend/src/services/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ import { download } from './download/download.js'

import { publisher } from './publisher/publisher.js'

import { shareLinkAnalytics } from './share-link-analytics/share-link-analytics.js'


export const services = (app) => {
app.configure(orgSecondaryReferences)

Expand Down Expand Up @@ -91,5 +94,7 @@ export const services = (app) => {

app.configure(publisher)

app.configure(shareLinkAnalytics)

// All services will be registered here
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { MongoDBService } from '@feathersjs/mongodb'

// By default calls the standard MongoDB adapter service methods but can be customized with your own functionality.
export class ShareLinkAnalyticsService extends MongoDBService {}

export const getOptions = (app) => {
return {
paginate: app.get('paginate'),
Model: app.get('mongodbClient').then((db) => db.collection('share-link-analytics'))
}
}
83 changes: 83 additions & 0 deletions backend/src/services/share-link-analytics/share-link-analytics.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// For more information about this file see https://dove.feathersjs.com/guides/cli/service.html
import { authenticate } from '@feathersjs/authentication'

import { hooks as schemaHooks } from '@feathersjs/schema'
import {
shareLinkAnalyticsDataValidator,
shareLinkAnalyticsPatchValidator,
shareLinkAnalyticsQueryValidator,
shareLinkAnalyticsResolver,
shareLinkAnalyticsExternalResolver,
shareLinkAnalyticsDataResolver,
shareLinkAnalyticsPatchResolver,
shareLinkAnalyticsQueryResolver,
shareLinkAnalyticsPatchSchema,
shareLinkAnalyticsDataSchema,
shareLinkAnalyticsQuerySchema,
shareLinkAnalyticsSchema,
} from './share-link-analytics.schema.js'
import { ShareLinkAnalyticsService, getOptions } from './share-link-analytics.class.js'
import { shareLinkAnalyticsPath, shareLinkAnalyticsMethods } from './share-link-analytics.shared.js'
import {disallow} from "feathers-hooks-common";
import {authenticateJwtWhenPrivate, tryToAuthenticate} from "../../hooks/handle-public-info-query.js";
import swagger from "feathers-swagger";

export * from './share-link-analytics.class.js'
export * from './share-link-analytics.schema.js'

// A configure function that registers the service and its hooks via `app.configure`
export const shareLinkAnalytics = (app) => {
// Register our service on the Feathers application
app.use(shareLinkAnalyticsPath, new ShareLinkAnalyticsService(getOptions(app)), {
// A list of all methods this service exposes externally
methods: shareLinkAnalyticsMethods,
// You can add additional custom events to be sent to clients here
events: [],
docs: swagger.createSwaggerServiceOptions({
schemas: { shareLinkAnalyticsSchema, shareLinkAnalyticsDataSchema, shareLinkAnalyticsQuerySchema, shareLinkAnalyticsPatchSchema },
docs: {
description: 'A Share link analytics service',
idType: 'string',
securities: ['all'],
}
})
})
// Initialize hooks
app.service(shareLinkAnalyticsPath).hooks({
around: {
all: [
schemaHooks.resolveExternal(shareLinkAnalyticsExternalResolver),
schemaHooks.resolveResult(shareLinkAnalyticsResolver)
],
find: [authenticate('jwt')],
get: [authenticate('jwt')],
create: [tryToAuthenticate()],
update: [disallow('external')],
patch: [disallow('external')],
remove: [disallow('external')],
},
before: {
all: [
schemaHooks.validateQuery(shareLinkAnalyticsQueryValidator),
schemaHooks.resolveQuery(shareLinkAnalyticsQueryResolver)
],
find: [],
get: [],
create: [
schemaHooks.validateData(shareLinkAnalyticsDataValidator),
schemaHooks.resolveData(shareLinkAnalyticsDataResolver)
],
patch: [
schemaHooks.validateData(shareLinkAnalyticsPatchValidator),
schemaHooks.resolveData(shareLinkAnalyticsPatchResolver)
],
remove: []
},
after: {
all: []
},
error: {
all: []
}
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// // For more information about this file see https://dove.feathersjs.com/guides/cli/service.schemas.html
import { resolve } from '@feathersjs/schema'
import { Type, getValidator, querySyntax } from '@feathersjs/typebox'
import { ObjectIdSchema } from '@feathersjs/typebox'
import { dataValidator, queryValidator } from '../../validators.js'
import {userSummarySchema} from "../users/users.subdocs.schema.js";
import {SourceType} from "../user-engagements/user-engagement.subdocs.schema.js";
import {buildUserSummary} from "../users/users.distrib.js";

// Main data model schema
export const shareLinkAnalyticsSchema = Type.Object(
{
_id: ObjectIdSchema(),
sharedModelId: ObjectIdSchema(),
accessedBy: Type.Optional(userSummarySchema),
accessedFrom: SourceType,
accessedAt: Type.Number(),
additionalData: Type.Optional(Type.Object({})),
},
{ $id: 'ShareLinkAnalytics', additionalProperties: false }
)
export const shareLinkAnalyticsValidator = getValidator(shareLinkAnalyticsSchema, dataValidator)
export const shareLinkAnalyticsResolver = resolve({})

export const shareLinkAnalyticsExternalResolver = resolve({})

// Schema for creating new entries
export const shareLinkAnalyticsDataSchema = Type.Pick(shareLinkAnalyticsSchema, [
'sharedModelId',
'accessedFrom',
'additionalData',
], {
$id: 'ShareLinkAnalyticsData'
})
export const shareLinkAnalyticsDataValidator = getValidator(shareLinkAnalyticsDataSchema, dataValidator)
export const shareLinkAnalyticsDataResolver = resolve({
accessedBy: async (_value, _message, context) => {
// Associate the record with the id of the authenticated user
if (context.params.user) {
return buildUserSummary(context.params.user);
}
return undefined;
},
accessedAt: async () => Date.now(),
})

// Schema for updating existing entries
export const shareLinkAnalyticsPatchSchema = Type.Partial(shareLinkAnalyticsSchema, {
$id: 'ShareLinkAnalyticsPatch'
})
export const shareLinkAnalyticsPatchValidator = getValidator(shareLinkAnalyticsPatchSchema, dataValidator)
export const shareLinkAnalyticsPatchResolver = resolve({})

// Schema for allowed query properties
export const shareLinkAnalyticsQueryProperties = Type.Pick(shareLinkAnalyticsSchema, [
'_id', 'sharedModelId', 'accessedBy', 'accessedAt', 'accessedFrom'
])
export const shareLinkAnalyticsQuerySchema = Type.Intersect(
[
querySyntax(shareLinkAnalyticsQueryProperties),
// Add additional query properties here
Type.Object({}, { additionalProperties: false })
],
{ additionalProperties: false }
)
export const shareLinkAnalyticsQueryValidator = getValidator(shareLinkAnalyticsQuerySchema, queryValidator)
export const shareLinkAnalyticsQueryResolver = resolve({})
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export const shareLinkAnalyticsPath = 'share-link-analytics'

export const shareLinkAnalyticsMethods = ['find', 'get', 'create', 'patch', 'remove']

export const shareLinkAnalyticsClient = (client) => {
const connection = client.get('connection')

client.use(shareLinkAnalyticsPath, connection.service(shareLinkAnalyticsPath), {
methods: shareLinkAnalyticsMethods
})
}