New: GET /api/key

This commit is contained in:
synt-xerror
2026-02-23 08:31:26 -03:00
parent 0543a9e9ce
commit b9b474af40
4 changed files with 41 additions and 70 deletions

View File

@@ -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 <API_KEY>
```
---
## 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)

View File

@@ -3,11 +3,15 @@
#include <stdlib.h>
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);

View File

@@ -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);
resp.data = malloc(1);
resp.len = 0;
resp.data[0] = '\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 rc = curl_easy_perform(curl);
if(rc == CURLE_OK) {
*out = resp.data;
} else {
return 1;
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;
}

View File

@@ -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