mirror of
https://github.com/nicotsx/zerobyte.git
synced 2026-06-15 03:50:37 -04:00
* feat(authentication): api key
Keeps selected UX pieces from b487b096.
Co-authored-by: Nguyen Quy Hy <nguyenquyhy@live.com.sg>
* refactor: pr feedbacks
* chore: bump @better-auth/api-key
* refactor: global limit of 50 api key instead of 10 per org
---------
Co-authored-by: Nguyen Quy Hy <nguyenquyhy@live.com.sg>
63 lines
1.8 KiB
TypeScript
63 lines
1.8 KiB
TypeScript
import { db } from "~/server/db/db";
|
|
import { parseApiKeyOrganizationId } from "./api-key-metadata";
|
|
|
|
export const MAX_API_KEYS_PER_USER = 50;
|
|
|
|
export const listApiKeys = async (userId: string, organizationId: string) => {
|
|
const rows = await db.query.apikey.findMany({
|
|
where: {
|
|
AND: [
|
|
{ referenceId: userId },
|
|
{ OR: [{ enabled: true }, { enabled: { isNull: true } }] },
|
|
{ OR: [{ expiresAt: { isNull: true } }, { expiresAt: { gt: new Date() } }] },
|
|
],
|
|
},
|
|
orderBy: (table, { desc }) => [desc(table.createdAt)],
|
|
});
|
|
|
|
return rows
|
|
.filter((row) => parseApiKeyOrganizationId(row.metadata) === organizationId)
|
|
.map((row) => ({
|
|
id: row.id,
|
|
name: row.name,
|
|
createdAt: row.createdAt.toISOString(),
|
|
expiresAt: row.expiresAt?.toISOString() ?? null,
|
|
lastRequestAt: row.lastRequest?.toISOString() ?? null,
|
|
}));
|
|
};
|
|
|
|
export const countActiveApiKeys = async (userId: string) => {
|
|
const rows = await db.query.apikey.findMany({
|
|
where: {
|
|
AND: [
|
|
{ referenceId: userId },
|
|
{ OR: [{ enabled: true }, { enabled: { isNull: true } }] },
|
|
{ OR: [{ expiresAt: { isNull: true } }, { expiresAt: { gt: new Date() } }] },
|
|
],
|
|
},
|
|
columns: { id: true },
|
|
});
|
|
|
|
return rows.length;
|
|
};
|
|
|
|
export const hasApiKey = async (userId: string, organizationId: string, apiKeyId: string) => {
|
|
const row = await db.query.apikey.findFirst({
|
|
where: {
|
|
AND: [{ id: apiKeyId }, { referenceId: userId }],
|
|
},
|
|
columns: { metadata: true },
|
|
});
|
|
|
|
return parseApiKeyOrganizationId(row?.metadata ?? null) === organizationId;
|
|
};
|
|
|
|
export const getApiKeyOrganizationId = async (apiKeyId: string) => {
|
|
const apiKeyRecord = await db.query.apikey.findFirst({
|
|
where: { id: apiKeyId },
|
|
columns: { metadata: true },
|
|
});
|
|
|
|
return parseApiKeyOrganizationId(apiKeyRecord?.metadata);
|
|
};
|