Skip to content

Secretele proiectului

Construiești ceva care comunică cu un API real? Vei avea nevoie de o cheie API — iar adăugarea ei direct în cod este o idee proastă: proiectele pot fi partajate, bifurcate (forked) și sunt vizibile pentru oricine are linkul.

Secretele rezolvă această problemă. Un secret este o pereche nume + valoare (de exemplu OPENAI_API_KEY = sk-…) pe care DojoCode o stochează criptată și o injectează în runtime-ul proiectului tău ca variabilă de mediu. Codul tău citește numele; valoarea nu apare niciodată în fișierele tale, în editor sau pentru altcineva.

Doar scriere prin design

Odată salvată, valoarea unui secret nu mai poate fi vizualizată niciodată — nici de tine, nici de alți utilizatori, nici de Asistentul AI. Poți doar să o înlocuiești sau să o ștergi. Dacă uiți o valoare, setează una nouă.

Cum funcționează secretele

  • Două domenii de aplicare. Secretele de cont (globale) sunt ale tale peste tot — fiecare proiect pe care îl deschizi le poate folosi. Secretele de proiect sunt declarate pentru un singur proiect.
  • Proiectul suprascrie globalul. Dacă un secret de proiect și un secret de cont au același nume, valoarea din proiect are prioritate în cadrul acelui proiect.
  • Fiecare vine cu propriile valori. Atunci când un alt utilizator îți deschide proiectul, acesta furnizează propriile valori pentru secretele de care are nevoie proiectul tău. Valorile tale nu sunt niciodată partajate — secretele sunt private per utilizator și per proiect.
  • Criptate în repaus (at rest), injectate la runtime. Valorile sunt criptate AES în baza de date și decriptate doar atunci când codul tău rulează efectiv — în previzualizarea din browser sau în sandbox-ul de rulare (Run).

Secretele de cont (Setări)

Gestionează-ți secretele globale din Setări cont → Secrete — ultima filă de pe pagina ta de setări.

Fiecare secret are:

CâmpScop
NumeVariabila de mediu pe care o citește codul tău, de ex. OPENAI_API_KEY.
Descriere (opțional)Scopul secretului. De asemenea, este afișată Asistentului AI, astfel încât acesta să știe că secretul există — valoarea nu este afișată niciodată.
ValoareDoar scriere. Afișată ca •••••••• de atunci încolo.

Apasă pe New secret (Secret nou), oferă-i un nume, o descriere opțională și valoarea — asta este tot:

Secretele de proiect (fila Secrete)

Fiecare editor de proiect — atât în pagina de editare, cât și în cea de vizualizare — are o filă Secrete lângă Detalii.

În calitate de autor al proiectului (pagina de editare): secretele pe care le adaugi aici devin cerințe ale proiectului. Acestea suprascriu secretele de cont cu același nume, iar oricui deschide proiectul i se va cere să furnizeze propriile valori pentru aceste nume. Ștergerea unui secret îl elimină din cerințele proiectului și șterge valoarea salvată a fiecărui utilizator pentru acesta.

În calitate de vizitator (pagina de vizualizare): fila Secrete arată numele declarate de autor, dacă ai configurat o valoare pentru fiecare, și îți permite să adaugi secrete suplimentare proprii pentru acest proiect — chiar dacă autorul nu a declarat niciunul. Dacă un nume solicitat se potrivește cu unul dintre secretele tale de cont, acesta este completat automat.

Dacă proiectul necesită secrete pe care nu le-ai setat, un mesaj de notificare îți va propune să deschizi fila Secrete. Poți să treci peste — secretele nesetate sunt pur și simplu undefined la runtime:

Oaspeții nu pot deschide proiecte care folosesc secrete — este necesară autentificarea:

Reguli de denumire și limite

  • Numele încep cu o literă sau cu _ și pot conține litere, cifre și caractere de subliniere. Numele sunt sensibile la majuscule și minuscule (case-sensitive) — OPENAI_API_KEY, apiKey, _internal_token.
  • Prefixe rezervate pe care nu le poți folosi: DOJOCODE_, VITE_DOJOCODE_, NODE_, NPM_, PATH.
  • Până la 100 de secrete de cont și 100 de secrete per proiect; valori de până la 8 KB.

