Add register-by-signature, web fixes, bin scripts, docs
CI / test (push) Successful in 5s

- Register by signing service key: GET /v1/service-key, POST /v1/auth/register-by-signature
- Login auto-attempts register first for new users
- Web: default API URL momswap.produktor.duckdns.org, /libs/ static handler
- Docker: webbuild stage for geo-api-client, copy web+libs to runtime
- Bin scripts: test.sh, run.sh, up.sh, down.sh
- docs/ed25519-security-use-cases.md: use cases, message formats, examples
- SERVICE_PUBLIC_KEY env (defaults to ADMIN_PUBLIC_KEY)

Made-with: Cursor
This commit is contained in:
2026-03-01 12:58:44 +00:00
parent 978e0403eb
commit a5a97a0ad9
19 changed files with 405 additions and 41 deletions
+19 -1
View File
@@ -4,7 +4,7 @@ const { createApp, ref, reactive, onMounted } = Vue;
createApp({
setup() {
const apiBase = ref(localStorage.getItem("geo_api_base") || "http://localhost:8122");
const apiBase = ref(localStorage.getItem("geo_api_base") || "https://momswap.produktor.duckdns.org");
const state = reactive({
publicKey: "",
privateKey: "",
@@ -33,8 +33,25 @@ createApp({
}
};
const register = async () => {
try {
await client.registerBySigningServiceKey(state.publicKey, state.privateKey);
state.status = "Registered. Use Login to authenticate.";
} catch (err) {
state.status = err.message;
}
};
const login = async () => {
try {
try {
await client.registerBySigningServiceKey(state.publicKey, state.privateKey);
} catch (err) {
if (!err.message.includes("already registered") && !err.message.includes("not configured")) {
throw err;
}
// Proceed to login: already registered or registration disabled (invitation flow)
}
state.accessToken = await client.loginWithSignature(state.publicKey, state.privateKey);
client.setAccessToken(state.accessToken);
state.status = "Authenticated.";
@@ -73,6 +90,7 @@ createApp({
state,
rebuildClient,
ensureKeys,
register,
login,
listCollections,
createCollection,