173 lines
4.4 KiB
TypeScript
173 lines
4.4 KiB
TypeScript
'use server';
|
|
|
|
const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3000';
|
|
|
|
interface BootstrapResponse {
|
|
apiKey: string;
|
|
type: string;
|
|
name: string;
|
|
expiresAt: string | null;
|
|
message: string;
|
|
}
|
|
|
|
interface CreateKeyResponse {
|
|
apiKey: string;
|
|
metadata: {
|
|
id: string;
|
|
type: string;
|
|
projectId: string;
|
|
name: string;
|
|
expiresAt: string | null;
|
|
scopes: string[];
|
|
createdAt: string;
|
|
};
|
|
message: string;
|
|
}
|
|
|
|
interface ListKeysApiResponse {
|
|
keys: Array<{
|
|
id: string;
|
|
type: string;
|
|
name: string | null;
|
|
scopes: string[];
|
|
isActive: boolean;
|
|
createdAt: string;
|
|
expiresAt: string | null;
|
|
lastUsedAt: string | null;
|
|
createdBy: string | null;
|
|
organization: {
|
|
id: string;
|
|
slug: string;
|
|
name: string;
|
|
email: string;
|
|
} | null;
|
|
project: {
|
|
id: string;
|
|
slug: string;
|
|
name: string;
|
|
} | null;
|
|
}>;
|
|
total: number;
|
|
}
|
|
|
|
interface ApiKeyListItem {
|
|
id: string;
|
|
keyType: string;
|
|
name: string | null;
|
|
scopes: string[];
|
|
isActive: boolean;
|
|
createdAt: Date;
|
|
expiresAt: Date | null;
|
|
lastUsedAt: Date | null;
|
|
organizationId: string | null;
|
|
organizationName: string | null;
|
|
organizationEmail: string | null;
|
|
projectId: string | null;
|
|
projectName: string | null;
|
|
}
|
|
|
|
export async function bootstrapMasterKey(): Promise<{
|
|
success: boolean;
|
|
apiKey?: string;
|
|
error?: string;
|
|
}> {
|
|
try {
|
|
const response = await fetch(`${API_BASE_URL}/api/bootstrap/initial-key`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
});
|
|
|
|
if (!response.ok) {
|
|
const error = await response.json();
|
|
return { success: false, error: error.message || 'Failed to bootstrap master key' };
|
|
}
|
|
|
|
const data: BootstrapResponse = await response.json();
|
|
return { success: true, apiKey: data.apiKey };
|
|
} catch (error) {
|
|
console.error('Bootstrap error:', error);
|
|
return { success: false, error: 'Network error while bootstrapping master key' };
|
|
}
|
|
}
|
|
|
|
export async function createProjectApiKey(
|
|
masterKey: string,
|
|
orgSlug: string,
|
|
projectSlug: string,
|
|
): Promise<{ success: boolean; apiKey?: string; error?: string }> {
|
|
try {
|
|
// Call API service to create the project key (API auto-creates org/project)
|
|
const response = await fetch(`${API_BASE_URL}/api/admin/keys`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-API-Key': masterKey,
|
|
},
|
|
body: JSON.stringify({
|
|
type: 'project',
|
|
organizationSlug: orgSlug,
|
|
projectSlug: projectSlug,
|
|
name: `${orgSlug} - ${projectSlug}`,
|
|
}),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
const error = await response.json();
|
|
return { success: false, error: error.message || 'Failed to create API key' };
|
|
}
|
|
|
|
const data: CreateKeyResponse = await response.json();
|
|
return { success: true, apiKey: data.apiKey };
|
|
} catch (error) {
|
|
console.error('Create key error:', error);
|
|
return { success: false, error: 'Network error while creating API key' };
|
|
}
|
|
}
|
|
|
|
export async function listApiKeys(masterKey: string): Promise<ApiKeyListItem[]> {
|
|
try {
|
|
if (!masterKey) {
|
|
console.error('Master key not provided');
|
|
return [];
|
|
}
|
|
|
|
const response = await fetch(`${API_BASE_URL}/api/admin/keys`, {
|
|
method: 'GET',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-API-Key': masterKey,
|
|
},
|
|
cache: 'no-store',
|
|
});
|
|
|
|
if (!response.ok) {
|
|
console.error('Failed to fetch API keys:', response.statusText);
|
|
return [];
|
|
}
|
|
|
|
const data: ListKeysApiResponse = await response.json();
|
|
|
|
// Transform nested API response to flat structure for backwards compatibility
|
|
return data.keys.map((key) => ({
|
|
id: key.id,
|
|
keyType: key.type,
|
|
name: key.name,
|
|
scopes: key.scopes,
|
|
isActive: key.isActive,
|
|
createdAt: new Date(key.createdAt),
|
|
expiresAt: key.expiresAt ? new Date(key.expiresAt) : null,
|
|
lastUsedAt: key.lastUsedAt ? new Date(key.lastUsedAt) : null,
|
|
organizationId: key.organization?.id || null,
|
|
organizationName: key.organization?.name || null,
|
|
organizationEmail: key.organization?.email || null,
|
|
projectId: key.project?.id || null,
|
|
projectName: key.project?.name || null,
|
|
}));
|
|
} catch (error) {
|
|
console.error('List keys error:', error);
|
|
return [];
|
|
}
|
|
}
|