Citirea secretelor în codul tău

Modul în care citești un secret depinde de runtime-ul șablonului. Referință rapidă:

ȘabloaneCitește cu
React, ReactTS, Vue, VueTS, Svelte, SolidJS, SolidTS, VanillaJS, VanillaTS, React Native, React Native TSimport.meta.env.VITE_NAME
SvelteKit, SvelteKit TS, Remix, Remix TSimport.meta.env.VITE_NAME (client) · process.env.NAME (cod server)
Next.js, Next.js TSprocess.env.NAME (Server Components, rute API)
Astro, AstroTSimport.meta.env.NAME
Angularimport { DOJOCODE_ENV } from './dojocode-env'; apoi DOJOCODE_ENV['NAME']
NodeJS, NodeTS, Fastify, Hono, NestJSprocess.env.NAME
Pythonos.environ["NAME"]
JavaSystem.getenv("NAME")
C#System.Environment.GetEnvironmentVariable("NAME")
Cgetenv("NAME")
C++std::getenv("NAME")
Goos.Getenv("NAME")
Ruststd::env::var("NAME")
RubyENV["NAME"]
PHPgetenv('NAME')
Solidityvm.envString("NAME")
PGlite, SQLiteNu este disponibil — mediile de testare (playgrounds) SQL nu au un runtime care să citească variabilele de mediu.

Toate exemplele de mai jos presupun un secret numit API_KEY.

Browser templates (Vite)

Codul din browser poate vedea doar variabilele prefixate cu VITE_, așa că DojoCode expune fiecare secret și sub un alias VITE_ de asemenea. Acest lucru este sigur, deoarece previzualizarea rulează întotdeauna doar propriile tale valori pe propria ta origine temporară — iar proiectele care folosesc secrete nu pot fi publicate.

jsx
export default function App() {
  return <h1>Key: {import.meta.env.VITE_API_KEY}</h1>;
}
vue
<script setup>
const apiKey = import.meta.env.VITE_API_KEY;
</script>

<template>
  <h1>Key: {{ apiKey }}</h1>
</template>
svelte
<h1>Key: {import.meta.env.VITE_API_KEY}</h1>
jsx
export default function App() {
  return <h1>Key: {import.meta.env.VITE_API_KEY}</h1>;
}
js
document.querySelector('#app').textContent = import.meta.env.VITE_API_KEY;
jsx
import { View, Text } from 'react-native';

export default function App() {
  return (
    <View>
      <Text>Key: {import.meta.env.VITE_API_KEY}</Text>
    </View>
  );
}

Full-stack templates

tsx
// src/app/page.tsx — Server Components and API routes read process.env
export default function Home() {
  return <h1>Key: {process.env.API_KEY}</h1>;
}
astro
---
const apiKey = import.meta.env.API_KEY;
---
<h1>Key: {apiKey}</h1>
svelte
<!-- src/routes/+page.svelte -->
<h1>Key: {import.meta.env.VITE_API_KEY}</h1>
<!-- In +page.server.js / hooks, use process.env.API_KEY -->
tsx
// app/routes/_index.tsx
export default function Index() {
  return <h1>Key: {import.meta.env.VITE_API_KEY}</h1>;
}
// In loaders/actions (server), use process.env.API_KEY

Angular

Angular nu are în procesul de build un mecanism pentru variabile de mediu, așa că DojoCode montează un modul virtual numit dojocode-env.ts în rădăcina proiectului ori de câte ori ai secrete. Acesta apare ca read-only în arborele de fișiere, astfel încât să poți vedea ce nume există — valorile din interior sunt completate doar în previzualizarea care rulează, niciodată în editor.

