diff --git a/README.md b/README.md index 55201ce..768c86f 100755 --- a/README.md +++ b/README.md @@ -1,12 +1,6 @@ -# Neocities C API +# Neocities API C library -Minimal, secure C wrapper for the Neocities API using API key authentication. - -No login flow. -No credential storage. -Stateless by design. - -Users must generate their own API key via the Neocities dashboard. +Minimal, secure C wrapper for the Neocities API. --- @@ -16,14 +10,9 @@ Users must generate their own API key via the Neocities dashboard. * File listing * Upload files * Delete files +* Get API key * TLS verification enabled by default -Authentication is performed exclusively via: - -``` -Authorization: Bearer -``` - --- ## Requirements @@ -38,17 +27,6 @@ sudo apt install libcurl4-openssl-dev --- -## Authentication - -Generate your API key at: - -Neocities > Settings > Manage Site Settings > API -(or https://neocities.org/settings/YOUR-USERNAME#api_key) - -If you're coding a CLI or application, you must provide the key at runtime (env var, config file, etc). - ---- - ## API Overview ### Info (public) @@ -96,7 +74,11 @@ Deletes files from the site. ### API Key -For security reasons, you should get the API key via Neocities settings. This function is not avaiable. +```c +int neocities_apikey(const char *user, const char *pass, char **out); +``` + +Get your API key. --- @@ -106,28 +88,6 @@ See example.c --- -## Security Notes - -* TLS verification is enforced -* Redirects are disabled intentionally -* API key is never persisted internally - -Recommended: - -* Store key in env vars -* Avoid hardcoding - ---- - -## Design Philosophy - -* No login/password support -* API key only -* Explicit memory ownership -* Minimal abstraction - ---- - ## License [MIT](LICENSE) diff --git a/example.c b/example.c index f4292f9..b2dcec6 100644 --- a/example.c +++ b/example.c @@ -3,11 +3,15 @@ #include int main() { - static const char* username = "YOUR_USER_NAME"; + static const char* username = "YOUR_USERNAME"; static const char* api_key = "YOUR_API_KEY"; char* out = NULL; + // GET /api/key + if (neocities_apikey(username, "YOUR_PASSWORD", &out) == 0) printf("%s", out); + free(out); + // GET /api/info if (neocities_info(username, &out) == 0) printf("%s", out); free(out); diff --git a/neocities.c b/neocities.c index c6ca441..7369f65 100644 --- a/neocities.c +++ b/neocities.c @@ -239,29 +239,35 @@ int neocities_upload( // ------------------------- // key — GET /api/key // ------------------------- +int neocities_apikey(const char *user, const char *pass, char **out) { + struct response resp = {0}; -int neocities_apikey( - const char *user, - const char *pass, - char **out + char userpass[256]; + snprintf(userpass, sizeof(userpass), "%s:%s", user, pass); -) -{ - CURL *curl; - CURLcode resp; + CURL *curl = curl_easy_init(); + if (!curl) return 1; - char buf[128]; - snprintf(buf, sizeof(buf), "%s:%s", user, pass); - - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &resp); - - CURLcode rc = curl_easy_perform(curl); - if(rc == CURLE_OK) { - *out = resp.data; - } else { - return 1; - } + resp.data = malloc(1); + resp.len = 0; + resp.data[0] = '\0'; - return 0; + curl_easy_setopt(curl, CURLOPT_URL, "https://neocities.org/api/key"); + curl_easy_setopt(curl, CURLOPT_USERPWD, userpass); // aqui é equivalente ao -u do curl + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &resp); + + CURLcode res = curl_easy_perform(curl); + long http_code = 0; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); + + curl_easy_cleanup(curl); + + if (res != CURLE_OK || http_code >= 400) { + free(resp.data); + return 2; + } + + *out = resp.data; // resposta da API + return 0; } diff --git a/neocities.h b/neocities.h index a3869a0..272690a 100644 --- a/neocities.h +++ b/neocities.h @@ -10,5 +10,6 @@ int neocities_info(const char *sitename, char **out); int neocities_list(const char *api_key, const char *path, char **out); int neocities_delete(const char *api_key, const char **filenames, size_t count, char **response); int neocities_upload(const char *api_key, const char **local_files, const char **remote_names, size_t count, char **response); +int neocities_apikey(const char *user, const char *pass, char **out); #endif // NEOCITIES_H