docs: add lic server api spec and index in second brain

This commit is contained in:
DanielS
2026-07-15 00:58:13 +02:00
parent d5593900fb
commit f783a98392
3 changed files with 179 additions and 0 deletions

View File

@@ -2,3 +2,4 @@
- [Supabase Schema](file:///c:/source/webshop/.brain/supabase-schema.md) - [Supabase Schema](file:///c:/source/webshop/.brain/supabase-schema.md)
- [ADR Log](file:///c:/source/webshop/.brain/adr-log.md) - [ADR Log](file:///c:/source/webshop/.brain/adr-log.md)
- [LicServer API Spezifikation](file:///c:/source/webshop/.brain/licserver-api.md)

114
.brain/licserver-api.md Normal file
View File

@@ -0,0 +1,114 @@
# LicServer API Spezifikation (v1)
Dokumentation der REST-Schnittstellen des CASPOS Lizenzservers (`http://192.168.178.174:9981`).
## 1. Endpunkte
### Activation (Aktivierung)
#### `POST /v1/activate`
Aktiviert eine neue Lizenz.
**Request Body (`application/json`):**
```json
{
"productId": "string",
"productVersion": "string",
"activationCode": "string",
"hardwareBindingType": "string",
"hardwareBindingId": "string"
}
```
**Response `200 OK` (`application/json`):**
```json
{
"licenseData": {
"id": "string",
"serialNumber": "string",
"productId": "string",
"filename": "string",
"content": "string" // Base64 Byte-Inhalt
},
"apiKey": "string",
"secret": "string"
}
```
**Response Headers:**
- `ETag` (string): Der ETag-Wert der Lizenz.
---
#### `POST /v1/activate-existing`
Aktiviert eine bereits vorhandene Lizenz erneut.
**Request Body (`application/json`):**
```json
{
"productId": "string",
"productVersion": "string",
"serialNumber": "string",
"proofOfPossessionHash": "string",
"salt": "string",
"hardwareBindingType": "string",
"hardwareBindingId": "string"
}
```
**Response `200 OK` (`application/json`):**
*Gleiche Struktur wie bei `/v1/activate`.*
---
### Licenses (Lizenzen)
#### `GET /v1/licenses/{id}`
Holt die Lizenz-Details zu einer bestimmten Lizenz-ID.
**Request Parameters:**
- `id` (path, string, required): Die UUID der Lizenz.
- `If-None-Match` (header, string, optional): ETag zur Cache-Validierung.
**Response `200 OK` (`application/json`):**
```json
{
"id": "string",
"serialNumber": "string",
"productId": "string",
"filename": "string",
"content": "string" // Base64 Byte-Inhalt
}
```
**Response `304 Not Modified`:**
Falls die Lizenz nicht verändert wurde.
**Response `404 Not Found` / `403 Forbidden`:**
Standard Fehlerobjekt `ProblemDetails`.
---
## 2. Typen & Schemas
### `LicenseData`
```json
{
"id": "string",
"serialNumber": "string",
"productId": "string",
"filename": "string",
"content": "string" // Base64 Byte-Inhalt
}
```
### `ProblemDetails`
```json
{
"type": "string",
"title": "string",
"status": 0,
"detail": "string",
"instance": "string"
}
```

64
shop/scratch_test.js Normal file
View File

@@ -0,0 +1,64 @@
const { createClient } = require('@supabase/supabase-js');
const fs = require('fs');
const path = require('path');
// Read .env.local
const envPath = path.join(__dirname, '.env.local');
const envContent = fs.readFileSync(envPath, 'utf8');
const env = {};
envContent.split('\n').forEach(line => {
const parts = line.split('=');
if (parts.length >= 2) {
env[parts[0].trim()] = parts.slice(1).join('=').trim();
}
});
const supabaseUrl = env['NEXT_PUBLIC_SUPABASE_URL'];
const supabaseKey = env['SUPABASE_SERVICE_ROLE_KEY'];
async function main() {
const supabase = createClient(supabaseUrl, supabaseKey);
const { data: licRow, error } = await supabase
.from('settings')
.select('licserver_base_url, licserver_api_key')
.eq('id', 'licserver')
.single();
if (error || !licRow) {
console.error("Failed to load licserver config:", error);
return;
}
const base = 'http://192.168.178.174:9981'; // Target API port 9981
const apiKey = licRow.licserver_api_key;
console.log("Using API Base:", base);
console.log("API Key found:", apiKey ? "Yes (length " + apiKey.length + ")" : "No");
// Try some standard endpoints
const endpoints = [
'/api-v1/licenses',
'/api-v1/partners',
'/api-v1/companies',
];
for (const ep of endpoints) {
const url = base + ep;
console.log(`\nFetching: ${url}`);
try {
const res = await fetch(url, {
headers: {
'X-Api-Key': apiKey || '',
'Accept': 'application/json'
}
});
console.log(`Status: ${res.status} ${res.statusText}`);
const text = await res.text();
console.log(`Response (first 500 chars):`, text.substring(0, 500));
} catch (e) {
console.error(`Error fetching ${url}:`, e.message);
}
}
}
main();