ts
// app.component.ts
import { Component } from '@angular/core';
import { DOJOCODE_ENV } from './dojocode-env';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent {
  apiKey = DOJOCODE_ENV['API_KEY'];
}

ATENȚIE

Nu crea și nu edita niciodată singur dojocode-env.ts — platforma se ocupă de gestionarea acestuia și nu este salvat niciodată în proiectul tău.

Backend JavaScript templates

Funcționează la fel în NodeJS, NodeTS, Fastify, Hono și NestJS:

js
console.log(process.env.API_KEY);

Python

python
import os

print(os.environ["API_KEY"])          # raises KeyError if unset
print(os.environ.get("API_KEY"))      # None if unset

Limbaje compilate și altele

Aceste șabloane rulează în panoul Output (butonul Run); secretele sunt injectate în mediul de rulare.

java
public class HelloWorld {
    public static String hello() {
        return System.getenv("API_KEY");
    }
}
csharp
namespace Challenge
{
    public class HelloWorld
    {
        public static string Hello()
        {
            return System.Environment.GetEnvironmentVariable("API_KEY");
        }
    }
}
c
#include <stdlib.h>
#include <stdio.h>

void print() {
    printf("%s\n", getenv("API_KEY"));
}
cpp
#include <cstdlib>
#include <iostream>

int main() {
    std::cout << std::getenv("API_KEY") << std::endl;
}
go
package main

import (
    "fmt"
    "os"
)

func main() {
    fmt.Println(os.Getenv("API_KEY"))
}
rust
fn main() {
    println!("{}", std::env::var("API_KEY").unwrap_or_default());
}
ruby
puts ENV["API_KEY"]
php
<?php
echo getenv('API_KEY');
solidity
// In a Foundry script (Main.s.sol)
import "forge-std/Script.sol";
import "forge-std/console.sol";

contract Main is Script {
    function run() external {
        console.log(vm.envString("API_KEY"));
    }
}

Playground-uri SQL

Șabloanele PGlite și SQLite execută doar fișiere .sql — nu există cod de utilizator care să poată citi o variabilă de mediu, prin urmare secretele nu sunt disponibile acolo, iar fila Secrets este ascunsă.

Secretele și publicarea

Un site publicat (*.dojocode.net) este un build static, public — orice valoare secretă utilizată în timpul build-ului ar ajunge să fie lizibilă în bundle. Pentru a-ți păstra cheile în siguranță, publicarea este blocată atunci când un proiect folosește secrete:

  • proiectul declară secrete de proiect, sau
  • codul său face referire la oricare dintre numele de secrete ale contului tău.

Caseta de dialog Publish explică exact ce nume blochează publicarea și rămâne blocată până când elimini referințele (sau le redenumești). Variabilele de deployment setate de proprietar sunt planificate pentru o versiune viitoare.

Secretele și Alex (asistentul AI)

Alex vede numele și descrierile secretelor disponibile pentru proiect — niciodată valorile. În acest fel, poate scrie cod care citește process.env.API_KEY pentru tine, se poate asigura că tratează valorile lipsă și te poate direcționa către panoul Secrets atunci când o funcționalitate are nevoie de o cheie pe care nu ai adăugat-o încă. Va refuza să scrie direct în cod valori secrete sau să scrie fișiere .env, deoarece acestea ar fi salvate în proiect pentru a fi văzute de toată lumea.

Bine de știut

  • Săritul peste pas este permis. Un vizitator care omite solicitarea de introducere a secretelor poate rula în continuare proiectul — secretele nesetate sunt doar undefined/goale la runtime, așa că asigură-te că tratezi valorile lipsă.
  • Fork-urile nu copiază secretele. Fă un fork unui proiect și acesta va începe de la zero; declară din nou ceea ce are nevoie.
  • Actualizarea păstrează vechea valoare dacă o lași goală. Editarea descrierii unui secret fără a tasta o nouă valoare lasă valoarea stocată neschimbată.
  • Previzualizarea se repornește automat atunci când secretele se modifică, astfel încât noile valori sunt preluate fără o reîncărcare manuală.