1
0
Fork 0

feat(backend): Track api calls per key

This commit is contained in:
joostdecock 2023-08-21 10:34:02 +02:00
parent 06bcf8a656
commit 1c4cc4920a
3 changed files with 25 additions and 3 deletions

View file

@ -11,9 +11,11 @@ datasource db {
model Apikey {
id String @id @default(uuid())
aud String @default("")
calls Int @default(0)
createdAt DateTime @default(now())
expiresAt DateTime
name String @default("")
lastSeen DateTime?
level Int @default(0)
secret String
user User @relation(fields: [userId], references: [id])

View file

@ -19,7 +19,7 @@ async function checkAccess(payload, tools, type) {
if (payload.aud !== `${api}/${instance}`) return false
const User = new UserModel(tools)
const uid = payload.userId || payload._id
const ok = await User.papersPlease(uid, type)
const ok = await User.papersPlease(uid, type, payload)
return ok
}

View file

@ -1526,7 +1526,7 @@ UserModel.prototype.isLusernameAvailable = async function (lusername) {
}
/*
* Helper method that is called by middleware to verifu whether the user
* Helper method that is called by middleware to verify whether the user
* is allowed in. It will update the `lastSeen` field of the user as
* well as increase the call counter for either JWT or KEY.
* It will also check whether the user status is ok and consent granted.
@ -1535,9 +1535,10 @@ UserModel.prototype.isLusernameAvailable = async function (lusername) {
*
* @param {id} string - The user ID
* @param {type} string - The authentication type (one of 'jwt' or 'key')
* @param {type} string - The middleware auth payload
* @returns {success} boolean - True if it worked, false if not
*/
UserModel.prototype.papersPlease = async function (id, type) {
UserModel.prototype.papersPlease = async function (id, type, payload) {
/*
* Construct data object for update operation
*/
@ -1558,6 +1559,25 @@ UserModel.prototype.papersPlease = async function (id, type) {
return false
}
/*
* If it's an API key, update the call call and lastSeen field too
*/
if (type === 'key') {
const keyData = {
calls: { increment: 1 },
lastSeen: new Date(),
}
try {
await this.prisma.apikey.update({ where: { id: payload.id }, data: keyData })
} catch (err) {
/*
* An error means it's not good. Return false
*/
log.warn({ id }, 'Could not update apikey lastSeen field from middleware')
return false
}
}
/*
* Verify the consent and status
*/