Skip to content

Commit

Permalink
Add new handler for the auth server to record interactions
Browse files Browse the repository at this point in the history
  • Loading branch information
ikprk committed Jul 2, 2024
1 parent 69076f8 commit 5be4304
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 0 deletions.
24 changes: 24 additions & 0 deletions src/auth-server/generated/api-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
*/

export interface paths {
'/register-user-interaction': {
/** @description Register a user interaction with Atlas part. */
post: operations['registerUserInteraction']
}
'/anonymous-auth': {
/** @description Authenticate as an anonymous user, either using an existing user identifier or creating a new one. */
post: operations['anonymousAuth']
Expand Down Expand Up @@ -58,6 +62,10 @@ export interface components {
signature: string
payload: components['schemas']['ActionExecutionPayload']
}
RegisterUserInteractionRequestData: {
entityId: string
type: string
}
AnonymousUserAuthRequestData: {
userId?: string
}
Expand Down Expand Up @@ -245,6 +253,11 @@ export interface components {
}
parameters: never
requestBodies: {
RegisterUserInteractionRequestBody?: {
content: {
'application/json': components['schemas']['RegisterUserInteractionRequestData']
}
}
AnonymousUserAuthRequestBody?: {
content: {
'application/json': components['schemas']['AnonymousUserAuthRequestData']
Expand Down Expand Up @@ -290,6 +303,17 @@ export type $defs = Record<string, never>
export type external = Record<string, never>

export interface operations {
/** @description Register a user interaction with Atlas part. */
registerUserInteraction: {
requestBody: components['requestBodies']['RegisterUserInteractionRequestBody']
responses: {
200: components['responses']['GenericOkResponse']
400: components['responses']['GenericBadRequestResponse']
401: components['responses']['UnauthorizedAnonymousUserResponse']
429: components['responses']['GenericTooManyRequestsResponse']
default: components['responses']['GenericInternalServerErrorResponse']
}
}
/** @description Authenticate as an anonymous user, either using an existing user identifier or creating a new one. */
anonymousAuth: {
requestBody: components['requestBodies']['AnonymousUserAuthRequestBody']
Expand Down
66 changes: 66 additions & 0 deletions src/auth-server/handlers/registerUserInteraction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import express from 'express'
import { AuthContext } from '../../utils/auth'
import { globalEm } from '../../utils/globalEm'
import { components } from '../generated/api-types'
import { UnauthorizedError } from '../errors'
import { UserInteractionCount } from '../../model'

type ReqParams = Record<string, string>
type ResBody =
| components['schemas']['GenericOkResponseData']
| components['schemas']['GenericErrorResponseData']
type ResLocals = { authContext: AuthContext }
type ReqBody = components['schemas']['RegisterUserInteractionRequestData']

export const registerUserInteraction: (
req: express.Request<ReqParams, ResBody, ReqBody>,
res: express.Response<ResBody, ResLocals>,
next: express.NextFunction
) => Promise<void> = async (req, res, next) => {
try {
const { authContext: session } = res.locals
const { type, entityId } = req.body

console.log(session)
if (!session) {
throw new UnauthorizedError('Cannot register interactions for empty session')
}

const em = await globalEm

await em.transaction(async (em) => {
const date = new Date()
const startOfDay = new Date(date.setHours(0, 0, 0, 0))
const endOfDay = new Date(date.setHours(23, 59, 59, 999))

const dailyInteractionRow = await em
.getRepository(UserInteractionCount)
.createQueryBuilder('entity')
.where('entity.entityId = :entityId', { entityId })
.andWhere('entity.type = :type', { type })
.andWhere('entity.dayTimestamp >= :startOfDay', { startOfDay })
.andWhere('entity.dayTimestamp <= :endOfDay', { endOfDay })
.getOne()

if (!dailyInteractionRow) {
await em.getRepository(UserInteractionCount).save({
id: `${Date.now()}-${entityId}-${type}`,
dayTimestamp: new Date(),
count: 1,
type,
entityId,
})

return
}

dailyInteractionRow.count++

await em.save(dailyInteractionRow)
})

res.status(200).json({ success: true })
} catch (e) {
next(e)
}
}
35 changes: 35 additions & 0 deletions src/auth-server/openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,26 @@ info:
servers:
- url: '/api/v1/'
paths:
/register-user-interaction:
post:
security:
- cookieAuth: []
operationId: registerUserInteraction
x-eov-operation-handler: registerUserInteraction
description: Register a user interaction with Atlas part.
requestBody:
$ref: '#/components/requestBodies/RegisterUserInteractionRequestBody'
responses:
'200':
$ref: '#/components/responses/GenericOkResponse'
'400':
$ref: '#/components/responses/GenericBadRequestResponse'
'401':
$ref: '#/components/responses/UnauthorizedAnonymousUserResponse'
'429':
$ref: '#/components/responses/GenericTooManyRequestsResponse'
default:
$ref: '#/components/responses/GenericInternalServerErrorResponse'
/anonymous-auth:
post:
operationId: anonymousAuth
Expand Down Expand Up @@ -225,6 +245,11 @@ components:
in: cookie
name: session_id
requestBodies:
RegisterUserInteractionRequestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/RegisterUserInteractionRequestData'
AnonymousUserAuthRequestBody:
content:
application/json:
Expand Down Expand Up @@ -415,6 +440,16 @@ components:
type: string
payload:
$ref: '#/components/schemas/ActionExecutionPayload'
RegisterUserInteractionRequestData:
type: object
required:
- entityId
- type
properties:
entityId:
type: string
type:
type: string
AnonymousUserAuthRequestData:
type: object
properties:
Expand Down
6 changes: 6 additions & 0 deletions src/auth-server/rateLimits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ export const globalRateLimit: SimpleRateLimit = {

// Route-specific rate limits
export const rateLimitsPerRoute: RateLimitsPerRoute = {
'/register-user-interaction': {
post: {
windowMinutes: 5,
limit: 1,
},
},
'/anonymous-auth': {
post: {
windowMinutes: 5,
Expand Down

0 comments on commit 5be4304

Please sign in to comment.