Przejdź do głównej zawartości

Szybki start z TypeScript

Ten przewodnik przeprowadzi Cię przez uwierzytelnianie do API VaultPAM oraz wykonanie pierwszego żądania przy użyciu TypeScript i natywnego API fetch (Node.js 18+).

Wymagania wstępne:

  • Node.js 18 lub nowszy (wbudowane API fetch)
  • TypeScript 5.x (opcjonalnie — przykłady działają również jako zwykły JavaScript)
  • Konto VaultPAM z włączonym dostępem do API

Krok 1 — Skonfiguruj środowisko

# Set your base URL in the environment — never hardcode in source
export VAULTPAM_BASE_URL="https://api.vaultpam.com"
export VAULTPAM_TOKEN="<your-token>" # Never commit — see auth-flow.md#token-storage

W przypadku integracji produkcyjnych ładuj te wartości z menedżera sekretów lub z pliku .env wymienionego w .gitignore.


Krok 2 — Uwierzytelnij się

const BASE_URL = process.env.VAULTPAM_BASE_URL ?? "https://api.vaultpam.com";

interface AuthResponse {
access_token: string;
expires_in: number;
}

async function login(email: string, password: string): Promise<AuthResponse> {
const response = await fetch(`${BASE_URL}/api/v1/auth/login`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email, password }),
});

if (!response.ok) {
throw new Error(`Login failed: ${response.status} ${await response.text()}`);
}

return response.json() as Promise<AuthResponse>;
}

// Load credentials from environment — never commit to source control (see auth-flow.md#token-storage)
const email = process.env.VAULTPAM_EMAIL ?? "";
const password = process.env.VAULTPAM_PASSWORD ?? "";

const { access_token: token, expires_in: expiresIn } = await login(email, password);
console.log(`Authenticated. Token expires in ${expiresIn} seconds.`);
Nigdy nie zapisuj tokenów w repozytorium

Ładuj VAULTPAM_TOKEN z process.env lub z menedżera sekretów — nigdy nie umieszczaj poświadczeń na stałe w kodzie. Zobacz Przechowywanie tokenów.


Krok 3 — Pobierz aktywną organizację

interface OrgMembershipsResponse {
active_org_id: string;
memberships: Array<{ org_id: string; role: string }>;
}

async function getActiveOrgId(token: string): Promise<string> {
const response = await fetch(`${BASE_URL}/api/v1/org/memberships`, {
headers: { Authorization: `Bearer ${token}` },
});

if (!response.ok) {
throw new Error(`Failed to get org memberships: ${response.status}`);
}

const data = (await response.json()) as OrgMembershipsResponse;
return data.active_org_id;
}

const orgId = await getActiveOrgId(token);
console.log(`Active org: ${orgId}`);

Krok 4 — Wyświetl swoje sejfy

interface Safe {
id: string;
name: string;
}

async function listSafes(token: string, orgId: string): Promise<Safe[]> {
const response = await fetch(`${BASE_URL}/api/v1/safes`, {
headers: {
Authorization: `Bearer ${token}`,
"X-Active-Org-Id": orgId,
},
});

if (!response.ok) {
throw new Error(`Failed to list safes: ${response.status} ${await response.text()}`);
}

return response.json() as Promise<Safe[]>;
}

const safes = await listSafes(token, orgId);
console.log(`Found ${safes.length} safe(s):`);
safes.forEach((s) => console.log(` - ${s.name}`));

Pełny przykład

const BASE_URL = process.env.VAULTPAM_BASE_URL ?? "https://api.vaultpam.com";

// Load from environment — never commit to source control (see auth-flow.md#token-storage)
const email = process.env.VAULTPAM_EMAIL ?? "";
const password = process.env.VAULTPAM_PASSWORD ?? "";

async function main(): Promise<void> {
// Step 1: Authenticate
const loginResp = await fetch(`${BASE_URL}/api/v1/auth/login`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email, password }),
});
if (!loginResp.ok) throw new Error(`Login failed: ${loginResp.status}`);
const { access_token: token } = (await loginResp.json()) as { access_token: string };

// Step 2: Get active org
const orgResp = await fetch(`${BASE_URL}/api/v1/org/memberships`, {
headers: { Authorization: `Bearer ${token}` },
});
if (!orgResp.ok) throw new Error(`Org lookup failed: ${orgResp.status}`);
const { active_org_id: orgId } = (await orgResp.json()) as { active_org_id: string };

// Step 3: List safes
const safesResp = await fetch(`${BASE_URL}/api/v1/safes`, {
headers: {
Authorization: `Bearer ${token}`,
"X-Active-Org-Id": orgId,
},
});
if (!safesResp.ok) throw new Error(`Safes request failed: ${safesResp.status}`);
const safes = (await safesResp.json()) as Array<{ id: string; name: string }>;
console.log(`Safes (${safes.length}):`);
safes.forEach((s) => console.log(` ${s.name}`));
}

main().catch((err) => {
console.error(err);
process.exit(1);
});

Obsługa błędów

Wszystkie wywołania fetch sprawdzają response.ok i zgłaszają wyjątek w przypadku niepowodzenia. Typowe kody statusu:

KodZnaczenie
401 UnauthorizedToken jest brakujący, wygasł lub jest nieprawidłowy. Uwierzytelnij się ponownie.
403 ForbiddenToken nie posiada zakresu wymaganego dla tego punktu końcowego.
429 Too Many RequestsPrzekroczono limit żądań. Sprawdź nagłówek retry-after.
500 Internal Server ErrorPrzejściowy błąd serwera. Ponów próbę z wykładniczym odstępem.

Świadomość limitów żądań

const response = await fetch(`${BASE_URL}/api/v1/safes`, {
headers: { Authorization: `Bearer ${token}`, "X-Active-Org-Id": orgId },
});

const remaining = response.headers.get("x-ratelimit-remaining");
console.log(`Rate limit remaining: ${remaining}`);

Zobacz Limity żądań, aby poznać strategie wykładniczego odstępu.


Następne kroki