feat: last used column for api tokens (#3230)

This commit is contained in:
Catalin Pit
2026-08-25 18:07:31 +10:00
committed by GitHub
parent 73d58bdf31
commit 10f2b80025
6 changed files with 58 additions and 10 deletions
@@ -1,9 +1,12 @@
import { prisma } from '@documenso/prisma';
import { AppError, AppErrorCode } from '../../errors/app-error';
import { logger } from '../../utils/logger';
import { hashString } from '../auth/hash';
import { assertOrganisationRatesAndLimits } from '../rate-limit/assert-organisation-rates-and-limits';
const LAST_USED_AT_UPDATE_INTERVAL = 60_000; // 1 minute
type GetApiTokenByTokenOptions = {
token: string;
@@ -96,6 +99,29 @@ export const getApiTokenByToken = async ({ token, bypassRateLimit = false }: Get
});
}
// Only update the lastUsedAt after X amount of time has passed to reduce
// the number of writes to the database
if (!apiToken.lastUsedAt || apiToken.lastUsedAt.getTime() + LAST_USED_AT_UPDATE_INTERVAL < Date.now()) {
void prisma.apiToken
.updateMany({
where: {
id: apiToken.id,
// Optimistic guard: skip if another request beat us
lastUsedAt: apiToken.lastUsedAt,
},
data: {
lastUsedAt: new Date(),
},
})
.catch((err) => {
logger.warn({
msg: 'Failed to update API token lastUsedAt',
apiTokenId: apiToken.id,
err,
});
});
}
return {
...apiToken,
user,
@@ -22,6 +22,7 @@ export const getApiTokens = async ({ userId, teamId }: GetApiTokensOptions) => {
name: true,
createdAt: true,
expires: true,
lastUsedAt: true,
},
orderBy: {
createdAt: 'desc',