Add useApiTokens hook and refactor token UI

Introduce a shared useApiTokens hook to centralize API token CRUD and UI state (fetch, create, delete, copy, formatting). Refactor ApiTab and ApiTokensSection to consume the hook and remove duplicated logic. Add getInstanceUrl utility for client origin used in curl examples. Include an id alias in TokenPayload and add id into generated JWTs across auth routes and providers; update tests accordingly. Improve auth middleware typing and add debug logging around lastUsedAt updates. Add admin logging when creating a token with a role that differs from the target user's role.
This commit is contained in:
kikootwo
2026-03-04 15:18:48 -05:00
parent d6eca611fc
commit a50fbc721e
17 changed files with 344 additions and 311 deletions
+8 -3
View File
@@ -13,7 +13,7 @@ import { API_TOKEN_PREFIX, isEndpointAllowed } from '../constants/api-tokens';
const logger = RMABLogger.create('Auth');
export interface AuthenticatedRequest extends NextRequest {
user?: TokenPayload & { id: string };
user?: TokenPayload;
}
/**
@@ -39,7 +39,7 @@ function extractToken(request: NextRequest): string | null {
* Returns a synthetic TokenPayload if valid, null otherwise.
* Updates lastUsedAt asynchronously.
*/
async function authenticateApiToken(token: string): Promise<(TokenPayload & { id: string }) | null> {
async function authenticateApiToken(token: string): Promise<TokenPayload | null> {
const tokenHash = crypto.createHash('sha256').update(token).digest('hex');
const apiToken = await prisma.apiToken.findUnique({
@@ -79,7 +79,12 @@ async function authenticateApiToken(token: string): Promise<(TokenPayload & { id
prisma.apiToken.update({
where: { id: apiToken.id },
data: { lastUsedAt: new Date() },
}).catch(() => {});
}).catch((err) => {
logger.debug('Failed to update API token lastUsedAt', {
error: err instanceof Error ? err.message : String(err),
tokenId: apiToken.id,
});
});
// Use the token's target user (userId), not the creator (createdById)
return {