diff --git a/packages/nocodb/src/lib/meta/api/ee/orgTokenApis.ts b/packages/nocodb/src/lib/meta/api/ee/orgTokenApis.ts index 3a1526f563..b838dc80bb 100644 --- a/packages/nocodb/src/lib/meta/api/ee/orgTokenApis.ts +++ b/packages/nocodb/src/lib/meta/api/ee/orgTokenApis.ts @@ -15,7 +15,7 @@ export async function apiTokenListEE(req, res) { await ApiToken.listWithCreatedBy({ ...req.query, fk_user_id }), { ...req.query, - count: await ApiToken.count(), + count: await ApiToken.count({}), } ) ); diff --git a/packages/nocodb/src/lib/meta/api/orgTokenApis.ts b/packages/nocodb/src/lib/meta/api/orgTokenApis.ts index aaa9564a8b..e1eba6ed9d 100644 --- a/packages/nocodb/src/lib/meta/api/orgTokenApis.ts +++ b/packages/nocodb/src/lib/meta/api/orgTokenApis.ts @@ -1,47 +1,54 @@ -import { Request, Response, Router } from 'express'; -import { OrgUserRoles } from '../../../enums/OrgUserRoles'; -import ApiToken from '../../models/ApiToken'; -import { Tele } from '../../utils/Tele'; -import { metaApiMetrics } from '../helpers/apiMetrics'; -import { NcError } from '../helpers/catchError'; -import getHandler from '../helpers/getHandler'; -import ncMetaAclMw from '../helpers/ncMetaAclMw'; -import { PagedResponseImpl } from '../helpers/PagedResponse'; -import { apiTokenListEE } from './ee/orgTokenApis'; +import { Request, Response, Router } from 'express' +import { OrgUserRoles } from '../../../enums/OrgUserRoles' +import ApiToken from '../../models/ApiToken' +import { Tele } from '../../utils/Tele' +import { metaApiMetrics } from '../helpers/apiMetrics' +import { NcError } from '../helpers/catchError' +import getHandler from '../helpers/getHandler' +import ncMetaAclMw from '../helpers/ncMetaAclMw' +import { PagedResponseImpl } from '../helpers/PagedResponse' +import { apiTokenListEE } from './ee/orgTokenApis' async function apiTokenList(req, res) { - const fk_user_id = req.user.id; + const fk_user_id = req.user.id + let includeUnmappedToken = false + if (req['user'].roles.includes(OrgUserRoles.SUPER)) { + includeUnmappedToken = true + } res.json( new PagedResponseImpl( - await ApiToken.listWithCreatedBy({ ...req.query, fk_user_id }), + await ApiToken.listWithCreatedBy({ ...req.query, fk_user_id, includeUnmappedToken }), { ...req.query, - count: await ApiToken.count(), - } - ) - ); + count: await ApiToken.count({ + includeUnmappedToken, + fk_user_id, + }), + }, + ), + ) } export async function apiTokenCreate(req: Request, res: Response) { - Tele.emit('evt', { evt_type: 'org:apiToken:created' }); - res.json(await ApiToken.insert({ ...req.body, fk_user_id: req['user'].id })); + Tele.emit('evt', { evt_type: 'org:apiToken:created' }) + res.json(await ApiToken.insert({ ...req.body, fk_user_id: req['user'].id })) } export async function apiTokenDelete(req: Request, res: Response) { - const fk_user_id = req['user'].id; - const apiToken = await ApiToken.getByToken(req.params.apiTokenId); + const fk_user_id = req['user'].id + const apiToken = await ApiToken.getByToken(req.params.apiTokenId) if ( !req['user'].roles.includes(OrgUserRoles.SUPER) && apiToken.fk_user_id !== fk_user_id ) { - NcError.notFound('Token not found'); + NcError.notFound('Token not found') } - Tele.emit('evt', { evt_type: 'org:apiToken:deleted' }); - res.json(await ApiToken.delete(req.params.token)); + Tele.emit('evt', { evt_type: 'org:apiToken:deleted' }) + res.json(await ApiToken.delete(req.params.token)) } -const router = Router({ mergeParams: true }); +const router = Router({ mergeParams: true }) router.get( '/api/v1/tokens', @@ -49,22 +56,22 @@ router.get( ncMetaAclMw(getHandler(apiTokenList, apiTokenListEE), 'apiTokenList', { // allowedRoles: [OrgUserRoles.SUPER], blockApiTokenAccess: true, - }) -); + }), +) router.post( '/api/v1/tokens', metaApiMetrics, ncMetaAclMw(apiTokenCreate, 'apiTokenCreate', { // allowedRoles: [OrgUserRoles.SUPER], blockApiTokenAccess: true, - }) -); + }), +) router.delete( '/api/v1/tokens/:token', metaApiMetrics, ncMetaAclMw(apiTokenDelete, 'apiTokenDelete', { // allowedRoles: [OrgUserRoles.SUPER], blockApiTokenAccess: true, - }) -); -export default router; + }), +) +export default router diff --git a/packages/nocodb/src/lib/meta/helpers/apiMetrics.ts b/packages/nocodb/src/lib/meta/helpers/apiMetrics.ts index cb9983b9de..1bc805e380 100644 --- a/packages/nocodb/src/lib/meta/helpers/apiMetrics.ts +++ b/packages/nocodb/src/lib/meta/helpers/apiMetrics.ts @@ -3,7 +3,7 @@ import { Tele } from '../../utils/Tele'; const countMap = {}; -const metrics = async (req: Request, c = 50) => { +const metrics = async (req: Request, c = 150) => { if (!req?.route?.path) return; const event = `a:api:${req.route.path}:${req.method}`; countMap[event] = (countMap[event] || 0) + 1; diff --git a/packages/nocodb/src/lib/models/ApiToken.ts b/packages/nocodb/src/lib/models/ApiToken.ts index 0d8ce26037..028c194c59 100644 --- a/packages/nocodb/src/lib/models/ApiToken.ts +++ b/packages/nocodb/src/lib/models/ApiToken.ts @@ -74,8 +74,23 @@ export default class ApiToken { return data && new ApiToken(data); } - public static async count(ncMeta = Noco.ncMeta): Promise { + public static async count( + { + fk_user_id, + includeUnmappedToken = false, + }: { fk_user_id?: string; includeUnmappedToken?: boolean } = {}, + ncMeta = Noco.ncMeta + ): Promise { const qb = ncMeta.knex(MetaTable.API_TOKENS); + + if (fk_user_id) { + qb.where(`${MetaTable.API_TOKENS}.fk_user_id`, fk_user_id); + } + + if (includeUnmappedToken) { + qb.orWhereNull(`${MetaTable.API_TOKENS}.fk_user_id`); + } + return (await qb.count('id', { as: 'count' }).first())?.count ?? 0; } @@ -84,7 +99,13 @@ export default class ApiToken { limit = 10, offset = 0, fk_user_id, - }: { limit: number; offset: number; fk_user_id?: string }, + includeUnmappedToken = false, + }: { + limit: number; + offset: number; + fk_user_id?: string; + includeUnmappedToken: boolean; + }, ncMeta = Noco.ncMeta ) { const queryBuilder = ncMeta @@ -111,7 +132,11 @@ export default class ApiToken { ); if (fk_user_id) { - queryBuilder.where('fk_user_id', fk_user_id); + queryBuilder.where(`${MetaTable.API_TOKENS}.fk_user_id`, fk_user_id); + } + + if (includeUnmappedToken) { + queryBuilder.orWhereNull(`${MetaTable.API_TOKENS}.fk_user_id`); } return queryBuilder;